comparison src/plugins/plugin_misc_quiz.py @ 587:952322b1d490

Remove trailing whitespaces.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Fri, 18 Jan 2013 17:55:34 +0100
parents ca13633d3b6b
children beaf6bec2fcd
comparison
equal deleted inserted replaced
586:6a718ede8be1 587:952322b1d490
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # -*- coding: utf-8 -*- 2 # -*- coding: utf-8 -*-
3 3
4 """ 4 """
5 SAT plugin for managing Quiz game 5 SAT plugin for managing Quiz game
6 Copyright (C) 2009, 2010, 2011, 2012, 2013 Jérôme Poisson (goffi@goffi.org) 6 Copyright (C) 2009, 2010, 2011, 2012, 2013 Jérôme Poisson (goffi@goffi.org)
7 7
8 This program is free software: you can redistribute it and/or modify 8 This program is free software: you can redistribute it and/or modify
9 it under the terms of the GNU Affero General Public License as published by 9 it under the terms of the GNU Affero General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or 10 the Free Software Foundation, either version 3 of the License, or
131 """Convert a game data dict to domish element""" 131 """Convert a game data dict to domish element"""
132 game_data_elt = domish.Element((None,'game_data')) 132 game_data_elt = domish.Element((None,'game_data'))
133 for data in game_data: 133 for data in game_data:
134 data_elt = domish.Element((None,data)) 134 data_elt = domish.Element((None,data))
135 data_elt.addContent(game_data[data]) 135 data_elt.addContent(game_data[data])
136 game_data_elt.addChild(data_elt) 136 game_data_elt.addChild(data_elt)
137 return game_data_elt 137 return game_data_elt
138 138
139 def __xml_to_game_data(self, game_data_elt): 139 def __xml_to_game_data(self, game_data_elt):
140 """Convert a domish element with game_data to a dict""" 140 """Convert a domish element with game_data to a dict"""
141 game_data = {} 141 game_data = {}
159 @param game_data: data of the game""" 159 @param game_data: data of the game"""
160 players_data = game_data['players_data'] 160 players_data = game_data['players_data']
161 score = {} 161 score = {}
162 for player in game_data['players']: 162 for player in game_data['players']:
163 score[player] = players_data[player]['score'] 163 score[player] = players_data[player]['score']
164 164
165 answer_result_elt = domish.Element((None,'answer_result')) 165 answer_result_elt = domish.Element((None,'answer_result'))
166 answer_result_elt['player'] = player_answering 166 answer_result_elt['player'] = player_answering
167 answer_result_elt['good_answer'] = str(good_answer) 167 answer_result_elt['good_answer'] = str(good_answer)
168 168
169 for player in score: 169 for player in score:
170 score_elt = domish.Element((None,"score")) 170 score_elt = domish.Element((None,"score"))
171 score_elt['player'] = player 171 score_elt['player'] = player
172 score_elt['score'] = str(score[player]) 172 score_elt['score'] = str(score[player])
173 answer_result_elt.addChild(score_elt) 173 answer_result_elt.addChild(score_elt)
174 174
175 return answer_result_elt 175 return answer_result_elt
176 176
177 def __create_started_elt(self, players): 177 def __create_started_elt(self, players):
178 """Create a game_started domish element""" 178 """Create a game_started domish element"""
179 started_elt = domish.Element((None,'started')) 179 started_elt = domish.Element((None,'started'))
191 question_elt = domish.Element((None,'question')) 191 question_elt = domish.Element((None,'question'))
192 question_elt['id'] = question_id 192 question_elt['id'] = question_id
193 question_elt['timer'] = str(timer) 193 question_elt['timer'] = str(timer)
194 question_elt.addContent(question) 194 question_elt.addContent(question)
195 return question_elt 195 return question_elt
196 196
197 def __start_play(self, room_jid, game_data, profile): 197 def __start_play(self, room_jid, game_data, profile):
198 """Start the game (tell to the first player after dealer to play""" 198 """Start the game (tell to the first player after dealer to play"""
199 game_data['stage'] = "play" 199 game_data['stage'] = "play"
200 next_player_idx = game_data['current_player'] = (game_data['init_player'] + 1) % len(game_data['players']) #the player after the dealer start 200 next_player_idx = game_data['current_player'] = (game_data['init_player'] + 1) % len(game_data['players']) #the player after the dealer start
201 game_data['first_player'] = next_player = game_data['players'][next_player_idx] 201 game_data['first_player'] = next_player = game_data['players'][next_player_idx]
229 def quizRoomJoined(room): 229 def quizRoomJoined(room):
230 _room = room.occupantJID.userhostJID() 230 _room = room.occupantJID.userhostJID()
231 for player in players: 231 for player in players:
232 self.host.plugins["XEP-0249"].invite(jid.JID(player), room.occupantJID.userhostJID(), {"game":"Quiz"}, profile) 232 self.host.plugins["XEP-0249"].invite(jid.JID(player), room.occupantJID.userhostJID(), {"game":"Quiz"}, profile)
233 self.waiting_inv[_room] = (time(), players) #TODO: remove invitation waiting for too long, using the time data 233 self.waiting_inv[_room] = (time(), players) #TODO: remove invitation waiting for too long, using the time data
234 234
235 def after_init(ignore): 235 def after_init(ignore):
236 room_name = "sat_quiz_%s" % self.host.plugins["XEP-0045"].getUniqueName(profile_key) 236 room_name = "sat_quiz_%s" % self.host.plugins["XEP-0045"].getUniqueName(profile_key)
237 print "\n\n===> room_name:", room_name 237 print "\n\n===> room_name:", room_name
238 muc_service = None 238 muc_service = None
239 for service in self.host.memory.getServerServiceEntities("conference", "text", profile): 239 for service in self.host.memory.getServerServiceEntities("conference", "text", profile):
240 if not ".irc." in service.userhost(): 240 if not ".irc." in service.userhost():
241 #FIXME: 241 #FIXME:
242 #This awfull ugly hack is here to avoid an issue with openfire: the irc gateway 242 #This awfull ugly hack is here to avoid an issue with openfire: the irc gateway
243 #use "conference/text" identity (instead of "conference/irc"), there is certainly a better way 243 #use "conference/text" identity (instead of "conference/irc"), there is certainly a better way
244 #to manage this, but this hack fill do it for test purpose 244 #to manage this, but this hack fill do it for test purpose
245 muc_service = service 245 muc_service = service
246 break 246 break
247 if not muc_service: 247 if not muc_service:
248 error(_("Can't find a MUC service")) 248 error(_("Can't find a MUC service"))
249 return 249 return
250 250
251 _jid, xmlstream = self.host.getJidNStream(profile) 251 _jid, xmlstream = self.host.getJidNStream(profile)
252 d = self.host.plugins["XEP-0045"].join(jid.JID("%s@%s" % (room_name, muc_service.userhost())), _jid.user, {}, profile).addCallback(quizRoomJoined) 252 d = self.host.plugins["XEP-0045"].join(jid.JID("%s@%s" % (room_name, muc_service.userhost())), _jid.user, {}, profile).addCallback(quizRoomJoined)
253 253
254 client = self.host.getClient(profile) 254 client = self.host.getClient(profile)
255 if not client: 255 if not client:
353 mess.firstChildElement().addChild(self.__ask_question(game_data['question_id'], u"Quel est l'âge du capitaine ?", timer)) 353 mess.firstChildElement().addChild(self.__ask_question(game_data['question_id'], u"Quel est l'âge du capitaine ?", timer))
354 self.host.profiles[profile].xmlstream.send(mess) 354 self.host.profiles[profile].xmlstream.send(mess)
355 game_data["timer"] = reactor.callLater(timer, self.timerExpired, room_jid, profile) 355 game_data["timer"] = reactor.callLater(timer, self.timerExpired, room_jid, profile)
356 game_data["time_left"] = None 356 game_data["time_left"] = None
357 357
358 def checkAnswer(self, room_jid, player, answer, profile): 358 def checkAnswer(self, room_jid, player, answer, profile):
359 """Check if the answer given is right""" 359 """Check if the answer given is right"""
360 game_data = self.games[room_jid.userhost()] 360 game_data = self.games[room_jid.userhost()]
361 players_data = game_data['players_data'] 361 players_data = game_data['players_data']
362 good_answer = game_data['question_id'] == "1" and answer=="42" 362 good_answer = game_data['question_id'] == "1" and answer=="42"
363 players_data[player]['score'] += 1 if good_answer else -1 363 players_data[player]['score'] += 1 if good_answer else -1
364 players_data[player]['score'] = min(9, max(0, players_data[player]['score'])) 364 players_data[player]['score'] = min(9, max(0, players_data[player]['score']))
365 365
366 mess = self.createGameElt(room_jid) 366 mess = self.createGameElt(room_jid)
367 mess.firstChildElement().addChild(self.__answer_result(player, good_answer, game_data)) 367 mess.firstChildElement().addChild(self.__answer_result(player, good_answer, game_data))
368 self.host.profiles[profile].xmlstream.send(mess) 368 self.host.profiles[profile].xmlstream.send(mess)
369 369
370 if good_answer: 370 if good_answer:
371 reactor.callLater(4, self.askQuestion, room_jid, profile) 371 reactor.callLater(4, self.askQuestion, room_jid, profile)
372 else: 372 else:
373 reactor.callLater(4, self.restartTimer, room_jid, profile) 373 reactor.callLater(4, self.restartTimer, room_jid, profile)
374 374
380 players_data = game_data['players_data'] 380 players_data = game_data['players_data']
381 game_data['stage'] = "init" 381 game_data['stage'] = "init"
382 382
383 for player in players: 383 for player in players:
384 players_data[player]['game_score'] = 0 384 players_data[player]['game_score'] = 0
385 385
386 new_game_data = {"instructions": _(u"""Bienvenue dans cette partie rapide de quizz, le premier à atteindre le score de 9 remporte le jeu 386 new_game_data = {"instructions": _(u"""Bienvenue dans cette partie rapide de quizz, le premier à atteindre le score de 9 remporte le jeu
387 387
388 Attention, tu es prêt ?""")} 388 Attention, tu es prêt ?""")}
389 389
390 mess = self.createGameElt(room_jid) 390 mess = self.createGameElt(room_jid)
391 mess.firstChildElement().addChild(self.__game_data_to_xml(new_game_data)) 391 mess.firstChildElement().addChild(self.__game_data_to_xml(new_game_data))
392 self.host.profiles[profile].xmlstream.send(mess) 392 self.host.profiles[profile].xmlstream.send(mess)
393 reactor.callLater(10, self.askQuestion, room_jid, profile) 393 reactor.callLater(10, self.askQuestion, room_jid, profile)
394 394
395 def quiz_game_cmd(self, mess_elt, profile): 395 def quiz_game_cmd(self, mess_elt, profile):
396 from_jid = jid.JID(mess_elt['from']) 396 from_jid = jid.JID(mess_elt['from'])
397 room_jid = jid.JID(from_jid.userhost()) 397 room_jid = jid.JID(from_jid.userhost())
398 game_elt = mess_elt.firstChildElement() 398 game_elt = mess_elt.firstChildElement()
399 game_data = self.games[room_jid.userhost()] 399 game_data = self.games[room_jid.userhost()]
400 players_data = game_data['players_data'] 400 players_data = game_data['players_data']
401 401
402 for elt in game_elt.elements(): 402 for elt in game_elt.elements():
403 403
404 if elt.name == 'started': #new game created 404 if elt.name == 'started': #new game created
405 players = [] 405 players = []
406 for player in elt.elements(): 406 for player in elt.elements():
407 players.append(unicode(player)) 407 players.append(unicode(player))
408 self.host.bridge.quizGameStarted(room_jid.userhost(), from_jid.full(), players, profile) 408 self.host.bridge.quizGameStarted(room_jid.userhost(), from_jid.full(), players, profile)
409 409
410 elif elt.name == 'player_ready': #ready to play 410 elif elt.name == 'player_ready': #ready to play
411 player = elt['player'] 411 player = elt['player']
412 status = self.games[room_jid.userhost()]['status'] 412 status = self.games[room_jid.userhost()]['status']
413 nb_players = len(self.games[room_jid.userhost()]['players']) 413 nb_players = len(self.games[room_jid.userhost()]['players'])
414 status[player] = 'ready' 414 status[player] = 'ready'
416 if status.values().count('ready') == nb_players: #everybody is ready, we can start the game 416 if status.values().count('ready') == nb_players: #everybody is ready, we can start the game
417 self.newGame(room_jid, profile) 417 self.newGame(room_jid, profile)
418 418
419 elif elt.name == 'game_data': 419 elif elt.name == 'game_data':
420 self.host.bridge.quizGameNew(room_jid.userhost(), self.__xml_to_game_data(elt), profile) 420 self.host.bridge.quizGameNew(room_jid.userhost(), self.__xml_to_game_data(elt), profile)
421 421
422 elif elt.name == 'question': #A question is asked 422 elif elt.name == 'question': #A question is asked
423 self.host.bridge.quizGameQuestion(room_jid.userhost(), elt["id"], unicode(elt), int(elt["timer"]), profile ) 423 self.host.bridge.quizGameQuestion(room_jid.userhost(), elt["id"], unicode(elt), int(elt["timer"]), profile )
424 424
425 elif elt.name == 'player_answer': 425 elif elt.name == 'player_answer':
426 player = elt['player'] 426 player = elt['player']
427 pause = game_data['stage'] == 'question' #we pause the game only if we are have a question at the moment 427 pause = game_data['stage'] == 'question' #we pause the game only if we are have a question at the moment
428 #we first send a buzzer message 428 #we first send a buzzer message
429 mess = self.createGameElt(room_jid) 429 mess = self.createGameElt(room_jid)
430 buzzer_elt = mess.firstChildElement().addElement('player_buzzed') 430 buzzer_elt = mess.firstChildElement().addElement('player_buzzed')
431 buzzer_elt['player'] = player 431 buzzer_elt['player'] = player
432 buzzer_elt['pause'] = str(pause) 432 buzzer_elt['pause'] = str(pause)
433 self.host.profiles[profile].xmlstream.send(mess) 433 self.host.profiles[profile].xmlstream.send(mess)
434 if pause: 434 if pause:
435 self.pauseTimer(room_jid) 435 self.pauseTimer(room_jid)
436 #and we send the player answer 436 #and we send the player answer
437 mess = self.createGameElt(room_jid) 437 mess = self.createGameElt(room_jid)
440 say_elt['player'] = player 440 say_elt['player'] = player
441 say_elt.addContent(_answer) 441 say_elt.addContent(_answer)
442 say_elt['delay'] = "3" 442 say_elt['delay'] = "3"
443 reactor.callLater(2, self.host.profiles[profile].xmlstream.send, mess) 443 reactor.callLater(2, self.host.profiles[profile].xmlstream.send, mess)
444 reactor.callLater(6, self.checkAnswer, room_jid, player, _answer, profile=profile) 444 reactor.callLater(6, self.checkAnswer, room_jid, player, _answer, profile=profile)
445 445
446 elif elt.name == 'player_buzzed': 446 elif elt.name == 'player_buzzed':
447 self.host.bridge.quizGamePlayerBuzzed(room_jid.userhost(), elt["player"], elt['pause'] == str(True), profile) 447 self.host.bridge.quizGamePlayerBuzzed(room_jid.userhost(), elt["player"], elt['pause'] == str(True), profile)
448 448
449 elif elt.name == 'player_says': 449 elif elt.name == 'player_says':
450 self.host.bridge.quizGamePlayerSays(room_jid.userhost(), elt["player"], unicode(elt), int(elt["delay"]), profile) 450 self.host.bridge.quizGamePlayerSays(room_jid.userhost(), elt["player"], unicode(elt), int(elt["delay"]), profile)
451 451
452 elif elt.name == 'answer_result': 452 elif elt.name == 'answer_result':
453 player, good_answer, score = self.__answer_result_to_signal_args(elt) 453 player, good_answer, score = self.__answer_result_to_signal_args(elt)
454 self.host.bridge.quizGameAnswerResult(room_jid.userhost(), player, good_answer, score, profile) 454 self.host.bridge.quizGameAnswerResult(room_jid.userhost(), player, good_answer, score, profile)
455 455
456 elif elt.name == 'timer_expired': 456 elif elt.name == 'timer_expired':
457 self.host.bridge.quizGameTimerExpired(room_jid.userhost(), profile) 457 self.host.bridge.quizGameTimerExpired(room_jid.userhost(), profile)
458 458
459 elif elt.name == 'timer_restarted': 459 elif elt.name == 'timer_restarted':
460 self.host.bridge.quizGameTimerRestarted(room_jid.userhost(), int(elt['time_left']), profile) 460 self.host.bridge.quizGameTimerRestarted(room_jid.userhost(), int(elt['time_left']), profile)
461 461
462 else: 462 else:
463 error (_('Unmanaged game element: %s') % elt.name) 463 error (_('Unmanaged game element: %s') % elt.name)
464 464
465 def getHandler(self, profile): 465 def getHandler(self, profile):
466 return QuizGameHandler(self) 466 return QuizGameHandler(self)
467 467
468 class QuizGameHandler (XMPPHandler): 468 class QuizGameHandler (XMPPHandler):
469 implements(iwokkel.IDisco) 469 implements(iwokkel.IDisco)
470 470
471 def __init__(self, plugin_parent): 471 def __init__(self, plugin_parent):
472 self.plugin_parent = plugin_parent 472 self.plugin_parent = plugin_parent
473 self.host = plugin_parent.host 473 self.host = plugin_parent.host
474 474
475 def connectionInitialized(self): 475 def connectionInitialized(self):