1 | from Plugins.Plugin import PluginDescriptor |
---|
2 | from Components.PluginComponent import plugins |
---|
3 | from Screens.Screen import Screen |
---|
4 | from Screens.VirtualKeyBoard import VirtualKeyBoard |
---|
5 | from Components.ActionMap import ActionMap, NumberActionMap, HelpableActionMap |
---|
6 | from GlobalActions import globalActionMap |
---|
7 | from Components.Label import Label, MultiColorLabel |
---|
8 | from Components.Button import Button |
---|
9 | from Components.MenuList import MenuList |
---|
10 | from Components.ConfigList import ConfigListScreen |
---|
11 | from Components.config import config, ConfigSubsection, ConfigPosition, getConfigListEntry, ConfigBoolean, ConfigInteger, ConfigText, ConfigSelection, configfile |
---|
12 | from Components.Sources.StaticText import StaticText |
---|
13 | from Components.Task import Task |
---|
14 | from enigma import eTimer, eServiceReference, iPlayableService, iServiceInformation, getDesktop, eRCInput, eServiceCenter, fbClass |
---|
15 | from Components.ServiceEventTracker import ServiceEventTracker |
---|
16 | from Screens.ChoiceBox import ChoiceBox |
---|
17 | from Screens.InputBox import InputBox |
---|
18 | from Screens.MessageBox import MessageBox |
---|
19 | from Screens.InfoBar import InfoBar |
---|
20 | from Screens.InfoBarGenerics import InfoBarAudioSelection, InfoBarSubtitleSupport, InfoBarTeletextPlugin, InfoBarRedButton |
---|
21 | from Screens.ChannelSelection import service_types_tv |
---|
22 | from Screens.LocationBox import MovieLocationBox |
---|
23 | import re, os, sys, socket, time |
---|
24 | from Tools.Directories import fileExists, copyfile, pathExists, createDir |
---|
25 | from Components.ServicePosition import ServicePosition |
---|
26 | from browser import Browser |
---|
27 | from bookmarks import BookmarkMenu, BookmarkEdit |
---|
28 | from help import HelpScreen |
---|
29 | from Components.VolumeControl import VolumeControl |
---|
30 | import urllib |
---|
31 | import urllib2 |
---|
32 | plugin_version = '1.0' |
---|
33 | browserinstance = None |
---|
34 | globalinstance = None |
---|
35 | G_CONFIG_LOCATION = '/etc/enigma2/' |
---|
36 | G_HOME_URL = 'http://www.google.com' |
---|
37 | config.plugins.settings = ConfigSubsection() |
---|
38 | config.plugins.settings.hasstartpage = ConfigBoolean(default=True) |
---|
39 | config.plugins.settings.startpage = ConfigText(default=G_HOME_URL) |
---|
40 | config.plugins.settings.usevirtualkeyboard = ConfigBoolean(default=True) |
---|
41 | user_agent = 'HbbbTV/1.1.1(+PVR;;;;;;) CE-HTML/1.0' |
---|
42 | accept_charset = 'ISO-8859-1,utf-8;q=0.7,*;q=0.7' |
---|
43 | accept = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' |
---|
44 | accept_language = 'en-us,en;q=0.5' |
---|
45 | keepalive = 'timeout=15, max=100' |
---|
46 | referer = 'http://hbbtv.ardmediathek.de/hbbtv-ard/mediathek/?devicegroup=hbbtvHost:hbbtv.ardmediathek.de' |
---|
47 | connection = 'keep-alive' |
---|
48 | strIsEmpty = lambda x: x is None or len(x) == 0 |
---|
49 | |
---|
50 | class bcastEvent(): |
---|
51 | BCAST_evCHANNEL_CHANGE_ERROR = 0 |
---|
52 | BCAST_evPLAYSTATE_CHANGE = 1 |
---|
53 | BCAST_evCHANNEL_CHANGE_SUCCEED = 2 |
---|
54 | BCAST_evFULLSCREEN_CHANGE = 3 |
---|
55 | BCAST_evPARENTAL_RATING_CHANGE = 4 |
---|
56 | BCAST_evPARENTAL_RATING_ERROR = 5 |
---|
57 | BCAST_evPROGRAMMES_CHANGED = 6 |
---|
58 | BCAST_evPLAY_SPEED_CHANGED = 7 |
---|
59 | BCAST_evPLAY_POSITION_CHANGED = 8 |
---|
60 | BCAST_evRECORDING_EVENT = 9 |
---|
61 | |
---|
62 | |
---|
63 | class bcastState(): |
---|
64 | BCAST_UNREALIZED = 0 |
---|
65 | BCAST_CONNECTING = 1 |
---|
66 | BCAST_PRESENTING = 2 |
---|
67 | BCAST_STOPPED = 3 |
---|
68 | |
---|
69 | |
---|
70 | class BrowserGlobalHelper(): |
---|
71 | |
---|
72 | def __init__(self): |
---|
73 | self.initializeBrowser() |
---|
74 | self.redButton = False |
---|
75 | self.loadBrowserRemoteControl = False |
---|
76 | self.browserStartState = 0 |
---|
77 | |
---|
78 | def initializeBrowser(self): |
---|
79 | global browserinstance |
---|
80 | if not browserinstance: |
---|
81 | browserinstance = Browser() |
---|
82 | if not fileExists(G_CONFIG_LOCATION + 'startpage.cfg'): |
---|
83 | copyfile(Browser.path + 'startpage.cfg', G_CONFIG_LOCATION + 'startpage.cfg') |
---|
84 | if not fileExists(G_CONFIG_LOCATION + 'bookmarks_web.cfg'): |
---|
85 | copyfile(Browser.path + 'bookmarks_web.cfg', G_CONFIG_LOCATION + 'bookmarks_web.cfg') |
---|
86 | if not fileExists(G_CONFIG_LOCATION + 'bookmarks_private.cfg'): |
---|
87 | copyfile(Browser.path + 'bookmarks_private.cfg', G_CONFIG_LOCATION + 'bookmarks_private.cfg') |
---|
88 | self.readStartPage() |
---|
89 | |
---|
90 | def isBrowserStart(self): |
---|
91 | if not fileExists('/etc/enigma2/settings'): |
---|
92 | return False |
---|
93 | lines = open('/etc/enigma2/settings').readlines() |
---|
94 | for line in lines: |
---|
95 | if line is not None: |
---|
96 | tmp = line.split('=') |
---|
97 | if tmp[0] == 'config.misc.firstrun': |
---|
98 | if tmp[1] == 'false\n' or tmp[1] == 'false': |
---|
99 | return True |
---|
100 | else: |
---|
101 | return False |
---|
102 | |
---|
103 | return False |
---|
104 | |
---|
105 | def openStartPage(self): |
---|
106 | wantUrl = config.plugins.settings.startpage.value |
---|
107 | if wantUrl == '': |
---|
108 | config.plugins.settings.startpage.value = G_HOME_URL |
---|
109 | wantUrl = config.plugins.settings.startpage.value |
---|
110 | browserinstance.showSendUrl(wantUrl.strip()) |
---|
111 | |
---|
112 | def sendKeyToBrowser(self, key): |
---|
113 | browserinstance.keyPressed(key) |
---|
114 | |
---|
115 | def writeStartPage(self, url): |
---|
116 | fp = open(G_CONFIG_LOCATION + 'startpage.cfg', 'w') |
---|
117 | if url is None: |
---|
118 | fp.write(G_HOME_URL) |
---|
119 | else: |
---|
120 | fp.write(url) |
---|
121 | fp.close() |
---|
122 | |
---|
123 | def readStartPage(self): |
---|
124 | if not fileExists(G_CONFIG_LOCATION + 'startpage.cfg'): |
---|
125 | return '' |
---|
126 | try: |
---|
127 | lines = open(G_CONFIG_LOCATION + 'startpage.cfg').readlines() |
---|
128 | for line in lines: |
---|
129 | if line is not None: |
---|
130 | config.plugins.settings.startpage.value = line |
---|
131 | return line |
---|
132 | return '' |
---|
133 | |
---|
134 | except: |
---|
135 | return '' |
---|
136 | |
---|
137 | def keyBrowser(self, target, dig = False): |
---|
138 | ver = 0 |
---|
139 | try: |
---|
140 | lines = open(target).readlines() |
---|
141 | for line in lines: |
---|
142 | if dig: |
---|
143 | return line |
---|
144 | ver = int(line) |
---|
145 | |
---|
146 | except: |
---|
147 | return '' |
---|
148 | |
---|
149 | return ver |
---|
150 | |
---|
151 | |
---|
152 | class mediaPlaylist(Screen): |
---|
153 | |
---|
154 | def __init__(self, session, browserinstance, url): |
---|
155 | self.skin = '\n\t\t\t\t<screen position="80,80" size="e-160,e-160" title="Playlist menu" >' |
---|
156 | self.skin += '\n\t\t\t\t\t<widget name="menu" position="10,10" size="e-20,e-20" scrollbarMode="showOnDemand" />\n\t\t\t\t</screen>' |
---|
157 | self.session = session |
---|
158 | self.browserinstance = browserinstance |
---|
159 | Screen.__init__(self, session) |
---|
160 | self.bookmarks = [] |
---|
161 | self.index = 0 |
---|
162 | urls = url.split() |
---|
163 | idx = 0 |
---|
164 | while idx < len(urls): |
---|
165 | self.bookmarks.append(urls[idx]) |
---|
166 | idx += 1 |
---|
167 | |
---|
168 | if len(self.bookmarks) > 1: |
---|
169 | self['menu'] = MenuList(self.bookmarks) |
---|
170 | self['actions'] = ActionMap(['WizardActions', 'DirectionActions'], {'ok': self.go, |
---|
171 | 'back': self.doExit}, -1) |
---|
172 | self.playTimer = eTimer() |
---|
173 | self.playTimer.callback.append(self.timerCallback) |
---|
174 | self.playTimer.start(500) |
---|
175 | else: |
---|
176 | self.close() |
---|
177 | |
---|
178 | def go(self): |
---|
179 | self.index = self['menu'].getSelectionIndex() |
---|
180 | self.doPlay() |
---|
181 | |
---|
182 | def doExit(self): |
---|
183 | self.close() |
---|
184 | |
---|
185 | def timerCallback(self): |
---|
186 | self.playTimer.stop() |
---|
187 | self.doPlay() |
---|
188 | |
---|
189 | def doPlay(self): |
---|
190 | self.browserinstance.hideBrowser() |
---|
191 | service = eServiceReference(4097, 0, self.bookmarks[self.index]) |
---|
192 | if '/usr/local/OpenOpera/index.html' not in self.browserinstance.currentUrl: |
---|
193 | service.setName(self.browserinstance.currentUrlInfo) |
---|
194 | else: |
---|
195 | service.setName('Streaming media') |
---|
196 | self.session.nav.playService(service) |
---|
197 | |
---|
198 | |
---|
199 | class BrowserRemoteControl(Screen): |
---|
200 | PLAY_STATE_STOPPED = 0 |
---|
201 | PLAY_STATE_PLAYING = 1 |
---|
202 | PLAY_STATE_PAUSED = 2 |
---|
203 | PLAY_STATE_CONNECTING = 3 |
---|
204 | PLAY_STATE_BUFFERING = 4 |
---|
205 | PLAY_STATE_FINISHED = 5 |
---|
206 | PLAY_STATE_ERROR = 6 |
---|
207 | skin = '\n\t\t<screen name="BrowserRemoteControl" position="0,0" size="e-0,e-0" backgroundColor="transparent" flags="wfNoBorder" title="Web Browser active">' |
---|
208 | skin += '\n\t</screen>' |
---|
209 | |
---|
210 | def __init__(self, session, redButton = False, clean = False): |
---|
211 | global globalinstance |
---|
212 | global browserinstance |
---|
213 | Screen.__init__(self, session) |
---|
214 | self.skin = BrowserRemoteControl.skin |
---|
215 | self.session = session |
---|
216 | self.lastservice = session.nav.getCurrentlyPlayingServiceReference() |
---|
217 | self.mediaurl = '' |
---|
218 | self.service = '' |
---|
219 | self.showMenuTimer = eTimer() |
---|
220 | self.showMenuTimer.callback.append(self.showMenuTimerCallback) |
---|
221 | self.exitPluginWaitTimer = eTimer() |
---|
222 | self.exitPluginWaitTimer.callback.append(self.exitPluginWaitTimerCallback) |
---|
223 | self.updateTimer = eTimer() |
---|
224 | self.updateTimer.callback.append(self.updateInfo) |
---|
225 | self.clean = clean |
---|
226 | self.helper = False |
---|
227 | self.exitLeavesPlugin = False |
---|
228 | self.isPlaying = False |
---|
229 | self.rtmp = False |
---|
230 | self.xrtmp = False |
---|
231 | self.mediasource = None |
---|
232 | self.state = self.PLAY_STATE_STOPPED |
---|
233 | self.startBuffering = False |
---|
234 | self.fullBuffer = False |
---|
235 | self.serviceStart = False |
---|
236 | self.isVOD = True |
---|
237 | self.buffering = False |
---|
238 | self.bufferSeconds = 0 |
---|
239 | self.bufferPercent = 0 |
---|
240 | self.bufferSecondsLeft = 0 |
---|
241 | self.selected_subtitle = None |
---|
242 | self.playPosition = 0 |
---|
243 | self.playDuration = 0 |
---|
244 | self.playPositionTime = 0 |
---|
245 | self.playDurationTime = 0 |
---|
246 | self.requestSpeed = False |
---|
247 | self.speed = 0 |
---|
248 | self.isBroadcast = False |
---|
249 | self.broadcastEvent = bcastEvent.BCAST_evCHANNEL_CHANGE_ERROR |
---|
250 | self.broadcastStatus = bcastState.BCAST_UNREALIZED |
---|
251 | self.youtubemedia = False |
---|
252 | if not globalinstance: |
---|
253 | globalinstance = BrowserGlobalHelper() |
---|
254 | if not browserinstance: |
---|
255 | browserinstance = Browser() |
---|
256 | self.globalHelper = globalinstance |
---|
257 | self.browserinstance = browserinstance |
---|
258 | self.globalHelper.redButton = redButton |
---|
259 | self.menu_screen = None |
---|
260 | if self.mediasource is None: |
---|
261 | self.__event_tracker = ServiceEventTracker(screen=self, eventmap={iPlayableService.evStart: self.__serviceStarted, |
---|
262 | iPlayableService.evEOF: self.__evEOF, |
---|
263 | iPlayableService.evEnd: self.__evEnd, |
---|
264 | iPlayableService.evBuffering: self.__evBuffering, |
---|
265 | iPlayableService.evStopped: self.__evStopped, |
---|
266 | iPlayableService.evUpdatedInfo: self.__evUpdatedInfo, |
---|
267 | iPlayableService.evUser + 10: self.__evAudioDecodeError, |
---|
268 | iPlayableService.evUser + 11: self.__evVideoDecodeError, |
---|
269 | iPlayableService.evUser + 12: self.__evPluginError, |
---|
270 | iPlayableService.evVideoSizeChanged: self.__evVideioSizeChanged, |
---|
271 | iPlayableService.evTunedIn: self.__evTunedIn, |
---|
272 | iPlayableService.evTuneFailed: self.__TuneFailed}) |
---|
273 | else: |
---|
274 | self.__event_tracker = ServiceEventTracker(screen=self, eventmap={iPlayableService.evStart: self.__serviceStarted, |
---|
275 | iPlayableService.evSeekableStatusChanged: self.__seekableStatusChanged, |
---|
276 | iPlayableService.evEOF: self.__evEOF, |
---|
277 | iPlayableService.evUpdatedInfo: self.__evUpdatedInfo, |
---|
278 | iPlayableService.evUser + 10: self.__evAudioDecodeError, |
---|
279 | iPlayableService.evUser + 11: self.__evVideoDecodeError, |
---|
280 | iPlayableService.evUser + 12: self.__evPluginError}) |
---|
281 | self['actions'] = NumberActionMap(['PiPSetupActions', |
---|
282 | 'NumberActions', |
---|
283 | 'ColorActions', |
---|
284 | 'TextEntryActions', |
---|
285 | 'InfobarSeekActions', |
---|
286 | 'MovieSelectionActions', |
---|
287 | 'HelpActions', |
---|
288 | 'InfobarSeekActions', |
---|
289 | 'InfobarSubtitleSelectionActions', |
---|
290 | 'InfobarTeletextActions', |
---|
291 | 'InfobarAudioSelectionActions', |
---|
292 | 'GlobalActions'], {'ok': self.go, |
---|
293 | 'up': self.up, |
---|
294 | 'down': self.down, |
---|
295 | 'left': self.left, |
---|
296 | 'right': self.right, |
---|
297 | 'size+': self.programUp, |
---|
298 | 'size-': self.programDown, |
---|
299 | 'deleteForward': self.jumpForward, |
---|
300 | 'deleteBackward': self.jumpBackward, |
---|
301 | '1': self.keyNumberGlobal, |
---|
302 | '2': self.keyNumberGlobal, |
---|
303 | '3': self.keyNumberGlobal, |
---|
304 | '4': self.keyNumberGlobal, |
---|
305 | '5': self.keyNumberGlobal, |
---|
306 | '6': self.keyNumberGlobal, |
---|
307 | '7': self.keyNumberGlobal, |
---|
308 | '8': self.keyNumberGlobal, |
---|
309 | '9': self.keyNumberGlobal, |
---|
310 | '0': self.keyNumberGlobal, |
---|
311 | 'red': self.keyRed, |
---|
312 | 'green': self.keyGreen, |
---|
313 | 'yellow': self.keyYellow, |
---|
314 | 'blue': self.keyBlue, |
---|
315 | 'contextMenu': self.keyMenu, |
---|
316 | 'showEventInfo': self.refresh, |
---|
317 | 'showMovies': self.keyTextInput, |
---|
318 | 'seekBack': self.keyRF, |
---|
319 | 'seekFwd': self.keyFF, |
---|
320 | 'displayHelp': self.showHelp, |
---|
321 | 'subtitleSelection': self.showSubtitle, |
---|
322 | 'startTeletext': self.showTeletext, |
---|
323 | 'audio_key': self.showAudioSelection, |
---|
324 | 'volumeUp': self.volumeup, |
---|
325 | 'volumeDown': self.volumedown, |
---|
326 | 'volumeMute': self.volumemute, |
---|
327 | 'unPauseService': self.unPauseService}, -1) |
---|
328 | self['WebBrowserActions'] = ActionMap(['WebBrowserActions'], {'portal': self.showHbbTVBrowser, |
---|
329 | 'record_s': self.keyRecord, |
---|
330 | 'stop': self.keyStop, |
---|
331 | 'play': self.keyPlay, |
---|
332 | 'pause': self.keyPause, |
---|
333 | 'historyBack': self.keyBack, |
---|
334 | 'exit_s': self.keyCancel}, -1) |
---|
335 | self.browserinstance.onMediaUrlChanged.append(self.mediaUrlChanged) |
---|
336 | self.browserinstance.onKeyReceived.append(self.KeyReceived) |
---|
337 | self.onClose.append(self.__onClose) |
---|
338 | if self.globalHelper.redButton: |
---|
339 | self.onLayoutFinish.append(self.layoutFinished) |
---|
340 | else: |
---|
341 | self.showMenuTimer.start(250) |
---|
342 | if self.clean: |
---|
343 | self.browserinstance.hideSendUrl() |
---|
344 | |
---|
345 | def layoutFinished(self): |
---|
346 | self.exitPluginWaitTimer.start(250) |
---|
347 | |
---|
348 | def setPlayingStatus(self, state): |
---|
349 | if self.state != state: |
---|
350 | self.state = state |
---|
351 | else: |
---|
352 | return |
---|
353 | self.browserinstance.playStatus = self.state |
---|
354 | |
---|
355 | def setBroadcastStatus(self, state): |
---|
356 | if not self.isBroadcast: |
---|
357 | return |
---|
358 | if self.broadcastStatus != state: |
---|
359 | self.broadcastStatus = state |
---|
360 | self.browserinstance.broadcastStatus = self.broadcastStatus |
---|
361 | self.setBroadcastEvent(bcastEvent.BCAST_evPLAYSTATE_CHANGE) |
---|
362 | |
---|
363 | def setBroadcastEvent(self, event): |
---|
364 | if not self.isBroadcast: |
---|
365 | return |
---|
366 | if self.broadcastEvent != event: |
---|
367 | self.broadcastEvent = event |
---|
368 | self.browserinstance.setBroadcastEvent(self.broadcastEvent) |
---|
369 | |
---|
370 | def showHbbTVBrowser(self): |
---|
371 | self.globalHelper.openStartPage() |
---|
372 | |
---|
373 | def exitPluginWaitTimerCallback(self): |
---|
374 | if self.globalHelper.browserStartState == -1: |
---|
375 | self.exitPluginWaitTimer.stop() |
---|
376 | self.close() |
---|
377 | elif self.globalHelper.browserStartState == 1: |
---|
378 | self.exitPluginWaitTimer.stop() |
---|
379 | |
---|
380 | def showMenuTimerCallback(self): |
---|
381 | if self.globalHelper.browserStartState == -1: |
---|
382 | self.showMenuTimer.stop() |
---|
383 | self.close() |
---|
384 | elif self.globalHelper.browserStartState == 1: |
---|
385 | self.showMenuTimer.stop() |
---|
386 | self.keyMenu() |
---|
387 | |
---|
388 | def __evUpdatedInfo(self): |
---|
389 | pass |
---|
390 | |
---|
391 | def __evAudioDecodeError(self): |
---|
392 | self.setPlayingStatus(self.PLAY_STATE_ERROR) |
---|
393 | currPlay = self.session.nav.getCurrentService() |
---|
394 | sTagAudioCodec = currPlay.info().getInfoString(iServiceInformation.sTagAudioCodec) |
---|
395 | self.session.open(MessageBox, _('This model cannot decode %s streams!') % sTagAudioCodec, type=MessageBox.TYPE_INFO, timeout=20) |
---|
396 | |
---|
397 | def __evVideoDecodeError(self): |
---|
398 | self.setPlayingStatus(self.PLAY_STATE_ERROR) |
---|
399 | currPlay = self.session.nav.getCurrentService() |
---|
400 | sTagVideoCodec = currPlay.info().getInfoString(iServiceInformation.sTagVideoCodec) |
---|
401 | self.session.open(MessageBox, _('This model cannot decode %s streams!') % sTagVideoCodec, type=MessageBox.TYPE_INFO, timeout=20) |
---|
402 | |
---|
403 | def __evPluginError(self): |
---|
404 | self.setPlayingStatus(self.PLAY_STATE_ERROR) |
---|
405 | currPlay = self.session.nav.getCurrentService() |
---|
406 | message = currPlay.info().getInfoString(iServiceInformation.sUser + 12) |
---|
407 | self.session.open(MessageBox, message, type=MessageBox.TYPE_INFO, timeout=20) |
---|
408 | |
---|
409 | def __serviceStarted(self): |
---|
410 | self.serviceStart = True |
---|
411 | self.startBuffering = True |
---|
412 | self.last_error = None |
---|
413 | if self.isVOD: |
---|
414 | self.setPlayingStatus(self.PLAY_STATE_CONNECTING) |
---|
415 | if config.ParentalControl.configured.getValue(): |
---|
416 | from Components.ParentalControl import parentalControl |
---|
417 | return |
---|
418 | |
---|
419 | def __evEOF(self): |
---|
420 | if self.exitLeavesPlugin: |
---|
421 | return |
---|
422 | if not self.isVOD: |
---|
423 | return |
---|
424 | if not self.startBuffering: |
---|
425 | self.setPlayingStatus(self.PLAY_STATE_ERROR) |
---|
426 | self.updateTimer.stop() |
---|
427 | if self.playDurationTime > self.playPositionTime + 10000: |
---|
428 | self.setPlayingStatus(self.PLAY_STATE_ERROR) |
---|
429 | elif self.playDurationTime > 0 and self.playPositionTime > 0: |
---|
430 | playPosition = '%s,%s' % (self.playDurationTime, self.playDurationTime) |
---|
431 | self.browserinstance.setplayPosition(playPosition) |
---|
432 | service = self.session.nav.getCurrentService() |
---|
433 | service.stop() |
---|
434 | self.startBuffering = False |
---|
435 | self.serviceStart = False |
---|
436 | self.isPlaying = False |
---|
437 | self.startBuffering = True |
---|
438 | |
---|
439 | def __evEnd(self): |
---|
440 | if self.exitLeavesPlugin: |
---|
441 | return |
---|
442 | self.startBuffering = False |
---|
443 | self.serviceStart = False |
---|
444 | if self.globalHelper.redButton: |
---|
445 | self.setPlayingStatus(self.PLAY_STATE_FINISHED) |
---|
446 | elif self.state != self.PLAY_STATE_STOPPED: |
---|
447 | self.setPlayingStatus(self.PLAY_STATE_STOPPED) |
---|
448 | self.setBroadcastStatus(bcastState.BCAST_STOPPED) |
---|
449 | self.isPlaying = False |
---|
450 | self.startBuffering = True |
---|
451 | self.playPositionTime = 0 |
---|
452 | self.playDurationTime = 0 |
---|
453 | self.browserinstance.setplayPosition('0,0') |
---|
454 | |
---|
455 | def __evBuffering(self): |
---|
456 | if self.exitLeavesPlugin: |
---|
457 | return |
---|
458 | if not self.serviceStart: |
---|
459 | return |
---|
460 | if not self.startBuffering: |
---|
461 | return |
---|
462 | bufferInfo = self.session.nav.getCurrentService().streamed().getBufferCharge() |
---|
463 | if bufferInfo[2] != 0: |
---|
464 | self.bufferSeconds = bufferInfo[4] / bufferInfo[2] |
---|
465 | if self.state != self.PLAY_STATE_BUFFERING: |
---|
466 | self.setPlayingStatus(self.PLAY_STATE_BUFFERING) |
---|
467 | else: |
---|
468 | self.bufferSeconds = 0 |
---|
469 | self.bufferPercent = bufferInfo[0] |
---|
470 | self.bufferSecondsLeft = self.bufferSeconds * self.bufferPercent / 100 |
---|
471 | |
---|
472 | def __evStopped(self): |
---|
473 | if self.exitLeavesPlugin: |
---|
474 | return |
---|
475 | self.setPlayingStatus(self.PLAY_STATE_STOPPED) |
---|
476 | self.setBroadcastStatus(bcastState.BCAST_STOPPED) |
---|
477 | self.browserinstance.setplayPosition('0,0') |
---|
478 | |
---|
479 | def __onClose(self): |
---|
480 | if self.state != self.PLAY_STATE_STOPPED: |
---|
481 | self.setPlayingStatus(self.PLAY_STATE_STOPPED) |
---|
482 | self.setBroadcastStatus(bcastState.BCAST_UNREALIZED) |
---|
483 | self.browserinstance.setplayPosition('0,0') |
---|
484 | self.updateTimer.stop() |
---|
485 | self.browserinstance.onKeyReceived.remove(self.KeyReceived) |
---|
486 | self.browserinstance.onMediaUrlChanged.remove(self.mediaUrlChanged) |
---|
487 | if not self.browserinstance.isFullScreenBrowser: |
---|
488 | self.browserinstance.setPosition(720, 576, 0, 720, 0, 576) |
---|
489 | time.sleep(2) |
---|
490 | self.session.nav.playService(self.lastservice) |
---|
491 | |
---|
492 | def __evVideioSizeChanged(self): |
---|
493 | pass |
---|
494 | |
---|
495 | def __evTunedIn(self): |
---|
496 | self.setBroadcastStatus(bcastState.BCAST_PRESENTING) |
---|
497 | self.setBroadcastEvent(bcastEvent.BCAST_evCHANNEL_CHANGE_SUCCEED) |
---|
498 | |
---|
499 | def __TuneFailed(self): |
---|
500 | self.setBroadcastEvent(bcastEvent.BCAST_evCHANNEL_CHANGE_ERROR) |
---|
501 | self.setBroadcastStatus(bcastState.BCAST_UNREALIZED) |
---|
502 | return |
---|
503 | service = self.session.nav.getCurrentService() |
---|
504 | info = service and service.info() |
---|
505 | error = info and info.getInfo(iServiceInformation.sDVBState) |
---|
506 | if error == self.last_error: |
---|
507 | error = None |
---|
508 | else: |
---|
509 | self.last_error = error |
---|
510 | from enigma import eDVBServicePMTHandler |
---|
511 | error = {eDVBServicePMTHandler.eventNoResources: _('No free tuner!'), |
---|
512 | eDVBServicePMTHandler.eventTuneFailed: _('Tune failed!'), |
---|
513 | eDVBServicePMTHandler.eventNoPAT: _('No data on transponder!\n(Timeout reading PAT)'), |
---|
514 | eDVBServicePMTHandler.eventNoPATEntry: _('Service not found!\n(SID not found in PAT)'), |
---|
515 | eDVBServicePMTHandler.eventNoPMT: _('Service invalid!\n(Timeout reading PMT)'), |
---|
516 | eDVBServicePMTHandler.eventNewProgramInfo: None, |
---|
517 | eDVBServicePMTHandler.eventTuned: None, |
---|
518 | eDVBServicePMTHandler.eventSOF: None, |
---|
519 | eDVBServicePMTHandler.eventEOF: None, |
---|
520 | eDVBServicePMTHandler.eventMisconfiguration: _('Service unavailable!\nCheck tuner configuration!')}.get(error) |
---|
521 | |
---|
522 | def doSeekRelative(self, timeValue): |
---|
523 | if timeValue is None: |
---|
524 | return |
---|
525 | want_position = playPosition + self.sec_to_pts(timeValue) |
---|
526 | seek = self.getSeek() |
---|
527 | seek.seekRelative(want_position < 0 and -1 or 1, abs(want_position)) |
---|
528 | |
---|
529 | def doSeek(self, pts): |
---|
530 | seekable = self.getSeek() |
---|
531 | if seekable is None: |
---|
532 | return |
---|
533 | tenSec = 900000 |
---|
534 | pts -= tenSec |
---|
535 | if pts >= tenSec: |
---|
536 | seekable.seekRelative(1, pts) |
---|
537 | else: |
---|
538 | seekable.seekTo(pts) |
---|
539 | |
---|
540 | def doSkip(self, timeValue): |
---|
541 | if timeValue is None: |
---|
542 | return |
---|
543 | self.doSeek(timeValue * 90) |
---|
544 | |
---|
545 | def sec_to_pts(self, sec): |
---|
546 | return long(sec * 90000) |
---|
547 | |
---|
548 | def pts_to_sec(self, pts): |
---|
549 | return int(pts / 90000) |
---|
550 | |
---|
551 | def pts_to_msec(self, pts): |
---|
552 | return int(pts / 90) |
---|
553 | |
---|
554 | def getCurrentPosition(self): |
---|
555 | seek = self.getSeek() |
---|
556 | if seek is None: |
---|
557 | return |
---|
558 | r = seek.getPlayPosition() |
---|
559 | if r[0]: |
---|
560 | return |
---|
561 | return long(r[1]) |
---|
562 | |
---|
563 | def getCurrentLength(self): |
---|
564 | seek = self.getSeek() |
---|
565 | if seek is None: |
---|
566 | return |
---|
567 | r = seek.getLength() |
---|
568 | if r[0]: |
---|
569 | return |
---|
570 | return long(r[1]) |
---|
571 | |
---|
572 | def mediaControlCallback(self): |
---|
573 | if self.isPlaying: |
---|
574 | self.session.nav.stopService() |
---|
575 | self.mediaurl = '' |
---|
576 | |
---|
577 | def mediaPlay(self): |
---|
578 | if self.state != self.PLAY_STATE_CONNECTING: |
---|
579 | self.setPlayingStatus(self.PLAY_STATE_CONNECTING) |
---|
580 | self.session.nav.playService(self.service) |
---|
581 | self.isPlaying = True |
---|
582 | self.updateInfo() |
---|
583 | |
---|
584 | def updateInfo(self): |
---|
585 | if self.isPlaying: |
---|
586 | self.updateTimer.stop() |
---|
587 | self.seek = self.getSeek() |
---|
588 | if self.seek is None: |
---|
589 | self.updateTimer.start(1000) |
---|
590 | return |
---|
591 | if self.state != self.PLAY_STATE_PAUSED: |
---|
592 | self.checkPosition() |
---|
593 | self.updateTimer.start(1000) |
---|
594 | else: |
---|
595 | self.updateTimer.stop() |
---|
596 | |
---|
597 | def checkPosition(self): |
---|
598 | length = self.seek.getLength() |
---|
599 | position = self.seek.getPlayPosition() |
---|
600 | if length[0] == -1: |
---|
601 | return |
---|
602 | if position[0] == -1: |
---|
603 | return |
---|
604 | if self.playDuration != length[1]: |
---|
605 | self.playDuration = length[1] |
---|
606 | if length[1] > 0: |
---|
607 | self.playDurationTime = self.pts_to_msec(length[1]) |
---|
608 | playPosition = '%s,%s' % (self.playDurationTime, 0) |
---|
609 | self.browserinstance.setplayPosition(playPosition) |
---|
610 | if self.playDuration > 0 and self.state != self.PLAY_STATE_PLAYING: |
---|
611 | self.setPlayingStatus(self.PLAY_STATE_PLAYING) |
---|
612 | self.startBuffering = False |
---|
613 | if self.playPosition != position[1]: |
---|
614 | self.playPosition = position[1] |
---|
615 | self.playPositionTime = self.pts_to_msec(position[1]) |
---|
616 | playPosition = '%s,%s' % (self.playDurationTime, self.playPositionTime) |
---|
617 | self.browserinstance.setplayPosition(playPosition) |
---|
618 | if self.startBuffering: |
---|
619 | self.startBuffering = False |
---|
620 | |
---|
621 | def checkSpeed(self): |
---|
622 | if not self.requestSpeed: |
---|
623 | return |
---|
624 | if self.speed != self.browserinstance.speed: |
---|
625 | if self.speed == -1: |
---|
626 | self.browserinstance.speedChange(self.browserinstance.speed, 0) |
---|
627 | self.browserinstance.speed = -1 |
---|
628 | else: |
---|
629 | self.browserinstance.speedChange(self.browserinstance.speed, 1) |
---|
630 | self.speed = self.browserinstance.speed |
---|
631 | self.requestSpeed = False |
---|
632 | |
---|
633 | def getSeek(self): |
---|
634 | service = self.session.nav.getCurrentService() |
---|
635 | if service is None: |
---|
636 | return |
---|
637 | seek = service.seek() |
---|
638 | if seek is None or not seek.isCurrentlySeekable(): |
---|
639 | return |
---|
640 | return seek |
---|
641 | |
---|
642 | def isSeekable(self): |
---|
643 | if self.getSeek() is None: |
---|
644 | return False |
---|
645 | return True |
---|
646 | |
---|
647 | def __seekableStatusChanged(self): |
---|
648 | if not self.isSeekable(): |
---|
649 | self.setSeekState(self.PLAY_STATE_PLAYING) |
---|
650 | else: |
---|
651 | pass |
---|
652 | |
---|
653 | def setSeekState(self, wantstate): |
---|
654 | service = self.session.nav.getCurrentService() |
---|
655 | if service is None: |
---|
656 | return |
---|
657 | pauseable = service.pause() |
---|
658 | if pauseable is None: |
---|
659 | self.setPlayingStatus(self.PLAY_STATE_PLAYING) |
---|
660 | return |
---|
661 | if pauseable is not None: |
---|
662 | if wantstate == self.PLAY_STATE_PAUSED: |
---|
663 | pauseable.pause() |
---|
664 | self.setPlayingStatus(self.PLAY_STATE_PAUSED) |
---|
665 | elif wantstate == self.PLAY_STATE_PLAYING: |
---|
666 | pauseable.unpause() |
---|
667 | self.setPlayingStatus(self.PLAY_STATE_PLAYING) |
---|
668 | |
---|
669 | def KeyReceived(self, key): |
---|
670 | if '2300' in key: |
---|
671 | if self.globalHelper.redButton: |
---|
672 | self.browserinstance.setPosition(720, 576, 0, 720, 0, 576) |
---|
673 | self.session.open(MessageBox, _('Leaving HBBTV Web Browser'), MessageBox.TYPE_INFO, timeout=2, simple=True) |
---|
674 | self.exitPluginWaitTimer.stop() |
---|
675 | self.close() |
---|
676 | return |
---|
677 | else: |
---|
678 | self.keyMenu() |
---|
679 | return |
---|
680 | elif '2200' in key: |
---|
681 | if not self.globalHelper.redButton: |
---|
682 | self.keyMenu() |
---|
683 | return |
---|
684 | else: |
---|
685 | if '2505' in key: |
---|
686 | self.session.open(MessageBox, _('Error HTTP Response'), MessageBox.TYPE_INFO, timeout=2, simple=True) |
---|
687 | return |
---|
688 | if '2600' in key: |
---|
689 | self.isVOD = False |
---|
690 | self.isBroadcast = True |
---|
691 | if self.browserinstance.currentChannel == '': |
---|
692 | self.setBroadcastStatus(bcastState.BCAST_UNREALIZED) |
---|
693 | return 1 |
---|
694 | self.setBroadcastStatus(bcastState.BCAST_CONNECTING) |
---|
695 | service = eServiceReference(self.browserinstance.currentChannel) |
---|
696 | self.session.nav.playService(service) |
---|
697 | return |
---|
698 | if '2601' in key: |
---|
699 | self.isVOD = False |
---|
700 | self.isBroadcast = True |
---|
701 | if self.browserinstance.currentChannel == '': |
---|
702 | self.setBroadcastStatus(bcastState.BCAST_UNREALIZED) |
---|
703 | service = self.session.nav.getCurrentService() |
---|
704 | service.stop() |
---|
705 | return 1 |
---|
706 | self.setBroadcastStatus(bcastState.BCAST_CONNECTING) |
---|
707 | service = eServiceReference(self.browserinstance.currentChannel) |
---|
708 | self.session.nav.playService(service) |
---|
709 | return |
---|
710 | if '2602' in key: |
---|
711 | self.isVOD = False |
---|
712 | self.isBroadcast = True |
---|
713 | if self.browserinstance.currentChannel == '': |
---|
714 | service = self.session.nav.getCurrentService() |
---|
715 | self.setBrodcastStatus(bcastState.BCAST_UNREALIZED) |
---|
716 | service.stop() |
---|
717 | return 1 |
---|
718 | self.setBroadcastStatus(bcastState.BCAST_CONNECTING) |
---|
719 | service = eServiceReference(self.browserinstance.currentChannel) |
---|
720 | self.session.nav.playService(service) |
---|
721 | return |
---|
722 | if '2603' in key: |
---|
723 | self.isVOD = False |
---|
724 | self.isBroadcast = True |
---|
725 | if self.browserinstance.currentChannel != '': |
---|
726 | service = self.session.nav.getCurrentService() |
---|
727 | service.stop() |
---|
728 | self.setBroadcastStatus(bcastState.BCAST_STOPPED) |
---|
729 | return |
---|
730 | if '2606' in key: |
---|
731 | self.isBroadcast = True |
---|
732 | if self.browserinstance.currentChannel != '': |
---|
733 | service = self.session.nav.getCurrentService() |
---|
734 | service.stop() |
---|
735 | self.setBroadcastStatus(bcastState.BCAST_UNREALIZED) |
---|
736 | return |
---|
737 | if '4100' in key: |
---|
738 | self.globalHelper.browserStartState = 1 |
---|
739 | elif '4200' in key: |
---|
740 | self.globalHelper.browserStartState = -1 |
---|
741 | if self.isPlaying is False: |
---|
742 | if '1006' in key: |
---|
743 | self.setPlayingStatus(self.PLAY_STATE_STOPPED) |
---|
744 | self.session.nav.stopService() |
---|
745 | elif '1010' in key: |
---|
746 | self.requestSpeed = True |
---|
747 | speed = self.browserinstance.speed |
---|
748 | if self.state == self.PLAY_STATE_FINISHED: |
---|
749 | if speed == 1: |
---|
750 | self.mediaPlay() |
---|
751 | else: |
---|
752 | if '1006' in key: |
---|
753 | self.setPlayingStatus(self.PLAY_STATE_STOPPED) |
---|
754 | self.session.nav.stopService() |
---|
755 | self.session.nav.playService(self.lastservice) |
---|
756 | return |
---|
757 | if '1007' in key: |
---|
758 | if self.state != self.PLAY_STATE_PAUSED: |
---|
759 | service = self.session.nav.getCurrentService() |
---|
760 | pausable = service.pause() |
---|
761 | if pausable is None: |
---|
762 | return |
---|
763 | pausable.pause() |
---|
764 | self.setPlayingStatus(self.PLAY_STATE_PAUSED) |
---|
765 | elif '1008' in key: |
---|
766 | if self.state == self.PLAY_STATE_PAUSED: |
---|
767 | service = self.session.nav.getCurrentService() |
---|
768 | pausable = service.pause() |
---|
769 | if pausable is not None: |
---|
770 | pausable.unpause() |
---|
771 | self.setPlayingStatus(self.PLAY_STATE_PLAYING) |
---|
772 | self.updateInfo() |
---|
773 | elif '1009' in key: |
---|
774 | if self.browserinstance.skipValue > 0: |
---|
775 | self.doSkip(self.browserinstance.skipValue) |
---|
776 | elif '1010' in key: |
---|
777 | self.requestSpeed = True |
---|
778 | speed = self.browserinstance.speed |
---|
779 | if speed is None: |
---|
780 | self.speed = -1 |
---|
781 | return |
---|
782 | service = self.session.nav.getCurrentService() |
---|
783 | if service is None: |
---|
784 | self.speed = -1 |
---|
785 | return |
---|
786 | if not self.getSeek(): |
---|
787 | self.speed = -1 |
---|
788 | return |
---|
789 | pauseable = service.pause() |
---|
790 | if pauseable is None: |
---|
791 | self.speed = -1 |
---|
792 | return |
---|
793 | if speed == 0: |
---|
794 | if self.playPosition < 1: |
---|
795 | pass |
---|
796 | else: |
---|
797 | pauseable.pause() |
---|
798 | self.setPlayingStatus(self.PLAY_STATE_PAUSED) |
---|
799 | elif speed == 100: |
---|
800 | if self.playPosition < 1: |
---|
801 | pass |
---|
802 | else: |
---|
803 | pauseable.unpause() |
---|
804 | self.setPlayingStatus(self.PLAY_STATE_PLAYING) |
---|
805 | elif speed < 0: |
---|
806 | self.speed = -1 |
---|
807 | elif speed > 0: |
---|
808 | if self.playPosition < 1: |
---|
809 | pass |
---|
810 | elif speed < 100: |
---|
811 | pauseable.setSlowMotion(speed / 10) |
---|
812 | else: |
---|
813 | pauseable.setFastForward(speed / 100) |
---|
814 | self.updateInfo() |
---|
815 | |
---|
816 | def mediaUrlChanged(self, mediatype, url): |
---|
817 | if self.isPlaying is True: |
---|
818 | if self.mediaurl.lower() == url.lower(): |
---|
819 | return |
---|
820 | self.session.nav.stopService() |
---|
821 | self.youtubemedia = False |
---|
822 | self.isVOD = True |
---|
823 | self.mediaurl = url |
---|
824 | self.rtmp = False |
---|
825 | self.xrtmp = False |
---|
826 | if mediatype is 'youtube': |
---|
827 | self.service = eServiceReference(4097, 0, self.mediaurl) |
---|
828 | self.mediaPlay() |
---|
829 | self.youtubemedia = True |
---|
830 | elif mediatype is 'mp4': |
---|
831 | req = urllib2.Request(url) |
---|
832 | req.add_header('User-Agent', user_agent) |
---|
833 | req.add_header('Accept', accept) |
---|
834 | req.add_header('Keep-Alive', keepalive) |
---|
835 | finalurl = '' |
---|
836 | try: |
---|
837 | response = urllib2.urlopen(req) |
---|
838 | finalurl = response.geturl() |
---|
839 | except urllib2.HTTPError as e: |
---|
840 | if e.code == '403': |
---|
841 | return |
---|
842 | except urllib2.URLError as e: |
---|
843 | pass |
---|
844 | |
---|
845 | if finalurl != '': |
---|
846 | self.service = eServiceReference(4097, 0, finalurl) |
---|
847 | else: |
---|
848 | self.service = eServiceReference(4097, 0, url) |
---|
849 | self.mediaPlay() |
---|
850 | elif mediatype is 'mov': |
---|
851 | self.service = eServiceReference(4097, 0, url) |
---|
852 | self.mediaPlay() |
---|
853 | elif mediatype is 'ts': |
---|
854 | self.service = eServiceReference(4097, 0, url) |
---|
855 | self.mediaPlay() |
---|
856 | elif mediatype is 'grtmp': |
---|
857 | self.getVideoUrl(url, 4) |
---|
858 | elif mediatype is 'mms': |
---|
859 | self.getVideoUrl(url, 4) |
---|
860 | elif mediatype is 'rtmp': |
---|
861 | self.rtmp = True |
---|
862 | self.tmpurl = url.split('\n')[0] |
---|
863 | self.session.nav.stopService() |
---|
864 | self.prepareFifos() |
---|
865 | self.browserinstance.startRtmp() |
---|
866 | self.rtmpTimer.start(2000) |
---|
867 | elif mediatype is 'xrtmp': |
---|
868 | self.xrtmp = True |
---|
869 | self.tmpurl = url.split('\n')[0] |
---|
870 | self.session.nav.stopService() |
---|
871 | self.prepareFifos() |
---|
872 | if self.kbs is not 0 or self.preload is not 0: |
---|
873 | self.browserinstance.setXrtmpParams(self.kbs, self.preload) |
---|
874 | self.rtmpTimer.start(10) |
---|
875 | elif mediatype is 'playlist': |
---|
876 | self.session.openWithCallback(self.mediaControlCallback, mediaPlaylist, self.browserinstance, url) |
---|
877 | elif mediatype is 'php': |
---|
878 | self.service = eServiceReference(4097, 0, url) |
---|
879 | self.mediaPlay() |
---|
880 | else: |
---|
881 | req = urllib2.Request(url) |
---|
882 | req.add_header('User-Agent', user_agent) |
---|
883 | req.add_header('Accept', accept) |
---|
884 | req.add_header('Connection', connection) |
---|
885 | req.add_header('Referer', referer) |
---|
886 | req.add_header('Keep-Alive', keepalive) |
---|
887 | finalurl = '' |
---|
888 | try: |
---|
889 | response = urllib2.urlopen(req) |
---|
890 | finalurl = response.geturl() |
---|
891 | except urllib2.HTTPError as e: |
---|
892 | if e.code == '403': |
---|
893 | return |
---|
894 | except urllib2.URLError as e: |
---|
895 | pass |
---|
896 | |
---|
897 | if finalurl != '': |
---|
898 | self.service = eServiceReference(4097, 0, finalurl) |
---|
899 | else: |
---|
900 | self.service = eServiceReference(4097, 0, url) |
---|
901 | self.mediaPlay() |
---|
902 | |
---|
903 | def cleanUpScreen(self, retval): |
---|
904 | if retval != '': |
---|
905 | if retval == 'exit': |
---|
906 | self.exit() |
---|
907 | return |
---|
908 | self.browserinstance.showBrowser() |
---|
909 | |
---|
910 | def keyboardCallback(self, callback = None): |
---|
911 | if callback is not None and len(callback): |
---|
912 | self.browserinstance.showSendUrl(callback.strip()) |
---|
913 | else: |
---|
914 | self.browserinstance.showBrowser() |
---|
915 | |
---|
916 | def showSubtitle(self): |
---|
917 | service = self.session.nav.getCurrentService() |
---|
918 | subtitle = service and service.subtitle() |
---|
919 | subtitlelist = subtitle and subtitle.getSubtitleList() |
---|
920 | if subtitlelist and len(subtitlelist) > 0: |
---|
921 | from Screens.AudioSelection import SubtitleSelection |
---|
922 | self.session.open(SubtitleSelection, self) |
---|
923 | |
---|
924 | def showTeletext(self): |
---|
925 | for p in plugins.getPlugins(PluginDescriptor.WHERE_TELETEXT): |
---|
926 | p(session=self.session, service=self.session.nav.getCurrentService()) |
---|
927 | |
---|
928 | def showAudioSelection(self): |
---|
929 | from Screens.AudioSelection import AudioSelection |
---|
930 | self.session.openWithCallback(self.audioSelected, AudioSelection, infobar=self) |
---|
931 | |
---|
932 | def audioSelected(self, ret = None): |
---|
933 | pass |
---|
934 | |
---|
935 | def volumeup(self): |
---|
936 | if VolumeControl.instance: |
---|
937 | VolumeControl.instance.volUp() |
---|
938 | |
---|
939 | def volumedown(self): |
---|
940 | if VolumeControl.instance: |
---|
941 | VolumeControl.instance.volDown() |
---|
942 | |
---|
943 | def volumemute(self): |
---|
944 | if VolumeControl.instance: |
---|
945 | VolumeControl.instance.volMute(True, True) |
---|
946 | |
---|
947 | def keyRecord(self): |
---|
948 | self.globalHelper.sendKeyToBrowser(61526) |
---|
949 | |
---|
950 | def keyStop(self): |
---|
951 | self.globalHelper.sendKeyToBrowser(61522) |
---|
952 | |
---|
953 | def keyPlay(self): |
---|
954 | self.globalHelper.sendKeyToBrowser(61521) |
---|
955 | |
---|
956 | def keyPause(self): |
---|
957 | self.globalHelper.sendKeyToBrowser(61450) |
---|
958 | |
---|
959 | def keyBack(self): |
---|
960 | self.globalHelper.sendKeyToBrowser(8) |
---|
961 | |
---|
962 | def unPauseService(self): |
---|
963 | self.globalHelper.sendKeyToBrowser(61521) |
---|
964 | |
---|
965 | def keyFF(self): |
---|
966 | if self.globalHelper.redButton: |
---|
967 | self.globalHelper.sendKeyToBrowser(61530) |
---|
968 | elif self.state == self.PLAY_STATE_STOPPED: |
---|
969 | self.history_forward() |
---|
970 | else: |
---|
971 | self.globalHelper.sendKeyToBrowser(61530) |
---|
972 | |
---|
973 | def keyRF(self): |
---|
974 | if self.globalHelper.redButton: |
---|
975 | self.globalHelper.sendKeyToBrowser(61529) |
---|
976 | elif self.state == self.PLAY_STATE_STOPPED: |
---|
977 | self.history_back() |
---|
978 | else: |
---|
979 | self.globalHelper.sendKeyToBrowser(61529) |
---|
980 | |
---|
981 | def keyRed(self): |
---|
982 | self.globalHelper.sendKeyToBrowser(61506) |
---|
983 | |
---|
984 | def keyGreen(self): |
---|
985 | self.globalHelper.sendKeyToBrowser(61507) |
---|
986 | |
---|
987 | def keyYellow(self): |
---|
988 | self.globalHelper.sendKeyToBrowser(61508) |
---|
989 | |
---|
990 | def keyBlue(self): |
---|
991 | self.globalHelper.sendKeyToBrowser(61509) |
---|
992 | |
---|
993 | def go(self): |
---|
994 | self.globalHelper.sendKeyToBrowser(61451) |
---|
995 | |
---|
996 | def exit(self): |
---|
997 | self.globalHelper.loadBrowserRemoteControl = False |
---|
998 | self.browserinstance.currentUrl = '' |
---|
999 | self.globalHelper.sendKeyToBrowser(61538) |
---|
1000 | self.browserinstance.start() |
---|
1001 | self.close(self.session) |
---|
1002 | |
---|
1003 | def up(self): |
---|
1004 | self.globalHelper.sendKeyToBrowser(61442) |
---|
1005 | |
---|
1006 | def down(self): |
---|
1007 | self.globalHelper.sendKeyToBrowser(61443) |
---|
1008 | |
---|
1009 | def left(self): |
---|
1010 | self.globalHelper.sendKeyToBrowser(61440) |
---|
1011 | |
---|
1012 | def right(self): |
---|
1013 | self.globalHelper.sendKeyToBrowser(61441) |
---|
1014 | |
---|
1015 | def programUp(self): |
---|
1016 | self.globalHelper.sendKeyToBrowser(61510) |
---|
1017 | |
---|
1018 | def programDown(self): |
---|
1019 | self.globalHelper.sendKeyToBrowser(61511) |
---|
1020 | |
---|
1021 | def pageUp(self): |
---|
1022 | self.globalHelper.sendKeyToBrowser(61447) |
---|
1023 | |
---|
1024 | def pageDown(self): |
---|
1025 | self.globalHelper.sendKeyToBrowser(61448) |
---|
1026 | |
---|
1027 | def jumpBackward(self): |
---|
1028 | if self.globalHelper.redButton: |
---|
1029 | self.globalHelper.sendKeyToBrowser(61531) |
---|
1030 | elif self.state == self.PLAY_STATE_STOPPED: |
---|
1031 | self.globalHelper.sendKeyToBrowser(61531) |
---|
1032 | else: |
---|
1033 | self.globalHelper.sendKeyToBrowser(61531) |
---|
1034 | |
---|
1035 | def jumpForward(self): |
---|
1036 | if self.globalHelper.redButton: |
---|
1037 | self.globalHelper.sendKeyToBrowser(61532) |
---|
1038 | elif self.state == self.PLAY_STATE_STOPPED: |
---|
1039 | self.globalHelper.sendKeyToBrowser(61532) |
---|
1040 | else: |
---|
1041 | self.globalHelper.sendKeyToBrowser(61532) |
---|
1042 | |
---|
1043 | def keyNumberGlobal(self, number): |
---|
1044 | if number == 0: |
---|
1045 | self.globalHelper.sendKeyToBrowser(48) |
---|
1046 | if number == 1: |
---|
1047 | self.globalHelper.sendKeyToBrowser(49) |
---|
1048 | if number == 2: |
---|
1049 | self.globalHelper.sendKeyToBrowser(50) |
---|
1050 | if number == 3: |
---|
1051 | self.globalHelper.sendKeyToBrowser(51) |
---|
1052 | if number == 4: |
---|
1053 | self.globalHelper.sendKeyToBrowser(52) |
---|
1054 | if number == 5: |
---|
1055 | self.globalHelper.sendKeyToBrowser(53) |
---|
1056 | if number == 6: |
---|
1057 | self.globalHelper.sendKeyToBrowser(54) |
---|
1058 | if number == 7: |
---|
1059 | self.globalHelper.sendKeyToBrowser(55) |
---|
1060 | if number == 8: |
---|
1061 | self.globalHelper.sendKeyToBrowser(56) |
---|
1062 | if number == 9: |
---|
1063 | self.globalHelper.sendKeyToBrowser(57) |
---|
1064 | |
---|
1065 | def keyMenu(self): |
---|
1066 | self.globalHelper.sendKeyToBrowser(61458) |
---|
1067 | time.sleep(1) |
---|
1068 | self.exitLeavesPlugin = False |
---|
1069 | self.mediaControlCallback() |
---|
1070 | if self.youtubemedia: |
---|
1071 | self.globalHelper.sendKeyToBrowser(8) |
---|
1072 | time.sleep(1) |
---|
1073 | if self.globalHelper.redButton: |
---|
1074 | return |
---|
1075 | self.browserinstance.hideBrowser() |
---|
1076 | self.menu_screen = self.session.openWithCallback(self.menuCallback, browserControlMenu, self.globalHelper) |
---|
1077 | |
---|
1078 | def keyCancel(self): |
---|
1079 | if self.globalHelper.redButton: |
---|
1080 | self.exit() |
---|
1081 | else: |
---|
1082 | self.keyMenu() |
---|
1083 | |
---|
1084 | def menuCallback(self, retval = ''): |
---|
1085 | if retval != '': |
---|
1086 | if retval == 'exit': |
---|
1087 | self.exit() |
---|
1088 | |
---|
1089 | def keyTextInput(self): |
---|
1090 | if config.plugins.settings.usevirtualkeyboard.value: |
---|
1091 | self.session.openWithCallback(self.keyboardCallbackText, VirtualKeyBoard, title=_('Enter TEXT'), text='') |
---|
1092 | else: |
---|
1093 | self.session.openWithCallback(self.keyboardCallbackText, InputBox, windowTitle=_('Enter text'), title=_('Text to edit:'), text='') |
---|
1094 | |
---|
1095 | def keyboardCallbackText(self, callback = None): |
---|
1096 | if callback is not None and len(callback): |
---|
1097 | self.browserinstance.sendTextInput(callback) |
---|
1098 | else: |
---|
1099 | self.browserinstance.showBrowser() |
---|
1100 | |
---|
1101 | def history_back(self): |
---|
1102 | if self.browserinstance and self.browserinstance.is_browser_running(): |
---|
1103 | self.browserinstance.pageBack() |
---|
1104 | |
---|
1105 | def history_forward(self): |
---|
1106 | if self.browserinstance and self.browserinstance.is_browser_running(): |
---|
1107 | self.browserinstance.pageForward() |
---|
1108 | |
---|
1109 | def refresh(self): |
---|
1110 | if self.browserinstance and self.browserinstance.is_browser_running(): |
---|
1111 | self.browserinstance.reloadPage() |
---|
1112 | |
---|
1113 | def showHelp(self): |
---|
1114 | self.session.open(HelpScreen, 'P+/P-\tnormal mode:\tpage up/down\n\tmouse mode:\tscroll up/down\n<\tsend backspace\n>\tsend delete\nMENU/EXIT\tenter menu\nVKEY\tenter text\nINFO\trefresh page\nTEXT\tshow page name\n<<\thistory back\n>>\thistory forward\nPLAY/PAUSE\tplay media buffered\nRECORD\tdownload file instead of playing\n\nWhen using an external keyboard you can use:\n\nF1\tenter menu\nF2\trefresh page\nF3\thistory back\nF4\thistory forward\nF5\tred button\nF6\tgreen button\nF7\tyellow button\nF8\tblue button\n\nup/down/left/right keys:\n\tnormal:\tscroll page\n\tshift:\tselect links\n\nenter:\tselect link\n\nctrl + enter\tplay media\nshift + enter:\topen link in new screen\n\nctrl + up:\tswitch tabbed screens\nctrl + down:\ttoggle selected tab show/hide\nctrl + right:\thide all screens\nctrl + left:\tshow screens\nctrl + \\:\tkill top screen') |
---|
1115 | |
---|
1116 | |
---|
1117 | G_MAIN_MENU = [('HOME', 'home'), |
---|
1118 | ('BACK', 'back'), |
---|
1119 | ('FORWARD', 'forward'), |
---|
1120 | ('REFERESH', 'refresh'), |
---|
1121 | ('MENU', 'mainMenu', (('Enter URL', 'enterurl', (('Use virtual keyboard', 'enterurlvkey'), ('Use SMS style', 'enterurlsms'))), ('Edit Bookmark', 'editbookmark', (('To web bookmarks', 'editweb'), ('To private bookmarks', 'editprivate'))), ('Set Startpage', 'setstartpage'))), |
---|
1122 | ('BOOKMARK', 'bookmarks', (('Web bookmarks', 'bookmarksweb'), ('Private bookmarks', 'bookmarksprivate'))), |
---|
1123 | ('HELP', 'help', (('Information', 'information'),)), |
---|
1124 | ('EXIT', 'exit')] |
---|
1125 | G_MAIN_V_OFFSET = 10 |
---|
1126 | G_MAIN_V_SIZE = 0 |
---|
1127 | G_MAIN_H_SIZE = 0 |
---|
1128 | G_SUB_H_SIZE = 55 |
---|
1129 | G_TOPBAR_V_SIZE = 55 |
---|
1130 | G_MAIN_BOTTOM_OFFSET = 0 |
---|
1131 | G_STATUSTEXT_TOP_OFFSET = 65 |
---|
1132 | G_STATUSTEXT_V_SIZE = 100 |
---|
1133 | G_ROW_SIZE_HD = 150 |
---|
1134 | G_FONT_SIZE_HD = 17 |
---|
1135 | G_MENU_WIDTH_HD = 215 |
---|
1136 | G_SKIN_COMMON_HD = '\t\t<ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/OpenOpera/images/home.png" position="65,20" size="100,46" alphatest="on" />' |
---|
1137 | G_SKIN_COMMON_HD += '<ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/OpenOpera/images/back.png" position="215,20" size="100,46" alphatest="on" />' |
---|
1138 | G_SKIN_COMMON_HD += '<ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/OpenOpera/images/forward.png" position="365,20" size="100,46" alphatest="on" />' |
---|
1139 | G_SKIN_COMMON_HD += '<ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/OpenOpera/images/refresh.png" position="515,20" size="100,46" alphatest="on" />' |
---|
1140 | G_SKIN_COMMON_HD += '<ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/OpenOpera/images/menu.png" position="665,20" size="100,46" alphatest="on" />' |
---|
1141 | G_SKIN_COMMON_HD += '<ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/OpenOpera/images/bookmark.png" position="815,20" size="100,46" alphatest="on" />' |
---|
1142 | G_SKIN_COMMON_HD += '<ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/OpenOpera/images/help.png" position="965,20" size="100,46" alphatest="on" />' |
---|
1143 | G_SKIN_COMMON_HD += '<ePixmap pixmap="/usr/lib/enigma2/python/Plugins/Extensions/OpenOpera/images/exit.png" position="1115,20" size="100,46" alphatest="on" />' |
---|
1144 | G_SKIN_COMMON_HD += '<widget name="info0" position="40,15" size="150,' + str(G_TOPBAR_V_SIZE) + '" halign="center" valign="bottom" font="Regular;18" backgroundColors="#A2A4AA,#EDED0A" foregroundColors="#FFFFFF,#FFFF00" />' |
---|
1145 | G_SKIN_COMMON_HD += '\t\t<widget name="info1" position="190,15" size="150,' + str(G_TOPBAR_V_SIZE) + '" halign="center" valign="bottom" font="Regular;18" backgroundColors="#A2A4AA,#EDED0A" foregroundColors="#FFFFFF,#FFFF00" />' |
---|
1146 | G_SKIN_COMMON_HD += '\t\t<widget name="info2" position="340,15" size="150,' + str(G_TOPBAR_V_SIZE) + '" halign="center" valign="bottom" font="Regular;18" backgroundColors="#A2A4AA,#EDED0A" foregroundColors="#FFFFFF,#FFFF00" />' |
---|
1147 | G_SKIN_COMMON_HD += '\t\t<widget name="info3" position="490,15" size="150,' + str(G_TOPBAR_V_SIZE) + '" halign="center" valign="bottom" font="Regular;18" backgroundColors="#A2A4AA,#EDED0A" foregroundColors="#FFFFFF,#FFFF00" />' |
---|
1148 | G_SKIN_COMMON_HD += '\t\t<widget name="info4" position="640,15" size="150,' + str(G_TOPBAR_V_SIZE) + '" halign="center" valign="bottom" font="Regular;18" backgroundColors="#A2A4AA,#EDED0A" foregroundColors="#FFFFFF,#FFFF00" />' |
---|
1149 | G_SKIN_COMMON_HD += '\t\t<widget name="info5" position="790,15" size="150,' + str(G_TOPBAR_V_SIZE) + '" halign="center" valign="bottom" font="Regular;18" backgroundColors="#A2A4AA,#EDED0A" foregroundColors="#FFFFFF,#FFFF00" />' |
---|
1150 | G_SKIN_COMMON_HD += '\t\t<widget name="info6" position="940,15" size="150,' + str(G_TOPBAR_V_SIZE) + '" halign="center" valign="bottom" font="Regular;18" backgroundColors="#A2A4AA,#EDED0A" foregroundColors="#FFFFFF,#FFFF00" />' |
---|
1151 | G_SKIN_COMMON_HD += '\t\t<widget name="info7" position="1090,15" size="150,' + str(G_TOPBAR_V_SIZE) + '" halign="center" valign="bottom" font="Regular;18" backgroundColors="#A2A4AA,#EDED0A" foregroundColors="#FFFFFF,#FFFF00" /> \t\t' |
---|
1152 | |
---|
1153 | class browserControlMenuHelper(): |
---|
1154 | |
---|
1155 | def __init__(self): |
---|
1156 | pass |
---|
1157 | |
---|
1158 | def buildMenuMain(self, list): |
---|
1159 | for x in G_MAIN_MENU: |
---|
1160 | list.append((x[0], x[1])) |
---|
1161 | |
---|
1162 | def buildMenuLevelOne(self, list, option): |
---|
1163 | for x in G_MAIN_MENU: |
---|
1164 | if option == x[1]: |
---|
1165 | for y in x[2]: |
---|
1166 | list.append((' ' + y[0], y[1], len(y))) |
---|
1167 | |
---|
1168 | return True |
---|
1169 | |
---|
1170 | return False |
---|
1171 | |
---|
1172 | def buildMenuLevelTwo(self, list, option, suboption): |
---|
1173 | for x in G_MAIN_MENU: |
---|
1174 | if option == x[1]: |
---|
1175 | for y in x[2]: |
---|
1176 | for z in x[2]: |
---|
1177 | if suboption == z[1]: |
---|
1178 | for zz in z[2]: |
---|
1179 | list.append((' ' + zz[0], zz[1])) |
---|
1180 | |
---|
1181 | return True |
---|
1182 | |
---|
1183 | return False |
---|
1184 | |
---|
1185 | def set_menu(self, index, m1, m2, m3, m4, m5, m6, m7, m8): |
---|
1186 | m1.setForegroundColorNum(1) |
---|
1187 | m2.setForegroundColorNum(1) |
---|
1188 | m3.setForegroundColorNum(1) |
---|
1189 | m4.setForegroundColorNum(1) |
---|
1190 | m5.setForegroundColorNum(1) |
---|
1191 | m6.setForegroundColorNum(1) |
---|
1192 | m7.setForegroundColorNum(1) |
---|
1193 | m8.setForegroundColorNum(1) |
---|
1194 | m1.setBackgroundColorNum(1) |
---|
1195 | m2.setBackgroundColorNum(1) |
---|
1196 | m3.setBackgroundColorNum(1) |
---|
1197 | m4.setBackgroundColorNum(1) |
---|
1198 | m5.setBackgroundColorNum(1) |
---|
1199 | m6.setBackgroundColorNum(1) |
---|
1200 | m7.setBackgroundColorNum(1) |
---|
1201 | m8.setBackgroundColorNum(1) |
---|
1202 | m1.setForegroundColorNum(0) |
---|
1203 | m2.setForegroundColorNum(0) |
---|
1204 | m3.setForegroundColorNum(0) |
---|
1205 | m4.setForegroundColorNum(0) |
---|
1206 | m5.setForegroundColorNum(0) |
---|
1207 | m6.setForegroundColorNum(0) |
---|
1208 | m7.setForegroundColorNum(0) |
---|
1209 | m8.setForegroundColorNum(0) |
---|
1210 | m1.setBackgroundColorNum(0) |
---|
1211 | m2.setBackgroundColorNum(0) |
---|
1212 | m3.setBackgroundColorNum(0) |
---|
1213 | m4.setBackgroundColorNum(0) |
---|
1214 | m5.setBackgroundColorNum(0) |
---|
1215 | m6.setBackgroundColorNum(0) |
---|
1216 | m7.setBackgroundColorNum(0) |
---|
1217 | m8.setBackgroundColorNum(0) |
---|
1218 | if index == 0: |
---|
1219 | m1.setForegroundColorNum(1) |
---|
1220 | m1.setBackgroundColorNum(1) |
---|
1221 | elif index == 1: |
---|
1222 | m2.setForegroundColorNum(1) |
---|
1223 | m2.setBackgroundColorNum(1) |
---|
1224 | elif index == 2: |
---|
1225 | m3.setForegroundColorNum(1) |
---|
1226 | m3.setBackgroundColorNum(1) |
---|
1227 | elif index == 3: |
---|
1228 | m4.setForegroundColorNum(1) |
---|
1229 | m4.setBackgroundColorNum(1) |
---|
1230 | elif index == 4: |
---|
1231 | m5.setForegroundColorNum(1) |
---|
1232 | m5.setBackgroundColorNum(1) |
---|
1233 | elif index == 5: |
---|
1234 | m6.setForegroundColorNum(1) |
---|
1235 | m6.setBackgroundColorNum(1) |
---|
1236 | elif index == 6: |
---|
1237 | m7.setForegroundColorNum(1) |
---|
1238 | m7.setBackgroundColorNum(1) |
---|
1239 | elif index == 7: |
---|
1240 | m8.setForegroundColorNum(1) |
---|
1241 | m8.setBackgroundColorNum(1) |
---|
1242 | |
---|
1243 | |
---|
1244 | class browserControlMenuLevelTwo(Screen): |
---|
1245 | |
---|
1246 | def __init__(self, session, option, infocus, index, helper): |
---|
1247 | self.session = session |
---|
1248 | self.helper = helper |
---|
1249 | self.mmenu = [] |
---|
1250 | self.helper.buildMenuMain(self.mmenu) |
---|
1251 | self.mmenu1 = [] |
---|
1252 | helper.buildMenuLevelOne(self.mmenu1, option[0]) |
---|
1253 | self.mmenu2 = [] |
---|
1254 | self.helper.buildMenuLevelTwo(self.mmenu2, option[0], option[1]) |
---|
1255 | skin_v = len(self.mmenu1) * 25 + 15 |
---|
1256 | skin_v2 = len(self.mmenu2) * 25 + 15 |
---|
1257 | hide_l = 0 |
---|
1258 | hide_r = 0 |
---|
1259 | if skin_v2 > skin_v: |
---|
1260 | hide_l = skin_v2 - skin_v |
---|
1261 | max_v = skin_v2 |
---|
1262 | else: |
---|
1263 | max_v = skin_v |
---|
1264 | hide_r = skin_v - skin_v2 |
---|
1265 | row_size = G_ROW_SIZE_HD |
---|
1266 | font_size = G_FONT_SIZE_HD |
---|
1267 | menu_width = G_MENU_WIDTH_HD |
---|
1268 | h_offset = 70 / 2 + index * row_size + 25 |
---|
1269 | skin = '<screen position="0,0" size="1280,720" title="" flags="wfNoBorder" backgroundColor="transparent" >' |
---|
1270 | skin += G_SKIN_COMMON_HD |
---|
1271 | skin += '<widget name="blankL" position="0,70" size="' + str(h_offset) + ',720" backgroundColor="transparent" zPosition="1"/>' |
---|
1272 | skin += '\t\t\t<widget name="menu" position="' + str(h_offset) + ',70" size="215,' + str(max_v) + '" scrollbarMode="showOnDemand" font="Regular;' + str(font_size) + '" foregroundColor="#848484" foregroundColorSelected="#848484" backgroundColorSelected="#151515"/>' |
---|
1273 | skin += '\t\t\t<widget name="blankML" position="' + str(h_offset) + ',' + str(skin_v + G_TOPBAR_V_SIZE) + '" size="' + str(menu_width) + ',e-' + str(skin_v + G_MAIN_BOTTOM_OFFSET) + '" backgroundColor="transparent" zPosition="1"/>' |
---|
1274 | skin += '\t\t\t<widget name="menu2" position="' + str(h_offset + menu_width) + ',' + str(G_TOPBAR_V_SIZE + 15) + '" size="' + str(menu_width) + ',' + str(max_v) + '" scrollbarMode="showOnDemand" font="Regular;' + str(font_size) + '"/>' |
---|
1275 | skin += '\t\t\t<widget name="blankMR" position="' + str(h_offset + menu_width) + ',' + str(skin_v2 + G_TOPBAR_V_SIZE) + '" size="' + str(menu_width) + ',e-' + str(skin_v2 + G_MAIN_BOTTOM_OFFSET) + '" backgroundColor="transparent" zPosition="1"/>' |
---|
1276 | skin += '\t\t\t<widget name="blankR" position="' + str(h_offset + 2 * menu_width) + ',' + str(G_TOPBAR_V_SIZE + 15) + '" size="e-' + str(h_offset + 2 * menu_width) + ',e-' + str(G_MAIN_BOTTOM_OFFSET) + '" backgroundColor="transparent" zPosition="1"/>' |
---|
1277 | skin += '\t\t</screen>' |
---|
1278 | self.skin = skin |
---|
1279 | Screen.__init__(self, session) |
---|
1280 | for x in range(8): |
---|
1281 | self['info' + str(x)] = MultiColorLabel() |
---|
1282 | self['info' + str(x)].setText(' ') |
---|
1283 | |
---|
1284 | self.index = index |
---|
1285 | self['blankL'] = Label('') |
---|
1286 | self['blankML'] = Label('') |
---|
1287 | self['blankMR'] = Label('') |
---|
1288 | self['blankR'] = Label('') |
---|
1289 | self['menu'] = MenuList(self.mmenu1, enableWrapAround=False) |
---|
1290 | self['menu2'] = MenuList(self.mmenu2, enableWrapAround=False) |
---|
1291 | self.inFocus = infocus |
---|
1292 | self.option = option |
---|
1293 | self.onLayoutFinish.append(self.layoutFinished) |
---|
1294 | self['actions'] = ActionMap(['WizardActions', 'DirectionActions'], {'ok': self.go, |
---|
1295 | 'left': self.keyLeft, |
---|
1296 | 'right': self.keyRight, |
---|
1297 | 'up': self.keyUp, |
---|
1298 | 'down': self.keyDown}, -1) |
---|
1299 | self['WebBrowserActions'] = ActionMap(['WebBrowserActions'], {'exit_l': self.keyExitLong, |
---|
1300 | 'exit_s': self.keyExit}, -1) |
---|
1301 | |
---|
1302 | def layoutFinished(self): |
---|
1303 | self['menu'].moveToIndex(self.inFocus) |
---|
1304 | self.set_menu() |
---|
1305 | |
---|
1306 | def set_menu(self): |
---|
1307 | self.helper.set_menu(self.index, self['info0'], self['info1'], self['info2'], self['info3'], self['info4'], self['info5'], self['info6'], self['info7']) |
---|
1308 | |
---|
1309 | def keyLeft(self): |
---|
1310 | self.close('') |
---|
1311 | |
---|
1312 | def keyRight(self): |
---|
1313 | self.close('moveright') |
---|
1314 | |
---|
1315 | def keyUp(self): |
---|
1316 | self['menu2'].up() |
---|
1317 | |
---|
1318 | def keyDown(self): |
---|
1319 | self['menu2'].down() |
---|
1320 | |
---|
1321 | def go(self): |
---|
1322 | selection = self['menu2'].l.getCurrentSelection() |
---|
1323 | if selection is not None: |
---|
1324 | self.close(self.close(selection[1])) |
---|
1325 | |
---|
1326 | def keyExit(self): |
---|
1327 | self.close('close') |
---|
1328 | |
---|
1329 | def keyExitLong(self): |
---|
1330 | self.session.open(MessageBox, _('Leaving webbrowser'), MessageBox.TYPE_INFO, timeout=2, simple=True) |
---|
1331 | self.close('exit') |
---|
1332 | |
---|
1333 | |
---|
1334 | class browserControlMenuLevelOne(Screen): |
---|
1335 | |
---|
1336 | def __init__(self, session, option, index, helper): |
---|
1337 | self.session = session |
---|
1338 | self.helper = helper |
---|
1339 | self.mmenu = [] |
---|
1340 | self.helper.buildMenuMain(self.mmenu) |
---|
1341 | self.mmenu2 = [] |
---|
1342 | self.helper.buildMenuLevelOne(self.mmenu2, option[1]) |
---|
1343 | row_size = G_ROW_SIZE_HD |
---|
1344 | font_size = G_FONT_SIZE_HD |
---|
1345 | menu_width = G_MENU_WIDTH_HD |
---|
1346 | h_offset = 70 / 2 + index * row_size + 25 |
---|
1347 | skin_v = len(self.mmenu2) * 25 + 15 |
---|
1348 | skin = '<screen position="0,0" size="1280,720" title="" flags="wfNoBorder" backgroundColor="transparent" >' |
---|
1349 | skin += G_SKIN_COMMON_HD |
---|
1350 | skin += '<widget name="blankL" position="0,70" size="' + str(h_offset) + ',720" backgroundColor="transparent" zPosition="1"/>' |
---|
1351 | skin += '\t\t\t<widget name="menu" position="' + str(h_offset) + ',70" size="215,' + str(skin_v) + '" scrollbarMode="showOnDemand" font="Regular;' + str(font_size) + '" />' |
---|
1352 | skin += '\t\t\t<widget name="blankMB" position="' + str(h_offset) + ',' + str(skin_v + G_TOPBAR_V_SIZE) + '" size="' + str(menu_width) + ',e-' + str(skin_v + G_MAIN_BOTTOM_OFFSET) + '" backgroundColor="transparent" zPosition="1"/>' |
---|
1353 | skin += '\t\t\t<widget name="blankR" position="' + str(h_offset + menu_width) + ',' + str(G_TOPBAR_V_SIZE + 15) + '" size="e-' + str(h_offset + menu_width) + ',e-' + str(G_MAIN_BOTTOM_OFFSET) + '" backgroundColor="transparent" zPosition="1"/>' |
---|
1354 | skin += '\t\t</screen>' |
---|
1355 | self.skin = skin |
---|
1356 | Screen.__init__(self, session) |
---|
1357 | for x in range(8): |
---|
1358 | self['info' + str(x)] = MultiColorLabel() |
---|
1359 | self['info' + str(x)].setText(' ') |
---|
1360 | |
---|
1361 | self.index = index |
---|
1362 | self['blankL'] = Label('') |
---|
1363 | self['blankMB'] = Label('') |
---|
1364 | self['blankR'] = Label('') |
---|
1365 | self['menu'] = MenuList(self.mmenu2, enableWrapAround=False) |
---|
1366 | self.option = option |
---|
1367 | self.onLayoutFinish.append(self.layoutFinished) |
---|
1368 | self['actions'] = ActionMap(['WizardActions', 'DirectionActions'], {'ok': self.go, |
---|
1369 | 'left': self.keyLeft, |
---|
1370 | 'right': self.keyRight, |
---|
1371 | 'up': self.keyUp, |
---|
1372 | 'down': self.keyDown}, -1) |
---|
1373 | self['WebBrowserActions'] = ActionMap(['WebBrowserActions'], {'exit_l': self.keyExitLong, |
---|
1374 | 'exit_s': self.keyExit}, -1) |
---|
1375 | |
---|
1376 | def layoutFinished(self): |
---|
1377 | self.setTitle(self.option[0]) |
---|
1378 | self.set_menu() |
---|
1379 | |
---|
1380 | def set_menu(self): |
---|
1381 | self.helper.set_menu(self.index, self['info0'], self['info1'], self['info2'], self['info3'], self['info4'], self['info5'], self['info6'], self['info7']) |
---|
1382 | |
---|
1383 | def keyLeft(self): |
---|
1384 | self.close('moveleft') |
---|
1385 | |
---|
1386 | def keyRight(self): |
---|
1387 | self.close('moveright') |
---|
1388 | |
---|
1389 | def keyUp(self): |
---|
1390 | if self['menu'].getSelectionIndex() == 0: |
---|
1391 | self['menu'].moveToIndex(len(self.mmenu2) - 1) |
---|
1392 | else: |
---|
1393 | self['menu'].up() |
---|
1394 | |
---|
1395 | def keyDown(self): |
---|
1396 | if self['menu'].getSelectionIndex() == len(self.mmenu2) - 1: |
---|
1397 | self['menu'].moveToIndex(0) |
---|
1398 | else: |
---|
1399 | self['menu'].down() |
---|
1400 | |
---|
1401 | def go(self): |
---|
1402 | selection = self['menu'].l.getCurrentSelection() |
---|
1403 | if selection is not None: |
---|
1404 | if selection[2] == 2: |
---|
1405 | self.close(selection[1]) |
---|
1406 | else: |
---|
1407 | self.session.openWithCallback(self.menuCallback, browserControlMenuLevelTwo, (self.option[1], selection[1]), self['menu'].getSelectionIndex(), self.index, self.helper) |
---|
1408 | |
---|
1409 | def keyExit(self): |
---|
1410 | self.close('close') |
---|
1411 | |
---|
1412 | def keyExitLong(self): |
---|
1413 | self.session.open(MessageBox, _('Leaving webbrowser'), MessageBox.TYPE_INFO, timeout=2, simple=True) |
---|
1414 | self.close('exit') |
---|
1415 | |
---|
1416 | def menuCallback(self, retval): |
---|
1417 | if retval: |
---|
1418 | self.close(retval) |
---|
1419 | |
---|
1420 | |
---|
1421 | class browserControlMenu(Screen): |
---|
1422 | |
---|
1423 | def __init__(self, session, globalHelper): |
---|
1424 | self.helper = browserControlMenuHelper() |
---|
1425 | skin = '<screen position="0,0" size="1280,720" title="" flags="wfNoBorder" backgroundColor="transparent">' |
---|
1426 | skin += G_SKIN_COMMON_HD |
---|
1427 | skin += '<widget name="blankMID" position="0,70" size="e-0,e-' + str(G_MAIN_BOTTOM_OFFSET) + '" backgroundColor="transparent" zPosition="1"/>' |
---|
1428 | skin += '\t\t\t</screen>' |
---|
1429 | self.skin = skin |
---|
1430 | Screen.__init__(self, session) |
---|
1431 | self.globalHelper = globalHelper |
---|
1432 | self.mmenu = [] |
---|
1433 | self.helper.buildMenuMain(self.mmenu) |
---|
1434 | for x in range(8): |
---|
1435 | self['info' + str(x)] = MultiColorLabel() |
---|
1436 | self['info' + str(x)].setText(' ') |
---|
1437 | |
---|
1438 | self.index = 0 |
---|
1439 | self.onLayoutFinish.append(self.layoutFinished) |
---|
1440 | self['blankMID'] = Label('') |
---|
1441 | self.restartTimer = eTimer() |
---|
1442 | self.restartTimer.callback.append(self.restartCallback) |
---|
1443 | self.openHomepage = False |
---|
1444 | self['actions'] = ActionMap(['WizardActions', |
---|
1445 | 'DirectionActions', |
---|
1446 | 'PiPSetupActions', |
---|
1447 | 'MovieSelectionActions', |
---|
1448 | 'HelpActions'], {'ok': self.go, |
---|
1449 | 'contextMenu': self.keyMenu, |
---|
1450 | 'left': self.keyLeft, |
---|
1451 | 'right': self.keyRight, |
---|
1452 | 'up': self.keyUp, |
---|
1453 | 'down': self.keyDown, |
---|
1454 | 'size+': self.bigger, |
---|
1455 | 'size-': self.smaller, |
---|
1456 | 'displayHelp': self.showHelp}, -1) |
---|
1457 | self['WebBrowserActions'] = ActionMap(['WebBrowserActions'], {'exit_l': self.keyExitLong, |
---|
1458 | 'exit_s': self.keyExit}, -1) |
---|
1459 | |
---|
1460 | def layoutFinished(self): |
---|
1461 | self.set_menu() |
---|
1462 | |
---|
1463 | def keyRight(self): |
---|
1464 | if self.index < 7: |
---|
1465 | self.index += 1 |
---|
1466 | else: |
---|
1467 | self.index = 0 |
---|
1468 | self.set_menu() |
---|
1469 | |
---|
1470 | def keyLeft(self): |
---|
1471 | if self.index > 0: |
---|
1472 | self.index -= 1 |
---|
1473 | else: |
---|
1474 | self.index = 7 |
---|
1475 | self.set_menu() |
---|
1476 | |
---|
1477 | def set_menu(self): |
---|
1478 | browserinstance.hideBrowser() |
---|
1479 | self.helper.set_menu(self.index, self['info0'], self['info1'], self['info2'], self['info3'], self['info4'], self['info5'], self['info6'], self['info7']) |
---|
1480 | |
---|
1481 | def keyUp(self): |
---|
1482 | selection = self.mmenu[self.index] |
---|
1483 | if selection is not None: |
---|
1484 | if self.index > 3 and self.index < 7: |
---|
1485 | self.session.openWithCallback(self.menuCallback, browserControlMenuLevelOne, self.mmenu[self.index], self.index, self.helper) |
---|
1486 | |
---|
1487 | def keyDown(self): |
---|
1488 | selection = self.mmenu[self.index] |
---|
1489 | if selection is not None: |
---|
1490 | if self.index > 3 and self.index < 7: |
---|
1491 | self.session.openWithCallback(self.menuCallback, browserControlMenuLevelOne, self.mmenu[self.index], self.index, self.helper) |
---|
1492 | |
---|
1493 | def go(self): |
---|
1494 | selection = self.mmenu[self.index] |
---|
1495 | if selection is not None: |
---|
1496 | if self.index > 3 and self.index < 7: |
---|
1497 | self.session.openWithCallback(self.menuCallback, browserControlMenuLevelOne, self.mmenu[self.index], self.index, self.helper) |
---|
1498 | else: |
---|
1499 | self.menuCallback(selection[1]) |
---|
1500 | |
---|
1501 | def keyMenu(self): |
---|
1502 | if browserinstance and browserinstance.is_browser_running() is True and browserinstance.currentUrl: |
---|
1503 | browserinstance.showBrowser() |
---|
1504 | self.exitScreen() |
---|
1505 | |
---|
1506 | def keyExit(self): |
---|
1507 | if browserinstance and browserinstance.is_browser_running() is True and browserinstance.currentUrl: |
---|
1508 | browserinstance.showBrowser() |
---|
1509 | self.exitScreen() |
---|
1510 | |
---|
1511 | def keyExitLong(self): |
---|
1512 | self.session.open(MessageBox, _('Leaving webbrowser'), MessageBox.TYPE_INFO, timeout=2, simple=True) |
---|
1513 | browserinstance.fbClassUnlock() |
---|
1514 | self.close('exit') |
---|
1515 | |
---|
1516 | def menuCallback(self, retval): |
---|
1517 | if retval: |
---|
1518 | if retval == 'exit': |
---|
1519 | browserinstance.fbClassUnlock() |
---|
1520 | self.close(retval) |
---|
1521 | else: |
---|
1522 | if retval == 'moveright': |
---|
1523 | self.keyRight() |
---|
1524 | if self.index > 3 and self.index < 7: |
---|
1525 | self.session.openWithCallback(self.menuCallback, browserControlMenuLevelOne, self.mmenu[self.index], self.index, self.helper) |
---|
1526 | return |
---|
1527 | if retval == 'moveleft': |
---|
1528 | self.keyLeft() |
---|
1529 | if self.index > 3 and self.index < 7: |
---|
1530 | self.session.openWithCallback(self.menuCallback, browserControlMenuLevelOne, self.mmenu[self.index], self.index, self.helper) |
---|
1531 | return |
---|
1532 | if retval == 'close': |
---|
1533 | self.exitScreen() |
---|
1534 | elif retval == 'home': |
---|
1535 | self.goStartPage() |
---|
1536 | elif retval == 'refresh': |
---|
1537 | self.refresh() |
---|
1538 | elif retval == 'back': |
---|
1539 | self.history_back() |
---|
1540 | elif retval == 'forward': |
---|
1541 | self.history_forward() |
---|
1542 | elif retval == 'enterurlvkey': |
---|
1543 | self.session.openWithCallback(self.keyboardCallback, VirtualKeyBoard, title=_('Enter URL'), text='') |
---|
1544 | elif retval == 'enterurlsms': |
---|
1545 | self.session.openWithCallback(self.keyboardCallback, InputBox, windowTitle=_('Enter URL'), title=_('Text to edit:'), text='') |
---|
1546 | elif retval == 'setstartpage': |
---|
1547 | self.setStartPage() |
---|
1548 | elif retval == 'bookmarksweb': |
---|
1549 | self.openBookmarks('web') |
---|
1550 | elif retval == 'bookmarksprivate': |
---|
1551 | self.openBookmarks('private') |
---|
1552 | elif retval == 'editweb': |
---|
1553 | self.openBookmarksEditor('web') |
---|
1554 | elif retval == 'editprivate': |
---|
1555 | self.openBookmarksEditor('private') |
---|
1556 | elif retval == 'addtoweb': |
---|
1557 | self.openBookmarksAddCurrent('web') |
---|
1558 | elif retval == 'addtoprivate': |
---|
1559 | self.openBookmarksAddCurrent('private') |
---|
1560 | elif retval == 'information': |
---|
1561 | self.openHelpInformation() |
---|
1562 | |
---|
1563 | def moveCallback(self): |
---|
1564 | configfile.save() |
---|
1565 | |
---|
1566 | def keyboardCallbackText(self, callback = None): |
---|
1567 | if callback is not None and len(callback): |
---|
1568 | browserinstance.sendTextInput(callback) |
---|
1569 | else: |
---|
1570 | browserinstance.showBrowser() |
---|
1571 | self.exitScreen() |
---|
1572 | |
---|
1573 | def keyboardCallback(self, callback = None): |
---|
1574 | if callback is not None and len(callback): |
---|
1575 | browserinstance.showSendUrl(callback.strip()) |
---|
1576 | elif browserinstance and browserinstance.is_browser_running() and browserinstance.currentUrl: |
---|
1577 | browserinstance.showBrowser() |
---|
1578 | self.exitScreen() |
---|
1579 | |
---|
1580 | def restartCallback(self): |
---|
1581 | self.restartTimer.stop() |
---|
1582 | if self.openHomepage: |
---|
1583 | self.openHomepage = False |
---|
1584 | self.goStartPage() |
---|
1585 | return |
---|
1586 | self.globalHelper.initializeBrowser() |
---|
1587 | if config.plugins.settings.hasstartpage.value: |
---|
1588 | self.openHomepage = True |
---|
1589 | self.restartTimer.start(3000) |
---|
1590 | return |
---|
1591 | self.exitScreen() |
---|
1592 | |
---|
1593 | def callbackResetBookmarks(self, answer): |
---|
1594 | answer = answer and answer[1] |
---|
1595 | if answer == 'clear': |
---|
1596 | copyfile(Browser.path + 'bookmarks_web.cfg', G_CONFIG_LOCATION + 'bookmarks_web.cfg') |
---|
1597 | copyfile(Browser.path + 'bookmarks_private.cfg', G_CONFIG_LOCATION + 'bookmarks_private.cfg') |
---|
1598 | |
---|
1599 | def exitScreen(self): |
---|
1600 | self.close('') |
---|
1601 | |
---|
1602 | def setStartPage(self): |
---|
1603 | if browserinstance.currentUrl is not None: |
---|
1604 | config.plugins.settings.hasstartpage.value = True |
---|
1605 | config.plugins.settings.hasstartpage.save() |
---|
1606 | config.plugins.settings.startpage.value = browserinstance.currentUrl |
---|
1607 | config.plugins.settings.startpage.save() |
---|
1608 | configfile.save() |
---|
1609 | self.globalHelper.writeStartPage(config.plugins.settings.startpage.value) |
---|
1610 | self.exitScreen() |
---|
1611 | |
---|
1612 | def goStartPage(self): |
---|
1613 | if browserinstance and browserinstance.is_browser_running(): |
---|
1614 | self.globalHelper.openStartPage() |
---|
1615 | self.exitScreen() |
---|
1616 | |
---|
1617 | def history_back(self): |
---|
1618 | if browserinstance and browserinstance.is_browser_running() and browserinstance.currentUrl and eval(browserinstance.history_count)['back'] > 0: |
---|
1619 | browserinstance.pageBack() |
---|
1620 | self.exitScreen() |
---|
1621 | |
---|
1622 | def history_forward(self): |
---|
1623 | if browserinstance and browserinstance.is_browser_running() and browserinstance.currentUrl and eval(browserinstance.history_count)['fwd'] > 0: |
---|
1624 | browserinstance.pageForward() |
---|
1625 | self.exitScreen() |
---|
1626 | |
---|
1627 | def refresh(self): |
---|
1628 | if browserinstance and browserinstance.is_browser_running() and browserinstance.currentUrl: |
---|
1629 | browserinstance.reloadPage() |
---|
1630 | self.exitScreen() |
---|
1631 | |
---|
1632 | def bigger(self): |
---|
1633 | browserinstance.zoomIn() |
---|
1634 | |
---|
1635 | def smaller(self): |
---|
1636 | browserinstance.zoomOut() |
---|
1637 | |
---|
1638 | def openBookmarks(self, value): |
---|
1639 | self.session.open(BookmarkMenu, browserinstance, config.ParentalControl, G_CONFIG_LOCATION, value) |
---|
1640 | self.exitScreen() |
---|
1641 | |
---|
1642 | def openBookmarksEditor(self, value): |
---|
1643 | self.session.openWithCallback(self.bookmarkEditCallback, BookmarkEdit, config.ParentalControl, browserinstance, G_CONFIG_LOCATION, value) |
---|
1644 | self.exitScreen() |
---|
1645 | |
---|
1646 | def openBookmarksAddCurrent(self, value): |
---|
1647 | self.session.openWithCallback(self.bookmarkEditCallback, BookmarkEdit, config.ParentalControl, browserinstance, G_CONFIG_LOCATION, value, True) |
---|
1648 | self.exitScreen() |
---|
1649 | |
---|
1650 | def bookmarkEditCallback(self, result = None): |
---|
1651 | if browserinstance and browserinstance.is_browser_running() and browserinstance.currentUrl: |
---|
1652 | browserinstance.showBrowser() |
---|
1653 | self.exitScreen() |
---|
1654 | |
---|
1655 | def openHelpInformation(self): |
---|
1656 | msg = 'OpenOpera HbbTV Browser Plugin\n\nVersion ' + plugin_version |
---|
1657 | self.session.open(MessageBox, _(msg), type=MessageBox.TYPE_INFO) |
---|
1658 | |
---|
1659 | def abortDownload(self): |
---|
1660 | downloadinstance.abortDownload() |
---|
1661 | |
---|
1662 | def windowClose(self): |
---|
1663 | browserinstance.closeScreen() |
---|
1664 | |
---|
1665 | def windowTabUp(self): |
---|
1666 | browserinstance.tabUp() |
---|
1667 | |
---|
1668 | def changeTempFileLocation(self): |
---|
1669 | self.session.openWithCallback(self.gotFilename, MovieLocationBox, _('Please select the temporary file path'), config.plugins.settings.tempstore.value) |
---|
1670 | |
---|
1671 | def gotFilename(self, res, selItem = None): |
---|
1672 | if not res: |
---|
1673 | return |
---|
1674 | config.plugins.settings.tempstore.value = res |
---|
1675 | config.plugins.settings.tempstore.save() |
---|
1676 | |
---|
1677 | def showHelp(self): |
---|
1678 | self.session.open(HelpScreen, 'MENU/EXIT\topen close menu\nUP/DOWN/P+/P-\tzoom in/out') |
---|
1679 | |
---|
1680 | |
---|
1681 | class HBBTVParser(Screen): |
---|
1682 | |
---|
1683 | def __init__(self, session): |
---|
1684 | Screen.__init__(self, session) |
---|
1685 | self.session = session |
---|
1686 | self.started = False |
---|
1687 | from Components.ServiceEventTracker import ServiceEventTracker |
---|
1688 | self.__event_tracker = ServiceEventTracker(screen=self, eventmap={iPlayableService.evStart: self.serviceStarted}) |
---|
1689 | self.openUrl = False |
---|
1690 | self.startBrowserTimer = eTimer() |
---|
1691 | self.startBrowserTimer.callback.append(self.startBrowserTimerCallback) |
---|
1692 | |
---|
1693 | def serviceStarted(self): |
---|
1694 | if self.started: |
---|
1695 | return |
---|
1696 | if InfoBar.instance: |
---|
1697 | InfoBar.instance.onHBBTVActivation.append(self.onHBBTVActivation) |
---|
1698 | self.started = True |
---|
1699 | |
---|
1700 | def onHBBTVActivation(self): |
---|
1701 | global browserinstance |
---|
1702 | if globalinstance.loadBrowserRemoteControl is False: |
---|
1703 | self.session.open(BrowserRemoteControl, True, False) |
---|
1704 | globalinstance.loadBrowserRemoteControl = True |
---|
1705 | if not browserinstance: |
---|
1706 | browserinstance = Browser() |
---|
1707 | if browserinstance.is_browser_running() is False: |
---|
1708 | browserinstance.start() |
---|
1709 | self.startBrowserTimer.start(250) |
---|
1710 | return |
---|
1711 | service = self.session.nav.getCurrentService() |
---|
1712 | info = service and service.info() |
---|
1713 | startUrl = info.getInfoString(iServiceInformation.sHBBTVUrl) |
---|
1714 | if 'launchpad' in startUrl: |
---|
1715 | return |
---|
1716 | self.openUrl = browserinstance.showSendUrl(startUrl.strip(), 1) |
---|
1717 | if not self.openUrl: |
---|
1718 | self.close() |
---|
1719 | return |
---|
1720 | |
---|
1721 | def startBrowserTimerCallback(self): |
---|
1722 | if fileExists('/tmp/.sock.url'): |
---|
1723 | if globalinstance.browserStartState == -1: |
---|
1724 | self.startBrowserTimer.stop() |
---|
1725 | self.close() |
---|
1726 | return |
---|
1727 | if globalinstance.browserStartState == 1: |
---|
1728 | self.startBrowserTimer.stop() |
---|
1729 | self.onHBBTVActivation() |
---|
1730 | else: |
---|
1731 | globalinstance.sendKeyToBrowser(61538) |
---|
1732 | browserinstance.start() |
---|
1733 | |
---|
1734 | |
---|
1735 | def main(session, **kwargs): |
---|
1736 | session.open(BrowserRemoteControl, False, True) |
---|
1737 | if browserinstance.is_browser_running() is False: |
---|
1738 | browserinstance.start() |
---|
1739 | |
---|
1740 | |
---|
1741 | def autostart(reason, **kwargs): |
---|
1742 | global globalinstance |
---|
1743 | if 'session' in kwargs: |
---|
1744 | if not globalinstance: |
---|
1745 | globalinstance = BrowserGlobalHelper() |
---|
1746 | HBBTVParser(kwargs['session']) |
---|
1747 | |
---|
1748 | |
---|
1749 | def Plugins(**kwargs): |
---|
1750 | menus = [] |
---|
1751 | menus.append(PluginDescriptor(where=[PluginDescriptor.WHERE_SESSIONSTART], fnc=autostart)) |
---|
1752 | menus.append(PluginDescriptor(name='OpenOpera HBBTV', description='OpenOpera HBBTV on Web Browser Plugin', where=PluginDescriptor.WHERE_EXTENSIONSMENU, icon='', fnc=main)) |
---|
1753 | menus.append(PluginDescriptor(name='OpenOpera HBBTV', description='OpenOpera HBBTV on Web Browser Plugin', where=PluginDescriptor.WHERE_PLUGINMENU, icon='', fnc=main)) |
---|
1754 | return menus |
---|