comparison browser_side/radiocol.py @ 129:dd0d39ae7d24

RadioCol: song preloading + fonctionnal players
author Goffi <goffi@goffi.org>
date Sun, 29 Jan 2012 00:15:04 +0100
parents 2849ec993d89
children 6576c5a90060
comparison
equal deleted inserted replaced
128:2849ec993d89 129:dd0d39ae7d24
21 21
22 import pyjd # this is dummy in pyjs 22 import pyjd # this is dummy in pyjs
23 from pyjamas.ui.VerticalPanel import VerticalPanel 23 from pyjamas.ui.VerticalPanel import VerticalPanel
24 from pyjamas.ui.HorizontalPanel import HorizontalPanel 24 from pyjamas.ui.HorizontalPanel import HorizontalPanel
25 from pyjamas.ui.SimplePanel import SimplePanel 25 from pyjamas.ui.SimplePanel import SimplePanel
26 from pyjamas.ui.FlexTable import FlexTable
26 from pyjamas.ui.FormPanel import FormPanel 27 from pyjamas.ui.FormPanel import FormPanel
27 from pyjamas.ui.NamedFrame import NamedFrame 28 from pyjamas.ui.NamedFrame import NamedFrame
28 from pyjamas.ui.FileUpload import FileUpload 29 from pyjamas.ui.FileUpload import FileUpload
29 from pyjamas.ui.Label import Label 30 from pyjamas.ui.Label import Label
30 from pyjamas.ui.Button import Button 31 from pyjamas.ui.Button import Button
31 from pyjamas.ui.ClickListener import ClickHandler 32 from pyjamas.ui.ClickListener import ClickHandler
32 from pyjamas.ui.MouseListener import MouseHandler 33 from pyjamas.ui.MouseListener import MouseHandler
33 from pyjamas.ui.Hidden import Hidden 34 from pyjamas.ui.Hidden import Hidden
34 from pyjamas.ui.HTML import HTML 35 from pyjamas.ui.HTML import HTML
35 from pyjamas import Window 36 from pyjamas import Window
37 from pyjamas.Timer import Timer
38 from __pyjamas__ import JS
36 39
37 from jid import JID 40 from jid import JID
38 from tools import html_sanitize 41 from tools import html_sanitize
39 42
40 43
41 class MetadataPanel(VerticalPanel): 44 class MetadataPanel(FlexTable):
42 45
43 def __init__(self): 46 def __init__(self):
44 VerticalPanel.__init__(self) 47 FlexTable.__init__(self)
45 self.title = Label("title:") 48 title_lbl = Label("title:")
46 self.artist = Label("artist:") 49 title_lbl.setStyleName('radiocol_metadata_lbl')
47 self.album = Label("album:") 50 artist_lbl = Label("artist:")
48 self.add(self.title) 51 artist_lbl.setStyleName('radiocol_metadata_lbl')
49 self.add(self.artist) 52 album_lbl = Label("album:")
50 self.add(self.album) 53 album_lbl.setStyleName('radiocol_metadata_lbl')
54 self.title = Label("")
55 self.title.setStyleName('radiocol_metadata')
56 self.artist = Label("")
57 self.artist.setStyleName('radiocol_metadata')
58 self.album = Label("")
59 self.album.setStyleName('radiocol_metadata')
60 self.setWidget(0,0,title_lbl)
61 self.setWidget(1,0,artist_lbl)
62 self.setWidget(2,0,album_lbl)
63 self.setWidget(0,1,self.title)
64 self.setWidget(1,1,self.artist)
65 self.setWidget(2,1,self.album)
66 self.setStyleName("radiocol_metadata_pnl")
67
68 def setTitle(self, title):
69 self.title.setText(title)
70
71 def setArtist(self, artist):
72 self.artist.setText(artist)
73
74 def setAlbum(self, album):
75 self.album.setText(album)
51 76
52 class ControlPanel(FormPanel): 77 class ControlPanel(FormPanel):
53 """Panel used to show controls to add a song, or vote for the current one""" 78 """Panel used to show controls to add a song, or vote for the current one"""
54 79
55 def __init__(self, referee): 80 def __init__(self, referee):
56 FormPanel.__init__(self) 81 FormPanel.__init__(self)
82 self._timer = Timer(notify=self._timeCb)
57 self.setEncoding(FormPanel.ENCODING_MULTIPART) 83 self.setEncoding(FormPanel.ENCODING_MULTIPART)
58 self.setMethod(FormPanel.METHOD_POST) 84 self.setMethod(FormPanel.METHOD_POST)
59 self.setAction("upload") # set this as appropriate 85 self.setAction("upload") # set this as appropriate
60 vPanel = VerticalPanel() 86 vPanel = VerticalPanel()
61 87
65 self.field.setName("song") 91 self.field.setName("song")
66 hPanel.add(self.field) 92 hPanel.add(self.field)
67 93
68 hPanel.add(Button("Upload song", getattr(self, "onBtnClick"))) 94 hPanel.add(Button("Upload song", getattr(self, "onBtnClick")))
69 95
96 self.status = Label()
97
70 vPanel.add(hPanel) 98 vPanel.add(hPanel)
71 99
72 #We need to know the referee 100 #We need to know the referee
73 referee_field = Hidden('referee', referee) 101 referee_field = Hidden('referee', referee)
74 vPanel.add(referee_field) 102 vPanel.add(referee_field)
75 103
76 self.add(vPanel) 104 self.add(vPanel)
77 self.addFormHandler(self) 105 self.addFormHandler(self)
106
107 def _timeCb(self, timer):
108 self.status.setText('')
78 109
79 def onBtnClick(self): 110 def onBtnClick(self):
80 self.submit() 111 self.submit()
81 112
82 def onSubmit(self, event): 113 def onSubmit(self, event):
83 pass 114 pass
84 115
85 def onSubmitComplete(self, event): 116 def onSubmitComplete(self, event):
86 result = event.getResults() 117 result = event.getResults()
87 if result == "OK": 118 if result == "OK":
88 Window.alert('Your song has been added to queue') 119 self.status.setText('Your song has been added to queue')
120 self.status.setStyleName('radiocol_upload_status_ok')
121 self._timer.schedule(5000)
89 elif result == "KO": 122 elif result == "KO":
90 Window.alert('Something went wrong during your song upload') 123 self.status.setText('Something went wrong during your song upload')
124 self.status.setStyleName('radiocol_upload_status_ko')
91 else: 125 else:
92 Window.alert('Submit error: %s' % result) 126 Window.alert('Submit error: %s' % result)
127
128 class Player(HTML):
129
130 def __init__(self, player_id, metadata_panel):
131 HTML.__init__(self)
132 self._id = player_id
133 self.metadata = metadata_panel
134 self.title=""
135 self.artist=""
136 self.album=""
137 self.filename = None
138 self.played = False #True when song is playing/played, become False on preload
139
140 def preload(self, filename, title, artist, album):
141 """preload the song but doesn't play it"""
142 self.filename = filename
143 self.title = title
144 self.artist = artist
145 self.album = album
146 self.played = False
147 self.setHTML('<audio id="%s" style="display: none" preload="auto" src="radiocol/%s" />' % (self._id, html_sanitize(filename)))
148 print "preloading %s in %s" % (title, self._id)
149
150 def play(self):
151 """actually play the song"""
152 self.played = True
153 self.metadata.setTitle(self.title)
154 self.metadata.setArtist(self.artist)
155 self.metadata.setAlbum(self.album)
156
157 JS("""
158 var player = top.document.getElementById(this._id);
159 player.play();
160 """)
161
162
93 163
94 class RadioColPanel(HorizontalPanel, ClickHandler): 164 class RadioColPanel(HorizontalPanel, ClickHandler):
95 165
96 def __init__(self, parent, referee, player_nick): 166 def __init__(self, parent, referee, player_nick):
97 HorizontalPanel.__init__(self) 167 HorizontalPanel.__init__(self)
98 ClickHandler.__init__(self) 168 ClickHandler.__init__(self)
99 self._parent = parent 169 self._parent = parent
100 self.referee = referee 170 self.referee = referee
101 self.setStyleName("radiocolPanel") 171 self.setStyleName("radiocolPanel")
172 self.setHeight('30%')
102 173
103 # Now we set up the layout 174 # Now we set up the layout
104 self.left_panel = VerticalPanel() 175 self.left_panel = VerticalPanel()
176 self.left_panel.setStyleName("radiocol_left_panel")
177 self.left_panel.setHeight('100%')
105 self.add(self.left_panel) 178 self.add(self.left_panel)
106 self.right_panel = VerticalPanel() 179 self.right_panel = VerticalPanel()
107 self.metadata_panel = MetadataPanel() 180 self.metadata_panel = MetadataPanel()
108 self.right_panel.add(self.metadata_panel) 181 self.right_panel.add(self.metadata_panel)
109 self.control_panel = ControlPanel(self.referee) 182 self.control_panel = ControlPanel(self.referee)
110 self.right_panel.add(self.control_panel) 183 self.right_panel.add(self.control_panel)
111 self.add(self.right_panel) 184 self.add(self.right_panel)
112 #self.right_panel.setBorderWidth(1) 185 #self.right_panel.setBorderWidth(1)
113 self.left_panel.add(Label("Musique 1")) 186 self.next_song_1 = Label()
114 self.left_panel.add(Label("Musique 2")) 187 self.next_song_1.setStyleName("radiocol_next_song")
115 self.audio = HTML("") 188 self.next_song_2 = Label()
116 self.right_panel.add(self.audio) 189 self.next_song_2.setStyleName("radiocol_next_song")
117 190 self.left_panel.add(self.next_song_1)
118 191 self.left_panel.add(self.next_song_2)
192 self.players = [Player("player_%d" % i, self.metadata_panel) for i in range(4)]
193 self.current_player = None
194 for player in self.players:
195 self.right_panel.add(player)
119 self.addClickListener(self) 196 self.addClickListener(self)
120 197
121 def radiocolPreload(self, filename, title, artist, album): 198 def radiocolPreload(self, filename, title, artist, album):
122 self.audio.setHTML('<audio preload="auto" controls="controls" src="radiocol/%s" />' % html_sanitize(filename)) 199 self.next_song_1.setText(self.next_song_2.getText())
123 200 self.next_song_2.setText(title)
201 preloaded = False
202 for player in self.players:
203 if not player.filename or \
204 (player.played and player != self.current_player):
205 #if player has no file loaded, or it has already played its song
206 #we use it to preload the next one
207 player.preload(filename, title, artist, album)
208 preloaded = True
209 break
210 if not preloaded:
211 print("WARNING: Can't preload song, we are getting too many songs to preload, we shouldn't have more than 2 at once")
212
213