MyTube: add option to disable msg "load new entries"
[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.MultiContent import MultiContentEntryText, MultiContentEntryPixmapAlphaTest
7 from Components.Pixmap import Pixmap
8 from Components.ProgressBar import ProgressBar
9 from Components.ScrollLabel import ScrollLabel
10 from Components.ServiceEventTracker import ServiceEventTracker
11 from Components.Sources.List import List
12 from Components.Task import Task, Job, job_manager
13 from Components.config import config, ConfigSelection, ConfigSubsection, ConfigText, ConfigYesNo, getConfigListEntry
14 #, ConfigIP, ConfigNumber, ConfigLocations
15 from MyTubeSearch import ConfigTextWithGoogleSuggestions, MyTubeSettingsScreen, MyTubeTasksScreen, MyTubeHistoryScreen
16 from MyTubeService import validate_cert, get_rnd, myTubeService
17 from Plugins.Plugin import PluginDescriptor
18 from Screens.ChoiceBox import ChoiceBox
19 from Screens.InfoBarGenerics import InfoBarNotifications
20 from Screens.MessageBox import MessageBox
21 from Screens.Screen import Screen
22 from Screens.VirtualKeyBoard import VirtualKeyBoard
23 from Tools.BoundFunction import boundFunction
24 from Tools.Directories import resolveFilename, SCOPE_HDD, SCOPE_CURRENT_PLUGIN
25 from Tools.Downloader import downloadWithProgress
26
27 from __init__ import decrypt_block
28
29 from enigma import eTPM, eTimer, ePoint, RT_HALIGN_LEFT, RT_VALIGN_CENTER, gFont, ePicLoad, eServiceReference, iPlayableService
30 from os import path as os_path, remove as os_remove
31 from twisted.web import client
32
33
34
35 etpm = eTPM()
36 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', ':', '?']
37
38 config.plugins.mytube = ConfigSubsection()
39 config.plugins.mytube.search = ConfigSubsection()
40
41
42 config.plugins.mytube.search.searchTerm = ConfigTextWithGoogleSuggestions("", False, threaded = True)
43 config.plugins.mytube.search.orderBy = ConfigSelection(
44                                 [
45                                  ("relevance", _("Relevance")),
46                                  ("viewCount", _("View Count")),
47                                  ("published", _("Published")),
48                                  ("rating", _("Rating"))
49                                 ], "relevance")
50 config.plugins.mytube.search.time = ConfigSelection(
51                                 [
52                                  ("all_time", _("All Time")),
53                                  ("this_month", _("This Month")),
54                                  ("this_week", _("This Week")),
55                                  ("today", _("Today"))
56                                 ], "all_time")
57 config.plugins.mytube.search.racy = ConfigSelection(
58                                 [
59                                  ("include", _("Yes")),
60                                  ("exclude", _("No"))
61                                 ], "include")
62 config.plugins.mytube.search.categories = ConfigSelection(
63                                 [
64                                  (None, _("All")),
65                                  ("Film", _("Film & Animation")),
66                                  ("Autos", _("Autos & Vehicles")),
67                                  ("Music", _("Music")),
68                                  ("Animals", _("Pets & Animals")),
69                                  ("Sports", _("Sports")),
70                                  ("Travel", _("Travel & Events")),
71                                  ("Shortmov", _("Short Movies")),
72                                  ("Games", _("Gaming")),
73                                  ("Comedy", _("Comedy")),
74                                  ("People", _("People & Blogs")),
75                                  ("News", _("News & Politics")),
76                                  ("Entertainment", _("Entertainment")),
77                                  ("Education", _("Education")),
78                                  ("Howto", _("Howto & Style")),
79                                  ("Nonprofit", _("Nonprofits & Activism")),
80                                  ("Tech", _("Science & Technology"))
81                                 ], None)
82 config.plugins.mytube.search.lr = ConfigSelection(
83                                 [
84                                  (None, _("All")),
85                                  ("au", _("Australia")),
86                                  ("br", _("Brazil")),
87                                  ("ca", _("Canada")),
88                                  ("cz", _("Czech Republic")),
89                                  ("fr", _("France")),
90                                  ("de", _("Germany")),
91                                  ("gb", _("Great Britain")),
92                                  ("au", _("Australia")),
93                                  ("nl", _("Holland")),
94                                  ("hk", _("Hong Kong")),
95                                  ("in", _("India")),
96                                  ("ie", _("Ireland")),
97                                  ("il", _("Israel")),
98                                  ("it", _("Italy")),
99                                  ("jp", _("Japan")),
100                                  ("mx", _("Mexico")),
101                                  ("nz", _("New Zealand")),
102                                  ("pl", _("Poland")),
103                                  ("ru", _("Russia")),
104                                  ("kr", _("South Korea")),
105                                  ("es", _("Spain")),
106                                  ("se", _("Sweden")),
107                                  ("tw", _("Taiwan")),
108                                  ("us", _("United States")) 
109                                 ], None)
110 config.plugins.mytube.search.sortOrder = ConfigSelection(
111                                 [
112                                  ("ascending", _("Ascending")),
113                                  ("descending", _("Descending"))
114                                 ], "ascending")
115
116 config.plugins.mytube.general = ConfigSubsection()
117 config.plugins.mytube.general.showHelpOnOpen = ConfigYesNo(default = True)
118 config.plugins.mytube.general.loadFeedOnOpen = ConfigYesNo(default = True)
119 config.plugins.mytube.general.startFeed = ConfigSelection(
120                                 [
121                                  ("hd", _("HD videos")),
122                                  ("most_viewed", _("Most viewed")),
123                                  ("top_rated", _("Top rated")),
124                                  ("recently_featured", _("Recently featured")),
125                                  ("most_discussed", _("Most discussed")),
126                                  ("top_favorites", _("Top favorites")),
127                                  ("most_linked", _("Most linked")),
128                                  ("most_responded", _("Most responded")),
129                                  ("most_recent", _("Most recent"))
130                                 ], "most_viewed")
131 config.plugins.mytube.general.on_movie_stop = ConfigSelection(default = "ask", choices = [
132         ("ask", _("Ask user")), ("quit", _("Return to movie list")), ("playnext", _("Play next video")), ("playagain", _("Play video again")) ])
133
134 config.plugins.mytube.general.on_exit = ConfigSelection(default = "ask", choices = [
135         ("ask", _("Ask user")), ("quit", _("Return to movie list"))])
136
137 default = resolveFilename(SCOPE_HDD)
138 tmp = config.movielist.videodirs.value
139 if default not in tmp:
140         tmp.append(default)
141 config.plugins.mytube.general.videodir = ConfigSelection(default = default, choices = tmp)
142 config.plugins.mytube.general.history = ConfigText(default="")
143 config.plugins.mytube.general.clearHistoryOnClose = ConfigYesNo(default = False)
144 config.plugins.mytube.general.AutoLoadFeeds = ConfigYesNo(default = True)
145 #config.plugins.mytube.general.useHTTPProxy = ConfigYesNo(default = False)
146 #config.plugins.mytube.general.ProxyIP = ConfigIP(default=[0,0,0,0])
147 #config.plugins.mytube.general.ProxyPort = ConfigNumber(default=8080)
148
149
150 class downloadJob(Job):
151         def __init__(self, url, file, title):
152                 Job.__init__(self, title)
153                 downloadTask(self, url, file)
154
155 class downloadTask(Task):
156         def __init__(self, job, url, file):
157                 Task.__init__(self, job, ("download task"))
158                 self.end = 100
159                 self.url = url
160                 self.local = file
161
162         def prepare(self):
163                 self.error = None
164
165         def run(self, callback):
166                 self.callback = callback
167                 self.download = downloadWithProgress(self.url,self.local)
168                 self.download.addProgress(self.http_progress)
169                 self.download.start().addCallback(self.http_finished).addErrback(self.http_failed)
170         
171         def http_progress(self, recvbytes, totalbytes):
172                 #print "[http_progress] recvbytes=%d, totalbytes=%d" % (recvbytes, totalbytes)
173                 self.progress = int(self.end*recvbytes/float(totalbytes))
174         
175         def http_finished(self, string=""):
176                 print "[http_finished]" + str(string)
177                 Task.processFinished(self, 0)
178         
179         def http_failed(self, failure_instance=None, error_message=""):
180                 if error_message == "" and failure_instance is not None:
181                         error_message = failure_instance.getErrorMessage()
182                         print "[http_failed] " + error_message
183                         Task.processFinished(self, 1)
184
185
186
187
188
189 class MyTubePlayerMainScreen(Screen, ConfigListScreen):
190         BASE_STD_FEEDURL = "http://gdata.youtube.com/feeds/api/standardfeeds/"
191         Details = {}
192         #(entry, Title, Description, TubeID, thumbnail, PublishedDate,Views,duration,ratings )  
193         skin = """
194                 <screen name="MyTubePlayerMainScreen" flags="wfNoBorder" position="0,0" size="720,576" title="MyTube - Browser" >
195                         <ePixmap position="0,0" zPosition="-1" size="720,576" pixmap="~/mytubemain_bg.png" alphatest="on" transparent="1" backgroundColor="transparent"/>
196                         <widget name="config" zPosition="2" position="60,60" size="600,50" scrollbarMode="showNever" transparent="1" />
197                         <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" >
198                                 <convert type="TemplatedMultiContent">
199                                 {"templates":
200                                         {"default": (77,[
201                                                         MultiContentEntryPixmapAlphaTest(pos = (0, 0), size = (100, 75), png = 4), # index 4 is the thumbnail
202                                                         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
203                                                         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
204                                                         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
205                                                         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
206                                                         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
207                                                 ]),
208                                         "state": (77,[
209                                                         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
210                                                         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
211                                                 ])
212                                         },
213                                         "fonts": [gFont("Regular", 22),gFont("Regular", 18),gFont("Regular", 26),gFont("Regular", 20)],
214                                         "itemHeight": 77
215                                 }
216                                 </convert>
217                         </widget>
218
219                         <ePixmap pixmap="skin_default/buttons/key_info.png" position="50,500" zPosition="4" size="35,25" alphatest="on" transparent="1" />
220                         <ePixmap pixmap="skin_default/buttons/key_menu.png" position="50,520" zPosition="4" size="35,25" alphatest="on" transparent="1" />
221                         <ePixmap position="90,500" size="100,40" zPosition="4" pixmap="~/plugin.png" alphatest="on" transparent="1" />
222                         <ePixmap position="190,500" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
223                         <ePixmap position="330,500" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
224                         <ePixmap position="470,500" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
225                         <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" />
226                         <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" />
227                         <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" />
228                         <widget name="ButtonBlue" pixmap="skin_default/buttons/button_blue.png" position="610,510" zPosition="10" size="15,16" transparent="1" alphatest="on" />
229                         <widget name="VKeyIcon" pixmap="skin_default/vkey_icon.png" position="620,495" zPosition="10" size="60,48" transparent="1" alphatest="on" />
230                         <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.
231                         <widget name="HelpWindow" position="160,255" zPosition="1" size="1,1" transparent="1" alphatest="on" />
232                 </screen>"""
233                 
234         def __init__(self, session, l2key):
235                 Screen.__init__(self, session)
236                 self.session = session
237                 self.l2key = l2key
238                 self.l3key = None
239                 self.skin_path = plugin_path
240                 self.FeedURL = None
241                 self.ytfeed = None
242                 self.currentFeedName = None
243                 self.videolist = []
244                 self.queryThread = None
245                 self.queryRunning = False
246
247                 self.video_playlist = []
248                 self.statuslist = []
249                 self.mytubeentries = None
250
251                 self.thumbnails = []
252                 self.index = 0
253                 self.maxentries = 0
254
255                 self.screenshotList = []
256                 self.pixmaps_to_load = []
257                 self.picloads = {}
258
259                 self.oldfeedentrycount = 0
260                 self.appendEntries = False
261                 self.lastservice = session.nav.getCurrentlyPlayingServiceReference()
262                 self.propagateUpDownNormally = True
263                 self.FirstRun = True
264                 self.HistoryWindow = None
265                 self.History = None
266                 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.")
267                 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.")
268                 self.currList = "configlist"
269                 self.oldlist = None
270
271                 self["feedlist"] = List(self.videolist)
272                 self["thumbnail"] = Pixmap()
273                 self["thumbnail"].hide()
274                 self["HelpWindow"] = Pixmap()
275                 self["HelpWindow"].hide()
276                 self["key_red"] = Button(_("Close"))
277                 self["key_green"] = Button(_("Std. Feeds"))
278                 self["key_yellow"] = Button(_("History"))
279                 self["ButtonBlue"] = Pixmap()
280                 self["VKeyIcon"] = Pixmap()
281                 self["ButtonBlue"].hide()
282                 self["VKeyIcon"].hide()         
283
284                 self["searchactions"] = ActionMap(["ShortcutActions", "WizardActions", "HelpActions", "MediaPlayerActions"],
285                 {
286                         "ok": self.keyOK,
287                         "back": self.leavePlayer,
288                         "red": self.leavePlayer,
289                         "blue": self.openKeyboard,
290                         "yellow": self.handleHistory,
291                         "up": self.keyUp,
292                         "down": self.handleSuggestions,
293                         "left": self.keyLeft,
294                         "right": self.keyRight,
295                         "prevBouquet": self.switchToFeedList,
296                         "nextBouquet": self.switchToConfigList,
297                         "displayHelp": self.handleHelpWindow,
298                         "menu" : self.handleMenu,
299                 }, -2)
300
301                 self["suggestionactions"] = ActionMap(["ShortcutActions", "WizardActions", "MediaPlayerActions", "HelpActions"],
302                 {
303                         "ok": self.keyOK,
304                         "back": self.switchToConfigList,
305                         "red": self.switchToConfigList,
306                         "nextBouquet": self.switchToConfigList,
307                         "prevBouquet": self.switchToFeedList,
308                         "up": self.keyUp,
309                         "down": self.keyDown,
310                         "left": self.keyLeft,
311                         "right": self.keyRight,
312                 }, -2)
313
314
315                 self["videoactions"] = ActionMap(["ShortcutActions", "WizardActions", "MediaPlayerActions", "MovieSelectionActions", "HelpActions"],
316                 {
317                         "ok": self.keyOK,
318                         "back": self.leavePlayer,
319                         "red": self.leavePlayer,
320                         "yellow": self.handleHistory,
321                         "up": self.keyUp,
322                         "down": self.keyDown,   
323                         "nextBouquet": self.switchToConfigList,
324                         "green": self.keyStdFeed,
325                         "showEventInfo": self.showVideoInfo,
326                         "displayHelp": self.handleHelpWindow,
327                         "menu" : self.handleMenu,
328                 }, -2)
329
330                 self["statusactions"] = ActionMap(["ShortcutActions", "WizardActions", "HelpActions", "MediaPlayerActions"],
331                 {
332                         "back": self.leavePlayer,
333                         "red": self.leavePlayer,
334                         "nextBouquet": self.switchToConfigList,
335                         "green": self.keyStdFeed,
336                         "yellow": self.handleHistory,
337                         "menu": self.handleMenu
338                 }, -2)
339
340                 self["historyactions"] = ActionMap(["ShortcutActions", "WizardActions", "MediaPlayerActions", "MovieSelectionActions", "HelpActions"],
341                 {
342                         "ok": self.keyOK,
343                         "back": self.closeHistory,
344                         "red": self.closeHistory,
345                         "yellow": self.handleHistory,
346                         "up": self.keyUp,
347                         "down": self.keyDown,   
348                         "left": self.keyLeft,
349                         "right": self.keyRight,
350                 }, -2)
351
352                 self["videoactions"].setEnabled(False)
353                 self["statusactions"].setEnabled(False)
354                 self["historyactions"].setEnabled(False)
355                 
356                 self.timer_startDownload = eTimer()
357                 self.timer_startDownload.timeout.callback.append(self.downloadThumbnails)
358                 self.timer_thumbnails = eTimer()
359                 self.timer_thumbnails.timeout.callback.append(self.updateFeedThumbnails)
360
361                 self.SearchConfigEntry = None
362                 self.searchContextEntries = []
363                 config.plugins.mytube.search.searchTerm.value = ""
364                 ConfigListScreen.__init__(self, self.searchContextEntries, session)
365                 self.createSetup()              
366                 self.onLayoutFinish.append(self.layoutFinished)
367                 self.onShown.append(self.setWindowTitle)
368                 self.onClose.append(self.__onClose)
369                 self.Timer = eTimer()
370                 self.Timer.callback.append(self.TimerFire)
371                 
372         def __onClose(self):
373                 del self.Timer
374                 del self.timer_startDownload
375                 del self.timer_thumbnails
376                 self.Details = {}
377                 self.session.nav.playService(self.lastservice)
378                 
379         def layoutFinished(self):
380                 self.currList = "status"
381                 current = self["config"].getCurrent()
382                 if current[1].help_window.instance is not None:
383                         current[1].help_window.instance.hide()
384
385                 l3cert = etpm.getCert(eTPM.TPMD_DT_LEVEL3_CERT)
386                 if l3cert is None or l3cert is "":
387                         self["videoactions"].setEnabled(False)
388                         self["searchactions"].setEnabled(False)
389                         self["config_actions"].setEnabled(False)
390                         self["historyactions"].setEnabled(False)
391                         self["statusactions"].setEnabled(True)
392                         self.hideSuggestions()
393                         self.statuslist = []
394                         self.statuslist.append(( _("Genuine Dreambox validation failed!"), _("Verify your Dreambox authenticity by running the genuine dreambox plugin!" ) ))
395                         self["feedlist"].style = "state"
396                         self['feedlist'].setList(self.statuslist)
397                         return
398
399                 self.l3key = validate_cert(l3cert, self.l2key)
400                 if self.l3key is None:
401                         print "l3cert invalid"
402                         return
403                 rnd = get_rnd()
404                 if rnd is None:
405                         print "random error"
406                         return
407
408                 val = etpm.challenge(rnd)
409                 result = decrypt_block(val, self.l3key)
410
411                 self.statuslist = []
412                 if result[80:88] == rnd:
413                         self.statuslist.append(( _("Fetching feed entries"), _("Trying to download the Youtube feed entries. Please wait..." ) ))
414                         self["feedlist"].style = "state"
415                         self['feedlist'].setList(self.statuslist)
416                         self.Timer.start(200)
417                 else:
418                         self.statuslist.append(( _("Genuine Dreambox validation failed!"), _("Verify your Dreambox authenticity by running the genuine dreambox plugin!" ) ))
419                         self["feedlist"].style = "state"
420                         self['feedlist'].setList(self.statuslist)               
421         
422         def TimerFire(self):
423                 self.Timer.stop()
424                 if config.plugins.mytube.general.loadFeedOnOpen.value:
425                         self.setState('getFeed')
426                 else:
427                         self.setState('byPass')
428                 
429         def setWindowTitle(self):
430                 self.setTitle(_("MyTubePlayer"))
431
432         def createSetup(self):
433                 self.searchContextEntries = []
434                 self.SearchConfigEntry = getConfigListEntry(_("Search Term(s)"), config.plugins.mytube.search.searchTerm)
435                 self.searchContextEntries.append(self.SearchConfigEntry)
436                 self["config"].list = self.searchContextEntries
437                 self["config"].l.setList(self.searchContextEntries)
438
439         def setState(self,status = None):
440                 if status:
441                         self.currList = "status"
442                         self["videoactions"].setEnabled(False)
443                         self["searchactions"].setEnabled(False)
444                         self["config_actions"].setEnabled(False)
445                         self["historyactions"].setEnabled(False)
446                         self["statusactions"].setEnabled(True)
447                         self["ButtonBlue"].hide()
448                         self["VKeyIcon"].hide() 
449                         self.statuslist = []
450                         self.hideSuggestions()
451                         result = None
452                         if self.l3key is not None:
453                                 rnd = get_rnd()
454                                 if rnd is None:
455                                         return
456                                 val = etpm.challenge(rnd)
457                                 result = decrypt_block(val, self.l3key)
458                         if not result or result[80:88] != rnd:
459                                 self["key_green"].show()
460                                 self.statuslist.append(( _("Genuine Dreambox validation failed!"), _("Verify your Dreambox authenticity by running the genuine dreambox plugin!" ) ))
461                                 self["feedlist"].style = "state"
462                                 self['feedlist'].setList(self.statuslist)
463                         else:
464                                 print "Genuine Dreambox validation passed"
465                                 if self.FirstRun == True:
466                                         self.appendEntries = False
467                                         myTubeService.startService()
468                                 if self.HistoryWindow is not None:
469                                         self.HistoryWindow.deactivate()
470                                         self.HistoryWindow.instance.hide()
471                                 if status == 'getFeed':
472                                         self.statuslist.append(( _("Fetching feed entries"), _("Trying to download the Youtube feed entries. Please wait..." ) ))
473                                 elif status == 'getSearchFeed':
474                                         self.statuslist.append(( _("Fetching search entries"), _("Trying to download the Youtube search results. Please wait..." ) ))
475                                 elif status == 'Error':
476                                         self.statuslist.append(( _("An error occured."), _("There was an error getting the feed entries. Please try again." ) ))
477                                 elif status == 'noVideos':
478                                         self["key_green"].show()
479                                         self.statuslist.append(( _("No videos to display"), _("Please select a standard feed or try searching for videos." ) ))
480                                 elif status == 'byPass':
481                                         self.statuslist.append(( _("Not fetching feed entries"), _("Please enter your search term." ) ))
482                                         self["feedlist"].style = "state"
483                                         self['feedlist'].setList(self.statuslist)
484                                         self.switchToConfigList()
485                                 self["feedlist"].style = "state"
486                                 self['feedlist'].setList(self.statuslist)
487                                 if self.FirstRun == True:
488                                         if config.plugins.mytube.general.loadFeedOnOpen.value:
489                                                 if config.plugins.mytube.general.startFeed.value == 'hd':
490                                                         self.FeedURL = "http://gdata.youtube.com/feeds/api/videos/-/HD"
491                                                 else:
492                                                         self.FeedURL = self.BASE_STD_FEEDURL + str(config.plugins.mytube.general.startFeed.value)
493                                                 self.getFeed(self.FeedURL, str(config.plugins.mytube.general.startFeed.value))
494
495
496         def handleHelpWindow(self):
497                 print "[handleHelpWindow]"
498                 if self.currList == "configlist":
499                         self.hideSuggestions()
500                         self.session.openWithCallback(self.ScreenClosed, MyTubeVideoHelpScreen, self.skin_path, wantedinfo = self.searchtext, wantedtitle = _("MyTubePlayer Help") )
501                 elif self.currList == "feedlist":
502                         self.session.openWithCallback(self.ScreenClosed, MyTubeVideoHelpScreen, self.skin_path, wantedinfo = self.feedtext, wantedtitle = _("MyTubePlayer Help") )
503                         
504         def handleFirstHelpWindow(self):
505                 print "[handleFirstHelpWindow]"
506                 if config.plugins.mytube.general.showHelpOnOpen.value is True:
507                         if self.currList == "configlist":
508                                 self.hideSuggestions()
509                                 self.session.openWithCallback(self.firstRunHelpClosed, MyTubeVideoHelpScreen, self.skin_path,wantedinfo = self.feedtext, wantedtitle = _("MyTubePlayer Help") )
510                 else:
511                         self.FirstRun = False
512                         
513         def firstRunHelpClosed(self):
514                 if self.FirstRun == True:       
515                         self.FirstRun = False
516                         self.switchToConfigList()
517
518         def handleMenu(self):
519                 if self.currList == "configlist" or self.currList == "status":
520                         menulist = (
521                                         (_("MyTube Settings"), "settings"),
522                                 )
523                         self.hideSuggestions()
524                         self.session.openWithCallback(self.openMenu, ChoiceBox, title=_("Select your choice."), list = menulist)
525
526                 elif self.currList == "feedlist":
527                         menulist = [(_("MyTube Settings"), "settings")]
528                         menulist.extend((
529                                         (_("View related videos"), "related"),
530                                         (_("View response videos"), "response")
531                                 ))
532                         if config.usage.setup_level.index >= 2: # expert+
533                                 menulist.extend((
534                                         (_("Download Video"), "download"),
535                                         (_("View active downloads"), "downview")
536                                 ))
537                                                 
538                         self.hideSuggestions()
539                         self.session.openWithCallback(self.openMenu, ChoiceBox, title=_("Select your choice."), list = menulist)
540
541         def openMenu(self, answer):
542                 answer = answer and answer[1]
543                 if answer == "settings":
544                         print "settings selected"
545                         self.session.openWithCallback(self.ScreenClosed,MyTubeSettingsScreen, self.skin_path )
546                 elif answer == "related":
547                         current = self["feedlist"].getCurrent()[0]
548                         self.setState('getFeed')
549                         self.getRelatedVideos(current)
550                 elif answer == "response":
551                         current = self["feedlist"].getCurrent()[0]
552                         self.setState('getFeed')
553                         self.getResponseVideos(current)
554                 elif answer == "download":
555                         if self.currList == "feedlist":
556                                 current = self[self.currList].getCurrent()
557                                 if current:
558                                         myentry = current[0]
559                                         if myentry:
560                                                 myurl = myentry.getVideoUrl()
561                                                 filename = str(config.plugins.mytube.general.videodir.value)+ str(myentry.getTitle()) + '.mp4'
562                                                 job_manager.AddJob(downloadJob(myurl,filename, str(myentry.getTitle())[:30]))
563                 elif answer == "downview":
564                         self.tasklist = []
565                         for job in job_manager.getPendingJobs():
566                                 self.tasklist.append((job,job.name,job.getStatustext(),int(100*job.progress/float(job.end)) ,str(100*job.progress/float(job.end)) + "%" ))
567                         self.session.open(MyTubeTasksScreen, self.skin_path , self.tasklist)            
568                 elif answer == None:
569                         self.ScreenClosed()
570         
571         def openKeyboard(self):
572                 self.hideSuggestions()
573                 self.session.openWithCallback(self.SearchEntryCallback, VirtualKeyBoard, title = (_("Enter your search term(s)")), text = config.plugins.mytube.search.searchTerm.value)
574
575         def ScreenClosed(self):
576                 print "ScreenCLosed, restoring old window state"
577                 if self.currList == "historylist":
578                         if self.HistoryWindow.status() is False:
579                                 self.HistoryWindow.activate()
580                                 self.HistoryWindow.instance.show()
581                 elif self.currList == "configlist":
582                         self.switchToConfigList()
583                         ConfigListScreen.keyOK(self)
584                 elif self.currList == "feedlist":
585                         self.switchToFeedList()
586
587         def SearchEntryCallback(self, callback = None):
588                 if callback is not None and len(callback):
589                         config.plugins.mytube.search.searchTerm.value = callback
590                         ConfigListScreen.keyOK(self)
591                         self["config"].getCurrent()[1].getSuggestions()
592                 current = self["config"].getCurrent()
593                 if current[1].help_window.instance is not None:
594                         current[1].help_window.instance.show()  
595                 if current[1].suggestionsWindow.instance is not None:
596                         current[1].suggestionsWindow.instance.show()
597                 self.propagateUpDownNormally = True
598
599         def openStandardFeedClosed(self, answer):
600                 answer = answer and answer[1]
601                 if answer is not None:
602                         if answer == 'hd':
603                                 self.FeedURL = "http://gdata.youtube.com/feeds/api/videos/-/HD"
604                         else:
605                                 self.FeedURL = self.BASE_STD_FEEDURL + str(answer)
606                         self.setState('getFeed')
607                         self.appendEntries = False
608                         self.getFeed(self.FeedURL, str(answer))
609
610         def handleLeave(self, how):
611                 self.is_closing = True
612                 if how == "ask":
613                         if self.currList == "configlist":
614                                 list = (
615                                         (_("Yes"), "quit"),
616                                         (_("No"), "continue"),
617                                         (_("No, but switch to video entries."), "switch2feed")
618                                 )
619                         else:
620                                 list = (
621                                         (_("Yes"), "quit"),
622                                         (_("No"), "continue"),
623                                         (_("No, but switch to video search."), "switch2search")
624                                 )                                       
625                         self.session.openWithCallback(self.leavePlayerConfirmed, ChoiceBox, title=_("Really quit MyTube Player?"), list = list)
626                 else:
627                         self.leavePlayerConfirmed([True, how])
628
629         def leavePlayer(self):
630                 print "leavePlayer"
631                 if self.HistoryWindow is not None:
632                         self.HistoryWindow.deactivate()
633                         self.HistoryWindow.instance.hide()
634                 if self.currList == "configlist":
635                         current = self["config"].getCurrent()
636                         if current[1].suggestionsWindow.activeState is True:
637                                 self.propagateUpDownNormally = True
638                                 current[1].deactivateSuggestionList()
639                                 self["config"].invalidateCurrent()
640                         else:
641                                 self.hideSuggestions()
642                                 self.handleLeave(config.plugins.mytube.general.on_exit.value)
643                 else:
644                         self.hideSuggestions()
645                         self.handleLeave(config.plugins.mytube.general.on_exit.value)
646
647         def leavePlayerConfirmed(self, answer):
648                 answer = answer and answer[1]
649                 if answer == "quit":
650                         self.doQuit()
651                 elif answer == "continue":
652                         if self.currList == "historylist":
653                                 if self.HistoryWindow.status() is False:
654                                         self.HistoryWindow.activate()
655                                         self.HistoryWindow.instance.show()
656                         elif self.currList == "configlist":
657                                 self.switchToConfigList()
658                         elif self.currList == "feedlist":
659                                 self.switchToFeedList()                         
660                 elif answer == "switch2feed":
661                         self.switchToFeedList()
662                 elif answer == "switch2search":
663                         self.switchToConfigList()
664                 elif answer == None:
665                         if self.currList == "historylist":
666                                 if self.HistoryWindow.status() is False:
667                                         self.HistoryWindow.activate()
668                                         self.HistoryWindow.instance.show()
669                         elif self.currList == "configlist":
670                                 self.switchToConfigList()
671                         elif self.currList == "feedlist":
672                                 self.switchToFeedList()
673
674         def doQuit(self):
675                 if self["config"].getCurrent()[1].suggestionsWindow is not None:
676                         self.session.deleteDialog(self["config"].getCurrent()[1].suggestionsWindow)
677                 if self.HistoryWindow is not None:
678                         self.session.deleteDialog(self.HistoryWindow)
679                 if config.plugins.mytube.general.showHelpOnOpen.value is True:
680                         config.plugins.mytube.general.showHelpOnOpen.value = False
681                         config.plugins.mytube.general.showHelpOnOpen.save()
682                 if not config.plugins.mytube.general.clearHistoryOnClose.value:
683                         if self.History and len(self.History):
684                                 config.plugins.mytube.general.history.value = ",".join(self.History)
685                 else:
686                         config.plugins.mytube.general.history.value = ""
687                 config.plugins.mytube.general.history.save()
688                 config.plugins.mytube.general.save()
689                 config.plugins.mytube.save()
690                 self.cancelThread()
691                 self.close()
692                         
693         def keyOK(self):
694                 print "self.currList im KeyOK",self.currList
695                 if self.currList == "configlist" or self.currList == "suggestionslist":
696                         self["config"].invalidateCurrent()
697                         if config.plugins.mytube.search.searchTerm.value != "":
698                                 self.add2History()
699                                 searchContext = config.plugins.mytube.search.searchTerm.value
700                                 print "Search searchcontext",searchContext
701                                 if isinstance(self["config"].getCurrent()[1], ConfigTextWithGoogleSuggestions) and not self.propagateUpDownNormally:
702                                         self.propagateUpDownNormally = True
703                                         self["config"].getCurrent()[1].deactivateSuggestionList()
704                                 self.setState('getSearchFeed')
705                                 self.runSearch(searchContext)
706                 elif self.currList == "feedlist":
707                         current = self[self.currList].getCurrent()
708                         if current:
709                                 print current
710                                 myentry = current[0]
711                                 if myentry is not None:
712                                         myurl = myentry.getVideoUrl()
713                                         print "Playing URL",myurl
714                                         if myurl is not None:
715                                                 myreference = eServiceReference(4097,0,myurl)
716                                                 myreference.setName(myentry.getTitle())
717                                                 self.session.open(MyTubePlayer, myreference, self.lastservice, infoCallback = self.showVideoInfo, nextCallback = self.getNextEntry, prevCallback = self.getPrevEntry )
718                                         else:
719                                                 self.session.open(MessageBox, _("Sorry, video is not available!"), MessageBox.TYPE_INFO)
720                 elif self.currList == "historylist":
721                         if self.HistoryWindow is not None:
722                                 config.plugins.mytube.search.searchTerm.value = self.HistoryWindow.getSelection()
723                         self["config"].invalidateCurrent()
724                         if config.plugins.mytube.search.searchTerm.value != "":
725                                 searchContext = config.plugins.mytube.search.searchTerm.value
726                                 print "Search searchcontext",searchContext
727                                 self.setState('getSearchFeed')
728                                 self.runSearch(searchContext)
729
730         def keyUp(self):
731                 print "self.currList im KeyUp",self.currList
732                 if self.currList == "suggestionslist":
733                         if config.plugins.mytube.search.searchTerm.value != "":
734                                 if not self.propagateUpDownNormally:
735                                         self["config"].getCurrent()[1].suggestionListUp()
736                                         self["config"].invalidateCurrent()
737                 elif self.currList == "feedlist":
738                         self[self.currList].selectPrevious()
739                 elif self.currList == "historylist":
740                         if self.HistoryWindow is not None and self.HistoryWindow.shown:
741                                 self.HistoryWindow.up()
742
743         def keyDown(self):
744                 print "self.currList im KeyDown",self.currList
745                 if self.currList == "suggestionslist":
746                         if config.plugins.mytube.search.searchTerm.value != "":
747                                 if not self.propagateUpDownNormally:
748                                         self["config"].getCurrent()[1].suggestionListDown()
749                                         self["config"].invalidateCurrent()
750                 elif self.currList == "feedlist":
751                         print self[self.currList].count()
752                         print self[self.currList].index
753                         if self[self.currList].index == self[self.currList].count()-1 and myTubeService.getNextFeedEntriesURL() is not None:
754                                 # load new feeds on last selected item
755                                 if config.plugins.mytube.general.AutoLoadFeeds.value is False:
756                                         self.session.openWithCallback(self.getNextEntries, MessageBox, _("Do you want to see more entries?"))
757                                 else:
758                                         self.getNextEntries(True)
759                         else:
760                                 self[self.currList].selectNext()
761                 elif self.currList == "historylist":
762                         if self.HistoryWindow is not None and self.HistoryWindow.shown:
763                                 self.HistoryWindow.down()
764         def keyRight(self):
765                 print "self.currList im KeyRight",self.currList
766                 if self.propagateUpDownNormally:
767                         ConfigListScreen.keyRight(self)
768                 else:
769                         if self.currList == "suggestionslist":
770                                 if config.plugins.mytube.search.searchTerm.value != "":
771                                         self["config"].getCurrent()[1].suggestionListPageDown()
772                                         self["config"].invalidateCurrent()
773                         elif self.currList == "historylist":
774                                 if self.HistoryWindow is not None and self.HistoryWindow.shown:
775                                         self.HistoryWindow.pageDown()
776
777         def keyLeft(self):
778                 print "self.currList im kEyLeft",self.currList
779                 if self.propagateUpDownNormally:
780                         ConfigListScreen.keyLeft(self)
781                 else:
782                         if self.currList == "suggestionslist":
783                                 if config.plugins.mytube.search.searchTerm.value != "":
784                                         self["config"].getCurrent()[1].suggestionListPageUp()
785                                         self["config"].invalidateCurrent()
786                         elif self.currList == "historylist":
787                                 if self.HistoryWindow is not None and self.HistoryWindow.shown:
788                                         self.HistoryWindow.pageDown()
789         def keyStdFeed(self):
790                 self.hideSuggestions()
791                 menulist = [(_("HD videos"), "hd")]
792                 menulist.extend((
793                         (_("Top rated"), "top_rated"),
794                         (_("Top favorites"), "top_favorites"),
795                         (_("Most viewed"), "most_viewed"),
796                         (_("Most popular"), "most_popular"),
797                         (_("Most recent"), "most_recent"),
798                         (_("Most discussed"), "most_discussed"),
799                         (_("Most linked"), "most_linked"),
800                         (_("Recently featured"), "recently_featured"),
801                         (_("Most responded"), "most_responded")
802                 ))
803                 self.session.openWithCallback(self.openStandardFeedClosed, ChoiceBox, title=_("Select new feed to view."), list = menulist)
804
805         def handleSuggestions(self):
806                 print "handleSuggestions"
807                 print "self.currList",self.currList
808                 if self.currList == "configlist":
809                         self.switchToSuggestionsList()
810                 elif self.currList == "historylist":
811                         if self.HistoryWindow is not None and self.HistoryWindow.shown:
812                                 self.HistoryWindow.down()
813
814         def switchToSuggestionsList(self):
815                 print "switchToSuggestionsList"
816                 self.currList = "suggestionslist"
817                 self["ButtonBlue"].hide()
818                 self["VKeyIcon"].hide() 
819                 self["statusactions"].setEnabled(False)
820                 self["config_actions"].setEnabled(False)        
821                 self["videoactions"].setEnabled(False)
822                 self["searchactions"].setEnabled(False)
823                 self["suggestionactions"].setEnabled(True)
824                 self["historyactions"].setEnabled(False)
825                 self["key_green"].hide()
826                 self.propagateUpDownNormally = False
827                 self["config"].invalidateCurrent()
828                 if self.HistoryWindow is not None and self.HistoryWindow.shown:
829                         self.HistoryWindow.deactivate()
830                         self.HistoryWindow.instance.hide()
831         
832         def switchToConfigList(self):
833                 print "switchToConfigList"
834                 self.currList = "configlist"
835                 self["config_actions"].setEnabled(True) 
836                 self["historyactions"].setEnabled(False)
837                 self["statusactions"].setEnabled(False)
838                 self["videoactions"].setEnabled(False)
839                 self["suggestionactions"].setEnabled(False)
840                 self["searchactions"].setEnabled(True)
841                 self["key_green"].hide()
842                 self["ButtonBlue"].show()
843                 self["VKeyIcon"].show()
844                 self["config"].invalidateCurrent()
845                 helpwindowpos = self["HelpWindow"].getPosition()
846                 current = self["config"].getCurrent()
847                 if current[1].help_window.instance is not None:
848                         current[1].help_window.instance.move(ePoint(helpwindowpos[0],helpwindowpos[1]))
849                         current[1].help_window.instance.show()
850                 if current[1].suggestionsWindow.instance is not None:
851                         current[1].suggestionsWindow.instance.show()
852                         self["config"].getCurrent()[1].getSuggestions()
853                 self.propagateUpDownNormally = True
854                 if self.HistoryWindow is not None and self.HistoryWindow.shown:
855                         self.HistoryWindow.deactivate()
856                         self.HistoryWindow.instance.hide()
857                 if self.FirstRun == True:
858                         self.handleFirstHelpWindow()
859
860         def switchToFeedList(self, append = False):
861                 print "switchToFeedList"
862                 print "switching to feedlist from:",self.currList
863                 print "len(self.videolist):",len(self.videolist)
864                 if self.HistoryWindow is not None and self.HistoryWindow.shown:
865                         self.HistoryWindow.deactivate()
866                         self.HistoryWindow.instance.hide()
867                 self.hideSuggestions()
868                 if len(self.videolist):
869                         self.currList = "feedlist"
870                         self["ButtonBlue"].hide()
871                         self["VKeyIcon"].hide() 
872                         self["videoactions"].setEnabled(True)
873                         self["suggestionactions"].setEnabled(False)
874                         self["searchactions"].setEnabled(False)
875                         self["statusactions"].setEnabled(False)
876                         self["historyactions"].setEnabled(False)
877                         self["key_green"].show()
878                         self["config_actions"].setEnabled(False)
879                         if not append:
880                                 self[self.currList].setIndex(0)
881                         self["feedlist"].updateList(self.videolist)
882                 else:
883                         self.setState('noVideos')
884
885
886         def switchToHistory(self):
887                 print "switchToHistory"
888                 self.oldlist = self.currList
889                 self.currList = "historylist"
890                 print "switchToHistory currentlist",self.currList
891                 print "switchToHistory oldlist",self.oldlist
892                 self.hideSuggestions()
893                 self["ButtonBlue"].hide()
894                 self["VKeyIcon"].hide() 
895                 self["key_green"].hide()
896                 self["videoactions"].setEnabled(False)
897                 self["suggestionactions"].setEnabled(False)
898                 self["searchactions"].setEnabled(False)
899                 self["statusactions"].setEnabled(False)
900                 self["config_actions"].setEnabled(False)
901                 self["historyactions"].setEnabled(True)
902                 self.HistoryWindow.activate()
903                 self.HistoryWindow.instance.show()      
904
905         def handleHistory(self):
906                 if self.HistoryWindow is None:
907                         self.HistoryWindow = self.session.instantiateDialog(MyTubeHistoryScreen)
908                 if self.currList in ("configlist","feedlist"):
909                         if self.HistoryWindow.status() is False:
910                                 print "status is FALSE,switchToHistory"
911                                 self.switchToHistory()
912                 elif self.currList == "historylist":
913                         self.closeHistory()
914
915         def closeHistory(self):
916                 print "closeHistory currentlist",self.currList
917                 print "closeHistory oldlist",self.oldlist
918                 if self.currList == "historylist":
919                         if self.HistoryWindow.status() is True:
920                                 print "status is TRUE, closing historyscreen"
921                                 self.HistoryWindow.deactivate()
922                                 self.HistoryWindow.instance.hide()
923                                 if self.oldlist == "configlist":
924                                         self.switchToConfigList()
925                                 elif self.oldlist == "feedlist":
926                                         self.switchToFeedList()
927
928         def add2History(self):
929                 if self.History is None:
930                         self.History = config.plugins.mytube.general.history.value.split(',')
931                 if self.History[0] == '':
932                         del self.History[0]
933                 print "self.History im add",self.History
934                 if config.plugins.mytube.search.searchTerm.value in self.History:
935                         self.History.remove((config.plugins.mytube.search.searchTerm.value))
936                 self.History.insert(0,(config.plugins.mytube.search.searchTerm.value))
937                 if len(self.History) == 30:
938                         self.History.pop()
939                 config.plugins.mytube.general.history.value = ",".join(self.History)
940                 config.plugins.mytube.general.history.save()
941                 print "configvalue",config.plugins.mytube.general.history.value
942
943         def hideSuggestions(self):
944                 current = self["config"].getCurrent()
945                 if current[1].help_window.instance is not None:
946                         current[1].help_window.instance.hide()  
947                 if current[1].suggestionsWindow.instance is not None:
948                         current[1].suggestionsWindow.instance.hide()
949                 self.propagateUpDownNormally = True
950
951         def getFeed(self, feedUrl, feedName):
952                 self.queryStarted()
953                 self.queryThread = myTubeService.getFeed(feedUrl, self.gotFeed, self.gotFeedError)
954
955         def getNextEntries(self, result):
956                 if not result:
957                         return
958                 nextUrl = myTubeService.getNextFeedEntriesURL()
959                 if nextUrl is not None:
960                         self.appendEntries = True
961                         self.getFeed(nextUrl, _("More video entries."))
962
963         def getRelatedVideos(self, myentry):
964                 if myentry:
965                         myurl =  myentry.getRelatedVideos()
966                         print "RELATEDURL--->",myurl
967                         if myurl is not None:
968                                 self.appendEntries = False
969                                 self.getFeed(myurl, _("Related video entries."))
970
971         def getResponseVideos(self, myentry):
972                 if myentry:
973                         myurl =  myentry.getResponseVideos()
974                         print "RESPONSEURL--->",myurl
975                         if myurl is not None:
976                                 self.appendEntries = False
977                                 self.getFeed(myurl, _("Response video entries."))
978
979         def runSearch(self, searchContext = None):
980                 print "[MyTubePlayer] runSearch"
981                 if searchContext is not None:
982                         print "[MyTubePlayer] searchDialogClosed: ", searchContext
983                         self.searchFeed(searchContext)
984
985         def searchFeed(self, searchContext, vals = {}):
986                 print "[MyTubePlayer] searchFeed"               
987                 
988                 defaults = {
989                   'time': config.plugins.mytube.search.orderBy.value,
990                         'orderby': config.plugins.mytube.search.orderBy.value,
991                 }
992                 
993                 defaults.update(vals)
994                 
995                 self.queryStarted()             
996                 self.appendEntries = False
997                 self.queryThread = myTubeService.search(searchContext, 
998                                         orderby = defaults['orderby'],
999                                         time = defaults['time'],
1000                                         lr = config.plugins.mytube.search.lr.value,
1001                                         categories = [ config.plugins.mytube.search.categories.value ],
1002                                         sortOrder = config.plugins.mytube.search.sortOrder.value,
1003                                         callback = self.gotSearchFeed, errorback = self.gotSearchFeedError)
1004         
1005         def queryStarted(self):
1006                 if self.queryRunning:
1007                         self.cancelThread()
1008                 self.queryRunning = True                
1009         
1010         def queryFinished(self):
1011                 self.queryRunning = False
1012         
1013         def cancelThread(self):
1014                 print "[MyTubePlayer] cancelThread"
1015                 if self.queryThread is not None:
1016                         self.queryThread.cancel()
1017                 self.queryFinished()
1018         
1019         def gotFeed(self, feed):
1020                 print "[MyTubePlayer] gotFeed"
1021                 self.queryFinished()
1022                 if feed is not None:
1023                         self.ytfeed = feed
1024                 self.buildEntryList()
1025         
1026         def gotFeedError(self, exception):
1027                 print "[MyTubePlayer] gotFeedError"
1028                 self.queryFinished()
1029                 self.setState('Error')
1030         
1031         def gotSearchFeed(self, feed):
1032                 if self.FirstRun:       
1033                         self.FirstRun = False
1034                 self.gotFeed(feed)
1035         
1036         def gotSearchFeedError(self, exception):
1037                 if self.FirstRun:       
1038                         self.FirstRun = False
1039                 self.gotFeedError(exception)
1040         
1041         def buildEntryList(self):
1042                 self.mytubeentries = None
1043                 self.screenshotList = []
1044                 self.maxentries = 0
1045                 self.mytubeentries = myTubeService.getEntries()
1046                 self.maxentries = len(self.mytubeentries)-1
1047                 if self.mytubeentries and len(self.mytubeentries):
1048                         if self.appendEntries == False:
1049                                 self.videolist = []
1050                                 for entry in self.mytubeentries:
1051                                         TubeID = entry.getTubeId()
1052                                         thumbnailUrl = None
1053                                         thumbnailUrl = entry.getThumbnailUrl(0)                         
1054                                         if thumbnailUrl is not None:
1055                                                 self.screenshotList.append((TubeID,thumbnailUrl))
1056                                         if not self.Details.has_key(TubeID):
1057                                                 self.Details[TubeID] = { 'thumbnail': None}
1058                                         self.videolist.append(self.buildEntryComponent(entry, TubeID))
1059                                 if len(self.videolist):
1060                                         self["feedlist"].style = "default"
1061                                         self["feedlist"].disable_callbacks = True
1062                                         self["feedlist"].list = self.videolist
1063                                         self["feedlist"].disable_callbacks = False
1064                                         self["feedlist"].setIndex(0)
1065                                         self["feedlist"].setList(self.videolist)
1066                                         self["feedlist"].updateList(self.videolist)
1067                                         if self.FirstRun and not config.plugins.mytube.general.loadFeedOnOpen.value:
1068                                                 self.switchToConfigList()
1069                                         else:
1070                                                 self.switchToFeedList()
1071                         else:           
1072                                 self.oldfeedentrycount = self["feedlist"].count()
1073                                 for entry in self.mytubeentries:
1074                                         TubeID = entry.getTubeId()
1075                                         thumbnailUrl = None
1076                                         thumbnailUrl = entry.getThumbnailUrl(0)                         
1077                                         if thumbnailUrl is not None:
1078                                                 self.screenshotList.append((TubeID,thumbnailUrl))
1079                                         if not self.Details.has_key(TubeID):
1080                                                 self.Details[TubeID] = { 'thumbnail': None}
1081                                         self.videolist.append(self.buildEntryComponent(entry, TubeID))
1082                                 if len(self.videolist):
1083                                         self["feedlist"].style = "default"
1084                                         old_index = self["feedlist"].index
1085                                         self["feedlist"].disable_callbacks = True
1086                                         self["feedlist"].list = self.videolist
1087                                         self["feedlist"].disable_callbacks = False
1088                                         self["feedlist"].setList(self.videolist)
1089                                         self["feedlist"].setIndex(old_index)
1090                                         self["feedlist"].updateList(self.videolist)
1091                                         self["feedlist"].selectNext()
1092                                         self.switchToFeedList(True)
1093                         if not self.timer_startDownload.isActive():
1094                                 print "STARRTDOWNLOADTIMER IM BUILDENTRYLIST"
1095                                 self.timer_startDownload.start(5)
1096                 else:
1097                         self.setState('Error')
1098                         pass
1099         
1100         def buildEntryComponent(self, entry,TubeID):
1101                 Title = entry.getTitle()
1102                 print "Titel-->",Title
1103                 Description = entry.getDescription()
1104                 myTubeID = TubeID
1105                 PublishedDate = entry.getPublishedDate()
1106                 if PublishedDate is not "unknown":
1107                         published = PublishedDate.split("T")[0]
1108                 else:
1109                         published = "unknown"
1110                 Views = entry.getViews()
1111                 if Views is not "not available":
1112                         views = Views
1113                 else:
1114                         views = "not available"
1115                 Duration = entry.getDuration()
1116                 if Duration is not 0:
1117                         durationInSecs = int(Duration)
1118                         mins = int(durationInSecs / 60)
1119                         secs = durationInSecs - mins * 60
1120                         duration = "%d:%02d" % (mins, secs)
1121                 else:
1122                         duration = "not available"
1123                 Ratings = entry.getNumRaters()
1124                 if Ratings is not "":
1125                         ratings = Ratings
1126                 else:
1127                         ratings = ""
1128                 thumbnail = None
1129                 if self.Details[myTubeID]["thumbnail"]:
1130                         thumbnail = self.Details[myTubeID]["thumbnail"]
1131                 return((entry, Title, Description, myTubeID, thumbnail, _("Added: ") + str(published), _("Views: ") + str(views), _("Duration: ") + str(duration), _("Ratings: ") + str(ratings) ))     
1132
1133         def getNextEntry(self):
1134                 i = self["feedlist"].getIndex() + 1
1135                 if i < len(self.videolist):
1136                         self["feedlist"].selectNext()
1137                         current = self["feedlist"].getCurrent()
1138                         if current:
1139                                 myentry = current[0]
1140                                 if myentry:
1141                                         myurl = myentry.getVideoUrl()
1142                                         if myurl is not None:
1143                                                 print "Got a URL to stream"
1144                                                 myreference = eServiceReference(4097,0,myurl)
1145                                                 myreference.setName(myentry.getTitle())
1146                                                 return myreference,False
1147                                         else:
1148                                                 print "NoURL im getNextEntry"
1149                                                 return None,True
1150                                                 
1151                 print "no more entries to play"
1152                 return None,False
1153
1154         def getPrevEntry(self):
1155                 i = self["feedlist"].getIndex() - 1
1156                 if i >= 0:
1157                         self["feedlist"].selectPrevious()
1158                         current = self["feedlist"].getCurrent()
1159                         if current:
1160                                 myentry = current[0]
1161                                 if myentry:
1162                                         myurl = myentry.getVideoUrl()
1163                                         if myurl is not None:
1164                                                 print "Got a URL to stream"
1165                                                 myreference = eServiceReference(4097,0,myurl)
1166                                                 myreference.setName(myentry.getTitle())
1167                                                 return myreference,False
1168                                         else:
1169                                                 return None,True
1170                 return None,False
1171
1172         def showVideoInfo(self):
1173                 if self.currList == "feedlist":
1174                         self.openInfoScreen()
1175
1176         def openInfoScreen(self):
1177                 if self.currList == "feedlist":
1178                         current = self[self.currList].getCurrent()
1179                         if current:
1180                                 myentry = current[0]
1181                                 if myentry:
1182                                         print "Title im showVideoInfo",myentry.getTitle()
1183                                         videoinfos = myentry.PrintEntryDetails()
1184                                         self.session.open(MyTubeVideoInfoScreen, self.skin_path, videoinfo = videoinfos )
1185
1186         def downloadThumbnails(self):
1187                 self.timer_startDownload.stop()
1188                 for entry in self.screenshotList:
1189                         thumbnailUrl = entry[1]
1190                         tubeid = entry[0]
1191                         thumbnailFile = "/tmp/"+str(tubeid)+".jpg"
1192                         if self.Details.has_key(tubeid):
1193                                 if self.Details[tubeid]["thumbnail"] is None:
1194                                         if thumbnailUrl is not None:
1195                                                 if tubeid not in self.pixmaps_to_load:
1196                                                         self.pixmaps_to_load.append(tubeid)
1197                                                         if (os_path.exists(thumbnailFile) == True):
1198                                                                 self.fetchFinished(False,tubeid)
1199                                                         else:
1200                                                                 client.downloadPage(thumbnailUrl,thumbnailFile).addCallback(self.fetchFinished,str(tubeid)).addErrback(self.fetchFailed,str(tubeid))
1201                                         else:
1202                                                 if tubeid not in self.pixmaps_to_load:
1203                                                         self.pixmaps_to_load.append(tubeid)
1204                                                         self.fetchFinished(False,tubeid, failed = True)
1205
1206         def fetchFailed(self,string,tubeid):
1207                 print "thumbnail-fetchFailed for: ",tubeid,string.getErrorMessage()
1208                 self.fetchFinished(False,tubeid, failed = True)
1209
1210         def fetchFinished(self,x,tubeid, failed = False):
1211                 print "thumbnail-fetchFinished for:",tubeid
1212                 self.pixmaps_to_load.remove(tubeid)
1213                 if failed:
1214                         thumbnailFile = resolveFilename(SCOPE_CURRENT_PLUGIN, "Extensions/MyTube/plugin.png")
1215                 else:
1216                         thumbnailFile = "/tmp/"+str(tubeid)+".jpg"
1217                 sc = AVSwitch().getFramebufferScale()
1218                 if (os_path.exists(thumbnailFile) == True):
1219                         self.picloads[tubeid] = ePicLoad()
1220                         self.picloads[tubeid].PictureData.get().append(boundFunction(self.finish_decode, tubeid))
1221                         self.picloads[tubeid].setPara((self["thumbnail"].instance.size().width(), self["thumbnail"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
1222                         self.picloads[tubeid].startDecode(thumbnailFile)
1223                 else:
1224                         self.pixmaps_to_load.append(tubeid)
1225                         self.fetchFinished(False,tubeid, failed = True)
1226
1227         def finish_decode(self,tubeid,info):
1228                 print "thumbnail finish_decode:", tubeid,info
1229                 ptr = self.picloads[tubeid].getData()
1230                 thumbnailFile = "/tmp/"+str(tubeid)+".jpg"
1231                 if ptr != None:
1232                         if self.Details.has_key(tubeid):
1233                                 self.Details[tubeid]["thumbnail"] = ptr
1234                         if (os_path.exists(thumbnailFile) == True):
1235                                 os_remove(thumbnailFile)
1236                         del self.picloads[tubeid]
1237                 else:
1238                         del self.picloads[tubeid]
1239                         if self.Details.has_key(tubeid):
1240                                 self.Details[tubeid]["thumbnail"] = None
1241                 self.timer_thumbnails.start(1)
1242
1243         def updateFeedThumbnails(self):
1244                 self.timer_thumbnails.stop()
1245                 if len(self.picloads) != 0:
1246                         self.timer_thumbnails.start(1)
1247                 else:
1248                         idx = 0
1249                         for entry in self.videolist:
1250                                 tubeid = entry[3]
1251                                 if self.Details.has_key(tubeid):
1252                                         if self.Details[tubeid]["thumbnail"] is not None:
1253                                                 thumbnail = entry[4]
1254                                                 if thumbnail == None:
1255                                                         myentry = entry[0]
1256                                                         self.videolist[idx] = self.buildEntryComponent(myentry, tubeid )
1257                                 idx += 1
1258                         if self.currList == "feedlist":
1259                                 self["feedlist"].updateList(self.videolist)             
1260
1261
1262 class MyTubeVideoInfoScreen(Screen):
1263         skin = """
1264                 <screen name="MyTubeVideoInfoScreen" flags="wfNoBorder" position="0,0" size="720,576" title="MyTube - Video Info" >
1265                         <ePixmap position="0,0" zPosition="-1" size="720,576" pixmap="~/mytubemain_bg.png" alphatest="on" transparent="1" backgroundColor="transparent"/>
1266                         <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" />
1267                         <widget name="starsbg" pixmap="~/starsbar_empty.png" position="560,220" zPosition="5" size="100,20" transparent="1" alphatest="on" />
1268                         <widget name="stars" pixmap="~/starsbar_filled.png" position="560,220" zPosition="6" size="100,20"  transparent="1" />
1269                         <widget source="infolist" render="Listbox" position="50,110" size="620,110" zPosition="6" scrollbarMode="showNever" selectionDisabled="1" transparent="1">
1270                                 <convert type="TemplatedMultiContent">
1271                                 {"templates":
1272                                         {"default": (110,[
1273                                                         MultiContentEntryPixmapAlphaTest(pos = (0, 4), size = (130, 98), png = 0), # index 0 is the thumbnail
1274                                                         MultiContentEntryPixmapAlphaTest(pos = (130, 4), size = (130, 98), png = 1), # index 0 is the thumbnail
1275                                                         MultiContentEntryPixmapAlphaTest(pos = (260, 4), size = (130, 98), png = 2), # index 0 is the thumbnail
1276                                                         MultiContentEntryPixmapAlphaTest(pos = (390, 4), size = (130, 98), png = 3), # index 0 is the thumbnail
1277                                                 ]),
1278                                         "state": (110,[
1279                                                         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
1280                                                 ])
1281                                         },
1282                                         "fonts": [gFont("Regular", 20),gFont("Regular", 14),gFont("Regular", 28)],
1283                                         "itemHeight": 110
1284                                 }
1285                                 </convert>
1286                         </widget>
1287                         <widget name="author" position="60,220" size="300,20" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top" />
1288                         <widget name="duration" position="370,220" size="200,20" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top" />
1289                         <widget name="published" position="60,245" size="300,20" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top" />
1290                         <widget name="views" position="370,245" size="200,20" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top" />
1291                         <widget name="tags" position="60,270" size="600,20" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top" />
1292                         <widget name="detailtext" position="60,300" size="610,200" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top"/>
1293                         <ePixmap position="100,500" size="100,40" zPosition="0" pixmap="~/plugin.png" alphatest="on" transparent="1" />
1294                         <ePixmap position="220,500" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
1295                         <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" />
1296                         <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.
1297                 </screen>"""
1298                 
1299         def __init__(self, session, plugin_path, videoinfo = None):
1300                 Screen.__init__(self, session)
1301                 self.session = session
1302                 self.skin_path = plugin_path
1303                 self.videoinfo = videoinfo
1304                 self.infolist = []
1305                 self.thumbnails = []
1306                 self.picloads = {}
1307                 self["title"] = Label()
1308                 self["key_red"] = Button(_("Close"))
1309                 self["thumbnail"] = Pixmap()
1310                 self["thumbnail"].hide()
1311                 self["detailtext"] = ScrollLabel()
1312                 self["starsbg"] = Pixmap()
1313                 self["stars"] = ProgressBar()
1314                 self["duration"] = Label()
1315                 self["author"] = Label()
1316                 self["published"] = Label()
1317                 self["views"] = Label()
1318                 self["tags"] = Label()
1319                 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions", "MovieSelectionActions"],
1320                 {
1321                         "back": self.close,
1322                         "red": self.close,
1323                         "up": self.pageUp,
1324                         "down": self.pageDown,
1325                         "left": self.pageUp,
1326                         "right": self.pageDown,
1327                 }, -2)
1328                 
1329                 self["infolist"] = List(self.infolist)
1330                 self.timer = eTimer()
1331                 self.timer.callback.append(self.picloadTimeout)
1332                 self.onLayoutFinish.append(self.layoutFinished)
1333                 self.onShown.append(self.setWindowTitle)
1334
1335         def layoutFinished(self):
1336                 self.statuslist = []
1337                 self.statuslist.append(( _("Downloading screenshots. Please wait..." ),_("Downloading screenshots. Please wait..." ) ))
1338                 self["infolist"].style = "state"
1339                 self['infolist'].setList(self.statuslist)
1340                 self.loadPreviewpics()          
1341                 if self.videoinfo["Title"] is not None:
1342                         self["title"].setText(self.videoinfo["Title"])
1343                 Description = None
1344                 if self.videoinfo["Description"] is not None:
1345                         Description = self.videoinfo["Description"]
1346                 else:
1347                         Description = None
1348                 if Description is not None:
1349                         self["detailtext"].setText(Description.strip())
1350
1351                 if self.videoinfo["RatingAverage"] is not 0:
1352                         ratingStars = int(round(20 * float(self.videoinfo["RatingAverage"]), 0))
1353                         self["stars"].setValue(ratingStars)
1354                 else:
1355                         self["stars"].hide()
1356                         self["starsbg"].hide()
1357                 
1358                 if self.videoinfo["Duration"] is not 0:
1359                         durationInSecs = int(self.videoinfo["Duration"])
1360                         mins = int(durationInSecs / 60)
1361                         secs = durationInSecs - mins * 60
1362                         duration = "%d:%02d" % (mins, secs)
1363                         self["duration"].setText(_("Duration: ") + str(duration))
1364                 
1365                 if self.videoinfo["Author"] is not None or '':
1366                         self["author"].setText(_("Author: ") + self.videoinfo["Author"])
1367
1368                 if self.videoinfo["Published"] is not "unknown":
1369                         self["published"].setText(_("Added: ") + self.videoinfo["Published"].split("T")[0])
1370                         
1371                 if self.videoinfo["Views"] is not "not available":
1372                         self["views"].setText(_("Views: ") + str(self.videoinfo["Views"]))
1373
1374                 if self.videoinfo["Tags"] is not "not available":
1375                         self["tags"].setText(_("Tags: ") + str(self.videoinfo["Tags"]))
1376
1377         def setWindowTitle(self):
1378                 self.setTitle(_("MyTubeVideoInfoScreen"))
1379
1380         def pageUp(self):
1381                 self["detailtext"].pageUp()
1382
1383         def pageDown(self):
1384                 self["detailtext"].pageDown()
1385
1386         def loadPreviewpics(self):
1387                 self.thumbnails = []
1388                 self.mythumbubeentries = None
1389                 self.index = 0
1390                 self.maxentries = 0
1391                 self.picloads = {}
1392                 self.mythumbubeentries = self.videoinfo["Thumbnails"]
1393                 self.maxentries = len(self.mythumbubeentries)-1
1394                 if self.mythumbubeentries and len(self.mythumbubeentries):
1395                         currindex = 0
1396                         for entry in self.mythumbubeentries:
1397                                 TubeID = self.videoinfo["TubeID"]
1398                                 ThumbID = TubeID + str(currindex)
1399                                 thumbnailFile = "/tmp/" + ThumbID + ".jpg"
1400                                 currPic = [currindex,ThumbID,thumbnailFile,None]
1401                                 self.thumbnails.append(currPic)
1402                                 thumbnailUrl = None
1403                                 thumbnailUrl = entry
1404                                 if thumbnailUrl is not None:
1405                                         client.downloadPage(thumbnailUrl,thumbnailFile).addCallback(self.fetchFinished,currindex,ThumbID).addErrback(self.fetchFailed,currindex,ThumbID)
1406                                 currindex +=1
1407                 else:
1408                         pass
1409
1410         def fetchFailed(self, string, index, id):
1411                 print "[fetchFailed] for index:" + str(index) + "for ThumbID:" + id + string.getErrorMessage()
1412
1413         def fetchFinished(self, string, index, id):
1414                 print "[fetchFinished] for index:" + str(index) + " for ThumbID:" + id
1415                 self.decodePic(index)
1416
1417         def decodePic(self, index):
1418                 sc = AVSwitch().getFramebufferScale()
1419                 self.picloads[index] = ePicLoad()
1420                 self.picloads[index].PictureData.get().append(boundFunction(self.finish_decode, index))
1421                 for entry in self.thumbnails:
1422                         if entry[0] == index:
1423                                 self.index = index
1424                                 thumbnailFile = entry[2]
1425                                 if (os_path.exists(thumbnailFile) == True):
1426                                         print "[decodePic] DECODING THUMBNAIL for INDEX:"+  str(self.index) + "and file: " + thumbnailFile
1427                                         self.picloads[index].setPara((self["thumbnail"].instance.size().width(), self["thumbnail"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000"))
1428                                         self.picloads[index].startDecode(thumbnailFile)
1429                                 else:
1430                                         print "[decodePic] Thumbnail file NOT FOUND !!!-->:",thumbnailFile
1431
1432         def finish_decode(self, picindex = None, picInfo=None):
1433                 print "finish_decode - of INDEX", picindex
1434                 ptr = self.picloads[picindex].getData()
1435                 if ptr != None:
1436                         self.thumbnails[picindex][3] = ptr
1437                         if (os_path.exists(self.thumbnails[picindex][2]) == True):
1438                                 print "removing", self.thumbnails[picindex][2]
1439                                 os_remove(self.thumbnails[picindex][2])
1440                                 del self.picloads[picindex]
1441                                 if len(self.picloads) == 0:
1442                                         self.timer.startLongTimer(3)
1443
1444         def picloadTimeout(self):
1445                 self.timer.stop()
1446                 if len(self.picloads) == 0:
1447                                 self.buildInfoList()
1448                 else:
1449                         self.timer.startLongTimer(2)
1450
1451         def buildInfoList(self):
1452                 self.infolist = []
1453                 Thumbail0 = None
1454                 Thumbail1 = None
1455                 Thumbail2 = None
1456                 Thumbail3 = None
1457                 if self.thumbnails[0][3] is not None:
1458                         Thumbail0 = self.thumbnails[0][3]
1459                 if self.thumbnails[1][3] is not None:
1460                         Thumbail1 = self.thumbnails[1][3]
1461                 if self.thumbnails[2][3] is not None:
1462                         Thumbail2 = self.thumbnails[2][3]
1463                 if self.thumbnails[3][3] is not None:
1464                         Thumbail3 = self.thumbnails[3][3]
1465                 self.infolist.append(( Thumbail0, Thumbail1, Thumbail2, Thumbail3))
1466                 if len(self.infolist):
1467                         self["infolist"].style = "default"
1468                         self["infolist"].disable_callbacks = True
1469                         self["infolist"].list = self.infolist
1470                         self["infolist"].disable_callbacks = False
1471                         self["infolist"].setIndex(0)
1472                         self["infolist"].setList(self.infolist)
1473                         self["infolist"].updateList(self.infolist)
1474
1475
1476 class MyTubeVideoHelpScreen(Screen):
1477         skin = """
1478                 <screen name="MyTubeVideoHelpScreen" flags="wfNoBorder" position="0,0" size="720,576" title="MyTube - Help" >
1479                         <ePixmap position="0,0" zPosition="-1" size="720,576" pixmap="~/mytubemain_bg.png" alphatest="on" transparent="1" backgroundColor="transparent"/>
1480                         <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" />
1481                         <widget name="detailtext" position="60,120" size="610,370" zPosition="10" font="Regular;21" transparent="1" halign="left" valign="top"/>
1482                         <ePixmap position="100,500" size="100,40" zPosition="0" pixmap="~/plugin.png" alphatest="on" transparent="1" />
1483                         <ePixmap position="220,500" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
1484                         <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" />
1485                 </screen>"""
1486                 
1487         def __init__(self, session, plugin_path, wantedinfo = None, wantedtitle = None):
1488                 Screen.__init__(self, session)
1489                 self.session = session
1490                 self.skin_path = plugin_path
1491                 self.wantedinfo = wantedinfo
1492                 self.wantedtitle = wantedtitle
1493                 self["title"] = Label()
1494                 self["key_red"] = Button(_("Close"))
1495                 self["detailtext"] = ScrollLabel()
1496                 
1497                 self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"],
1498                 {
1499                         "back": self.close,
1500                         "red": self.close,
1501                         "up": self.pageUp,
1502                         "down": self.pageDown,
1503                         "left": self.pageUp,
1504                         "right": self.pageDown,
1505                 }, -2)
1506                 
1507                 self.onLayoutFinish.append(self.layoutFinished)
1508                 self.onShown.append(self.setWindowTitle)
1509
1510         def layoutFinished(self):
1511                 if self.wantedtitle is None:
1512                         self["title"].setText(_("Help"))
1513                 else:
1514                         self["title"].setText(self.wantedtitle)
1515                 if self.wantedinfo is None:
1516                         self["detailtext"].setText(_("This is the help screen. Feed me with something to display."))
1517                 else:
1518                         self["detailtext"].setText(self.wantedinfo)
1519         
1520         def setWindowTitle(self):
1521                 self.setTitle(_("MyTubeVideohelpScreen"))
1522
1523         def pageUp(self):
1524                 self["detailtext"].pageUp()
1525
1526         def pageDown(self):
1527                 self["detailtext"].pageDown()
1528
1529
1530 class MyTubePlayer(Screen, InfoBarNotifications):
1531         STATE_IDLE = 0
1532         STATE_PLAYING = 1
1533         STATE_PAUSED = 2
1534         ENABLE_RESUME_SUPPORT = True
1535         ALLOW_SUSPEND = True
1536
1537         skin = """<screen name="MyTubePlayer" flags="wfNoBorder" position="0,380" size="720,160" title="InfoBar" backgroundColor="transparent">
1538                 <ePixmap position="0,0" pixmap="skin_default/info-bg_mp.png" zPosition="-1" size="720,160" />
1539                 <ePixmap position="29,40" pixmap="skin_default/screws_mp.png" size="665,104" alphatest="on" />
1540                 <ePixmap position="48,70" pixmap="skin_default/icons/mp_buttons.png" size="108,13" alphatest="on" />
1541                 <ePixmap pixmap="skin_default/icons/icon_event.png" position="207,78" size="15,10" alphatest="on" />
1542                 <widget source="session.CurrentService" render="Label" position="230,73" size="360,40" font="Regular;20" backgroundColor="#263c59" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1">
1543                         <convert type="ServiceName">Name</convert>
1544                 </widget>
1545                 <widget source="session.CurrentService" render="Label" position="580,73" size="90,24" font="Regular;20" halign="right" backgroundColor="#4e5a74" transparent="1">
1546                         <convert type="ServicePosition">Length</convert>
1547                 </widget>
1548                 <widget source="session.CurrentService" render="Label" position="205,129" size="100,20" font="Regular;18" halign="center" valign="center" backgroundColor="#06224f" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1">
1549                         <convert type="ServicePosition">Position</convert>
1550                 </widget>
1551                 <widget source="session.CurrentService" render="PositionGauge" position="300,133" size="270,10" zPosition="2" pointer="skin_default/position_pointer.png:540,0" transparent="1" foregroundColor="#20224f">
1552                         <convert type="ServicePosition">Gauge</convert>
1553                 </widget>
1554                 <widget source="session.CurrentService" render="Label" position="576,129" size="100,20" font="Regular;18" halign="center" valign="center" backgroundColor="#06224f" shadowColor="#1d354c" shadowOffset="-1,-1" transparent="1">
1555                         <convert type="ServicePosition">Remaining</convert>
1556                 </widget>
1557                 </screen>"""
1558
1559         def __init__(self, session, service, lastservice, infoCallback = None, nextCallback = None, prevCallback = None):
1560                 Screen.__init__(self, session)
1561                 InfoBarNotifications.__init__(self)
1562                 self.session = session
1563                 self.service = service
1564                 self.infoCallback = infoCallback
1565                 self.nextCallback = nextCallback
1566                 self.prevCallback = prevCallback
1567                 self.screen_timeout = 5000
1568                 self.nextservice = None
1569
1570                 print "evEOF=%d" % iPlayableService.evEOF
1571                 self.__event_tracker = ServiceEventTracker(screen = self, eventmap =
1572                         {
1573                                 iPlayableService.evSeekableStatusChanged: self.__seekableStatusChanged,
1574                                 iPlayableService.evStart: self.__serviceStarted,
1575                                 iPlayableService.evEOF: self.__evEOF,
1576                         })
1577                 
1578                 self["actions"] = ActionMap(["OkCancelActions", "InfobarSeekActions", "MediaPlayerActions", "MovieSelectionActions"],
1579                 {
1580                                 "ok": self.ok,
1581                                 "cancel": self.leavePlayer,
1582                                 "stop": self.leavePlayer,
1583                                 "playpauseService": self.playpauseService,
1584                                 "seekFwd": self.playNextFile,
1585                                 "seekBack": self.playPrevFile,
1586                                 "showEventInfo": self.showVideoInfo,
1587                         }, -2)
1588
1589
1590                 self.lastservice = lastservice
1591
1592                 self.hidetimer = eTimer()
1593                 self.hidetimer.timeout.get().append(self.ok)
1594                 self.returning = False
1595
1596                 self.state = self.STATE_PLAYING
1597                 self.lastseekstate = self.STATE_PLAYING
1598
1599                 self.onPlayStateChanged = [ ]
1600                 self.__seekableStatusChanged()
1601         
1602                 self.play()
1603                 self.onClose.append(self.__onClose)
1604                 
1605         def __onClose(self):
1606                 self.session.nav.stopService()
1607
1608         def __evEOF(self):
1609                 print "evEOF=%d" % iPlayableService.evEOF
1610                 print "Event EOF"
1611                 self.handleLeave(config.plugins.mytube.general.on_movie_stop.value)
1612
1613         def __setHideTimer(self):
1614                 self.hidetimer.start(self.screen_timeout)
1615
1616         def showInfobar(self):
1617                 self.show()
1618                 if self.state == self.STATE_PLAYING:
1619                         self.__setHideTimer()
1620                 else:
1621                         pass
1622
1623         def hideInfobar(self):
1624                 self.hide()
1625                 self.hidetimer.stop()
1626
1627         def ok(self):
1628                 if self.shown:
1629                         self.hideInfobar()
1630                 else:
1631                         self.showInfobar()
1632
1633         def showVideoInfo(self):
1634                 if self.shown:
1635                         self.hideInfobar()
1636                 if self.infoCallback is not None:       
1637                         self.infoCallback()
1638
1639         def playNextFile(self):
1640                 print "playNextFile"
1641                 nextservice,error = self.nextCallback()
1642                 print "nextservice--->",nextservice
1643                 if nextservice is None:
1644                         self.handleLeave(config.plugins.mytube.general.on_movie_stop.value, error)
1645                 else:
1646                         self.playService(nextservice)
1647                         self.showInfobar()
1648
1649         def playPrevFile(self):
1650                 print "playPrevFile"
1651                 prevservice,error = self.prevCallback()
1652                 if prevservice is None:
1653                         self.handleLeave(config.plugins.mytube.general.on_movie_stop.value, error)
1654                 else:
1655                         self.playService(prevservice)
1656                         self.showInfobar()
1657
1658         def playagain(self):
1659                 print "playagain"
1660                 if self.state != self.STATE_IDLE:
1661                         self.stopCurrent()
1662                 self.play()
1663         
1664         def playService(self, newservice):
1665                 if self.state != self.STATE_IDLE:
1666                         self.stopCurrent()
1667                 self.service = newservice
1668                 self.play()
1669
1670         def play(self):
1671                 if self.state == self.STATE_PAUSED:
1672                         if self.shown:
1673                                 self.__setHideTimer()   
1674                 self.state = self.STATE_PLAYING
1675                 self.session.nav.playService(self.service)
1676                 if self.shown:
1677                         self.__setHideTimer()
1678
1679         def stopCurrent(self):
1680                 print "stopCurrent"
1681                 self.session.nav.stopService()
1682                 self.state = self.STATE_IDLE
1683
1684         def playpauseService(self):
1685                 print "playpauseService"
1686                 if self.state == self.STATE_PLAYING:
1687                         self.pauseService()
1688                 elif self.state == self.STATE_PAUSED:
1689                         self.unPauseService()
1690
1691         def pauseService(self):
1692                 print "pauseService"
1693                 if self.state == self.STATE_PLAYING:
1694                         self.setSeekState(self.STATE_PAUSED)
1695                 
1696         def unPauseService(self):
1697                 print "unPauseService"
1698                 if self.state == self.STATE_PAUSED:
1699                         self.setSeekState(self.STATE_PLAYING)
1700
1701
1702         def getSeek(self):
1703                 service = self.session.nav.getCurrentService()
1704                 if service is None:
1705                         return None
1706
1707                 seek = service.seek()
1708
1709                 if seek is None or not seek.isCurrentlySeekable():
1710                         return None
1711
1712                 return seek
1713
1714         def isSeekable(self):
1715                 if self.getSeek() is None:
1716                         return False
1717                 return True
1718
1719         def __seekableStatusChanged(self):
1720                 print "seekable status changed!"
1721                 if not self.isSeekable():
1722                         self.setSeekState(self.STATE_PLAYING)
1723                 else:
1724                         print "seekable"
1725
1726         def __serviceStarted(self):
1727                 self.state = self.STATE_PLAYING
1728                 self.__seekableStatusChanged()
1729
1730         def setSeekState(self, wantstate):
1731                 print "setSeekState"
1732                 if wantstate == self.STATE_PAUSED:
1733                         print "trying to switch to Pause- state:",self.STATE_PAUSED
1734                 elif wantstate == self.STATE_PLAYING:
1735                         print "trying to switch to playing- state:",self.STATE_PLAYING
1736                 service = self.session.nav.getCurrentService()
1737                 if service is None:
1738                         print "No Service found"
1739                         return False
1740                 pauseable = service.pause()
1741                 if pauseable is None:
1742                         print "not pauseable."
1743                         self.state = self.STATE_PLAYING
1744
1745                 if pauseable is not None:
1746                         print "service is pausable"
1747                         if wantstate == self.STATE_PAUSED:
1748                                 print "WANT TO PAUSE"
1749                                 pauseable.pause()
1750                                 self.state = self.STATE_PAUSED
1751                                 if not self.shown:
1752                                         self.hidetimer.stop()
1753                                         self.show()
1754                         elif wantstate == self.STATE_PLAYING:
1755                                 print "WANT TO PLAY"
1756                                 pauseable.unpause()
1757                                 self.state = self.STATE_PLAYING
1758                                 if self.shown:
1759                                         self.__setHideTimer()
1760
1761                 for c in self.onPlayStateChanged:
1762                         c(self.state)
1763                 
1764                 return True
1765
1766         def handleLeave(self, how, error = False):
1767                 self.is_closing = True
1768                 if how == "ask":
1769                         list = (
1770                                 (_("Yes"), "quit"),
1771                                 (_("No, but play video again"), "playagain"),
1772                                 (_("Yes, but play next video"), "playnext"),
1773                                 (_("Yes, but play previous video"), "playprev"),
1774                         )
1775                         if error is False:
1776                                 self.session.openWithCallback(self.leavePlayerConfirmed, ChoiceBox, title=_("Stop playing this movie?"), list = list)
1777                         else:
1778                                 self.session.openWithCallback(self.leavePlayerConfirmed, ChoiceBox, title=_("No playable video found! Stop playing this movie?"), list = list)
1779                 else:
1780                         self.leavePlayerConfirmed([True, how])
1781
1782         def leavePlayer(self):
1783                 self.handleLeave(config.plugins.mytube.general.on_movie_stop.value)
1784
1785         def leavePlayerConfirmed(self, answer):
1786                 answer = answer and answer[1]
1787                 if answer == "quit":
1788                         self.close()
1789                 elif answer == "playnext":
1790                         self.playNextFile()
1791                 elif answer == "playprev":
1792                         self.playPrevFile()
1793                 elif answer == "playagain":
1794                         self.playagain()
1795                         
1796         def doEofInternal(self, playing):
1797                 if not self.execing:
1798                         return
1799                 if not playing :
1800                         return
1801                 self.handleLeave(config.usage.on_movie_eof.value)
1802
1803
1804 def MyTubeMain(session, **kwargs):
1805         l2 = False
1806         l2cert = etpm.getCert(eTPM.TPMD_DT_LEVEL2_CERT)
1807         if l2cert is None:
1808                 print "l2cert not found"
1809                 return
1810         
1811         l2key = validate_cert(l2cert, rootkey)
1812         if l2key is None:
1813                 print "l2cert invalid"
1814                 return
1815         l2 = True
1816         if l2:
1817                 session.open(MyTubePlayerMainScreen,l2key)
1818
1819
1820 def Plugins(path, **kwargs):
1821         global plugin_path
1822         plugin_path = path
1823         return PluginDescriptor(
1824                 name=_("My TubePlayer"),
1825                 description=_("Play YouTube movies"),
1826                 where = [ PluginDescriptor.WHERE_EXTENSIONSMENU, PluginDescriptor.WHERE_PLUGINMENU ],
1827                 icon = "plugin.png", fnc = MyTubeMain)