Mercurial > libervia-web
view browser_side/radiocol.py @ 286:e76ec07be8e5
browser_side (plugin radiocol): the UI uses CaptionPanel
author | souliane <souliane@mailoo.org> |
---|---|
date | Wed, 27 Nov 2013 13:33:56 +0100 |
parents | 4f0c2fea358a |
children | 7a1dc69112b8 |
line wrap: on
line source
#!/usr/bin/python # -*- coding: utf-8 -*- """ Libervia: a Salut à Toi frontend Copyright (C) 2011, 2012, 2013 Jérôme Poisson <goffi@goffi.org> This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. """ import pyjd # this is dummy in pyjs from pyjamas.ui.VerticalPanel import VerticalPanel from pyjamas.ui.HorizontalPanel import HorizontalPanel from pyjamas.ui.FlexTable import FlexTable from pyjamas.ui.FormPanel import FormPanel from pyjamas.ui.Label import Label from pyjamas.ui.Button import Button from pyjamas.ui.ClickListener import ClickHandler from pyjamas.ui.Hidden import Hidden from pyjamas.ui.HTML import HTML from pyjamas.ui.CaptionPanel import CaptionPanel from pyjamas import Window from pyjamas.Timer import Timer from __pyjamas__ import JS from tools import html_sanitize from tools import FilterFileUpload from sat_frontends.tools.misc import DEFAULT_MUC class MetadataPanel(FlexTable): def __init__(self): FlexTable.__init__(self) title_lbl = Label("title:") title_lbl.setStyleName('radiocol_metadata_lbl') artist_lbl = Label("artist:") artist_lbl.setStyleName('radiocol_metadata_lbl') album_lbl = Label("album:") album_lbl.setStyleName('radiocol_metadata_lbl') self.title = Label("") self.title.setStyleName('radiocol_metadata') self.artist = Label("") self.artist.setStyleName('radiocol_metadata') self.album = Label("") self.album.setStyleName('radiocol_metadata') self.setWidget(0, 0, title_lbl) self.setWidget(1, 0, artist_lbl) self.setWidget(2, 0, album_lbl) self.setWidget(0, 1, self.title) self.setWidget(1, 1, self.artist) self.setWidget(2, 1, self.album) self.setStyleName("radiocol_metadata_pnl") def setTitle(self, title): self.title.setText(title) def setArtist(self, artist): self.artist.setText(artist) def setAlbum(self, album): self.album.setText(album) class ControlPanel(FormPanel): """Panel used to show controls to add a song, or vote for the current one""" def __init__(self, parent): FormPanel.__init__(self) self.setEncoding(FormPanel.ENCODING_MULTIPART) self.setMethod(FormPanel.METHOD_POST) self.setAction("upload_radiocol") self._parent = parent vPanel = VerticalPanel() types = [('audio/ogg', '*.ogg', 'Ogg Vorbis Audio'), ('video/ogg', '*.ogv', 'Ogg Vorbis Video'), ('application/ogg', '*.ogx', 'Ogg Vorbis Multiplex')] self.file_upload = FilterFileUpload("song", 5, types) vPanel.add(self.file_upload) hPanel = HorizontalPanel() self.upload_btn = Button("Upload song", getattr(self, "onBtnClick")) hPanel.add(self.upload_btn) self.status = Label() self.updateStatus() hPanel.add(self.status) #We need to know the referee referee_field = Hidden('referee', self._parent.referee) hPanel.add(referee_field) vPanel.add(hPanel) self.add(vPanel) self.addFormHandler(self) def updateStatus(self): # TODO: the status should be different if a song is being played or not queue = self._parent.getQueueSize() queue_data = self._parent.queue_data if queue < queue_data[0]: left = queue_data[0] - queue self.status.setText("[we need %d more song%s]" % (left, "s" if left > 1 else "")) elif queue < queue_data[1]: left = queue_data[1] - queue self.status.setText("[%d available spot%s]" % (left, "s" if left > 1 else "")) elif queue >= queue_data[1]: self.status.setText("[The queue is currently full]") self.status.setStyleName('radiocol_status') def onBtnClick(self): if self.file_upload.check(): self.submit() self.file_upload.setFilename("") self.status.setText('[Submitting, please wait...]') def onSubmit(self, event): pass def blockUpload(self): self.file_upload.setVisible(False) self.upload_btn.setEnabled(False) def unblockUpload(self): self.file_upload.setVisible(True) self.upload_btn.setEnabled(True) def setTemporaryStatus(self, text, style): self.status.setText(text) self.status.setStyleName('radiocol_upload_status_%s' % style) Timer(5000, self.updateStatus) def onSubmitComplete(self, event): result = event.getResults() if result == "OK": self.setTemporaryStatus('[Your song has been added to queue]', "ok") elif result == "KO": self.setTemporaryStatus('[Something went wrong during your song upload]', "ko") else: Window.alert('Submit error: %s' % result) self.status.setText('') class Player(HTML): def __init__(self, player_id, metadata_panel): HTML.__init__(self) self._id = player_id self.metadata = metadata_panel self.title = "" self.artist = "" self.album = "" self.filename = None self.played = False # True when song is playing/played, become False on preload def preload(self, filename, title, artist, album): """preload the song but doesn't play it""" self.filename = filename self.title = title self.artist = artist self.album = album self.played = False self.setHTML('<audio id="%s" style="display: none" preload="auto" src="radiocol/%s" />' % (self._id, html_sanitize(filename))) print "preloading %s in %s" % (title, self._id) def play(self): """actually play the song""" self.played = True self.metadata.setTitle(self.title) self.metadata.setArtist(self.artist) self.metadata.setAlbum(self.album) JS(""" var player = top.document.getElementById(this._id); player.play(); """) class RadioColPanel(HorizontalPanel, ClickHandler): def __init__(self, parent, referee, player_nick, players, queue_data): # We need to set it here and not in the CSS :( HorizontalPanel.__init__(self, Height="90px") ClickHandler.__init__(self) self._parent = parent self.referee = referee self.queue_data = queue_data self.setStyleName("radiocolPanel") # Now we set up the layout self.metadata_panel = MetadataPanel() self.add(CaptionPanel("Now playing", self.metadata_panel)) self.playlist_panel = VerticalPanel() self.add(CaptionPanel("Songs queue", self.playlist_panel)) self.control_panel = ControlPanel(self) self.add(CaptionPanel("Controls", self.control_panel)) self.next_songs = [] self.players = [Player("player_%d" % i, self.metadata_panel) for i in range(4)] self.current_player = None for player in self.players: self.add(player) self.addClickListener(self) help_msg = HTML("""- This radio plays Ogg Vorbis files.<br /> - What's that? I only know MP3!<br /> - Click <a style="color: red;">here</a> if you need some support :) """) help_msg.setStyleName('chatTextInfo-link') help_msg.addClickListener(lambda: self._parent.host.bridge.call('joinMUC', None, DEFAULT_MUC, self._parent.nick)) self._parent.content.add(help_msg) def pushNextSong(self, title): """Add a song to the left panel's next songs queue""" next_song = Label(title) next_song.setStyleName("radiocol_next_song") self.next_songs.append(next_song) self.playlist_panel.append(next_song) def popNextSong(self): """Remove the first song of next songs list should be called when the song is played""" #FIXME: should check that the song we remove is the one we play next_song = self.next_songs.pop(0) self.playlist_panel.remove(next_song) def getQueueSize(self): return len(self.playlist_panel.getChildren()) def radiocolPreload(self, filename, title, artist, album): preloaded = False for player in self.players: if not player.filename or \ (player.played and player != self.current_player): #if player has no file loaded, or it has already played its song #we use it to preload the next one player.preload(filename, title, artist, album) preloaded = True break if not preloaded: print("WARNING: Can't preload song, we are getting too many songs to preload, we shouldn't have more than 2 at once") else: self.pushNextSong(title) def radiocolPlay(self, filename): for player in self.players: if player.filename == filename: player.play() self.popNextSong() self.current_player = player self.control_panel.updateStatus() return print("WARNING: Song not found in queue, can't play it. This should not happen") def radiocolNoUpload(self): self.control_panel.blockUpload() def radiocolUploadOk(self): self.control_panel.unblockUpload() def radiocolSongRejected(self, reason): Window.alert("Song rejected: %s" % reason)