2010 年 2 月の記事一覧です(3 件)

[Life]河津桜を見に行ってきました

IMG_0439

河津桜を見に今年も河津町へ行ってきました。すごく暖かかった去年と違って今年は2月に入ってからも非常に寒く、開花は遅れ気味のようで、まだ5〜6分咲きでしたが、それでも1年ぶりに見た河津桜は力強く、確実に春はそこまで来ているんだなと感じました。
ちなみに昨年のエントリはこちら 河津桜 - 本州一の早咲き桜 - “南船北馬”

IMG_0470

今回撮った写真はFlickrにアップしております。kawazu 2010 やっぱりデジイチ欲しいなぁ...

[Twitter]今まで作成したTwitter botのまとめ

Twitter botをOAuth対応させたついでに今まで作ったbotをまとめておきます。
  • @cookpad_recipe
    • クックパッドの話題のレシピを都度配信しています
  • @keiba_news
    • ラジオNIKKEI競馬実況webのニュースを配信しています
  • @ad_min_kun
    • @ITで連載中の4コマ漫画 がんばれ! アドミンくん の新作を配信します
    • ちなみに絶賛文字化け中です(>_<)現在対応中です。ゴメンナサイ

環境について

  • サーバ
    • Prime Magnate GCD(ドスパラWebのBTOです)
  • OS
    • CentOS5.4
  • その他
    • 上記botはすべてPython2.6で動いています
    • TwitterAPIのPythonラッパーはtweepyを使用しています

[Python]Python製Twitter(Wasser)CUIクライアントをOAuth対応にしてみた

Twitter APIは近い将来BASICによる認証が出来なくなるらしいという話を聞き、重い腰をあげて自分が管理しているBotをOAuth対応すべく勉強を始めました。 今回は勉強ついでに少し寄り道して、色々と参考にさせてもらっているPython製Twitter(Wasser)CUIクライアントを基本ベースにOAuth対応に改造してみました。

オリジナルはこちらで
wassr と Twitter への投稿クライアント(清楚なクライアント) - Djangoへの片思い日記
ブランチされているのはこちらでしょうか
tw2改造した - a2c.get.diary

本当はブランチとかするのがいいと思うのですが、
  • Wasserへの対応を削ってしまっている(自分、Wasserは放置しちゃってます><)
  • TwitterAPIのWrapperをすっかり変えている(tweepyを使用)
  • Sqlite3をつかってin_reply_to_id付きreplyに対応している
などなどからこちらのBlogにあげさせてもらいます。何か問題あれば言ってください。

留意事項

使用方法

  • scriptと同じ場所等にdbを作成します。db名はtwit.dbでtable名はtwitlogです。内容はこんな感じでお願いします。
    $ sqlite3 twit.db
    sqlite> .schema twitlog
    CREATE TABLE twitlog
                    (id INTEGER PRIMARY KEY,
                    date INTEGER,
                    repid INTEGER,
                    screen TEXT, body TEXT);
    sqlite> 
    

  • 使用方法は殆どオリジナルと変更ありません。起動後、取得したい情報のkeyや発言内容を入力してリターンキーを押して下さい
  • in_reply_to_id付きreplyは、replyしたい内容の番号を入力してから @screen_name のように入力します(下図ご参照)

  • 20100209_02


コードはこちらです。自分のコードでsqlite3使ったり、SQL文書いたりしたのは実は今回が初めてです。こうしたほうがいいみたいなことありましたら教えてください><
#!/usr/bin/env python
# coding: utf-8
# thanks yoshiori: http://d.hatena.ne.jp/jYoshiori/20081201/1228123623
# thanks a2c: http://d.hatena.ne.jp/a2c/20081221/1229799599

import readline
from pit import Pit
from datetime import timedelta
import sqlite3

# KeyConfig
getFriendsTimeLineKey = ['friends', 'f']
getRepliesKey = ['res', 'r', '']
sendPostKey = ['post', 'p']
searchKey = ['search', 's']
exitKey = ['x', 'ZZ', 'exit', 'bye']

readline.parse_and_bind('tab: complete')

friends = set()

def complete(text, status):
    results = [x for x in friends if x.startswith(text)] + [None]
    return results[status]

def date_jst(utf_date):
    # UTC -> JST
    d = utf_date + timedelta(hours=9)
    return d

def twitPost(input):
    # Post twitterr
    api.update_status(input)
    print 'update : ' + input

