]> code.delx.au - pymsnt/blob - src/groupchat.py
Groupchat timeout is configurable.
[pymsnt] / src / groupchat.py
1 # Copyright 2004-2005 James Bunton <james@delx.cjb.net>
2 # Licensed for distribution under the GPL version 2, check COPYING for details
3
4 import utils
5 from twisted.internet import reactor
6 from tlib.xmlw import Element
7 from debug import LogEvent, INFO, WARN, ERROR
8 import disco
9 import jabw
10 import config
11 import lang
12 import string
13 import time
14
15
16 class BaseGroupchat:
17 """ A class to map a groupchat from a legacy service back to the Jabber user """
18 def __init__(self, session, resource, ID=None):
19 self.session = session
20 self.session.groupchats.append(self)
21 self.nick = resource
22 if(ID):
23 self.ID = ID
24 self.session.pytrans.reserveID(self.ID)
25 else:
26 self.ID = self.session.pytrans.makeID()
27
28 self.ready = False # Is True only after the user has joined
29 self.messageBuffer = []
30 self.contacts = []
31
32 self.checkTimer = reactor.callLater(float(config.groupchatTimeout), self.checkUserJoined, None)
33
34 LogEvent(INFO, self.roomJID())
35
36 def removeMe(self):
37 """ Cleanly removes the object """
38 self.session.groupchats.remove(self)
39 if(self.ready):
40 self.session.sendPresence(to=self.user(), fro=self.roomJID() + "/" + self.nick, ptype="unavailable")
41 self.ready = False
42 self.session = None
43
44 if(self.checkTimer and not self.checkTimer.called):
45 self.checkTimer.cancel()
46 self.checkTimer = None
47
48 LogEvent(INFO, self.roomJID())
49
50 def roomJID(self):
51 """ Returns the room JID """
52 return self.ID + "@" + config.jid
53
54 def user(self):
55 """ Returns the full JID of the Jabber user in this groupchat """
56 jid = self.session.jabberID
57 # FIXME, this probably won't work with multiple resources (unless you're using the highest resource)
58 # if(self.resource):
59 # jid += "/" + self.resource
60 return jid
61
62 def checkUserJoined(self, ignored=None):
63 self.checkTimer = None
64 if(not self.ready):
65 LogEvent(INFO, self.roomJID(), "User hasn't joined after two minutes. Removing them from the room.")
66
67 text = []
68 text.append(lang.get(self.session.lang).groupchatFailJoin1 % (self.roomJID()))
69 for contact in self.contacts:
70 text.append("\t%s" % (contact))
71 text.append("")
72 text.append(lang.get(self.session.lang).groupchatFailJoin2)
73 text.append("")
74 for (source, message, timestamp) in self.messageBuffer:
75 if(source):
76 text.append("%s says: %s" % (source, message))
77 else:
78 text.append(message)
79
80 body = string.join(text, "\n")
81
82 self.session.sendMessage(to=self.user(), fro=config.jid, body=body)
83
84 self.removeMe()
85
86 def sendUserInvite(self, fro):
87 """ Sends the invitation out to the Jabber user to join this room """
88 LogEvent(INFO, self.roomJID(), "Sending invitation to user")
89 el = Element((None, "message"))
90 el.attributes["from"] = fro
91 el.attributes["to"] = self.user()
92 body = el.addElement("body")
93 text = lang.get(self.session.lang).groupchatInvite % (self.roomJID())
94 body.addContent(text)
95 x = el.addElement("x")
96 x.attributes["jid"] = self.roomJID()
97 x.attributes["xmlns"] = disco.XCONFERENCE
98 self.session.pytrans.send(el)
99
100 def userJoined(self, nick):
101 # Send any buffered messages
102 self.nick = nick
103 if(not self.nick):
104 self.nick = self.session.username
105 self.session.sendPresence(to=self.user(), fro=self.roomJID() + "/" + self.nick)
106 if(not self.ready):
107 LogEvent(INFO, self.roomJID())
108 self.ready = True
109 for (source, text, timestamp) in self.messageBuffer:
110 self.messageReceived(source, text, timestamp)
111 self.messageBuffer = None
112 for contact in self.contacts:
113 self.contactPresenceChanged(contact)
114
115 def contactJoined(self, contact):
116 if(self.contacts.count(contact) == 0):
117 self.contacts.append(contact)
118 LogEvent(INFO, self.roomJID())
119 self.contactPresenceChanged(contact)
120 self.messageReceived(None, "%s has joined the conference." % (contact))
121
122 def contactLeft(self, contact):
123 if(self.contacts.count(contact) > 0):
124 self.contacts.remove(contact)
125 LogEvent(INFO, self.roomJID())
126 self.contactPresenceChanged(contact, ptype="unavailable")
127 self.messageReceived(None, "%s has left the conference." % (contact))
128
129 def messageReceived(self, source, message, timestamp=None):
130 if(not self.ready):
131 timestamp = time.strftime("%Y%m%dT%H:%M:%S")
132 self.messageBuffer.append((source, message, timestamp))
133 else:
134 self.session.pytrans.statistics.stats["MessageCount"] += 1
135 fro = self.roomJID()
136 if(source):
137 fro += "/" + source
138 LogEvent(INFO, self.roomJID())
139 self.session.sendMessage(to=self.user(), fro=fro, body=message, mtype="groupchat", delay=timestamp)
140
141 def contactPresenceChanged(self, contact, ptype=None):
142 if(self.session):
143 fro = self.roomJID() + "/" + contact
144 self.session.sendPresence(to=self.user(), fro=fro, ptype=ptype)
145
146 def sendMessage(self, text, noerror):
147 LogEvent(INFO, self.roomJID())
148 self.messageReceived(self.nick, text)
149 self.sendLegacyMessage(text, noerror)
150
151 def sendLegacyMessage(self, text):
152 """ Reimplement this to send the packet to the legacy service """
153 pass
154
155 def sendContactInvite(self, contact):
156 """ Reimplement this to send the packet to the legacy service """
157 pass
158
159