X-Git-Url: http://code.vuplus.com/gitweb/?a=blobdiff_plain;f=autotimer%2Fsrc%2FAutoTimerEditor.py;h=0d623def0b6ec1072564d27325ec1b0ec863eb60;hb=07aa7c4f56ead32aad37b8ff0cc82d91428d2db6;hp=22ad9887d683ec00b54b2f1a8452d5070508ebf0;hpb=17d9041eb664be81d5e0099ec4d4eb73af843777;p=vuplus_dvbapp-plugin diff --git a/autotimer/src/AutoTimerEditor.py b/autotimer/src/AutoTimerEditor.py index 22ad988..0d623de 100644 --- a/autotimer/src/AutoTimerEditor.py +++ b/autotimer/src/AutoTimerEditor.py @@ -1,3 +1,4 @@ +# -*- coding: UTF-8 -*- # for localized messages from . import _ @@ -5,6 +6,7 @@ from . import _ from Screens.Screen import Screen from Components.ConfigList import ConfigListScreen from Screens.ChannelSelection import SimpleChannelSelection +from Screens.EpgSelection import EPGSelection from Screens.MessageBox import MessageBox from Screens.ChoiceBox import ChoiceBox @@ -13,12 +15,12 @@ from Screens.Setup import SetupSummary # GUI (Components) from Components.ActionMap import ActionMap -from Components.Button import Button +from Components.Sources.StaticText import StaticText # Configuration from Components.config import getConfigListEntry, ConfigEnableDisable, \ ConfigYesNo, ConfigText, ConfigClock, ConfigNumber, ConfigSelection, \ - config + config, NoSave # Timer from RecordTimer import AFTEREVENT @@ -29,12 +31,15 @@ from time import localtime, mktime # Show ServiceName instead of ServiceReference from ServiceReference import ServiceReference -# addAutotimerFromService -from enigma import eServiceCenter, iServiceInformation +# addAutotimerFromService, AutoTimerChannelSelection +from enigma import eServiceCenter, eServiceReference, iServiceInformation # Default Record Directory from Tools import Directories +# Tags +from Screens.MovieSelection import getPreferredTagEditor + weekdays = [ ("0", _("Monday")), ("1", _("Tuesday")), @@ -47,12 +52,26 @@ weekdays = [ ("weekday", _("Weekday")) ] +class ExtendedConfigText(ConfigText): + def __init__(self, default = "", fixed_size = True, visible_width = False): + ConfigText.__init__(self, default = default, fixed_size = fixed_size, visible_width = visible_width) + + # Workaround some characters currently not "typeable" using NumericalTextInput + mapping = self.mapping + if mapping: + if "&" not in mapping[0]: + mapping[0] += "&" + if ";" not in mapping[0]: + mapping[0] += ";" + if "%" not in mapping[0]: + mapping[0] += "%" + class SimpleBouquetSelection(SimpleChannelSelection): def __init__(self, session, title): SimpleChannelSelection.__init__(self, session, title) self.skinName = "SimpleChannelSelection" - def channelSelected(self): # just return selected service + def channelSelected(self): ref = self.getCurrentSelection() if (ref.flags & 7) == 7: self.close(ref) @@ -61,7 +80,49 @@ class SimpleBouquetSelection(SimpleChannelSelection): # Asking the user if this is what he wants might be better though self.close(self.servicePath[-1]) -class AutoTimerEditorBase(): +class AutoTimerChannelSelection(SimpleChannelSelection): + def __init__(self, session, autotimer): + SimpleChannelSelection.__init__(self, session, _("Channel Selection")) + self.skinName = "SimpleChannelSelection" + self.autotimer = autotimer + + self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"], + { + "showEPGList": self.channelSelected + } + ) + + def channelSelected(self): + ref = self.getCurrentSelection() + if (ref.flags & 7) == 7: + self.enterPath(ref) + elif not (ref.flags & eServiceReference.isMarker): + self.session.open( + AutoTimerEPGSelection, + ref + ) + +class AutoTimerEPGSelection(EPGSelection): + def __init__(self, *args): + EPGSelection.__init__(self, *args) + self.skinName = "EPGSelection" + + def infoKeyPressed(self): + self.timerAdd() + + def timerAdd(self): + cur = self["list"].getCurrent() + evt = cur[0] + sref = cur[1] + if not evt: + return + + addAutotimerFromEvent(self.session, evt = evt, service = sref) + + def onSelectionChanged(self): + pass + +class AutoTimerEditorBase: """ Base Class for all Editors """ def __init__(self, timer, editingDefaults = False): # Keep Timer @@ -69,30 +130,32 @@ class AutoTimerEditorBase(): self.editingDefaults = editingDefaults # See if we are filtering some strings - self.excludes = ( + excludes = ( timer.getExcludedTitle(), timer.getExcludedShort(), timer.getExcludedDescription(), timer.getExcludedDays() ) - self.includes = ( + includes = ( timer.getIncludedTitle(), timer.getIncludedShort(), timer.getIncludedDescription(), timer.getIncludedDays() ) - if len(self.excludes[0]) or len(self.excludes[1]) \ - or len(self.excludes[2]) or len(self.excludes[3]) \ - or len(self.includes[0]) or len(self.includes[1]) \ - or len(self.includes[2]) or len(self.includes[3]): + if excludes[0] or excludes[1] \ + or excludes[2] or excludes[3] \ + or includes[0] or includes[1] \ + or includes[2] or includes[3]: self.filterSet = True else: self.filterSet = False + self.excludes = excludes + self.includes = includes # See if services are restricted - self.services = timer.getServices() - self.bouquets = timer.getBouquets() - if len(self.services) or len(self.bouquets): + self.services = timer.services + self.bouquets = timer.bouquets + if self.services or self.bouquets: self.serviceRestriction = True else: self.serviceRestriction = False @@ -101,14 +164,27 @@ class AutoTimerEditorBase(): def createSetup(self, timer): # Name - self.name = ConfigText(default = timer.name, fixed_size = False) + self.name = NoSave(ExtendedConfigText(default = timer.name, fixed_size = False)) # Match - self.match = ConfigText(default = timer.match, fixed_size = False) - self.match.setUseableChars('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789') # XXX: what exactly is useable? :-) + self.match = NoSave(ExtendedConfigText(default = timer.match, fixed_size = False)) + + # Encoding + default = timer.encoding + selection = ['UTF-8', 'ISO8859-15'] + if default not in selection: + selection.append(default) + self.encoding = NoSave(ConfigSelection(choices = selection, default = default)) + + # ... + self.searchType = NoSave(ConfigSelection(choices = [("partial", _("partial match")), ("exact", _("exact match"))], default = timer.searchType)) + self.searchCase = NoSave(ConfigSelection(choices = [("sensitive", _("case-sensitive search")), ("insensitive", _("case-insensitive search"))], default = timer.searchCase)) + + # Alternatives override + self.overrideAlternatives = NoSave(ConfigYesNo(default = timer.overrideAlternatives)) # Justplay - self.justplay = ConfigSelection(choices = [("zap", _("zap")), ("record", _("record"))], default = {0: "record", 1: "zap"}[int(timer.justplay)]) + self.justplay = NoSave(ConfigSelection(choices = [("zap", _("zap")), ("record", _("record"))], default = {0: "record", 1: "zap"}[int(timer.justplay)])) # Timespan now = [x for x in localtime()] @@ -128,9 +204,9 @@ class AutoTimerEditorBase(): now[3] = 23 now[4] = 15 end = mktime(now) - self.timespan = ConfigEnableDisable(default = default) - self.timespanbegin = ConfigClock(default = begin) - self.timespanend = ConfigClock(default = end) + self.timespan = NoSave(ConfigEnableDisable(default = default)) + self.timespanbegin = NoSave(ConfigClock(default = begin)) + self.timespanend = NoSave(ConfigClock(default = end)) # Services have their own Screen @@ -143,16 +219,26 @@ class AutoTimerEditorBase(): default = False begin = 5 end = 5 - self.offset = ConfigEnableDisable(default = default) - self.offsetbegin = ConfigNumber(default = begin) - self.offsetend = ConfigNumber(default = end) + self.offset = NoSave(ConfigEnableDisable(default = default)) + self.offsetbegin = NoSave(ConfigNumber(default = begin)) + self.offsetend = NoSave(ConfigNumber(default = end)) # AfterEvent if timer.hasAfterEvent(): - afterevent = { None: "default", AFTEREVENT.NONE: "nothing", AFTEREVENT.DEEPSTANDBY: "deepstandby", AFTEREVENT.STANDBY: "standby"}[timer.afterevent[0][0]] + default = { + None: "default", + AFTEREVENT.NONE: "nothing", + AFTEREVENT.DEEPSTANDBY: "deepstandby", + AFTEREVENT.STANDBY: "standby", + AFTEREVENT.AUTO: "auto" + }[timer.afterevent[0][0]] else: - afterevent = "default" - self.afterevent = ConfigSelection(choices = [("default", _("standard")), ("nothing", _("do nothing")), ("standby", _("go to standby")), ("deepstandby", _("go to deep standby"))], default = afterevent) + default = "default" + self.afterevent = NoSave(ConfigSelection(choices = [ + ("default", _("standard")), ("nothing", _("do nothing")), + ("standby", _("go to standby")), + ("deepstandby", _("go to deep standby")), + ("auto", _("auto"))], default = default)) # AfterEvent (Timespan) if timer.hasAfterEvent() and timer.afterevent[0][1][0] is not None: @@ -171,12 +257,12 @@ class AutoTimerEditorBase(): now[3] = 7 now[4] = 0 end = mktime(now) - self.afterevent_timespan = ConfigEnableDisable(default = default) - self.afterevent_timespanbegin = ConfigClock(default = begin) - self.afterevent_timespanend = ConfigClock(default = end) + self.afterevent_timespan = NoSave(ConfigEnableDisable(default = default)) + self.afterevent_timespanbegin = NoSave(ConfigClock(default = begin)) + self.afterevent_timespanend = NoSave(ConfigClock(default = end)) # Enabled - self.enabled = ConfigYesNo(default = timer.enabled) + self.enabled = NoSave(ConfigYesNo(default = timer.enabled)) # Maxduration if timer.hasDuration(): @@ -185,29 +271,30 @@ class AutoTimerEditorBase(): else: default = False duration =70 - self.duration = ConfigEnableDisable(default = default) - self.durationlength = ConfigNumber(default = duration) + self.duration = NoSave(ConfigEnableDisable(default = default)) + self.durationlength = NoSave(ConfigNumber(default = duration)) # Counter if timer.hasCounter(): default = timer.matchCount else: default = 0 - self.counter = ConfigNumber(default = default) - self.counterLeft = ConfigNumber(default = timer.matchLeft) + self.counter = NoSave(ConfigNumber(default = default)) + self.counterLeft = NoSave(ConfigNumber(default = timer.matchLeft)) + default = timer.getCounterFormatString() selection = [("", _("Never")), ("%m", _("Monthly")), ("%U", _("Weekly (Sunday)")), ("%W", _("Weekly (Monday)"))] - if timer.getCounterFormatString() not in ["", "%m", "%U", "%W"]: - selection.append((timer.getCounterFormatString(), _("Custom (%s)") % (timer.getCounterFormatString()))) - self.counterFormatString = ConfigSelection(selection, default = timer.getCounterFormatString()) + if default not in ('', '%m', '%U', '%W'): + selection.append((default, _("Custom (%s)") % (default))) + self.counterFormatString = NoSave(ConfigSelection(selection, default = default)) # Avoid Duplicate Description - self.avoidDuplicateDescription = ConfigSelection([ + self.avoidDuplicateDescription = NoSave(ConfigSelection([ ("0", _("No")), ("1", _("On same service")), ("2", _("On any service")), ], default = str(timer.getAvoidDuplicateDescription()) - ) + )) # Custom Location if timer.hasDestination(): @@ -215,20 +302,24 @@ class AutoTimerEditorBase(): else: default = False - self.useDestination = ConfigYesNo(default = default) + self.useDestination = NoSave(ConfigYesNo(default = default)) default = timer.destination or Directories.resolveFilename(Directories.SCOPE_HDD) choices = config.movielist.videodirs.value if default not in choices: choices.append(default) - self.destination = ConfigSelection(default = default, choices = choices) + self.destination = NoSave(ConfigSelection(default = default, choices = choices)) + + # Tags + self.timerentry_tags = timer.tags + self.tags = NoSave(ConfigSelection(choices = [len(self.timerentry_tags) == 0 and _("None") or ' '.join(self.timerentry_tags)])) def pathSelected(self, res): if res is not None: - if res not in self.destination.choices: - self.destination.choices.append(res) - self.destination.description[res] = res + # I'm pretty sure this will always fail + if config.movielist.videodirs.value != self.destination.choices: + self.destination.setChoices(config.movielist.videodirs.value, default = res) self.destination.value = res def chooseDestination(self): @@ -242,19 +333,35 @@ class AutoTimerEditorBase(): minFree = 100 # Same requirement as in Screens.TimerEntry ) + def tagEditFinished(self, ret): + if ret is not None: + self.timerentry_tags = ret + self.tags.setChoices([len(ret) == 0 and _("None") or ' '.join(ret)]) + + def chooseTags(self): + preferredTagEditor = getPreferredTagEditor() + if preferredTagEditor: + self.session.openWithCallback( + self.tagEditFinished, + preferredTagEditor, + self.timerentry_tags + ) + class AutoTimerEditor(Screen, ConfigListScreen, AutoTimerEditorBase): """Edit AutoTimer""" - skin = """ - - - - - - - - - + skin = """ + + + + + + + + + + + """ def __init__(self, session, timer, editingDefaults = False): @@ -263,7 +370,7 @@ class AutoTimerEditor(Screen, ConfigListScreen, AutoTimerEditorBase): AutoTimerEditorBase.__init__(self, timer, editingDefaults) # Summary - self.setup_title = "AutoTimer Editor" + self.setup_title = _("AutoTimer Editor") self.onChangedEntry = [] # We might need to change shown items, so add some notifiers @@ -276,14 +383,19 @@ class AutoTimerEditor(Screen, ConfigListScreen, AutoTimerEditorBase): self.useDestination.addNotifier(self.reloadList, initial_call = False) self.refresh() + self.initHelpTexts() - ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed) + # XXX: no help for numericaltextinput since it is shown on top of our help + ConfigListScreen.__init__(self, self.list, on_change = self.changed) + self["config"].onSelectionChanged.append(self.updateHelp) # Initialize Buttons - self["key_red"] = Button(_("Cancel")) - self["key_green"] = Button(_("OK")) - self["key_yellow"] = Button() - self["key_blue"] = Button() + self["key_red"] = StaticText(_("Cancel")) + self["key_green"] = StaticText(_("OK")) + self["key_yellow"] = StaticText() + self["key_blue"] = StaticText() + + self["help"] = StaticText() # Set Button texts self.renameServiceButton() @@ -303,23 +415,33 @@ class AutoTimerEditor(Screen, ConfigListScreen, AutoTimerEditorBase): # Trigger change self.changed() + self.onLayoutFinish.append(self.setCustomTitle) + + def setCustomTitle(self): + self.setTitle(_("Edit AutoTimer")) + def renameFilterButton(self): if self.filterSet: - self["key_yellow"].setText(_("Edit Filters")) + self["key_yellow"].text = _("edit filters") else: - self["key_yellow"].setText(_("Add Filters")) + self["key_yellow"].text = _("add filters") def renameServiceButton(self): if self.serviceRestriction: - self["key_blue"].setText(_("Edit Services")) + self["key_blue"].text = _("edit services") else: - self["key_blue"].setText(_("Add Services")) + self["key_blue"].text = _("add services") + + def updateHelp(self): + cur = self["config"].getCurrent() + if cur: + self["help"].text = self.helpDict[cur[1]] def changed(self): for x in self.onChangedEntry: try: x() - except: + except Exception: pass def getCurrentEntry(self): @@ -331,70 +453,109 @@ class AutoTimerEditor(Screen, ConfigListScreen, AutoTimerEditorBase): def createSummary(self): return SetupSummary + def initHelpTexts(self): + self.helpDict = { + self.enabled: _("Set this NO to disable this AutoTimer."), + self.name: _("This is a name you can give the AutoTimer. It will be shown in the Overview and the Preview."), + self.match: _("This is what will be looked for in event titles. Note that looking for e.g. german umlauts can be tricky as you have to know the encoding the channel uses."), + self.encoding: _("Encoding the channel uses for it's EPG data. You only need to change this if you're searching for special characters like the german umlauts."), + self.searchType: _("Select \"exact match\" to enforce \"Match title\" to match exactly or \"partial match\" if you only want to search for a part of the event title."), + self.searchCase: _("Select whether or not you want to enforce case correctness."), + self.justplay: _("Add zap timer instead of record timer?"), + self.overrideAlternatives: _("With this option enabled the channel to record on can be changed to a alternative service it is restricted to."), + self.timespan: _("Should this AutoTimer be restricted to a timespan?"), + self.timespanbegin: _("Lower bound of timespan. Nothing before this time will be matched. Offsets are not taken into account!"), + self.timespanend: _("Upper bound of timespan. Nothing after this time will be matched. Offsets are not taken into account!"), + self.offset: _("Change default recording offset?"), + self.offsetbegin: _("Time in minutes to prepend to recording."), + self.offsetend: _("Time in minutes to append to recording."), + self.duration: _("Should this AutoTimer only match up to a certain event duration?"), + self.durationlength: _("Maximum event duration to match. If an event is longer than this ammount of time (without offset) it won't be matched."), + self.afterevent: _("Power state to change to after recordings. Select \"standard\" to not change the default behavior of enigma2 or values changed by yourself."), + self.afterevent_timespan: _("Restrict \"after event\" to a certain timespan?"), + self.afterevent_timespanbegin: _("Lower bound of timespan."), + self.afterevent_timespanend: _("Upper bound of timespan."), + self.counter: _("With this option you can restrict the AutoTimer to a certain ammount of scheduled recordings. Set this to 0 to disable this functionality."), + self.counterLeft: _("Number of scheduled recordings left."), + self.counterFormatString: _("The counter can automatically be reset to the limit at certain intervals."), + self.avoidDuplicateDescription: _("When this option is enabled the AutoTimer won't match events where another timer with the same description already exists in the timer list."), + self.useDestination: _("Should timers created by this AutoTimer be recorded to a custom location?"), + self.destination: _("Select the location to save the recording to."), + self.tags: _("Tags the Timer/Recording will have."), + } + def refresh(self): # First three entries are only showed when not editing defaults - self.list = [] + list = [] if not self.editingDefaults: - self.list.extend([ + list.extend(( getConfigListEntry(_("Enabled"), self.enabled), getConfigListEntry(_("Description"), self.name), - getConfigListEntry(_("Match Title"), self.match), - ]) - - self.list.extend([ - getConfigListEntry(_("Timer Type"), self.justplay), - getConfigListEntry(_("Only match during Timespan"), self.timespan) - ]) + getConfigListEntry(_("Match title"), self.match), + )) + + list.extend(( + getConfigListEntry(_("EPG encoding"), self.encoding), + getConfigListEntry(_("Search type"), self.searchType), + getConfigListEntry(_("Search strictness"), self.searchCase), + getConfigListEntry(_("Timer type"), self.justplay), + getConfigListEntry(_("Override found with alternative service"), self.overrideAlternatives), + getConfigListEntry(_("Only match during timespan"), self.timespan) + )) # Only allow editing timespan when it's enabled if self.timespan.value: - self.list.extend([ - getConfigListEntry(_("Begin of Timespan"), self.timespanbegin), - getConfigListEntry(_("End of Timespan"), self.timespanend) - ]) + list.extend(( + getConfigListEntry(_("Begin of timespan"), self.timespanbegin), + getConfigListEntry(_("End of timespan"), self.timespanend) + )) - self.list.append(getConfigListEntry(_("Custom offset"), self.offset)) + list.append(getConfigListEntry(_("Custom offset"), self.offset)) # Only allow editing offsets when it's enabled if self.offset.value: - self.list.extend([ + list.extend(( getConfigListEntry(_("Offset before recording (in m)"), self.offsetbegin), getConfigListEntry(_("Offset after recording (in m)"), self.offsetend) - ]) + )) - self.list.append(getConfigListEntry(_("Set maximum Duration"), self.duration)) + list.append(getConfigListEntry(_("Set maximum duration"), self.duration)) # Only allow editing maxduration when it's enabled if self.duration.value: - self.list.append(getConfigListEntry(_("Maximum Duration (in m)"), self.durationlength)) + list.append(getConfigListEntry(_("Maximum duration (in m)"), self.durationlength)) - self.list.append(getConfigListEntry(_("After event"), self.afterevent)) + list.append(getConfigListEntry(_("After event"), self.afterevent)) # Only allow setting afterevent timespan when afterevent is active if self.afterevent.value != "default": - self.list.append(getConfigListEntry(_("Execute after Event during Timespan"), self.afterevent_timespan)) + list.append(getConfigListEntry(_("Execute \"after event\" during timespan"), self.afterevent_timespan)) # Only allow editing timespan when it's enabled if self.afterevent_timespan.value: - self.list.extend([ - getConfigListEntry(_("Begin of after Event Timespan"), self.afterevent_timespanbegin), - getConfigListEntry(_("End of after Event Timespan"), self.afterevent_timespanend) - ]) + list.extend(( + getConfigListEntry(_("Begin of \"after event\" timespan"), self.afterevent_timespanbegin), + getConfigListEntry(_("End of \"after event\" timespan"), self.afterevent_timespanend) + )) - self.list.append(getConfigListEntry(_("Record a maximum of x times"), self.counter)) + list.append(getConfigListEntry(_("Record a maximum of x times"), self.counter)) # Only allow setting matchLeft when counting hits if self.counter.value: if not self.editingDefaults: - self.list.append(getConfigListEntry(_("Ammount of recordings left"), self.counterLeft)) - self.list.append(getConfigListEntry(_("Reset Count"), self.counterFormatString)) + list.append(getConfigListEntry(_("Ammount of recordings left"), self.counterLeft)) + list.append(getConfigListEntry(_("Reset count"), self.counterFormatString)) - self.list.append(getConfigListEntry(_("Require Description to be unique"), self.avoidDuplicateDescription)) + list.append(getConfigListEntry(_("Require description to be unique"), self.avoidDuplicateDescription)) # We always add this option though its expert only in enigma2 - self.list.append(getConfigListEntry(_("Use a custom location"), self.useDestination)) + list.append(getConfigListEntry(_("Use a custom location"), self.useDestination)) if self.useDestination.value: - self.list.append(getConfigListEntry(_("Custom Location"), self.destination)) + list.append(getConfigListEntry(_("Custom location"), self.destination)) + + list.append(getConfigListEntry(_("Tags"), self.tags)) + + self.list = list def reloadList(self, value): self.refresh() @@ -432,11 +593,29 @@ class AutoTimerEditor(Screen, ConfigListScreen, AutoTimerEditorBase): self.bouquets = ret[1][1] self.renameServiceButton() + def keyLeft(self): + cur = self["config"].getCurrent() + cur = cur and cur[1] + if cur == self.tags: + self.chooseTags() + else: + ConfigListScreen.keyLeft(self) + + def keyRight(self): + cur = self["config"].getCurrent() + cur = cur and cur[1] + if cur == self.tags: + self.chooseTags() + else: + ConfigListScreen.keyRight(self) + def ok(self): cur = self["config"].getCurrent() cur = cur and cur[1] if cur == self.destination: self.chooseDestination() + elif cur == self.tags: + self.chooseTags() else: ConfigListScreen.keyOK(self) @@ -455,6 +634,9 @@ class AutoTimerEditor(Screen, ConfigListScreen, AutoTimerEditorBase): self.close(None) def maybeSave(self): + if self.editingDefaults: + self.save() + return # Check if any match is set if not self.match.value.strip(): self.session.open( @@ -488,6 +670,16 @@ class AutoTimerEditor(Screen, ConfigListScreen, AutoTimerEditorBase): # Name self.timer.name = self.name.value.strip() or self.timer.match + # Encoding + self.timer.encoding = self.encoding.value + + # ... + self.timer.searchType = self.searchType.value + self.timer.searchCase = self.searchCase.value + + # Alternatives + self.timer.overrideAlternatives = self.overrideAlternatives.value + # Enabled self.timer.enabled = self.enabled.value @@ -520,7 +712,12 @@ class AutoTimerEditor(Screen, ConfigListScreen, AutoTimerEditorBase): if self.afterevent.value == "default": self.timer.afterevent = [] else: - afterevent = {"nothing": AFTEREVENT.NONE, "deepstandby": AFTEREVENT.DEEPSTANDBY, "standby": AFTEREVENT.STANDBY}[self.afterevent.value] + afterevent = { + "nothing": AFTEREVENT.NONE, + "deepstandby": AFTEREVENT.DEEPSTANDBY, + "standby": AFTEREVENT.STANDBY, + "auto": AFTEREVENT.AUTO + }[self.afterevent.value] # AfterEvent Timespan if self.afterevent_timespan.value: start = self.afterevent_timespanbegin.value @@ -566,35 +763,42 @@ class AutoTimerEditor(Screen, ConfigListScreen, AutoTimerEditorBase): else: self.timer.destination = None + self.timer.tags = self.timerentry_tags + # Close self.close(self.timer) class AutoTimerFilterEditor(Screen, ConfigListScreen): """Edit AutoTimer Filter""" - skin = """ - - - - - - - - - + skin = """ + + + + + + + + + """ def __init__(self, session, filterset, excludes, includes): Screen.__init__(self, session) # Summary - self.setup_title = "AutoTimer Filters" + self.setup_title = _("AutoTimer Filters") self.onChangedEntry = [] - self.typeSelection = ConfigSelection(choices = [("title", _("in Title")), ("short", _("in Shortdescription")), ("desc", _("in Description")), ("day", _("on Weekday"))]) + self.typeSelection = NoSave(ConfigSelection(choices = [ + ("title", _("in Title")), + ("short", _("in Shortdescription")), + ("desc", _("in Description")), + ("day", _("on Weekday"))] + )) self.typeSelection.addNotifier(self.refresh, initial_call = False) - self.enabled = ConfigEnableDisable(default = filterset) + self.enabled = NoSave(ConfigEnableDisable(default = filterset)) self.excludes = excludes self.includes = includes @@ -604,10 +808,10 @@ class AutoTimerFilterEditor(Screen, ConfigListScreen): ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed) # Initialize Buttons - self["key_red"] = Button(_("Cancel")) - self["key_green"] = Button(_("Save")) - self["key_yellow"] = Button(_("delete")) - self["key_blue"] = Button(_("New")) + self["key_red"] = StaticText(_("Cancel")) + self["key_green"] = StaticText(_("Save")) + self["key_yellow"] = StaticText(_("delete")) + self["key_blue"] = StaticText(_("New")) # Define Actions self["actions"] = ActionMap(["SetupActions", "ColorActions"], @@ -622,11 +826,17 @@ class AutoTimerFilterEditor(Screen, ConfigListScreen): # Trigger change self.changed() + self.onLayoutFinish.append(self.setCustomTitle) + + def setCustomTitle(self): + self.setTitle(_("Edit AutoTimer filters")) + + def changed(self): for x in self.onChangedEntry: try: x() - except: + except Exception: pass def getCurrentEntry(self): @@ -672,12 +882,12 @@ class AutoTimerFilterEditor(Screen, ConfigListScreen): # Weekdays are presented as ConfigSelection self.list.extend([ - getConfigListEntry(_("Exclude"), ConfigSelection(choices = weekdays, default = x)) + getConfigListEntry(_("Exclude"), NoSave(ConfigSelection(choices = weekdays, default = x))) for x in self.excludes[3] ]) self.lenExcludes = len(self.list) self.list.extend([ - getConfigListEntry(_("Include"), ConfigSelection(choices = weekdays, default = x)) + getConfigListEntry(_("Include"), NoSave(ConfigSelection(choices = weekdays, default = x))) for x in self.includes[3] ]) return @@ -689,12 +899,12 @@ class AutoTimerFilterEditor(Screen, ConfigListScreen): self.idx = 2 self.list.extend([ - getConfigListEntry(_("Exclude"), ConfigText(default = x, fixed_size = False)) + getConfigListEntry(_("Exclude"), NoSave(ExtendedConfigText(default = x, fixed_size = False))) for x in self.excludes[self.idx] ]) self.lenExcludes = len(self.list) self.list.extend([ - getConfigListEntry(_("Include"), ConfigText(default = x, fixed_size = False)) + getConfigListEntry(_("Include"), NoSave(ExtendedConfigText(default = x, fixed_size = False))) for x in self.includes[self.idx] ]) @@ -732,9 +942,9 @@ class AutoTimerFilterEditor(Screen, ConfigListScreen): text = ret[0] if self.typeSelection.value == "day": - entry = getConfigListEntry(text, ConfigSelection(choices = weekdays)) + entry = getConfigListEntry(text, NoSave(ConfigSelection(choices = weekdays))) else: - entry = getConfigListEntry(text, ConfigText(fixed_size = False)) + entry = getConfigListEntry(text, NoSave(ExtendedConfigText(fixed_size = False))) list.insert(pos, entry) self["config"].setList(list) @@ -765,23 +975,23 @@ class AutoTimerFilterEditor(Screen, ConfigListScreen): class AutoTimerServiceEditor(Screen, ConfigListScreen): """Edit allowed Services of a AutoTimer""" - skin = """ - - - - - - - - - + skin = """ + + + + + + + + + """ def __init__(self, session, servicerestriction, servicelist, bouquetlist): Screen.__init__(self, session) # Summary - self.setup_title = "AutoTimer Services" + self.setup_title = _("AutoTimer Services") self.onChangedEntry = [] self.services = ( @@ -789,8 +999,11 @@ class AutoTimerServiceEditor(Screen, ConfigListScreen): bouquetlist[:] ) - self.enabled = ConfigEnableDisable(default = servicerestriction) - self.typeSelection = ConfigSelection(choices = [("channels", _("Channels")), ("bouquets", _("Bouquets"))]) + self.enabled = NoSave(ConfigEnableDisable(default = servicerestriction)) + self.typeSelection = NoSave(ConfigSelection(choices = [ + ("channels", _("Channels")), + ("bouquets", _("Bouquets"))] + )) self.typeSelection.addNotifier(self.refresh, initial_call = False) self.reloadList() @@ -798,10 +1011,10 @@ class AutoTimerServiceEditor(Screen, ConfigListScreen): ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed) # Initialize Buttons - self["key_red"] = Button(_("Cancel")) - self["key_green"] = Button(_("OK")) - self["key_yellow"] = Button(_("delete")) - self["key_blue"] = Button(_("New")) + self["key_red"] = StaticText(_("Cancel")) + self["key_green"] = StaticText(_("OK")) + self["key_yellow"] = StaticText(_("delete")) + self["key_blue"] = StaticText(_("New")) # Define Actions self["actions"] = ActionMap(["SetupActions", "ColorActions"], @@ -816,10 +1029,14 @@ class AutoTimerServiceEditor(Screen, ConfigListScreen): # Trigger change self.changed() - + self.onLayoutFinish.append(self.setCustomTitle) + + def setCustomTitle(self): + self.setTitle(_("Edit AutoTimer services")) + def saveCurrent(self): del self.services[self.idx][:] - + # Warning, accessing a ConfigListEntry directly might be considered evil! myl = self["config"].getList()[:] @@ -839,14 +1056,14 @@ class AutoTimerServiceEditor(Screen, ConfigListScreen): getConfigListEntry(_("Enable Service Restriction"), self.enabled), getConfigListEntry(_("Editing"), self.typeSelection) ] - + if self.typeSelection.value == "channels": self.idx = 0 else: # self.typeSelection.value == "bouquets": self.idx = 1 self.list.extend([ - getConfigListEntry(_("Record on"), ConfigSelection(choices = [(str(x), ServiceReference(str(x)).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))])) + getConfigListEntry(_("Record on"), NoSave(ConfigSelection(choices = [(str(x), ServiceReference(str(x)).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))]))) for x in self.services[self.idx] ]) @@ -854,7 +1071,7 @@ class AutoTimerServiceEditor(Screen, ConfigListScreen): for x in self.onChangedEntry: try: x() - except: + except Exception: pass def getCurrentEntry(self): @@ -887,17 +1104,19 @@ class AutoTimerServiceEditor(Screen, ConfigListScreen): ) def finishedServiceSelection(self, *args): - if len(args): + if args: list = self["config"].getList() sname = args[0].toString() - if self.typeSelection.value == "channels": - # strip all after last : when adding a channel + if self.typeSelection.value == "channels" and not (args[0].flags & eServiceReference.isGroup): + # strip all after last : when adding a (non alternative) channel pos = sname.rfind(':') if pos != -1: + if sname[pos-1] == ':': + pos -= 1 sname = sname[:pos+1] - list.append(getConfigListEntry(_("Record on"), ConfigSelection(choices = [(sname, ServiceReference(args[0]).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))]))) + list.append(getConfigListEntry(_("Record on"), NoSave(ConfigSelection(choices = [(sname, ServiceReference(args[0]).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))])))) self["config"].setList(list) def cancel(self): @@ -922,29 +1141,65 @@ class AutoTimerServiceEditor(Screen, ConfigListScreen): self.services )) +def addAutotimerFromSearchString(session, match): + from AutoTimerComponent import preferredAutoTimerComponent + from AutoTimerImporter import AutoTimerImporter + from plugin import autotimer + + # Create instance if needed + if autotimer is None: + from AutoTimer import AutoTimer + autotimer = AutoTimer() + autotimer.readXml() + + session.openWithCallback( + importerCallback, + AutoTimerImporter, + preferredAutoTimerComponent( + autotimer.getUniqueId(), + match, + '', # Match + True # Enabled + ), + match, # Proposed Match + None, # Proposed Begin + None, # Proposed End + None, # Proposed Disabled + None, # Proposed ServiceReference + None, # Proposed afterEvent + None, # Proposed justplay + None, # Proposed dirname, can we get anything useful here? + [] # Proposed tags + ) + def addAutotimerFromEvent(session, evt = None, service = None): - from AutoTimerComponent import AutoTimerComponent + from AutoTimerComponent import preferredAutoTimerComponent from AutoTimerImporter import AutoTimerImporter from plugin import autotimer - + # Create instance if needed if autotimer is None: from AutoTimer import AutoTimer autotimer = AutoTimer() + autotimer.readXml() match = evt and evt.getEventName() or "" name = match or "New AutoTimer" sref = None if service is not None: service = str(service) - # strip all after last : - pos = service.rfind(':') - if pos != -1: - service = service[:pos+1] - - sref = ServiceReference(service) + myref = eServiceReference(service) + if not (myref.flags & eServiceReference.isGroup): + # strip all after last : + pos = service.rfind(':') + if pos != -1: + if service[pos-1] == ':': + pos -= 1 + service = service[:pos+1] + + sref = ServiceReference(myref) if evt: - # timespan defaults to +- 1h + # timespan defaults to +- 1h begin = evt.getBeginTime()-3600 end = begin + evt.getDuration()+7200 else: @@ -955,31 +1210,33 @@ def addAutotimerFromEvent(session, evt = None, service = None): session.openWithCallback( importerCallback, AutoTimerImporter, - AutoTimerComponent( - autotimer.getUniqueId(), # Id - name, # Name - "", # Match - True # Enabled + preferredAutoTimerComponent( + autotimer.getUniqueId(), + name, + '', # Match + True # Enabled ), - match, # Proposed Match - begin, # Proposed Begin - end, # Proposed End - None, # Proposed Disabled - sref, # Proposed ServiceReference - None, # Proposed afterEvent - None, # Proposed justplay - None # Proposed dirname, can we get anything useful here? + match, # Proposed Match + begin, # Proposed Begin + end, # Proposed End + None, # Proposed Disabled + sref, # Proposed ServiceReference + None, # Proposed afterEvent + None, # Proposed justplay + None, # Proposed dirname, can we get anything useful here? + [] # Proposed tags ) -def addAutotimerFromService(session, service = None): - from AutoTimerComponent import AutoTimerComponent +def addAutotimerFromService(session, service = None): + from AutoTimerComponent import preferredAutoTimerComponent from AutoTimerImporter import AutoTimerImporter from plugin import autotimer - + # Create instance if needed if autotimer is None: from AutoTimer import AutoTimer autotimer = AutoTimer() + autotimer.readXml() serviceHandler = eServiceCenter.getInstance() info = serviceHandler.info(service) @@ -991,6 +1248,8 @@ def addAutotimerFromService(session, service = None): # strip all after last : pos = sref.rfind(':') if pos != -1: + if sref[pos-1] == ':': + pos -= 1 sref = sref[:pos+1] sref = ServiceReference(sref) @@ -1000,31 +1259,40 @@ def addAutotimerFromService(session, service = None): else: begin = end = 0 + from os.path import dirname + path = dirname(service.getPath()) + if not path == '/': + path += '/' + + tags = info.getInfoString(service, iServiceInformation.sTags) + tags = tags and tags.split(' ') or [] + # XXX: we might want to make sure that we actually collected any data because the importer does not do so :-) session.openWithCallback( importerCallback, AutoTimerImporter, - AutoTimerComponent( - autotimer.getUniqueId(), # Id - name, # Name - "", # Match - True # Enabled + preferredAutoTimerComponent( + autotimer.getUniqueId(), + name, + '', # Match + True # Enabled ), - match, # Proposed Match - begin, # Proposed Begin - end, # Proposed End - None, # Proposed Disabled - sref, # Proposed ServiceReference - None, # Proposed afterEvent - None, # Proposed justplay - None # Proposed dirname, can we get anything useful here? + match, # Proposed Match + begin, # Proposed Begin + end, # Proposed End + None, # Proposed Disabled + sref, # Proposed ServiceReference + None, # Proposed afterEvent + None, # Proposed justplay + path, # Proposed dirname + tags # Proposed tags ) def importerCallback(ret): if ret: ret, session = ret - + session.openWithCallback( editorCallback, AutoTimerEditor, @@ -1036,21 +1304,22 @@ def importerCallback(ret): from plugin import autotimer autotimer = None - def editorCallback(ret): if ret: from plugin import autotimer - + # Create instance if needed (should have been created by addAutotimerFrom* above though) if autotimer is None: from AutoTimer import AutoTimer autotimer = AutoTimer() + autotimer.readXml() autotimer.add(ret) - + + # Save modified xml + autotimer.writeXml() + # Remove instance if not running in background if not config.plugins.autotimer.autopoll.value: - # Save xml (as long as we added something) - ret and autotimer and autotimer.writeXml() autotimer = None