def select_repid(num):
    con = sqlite3.connect(db_name)
    sql = 'SELECT repid FROM twitlog WHERE id = ?'
    stid = con.execute(sql, (num,)).fetchone()[0] 
    con.close()
    return stid
    
def twitRepost(input, stid):
    # Repost twitterr
    api.update_status(input, stid)
    print 'update : ' + input
    
def getReplies(maxid):
    # Get twitter friends Replies
    insert_data(api.mentions(count=maxid))
    con = sqlite3.connect(db_name)
    cur = con.cursor()
    cur.execute('select * from twitlog')

    print '\n\ttwitter replies\t'
    for row in cur:
        print ('%s :%s : %s %s' % (row[0], row[1], row[3], row[4]))
        friends.add(row[3])
    cur.close()
    con.close()

def getFriensTimeLine(maxid):
    # Get FriendsTimeLine
    insert_data(api.friends_timeline(count=maxid))
    con = sqlite3.connect(db_name)
    cur = con.cursor()
    cur.execute('select * from twitlog')

    print '\n  -----  twitter Friends Time Line  -----'
    for row in cur:
        print ('%s :%s : %s %s' % (row[0], row[1], row[3], row[4]))
        friends.add(row[3])
    cur.close()
    con.close()

def twitSearch(word):
    # Twitter Search
    insert_search_data(api.search(word))
    con = sqlite3.connect(db_name)
    cur = con.cursor()
    cur.execute('select * from twitlog')

    print '\n  -----  twitter search  -----'
    for row in cur:
        print ('%s :%s : %s %s' % (row[0], row[1], row[3], row[4]))
        friends.add(row[3])
    cur.close()
    con.close()

def insert_data(api):
    sql = 'insert into twitlog values(null,?,?,?,?)' 
    con = sqlite3.connect(db_name)
    con.execute('delete from twitlog')       
    for data in reversed(api):
        con.execute(sql, (date_jst(data.created_at), data.id, data.user.screen_name, data.text))
    con.commit()
    con.close()

def insert_search_data(api):
    sql = 'insert into twitlog values(null,?,?,?,?)' 
    con = sqlite3.connect(db_name)
    con.execute('delete from twitlog')       
    for data in reversed(api):
        con.execute(sql, (date_jst(data.created_at), data.id, data.from_user, data.text))
    con.commit()
    con.close()

def create_twitdb():
    # DBがぶっ壊れた時用
    db = sqlite3.connect(db_name)
    sql = (
            '''CREATE TABLE twitlog
                (id INTEGER PRIMARY KEY,
                date INTEGER,
                repid INTEGER,
                screen TEXT, body TEXT);'''
          )
    db.execute(sql)
    db.commit()
    db.close()

if __name__ == "__main__":
    db_name = 'twit.db'
   # create_twitdb()
    try:
        import tweepy
    except:
        print "error:\tcan't import tweepy module, you must install the module:\n"
        print "\tto install: 'easy_install tweepy'\n"
        exit()
    # OAuth setting
    consumer_config = Pit.get('twoauth')
    auth = tweepy.OAuthHandler(consumer_config['consumer_key'], consumer_config['consumer_secret'])
    access_config = Pit.get('access_key')
    auth.set_access_token(access_config['access_token'], access_config['access_secret'])

    readline.set_completer(complete)
    prompt = '\n cmd: Friendstimeline[f] Search[s] Post[p] Repost[num + @] Replies[r] Exit[x] \n> '
    maxid = 20
    api = tweepy.API(auth)

    while True:
        all_input = raw_input(prompt)
        input = all_input.split(" ")
        if input[0] != '':
            if input[0] in getFriendsTimeLineKey: 
                getFriensTimeLine(maxid)
                continue
            elif input[0] in sendPostKey:
                twitPost(unicode(' '.join(input[1:]), 'utf-8'))
                continue
            elif input[0].isdigit():
                sid = select_repid(input[0])
                #print sid
                twitRepost(unicode(' '.join(input[1:]), 'utf-8'), sid)
                continue
            elif input[0] in getRepliesKey:
                getReplies(maxid)
                continue
            elif input[0] in searchKey:
                twitSearch(' '.join(input[1:]))
                continue
            elif input[0] in exitKey:
                print 'bye ;-)'
                break
            else:
                twitPost(unicode('%s'%(all_input), 'utf-8'))
                continue
        else: 
            getReplies(maxid)

pit使うとID、パスワードを書き換えてから貼付け...とか考えなくていいのが嬉しいです:)
PAGE TOP