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