twitterのつぶやきをはてな日記に投稿する・その2

twitterdq_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')

あとは「$config['twitter']['id']」と書けばtwitterのIDを引っ張れます。

要らない発言を削除

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