Merge branch 'vuplus_experimental' of code.vuplus.com:/opt/repository/dvbapp into...
[vuplus_dvbapp] / lib / python / Plugins / Extensions / Vbrowser / plugin.py
1 from Plugins.Plugin import PluginDescriptor
2 from Screens.Screen import Screen
3 from Screens.InfoBar import InfoBar
4 from Screens.ChoiceBox import ChoiceBox
5 from Screens.HelpMenu import HelpableScreen
6 from Screens.MessageBox import MessageBox
7 from Screens.VirtualKeyBoard import VirtualKeyBoard
8 from Components.config import config
9 from Components.ActionMap import ActionMap
10 from Components.Language import language
11 from Components.ServiceEventTracker import ServiceEventTracker
12
13 from enigma import eTimer, fbClass, eRCInput, iServiceInformation, iPlayableService
14
15 import os, struct, vbcfg
16
17 from __init__ import _
18 from hbbtv import HbbTVWindow
19 from browser import Browser
20 from youtube import YoutubeTVWindow, YoutubeTVSettings
21 from vbipc import VBController, VBServerThread, VBHandlers
22
23 strIsEmpty = lambda x: x is None or len(x) == 0
24
25 vbcfg.SOCKETFILE = '/tmp/vbrowser.support'
26 vbcfg.CONTROLFILE = '/tmp/vbrowser.controller'
27 _OPCODE_LIST = [
28                 'CONTROL_BACK',
29                 'CONTROL_FORWARD',
30                 'CONTROL_STOP',
31                 'CONTROL_RELOAD',
32                 'CONTROL_OPENURL',
33                 'CONTROL_EXIT',
34                 'CONTROL_TITLE',
35                 'CONTROL_OK',
36                 'CONTROL_OUT_OF_MEMORY',
37                 'HBBTV_LOADAIT',
38                 'HBBTV_OPENURL',
39                 'YOUTUBETV_OPENURL',
40                 'BROWSER_OPENURL',
41                 'BROWSER_MENU_OPEN',
42                 'BROWSER_MENU_CLOSE',
43                 'BROWSER_VKB_OPEN',
44                 'BROWSER_VKB_CLOSE',
45                 'OOIF_GET_CURRENT_CHANNEL',
46                 'OOIF_GET_VOLUME',
47                 'OOIF_BROADCAST_PLAY',
48                 'OOIF_BROADCAST_STOP',
49                 'OOIF_BROADCAST_CHECK',
50                 'OPCODE_END'
51                 ]
52
53 class VBHandler(VBHandlers):
54         def __init__(self, session):
55                 self._session = session
56                 self.current_title = None
57                 self.videobackend_activate = False
58                 self.onSetTitleCB = []
59                 self.onCloseCB = []
60                 VBHandlers.__init__(self, _OPCODE_LIST, '_CB_')
61
62         def close_vkb(self, data=""):
63                 fbClass.getInstance().lock()
64                 eRCInput.getInstance().lock()
65
66                 if strIsEmpty(data):
67                         data = ""
68                 VBController.command("BROWSER_VKB_CLOSE", data)
69
70         def _CB_CONTROL_EXIT(self, result, packet):
71                 if self.onCloseCB:
72                         for x in self.onCloseCB:
73                                 try:
74                                         x()
75                                 except Exception:
76                                         if x in self.onCloseCB:
77                                                 self.onCloseCB.remove(x)
78                 if self.videobackend_activate is False:
79                         if vbcfg.g_service is not None:
80                                 self._session.nav.playService(vbcfg.g_service)
81                 return (True, None)
82
83         def _CB_CONTROL_TITLE(self, result, packet):
84                 if packet.startswith('file://') or packet.startswith('http://'):
85                         return (True, None)
86                 for x in self.onSetTitleCB:
87                         try:
88                                 x(packet)
89                                 self.current_title = packet
90                         except Exception:
91                                 if x in self.onSetTitleCB:
92                                         self.onSetTitleCB.remove(x)
93                 return (True, None)
94
95         def _CB_CONTROL_OK(self, result, packet):
96                 if vbcfg.g_browser and packet.startswith('stop'):
97                         vbcfg.g_browser.keyOK()
98                 return (True, None)
99
100         def _CB_CONTROL_OUT_OF_MEMORY(self, result, packet):
101                 vbcfg.need_restart = True;
102                 return (True, None)
103
104         def _CB_BROWSER_MENU_OPEN(self, result, packet):
105                 if vbcfg.g_browser and vbcfg.g_browser.is_browser_opened:
106                         vbcfg.setPosition(vbcfg.g_position)
107                         fbClass.getInstance().unlock()
108                         eRCInput.getInstance().unlock()
109
110                         vbcfg.g_browser.toggle_browser(packet, self.current_title)
111                 return (True, None)
112
113         def _CB_BROWSER_VKB_OPEN(self, result, packet):
114                 if vbcfg.g_browser and vbcfg.g_browser.is_browser_opened:
115                         vbcfg.setPosition(vbcfg.g_position)
116                         fbClass.getInstance().unlock()
117                         eRCInput.getInstance().unlock()
118
119                         if strIsEmpty(packet):
120                                 packet = ""
121                         self._session.openWithCallback(self.close_vkb, VirtualKeyBoard, title=("Please enter URL here"), text=str(packet))
122                 return (True, None)
123
124         def _CB_OOIF_GET_CURRENT_CHANNEL(self, result, packet):
125                 if (vbcfg.g_channel_info):
126                         try:
127                                 data = struct.pack('iiii', vbcfg.g_channel_info[1], vbcfg.g_channel_info[2], vbcfg.g_channel_info[0], len(vbcfg.g_channel_info[3])) + vbcfg.g_channel_info[3]
128                         except Exception, err:
129                                 vbcfg.ERR(err)
130                                 return (False, None)
131                 else:
132                         return (False, None)
133                 return (True, data)
134
135         def _CB_OOIF_BROADCAST_PLAY(self, result, packet):
136                 if vbcfg.g_service is not None:
137                         self._session.nav.playService(vbcfg.g_service)
138                 self.videobackend_activate = False
139                 return (True, None)
140
141         def _CB_OOIF_BROADCAST_STOP(self, result, packet):
142                 vbcfg.g_service = self._session.nav.getCurrentlyPlayingServiceReference()
143                 self._session.nav.stopService()
144                 self.videobackend_activate = True
145                 return (True, None)
146
147         def _CB_OOIF_BROADCAST_CHECK(self, result, packet):
148                 if self._session.nav.getCurrentService() is None:
149                         return (False, None)
150                 return (True, None)
151
152 class VBMain(Screen):
153         skin = """<screen name="VBMAIN" position="0,0" size="0,0" backgroundColor="transparent" flags="wfNoBorder" title=" "></screen>"""
154         def __init__(self, session):
155                 Screen.__init__(self, session)
156
157                 self.vbcallback = None
158                 self.vbhandler = VBHandler(session)
159                 self.vbserver = VBServerThread()
160                 self.vbserver.open(1)
161                 self.vbserver.start()
162
163                 # comment for dev
164                 self.restart_vbrowser()
165                 vbcfg.LOG("vbrowser start")
166
167                 self._timer_infobar = eTimer()
168                 self._timer_infobar.callback.append(self._cb_register_infobar)
169                 self._timer_infobar.start(1000)
170
171                 self._event = ServiceEventTracker(screen=self, eventmap={
172                                 iPlayableService.evHBBTVInfo: self._cb_ait_detected,
173                                 iPlayableService.evUpdatedInfo: self._cb_info_updated
174                         })
175                 self._applicationList = None
176                 self._app_info = None
177
178                 try:
179                         from Screens.InfoBarGenerics import gHbbtvApplication
180                         self.m_vuplus = gHbbtvApplication.getUseAit()
181                 except:
182                         self.m_vuplus = False
183
184         def _cb_register_infobar(self):
185                 if InfoBar.instance:
186                         self._timer_infobar.stop()
187                         if self._cb_hbbtv_activated not in InfoBar.instance.onHBBTVActivation:
188                                 InfoBar.instance.onHBBTVActivation.append(self._cb_hbbtv_activated)
189                 vbcfg.DEBUG("registred HbbTV in InfoBar")
190
191         def _cb_hbbtv_activated(self, url=None, app_info=None):
192                 if not self.check_vbrowser():
193                         message = _("HbbTV Browser was not running.\nPlease running browser before start HbbTV Application.")
194                         self.session.open(MessageBox, message, MessageBox.TYPE_INFO)
195                         return
196                 self.start_hbbtv_application(url, app_info)
197
198         def _cb_ait_detected(self):
199                 vbcfg.g_channel_info = None
200                 self._applicationList = None
201                 self._app_info = self.get_autostart_application()
202                 vbcfg.DEBUG("detected AIT")
203
204         def _cb_info_updated(self):
205                 vbcfg.g_service = self.session.nav.getCurrentlyPlayingServiceReference()
206                 vbcfg.DEBUG("updated channel info")
207
208         def start_hbbtv_application(self, url, app_info):
209                 if vbcfg.need_restart:
210                         self.restart_vbrowser()
211                         os.time.sleep(2)
212                         vbcfg.need_restart = False
213
214                 if not app_info:
215                         app_info = self._app_info
216                 self.session.open(HbbTVWindow, url, app_info)
217
218         def menu_toggle_vbrowser(self, callback=None):
219                 mode = []
220                 self.vbcallback = callback
221                 if self.check_vbrowser():
222                         mode.append((_('Stop'), 'Stop'))
223                 else:
224                         mode.append((_('Start'), 'Start'))
225                 self.session.openWithCallback(self.toggle_vbrowser, ChoiceBox, title=_("Please choose one."), list=mode)
226
227         def toggle_vbrowser(self, selected):
228                 if selected is not None:
229                         if self.vbcallback:
230                                 self.vbcallback()
231                         try:
232                                 mode = selected[1]
233                                 if mode == 'Start':
234                                         if not self.check_vbrowser():
235                                                 self.start_vbrowser()
236                                 elif mode == 'Stop':
237                                         self.stop_vbrowser()
238
239                         except Exception, ErrMsg:
240                                 vbcfg.ERR("toggle vbrowser: %s" % ErrMsg)
241
242         def menu_hbbtv_applications(self):
243                 applications = []
244                 if self._applicationList is not None:
245                         for x in self._applicationList:
246                                 applications.append((x["name"], x))
247                 else:
248                         applications.append((_("No detected HbbTV applications."), None))
249                 self.session.openWithCallback(self.start_application_selected, ChoiceBox, title=_("Please choose an HbbTV application."), list=applications)
250
251         def start_application_selected(self, selected):
252                 vbcfg.DEBUG(selected)
253                 try:
254                         if selected[1] is not None:
255                                 self._cb_hbbtv_activated(selected[1]["url"], selected[1])
256                 except Exception, ErrMsg:
257                         vbcfg.ERR(ErrMsg)
258
259         def get_autostart_application(self):
260                 if self._applicationList is None:
261                         service = self.session.nav.getCurrentService()
262                         info = service and service.info()
263                         if info is not None:
264                                 sid = info.getInfo(iServiceInformation.sSID)
265                                 onid = info.getInfo(iServiceInformation.sONID)
266                                 tsid = info.getInfo(iServiceInformation.sTSID)
267                                 name = info.getName()
268                                 vbcfg.g_channel_info = (sid, onid, tsid, name)
269
270                                 pmtid = info.getInfo(iServiceInformation.sPMTPID)
271                                 demux = info.getInfoString(iServiceInformation.sLiveStreamDemuxId)
272                                 vbcfg.DEBUG("demux = %s, pmtid = 0x%x, sid = 0x%x" % (demux, pmtid, sid))
273
274                                 from aitreader import eAITSectionReader
275                                 reader = eAITSectionReader(demux, pmtid, sid)
276                                 if reader.doOpen(info, self.m_vuplus):
277                                         reader.doParseApplications()
278                                         reader.doDump()
279                                 else:
280                                         vbcfg.ERR("no AIT")
281
282                                 try:
283                                         self._applicationList = reader.getApplicationList()
284                                 except:
285                                         pass
286
287                 if self._applicationList is not None:
288                         for app in self._applicationList:
289                                 if app["control"] in (1, -1):
290                                         return app
291                 return None
292
293         def start_vbrowser(self):
294                 if not self.check_vbrowser():
295                         os.system("%s/%s start"%(vbcfg.APPROOT, vbcfg.APP_RUN))
296                 return True
297
298         def stop_vbrowser(self):
299                 VBController.command('CONTROL_EXIT')
300                 return True
301                 try:
302                         os.system("%s/%s stop"%(vbcfg.APPROOT, vbcfg.APP_RUN))
303                 except:
304                         pass
305                 return True
306
307         def check_vbrowser(self):
308                 try:
309                         ret = os.popen('%s/%s check'%(vbcfg.APPROOT, vbcfg.APP_RUN)).read()
310                         return ret.strip() != "0"
311                 except Exception, ErrMsg:
312                         vbcfg.ERR("check vbrowser running: %s" % ErrMsg)
313                 return False
314
315         def restart_vbrowser(self):
316                 try:
317                         os.system("%s/%s restart"%(vbcfg.APPROOT, vbcfg.APP_RUN))
318                 except:
319                         pass
320                 return True
321
322 def HelpableScreen__init__(self):
323         if isinstance(self, HelpableScreen):
324                 HelpableScreen.showManual = showManual
325
326                 self["helpActions"] = ActionMap(["HelpbuttonActions"], {
327                         "help_b" : self.showHelp,
328                         "help_l" : self.showManual,
329                 }, -2)
330
331 def showManual(self):
332         if not os.path.exists(vbcfg.MANUALROOT):
333                 return
334
335         url = 'file://' + vbcfg.MANUALROOT + '/main.html'
336         lang = language.getLanguage()
337         if os.path.exists(vbcfg.MANUALROOT + '/' + lang):
338                 url = 'file://' + vbcfg.MANUALROOT + '/' + lang + '/main.html'
339
340         vbcfg.g_browser = self.session.open(Browser, url)
341
342 def auto_start_main(reason, **kwargs):
343         if reason:
344                 try:
345                         if vbcfg.g_main.vbserver is not None:
346                                 vbcfg.g_main.vbserver.kill()
347                 except: pass
348
349 def session_start_main(session, reason, **kwargs):
350         vbcfg.g_main = session.open(VBMain)
351         HelpableScreen.__init__ = HelpableScreen__init__
352         HelpableScreen.session = session
353
354 def start_youtubetv_main(session, **kwargs):
355         def _cb_youtubetv_close(ret):
356                 if ret:
357                         vbcfg.g_service = session.nav.getCurrentlyPlayingServiceReference()
358                         if vbcfg.g_service is not None:
359                                 session.nav.stopService()
360                         vbcfg.g_browser = session.open(Browser, vbcfg.g_youtubetv_cfg.uri.value, True)
361
362         if config.plugins.youtubetv.showhelp.value == True:
363                 _cb_youtubetv_close(True)
364         else:
365                 session.openWithCallback(_cb_youtubetv_close, YoutubeTVWindow)
366
367
368 def menu_start_youtube(menuid, **kwargs):
369         if menuid == "mainmenu":
370                 return [(_("YouTube TV"), start_youtubetv_main, "youtube_tv", 46)]
371         return []
372
373 def plugin_setting_youtube(session, **kwargs):
374         session.open(YoutubeTVSettings)
375
376 def plugin_start_browser(session, **kwargs):
377         vbcfg.g_browser = session.open(Browser)
378
379 def extension_toggle_browser(session, **kwargs):
380         if vbcfg.g_main is not None:
381                 vbcfg.g_main.menu_toggle_vbrowser()
382
383 def extension_start_application(session, **kwargs):
384         if vbcfg.g_main is not None:
385                 vbcfg.g_main.menu_hbbtv_applications()
386
387 def Plugins(**kwargs):
388         l = []
389         l.append(PluginDescriptor(where=PluginDescriptor.WHERE_AUTOSTART, fnc=auto_start_main))
390         l.append(PluginDescriptor(where=PluginDescriptor.WHERE_SESSIONSTART, needsRestart=True, fnc=session_start_main, weight=-10))
391         l.append(PluginDescriptor(name=_("YouTube TV"), where=PluginDescriptor.WHERE_MENU, fnc=menu_start_youtube))
392         l.append(PluginDescriptor(name=_("YouTube TV Settings"), where=PluginDescriptor.WHERE_PLUGINMENU, fnc=plugin_setting_youtube))
393         l.append(PluginDescriptor(name=_("Browser Start/Stop"), where=PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart=True, fnc=extension_toggle_browser))
394         l.append(PluginDescriptor(name=_("HbbTV Applications"), where=PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart=True, fnc=extension_start_application))
395         l.append(PluginDescriptor(name=_("Vuplus Web Browser"), description=_("start vuplus web browser"), where=PluginDescriptor.WHERE_PLUGINMENU, needsRestart=True, fnc=plugin_start_browser))
396         return l