OLD | NEW |
| (Empty) |
1 # Copyright (c) 2001-2004 Twisted Matrix Laboratories. | |
2 # See LICENSE for details. | |
3 | |
4 | |
5 """TOC (i.e. AIM) support for Instance Messenger.""" | |
6 | |
7 # System Imports | |
8 import string, re | |
9 from zope.interface import implements | |
10 | |
11 # Twisted Imports | |
12 from twisted.words.protocols import toc | |
13 from twisted.words.im.locals import ONLINE, OFFLINE, AWAY | |
14 from twisted.internet import defer, reactor, protocol | |
15 from twisted.internet.defer import succeed | |
16 | |
17 # Sibling Imports | |
18 from twisted.words.im import basesupport, interfaces, locals | |
19 | |
20 def dehtml(text): | |
21 text=string.replace(text,"<br>","\n") | |
22 text=string.replace(text,"<BR>","\n") | |
23 text=string.replace(text,"<Br>","\n") # XXX make this a regexp | |
24 text=string.replace(text,"<bR>","\n") | |
25 text=re.sub('<.*?>','',text) | |
26 text=string.replace(text,'>','>') | |
27 text=string.replace(text,'<','<') | |
28 text=string.replace(text,'&','&') | |
29 text=string.replace(text,' ',' ') | |
30 text=string.replace(text,'"','"') | |
31 return text | |
32 | |
33 def html(text): | |
34 text=string.replace(text,'"','"') | |
35 text=string.replace(text,'&','&') | |
36 text=string.replace(text,'<','<') | |
37 text=string.replace(text,'>','>') | |
38 text=string.replace(text,"\n","<br>") | |
39 return '<font color="#000000" back="#ffffff" size=3>%s</font>'%text | |
40 | |
41 class TOCPerson(basesupport.AbstractPerson): | |
42 def isOnline(self): | |
43 return self.status != OFFLINE | |
44 | |
45 def getStatus(self): | |
46 return self.status | |
47 | |
48 def getIdleTime(self): | |
49 return str(self.idletime) | |
50 | |
51 def setStatusAndIdle(self, status, idletime): | |
52 if self.account.client is None: | |
53 raise locals.OfflineError | |
54 self.status = status | |
55 self.idletime = idletime | |
56 self.account.client.chat.getContactsList().setContactStatus(self) | |
57 | |
58 def sendMessage(self, text, meta=None): | |
59 if self.account.client is None: | |
60 raise locals.OfflineError | |
61 if meta: | |
62 if meta.get("style", None) == "emote": | |
63 text="* "+text+"* " | |
64 self.account.client.say(self.name,html(text)) | |
65 return succeed(text) | |
66 | |
67 class TOCGroup(basesupport.AbstractGroup): | |
68 implements(interfaces.IGroup) | |
69 def __init__(self, name, tocAccount): | |
70 basesupport.AbstractGroup.__init__(self, name, tocAccount) | |
71 self.roomID = self.client.roomID[self.name] | |
72 | |
73 def sendGroupMessage(self, text, meta=None): | |
74 if self.account.client is None: | |
75 raise locals.OfflineError | |
76 if meta: | |
77 if meta.get("style", None) == "emote": | |
78 text="* "+text+"* " | |
79 self.account.client.chat_say(self.roomID,html(text)) | |
80 return succeed(text) | |
81 | |
82 def leave(self): | |
83 if self.account.client is None: | |
84 raise locals.OfflineError | |
85 self.account.client.chat_leave(self.roomID) | |
86 | |
87 | |
88 class TOCProto(basesupport.AbstractClientMixin, toc.TOCClient): | |
89 def __init__(self, account, chatui, logonDeferred): | |
90 toc.TOCClient.__init__(self, account.username, account.password) | |
91 basesupport.AbstractClientMixin.__init__(self, account, chatui, | |
92 logonDeferred) | |
93 self.roomID = {} | |
94 self.roomIDreverse = {} | |
95 | |
96 def _debug(self, m): | |
97 pass #print '<toc debug>', repr(m) | |
98 | |
99 def getGroupConversation(self, name, hide=0): | |
100 return self.chat.getGroupConversation( | |
101 self.chat.getGroup(name, self), hide) | |
102 | |
103 def addContact(self, name): | |
104 self.add_buddy([name]) | |
105 if not self._buddylist.has_key('TwistedIM'): | |
106 self._buddylist['TwistedIM'] = [] | |
107 if name in self._buddylist['TwistedIM']: | |
108 # whoops, don't add again | |
109 return | |
110 self._buddylist['TwistedIM'].append(name) | |
111 self.set_config(self._config_mode, self._buddylist, self._permit, self._
deny) | |
112 | |
113 def getPerson(self,name): | |
114 return self.chat.getPerson(name, self) | |
115 | |
116 def onLine(self): | |
117 self.account._isOnline = 1 | |
118 #print '$$!&*$&!(@$*& TOC ONLINE *!#@&$(!*%&' | |
119 | |
120 def gotConfig(self, mode, buddylist, permit, deny): | |
121 #print 'got toc config', repr(mode), repr(buddylist), repr(permit), repr
(deny) | |
122 self._config_mode = mode | |
123 self._buddylist = buddylist | |
124 self._permit = permit | |
125 self._deny = deny | |
126 if permit: | |
127 self._debug('adding permit') | |
128 self.add_permit(permit) | |
129 if deny: | |
130 self._debug('adding deny') | |
131 self.add_deny(deny) | |
132 clist=[] | |
133 for k in buddylist.keys(): | |
134 self.add_buddy(buddylist[k]) | |
135 for name in buddylist[k]: | |
136 self.getPerson(name).setStatusAndIdle(OFFLINE, '--') | |
137 self.signon() | |
138 name = None | |
139 def tocNICK(self,data): | |
140 if not self.name: | |
141 print 'Waiting for second NICK', data | |
142 self.name=data[0] | |
143 self.accountName = '%s (TOC)' % self.name | |
144 self.chat.getContactsList() | |
145 else: | |
146 print 'reregistering...?', data | |
147 self.name=data[0] | |
148 # self.accountName = "%s (TOC)"%data[0] | |
149 if self._logonDeferred is not None: | |
150 self._logonDeferred.callback(self) | |
151 self._logonDeferred = None | |
152 | |
153 ### Error Messages | |
154 def hearError(self, code, args): | |
155 print '*** TOC ERROR ***', repr(code), repr(args) | |
156 def hearWarning(self, newamount, username): | |
157 print '*** TOC WARNING ***', repr(newamount), repr(username) | |
158 ### Buddy Messages | |
159 def hearMessage(self,username,message,autoreply): | |
160 if autoreply: | |
161 message='<AUTO-REPLY>: '+message | |
162 self.chat.getConversation(self.getPerson(username) | |
163 ).showMessage(dehtml(message)) | |
164 def updateBuddy(self,username,online,evilness,signontime,idletime,userclass,
away): | |
165 if away: | |
166 status=AWAY | |
167 elif online: | |
168 status=ONLINE | |
169 else: | |
170 status=OFFLINE | |
171 self.getPerson(username).setStatusAndIdle(status, idletime) | |
172 | |
173 ### Group Chat | |
174 def chatJoined(self, roomid, roomname, users): | |
175 self.roomID[roomname]=roomid | |
176 self.roomIDreverse[roomid]=roomname | |
177 self.getGroupConversation(roomname).setGroupMembers(users) | |
178 def chatUpdate(self,roomid,member,inroom): | |
179 group=self.roomIDreverse[roomid] | |
180 if inroom: | |
181 self.getGroupConversation(group).memberJoined(member) | |
182 else: | |
183 self.getGroupConversation(group).memberLeft(member) | |
184 def chatHearMessage(self, roomid, username, message): | |
185 if toc.normalize(username) == toc.normalize(self.name): | |
186 return # ignore the message | |
187 group=self.roomIDreverse[roomid] | |
188 self.getGroupConversation(group).showGroupMessage(username, dehtml(messa
ge)) | |
189 def chatHearWhisper(self, roomid, username, message): | |
190 print '*** user whispered *** ', roomid, username, message | |
191 def chatInvited(self, roomid, roomname, username, message): | |
192 print '*** user invited us to chat *** ',roomid, roomname, username, mes
sage | |
193 def chatLeft(self, roomid): | |
194 group=self.roomIDreverse[roomid] | |
195 self.getGroupConversation(group,1) | |
196 del self.roomID[group] | |
197 del self.roomIDreverse[roomid] | |
198 def rvousProposal(self,type,cookie,user,vip,port,**kw): | |
199 print '*** rendezvous. ***', type, cookie, user, vip, port, kw | |
200 def receiveBytes(self, user, file, chunk, sofar, total): | |
201 print '*** File transfer! ***', user, file, chunk, sofar, total | |
202 | |
203 def joinGroup(self,name): | |
204 self.chat_join(4,toc.normalize(name)) | |
205 | |
206 class TOCAccount(basesupport.AbstractAccount): | |
207 implements(interfaces.IAccount) | |
208 gatewayType = "AIM (TOC)" | |
209 | |
210 _groupFactory = TOCGroup | |
211 _personFactory = TOCPerson | |
212 | |
213 def _startLogOn(self, chatui): | |
214 logonDeferred = defer.Deferred() | |
215 cc = protocol.ClientCreator(reactor, TOCProto, self, chatui, | |
216 logonDeferred) | |
217 d = cc.connectTCP(self.host, self.port) | |
218 d.addErrback(logonDeferred.errback) | |
219 return logonDeferred | |
220 | |
OLD | NEW |