[EPGRefresh] removed NumVideoDecoders depend for background refresh
[enigma2-plugins.git] / epgrefresh / src / EPGRefreshConfiguration.py
1 from __future__ import print_function
2 # GUI (Screens)
3 from Screens.Screen import Screen
4 from Screens.ChoiceBox import ChoiceBox
5 from Components.ConfigList import ConfigListScreen
6 from Components.config import KEY_OK
7 from Screens.LocationBox import LocationBox
8 from EPGRefreshChannelEditor import EPGRefreshServiceEditor
9
10 # GUI (Summary)
11 from Screens.Setup import SetupSummary
12
13 # GUI (Components)
14 from Components.ActionMap import ActionMap, HelpableActionMap
15 from Screens.HelpMenu import HelpMenu, HelpableScreen
16 from Components.Sources.StaticText import StaticText
17
18 # Configuration
19 from Components.config import config, getConfigListEntry, configfile, NoSave
20 from Screens.FixedMenu import FixedMenu
21 from Tools.BoundFunction import boundFunction
22
23 from EPGRefresh import epgrefresh
24 from Components.SystemInfo import SystemInfo
25 from Screens.MessageBox import MessageBox
26
27 # Error-print
28 from traceback import print_exc
29 from sys import stdout
30 import os
31
32 VERSION = "2.3.1"
33 class EPGHelpContextMenu(FixedMenu):
34         HELP_RETURN_MAINHELP = 0
35         HELP_RETURN_KEYHELP = 1
36
37         def __init__(self, session):
38                 menu = [(_("General Help"), boundFunction(self.close, self.HELP_RETURN_MAINHELP)),
39                         (_("Key Help"), boundFunction(self.close, self.HELP_RETURN_KEYHELP)),
40                         (_("Cancel"), self.close)]
41
42                 FixedMenu.__init__(self, session, _("EPGRefresh Configuration Help"), menu)
43                 self.skinName = ["EPGRefreshConfigurationHelpContextMenu", "Menu" ]
44
45 class EPGFunctionMenu(FixedMenu):
46         FUNCTION_RETURN_FORCEREFRESH = 0
47         FUNCTION_RETURN_STOPREFRESH = 1
48         FUNCTION_RETURN_SHOWPENDING = 2
49         FUNCTION_RETURN_EPGRESET = 3
50
51
52         def __init__(self, session):
53                 if epgrefresh.isRunning():
54                         menu = [(_("Stop running refresh"), boundFunction(self.close, self.FUNCTION_RETURN_STOPREFRESH)),
55                                 (_("Pending Services"), boundFunction(self.close, self.FUNCTION_RETURN_SHOWPENDING))]
56                 else:
57                         if config.plugins.epgrefresh.epgreset.value:
58                                 menu = [(_("Refresh now"), boundFunction(self.close, self.FUNCTION_RETURN_FORCEREFRESH)),
59                                         (_("Reset")+" "+_("EPG.db"), boundFunction(self.close, self.FUNCTION_RETURN_EPGRESET))]
60                         else:
61                                 menu = [(_("Refresh now"), boundFunction(self.close, self.FUNCTION_RETURN_FORCEREFRESH))]
62                 menu.append((_("Cancel"), self.close))
63
64                 FixedMenu.__init__(self, session, _("EPGRefresh Functions"), menu)
65                 self.skinName = ["EPGRefreshConfigurationFunctionContextMenu", "Menu" ]
66
67 class EPGRefreshConfiguration(Screen, HelpableScreen, ConfigListScreen):
68         """Configuration of EPGRefresh"""
69         
70         skin = """<screen name="EPGRefreshConfiguration" position="center,120" size="820,520" >
71                 <ePixmap pixmap="skin_default/buttons/red.png" position="10,5" size="200,40" alphatest="on" />
72                 <ePixmap pixmap="skin_default/buttons/green.png" position="210,5" size="200,40" alphatest="on" />
73                 <ePixmap pixmap="skin_default/buttons/yellow.png" position="410,5" size="200,40" alphatest="on" />
74                 <ePixmap pixmap="skin_default/buttons/blue.png" position="610,5" size="200,40" alphatest="on" />
75                 <widget source="key_red" render="Label" position="10,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
76                 <widget source="key_green" render="Label" position="210,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
77                 <widget source="key_yellow" render="Label" position="410,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
78                 <widget source="key_blue" render="Label" position="610,5" size="200,40" zPosition="1" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" shadowColor="black" shadowOffset="-2,-2" />
79                 <eLabel position="10,50" size="800,1" backgroundColor="grey" />
80                 <widget name="config" position="10,60" size="800,330" enableWrapAround="1" scrollbarMode="showOnDemand" />
81                 <eLabel position="10,400" size="800,1" backgroundColor="grey" />
82                 <widget source="help" render="Label" position="60,410" size="700,100" font="Regular;22" valign="center" halign="center" />
83                 <ePixmap position="760,490" size="50,25" pixmap="skin_default/buttons/key_info.png" alphatest="on" />
84         </screen>"""
85         
86         def __init__(self, session):
87                 Screen.__init__(self, session)
88                 HelpableScreen.__init__(self)
89                 self.list = []
90                 # Summary
91                 self.setup_title = _("EPGRefresh Configuration")
92                 self.onChangedEntry = []
93                 
94                 self.session = session
95                 
96                 # Although EPGRefresh keeps services in a Set we prefer a list
97                 self.services = (
98                         [x for x in epgrefresh.services[0]],
99                         [x for x in epgrefresh.services[1]]
100                 )
101
102                 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
103                 self._getConfig()
104
105                 self["config"].onSelectionChanged.append(self.updateHelp)
106
107                 # Initialize Buttons
108                 self["key_red"] = StaticText(_("Cancel"))
109                 self["key_green"] = StaticText(_("OK"))
110                 self["key_yellow"] = StaticText(_("Functions"))
111                 self["key_blue"] = StaticText(_("Edit Services"))
112
113                 self["help"] = StaticText()
114
115                 # Define Actions
116                 self["ColorActions"] = HelpableActionMap(self, "ColorActions",
117                         {
118                                 "yellow": (self.showFunctionMenu, _("Show more Functions")),
119                                 "blue": (self.editServices, _("Edit Services")),
120                         }
121                 )
122                 self["actions"] = HelpableActionMap(self, "ChannelSelectEPGActions",
123                         {
124                                 "showEPGList": (self.keyInfo, _("Show last EPGRefresh - Time")),
125                         }
126                 )
127                 self["ChannelSelectBaseActions"] = HelpableActionMap(self, "ChannelSelectBaseActions",
128                         {
129                                 "nextBouquet": (self.pageup, _("Move page up")),
130                                 "prevBouquet": (self.pagedown, _("Move page down")),
131                         }
132                 )
133                 self["actionstmp"] = ActionMap(["HelpActions"],
134                         {
135                                 "displayHelp": self.showHelp,
136                         }
137                 )
138                 self["SetupActions"] = HelpableActionMap(self, "SetupActions",
139                         {
140                                 "cancel": (self.keyCancel, _("Close and forget changes")),
141                                 "save": (self.keySave, _("Close and save changes")),
142                         }
143                 )
144                 
145                 # Trigger change
146                 self.changed()
147                 self.needsEnigmaRestart = False
148                 self.ServicesChanged = False
149                 
150                 self.onLayoutFinish.append(self.setCustomTitle)
151                 self.onFirstExecBegin.append(self.firstExec)
152                 self["config"].isChanged = self._ConfigisChanged
153
154         def _getConfig(self):
155                 # Name, configElement, HelpTxt, reloadConfig
156                 self.list = [] 
157                 self.list.append(getConfigListEntry(_("Refresh EPG automatically"), config.plugins.epgrefresh.enabled, _("Unless this is enabled, EPGRefresh won't automatically run but needs to be explicitly started by the yellow button in this menu."), True))
158                 if config.plugins.epgrefresh.enabled.value:
159                         # temporary until new mode is successfully tested
160                         self.list.append(getConfigListEntry(_("Use time-based duration to stay on service"), config.plugins.epgrefresh.usetimebased, _("Duration to stay can be automatically detected by enigma2 or manually set by the user"), True))
161                         if config.plugins.epgrefresh.usetimebased.value:
162                                 self.list.append(getConfigListEntry(_("Duration to stay on service (seconds)"), config.plugins.epgrefresh.interval_seconds, _("This is the duration each service/channel will stay active during a refresh."), False))
163                         self.list.append(getConfigListEntry(_("EPG refresh auto-start earliest (hh:mm)"), config.plugins.epgrefresh.begin, _("An automated refresh will start after this time of day, but before the time specified in next setting."), False))
164                         self.list.append(getConfigListEntry(_("EPG refresh auto-start latest (hh:mm)"), config.plugins.epgrefresh.end, _("An automated refresh will start before this time of day, but after the time specified in previous setting."), False))
165                         self.list.append(getConfigListEntry(_("Delay if not in standby (minutes)"), config.plugins.epgrefresh.delay_standby, _("If the receiver currently isn't in standby, this is the duration which EPGRefresh will wait before retry."), False))
166                         self.list.append(getConfigListEntry(_("Refresh EPG using"), config.plugins.epgrefresh.adapter, _("If you want to refresh the EPG in background, you can choose the method which best suits your needs here, e.g. hidden, fake reocrding or regular Picture in Picture."), False))
167                         self.list.append(getConfigListEntry(_("Show Advanced Options"), NoSave(config.plugins.epgrefresh.showadvancedoptions), _("Display more Options"), True))
168                         if config.plugins.epgrefresh.showadvancedoptions.value:
169                                 if config.ParentalControl.configured.value and  config.ParentalControl.servicepinactive.value:
170                                         self.list.append(getConfigListEntry(_("Skip protected Services"), config.plugins.epgrefresh.skipProtectedServices, _("Should protected services be skipped if refresh was started in interactive-mode?"), False))
171                                 self.list.append(getConfigListEntry(_("Show Setup in extension menu"), config.plugins.epgrefresh.show_in_extensionsmenu, _("Enable this to be able to access the EPGRefresh configuration from within the extension menu."), False))
172                                 self.list.append(getConfigListEntry(_("Show 'EPGRefresh Start now' in extension menu"), config.plugins.epgrefresh.show_run_in_extensionsmenu, _("Enable this to be able to start the EPGRefresh from within the extension menu."), False))
173                                 self.list.append(getConfigListEntry(_("Show popup when refresh starts and ends"), config.plugins.epgrefresh.enablemessage, _("This setting controls whether or not an informational message will be shown at start and completion of refresh."), False))
174                                 self.list.append(getConfigListEntry(_("Wake up from standby for EPG refresh"), config.plugins.epgrefresh.wakeup, _("If this is enabled, the plugin will wake up the receiver from standby if possible. Otherwise it needs to be switched on already."), False))
175                                 self.list.append(getConfigListEntry(_("Force scan even if receiver is in use"), config.plugins.epgrefresh.force, _("This setting controls whether or not the refresh will be initiated even though the receiver is active (either not in standby or currently recording)."), False))
176                                 self.list.append(getConfigListEntry(_("Shutdown after EPG refresh"), config.plugins.epgrefresh.afterevent, _("This setting controls whether the receiver should be set to standby after refresh is completed."), False))
177                                 self.list.append(getConfigListEntry(_("Force save EPG.db"), config.plugins.epgrefresh.epgsave, _("If this is enabled, the Plugin save the epg.db /etc/enigma2/epg.db."), False)) 
178                                 self.list.append(getConfigListEntry(_("Reset")+" "+_("EPG.db"), config.plugins.epgrefresh.epgreset, _("If this is enabled, the Plugin shows the Reset EPG.db function."), False)) 
179                                 try:
180                                         # try to import autotimer module to check for its existence
181                                         from Plugins.Extensions.AutoTimer.AutoTimer import AutoTimer
182                 
183                                         self.list.append(getConfigListEntry(_("Inherit Services from AutoTimer"), config.plugins.epgrefresh.inherit_autotimer, _("Extend the list of services to refresh by those your AutoTimers use?"), True))
184                                         self.list.append(getConfigListEntry(_("Run AutoTimer after refresh"), config.plugins.epgrefresh.parse_autotimer, _("After a successful refresh the AutoTimer will automatically search for new matches if this is enabled. The options 'Ask*' has only affect on a manually refresh. If EPG-Refresh was called in background the default-Answer will be executed!"), False))
185                                 except ImportError as ie:
186                                         print("[EPGRefresh] AutoTimer Plugin not installed:", ie)
187                         
188                 self["config"].list = self.list
189                 self["config"].setList(self.list)
190
191         def firstExec(self):
192                 from plugin import epgrefreshHelp
193                 if config.plugins.epgrefresh.show_help.value and epgrefreshHelp:
194                         config.plugins.epgrefresh.show_help.value = False
195                         config.plugins.epgrefresh.show_help.save()
196                         epgrefreshHelp.open(self.session)
197
198         def setCustomTitle(self):
199                 self.setTitle(' '.join((_("EPGRefresh Configuration"), _("Version"), VERSION)))
200
201         # overwrites / extendends
202         def keyLeft(self):
203                 ConfigListScreen.keyLeft(self)
204                 self._onKeyChange()
205
206         def keyRight(self):
207                 ConfigListScreen.keyRight(self)
208                 self._onKeyChange()
209         
210         # overwrite configlist.isChanged
211         def _ConfigisChanged(self):
212                 is_changed = False
213                 for x in self["config"].list:
214                         if not x[1].save_disabled:
215                                 is_changed |= x[1].isChanged()
216                 return is_changed
217         
218         def isConfigurationChanged(self):
219                 return self.ServicesChanged or self._ConfigisChanged()
220         
221         def _onKeyChange(self):
222                 cur = self["config"].getCurrent()
223                 if cur and cur[3]:
224                         self._getConfig()
225
226         def showHelp(self):
227                 self.session.openWithCallback(self._HelpMenuCallback, EPGHelpContextMenu)
228
229         def _HelpMenuCallback(self, *result):
230                 if not len(result):
231                         return
232                 result = result[0]
233
234                 if result == EPGHelpContextMenu.HELP_RETURN_MAINHELP:
235                         self._showMainHelp()
236                 else:
237                         self._showKeyhelp()
238         
239         def _showMainHelp(self):
240                 from plugin import epgrefreshHelp
241                 if epgrefreshHelp:
242                         epgrefreshHelp.open(self.session)
243         
244         def _showKeyhelp(self):
245                 self.session.openWithCallback(self.callHelpAction, HelpMenu, self.helpList)
246
247         def updateHelp(self):
248                 cur = self["config"].getCurrent()
249                 if cur:
250                         self["help"].text = cur[2]
251
252         def showFunctionMenu(self):
253                 self.session.openWithCallback(self._FunctionMenuCB, EPGFunctionMenu)
254
255         def _FunctionMenuCB(self, *result):
256                 if not len(result):
257                         return
258                 result = result[0]
259
260                 try:
261                         if result == EPGFunctionMenu.FUNCTION_RETURN_FORCEREFRESH:
262                                 self.forceRefresh()
263                         if result == EPGFunctionMenu.FUNCTION_RETURN_STOPREFRESH:
264                                 self.stopRunningRefresh()
265                         if result == EPGFunctionMenu.FUNCTION_RETURN_SHOWPENDING:
266                                 self.showPendingServices()
267                         if result == EPGFunctionMenu.FUNCTION_RETURN_EPGRESET:
268                                 self.resetEPG()
269                 except:
270                         print("[EPGRefresh] Error in Function - Call")
271                         print_exc(file=stdout)
272         
273         def forceRefresh(self):
274                 if not epgrefresh.isRefreshAllowed():
275                         return
276         
277                 self._saveConfiguration()
278                 epgrefresh.services = (set(self.services[0]), set(self.services[1]))
279                 epgrefresh.forceRefresh(self.session)
280                 self.keySave(False)
281
282         def resetEPG(self):
283                 epgrefresh.resetEPG(self.session)
284
285         def showPendingServices(self):
286                 epgrefresh.showPendingServices(self.session)
287         
288         def stopRunningRefresh(self):
289                 epgrefresh.stopRunningRefresh(self.session)
290
291         def editServices(self):
292                 self.session.openWithCallback(
293                         self.editServicesCallback,
294                         EPGRefreshServiceEditor,
295                         self.services
296                 )
297
298         def editServicesCallback(self, ret):
299                 if ret:
300                         self.services = ret
301                         self.ServicesChanged = True
302
303         # for Summary
304         def changed(self):
305                 for x in self.onChangedEntry:
306                         try:
307                                 x()
308                         except Exception:
309                                 pass
310         
311         # for Summary
312         def getCurrentEntry(self):
313                 if self["config"].getCurrent():
314                         return self["config"].getCurrent()[0]
315
316         # for Summary
317         def getCurrentValue(self):
318                 if self["config"].getCurrent():
319                         return str(self["config"].getCurrent()[1].getText())
320
321         # for Summary
322         def createSummary(self):
323                 return SetupSummary
324
325         def pageup(self):
326                 self["config"].instance.moveSelection(self["config"].instance.pageUp)
327
328         def pagedown(self):
329                 self["config"].instance.moveSelection(self["config"].instance.pageDown)
330
331         def keyInfo(self):
332                 lastscan = config.plugins.epgrefresh.lastscan.value
333                 if lastscan:
334                         from Tools.FuzzyDate import FuzzyTime
335                         scanDate = ', '.join(FuzzyTime(lastscan))
336                 else:
337                         scanDate = _("never")
338
339                 self.session.open(
340                                 MessageBox,
341                                 _("Last refresh was %s") % (scanDate,),
342                                 type=MessageBox.TYPE_INFO
343                 )
344
345         def cancelConfirm(self, doCancel):
346                 if not doCancel:
347                         return
348                 for x in self["config"].list:
349                         x[1].cancel()
350                 self.close(self.session, False)
351
352         def keyCancel(self):
353                 if self.isConfigurationChanged():
354                         self.session.openWithCallback(
355                                 self.cancelConfirm,
356                                 MessageBox,
357                                 _("Really close without saving settings?")
358                         )
359                 else:
360                         self.close(self.session, False)
361         
362         def _saveConfiguration(self):
363                 epgrefresh.services = (set(self.services[0]), set(self.services[1]))
364                 epgrefresh.saveConfiguration()
365
366                 for x in self["config"].list:
367                         x[1].save()             
368                 configfile.save()
369                 
370         def keySave(self, doSaveConfiguration = True):
371                 if self.isConfigurationChanged():
372                         if not epgrefresh.isRefreshAllowed():
373                                 return
374                         else:
375                                 epgrefresh.stop()
376                                 if doSaveConfiguration:
377                                         self._saveConfiguration()
378
379                 if len(self.services[0]) == 0 and len(self.services[1]) == 0 and config.plugins.epgrefresh.enabled.value:
380                         self.session.openWithCallback(self.checkAnswer, MessageBox, _("EPGRefresh requires services/bouquets to be configured. Configure now?"), MessageBox.TYPE_YESNO, timeout=0)
381                 else:                                   
382                         self.close(self.session, self.needsEnigmaRestart)
383
384         def checkAnswer(self, answer):
385                 if answer:
386                         self.editServices()
387                 else:           
388                         self.close(self.session, self.needsEnigmaRestart)
389
390