2 from Plugins.Plugin import PluginDescriptor
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 from operator import attrgetter
14 config.plugins.movieepg = ConfigSubsection()
15 config.plugins.movieepg.show_epg_entry = ConfigSelection(choices=[
16 ("never", _("Never")),
17 ("movie", _("Movie Player")),
18 ("always", _("always")),
21 config.plugins.movieepg.show_servicelist_plugins_in_movieplayer = ConfigYesNo(default = True)
27 # 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.
28 # Each of these steps are enclosed in their own sections and their purpose is explained.
30 # Step 1: change way used to determine if plugins requiring service list should be shown
31 # Base implementation uses isinstance(self, InfoBarChannelSelection) which we do not want (to implement) for various reasons.
32 # Instead we we check for the instance variable "servicelist".
34 # Additionally, we inject our "fake" plugin only if the (original?) movie player is running.
36 # Doing so should not affect behavior if plugin is disabled, though we still overwrite these functions to make things easier to manage internally.
37 def InfoBarPlugins_getPluginList(self, *args, **kwargs):
39 showSlistPlugins = (config.plugins.movieepg.show_servicelist_plugins_in_movieplayer.value and hasattr(self, 'servicelist')) or isinstance(self, InfoBarChannelSelection)
40 for p in plugins.getPlugins(where = PluginDescriptor.WHERE_EXTENSIONSMENU):
41 args = inspect.getargspec(p.__call__)[0]
42 if len(args) == 1 or len(args) == 2 and showSlistPlugins:
44 l.sort(key=attrgetter('weight', 'name')) # sort first by weight, then by name
46 # "tranform" into weird internal format
47 l = [((boundFunction(self.getPluginName, p.name), boundFunction(self.runPlugin, p), lambda: True), None, p.name) for p in l]
49 # add fake plugin if show_epg_entry set to "always" or "movie" and this is the movie player
50 show_epg_entry = config.plugins.movieepg.show_epg_entry.value
51 if show_epg_entry == "always" or show_epg_entry == "movie" and isinstance(self, InfoBarMoviePlayerSummarySupport):
52 l.append(((boundFunction(self.getPluginName, "EPG"), boundFunction(self.runPlugin, entry), lambda: True), None, "EPG"))
55 def InfoBarPlugins_runPlugin(self, plugin, *args, **kwargs):
56 if hasattr(self, 'servicelist'):
57 plugin(session = self.session, servicelist = self.servicelist)
59 plugin(session = self.session)
60 InfoBarPlugins.getPluginList = InfoBarPlugins_getPluginList
61 InfoBarPlugins.runPlugin = InfoBarPlugins_runPlugin
63 # Step 2: Overwrite some ChannelSelection code to be able to interject channel selection
65 # Doing so should not affect behavior if plugin is disabled, though we still overwrite these functions to make things easier to manage internally.
66 def ChannelSelection_close(self, *args, **kwargs):
67 if hasattr(self, 'secretMovieMode') and self.secretMovieMode != MODE_MOVIEPLAYER:
68 # handles "plugin" close
69 self.secretMovieMode = MODE_OFF
70 baseChannelSelection_close(self, *args, **kwargs)
71 baseChannelSelection_close = ChannelSelection.close
72 ChannelSelection.close = ChannelSelection_close
74 def ChannelSelection_zap(self, *args, **kwargs):
75 if hasattr(self, 'secretMovieMode') and self.secretMovieMode:
76 if movieEpgMoviePlayerInstance is not None:
77 movieEpgMoviePlayerInstance.lastservice = self.getCurrentSelection()
78 movieEpgMoviePlayerInstance.leavePlayer()
80 baseChannelSelection_zap(self, *args, **kwargs)
81 baseChannelSelection_zap = ChannelSelection.zap
82 ChannelSelection.zap = ChannelSelection_zap
84 # Step 3: Plugin which allows access to service list from extension menu (and possibly later on from plugin menu)
85 # Absolutely no effect on its own.
86 def entry(session = None, servicelist = None):
87 # XXX: session.current_dialog is the movie player (or infobar if ran from "regular" extension menu)
88 if not session: return
91 servicelist = InfoBar.instance.servicelist
93 session.open(MessageBox, _("Unable to access InfoBar!\nEPG not available."), MessageBox.TYPE_ERROR)
96 if hasattr(servicelist, 'secretMovieMode') and servicelist.secretMovieMode != MODE_MOVIEPLAYER:
97 servicelist.secretMovieMode = MODE_ON
98 session.execDialog(servicelist)
100 # Step 4: Modify standard movie player to keep a reference to the service list (taken from the info bar)
101 # We also save a reference to the movie list here which we use to provide the "standard" close dialog when trying to zap
103 # Basically no effect on its own.
104 movieEpgMoviePlayerInstance = None
105 def MoviePlayer___init__(self, *args, **kwargs):
106 baseMoviePlayer___init__(self, *args, **kwargs)
108 self.servicelist = InfoBar.instance.servicelist
109 self.servicelist.secretMovieMode = MODE_MOVIEPLAYER
110 global movieEpgMoviePlayerInstance
111 movieEpgMoviePlayerInstance = self
112 baseMoviePlayer___init__ = MoviePlayer.__init__
113 MoviePlayer.__init__ = MoviePlayer___init__
115 def MoviePlayer_close(self, *args, **kwargs):
116 global movieEpgMoviePlayerInstance
117 movieEpgMoviePlayerInstance = None
118 if hasattr(self, 'servicelist'):
119 self.servicelist.secretMovieMode = MODE_OFF
120 baseMoviePlayer_close(self, *args, **kwargs)
121 baseMoviePlayer_close = MoviePlayer.close
122 MoviePlayer.close = MoviePlayer_close
125 from MovieEpgSetup import MovieEpgSetup
126 session.open(MovieEpgSetup)
128 def Plugins(**kwargs):
132 description=_("Configure Movie-EPG Plugin"),
133 where=PluginDescriptor.WHERE_PLUGINMENU,
135 needsRestart=True, # XXX: force restart for now as I don't think it will work properly without doing so