Mercurial > libervia-backend
comparison src/plugins/plugin_misc_radiocol.py @ 717:358018c5c398
plugins (games): more factorization and flexibility for launching and joining games:
- "MUC user joined", "MUC user left" and class XMPPHandler are managed directly in RoomGame
- renamed __init__ parameters 'player_init_data' to 'player_init' and 'options' to 'game_init'
- pass the players list in radiocol method 'createGame' and signal 'radiocolStarted' (needed for invitation system and for UI players identification)
- added some parameters to manage who can invite, who can join, who to wait for... managed with check***Auth methods
- joining a game that is already launched may be possible, regarding these parameters and the invitation list
- leave and join a game again is partly managed: new tarot round is launched, we should keep playing the same round instead
author | souliane <souliane@mailoo.org> |
---|---|
date | Thu, 21 Nov 2013 15:49:53 +0100 |
parents | ecc5a5b34ee1 |
children | 074970227bc0 |
comparison
equal
deleted
inserted
replaced
716:30eb49e4e05d | 717:358018c5c398 |
---|---|
20 from logging import debug, info, warning, error | 20 from logging import debug, info, warning, error |
21 from twisted.words.xish import domish | 21 from twisted.words.xish import domish |
22 from twisted.internet import reactor | 22 from twisted.internet import reactor |
23 from twisted.words.protocols.jabber import jid | 23 from twisted.words.protocols.jabber import jid |
24 | 24 |
25 from wokkel import disco, iwokkel | |
26 | |
27 from zope.interface import implements | |
28 | |
29 import os.path | 25 import os.path |
30 from os import unlink | 26 from os import unlink |
31 from mutagen.oggvorbis import OggVorbis, OggVorbisHeaderError | 27 from mutagen.oggvorbis import OggVorbis, OggVorbisHeaderError |
32 from sat.tools.plugins.games import RoomGame | 28 from sat.tools.plugins.games import RoomGame |
33 try: | 29 |
34 from twisted.words.protocols.xmlstream import XMPPHandler | 30 |
35 except ImportError: | |
36 from wokkel.subprotocols import XMPPHandler | |
37 | |
38 MESSAGE = '/message' | |
39 NC_RADIOCOL = 'http://www.goffi.org/protocol/radiocol' | 31 NC_RADIOCOL = 'http://www.goffi.org/protocol/radiocol' |
40 RADIOC_TAG = 'radiocol' | 32 RADIOC_TAG = 'radiocol' |
41 RADIOC_REQUEST = MESSAGE + '/' + RADIOC_TAG + '[@xmlns="' + NC_RADIOCOL + '"]' | |
42 | 33 |
43 PLUGIN_INFO = { | 34 PLUGIN_INFO = { |
44 "name": "Radio collective plugin", | 35 "name": "Radio collective plugin", |
45 "import_name": "Radiocol", | 36 "import_name": "Radiocol", |
46 "type": "Exp", | 37 "type": "Exp", |
57 class Radiocol(RoomGame): | 48 class Radiocol(RoomGame): |
58 | 49 |
59 def __init__(self, host): | 50 def __init__(self, host): |
60 info(_("Radio collective initialization")) | 51 info(_("Radio collective initialization")) |
61 RoomGame.__init__(self, host, PLUGIN_INFO, (NC_RADIOCOL, RADIOC_TAG), | 52 RoomGame.__init__(self, host, PLUGIN_INFO, (NC_RADIOCOL, RADIOC_TAG), |
62 options={'queue': [], 'upload': True, 'playing': False, 'to_delete': {}}) | 53 game_init={'queue': [], 'upload': True, 'playing': False, 'to_delete': {}}) |
63 self.host = host | 54 self.host = host |
64 host.bridge.addMethod("radiocolLaunch", ".plugin", in_sign='asss', out_sign='', method=self.prepareRoom) | 55 host.bridge.addMethod("radiocolLaunch", ".plugin", in_sign='asss', out_sign='', method=self.prepareRoom) |
65 host.bridge.addMethod("radiocolCreate", ".plugin", in_sign='ss', out_sign='', method=self.createCollectiveGame) | 56 host.bridge.addMethod("radiocolCreate", ".plugin", in_sign='sass', out_sign='', method=self.createGame) |
66 host.bridge.addMethod("radiocolSongAdded", ".plugin", in_sign='sss', out_sign='', method=self.radiocolSongAdded) | 57 host.bridge.addMethod("radiocolSongAdded", ".plugin", in_sign='sss', out_sign='', method=self.radiocolSongAdded) |
67 host.bridge.addSignal("radiocolStarted", ".plugin", signature='sss') # room_jid, referee, profile | 58 host.bridge.addSignal("radiocolPlayers", ".plugin", signature='ssass') # room_jid, referee, players, profile |
59 host.bridge.addSignal("radiocolStarted", ".plugin", signature='ssass') # room_jid, referee, players, profile | |
68 host.bridge.addSignal("radiocolSongRejected", ".plugin", signature='sss') # room_jid, reason, profile | 60 host.bridge.addSignal("radiocolSongRejected", ".plugin", signature='sss') # room_jid, reason, profile |
69 host.bridge.addSignal("radiocolPreload", ".plugin", signature='ssssss') # room_jid, filename, title, artist, album, profile | 61 host.bridge.addSignal("radiocolPreload", ".plugin", signature='ssssss') # room_jid, filename, title, artist, album, profile |
70 host.bridge.addSignal("radiocolPlay", ".plugin", signature='sss') # room_jid, filename, profile | 62 host.bridge.addSignal("radiocolPlay", ".plugin", signature='sss') # room_jid, filename, profile |
71 host.bridge.addSignal("radiocolNoUpload", ".plugin", signature='ss') # room_jid, profile | 63 host.bridge.addSignal("radiocolNoUpload", ".plugin", signature='ss') # room_jid, profile |
72 host.bridge.addSignal("radiocolUploadOk", ".plugin", signature='ss') # room_jid, profile | 64 host.bridge.addSignal("radiocolUploadOk", ".plugin", signature='ss') # room_jid, profile |
73 host.trigger.add("MUC user joined", self.userJoinedTrigger) | |
74 | 65 |
75 def __create_preload_elt(self, sender, filename, title, artist, album): | 66 def __create_preload_elt(self, sender, filename, title, artist, album): |
76 preload_elt = domish.Element((None, 'preload')) | 67 preload_elt = domish.Element((None, 'preload')) |
77 preload_elt['sender'] = sender | 68 preload_elt['sender'] = sender |
78 preload_elt['filename'] = filename # XXX: the frontend should know the temporary directory where file is put | 69 preload_elt['filename'] = filename # XXX: the frontend should know the temporary directory where file is put |
149 return | 140 return |
150 | 141 |
151 #we wait more than the song length to delete the file, to manage poorly reactive networks/clients | 142 #we wait more than the song length to delete the file, to manage poorly reactive networks/clients |
152 reactor.callLater(length + 90, unlink, file_to_delete) # FIXME: same host trick (see above) | 143 reactor.callLater(length + 90, unlink, file_to_delete) # FIXME: same host trick (see above) |
153 | 144 |
154 def radiocol_game_cmd(self, mess_elt, profile): | 145 def room_game_cmd(self, mess_elt, profile): |
155 #FIXME: we should check sender (is it referee ?) here before accepting commands | 146 #FIXME: we should check sender (is it referee ?) here before accepting commands |
156 from_jid = jid.JID(mess_elt['from']) | 147 from_jid = jid.JID(mess_elt['from']) |
157 room_jid = jid.JID(from_jid.userhost()) | 148 room_jid = jid.JID(from_jid.userhost()) |
158 radio_elt = mess_elt.firstChildElement() | 149 radio_elt = mess_elt.firstChildElement() |
159 radio_data = self.games[room_jid.userhost()] | 150 radio_data = self.games[room_jid.userhost()] |
160 queue = radio_data['queue'] | 151 if 'queue' in radio_data: |
152 queue = radio_data['queue'] | |
161 | 153 |
162 for elt in radio_elt.elements(): | 154 for elt in radio_elt.elements(): |
163 | 155 |
164 if elt.name == 'started': # new game created | 156 if elt.name == 'started' or elt.name == 'players': # new game created |
165 self.host.bridge.radiocolStarted(room_jid.userhost(), from_jid.full(), profile) | 157 players = [] |
158 for player in elt.elements(): | |
159 players.append(unicode(player)) | |
160 signal = self.host.bridge.radiocolStarted if elt.name == 'started' else self.host.bridge.radiocolPlayers | |
161 signal(room_jid.userhost(), from_jid.full(), players, profile) | |
166 elif elt.name == 'preload': # a song is in queue and must be preloaded | 162 elif elt.name == 'preload': # a song is in queue and must be preloaded |
167 self.host.bridge.radiocolPreload(room_jid.userhost(), elt['filename'], elt['title'], elt['artist'], elt['album'], profile) | 163 self.host.bridge.radiocolPreload(room_jid.userhost(), elt['filename'], elt['title'], elt['artist'], elt['album'], profile) |
168 elif elt.name == 'play': | 164 elif elt.name == 'play': |
169 self.host.bridge.radiocolPlay(room_jid.userhost(), elt['filename'], profile) | 165 self.host.bridge.radiocolPlay(room_jid.userhost(), elt['filename'], profile) |
170 elif elt.name == 'song_rejected': # a song has been refused | 166 elif elt.name == 'song_rejected': # a song has been refused |
206 #we can now start the party :) | 202 #we can now start the party :) |
207 radio_data['playing'] = True | 203 radio_data['playing'] = True |
208 self.playNext(room_jid, profile) | 204 self.playNext(room_jid, profile) |
209 else: | 205 else: |
210 error(_('Unmanaged game element: %s') % elt.name) | 206 error(_('Unmanaged game element: %s') % elt.name) |
211 | |
212 def getHandler(self, profile): | |
213 return RadiocolHandler(self) | |
214 | |
215 | |
216 class RadiocolHandler (XMPPHandler): | |
217 implements(iwokkel.IDisco) | |
218 | |
219 def __init__(self, plugin_parent): | |
220 self.plugin_parent = plugin_parent | |
221 self.host = plugin_parent.host | |
222 | |
223 def connectionInitialized(self): | |
224 self.xmlstream.addObserver(RADIOC_REQUEST, self.plugin_parent.radiocol_game_cmd, profile=self.parent.profile) | |
225 | |
226 def getDiscoInfo(self, requestor, target, nodeIdentifier=''): | |
227 return [disco.DiscoFeature(NC_RADIOCOL)] | |
228 | |
229 def getDiscoItems(self, requestor, target, nodeIdentifier=''): | |
230 return [] |