Pythonでtwitterクライアント作ってみる - その2
ってかぜんぜん進んでない・・・
前に指摘されたとこも取り入れて
一覧を10秒おきに取得してコメントがあれば表示するようにしてみました
で、修正してみたけど問題発生
Ctl-Cで終了させたときにプロセスが残っちゃう
あとターミナルの制御が奪えてない(標準出力に吐き出してるだけ)からダサい・・・
#!/usr/bin/env python
# -*- coding: utf-8 -*-"""
/** twitter cuiクライアントもどき
*
* @version 0.0.1
* @auther mochi
*
*/
"""import sys, time, os, re
#import tty, termios
#import commands
import StringIO
import pycurl
import threading
from xml.parsers import pyexpat
#import difflib
#import sqlite3class Product(object): # Interface
def setAttribute(name, value): pass
def getAttribute(name): pass
def execute(): raise NotImplementedErrorclass Parser: # Interface
def __init__(): pass
def parse(): passclass XMLParser(Parser, threading.Thread):
p = None
str = ""
def __init__(self):
threading.Thread.__init__(self)
self.p = pyexpat.ParserCreate()
def createParser(self):
self.p = pyexpat.ParserCreate()def startElement(obj, name, nodes):
global dispflg
if name == 'text':
dispflg = True
elif name == 'screen_name':
dispflg = True
else:
dispflg = False
def endElement(obj, name):
if name == 'text':
sys.stdout.write(" -> [ ")
sys.stdout.flush()
elif name == 'screen_name':
sys.stdout.write(" ]\n")
sys.stdout.flush()
time.sleep(0.1)
def charData(text, value):
if dispflg is True:
str = value.encode('UTF-8', 'replace').replace("\n", "")
str = str.replace(" ", "")
sys.stdout.write(str)
sys.stdout.flush()
#
def parse(self, str=""):
if not self.p: self.createParser()
if str is not "": self.str = str
self.p.StartElementHandler = self.startElement
self.p.EndElementHandler = self.endElement
self.p.CharacterDataHandler = self.charData
self.p.Parse(self.str)del(self.p)
#
def run():
passclass ApiContext(object): # Context
userID = 4671321
userName = "hagaeru3sei"
password = "******"
responseType = "xml" # [xml, json, atom, rss] which one choise
url = "http://twitter.com"
response = ""
parser = XMLParser()#
def setResponseType(self, type):
self.responseType = type
#
def getResponseType(self):
return self.type
#
def getUserURL(self):
return self.url + "/users/show."+ self.responseType +"?screen_name=" + self.userName
#
def getTimeLineURL(self):
return self.url + "/statuses/friends_timeline." + self.responseType#
def getUpdateURL(self):
return self.url + "/statuses/update." + self.responseType# factory method
def Curl(*args):
return pycurl.Curl()
# set httpResponse
def setResponse(self, res):
self.response = res#
def parse(self):
self.parser.parse(self.response)class Twitter(Product, threading.Thread): # Twitter
context = None
type, value = "", ""
prevStr = ""#
def __init__(self):
threading.Thread.__init__(self)
self.context = ApiContext()
def setOpt(self, type, value):
self.type = type
self.value = value
#
def execute(self, *args, **kwargs):
self.buffer = StringIO.StringIO()
curl = self.context.Curl()
curl.setopt(pycurl.URL, self.getURL())
curl.setopt(pycurl.USERPWD, self.context.userName + ':' + self.context.password)
if self.type == 'update':
curl.setopt(pycurl.POST, 1)
curl.setopt(pycurl.POSTFIELDS, "status=" + self.value)
elif self.type == "follow":
pass
elif self.type == "search":
pass
else:
curl.setopt(pycurl.WRITEFUNCTION, self.buffer.write)
curl.setopt(pycurl.FOLLOWLOCATION, 1)
curl.setopt(pycurl.MAXREDIRS, 5)
curl.setopt(pycurl.CONNECTTIMEOUT, 30)
curl.setopt(pycurl.TIMEOUT, 300)
curl.setopt(pycurl.NOSIGNAL, 1)
curl.perform()
#sys.stdout.write("\n")
#sys.stdout.flush()
#patt = re.compile("^.*(<\/.*>).*$")
o = self.buffer.getvalue().rstrip()
# 変更が無い場合表示しない
if o == self.prevStr: return#print(difflib.context_diff(self.prevStr,o))
self.prevStr = oself.context.setResponse(o)
self.context.parse()self.buffer.close()
#
def load(self):
threads = []
sys.stdout.write("Loading...")
sys.stdout.flush()self.start()
threads.append(self)
cnt = 0
list = ['|', '/', '-', '\\']
while self.isAlive() is True:
sys.stdout.write(list[cnt])
sys.stdout.flush()
sys.stdout.write("\b")
sys.stdout.flush()
time.sleep(0.1)
cnt += 1
if cnt > 3:
cnt = 0for thread in threads:
thread.join()
#
def run(self):
if self.type == 'update':
self.execute()
else:
while True:
self.execute()
time.sleep(10)#
def reload(self):
print('reload')#
def follow(userId):
pass
#
def sendDirectMessage(userId):
pass#
def setMessage(message):
self.message = message
return 0
#
def getURL(self):
if self.type == "update":
return self.context.getUpdateURL()
elif self.type == "follow":
return ""
elif self.type == "search":
return ""
else:
return self.context.getTimeLineURL()
# main
def main(*args, **kwargs):
type, value = "", ""
if not args[0].count(1): args[0].append(None)
if not args[0].count(2): args[0].append(None)
if args[0][1]:
type = args[0][1]
if args[0][2]:
value = args[0][2]
t = Twitter()
t.setOpt(type, value)
t.load()
return 0if __name__ == "__main__":
try:
main(sys.argv);
except Exception,e:
print(e)exit(0)
あ、あとXMLParserのparseでパースごとにインスタンス作ってやらないと例外投げられちゃったので修正したのと
起動時のオプションで投稿できるようにしました
shell> ./twitter.py update てすと
みたいな感じで