summaryrefslogtreecommitdiff
path: root/data
diff options
context:
space:
mode:
Diffstat (limited to 'data')
-rw-r--r--data/rbot/plugins/freshmeat.rb246
1 files changed, 0 insertions, 246 deletions
diff --git a/data/rbot/plugins/freshmeat.rb b/data/rbot/plugins/freshmeat.rb
deleted file mode 100644
index 810b82fd..00000000
--- a/data/rbot/plugins/freshmeat.rb
+++ /dev/null
@@ -1,246 +0,0 @@
-#-- vim:sw=2:et
-#++
-#
-# :title: Freshmeat plugin for rbot
-
-require 'rexml/document'
-
-class FreshmeatPlugin < Plugin
- include REXML
-
- Config.register Config::StringValue.new('freshmeat.api_token',
- :desc => "Auth token for freshmeat API requests. Without this, no freshmeat calls will be made. Find it in your freshmeat user account settings.",
- :default => "")
-
- def api_token
- return @bot.config['freshmeat.api_token']
- end
-
- # Checks if an API token is configure, warns if not, returns true or false
- def check_api_token(m=nil)
- if api_token.empty?
- if m
- m.reply _("you must set the configuration value freshmeat.api_token to a valid freshmeat auth token, otherwise I cannot make requests to the site")
- end
- return false
- end
- return true
- end
-
- def help(plugin, topic="")
- "freshmeat search [<max>=4] <string> => search freshmeat for <string>, freshmeat [<max>=4] => return up to <max> freshmeat headlines"
- end
-
- REL_ENTRY = %r{<a href="/(release)s/(\d+)/"><font color="#000000">(.*?)</font></a>}
- PRJ_ENTRY = %r{<a href="/(project)s/(\S+?)/"><b>(.*?)</b></a>}
-
- # This method defines a filter for fm pages. It's needed because the generic
- # summarization grabs a comment, not the actual article.
- #
- def freshmeat_filter(s)
- loc = Utils.check_location(s, /freshmeat\.net/)
- return nil unless loc
- entries = []
- s[:text].scan(/#{REL_ENTRY}|#{PRJ_ENTRY}/) { |m|
- entry = {
- :type => ($1 || $4).dup,
- :code => ($2 || $5).dup,
- :name => ($3 || $6).dup
- }
- entries << entry
- }
- return nil if entries.empty?
- title = s[:text].ircify_html_title
- content = entries.inject([]) { |l, e| l << e[:name] }.join(" | ")
- return {:title => title, :content => content}
- end
-
- def initialize
- super
- @bot.register_filter(:freshmeat, :htmlinfo) { |s| freshmeat_filter(s) }
- end
-
- def search_freshmeat(m, params)
- return unless check_api_token(m)
- max = params[:limit].to_i
- search = params[:search].to_s
- max = 8 if max > 8
- xml = @bot.httputil.get("http://freshmeat.net/search.xml?auth_code=#{api_token}&q=#{CGI.escape(search)}")
- unless xml
- m.reply "search for #{search} failed (is the API token configured correctly?)"
- return
- end
- doc = nil
- begin
- doc = Document.new xml
- rescue
- debug xml
- error $!
- end
- unless doc
- m.reply "search for #{search} failed"
- return
- end
- matches = Array.new
- max_width = 250
- title_width = 0
- url_width = 0
- done = 0
- doc.elements.each("hash/projects/project") {|e|
- title = e.elements["name"].text
- title_width = title.length if title.length > title_width
-
- url = "http://freshmeat.net/projects/#{e.elements['permalink'].text}"
- url_width = url.length if url.length > url_width
-
- desc = e.elements["oneliner"].text
-
- matches << [title, url, desc]
- done += 1
- break if done >= max
- }
- if matches.length == 0
- m.reply "not found: #{search}"
- end
-
- title_width += 2 # for bold
-
- matches.each {|mat|
- title = Bold + mat[0] + Bold
- url = mat[1]
- desc = mat[2]
- reply = sprintf("%s | %s | %s", title.ljust(title_width), url.ljust(url_width), desc)
- m.reply reply, :overlong => :truncate
- }
- end
-
- # We do manual parsing so that we can work even with the RSS plugin not loaded
- def freshmeat_rss(m, params)
- max = params[:limit].to_i
- max = 8 if max > 8
-
- text = _("retrieving freshmeat news from the RSS")
- reason = ""
- case params[:api_token]
- when :missing
- reason = _(" because no API token is configured")
- when :wrong
- reason = _(" because the configured API token is wrong")
- end
-
- m.reply text + reason
-
- begin
- xml = @bot.httputil.get('http://freshmeat.net/?format=atom')
- unless xml
- m.reply _("couldn't retrieve freshmeat news feed")
- return
- end
- doc = Document.new xml
- unless doc
- m.reply "freshmeat news parse failed"
- return
- end
- rescue
- error $!
- m.reply "freshmeat news parse failed"
- return
- end
-
- matches = Array.new
- max_width = 60
- title_width = 0
- done = 0
- doc.elements.each("feed/entry") {|e|
- # TODO desc should be replaced by the oneliner, but this means one more hit per project
- # so we clip out all of the description and leave just the 'changes' part
- desc = e.elements["content"].text.ircify_html.sub(/.*?#{Bold}Changes:#{Bold}/,'').strip
- title = e.elements["title"].text.ircify_html.strip
- title_width = title.length if title.length > title_width
- matches << [title, desc]
- done += 1
- break if done >= max
- }
- title_width += 2
- matches.each {|mat|
- title = Bold + mat[0] + Bold
- desc = mat[1]
- reply = sprintf("%s | %s", title.ljust(title_width), desc)
- m.reply reply, :overlong => :truncate
- }
- end
-
- def freshmeat(m, params)
- # use the RSS if no API token is defined
- return freshmeat_rss(m, params.merge(:api_token => :missing)) unless check_api_token
- xml = @bot.httputil.get("http://freshmeat.net/index.xml?auth_code=#{api_token}")
- # use the RSS if we couldn't get the XML
- return freshmeat_rss(m, params.merge(:api_token => :wrong)) unless xml
-
- max = params[:limit].to_i
- max = 8 if max > 8
- begin
- doc = Document.new xml
- unless doc
- m.reply "freshmeat news parse failed"
- return
- end
- rescue
- error $!
- m.reply "freshmeat news parse failed"
- return
- end
-
- matches = Array.new
- title_width = 0
- url_width = 0
- time_width = 0
- done = 0
- now = Time.now
- doc.elements.each("releases/release") {|e|
- approved = e.elements["approved-at"].text.strip
- date = Time.parse(approved) rescue nil
- timeago = date ? (Utils.timeago(date, :start_date => now) rescue nil) : approved
- time_width = timeago.length if timeago.length > time_width
-
- changelog = e.elements["changelog"].text.ircify_html
-
- title = e.elements["project/name"].text.ircify_html
- title_width = title.length if title.length > title_width
- url = "http://freshmeat.net/projects/#{e.elements['project/permalink'].text}"
- url_width = url.length if url.length > url_width
-
- desc = e.elements["project/oneliner"].text.ircify_html
-
- matches << [title, timeago, desc, url, changelog]
-
- done += 1
- break if done >= max
- }
-
- if matches.empty?
- m.reply _("no news in freshmeat!")
- return
- end
-
- title_width += 2
- matches.each {|mat|
- title = Bold + mat[0] + Bold
- timeago = mat[1]
- desc = mat[2]
- url = mat[3]
- changelog = mat[4]
- reply = sprintf("%s | %s | %s | %s",
- timeago.rjust(time_width),
- title.ljust(title_width),
- url.ljust(url_width),
- desc)
- m.reply reply, :overlong => :truncate
- }
- end
-end
-plugin = FreshmeatPlugin.new
-plugin.map 'freshmeat search :limit *search', :action => 'search_freshmeat',
- :defaults => {:limit => 4}, :requirements => {:limit => /^\d+$/}
-plugin.map 'freshmeat :limit', :defaults => {:limit => 4},
- :requirements => {:limit => /^\d+$/}