class RSS2Mail::Feed
Constants
- KEEP
Attributes
content[R]
debug[R]
feed[R]
reload[R]
rss[R]
simple[R]
transport[R]
updated[R]
verbose[R]
Public Class Methods
new(feed, options = {})
click to toggle source
# File lib/rss2mail/feed.rb, line 35 def initialize(feed, options = {}) raise TypeError, "Hash expected, got #{feed.class}" unless feed.is_a?(Hash) required = [:url, :to, :title].delete_if { |key| feed.key?(key) } unless required.empty? raise ArgumentError, "Feed incomplete: #{required.join(', ')} missing" end @feed = feed @simple = feed[:simple] @updated = feed[:updated] @reload = options[:reload] @verbose = options[:verbose] @debug = options[:debug] klass, opt = transport_from(options) @transport = "#{klass.name.split('::').last} @ #{opt}" extend klass end
Public Instance Methods
deliver(templates)
click to toggle source
# File lib/rss2mail/feed.rb, line 62 def deliver(templates) check_deliver_requirements if respond_to?(:check_deliver_requirements) if (to = Array(feed[:to])).empty? log 'No one to send to' return end unless get && parse log 'Nothing to send' return end if (items = rss.items).empty? log 'No new items' return end type = feed[:content_type] || 'text/html' if template = templates[type[/\/(.*)/, 1]] type = "Content-type: #{type}; charset=#{feed[:encoding] || 'UTF-8'}" else log "Template not found: #{type}" return end sent = feed[:sent] ||= [] count, title = 0, feed[:title] items.each { |item| link, subject, body = render(feed, item, template) send_mail(to, "[#{title}] #{subject}", body, type) { sent << link count += 1 } if link } sent.uniq! sent.slice!(0...-KEEP) log "#{count} items sent" count end
Private Instance Methods
error(err = nil, occasion = nil, extra = nil)
click to toggle source
# File lib/rss2mail/feed.rb, line 239 def error(err = nil, occasion = nil, extra = nil) msg = 'Error' msg << " #{occasion}" if occasion msg << ": #{err} (#{err.class})" if err msg << " [#{extra}]" if extra msg = [msg, *err.backtrace].join("\n ") if debug log msg, true end
get(reload = reload())
click to toggle source
# File lib/rss2mail/feed.rb, line 133 def get(reload = reload()) conditions = {} if reload @content = nil else if etag = feed[:etag] conditions['If-None-Match'] = etag end if mtime = feed[:mtime] conditions['If-Modified-Since'] = mtime end end log conditions.inspect, debug begin open_feed(feed[:url], conditions) { |uri| if etag = uri.meta['etag'] feed[:etag] = etag else feed.delete(:etag) end if mtime = begin; uri.last_modified; rescue ArgumentError; end feed[:mtime] = mtime.rfc822 else feed.delete(:mtime) end unless etag || mtime feed[:updated] = Time.now else feed.delete(:updated) end @content ||= uri.read } log feed.values_at(:etag, :mtime, :updated).inspect, debug rescue OpenURI::HTTPError => err log "Feed not found or unchanged: #{err} (#{err.class})" rescue Exception => err error err, 'while getting feed' end content end
log(msg, verbose = verbose())
click to toggle source
# File lib/rss2mail/feed.rb, line 235 def log(msg, verbose = verbose()) warn "[#{feed[:title]}] #{msg}" if verbose end
parse(reload = reload())
click to toggle source
# File lib/rss2mail/feed.rb, line 183 def parse(reload = reload()) @rss = nil if reload if content @rss ||= RSS.feed(content, simple) { |err| error err, 'while parsing feed' } if rss && !reload if update = updated rss.items.delete_if { |item| (date = item.date) && date <= update } end if sent = feed[:sent] set = Set.new(sent) rss.items.delete_if { |item| set.include?(item.link) } end end else log 'Nothing to parse' end rss end
render(feed, item, template)
click to toggle source
# File lib/rss2mail/feed.rb, line 208 def render(feed, item, template) title = item.title link = item.link description = item.description(feed[:unescape_html]) date = item.date author = item.author body = item.body(feed[:body]) subject = item.subject log "#{title} / #{date} [#{author}]", debug log "<#{link}>", debug [link, subject, ERB.new(template).result(binding)] rescue => err error err, 'while rendering feed', title end
send_mail(*args) { || ... }
click to toggle source
# File lib/rss2mail/feed.rb, line 225 def send_mail(*args) return if debug deliver_mail(*args) yield if block_given? rescue Exception => err error err, 'while sending mail', transport end
transport_from(options)
click to toggle source
# File lib/rss2mail/feed.rb, line 110 def transport_from(options) if lmtp = options[:lmtp] or smtp = options[:smtp] klass = smtp ? Transport::SMTP : Transport::LMTP case @smtp = lmtp || smtp when Array # ok when true then @smtp = [] when Fixnum then @smtp = [nil, @smtp] when String then @smtp = @smtp.split(':') else raise TypeError, "Array expected, got #{@smtp.class}" end host, port = @smtp.shift, @smtp.shift host = klass::DEFAULT_HOST if host.nil? || host.empty? port = klass::DEFAULT_PORT if port.nil? [klass, @smtp.unshift(port.to_i).unshift(host)[0, 4].join(':')] else [klass = Transport::Mail, "#{klass::CMD} = #{klass::BIN.inspect}"] end end