AUTOMAKE_OPTIONS = gnu
-SUBDIRS = antiscrollbar movietagger webinterface wirelesslan netcaster lastfm logomanager vlcplayer simplerss trafficinfo fritzcall webcamviewer emailclient autotimer epgrefresh werbezapper httpproxy startuptostandby imdb ofdb networkwizard movieretitle moviecut tageditor cdinfo unwetterzentrale
+SUBDIRS = antiscrollbar movietagger webinterface wirelesslan netcaster lastfm logomanager vlcplayer simplerss trafficinfo fritzcall webcamviewer emailclient autotimer epgrefresh werbezapper httpproxy startuptostandby imdb ofdb networkwizard movieretitle moviecut tageditor cdinfo unwetterzentrale youtubeplayer
unwetterzentrale/Makefile
unwetterzentrale/src/Makefile
+youtubeplayer/Makefile
+youtubeplayer/src/Makefile
+youtubeplayer/src/Nemesis.GlassLine_Mod/Makefile
+
])
--- /dev/null
+Package: enigma2-plugin-extensions-youtubeplayer
+Version: 0.2
+Description: Enigma2 Plugin to search and play YouTube Movies
+Section: base
+Priority: optional
+Maintainer: Volker Christian <volker.christian@fh-hagenberg.at>
+Architecture: mipsel
+Homepage: http://www.i-have-a-dreambox.com/wbb2/board.php?boardid=240
+Depends: enigma2, enigma2-plugin-extensions-vlcplayer, twisted-web python-gdata
+Source: Just localy at my harddrive
--- /dev/null
+SUBDIRS = src
--- /dev/null
+############################################################################
+# Copyright (C) 2008 by Volker Christian #
+# Volker.Christian@fh-hagenberg.at #
+# #
+# This program is free software; you can redistribute it and#or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation; either version 2 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 General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program; if not, write to the #
+# Free Software Foundation, Inc., #
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
+############################################################################
+
+from GoogleSuggestions import GoogleSuggestions
+
+from Screens.Screen import Screen
+from Components.config import ConfigText
+from Components.config import KEY_DELETE, KEY_BACKSPACE, KEY_LEFT, KEY_RIGHT
+from Components.config import KEY_HOME, KEY_END, KEY_TOGGLEOW, KEY_ASCII, KEY_TIMEOUT
+from Components.MenuList import MenuList
+from enigma import eListboxPythonMultiContent, RT_HALIGN_LEFT, gFont
+
+from threading import Thread
+from threading import Condition
+
+
+def SuggestionListEntry(suggestion):
+ res = [ suggestion ]
+ res.append((eListboxPythonMultiContent.TYPE_TEXT, 5, 1, 370, 20, 0, RT_HALIGN_LEFT, suggestion[0]))
+ return res
+
+
+class SuggestionsList(MenuList):
+ def __init__(self):
+ MenuList.__init__(self, list, False, eListboxPythonMultiContent)
+ self.l.setFont(0, gFont("Regular", 18))
+ self.l.setItemHeight(23)
+
+
+ def update(self, suggestions):
+ self.list = []
+ if suggestions:
+ suggests = suggestions[1]
+ for suggestion in suggests:
+ self.list.append(SuggestionListEntry(suggestion))
+ self.l.setList(self.list)
+ self.moveToIndex(0)
+
+
+ def getSelection(self):
+ if self.getCurrent() is None:
+ return None
+ return self.l.getCurrentSelection()[0][0]
+
+
+class SuggestionsListScreen(Screen):
+ skin = """
+ <screen name="SuggestionsListScreen" position="170,120" zPosition="2" size="394,185" backgroundColor="#202020" flags="wfNoBorder">
+ <eLabel position="0,0" size="394,185" backgroundColor="#c0c0c0" zPosition="-1" />
+ <widget name="suggestionslist" position="2,2" size="390,181" scrollbarMode="showOnDemand"/>
+ </screen>"""
+
+
+ def __init__(self, session, configTextWithSuggestion):
+ Screen.__init__(self, session)
+ self.suggestionlist = SuggestionsList()
+ self["suggestionslist"] = self.suggestionlist
+ self.configTextWithSuggestion = configTextWithSuggestion
+
+
+ def update(self, suggestions):
+ if suggestions:
+ if not self.shown:
+ self.show()
+ self.suggestionlist.update(suggestions)
+ else:
+ self.hide()
+
+
+ def up(self):
+ self.suggestionlist.up()
+ return self.suggestionlist.getSelection()
+
+
+ def down(self):
+ self.suggestionlist.down()
+ return self.suggestionlist.getSelection()
+
+
+ def pageUp(self):
+ self.suggestionlist.pageUp()
+ return self.suggestionlist.getSelection()
+
+
+ def pageDown(self):
+ self.suggestionlist.pageDown()
+ return self.suggestionlist.getSelection()
+
+
+ def activate(self):
+ self.suggestionlist.selectionEnabled(1)
+ return self.suggestionlist.getSelection()
+
+
+ def deactivate(self):
+ self.suggestionlist.selectionEnabled(0)
+ return self.suggestionlist.getSelection()
+
+
+class ConfigTextWithSuggestions(ConfigText):
+ class SuggestionsThread(Thread):
+ def __init__(self, suggestionsService):
+ Thread.__init__(self)
+ self.suggestionsService = suggestionsService
+ self.value = None
+ self.running = True
+ self.condition = Condition()
+
+ def run(self):
+ while self.running:
+ self.condition.acquire()
+ if self.value is None:
+ self.condition.wait()
+ value = self.value
+ self.value = None
+ self.condition.release()
+ if value is not None:
+ self.suggestionsService.getSuggestions(value)
+
+ def stop(self):
+ self.running = False
+ self.condition.acquire()
+ self.condition.notify()
+ self.condition.release()
+ self.join()
+
+ def getSuggestions(self, value):
+ self.condition.acquire()
+ self.value = value
+ self.condition.notify()
+ self.condition.release()
+
+ def __init__(self, default = "", fixed_size = True, visible_width = False, threaded = False):
+ ConfigText.__init__(self, default, fixed_size, visible_width)
+ self.suggestions = GoogleSuggestions(self.propagateSuggestions, ds = "yt", hl = "en")
+ self.timeoutlistener = []
+ self.suggestionsThread = None
+ self.threaded = threaded
+ self.suggestionsListActivated = False
+
+
+ def propagateSuggestions(self, suggestionsList):
+ if self.suggestionsWindow:
+ self.suggestionsWindow.update(suggestionsList)
+
+
+ def getSuggestions(self):
+ if self.suggestionsThread is not None:
+ self.suggestionsThread.getSuggestions(self.value)
+ else:
+ self.suggestions.getSuggestions(self.value)
+
+
+ def handleKey(self, key):
+ if not self.suggestionsListActivated:
+ ConfigText.handleKey(self, key)
+ if key in [KEY_DELETE, KEY_BACKSPACE, KEY_ASCII, KEY_TIMEOUT]:
+ self.getSuggestions()
+
+
+ def onSelect(self, session):
+ if self.threaded:
+ self.suggestionsThread = ConfigTextWithSuggestions.SuggestionsThread(self.suggestions)
+ self.suggestionsThread.start()
+ else:
+ self.suggestionsThread = None
+ ConfigText.onSelect(self, session)
+ if session is not None:
+ self.suggestionsWindow = session.instantiateDialog(SuggestionsListScreen, self)
+ self.suggestionsWindow.deactivate()
+ self.suggestionsWindow.hide()
+ self.suggestions.getSuggestions(self.value)
+
+
+ def onDeselect(self, session):
+ if self.suggestionsThread is not None:
+ self.suggestionsThread.stop()
+ ConfigText.onDeselect(self, session)
+ if self.suggestionsWindow:
+ session.deleteDialog(self.suggestionsWindow)
+ self.suggestionsWindow = None
+
+
+ def suggestionListUp(self):
+ self.value = self.suggestionsWindow.up()
+
+
+ def suggestionListDown(self):
+ self.value = self.suggestionsWindow.down()
+
+
+ def suggestionListPageDown(self):
+ self.value = self.suggestionsWindow.pageDown()
+
+
+ def suggestionListPageUp(self):
+ self.value = self.suggestionsWindow.pageUp()
+
+
+ def activateSuggestionList(self):
+ ret = False
+ if self.suggestionsWindow is not None and self.suggestionsWindow.shown:
+ self.tmpValue = self.value
+ self.value = self.suggestionsWindow.activate()
+ self.allmarked = False
+ self.marked_pos = -1
+ self.suggestionsListActivated = True
+ ret = True
+ return ret
+
+
+ def deactivateSuggestionList(self):
+ ret = False
+ if self.suggestionsWindow is not None:
+ self.suggestionsWindow.deactivate()
+ self.getSuggestions()
+ self.allmarked = True
+ self.suggestionsListActivated = False
+ ret = True
+ return ret
+
+
+ def cancelSuggestionList(self):
+ self.value = self.tmpValue
+ return self.deactivateSuggestionList()
--- /dev/null
+############################################################################
+# Copyright (C) 2008 by Volker Christian #
+# Volker.Christian@fh-hagenberg.at #
+# #
+# This program is free software; you can redistribute it and#or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation; either version 2 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 General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program; if not, write to the #
+# Free Software Foundation, Inc., #
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
+############################################################################
+
+import urllib
+import httplib
+import socket
+
+
+class GoogleSuggestions():
+ def __init__(self, callback, ds = None, json = None, hl = None):
+ self.callback = callback
+ self.conn = httplib.HTTPConnection("google.com")
+ self.prepQuerry = "/complete/search?"
+ if ds is not None:
+ self.prepQuerry = self.prepQuerry + "ds=" + ds + "&"
+ if json is not None:
+ self.prepQuerry = self.prepQuerry + "json=" + json + "&"
+ if hl is not None:
+ self.prepQuerry = self.prepQuerry + "hl=" + hl + "&"
+ self.prepQuerry = self.prepQuerry + "jsonp=self.gotSuggestions&q="
+
+
+ def gotSuggestions(self, suggestslist):
+ self.callback(suggestslist)
+
+
+ def getSuggestions(self, querryString):
+ if querryString is not "":
+ querry = self.prepQuerry + urllib.quote(querryString)
+ try:
+ self.conn.request("GET", querry)
+ except (httplib.CannotSendRequest, socket.gaierror, socket.error):
+ print "[YTB] Can not send request for suggestions"
+ self.callback(None)
+ else:
+ try:
+ response = self.conn.getresponse()
+ except httplib.BadStatusLine:
+ print "[YTB] Can not get a response from google"
+ self.callback(None)
+ else:
+ if response.status == 200:
+ data = response.read()
+ exec data
+ else:
+ self.callback(None)
+ self.conn.close()
+ else:
+ self.callback(None)
+
+
+
+#class GoogleSuggestions():
+# def __init__(self, callback, ds = None, json = None, hl = None):
+# self.callback = callback
+# self.prepQuerry = "http://www.google.com/complete/search?"
+# if ds is not None:
+# self.prepQuerry = self.prepQuerry + "ds=" + ds + "&"
+# if json is not None:
+# self.prepQuerry = self.prepQuerry + "json=" + json + "&"
+# if hl is not None:
+# self.prepQuerry = self.prepQuerry + "hl=" + hl + "&"
+# self.prepQuerry = self.prepQuerry + "jsonp=self.gotSuggestions&q="
+#
+#
+# def gotSuggestions(self, suggestslist):
+# self.callback(suggestslist)
+#
+#
+# def getSuggestions(self, querryString):
+# if querryString is not "":
+# querry = self.prepQuerry + urllib.quote(querryString)
+# try:
+# filehandler = urllib.urlopen(url = querry)
+# except IOError e:
+# print "[YTB] Error during urlopen: ", e
+# self.callback(None)
+# else:
+# try:
+# content = filehandler.read()
+# filehandler.close()
+# except IOError e:
+# print "[YTB] Error during read: ", e
+# self.callback(None)
+# else:
+# exec content
+# else:
+# self.callback(None)
--- /dev/null
+SUBDIRS = Nemesis.GlassLine_Mod
+
+installdir = /usr/lib/enigma2/python/Plugins/Extensions/YouTubePlayer
+
+install_PYTHON = *.py
+
+install_DATA = plugin.png starsbar_empty.png starsbar_filled.png user_default.png user.png keymap.xml skin.xml
--- /dev/null
+installdir = /usr/lib/enigma2/python/Plugins/Extensions/YouTubePlayer/Nemesis.GlassLine_Mod
+
+install_DATA = skin.xml
--- /dev/null
+<skin>
+<!--
+ <ePixmap name="red" position="10,10" size="21,21" pixmap="Nemesis.GlassLine_Mod/red.png" alphatest="on" />
+ <ePixmap name="green" position="140,10" size="21,21" pixmap="Nemesis.GlassLine_Mod/green.png" alphatest="on" />
+ <ePixmap name="yellow" position="280,10" size="21,21" pixmap="Nemesis.GlassLine_Mod/yellow.png" alphatest="on" />
+ <ePixmap name="blue" position="420,10" size="21,21" pixmap="Nemesis.GlassLine_Mod/blue.png" alphatest="on" />
+ <widget name="key_red" position="40,10" size="115,21" halign="left" valign="center" font="Regular;20" />
+ <widget name="key_green" position="170,10" size="115,21" halign="left" valign="center" font="Regular;20" />
+ <widget name="key_yellow" position="310,10" size="115,21" halign="left" valign="center" font="Regular;20" />
+ <widget name="key_blue" position="450,10" size="115,21" halign="left" valign="center" font="Regular;20" />
+-->
+ <!-- YouTube-Player -->
+ <screen name = "YouTubeVideoDetailsScreen" position = "80,85" size = "560,410" title = "Video Details" transparent = "0">
+ <widget name = "video_thumbnail_1" position = "10,10" size = "130,97" alphatest = "on" />
+ <widget name = "video_thumbnail_2" position = "10,110" size = "130,97" alphatest = "on" />
+ <widget name = "video_thumbnail_3" position = "10,210" size = "130,97" alphatest = "on" />
+ <widget name = "label_video_duration" position = "150,10" size = "95,20" font = "Regular;20" halign = "right" />
+ <widget name = "video_duration" position = "250,10" size = "90,20" valign = "left" font = "Regular;20"/>
+ <widget name = "label_video_rating_average" position = "345,10" size = "95,20" font = "Regular;20" halign = "right" />
+ <widget name = "starsbg" pixmap = "/usr/lib/enigma2/python/Plugins/Extensions/YouTubePlayer/starsbar_empty.png" position = "445,10" zPosition = "0" size = "100,20" transparent = "1" alphatest = "on" />
+ <widget name = "stars" position = "445,10" size = "100,20" pixmap = "/usr/lib/enigma2/python/Plugins/Extensions/YouTubePlayer/starsbar_filled.png" transparent = "1" />
+ <widget name = "label_video_statistics_view_count" position = "150,30" size = "95,20" font = "Regular;20" halign = "right" />
+ <widget name = "video_statistics_view_count" position = "250,30" size = "90,20" valign = "left" font = "Regular;20"/>
+ <widget name = "label_video_numraters" position = "345,30" size = "95,20" font = "Regular;20" halign = "right" />
+ <widget name = "video_numraters" position = "445,30" size = "105,20" valign = "left" font = "Regular;20"/>
+ <widget name = "label_video_statistics_favorite_count" position = "150,50" size = "95,20" font = "Regular;20" halign = "right" />
+ <widget name = "video_statistics_favorite_count" position = "250,50" size = "90,20" valign = "left" font = "Regular;20"/>
+ <widget name = "label_video_published_on" position = "345,50" size = "95,20" font = "Regular;20" halign = "right" />
+ <widget name = "video_published_on" position = "445,50" size = "105,20" valign = "left" font = "Regular;20"/>
+ <widget name = "label_video_author" position = "150,70" size = "95,20" font = "Regular;20" halign = "right" />
+ <widget name = "video_author" position = "250,70" size = "300,20" valign = "left" font = "Regular;20"/>
+ <widget name = "label_video_category" position = "150,90" size = "95,20" font = "Regular;20" halign = "right" />
+ <widget name = "video_category" position = "250,90" size = "300,20" valign = "left" font = "Regular;20"/>
+ <widget name = "label_video_tags" position = "150,110" size = "95,20" font = "Regular;20" halign = "right" />
+ <widget name = "video_tags" position = "250,110" size = "300,60" valign = "left" font = "Regular;20"/>
+ <ePixmap pixmap="Nemesis.GlassLine_Mod/separator.png" position="150,178" zPosition="1" size="400,4" />
+ <widget name = "video_description" position = "150,190" size = "400,210" font = "Regular;20" />
+ </screen>
+
+ <screen name = "YouTubeListScreen" position = "80,85" size = "560,410" title = "YouTube Videos" transparent = "0">
+ <widget name = "label_total_results" position = "0,13" size = "160,20" font = "Regular;20" halign = "right" />
+ <widget name = "total_results" position = "170,13" size = "110,20" font = "Regular;20" />
+ <widget name = "label_currently_shown" position = "280,13" size = "110,20" font = "Regular;20" halign = "right" />
+ <widget name = "currently_shown" position = "400,13" size = "160,20" font = "Regular;20" />
+ <ePixmap pixmap="Nemesis.GlassLine_Mod/separator.png" position="0,43" zPosition="1" size="560,4" />
+ <widget name = "list" position = "5,55" size = "550,315" scrollbarMode = "showOnDemand" />
+ <ePixmap name = "key_red" position = "40,370" zPosition = "1" size = "200,40" pixmap = "skin_default/buttons/red-big.png" transparent = "1" alphatest = "on" />
+ <ePixmap name = "key_green" position = "320,370" zPosition = "1" size = "200,40" pixmap = "skin_default/buttons/green-big.png" transparent = "1" alphatest = "on" />
+ <widget name = "red" position = "40,370" size = "200,40" font = "Regular;19" valign = "center" halign = "center" transparent = "1" zPosition = "2" />
+ <widget name = "green" position = "320,370" size = "200,40" font = "Regular;19" valign = "center" halign = "center" transparent = "1" zPosition = "2" />
+ </screen>
+
+ <screen name = "YouTubeUserListScreen" position = "80,85" size = "560,410" title = "YouTube User-Profiles" >
+ <widget name = "label_info" position = "10,9" size = "540,42" halign = "center" valign = "center" font = "Regular;21" />
+ <ePixmap pixmap="Nemesis.GlassLine_Mod/separator.png" position="0,55" zPosition="1" size="560,4" />
+ <widget name = "userlist" position = "10,62" size = "540,283" scrollbarMode = "showOnDemand"/>
+ <ePixmap name = "red" position = "0,370" zPosition = "4" size = "140,40" pixmap = "skin_default/buttons/red.png" transparent = "1" alphatest = "on" />
+ <ePixmap name = "green" position = "140,370" zPosition = "4" size = "140,40" pixmap = "skin_default/buttons/green.png" transparent = "1" alphatest = "on" />
+ <ePixmap name = "yellow" position = "280,370" zPosition = "4" size = "140,40" pixmap = "skin_default/buttons/yellow.png" transparent = "1" alphatest = "on" />
+ <ePixmap name = "blue" position = "420,370" zPosition = "4" size = "140,40" pixmap = "skin_default/buttons/blue.png" transparent = "1" alphatest = "on" />
+ <widget name = "key_red" position = "0,370" zPosition = "5" size = "140,40" valign = "center" halign = "center" font = "Regular;21" transparent = "1" foregroundColor = "white" shadowColor = "black" shadowOffset = "-1,-1" />
+ <widget name = "key_green" position = "140,370" zPosition = "5" size = "140,40" valign = "center" halign = "center" font = "Regular;21" transparent = "1" foregroundColor = "white" shadowColor = "black" shadowOffset = "-1,-1" />
+ <widget name = "key_yellow" position = "280,370" zPosition = "5" size = "140,40" valign = "center" halign = "center" font = "Regular;21" transparent = "1" foregroundColor = "white" shadowColor = "black" shadowOffset = "-1,-1" />
+ <widget name = "key_blue" position = "420,370" zPosition = "5" size = "140,40" valign = "center" halign = "center" font = "Regular;21" transparent = "1" foregroundColor = "white" shadowColor = "black" shadowOffset = "-1,-1" />
+ </screen>
+</skin>
\ No newline at end of file
--- /dev/null
+############################################################################
+# Copyright (C) 2008 by Volker Christian #
+# Volker.Christian@fh-hagenberg.at #
+# #
+# This program is free software; you can redistribute it and#or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation; either version 2 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 General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program; if not, write to the #
+# Free Software Foundation, Inc., #
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
+############################################################################
+
+from Components.config import config
+from skin import loadSkin
+import os
+
+
+def loadSkinReal(skinPath):
+ if os.path.exists(skinPath):
+ print "[SKLDR] Loading skin ", skinPath
+ loadSkin(skinPath)
+
+
+def loadPluginSkin(pluginPath):
+ loadSkinReal(pluginPath + "/" + config.skin.primary_skin.value)
+ loadSkinReal(pluginPath + "/skin.xml")
--- /dev/null
+############################################################################
+# Copyright (C) 2008 by Volker Christian #
+# Volker.Christian@fh-hagenberg.at #
+# #
+# This program is free software; you can redistribute it and#or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation; either version 2 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 General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program; if not, write to the #
+# Free Software Foundation, Inc., #
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
+############################################################################
+
+from Screens.Screen import Screen
+
+from Components.config import Config
+from Components.config import ConfigText
+from Components.config import ConfigYesNo
+from Components.config import getConfigListEntry
+from Components.ConfigList import ConfigListScreen
+from Components.ActionMap import ActionMap
+from Components.Button import Button
+
+from ConfigTextWithSuggestions import ConfigTextWithSuggestions
+
+from . import _
+
+playlistContext = Config()
+playlistContext.name = ConfigText(_("Name"), False)
+playlistContext.description = ConfigText(_("Description"), False)
+playlistContext.private = ConfigYesNo()
+
+
+class YouTubeAddPlaylistDialog(Screen, ConfigListScreen):
+ def __init__(self, session):
+ Screen.__init__(self, session)
+
+ self.session = session
+
+ self["actions"] = ActionMap(["YouTubeAddPlaylistActions"],
+ {
+ "save" : self.keySave,
+ "cancel" : self.keyCancel
+ }, -2)
+
+ self["key_red"] = Button(_("Cancel"))
+ self["key_green"] = Button(_("Save"))
+ self["key_yellow"] = Button("")
+ self["key_blue"] = Button("")
+
+ cfglist = []
+ cfglist.append(getConfigListEntry(_("Playlist Name"), playlistContext.name))
+ cfglist.append(getConfigListEntry(_("Playlist Description"), playlistContext.description))
+ cfglist.append(getConfigListEntry(_("private"), playlistContext.private))
+
+ ConfigListScreen.__init__(self, cfglist, session)
+
+
+ def keySave(self):
+ self.close(True, playlistContext)
+
+
+ def keyCancel(self):
+ self.close(False, playlistContext)
--- /dev/null
+############################################################################
+# Copyright (C) 2008 by Volker Christian #
+# Volker.Christian@fh-hagenberg.at #
+# #
+# This program is free software; you can redistribute it and#or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation; either version 2 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 General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program; if not, write to the #
+# Free Software Foundation, Inc., #
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
+############################################################################
+
+
+from Components.MenuList import MenuList
+from Screens.Screen import Screen
+from Components.ActionMap import ActionMap
+
+
+class YouTubeEntryContextMenuList(MenuList):
+ def __init__(self):
+ self.menuList = []
+ MenuList.__init__(self, self.menuList)
+
+
+ def appendEntry(self, entry):
+ self.menuList.append(entry)
+
+
+class YouTubeEntryContextMenu(Screen):
+ def __init__(self, session, menuList, title):
+ Screen.__init__(self, session)
+ self.tmpTitle = title
+
+ self["actions"] = ActionMap(["OkCancelActions"],
+ {
+ "ok": self.okbuttonClick,
+ "cancel": self.cancelClick
+ })
+ self["menu"] = menuList
+
+ self.onFirstExecBegin.append(self.setTitleDelaied)
+
+
+ def okbuttonClick(self):
+ self.close(self["menu"].getCurrent()[1])
+
+
+ def cancelClick(self):
+ self.close(None)
+
+
+ def setTitleDelaied(self):
+ self.setTitle(self.tmpTitle)
--- /dev/null
+############################################################################
+# Copyright (C) 2008 by Volker Christian #
+# Volker.Christian@fh-hagenberg.at #
+# #
+# This program is free software; you can redistribute it and#or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation; either version 2 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 General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program; if not, write to the #
+# Free Software Foundation, Inc., #
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
+############################################################################
+
+import gdata.youtube
+import gdata.youtube.service
+
+from gdata.service import BadAuthentication
+
+from Tools.LoadPixmap import LoadPixmap
+
+from twisted.web.client import downloadPage
+
+from urllib import urlretrieve, quote
+
+from httplib import HTTPConnection
+
+from socket import gaierror
+
+import os
+import re
+
+# http://code.google.com/apis/youtube/reference.html#youtube_data_api_tag_media:group
+
+
+class YouTubeUser():
+ def __init__(self, cfg):
+ self.cfg = cfg
+
+
+ def getCfg(self):
+ return self.cfg
+
+
+ def getName(self):
+ return self.cfg.name.value
+
+
+ def name(self):
+ return self.cfg.name
+
+
+ def getEmail(self):
+ return self.cfg.email.value
+
+
+ def email(self):
+ return self.cfg.email
+
+
+ def getPassword(self):
+ return self.cfg.password.value
+
+
+ def password(self):
+ return self.cfg.password
+
+
+ def login(self):
+ return interface.login(self)
+
+
+class YouTubeFeed():
+ def __init__(self, feed, favoritesFeed = False):
+ print "[YTB] YouTubeFeed::__init__()"
+ self.feed = feed
+ self.favoritesFeed = favoritesFeed
+ self.entries = []
+ self.update()
+
+
+ def update(self):
+ print "[YTB] YouTubeFeed::update()"
+ sequenceNumber = int(self.feed.start_index.text)
+ print self.feed.entry
+ for entry in self.feed.entry:
+ self.entries.append(YouTubeEntry(self, entry, sequenceNumber, self.favoritesFeed))
+ sequenceNumber = sequenceNumber + 1
+
+
+ def getTitle(self):
+ return self.feed.title.text
+
+
+ def getEntries(self):
+ print "[YTB] YouTubeFeed::getEntries()"
+ return self.entries
+
+
+ def itemCount(self):
+ print "[YTB] YouTubeFeed::itemCount()"
+ return self.feed.items_per_page.text
+
+
+ def getTotalResults(self):
+ return self.feed.total_results.text
+
+
+ def getNextFeed(self):
+ print "[YTB] YouTubeFeed::getNextFeed()"
+ for link in self.feed.link:
+ if link.rel == "next":
+ return link.href
+ return None
+
+
+ def getPreviousFeed(self):
+ print "[YTB] YouTubeFeed::getPreviousFeed()"
+ for link in self.feed.link:
+ if link.rel == "previous":
+ return link.href
+ return None
+
+
+ def getSelfFeed(self):
+ print "[YTB] YouTubeFeed::getSelfFeed()"
+ for link in self.feed.link:
+ if link.rel == "self":
+ return link.href
+ return None
+
+
+ def loadThumbnails(self, callback):
+ print "[YTB] YouTubeFeed::loadThumbnails()"
+ for entry in self.entries:
+ entry.loadThumbnails(callback)
+
+
+class YouTubeEntry():
+ def __init__(self, feed, entry, sequenceNumber, favoritesFeed = False):
+ print "[YTB] YouTubeEntry::__init__()"
+ self.feed = feed
+ self.entry = entry
+ self.sequenceNumber = sequenceNumber
+ self.favoritesFeed = favoritesFeed
+ self.thumbnail = {}
+
+
+ def isPlaylistEntry(self):
+ return False
+
+
+ def getYouTubeId(self):
+ print "[YTB] YouTubeEntry::getYouTubeId()"
+ return self.entry.media.player.url.split("=").pop()
+
+
+ def getTitle(self):
+ print "[YTB] YouTubeEntry::getTitle()"
+ return self.entry.media.title.text
+
+
+ def getDescription(self):
+ print "[YTB] YouTubeEntry::getDescription()"
+ return self.entry.media.description.text
+
+
+ def getThumbnailUrl(self, index):
+ print "[YTB] YouTubeEntry::getThumbnailUrl"
+ if index < len(self.entry.media.thumbnail):
+ return self.entry.media.thumbnail[index].url
+ return None
+
+
+ def getRelatedFeed(self):
+ print "[YTB] YouTubeEntry::getRelatedFeed()"
+ for link in self.entry.link:
+ print "Related link: ", link.rel.endswith
+ if link.rel.endswith("video.related"):
+ print "Found Related: ", link.href
+ return link.href
+
+
+ def getResponsesFeed(self):
+ print "[YTB] YouTubeEntry::getResponseFeed()"
+ for link in self.entry.link:
+ print "Responses link: ", link.rel.endswith
+ if link.rel.endswith("video.responses"):
+ print "Found Responses: ", link.href
+ return link.href
+
+
+ def loadThumbnail(self, index, callback):
+ print "[YTB] YouTubeEntry::loadThumbnail()"
+ thumbnailUrl = self.getThumbnailUrl(index)
+ if thumbnailUrl is not None and self.getYouTubeId() is not None:
+ thumbnailFile = "/tmp/" + self.getYouTubeId() + "_" + str(index) + ".jpg"
+ self.thumbnail[str(index)] = None
+ cookie = {"entry" : self, "file" : thumbnailFile, "callback" : callback, "index" : index}
+ downloadPage(thumbnailUrl, thumbnailFile).addCallback(fetchFinished, cookie).addErrback(fetchFailed, cookie)
+
+
+ def loadThumbnails(self, callback):
+ print "[YTB] YouTubeEntry::loadThumbnails()"
+ self.loadThumbnail(0, callback)
+
+
+ def getVideoUrl(self, fmt):
+ conn = HTTPConnection("www.youtube.com")
+ conn.request("GET", "/v/" + quote(self.getYouTubeId()))
+ response = conn.getresponse()
+ conn.close()
+ mrl = None
+ print "[YTB] Response: ", response.status, response.reason
+ if response.status == 303:
+ location = response.getheader("location")
+ mrl = "http://www.youtube.com/get_video?video_id=" + quote(self.getYouTubeId()) + "&t=" + quote(re.match (".*[?&]t=([^&]+)", location).groups()[0]) + fmt
+ print "[YTB] Playing ", mrl
+ else:
+ print "[YTB] No valid flv-mrl found"
+ return mrl
+
+
+ def getDuration(self):
+ if self.entry.media is not None and self.entry.media.duration is not None:
+ return self.entry.media.duration.seconds
+ return "not available"
+
+
+ def getRatingAverage(self):
+ if self.entry.rating is not None:
+ return self.entry.rating.average
+ return "not available"
+
+
+ def getNumRaters(self):
+ if self.entry.rating is not None:
+ return self.entry.rating.num_raters
+ return ""
+
+
+ def getRatingMax(self):
+ if self.entry.rating is not None:
+ return self.entry.rating.max
+ return "not available"
+
+ def getRatingMin(self):
+ if self.entry.rating is not None:
+ return self.entry.rating.min
+ return "not available"
+
+
+ def getFavoriteCount(self):
+ if self.entry.statistics is not None:
+ return self.entry.statistics.favorite_count
+ return "not available"
+
+
+ def getViewCount(self):
+ if self.entry.statistics is not None:
+ return self.entry.statistics.view_count
+ return "not available"
+
+
+ def getAuthor(self):
+ authorList = []
+ for author in self.entry.author:
+ authorList.append(author.name.text)
+ authors = ", ".join(authorList)
+ return authors
+
+
+ def getPublishedOn(self):
+ if self.entry.published is not None:
+ return self.entry.published.text
+ return "unknown"
+
+
+ def getCategory(self):
+ return self.entry.GetYouTubeCategoryAsString()
+
+
+ def getTags(self):
+ if self.entry.media is not None and self.entry.media.keywords is not None:
+ return self.entry.media.keywords.text
+ return "not available"
+
+
+ def belongsToFavorites(self):
+ return self.favoritesFeed
+
+
+ def belongsToPlaylistId(self):
+ return self.playlistId
+
+
+class YouTubePlaylistFeed():
+ def __init__(self, feed):
+ print "[YTB] YouTubePlayListFeed::__init__()"
+ self.feed = feed
+ self.entries = []
+ self.update()
+
+
+ def update(self):
+ print "[YTB] YouTubePlayListFeed::update()"
+ for entry in self.feed.entry:
+ self.entries.append(YouTubePlaylistEntry(entry))
+
+
+ def getTitle(self):
+ print "[YTB] YouTubePlayListFeed::getTitle()"
+ return self.feed.title.text
+
+
+ def getEntries(self):
+ print "[YTB] YouTubePlayListFeed::getEntries()"
+ return self.entries
+
+
+class YouTubePlaylistEntry():
+ def __init__(self, entry):
+ print "[YTB] YouTubePlaylistEntry::__init__()"
+ self.entry = entry
+
+
+ def getTitle(self):
+ print "[YTB] YouTubePlaylistEntry::getTitle()"
+ return self.entry.title.text
+
+
+ def getDescription(self):
+ print "[YTB] YouTubePlaylistEntry::getDescription()"
+ return self.entry.description.text
+
+
+ def getFeed(self, index = 0):
+ print "[YTB] YouTubePlaylistEntry::getFeed()"
+ return self.entry.feed_link[index].href
+
+
+ def getSelfFeed(self):
+ print "[YTB] YouTubeFeed::getSelfFeed()"
+ for link in self.entry.link:
+ if link.rel == "self":
+ return link.href
+ return None
+
+
+class YouTubePlaylistVideoFeed(YouTubeFeed):
+ def __init__(self, feed):
+ print "[YTB] YouTubePlaylistVideoFeed::__init__()"
+ YouTubeFeed.__init__(self, feed)
+
+
+ def update(self):
+ print "[YTB] YouTubePlaylistVideoFeed::update()"
+ sequenceNumber = 1
+ print self.feed.entry
+ for entry in self.feed.entry:
+ self.entries.append(YouTubePlaylistVideoEntry(self, entry, sequenceNumber))
+ sequenceNumber = sequenceNumber + 1
+
+ def getFeed(self):
+ print "[YTB] YouTubeFeed::getSelfFeed()"
+ for link in self.feed.link:
+ if link.rel == "feed":
+ return link.href
+ return None
+
+
+class YouTubePlaylistVideoEntry(YouTubeEntry):
+ def __init__(self, feed, entry, sequenceNumber):
+ print "[YTB] YouTubePlaylistVideoEntry::__init__()"
+ YouTubeEntry.__init__(self, feed, entry, sequenceNumber)
+
+
+ def isPlaylistEntry(self):
+ return True
+
+
+ def getSelf(self):
+ print "[YTB] YouTubePlaylistVideoEntry::getSelfFeed()"
+ for link in self.entry.link:
+ if link.rel == "self":
+ return link.href
+ return None
+
+
+ YOUTUBE_DEVELOPER_TAG_SCHEME = "http://gdata.youtube.com/schemas/2007/developertags.cat"
+ def getCategory(self):
+ for category in self.entry.media.category:
+ if category.scheme != YouTubePlaylistVideoEntry.YOUTUBE_DEVELOPER_TAG_SCHEME:
+ return category.text
+ return "not available"
+
+
+class YouTubeInterface():
+# Do not change the client_id and developer_key in the login-section!
+# ClientId: ytapi-VolkerChristian-YouTubePlayer-pq3mrg1o-0
+# DeveloperKey: AI39si7t0WNyg_tvjBPdRIvBfaUA_XrTY1LNzfjLgCn8A_m92YKtWTcR_auEmI5gKGitJb4SskrjxJSmRc3yhQ4YlHTBAzPSig
+ def __init__(self):
+ print "[YTB] YouTubeInterface::__init__()"
+
+
+ def open(self):
+ self.ytService = gdata.youtube.service.YouTubeService()
+ print "[YTB] YouTubeInterface::open()"
+ self.loggedIn = False
+
+
+ def close(self):
+ print "[YTB] YouTubeInterface::close()"
+ del self.ytService
+ self.loggedIn = False
+
+
+ def login(self, user):
+ print "[YTB] YouTubeInterface::login()"
+ ret = False
+ if user is not None:
+ try:
+ # http://code.google.com/apis/youtube/developers_guide_python.html#ClientLogin
+ self.ytService.email = user.getEmail()
+ self.ytService.password = user.getPassword()
+ self.ytService.source = 'my-example-application'
+ self.ytService.developer_key = "AI39si7t0WNyg_tvjBPdRIvBfaUA_XrTY1LNzfjLgCn8A_m92YKtWTcR_auEmI5gKGitJb4SskrjxJSmRc3yhQ4YlHTBAzPSig"
+ self.ytService.client_id = "ytapi-VolkerChristian-YouTubePlayer-pq3mrg1o-0"
+ self.ytService.ProgrammaticLogin()
+ except BadAuthentication:
+ pass
+ else:
+ self.loggedIn = True
+ ret = True
+ return ret
+
+
+ def isLoggedIn(self):
+ return self.loggedIn
+
+
+ def search(self, searchTerms, startIndex = 1, maxResults = 25,
+ orderby = "relevance", time = "all_time", racy = "include",
+ author = ""):
+ print "[YTB] YouTubeInterface::search()"
+ query = gdata.youtube.service.YouTubeVideoQuery()
+ query.vq = searchTerms
+ query.orderby = orderby
+ query.racy = racy
+ query.start_index = startIndex
+ query.max_results = maxResults
+ try:
+ feed = YouTubeFeed(self.ytService.YouTubeQuery(query))
+ except gaierror:
+ feed = None
+ return feed
+
+
+ def getFeed(self, url):
+ return YouTubeFeed(self.ytService.GetYouTubeVideoFeed(url))
+
+
+ def getUserFavoritesFeed(self, userName = "default"):
+ return YouTubeFeed(self.ytService.GetUserFavoritesFeed(userName), favoritesFeed = True)
+
+
+ def getUserPlaylistFeed(self, playlistEntry):
+ print "[YTB] getUserPlaylistFeed: ", playlistEntry.getFeed()
+ return YouTubePlaylistVideoFeed(self.ytService.GetYouTubePlaylistVideoFeed(playlistEntry.getFeed()))
+
+
+ def addToFavorites(self, entry):
+ response = self.ytService.AddVideoEntryToFavorites(entry.entry)
+ # The response, if succesfully posted is a YouTubeVideoEntry
+ if isinstance(response, gdata.youtube.YouTubeVideoEntry):
+ print "[YTB] Video successfully added to favorites"
+ return response
+ else:
+ return None
+
+
+ def removeFromFavorites(self, entry):
+ response = self.ytService.DeleteVideoEntryFromFavorites(entry.getYouTubeId())
+ if response is True:
+ print "[YTB] Video deleted from favorites"
+ return response
+
+
+ def getPlaylistFeed(self):
+ return YouTubePlaylistFeed(self.ytService.GetYouTubePlaylistFeed())
+
+
+ def addPlaylist(self, name, description, private):
+ newPlaylist = None
+ newPlaylistEntry = self.ytService.AddPlaylist(name, description, private)
+ if isinstance(newPlaylistEntry, gdata.youtube.YouTubePlaylistEntry):
+ newPlaylist = YouTubePlaylistEntry(newPlaylistEntry)
+ return newPlaylist
+
+
+ def deletePlaylist(self, playlistEntry):
+ playListUrl = playlistEntry.getSelfFeed()
+ return self.ytService.DeletePlaylist(playListUrl)
+
+
+ def removeFromPlaylist(self, playlistVideoEntry):
+ print "[YTB] Removing from Playlist"
+ response = self.ytService.Delete(playlistVideoEntry.getSelf())
+ if response:
+ print "[YTB] Successfull deleted"
+ else:
+ print "[YTB] Delete unsuccessfull"
+ return response
+
+
+ def addToPlaylist(self, playlistEntry, videoEntry):
+ print "[YTB] Adding to Playlist"
+ playlistUri = playlistEntry.getFeed()
+ response = self.ytService.AddPlaylistVideoEntryToPlaylist(
+ playlistUri, videoEntry.getYouTubeId(), videoEntry.getTitle(), videoEntry.getDescription())
+ if isinstance(response, gdata.youtube.YouTubePlaylistVideoEntry):
+ print "[YTB] Video added"
+ return response
+ else:
+ return None
+
+
+def fetchFailed(string, cookie):
+ print "[YTB] fetchFailed(): ", string
+ if os.path.exists(cookie["file"]):
+ os.remove(cookie["file"])
+ cookie["callback"](cookie["entry"])
+
+
+def fetchFinished(string, cookie):
+ print "[YTB] fetchFinished(): ", string
+ if os.path.exists(cookie["file"]):
+ print "Loading filename %s" % cookie["file"]
+ cookie["entry"].thumbnail[str(cookie["index"])] = LoadPixmap(cookie["file"])
+ os.remove(cookie["file"])
+ cookie["callback"](cookie["entry"])
+
+
+interface = YouTubeInterface()
--- /dev/null
+############################################################################
+# Copyright (C) 2008 by Volker Christian #
+# Volker.Christian@fh-hagenberg.at #
+# #
+# This program is free software; you can redistribute it and#or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation; either version 2 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 General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program; if not, write to the #
+# Free Software Foundation, Inc., #
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
+############################################################################
+
+from YouTubeInterface import interface
+
+from Components.ActionMap import ActionMap
+from Components.MenuList import MenuList
+from Components.Label import Label
+from Components.ScrollLabel import ScrollLabel
+from Components.Pixmap import Pixmap
+from Components.ProgressBar import ProgressBar
+
+from Components.MultiContent import MultiContentEntryText, MultiContentEntryPixmapAlphaTest
+from Tools.Directories import resolveFilename, SCOPE_PLUGINS, SCOPE_SKIN_IMAGE
+from enigma import eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT, RT_VALIGN_TOP, RT_WRAP
+from enigma import eTimer
+
+from Tools.NumericalTextInput import NumericalTextInput
+
+from Screens.Screen import Screen
+from Screens.MessageBox import MessageBox
+
+from Components.config import config
+
+from Plugins.Extensions.VlcPlayer.VlcServerConfig import vlcServerConfig
+from Plugins.Extensions.VlcPlayer.VlcServer import VlcServer
+from Plugins.Extensions.VlcPlayer.VlcServerList import VlcServerListScreen
+
+from YouTubeContextMenu import YouTubeEntryContextMenu, YouTubeEntryContextMenuList
+
+from Tools.BoundFunction import boundFunction
+
+from YouTubePlayer import YouTubePlayer
+
+from YouTubeUserConfig import youTubeUserConfig
+from YouTubeUserList import YouTubeUserListScreen
+from YouTubePlayList import YouTubePlaylistScreen
+
+from . import _
+
+def YouTubeEntryComponent(entry):
+ res = [ entry ]
+# 385
+ res.append(MultiContentEntryText(pos = (150, 5), size = (370, 42), font = 0, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = entry.getTitle()))
+ res.append(MultiContentEntryText(pos = (150, 46), size = (370, 56), font = 1, color = 0xFFA323, color_sel = 0xFFA323, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = entry.getDescription()))
+
+ if entry.thumbnail["0"] is None:
+ png = LoadPixmap(resolveFilename(SCOPE_SKIN_IMAGE, "skin_default/icons/plugin.png"))
+ else:
+ png = entry.thumbnail["0"]
+ res.append(MultiContentEntryPixmapAlphaTest(pos = (10, 5), size = (130, 97), png = png))
+
+ return res
+
+
+class YouTubeVideoDetailsScreen(Screen):
+ def __init__(self, session, entry):
+ Screen.__init__(self, session)
+ self.entry = entry
+ self["video_description"] = ScrollLabel(entry.getDescription())
+ durationInSecs = int(entry.getDuration())
+ mins = int(durationInSecs / 60)
+ secs = durationInSecs - mins * 60
+ duration = "%d:%02d" % (mins, secs)
+
+ self["label_video_duration"] = Label(_("Duration") + ":")
+ self["video_duration"] = Label(duration)
+
+ self["label_video_rating_average"] = Label(_("Rate") + ":")
+ self["starsbg"] = Pixmap()
+ self["stars"] = ProgressBar()
+
+ self["label_video_numraters"] = Label(_("Ratings") + ":")
+ self["video_numraters"] = Label(entry.getNumRaters())
+
+ self["label_video_statistics_favorite_count"] = Label(_("Favorited") + ":")
+ self["video_statistics_favorite_count"] = Label(entry.getFavoriteCount())
+
+ self["label_video_statistics_view_count"] = Label(_("Views") + ":")
+ self["video_statistics_view_count"] = Label(entry.getViewCount())
+
+ self["label_video_author"] = Label(_("Author:") + ":")
+ self["video_author"] = Label(entry.getAuthor())
+
+ self["label_video_published_on"] = Label(_("Added") + ":")
+ self["video_published_on"] = Label(entry.getPublishedOn().split("T")[0])
+
+ self["label_video_category"] = Label(_("Category") + ":")
+ self["video_category"] = Label(entry.getCategory())
+ self["label_video_tags"] = Label(_("Tags") + ":")
+ self["video_tags"] = Label(entry.getTags())
+
+ self["video_thumbnail_1"] = Pixmap()
+ self["video_thumbnail_2"] = Pixmap()
+ self["video_thumbnail_3"] = Pixmap()
+
+ self["actions"] = ActionMap(["YouTubeVideoDetailsScreenActions"],
+ {
+ "ok" : self.close,
+ "cancel" : self.close,
+ "up" : self.pageUp,
+ "down" : self.pageDown,
+ "left" : self.pageUp,
+ "right" : self.pageDown
+ })
+
+ self.onFirstExecBegin.append(self.setPixmap)
+ self.onFirstExecBegin.append(self.setInitialize)
+
+
+ def pageUp(self):
+ self["video_description"].pageUp()
+
+
+ def pageDown(self):
+ self["video_description"].pageDown()
+
+
+ def setInitialize(self):
+ Screen.setTitle(self, self.entry.getTitle())
+ if self.entry.getRatingAverage() != "not available":
+ ratingStars = int(round(20 * float(self.entry.getRatingAverage()), 0))
+ print "[YTB] Rating: ", ratingStars, " ", self["stars"].getRange()
+ self["stars"].setValue(ratingStars)
+ else:
+ self["stars"].hide()
+ self["starsbg"].hide()
+
+
+ def setPixmap(self):
+ self["video_thumbnail_1"].instance.setPixmap(self.entry.thumbnail["0"].__deref__())
+ self.entry.loadThumbnail(1, self.setThumbnail_2)
+ self.entry.loadThumbnail(2, self.setThumbnail_3)
+ self["video_thumbnail_2"].hide()
+ self["video_thumbnail_3"].hide()
+
+
+ def setThumbnail_2(self, entry):
+ self["video_thumbnail_2"].instance.setPixmap(self.entry.thumbnail["1"].__deref__())
+ self["video_thumbnail_2"].show()
+
+
+ def setThumbnail_3(self, entry):
+ self["video_thumbnail_3"].instance.setPixmap(self.entry.thumbnail["2"].__deref__())
+ self["video_thumbnail_3"].show()
+
+
+class PatientMessageBox(MessageBox):
+ def __init__(self, session, text, type = 1, timeout = -1, close_on_any_key = False, default = True):
+ MessageBox.__init__(self, session, text, type, timeout, close_on_any_key, default)
+ self.skinName = "MessageBox"
+
+
+ def processDelayed(self, function):
+ self.delay_timer = eTimer()
+ self.delay_timer.callback.append(self.processDelay)
+ self.delay_timer.start(0, 1)
+ self.function = function
+
+
+ def processDelay(self):
+ self.function()
+
+
+ def cancel(self):
+ pass
+
+
+ def ok(self):
+ pass
+
+
+ def alwaysOK(self):
+ pass
+
+
+class YouTubeList(MenuList):
+ def __init__(self, list, enableWrapAround = False):
+ MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent)
+ self.l.setFont(0, gFont("Regular", 18))
+ self.l.setFont(1, gFont("Regular", 14))
+ self.l.setItemHeight(105)
+
+
+class YouTubeListScreen(Screen, NumericalTextInput):
+ def __init__(self, session):
+ Screen.__init__(self, session)
+ NumericalTextInput.__init__(self)
+
+ self.session = session
+ self.serverName = config.plugins.youtubeplayer.serverprofile.value
+ self.currentServer = vlcServerConfig.getServerByName(self.serverName)
+
+ self["red"] = Label(_("Select a VLC-Server"))
+ self["green"] = Label(_("New YouTube search"))
+
+ self.list = []
+ self["list"] = YouTubeList(self.list)
+
+ self["label_total_results"] = Label(_("Total results") + ":")
+ self["total_results"] = Label("")
+
+ self["label_currently_shown"] = Label(_("Shown") + ":")
+ self["currently_shown"] = Label("")
+
+ self.history = []
+ self.historyIndex = 0
+
+ self.isFavoritesFeed = False
+
+ self.patientDialog = None
+
+ self["actions"] = ActionMap(["YouTubeVideoListActions"],
+ {
+ "play" : self.tryToPlay,
+ "select" : self.justSelectServer,
+ "search" : self.searchAgain,
+ "menu" : self.openContextMenu,
+ "forward" : self.forwardInHistory,
+ "backward" : self.backInHistory,
+ "left" : self.keyLeft,
+ "right" : self.keyRight,
+ "up" : self.keyUp,
+ "down" : self.keyDown,
+ "info" : self.showVideoInfo,
+ "cancel" : self.close
+ }, -1)
+
+
+ def keyLeft(self):
+ self["list"].pageUp()
+
+
+ def keyRight(self):
+ if self["list"].getSelectionIndex() == len(self.list) - 1 and self.feed.getNextFeed() is not None:
+ dlg = self.session.openWithCallback(self.loadNextFeed, MessageBox, _("Load further entries of current Feed?"))
+ else:
+ self["list"].pageDown()
+
+
+ def keyUp(self):
+ self["list"].up()
+
+
+ def keyDown(self):
+ if self["list"].getSelectionIndex() == len(self.list) - 1 and self.feed.getNextFeed() is not None:
+ dlg = self.session.openWithCallback(self.loadNextFeed, MessageBox, _("Load further entries of current Feed?"))
+ else:
+ self["list"].down()
+
+
+ def insertEntry(self, entry):
+ print "[YTB] YouTubeTest::updateFinished()"
+ self.list.append(YouTubeEntryComponent(entry))
+ self.list.sort(cmp = lambda x, y : cmp(x[0].sequenceNumber, y[0].sequenceNumber))
+ currentlyShown = "%d" % len(self.list)
+ self["currently_shown"].setText(currentlyShown)
+ self["list"].setList(self.list)
+
+
+ def closePatientDialogDelayed(self):
+ if self.patientDialog:
+ self.patientDialog.close()
+ self.patientDialog = None
+ self["list"].setList(self.list)
+
+
+ def showFeed(self, feed, append):
+ self.feed = feed
+ self.setTitle(feed.getTitle())
+ self["total_results"].setText(feed.getTotalResults())
+ if not append:
+ self.list = []
+ self["list"].setList(self.list)
+ self.feed.loadThumbnails(self.insertEntry)
+ self.delay_timer = eTimer()
+ self.delay_timer.callback.append(self.closePatientDialogDelayed)
+ self.delay_timer.start(100, 1)
+
+
+ def addToHistory(self, feed):
+ del self.history[self.historyIndex : len(self.history)]
+ self.history.insert(self.historyIndex, feed.getSelfFeed())
+ self.historyIndex = self.historyIndex + 1
+
+
+ def searchFeedReal(self, searchContext):
+ print "[YTB] youTubeTest"
+ feed = interface.search(searchContext.searchTerm.value)
+ self.showFeed(feed, False)
+ self.addToHistory(feed)
+
+
+ def searchFeed(self, searchContext):
+ self.patientDialog = self.session.open(PatientMessageBox, _("Searching, be patient ..."))
+ self.patientDialog.processDelayed(boundFunction(self.searchFeedReal, searchContext = searchContext))
+ self.isFavoritesFeed = False
+
+
+ def loadPlaylistFeedReal(self, playlist):
+ feed = interface.getUserPlaylistFeed(playlist)
+ self.showFeed(feed, False)
+ self.addToHistory(feed)
+
+
+ def loadPlaylistFeed(self, playlist):
+ self.patientDialog = self.session.open(PatientMessageBox, _("Loading playlist, be patient ..."))
+ self.patientDialog.processDelayed(boundFunction(self.loadPlaylistFeedReal, playlist = playlist))
+
+
+ def loadFavoritesFeedReal(self, userName = "default"):
+ feed = interface.getUserFavoritesFeed(userName)
+ self.showFeed(feed, False)
+ self.addToHistory(feed)
+
+
+ def loadFavoritesFeed(self, userName = "default"):
+ self.patientDialog = self.session.open(PatientMessageBox, _("Loading favorits, be patient ..."))
+ self.patientDialog.processDelayed(boundFunction(self.loadFavoritesFeedReal, userName = userName))
+ self.isFavoritesFeed = True
+
+
+ def loadStandardFeed(self, url):
+ self.loadFeed(_("Loading standard feed, be patient ..."), url)
+
+
+ def loadFeedReal(self, feedUrl, append = False, addToHistory = True):
+ feed = interface.getFeed(feedUrl)
+ self.showFeed(feed, append)
+ if addToHistory:
+ self.addToHistory(feed)
+
+
+ def loadFeed(self, text, feedUrl, append = False, addToHistory = True):
+ self.patientDialog = self.session.open(PatientMessageBox, text)
+ self.patientDialog.processDelayed(boundFunction(self.loadFeedReal, feedUrl = feedUrl,
+ append = append, addToHistory = addToHistory))
+
+
+ def loadPreviousFeed(self, result):
+ if not result:
+ return
+ prevUrl = self.feed.getPreviousFeed()
+ if prevUrl is not None:
+ self.loadFeed(_("Loading additional videos, be patient ..."), prevUrl, True, True)
+
+
+ def loadNextFeed(self, result):
+ if not result:
+ return
+ nextUrl = self.feed.getNextFeed()
+ if nextUrl is not None:
+ self.loadFeed(_("Loading additional videos, be patient ..."), nextUrl, True, True)
+
+
+ def getRelated(self):
+ self.loadFeed(_("Loading related videos, be patient ..."), self["list"].getCurrent()[0].getRelatedFeed(), False, True)
+ self.isFavoritesFeed = False
+
+
+ def getResponses(self):
+ self.loadFeed(_("Loading response videos, be patient ..."), self["list"].getCurrent()[0].getResponsesFeed(), False, True)
+ self.isFavoritesFeed = False
+
+
+ def backInHistory(self):
+ if self.historyIndex > 1:
+ self.historyIndex = self.historyIndex - 1
+ self.loadFeed(_("Back in history, be patient ..."), self.history[self.historyIndex - 1], False, False)
+
+
+ def forwardInHistory(self):
+ if self.historyIndex < len(self.history):
+ self.historyIndex = self.historyIndex + 1
+ self.loadFeed(_("Forward in history, be patient ..."), self.history[self.historyIndex - 1], False, False)
+
+
+ def showVideoInfo(self):
+ self.session.open(YouTubeVideoDetailsScreen, self["list"].getCurrent()[0])
+
+
+ def justSelectServer(self):
+ defaultServer = vlcServerConfig.getServerByName(config.plugins.youtubeplayer.serverprofile.value)
+ self.selectServer(self.serverSelectedCB, defaultServer)
+
+
+ def selectServer(self, callback, currentServer):
+ self.session.openWithCallback(callback, VlcServerListScreen, currentServer)
+
+
+ def serverSelectedCB(self, selectedServer, defaultServer):
+ if selectedServer is not None:
+ self.currentServer = selectedServer
+ elif defaultServer is not None:
+ self.currentServer = defaultServer
+ if defaultServer is not None:
+ config.plugins.youtubeplayer.serverprofile.value = defaultServer.getName()
+ config.plugins.youtubeplayer.serverprofile.save()
+
+
+ def selectAndPlayCB(self, selectedServer, defaultServer):
+ self.serverSelectedCB(selectedServer, defaultServer)
+ self.tryToPlay()
+
+
+ def tryToPlay(self):
+ if self.currentServer is not None:
+ self.play()
+ else:
+ self.selectServer(self.selectAndPlayCB, None)
+
+
+ def login(self, callback):
+ self.session.openWithCallback(callback, YouTubeUserListScreen, youTubeUserConfig.getDefaultUser())
+
+
+ def addToFavoritesReal(self):
+ interface.addToFavorites(self["list"].getCurrent()[0])
+
+
+ def addToFavoritesLogin(self, loginState):
+ if loginState == YouTubeUserListScreen.LOGIN_SUCCESS:
+ self.addToFavoritesReal()
+ elif loginState == YouTubeUserListScreen.LOGIN_FAILED:
+ self.session.open(MessageBox, _("Login not successful"), MessageBox.TYPE_INFO)
+ else:
+ pass
+
+
+ def addToFavorites(self):
+ if not interface.isLoggedIn():
+ self.login(self.addToFavoritesLogin)
+ else:
+ self.addToFavoritesReal()
+
+
+ def removeFromFavoritesReal(self):
+ if interface.removeFromFavorites(self["list"].getCurrent()[0]):
+ self.list.remove(self["list"].getCurrent())
+ self["list"].setList(self.list)
+
+
+ def removeFromFavoritesLogin(self, loginState):
+ if loginState == YouTubeUserListScreen.LOGIN_SUCCESS:
+ self.removeFromFavoritesReal()
+ elif loginState == YouTubeUserListScreen.LOGIN_FAILED:
+ self.session.open(MessageBox, _("Login not successful"), MessageBox.TYPE_INFO)
+ else:
+ pass
+
+
+ def removeFromFavorites(self):
+ if not interface.isLoggedIn():
+ self.login(self.removeFromFavoritesLogin)
+ else:
+ self.removeFromFavoritesReal()
+
+
+ def removeFromPlaylistReal(self):
+ if interface.removeFromPlaylist(self["list"].getCurrent()[0]):
+ self.list.remove(self["list"].getCurrent())
+ self["list"].setList(self.list)
+
+
+ def removeFromPlaylistLogin(self, loginState):
+ if loginState == YouTubeUserListScreen.LOGIN_SUCCESS:
+ self.removeFromPlaylistReal()
+ elif loginState == YouTubeUserListScreen.LOGIN_FAILED:
+ self.session.open(MessageBox, _("Login not successful"), MessageBox.TYPE_INFO)
+ else:
+ pass
+
+
+ def removeFromPlaylist(self):
+ if not interface.isLoggedIn():
+ self.login(self.removeFromPlaylistLogin)
+ else:
+ self.removeFromPlaylistReal()
+
+
+ def playlistChoosen(self, playlist):
+ if playlist is not None:
+ interface.addToPlaylist(playlist, self["list"].getCurrent()[0])
+
+
+ def addToPlaylistReal(self):
+ dlg = self.session.openWithCallback(self.playlistChoosen, YouTubePlaylistScreen)
+ dlg.loadPlaylist()
+
+
+ def addToPlaylistLogin(self, loginState):
+ if loginState == YouTubeUserListScreen.LOGIN_SUCCESS:
+ self.addToPlaylistReal()
+ elif loginState == YouTubeUserListScreen.LOGIN_FAILED:
+ self.session.open(MessageBox, _("Login not successful"), MessageBox.TYPE_INFO)
+ else:
+ pass
+
+
+ def addToPlaylist(self):
+ if not interface.isLoggedIn():
+ self.login(self.addToPlaylistLogin)
+ else:
+ self.addToPlaylistReal()
+
+
+# http://cacan.blog385.com/index.php/2008/05/09/youtube-high-quality-hacks/
+# add the &fmt=6 onto the end:
+#
+# http://youtube.com/watch?v=CQzUsTFqtW0&fmt=6
+#
+# If the YouTube video just sits there loading then that
+# is a sign that the video has not been converted to the
+# higher resolution yet. To really see the difference you
+# should view the video in full screen mode by clicking
+# the button in the bottom-right corner of the player.
+#
+# Note: Alternatively you can add &fmt=18 and it will play
+# the high-resolution version when available, otherwise it
+# will play the regular version. Here?s a Greasemonkey
+# script that will automatically add &fmt=18 onto the end
+# of each YouTube URL.
+ def play(self):
+ print "[YTB] Play()"
+ youTubeEntry = self["list"].getCurrent()[0]
+ mrl = youTubeEntry.getVideoUrl("&fmt=18")
+############## To be resolved
+#Traceback (most recent call last):
+# File "/usr/lib/enigma2/python/Components/ActionMap.py", line 46, in action
+# res = self.actions[action]()
+# File "/usr/lib/enigma2/python/Plugins/Extensions/YouTubePlayer/YouTubeList.py", line 425, in tryToPlay
+# self.play()
+# File "/usr/lib/enigma2/python/Plugins/Extensions/YouTubePlayer/YouTubeList.py", line 543, in play
+# mrl = youTubeEntry.getVideoUrl("&fmt=18")
+# File "/usr/lib/enigma2/python/Plugins/Extensions/YouTubePlayer/YouTubeInterface.py", line 216, in getVideoUrl
+# conn.request("GET", "/v/" + quote(self.getYouTubeId()))
+# File "/usr/lib/python2.5/httplib.py", line 862, in request
+# self._send_request(method, url, body, headers)
+# File "/usr/lib/python2.5/httplib.py", line 885, in _send_request
+# self.endheaders()
+# File "/usr/lib/python2.5/httplib.py", line 856, in endheaders
+# self._send_output()
+# File "/usr/lib/python2.5/httplib.py", line 728, in _send_output
+# self.send(msg)
+# File "/usr/lib/python2.5/httplib.py", line 695, in send
+# self.connect()
+# File "/usr/lib/python2.5/httplib.py", line 663, in connect
+# socket.SOCK_STREAM):
+#socket.gaierror: (2, 'temporary failure in name resolution.')
+
+ if mrl is not None:
+ entries = []
+ entries.append((_("Show video detail info"), [self.showVideoInfo, False]))
+ if self["list"].getCurrent()[0].belongsToFavorites():
+ entries.append((_("Remove from favorites"), [self.removeFromFavorites, False]))
+ else:
+ entries.append((_("Add to favorites"), [self.addToFavorites, False]))
+
+ if self["list"].getCurrent()[0].isPlaylistEntry():
+ entries.append((_("Remove from playlist"), [self.removeFromPlaylist, False]))
+ else:
+ entries.append((_("Add to playlist"), [self.addToPlaylist, False]))
+ entries.append((_("Get related videos"), [self.getRelated, True]))
+ entries.append((_("Get video responses"), [self.getResponses, True]))
+
+ self.currentServer.play(self.session, mrl, youTubeEntry.getTitle(), self,
+ player = boundFunction(YouTubePlayer, contextMenuEntries = entries, infoCallback = self.showVideoInfo, name = self["list"].getCurrent()[0].getTitle()))
+ else:
+ print "[YTB] No valid flv-mrl found"
+
+
+ def getNextFile(self):
+ i = self["list"].getSelectedIndex() + 1
+ if i < len(self.list):
+ self["list"].moveToIndex(i)
+ youTubeEntry = self["list"].getCurrent()[0]
+ return youTubeEntry.getVideoUrl("&fmt=18"), youTubeEntry.getTitle()
+ return None, None
+
+
+ def getPrevFile(self):
+ i = self["list"].getSelectedIndex() - 1
+ if i >= 0:
+ self["list"].moveToIndex(i)
+ youTubeEntry = self["list"].getCurrent()[0]
+ return youTubeEntry.getVideoUrl("&fmt=18"), youTubeEntry.getTitle()
+ return None, None
+
+
+ def openContextMenu(self):
+ contextMenuList = YouTubeEntryContextMenuList()
+ contextMenuList.appendEntry((_("Show video detail info"), self.showVideoInfo))
+ if self["list"].getCurrent()[0].belongsToFavorites():
+ contextMenuList.appendEntry((_("Remove from favorites"), self.removeFromFavorites))
+ else:
+ contextMenuList.appendEntry((_("Add to favorites"), self.addToFavorites))
+ if self["list"].getCurrent()[0].isPlaylistEntry():
+ contextMenuList.appendEntry((_("Remove from playlist"), self.removeFromPlaylist))
+ else:
+ contextMenuList.appendEntry((_("Add to playlist"), self.addToPlaylist))
+ contextMenuList.appendEntry((_("Get related videos"), self.getRelated))
+ contextMenuList.appendEntry((_("Get video responses"), self.getResponses))
+ self.session.openWithCallback(self.menuActionCoosen, YouTubeEntryContextMenu, contextMenuList, self["list"].getCurrent()[0].getTitle())
+
+
+ def menuActionCoosen(self, function):
+ if function is not None:
+ function()
+
+
+ def searchAgain(self):
+ Screen.close(self, True)
+
+
+ def close(self):
+ Screen.close(self, False)
\ No newline at end of file
--- /dev/null
+############################################################################
+# Copyright (C) 2008 by Volker Christian #
+# Volker.Christian@fh-hagenberg.at #
+# #
+# This program is free software; you can redistribute it and#or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation; either version 2 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 General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program; if not, write to the #
+# Free Software Foundation, Inc., #
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
+############################################################################
+
+from YouTubeInterface import interface
+from YouTubeAddPlayList import YouTubeAddPlaylistDialog
+from Components.ActionMap import ActionMap
+from Components.MenuList import MenuList
+from Components.Label import Label
+from Components.MultiContent import MultiContentEntryText
+from Screens.MessageBox import MessageBox
+from Screens.Screen import Screen
+from enigma import eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT, RT_VALIGN_TOP, RT_WRAP
+
+from . import _
+
+
+def YouTubePlaylistEntryComponent(entry):
+ res = [ entry ]
+
+ res.append(MultiContentEntryText(pos = (5, 5), size = (550, 18), font = 0, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = entry.getTitle()))
+ res.append(MultiContentEntryText(pos = (5, 23), size = (550, 14), font = 1, color = 0xFFA323, color_sel = 0xFFA323, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = entry.getDescription()))
+
+ return res
+
+
+class YouTubePlaylistList(MenuList):
+ def __init__(self, list, enableWrapAround = False):
+ MenuList.__init__(self, list, enableWrapAround, eListboxPythonMultiContent)
+ self.l.setFont(0, gFont("Regular", 18))
+ self.l.setFont(1, gFont("Regular", 14))
+ self.l.setItemHeight(41)
+
+
+class YouTubePlaylistScreen(Screen):
+ def __init__(self, session):
+ Screen.__init__(self, session)
+
+ self.session = session
+
+ self["red"] = Label(_("Delete Playlist"))
+ self["green"] = Label(_("Add new Playlist"))
+
+ self.list = []
+ self["list"] = YouTubePlaylistList(self.list)
+
+ self["actions"] = ActionMap(["YouTubePlaylistScreenActions"],
+ {
+ "ok" : self.choosePlaylist,
+ "delete" : self.deletePlaylist,
+ "add" : self.addPlaylist,
+ "cancel" : self.close
+ }, -1)
+
+
+ def loadPlaylist(self):
+ self.list = []
+ feed = interface.getPlaylistFeed()
+ for entry in feed.getEntries():
+ self.list.append(YouTubePlaylistEntryComponent(entry))
+ self["list"].setList(self.list)
+
+
+ def choosePlaylist(self):
+ Screen.close(self, self["list"].getCurrent()[0])
+
+
+ def deletePlaylist(self):
+ playList = self["list"].getCurrent()[0]
+ if playList is not None:
+ self.session.openWithCallback(self.deleteCallback, MessageBox, _("Really delete %(playlist)s?") % {"playlist" : playList.getTitle()})
+
+
+ def deleteCallback(self, result):
+ if result:
+ if interface.deletePlaylist(self["list"].getCurrent()[0]):
+ self.list.remove(self["list"].getCurrent())
+ self["list"].setList(self.list)
+
+
+ def addPlaylist(self):
+ self.session.openWithCallback(self.addCallback, YouTubeAddPlaylistDialog)
+
+
+ def addCallback(self, result, playlistContext):
+ if result:
+ entry = interface.addPlaylist(playlistContext.name.value, playlistContext.description.value, playlistContext.private.value)
+ self.list.append(YouTubePlaylistEntryComponent(entry))
+ self["list"].setList(self.list)
+
+
+ def close(self):
+ Screen.close(self, None)
--- /dev/null
+############################################################################
+# Copyright (C) 2008 by Volker Christian #
+# Volker.Christian@fh-hagenberg.at #
+# #
+# This program is free software; you can redistribute it and#or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation; either version 2 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 General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program; if not, write to the #
+# Free Software Foundation, Inc., #
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
+############################################################################
+
+from Plugins.Extensions.VlcPlayer.VlcPlayer import VlcPlayer
+from Components.ActionMap import ActionMap
+
+from YouTubeContextMenu import YouTubeEntryContextMenu, YouTubeEntryContextMenuList
+
+
+class YouTubePlayer(VlcPlayer):
+ def __init__(self, session, server, currentList, contextMenuEntries, infoCallback, name):
+ VlcPlayer.__init__(self, session, server, currentList)
+ self.contextMenuEntries = contextMenuEntries
+ self.infoCallback = infoCallback
+ self.name = name
+
+ self["menuactions"] = ActionMap(["YouTubePlayerScreenActions"],
+ {
+ "menu" : self.openContextMenu,
+ "info" : self.showVideoInfo,
+ }, -1)
+
+
+ def showVideoInfo(self):
+ if self.shown:
+ self.hideInfobar()
+ self.infoCallback()
+
+
+ def openContextMenu(self):
+ if self.shown:
+ self.hideInfobar()
+ contextMenuList = YouTubeEntryContextMenuList()
+ for entry in self.contextMenuEntries:
+ contextMenuList.appendEntry(entry)
+ self.session.openWithCallback(self.menuActionCoosen, YouTubeEntryContextMenu, contextMenuList, self.name)
+
+
+ def menuActionCoosen(self, cookie):
+ if cookie is not None:
+ if cookie[1]:
+ self.stop()
+ cookie[0]()
--- /dev/null
+############################################################################
+# Copyright (C) 2008 by Volker Christian #
+# Volker.Christian@fh-hagenberg.at #
+# #
+# This program is free software; you can redistribute it and#or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation; either version 2 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 General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program; if not, write to the #
+# Free Software Foundation, Inc., #
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
+############################################################################
+
+from Screens.Screen import Screen
+
+from Components.config import Config
+from Components.config import ConfigText
+from Components.config import getConfigListEntry
+from Components.ConfigList import ConfigListScreen
+from Components.ActionMap import ActionMap
+from Components.Button import Button
+
+from ConfigTextWithSuggestions import ConfigTextWithSuggestions
+
+from . import _
+
+searchContext = Config()
+searchContext.searchTerm = ConfigTextWithSuggestions("", False, threaded = True)
+
+
+SEARCH = 1
+STDFEEDS = 2
+PLAYLISTS = 3
+FAVORITES = 4
+CANCEL = 5
+
+
+class YouTubeSearchDialog(Screen, ConfigListScreen):
+ def __init__(self, session):
+ Screen.__init__(self, session)
+
+ self.session = session
+
+ self.propagateUpDownNormally = True
+
+ self["actions"] = ActionMap(["YouTubeSearchDialogActions"],
+ {
+ "standard" : self.keyStdFeeds,
+ "search" : self.keySearch,
+ "playlists" : self.keyPlaylists,
+ "favorites" : self.keyFavorites,
+
+ "cancel" : self.keyCancel,
+ "left" : self.keyLeft,
+ "right" : self.keyRight,
+ "up" : self.keyUp,
+ "down" : self.keyDown,
+ }, -2)
+
+ self["key_red"] = Button(_("Std.Feeds"))
+ self["key_green"] = Button(_("Search"))
+ self["key_yellow"] = Button(_("Playlists"))
+ self["key_blue"] = Button(_("Favorites"))
+
+ searchContextEntries = []
+ searchContextEntries.append(getConfigListEntry(_("Search Term(s)"), searchContext.searchTerm))
+
+ ConfigListScreen.__init__(self, searchContextEntries, session)
+
+
+ def keyOK(self):
+ if isinstance(self["config"].getCurrent()[1], ConfigTextWithSuggestions):
+ if not self.propagateUpDownNormally:
+ self.propagateUpDownNormally = True
+ self["config"].getCurrent()[1].deactivateSuggestionList()
+ else:
+ if self["config"].getCurrent()[1].activateSuggestionList():
+ self.propagateUpDownNormally = False
+ self["config"].invalidateCurrent()
+ else:
+ ConfigListScreen.keyOK(self)
+
+
+ def keyUp(self):
+ if self.propagateUpDownNormally:
+ self["config"].instance.moveSelection(self["config"].instance.moveUp)
+ else:
+ self["config"].getCurrent()[1].suggestionListUp()
+ self["config"].invalidateCurrent()
+
+
+ def keyDown(self):
+ if self.propagateUpDownNormally:
+ self["config"].instance.moveSelection(self["config"].instance.moveDown)
+ else:
+ self["config"].getCurrent()[1].suggestionListDown()
+ self["config"].invalidateCurrent()
+
+
+ def keyRight(self):
+ if self.propagateUpDownNormally:
+ ConfigListScreen.keyRight(self)
+ else:
+ self["config"].getCurrent()[1].suggestionListPageDown()
+ self["config"].invalidateCurrent()
+
+
+ def keyLeft(self):
+ if self.propagateUpDownNormally:
+ ConfigListScreen.keyLeft(self)
+ else:
+ self["config"].getCurrent()[1].suggestionListPageUp()
+ self["config"].invalidateCurrent()
+
+
+ def keyCancel(self):
+ if self.propagateUpDownNormally:
+ self.close(CANCEL)
+ else:
+ self.propagateUpDownNormally = True
+ self["config"].getCurrent()[1].cancelSuggestionList()
+ self["config"].invalidateCurrent()
+
+
+ def keySearch(self):
+ if searchContext.searchTerm.value != "":
+ if isinstance(self["config"].getCurrent()[1], ConfigTextWithSuggestions) and not self.propagateUpDownNormally:
+ self.propagateUpDownNormally = True
+ self["config"].getCurrent()[1].deactivateSuggestionList()
+ self.close(SEARCH, searchContext)
+
+
+ def keyStdFeeds(self):
+ if isinstance(self["config"].getCurrent()[1], ConfigTextWithSuggestions) and not self.propagateUpDownNormally:
+ self.propagateUpDownNormally = True
+ self["config"].getCurrent()[1].deactivateSuggestionList()
+ self.close(STDFEEDS)
+
+
+ def keyPlaylists(self):
+ if isinstance(self["config"].getCurrent()[1], ConfigTextWithSuggestions) and not self.propagateUpDownNormally:
+ self.propagateUpDownNormally = True
+ self["config"].getCurrent()[1].deactivateSuggestionList()
+ self.close(PLAYLISTS)
+
+
+ def keyFavorites(self):
+ if isinstance(self["config"].getCurrent()[1], ConfigTextWithSuggestions) and not self.propagateUpDownNormally:
+ self.propagateUpDownNormally = True
+ self["config"].getCurrent()[1].deactivateSuggestionList()
+ self.close(FAVORITES)
--- /dev/null
+############################################################################
+# Copyright (C) 2008 by Volker Christian #
+# Volker.Christian@fh-hagenberg.at #
+# #
+# This program is free software; you can redistribute it and#or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation; either version 2 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 General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program; if not, write to the #
+# Free Software Foundation, Inc., #
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
+############################################################################
+
+from Screens.Screen import Screen
+from Components.Sources.List import List
+from Components.ActionMap import ActionMap
+from Components.Sources.StaticText import StaticText
+
+from . import _
+
+class YouTubeStdFeedSelectionScreen(Screen):
+ STD_FEED = "http://gdata.youtube.com/feeds/api/standardfeeds/"
+
+ def __init__(self, session):
+ Screen.__init__(self, session)
+
+ self["actions"] = ActionMap(["OkCancelActions"],
+ {
+ "ok" : self.ok,
+ "cancel" : self.close
+ })
+
+ menu = [(_("Most Viewed"), "most_viewed")]
+ menu.append((_("Top Rated"), "top_rated"))
+ menu.append((_("Recently Featured"), "recently_featured"))
+ menu.append((_("Watch On Mobile"), "watch_on_mobile"))
+ menu.append((_("Most Discussed"), "most_discussed"))
+ menu.append((_("Top Favorites"), "top_favorites"))
+ menu.append((_("Most Linked"), "most_linked"))
+ menu.append((_("Most Responded"), "most_responded"))
+ menu.append((_("Most Recent"), "most_recent"))
+
+ self["menu"] = List(menu)
+
+
+ def ok(self):
+ Screen.close(self, self.STD_FEED + self["menu"].getCurrent()[1])
+
+
+ def close(self):
+ Screen.close(self, None)
\ No newline at end of file
--- /dev/null
+############################################################################
+# Copyright (C) 2008 by Volker Christian #
+# Volker.Christian@fh-hagenberg.at #
+# #
+# This program is free software; you can redistribute it and#or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation; either version 2 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 General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program; if not, write to the #
+# Free Software Foundation, Inc., #
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
+############################################################################
+
+from Components.ActionMap import ActionMap
+from Components.Button import Button
+from Components.ConfigList import ConfigListScreen
+from Components.config import ConfigInteger
+from Components.config import ConfigSubsection
+from Components.config import ConfigSubList
+from Components.config import ConfigText
+from Components.config import config
+from Components.config import getConfigListEntry
+from Screens.Screen import Screen
+from YouTubeInterface import YouTubeUser
+
+from . import _
+
+# This should be executed only once during an enigma2-session
+config.plugins.youtubeplayer = ConfigSubsection()
+config.plugins.youtubeplayer.serverprofile = ConfigText("", False)
+
+class __YouTubeUserConfig():
+ def __init__(self):
+ self.userlist = []
+ config.plugins.youtubeplayer.usercount = ConfigInteger(0)
+ config.plugins.youtubeplayer.users = ConfigSubList()
+ config.plugins.youtubeplayer.defaultuser = ConfigText("", False)
+ for usernum in range(0, config.plugins.youtubeplayer.usercount.value):
+ self.new()
+
+
+ # Add a new server or load a configsection if existing
+ def new(self):
+ newUserConfigSubsection = ConfigSubsection()
+ config.plugins.youtubeplayer.users.append(newUserConfigSubsection)
+ newUserConfigSubsection.name = ConfigText("User " + str(self.__getUserCount()), False)
+ if newUserConfigSubsection.name.value == newUserConfigSubsection.name.default:
+ newUserConfigSubsection.name.default = ""
+ newUserConfigSubsection.email = ConfigText("", False)
+ newUserConfigSubsection.password = ConfigText("", False)
+
+ newUser = YouTubeUser(newUserConfigSubsection)
+
+ self.userlist.append(newUser)
+
+ return newUser
+
+ # Add was canceled or existing server should be removed
+ def delete(self, user):
+ config.plugins.youtubeplayer.users.remove(user.getCfg())
+ self.userlist.remove(user)
+ self.__save()
+
+ # Edit or Add should complete
+ def save(self, user):
+ user.getCfg().save()
+ self.__save()
+
+ # Edit has been canceled
+ def cancel(self, user):
+ for element in user.getCfg().dict().values():
+ element.cancel()
+
+ def getUserlist(self):
+ return self.userlist
+
+ def getUserByName(self, name):
+ for user in self.userlist:
+ if user.getName() == name:
+ return user
+ return None
+
+ def getDefaultUser(self):
+ return self.getUserByName(config.plugins.youtubeplayer.defaultuser.value)
+
+ def setAsDefault(self, defaultUser):
+ if defaultUser is not None:
+ config.plugins.youtubeplayer.defaultuser.value = defaultUser.getName()
+ config.plugins.youtubeplayer.defaultuser.save()
+
+ def __save(self):
+ config.plugins.youtubeplayer.usercount.value = self.__getUserCount()
+ config.plugins.youtubeplayer.usercount.save()
+
+ def __getUserCount(self):
+ return len(config.plugins.youtubeplayer.users)
+
+
+youTubeUserConfig = __YouTubeUserConfig()
+
+
+class YouTubeUserConfigScreen(Screen, ConfigListScreen):
+ def __init__(self, session, user):
+ Screen.__init__(self, session)
+ self.user = user
+ self["actions"] = ActionMap(["YouTubeUserConfigScreenActions"],
+ {
+ "save" : self.keySave,
+ "cancel" : self.keyCancel
+ }, -2)
+
+ self["key_red"] = Button(_("Cancel"))
+ self["key_green"] = Button(_("Save"))
+ self["key_yellow"] = Button("")
+ self["key_blue"] = Button("")
+
+ cfglist = []
+ cfglist.append(getConfigListEntry(_("User Profile Name"), user.name()))
+ cfglist.append(getConfigListEntry(_("E-Mail Address"), user.email()))
+ cfglist.append(getConfigListEntry(_("Password"), user.password()))
+
+ ConfigListScreen.__init__(self, cfglist, session)
+
+ def keySave(self):
+ self.close(True, self.user)
+
+ def keyCancel(self):
+ self.close(False, self.user)
--- /dev/null
+############################################################################
+# Copyright (C) 2008 by Volker Christian #
+# Volker.Christian@fh-hagenberg.at #
+# #
+# This program is free software; you can redistribute it and#or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation; either version 2 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 General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program; if not, write to the #
+# Free Software Foundation, Inc., #
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
+############################################################################
+
+from Components.ActionMap import ActionMap
+from Components.Button import Button
+from Components.Label import Label
+from Components.MenuList import MenuList
+from Screens.MessageBox import MessageBox
+from Screens.Screen import Screen
+from Tools.Directories import resolveFilename, SCOPE_PLUGINS
+from Tools.LoadPixmap import LoadPixmap
+from YouTubeUserConfig import youTubeUserConfig
+from YouTubeUserConfig import YouTubeUserConfigScreen
+from enigma import eListboxPythonMultiContent, RT_HALIGN_LEFT, gFont
+
+from . import _
+
+def YouTubeUserListEntry(youTubeUser, defaultUser):
+ res = [ youTubeUser ]
+ res.append((eListboxPythonMultiContent.TYPE_TEXT, 35, 1, 470, 20, 0, RT_HALIGN_LEFT, youTubeUser.getName()))
+
+ if defaultUser is not None and defaultUser.getName() == youTubeUser.getName():
+ png = LoadPixmap(resolveFilename(SCOPE_PLUGINS, "Extensions/YouTubePlayer/user_default.png"))
+ else:
+ png = LoadPixmap(resolveFilename(SCOPE_PLUGINS, "Extensions/YouTubePlayer/user.png"))
+ if png is not None:
+ res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHATEST, 10, 2, 20, 20, png))
+
+ return res
+
+
+class YouTubeUserList(MenuList):
+ def __init__(self):
+ MenuList.__init__(self, list, False, eListboxPythonMultiContent)
+ self.l.setFont(0, gFont("Regular", 18))
+ self.l.setItemHeight(23)
+
+ def update(self, userList, defaultUser):
+ self.list = []
+ for user in userList:
+ self.list.append(YouTubeUserListEntry(user, defaultUser))
+ self.l.setList(self.list)
+ self.moveToIndex(0)
+
+ def getSelection(self):
+ if self.l.getCurrentSelection() is None:
+ return None
+ return self.l.getCurrentSelection()[0]
+
+
+class YouTubeUserListScreen(Screen):
+ LOGIN_SUCCESS = 1
+ LOGIN_CANCEL = 2
+ LOGIN_FAILED = 3
+
+ def __init__(self, session, defaultUser):
+ Screen.__init__(self, session)
+ self.session = session
+ self.userlist = YouTubeUserList()
+ self.defaultUser = defaultUser
+
+ self["label_info"] = Label(_("To use the selected feature you have to login to YouTube. Select a user-profile to login!"))
+ self["userlist"] = self.userlist
+ self["key_red"] = Button(_("delete user"))
+ self["key_green"] = Button(_("add user"))
+ self["key_yellow"] = Button(_("edit user"))
+ self["key_blue"] = Button(_("set default"))
+
+ self["actions"] = ActionMap(["YouTubeUserListScreenActions"],
+ {
+ "delete": self.keyDelete,
+ "add": self.keyAddUser,
+ "edit": self.keyEditUser,
+ "default": self.keySetAsDefault,
+
+ "ok": self.ok,
+ "cancel": self.close,
+ "up": self.up,
+ "down": self.down,
+ "left": self.left,
+ "right": self.right,
+ }, -2)
+
+ self.onLayoutFinish.append(self.initialUserlistUpdate)
+
+
+ def showTestScreen(self):
+ self.suggestionsWindow.show()
+
+
+ def initialUserlistUpdate(self):
+ self.updateUserlist()
+ if self.defaultUser is not None:
+ defaultIndex = youTubeUserConfig.getUserlist().index(self.defaultUser)
+ self.userlist.moveToIndex(defaultIndex)
+
+
+ def updateUserlist(self):
+ self.userlist.update(youTubeUserConfig.getUserlist(), self.defaultUser)
+
+
+ def keyDelete(self):
+ user = self.userlist.getSelection()
+ if user is not None:
+ self.session.openWithCallback(self.deleteCallback, MessageBox, _("Really delete %(user)s?") % {"user" : user.getName()})
+
+ def deleteCallback(self, result):
+ if result:
+ youTubeUserConfig.delete(self.userlist.getSelection())
+ self.updateUserlist()
+
+
+ def keyAddUser(self):
+ newUser = youTubeUserConfig.new()
+ self.session.openWithCallback(self.addCallback, YouTubeUserConfigScreen, newUser)
+
+
+ def addCallback(self, result, user):
+ if result:
+ youTubeUserConfig.save(user)
+ self.updateUserlist()
+ else:
+ youTubeUserConfig.delete(user)
+
+
+ def keyEditUser(self):
+ user = self.userlist.getSelection()
+ if user is not None:
+ self.session.openWithCallback(self.editCallback, YouTubeUserConfigScreen, user)
+
+
+ def editCallback(self, result, user):
+ if result:
+ youTubeUserConfig.save(user)
+ index = self.userlist.getSelectedIndex()
+ self.updateUserlist()
+ self.userlist.moveToIndex(index)
+ else:
+ youTubeUserConfig.cancel(user)
+
+
+ def keySetAsDefault(self):
+ self.defaultUser = self.userlist.getSelection()
+ index = self.userlist.getSelectedIndex()
+ self.updateUserlist()
+ self.userlist.moveToIndex(index)
+
+
+ def up(self):
+ self.userlist.up()
+
+
+ def down(self):
+ self.userlist.down()
+
+
+ def left(self):
+ self.userlist.pageUp()
+
+
+ def right(self):
+ self.userlist.pageDown()
+
+
+ def close(self, loginState = LOGIN_CANCEL):
+ youTubeUserConfig.setAsDefault(self.defaultUser)
+ Screen.close(self, loginState)
+
+
+ def ok(self):
+ if self.userlist.getSelection().login():
+ self.close(YouTubeUserListScreen.LOGIN_SUCCESS)
+ else:
+ self.close(YouTubeUserListScreen.LOGIN_FAILED)
--- /dev/null
+# -*- coding: ISO-8859-1 -*-
+#===============================================================================
+# YouTube Plugin by Volker Christian 2008
+#
+# This is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2, or (at your option) any later
+# version.
+#===============================================================================
+
+from Components.Language import language
+from Tools.Directories import resolveFilename, SCOPE_PLUGINS, SCOPE_LANGUAGE
+import os,gettext
+
+def localeInit():
+ lang = language.getLanguage()[:2] # getLanguage returns e.g. "fi_FI" for "language_country"
+ os.environ["LANGUAGE"] = lang # Enigma doesn't set this (or LC_ALL, LC_MESSAGES, LANG). gettext needs it!
+ gettext.bindtextdomain("enigma2", resolveFilename(SCOPE_LANGUAGE))
+ gettext.textdomain("enigma2")
+ gettext.bindtextdomain("YouTubePlayer", resolveFilename(SCOPE_PLUGINS, "Extensions/YouTubePlayer/locale"))
+
+def _(txt):
+ t = gettext.dgettext("YouTubePlayer", txt)
+ if t == txt:
+ print "[YTB] fallback to default translation for", txt
+ t = gettext.gettext(txt)
+ return t
+
+localeInit()
--- /dev/null
+<keymap>
+<!--
+"m" kommt einmal sobald die taste gedrueckt wurde.
+"r" kommt dann nach "m" wenn man die taste feshaelt.. und das solange bis man die taste loslaesst,
+"l" kommt nachdem 5 repeats kamen..aber nur exakt einmal (repeat kommt dann trotzdem weiter..)
+"b" kommt nachdem man die taste losgelassen hat.
+
+Wenn man nun also ein Fenster mit "m" oeffnet.. dann kann man im selben context r, l, b nicht mehr benutzen.
+Deshalb muss man dann halt das Fenster erst auf "b" oeffnen..
+-->
+ <map context = "YouTubeAddPlaylistActions">
+ <key id = "KEY_GREEN" mapto = "save" flags = "m" />
+ <key id = "KEY_RED" mapto = "cancel" flags = "m" />
+ <key id = "KEY_EXIT" mapto = "cancel" flags = "m" />
+ <key id = "KEY_ESC" mapto = "cancel" flags = "m" />
+ </map>
+
+ <map context = "YouTubeVideoDetailsScreenActions">
+ <key id = "KEY_LEFT" mapto = "left" flags = "mr" />
+ <key id = "KEY_RIGHT" mapto = "right" flags = "mr" />
+ <key id = "KEY_UP" mapto = "up" flags = "mr" />
+ <key id = "KEY_DOWN" mapto = "down" flags = "mr" />
+
+ <key id = "KEY_OK" mapto = "ok" flags = "m" />
+ <key id = "KEY_EXIT" mapto = "cancel" flags = "m" />
+
+ <key id = "KEY_ENTER" mapto = "ok" flags = "m" />
+ <key id = "KEY_ESC" mapto = "cancel" flags = "m" />
+ </map>
+
+ <map context = "YouTubeVideoListActions">
+ <key id = "KEY_OK" mapto = "play" flags = "m" />
+ <key id = "KEY_ENTER" mapto = "play" flags = "m" />
+
+ <key id = "KEY_RED" mapto = "select" flags = "m" />
+ <key id = "KEY_GREEN" mapto = "search" flags = "m" />
+
+ <key id = "KEY_MENU" mapto = "menu" flags = "m" />
+
+ <key id = "KEY_CHANNELUP" mapto = "forward" flags = "m" />
+ <key id = "KEY_CHANNELDOWN" mapto = "backward" flags = "m" />
+
+ <key id = "KEY_LEFT" mapto = "left" flags = "mr" />
+ <key id = "KEY_RIGHT" mapto = "right" flags = "mr" />
+ <key id = "KEY_UP" mapto = "up" flags = "mr" />
+ <key id = "KEY_DOWN" mapto = "down" flags = "mr" />
+
+ <key id = "KEY_INFO" mapto = "info" flags = "m" />
+
+ <key id = "KEY_EXIT" mapto = "cancel" flags = "m" />
+ <key id = "KEY_ESC" mapto = "cancel" flags = "m" />
+ </map>
+
+ <map context = "YouTubePlayerScreenActions">
+ <key id = "KEY_MENU" mapto = "menu" flags = "m" />
+ <key id = "KEY_INFO" mapto = "info" flags = "m" />
+ </map>
+
+ <map context = "YouTubePlaylistScreenActions">
+ <key id = "KEY_OK" mapto = "ok" flags = "m" />
+ <key id = "KEY_EXIT" mapto = "cancel" flags = "m" />
+
+ <key id = "KEY_ENTER" mapto = "ok" flags = "m" />
+ <key id = "KEY_ESC" mapto = "cancel" flags = "m" />
+
+ <key id = "KEY_GREEN" mapto = "add" flags = "m" />
+ <key id = "KEY_RED" mapto = "delete" flags = "m" />
+ </map>
+
+ <map context = "YouTubeSearchDialogActions">
+ <key id = "KEY_RED" mapto = "standard" flags = "m" />
+ <key id = "KEY_GREEN" mapto = "search" flags = "m" />
+ <key id = "KEY_BLUE" mapto = "favorites" flags = "m" />
+ <key id = "KEY_YELLOW" mapto = "playlists" flags = "m" />
+
+ <key id = "KEY_ESC" mapto = "cancel" flags = "m" />
+ <key id = "KEY_EXIT" mapto = "cancel" flags = "m" />
+
+ <key id = "KEY_LEFT" mapto = "left" flags = "mr" />
+ <key id = "KEY_RIGHT" mapto = "right" flags = "mr" />
+ <key id = "KEY_UP" mapto = "up" flags = "mr" />
+ <key id = "KEY_DOWN" mapto = "down" flags = "mr" />
+ </map>
+
+ <map context = "YouTubeUserConfigScreenActions">
+ <key id = "KEY_GREEN" mapto = "save" flags = "m" />
+ <key id = "KEY_RED" mapto = "cancel" flags = "m" />
+ <key id = "KEY_EXIT" mapto = "cancel" flags = "m" />
+ <key id = "KEY_ESC" mapto = "cancel" flags = "m" />
+ </map>
+
+ <map context = "YouTubeUserListScreenActions">
+ <key id = "KEY_RED" mapto = "delete" flags = "m" />
+ <key id = "KEY_GREEN" mapto = "add" flags = "m" />
+ <key id = "KEY_BLUE" mapto = "default" flags = "m" />
+ <key id = "KEY_YELLOW" mapto = "edit" flags = "m" />
+
+ <key id = "KEY_OK" mapto = "ok" flags = "m" />
+ <key id = "KEY_EXIT" mapto = "cancel" flags = "m" />
+
+ <key id = "KEY_ENTER" mapto = "ok" flags = "m" />
+ <key id = "KEY_ESC" mapto = "cancel" flags = "m" />
+
+ <key id = "KEY_LEFT" mapto = "left" flags = "mr" />
+ <key id = "KEY_RIGHT" mapto = "right" flags = "mr" />
+ <key id = "KEY_UP" mapto = "up" flags = "mr" />
+ <key id = "KEY_DOWN" mapto = "down" flags = "mr" />
+ </map>
+</keymap>
--- /dev/null
+# translation of YouTubePlayer.po to German
+# translation of YouTubePlayer_old.po to
+# translation of YouTubePlayer.po to
+# translation of messages.po to
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Volker Christian <Volker.Christian@fh-hagenberg.at>, 2008.
+msgid ""
+msgstr ""
+"Project-Id-Version: YouTubePlayer\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2008-08-09 16:00+0200\n"
+"PO-Revision-Date: 2008-08-09 16:34+0200\n"
+"Last-Translator: Volker Christian <Volker.Christian@fh-hagenberg.at>\n"
+"Language-Team: German <en@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+#: ../plugin.py:103 ../plugin.py:123 ../YouTubeList.py:442
+#: ../YouTubeList.py:464 ../YouTubeList.py:486 ../YouTubeList.py:512
+msgid "Login not successful"
+msgstr "Login nicht erfolgreich"
+
+#: ../plugin.py:146
+msgid "Search and play YouTube movies"
+msgstr "Videos auf YouTube suchen und abspielen"
+
+#: ../YouTubeAddPlayList.py:36
+msgid "Name"
+msgstr "Name"
+
+#: ../YouTubeAddPlayList.py:37
+msgid "Description"
+msgstr "Beschreibung "
+
+#: ../YouTubeAddPlayList.py:53 ../YouTubeUserConfig.py:119
+msgid "Cancel"
+msgstr "Abbrechen"
+
+#: ../YouTubeAddPlayList.py:54 ../YouTubeUserConfig.py:120
+msgid "Save"
+msgstr "Speichern"
+
+#: ../YouTubeAddPlayList.py:59
+msgid "Playlist Name"
+msgstr "Playlistenname"
+
+#: ../YouTubeAddPlayList.py:60
+msgid "Playlist Description"
+msgstr "Playlistenbeschreibung"
+
+#: ../YouTubeAddPlayList.py:61
+msgid "private"
+msgstr "privat"
+
+#: ../YouTubeList.py:83
+msgid "Duration"
+msgstr "Dauer"
+
+#: ../YouTubeList.py:86
+msgid "Rate"
+msgstr "Güte"
+
+#: ../YouTubeList.py:90
+msgid "Ratings"
+msgstr "Bewerter"
+
+#: ../YouTubeList.py:93
+msgid "Favorited"
+msgstr "Favoriten"
+
+#: ../YouTubeList.py:96
+msgid "Views"
+msgstr "Gesehen"
+
+#: ../YouTubeList.py:99
+msgid "Author:"
+msgstr "Autor"
+
+#: ../YouTubeList.py:102
+msgid "Added"
+msgstr "Datum"
+
+#: ../YouTubeList.py:105
+msgid "Category"
+msgstr "Rubrik"
+
+#: ../YouTubeList.py:107
+msgid "Tags"
+msgstr "Marken"
+
+#: ../YouTubeList.py:211
+msgid "Select a VLC-Server"
+msgstr "VLC-Server wählen"
+
+#: ../YouTubeList.py:212
+msgid "New YouTube search"
+msgstr "Neue YouTube-Suche"
+
+#: ../YouTubeList.py:217
+msgid "Total results"
+msgstr "Gesamtzahl"
+
+#: ../YouTubeList.py:220
+msgid "Shown"
+msgstr "Angezeigt"
+
+#: ../YouTubeList.py:253 ../YouTubeList.py:264
+msgid "Load further entries of current Feed?"
+msgstr "Weitere Einträge des aktuellen Feeds laden?"
+
+#: ../YouTubeList.py:312
+msgid "Searching, be patient ..."
+msgstr "Suche läuft, bitte haben Sie geduld ..."
+
+#: ../YouTubeList.py:324
+msgid "Loading playlist, be patient ..."
+msgstr "Playliste wird geladen, bitte haben Sie geduld ..."
+
+#: ../YouTubeList.py:335
+msgid "Loading favorits, be patient ..."
+msgstr "Favoriten werden geladen, bitte haben Sie geduld ..."
+
+#: ../YouTubeList.py:341
+msgid "Loading standard feed, be patient ..."
+msgstr "Standardfeed wird geladen, bitte haben Sie geduld ..."
+
+#: ../YouTubeList.py:362 ../YouTubeList.py:370
+msgid "Loading additional videos, be patient ..."
+msgstr "Weitere Videos werden geladen, bitte haben Sie geduld ..."
+
+#: ../YouTubeList.py:374
+msgid "Loading related videos, be patient ..."
+msgstr "Ähnliche Videos werden geladen, bitte haben Sie geduld ... "
+
+#: ../YouTubeList.py:379
+msgid "Loading response videos, be patient ..."
+msgstr "Antwortvideos werden geladen, bitte haben Sie geduld ..."
+
+#: ../YouTubeList.py:386
+msgid "Back in history, be patient ..."
+msgstr "Zurück in der Historie, bitte haben Sie geduld"
+
+#: ../YouTubeList.py:392
+msgid "Forward in history, be patient ..."
+msgstr "Vorwärts in der Historie, bitte haben Sie geduld"
+
+#: ../YouTubeList.py:546 ../YouTubeList.py:585
+msgid "Show video detail info"
+msgstr "Video-Detailinformation anzeigen"
+
+#: ../YouTubeList.py:548 ../YouTubeList.py:587
+msgid "Remove from favorites"
+msgstr "Von Favoriten löschen"
+
+#: ../YouTubeList.py:550 ../YouTubeList.py:589
+msgid "Add to favorites"
+msgstr "Zu Fovoriten hinzufügen"
+
+#: ../YouTubeList.py:553 ../YouTubeList.py:591
+msgid "Remove from playlist"
+msgstr "Von Wiedergabeliste löschen"
+
+#: ../YouTubeList.py:555 ../YouTubeList.py:593
+msgid "Add to playlist"
+msgstr "Zu Wiedergabeliste hinzufügen"
+
+#: ../YouTubeList.py:556 ../YouTubeList.py:594
+msgid "Get related videos"
+msgstr "Ähnliche Videos laden"
+
+#: ../YouTubeList.py:557 ../YouTubeList.py:595
+msgid "Get video responses"
+msgstr "Antwortvideos laden"
+
+#: ../YouTubePlayList.py:57
+msgid "Delete Playlist"
+msgstr "Playliste löschen"
+
+#: ../YouTubePlayList.py:58
+msgid "Add new Playlist"
+msgstr "Playliste hinzufügen"
+
+#: ../YouTubePlayList.py:86
+#, python-format
+msgid "Really delete %(playlist)s?"
+msgstr "%(playlist)s löschen?"
+
+#: ../YouTubeSearchDialog.py:67
+msgid "Std.Feeds"
+msgstr "Std.Feeds"
+
+#: ../YouTubeSearchDialog.py:68
+msgid "Search"
+msgstr "Suchen"
+
+#: ../YouTubeSearchDialog.py:69
+msgid "Playlists"
+msgstr "Playliste"
+
+#: ../YouTubeSearchDialog.py:70
+msgid "Favorites"
+msgstr "Favoriten"
+
+#: ../YouTubeSearchDialog.py:73
+msgid "Search Term(s)"
+msgstr "Suchbegriff(e)"
+
+#: ../YouTubeStdFeedSelection.py:40
+msgid "Most Viewed"
+msgstr "Am häufigsten gesehen"
+
+#: ../YouTubeStdFeedSelection.py:41
+msgid "Top Rated"
+msgstr "Am höchsten bewertet"
+
+#: ../YouTubeStdFeedSelection.py:42
+msgid "Recently Featured"
+msgstr "Kürzlich beworben"
+
+#: ../YouTubeStdFeedSelection.py:43
+msgid "Watch On Mobile"
+msgstr "Auf einem Mobilgerät betrachtbar"
+
+#: ../YouTubeStdFeedSelection.py:44
+msgid "Most Discussed"
+msgstr "Am häufigsten diskutiert"
+
+#: ../YouTubeStdFeedSelection.py:45
+msgid "Top Favorites"
+msgstr "Am häufigsten in Favoriten eingetragen"
+
+#: ../YouTubeStdFeedSelection.py:46
+msgid "Most Linked"
+msgstr "Am häufigsten verlinkt"
+
+#: ../YouTubeStdFeedSelection.py:47
+msgid "Most Responded"
+msgstr "Am häufigsten beantwortet"
+
+#: ../YouTubeStdFeedSelection.py:48
+msgid "Most Recent"
+msgstr "Kürzlich hinzugefügt"
+
+#: ../YouTubeUserConfig.py:125
+msgid "User Profile Name"
+msgstr "Benutzerprofilname"
+
+#: ../YouTubeUserConfig.py:126
+msgid "E-Mail Address"
+msgstr "E-Mail Adresse"
+
+#: ../YouTubeUserConfig.py:127
+msgid "Password"
+msgstr "Passwort"
+
+#: ../YouTubeUserList.py:79
+msgid ""
+"To use the selected feature you have to login to YouTube. Select a user-"
+"profile to login!"
+msgstr "Um diese Funktion nutzen zu können, wählen Sie einen Benutzer und melden Sie sich damit bei YouTube an."
+
+#: ../YouTubeUserList.py:81
+msgid "delete user"
+msgstr "löschen"
+
+#: ../YouTubeUserList.py:82
+msgid "add user"
+msgstr "hinzufügen"
+
+#: ../YouTubeUserList.py:83
+msgid "edit user"
+msgstr "ändern "
+
+#: ../YouTubeUserList.py:84
+msgid "set default"
+msgstr "standard"
+
+#: ../YouTubeUserList.py:122
+#, python-format
+msgid "Really delete %(user)s?"
+msgstr "%(user)s löschen?"
+
--- /dev/null
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2008-08-09 16:00+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../plugin.py:103 ../plugin.py:123 ../YouTubeList.py:442
+#: ../YouTubeList.py:464 ../YouTubeList.py:486 ../YouTubeList.py:512
+msgid "Login not successful"
+msgstr ""
+
+#: ../plugin.py:146
+msgid "Search and play YouTube movies"
+msgstr ""
+
+#: ../YouTubeAddPlayList.py:36
+msgid "Name"
+msgstr ""
+
+#: ../YouTubeAddPlayList.py:37
+msgid "Description"
+msgstr ""
+
+#: ../YouTubeAddPlayList.py:53 ../YouTubeUserConfig.py:119
+msgid "Cancel"
+msgstr ""
+
+#: ../YouTubeAddPlayList.py:54 ../YouTubeUserConfig.py:120
+msgid "Save"
+msgstr ""
+
+#: ../YouTubeAddPlayList.py:59
+msgid "Playlist Name"
+msgstr ""
+
+#: ../YouTubeAddPlayList.py:60
+msgid "Playlist Description"
+msgstr ""
+
+#: ../YouTubeAddPlayList.py:61
+msgid "private"
+msgstr ""
+
+#: ../YouTubeList.py:83
+msgid "Duration"
+msgstr ""
+
+#: ../YouTubeList.py:86
+msgid "Rate"
+msgstr ""
+
+#: ../YouTubeList.py:90
+msgid "Ratings"
+msgstr ""
+
+#: ../YouTubeList.py:93
+msgid "Favorited"
+msgstr ""
+
+#: ../YouTubeList.py:96
+msgid "Views"
+msgstr ""
+
+#: ../YouTubeList.py:99
+msgid "Author:"
+msgstr ""
+
+#: ../YouTubeList.py:102
+msgid "Added"
+msgstr ""
+
+#: ../YouTubeList.py:105
+msgid "Category"
+msgstr ""
+
+#: ../YouTubeList.py:107
+msgid "Tags"
+msgstr ""
+
+#: ../YouTubeList.py:211
+msgid "Select a VLC-Server"
+msgstr ""
+
+#: ../YouTubeList.py:212
+msgid "New YouTube search"
+msgstr ""
+
+#: ../YouTubeList.py:217
+msgid "Total results"
+msgstr ""
+
+#: ../YouTubeList.py:220
+msgid "Shown"
+msgstr ""
+
+#: ../YouTubeList.py:253 ../YouTubeList.py:264
+msgid "Load further entries of current Feed?"
+msgstr ""
+
+#: ../YouTubeList.py:312
+msgid "Searching, be patient ..."
+msgstr ""
+
+#: ../YouTubeList.py:324
+msgid "Loading playlist, be patient ..."
+msgstr ""
+
+#: ../YouTubeList.py:335
+msgid "Loading favorits, be patient ..."
+msgstr ""
+
+#: ../YouTubeList.py:341
+msgid "Loading standard feed, be patient ..."
+msgstr ""
+
+#: ../YouTubeList.py:362 ../YouTubeList.py:370
+msgid "Loading additional videos, be patient ..."
+msgstr ""
+
+#: ../YouTubeList.py:374
+msgid "Loading related videos, be patient ..."
+msgstr ""
+
+#: ../YouTubeList.py:379
+msgid "Loading response videos, be patient ..."
+msgstr ""
+
+#: ../YouTubeList.py:386
+msgid "Back in history, be patient ..."
+msgstr ""
+
+#: ../YouTubeList.py:392
+msgid "Forward in history, be patient ..."
+msgstr ""
+
+#: ../YouTubeList.py:546 ../YouTubeList.py:585
+msgid "Show video detail info"
+msgstr ""
+
+#: ../YouTubeList.py:548 ../YouTubeList.py:587
+msgid "Remove from favorites"
+msgstr ""
+
+#: ../YouTubeList.py:550 ../YouTubeList.py:589
+msgid "Add to favorites"
+msgstr ""
+
+#: ../YouTubeList.py:553 ../YouTubeList.py:591
+msgid "Remove from playlist"
+msgstr ""
+
+#: ../YouTubeList.py:555 ../YouTubeList.py:593
+msgid "Add to playlist"
+msgstr ""
+
+#: ../YouTubeList.py:556 ../YouTubeList.py:594
+msgid "Get related videos"
+msgstr ""
+
+#: ../YouTubeList.py:557 ../YouTubeList.py:595
+msgid "Get video responses"
+msgstr ""
+
+#: ../YouTubePlayList.py:57
+msgid "Delete Playlist"
+msgstr ""
+
+#: ../YouTubePlayList.py:58
+msgid "Add new Playlist"
+msgstr ""
+
+#: ../YouTubePlayList.py:86
+#, python-format
+msgid "Really delete %(playlist)s?"
+msgstr ""
+
+#: ../YouTubeSearchDialog.py:67
+msgid "Std.Feeds"
+msgstr ""
+
+#: ../YouTubeSearchDialog.py:68
+msgid "Search"
+msgstr ""
+
+#: ../YouTubeSearchDialog.py:69
+msgid "Playlists"
+msgstr ""
+
+#: ../YouTubeSearchDialog.py:70
+msgid "Favorites"
+msgstr ""
+
+#: ../YouTubeSearchDialog.py:73
+msgid "Search Term(s)"
+msgstr ""
+
+#: ../YouTubeStdFeedSelection.py:40
+msgid "Most Viewed"
+msgstr ""
+
+#: ../YouTubeStdFeedSelection.py:41
+msgid "Top Rated"
+msgstr ""
+
+#: ../YouTubeStdFeedSelection.py:42
+msgid "Recently Featured"
+msgstr ""
+
+#: ../YouTubeStdFeedSelection.py:43
+msgid "Watch On Mobile"
+msgstr ""
+
+#: ../YouTubeStdFeedSelection.py:44
+msgid "Most Discussed"
+msgstr ""
+
+#: ../YouTubeStdFeedSelection.py:45
+msgid "Top Favorites"
+msgstr ""
+
+#: ../YouTubeStdFeedSelection.py:46
+msgid "Most Linked"
+msgstr ""
+
+#: ../YouTubeStdFeedSelection.py:47
+msgid "Most Responded"
+msgstr ""
+
+#: ../YouTubeStdFeedSelection.py:48
+msgid "Most Recent"
+msgstr ""
+
+#: ../YouTubeUserConfig.py:125
+msgid "User Profile Name"
+msgstr ""
+
+#: ../YouTubeUserConfig.py:126
+msgid "E-Mail Address"
+msgstr ""
+
+#: ../YouTubeUserConfig.py:127
+msgid "Password"
+msgstr ""
+
+#: ../YouTubeUserList.py:79
+msgid ""
+"To use the selected feature you have to login to YouTube. Select a user-"
+"profile to login!"
+msgstr ""
+
+#: ../YouTubeUserList.py:81
+msgid "delete user"
+msgstr ""
+
+#: ../YouTubeUserList.py:82
+msgid "add user"
+msgstr ""
+
+#: ../YouTubeUserList.py:83
+msgid "edit user"
+msgstr ""
+
+#: ../YouTubeUserList.py:84
+msgid "set default"
+msgstr ""
+
+#: ../YouTubeUserList.py:122
+#, python-format
+msgid "Really delete %(user)s?"
+msgstr ""
--- /dev/null
+############################################################################
+# Copyright (C) 2008 by Volker Christian #
+# Volker.Christian@fh-hagenberg.at #
+# #
+# This program is free software; you can redistribute it and#or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation; either version 2 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 General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program; if not, write to the #
+# Free Software Foundation, Inc., #
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
+############################################################################
+
+from Plugins.Plugin import PluginDescriptor
+from Tools.BoundFunction import boundFunction
+
+from YouTubeList import YouTubeListScreen
+from YouTubePlayList import YouTubePlaylistScreen
+from YouTubeSearchDialog import YouTubeSearchDialog, SEARCH, STDFEEDS, PLAYLISTS, FAVORITES, CANCEL
+from YouTubeUserList import YouTubeUserListScreen
+from YouTubeUserConfig import youTubeUserConfig
+from YouTubeStdFeedSelection import YouTubeStdFeedSelectionScreen
+from YouTubeInterface import interface, YouTubeInterface
+from SkinLoader import loadPluginSkin
+from Screens.MessageBox import MessageBox
+
+import gettext
+
+
+def _(txt):
+ t = gettext.dgettext("YouTube", txt)
+ if t == txt:
+ print "[YTB] fallback to default translation for", txt
+ t = gettext.gettext(txt)
+ return t
+
+
+class YouTubeManager():
+ def __init__(self, session):
+ self.session = session
+ interface.open()
+
+
+ def openSearchDialog(self):
+ self.session.openWithCallback(self.searchDialogClosed, YouTubeSearchDialog)
+
+
+ def searchDialogClosed(self, what, searchContext = None):
+ print "[YTB] searchDialogClosed: ", what
+ if what == SEARCH:
+ dlg = self.session.openWithCallback(self.youTubeListScreenClosed, YouTubeListScreen)
+ dlg.searchFeed(searchContext)
+ elif what == CANCEL:
+ interface.close()
+ elif what == STDFEEDS:
+ self.openStandardFeeds()
+ else:
+ if what == PLAYLISTS:
+ callback = self.openPlaylists
+ elif what == FAVORITES:
+ callback = self.openFavorites
+ if not interface.isLoggedIn():
+ self.session.openWithCallback(callback, YouTubeUserListScreen, youTubeUserConfig.getDefaultUser())
+ else:
+ callback(YouTubeUserListScreen.LOGIN_SUCCESS)
+
+
+ def openStandardFeeds(self):
+ self.session.openWithCallback(self.standardFeedSelected, YouTubeStdFeedSelectionScreen)
+
+
+ def standardFeedSelected(self, stdFeedUrl):
+ if stdFeedUrl is not None:
+ dlg = self.session.openWithCallback(self.youTubeListScreenClosed, YouTubeListScreen)
+ dlg.loadStandardFeed(stdFeedUrl)
+ else:
+ self.openSearchDialog()
+
+
+ def openPlaylists(self, loginState):
+ if loginState == YouTubeUserListScreen.LOGIN_SUCCESS:
+ print "[YTB] logged in"
+ dlg = self.session.openWithCallback(self.playlistChoosen, YouTubePlaylistScreen)
+ dlg.loadPlaylist()
+ elif loginState == YouTubeUserListScreen.LOGIN_FAILED:
+ print "[YTB] not logged in"
+ self.session.openWithCallback(self.backToSearchDialog, MessageBox, _("Login not successful"), MessageBox.TYPE_INFO)
+ else:
+ self.backToSearchDialog()
+
+
+ def playlistChoosen(self, playlist):
+ if playlist is not None:
+ dlg = self.session.openWithCallback(self.youTubeListScreenClosed, YouTubeListScreen)
+ dlg.loadPlaylistFeed(playlist)
+ else:
+ self.openSearchDialog()
+
+
+ def openFavorites(self, loginState):
+ if loginState == YouTubeUserListScreen.LOGIN_SUCCESS:
+ print "[YTB] logged in"
+ dlg = self.session.openWithCallback(self.youTubeListScreenClosed, YouTubeListScreen)
+ dlg.loadFavoritesFeed("default")
+ elif loginState == YouTubeUserListScreen.LOGIN_FAILED:
+ print "[YTB] not logged in"
+ self.session.openWithCallback(self.backToSearchDialog, MessageBox, _("Login not successful"), MessageBox.TYPE_INFO)
+ else:
+ self.backToSearchDialog()
+
+
+ def backToSearchDialog(self, dummy = True):
+ self.openSearchDialog()
+
+
+ def youTubeListScreenClosed(self, proceed):
+ if proceed:
+ self.openSearchDialog()
+ else:
+ interface.close()
+
+
+def main(session, **kwargs):
+ YouTubeManager(session).openSearchDialog()
+
+
+def Plugins(**kwargs):
+ loadPluginSkin(kwargs["path"])
+ return PluginDescriptor(
+ name="YouTube Player",
+ description=_("Search and play YouTube movies"),
+ where = [ PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_PLUGINMENU ],
+ icon = "plugin.png", fnc = boundFunction(main))
--- /dev/null
+<skin>
+ <screen name = "SuggestionsListScreen" position = "170,120" zPosition = "2" size = "394,185" backgroundColor = "#202020" flags = "wfNoBorder">
+ <eLabel position = "0,0" size = "394,185" backgroundColor = "#c0c0c0" zPosition = "-1" />
+ <widget name = "suggestionslist" position = "2,2" size = "390,181" scrollbarMode = "showOnDemand"/>
+ </screen>
+
+ <screen name = "YouTubeAddPlaylistDialog" position = "80,85" size = "560,315" title = "Edit YouTube Playlists">
+ <widget name = "config" position = "10,10" size = "540,250" scrollbarMode = "showOnDemand" />
+ <ePixmap name = "red" position = "0,275" zPosition = "4" size = "140,40" pixmap = "skin_default/buttons/red.png" transparent = "1" alphatest = "on" />
+ <ePixmap name = "green" position = "140,275" zPosition = "4" size = "140,40" pixmap = "skin_default/buttons/green.png" transparent = "1" alphatest = "on" />
+ <ePixmap name = "yellow" position = "280,275" zPosition = "4" size = "140,40" pixmap = "skin_default/buttons/yellow.png" transparent = "1" alphatest = "on" />
+ <ePixmap name = "blue" position = "420,275" zPosition = "4" size = "140,40" pixmap = "skin_default/buttons/blue.png" transparent = "1" alphatest = "on" />
+ <widget name = "key_red" position = "0,275" zPosition = "5" size = "140,40" valign = "center" halign = "center" font = "Regular;21" transparent = "1" foregroundColor = "white" shadowColor = "black" shadowOffset = "-1,-1" />
+ <widget name = "key_green" position = "140,275" zPosition = "5" size = "140,40" valign = "center" halign = "center" font = "Regular;21" transparent = "1" foregroundColor = "white" shadowColor = "black" shadowOffset = "-1,-1" />
+ <widget name = "key_yellow" position = "280,275" zPosition = "5" size = "140,40" valign = "center" halign = "center" font = "Regular;21" transparent = "1" foregroundColor = "white" shadowColor = "black" shadowOffset = "-1,-1" />
+ <widget name = "key_blue" position = "420,275" zPosition = "5" size = "140,40" valign = "center" halign = "center" font = "Regular;21" transparent = "1" foregroundColor = "white" shadowColor = "black" shadowOffset = "-1,-1" />
+ </screen>
+
+ <screen name = "YouTubeEntryContextMenu" position = "150,160" size = "400,260" title = "Video Context Menu">
+ <widget name = "menu" position = "10,10" size = "390,250" scrollbarMode = "showOnDemand" />
+ </screen>
+
+ <screen name = "YouTubeVideoDetailsScreen" position = "80,85" size = "560,410" title = "Video Details" transparent = "0">
+ <widget name = "video_thumbnail_1" position = "10,10" size = "130,97" alphatest = "on" />
+ <widget name = "video_thumbnail_2" position = "10,110" size = "130,97" alphatest = "on" />
+ <widget name = "video_thumbnail_3" position = "10,210" size = "130,97" alphatest = "on" />
+ <widget name = "label_video_duration" position = "150,10" size = "95,20" font = "Regular;20" halign = "right" />
+ <widget name = "video_duration" position = "250,10" size = "90,20" valign = "left" font = "Regular;20"/>
+ <widget name = "label_video_rating_average" position = "345,10" size = "95,20" font = "Regular;20" halign = "right" />
+ <widget name = "starsbg" pixmap = "/usr/lib/enigma2/python/Plugins/Extensions/YouTubePlayer/starsbar_empty.png" position = "445,10" zPosition = "0" size = "100,20" transparent = "1" alphatest = "on" />
+ <widget name = "stars" position = "445,10" size = "100,20" pixmap = "/usr/lib/enigma2/python/Plugins/Extensions/YouTubePlayer/starsbar_filled.png" transparent = "1" />
+ <widget name = "label_video_statistics_view_count" position = "150,30" size = "95,20" font = "Regular;20" halign = "right" />
+ <widget name = "video_statistics_view_count" position = "250,30" size = "90,20" valign = "left" font = "Regular;20"/>
+ <widget name = "label_video_numraters" position = "345,30" size = "95,20" font = "Regular;20" halign = "right" />
+ <widget name = "video_numraters" position = "445,30" size = "105,20" valign = "left" font = "Regular;20"/>
+ <widget name = "label_video_statistics_favorite_count" position = "150,50" size = "95,20" font = "Regular;20" halign = "right" />
+ <widget name = "video_statistics_favorite_count" position = "250,50" size = "90,20" valign = "left" font = "Regular;20"/>
+ <widget name = "label_video_published_on" position = "345,50" size = "95,20" font = "Regular;20" halign = "right" />
+ <widget name = "video_published_on" position = "445,50" size = "105,20" valign = "left" font = "Regular;20"/>
+ <widget name = "label_video_author" position = "150,70" size = "95,20" font = "Regular;20" halign = "right" />
+ <widget name = "video_author" position = "250,70" size = "300,20" valign = "left" font = "Regular;20"/>
+ <widget name = "label_video_category" position = "150,90" size = "95,20" font = "Regular;20" halign = "right" />
+ <widget name = "video_category" position = "250,90" size = "300,20" valign = "left" font = "Regular;20"/>
+ <widget name = "label_video_tags" position = "150,110" size = "95,20" font = "Regular;20" halign = "right" />
+ <widget name = "video_tags" position = "250,110" size = "300,60" valign = "left" font = "Regular;20"/>
+ <ePixmap pixmap = "skin_default/div-h.png" position = "150,179" zPosition = "1" size = "400,2" />
+ <widget name = "video_description" position = "150,190" size = "400,210" font = "Regular;20" />
+ </screen>
+
+ <screen name = "YouTubeListScreen" position = "80,85" size = "560,410" title = "YouTube Videos" transparent = "0">
+ <widget name = "label_total_results" position = "0,13" size = "160,20" font = "Regular;20" halign = "right" />
+ <widget name = "total_results" position = "170,13" size = "110,20" font = "Regular;20" />
+ <widget name = "label_currently_shown" position = "280,13" size = "110,20" font = "Regular;20" halign = "right" />
+ <widget name = "currently_shown" position = "400,13" size = "160,20" font = "Regular;20" />
+ <ePixmap pixmap = "skin_default/div-h.png" position = "0,44" zPosition = "1" size = "560,2" />
+ <widget name = "list" position = "5,55" size = "550,315" scrollbarMode = "showOnDemand" />
+ <ePixmap name = "key_red" position = "40,370" zPosition = "1" size = "200,40" pixmap = "skin_default/buttons/red-big.png" transparent = "1" alphatest = "on" />
+ <ePixmap name = "key_green" position = "320,370" zPosition = "1" size = "200,40" pixmap = "skin_default/buttons/green-big.png" transparent = "1" alphatest = "on" />
+ <widget name = "red" position = "40,370" size = "200,40" font = "Regular;19" valign = "center" halign = "center" transparent = "1" zPosition = "2" />
+ <widget name = "green" position = "320,370" size = "200,40" font = "Regular;19" valign = "center" halign = "center" transparent = "1" zPosition = "2" />
+ </screen>
+
+ <screen name = "YouTubePlaylistScreen" position = "80,85" size = "560,410" title = "YouTube Playlists" transparent = "0">
+ <widget name = "list" position = "5,10" size = "550,350" scrollbarMode = "showOnDemand" />
+ <ePixmap name = "key_red" position = "40,370" zPosition = "1" size = "200,40" pixmap = "skin_default/buttons/red-big.png" transparent = "1" alphatest = "on" />
+ <ePixmap name = "key_green" position = "320,370" zPosition = "1" size = "200,40" pixmap = "skin_default/buttons/green-big.png" transparent = "1" alphatest = "on" />
+ <widget name = "red" position = "40,370" size = "200,40" font = "Regular;19" valign = "center" halign = "center" transparent = "1" zPosition = "2" />
+ <widget name = "green" position = "320,370" size = "200,40" font = "Regular;19" valign = "center" halign = "center" transparent = "1" zPosition = "2" />
+ </screen>
+
+ <screen name = "YouTubeSearchDialog" position = "80,85" size = "560,315" title = "YouTube Player">
+ <widget name = "config" position = "10,10" size = "540,250" scrollbarMode = "showOnDemand" />
+ <ePixmap name = "red" position = "0,275" zPosition = "4" size = "140,40" pixmap = "skin_default/buttons/red.png" transparent = "1" alphatest = "on" />
+ <ePixmap name = "green" position = "140,275" zPosition = "4" size = "140,40" pixmap = "skin_default/buttons/green.png" transparent = "1" alphatest = "on" />
+ <ePixmap name = "yellow" position = "280,275" zPosition = "4" size = "140,40" pixmap = "skin_default/buttons/yellow.png" transparent = "1" alphatest = "on" />
+ <ePixmap name = "blue" position = "420,275" zPosition = "4" size = "140,40" pixmap = "skin_default/buttons/blue.png" transparent = "1" alphatest = "on" />
+ <widget name = "key_red" position = "0,275" zPosition = "5" size = "140,40" valign = "center" halign = "center" font = "Regular;21" transparent = "1" foregroundColor = "white" shadowColor = "black" shadowOffset = "-1,-1" />
+ <widget name = "key_green" position = "140,275" zPosition = "5" size = "140,40" valign = "center" halign = "center" font = "Regular;21" transparent = "1" foregroundColor = "white" shadowColor = "black" shadowOffset = "-1,-1" />
+ <widget name = "key_yellow" position = "280,275" zPosition = "5" size = "140,40" valign = "center" halign = "center" font = "Regular;21" transparent = "1" foregroundColor = "white" shadowColor = "black" shadowOffset = "-1,-1" />
+ <widget name = "key_blue" position = "420,275" zPosition = "5" size = "140,40" valign = "center" halign = "center" font = "Regular;21" transparent = "1" foregroundColor = "white" shadowColor = "black" shadowOffset = "-1,-1" />
+ </screen>
+
+ <screen name = "YouTubeStdFeedSelectionScreen" position = "80,85" size = "560,410" title = "YouTube Standard-Feeds">
+ <widget source = "menu" render = "Listbox" position = "10,10" size = "540,390" scrollbarMode = "showOnDemand" >
+ <convert type = "StringList" />
+ </widget>
+ </screen>
+
+ <screen name = "YouTubeUserConfigScreen" position = "80,85" size = "560,315" title = "Edit YouTube User-Profiles">
+ <widget name = "config" position = "10,10" size = "540,250" scrollbarMode = "showOnDemand" />
+ <ePixmap name = "red" position = "0,275" zPosition = "4" size = "140,40" pixmap = "skin_default/buttons/red.png" transparent = "1" alphatest = "on" />
+ <ePixmap name = "green" position = "140,275" zPosition = "4" size = "140,40" pixmap = "skin_default/buttons/green.png" transparent = "1" alphatest = "on" />
+ <ePixmap name = "yellow" position = "280,275" zPosition = "4" size = "140,40" pixmap = "skin_default/buttons/yellow.png" transparent = "1" alphatest = "on" />
+ <ePixmap name = "blue" position = "420,275" zPosition = "4" size = "140,40" pixmap = "skin_default/buttons/blue.png" transparent = "1" alphatest = "on" />
+ <widget name = "key_red" position = "0,275" zPosition = "5" size = "140,40" valign = "center" halign = "center" font = "Regular;21" transparent = "1" foregroundColor = "white" shadowColor = "black" shadowOffset = "-1,-1" />
+ <widget name = "key_green" position = "140,275" zPosition = "5" size = "140,40" valign = "center" halign = "center" font = "Regular;21" transparent = "1" foregroundColor = "white" shadowColor = "black" shadowOffset = "-1,-1" />
+ <widget name = "key_yellow" position = "280,275" zPosition = "5" size = "140,40" valign = "center" halign = "center" font = "Regular;21" transparent = "1" foregroundColor = "white" shadowColor = "black" shadowOffset = "-1,-1" />
+ <widget name = "key_blue" position = "420,275" zPosition = "5" size = "140,40" valign = "center" halign = "center" font = "Regular;21" transparent = "1" foregroundColor = "white" shadowColor = "black" shadowOffset = "-1,-1" />
+ </screen>
+
+ <screen name = "YouTubeUserListScreen" position = "80,85" size = "560,410" title = "YouTube User-Profiles" >
+ <widget name = "label_info" position = "10,9" size = "540,42" halign = "center" valign = "center" font = "Regular;21" />
+ <ePixmap pixmap = "skin_default/div-h.png" position = "0,56" zPosition = "1" size = "560,2" />
+ <widget name = "userlist" position = "10,62" size = "540,283" scrollbarMode = "showOnDemand"/>
+ <ePixmap name = "red" position = "0,370" zPosition = "4" size = "140,40" pixmap = "skin_default/buttons/red.png" transparent = "1" alphatest = "on" />
+ <ePixmap name = "green" position = "140,370" zPosition = "4" size = "140,40" pixmap = "skin_default/buttons/green.png" transparent = "1" alphatest = "on" />
+ <ePixmap name = "yellow" position = "280,370" zPosition = "4" size = "140,40" pixmap = "skin_default/buttons/yellow.png" transparent = "1" alphatest = "on" />
+ <ePixmap name = "blue" position = "420,370" zPosition = "4" size = "140,40" pixmap = "skin_default/buttons/blue.png" transparent = "1" alphatest = "on" />
+ <widget name = "key_red" position = "0,370" zPosition = "5" size = "140,40" valign = "center" halign = "center" font = "Regular;21" transparent = "1" foregroundColor = "white" shadowColor = "black" shadowOffset = "-1,-1" />
+ <widget name = "key_green" position = "140,370" zPosition = "5" size = "140,40" valign = "center" halign = "center" font = "Regular;21" transparent = "1" foregroundColor = "white" shadowColor = "black" shadowOffset = "-1,-1" />
+ <widget name = "key_yellow" position = "280,370" zPosition = "5" size = "140,40" valign = "center" halign = "center" font = "Regular;21" transparent = "1" foregroundColor = "white" shadowColor = "black" shadowOffset = "-1,-1" />
+ <widget name = "key_blue" position = "420,370" zPosition = "5" size = "140,40" valign = "center" halign = "center" font = "Regular;21" transparent = "1" foregroundColor = "white" shadowColor = "black" shadowOffset = "-1,-1" />
+ </screen>
+</skin>