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