Functionality:
[enigma2-plugins.git] / epgrefresh / src / EPGRefreshConfiguration.py
1 from __future__ import print_function
2
3 # for localized messages
4 from . import _
5
6 # GUI (Screens)
7 from Screens.Screen import Screen
8 from Screens.ChoiceBox import ChoiceBox
9 from Components.ConfigList import ConfigListScreen
10 from Components.config import KEY_OK
11 from Screens.LocationBox import LocationBox
12 from EPGRefreshChannelEditor import EPGRefreshServiceEditor
13
14 # GUI (Summary)
15 from Screens.Setup import SetupSummary
16
17 # GUI (Components)
18 from Components.ActionMap import ActionMap, HelpableActionMap
19 from Screens.HelpMenu import HelpMenu, HelpableScreen
20 from Components.Sources.StaticText import StaticText
21
22 # Configuration
23 from Components.config import config, getConfigListEntry, configfile, NoSave
24 from Screens.FixedMenu import FixedMenu
25 from Tools.BoundFunction import boundFunction
26
27 from EPGRefresh import epgrefresh
28 from Components.SystemInfo import SystemInfo
29 from Screens.MessageBox import MessageBox
30
31 # Error-print
32 from traceback import print_exc
33 from sys import stdout
34 import os
35
36 VERSION = "2.0"
37 class EPGHelpContextMenu(FixedMenu):
38         HELP_RETURN_MAINHELP = 0
39         HELP_RETURN_KEYHELP = 1
40
41         def __init__(self, session):
42                 menu = [(_("General Help"), boundFunction(self.close, self.HELP_RETURN_MAINHELP)),
43                         (_("Key Help"), boundFunction(self.close, self.HELP_RETURN_KEYHELP)),
44                         (_("Cancel"), self.close)]
45
46                 FixedMenu.__init__(self, session, _("EPGRefresh Configuration Help"), menu)
47                 self.skinName = ["EPGRefreshConfigurationHelpContextMenu", "Menu" ]
48
49 class EPGFunctionMenu(FixedMenu):
50         FUNCTION_RETURN_FORCEREFRESH = 0
51         FUNCTION_RETURN_BACKUP_DATE = 1
52         FUNCTION_RETURN_BACKUP_SIZE = 2
53         FUNCTION_RETURN_BACKUP_UNINSTALL = 3
54
55         def __init__(self, session, ispatched = False):
56                 menu = [(_("Refresh now"), boundFunction(self.close, self.FUNCTION_RETURN_FORCEREFRESH))]
57                 if config.plugins.epgrefresh.backup_enabled.value:
58                         menu.append((_("Restore EPG-Backups (Date)"), boundFunction(self.close, self.FUNCTION_RETURN_BACKUP_DATE)))
59                         menu.append((_("Restore EPG-Backups (Size)"), boundFunction(self.close, self.FUNCTION_RETURN_BACKUP_SIZE)))
60                 else:
61                         menu.append((_("EPG-Backup is disabled"), self.close))
62                 if ispatched:
63                         menu.append((_("Uninstall EPG-Backup"), boundFunction(self.close, self.FUNCTION_RETURN_BACKUP_UNINSTALL)))
64                 menu.append((_("Cancel"), self.close))
65
66                 FixedMenu.__init__(self, session, _("EPGRefresh Functions"), menu)
67                 self.skinName = ["EPGRefreshConfigurationFunctionContextMenu", "Menu" ]
68
69 class EPGRefreshConfiguration(Screen, HelpableScreen, ConfigListScreen):
70         """Configuration of EPGRefresh"""
71         
72         skin = """<screen name="EPGRefreshConfiguration" position="center,center" size="600,430">
73                 <ePixmap position="0,5" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
74                 <ePixmap position="140,5" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
75                 <ePixmap position="280,5" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
76                 <ePixmap position="420,5" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
77                 <ePixmap position="562,15" size="35,25" pixmap="skin_default/buttons/key_info.png" alphatest="on" />
78
79                 <widget source="key_red" render="Label" position="0,5" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
80                 <widget source="key_green" render="Label" position="140,5" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
81                 <widget source="key_yellow" render="Label" position="280,5" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
82                 <widget source="key_blue" render="Label" position="420,5" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
83
84                 <widget name="config" position="5,50" size="590,275" scrollbarMode="showOnDemand" />
85                 <ePixmap pixmap="skin_default/div-h.png" position="0,335" zPosition="1" size="565,2" />
86                 <widget source="help" render="Label" position="5,345" size="590,83" font="Regular;21" />
87         </screen>"""
88         
89         def __init__(self, session):
90                 Screen.__init__(self, session)
91                 HelpableScreen.__init__(self)
92                 self.list = []
93                 # Summary
94                 self.setup_title = _("EPGRefresh Configuration")
95                 self.onChangedEntry = []
96                 
97                 self.session = session
98                 
99                 # Although EPGRefresh keeps services in a Set we prefer a list
100                 self.services = (
101                         [x for x in epgrefresh.services[0]],
102                         [x for x in epgrefresh.services[1]]
103                 )
104
105                 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
106                 self._getConfig()
107
108                 self["config"].onSelectionChanged.append(self.updateHelp)
109
110                 # Initialize Buttons
111                 self["key_red"] = StaticText(_("Cancel"))
112                 self["key_green"] = StaticText(_("OK"))
113                 self["key_yellow"] = StaticText(_("Functions"))
114                 self["key_blue"] = StaticText(_("Edit Services"))
115
116                 self["help"] = StaticText()
117
118                 # Define Actions
119                 self["ColorActions"] = HelpableActionMap(self, "ColorActions",
120                         {
121                                 "yellow": (self.showFunctionMenu, _("Show more Functions")),
122                                 "blue": (self.editServices, _("Edit Services")),
123                         }
124                 )
125                 self["SetupActions"] = HelpableActionMap(self, "SetupActions",
126                         {
127                                 "cancel": (self.keyCancel, _("Close and forget changes")),
128                                 "save": (self.keySave, _("Close and save changes")),
129                         }
130                 )
131                 self["actions"] = HelpableActionMap(self, "ChannelSelectEPGActions",
132                         {
133                                 "showEPGList": (self.keyInfo, _("Show last EPGRefresh - Time")),
134                         }
135                 )
136                 self["ChannelSelectBaseActions"] = HelpableActionMap(self, "ChannelSelectBaseActions",
137                         {
138                                 "nextBouquet": (self.pageup, _("Move page up")),
139                                 "prevBouquet": (self.pagedown, _("Move page down")),
140                         }
141                 )
142                 self["actionstmp"] = ActionMap(["HelpActions"],
143                         {
144                                 "displayHelp": self.showHelp,
145                         }
146                 )
147                 
148                 # Trigger change
149                 self.changed()
150                 self.needsEnigmaRestart = False
151                 
152                 self.onLayoutFinish.append(self.setCustomTitle)
153                 self.onFirstExecBegin.append(self.firstExec)
154
155         def _getConfig(self):
156                 # Name, configElement, HelpTxt, reloadConfig
157                 self.list = [] 
158                 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))
159                 if config.plugins.epgrefresh.enabled.value:
160                         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))
161                         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))
162                         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))
163                         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))
164                         if SystemInfo.get("NumVideoDecoders", 1) > 1:
165                                 self.list.insert(3, 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))
166                         self.list.append(getConfigListEntry(_("Enable Backup"), config.plugins.epgrefresh.backup_enabled, _("Should the Backup-Functionality be enabled?\nFor more Information have a look at the Help-Screen."), True))
167                         if config.plugins.epgrefresh.backup_enabled.value:
168                                 self.list.append(getConfigListEntry(_("Valid Filesize"), config.plugins.epgrefresh.backup_filesize_valid, _("EPG-Files with a less size of this value (KB) won't be backuped."), False))
169                                 self.list.append(getConfigListEntry(_("Valid Age"), config.plugins.epgrefresh.backup_timespan_valid, _("Only keep EPG-Backup-Files younger than this days."), False))
170                                 self.list.append(getConfigListEntry(_("Show Advanced Options"), NoSave(config.plugins.epgrefresh.showadvancedoptions), _("Display more Options"), True))
171                                 if config.plugins.epgrefresh.showadvancedoptions.value:
172                                         self.list.append(getConfigListEntry(_("Backup-Strategy"), config.plugins.epgrefresh.backup_strategy, _("Should the biggest or the youngest File be backuped?\nIf it is smaller than the Real-EPG-File then the other strategy will be the Fallback-Strategy."), False))
173                                         self.list.append(getConfigListEntry(_("EPG-File-Write Wait"), config.plugins.epgrefresh.backup_epgwrite_wait, _("How many seconds should EPGRefresh be wait to check if the EPG-File-Size didn't change before it starts the Backup."), False))
174                                         self.list.append(getConfigListEntry(_("Maximum Boot-Count"), config.plugins.epgrefresh.backup_max_boot_count, _("After that times of unsuccesfully boot enigma2, the EPG-File will be deleted."), False))
175                                         self.list.append(getConfigListEntry(_("Enable Debug"), config.plugins.epgrefresh.backup_enable_debug, _("Should debugmessages be printed in a File?\nThe filename will be added with the current date"), True))
176                                         if config.plugins.epgrefresh.backup_enable_debug.value:
177                                                 self.list.append(getConfigListEntry(_("Log-directory"), config.plugins.epgrefresh.backup_log_dir, _("Directory for the Logfiles."), False))
178                                         if os.path.exists("/usr/script"):
179                                                 self.list.append(getConfigListEntry(_("Show in User-Scripts"), config.plugins.epgrefresh.showin_usr_scripts, _("Should the Manage-Script be shown in User-Scripts?"), False))
180                         else:
181                                 self.list.append(getConfigListEntry(_("Show Advanced Options"), NoSave(config.plugins.epgrefresh.showadvancedoptions), _("Display more Options"), True))
182                         if config.plugins.epgrefresh.showadvancedoptions.value:
183                                 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))
184                                 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))
185                                 if config.plugins.epgrefresh.backup_enabled.value:
186                                         self.list.append(getConfigListEntry(_("Show 'EPGRefresh Restore Backup' in extension menu"), config.plugins.epgrefresh.show_backuprestore_in_extmenu, _("Enable this to be able to start a restore of a Backup-File from within the extension menu."), False))
187                                 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))
188                                 self.list.append(getConfigListEntry(_("Wake up from deep standby for EPG refresh"), config.plugins.epgrefresh.wakeup, _("If this is enabled, the plugin will wake up the receiver from deep standby if possible. Otherwise it needs to be switched on already."), False))
189                                 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))
190                                 self.list.append(getConfigListEntry(_("Shutdown after EPG refresh"), config.plugins.epgrefresh.afterevent, _("This setting controls whether the receiver should be set to deep standby after refresh is completed."), False))
191                                 try:
192                                         # try to import autotimer module to check for its existence
193                                         from Plugins.Extensions.AutoTimer.AutoTimer import AutoTimer
194                 
195                                         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))
196                                         if config.plugins.epgrefresh.inherit_autotimer.value:
197                                                 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))
198                                 except ImportError as ie:
199                                         print("[EPGRefresh] AutoTimer Plugin not installed:", ie)
200                         
201                 self["config"].list = self.list
202                 self["config"].setList(self.list)
203
204         def _maybeNeedsRestart(self):
205                 if config.plugins.epgrefresh.backup_enabled.value:
206                         # maybe self.needsEnigmaRestart was setted by "uninstall"
207                         if not self.needsEnigmaRestart:
208                                 try:
209                                         from plugin import epgbackup
210                                         ispatched = self._isPatched()
211                                         # only install it, if it was enabled for the first time
212                                         if config.plugins.epgrefresh.backup_enabled.value and not ispatched:
213                                                 epgbackup.install()
214                                                 self.session.open(MessageBox, _("EPG-Backup has been installed!:"), \
215                                                         MessageBox.TYPE_INFO, timeout = 10)
216                                                 self.needsEnigmaRestart = True
217                                 except:
218                                         print("[EPGRefresh] Error importing EPGBackup")
219                                         print_exc(file=stdout)
220         
221         def _isPatched(self):
222                 ispatched = False
223                 try:
224                         from plugin import epgbackup
225                         ispatched = epgbackup.isPatched()
226                 except:
227                         print("[EPGRefresh] Error importing EPGBackup")
228                         print_exc(file=stdout)
229                 return ispatched
230
231         def firstExec(self):
232                 from plugin import epgrefreshHelp
233                 if config.plugins.epgrefresh.show_help.value and epgrefreshHelp:
234                         config.plugins.epgrefresh.show_help.value = False
235                         config.plugins.epgrefresh.show_help.save()
236                         epgrefreshHelp.open(self.session)
237
238         def setCustomTitle(self):
239                 self.setTitle(' '.join((_("EPGRefresh Configuration"), _("Version"), VERSION)))
240
241         # overwrites / extendends
242         def keyLeft(self):
243                 ConfigListScreen.keyLeft(self)
244                 self._onKeyChange()
245
246         def keyRight(self):
247                 ConfigListScreen.keyRight(self)
248                 self._onKeyChange()
249         
250         def keyOK(self):
251                 self["config"].handleKey(KEY_OK)
252                 cur = self["config"].getCurrent()
253                 if cur[1] == config.plugins.epgrefresh.backup_log_dir:
254                         self.session.openWithCallback(self.directorySelected, LocationBox, \
255                                 _("Select Logfile-Location"), "", \
256                                 config.plugins.epgrefresh.backup_log_dir.value)
257
258         def directorySelected(self, res):
259                 if res is not None:
260                         config.plugins.epgrefresh.backup_log_dir.value = res
261
262         def _onKeyChange(self):
263                 cur = self["config"].getCurrent()
264                 if cur and cur[3]:
265                         self._getConfig()
266
267         def showHelp(self):
268                 self.session.openWithCallback(self._HelpMenuCallback, EPGHelpContextMenu)
269
270         def _HelpMenuCallback(self, *result):
271                 if not len(result):
272                         return
273                 result = result[0]
274
275                 if result == EPGHelpContextMenu.HELP_RETURN_MAINHELP:
276                         self._showMainHelp()
277                 else:
278                         self._showKeyhelp()
279         
280         def _showMainHelp(self):
281                 from plugin import epgrefreshHelp
282                 if epgrefreshHelp:
283                         epgrefreshHelp.open(self.session)
284         
285         def _showKeyhelp(self):
286                 self.session.openWithCallback(self.callHelpAction, HelpMenu, self.helpList)
287
288         def updateHelp(self):
289                 cur = self["config"].getCurrent()
290                 if cur:
291                         self["help"].text = cur[2]
292
293         def showFunctionMenu(self):
294                 ispatched = self._isPatched()
295                 self.session.openWithCallback(self._FunctionMenuCB, EPGFunctionMenu, ispatched)
296
297         def _FunctionMenuCB(self, *result):
298                 if not len(result):
299                         return
300                 result = result[0]
301
302                 try:
303                         from plugin import epgbackup
304                         if result == EPGFunctionMenu.FUNCTION_RETURN_FORCEREFRESH:
305                                 self.forceRefresh()
306                         elif result == EPGFunctionMenu.FUNCTION_RETURN_BACKUP_SIZE:
307                                 epgbackup.forceBackupBySize()
308                         elif result == EPGFunctionMenu.FUNCTION_RETURN_BACKUP_DATE:
309                                 epgbackup.forceBackup()
310                         elif result == EPGFunctionMenu.FUNCTION_RETURN_BACKUP_UNINSTALL:
311                                 epgbackup.uninstall()
312                                 config.plugins.epgrefresh.backup_enabled.setValue(False)
313                                 self.session.open(MessageBox, _("EPG-Backup has been uninstalled!:"), \
314                                         MessageBox.TYPE_INFO, timeout = 10)
315                                 self.needsEnigmaRestart = True
316                 except:
317                         print("[EPGRefresh] Error in Function - Call")
318                         print_exc(file=stdout)
319         
320         def forceRefresh(self):
321                 epgrefresh.services = (set(self.services[0]), set(self.services[1]))
322                 epgrefresh.forceRefresh(self.session)
323                 self.keySave()
324
325         def editServices(self):
326                 self.session.openWithCallback(
327                         self.editServicesCallback,
328                         EPGRefreshServiceEditor,
329                         self.services
330                 )
331
332         def editServicesCallback(self, ret):
333                 if ret:
334                         self.services = ret
335
336         # for Summary
337         def changed(self):
338                 for x in self.onChangedEntry:
339                         try:
340                                 x()
341                         except Exception:
342                                 pass
343         
344         # for Summary
345         def getCurrentEntry(self):
346                 if self["config"].getCurrent():
347                         return self["config"].getCurrent()[0]
348
349         # for Summary
350         def getCurrentValue(self):
351                 if self["config"].getCurrent():
352                         return str(self["config"].getCurrent()[1].getText())
353
354         # for Summary
355         def createSummary(self):
356                 return SetupSummary
357
358         def pageup(self):
359                 self["config"].instance.moveSelection(self["config"].instance.pageUp)
360
361         def pagedown(self):
362                 self["config"].instance.moveSelection(self["config"].instance.pageDown)
363
364         def keyInfo(self):
365                 lastscan = config.plugins.epgrefresh.lastscan.value
366                 if lastscan:
367                         from Tools.FuzzyDate import FuzzyTime
368                         scanDate = ', '.join(FuzzyTime(lastscan))
369                 else:
370                         scanDate = _("never")
371
372                 self.session.open(
373                                 MessageBox,
374                                 _("Last refresh was %s") % (scanDate,),
375                                 type=MessageBox.TYPE_INFO
376                 )
377
378         def cancelConfirm(self, doCancel):
379                 if not doCancel:
380                         return
381                 for x in self["config"].list:
382                         x[1].cancel()
383                 self.close(self.session, False)
384
385         def keyCancel(self):
386                 if self["config"].isChanged():
387                         self.session.openWithCallback(
388                                 self.cancelConfirm,
389                                 MessageBox,
390                                 _("Really close without saving settings?")
391                         )
392                 else:
393                         self.close(self.session, False)
394
395         def keySave(self):
396                 epgrefresh.services = (set(self.services[0]), set(self.services[1]))
397                 epgrefresh.saveConfiguration()
398
399                 if not config.plugins.epgrefresh.backup_enabled.value \
400                         and config.plugins.epgrefresh.show_backuprestore_in_extmenu.value:
401                         config.plugins.epgrefresh.show_backuprestore_in_extmenu.setValue(False)
402
403                 for x in self["config"].list:
404                         x[1].save()             
405                 configfile.save()
406                 
407                 self._maybeNeedsRestart()
408                 self.close(self.session, self.needsEnigmaRestart)
409
410