its mandatory to call deleteDialog for the pip screen
[enigma2-plugins.git] / epgrefresh / src / plugin.py
1 from __future__ import print_function
2
3 # for localized messages
4 from . import _, NOTIFICATIONDOMAIN
5
6 # Config
7 from Components.config import config, ConfigYesNo, ConfigNumber, ConfigSelection, \
8         ConfigSubsection, ConfigClock, ConfigYesNo, ConfigInteger, NoSave
9 from Screens.MessageBox import MessageBox
10 from Screens.Standby import TryQuitMainloop
11 from Tools.BoundFunction import boundFunction
12
13 # Error-print
14 from traceback import print_exc
15 from sys import stdout
16
17 # Calculate default begin/end
18 from time import time, localtime, mktime
19 now = localtime()
20 begin = mktime((
21         now.tm_year, now.tm_mon, now.tm_mday, 20, 15, \
22         0, now.tm_wday, now.tm_yday, now.tm_isdst)
23 )
24 end = mktime((
25         now.tm_year, now.tm_mon, now.tm_mday, 06, 30, \
26         0, now.tm_wday, now.tm_yday, now.tm_isdst)
27 )
28
29 #Configuration
30 config.plugins.epgrefresh = ConfigSubsection()
31 config.plugins.epgrefresh.enabled = ConfigYesNo(default = False)
32 config.plugins.epgrefresh.begin = ConfigClock(default = int(begin))
33 config.plugins.epgrefresh.end = ConfigClock(default = int(end))
34 config.plugins.epgrefresh.interval_seconds = ConfigNumber(default = 120)
35 config.plugins.epgrefresh.delay_standby = ConfigNumber(default = 10)
36 config.plugins.epgrefresh.inherit_autotimer = ConfigYesNo(default = False)
37 config.plugins.epgrefresh.afterevent = ConfigYesNo(default = False)
38 config.plugins.epgrefresh.force = ConfigYesNo(default = False)
39 config.plugins.epgrefresh.skipProtectedServices = ConfigSelection(choices = [
40                 ("bg_only", _("Background only")),
41                 ("always", _("Foreground also")),
42         ], default = "bg_only"
43 )
44 config.plugins.epgrefresh.enablemessage = ConfigYesNo(default = True)
45 config.plugins.epgrefresh.wakeup = ConfigYesNo(default = False)
46 config.plugins.epgrefresh.lastscan = ConfigNumber(default = 0)
47 config.plugins.epgrefresh.parse_autotimer = ConfigSelection(choices = [
48                 ("always", _("Yes")),
49                 ("never", _("No")),
50                 ("bg_only", _("Background only")),
51                 ("ask_yes", _("Ask default Yes")),
52                 ("ask_no", _("Ask default No")),
53         ], default = "never"
54 )
55 config.plugins.epgrefresh.adapter = ConfigSelection(choices = [
56                 ("main", _("Main Picture")),
57                 ("pip", _("Picture in Picture")),
58                 ("pip_hidden", _("Picture in Picture (hidden)")),
59                 ("record", _("Fake recording")),
60         ], default = "main"
61 )
62 config.plugins.epgrefresh.show_in_extensionsmenu = ConfigYesNo(default = False)
63 config.plugins.epgrefresh.show_run_in_extensionsmenu = ConfigYesNo(default = True)
64 config.plugins.epgrefresh.show_help = ConfigYesNo(default = True)
65 config.plugins.epgrefresh.wakeup_time = ConfigInteger(default=-1)
66 config.plugins.epgrefresh.showadvancedoptions = NoSave(ConfigYesNo(default = False))
67
68 # convert previous parameters
69 config.plugins.epgrefresh.background = ConfigYesNo(default = False)
70 if config.plugins.epgrefresh.background.value:
71         config.plugins.epgrefresh.adapter.value = "pip_hidden"
72         config.plugins.epgrefresh.background.value = False
73         config.plugins.epgrefresh.save()
74 config.plugins.epgrefresh.interval = ConfigNumber(default = 2)
75 if config.plugins.epgrefresh.interval.value != 2:
76         config.plugins.epgrefresh.interval_seconds.value = config.plugins.epgrefresh.interval.value * 60
77         config.plugins.epgrefresh.interval.value = 2
78         config.plugins.epgrefresh.save()
79
80 #pragma mark - Help
81 try:
82         from Components.Language import language
83         from Plugins.SystemPlugins.MPHelp import registerHelp, XMLHelpReader
84         from Tools.Directories import resolveFilename, SCOPE_PLUGINS, fileExists
85         lang = language.getLanguage()[:2]
86         
87         HELPPATH = resolveFilename(SCOPE_PLUGINS, "Extensions/EPGRefresh")
88         if fileExists(HELPPATH + "/locale/" + str(lang) + "/mphelp.xml"):
89                 helpfile = HELPPATH + "/locale/" + str(lang) + "/mphelp.xml"
90         else:
91                 helpfile = HELPPATH + "/mphelp.xml"
92         reader = XMLHelpReader(helpfile)
93         epgrefreshHelp = registerHelp(*reader)
94 except Exception as e:
95         print("[EPGRefresh] Unable to initialize MPHelp:", e,"- Help not available!")
96         epgrefreshHelp = None
97 #pragma mark -
98
99 # Notification-Domain
100 from Tools import Notifications
101 try:
102         Notifications.notificationQueue.registerDomain(NOTIFICATIONDOMAIN, _("EPGREFRESH_NOTIFICATION_DOMAIN"), deferred_callable = True)
103 except Exception as e:
104         EPGRefreshNotificationKey = ""
105         print("[EPGRefresh] Error registering Notification-Domain:", e)
106         
107 # Plugin
108 from EPGRefresh import epgrefresh
109 from EPGRefreshService import EPGRefreshService
110
111 # Plugins
112 from Components.PluginComponent import plugins
113 from Plugins.Plugin import PluginDescriptor
114
115 #pragma mark - Workaround for unset clock
116 from enigma import eDVBLocalTimeHandler
117
118 def timeCallback(isCallback=True):
119         global time_updated_conn
120         """Time Callback/Autostart management."""
121         thInstance = eDVBLocalTimeHandler.getInstance()
122         if isCallback:
123                 # NOTE: this assumes the clock is actually ready when called back
124                 # this may not be true, but we prefer silently dying to waiting forever
125                 time_updated_conn = None
126         elif not thInstance.ready():
127                 time_updated_conn = thInstance.m_timeUpdated.connect(timeCallback)
128                 return
129         epgrefresh.start()
130
131 # Autostart
132 def autostart(reason, **kwargs):
133         if reason == 0 and "session" in kwargs:
134                 session = kwargs["session"]
135                 epgrefresh.session = session
136
137                 if config.plugins.epgrefresh.enabled.value:
138                         # check if box was woken up by a timer, if so, check if epgrefresh set this timer
139                         if session.nav.wasTimerWakeup() and config.misc.prev_wakeup_time.value == config.plugins.epgrefresh.wakeup_time.value:
140                                 # if box is not in idle mode, do that
141                                 from Screens.Standby import Standby, inStandby
142                                 if not inStandby:
143                                         from Tools import Notifications
144                                         Notifications.AddNotificationWithID("Standby", Standby)
145                         timeCallback(isCallback=False)
146                 
147         elif reason == 1:
148                 epgrefresh.stop()
149
150 def getNextWakeup():
151         # Return invalid time if not automatically refreshing
152         if not config.plugins.epgrefresh.enabled.value or \
153                 not config.plugins.epgrefresh.wakeup.value:
154
155                 setConfigWakeupTime(-1) 
156                 return -1
157
158         now = localtime()
159         begin = int(mktime(
160                 (now.tm_year, now.tm_mon, now.tm_mday,
161                 config.plugins.epgrefresh.begin.value[0],
162                 config.plugins.epgrefresh.begin.value[1],
163                 0, now.tm_wday, now.tm_yday, now.tm_isdst)
164         ))
165
166         # todays timespan has not yet begun
167         if begin > time():
168                 setConfigWakeupTime(begin)
169                 return begin
170
171         # otherwise add 1 day
172         setConfigWakeupTime(begin+86400)
173         return begin+86400
174
175 def setConfigWakeupTime(value):
176         config.plugins.epgrefresh.wakeup_time.value = value
177         config.plugins.epgrefresh.save()
178
179 # Mainfunction
180 def main(session, **kwargs):
181         try:
182                 from EPGRefreshConfiguration import EPGRefreshConfiguration
183                 session.openWithCallback(
184                         doneConfiguring,
185                         EPGRefreshConfiguration
186                 )
187         except:
188                 print("[EPGRefresh] Error while Opening EPGRefreshConfiguration")
189                 print_exc(file=stdout)
190
191 def forceRefresh(session, **kwargs):
192         epgrefresh.forceRefresh(session)
193
194 def stopRunningRefresh(session, **kwargs):
195         epgrefresh.stopRunningRefresh(session)
196
197 def showPendingServices(session, **kwargs):
198         epgrefresh.showPendingServices(session)
199
200 def doneConfiguring(session, needsRestart):
201         if needsRestart:
202                 session.openWithCallback(boundFunction(restartGUICB, session), MessageBox, \
203                                 _("To apply your Changes the GUI has to be restarted.\nDo you want to restart the GUI now?"), \
204                                 MessageBox.TYPE_YESNO, timeout =  30)
205         else:
206                 _startAfterConfig(session)
207
208 def restartGUICB(session, answer):
209         if answer is True:
210                 session.open(TryQuitMainloop, 3)
211         else:
212                 _startAfterConfig(session)
213
214 def _startAfterConfig(session):
215         if config.plugins.epgrefresh.enabled.value:
216                 if not epgrefresh.isRunning():
217                         epgrefresh.start(session)
218
219 # Eventinfo
220 def eventinfo(session, servicelist, **kwargs):
221         ref = session.nav.getCurrentlyPlayingServiceReference()
222         if not ref:
223                 return
224         sref = ref.toString()
225         # strip all after last :
226         pos = sref.rfind(':')
227         if pos != -1:
228                 sref = sref[:pos+1]
229
230         epgrefresh.services[0].add(EPGRefreshService(str(sref), None))
231
232 # XXX: we need this helper function to identify the descriptor
233 # Extensions menu
234 def extensionsmenu(session, **kwargs):
235         main(session, **kwargs)
236
237 extPrefix = _("EXTENSIONMENU_PREFIX")
238 extSetupDescriptor = PluginDescriptor(name = extPrefix + " " + _("EXTENSIONNAME_SETUP"), description = _("Automatically refresh EPG"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc = extensionsmenu, needsRestart=False)
239 extRunDescriptor = PluginDescriptor(name = extPrefix + " " + _("Refresh now"), description = _("Start EPGrefresh immediately"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc = forceRefresh, needsRestart = False)
240 extStopDescriptor = PluginDescriptor(name = extPrefix + " " + _("Stop Refresh"), description = _("Stop Running EPG-refresh"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc = stopRunningRefresh, needsRestart = False)
241 extPendingServDescriptor = PluginDescriptor(name = extPrefix + " " + _("Pending Services"), description = _("Show the pending Services for refresh"), where = PluginDescriptor.WHERE_EXTENSIONSMENU, fnc = showPendingServices, needsRestart = False)
242
243 def AdjustExtensionsmenu(enable, PlugDescriptor):
244         if enable:
245                 plugins.addPlugin(PlugDescriptor)
246         else:
247                 try:
248                         plugins.removePlugin(PlugDescriptor)
249                 except ValueError as ve:
250                         if PlugDescriptor != extRunDescriptor:
251                                 print("[EPGRefresh] AdjustExtensionsmenu got confused, tried to remove non-existant plugin entry... ignoring.")
252
253 def housekeepingExtensionsmenu(configentry, force=False):
254         if force or (epgrefresh != None and not epgrefresh.isRunning()):
255                 PlugDescriptor = None
256                 if configentry == config.plugins.epgrefresh.show_in_extensionsmenu:
257                         PlugDescriptor = extSetupDescriptor
258                 elif configentry == config.plugins.epgrefresh.show_run_in_extensionsmenu:
259                         PlugDescriptor = extRunDescriptor
260                 if PlugDescriptor != None:
261                         AdjustExtensionsmenu(configentry.value, PlugDescriptor)
262
263 config.plugins.epgrefresh.show_in_extensionsmenu.addNotifier(housekeepingExtensionsmenu, initial_call = False, immediate_feedback = True)
264 config.plugins.epgrefresh.show_run_in_extensionsmenu.addNotifier(housekeepingExtensionsmenu, initial_call = False, immediate_feedback = True)
265
266 def Plugins(**kwargs):
267         # NOTE: this might be a little odd to check this, but a user might expect
268         # the plugin to resume normal operation if installed during runtime, but
269         # this is not given if the plugin is supposed to run in background (as we
270         # won't be handed the session which we need to zap). So in turn we require
271         # a restart if-and only if-we're installed during runtime AND running in
272         # background. To improve the user experience in this situation, we hide
273         # all references to this plugin.
274         needsRestart = config.plugins.epgrefresh.enabled.value and not plugins.firstRun
275         list = [
276                 PluginDescriptor(
277                         name = "EPGRefresh",
278                         where = [
279                                 PluginDescriptor.WHERE_AUTOSTART,
280                                 PluginDescriptor.WHERE_SESSIONSTART
281                         ],
282                         fnc = autostart,
283                         wakeupfnc = getNextWakeup,
284                         needsRestart = needsRestart,
285                 ),
286                 PluginDescriptor(
287                         name = _("add to EPGRefresh"),
288                         where = PluginDescriptor.WHERE_EVENTINFO,
289                         fnc = eventinfo,
290                         needsRestart = needsRestart,
291                 ),
292                 PluginDescriptor(
293                         name = _("PLUGINNAME_EPGRefresh"),
294                         description = _("Automatically refresh EPG"),
295                         where = PluginDescriptor.WHERE_PLUGINMENU, 
296                         fnc = main,
297                         icon = "EPGRefresh.png",
298                         needsRestart = needsRestart,
299                 ),
300         ]
301         if config.plugins.epgrefresh.show_in_extensionsmenu.value:
302                 extSetupDescriptor.needsRestart = needsRestart
303                 list.append(extSetupDescriptor)
304         if config.plugins.epgrefresh.show_run_in_extensionsmenu.value:
305                 extRunDescriptor.needsRestart = needsRestart
306                 list.append(extRunDescriptor)
307
308         return list