Skip to content

Instantly share code, notes, and snippets.

@jawngee
Created April 27, 2009 18:33
Show Gist options
  • Save jawngee/102646 to your computer and use it in GitHub Desktop.
Save jawngee/102646 to your computer and use it in GitHub Desktop.
imap:
server: imap.gmail.com
port: 993
user: YOUR GMAIL ADDRESS
password: YOUR PASSWORD
mailbox: INBOX
#!/usr/bin/env ruby
#
# Created by on 2009-04-25.
# Copyright (c) 2009. All rights reserved.
require 'net/imap'
require 'yaml'
require 'rss/maker'
conf=YAML::load(File.open('conf.yaml'))
version = "2.0" # ["0.9", "1.0", "2.0"]
destination = "test_maker.xml" # local file to write
imap = Net::IMAP.new(conf['imap']['server'],conf['imap']['port'],true)
imap.login(conf['imap']['user'], conf['imap']['password'])
imap.select(conf['imap']['mailbox'])
content = RSS::Maker.make(version) do |m|
m.channel.title = "Gmail Feed"
m.channel.link = "http://www.interfacelab.com"
m.channel.description = "Gmail inbox as RSS"
m.items.do_sort = true # sort items by date
imap.search(["NOT", "DELETED"]).each do |message_id|
envelope=imap.fetch(message_id, "ENVELOPE")[0].attr["ENVELOPE"]
body=imap.fetch(message_id, "BODY[TEXT]")[0].attr["BODY[TEXT]"]
puts "#{envelope.from[0].name}: \t#{envelope.subject}\n"
i = m.items.new_item
i.title = envelope.subject
i.description = body
i.date = Time.parse(envelope.date)
# break
end
end
File.open(destination,"w") do |f|
f.write(content)# break
end
imap.logout()
imap.disconnect()
#
# RubyRSS
# Copyright (c) 2006 Sergey Tikhonov <st@dairon.net>
# Distributed under MIT License
#
require "simple-rss"
require "open-uri"
load "templates.rb"
class RubyRSS
attr_accessor :title, :link, :desc, :date, :items
attr_reader :filename
class Item < self
attr_accessor :title, :link, :desc, :date
def initialize( title, link, desc, date )
@title = title
@link = link
@desc = desc
@date = date
end
end
def initialize( filename )
@filename = filename
@title = ""
@link = ""
@date = Time.new
@items = []
end
def parse( template_name = "default" )
rss = SimpleRSS.parse open(@filename)
@title = rss.channel.title
@link = rss.channel.link
@date = rss.channel.pubDate || rss.channel.lastBuildDate || rss.channel.modified || Time.now.gmtime
rss.items.each { |item|
d = item.pubDate || item.lastBuildDate || item.modified || Time.now.gmtime
@items << Item.new( item.title, item.link, item.description, d )
}
html = $html_templates[ template_name ].strip
item_html = ($1).strip if html =~ /#items-start(?::\d+)?(.+)#items-end/m
num_items, desc_size = 10, 0
num_items = ($1).to_i if html =~ /#items-start:(\d+)/
desc_size = ($1).to_i if html =~ /#item-desc:(\d+)/
html.gsub!( /#title/, title )
html.gsub!( /#link/, link )
html.gsub!( /#desc/, desc ) if desc
html.gsub!( /#date/, date.to_s )
items_html = ""
items[0..num_items].each { |item|
temp_html = item_html.dup
temp_html.gsub!( /#item-title/, item.title )
temp_html.gsub!( /#item-link/, item.link )
d = item.desc
if desc_size != 0
d = CGI.unescapeHTML(d).gsub( /<([^>]+)>/, "" )
d = d[ 0, desc_size ]
d.gsub!( /(\s[^\s]*)$/, "&hellip;" )
end
temp_html.gsub!( /#item-desc(:\d+)?/, d )
temp_html.gsub!( /#item-date/, item.date.strftime("%b %d %H:%M") )
items_html << temp_html
}
html.gsub!( /#items-start(:\d+)?(.*)#items-end/m, items_html )
html
end
def generate( template_name = "rss2.0" )
rss = $rss_templates[ template_name ].strip
item_rss = ($1).strip if rss =~ /#items-start(.+)#items-end/m
rss.gsub!( /#title/, title )
rss.gsub!( /#link/, link )
rss.gsub!( /#desc/, desc )
rss.gsub!( /#date/, date.to_s )
items_rss = ""
items.each { |item|
temp_rss = item_rss.dup
temp_rss.gsub!( /#item-title/, item.title )
temp_rss.gsub!( /#item-link/, item.link )
temp_rss.gsub!( /#item-desc/, CGI.escapeHTML(item.desc) )
temp_rss.gsub!( /#item-date/, item.date.to_s )
items_rss << temp_rss + "\n"
}
rss.gsub!( /#items-start\n(.*)#items-end\n/m, items_rss )
rss
end
end
require 'cgi'
require 'time'
class SimpleRSS
VERSION = "1.2"
attr_reader :items, :source
alias :entries :items
@@feed_tags = [
:id,
:title, :subtitle, :link,
:description,
:author, :webMaster, :managingEditor, :contributor,
:pubDate, :lastBuildDate, :updated, :'dc:date',
:generator, :language, :docs, :cloud,
:ttl, :skipHours, :skipDays,
:image, :logo, :icon, :rating,
:rights, :copyright,
:textInput, :'feedburner:browserFriendly',
:'itunes:author', :'itunes:category'
]
@@item_tags = [
:id,
:title, :link, :'link+alternate', :'link+self', :'link+edit', :'link+replies',
:author, :contributor,
:description, :summary, :content, :'content:encoded', :comments,
:pubDate, :published, :updated, :expirationDate, :modified, :'dc:date',
:category, :guid,
:'trackback:ping', :'trackback:about',
:'dc:creator', :'dc:title', :'dc:subject', :'dc:rights', :'dc:publisher',
:'feedburner:origLink'
]
def initialize(source)
@source = source.respond_to?(:read) ? source.read : source.to_s
@items = Array.new
parse
end
def channel() self end
alias :feed :channel
class << self
def feed_tags
@@feed_tags
end
def feed_tags=(ft)
@@feed_tags = ft
end
def item_tags
@@item_tags
end
def item_tags=(it)
@@item_tags = it
end
# The strict attribute is for compatibility with Ruby's standard RSS parser
def parse(source, do_validate=true, ignore_unknown_element=true, parser_class=false)
new source
end
end
private
def parse
raise SimpleRSSError, "Poorly formatted feed" unless @source =~ %r{<(channel|feed).*?>.*?</(channel|feed)>}mi
# Feed's title and link
feed_content = $1 if @source =~ %r{(.*?)<(rss:|atom:)?(item|entry).*?>.*?</(rss:|atom:)?(item|entry)>}mi
@@feed_tags.each do |tag|
if feed_content && feed_content =~ %r{<(rss:|atom:)?#{tag}(.*?)>(.*?)</(rss:|atom:)?#{tag}>}mi
nil
elsif feed_content && feed_content =~ %r{<(rss:|atom:)?#{tag}(.*?)\/\s*>}mi
nil
elsif @source =~ %r{<(rss:|atom:)?#{tag}(.*?)>(.*?)</(rss:|atom:)?#{tag}>}mi
nil
elsif @source =~ %r{<(rss:|atom:)?#{tag}(.*?)\/\s*>}mi
nil
end
if $2 || $3
tag_cleaned = clean_tag(tag)
eval %{ @#{ tag_cleaned } = clean_content(tag, $2, $3) }
self.class.class_eval %{ attr_reader :#{ tag_cleaned } }
end
end
# RSS items' title, link, and description
@source.scan( %r{<(rss:|atom:)?(item|entry)([\s][^>]*)?>(.*?)</(rss:|atom:)?(item|entry)>}mi ) do |match|
item = Hash.new
@@item_tags.each do |tag|
if tag.to_s.include?("+")
tag_data = tag.to_s.split("+")
tag = tag_data[0]
rel = tag_data[1]
if match[3] =~ %r{<(rss:|atom:)?#{tag}(.*?)rel=['"]#{rel}['"](.*?)>(.*?)</(rss:|atom:)?#{tag}>}mi
nil
elsif match[3] =~ %r{<(rss:|atom:)?#{tag}(.*?)rel=['"]#{rel}['"](.*?)/\s*>}mi
nil
end
item[clean_tag("#{tag}+#{rel}")] = clean_content(tag, $3, $4) if $3 || $4
else
if match[3] =~ %r{<(rss:|atom:)?#{tag}(.*?)>(.*?)</(rss:|atom:)?#{tag}>}mi
nil
elsif match[3] =~ %r{<(rss:|atom:)?#{tag}(.*?)/\s*>}mi
nil
end
item[clean_tag(tag)] = clean_content(tag, $2, $3) if $2 || $3
end
end
def item.method_missing(name, *args) self[name] end
@items << item
end
end
def clean_content(tag, attrs, content)
content = content.to_s
case tag
when :pubDate, :lastBuildDate, :published, :updated, :expirationDate, :modified, :'dc:date'
Time.parse(content) rescue unescape(content)
when :author, :contributor, :skipHours, :skipDays
unescape(content.gsub(/<.*?>/,''))
else
content.empty? && "#{attrs} " =~ /href=['"]?([^'"]*)['" ]/mi ? $1.strip : unescape(content)
end
end
def clean_tag(tag)
tag.to_s.gsub(':','_').intern
end
def unescape(content)
if content =~ /([^-_.!~*'()a-zA-Z\d;\/?:@&=+$,\[\]]%)/n then
CGI.unescape(content).gsub(/(<!\[CDATA\[|\]\]>)/,'').strip
else
content.gsub(/(<!\[CDATA\[|\]\]>)/,'').strip
end
end
end
class SimpleRSSError < StandardError
end
#
# RubyRSS
# Copyright (c) 2006 Sergey Tikhonov <st@dairon.net>
# Distributed under MIT License
#
$html_templates = { "default" => '
<h3><a href="#link">#title</a></h3>
<ul>
#items-start:5
<li><a href="#item-link">#item-title</a> (#item-date)<br/>
#item-desc:100</li>
#items-end
</ul>
'
}
$rss_templates = { "rss2.0" => '
<?xml version="1.0" encoding="iso-8859-1"?>
<rss version="2.0">
<channel>
<title>#title</title>
<link>#link</link>
<description>#desc</description>
<pubDate>#date</pubDate>
<language>en-us</language>
<ttl>60</ttl>
#items-start
<item>
<title>#item-title</title>
<link>#item-link</link>
<description>#item-desc</description>
<pubDate>#item-date</pubDate>
<guid isPermaLink="true">#item-link</guid>
</item>
#items-end
</channel>
</rss>
'
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment