4 # :title: tumblr interface
6 # Author:: Giuseppe Bilotta <giuseppe.bilotta@gmail.com>
7 # Copyright:: (C) 2009 Giuseppe Bilotta
10 # Submit URLs to channel-specific tumblr accounts
12 # TODO support other video providers (maybe detect embed codes?)
13 # TODO support image better (e.g. pages with a single big image)
14 # TODO customize caption/description format
15 # TODO do not reblog own posts (maybe?)
17 require 'rexml/document'
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 TAGS = "&tags=%{tags}"
36 def help(plugin, topic="")
39 "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"
41 "tumblr deconfigure [<channel>]: forget credentials for channel <channel> (default: current)."
43 "post links, photos and videos to a channel-specific tumblr. topics: configure, deconfigure"
47 def event_url_added(url, options={})
48 return unless options.key? :channel
49 chan = options[:channel]
50 return unless @registry.key? chan
52 account = @registry[chan]
54 line = options[:ircline]
55 line = nil if line and line.empty?
56 if line and nick = options[:nick]
57 line = "<#{nick}> #{line}"
59 html_line = line ? CGI.escapeHTML(line) : line
60 tags = line ? line.scan(/\[([^\]]+)\]/).flatten : []
65 tumblr = options[:htmlinfo][:headers]['x-tumblr-user'].to_s rescue nil
67 id = url.match(/\/post\/(\d+)/)
71 read_url = READ_URL % { :user => tumblr, :id => id}
72 # TODO seems to return 503 a little too frequently
73 xml = @bot.httputil.get(read_url)
76 reblog = REXML::Document.new(xml).elements["//post"].attributes["reblog-key"] rescue nil
77 if reblog and not reblog.empty?
81 html_line = CGI.escapeHTML("(via <a href=%{url}>%{tumblr}</a>" % {
82 :url => url, :tumblr => tmblr
87 :desc => CGI.escape(html_line)
96 type = options[:htmlinfo][:headers]['content-type'].first rescue nil
100 data << CAPTION if line
102 if url.match(%r{^http://(\w+\.)?(youtube\.com/watch.*|vimeo.com/\d+)})
104 data << CAPTION if line
110 data << TAGS unless tags.empty?
112 :src => CGI.escape(url),
113 :desc => CGI.escape(html_line),
114 :tags => CGI.escape(tags.join(',')),
115 :name => CGI.escape(line)
119 debug "posting #{req.inspect}"
120 resp = @bot.httputil.post(api_url, req)
121 debug "tumblr response: #{resp.inspect}"
124 def configuration(m, params={})
125 channel = params[:channel] || m.channel
127 m.reply _("Please specify a channel")
130 if not @registry.key? channel
131 m.reply _("No tumblr credentials set for %{chan}" % { :chan => channel })
135 account = @registry[channel]
137 account[:pwd] = _("<hidden>") if m.public?
138 account[:chan] = channel
140 m.reply _("Links on %{chan} will go to %{group} using account %{email} and password %{pwd}" % account)
143 def deconfigure(m, params={})
144 channel = params[:channel] || m.channel
146 m.reply _("Please specify a channel")
149 if not @registry.key? channel
150 m.reply _("No tumblr credentials set for %{chan}" % { :chan => channel })
154 @registry.delete channel
156 m.reply _("Links on %{chan} will not be posted to tumblr anymore" % {:chan => channel})
159 def configure(m, params={})
160 channel = params[:channel] || m.channel
162 m.reply _("Please specify a channel")
165 if @registry.key? channel
166 m.reply _("%{chan} already has credentials configured" % { :chan => channel })
168 group = params[:group] || Channel.npname(channel)
169 group << ".tumblr.com" unless group.match(/\.tumblr\.com/)
170 @registry[channel] = {
171 :email => CGI.escape(params[:email]),
172 :pwd => CGI.escape(params[:pwd]),
173 :group => CGI.escape(group)
178 return configuration(m, params)
183 plugin = TumblrPlugin.new
185 plugin.default_auth('*', false)
187 plugin.map 'tumblr configure [:channel]', :action => :configuration
188 plugin.map 'tumblr deconfigure [:channel]', :action => :deconfigure
189 plugin.map 'tumblr configure [:channel] :email :pwd [:group]',
190 :action => :configure,
191 :requirements => {:channel => Regexp::Irc::GEN_CHAN, :email => /.+@.+/, :group => /[A-Za-z-]+/}