"""TOC (i.e. AIM) support for Instance Messenger."""
import string, re
from twisted.protocols import toc
from twisted.im.locals import ONLINE, OFFLINE, AWAY
from twisted.internet import defer, reactor, protocol
from twisted.internet.defer import succeed
import basesupport, interfaces, locals
def dehtml(text):
text=string.replace(text,"<br>","\n")
text=string.replace(text,"<BR>","\n")
text=string.replace(text,"<Br>","\n") text=string.replace(text,"<bR>","\n")
text=re.sub('<.*?>','',text)
text=string.replace(text,'>','>')
text=string.replace(text,'<','<')
text=string.replace(text,'&','&')
text=string.replace(text,' ',' ')
text=string.replace(text,'"','"')
return text
def html(text):
text=string.replace(text,'"','"')
text=string.replace(text,'&','&')
text=string.replace(text,'<','<')
text=string.replace(text,'>','>')
text=string.replace(text,"\n","<br>")
return '<font color="#000000" back="#ffffff" size=3>%s</font>'%text
class TOCPerson(basesupport.AbstractPerson):
def isOnline(self):
return self.status != OFFLINE
def getStatus(self):
return self.status
def getIdleTime(self):
return str(self.idletime)
def setStatusAndIdle(self, status, idletime):
if self.account.client is None:
raise locals.OfflineError
self.status = status
self.idletime = idletime
self.account.client.chat.getContactsList().setContactStatus(self)
def sendMessage(self, text, meta=None):
if self.account.client is None:
raise locals.OfflineError
if meta:
if meta.get("style", None) == "emote":
text="* "+text+"* "
self.account.client.say(self.name,html(text))
return succeed(text)
class TOCGroup(basesupport.AbstractGroup):
__implements__ = (interfaces.IGroup,)
def __init__(self, name, tocAccount):
basesupport.AbstractGroup.__init__(self, name, tocAccount)
self.roomID = self.client.roomID[self.name]
def sendGroupMessage(self, text, meta=None):
if self.account.client is None:
raise locals.OfflineError
if meta:
if meta.get("style", None) == "emote":
text="* "+text+"* "
self.account.client.chat_say(self.roomID,html(text))
return succeed(text)
def leave(self):
if self.account.client is None:
raise locals.OfflineError
self.account.client.chat_leave(self.roomID)
class TOCProto(basesupport.AbstractClientMixin, toc.TOCClient):
def __init__(self, account, chatui, logonDeferred):
toc.TOCClient.__init__(self, account.username, account.password)
basesupport.AbstractClientMixin.__init__(self, account, chatui,
logonDeferred)
self.roomID = {}
self.roomIDreverse = {}
def _debug(self, m):
pass
def getGroupConversation(self, name, hide=0):
return self.chat.getGroupConversation(
self.chat.getGroup(name, self), hide)
def addContact(self, name):
self.add_buddy([name])
if not self._buddylist.has_key('TwistedIM'):
self._buddylist['TwistedIM'] = []
if name in self._buddylist['TwistedIM']:
return
self._buddylist['TwistedIM'].append(name)
self.set_config(self._config_mode, self._buddylist, self._permit, self._deny)
def getPerson(self,name):
return self.chat.getPerson(name, self)
def onLine(self):
self.account._isOnline = 1
def gotConfig(self, mode, buddylist, permit, deny):
self._config_mode = mode
self._buddylist = buddylist
self._permit = permit
self._deny = deny
if permit:
self._debug('adding permit')
self.add_permit(permit)
if deny:
self._debug('adding deny')
self.add_deny(deny)
clist=[]
for k in buddylist.keys():
self.add_buddy(buddylist[k])
for name in buddylist[k]:
self.getPerson(name).setStatusAndIdle(OFFLINE, '--')
self.signon()
name = None
def tocNICK(self,data):
if not self.name:
print 'Waiting for second NICK', data
self.name=data[0]
self.accountName = '%s (TOC)' % self.name
self.chat.getContactsList()
else:
print 'reregistering...?', data
self.name=data[0]
if self._logonDeferred is not None:
self._logonDeferred.callback(self)
def hearError(self, code, args):
print '*** TOC ERROR ***', repr(code), repr(args)
def hearWarning(self, newamount, username):
print '*** TOC WARNING ***', repr(newamount), repr(username)
def hearMessage(self,username,message,autoreply):
if autoreply:
message='<AUTO-REPLY>: '+message
self.chat.getConversation(self.getPerson(username)
).showMessage(dehtml(message))
def updateBuddy(self,username,online,evilness,signontime,idletime,userclass,away):
if away:
status=AWAY
elif online:
status=ONLINE
else:
status=OFFLINE
self.getPerson(username).setStatusAndIdle(status, idletime)
def chatJoined(self, roomid, roomname, users):
self.roomID[roomname]=roomid
self.roomIDreverse[roomid]=roomname
self.getGroupConversation(roomname).setGroupMembers(users)
def chatUpdate(self,roomid,member,inroom):
group=self.roomIDreverse[roomid]
if inroom:
self.getGroupConversation(group).memberJoined(member)
else:
self.getGroupConversation(group).memberLeft(member)
def chatHearMessage(self, roomid, username, message):
if toc.normalize(username) == toc.normalize(self.name):
return group=self.roomIDreverse[roomid]
self.getGroupConversation(group).showGroupMessage(username, dehtml(message))
def chatHearWhisper(self, roomid, username, message):
print '*** user whispered *** ', roomid, username, message
def chatInvited(self, roomid, roomname, username, message):
print '*** user invited us to chat *** ',roomid, roomname, username, message
def chatLeft(self, roomid):
group=self.roomIDreverse[roomid]
self.getGroupConversation(group,1)
del self.roomID[group]
del self.roomIDreverse[roomid]
def rvousProposal(self,type,cookie,user,vip,port,**kw):
print '*** rendezvous. ***', type, cookie, user, vip, port, kw
def receiveBytes(self, user, file, chunk, sofar, total):
print '*** File transfer! ***', user, file, chunk, sofar, total
def joinGroup(self,name):
self.chat_join(4,toc.normalize(name))
class TOCAccount(basesupport.AbstractAccount):
__implements__ = (interfaces.IAccount,)
gatewayType = "AIM (TOC)"
_groupFactory = TOCGroup
_personFactory = TOCPerson
def _startLogOn(self, chatui):
logonDeferred = defer.Deferred()
cc = protocol.ClientCreator(reactor, TOCProto, self, chatui,
logonDeferred)
d = cc.connectTCP(self.host, self.port)
d.addErrback(logonDeferred.errback)
return logonDeferred