:dc_creator => %w{dc_creator}
}.each { |name, chain| def_bang name, chain }
+ def categories!
+ return nil unless self.respond_to? :categories
+ cats = categories.map do |c|
+ blank2nil { c.content rescue c rescue nil }
+ end.compact
+ cats.empty? ? nil : cats
+ end
+
protected
def blank2nil(&block)
x = yield
:default => true,
:desc => "Whether to display links from the text of a feed item.")
+ Config.register Config::EnumValue.new('rss.announce_method',
+ :values => ['say', 'notice'],
+ :default => 'say',
+ :desc => "Whether to display links from the text of a feed item.")
+
# Make an 'unique' ID for a given item, based on appropriate bot options
# Currently only suppored is bot.config['rss.show_updated']: when false,
# only the guid/link is accounted for.
# Auxiliary method used to collect two lines for rss output filters,
# running substitutions against DataStream _s_ optionally joined
- # with hash _h_
+ # with hash _h_.
+ #
+ # For substitutions, *_wrap keys can be used to alter the content of
+ # other nonempty keys. If the value of *_wrap is a String, it will be
+ # put before and after the corresponding key; if it's an Array, the first
+ # and second elements will be used for wrapping; if it's nil, no wrapping
+ # will be done (useful to override a default wrapping).
+ #
+ # For example:
+ # :handle_wrap => '::'::
+ # will wrap s[:handle] by prefixing and postfixing it with '::'
+ # :date_wrap => [nil, ' :: ']::
+ # will put ' :: ' after s[:date]
def make_stream(line1, line2, s, h={})
ss = s.merge(h)
- DataStream.new([line1, line2].compact.join("\n") % ss, ss)
+ subs = {}
+ wraps = {}
+ ss.each do |k, v|
+ kk = k.to_s.chomp!('_wrap')
+ if kk
+ nk = kk.intern
+ case v
+ when String
+ wraps[nk] = ss[nk].wrap_nonempty(v, v)
+ when Array
+ wraps[nk] = ss[nk].wrap_nonempty(*v)
+ when nil
+ # do nothing
+ else
+ warning "ignoring #{v.inspect} wrapping of unknown class"
+ end
+ else
+ subs[k] = v
+ end
+ end
+ subs.merge! wraps
+ DataStream.new([line1, line2].compact.join("\n") % subs, ss)
end
# Auxiliary method used to define rss output filters
# Define default output filters (rss types), and load custom ones.
# Custom filters are looked for in the plugin's default filter locations
- # and in rss/types under botclass.
+ # and in rss/types.rb under botclass.
# Preferably, the rss_type method should be used in these files, e.g.:
# rss_type :my_type do |s|
# line1 = "%{handle} and some %{author} info"
# make_stream(line1, nil, s)
# end
- # to define the new type 'my_type'
+ # to define the new type 'my_type'. The keys available in the DataStream
+ # are:
+ # item::
+ # the actual rss item
+ # handle::
+ # the item handle
+ # date::
+ # the item date
+ # title::
+ # the item title
+ # desc, link, category, author::
+ # the item description, link, category, author
+ # at::
+ # the string ' @ ' if the item has both an title and a link
+ # handle_wrap, date_wrap, title_wrap, ...::
+ # these keys can be defined to wrap the corresponding elements if they
+ # are nonempty. By default handle is wrapped with '::', date has a ' ::'
+ # appended and title is enbolden
+ #
def define_filters
@outkey ||= :"rss.out"
m.reply "Channel : #{title}"
disp.each do |item|
- printFormattedRss(feed, item, {:places=>[m.replyto],:handle=>nil,:date=>true})
+ printFormattedRss(feed, item, {
+ :places => [m.replyto],
+ :handle => nil,
+ :date => true,
+ :announce_method => :say
+ })
end
end
return seconds
end
+ def make_date(obj)
+ if obj.kind_of? Time
+ obj.strftime("%Y/%m/%d %H:%M")
+ else
+ obj.to_s
+ end
+ end
+
def printFormattedRss(feed, item, options={})
# debug item
opts = {
:places => feed.watchers,
- :handle => feed.handle.empty? ? "" : "::#{feed.handle}:: ",
- :date => false
+ :handle => feed.handle,
+ :date => false,
+ :announce_method => @bot.config['rss.announce_method']
}.merge options
- date = String.new
-
places = opts[:places]
+ announce_method = opts[:announce_method]
+
handle = opts[:handle].to_s
+
+ date = \
if opts[:date]
if item.respond_to?(:updated)
- if item.updated.content.class <= Time
- date = item.updated.content.strftime("%Y/%m/%d %H:%M")
- else
- date = item.updated.content.to_s
- end
+ make_date(item.updated.content)
elsif item.respond_to?(:source) and item.source.respond_to?(:updated)
- if item.source.updated.content.class <= Time
- date = item.source.updated.content.strftime("%Y/%m/%d %H:%M")
- else
- date = item.source.updated.content.to_s
- end
+ make_date(item.source.updated.content)
elsif item.respond_to?(:pubDate)
- if item.pubDate.class <= Time
- date = item.pubDate.strftime("%Y/%m/%d %H:%M")
- else
- date = item.pubDate.to_s
- end
+ make_date(item.pubDate)
elsif item.respond_to?(:date)
- if item.date.class <= Time
- date = item.date.strftime("%Y/%m/%d %H:%M")
- else
- date = item.date.to_s
- end
+ make_date(item.date)
else
- date = "(no date)"
+ "(no date)"
end
- date << " :: "
+ else
+ String.new
end
tit_opt = {}
# visible in the URL anyway
# TODO make this optional?
base_title.sub!(/^Changeset \[([\da-f]{40})\]:/) { |c| "(git commit)"} if feed.type == 'trac'
- title = "#{Bold}#{base_title.ircify_html(tit_opt)}#{Bold}"
+ title = base_title.ircify_html(tit_opt)
end
desc_opt = {}
link = item.link!
link.strip! if link
+ categories = item.categories!
category = item.category! || item.dc_subject!
category.strip! if category
author = item.dc_creator! || item.author!
key = @bot.global_filter_name(feed.type, @outkey)
key = @bot.global_filter_name(:default, @outkey) unless @bot.has_filter?(key)
- output = @bot.filter(key, :item => item, :handle => handle, :date => date,
- :title => title, :desc => desc, :link => link,
- :category => category, :author => author, :at => at)
+ stream_hash = {
+ :item => item,
+ :handle => handle,
+ :handle_wrap => ['::', ':: '],
+ :date => date,
+ :date_wrap => [nil, ' :: '],
+ :title => title,
+ :title_wrap => Bold,
+ :desc => desc, :link => link,
+ :categories => categories,
+ :category => category, :author => author, :at => at
+ }
+ output = @bot.filter(key, stream_hash)
return output if places.empty?
places.each { |loc|
output.to_s.each_line { |line|
- @bot.say loc, line, :overlong => :truncate
+ @bot.__send__(announce_method, loc, line, :overlong => :truncate)
}
}
end