Merge branch 'master' of ssh://drmichael@scm.schwerkraft.elitedvb.net/scmrepos/git...
[enigma2-plugins.git] / mytube / src / plugin.py
1 from Components.AVSwitch import AVSwitch
2 from Components.ActionMap import ActionMap
3 from Components.Button import Button
4 from Components.ConfigList import ConfigListScreen
5 from Components.Label import Label
6 from Components.Pixmap import Pixmap
7 from Components.ProgressBar import ProgressBar
8 from Components.ScrollLabel import ScrollLabel
9 from Components.Sources.List import List
10 from Components.Task import Task, Job, job_manager
11 from Components.config import config, ConfigSelection, ConfigSubsection, ConfigText, ConfigYesNo, getConfigListEntry
12 #, ConfigIP, ConfigNumber, ConfigLocations
13 from Screens.ChoiceBox import ChoiceBox
14 from Screens.MessageBox import MessageBox
15 from Screens.Screen import Screen
16 from Screens.VirtualKeyBoard import VirtualKeyBoard
17 from Tools.BoundFunction import boundFunction
18 from Tools.Directories import resolveFilename, SCOPE_HDD, SCOPE_CURRENT_PLUGIN
19 from Tools.Downloader import downloadWithProgress
20 from Tools.Log import Log
21
22 from Plugins.Plugin import PluginDescriptor
23
24 from MyTubePlayer import MyTubePlayer
25 from MyTubeSearch import ConfigTextWithGoogleSuggestions, MyTubeTasksScreen, MyTubeHistoryScreen
26 from MyTubeService import validate_cert, get_rnd, myTubeService
27 from MyTubeSettings import MyTubeSettingsScreen
28
29 from Plugins.SystemPlugins.TubeLib.youtube.Search import Search
30
31 from __init__ import decrypt_block
32
33 from enigma import eTPM, eTimer, ePoint, ePicLoad, eServiceReference
34 from os import path as os_path, remove as os_remove
35 from twisted.web import client
36
37 etpm = eTPM()
38 rootkey = ['\x9f', '|', '\xe4', 'G', '\xc9', '\xb4', '\xf4', '#', '&', '\xce', '\xb3', '\xfe', '\xda', '\xc9', 'U', '`', '\xd8', '\x8c', 's', 'o', '\x90', '\x9b', '\\', 'b', '\xc0', '\x89', '\xd1', '\x8c', '\x9e', 'J', 'T', '\xc5', 'X', '\xa1', '\xb8', '\x13', '5', 'E', '\x02', '\xc9', '\xb2', '\xe6', 't', '\x89', '\xde', '\xcd', '\x9d', '\x11', '\xdd', '\xc7', '\xf4', '\xe4', '\xe4', '\xbc', '\xdb', '\x9c', '\xea', '}', '\xad', '\xda', 't', 'r', '\x9b', '\xdc', '\xbc', '\x18', '3', '\xe7', '\xaf', '|', '\xae', '\x0c', '\xe3', '\xb5', '\x84', '\x8d', '\r', '\x8d', '\x9d', '2', '\xd0', '\xce', '\xd5', 'q', '\t', '\x84', 'c', '\xa8', ')', '\x99', '\xdc', '<', '"', 'x', '\xe8', '\x87', '\x8f', '\x02', ';', 'S', 'm', '\xd5', '\xf0', '\xa3', '_', '\xb7', 'T', '\t', '\xde', '\xa7', '\xf1', '\xc9', '\xae', '\x8a', '\xd7', '\xd2', '\xcf', '\xb2', '.', '\x13', '\xfb', '\xac', 'j', '\xdf', '\xb1', '\x1d', ':', '?']
39
40 config.plugins.mytube = ConfigSubsection()
41 config.plugins.mytube.search = ConfigSubsection()
42
43
44 config.plugins.mytube.search.searchTerm = ConfigTextWithGoogleSuggestions("", False)
45 config.plugins.mytube.search.orderBy = ConfigSelection(
46                                 [
47                                  ("relevance", _("Relevance")),
48                                  ("viewCount", _("View Count")),
49                                  ("date", _("Published")),
50                                  ("rating", _("Rating"))
51                                 ], "relevance")
52 config.plugins.mytube.search.time = ConfigSelection(
53                                 [
54                                  ("all_time", _("All Time")),
55                                  ("this_month", _("This Month")),
56                                  ("this_week", _("This Week")),
57                                  ("today", _("Today"))
58                                 ], "all_time")
59 config.plugins.mytube.search.safeSearch = ConfigSelection(
60                                 [
61                                  (Search.SAFE_SEARCH_NONE, _("No")),
62                                  (Search.SAFE_SEARCH_MODERATE, _("Moderately")),
63                                  (Search.SAFE_SEARCH_STRICT, _("Strictly")),
64                                 ], Search.SAFE_SEARCH_NONE)
65 config.plugins.mytube.search.categories = ConfigSelection(
66                                 [
67                                  (None, _("All")),
68                                  ("Film", _("Film & Animation")),
69                                  ("Autos", _("Autos & Vehicles")),
70                                  ("Music", _("Music")),
71                                  ("Animals", _("Pets & Animals")),
72                                  ("Sports", _("Sports")),
73                                  ("Travel", _("Travel & Events")),
74                                  ("Shortmov", _("Short Movies")),
75                                  ("Games", _("Gaming")),
76                                  ("Comedy", _("Comedy")),
77                                  ("People", _("People & Blogs")),
78                                  ("News", _("News & Politics")),
79                                  ("Entertainment", _("Entertainment")),
80                                  ("Education", _("Education")),
81                                  ("Howto", _("Howto & Style")),
82                                  ("Nonprofit", _("Nonprofits & Activism")),
83                                  ("Tech", _("Science & Technology"))
84                                 ], None)
85 config.plugins.mytube.search.lr = ConfigSelection(
86                                 [
87                                  ("au", _("Australia")),
88                                  ("br", _("Brazil")),
89                                  ("ca", _("Canada")),
90                                  ("cz", _("Czech Republic")),
91                                  ("fr", _("France")),
92                                  ("de", _("Germany")),
93                                  ("gb", _("Great Britain")),
94                                  ("au", _("Australia")),
95                                  ("nl", _("Holland")),
96                                  ("hk", _("Hong Kong")),
97                                  ("in", _("India")),
98                                  ("ie", _("Ireland")),
99                                  ("il", _("Israel")),
100                                  ("it", _("Italy")),
101                                  ("jp", _("Japan")),
102                                  ("mx", _("Mexico")),
103                                  ("nz", _("New Zealand")),
104                                  ("pl", _("Poland")),
105                                  ("ru", _("Russia")),
106                                  ("kr", _("South Korea")),
107                                  ("es", _("Spain")),
108                                  ("se", _("Sweden")),
109                                  ("tw", _("Taiwan")),
110                                  ("us", _("United States"))
111                                 ], "de")
112
113 config.plugins.mytube.general = ConfigSubsection()
114 config.plugins.mytube.general.showHelpOnOpen = ConfigYesNo(default = True)
115 config.plugins.mytube.general.loadFeedOnOpen = ConfigYesNo(default = True)
116 config.plugins.mytube.general.startFeed = ConfigSelection(
117                                 [
118                                  ("top_rated", _("Top rated")),
119                                 ], "top_rated")
120 config.plugins.mytube.general.on_movie_stop = ConfigSelection(default = "ask", choices = [
121         ("ask", _("Ask user")), ("quit", _("Return to movie list")), ("playnext", _("Play next video")), ("playagain", _("Play video again")) ])
122
123 config.plugins.mytube.general.on_exit = ConfigSelection(default = "ask", choices = [
124         ("ask", _("Ask user")), ("quit", _("Return to movie list"))])
125
126 default = resolveFilename(SCOPE_HDD)
127 tmp = config.movielist.videodirs.value
128 if default not in tmp:
129         tmp.append(default)
130 config.plugins.mytube.general.videodir = ConfigSelection(default = default, choices = tmp)
131 config.plugins.mytube.general.history = ConfigText(default="")
132 config.plugins.mytube.general.clearHistoryOnClose = ConfigYesNo(default = False)
133 config.plugins.mytube.general.AutoLoadFeeds = ConfigYesNo(default = True)
134 config.plugins.mytube.general.resetPlayService = ConfigYesNo(default = False)
135 config.plugins.mytube.general.authenticate = ConfigYesNo(default=False)
136
137 class downloadJob(Job):
138         def __init__(self, url, file, title):
139                 Job.__init__(self, title)
140                 downloadTask(self, url, file)
141
142 class downloadTask(Task):
143         def __init__(self, job, url, file):
144                 Task.__init__(self, job, ("download task"))
145                 self.end = 100
146                 self.url = url
147                 self.local = file
148
149         def prepare(self):
150                 self.error = None
151
152         def run(self, callback):
153                 self.callback = callback
154                 self.download = downloadWithProgress(self.url,self.local)
155                 self.download.addProgress(self.http_progress)
156                 self.download.start().addCallback(self.http_finished).addErrback(self.http_failed)
157
158         def http_progress(self, recvbytes, totalbytes):
159                 #print "[http_progress] recvbytes=%d, totalbytes=%d" % (recvbytes, totalbytes)
160                 self.progress = int(self.end*recvbytes/float(totalbytes))
161
162         def http_finished(self, string=""):
163                 print "[http_finished]" + str(string)
164                 Task.processFinished(self, 0)
165
166         def http_failed(self, failure_instance=None, error_message=""):
167                 if error_message == "" and failure_instance is not None:
168                         error_message = failure_instance.getErrorMessage()
169                         print "[http_failed] " + error_message
170                         Task.processFinished(self, 1)
171
172
173
174
175
176 class MyTubePlayerMainScreen(Screen, ConfigListScreen):
177         Details = {}
178         #(entry, Title, Description, TubeID, thumbnail, PublishedDate,Views,duration,ratings )
179         skin = """
180                 <screen name="MyTubePlayerMainScreen" flags="wfNoBorder" position="0,0" size="720,576" title="MyTube - Browser" >
181                         <ePixmap position="0,0" zPosition="-1" size="720,576" pixmap="~/mytubemain_bg.png" alphatest="on" transparent="1" backgroundColor="transparent"/>
182                         <widget name="config" zPosition="2" position="60,60" size="600,50" scrollbarMode="showNever" transparent="1" />
183                         <widget name="result" position="300,60" zPosition="3" size="350,50" font="Regular;21" transparent="1" backgroundColor="transparent" halign="right"/>
184                         <widget source="feedlist" render="Listbox" position="49,110" size="628,385" zPosition="1" scrollbarMode="showOnDemand" transparent="1" backgroundPixmap="~/list_bg.png" selectionPixmap="~/list_sel.png" >
185                                 <convert type="TemplatedMultiContent">
186                                 {"templates":
187                                         {"default": (77,[
188                                                         MultiContentEntryPixmapAlphaTest(pos = (0, 0), size = (100, 75), png = 4), # index 4 is the thumbnail
189                                                         MultiContentEntryText(pos = (100, 1), size = (500, 22), font=0, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = 1), # index 1 is the Title
190                                                         MultiContentEntryText(pos = (100, 24), size = (300, 18), font=1, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = 5), # index 5 is the Published Date
191                                                         MultiContentEntryText(pos = (100, 43), size = (300, 18), font=1, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = 6), # index 6 is the Views Count
192                                                         MultiContentEntryText(pos = (400, 24), size = (200, 18), font=1, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = 7), # index 7 is the duration
193                                                         MultiContentEntryText(pos = (400, 43), size = (200, 18), font=1, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = 8), # index 8 is the ratingcount
194                                                 ]),
195                                         "state": (77,[
196                                                         MultiContentEntryText(pos = (10, 1), size = (560, 28), font=2, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = 0), # index 0 is the name
197                                                         MultiContentEntryText(pos = (10, 22), size = (560, 46), font=3, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = 1), # index 2 is the description
198                                                 ])
199                                         },
200                                         "fonts": [gFont("Regular", 22),gFont("Regular", 18),gFont("Regular", 26),gFont("Regular", 20)],
201                                         "itemHeight": 77
202                                 }
203                                 </convert>
204                         </widget>
205
206                         <ePixmap pixmap="skin_default/buttons/key_info.png" position="50,500" zPosition="4" size="35,25" alphatest="on" transparent="1" />
207                         <ePixmap pixmap="skin_default/buttons/key_menu.png" position="50,520" zPosition="4" size="35,25" alphatest="on" transparent="1" />
208                         <ePixmap position="90,500" size="100,40" zPosition="4" pixmap="~/plugin.png" alphatest="on" transparent="1" />
209                         <ePixmap position="190,500" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
210                         <ePixmap position="330,500" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
211                         <ePixmap position="470,500" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
212                         <widget name="key_red" position="190,500" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
213                         <widget name="key_green" position="330,500" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
214                         <widget name="key_yellow" position="470,500" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
215                         <widget name="ButtonBlue" pixmap="skin_default/buttons/button_blue.png" position="610,510" zPosition="10" size="15,16" transparent="1" alphatest="on" />
216                         <widget name="VKeyIcon" pixmap="skin_default/vkey_icon.png" position="620,495" zPosition="10" size="60,48" transparent="1" alphatest="on" />
217                         <widget name="thumbnail" position="0,0" size="100,75" alphatest="on"/> # fake entry for dynamic thumbnail resizing, currently there is no other way doing this.
218                         <widget name="HelpWindow" position="160,255" zPosition="1" size="1,1" transparent="1" alphatest="on" />
219                 </screen>"""
220
221         def __init__(self, session, l2key=None):
222                 Screen.__init__(self, session)
223                 self.session = session
224                 self._userCodeMbx = None
225                 self.l2key = l2key
226                 self.l3key = None
227                 self.skin_path = plugin_path
228                 self.FeedURL = None
229                 self.ytfeed = None
230                 self.currentFeedName = None
231                 self.videolist = []
232                 self.queryThread = None
233                 self.queryRunning = False
234
235                 self.video_playlist = []
236                 self.statuslist = []
237                 self.mytubeentries = None
238
239                 self.thumbnails = []
240                 self.index = 0
241                 self.maxentries = 0
242
243                 self.screenshotList = []
244                 self.pixmaps_to_load = []
245                 self.picloads = {}
246
247                 self.oldfeedentrycount = 0
248                 self.appendEntries = False
249                 self.lastservice = session.nav.getCurrentlyPlayingServiceReference()
250                 self.propagateUpDownNormally = True
251                 self.FirstRun = True
252                 self.HistoryWindow = None
253                 self.History = None
254                 self.searchtext = _("Welcome to the MyTube Youtube Player.\n\nWhile entering your search term(s) you will get suggestions displayed matching your search term.\n\nTo select a suggestion press DOWN on your remote, select the desired result and press OK on your remote to start the search.\n\nPress exit to get back to the input field.")
255                 self.feedtext = _("Welcome to the MyTube Youtube Player.\n\nUse the Bouqet+ button to navigate to the search field and the Bouqet- to navigate to the video entries.\n\nTo play a movie just press OK on your remote control.\n\nPress info to see the movie description.\n\nPress the Menu button for additional options.\n\nThe Help button shows this help again.")
256                 self.currList = "configlist"
257                 self.oldlist = None
258
259                 self["feedlist"] = List(self.videolist)
260                 self["thumbnail"] = Pixmap()
261                 self["thumbnail"].hide()
262                 self["HelpWindow"] = Pixmap()
263                 self["HelpWindow"].hide()
264                 self["key_red"] = Button(_("Close"))
265                 self["key_green"] = Button(_("Std. Feeds"))
266                 self["key_yellow"] = Button(_("History"))
267                 self["ButtonBlue"] = Pixmap()
268                 self["VKeyIcon"] = Pixmap()
269                 self["ButtonBlue"].hide()
270                 self["VKeyIcon"].hide()
271                 self["result"] = Label("")
272
273
274                 self["searchactions"] = ActionMap(["ShortcutActions", "WizardActions", "HelpActions", "MediaPlayerActions"],
275                 {
276                         "ok": self.keyOK,
277                         "back": self.leavePlayer,
278                         "red": self.leavePlayer,
279                         "blue": self.openKeyboard,
280                         "yellow": self.handleHistory,
281                         "up": self.keyUp,
282                         "down": self.handleSuggestions,
283                         "left": self.keyLeft,
284                         "right": self.keyRight,
285                         "prevBouquet": self.switchToFeedList,
286                         "nextBouquet": self.switchToConfigList,
287                         "displayHelp": self.handleHelpWindow,
288                         "menu" : self.handleMenu,
289                 }, -2)
290
291                 self["suggestionactions"] = ActionMap(["ShortcutActions", "WizardActions", "MediaPlayerActions", "HelpActions", "NumberActions"],
292                 {
293                         "ok": self.keyOK,
294                         "back": self.switchToConfigList,
295                         "red": self.switchToConfigList,
296                         "nextBouquet": self.switchToConfigList,
297                         "prevBouquet": self.switchToFeedList,
298                         "up": self.keyUp,
299                         "down": self.keyDown,
300                         "left": self.keyLeft,
301                         "right": self.keyRight,
302                         "0": self.toggleScreenVisibility
303                 }, -2)
304
305
306                 self["videoactions"] = ActionMap(["ShortcutActions", "WizardActions", "MediaPlayerActions", "MovieSelectionActions", "HelpActions"],
307                 {
308                         "ok": self.keyOK,
309                         "back": self.leavePlayer,
310                         "red": self.leavePlayer,
311                         "yellow": self.handleHistory,
312                         "up": self.keyUp,
313                         "down": self.keyDown,
314                         "nextBouquet": self.switchToConfigList,
315                         "green": self.keyStdFeed,
316                         "showEventInfo": self.showVideoInfo,
317                         "displayHelp": self.handleHelpWindow,
318                         "menu" : self.handleMenu,
319                 }, -2)
320
321                 self["statusactions"] = ActionMap(["ShortcutActions", "WizardActions", "HelpActions", "MediaPlayerActions"],
322                 {
323                         "back": self.leavePlayer,
324                         "red": self.leavePlayer,
325                         "nextBouquet": self.switchToConfigList,
326                         "green": self.keyStdFeed,
327                         "yellow": self.handleHistory,
328                         "menu": self.handleMenu
329                 }, -2)
330
331                 self["historyactions"] = ActionMap(["ShortcutActions", "WizardActions", "MediaPlayerActions", "MovieSelectionActions", "HelpActions"],
332                 {
333                         "ok": self.keyOK,
334                         "back": self.closeHistory,
335                         "red": self.closeHistory,
336                         "yellow": self.handleHistory,
337                         "up": self.keyUp,
338                         "down": self.keyDown,
339                         "left": self.keyLeft,
340                         "right": self.keyRight,
341                 }, -2)
342
343                 self["videoactions"].setEnabled(False)
344                 self["statusactions"].setEnabled(False)
345                 self["historyactions"].setEnabled(False)
346
347                 self.timer_startDownload = eTimer()
348                 self.timer_startDownload_conn = self.timer_startDownload.timeout.connect(self.downloadThumbnails)
349                 self.timer_thumbnails = eTimer()
350                 self.timer_thumbnails_conn = self.timer_thumbnails.timeout.connect(self.updateFeedThumbnails)
351
352                 self.SearchConfigEntry = None
353                 self.searchContextEntries = []
354                 config.plugins.mytube.search.searchTerm.value = ""
355                 ConfigListScreen.__init__(self, self.searchContextEntries, session)
356                 self.createSetup()
357                 self.onLayoutFinish.append(self.layoutFinished)
358                 self.onShown.append(self.setWindowTitle)
359                 self.onClose.append(self.__onClose)
360
361         def __onClose(self):
362                 del self.timer_startDownload
363                 del self.timer_thumbnails
364                 self.Details = {}
365                 self.session.nav.playService(self.lastservice)
366
367         def layoutFinished(self):
368                 self.currList = "status"
369                 current = self["config"].getCurrent()
370                 if current[1].help_window.instance is not None:
371                         current[1].help_window.instance.hide()
372
373                 l3cert = etpm.getData(eTPM.DT_LEVEL3_CERT)
374                 if l3cert is None or l3cert is "":
375                         self["videoactions"].setEnabled(False)
376                         self["searchactions"].setEnabled(False)
377                         self["config_actions"].setEnabled(False)
378                         self["historyactions"].setEnabled(False)
379                         self["statusactions"].setEnabled(True)
380                         self.hideSuggestions()
381                         self.statuslist = []
382                         self.statuslist.append(( _("Genuine Dreambox validation failed!"), _("Verify your Dreambox authenticity by running the genuine dreambox plugin!" ) ))
383                         self["feedlist"].style = "state"
384                         self['feedlist'].setList(self.statuslist)
385                         return
386
387                 self.l3key = validate_cert(l3cert, self.l2key)
388                 if self.l3key is None:
389                         print "l3cert invalid"
390                         return
391                 rnd = get_rnd()
392                 if rnd is None:
393                         print "random error"
394                         return
395
396                 val = etpm.computeSignature(rnd)
397                 result = decrypt_block(val, self.l3key)
398
399                 self.statuslist = []
400                 if result[80:88] != rnd:
401                         self.statuslist.append(( _("Genuine Dreambox validation failed!"), _("Verify your Dreambox authenticity by running the genuine dreambox plugin!" ) ))
402                         self["feedlist"].style = "state"
403                         self['feedlist'].setList(self.statuslist)
404                         return
405
406                 # we need to login here; startService() is fired too often for external curl
407 #               self.tryUserLogin()
408
409                 self.statuslist.append(( _("Fetching feed entries"), _("Trying to download the Youtube feed entries. Please wait..." ) ))
410                 self["feedlist"].style = "state"
411                 self['feedlist'].setList(self.statuslist)
412                 myTubeService.addReadyCallback(self._onServiceReady)
413                 if config.plugins.mytube.general.authenticate.value:
414                         myTubeService.startAuthenticatedService(self._onUserCodeReady)
415                 else:
416                         myTubeService.startService()
417
418         def _onServiceReady(self, ready):
419                 Log.w("%s" %(ready,))
420                 if self._userCodeMbx:
421                         self._userCodeMbx.close()
422                         self._userCodeMbx = None
423
424                 if ready:
425                         if config.plugins.mytube.general.loadFeedOnOpen.value:
426                                 self.getFeed()
427                                 self.setState('getFeed')
428                         else:
429                                 self.setState('byPass')
430
431         def setWindowTitle(self):
432                 self.setTitle(_("MyTubePlayer"))
433
434         def createSetup(self):
435                 self.searchContextEntries = []
436                 self.SearchConfigEntry = getConfigListEntry(_("Search Term(s)"), config.plugins.mytube.search.searchTerm)
437                 self.searchContextEntries.append(self.SearchConfigEntry)
438                 self["config"].list = self.searchContextEntries
439                 self["config"].l.setList(self.searchContextEntries)
440
441         def setState(self,status = None):
442                 if status:
443                         self.currList = "status"
444                         self["videoactions"].setEnabled(False)
445                         self["searchactions"].setEnabled(False)
446                         self["config_actions"].setEnabled(False)
447                         self["historyactions"].setEnabled(False)
448                         self["statusactions"].setEnabled(True)
449                         self["ButtonBlue"].hide()
450                         self["VKeyIcon"].hide()
451                         self.statuslist = []
452                         self.hideSuggestions()
453                         result = None
454                         if self.l3key is not None:
455                                 rnd = get_rnd()
456                                 if rnd is None:
457                                         return
458                                 val = etpm.computeSignature(rnd)
459                                 result = decrypt_block(val, self.l3key)
460                         if not result or result[80:88] != rnd:
461                                 self["key_green"].show()
462                                 self.statuslist.append(( _("Genuine Dreambox validation failed!"), _("Verify your Dreambox authenticity by running the genuine dreambox plugin!" ) ))
463                                 self["feedlist"].style = "state"
464                                 self['feedlist'].setList(self.statuslist)
465                                 return
466
467                         print "Genuine Dreambox validation passed"
468
469                         if self.HistoryWindow is not None:
470                                 self.HistoryWindow.deactivate()
471                                 self.HistoryWindow.instance.hide()
472                         if status == 'getFeed':
473                                 self.statuslist.append(( _("Fetching feed entries"), _("Trying to download the Youtube feed entries. Please wait..." ) ))
474                         elif status == 'getSearchFeed':
475                                 self.statuslist.append(( _("Fetching search entries"), _("Trying to download the Youtube search results. Please wait..." ) ))
476                         elif status == 'Error':
477                                 self.statuslist.append(( _("An error occured."), _("There was an error getting the feed entries. Please try again." ) ))
478                         elif status == 'noVideos':
479                                 self["key_green"].show()
480                                 self.statuslist.append(( _("No videos to display"), _("Please select a standard feed or try searching for videos." ) ))
481                         elif status == 'byPass':
482                                 self.statuslist.append(( _("Not fetching feed entries"), _("Please enter your search term." ) ))
483                                 self["feedlist"].style = "state"
484                                 self['feedlist'].setList(self.statuslist)
485                                 self.switchToConfigList()
486                         self["feedlist"].style = "state"
487                         self['feedlist'].setList(self.statuslist)
488
489
490         def _onUserCodeReady(self, userCode):
491                 self._userCodeMbx = self.session.open(MessageBox, str(_("Please visit: %s\nAnd enter: %s") % (userCode.verification_url, userCode.user_code)), type=MessageBox.TYPE_INFO, title=_("Authentication awaiting"))
492                 Log.w(userCode)
493
494         def handleHelpWindow(self):
495                 print "[handleHelpWindow]"
496                 if self.currList == "configlist":
497                         self.hideSuggestions()
498                         self.session.openWithCallback(self.ScreenClosed, MyTubeVideoHelpScreen, self.skin_path, wantedinfo = self.searchtext, wantedtitle = _("MyTubePlayer Help") )
499                 elif self.currList == "feedlist":
500                         self.session.openWithCallback(self.ScreenClosed, MyTubeVideoHelpScreen, self.skin_path, wantedinfo = self.feedtext, wantedtitle = _("MyTubePlayer Help") )
501
502         def handleFirstHelpWindow(self):
503                 print "[handleFirstHelpWindow]"
504                 if config.plugins.mytube.general.showHelpOnOpen.value is True:
505                         if self.currList == "configlist":
506                                 self.hideSuggestions()
507                                 self.session.openWithCallback(self.firstRunHelpClosed, MyTubeVideoHelpScreen, self.skin_path,wantedinfo = self.feedtext, wantedtitle = _("MyTubePlayer Help") )
508                 else:
509                         self.FirstRun = False
510
511         def firstRunHelpClosed(self):
512                 if self.FirstRun == True:
513                         self.FirstRun = False
514                         self.switchToConfigList()
515
516         def handleMenu(self):
517                 if self.currList == "configlist" or self.currList == "status":
518                         menulist = (
519                                         (_("MyTube Settings"), "settings"),
520                                 )
521                         self.hideSuggestions()
522                         self.session.openWithCallback(self.openMenu, ChoiceBox, title=_("Select your choice."), list = menulist)
523
524                 elif self.currList == "feedlist":
525                         menulist = [(_("MyTube Settings"), "settings")]
526                         menulist.extend((
527                                         (_("Related videos"), "related"),
528                                         (_("Channel videos"), "channel_videos"),
529                                 ))
530                         
531                         if myTubeService.is_auth() is True:
532                                 menulist.extend((
533                                                 (_("Subscribe to channel"), "subscribe"),
534                                                 (_("Add to favorites"), "favorite"),
535                                         ))                              
536                         
537                         if config.usage.setup_level.index >= 2: # expert+
538                                 menulist.extend((
539                                         (_("Download Video"), "download"),
540                                         (_("View active downloads"), "downview")
541                                 ))
542
543                         self.hideSuggestions()
544                         self.session.openWithCallback(self.openMenu, ChoiceBox, title=_("Select your choice."), list = menulist)
545
546         def openMenu(self, answer):
547                 answer = answer and answer[1]
548                 if answer == "settings":
549                         print "settings selected"
550                         self.session.openWithCallback(self.ScreenClosed,MyTubeSettingsScreen, self.skin_path )
551                 elif answer == "related":
552                         current = self["feedlist"].getCurrent()[0]
553                         self.setState('getFeed')
554                         self.getRelatedVideos(current)
555                 elif answer == "channel_videos":
556                         current = self["feedlist"].getCurrent()[0]
557                         self.setState('getFeed')
558                         self.getChannelVideos(current)
559                 elif answer == "subscribe":
560                         current = self["feedlist"].getCurrent()[0]
561                         self.session.open(MessageBox, current.subscribeToUser(), MessageBox.TYPE_INFO)
562                 elif answer == "favorite":
563                         current = self["feedlist"].getCurrent()[0]
564                         self.session.open(MessageBox, current.addToFavorites(), MessageBox.TYPE_INFO)
565                                         
566                 elif answer == "response":
567                         current = self["feedlist"].getCurrent()[0]
568                         self.setState('getFeed')
569                         self.getResponseVideos(current)
570                 elif answer == "download":
571                         if self.currList == "feedlist":
572                                 current = self[self.currList].getCurrent()
573                                 if current:
574                                         video = current[0]
575                                         if video:
576                                                 myurl = video.url
577                                                 filename = str(config.plugins.mytube.general.videodir.value)+ str(video.title) + '.mp4'
578                                                 job_manager.AddJob(downloadJob(myurl,filename, str(video.title)[:30]))
579                 elif answer == "downview":
580                         self.tasklist = []
581                         for job in job_manager.getPendingJobs():
582                                 self.tasklist.append((job,job.name,job.getStatustext(),int(100*job.progress/float(job.end)) ,str(100*job.progress/float(job.end)) + "%" ))
583                         self.session.open(MyTubeTasksScreen, self.skin_path , self.tasklist)
584                 elif answer == None:
585                         self.ScreenClosed()
586
587         def openKeyboard(self):
588                 self.hideSuggestions()
589                 self.session.openWithCallback(self.SearchEntryCallback, VirtualKeyBoard, title = (_("Enter your search term(s)")), text = config.plugins.mytube.search.searchTerm.value)
590
591         def ScreenClosed(self):
592                 print "ScreenCLosed, restoring old window state"
593                 if self.currList == "historylist":
594                         if self.HistoryWindow.status() is False:
595                                 self.HistoryWindow.activate()
596                                 self.HistoryWindow.instance.show()
597                 elif self.currList == "configlist":
598                         self.switchToConfigList()
599                         ConfigListScreen.keyOK(self)
600                 elif self.currList == "feedlist":
601                         self.switchToFeedList()
602
603         def SearchEntryCallback(self, callback = None):
604                 if callback is not None and len(callback):
605                         config.plugins.mytube.search.searchTerm.value = callback
606                         ConfigListScreen.keyOK(self)
607                         self["config"].getCurrent()[1].getSuggestions()
608                 current = self["config"].getCurrent()
609                 if current[1].help_window.instance is not None:
610                         current[1].help_window.instance.show()
611                 if current[1].suggestionsWindow.instance is not None:
612                         current[1].suggestionsWindow.instance.show()
613                 self.propagateUpDownNormally = True
614
615         def openStandardFeedClosed(self, answer):
616                 answer = answer and answer[1]
617                 if answer is not None:
618                         self.setState('getFeed')
619                         self.appendEntries = False
620                         self.getFeed(videoCategoryId=answer)
621
622         def handleLeave(self, how):
623                 self.is_closing = True
624                 if how == "ask":
625                         if self.currList == "configlist":
626                                 list = (
627                                         (_("Yes"), "quit"),
628                                         (_("No"), "continue"),
629                                         (_("No, but switch to video entries."), "switch2feed")
630                                 )
631                         else:
632                                 list = (
633                                         (_("Yes"), "quit"),
634                                         (_("No"), "continue"),
635                                         (_("No, but switch to video search."), "switch2search")
636                                 )
637                         self.session.openWithCallback(self.leavePlayerConfirmed, ChoiceBox, title=_("Really quit MyTube Player?"), list = list)
638                 else:
639                         self.leavePlayerConfirmed([True, how])
640
641         def leavePlayer(self):
642                 print "leavePlayer"
643                 if self.HistoryWindow is not None:
644                         self.HistoryWindow.deactivate()
645                         self.HistoryWindow.instance.hide()
646                 if self.currList == "configlist":
647                         current = self["config"].getCurrent()
648                         if current[1].suggestionsWindow.activeState is True:
649                                 self.propagateUpDownNormally = True
650                                 current[1].deactivateSuggestionList()
651                                 self["config"].invalidateCurrent()
652                         else:
653                                 self.hideSuggestions()
654                                 self.handleLeave(config.plugins.mytube.general.on_exit.value)
655                 else:
656                         self.hideSuggestions()
657                         self.handleLeave(config.plugins.mytube.general.on_exit.value)
658
659         def leavePlayerConfirmed(self, answer):
660                 answer = answer and answer[1]
661                 if answer == "quit":
662                         self.doQuit()
663                 elif answer == "continue":
664                         if self.currList == "historylist":
665                                 if self.HistoryWindow.status() is False:
666                                         self.HistoryWindow.activate()
667                                         self.HistoryWindow.instance.show()
668                         elif self.currList == "configlist":
669                                 self.switchToConfigList()
670                         elif self.currList == "feedlist":
671                                 self.switchToFeedList()
672                 elif answer == "switch2feed":
673                         self.switchToFeedList()
674                 elif answer == "switch2search":
675                         self.switchToConfigList()
676                 elif answer == None:
677                         if self.currList == "historylist":
678                                 if self.HistoryWindow.status() is False:
679                                         self.HistoryWindow.activate()
680                                         self.HistoryWindow.instance.show()
681                         elif self.currList == "configlist":
682                                 self.switchToConfigList()
683                         elif self.currList == "feedlist":
684                                 self.switchToFeedList()
685
686         def doQuit(self):
687                 myTubeService.onReady.remove(self._onServiceReady)
688
689                 if self["config"].getCurrent()[1].suggestionsWindow is not None:
690                         self.session.deleteDialog(self["config"].getCurrent()[1].suggestionsWindow)
691                 if self.HistoryWindow is not None:
692                         self.session.deleteDialog(self.HistoryWindow)
693                 if config.plugins.mytube.general.showHelpOnOpen.value is True:
694                         config.plugins.mytube.general.showHelpOnOpen.value = False
695                         config.plugins.mytube.general.showHelpOnOpen.save()
696                 if not config.plugins.mytube.general.clearHistoryOnClose.value:
697                         if self.History and len(self.History):
698                                 config.plugins.mytube.general.history.value = ",".join(self.History)
699                 else:
700                         config.plugins.mytube.general.history.value = ""
701                 config.plugins.mytube.general.history.save()
702                 config.plugins.mytube.general.save()
703                 config.plugins.mytube.save()
704                 self.cancelThread()
705                 self.close()
706
707         def keyOK(self):
708                 print "self.currList im KeyOK",self.currList
709                 if self.currList == "configlist" or self.currList == "suggestionslist":
710                         self["config"].invalidateCurrent()
711                         if config.plugins.mytube.search.searchTerm.value != "":
712                                 self.add2History()
713                                 searchTerm = config.plugins.mytube.search.searchTerm.value
714                                 print "Search searchcontext",searchTerm
715                                 if isinstance(self["config"].getCurrent()[1], ConfigTextWithGoogleSuggestions) and not self.propagateUpDownNormally:
716                                         self.propagateUpDownNormally = True
717                                         self["config"].getCurrent()[1].deactivateSuggestionList()
718                                 self.setState('getSearchFeed')
719                                 self.runSearch(searchTerm)
720                 elif self.currList == "feedlist":
721                         current = self[self.currList].getCurrent()
722                         if current:
723                                 Log.d(current)
724                                 video = current[0]
725                                 if video is not None:
726                                         myurl = video.url
727                                         print "Playing URL",myurl
728                                         if myurl is not None:
729                                                 myreference = eServiceReference(4097,0,myurl)
730                                                 myreference.setName(video.title)
731                                                 self.session.openWithCallback(self.onPlayerClosed, MyTubePlayer, myreference, self.lastservice, infoCallback = self.showVideoInfo, nextCallback = self.getNextEntry, prevCallback = self.getPrevEntry )
732                                         else:
733                                                 self.session.open(MessageBox, _("Sorry, video is not available!"), MessageBox.TYPE_INFO)
734                 elif self.currList == "historylist":
735                         if self.HistoryWindow is not None:
736                                 config.plugins.mytube.search.searchTerm.value = self.HistoryWindow.getSelection()
737                         self["config"].invalidateCurrent()
738                         if config.plugins.mytube.search.searchTerm.value != "":
739                                 searchTerm = config.plugins.mytube.search.searchTerm.value
740                                 print "Search searchcontext",searchTerm
741                                 self.setState('getSearchFeed')
742                                 self.runSearch(searchTerm)
743
744         def onPlayerClosed(self):
745                 if config.plugins.mytube.general.resetPlayService.value is True:
746                         self.session.nav.playService(self.lastservice)
747
748         def toggleScreenVisibility(self):
749                 if self.shown is True:
750                         self.hide()
751                 else:
752                         self.show()
753
754         def keyUp(self):
755                 print "self.currList im KeyUp",self.currList
756                 if self.currList == "suggestionslist":
757                         if config.plugins.mytube.search.searchTerm.value != "":
758                                 if not self.propagateUpDownNormally:
759                                         self["config"].getCurrent()[1].suggestionListUp()
760                                         self["config"].invalidateCurrent()
761                 elif self.currList == "feedlist":
762                         self[self.currList].selectPrevious()
763                 elif self.currList == "historylist":
764                         if self.HistoryWindow is not None and self.HistoryWindow.shown:
765                                 self.HistoryWindow.up()
766
767         def keyDown(self):
768                 print "self.currList im KeyDown",self.currList
769                 if self.currList == "suggestionslist":
770                         if config.plugins.mytube.search.searchTerm.value != "":
771                                 if not self.propagateUpDownNormally:
772                                         self["config"].getCurrent()[1].suggestionListDown()
773                                         self["config"].invalidateCurrent()
774                 elif self.currList == "feedlist":
775                         print self[self.currList].count()
776                         print self[self.currList].index
777                         if self[self.currList].index == self[self.currList].count()-1 and myTubeService.hasNextPage():
778                                 # load new feeds on last selected item
779                                 if config.plugins.mytube.general.AutoLoadFeeds.value is False:
780                                         self.session.openWithCallback(self.getNextEntries, MessageBox, _("Do you want to see more entries?"))
781                                 else:
782                                         self.getNextEntries(True)
783                         else:
784                                 self[self.currList].selectNext()
785                 elif self.currList == "historylist":
786                         if self.HistoryWindow is not None and self.HistoryWindow.shown:
787                                 self.HistoryWindow.down()
788         def keyRight(self):
789                 print "self.currList im KeyRight",self.currList
790                 if self.propagateUpDownNormally:
791                         ConfigListScreen.keyRight(self)
792                 else:
793                         if self.currList == "suggestionslist":
794                                 if config.plugins.mytube.search.searchTerm.value != "":
795                                         self["config"].getCurrent()[1].suggestionListPageDown()
796                                         self["config"].invalidateCurrent()
797                         elif self.currList == "historylist":
798                                 if self.HistoryWindow is not None and self.HistoryWindow.shown:
799                                         self.HistoryWindow.pageDown()
800
801         def keyLeft(self):
802                 print "self.currList im kEyLeft",self.currList
803                 if self.propagateUpDownNormally:
804                         ConfigListScreen.keyLeft(self)
805                 else:
806                         if self.currList == "suggestionslist":
807                                 if config.plugins.mytube.search.searchTerm.value != "":
808                                         self["config"].getCurrent()[1].suggestionListPageUp()
809                                         self["config"].invalidateCurrent()
810                         elif self.currList == "historylist":
811                                 if self.HistoryWindow is not None and self.HistoryWindow.shown:
812                                         self.HistoryWindow.pageDown()
813         def keyStdFeed(self):
814                 self.hideSuggestions()
815                 menulist = []
816                 for category in myTubeService.getCategories():
817                         menulist.append((category.title, category.id))
818 #               if myTubeService.is_auth():
819 #                       menulist.extend((
820 #                               (_("My Subscriptions"), "my_subscriptions"),
821 #                               (_("My Favorites"), "my_favorites"),
822 #                               (_("My History"), "my_history"),
823 #                               (_("My Watch Later"), "my_watch_later"),
824 #                               (_("My Recommendations"), "my_recommendations"),
825 #                               (_("My Uploads"), "my_uploads"),
826 #                       ))
827
828                 self.session.openWithCallback(self.openStandardFeedClosed, ChoiceBox, title=_("Select new feed to view."), list = menulist)
829
830         def handleSuggestions(self):
831                 print "handleSuggestions"
832                 print "self.currList",self.currList
833                 if self.currList == "configlist":
834                         self.switchToSuggestionsList()
835                 elif self.currList == "historylist":
836                         if self.HistoryWindow is not None and self.HistoryWindow.shown:
837                                 self.HistoryWindow.down()
838
839         def switchToSuggestionsList(self):
840                 print "switchToSuggestionsList"
841                 self.currList = "suggestionslist"
842                 self["ButtonBlue"].hide()
843                 self["VKeyIcon"].hide()
844                 self["statusactions"].setEnabled(False)
845                 self["config_actions"].setEnabled(False)
846                 self["videoactions"].setEnabled(False)
847                 self["searchactions"].setEnabled(False)
848                 self["suggestionactions"].setEnabled(True)
849                 self["historyactions"].setEnabled(False)
850                 self["key_green"].hide()
851                 self.propagateUpDownNormally = False
852                 self["config"].invalidateCurrent()
853                 if self.HistoryWindow is not None and self.HistoryWindow.shown:
854                         self.HistoryWindow.deactivate()
855                         self.HistoryWindow.instance.hide()
856
857         def switchToConfigList(self):
858                 print "switchToConfigList"
859                 self.currList = "configlist"
860                 self["config_actions"].setEnabled(True)
861                 self["historyactions"].setEnabled(False)
862                 self["statusactions"].setEnabled(False)
863                 self["videoactions"].setEnabled(False)
864                 self["suggestionactions"].setEnabled(False)
865                 self["searchactions"].setEnabled(True)
866                 self["key_green"].hide()
867                 self["ButtonBlue"].show()
868                 self["VKeyIcon"].show()
869                 self["config"].invalidateCurrent()
870                 helpwindowpos = self["HelpWindow"].getPosition()
871                 current = self["config"].getCurrent()
872                 if current[1].help_window.instance is not None:
873                         current[1].help_window.instance.move(ePoint(helpwindowpos[0],helpwindowpos[1]))
874                         current[1].help_window.instance.show()
875                 if current[1].suggestionsWindow.instance is not None:
876                         current[1].suggestionsWindow.instance.show()
877                         self["config"].getCurrent()[1].getSuggestions()
878                 self.propagateUpDownNormally = True
879                 if self.HistoryWindow is not None and self.HistoryWindow.shown:
880                         self.HistoryWindow.deactivate()
881                         self.HistoryWindow.instance.hide()
882                 if self.FirstRun == True:
883                         self.handleFirstHelpWindow()
884
885         def switchToFeedList(self, append = False):
886                 print "switchToFeedList"
887                 print "switching to feedlist from:",self.currList
888                 print "len(self.videolist):",len(self.videolist)
889                 if self.HistoryWindow is not None and self.HistoryWindow.shown:
890                         self.HistoryWindow.deactivate()
891                         self.HistoryWindow.instance.hide()
892                 self.hideSuggestions()
893                 if len(self.videolist):
894                         self.currList = "feedlist"
895                         self["ButtonBlue"].hide()
896                         self["VKeyIcon"].hide()
897                         self["videoactions"].setEnabled(True)
898                         self["suggestionactions"].setEnabled(False)
899                         self["searchactions"].setEnabled(False)
900                         self["statusactions"].setEnabled(False)
901                         self["historyactions"].setEnabled(False)
902                         self["key_green"].show()
903                         self["config_actions"].setEnabled(False)
904                         if not append:
905                                 self[self.currList].setIndex(0)
906                         self["feedlist"].updateList(self.videolist)
907                 else:
908                         self.setState('noVideos')
909
910
911         def switchToHistory(self):
912                 print "switchToHistory"
913                 self.oldlist = self.currList
914                 self.currList = "historylist"
915                 print "switchToHistory currentlist",self.currList
916                 print "switchToHistory oldlist",self.oldlist
917                 self.hideSuggestions()
918                 self["ButtonBlue"].hide()
919                 self["VKeyIcon"].hide()
920                 self["key_green"].hide()
921                 self["videoactions"].setEnabled(False)
922                 self["suggestionactions"].setEnabled(False)
923                 self["searchactions"].setEnabled(False)
924                 self["statusactions"].setEnabled(False)
925                 self["config_actions"].setEnabled(False)
926                 self["historyactions"].setEnabled(True)
927                 self.HistoryWindow.activate()
928                 self.HistoryWindow.instance.show()
929
930         def handleHistory(self):
931                 if self.HistoryWindow is None:
932                         self.HistoryWindow = self.session.instantiateDialog(MyTubeHistoryScreen, zPosition=1000)
933                 if self.currList in ("configlist","feedlist"):
934                         if self.HistoryWindow.status() is False:
935                                 print "status is FALSE,switchToHistory"
936                                 self.switchToHistory()
937                 elif self.currList == "historylist":
938                         self.closeHistory()
939
940         def closeHistory(self):
941                 print "closeHistory currentlist",self.currList
942                 print "closeHistory oldlist",self.oldlist
943                 if self.currList == "historylist":
944                         if self.HistoryWindow.status() is True:
945                                 print "status is TRUE, closing historyscreen"
946                                 self.HistoryWindow.deactivate()
947                                 self.HistoryWindow.instance.hide()
948                                 if self.oldlist == "configlist":
949                                         self.switchToConfigList()
950                                 elif self.oldlist == "feedlist":
951                                         self.switchToFeedList()
952
953         def add2History(self):
954                 if self.History is None:
955                         self.History = config.plugins.mytube.general.history.value.split(',')
956                 if self.History[0] == '':
957                         del self.History[0]
958                 print "self.History im add",self.History
959                 if config.plugins.mytube.search.searchTerm.value in self.History:
960                         self.History.remove((config.plugins.mytube.search.searchTerm.value))
961                 self.History.insert(0,(config.plugins.mytube.search.searchTerm.value))
962                 if len(self.History) == 30:
963                         self.History.pop()
964                 config.plugins.mytube.general.history.value = ",".join(self.History)
965                 config.plugins.mytube.general.history.save()
966                 print "configvalue",config.plugins.mytube.general.history.value
967
968         def hideSuggestions(self):
969                 current = self["config"].getCurrent()
970                 if current[1].help_window.instance is not None:
971                         current[1].help_window.instance.hide()
972                 if current[1].suggestionsWindow.instance is not None:
973                         current[1].suggestionsWindow.instance.hide()
974                 self.propagateUpDownNormally = True
975
976         def getFeed(self, chart=None, videoCategoryId=None, ids=[]):
977                 self.queryStarted()
978                 self.queryThread = myTubeService.getFeed(callback=self.gotFeed, chart=chart, videoCategoryId=videoCategoryId, ids=ids)
979
980         def getNextEntries(self, result):
981                 if not result:
982                         return
983                 if myTubeService.hasNextPage():
984                         self.appendEntries = True
985                         myTubeService.getNextPage()
986
987         def getRelatedVideos(self, video):
988                 if video:
989                         self.search(relatedToVideoId=video.id)
990
991         def getChannelVideos(self, video):
992                 if video:
993                         self.search(channelId=video.channelId)
994
995         def runSearch(self, searchTerm = None):
996                 Log.d(searchTerm)
997                 if searchTerm:
998                         self.search(searchTerm=searchTerm)
999
1000         def search(self, searchTerm=None, relatedToVideoId=None, channelId=None):
1001                 Log.d("searchTerm=%s, relatedToVideoId=%s, channelId=%s" % (searchTerm, relatedToVideoId, channelId))
1002                 self.queryStarted()
1003                 self.appendEntries = False
1004
1005 #               categories = [ config.plugins.mytube.search.categories.value ],
1006
1007                 self.queryThread = myTubeService.search(
1008                                         searchTerm=searchTerm,
1009                                         orderby=config.plugins.mytube.search.orderBy.value,
1010                                         time=config.plugins.mytube.search.time.value,
1011                                         lr=config.plugins.mytube.search.lr.value,
1012                                         relatedToVideoId=relatedToVideoId,
1013                                         channelId=channelId,
1014                                         safeSearch=config.plugins.mytube.search.safeSearch.value,
1015                                         callback=self.gotSearchFeed)
1016
1017         def queryStarted(self):
1018                 if self.queryRunning:
1019                         self.cancelThread()
1020                 self.queryRunning = True
1021
1022         def queryFinished(self):
1023                 self.queryRunning = False
1024
1025         def cancelThread(self):
1026                 print "[MyTubePlayer] cancelThread"
1027                 if self.queryThread is not None:
1028                         self.queryThread.cancel()
1029                 self.queryFinished()
1030
1031         def gotFeed(self, success, items, data):
1032                 print "[MyTubePlayer] gotFeed"
1033                 if self.FirstRun:
1034                         self.FirstRun = False
1035                 self.queryFinished()
1036                 if not success:
1037                         self.gotFeedError(items)
1038                 if success and items is not None:
1039                         self.ytfeed = items
1040                 myTubeService.feed = data
1041                 self.buildEntryList()
1042                 text = _("Results: %s - Page: %s " % (str(myTubeService.getTotalResults()), str(myTubeService.getCurrentPage())))
1043                 text = "TODO" #TODO text
1044                 #auth_username = myTubeService.getAuthedUsername()
1045                 #if auth_username:
1046                 #                       text = auth_username + ' - ' + text
1047                 self["result"].setText(text)
1048
1049         def gotFeedError(self, error):
1050                 print "[MyTubePlayer] gotFeedError"
1051                 self.queryFinished()
1052                 self.setState('Error')
1053
1054         def gotSearchFeed(self, success, feed, data):
1055                 if self.FirstRun:
1056                         self.FirstRun = False
1057                 self.gotFeed(success, feed, data)
1058
1059         def buildEntryList(self):
1060                 self.mytubeentries = None
1061                 self.screenshotList = []
1062                 self.maxentries = 0
1063                 self.mytubeentries = self.ytfeed
1064                 self.maxentries = len(self.mytubeentries)-1
1065                 if self.mytubeentries and len(self.mytubeentries):
1066                         if self.appendEntries == False:
1067                                 self.videolist = []
1068                                 for video in self.mytubeentries:
1069                                         video_id = video.id
1070                                         thumbnailUrl = None
1071                                         thumbnailUrl = video.thumbnailUrl
1072                                         if thumbnailUrl is not None:
1073                                                 self.screenshotList.append((video_id,thumbnailUrl))
1074                                         if not self.Details.has_key(video_id):
1075                                                 self.Details[video_id] = { 'thumbnail': None}
1076                                         self.videolist.append(self.buildEntryComponent(video, video_id))
1077                                 if len(self.videolist):
1078                                         self["feedlist"].style = "default"
1079                                         self["feedlist"].disable_callbacks = True
1080                                         self["feedlist"].list = self.videolist
1081                                         self["feedlist"].disable_callbacks = False
1082                                         self["feedlist"].setIndex(0)
1083                                         self["feedlist"].setList(self.videolist)
1084                                         self["feedlist"].updateList(self.videolist)
1085                                         if self.FirstRun and not config.plugins.mytube.general.loadFeedOnOpen.value:
1086                                                 self.switchToConfigList()
1087                                         else:
1088                                                 self.switchToFeedList()
1089                         else:
1090                                 self.oldfeedentrycount = 0 #TODO self["feedlist"].count()
1091                                 for video in self.mytubeentries:
1092                                         video_id = video.id
1093                                         thumbnailUrl = None
1094                                         thumbnailUrl = video.thumbnailUrl
1095                                         if thumbnailUrl is not None:
1096                                                 self.screenshotList.append((video_id,thumbnailUrl))
1097                                         if not self.Details.has_key(video_id):
1098                                                 self.Details[video_id] = { 'thumbnail': None}
1099                                         self.videolist.append(self.buildEntryComponent(video, video_id))
1100                                 if len(self.videolist):
1101                                         self["feedlist"].style = "default"
1102                                         old_index = self["feedlist"].index
1103                                         self["feedlist"].disable_callbacks = True
1104                                         self["feedlist"].list = self.videolist
1105                                         self["feedlist"].disable_callbacks = False
1106                                         self["feedlist"].setList(self.videolist)
1107                                         self["feedlist"].setIndex(old_index)
1108                                         self["feedlist"].updateList(self.videolist)
1109                                         self["feedlist"].selectNext()
1110                                         self.switchToFeedList(True)
1111                         if not self.timer_startDownload.isActive():
1112                                 print "STARRTDOWNLOADTIMER IM BUILDENTRYLIST"
1113                                 self.timer_startDownload.start(5)
1114                 else:
1115                         self.setState('Error')
1116                         pass
1117
1118         def buildEntryComponent(self, entry,TubeID):
1119                 title = entry.title
1120                 description = entry.description
1121                 myTubeID = TubeID
1122                 publishedDate = entry.publishedDate
1123                 if publishedDate is not "unknown":
1124                         published = publishedDate.split("T")[0]
1125                 else:
1126                         published = "unknown"
1127                 Views = entry.views
1128                 if Views is not "not available":
1129                         views = Views
1130                 else:
1131                         views = "not available"
1132                 duration = entry.duration
1133                 if duration is not 0:
1134                         durationInSecs = int(duration)
1135                         mins = int(durationInSecs / 60)
1136                         secs = durationInSecs - mins * 60
1137                         duration = "%d:%02d" % (mins, secs)
1138                 else:
1139                         duration = "not available"
1140                 likes = entry.likes
1141                 if likes is not "":
1142                         likes = likes
1143                 else:
1144                         likes = ""
1145                 thumbnail = None
1146                 if self.Details[myTubeID]["thumbnail"]:
1147                         thumbnail = self.Details[myTubeID]["thumbnail"]
1148                 return((entry, title, description, myTubeID, thumbnail, _("Added: ") + str(published), _("Views: ") + str(views), _("Duration: ") + str(duration), _("Likes: ") + str(likes) ))
1149
1150         def getNextEntry(self):
1151                 i = self["feedlist"].getIndex() + 1
1152                 if i < len(self.videolist):
1153                         self["feedlist"].selectNext()
1154                         current = self["feedlist"].getCurrent()
1155                         if current:
1156                                 video = current[0]
1157                                 if video:
1158                                         myurl = video.url
1159                                         if myurl is not None:
1160                                                 print "Got a URL to stream"
1161                                                 myreference = eServiceReference(4097,0,myurl)
1162                                                 myreference.setName(video.title)
1163                                                 return myreference,False
1164                                         else:
1165                                                 print "NoURL im getNextEntry"
1166                                                 return None,True
1167
1168                 print "no more entries to play"
1169                 return None,False
1170
1171         def getPrevEntry(self):
1172                 i = self["feedlist"].getIndex() - 1
1173                 if i >= 0:
1174                         self["feedlist"].selectPrevious()
1175                         current = self["feedlist"].getCurrent()
1176                         if current:
1177                                 video = current[0]
1178                                 if video:
1179                                         myurl = video.url
1180                                         if myurl is not None:
1181                                                 print "Got a URL to stream"
1182                                                 myreference = eServiceReference(4097,0,myurl)
1183                                                 myreference.setName(video.title)
1184                                                 return myreference,False
1185                                         else:
1186                                                 return None,True
1187                 return None,False
1188
1189         def showVideoInfo(self):
1190                 if self.currList == "feedlist":
1191                         self.openInfoScreen()
1192
1193         def openInfoScreen(self):
1194                 if self.currList == "feedlist":
1195                         current = self[self.currList].getCurrent()
1196                         if current:
1197                                 video = current[0]
1198                                 if video:
1199                                         print "Title im showVideoInfo",video.title
1200                                         self.session.open(MyTubeVideoInfoScreen, self.skin_path, video = video )
1201
1202         def downloadThumbnails(self):
1203                 self.timer_startDownload.stop()
1204                 for entry in self.screenshotList:
1205                         thumbnailUrl = entry[1]
1206                         tubeid = entry[0]
1207                         thumbnailFile = "/tmp/"+str(tubeid)+".jpg"
1208                         if self.Details.has_key(tubeid):
1209                                 if self.Details[tubeid]["thumbnail"] is None:
1210                                         if thumbnailUrl is not None:
1211                                                 if tubeid not in self.pixmaps_to_load:
1212                                                         self.pixmaps_to_load.append(tubeid)
1213                                                         if (os_path.exists(thumbnailFile) == True):
1214                                                                 self.fetchFinished(False,tubeid)
1215                                                         else:
1216                                                                 client.downloadPage(thumbnailUrl,thumbnailFile).addCallback(self.fetchFinished,str(tubeid)).addErrback(self.fetchFailed,str(tubeid))
1217                                         else:
1218                                                 if tubeid not in self.pixmaps_to_load:
1219                                                         self.pixmaps_to_load.append(tubeid)
1220                                                         self.fetchFinished(False,tubeid, failed = True)
1221
1222         def fetchFailed(self,string,tubeid):
1223                 print "thumbnail-fetchFailed for: ",tubeid,string.getErrorMessage()
1224                 self.fetchFinished(False,tubeid, failed = True)
1225
1226         def fetchFinished(self,x,tubeid, failed = False):
1227                 print "thumbnail-fetchFinished for:",tubeid
1228                 self.pixmaps_to_load.remove(tubeid)
1229                 if failed:
1230                         thumbnailFile = resolveFilename(SCOPE_CURRENT_PLUGIN, "Extensions/MyTube/plugin.png")
1231                 else:
1232                         thumbnailFile = "/tmp/"+str(tubeid)+".jpg"
1233                 sc = AVSwitch().getFramebufferScale()
1234                 if (os_path.exists(thumbnailFile) == True):
1235                         self.picloads[tubeid] = ePicLoad()
1236                         self.picloads[tubeid].conn = self.picloads[tubeid].PictureData.connect(boundFunction(self.finish_decode, tubeid))
1237                         self.picloads[tubeid].setPara((self["thumbnail"].instance.size().width(), self["thumbnail"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
1238                         self.picloads[tubeid].startDecode(thumbnailFile)
1239                 else:
1240                         self.pixmaps_to_load.append(tubeid)
1241                         self.fetchFinished(False,tubeid, failed = True)
1242
1243         def finish_decode(self,tubeid,info):
1244                 print "thumbnail finish_decode:", tubeid,info
1245                 ptr = self.picloads[tubeid].getData()
1246                 thumbnailFile = "/tmp/"+str(tubeid)+".jpg"
1247                 if ptr != None:
1248                         if self.Details.has_key(tubeid):
1249                                 self.Details[tubeid]["thumbnail"] = ptr
1250                         if (os_path.exists(thumbnailFile) == True):
1251                                 os_remove(thumbnailFile)
1252                         del self.picloads[tubeid]
1253                 else:
1254                         del self.picloads[tubeid]
1255                         if self.Details.has_key(tubeid):
1256                                 self.Details[tubeid]["thumbnail"] = None
1257                 self.timer_thumbnails.start(1)
1258
1259         def updateFeedThumbnails(self):
1260                 self.timer_thumbnails.stop()
1261                 if len(self.picloads) != 0:
1262                         self.timer_thumbnails.start(1)
1263                 else:
1264                         idx = 0
1265                         for entry in self.videolist:
1266                                 tubeid = entry[3]
1267                                 if self.Details.has_key(tubeid):
1268                                         if self.Details[tubeid]["thumbnail"] is not None:
1269                                                 thumbnail = entry[4]
1270                                                 if thumbnail == None:
1271                                                         video = entry[0]
1272                                                         self.videolist[idx] = self.buildEntryComponent(video, tubeid )
1273                                 idx += 1
1274                         if self.currList == "feedlist":
1275                                 self["feedlist"].updateList(self.videolist)
1276
1277
1278 class MyTubeVideoInfoScreen(Screen):
1279         skin = """
1280                 <screen name="MyTubeVideoInfoScreen" flags="wfNoBorder" position="0,0" size="720,576" title="MyTube - Video Info" >
1281                         <ePixmap position="0,0" zPosition="-1" size="720,576" pixmap="~/mytubemain_bg.png" alphatest="on" transparent="1" backgroundColor="transparent"/>
1282                         <widget name="title" position="60,50" size="600,50" zPosition="5" valign="center" halign="left" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
1283                         <widget name="starsbg" pixmap="~/starsbar_empty.png" position="560,220" zPosition="5" size="100,20" transparent="1" alphatest="on" />
1284                         <widget name="stars" pixmap="~/starsbar_filled.png" position="560,220" zPosition="6" size="100,20"  transparent="1" />
1285                         <widget source="infolist" render="Listbox" position="50,110" size="620,110" zPosition="6" scrollbarMode="showNever" selectionDisabled="1" transparent="1">
1286                                 <convert type="TemplatedMultiContent">
1287                                 {"templates":
1288                                         {"default": (110,[
1289                                                         MultiContentEntryPixmapAlphaTest(pos = (0, 4), size = (130, 98), png = 0), # index 0 is the thumbnail
1290                                                         MultiContentEntryPixmapAlphaTest(pos = (130, 4), size = (130, 98), png = 1), # index 0 is the thumbnail
1291                                                         MultiContentEntryPixmapAlphaTest(pos = (260, 4), size = (130, 98), png = 2), # index 0 is the thumbnail
1292                                                         MultiContentEntryPixmapAlphaTest(pos = (390, 4), size = (130, 98), png = 3), # index 0 is the thumbnail
1293                                                 ]),
1294                                         "state": (110,[
1295                                                         MultiContentEntryText(pos = (10, 40), size = (550, 38), font=2, flags = RT_HALIGN_LEFT | RT_VALIGN_TOP| RT_WRAP, text = 0), # index 0 is the name
1296                                                 ])
1297                                         },
1298                                         "fonts": [gFont("Regular", 20),gFont("Regular", 14),gFont("Regular", 28)],
1299                                         "itemHeight": 110
1300                                 }
1301                                 </convert>
1302                         </widget>
1303                         <widget name="channelTitle" position="60,220" size="300,20" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top" />
1304                         <widget name="duration" position="370,220" size="200,20" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top" />
1305                         <widget name="published" position="60,245" size="300,20" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top" />
1306                         <widget name="views" position="370,245" size="200,20" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top" />
1307                         <widget name="tags" position="60,270" size="600,20" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top" />
1308                         <widget name="detailtext" position="60,300" size="610,200" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top"/>
1309                         <ePixmap position="100,500" size="100,40" zPosition="0" pixmap="~/plugin.png" alphatest="on" transparent="1" />
1310                         <ePixmap position="220,500" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
1311                         <widget name="key_red" position="220,500" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
1312                         <widget name="thumbnail" position="0,0" size="130,98" alphatest="on"/> # fake entry for dynamic thumbnail resizing, currently there is no other way doing this.
1313                 </screen>"""
1314
1315         def __init__(self, session, plugin_path, video = None):
1316                 Screen.__init__(self, session)
1317                 self.session = session
1318                 self.skin_path = plugin_path
1319                 self.video = video
1320                 self.infolist = []
1321                 self.thumbnails = []
1322                 self.picloads = {}
1323                 self["title"] = Label()
1324                 self["key_red"] = Button(_("Close"))
1325                 self["thumbnail"] = Pixmap()
1326                 self["thumbnail"].hide()
1327                 self["detailtext"] = ScrollLabel()
1328                 self["starsbg"] = Pixmap()
1329                 self["stars"] = ProgressBar()
1330                 self["duration"] = Label()
1331                 self["channelTitle"] = Label()
1332                 self["author"] = self["channelTitle"] #skincompat
1333                 self["published"] = Label()
1334                 self["views"] = Label()
1335                 self["tags"] = Label()
1336                 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions", "MovieSelectionActions"],
1337                 {
1338                         "back": self.close,
1339                         "red": self.close,
1340                         "up": self.pageUp,
1341                         "down": self.pageDown,
1342                         "left": self.pageUp,
1343                         "right": self.pageDown,
1344                 }, -2)
1345
1346                 self["infolist"] = List(self.infolist)
1347                 self.timer = eTimer()
1348                 self.timer_conn = self.timer.timeout.connect(self.picloadTimeout)
1349                 self.onLayoutFinish.append(self.layoutFinished)
1350                 self.onShown.append(self.setWindowTitle)
1351
1352         def layoutFinished(self):
1353                 self.statuslist = []
1354                 self.statuslist.append(( _("Downloading screenshots. Please wait..." ),_("Downloading screenshots. Please wait..." ) ))
1355                 self["infolist"].style = "state"
1356                 self['infolist'].setList(self.statuslist)
1357                 self.loadPreviewpics()
1358                 if self.video.title is not None:
1359                         self["title"].setText(self.video.title)
1360                 description = None
1361                 if self.video.description is not None:
1362                         self["detailtext"].setText(self.video.description.strip())
1363
1364                 #TODO implement Likes
1365                 self["stars"].hide()
1366                 self["starsbg"].hide()
1367
1368                 if self.video.duration is not 0:
1369                         durationInSecs = int(self.video.duration)
1370                         mins = int(durationInSecs / 60)
1371                         secs = durationInSecs - mins * 60
1372                         duration = "%d:%02d" % (mins, secs)
1373                         self["duration"].setText(_("Duration: ") + str(duration))
1374
1375                 if self.video.channelTitle:
1376                         self["channelTitle"].setText(_("Channel: ") + self.video.channelTitle)
1377
1378                 if self.video.publishedDate is not "unknown":
1379                         self["published"].setText(_("Added: ") + self.video.publishedDate.split("T")[0])
1380
1381                 if self.video.views is not "not available":
1382                         self["views"].setText(_("Views: ") + str(self.video.views))
1383
1384         def setWindowTitle(self):
1385                 self.setTitle(_("MyTubeVideoInfoScreen"))
1386
1387         def pageUp(self):
1388                 self["detailtext"].pageUp()
1389
1390         def pageDown(self):
1391                 self["detailtext"].pageDown()
1392
1393         def loadPreviewpics(self):
1394                 self.thumbnails = []
1395                 self.mythumbubeentries = None
1396                 self.index = 0
1397                 self.maxentries = 0
1398                 self.picloads = {}
1399                 self.mythumbubeentries = [self.video.thumbnailUrl]
1400                 self.maxentries = len(self.mythumbubeentries)-1
1401                 if self.mythumbubeentries:
1402                         currindex = 0
1403                         for entry in self.mythumbubeentries:
1404                                 thumbID = self.video.id + str(currindex)
1405                                 thumbnailFile = "/tmp/" + thumbID + ".jpg"
1406                                 currPic = [currindex,thumbID,thumbnailFile,None]
1407                                 self.thumbnails.append(currPic)
1408                                 thumbnailUrl = None
1409                                 thumbnailUrl = entry
1410                                 if thumbnailUrl is not None:
1411                                         client.downloadPage(thumbnailUrl,thumbnailFile).addCallback(self.fetchFinished,currindex,thumbID).addErrback(self.fetchFailed,currindex,thumbID)
1412                                 currindex +=1
1413                 else:
1414                         pass
1415
1416         def fetchFailed(self, string, index, id):
1417                 print "[fetchFailed] for index:" + str(index) + "for ThumbID:" + id + string.getErrorMessage()
1418
1419         def fetchFinished(self, string, index, id):
1420                 print "[fetchFinished] for index:" + str(index) + " for ThumbID:" + id
1421                 self.decodePic(index)
1422
1423         def decodePic(self, index):
1424                 sc = AVSwitch().getFramebufferScale()
1425                 self.picloads[index] = ePicLoad()
1426                 self.picloads[index].conn = self.picloads[index].PictureData.connect(boundFunction(self.finish_decode, index))
1427                 for entry in self.thumbnails:
1428                         if entry[0] == index:
1429                                 self.index = index
1430                                 thumbnailFile = entry[2]
1431                                 if (os_path.exists(thumbnailFile) == True):
1432                                         print "[decodePic] DECODING THUMBNAIL for INDEX:"+  str(self.index) + "and file: " + thumbnailFile
1433                                         self.picloads[index].setPara((self["thumbnail"].instance.size().width(), self["thumbnail"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
1434                                         self.picloads[index].startDecode(thumbnailFile)
1435                                 else:
1436                                         print "[decodePic] Thumbnail file NOT FOUND !!!-->:",thumbnailFile
1437
1438         def finish_decode(self, picindex = None, picInfo=None):
1439                 print "finish_decode - of INDEX", picindex
1440                 ptr = self.picloads[picindex].getData()
1441                 if ptr != None:
1442                         self.thumbnails[picindex][3] = ptr
1443                         if (os_path.exists(self.thumbnails[picindex][2]) == True):
1444                                 print "removing", self.thumbnails[picindex][2]
1445                                 os_remove(self.thumbnails[picindex][2])
1446                                 del self.picloads[picindex]
1447                                 if len(self.picloads) == 0:
1448                                         self.timer.startLongTimer(3)
1449
1450         def picloadTimeout(self):
1451                 self.timer.stop()
1452                 if len(self.picloads) == 0:
1453                                 self.buildInfoList()
1454                 else:
1455                         self.timer.startLongTimer(2)
1456
1457         def buildInfoList(self):
1458                 self.infolist = []
1459                 thumb0 = None
1460                 thumb1 = None
1461                 thumb2 = None
1462                 thumb3 = None
1463                 count = len(self.thumbnails)
1464                 if count > 0:
1465                         thumb0 = self.thumbnails[0][3]
1466                 if count > 1:
1467                         thumb1 = self.thumbnails[1][3]
1468                 if count > 2:
1469                         thumb2 = self.thumbnails[2][3]
1470                 if count > 3:
1471                         thumb3 = self.thumbnails[3][3]
1472                 self.infolist.append(( thumb0, thumb1, thumb2, thumb3))
1473                 if len(self.infolist):
1474                         self["infolist"].style = "default"
1475                         self["infolist"].disable_callbacks = True
1476                         self["infolist"].list = self.infolist
1477                         self["infolist"].disable_callbacks = False
1478                         self["infolist"].setIndex(0)
1479                         self["infolist"].setList(self.infolist)
1480                         self["infolist"].updateList(self.infolist)
1481
1482
1483 class MyTubeVideoHelpScreen(Screen):
1484         skin = """
1485                 <screen name="MyTubeVideoHelpScreen" flags="wfNoBorder" position="0,0" size="720,576" title="MyTube - Help" >
1486                         <ePixmap position="0,0" zPosition="-1" size="720,576" pixmap="~/mytubemain_bg.png" alphatest="on" transparent="1" backgroundColor="transparent"/>
1487                         <widget name="title" position="60,50" size="600,50" zPosition="5" valign="center" halign="left" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
1488                         <widget name="detailtext" position="60,120" size="610,370" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top"/>
1489                         <ePixmap position="100,500" size="100,40" zPosition="0" pixmap="~/plugin.png" alphatest="on" transparent="1" />
1490                         <ePixmap position="220,500" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
1491                         <widget name="key_red" position="220,500" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
1492                 </screen>"""
1493
1494         def __init__(self, session, plugin_path, wantedinfo = None, wantedtitle = None):
1495                 Screen.__init__(self, session)
1496                 self.session = session
1497                 self.skin_path = plugin_path
1498                 self.wantedinfo = wantedinfo
1499                 self.wantedtitle = wantedtitle
1500                 self["title"] = Label()
1501                 self["key_red"] = Button(_("Close"))
1502                 self["detailtext"] = ScrollLabel()
1503
1504                 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
1505                 {
1506                         "back": self.close,
1507                         "red": self.close,
1508                         "up": self.pageUp,
1509                         "down": self.pageDown,
1510                         "left": self.pageUp,
1511                         "right": self.pageDown,
1512                 }, -2)
1513
1514                 self.onLayoutFinish.append(self.layoutFinished)
1515                 self.onShown.append(self.setWindowTitle)
1516
1517         def layoutFinished(self):
1518                 if self.wantedtitle is None:
1519                         self["title"].setText(_("Help"))
1520                 else:
1521                         self["title"].setText(self.wantedtitle)
1522                 if self.wantedinfo is None:
1523                         self["detailtext"].setText(_("This is the help screen. Feed me with something to display."))
1524                 else:
1525                         self["detailtext"].setText(self.wantedinfo)
1526
1527         def setWindowTitle(self):
1528                 self.setTitle(_("MyTubeVideohelpScreen"))
1529
1530         def pageUp(self):
1531                 self["detailtext"].pageUp()
1532
1533         def pageDown(self):
1534                 self["detailtext"].pageDown()
1535
1536
1537 def MyTubeMain(session, **kwargs):
1538         l2 = False
1539         l2cert = etpm.getData(eTPM.DT_LEVEL2_CERT)
1540         if l2cert is None:
1541                 print "l2cert not found"
1542                 return
1543
1544         l2key = validate_cert(l2cert, rootkey)
1545         if l2key is None:
1546                 print "l2cert invalid"
1547                 return
1548         l2 = True
1549         if l2:
1550                 session.open(MyTubePlayerMainScreen, l2key)
1551
1552 def Plugins(path, **kwargs):
1553         global plugin_path
1554         plugin_path = path
1555         return PluginDescriptor(
1556                 name=_("My TubePlayer"),
1557                 description=_("Play YouTube movies"),
1558                 where = [ PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_PLUGINMENU ],
1559                 icon = "plugin.png", fnc = MyTubeMain)