comparison src/plugins/plugin_misc_radiocol.py @ 455:72522263cbc9

plugin RadioCol: basic functionnality working approximately
author Goffi <goffi@goffi.org>
date Mon, 23 Jan 2012 00:14:33 +0100
parents 5731b038fc7f
children ba6e1feda03e
comparison
equal deleted inserted replaced
454:60a9086b35c5 455:72522263cbc9
32 from wokkel import disco, iwokkel, data_form 32 from wokkel import disco, iwokkel, data_form
33 from sat.tools.xml_tools import dataForm2xml 33 from sat.tools.xml_tools import dataForm2xml
34 from sat.tools.games import TarotCard 34 from sat.tools.games import TarotCard
35 35
36 from time import time 36 from time import time
37 import os.path
38 from mutagen.oggvorbis import OggVorbis
37 39
38 try: 40 try:
39 from twisted.words.protocols.xmlstream import XMPPHandler 41 from twisted.words.protocols.xmlstream import XMPPHandler
40 except ImportError: 42 except ImportError:
41 from wokkel.subprotocols import XMPPHandler 43 from wokkel.subprotocols import XMPPHandler
61 63
62 def __init__(self, host): 64 def __init__(self, host):
63 info(_("Radio collective initialization")) 65 info(_("Radio collective initialization"))
64 self.host = host 66 self.host = host
65 self.radios={} 67 self.radios={}
66 host.bridge.addMethod("radiocolLaunch", ".plugin", in_sign='ass', out_sign='', method=self.radiocolLaunch) #args: occupants, profile 68 host.bridge.addMethod("radiocolLaunch", ".plugin", in_sign='ass', out_sign='', method=self.radiocolLaunch)
67 host.bridge.addMethod("radiocolCreate", ".plugin", in_sign='ss', out_sign='', method=self.radiocolCreate) #args: room_jid, profile 69 host.bridge.addMethod("radiocolCreate", ".plugin", in_sign='ss', out_sign='', method=self.radiocolCreate)
68 host.bridge.addSignal("radiocolStarted", ".plugin", signature='sss') #args: room_jid, referee, profile 70 host.bridge.addMethod("radiocolSongAdded", ".plugin", in_sign='sss', out_sign='', method=self.radiocolSongAdded)
71 host.bridge.addSignal("radiocolStarted", ".plugin", signature='sss') #room_jid, referee, profile
72 host.bridge.addSignal("radiocolSongRejected", ".plugin", signature='sss') #room_jid, reason, profile
73 host.bridge.addSignal("radiocolPreload", ".plugin", signature='ssssss') #room_jid, filename, title, artist, album, profile
69 host.trigger.add("MUC user joined", self.userJoinedTrigger) 74 host.trigger.add("MUC user joined", self.userJoinedTrigger)
70 75
71 def createRadiocolElt(self, to_jid, type="normal"): 76 def createRadiocolElt(self, to_jid, type="normal"):
72 type = "normal" if to_jid.resource else "groupchat" 77 type = "normal" if to_jid.resource else "groupchat"
73 elt = domish.Element(('jabber:client','message')) 78 elt = domish.Element(('jabber:client','message'))
74 elt["to"] = to_jid.full() 79 elt["to"] = to_jid.full()
75 elt["type"] = type 80 elt["type"] = type
76 elt.addElement((NC_RADIOCOL, RADIOC_TAG)) 81 elt.addElement((NC_RADIOCOL, RADIOC_TAG))
77 return elt 82 return elt
78 83
79 def __create_started_elt(self): 84 def __create_started_elt(self):
80 """Create a game_started domish element""" 85 """Create a game_started domish element"""
81 started_elt = domish.Element(('','started')) 86 started_elt = domish.Element(('','started'))
82 return started_elt 87 return started_elt
83 88
157 self.radios[room_jid.userhost()] = {'referee':referee, 'occupants_data':occupants_data} 162 self.radios[room_jid.userhost()] = {'referee':referee, 'occupants_data':occupants_data}
158 mess = self.createRadiocolElt(jid.JID(room_jid.userhost())) 163 mess = self.createRadiocolElt(jid.JID(room_jid.userhost()))
159 mess.firstChildElement().addChild(self.__create_started_elt()) 164 mess.firstChildElement().addChild(self.__create_started_elt())
160 self.host.profiles[profile].xmlstream.send(mess) 165 self.host.profiles[profile].xmlstream.send(mess)
161 166
167 def radiocolSongAdded(self, referee, song_path, profile):
168 """This method is called by libervia when a song has been uploaded
169 @param room_jid_param: jid of the room
170 @song_path: absolute path of the song added
171 @param profile_key: %(doc_profile_key)s"""
172 #XXX: this is a Q&D way for the proof of concept. In the future, the song should
173 # be streamed to the backend using XMPP file copy
174 # Here we cheat because we know we are on the same host, and we don't
175 # check data. Referee will have to parse the song himself to check it
176 client = self.host.getClient(profile)
177 if not client:
178 error(_("Can't access profile's data"))
179 return
180 try:
181 song = OggVorbis(song_path)
182 except OggVorbisHeaderError:
183 #this file is not ogg vorbis, we reject it
184 import pdb
185 pdb.set_trace()
186 """mess = self.createRadiocolElt(jid.JID(referee))
187 reject_elt = mess.firstChildElement().addElement(('','song_rejected'))
188 reject_elt['sender'] = client.jid
189 reject_elt['reason'] = _("Uploaded file is not Ogg Vorbis song, only Ogg Vorbis songs are acceptable")
190 #FIXME: add an error code
191 self.host.profiles[profile].xmlstream.send(mess)"""
192 return
193 title = song.get("title", ["Unknown"])[0]
194 artist = song.get("artist", ["Unknown"])[0]
195 album = song.get("album", ["Unknown"])[0]
196 length = song.info.length
197 mess = self.createRadiocolElt(jid.JID(referee))
198 added_elt = mess.firstChildElement().addElement(('','song_added'))
199 added_elt['filename'] = os.path.basename(song_path)
200 added_elt['title'] = title
201 added_elt['artist'] = artist
202 added_elt['album'] = album
203 added_elt['length'] = str(length)
204 self.host.profiles[profile].xmlstream.send(mess)
205 return
206
207
208
162 def radiocol_game_cmd(self, mess_elt, profile): 209 def radiocol_game_cmd(self, mess_elt, profile):
163 from_jid = jid.JID(mess_elt['from']) 210 from_jid = jid.JID(mess_elt['from'])
164 room_jid = jid.JID(from_jid.userhost()) 211 room_jid = jid.JID(from_jid.userhost())
165 radio_elt = mess_elt.firstChildElement() 212 radio_elt = mess_elt.firstChildElement()
166 radio_data = self.radios[room_jid.userhost()] 213 radio_data = self.radios[room_jid.userhost()]
168 215
169 for elt in radio_elt.elements(): 216 for elt in radio_elt.elements():
170 217
171 if elt.name == 'started': #new game created 218 if elt.name == 'started': #new game created
172 self.host.bridge.radiocolStarted(room_jid.userhost(), from_jid.full(), profile) 219 self.host.bridge.radiocolStarted(room_jid.userhost(), from_jid.full(), profile)
220 elif elt.name == 'preload': #a song is in queue and must be preloaded
221 self.host.bridge.radiocolPreload(room_jid.userhost(), elt['filename'], elt['title'], elt['artist'], elt['album'], profile)
222 elif elt.name == 'song_rejected': #a song has been refused
223 import pdb
224 pdb.set_trace()
225 elif elt.name == 'song_added': #a song has been refused
226 #FIXME: we are KISS for the PoC: every song is added. Need to manage some sort of rules to allow peoples to send songs
227 mess = self.createRadiocolElt(room_jid)
228 preload_elt = mess.firstChildElement().addElement(('','preload'))
229 preload_elt['sender'] = from_jid.resource
230 preload_elt['filename'] = elt['filename'] #XXX: the frontend should know the temporary directory where file is put
231 preload_elt['title'] = elt['title']
232 preload_elt['artist'] = elt['artist']
233 preload_elt['album'] = elt['album']
234 preload_elt['length'] = elt['length']
235 self.host.profiles[profile].xmlstream.send(mess)
173 else: 236 else:
174 error (_('Unmanaged game element: %s') % elt.name) 237 error (_('Unmanaged game element: %s') % elt.name)
175 238
176 def getHandler(self, profile): 239 def getHandler(self, profile):
177 return RadiocolHandler(self) 240 return RadiocolHandler(self)