| 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 |