twitterのつぶやきをはてな日記に投稿する・その2
twitterにdq_jumonというものがあります。replyで呪文を唱えてスライムと闘います。ちなみに、Firefox 3.5で見ると哀しいことになりました。それはさておき、「twitterのつぶやきをはてな日記に投稿する」で書いたスクリプトでつぶやきをはてな日記の方に投稿するときに、dq_jumonへのリプライも一緒だと少々うざいことになります。
そこで、今日は前のスクリプトを改造して、要らないつぶやきは投稿対象外にするようにします。
要件定義
単純に「@dq_jumon」を排除しても汎用性がないので、設定ファイルから取り込んで、その単語が入っている場合には投稿対象としないようにします。その前に、twitterとかのIDやパスワードがスクリプト中に埋め込みになっているのもなんなので、yamlの設定ファイルから読み込むようにします。
設定ファイルはこんな感じで。
twitter: id: twitterのID pw: twitterのパスワード url1: http://twitter.com/ url2: /statuses/ hatena: id: はてなのID pw: はてなのパスワード work_file: __twitter_last_id killwords: - @dq_jumon
読み込み部分はこれだけ。
$config = YAML.load_file('twitter2hatena.yaml')
要らない発言を削除
twitterからtweetを取ってきて内部データを読み込む部分で、除外リストに応じて処理します。
# killword処理 skip_flag = false unless $config['killwords'].nil? $config['killwords'].each do |word| if tweet.text.include?(word) skip_flag = true break end end next if skip_flag tweets.push tweet i += 1
除外リストにあったら処理を中断して、なかったらつぶやきを追加します。
正規表現にしてみる
これでも問題ないですけど、もうちょっと汎用的にするために正規表現を使えるようにします。
# killword処理 skip_flag = false unless $config['killwords'].nil? $config['killwords'].each do |word| if tweet.text.include?(word) re = Regexp.new(word) if re.match(tweet.text) skip_flag = true break end end next if skip_flag tweets.push tweet i += 1
まとめ
そんな感じで、全体はこんな感じ。
#!/usr/bin/ruby -Ku # Author: woinary (yoshiaki.y@awagumo.net) # Created at: 2009/07/04 $KCODE = 'u' require 'rubygems' require 'open-uri' require 'twitter' require 'atomutil' require 'kconv' require 'yaml' $config = YAML.load_file('twitter2hatena.yaml') module Atompub class HatenaClient < Client def publish_entry(uri) @hatena_publish = true update_resource(uri, ' ', Atom::MediaType::ENTRY.to_s) ensure @hatena_publish = false end private def set_common_info(req) req['X-Hatena-Publish'] = 1 if @hatena_publish super(req) end end end def write_work(last_id) $stderr.print "last:#{last_id}.\n" open($config['work_file'], "w") do |work| # write last id work.print "#{last_id}" end end def read_work begin open($config['work_file'], 'r') do |work| #read last id return work.read.to_i end rescue # read error is return zero return 0 end end # get tweets def getStatus i = 1 tweets = Array.new last_id = read_work $stderr.print "latest id:#{last_id}\n" c = Twitter::Client.new(:login => $config['twitter']['id'], :password => $config['twitter']['pw']) c.timeline_for(:me) do |status_id| # この先はもう読んだ break if status_id.id <= last_id # このtweetは処理する tweet = c.status(:get, status_id) # killword処理 skip_flag = false unless $config['killwords'].nil? $config['killwords'].each do |word| re = Regexp.new(word) if re.match(tweet.text) skip_flag = true break end end end next if skip_flag tweets.push tweet i += 1 end return tweets end def layout(tweet) #$stderr.print "layout.\n" return "-[#{$config['twitter']['url1']}#{$config['twitter']['id']}#{$config['twitter']['url2']}#{tweet.id}:title=#{tweet.created_at.to_s.gsub(/^.+(\d\d:\d\d):\d\d.+$/,'\\1')}] #{tweet.text}" end def output(tweets) i = 0 contents = "" last_id = "" tweets.reverse.each do |tweet| i += 1 contents += layout(tweet) + "\n" last_id = tweet.id end hatena_entry(contents) write_work(last_id) end def hatena_entry(contents) auth = Atompub::Auth::Wsse.new :username => $config['hatena']['id'], :password => $config['hatena']['pw'] client = Atompub::HatenaClient.new :auth => auth service = client.get_service("http://d.hatena.ne.jp/#{$config['hatena']['id']}/atom/") collection_uri = service.workspace.collections[1].href entry = Atom::Entry.new( :title => Kconv.toutf8('今日のつぶやき'), :published => Time.now ) entry.content = Kconv.toutf8(contents) client.create_entry(collection_uri, entry) end # main tweets = Array.new tweets = getStatus unless tweets.nil? output(tweets) end