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