lastfm plugin: added now playing info to the help
[rbot] / data / rbot / plugins / delicious.rb
1 #-- vim:sw=2:et
2 #++
3 #
4 # :title: Del.icio.us plugin
5 #
6 # Author:: dmitry kim <dmitry.kim@gmail.com>
7 # Copyright:: (C) 2007 dmitry kim
8 # License:: MIT
9 #
10 # This plugin uses url_added hook (event) to submit all urls seen by url.rb
11 # plugin to a preconfigured account on http://del.icio.us/
12 #
13 require 'rexml/document'
14 require 'cgi'
15
16 class DeliciousPlugin < Plugin
17   DIU_BASE = 'https://api.del.icio.us/v1/posts/'
18
19   attr_accessor :last_error
20
21   Config.register Config::StringValue.new('delicious.user',
22     :default => '', :desc => "Username on del.icio.us")
23   Config.register Config::StringValue.new('delicious.password',
24     :default => '', :desc => "Password on del.icio.us")
25   Config.register Config::StringValue.new('delicious.user_fmt',
26     :default => 'user:%s', :desc => "How to convert users to tags?")
27   Config.register Config::StringValue.new('delicious.channel_fmt',
28     :default => 'channel:%s', :desc => "How to convert channels to tags?")
29
30   def help(plugin, topic="")
31     "logs urls seen to del.icio.us. you can use [tags: tag1 tag2 ...] to provide tags. special tags are: #{Underline}!hide#{Underline} - log the url as non-shared, #{Underline}!skip#{Underline} - don't log the url. Commands: !#{Bold}delicious#{Bold} => show url of del.icio.us feed of bot url log. "
32   end
33
34   def diu_req(verb, opts = {})
35     uri = URI.parse(DIU_BASE + verb)
36     uri.query = opts.map { |k, v| "#{k}=#{CGI.escape v}" }.join('&')
37     uri.user = @bot.config['delicious.user']
38     uri.password = @bot.config['delicious.password']
39
40     if uri.user.empty? || uri.password.empty?
41       self.last_error = 'delicious.user and delicious.password must be set!'
42       raise self.last_error
43     end
44
45     return REXML::Document.new(@bot.httputil.get(uri, :cache => false))
46   end
47
48   def diu_add(url, opts = {})
49     old = diu_req('get', :url => url).root.get_elements('/posts/post')[0] rescue nil
50     opts[:tags] ||= ''
51     if old
52       opts[:description] ||= old.attribute('description').to_s
53       opts[:extended] ||= old.attribute('extended').to_s
54       opts[:tags] = [opts[:tags].split, old.attribute('tag').to_s.split].flatten.uniq.compact.join(' ')
55       debug "reusing existing del.icio.us post"
56     else
57       debug "adding new del.icio.us post"
58     end
59     opts[:url] = url
60     diu_req('add', opts)
61   end
62
63   def event_url_added(url, options = {})
64     debug("called with #{url}, #{options.inspect}")
65     opts = Hash.new
66     opts[:description] = options[:title] || options[:info] || url
67     opts[:extended] = options[:extra] if options[:extra]
68     opts[:tags] = @bot.config['delicious.user_fmt'] % options[:nick]
69     if options[:channel]
70       opts[:tags] << ' ' + (@bot.config['delicious.channel_fmt'] % options[:channel])
71     end
72     if options[:ircline] and options[:ircline].match(/\[tag(?:s)?:([^\]]+)\]/)
73       tags = $1
74       tags.tr(',', ' ').split(/\s+/).each do |t|
75         if t.sub!(/^!/, '')
76           case t
77           when 'nolog', 'no-log', 'dont-log', 'dontlog', 'skip':
78             debug "skipping #{url} on user request"
79             return
80           when 'private', 'unshared', 'not-shared', 'notshared', 'hide':
81             debug "hiding #{url} on user request"
82             opts[:shared] = 'no'
83           end
84         else
85           opts[:tags] << ' ' + t
86         end
87       end
88     end
89     debug "backgrounding del.icio.us api call"
90     Thread.new { diu_add(url, opts) }
91   end
92
93   def delicious(m, params)
94     uname = @bot.config['delicious.user']
95     repl = String.new
96     if uname.empty?
97       repl << 'error: del.icio.us username not set'
98     else
99       repl << "http://del.icio.us/#{uname}"
100       if self.last_error
101         repl << ", last error: #{self.last_error}"
102         self.last_error = nil
103       end
104     end
105     m.reply repl
106   end
107 end
108 plugin = DeliciousPlugin.new
109 plugin.map 'delicious'