Changeset 137
- Timestamp:
- 04/26/08 16:07:44 (7 months ago)
- Files:
-
- randomchat/randomchat.py (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
randomchat/randomchat.py
r129 r137 1 #!/usr/bin/python 2 # -*- coding: UTF-8 -*- 3 4 import xmpp 5 import random 6 import sha 7 import time 1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 4 #import xmpp 5 from xmpp import (NS_DISCO_ITEMS, NS_DISCO_INFO, NS_REGISTER, NS_MUC, JID, \ 6 Error, Message, Presence, Node, Component, browser) 7 8 from random import choice as random_choice 9 from sha import sha 10 from time import time 8 11 9 12 import config 10 13 11 NS_MUC_USER = xmpp.NS_MUC+'#user'14 NS_MUC_USER = NS_MUC + '#user' 12 15 13 16 def db_connect(config): 14 17 if config.DB_MODULE == 'sqlite': 15 from pysqlite2 import dbapi2 as sqlite 16 return sqlite.connect(config.SQLITE_DB) 17 else: 18 raise Exception("Incorrect DB module") 18 try: 19 import sqlite3 as sqlite 20 except ImportError: 21 try: 22 from pysqlite2 import dbapi2 as sqlite 23 except ImportError: 24 raise ImportError('Incorrect DB module') 25 26 return sqlite.connect(config.SQLITE_DB) 27 28 19 29 20 30 class Users: … … 26 36 def read_users(self): 27 37 cursor = self.db.cursor() 28 cursor.execute("SELECT jid FROM randomchat WHERE 1") 29 user = cursor.fetchone() 30 while user: 38 cursor.execute('SELECT jid FROM randomchat') 39 users = cursor.fetchall() 40 41 for user in users: 31 42 self.users_list[user[0]] = False 32 user = cursor.fetchone() 43 33 44 cursor.close() 34 45 … … 37 48 38 49 def add_user(self, jid): 39 self.db.execute( "INSERT INTO randomchat (jid) VALUES (?)", (jid,))50 self.db.execute('INSERT INTO randomchat (jid) VALUES (?)', (jid,)) 40 51 self.db.commit() 41 52 self.users_list[jid] = False 42 53 43 54 def remove_user(self, jid): 44 self.db.execute( "DELETE FROM randomchat WHERE jid=?", (jid,))55 self.db.execute('DELETE FROM randomchat WHERE jid=?', (jid,)) 45 56 self.db.commit() 46 57 del self.users_list[jid] … … 49 60 user = jid.getStripped() 50 61 users = [jid for jid in self.users_list.keys() if self.users_list[jid]] 51 #if we have only one participant don't start a chat, except when the user is not in this list (so in fact we have two participants) 62 63 # If we have only one participant don't start a chat, except when the 64 # user is not in this list (so in fact we have two participants). 65 52 66 if (len(users) < 2 and user in users) or len(users) < 1: 53 67 return None 54 68 else: 55 other = random .choice(users)69 other = random_choice(users) 56 70 while other == user: 57 other = random.choice(users) 71 other = random_choice(users) 72 58 73 return other 59 74 … … 61 76 if not self.has_user(jid): 62 77 return 78 63 79 self.users_list[jid] = availability 64 80 … … 72 88 self.jid = selfjid 73 89 self.con = con 74 self.users = {} # contains the users list as keys 75 self.rooms = {} # contains the rooms name as keys and the full JID of the participants as values 90 91 # Contains the users list as keys. 92 self.users = {} 93 94 # Contains the rooms name as keys and the full JID of the participants 95 # as values. 96 self.rooms = {} 76 97 77 98 def message_handler(self, con, msg): … … 79 100 frm_str = frm.getStripped() 80 101 room = msg.getTo().getNode() 81 room_jid = room+'@'+self.jid 82 if not frm_str in self.users or not self.users[frm_str].has_key(room) or self.users[frm_str][room]['nick'] is None: 83 con.send(xmpp.Error(msg, 'item-not-found')) 102 room_jid = room + '@' + self.jid 103 104 if not frm_str in self.users or not self.users[frm_str].has_key(room) \ 105 or not self.users[frm_str][room]['nick']: 106 con.send(Error(msg, 'item-not-found')) 84 107 return 85 108 if msg.getType() != 'groupchat': 86 con.send( xmpp.Error(msg, 'bad-format'))87 88 message = xmpp.Message(body = msg.getBody(), typ='groupchat')109 con.send(Error(msg, 'bad-format')) 110 111 message = Message(body = msg.getBody(), typ='groupchat') 89 112 for jid in self.rooms[room]: 90 113 message.setTo(jid) 91 114 if jid == frm: 92 message.setFrom(room_jid+'/'+self.users[frm_str][room]['nick']) 115 message.setFrom(room_jid + '/' + 116 self.users[frm_str][room]['nick']) 93 117 else: 94 message.setFrom(room_jid+'/'+config.NICK_GUEST) 118 message.setFrom(room_jid + '/' + config.NICK_GUEST) 119 95 120 con.send(message) 96 121 … … 99 124 if not self.users.has_key(jid.getStripped()): 100 125 continue 126 101 127 user = self.users[jid.getStripped()][room] 102 destroy = xmpp.Presence(to = jid, frm = room+'@'+self.jid+'/'+user['nick'], typ = 'unavailable', payload = [ 103 xmpp.Node('x', attrs={'xmlns': xmpp.NS_MUC+'#user'}, payload = [ 104 xmpp.Node('item', attrs={'affiliation': 'none', 'role': 'none'}), 105 xmpp.Node('destroy',payload = [ 106 xmpp.Node('reason', payload = ['Votre interlocuteur a quitté le salon'] ) 128 destroy = Presence(to=jid, frm=room + 129 '@' + 130 self.jid +'/' + 131 user['nick'], typ='unavailable', 132 payload = 133 [ 134 Node('x', attrs={'xmlns': NS_MUC+'#user'}, payload = 135 [ 136 Node('item', attrs={'affiliation': 'none', 'role': 'none'}), 137 Node('destroy',payload = 138 [ 139 Node('reason', 140 payload = ['Votre interlocuteur a quitté le salon'] ) 107 141 ]) 108 142 ]) 109 143 ]) 144 110 145 self.con.send(destroy) 111 146 del self.users[jid.getStripped()] 147 112 148 del self.rooms[room] 113 114 149 115 150 def presence_handler(self, con, prs): … … 117 152 frm_str = frm.getStripped() 118 153 room = prs.getTo().getNode() 119 room_jid = room +'@'+self.jid154 room_jid = room + '@' + self.jid 120 155 nick = prs.getTo().getResource() 156 121 157 if nick == '': 122 con.send(xmpp.Error(prs, 'bad-format')) 123 return 124 if not self.users.has_key(frm_str) or not self.users[frm_str].has_key(room): 125 con.send(xmpp.Error(prs, 'item-not-found')) 158 con.send(Error(prs, 'bad-format')) 159 return 160 161 if not self.users.has_key(frm_str) \ 162 or not self.users[frm_str].has_key(room): 163 con.send(Error(prs, 'item-not-found')) 126 164 return 127 165 128 166 user = self.users[frm_str][room] 129 130 167 print user['nick'] 131 if user['nick'] is not None and prs.getType() == 'available': # discard presence if the user is already in the chat 168 169 # Discard presence if the user is already in the chat. 170 if user['nick'] is not None and prs.getType() == 'available': 132 171 return 133 172 134 173 if user['nick'] is None: 135 presence = xmpp.Presence(show = 'chat', payload = [xmpp.Node('x', attrs = {'xmlns': NS_MUC_USER})]) 174 presence = Presence(show='chat', payload=[ 175 Node('x', attrs = {'xmlns': NS_MUC_USER})]) 176 136 177 x = presence.getTag('x') 137 x.addChild('item', attrs = {'affiliation': 'member', 'role': 'participant'}) 178 x.addChild('item', attrs = {'affiliation': 'member', 179 'role': 'participant'}) 180 138 181 if len(self.rooms[room]) == 1: 139 182 presence.setTo(frm) 140 presence.setFrom(room_jid+'/'+config.NICK_GUEST) 141 con.send(presence) # sends the presence of the other participant to the current participant 183 presence.setFrom(room_jid + '/' + config.NICK_GUEST) 184 185 # Sends the presence of the other participant to 186 # the current participant. 187 con.send(presence) 142 188 presence.setTo(self.rooms[room][0]) 143 con.send(presence) # does the opposite 189 190 # Does the opposite. 191 con.send(presence) 192 144 193 presence.setTo(frm) 145 presence.setFrom(room_jid +'/'+nick)194 presence.setFrom(room_jid + '/' + nick) 146 195 x.addChild('status', attrs = {'code': '110'}) 147 con.send(presence) # send the user self presence 148 # add the user in the room 196 197 # Send the user self presence. 198 con.send(presence) 199 200 # Add the user in the room. 149 201 user['nick'] = nick 150 202 self.rooms[room].append(frm) 151 else: # if the user is already in, and we are this far, that means that we got a presence type!= available, we assume that he has left the chat 203 204 # If the user is already in, and we are this far, that means that we 205 # got a presence type != available, we assume that he has left the chat. 206 else: 152 207 self.destroy_room(room) 153 154 208 155 209 def invite(self, room, jid): 156 invite = xmpp.Message(to = jid, frm = room+'@'+self.jid, body = 'Vous avez été invité dans le salon '+room+'@'+self.jid, payload = [ 157 xmpp.Node('x', attrs={'xmlns': xmpp.NS_MUC+'#user'}, payload = [ 158 xmpp.Node('invite', attrs={'from': room+'@'+self.jid}, payload = [ 159 xmpp.Node('reason', payload = ['Random chat !'] ) 160 ]) 161 ]) 162 ]) 210 invite = Message(to=jid, frm=room + '@' + self.jid, 211 body = 'Vous avez été invité dans le salon ' + room + '@' + self.jid, 212 payload = 213 [ 214 Node('x', attrs={'xmlns': NS_MUC+'#user'}, payload = 215 [ 216 Node('invite', attrs={'from': room+'@'+self.jid}, payload = 217 [ 218 Node('reason', payload=['Random chat !'] ) 219 ]) 220 ]) 221 ]) 222 163 223 self.con.send(invite) 164 224 165 225 def invite_users(self, jid1, jid2): 166 room = sha.sha(str(jid1)+str(jid2)+str(time.time())).hexdigest() 226 room = sha(str(jid1) + str(jid2) + str(time())).hexdigest() 227 167 228 self.rooms[room] = [] 168 229 jid1_str = jid1.getStripped() 169 230 jid2_str = jid2.getStripped() 231 170 232 if not self.users.has_key(jid1_str): 171 233 self.users[jid1_str]={} 172 234 self.users[jid1_str][room] = {'other': jid2_str, 'nick': None} 235 173 236 if not self.users.has_key(jid2_str): 174 237 self.users[jid2_str]={} 238 175 239 self.users[jid2_str][room] = {'other': jid1_str, 'nick': None} 176 240 self.invite(room,jid1) 177 241 self.invite(room,jid2) 178 #TODO add a timeout and destroy the room if neither of them has joined the room 242 # TODO: add a timeout and destroy the room if neither 243 # of them has joined the room 179 244 180 245 … … 183 248 def __init__(self, users, jid, pwd, server, port=5347): 184 249 self.users = users 185 self.con = xmpp.Component(server, port)250 self.con = Component(server, port) 186 251 self.jid = jid 187 252 self.muc = MUC(jid, self.con) 253 188 254 if not self.con.connect(): 189 255 raise Exception('Unable to connect to %s:%s' % (server, port)) … … 191 257 raise Exception('Unable to authenticate as %s' % (jid)) 192 258 193 # register the handlers259 # Register XMPP handlers. 194 260 self.con.RegisterHandler('presence', self.presence_handler) 195 self.con.RegisterHandler('presence', self.subscribe_handler, 'subscribe') 196 self.con.RegisterHandler('presence', self.subscribed_handler, 'subscribed') 197 self.con.RegisterHandler('presence', self.unsubscribe_handler, 'unsubscribe') 198 self.con.RegisterHandler('presence', self.unsubscribed_handler, 'unsubscribed') 261 self.con.RegisterHandler('presence', self.subscribe_handler, 262 'subscribe') 263 self.con.RegisterHandler('presence', self.subscribed_handler, 264 'subscribed') 265 self.con.RegisterHandler('presence', self.unsubscribe_handler, 266 'unsubscribe') 267 self.con.RegisterHandler('presence', self.unsubscribed_handler, 268 'unsubscribed') 199 269 self.con.RegisterHandler('message', self.message_handler) 200 270 201 b =xmpp.browser.Browser()271 b = browser.Browser() 202 272 b.PlugIn(self.con) 203 items=[] 204 info={'ids':[{'category': 'conference', 'type': 'text', 'name': 'Random Chat'}], 'features':[xmpp.NS_REGISTER, xmpp.NS_DISCO_INFO, xmpp.NS_DISCO_ITEMS]} 205 b.setDiscoHandler({'items':items,'info':info}) 206 273 items = [] 274 info = {'ids': [{'category': 'conference', 275 'type': 'text', 276 'name': 'Random Chat'}], 277 'features': [NS_REGISTER, NS_DISCO_INFO, NS_DISCO_ITEMS]} 278 279 b.setDiscoHandler({'items': items,'info': info}) 207 280 208 281 self.send_probes() 209 210 282 211 283 while 1: 212 284 self.con.Process(10) 213 285 214 215 286 def subscribe_handler(self, con, prs): 216 287 user = prs.getFrom().getStripped() 288 217 289 if not self.users.has_user(user): 218 self.con.send(xmpp.Presence(to = prs.getFrom(), frm = self.jid, typ = 'subscribe')) 219 self.con.send(xmpp.Presence(to = prs.getFrom(), frm = self.jid, typ = 'subscribed')) 290 self.con.send(Presence(to=prs.getFrom(), frm=self.jid, 291 typ='subscribe')) 292 self.con.send(Presence(to=prs.getFrom(), frm=self.jid, 293 typ='subscribed')) 220 294 221 295 def subscribed_handler(self, con, prs): … … 225 299 226 300 def unsubscribe_handler(self, con, prs): 227 self.con.send(xmpp.Presence(to = prs.getFrom(), frm = self.jid, typ = 'unsubscribe')) 301 self.con.send(Presence(to=prs.getFrom(), frm=self.jid, 302 typ='unsubscribe')) 228 303 229 304 def unsubscribed_handler(self, con, prs): 230 305 user = prs.getFrom().getStripped() 231 306 self.users.remove_user(user) 232 self.con.send(xmpp.Presence(to = prs.getFrom(), frm = self.jid, typ = 'unsubscribed')) 307 self.con.send(Presence(to=prs.getFrom(), frm=self.jid, 308 typ='unsubscribed')) 233 309 234 310 def presence_handler(self, con, prs): 235 311 if prs.getType() == 'error': 236 312 return 313 237 314 if prs.getTo().getNode() != '': 238 315 self.muc.presence_handler(con, prs) 239 316 return 317 240 318 if prs.getType() is None and prs.getShow() == 'chat': 241 #available to chat 319 320 # Available to chat. 242 321 self.users.update_availability(prs.getFrom().getStripped(), True) 243 con.send( xmpp.Presence(frm = self.jid, to = prs.getFrom(), show ='chat'))322 con.send(Presence(frm=self.jid, to=prs.getFrom(), show='chat')) 244 323 else: 245 324 self.users.update_availability(prs.getFrom().getStripped(), False) 246 325 if prs.getType() is None: 247 con.send( xmpp.Presence(frm = self.jid, to =prs.getFrom()))326 con.send(Presence(frm=self.jid, to=prs.getFrom())) 248 327 else: 249 con.send( xmpp.Presence(frm = self.jid, to = prs.getFrom(), typ = 'unavailable'))250 328 con.send(Presence(frm=self.jid, to=prs.getFrom(), 329 typ='unavailable')) 251 330 252 331 def message_handler(self, con, msg): 253 if msg.getTo().getNode() != '':332 if msg.getTo().getNode(): 254 333 self.muc.message_handler(con, msg) 255 334 return 335 256 336 if not self.init_chat(msg.getFrom()): 257 con.send(xmpp.Message(to = msg.getFrom(), frm = msg.getTo(), body = 'Pas de participant trouvé', typ = msg.getType())) 337 con.send(Message(to=msg.getFrom(), frm=msg.getTo(), 338 body='Pas de participant trouvé', 339 typ=msg.getType())) 258 340 259 341 def init_chat(self, jid): 260 342 other_jid = self.users.get_chat_partner(jid) 261 if other_jid is None: 343 344 if not other_jid: 262 345 return False 263 self.muc.invite_users(jid, xmpp.JID(other_jid)) 346 347 self.muc.invite_users(jid, JID(other_jid)) 264 348 return True 265 349 266 350 def send_probes(self): 267 351 for jid in self.users.jid_list(): 268 self.con.send( xmpp.Presence(to = jid, frm =self.jid, typ='probe'))352 self.con.send(Presence(to=jid, frm=self.jid, typ='probe')) 269 353 270 354
