movieepg: don't crash if InfoBar.instance is None
[enigma2-plugins.git] / movieepg / src / plugin.py
1 # Plugin definition
2 from Plugins.Plugin import PluginDescriptor
3
4 from Components.PluginComponent import plugins
5 from Tools.BoundFunction import boundFunction
6 from Screens.InfoBarGenerics import InfoBarPlugins, InfoBarMoviePlayerSummarySupport, InfoBarChannelSelection
7 from Screens.ChannelSelection import ChannelSelection
8 from Screens.InfoBar import InfoBar, MoviePlayer
9 from Screens.MessageBox import MessageBox
10 from Components.config import config, ConfigSubsection, ConfigSelection, ConfigYesNo
11 import inspect
12
13 config.plugins.movieepg = ConfigSubsection()
14 config.plugins.movieepg.show_epg_entry = ConfigSelection(choices=[
15                 ("never", _("Never")),
16                 ("movie", _("Movie Player")),
17                 ("always", _("always")),
18         ], default = "movie"
19 )
20 config.plugins.movieepg.show_servicelist_plugins_in_movieplayer = ConfigYesNo(default = True)
21
22 MODE_OFF = False
23 MODE_ON = True
24 MODE_MOVIEPLAYER = 2
25
26 # This plugin consists of 4 "steps" which serve their own purpose and if combined allow access to both the service list and plugins requiring the service list from within the movie player.
27 # Each of these steps are enclosed in their own sections and their purpose is explained.
28
29 # Step 1: change way used to determine if plugins requiring service list should be shown
30 # Base implementation uses isinstance(self, InfoBarChannelSelection) which we do not want (to implement) for various reasons.
31 # Instead we we check for the instance variable "servicelist".
32 #
33 # Additionally, we inject our "fake" plugin only if the (original?) movie player is running.
34 #
35 # Doing so should not affect behavior if plugin is disabled, though we still overwrite these functions to make things easier to manage internally.
36 def InfoBarPlugins_getPluginList(self, *args, **kwargs):
37         l = []
38         showSlistPlugins = (config.plugins.movieepg.show_servicelist_plugins_in_movieplayer.value and hasattr(self, 'servicelist')) or isinstance(self, InfoBarChannelSelection)
39         for p in plugins.getPlugins(where = PluginDescriptor.WHERE_EXTENSIONSMENU):
40                 args = inspect.getargspec(p.__call__)[0]
41                 if len(args) == 1 or len(args) == 2 and showSlistPlugins:
42                         l.append(((boundFunction(self.getPluginName, p.name), boundFunction(self.runPlugin, p), lambda: True), None, p.name))
43
44         # add fake plugin if show_epg_entry set to "always" or "movie" and this is the movie player
45         show_epg_entry = config.plugins.movieepg.show_epg_entry.value
46         if show_epg_entry == "always" or show_epg_entry == "movie" and isinstance(self, InfoBarMoviePlayerSummarySupport):
47                 l.append(((boundFunction(self.getPluginName, "EPG"), boundFunction(self.runPlugin, entry), lambda: True), None, "EPG"))
48
49         l.sort(key = lambda e: e[2]) # sort by name
50         return l
51 def InfoBarPlugins_runPlugin(self, plugin, *args, **kwargs):
52         if hasattr(self, 'servicelist'):
53                 plugin(session = self.session, servicelist = self.servicelist)
54         else:
55                 plugin(session = self.session)
56 InfoBarPlugins.getPluginList = InfoBarPlugins_getPluginList
57 InfoBarPlugins.runPlugin = InfoBarPlugins_runPlugin
58
59 # Step 2: Overwrite some ChannelSelection code to be able to interject channel selection
60 #
61 # Doing so should not affect behavior if plugin is disabled, though we still overwrite these functions to make things easier to manage internally.
62 def ChannelSelection_close(self, *args, **kwargs):
63         if hasattr(self, 'secretMovieMode') and self.secretMovieMode != MODE_MOVIEPLAYER:
64                 # handles "plugin" close
65                 self.secretMovieMode = MODE_OFF
66         baseChannelSelection_close(self, *args, **kwargs)
67 baseChannelSelection_close = ChannelSelection.close
68 ChannelSelection.close = ChannelSelection_close
69
70 def ChannelSelection_zap(self, *args, **kwargs):
71         if hasattr(self, 'secretMovieMode') and self.secretMovieMode:
72                 if movieEpgMoviePlayerInstance is not None:
73                         movieEpgMoviePlayerInstance.lastservice = self.getCurrentSelection()
74                         movieEpgMoviePlayerInstance.leavePlayer()
75                 return
76         baseChannelSelection_zap(self, *args, **kwargs)
77 baseChannelSelection_zap = ChannelSelection.zap
78 ChannelSelection.zap = ChannelSelection_zap
79
80 # Step 3: Plugin which allows access to service list from extension menu (and possibly later on from plugin menu)
81 # Absolutely no effect on its own.
82 def entry(session = None, servicelist = None):
83         # XXX: session.current_dialog is the movie player (or infobar if ran from "regular" extension menu)
84         if not session: return
85         if not servicelist:
86                 if InfoBar.instance:
87                         servicelist = InfoBar.instance.servicelist
88                 else:
89                         session.open(MessageBox, _("Unable to access InfoBar!\nEPG not available."), MessageBox.TYPE_ERROR)
90                         return
91
92         if hasattr(servicelist, 'secretMovieMode') and servicelist.secretMovieMode != MODE_MOVIEPLAYER:
93                 servicelist.secretMovieMode = MODE_ON
94         session.execDialog(servicelist)
95
96 # Step 4: Modify standard movie player to keep a reference to the service list (taken from the info bar)
97 # We also save a reference to the movie list here which we use to provide the "standard" close dialog when trying to zap
98 #
99 # Basically no effect on its own.
100 movieEpgMoviePlayerInstance = None
101 def MoviePlayer___init__(self, *args, **kwargs):
102         baseMoviePlayer___init__(self, *args, **kwargs)
103         if InfoBar.instance:
104                 self.servicelist = InfoBar.instance.servicelist
105                 self.servicelist.secretMovieMode = MODE_MOVIEPLAYER
106         global movieEpgMoviePlayerInstance
107         movieEpgMoviePlayerInstance = self
108 baseMoviePlayer___init__ = MoviePlayer.__init__
109 MoviePlayer.__init__ = MoviePlayer___init__
110
111 def MoviePlayer_close(self, *args, **kwargs):
112         global movieEpgMoviePlayerInstance
113         movieEpgMoviePlayerInstance = None
114         self.servicelist.secretMovieMode = MODE_OFF
115         baseMoviePlayer_close(self, *args, **kwargs)
116 baseMoviePlayer_close = MoviePlayer.close
117 MoviePlayer.close = MoviePlayer_close
118
119 # Configuration
120 from MovieEpgSetup import MovieEpgSetup
121
122 def main(session):
123         session.open(MovieEpgSetup)
124
125 def Plugins(**kwargs):
126         return [
127                 PluginDescriptor(
128                         name="Movie-EPG",
129                         description=_("Configure Movie-EPG Plugin"),
130                         where=PluginDescriptor.WHERE_PLUGINMENU,
131                         fnc=main,
132                         needsRestart=True, # XXX: force restart for now as I don't think it will work properly without doing so
133                 ),
134         ]