diff options
author | Dmitry Kim <dmitry point kim at gmail point com> | 2007-05-11 16:24:41 +0000 |
---|---|---|
committer | Dmitry Kim <dmitry point kim at gmail point com> | 2007-05-11 16:24:41 +0000 |
commit | d7be2632c61ddec26a7cf033f0b7cec91a1003fd (patch) | |
tree | 8f167ce417129c7c314d4f773465b420c2c9cf7b | |
parent | 6b4b057692a21a76cc0aaf5d1149cd860810511d (diff) |
+ (plugins/delicious) automatic url logging to del.icio.us (alpha)
+ (plugins/url) logging hook / event
-rw-r--r-- | data/rbot/plugins/delicious.rb | 92 | ||||
-rw-r--r-- | data/rbot/plugins/url.rb | 36 |
2 files changed, 119 insertions, 9 deletions
diff --git a/data/rbot/plugins/delicious.rb b/data/rbot/plugins/delicious.rb new file mode 100644 index 00000000..8ed6d5b7 --- /dev/null +++ b/data/rbot/plugins/delicious.rb @@ -0,0 +1,92 @@ +#-- vim:sw=2:et +#++ +# +# :title: Del.icio.us plugin +# +# Author:: dmitry kim <dmitry.kim@gmail.com> +# Copyright:: (C) 2007 dmitry kim +# License:: MIT +# +# This plugin uses url_added hook (event) to submit all urls seen by url.rb +# plugin to a preconfigured account on http://del.icio.us/ +# +require 'rexml/document' +require 'cgi' + +class DeliciousPlugin < Plugin + DIU_BASE = 'https://api.del.icio.us/v1/posts/' + + attr_accessor :last_error + + BotConfig.register BotConfigStringValue.new('delicious.user', + :default => '', :desc => "Username on del.icio.us") + BotConfig.register BotConfigStringValue.new('delicious.password', + :default => '', :desc => "Password on del.icio.us") + BotConfig.register BotConfigStringValue.new('delicious.user_fmt', + :default => 'user:%s', :desc => "How to convert users to tags?") + BotConfig.register BotConfigStringValue.new('delicious.channel_fmt', + :default => 'channel:%s', :desc => "How to convert channels to tags?") + + def help(plugin, topic="") + "delicious => show url of del.icio.us feed of bot url log." + end + + def diu_req(verb, opts = {}) + uri = URI.parse(DIU_BASE + verb) + uri.query = opts.map { |k, v| "#{k}=#{CGI.escape v}" }.join('&') + uri.user = @bot.config['delicious.user'] + uri.password = @bot.config['delicious.password'] + + if uri.user.empty? || uri.password.empty? + self.last_error = 'delicious.user and delicious.password must be set!' + raise self.last_error + end + + return REXML::Document.new(@bot.httputil.get(uri, :cache => false)) + end + + def diu_add(url, opts = {}) + old = diu_req('get', :url => url).root.get_elements('/posts/post')[0] rescue ni + opts[:tags] ||= '' + if old + opts[:description] ||= old.attribute('description').to_s + opts[:extended] ||= old.attribute('extended').to_s + opts[:tags] = [opts[:tags].split, old.attribute('tag').to_s.split].flatten.uniq.compact.join(' ') + debug "reusing existing del.icio.us post" + else + debug "adding new del.icio.us post" + end + opts[:url] = url + diu_req('add', opts) + end + + def event_url_added(url, options = {}) + debug("called with #{url}, #{options.inspect}") + opts = Hash.new + opts[:description] = options[:title] || options[:info] || url + opts[:extended] = options[:extra] if options[:extra] + opts[:tags] = @bot.config['delicious.user_fmt'] % options[:nick] + if options[:channel] + opts[:tags] << ' ' + (@bot.config['delicious.channel_fmt'] % options[:channel]) + end + debug "backgrounding del.icio.us api call" + Thread.new { diu_add(url, opts) } + end + + def delicious(m, params) + uname = @bot.config['delicious.user'] + repl = String.new + if uname.empty? + repl << 'error: del.icio.us username not set' + else + repl << "http://del.icio.us/#{uname}" + if self.last_error + repl << ", last error: #{self.last_error}" + self.last_error = nil + end + end + m.reply repl + end +end +plugin = DeliciousPlugin.new +plugin.map 'delicious' diff --git a/data/rbot/plugins/url.rb b/data/rbot/plugins/url.rb index 6d82099f..269227a3 100644 --- a/data/rbot/plugins/url.rb +++ b/data/rbot/plugins/url.rb @@ -38,11 +38,15 @@ class UrlPlugin < Plugin $1.ircify_html end - def get_title_for_url(uri_str) + def get_title_for_url(uri_str, nick = nil, channel = nil) url = uri_str.kind_of?(URI) ? uri_str : URI.parse(uri_str) return if url.scheme !~ /https?/ + logopts = Hash.new + logopts[:nick] = nick if nick + logopts[:channel] = channel if channel + title = nil extra = String.new @@ -65,13 +69,18 @@ class UrlPlugin < Plugin # if @bot.config['url.first_par'] partial = resp.partial_body(@bot.config['http.info_bytes']) - title = get_title_from_html(partial) + logopts[:title] = title = get_title_from_html(partial) first_par = Utils.ircify_first_html_par(partial, :strip => title) - extra << ", #{Bold}text#{Bold}: #{first_par}" unless first_par.empty? + unless first_par.empty? + logopts[:extra] = first_par + extra << ", #{Bold}text#{Bold}: #{first_par}" + end + call_event(:url_added, url.to_s, logopts) return "#{Bold}title#{Bold}: #{title}#{extra}" if title else resp.partial_body(@bot.config['http.info_bytes']) { |part| - title = get_title_from_html(part) + logopts[:title] = title = get_title_from_html(part) + call_event(:url_added, url.to_s, logopts) return "#{Bold}title#{Bold}: #{title}" if title } end @@ -81,15 +90,24 @@ class UrlPlugin < Plugin end enc = resp['content-encoding'] - - extra << ", #{Bold}encoding#{Bold}: #{enc}" if enc + logopts[:extra] = String.new + logopts[:extra] << "Content Type: #{resp['content-type']}" + if enc + logopts[:extra] << ", encoding: #{enc}" + extra << ", #{Bold}encoding#{Bold}: #{enc}" + end unless @bot.config['url.titles_only'] # content doesn't have title, just display info. size = resp['content-length'].gsub(/(\d)(?=\d{3}+(?:\.|$))(\d{3}\..*)?/,'\1,\2') rescue nil - size = size ? ", #{Bold}size#{Bold}: #{size} bytes" : "" + if size + logopts[:extra] << ", size: #{size} bytes" + size = ", #{Bold}size#{Bold}: #{size} bytes" + end + call_event(:url_added, url.to_s, logopts) return "#{Bold}type#{Bold}: #{resp['content-type']}#{size}#{extra}" end + call_event(:url_added, url.to_s, logopts) else raise UrlLinkError, "getting link (#{resp.code} - #{resp.message})" end @@ -120,7 +138,7 @@ class UrlPlugin < Plugin Thread.start do debug "Getting title for #{urlstr}..." begin - title = get_title_for_url urlstr + title = get_title_for_url urlstr, m.source.nick, m.channel if title m.reply "#{LINK_INFO} #{title}", :overlong => :truncate debug "Title found!" @@ -158,7 +176,7 @@ class UrlPlugin < Plugin list[0..(max-1)].each do |url| disp = "[#{url.time.strftime('%Y/%m/%d %H:%M:%S')}] <#{url.nick}> #{url.url}" if @bot.config['url.info_on_list'] - title = url.info || get_title_for_url(url.url) rescue nil + title = url.info || get_title_for_url(url.url, url.nick, channel) rescue nil # If the url info was missing and we now have some, try to upgrade it if channel and title and not url.info ll = @registry[channel] |