読者です 読者をやめる 読者になる 読者になる

When it’s ready.

出来るまで出来ない

friendfeed のクライアントをPythonで作ったぉ。pyff ターミナルクライアント

清楚なクライアントから始まり、pytterにしたりと色々クライアント弄ってきたけど、twitterのライブラリが同じ名前で色々存在していたり、検索機能がいちいちパッとしないので最近あまり使わずにいた。先週くらいからFriendFeedのフォロー祭りが始まってそこそこFeedが賑やかになってきたので、friendfeed用のクライアントを作ってみた。まだ、投稿機能とかファイルに落とすところとか無いけど、見るだけはある程度出来たので公開。

必要モジュール

  • Pit

easy_install pitで入るはず。

ここ(http://code.google.com/p/friendfeed-api/)にあるアーカイブ落として、pythonフォルダー中からfriendfeed.pyをsite-packeagesに入れる or pyff.py(ソースはこのページの下)と同階層に置く。

アカウント設定

friendfeedは、リモートからアクセスする為にリモートキーというのが必要になる。よくありがちなめんどくさいDevIDとかの発行は一切要らない。
https://friendfeed.com/account/api
にログインした状態でアクセスすると、ニックネームとアクセスキーを教えてもらえる。IDとKeyは、初回起動時に聞かれるので適宜入力して、保存する。>Pit最高!

ソース

pyff.py という名前にしてみた。

#!/usr/bin/env python
# coding:utf-8
"""
pyff.py

Created by atusi on 2009-05-12.
Copyright (c) 2009 a2c. All rights reserved.
"""
import friendfeed
import datetime
import readline, os
from pit import Pit

ff_conf = Pit.get('friendfeed.com',
      {'require' : {'nickname':'Your friendfeed nickname','remote_key':'Your friendfeed key'}})

session = friendfeed.FriendFeed(ff_conf['nickname'], ff_conf['remote_key'])

searchKey = ['s']
exitKey = ['x', 'ZZ', 'exit', 'bye']
service_list = {'t':'Twitter', 'h':u'はてな', 'd':'del.icio.us', 'r':'Tumblr'}
friends_list = set()

def getJST(time):
  # UTCをJSTに変換する
  return time + datetime.timedelta(hours=9)

def getHome(service=None):
  # serviceを指定してFeedを取得する。指定がない場合は全てのサービスを取得する 
  feeds = session.fetch_home_feed()
  for feed in reversed(feeds['entries']):
    setFriendList(feed['user'])
    if service == None:
      printTL(feed)
    else:
      if feed['service']['name'] == service_list[service]:
        printTL(feed)

def setFriendList(friendID):
    friends_list.add(friendID['nickname'])
    friends_list.add(friendID['name'])

def getSearch(q):
  feeds = session.search(q)
  for feed in reversed(feeds['entries']):
    setFriendList(feed['user'])
    printTL(feed)


def printTL(one_post):
  print 'usr:%s date: %s'%(one_post['user']['nickname'], getJST(one_post['published']).strftime("%m/%d %X"))
  print 'title:', one_post['title'], 'from', one_post['service']['name']
  if one_post['comments']:
    print 'comment:'
    for com in one_post['comments']:
      print '\t%s : %s'%(com['user']['name'],com['body'])
  print ' -- '

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

if __name__ == "__main__":
  readline.parse_and_bind("tab: complete")
  readline.set_completer(complete)
  prompt = '\n cmd: twitter[t] hatena[h] del[d] tumblr[r] eXit[x] \n> '
  while True:
    if os.name == 'nt':
      print prompt,
      input = sys.stdin.readline().decode('mbcs').encode('utf-8').strip()
      input = input.split(" ")
    else:
      input = raw_input(prompt)
      input = input.split(" ")
    if input[0] != '':
      if input[0] in service_list:
        getHome(input[0])
        continue
      elif input[0] in searchKey:
        getSearch(input[1])
        continue
      elif input[0] in exitKey:
        print 'bye ;-)'
        break
    else:
      getHome()
      continue

実行してみる

python pyff.py

と起動すると、若干の時間をおいてプロンプトが表示されます。

 cmd: twitter[t] hatena[h] del[d] tumblr[r] search[s arg] eXit[x] 
> 

それぞれのサービスの後ろに付いてる英語1文字だけ入力してエンターをすると、各サービスだけのFeedがPrintされます。何も打たずにエンターすると、全てのサービスのFeedがPrintされます。

さらに、とっても便利な横断検索が出来ます

 cmd: twitter[t] hatena[h] del[d] tumblr[r] search[s arg] eXit[x] 
> s 検索語

と打つことで、自分が購読している範囲で全てのサービスに渡って検索をする事が出来ます。これは大変便利。
また、購読しているユーザーのnicknameとnameを補完してくれる(既に呼んだことある人のみ)ので
atusiであれば at まで打ってすれば、atusiと補完されます。曖昧にしか覚えてない人も頭の
数文字打てば補完されます。

Todo

  • bitbucketsにリポジトリ作って上げる
  • TumblrのFeedが無駄に改行されてしまう
  • Twitterに投稿出来る用にしたい。
  • Friend_Listを永続化させる
  • multiprocess化して、データの抜けを無くす
  • fetchしてきたデータを、sqlite3かTCで永続化

出来るのかな?

ターミナルのurlの文字列をクリックすると、Firefoxでそこ開いたり、マウス乗っけると画像を表示させたりしたいんだけど、そういうのって出来るのかな? だれか教えてくらさいm(_ _)m