Skip to content

Instantly share code, notes, and snippets.

@yingtai
Created July 17, 2011 13:18
Show Gist options
  • Save yingtai/1087581 to your computer and use it in GitHub Desktop.
Save yingtai/1087581 to your computer and use it in GitHub Desktop.
#coding: utf-8
import tweepy, random, re, os, time, urllib, urllib2, cookielib, csv,MeCab
from xml.etree.ElementTree import *
from PIL import Image
from BeautifulSoup import BeautifulSoup
secrets=[i for i in csv.reader(open('Database\\password.csv'))]
consumer_key=secrets[2][1]; consumer_secret=secrets[3][1]
access_key=secrets[4][1]; access_secret=secrets[5][1]
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_key, access_secret)
api = tweepy.API(auth_handler=auth)
class Maze():
def __init__(self):
self.ROAD=0; self.WALL=1; self.ROUTE=2
self.STRROAD=u'□'; self.STRWALL=u'■'; self.STRROUTE=u'△'
self.width=11; self.height=9
self.sx=1; self.sy=0
self.gx=self.width-2; self.gy=self.height-1
def makeMazeData(self):
bigdata=[[[] for x in range(self.width+2)] for y in range(self.height+2)]
for x in range(self.width+2):
for y in range(self.height+2):
if x in set(i+1 for i in range(self.width)) and y in set(j+1 for j in range(self.height)):
bigdata[y][x]=self.WALL
else: bigdata[y][x]=self.ROAD
self.dig(self.sx+1, self.sy+2, bigdata)
bigdata[self.sy+1][self.sx+1]=bigdata[self.gy+1][self.gx+1]=self.ROAD
data=[L[1:self.width+1] for L in bigdata[1:self.height+1]]
return data
def dig(self,px,py,bigdata):
for i in range(100):
vector=[[0,1,0,-1],[1,0,-1,0]]; r=random.randint(0,3)
dx=vector[0][r]; dy=vector[1][r]
if bigdata[py+dy*2][px+dx*2]!=self.ROAD:
bigdata [py+dy][px+dx]=bigdata[py+dy*2][px+dx*2]=self.ROAD
self.dig(px+dx*2, py+dy*2, bigdata)
def data2String(self,data):
stringData=''
for y in range(self.height):
for x in range(self.width):
if data[y][x]==self.ROAD: stringData+=self.STRROAD
elif data[y][x]==self.WALL: stringData+=self.STRWALL
elif data[y][x]==self.ROUTE: stringData+=self.STRROUTE
else: print 'translate error'
stringData+='\n'
return stringData
def string2Data(self,stringData):
data=[[[] for x in range(self.width)] for y in range(self.height)]
for x in range(width):
for y in range(height):
count=x+y*(self.width+1)
if stringData[cnt]==self.STRWALL: data[y][x]=self.WALL
elif stringData[cnt]==self.STRROAD: data[y][x]==self.ROAD
elif stringData[cnt]==self.STRROUTE: data[y][x]==self.ROUTE
else: print 'transtate error'
return data
def solve(self,data):
INF=1000; vector=[[1,0,-1,0],[0,1,0,-1]]; d=[[INF for x in range(self.width)] for y in range(self.height)]
d[self.sy][self.sx]=now=0
que=[(self.sy,self.sx)]; goal=(self.gy,self.gx)
while True:
for count in que[:]:
p=que.pop(0)
for i in range(4):
newque=(p[0]+vector[0][i],p[1]+vector[1][i]);
if 0<=newque[0]<self.height and 0<=newque[1]<self.width and d[newque[0]][newque[1]]==INF and data[newque[0]][newque[1]]==self.ROAD:
d[newque[0]][newque[1]]=now+1; que.append(newque)
if d[self.gy][self.gx]!=INF:
data[self.gy][self.gx]=self.ROUTE; break
now+=1
while True:
for i in range(4):
x=map(lambda g,v:g+v,goal,(vector[0][i],vector[1][i]))
if 0<=x[0]<self.height and 0<x[1]<self.width and d[x[0]][x[1]]==now:
goal=x; now-=1 ;data[x[0]][x[1]]=self.ROUTE; break
if now==0: break
data[self.sy][self.sx]=self.ROUTE
return data
def makeMain(self):
return self.data2String(self.makeMazeData())
def solveMain(self,text):
text=re.split(u'(\W+)',text[3].lstrip(u'\n')+'\n')
return self.data2String(self.solve(self.string2Data(tweet)))
class Weather():
def main(self,text):
text=unicode(text)
regionlist=[{'jp':unicode(i[0]),'en':i[1]} for i in csv.reader(open('Database\\region.csv'))]
conditionlist=[{'en':i[0],'jp':unicode(i[1])} for i in csv.reader(open('Database\\condition.csv'))]
datelist=[{'reg':u'現在','date':u'現在','n':0},{'reg':u'(きょう|今日)','date':u'今日','n':1},{'reg':u'(あした|あす|明日)','date':u'明日','n':2},
{'reg':u'(!し|!明)(あさって|明後日)',u'date':'明後日','n':3},{'reg':u'[し明](あさって|明後日)','date':u'明後日','n':4}]
week=['Sun','Mon','Tue','Wed','Thu','Fri','Sat']
region={'jp':'神戸','en':'Kobe'}
for i in regionlist:
if re.search(i['jp'],text)!=None: region=i; break
for i in datelist:
if re.search(i['reg'],text)!=None: date=i;break
elem=ElementTree(file=urllib2.urlopen('http://www.google.com/ig/api?weather=%s'%region['en']))
current = elem.find('.//current_conditions')
forecasts=elem.findall('.//forecast_conditions')
if date['date']==u'現在':
condition={'en':current.find('condition').get('data')}
temp_c=current.find('temp_c').get('data')
humidity={'en':current.find('humidity').get('data')}
condition['jp']=condition['en']
for i in conditionlist:
if condition['en']==i['en']: condition['jp']=i['jp'];break
humidity['jp']=humidity['en'].split(' ')[1]
return u'現在の%sの天気は%sです、気温は%s℃、湿度は&sです'%(region['jp'],condition['jp'],temp_c,humidity['jp'])
else:
for forecast in forecasts:
low=forecast.find('low').get('data')
high=forecast.find('high').get('data')
low=str((int(low)-32)*5/9); high=str((int(high)-32)*5/9)
condition={'en':forecast.find('condition').get('data')}
day_of_week=forecast.find('day_of_week').get('data')
condition['jp']=condition['en']
for i in conditionlist:
if condition['en']==i['en']: condition['jp']=i['jp'];break
if week[(int(time.strftime('%w'))+date['n']-1)%7]==day_of_week:
return u'%sの%sの天気は%s、最高気温は%s℃、最低気温は%s℃でしょう'%(date['date'],region['jp'],condition['jp'],high,low)
class Sisoku():
def __init__(self):
self.comb=[[(i,j) for i in range(j) for j in range(j+1) if i<j] for j in range(6) if 0<j]
def solve(self,opes,ans,n=6):
print opes,ans
length=len(opes)
opes=map(float,opes); opes_copy=opes[:]; ans=float(ans)
if not n in [1,2,3,4,5,6] or not length in [1,2,3,4,5,6]:return False
funclist=[lambda x,y:x+y, lambda x,y:x*y, lambda x,y:x-y, lambda x,y:y-x, lambda x,y:x/y, lambda x,y:y/x]
funcs=map(lambda i:i[:length],map(lambda list:map(lambda h:funclist[h],list),[(i,j,k,l,m) for i in range(n) for j in range(n) for k in range(n) for l in range(n) for m in range(n)]))
turns=map(lambda i:i[:length-1],[(i,j,k,l,m) for i in range((length-1)*(length)/2) for j in range((length-2)*(length-1)/2 if 2<length else 1) for k in range((length-3)*(length-2)/2 if 3<length else 1) for l in range((length-4)*(length-3)/2 if 4<length else 1) for m in range((length-5)*(length-4)/2 if 5<length else 1)])
for func in funcs:
for turn in turns:
opes=opes_copy[:]
try:
for i in range(length-1):
opes[self.comb[length-(i+2)][turn[i]][0]] = func[i](opes[self.comb[length-(i+2)][turn[i]][0]],opes[self.comb[length-(i+2)][turn[i]][1]])
opes.pop(self.comb[length-(i+2)][turn[i]][1])
if -0.00001<opes[0]-ans<0.00001: return {'opes':opes_copy,'turn':turn,'func':func}
except (ZeroDivisionError,OverflowError,ValueError):continue
def data2String(self,data):
if data:
funcchr=['+','*','-','-','/','/']; func=[]
opes=data['opes']; turn=data['turn']; length=len(opes)
tests = map(lambda f:f(2.0,3.0),data['func'])
for test in tests:
if test==5: func.append(0)
elif test==6: func.append(1)
elif test==-1: func.append(2)
elif test==1: func.append(3)
elif test==2.0/3.0: func.append(4)
else: func.append(5)
opes=map(lambda i:str(int(i)),opes)
for i in range(length-1):
if func[i] in [3,5]:
opes[self.comb[length-(i+2)][turn[i]][0]]='('+opes[self.comb[length-(i+2)][turn[i]][1]]+funcchr[func[i]]+opes[self.comb[length-(i+2)][turn[i]][0]]+')'
opes.pop(self.comb[length-(i+2)][turn[i]][1])
else:
opes[self.comb[length-(i+2)][turn[i]][0]]='('+opes[self.comb[length-(i+2)][turn[i]][0]]+funcchr[func[i]]+opes[self.comb[length-(i+2)][turn[i]][1]]+')'
opes.pop(self.comb[length-(i+2)][turn[i]][1])
opes[0]=opes[0][1:len(opes[0])-1]
return opes[0]
else:
return u'解がありません'
def tweet2Data(self,text):
textlist=re.split('[^0-9\.]',text)
while True:
if '' in textlist: textlist.remove('')
else:break
list=[float(i) for i in textlist]
opes=list[:len(list)-1]
ans=list[len(list)-1]
return [opes,ans]
class Icon():
def __init__(self):
pixiv_id=secrets[0][1];pixiv_pw=secrets[1][1]
self.connect =urllib2.build_opener(urllib2.HTTPCookieProcessor(cookielib.CookieJar()))
req = urllib2.Request("http://www.pixiv.net/index.php")
req.add_data( urllib.urlencode( {"mode":"login", "pixiv_id":pixiv_id, "pass":pixiv_pw} ))
res = self.connect.open(req).read()
def searchPageParser(self,html):
info=[]
illustList=BeautifulSoup(html).findAll('section',{'id':'search-result'})[0].findAll('li')
for illust in illustList:
a=illust.findAll('a')
if len(a)==1:continue
else:
image_author_name=a[1].string; image_author_id=a[1]['href']
illust_id=a[0]['href'].split('illust_id=')[1]
if len(a)==2: bkm=0
else: bkm=int(a[2]['data-tooltip'].split(u'件')[0].replace(',',''))
info.append({'bkm':bkm, 'illust_id':illust_id, 'image_author_name':image_author_name, 'image_author_id':image_author_id})
return info
def illustPageParser(self,illust_id):
illusturl='http://www.pixiv.net/member_illust.php?mode=big&illust_id=%s'%illust_id
req=urllib2.Request(illusturl)
req.add_header('Referer',illusturl.replace("big","medium"))
html=self.connect.open(req).read().decode("utf8")
imgurl=BeautifulSoup(html).findAll('img')[0]['src']
return imgurl
def download(self,illust_id):
try:
imgurl=self.illustPageParser(illust_id)
req=urllib2.Request(imgurl)
req.add_header('Referer','http://www.pixiv.net/member_illust.php?mode=big&illust_id=%s'%illust_id)
image=self.connect.open(req).read()
savedir=os.getcwd(+'\\Images')
file=open(savedir+'\\'+os.path.basename(imgurl),'wb')
for i in image:
file.write(i)
file.close(); print 'Done.'
except Exception,e:print e
def downloadMostFaved(self,query):
imgdatas=[];maxbkm=0;illust_id=-1
for i in range(100):
url=u'http://www.pixiv.net/search.php?s_mode=s_tag&word=%s&order=date_d&p=%s'%(urllib.quote_plus(query.encode('utf-8')),str(i))
html=self.connect.open(urllib2.Request(url)).read()
if re.search(u'<div class="no-item">見つかりませんでした</div>',html)!=None:break
imgdatas.extend(self.searchPageParser(html))
for i in imgdatas:
if i['bkm']>maxbkm: maxbkm=i['bkm'];illust_id=i['illust_id']
self.download(illust_id)
def makeFromTwitterIcon(self):
pass
class Twitter():
def returnNewStatuslist(self,method):
statuses=method()
try:
statuses_data_path='Database\\mention_statuses.csv' if all([0<=i.text.find('@yingtai_bot') for i in statuses]) else 'Database\\timeline_statuses.csv'
old_statuses=[i for i in csv.reader(open(statuses_data_path))]
last_status_id=int(old_statuses[0][0].replace('\xef\xbb\xbf',''))
newstatuslist=[]
for status in statuses:
if status.id >last_status_id: newstatuslist.append(status)
new_status_writer=csv.writer(file(statuses_data_path,'w'))
for newstatus in newstatuslist:
new_status_writer.writerow([newstatus.id,newstatus.text,newstatus.author.id,newstatus.author.screen_name])
new_status_writer.writerows(old_statuses)
return newstatuslist
except tweepy.error.TweepError,e:
print e
if not str(e).find('Rate limit exceeded.')>-1:
self.returnNewStatuslist(method)
def tweetResponser(self,statuses):
followers_ids=api.followers_ids()
if statuses:
for status in statuses:
if status.author.id in followers_ids:
def reply(text):
try: api.update_status(u'@%s %s'%(status.author.screen_name,text),status.id)
except:
try:api.update_status(u'@%s %s '%(status.author.screen_name,text),status.id)
except:pass
if status.text.find('@yingtai_bot')>-1:
if status.text.find(u'天気')>-1:
api.update_status
elif re.search(u'迷路.*(昨|書|出)',status.text)!=None:
reply(u'\n%s'%m.makeMain())
elif re.search(u'解[いきくけこ]',status.text)!=None:
try:
reply(u'\n%s'%m.solveMain(api.get_status(status.in_reply_to_status_id).text))
except:
if status.id!=None: reply(u'迷路以外のツイートにリプライ飛ばしてませんか')
else: api.update_status(u'@%s えっ'%status.author.screen_name,status.id)
elif re.search(u'@yingtai_bot.*@[\w]+に[0-9]個の?(fav|ふぁぼ)',status.text):
self.favbomb(status)
else: reply('はい')
else:
if status.text.find('@')<0:
if re.search(u'((!ちゃん)|[ね寝](る|ます))|[nNnN][eeEE](1|[rrRRllLL])(!vv)|おやす',status.text)!=None:
reply([u'おやすみ',u'おやすみー',u'おやすみなさい'][random.randint(0,2)])
elif re.search(u'(お[はそ][およ]|ohayo|[gGgG](ood|ood|OOD|OOD).*[mmMM](orning,orning,ORNING,ORNING)|ごおdもrにんg|むくり|mkr|[起お]きた|すらま|スラマ|早上好)',status.text)!=None:
reply([u'おはよう',u'おはよー',u'おはようございます'][random.randint(0,2)])
elif re.search(u'離脱|りだ[つる]|([ppPP][ccCC]|パソ).*([閉と]じる|[け消]す|[き切]る|[お落]とす)|[で出][か掛]ける|を[で出]る|[い行]って[くき来](る|ます)|出発',status.text)!=None:
reply('いってらっしゃい')
elif re.search(u'(!聞|!吐|!嘆)きたく|帰宅|ただいま|kitaku|KITAKU',status.text):
reply([u'おかえり',u'おかえりなさい'][random.randint(0,1)])
if re.search(u'([0-9.]+,)+[0-9\.] *(→|から|⇒|[-=]>) *[0-9\.]+',status.text)!=None:
data=sisoku.tweet2Data(status.text)
reply(sisoku.data2String(sisoku.solve(data[0],data[1])))
def favbomb(self,status):
splited=re.split(u'(\W+)',status.text)
userid=splited[4];number=int(splited[6])
print userid,"に",number,"個"
for p in tweepy.Cursor(api.user_timeline,id=userid).items(number):
try: api.create_favorite(p.id)
except: continue
api.update_status(u'@%sの代行として%s個のfavを贈りました'%(userid,number),status.id)
def follow_remove(self):
global hour
try:
fol=set(api.followers_ids())
fri=set(api.friends_ids())
#fol+=set('rh_ruson','alsuce10','ConstantineJP','e__ki','isennite','akatikukitiku')
for i in list(fol-fri):
api.create_friendship(i)
#for i in list(fri-fol):
# api.destroy_friendship(i)
except: hour-=1
def main(self):
global hour
if time.localtime()[3]!=hour:
self.follow_remove()
api.update_status(analyzer.markov(analyzer.getwordlist()))
self.tweetResponser(self.returnNewStatuslist(api.mentions))
self.tweetResponser(self.returnNewStatuslist(api.friends_timeline))
hour=time.localtime()[3]
class Analyzer():
def __init__(self):
self.wkt=lambda text:MeCab.Tagger("-Owakati").parse(text)
self.cha=lambda text:MeCab.Tagger('-Ochasen').parse(text)
def markov(self,texts):
wordlist=[]
for text in texts:
wordlist.extend(self.split(text))
markov={}; word1=word2=''
for word in wordlist:
if word1 and word2:
if (word1,word2) not in markov: markov[(word1,word2)]=[]
markov[(word1,word2)].append(word)
word1,word2=word2,word
sentence=''
word1,word2=random.choice(markov.keys())
while True:
while True:
if any([self.cha(sentence).split('\n')[0].find(pos)>-1 for pos in [u'フィラー',u'動詞',u'助詞',u'助動詞',u'記号']]):
sentence=''
try: tmp=random.choice(markov[(word1,word2)]);break
except:
word1,word2=random.choice(markov.keys())
sentence+=tmp
word1,word2=word2,tmp
sentence=re.sub('(@(\w+)|#(\w+)|\w*_\w*|h?ttp://[\w\./]+)','',sentence)
if re.search('終助詞|助動詞|。',self.cha(sentence))!=None:
if 50<len(sentence)<140:
f=lambda list:list[len(list)-3]
#for i in self.cha(sentence).split('\n'):
# print '"%s"'%i
if not any(f(self.cha(sentence).split('\n')).find(pos)>-1 for pos in [u'連用',u'連体',u'未然',u'接頭',u'接続']):
if not sentence.endswith('。'):sentence+='。'
break
else:sentence=''
print self.cha(sentence)
#print '>',f(self.cha(sentence).split('\n'))
#print any(f(self.cha(sentence).split('\n')).find(pos)>-1 for pos in [u'連用',u'連体','未然','接頭'])
return sentence
def split(self,text):
m = self.wkt(text)
result = m.rstrip("\n").split(" ")
return result
def getwordlist(self):
return [i[1] for i in csv.reader(open('Database\\timeline_statuses.csv'))]
maze=Maze()
weather=Weather()
sisoku=Sisoku()
icon=Icon()
twitter=Twitter()
analyzer=Analyzer()
if __name__ == '__main__':
hour=time.localtime()[3]
while True:
time.sleep(0.1)
#print analyzer.markov(analyzer.getwordlist())
#"""
print u'残りAPI数: %s リセット: %s'%(api.rate_limit_status()['remaining_hits'],api.rate_limit_status()['reset_time'])
time.sleep(50)
print 'start'
twitter.main()
print 'end'
#"""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment