Skip to content

Instantly share code, notes, and snippets.

@tatsuru
Created July 17, 2011 01:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tatsuru/1087008 to your computer and use it in GitHub Desktop.
Save tatsuru/1087008 to your computer and use it in GitHub Desktop.
Tumblr Desktop Notification with libnotify
cache:
directory: /home/tatsuru/.tumblr-cache
max: 1000
dashboard:
limit: 10
check_interval: 30
notify_timeout: 30
text_length: 100
reblog:
hostname: tatsuru.tumblr.com
server_port: 10080
retry_max: 5
state: published # published, draft, queue
api:
consumer_key:
consumer_secret:
oauth_token:
oauth_secret:
#!/usr/bin/env ruby
=begin
Tumblr Desktop Notification.
requires notification-daemon.
Usage:
./notify_tumblr.rb [config.yaml]
Config file
config file is $HOME/.notify_tumblr.yaml by default.
edit the sample file dot.notify_tumblr.yaml
=end
exit if RUBY_VERSION < '1.9'
require 'rubygems'
require 'tumblife'
require 'libnotify'
require 'net/http'
require 'uri'
require 'webrick'
require 'pp'
require 'yaml'
# read config
$config = YAML.load_file(ARGV[0].nil? ? ENV['HOME'] + '/.notify_tumblr.yaml' : ARGV[0])
def remove_tag(str)
str.sub!(/<[^<>]*>/,"") while /<[^<>]*>/ =~ str
end
def reblog_button(post)
ret = <<EOS.chomp
<a href="http://www.tumblr.com/reblog/#{post.id}/#{post.reblog_key}">edit/preview reblog</a>
<a href="http://localhost:#{$config["reblog"]["server_port"]}/#{post.type}/#{post.id}/#{post.reblog_key}">reblog now!</a>
EOS
end
# main
# Tumblr API
consumer = OAuth::Consumer.new( $config["api"]["consumer_key"], $config["api"]["consumer_secret"], {site: 'http://api.tumblr.com'} )
access_token = OAuth::AccessToken.new( consumer, $config["api"]["oauth_token"], $config["api"]["oauth_secret"] )
client = Tumblife.new(access_token)
# temporary files
remove_files = []
# reblog server
reblog_server = WEBrick::HTTPServer.new( :BindAddress => '127.0.0.1', :Port => $config["reblog"]["server_port"] )
reblog_server.mount_proc("/") { |req, res|
dummy, type, id, reblog_key = req.path.split '/'
unless reblog_key.nil?
# create thread for the post
# request returns immediately
Thread.new do
retry_count = 0
begin
puts "reblogging... #{reblog_key}"
client.reblog_post($config["reblog"]["hostname"], :type => type, :id => id.to_i, :reblog_key => reblog_key,
:state => $config["reblog"]["state"] )
puts "reblog finished #{reblog_key}"
rescue
retry_count += 1
puts "reblog #{reblog_key} failed. retrying [#{retry_count}/#{$config["reblog"]["retry_max"]}]"
retry if retry_count < RETRY_MAX
end
end.run
end
res.body = <<EOS
<html>
<head />
<body onLoad="setTimeout('window.close()',100)" />
</html>
EOS
}
reblog_thread = Thread.new do
reblog_server.start
end
reblog_thread.run
# kill with SIGINT
Signal.trap(:INT) {
puts "shutting down"
reblog_server.shutdown
Thread::kill(reblog_thread)
remove_files.each { |f| File.unlink(f) }
exit(0)
}
# dashboard loop
last_id = 0
loop do
begin
dsbd = client.dashboard(:limit => $config["dashboard"]["limit"])
rescue => ex
pp ex
else
posts = dsbd.posts
break if posts.length == 0
posts.each do |post|
break if post.id == last_id
notify = Libnotify.new( :summary => post.blog_name,
:timeout => $config["dashboard"]["notify_timeout"]
)
#pp post
puts "[#{post.blog_name}] #{post.type} post: #{post.post_url}"
case post.type
when "text"
body = post.body
remove_tag(body)
notify.body = <<EOS
<a href="#{post.post_url}"><b>#{post.title ? post.title : 'No Title'}</b></a> #{body[0..$config["dashboard"]["text_length"]]}
#{reblog_button(post)}
EOS
when "quote"
text = post.text
remove_tag(text)
notify.body = <<EOS
<a href="#{post.post_url}"><b>#{post.text[0..$config["dashboard"]["text_length"]]}</b></a> #{post.source_title}
#{reblog_button(post)}
EOS
when "photo"
caption = post.caption
remove_tag(caption)
notify.body = <<EOS
<a href="#{post.post_url}">#{caption == '' ? 'No Title' : caption[0..$config["dashboard"]["text_length"]]}</a>
#{reblog_button(post)}
EOS
photo = post.photos[0].alt_sizes.sort_by{|v| v.width}[0]
local_img = $config["cache"]["directory"] + '/' + File.basename(photo.url)
unless File.exists?(local_img) # download photo
res = Net::HTTP.get_response(URI.parse(photo.url))
if res.class == Net::HTTPOK
open(local_img, 'wb') do |f|
f.write(res.body)
end
remove_files.push(local_img)
end
end
notify.icon_path = local_img
when "link"
description = post.description
remove_tag(description)
notify.body = <<EOS
<a href="#{post.url}"><b>#{post.title[0..$config["dashboard"]["text_length"]]}</b></a> #{description[0..$config["dashboard"]["text_length"]]}
#{reblog_button(post)}
EOS
else
notify.body = <<EOS
<a href="#{post.post_url}"><b>#{post.type} post</b></a>
EOS
end # case post.type
notify.show!
end # posts.each do |post|
last_id = posts[0].id
ensure # try
sleep($config["dashboard"]["check_interval"])
end
(remove_files.length - $config["cache"]["max"]).times do
f = remove_files[0]
File.unlink(f)
remove_files.delete(f)
end
end # loop do
@tatsuru
Copy link
Author

tatsuru commented Jul 20, 2011

/home/tatsuru/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/net/protocol.rb:140:in rescue in rbuf_fill': Timeout::Error (Timeout::Error) from /home/tatsuru/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/net/protocol.rb:134:inrbuf_fill'
from /home/tatsuru/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/net/protocol.rb:116:in readuntil' from /home/tatsuru/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/net/protocol.rb:126:inreadline'
from /home/tatsuru/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/net/http.rb:2219:in read_status_line' from /home/tatsuru/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/net/http.rb:2208:inread_new'
from /home/tatsuru/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/net/http.rb:1191:in transport_request' from /home/tatsuru/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/net/http.rb:1177:inrequest'
from /home/tatsuru/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/net/http.rb:1081:in request_get' from /home/tatsuru/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/net/http.rb:394:inblock in get_response'
from /home/tatsuru/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/net/http.rb:627:in start' from /home/tatsuru/.rvm/rubies/ruby-1.9.2-p180/lib/ruby/1.9.1/net/http.rb:393:inget_response'
from ./notify_tumblr.rb:92:in block (2 levels) in <main>' from ./notify_tumblr.rb:56:ineach'
from ./notify_tumblr.rb:56:in block in <main>' from ./notify_tumblr.rb:51:inloop'
from ./notify_tumblr.rb:51:in `

'
zsh: exit 1 ./notify_tumblr.rb

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment