root/lang/python/crochet/chat_allsrc.py @ 19302

Revision 19302, 18.0 kB (checked in by showyou, 5 years ago)

gui不具合修正

  • Property svn:executable set to *
Line 
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4import sys
5import os
6import wx
7import wx_utils
8
9import main_icon
10
11import twitter3
12import simplejson
13import Image
14
15import thread
16
17g_config = {}
18g_config['mycolor'] = wx.Color(192,255,255)
19
20
21
22"""
23画像取得用スレッド
24"""
25class ImageGetFrame(wx.Frame):
26        def __init__(self,url,callbackFunc,result,lock):
27                self.url = url
28                self.func = callbackFunc
29                self.result = result
30                self.lock = lock
31        def start(self):
32                thread.start_new_thread(self.run, ())
33
34        def run(self):
35                import urllib,time
36                #ここに通信処理を書く
37                imagePath = urllib.urlopen(self.url).read()
38                #time.sleep(1)
39                self.lock.acquire()
40                self.func(imagePath,self.result)
41                self.lock.release()
42
43"""
44twitterにhttpRequestを投げるスレッド
45"""
46class TwDMHttpFrame(wx.Frame):
47        def __init__(self,tw,func,lock):
48                self.tw = tw
49                self.func = func
50                self.lock = lock
51        def start(self):
52                thread.start_new_thread(self.run, ())
53        def run(self):
54                #ここに通信処理を書く
55                self.lock.acquire()
56                try:
57                        a = self.tw.getDM("")
58                        self.func(a)
59                finally:
60                        self.lock.release()
61"""
62twitterにhttpRequestを投げるスレッド
63"""
64class TwReplyHttpFrame(wx.Frame):
65        def __init__(self,tw,func,lock):
66                self.tw = tw
67                self.func = func
68                self.lock = lock
69        def start(self):
70
71                thread.start_new_thread(self.run, ())
72       
73        def run(self):
74                #ここに通信処理を書く
75                self.lock.acquire()     
76                a = self.tw.getReplies("")
77                self.func(a)
78                self.lock.release()
79"""
80twitterにhttpRequestを投げるスレッド
81"""
82class TwHttpFrame(wx.Frame):
83        def __init__(self,tw,func,lock):
84                self.tw = tw
85                self.func = func
86                self.lock = lock
87        def start(self):
88                thread.start_new_thread(self.run, ())
89
90        def run(self):
91                #ここに通信処理を書く
92                #a = self.tw.get("")
93                self.lock.acquire()
94                try:
95                        a = self.tw.getWithScraping("")
96                except:
97                        import traceback
98                        print traceback.print_exception()       
99                self.func(a)
100                self.lock.release()
101
102
103"""
104全てのnotebookpageの基になるページクラス
105"""
106class TmpTwitPage(wx.NotebookPage):
107        def __init__(self, title, parent, threadLock):
108               
109                self.dataList = []
110                self.hiddenDataList = []
111                self.tmpDataList = []
112                self.tmpHiddenDataList = []
113                self.count = 0
114                self.owner = parent
115                self.lock = threadLock
116                wx.NotebookPage.__init__(self,parent.getNotebook(),-1)
117                parent.getNotebook().AddPage(self,title)
118                list = self.list = wx.ListCtrl(self,-1,style=wx.LC_REPORT|wx.LC_HRULES|wx.LC_SINGLE_SEL)
119                list.Bind(wx.EVT_KEY_DOWN, self.myKeyHandler)
120                list.Bind(wx.EVT_LIST_ITEM_ACTIVATED,self.OnDoubleClick)
121
122                list.InsertColumn(0," ",1,20)
123                list.InsertColumn(1,u"ユーザ")
124                list.InsertColumn(2,u"発言",0,200)
125                list.Bind(wx.EVT_LIST_ITEM_SELECTED,self.OnTwitListSelect)
126
127        def OnTwitListSelect(self,event):
128                import re
129                selectedRow = self.selectedRow = event.GetIndex()
130                dataList = self.dataList
131                label = self.owner.userName
132                text = self.owner.messageText
133                text.SetValue(dataList[selectedRow][2])
134                label.SetLabel(dataList[selectedRow][1])
135                self.owner.SetImage(dataList[selectedRow][4])
136                #選択したユーザに関する発言の色を変えてみる
137                               
138                user = self.owner.tw.user['user']
139                p = re.compile(dataList[selectedRow][1])
140                for i in range(0,self.list.GetItemCount()):
141                        if p.search(dataList[i][1]):
142                                self.list.SetItemBackgroundColour(i,wx.Color(225,225,225))             
143                        elif p.search(self.dataList[i][2]) :
144                                self.list.SetItemBackgroundColour(i,wx.Color(192,225,225))             
145                        else:
146                                self.list.SetItemBackgroundColour(i,wx.Color(255,255,255))
147
148                        if re.match(user,self.dataList[i][1]):
149                                self.list.SetItemBackgroundColour(i,g_config['mycolor'])
150
151                        if re.search(user,self.dataList[i][2]):
152                                self.list.SetItemBackgroundColour(i,wx.Color(255,153,153))
153
154        def ResetCount(self):
155                self.count = 0
156        # 後で多分実装       
157        def ChangeItemColour(self,index,data,re,color):
158                pass   
159        def OnDoubleClick(self,event):
160                selectedRow = event.GetIndex()
161                user = "@" + self.dataList[selectedRow][1]
162                self.owner.addUser2Inputbox(user)
163
164        def myKeyHandler(self,evt):
165                print evt.GetKeyCode(),
166                if self.selectedRow != -1:
167                        if evt.GetKeyCode() in [ord('k'),ord('K'),wx.WXK_UP]:
168                                print ('up')
169                                if self.selectedRow > 0:
170                                        self.MoveList(self.selectedRow-1)
171                        if evt.GetKeyCode() in [ord('j'),ord('J'),wx.WXK_DOWN]:
172                                print ('down')
173                                if self.selectedRow < self.list.GetItemCount()-1:
174                                        self.MoveList(self.selectedRow+1)
175                        if evt.GetKeyCode() in [ord('h'),ord('H'),wx.WXK_LEFT]:
176                                print ('left')
177                                leftcol = self.GetPrevItem(self.selectedRow)
178                                if leftcol != -1:
179                                        self.MoveList(leftcol)
180                        if evt.GetKeyCode() in [ord('l'),ord('L'),wx.WXK_RIGHT]:
181                                print ('right')
182                                rightcol = self.GetNextItem(self.selectedRow)
183                                if rightcol != -1:
184                                        self.MoveList(rightcol)
185                        if evt.GetKeyCode() in [ord('s'),ord('S')]:
186                                print("favorite")
187                                id = self.hiddenDataList[self.selectedRow][0]
188                                self.owner.tw.createFavorite(id)
189                                self.owner.SetStatusBar(u"fav登録しました")
190                if evt.GetKeyCode() in [ord('q'), ord('Q')]:
191                        wx.Exit()
192
193        # 今のユーザ名を含む、前の発言を検索
194        def GetPrevItem(self,row):
195                import re
196                print ('getprevItem')
197
198                userName = self.dataList[row][1]
199                p = re.compile(userName)
200                currentRow = row-1
201                while currentRow >= 0 :
202                        if (p.search(self.dataList[currentRow][1])):
203                                return currentRow
204                        currentRow-=1
205                return -1
206       
207        # 今のユーザ名を含む、後ろの発言を取得
208        def GetNextItem(self,row):
209                import re
210                print ('getnextItem')
211                userName = self.dataList[row][1]
212                p = re.compile(userName)
213                currentRow = row+1
214                while currentRow < len(self.dataList) :
215                        if (p.search(self.dataList[currentRow][1])):
216                                return currentRow
217                        currentRow+=1
218                return -1
219
220        def MoveList(self,newRow):
221                self.list.Select(self.selectedRow,0)
222                self.list.Select(newRow)
223                self.list.Focus(self.selectedRow)
224
225        def InsertData(self,data,hiddenData):
226
227                i = self.count
228                #ここでロック
229                self.tmpDataList.insert(i,data)# + self.dataList
230                self.tmpHiddenDataList.insert(i,hiddenData)# + self.hiddenDataList
231                #ここでアンロック
232                self.count += 1
233
234        #InsertDataで追加されてるかどうか確認して、あればリストに入れる
235        def CheckUpdate(self):
236                if len(self.tmpDataList) < 0 or len(self.tmpHiddenDataList) < 0:
237                        return
238
239                user = self.owner.tw.user['user']
240                import re
241                i = 0
242                for b in self.tmpDataList:
243       
244                        self.list.InsertStringItem(i,"")
245                        for j in range(3):
246                                self.list.SetStringItem(i,j,b[j])
247               
248                        if re.match(user,b[1]):
249                                self.list.SetItemBackgroundColour(i,g_config['mycolor'])
250
251                        if re.search(user,b[2]):
252                                self.list.SetItemBackgroundColour(i,wx.Color(255,153,153))
253               
254                        #import time
255                        #time.sleep(1)         
256                        #if 先読み=on
257                        #try:   
258                        self.owner.GetImageListElement(b[4])
259                        #except:
260                        #       print "Error:GetImageListElement"
261                        #       pass
262                        i += 1
263                self.dataList[:0] =self.tmpDataList
264                self.hiddenDataList[:0] = self.tmpHiddenDataList
265                self.tmpDataList = []
266                self.tmpHiddenDataList = []
267                self.ResetCount()
268"""
269カスタムページ(自分でフィルタリングする)
270"""
271class CustomPage(TmpTwitPage):
272        def __init__(self,title, parent,threadLock):
273                self.dataList = []     
274                TmpTwitPage.__init__(self,title,parent, threadLock)     
275       
276"""
277最近のfriendsの発言一覧を表示するページ
278"""
279
280customPage = [
281        u"小手指",
282        u"fav",
283        u"ゴミ"
284]
285try:
286        import Growl
287        g_growl = True
288except:
289        print "not exist:Growl sdk"
290        g_growl = False
291
292class RecentPage(TmpTwitPage):
293        def __init__(self, parent,threadLock):
294                TmpTwitPage.__init__(self,"Recent",parent,threadLock)
295
296                #self.dataList = []
297                #self.hiddenDataList = []
298                self.customPages = [] # フィルタリングページの固まり?
299               
300                if g_growl == True:
301                        self.g = Growl.GrowlNotifier(
302                                applicationName='crochet',notifications=['newTwit'])
303                        self.g.register()
304               
305        def ResetCount(self):
306                TmpTwitPage.ResetCount(self)           
307                for p in self.customPages:
308                        p.ResetCount()
309       
310        def AppendCustomPage(self, customPage):
311                self.customPages.append(customPage)
312
313        def Reflesh(self):
314                t = TwHttpFrame(self.owner.tw,self.RefleshList,self.lock)
315                t.start()
316                #t.run()
317
318        def RefleshList(self,a):
319                #lockかけた方がいいのかも。。
320                self.ResetCount()
321                user = self.owner.tw.user['user']
322                for x in a:
323                        flag = 0
324                       
325                        # 重複発言チェック
326                        for d in self.dataList:
327                                if d[2] == x[1]:
328                                        flag = 1
329                                        break
330
331                        for p in self.customPages:
332                                for d in p.dataList:
333                                        if d[2] == x[1]:
334                                                flag = 1
335                                                break
336                                if flag == 1: break
337
338                        if flag == 0 :
339                                dataListElement = []
340                                dataListElement.append("")
341                                dataListElement.append(x[0])
342                                dataListElement.append(x[1])
343                                dataListElement.append(x[2])
344                                dataListElement.append(x[3])
345
346                                hiddenDataListElement = []
347                                hiddenDataListElement.append(x[4])#発言id
348                               
349                                flag2 = 0
350                                if x[0] == "yuumizusawa" or x[0] == "miz_" or x[0] == "breeziness":
351                                        self.customPages[0].InsertData(user,dataListElement,hiddenDataListElement)
352                                        flag2 = 1
353       
354                                if flag2 == 0:
355                                        self.InsertData(dataListElement,hiddenDataListElement)
356                                        if g_growl == True:
357                                                self.g.notify(noteType='newTwit',title=x[0],
358                                                        description=x[1],sticky=False)
359                                self.owner.SetNowTime2StatusBar()
360                print "end setdataList"
361
362class ReplyPage(TmpTwitPage):
363
364        def __init__(self, parent,threadLock):
365                TmpTwitPage.__init__(self,"Reply",parent,threadLock)
366                #self.dataList = []
367                #self.hiddenDataList = []
368       
369        def Reflesh(self):
370                t = TwReplyHttpFrame(self.owner.tw,self.RefleshList,self.lock)
371                t.start()
372                       
373        def RefleshList(self,a):
374                #lockかけた方がいいのかも。。
375                self.ResetCount()
376                user = self.owner.tw.user['user']
377                for x in a:
378                        flag = 0
379                       
380                        # 重複発言チェック
381                        for d in self.dataList:
382                                if d[2] == x[1]:
383                                        flag = 1
384                                        break
385                        if flag == 0 :
386                                dataListElement = []
387                                dataListElement.append("")
388                                dataListElement.append(x[0])
389                                dataListElement.append(x[1])
390                                dataListElement.append(x[2])
391                                dataListElement.append(x[3])
392
393                                hiddenDataListElement = []
394                                hiddenDataListElement.append(x[4])#発言id
395       
396                                self.InsertData(dataListElement,hiddenDataListElement) 
397                print "end setdataList"
398
399class DMPage(TmpTwitPage):
400
401        def __init__(self, parent,threadLock):
402                TmpTwitPage.__init__(self,"DM",parent,threadLock)
403                dataList = []
404        def Reflesh(self):
405                t = TwDMHttpFrame(self.owner.tw,self.RefleshList,self.lock)
406                t.start()
407
408        def RefleshList(self,a):
409                #lockかけた方がいいのかも。。
410                self.ResetCount()
411                user = self.owner.tw.user['user']
412                for x in a:
413                        flag = 0
414                       
415                        # 重複発言チェック
416                        for d in self.dataList:
417                                if d[2] == x[1]:
418                                        flag = 1
419                                        break
420                        if flag == 0 :
421                                dataListElement = []
422                                dataListElement.append("")
423                                dataListElement.append(x[0])
424                                dataListElement.append(x[1])
425                                dataListElement.append(x[2])
426                                dataListElement.append(x[3])
427
428                                hiddenDataListElement = []
429                                hiddenDataListElement.append(x[4])#発言id
430       
431                                self.InsertData(dataListElement,hiddenDataListElement) 
432                print "end setdataList"
433       
434class MainFrame(wx.Frame):
435        """MainFrame class deffinition.
436        """
437        binder = wx_utils.bind_manager()
438
439        TIMER_ID = 1
440        TIMER_ID2= TIMER_ID+1
441        TIMER_ID3= TIMER_ID2+1
442        imageList = {}
443        t = {}
444        def loadUserData(self, fileName):
445                #ファイルを開いて、データを読み込んで変換する
446                #データ形式は(user,password)
447                #try
448                file = open(fileName,'r')
449                a = simplejson.read(file.read())
450                file.close()
451                return a
452                #catch exit(1)
453               
454        def __init__(self, parent=None):
455                #from pit import Pit
456                #twUserdata = Pit.get('twitter.com',{'require' : {'user':'','pass':''}})
457                twUserdata = self.loadUserData(".chat/twdata")
458                wx.Frame.__init__(self,None, -1, "crochet")
459               
460                self.CreateStatusBar()
461
462                self.selectedRow = -1
463                text = self.text = wx.TextCtrl(self,-1,style=wx.TE_PROCESS_ENTER)
464                text.Bind(wx.EVT_TEXT_ENTER, self.OnSendTW)
465                button = self.button = wx.Button(self, -1, "Send")
466                self.button.Bind(wx.EVT_BUTTON, self.OnSendTW)
467       
468                notebook = self.notebook = wx.Notebook(self,-1)
469
470
471                self.imageThreadLock = thread.allocate_lock()
472                self.httpThreadLock = thread.allocate_lock()
473               
474                self.recentPage = RecentPage(self,self.httpThreadLock)
475                self.replyPage = ReplyPage(self,self.httpThreadLock)
476                self.directPage = DMPage(self,self.httpThreadLock)
477
478                for p in customPage:
479                        page = CustomPage(p,self,self.httpThreadLock)
480                        self.recentPage.AppendCustomPage(page) 
481               
482                inputSizer = wx.BoxSizer(wx.HORIZONTAL)
483                inputSizer.Add(self.text,2,wx.EXPAND)
484                inputSizer.Add(self.button,0)
485               
486
487                messageText=self.messageText = wx.TextCtrl(self,-1,style=wx.TE_MULTILINE|wx.TE_AUTO_URL|wx.TE_READONLY)
488                userIcon = self.userIcon = wx.StaticBitmap(self,-1,wx.NullBitmap,(0,0),(64,64))
489                userName = self.userName = wx.StaticText(self,-1,"test")
490                twitTime = self.twitTime = wx.StaticText(self,-1,"---")
491               
492                messageSizer3 = wx.BoxSizer(wx.HORIZONTAL)
493                messageSizer3.Add(userName,1,wx.EXPAND)
494                messageSizer3.Add(twitTime,1,wx.EXPAND)
495
496                messageSizer2 = wx.BoxSizer(wx.VERTICAL)
497                messageSizer2.Add(messageSizer3,0,wx.EXPAND)
498                messageSizer2.Add(messageText,1,wx.EXPAND)
499               
500                messageSizer1 = wx.BoxSizer(wx.HORIZONTAL)
501                messageSizer1.Add(userIcon,0)
502                messageSizer1.Add(messageSizer2,1,wx.EXPAND)
503       
504                messageSizer = wx.BoxSizer(wx.VERTICAL)
505                messageSizer.Add(messageSizer1,3,wx.EXPAND)
506                messageSizer.Add(inputSizer,1,wx.EXPAND)
507               
508                self.sizer = wx.BoxSizer(wx.VERTICAL)
509                self.sizer.Add(notebook,1,wx.EXPAND)
510                self.sizer.Add(messageSizer,0,wx.EXPAND)
511               
512                self.SetSizer(self.sizer)
513                self.SetAutoLayout(True)
514                inputSizer.Fit(self)
515                self.sizer.Fit(self)
516       
517                self.tw = twitter3.Twitter(twUserdata)
518                self.tw.setAuthService("twitter")
519                self.SetIcon(main_icon.getIcon())
520                self.SetSize((300,400))
521                self.timer = wx.Timer(self,self.TIMER_ID)
522                wx.EVT_TIMER(self,self.TIMER_ID,self.OnUpdate)
523                self.timer.Start(60000)
524               
525                self.timer11 = wx.Timer(self,self.TIMER_ID3+1)
526                wx.EVT_TIMER(self,self.TIMER_ID3+1,self.OnUpdate2)
527                self.timer11.Start(10000)
528
529                self.timer2 = wx.Timer(self,self.TIMER_ID2)
530                wx.EVT_TIMER(self,self.TIMER_ID2,self.OnReplyUpdate)
531                self.timer2.Start(300000)
532               
533                self.timer3 = wx.Timer(self,self.TIMER_ID3)
534                wx.EVT_TIMER(self,self.TIMER_ID3,self.OnDMUpdate)
535                self.timer3.Start(300000)
536                self.RefleshTw()
537
538                self.replyPage.Reflesh()
539                self.directPage.Reflesh()
540
541                self.SetNowTime2StatusBar()
542       
543        def OnSendTW(self, event):
544                # 送信する
545                # コンボボックスの中身を空にする
546                combo = self.text
547                self.tw.put(combo.GetValue())   
548                combo.SetValue("")
549                self.RefleshTw()
550       
551        # チャットのログデータをListCtrlに表示
552        def RefleshTw(self):
553                self.recentPage.Reflesh()       
554       
555        def OnUpdate(self, event):
556                self.SetStatusBar(u"新着取得中...")
557                self.RefleshTw()
558       
559        def OnUpdate2(self, event):
560                self.SetStatusBar(u"新着取得中...")
561                self.recentPage.CheckUpdate()
562                self.replyPage.CheckUpdate()
563                self.directPage.CheckUpdate()
564                self.SetNowTime2StatusBar()
565
566        def OnReplyUpdate(self, event):
567       
568                self.SetStatusBar(u"Reply取得中")
569                self.replyPage.Reflesh()
570
571        def OnDMUpdate(self, event):
572               
573                self.SetStatusBar(u"DM取得中...")
574                self.directPage.Reflesh()
575
576        def SetStatusBar(self,str):
577               
578                sb = wx.GetApp().GetTopWindow().GetStatusBar()
579                sb.SetStatusText(str)
580        def SetNowTime2StatusBar(self):
581                #現在時刻を表示
582                from time import localtime, strftime
583                nowtime = strftime("%H:%M:%S", localtime())
584                sb = wx.GetApp().GetTopWindow().GetStatusBar()
585                sb.SetStatusText(nowtime+u"に更新しました")
586       
587        def myKeyHandler(self,evt):
588                print evt.GetKeyCode(),
589                if self.selectedRow != -1:
590                        if evt.GetKeyCode() in [ord('k'),ord('K'),wx.WXK_UP]:
591                                print ('up')
592                                if self.selectedRow > 0:
593                                        self.MoveList(self.selectedRow-1)
594                        if evt.GetKeyCode() in [ord('j'),ord('J'),wx.WXK_DOWN]:
595                                print ('down')
596                                if self.selectedRow < self.list.GetItemCount()-1:
597                                        self.MoveList(self.selectedRow+1)
598                        if evt.GetKeyCode() in [ord('h'),ord('H'),wx.WXK_LEFT]:
599                                print ('left')
600                                leftcol = self.GetPrevItem(self.selectedRow)
601                                if leftcol != -1:
602                                        self.MoveList(leftcol)
603                        if evt.GetKeyCode() in [ord('l'),ord('L'),wx.WXK_RIGHT]:
604                                print ('right')
605                                rightcol = self.GetNextItem(self.selectedRow)
606                                if rightcol != -1:
607                                        self.MoveList(rightcol)
608                        if evt.GetKeyCode() in [ord('s'),ord('S')]:
609                                print "S"
610                                #id = self.hiddenDataList[self.selectedRow][0]
611                                #print "fav"+id
612                                #self.tw.createFavorite(id)
613                #print list.
614                if evt.GetKeyCode() in [ord('q'), ord('Q')]:
615                        wx.Exit()
616
617        """Web上の画像を読み込みImageListとして保持する。
618                既に読まれてるなら読みに行かない。ImageList['URL']という形で格納
619        """
620        def GetImageListElement(self,url):
621                unicodeUrl = url
622                if self.imageList.has_key(unicodeUrl):
623                        if self.imageList[unicodeUrl] == "":
624                                return None
625                        #self.userIcon.SetBitmap(self.imageList[unicodeUrl].ConvertToBitmap())
626                        return self.imageList[unicodeUrl]
627                else:
628                        self.imageList[unicodeUrl] = ""
629                        self.WebImage2StringIO(url,unicodeUrl)
630                return None
631       
632        # Web上の画像を引っ張ってくる
633        def WebImage2StringIO(self,url,result):
634                import urllib,sys
635
636                try:
637                        urlName = urllib.quote_plus(url,':;/')
638                #print "url:"+url
639                #print "urlName:"+urlName
640                        t = ImageGetFrame(urlName,self.WebImageCallback,result,self.imageThreadLock)
641                        t.start()
642                except:
643                        print "WebImage2StringIO.error", sys.exc_info()[0]
644
645
646        def WebImageCallback(self,imageData,result):
647                from cStringIO import StringIO
648                image_pil = Image.open(StringIO(imageData))
649                image_pil.thumbnail((64,64))
650
651                image_wx = wx.EmptyImage(image_pil.size[0],image_pil.size[1])
652                image_wx.SetData(image_pil.convert('RGB').tostring())
653                #self.userIcon.SetBitmap(image_wx.ConvertToBitmap())
654                self.imageList[result] = image_wx
655                #except:
656                #       print "Error:URL not valid!:"+url
657                #return null   
658       
659        # 画像を読み込んで表示のテスト
660        def SetImage(self,imageName):
661                bmp = self.userIcon
662                image = self.GetImageListElement(imageName)
663                if image != None:
664                        bmp.SetBitmap(image.ConvertToBitmap())
665       
666        def addUser2Inputbox(self,user):
667               
668                text = self.text
669                value = text.GetValue()
670               
671                flag = 1
672                import re
673                print value + ":" + user
674                if re.search(user,value):
675                        flag = 0
676
677                if flag == 1:
678                        text.SetValue(user+value)
679
680        def getNotebook(self):
681                return self.notebook
682
683# startup application.
684if __name__=='__main__':
685        app = wx.App(False)
686        frame = MainFrame()
687        app.SetTopWindow(frame)
688        frame.Show()
689        app.MainLoop()
Note: See TracBrowser for help on using the browser.