| OLD | NEW |
| (Empty) |
| 1 # Copyright (c) 2001-2004 Twisted Matrix Laboratories. | |
| 2 # See LICENSE for details. | |
| 3 | |
| 4 | |
| 5 """IRC support for Instance Messenger.""" | |
| 6 | |
| 7 import string | |
| 8 | |
| 9 from twisted.words.protocols import irc | |
| 10 from twisted.words.im.locals import ONLINE | |
| 11 from twisted.internet import defer, reactor, protocol | |
| 12 from twisted.internet.defer import succeed | |
| 13 from twisted.words.im import basesupport, interfaces, locals | |
| 14 from zope.interface import implements | |
| 15 | |
| 16 | |
| 17 class IRCPerson(basesupport.AbstractPerson): | |
| 18 | |
| 19 def imperson_whois(self): | |
| 20 if self.account.client is None: | |
| 21 raise locals.OfflineError | |
| 22 self.account.client.sendLine("WHOIS %s" % self.name) | |
| 23 | |
| 24 ### interface impl | |
| 25 | |
| 26 def isOnline(self): | |
| 27 return ONLINE | |
| 28 | |
| 29 def getStatus(self): | |
| 30 return ONLINE | |
| 31 | |
| 32 def setStatus(self,status): | |
| 33 self.status=status | |
| 34 self.chat.getContactsList().setContactStatus(self) | |
| 35 | |
| 36 def sendMessage(self, text, meta=None): | |
| 37 if self.account.client is None: | |
| 38 raise locals.OfflineError | |
| 39 for line in string.split(text, '\n'): | |
| 40 if meta and meta.get("style", None) == "emote": | |
| 41 self.account.client.ctcpMakeQuery(self.name,[('ACTION', line)]) | |
| 42 else: | |
| 43 self.account.client.msg(self.name, line) | |
| 44 return succeed(text) | |
| 45 | |
| 46 class IRCGroup(basesupport.AbstractGroup): | |
| 47 | |
| 48 implements(interfaces.IGroup) | |
| 49 | |
| 50 def imgroup_testAction(self): | |
| 51 print 'action test!' | |
| 52 | |
| 53 def imtarget_kick(self, target): | |
| 54 if self.account.client is None: | |
| 55 raise locals.OfflineError | |
| 56 reason = "for great justice!" | |
| 57 self.account.client.sendLine("KICK #%s %s :%s" % ( | |
| 58 self.name, target.name, reason)) | |
| 59 | |
| 60 ### Interface Implementation | |
| 61 | |
| 62 def setTopic(self, topic): | |
| 63 if self.account.client is None: | |
| 64 raise locals.OfflineError | |
| 65 self.account.client.topic(self.name, topic) | |
| 66 | |
| 67 def sendGroupMessage(self, text, meta={}): | |
| 68 if self.account.client is None: | |
| 69 raise locals.OfflineError | |
| 70 if meta and meta.get("style", None) == "emote": | |
| 71 self.account.client.me(self.name,text) | |
| 72 return succeed(text) | |
| 73 #standard shmandard, clients don't support plain escaped newlines! | |
| 74 for line in string.split(text, '\n'): | |
| 75 self.account.client.say(self.name, line) | |
| 76 return succeed(text) | |
| 77 | |
| 78 def leave(self): | |
| 79 if self.account.client is None: | |
| 80 raise locals.OfflineError | |
| 81 self.account.client.leave(self.name) | |
| 82 self.account.client.getGroupConversation(self.name,1) | |
| 83 | |
| 84 | |
| 85 class IRCProto(basesupport.AbstractClientMixin, irc.IRCClient): | |
| 86 def __init__(self, account, chatui, logonDeferred=None): | |
| 87 basesupport.AbstractClientMixin.__init__(self, account, chatui, | |
| 88 logonDeferred) | |
| 89 self._namreplies={} | |
| 90 self._ingroups={} | |
| 91 self._groups={} | |
| 92 self._topics={} | |
| 93 | |
| 94 def getGroupConversation(self, name, hide=0): | |
| 95 name=string.lower(name) | |
| 96 return self.chat.getGroupConversation(self.chat.getGroup(name, self), | |
| 97 stayHidden=hide) | |
| 98 | |
| 99 def getPerson(self,name): | |
| 100 return self.chat.getPerson(name, self) | |
| 101 | |
| 102 def connectionMade(self): | |
| 103 # XXX: Why do I duplicate code in IRCClient.register? | |
| 104 try: | |
| 105 print 'connection made on irc service!?', self | |
| 106 if self.account.password: | |
| 107 self.sendLine("PASS :%s" % self.account.password) | |
| 108 self.setNick(self.account.username) | |
| 109 self.sendLine("USER %s foo bar :Twisted-IM user" % (self.nickname,)) | |
| 110 for channel in self.account.channels: | |
| 111 self.joinGroup(channel) | |
| 112 self.account._isOnline=1 | |
| 113 print 'uh, registering irc acct' | |
| 114 if self._logonDeferred is not None: | |
| 115 self._logonDeferred.callback(self) | |
| 116 self.chat.getContactsList() | |
| 117 except: | |
| 118 import traceback | |
| 119 traceback.print_exc() | |
| 120 | |
| 121 def setNick(self,nick): | |
| 122 self.name=nick | |
| 123 self.accountName="%s (IRC)"%nick | |
| 124 irc.IRCClient.setNick(self,nick) | |
| 125 | |
| 126 def kickedFrom(self, channel, kicker, message): | |
| 127 """Called when I am kicked from a channel. | |
| 128 """ | |
| 129 print 'ono i was kicked', channel, kicker, message | |
| 130 return self.chat.getGroupConversation( | |
| 131 self.chat.getGroup(channel[1:], self), 1) | |
| 132 | |
| 133 def userKicked(self, kickee, channel, kicker, message): | |
| 134 print 'whew somebody else', kickee, channel, kicker, message | |
| 135 | |
| 136 def noticed(self, username, channel, message): | |
| 137 self.privmsg(username, channel, message, {"dontAutoRespond": 1}) | |
| 138 | |
| 139 def privmsg(self, username, channel, message, metadata=None): | |
| 140 if metadata is None: | |
| 141 metadata = {} | |
| 142 username=string.split(username,'!',1)[0] | |
| 143 if username==self.name: return | |
| 144 if channel[0]=='#': | |
| 145 group=channel[1:] | |
| 146 self.getGroupConversation(group).showGroupMessage(username, message,
metadata) | |
| 147 return | |
| 148 self.chat.getConversation(self.getPerson(username)).showMessage(message,
metadata) | |
| 149 | |
| 150 def action(self,username,channel,emote): | |
| 151 username=string.split(username,'!',1)[0] | |
| 152 if username==self.name: return | |
| 153 meta={'style':'emote'} | |
| 154 if channel[0]=='#': | |
| 155 group=channel[1:] | |
| 156 self.getGroupConversation(group).showGroupMessage(username, emote, m
eta) | |
| 157 return | |
| 158 self.chat.getConversation(self.getPerson(username)).showMessage(emote,me
ta) | |
| 159 | |
| 160 def irc_RPL_NAMREPLY(self,prefix,params): | |
| 161 """ | |
| 162 RPL_NAMREPLY | |
| 163 >> NAMES #bnl | |
| 164 << :Arlington.VA.US.Undernet.Org 353 z3p = #bnl :pSwede Dan-- SkOyg AG | |
| 165 """ | |
| 166 group=string.lower(params[2][1:]) | |
| 167 users=string.split(params[3]) | |
| 168 for ui in range(len(users)): | |
| 169 while users[ui][0] in ["@","+"]: # channel modes | |
| 170 users[ui]=users[ui][1:] | |
| 171 if not self._namreplies.has_key(group): | |
| 172 self._namreplies[group]=[] | |
| 173 self._namreplies[group].extend(users) | |
| 174 for nickname in users: | |
| 175 try: | |
| 176 self._ingroups[nickname].append(group) | |
| 177 except: | |
| 178 self._ingroups[nickname]=[group] | |
| 179 | |
| 180 def irc_RPL_ENDOFNAMES(self,prefix,params): | |
| 181 group=params[1][1:] | |
| 182 self.getGroupConversation(group).setGroupMembers(self._namreplies[string
.lower(group)]) | |
| 183 del self._namreplies[string.lower(group)] | |
| 184 | |
| 185 def irc_RPL_TOPIC(self,prefix,params): | |
| 186 self._topics[params[1][1:]]=params[2] | |
| 187 | |
| 188 def irc_333(self,prefix,params): | |
| 189 group=params[1][1:] | |
| 190 self.getGroupConversation(group).setTopic(self._topics[group],params[2]) | |
| 191 del self._topics[group] | |
| 192 | |
| 193 def irc_TOPIC(self,prefix,params): | |
| 194 nickname = string.split(prefix,"!")[0] | |
| 195 group = params[0][1:] | |
| 196 topic = params[1] | |
| 197 self.getGroupConversation(group).setTopic(topic,nickname) | |
| 198 | |
| 199 def irc_JOIN(self,prefix,params): | |
| 200 nickname=string.split(prefix,"!")[0] | |
| 201 group=string.lower(params[0][1:]) | |
| 202 if nickname!=self.nickname: | |
| 203 try: | |
| 204 self._ingroups[nickname].append(group) | |
| 205 except: | |
| 206 self._ingroups[nickname]=[group] | |
| 207 self.getGroupConversation(group).memberJoined(nickname) | |
| 208 | |
| 209 def irc_PART(self,prefix,params): | |
| 210 nickname=string.split(prefix,"!")[0] | |
| 211 group=string.lower(params[0][1:]) | |
| 212 if nickname!=self.nickname: | |
| 213 if group in self._ingroups[nickname]: | |
| 214 self._ingroups[nickname].remove(group) | |
| 215 self.getGroupConversation(group).memberLeft(nickname) | |
| 216 else: | |
| 217 print "%s left %s, but wasn't in the room."%(nickname,group) | |
| 218 | |
| 219 def irc_QUIT(self,prefix,params): | |
| 220 nickname=string.split(prefix,"!")[0] | |
| 221 if self._ingroups.has_key(nickname): | |
| 222 for group in self._ingroups[nickname]: | |
| 223 self.getGroupConversation(group).memberLeft(nickname) | |
| 224 self._ingroups[nickname]=[] | |
| 225 else: | |
| 226 print '*** WARNING: ingroups had no such key %s' % nickname | |
| 227 | |
| 228 def irc_NICK(self, prefix, params): | |
| 229 fromNick = string.split(prefix, "!")[0] | |
| 230 toNick = params[0] | |
| 231 if not self._ingroups.has_key(fromNick): | |
| 232 print "%s changed nick to %s. But she's not in any groups!?" % (from
Nick, toNick) | |
| 233 return | |
| 234 for group in self._ingroups[fromNick]: | |
| 235 self.getGroupConversation(group).memberChangedNick(fromNick, toNick) | |
| 236 self._ingroups[toNick] = self._ingroups[fromNick] | |
| 237 del self._ingroups[fromNick] | |
| 238 | |
| 239 def irc_unknown(self, prefix, command, params): | |
| 240 print "unknown message from IRCserver. prefix: %s, command: %s, params:
%s" % (prefix, command, params) | |
| 241 | |
| 242 # GTKIM calls | |
| 243 def joinGroup(self,name): | |
| 244 self.join(name) | |
| 245 self.getGroupConversation(name) | |
| 246 | |
| 247 class IRCAccount(basesupport.AbstractAccount): | |
| 248 implements(interfaces.IAccount) | |
| 249 gatewayType = "IRC" | |
| 250 | |
| 251 _groupFactory = IRCGroup | |
| 252 _personFactory = IRCPerson | |
| 253 | |
| 254 def __init__(self, accountName, autoLogin, username, password, host, port, | |
| 255 channels=''): | |
| 256 basesupport.AbstractAccount.__init__(self, accountName, autoLogin, | |
| 257 username, password, host, port) | |
| 258 self.channels = map(string.strip,string.split(channels,',')) | |
| 259 if self.channels == ['']: | |
| 260 self.channels = [] | |
| 261 | |
| 262 def _startLogOn(self, chatui): | |
| 263 logonDeferred = defer.Deferred() | |
| 264 cc = protocol.ClientCreator(reactor, IRCProto, self, chatui, | |
| 265 logonDeferred) | |
| 266 d = cc.connectTCP(self.host, self.port) | |
| 267 d.addErrback(logonDeferred.errback) | |
| 268 return logonDeferred | |
| OLD | NEW |