]> git.netwichtig.de Git - user/henk/code/ruby/rbot.git/blob - data/rbot/plugins/tumblr.rb
a135e6c371aac43e7bea760894273901b7301b8e
[user/henk/code/ruby/rbot.git] / data / rbot / plugins / tumblr.rb
1 #-- vim:sw=2:et
2 #++
3 #
4 # :title: tumblr interface
5 #
6 # Author:: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
7 # Copyright:: (C) 2009 Giuseppe Bilotta
8 # License:: GPLv2
9 #
10 # Submit URLs to channel-specific tumblr accounts
11 #
12 # TODO reblog tumblr URLs
13 # TODO support video better (e.g. Vimeo or anything else with embed)
14 # TODO support image better (e.g. pages with a single big image)
15 # TODO customize caption/description format
16
17 require 'rexml/document'
18 require 'cgi'
19
20 class TumblrPlugin < Plugin
21   RBOT = CGI.escape("rbot #{$version.split.first}")
22   WRITE_URL = "http://www.tumblr.com/api/write"
23   REBLOG_URL = "http://www.tumblr.com/api/reblog"
24   READ_URL = "http://%{user}.tumblr.com/api/read?id=%{id}"
25   LOGIN = "email=%{email}&password=%{pwd}&group=%{group}&format=markdown&generator=" + RBOT
26   PHOTO = "&type=photo&source=%{src}&click-through-url=%{src}"
27   VIDEO = "&type=video&embed=%{src}"
28   CAPTION = "&caption=%{desc}"
29   LINK = "&type=link&url=%{src}"
30   NAME = "&name=%{name}"
31   DESC = "&description=%{desc}"
32   REBLOG = "&post-id=%{id}&reblog-key=%{reblog}"
33   COMMENT = "&comment=%{desc}"
34
35   def help(plugin, topic="")
36     case topic
37     when "configure"
38       "tumblr configure [<channel>]: show credentials used for channel <channel> (default: current).    tumblr configure [<channel>] <email> <password> [<group>] => post links from channel <channel> (default: current) to group <group> (default: name of channel) using the given tumblr credentials"
39     when "deconfigure"
40       "tumblr deconfigure [<channel>]: forget credentials for channel <channel> (default: current)."
41     else
42       "post links, photos and videos to a channel-specific tumblr. topics: configure, deconfigure"
43     end
44   end
45
46   def event_url_added(url, options={})
47     return unless options.key? :channel
48     chan = options[:channel]
49     return unless @registry.key? chan
50
51     account = @registry[chan]
52
53     line = options[:ircline]
54     line = nil if line and line.empty?
55     if line and nick = options[:nick]
56       line = "<#{nick}> #{line}"
57     end
58     html_line = line ? CGI.escapeHTML(line) : line
59
60     req = LOGIN % account
61     ready = false
62     api_url = WRITE_URL
63     tumblr = options[:htmlinfo][:headers]['x-tumblr-user'].to_s rescue nil
64     if tumblr
65       id = url.match(/\/post\/(\d+)/)
66       if id
67         id = id[1]
68
69         read_url = READ_URL % { :user => tumblr, :id => id}
70         # TODO seems to return 503 a little too frequently
71         xml = @bot.httputil.get(read_url)
72
73         if xml
74           reblog = REXML::Document.new(xml).elements["//post"].attributes["reblog-key"] rescue nil
75           if reblog and not reblog.empty?
76             api_url = REBLOG_URL
77             data = REBLOG
78             data << COMMENT
79             html_line = CGI.escapeHTML("(via <a href=%{url}>%{tumblr}</a>" % {
80               :url => url, :tumblr => tmblr
81             }) unless html_line
82             req << (data % {
83               :id => id,
84               :reblog => reblog,
85               :desc => CGI.escape(htmlline)
86             })
87             ready = true
88           end
89         end
90       end
91     end
92
93     if not ready
94       type = options[:htmlinfo][:headers]['content-type'].first rescue nil
95       case type
96       when /^image\/.*/
97         data = PHOTO
98         data << CAPTION if line
99       else
100         if url.match(%r{^http://(\w+\.)?youtube\.com/watch.*})
101           data = VIDEO
102           data << CAPTION if line
103         else
104           data = LINK
105           data << NAME if line
106         end
107       end
108       req << (data % {
109         :src => CGI.escape(url),
110         :desc => CGI.escape(html_line),
111         :name => CGI.escape(line)
112       })
113     end
114
115     debug "posting #{req.inspect}"
116     resp  = @bot.httputil.post(api_url, req)
117     debug "tumblr response: #{resp.inspect}"
118   end
119
120   def configuration(m, params={})
121     channel = params[:channel] || m.channel
122     if not channel
123       m.reply _("Please specify a channel")
124       return
125     end
126     if not @registry.key? channel
127       m.reply _("No tumblr credentials set for %{chan}" % { :chan => channel })
128       return false
129     end
130
131     account = @registry[channel]
132
133     account[:pwd] = _("<hidden>") if m.public?
134     account[:chan] = channel
135
136     m.reply _("Links on %{chan} will go to %{group} using account %{email} and password %{pwd}" % account)
137   end
138
139   def deconfigure(m, params={})
140     channel = params[:channel] || m.channel
141     if not channel
142       m.reply _("Please specify a channel")
143       return
144     end
145     if not @registry.key? channel
146       m.reply _("No tumblr credentials set for %{chan}" % { :chan => channel })
147       return false
148     end
149
150     @registry.delete channel
151
152     m.reply _("Links on %{chan} will not be posted to tumblr anymore" % {:chan => channel})
153   end
154
155   def configure(m, params={})
156     channel = params[:channel] || m.channel
157     if not channel
158       m.reply _("Please specify a channel")
159       return
160     end
161     if @registry.key? channel
162       m.reply _("%{chan} already has credentials configured" % { :chan => channel })
163     else
164       group = params[:group] || Channel.npname(channel)
165       group << ".tumblr.com" unless group.match(/\.tumblr\.com/)
166       @registry[channel] = {
167         :email => CGI.escape(params[:email]),
168         :pwd => CGI.escape(params[:pwd]),
169         :group => CGI.escape(group)
170       }
171
172     end
173
174     return configuration(m, params)
175   end
176
177 end
178
179 plugin = TumblrPlugin.new
180
181 plugin.default_auth('*', false)
182
183 plugin.map 'tumblr configure [:channel]', :action => :configuration
184 plugin.map 'tumblr deconfigure [:channel]', :action => :deconfigure
185 plugin.map 'tumblr configure [:channel] :email :pwd [:group]',
186   :action => :configure,
187   :requirements => {:channel => Regexp::Irc::GEN_CHAN, :email => /.+@.+/, :group => /[A-Za-z-]+/}
188