1 # -*- coding: UTF-8 -*-
2 # for localized messages
6 from Screens.Screen import Screen
7 from Components.ConfigList import ConfigListScreen
8 from Screens.ChannelSelection import SimpleChannelSelection
9 from Screens.EpgSelection import EPGSelection
10 from Screens.MessageBox import MessageBox
11 from Screens.ChoiceBox import ChoiceBox
14 from Screens.Setup import SetupSummary
17 from Components.ActionMap import ActionMap
18 from Components.Sources.StaticText import StaticText
21 from Components.config import getConfigListEntry, ConfigEnableDisable, \
22 ConfigYesNo, ConfigText, ConfigClock, ConfigNumber, ConfigSelection, \
26 from RecordTimer import AFTEREVENT
28 # Needed to convert our timestamp back and forth
29 from time import localtime, mktime
31 # Show ServiceName instead of ServiceReference
32 from ServiceReference import ServiceReference
34 # addAutotimerFromService, AutoTimerChannelSelection
35 from enigma import eServiceCenter, eServiceReference, iServiceInformation
37 # Default Record Directory
38 from Tools import Directories
41 from Screens.MovieSelection import getPreferredTagEditor
46 ("2", _("Wednesday")),
51 ("weekend", _("Weekend")),
52 ("weekday", _("Weekday"))
55 class ExtendedConfigText(ConfigText):
56 def __init__(self, default = "", fixed_size = True, visible_width = False):
57 ConfigText.__init__(self, default = default, fixed_size = fixed_size, visible_width = visible_width)
59 # Workaround some characters currently not "typeable" using NumericalTextInput
60 mapping = self.mapping
62 if "&" not in mapping[0]:
64 if ";" not in mapping[0]:
66 if "%" not in mapping[0]:
69 class SimpleBouquetSelection(SimpleChannelSelection):
70 def __init__(self, session, title):
71 SimpleChannelSelection.__init__(self, session, title)
72 self.skinName = "SimpleChannelSelection"
74 def channelSelected(self):
75 ref = self.getCurrentSelection()
76 if (ref.flags & 7) == 7:
79 # We return the currently active path here
80 # Asking the user if this is what he wants might be better though
81 self.close(self.servicePath[-1])
83 class AutoTimerChannelSelection(SimpleChannelSelection):
84 def __init__(self, session, autotimer):
85 SimpleChannelSelection.__init__(self, session, _("Channel Selection"))
86 self.skinName = "SimpleChannelSelection"
87 self.autotimer = autotimer
89 self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
91 "showEPGList": self.channelSelected
95 def channelSelected(self):
96 ref = self.getCurrentSelection()
97 if (ref.flags & 7) == 7:
99 elif not (ref.flags & eServiceReference.isMarker):
101 AutoTimerEPGSelection,
105 class AutoTimerEPGSelection(EPGSelection):
106 def __init__(self, *args):
107 EPGSelection.__init__(self, *args)
108 self.skinName = "EPGSelection"
110 def infoKeyPressed(self):
114 cur = self["list"].getCurrent()
120 addAutotimerFromEvent(self.session, evt = evt, service = sref)
122 def onSelectionChanged(self):
125 class AutoTimerEditorBase:
126 """ Base Class for all Editors """
127 def __init__(self, timer, editingDefaults = False):
130 self.editingDefaults = editingDefaults
132 # See if we are filtering some strings
134 timer.getExcludedTitle(),
135 timer.getExcludedShort(),
136 timer.getExcludedDescription(),
137 timer.getExcludedDays()
140 timer.getIncludedTitle(),
141 timer.getIncludedShort(),
142 timer.getIncludedDescription(),
143 timer.getIncludedDays()
145 if excludes[0] or excludes[1] \
146 or excludes[2] or excludes[3] \
147 or includes[0] or includes[1] \
148 or includes[2] or includes[3]:
149 self.filterSet = True
151 self.filterSet = False
152 self.excludes = excludes
153 self.includes = includes
155 # See if services are restricted
156 self.services = timer.services
157 self.bouquets = timer.bouquets
158 if self.services or self.bouquets:
159 self.serviceRestriction = True
161 self.serviceRestriction = False
163 self.createSetup(timer)
165 def createSetup(self, timer):
167 self.name = NoSave(ExtendedConfigText(default = timer.name, fixed_size = False))
170 self.match = NoSave(ExtendedConfigText(default = timer.match, fixed_size = False))
173 default = timer.encoding
174 selection = ['UTF-8', 'ISO8859-15']
175 if default not in selection:
176 selection.append(default)
177 self.encoding = NoSave(ConfigSelection(choices = selection, default = default))
180 self.searchType = NoSave(ConfigSelection(choices = [("partial", _("partial match")), ("exact", _("exact match"))], default = timer.searchType))
181 self.searchCase = NoSave(ConfigSelection(choices = [("sensitive", _("case-sensitive search")), ("insensitive", _("case-insensitive search"))], default = timer.searchCase))
183 # Alternatives override
184 self.overrideAlternatives = NoSave(ConfigYesNo(default = timer.overrideAlternatives))
187 self.justplay = NoSave(ConfigSelection(choices = [("zap", _("zap")), ("record", _("record"))], default = {0: "record", 1: "zap"}[int(timer.justplay)]))
190 now = [x for x in localtime()]
191 if timer.hasTimespan():
193 now[3] = timer.timespan[0][0]
194 now[4] = timer.timespan[0][1]
196 now[3] = timer.timespan[1][0]
197 now[4] = timer.timespan[1][1]
207 self.timespan = NoSave(ConfigEnableDisable(default = default))
208 self.timespanbegin = NoSave(ConfigClock(default = begin))
209 self.timespanend = NoSave(ConfigClock(default = end))
211 # Services have their own Screen
214 if timer.hasOffset():
216 begin = timer.getOffsetBegin()
217 end = timer.getOffsetEnd()
222 self.offset = NoSave(ConfigEnableDisable(default = default))
223 self.offsetbegin = NoSave(ConfigNumber(default = begin))
224 self.offsetend = NoSave(ConfigNumber(default = end))
227 if timer.hasAfterEvent():
230 AFTEREVENT.NONE: "nothing",
231 AFTEREVENT.DEEPSTANDBY: "deepstandby",
232 AFTEREVENT.STANDBY: "standby",
233 AFTEREVENT.AUTO: "auto"
234 }[timer.afterevent[0][0]]
237 self.afterevent = NoSave(ConfigSelection(choices = [
238 ("default", _("standard")), ("nothing", _("do nothing")),
239 ("standby", _("go to standby")),
240 ("deepstandby", _("go to deep standby")),
241 ("auto", _("auto"))], default = default))
243 # AfterEvent (Timespan)
244 if timer.hasAfterEvent() and timer.afterevent[0][1][0] is not None:
246 now[3] = timer.afterevent[0][1][0][0]
247 now[4] = timer.afterevent[0][1][0][1]
249 now[3] = timer.afterevent[0][1][1][0]
250 now[4] = timer.afterevent[0][1][1][1]
260 self.afterevent_timespan = NoSave(ConfigEnableDisable(default = default))
261 self.afterevent_timespanbegin = NoSave(ConfigClock(default = begin))
262 self.afterevent_timespanend = NoSave(ConfigClock(default = end))
265 self.enabled = NoSave(ConfigYesNo(default = timer.enabled))
268 if timer.hasDuration():
270 duration = timer.getDuration()
274 self.duration = NoSave(ConfigEnableDisable(default = default))
275 self.durationlength = NoSave(ConfigNumber(default = duration))
278 if timer.hasCounter():
279 default = timer.matchCount
282 self.counter = NoSave(ConfigNumber(default = default))
283 self.counterLeft = NoSave(ConfigNumber(default = timer.matchLeft))
284 default = timer.getCounterFormatString()
285 selection = [("", _("Never")), ("%m", _("Monthly")), ("%U", _("Weekly (Sunday)")), ("%W", _("Weekly (Monday)"))]
286 if default not in ('', '%m', '%U', '%W'):
287 selection.append((default, _("Custom (%s)") % (default)))
288 self.counterFormatString = NoSave(ConfigSelection(selection, default = default))
290 # Avoid Duplicate Description
291 self.avoidDuplicateDescription = NoSave(ConfigSelection([
293 ("1", _("On same service")),
294 ("2", _("On any service")),
296 default = str(timer.getAvoidDuplicateDescription())
300 if timer.hasDestination():
305 self.useDestination = NoSave(ConfigYesNo(default = default))
307 default = timer.destination or Directories.resolveFilename(Directories.SCOPE_HDD)
308 choices = config.movielist.videodirs.value
310 if default not in choices:
311 choices.append(default)
312 self.destination = NoSave(ConfigSelection(default = default, choices = choices))
315 self.timerentry_tags = timer.tags
316 self.tags = NoSave(ConfigSelection(choices = [len(self.timerentry_tags) == 0 and _("None") or ' '.join(self.timerentry_tags)]))
318 def pathSelected(self, res):
320 # I'm pretty sure this will always fail
321 if config.movielist.videodirs.value != self.destination.choices:
322 self.destination.setChoices(config.movielist.videodirs.value, default = res)
323 self.destination.value = res
325 def chooseDestination(self):
326 from Screens.LocationBox import MovieLocationBox
328 self.session.openWithCallback(
331 _("Choose target folder"),
332 self.destination.value,
333 minFree = 100 # Same requirement as in Screens.TimerEntry
336 def tagEditFinished(self, ret):
338 self.timerentry_tags = ret
339 self.tags.setChoices([len(ret) == 0 and _("None") or ' '.join(ret)])
341 def chooseTags(self):
342 preferredTagEditor = getPreferredTagEditor()
343 if preferredTagEditor:
344 self.session.openWithCallback(
345 self.tagEditFinished,
350 class AutoTimerEditor(Screen, ConfigListScreen, AutoTimerEditorBase):
353 skin = """<screen name="AutoTimerEditor" title="Edit AutoTimer" position="center,center" size="565,280">
354 <widget name="config" position="5,5" size="555,225" scrollbarMode="showOnDemand" />
355 <ePixmap position="0,235" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
356 <ePixmap position="140,235" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
357 <ePixmap position="280,235" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
358 <ePixmap position="420,235" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
359 <widget source="key_red" render="Label" position="0,235" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
360 <widget source="key_green" render="Label" position="140,235" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
361 <widget source="key_yellow" render="Label" position="280,235" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
362 <widget source="key_blue" render="Label" position="420,235" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
365 def __init__(self, session, timer, editingDefaults = False):
366 Screen.__init__(self, session)
368 AutoTimerEditorBase.__init__(self, timer, editingDefaults)
371 self.setup_title = _("AutoTimer Editor")
372 self.onChangedEntry = []
374 # We might need to change shown items, so add some notifiers
375 self.timespan.addNotifier(self.reloadList, initial_call = False)
376 self.offset.addNotifier(self.reloadList, initial_call = False)
377 self.duration.addNotifier(self.reloadList, initial_call = False)
378 self.afterevent.addNotifier(self.reloadList, initial_call = False)
379 self.afterevent_timespan.addNotifier(self.reloadList, initial_call = False)
380 self.counter.addNotifier(self.reloadList, initial_call = False)
381 self.useDestination.addNotifier(self.reloadList, initial_call = False)
385 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
388 self["key_red"] = StaticText(_("Cancel"))
389 self["key_green"] = StaticText(_("OK"))
390 self["key_yellow"] = StaticText()
391 self["key_blue"] = StaticText()
394 self.renameServiceButton()
395 self.renameFilterButton()
398 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
400 "cancel": self.cancel,
401 "save": self.maybeSave,
403 "yellow": self.editFilter,
404 "blue": self.editServices
411 self.onLayoutFinish.append(self.setCustomTitle)
413 def setCustomTitle(self):
414 self.setTitle(_("Edit AutoTimer"))
416 def renameFilterButton(self):
418 self["key_yellow"].setText(_("Edit Filters"))
420 self["key_yellow"].setText(_("Add Filters"))
422 def renameServiceButton(self):
423 if self.serviceRestriction:
424 self["key_blue"].setText(_("Edit Services"))
426 self["key_blue"].setText(_("Add Services"))
429 for x in self.onChangedEntry:
435 def getCurrentEntry(self):
436 return self["config"].getCurrent()[0]
438 def getCurrentValue(self):
439 return str(self["config"].getCurrent()[1].getText())
441 def createSummary(self):
445 # First three entries are only showed when not editing defaults
447 if not self.editingDefaults:
449 getConfigListEntry(_("Enabled"), self.enabled),
450 getConfigListEntry(_("Description"), self.name),
451 getConfigListEntry(_("Match Title"), self.match),
455 getConfigListEntry(_("EPG Encoding"), self.encoding),
456 getConfigListEntry(_("Search Type"), self.searchType),
457 getConfigListEntry(_("Search strictness"), self.searchCase),
458 getConfigListEntry(_("Timer Type"), self.justplay),
459 getConfigListEntry(_("Override found with alternative Service"), self.overrideAlternatives),
460 getConfigListEntry(_("Only match during Timespan"), self.timespan)
463 # Only allow editing timespan when it's enabled
464 if self.timespan.value:
466 getConfigListEntry(_("Begin of Timespan"), self.timespanbegin),
467 getConfigListEntry(_("End of Timespan"), self.timespanend)
470 list.append(getConfigListEntry(_("Custom offset"), self.offset))
472 # Only allow editing offsets when it's enabled
473 if self.offset.value:
475 getConfigListEntry(_("Offset before recording (in m)"), self.offsetbegin),
476 getConfigListEntry(_("Offset after recording (in m)"), self.offsetend)
479 list.append(getConfigListEntry(_("Set maximum Duration"), self.duration))
481 # Only allow editing maxduration when it's enabled
482 if self.duration.value:
483 list.append(getConfigListEntry(_("Maximum Duration (in m)"), self.durationlength))
485 list.append(getConfigListEntry(_("After event"), self.afterevent))
487 # Only allow setting afterevent timespan when afterevent is active
488 if self.afterevent.value != "default":
489 list.append(getConfigListEntry(_("Execute after Event during Timespan"), self.afterevent_timespan))
491 # Only allow editing timespan when it's enabled
492 if self.afterevent_timespan.value:
494 getConfigListEntry(_("Begin of after Event Timespan"), self.afterevent_timespanbegin),
495 getConfigListEntry(_("End of after Event Timespan"), self.afterevent_timespanend)
498 list.append(getConfigListEntry(_("Record a maximum of x times"), self.counter))
500 # Only allow setting matchLeft when counting hits
501 if self.counter.value:
502 if not self.editingDefaults:
503 list.append(getConfigListEntry(_("Ammount of recordings left"), self.counterLeft))
504 list.append(getConfigListEntry(_("Reset Count"), self.counterFormatString))
506 list.append(getConfigListEntry(_("Require Description to be unique"), self.avoidDuplicateDescription))
508 # We always add this option though its expert only in enigma2
509 list.append(getConfigListEntry(_("Use a custom location"), self.useDestination))
510 if self.useDestination.value:
511 list.append(getConfigListEntry(_("Custom Location"), self.destination))
513 list.append(getConfigListEntry(_("Tags"), self.tags))
517 def reloadList(self, value):
519 self["config"].setList(self.list)
521 def editFilter(self):
522 self.session.openWithCallback(
523 self.editFilterCallback,
524 AutoTimerFilterEditor,
530 def editFilterCallback(self, ret):
532 self.filterSet = ret[0]
533 self.excludes = ret[1]
534 self.includes = ret[2]
535 self.renameFilterButton()
537 def editServices(self):
538 self.session.openWithCallback(
539 self.editServicesCallback,
540 AutoTimerServiceEditor,
541 self.serviceRestriction,
546 def editServicesCallback(self, ret):
548 self.serviceRestriction = ret[0]
549 self.services = ret[1][0]
550 self.bouquets = ret[1][1]
551 self.renameServiceButton()
554 cur = self["config"].getCurrent()
559 ConfigListScreen.keyLeft(self)
562 cur = self["config"].getCurrent()
567 ConfigListScreen.keyRight(self)
570 cur = self["config"].getCurrent()
572 if cur == self.destination:
573 self.chooseDestination()
574 elif cur == self.tags:
577 ConfigListScreen.keyOK(self)
580 if self["config"].isChanged():
581 self.session.openWithCallback(
584 _("Really close without saving settings?")
589 def cancelConfirm(self, ret):
594 if self.editingDefaults:
597 # Check if any match is set
598 if not self.match.value.strip():
601 _("The match attribute is mandatory."),
602 type = MessageBox.TYPE_ERROR,
605 # Check if we have a trailing whitespace
606 elif self.match.value[-1:] == " ":
607 self.session.openWithCallback(
610 _('You entered "%s" as Text to match.\nDo you want to remove trailing whitespaces?') % (self.match.value)
616 def saveCallback(self, ret):
619 self.match.value = self.match.value.rstrip()
621 # Don't to anything if MessageBox was canceled!
625 self.timer.match = self.match.value
628 self.timer.name = self.name.value.strip() or self.timer.match
631 self.timer.encoding = self.encoding.value
634 self.timer.searchType = self.searchType.value
635 self.timer.searchCase = self.searchCase.value
638 self.timer.overrideAlternatives = self.overrideAlternatives.value
641 self.timer.enabled = self.enabled.value
644 self.timer.justplay = self.justplay.value == "zap"
647 if self.timespan.value:
648 start = self.timespanbegin.value
649 end = self.timespanend.value
650 self.timer.timespan = (start, end)
652 self.timer.timespan = None
655 if self.serviceRestriction:
656 self.timer.services = self.services
657 self.timer.bouquets = self.bouquets
659 self.timer.services = None
660 self.timer.bouquets = None
663 if self.offset.value:
664 self.timer.offset = (self.offsetbegin.value*60, self.offsetend.value*60)
666 self.timer.offset = None
669 if self.afterevent.value == "default":
670 self.timer.afterevent = []
673 "nothing": AFTEREVENT.NONE,
674 "deepstandby": AFTEREVENT.DEEPSTANDBY,
675 "standby": AFTEREVENT.STANDBY,
676 "auto": AFTEREVENT.AUTO
677 }[self.afterevent.value]
678 # AfterEvent Timespan
679 if self.afterevent_timespan.value:
680 start = self.afterevent_timespanbegin.value
681 end = self.afterevent_timespanend.value
682 self.timer.afterevent = [(afterevent, (start, end))]
684 self.timer.afterevent = [(afterevent, None)]
687 if self.duration.value:
688 self.timer.maxduration = self.durationlength.value*60
690 self.timer.maxduration = None
694 self.timer.exclude = self.excludes
695 self.timer.include = self.includes
697 self.timer.exclude = None
698 self.timer.include = None
701 if self.counter.value:
702 self.timer.matchCount = self.counter.value
703 if self.counterLeft.value <= self.counter.value:
704 self.timer.matchLeft = self.counterLeft.value
706 self.timer.matchLeft = self.counter.value
707 if self.counterFormatString.value:
708 self.timer.matchFormatString = self.counterFormatString.value
710 self.timer.matchFormatString = ''
712 self.timer.matchCount = 0
713 self.timer.matchLeft = 0
714 self.timer.matchFormatString = ''
716 self.timer.avoidDuplicateDescription = int(self.avoidDuplicateDescription.value)
718 if self.useDestination.value:
719 self.timer.destination = self.destination.value
721 self.timer.destination = None
723 self.timer.tags = self.timerentry_tags
726 self.close(self.timer)
728 class AutoTimerFilterEditor(Screen, ConfigListScreen):
729 """Edit AutoTimer Filter"""
731 skin = """<screen name="AutoTimerFilterEditor" title="Edit AutoTimer Filters" position="center,center" size="565,280">
732 <widget name="config" position="5,5" size="555,225" scrollbarMode="showOnDemand" />
733 <ePixmap position="0,235" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
734 <ePixmap position="140,235" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
735 <ePixmap position="280,235" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
736 <ePixmap position="420,235" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
737 <widget source="key_red" render="Label" position="0,235" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
738 <widget source="key_green" render="Label" position="140,235" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
739 <widget source="key_yellow" render="Label" position="280,235" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
740 <widget source="key_blue" render="Label" position="420,235" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
743 def __init__(self, session, filterset, excludes, includes):
744 Screen.__init__(self, session)
747 self.setup_title = _("AutoTimer Filters")
748 self.onChangedEntry = []
750 self.typeSelection = NoSave(ConfigSelection(choices = [
751 ("title", _("in Title")),
752 ("short", _("in Shortdescription")),
753 ("desc", _("in Description")),
754 ("day", _("on Weekday"))]
756 self.typeSelection.addNotifier(self.refresh, initial_call = False)
758 self.enabled = NoSave(ConfigEnableDisable(default = filterset))
760 self.excludes = excludes
761 self.includes = includes
765 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
768 self["key_red"] = StaticText(_("Cancel"))
769 self["key_green"] = StaticText(_("Save"))
770 self["key_yellow"] = StaticText(_("delete"))
771 self["key_blue"] = StaticText(_("New"))
774 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
776 "cancel": self.cancel,
778 "yellow": self.remove,
786 self.onLayoutFinish.append(self.setCustomTitle)
788 def setCustomTitle(self):
789 self.setTitle(_("Edit AutoTimer Filters"))
793 for x in self.onChangedEntry:
799 def getCurrentEntry(self):
800 return self["config"].getCurrent()[0]
802 def getCurrentValue(self):
803 return str(self["config"].getCurrent()[1].getText())
805 def createSummary(self):
808 def saveCurrent(self):
809 del self.excludes[self.idx][:]
810 del self.includes[self.idx][:]
812 # Warning, accessing a ConfigListEntry directly might be considered evil!
815 for item in self["config"].getList()[:]:
817 # Skip empty entries (and those which are no filters)
818 if item[1].value == "" or idx < 2:
820 elif idx < self.lenExcludes:
821 self.excludes[self.idx].append(item[1].value.encode("UTF-8"))
823 self.includes[self.idx].append(item[1].value.encode("UTF-8"))
825 def refresh(self, *args, **kwargs):
829 self["config"].setList(self.list)
831 def reloadList(self):
833 getConfigListEntry(_("Enable Filtering"), self.enabled),
834 getConfigListEntry(_("Filter"), self.typeSelection)
837 if self.typeSelection.value == "day":
840 # Weekdays are presented as ConfigSelection
842 getConfigListEntry(_("Exclude"), NoSave(ConfigSelection(choices = weekdays, default = x)))
843 for x in self.excludes[3]
845 self.lenExcludes = len(self.list)
847 getConfigListEntry(_("Include"), NoSave(ConfigSelection(choices = weekdays, default = x)))
848 for x in self.includes[3]
851 elif self.typeSelection.value == "title":
853 elif self.typeSelection.value == "short":
855 else: # self.typeSelection.value == "desc":
859 getConfigListEntry(_("Exclude"), NoSave(ExtendedConfigText(default = x, fixed_size = False)))
860 for x in self.excludes[self.idx]
862 self.lenExcludes = len(self.list)
864 getConfigListEntry(_("Include"), NoSave(ExtendedConfigText(default = x, fixed_size = False)))
865 for x in self.includes[self.idx]
869 idx = self["config"].getCurrentIndex()
871 if idx < self.lenExcludes:
872 self.lenExcludes -= 1
874 list = self["config"].getList()
875 list.remove(self["config"].getCurrent())
876 self["config"].setList(list)
879 self.session.openWithCallback(
882 _("Select type of Filter"),
889 def typeSelected(self, ret):
891 list = self["config"].getList()
894 pos = self.lenExcludes
895 self.lenExcludes += 1
901 if self.typeSelection.value == "day":
902 entry = getConfigListEntry(text, NoSave(ConfigSelection(choices = weekdays)))
904 entry = getConfigListEntry(text, NoSave(ExtendedConfigText(fixed_size = False)))
906 list.insert(pos, entry)
907 self["config"].setList(list)
910 if self["config"].isChanged():
911 self.session.openWithCallback(
914 _("Really close without saving settings?")
919 def cancelConfirm(self, ret):
932 class AutoTimerServiceEditor(Screen, ConfigListScreen):
933 """Edit allowed Services of a AutoTimer"""
935 skin = """<screen name="AutoTimerServiceEditor" title="Edit AutoTimer Services" position="center,center" size="565,280">
936 <widget name="config" position="5,5" size="555,225" scrollbarMode="showOnDemand" />
937 <ePixmap position="0,235" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
938 <ePixmap position="140,235" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
939 <ePixmap position="280,235" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
940 <ePixmap position="420,235" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
941 <widget source="key_red" render="Label" position="0,235" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
942 <widget source="key_green" render="Label" position="140,235" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
943 <widget source="key_yellow" render="Label" position="280,235" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
944 <widget source="key_blue" render="Label" position="420,235" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
947 def __init__(self, session, servicerestriction, servicelist, bouquetlist):
948 Screen.__init__(self, session)
951 self.setup_title = _("AutoTimer Services")
952 self.onChangedEntry = []
959 self.enabled = NoSave(ConfigEnableDisable(default = servicerestriction))
960 self.typeSelection = NoSave(ConfigSelection(choices = [
961 ("channels", _("Channels")),
962 ("bouquets", _("Bouquets"))]
964 self.typeSelection.addNotifier(self.refresh, initial_call = False)
968 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
971 self["key_red"] = StaticText(_("Cancel"))
972 self["key_green"] = StaticText(_("OK"))
973 self["key_yellow"] = StaticText(_("delete"))
974 self["key_blue"] = StaticText(_("New"))
977 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
979 "cancel": self.cancel,
981 "yellow": self.remove,
989 self.onLayoutFinish.append(self.setCustomTitle)
991 def setCustomTitle(self):
992 self.setTitle(_("Edit AutoTimer Services"))
994 def saveCurrent(self):
995 del self.services[self.idx][:]
997 # Warning, accessing a ConfigListEntry directly might be considered evil!
999 myl = self["config"].getList()[:]
1000 myl.pop(0) # Enabled
1003 self.services[self.idx].append(item[1].value)
1005 def refresh(self, *args, **kwargs):
1009 self["config"].setList(self.list)
1011 def reloadList(self):
1013 getConfigListEntry(_("Enable Service Restriction"), self.enabled),
1014 getConfigListEntry(_("Editing"), self.typeSelection)
1017 if self.typeSelection.value == "channels":
1019 else: # self.typeSelection.value == "bouquets":
1023 getConfigListEntry(_("Record on"), NoSave(ConfigSelection(choices = [(str(x), ServiceReference(str(x)).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))])))
1024 for x in self.services[self.idx]
1028 for x in self.onChangedEntry:
1034 def getCurrentEntry(self):
1035 return self["config"].getCurrent()[0]
1037 def getCurrentValue(self):
1038 return str(self["config"].getCurrent()[1].getText())
1040 def createSummary(self):
1044 if self["config"].getCurrentIndex() != 0:
1045 list = self["config"].getList()
1046 list.remove(self["config"].getCurrent())
1047 self["config"].setList(list)
1050 if self.typeSelection.value == "channels":
1051 self.session.openWithCallback(
1052 self.finishedServiceSelection,
1053 SimpleChannelSelection,
1054 _("Select channel to record on")
1056 else: # self.typeSelection.value == "bouquets":
1057 self.session.openWithCallback(
1058 self.finishedServiceSelection,
1059 SimpleBouquetSelection,
1060 _("Select bouquet to record on")
1063 def finishedServiceSelection(self, *args):
1065 list = self["config"].getList()
1066 sname = args[0].toString()
1068 if self.typeSelection.value == "channels" and not (args[0].flags & eServiceReference.isGroup):
1069 # strip all after last : when adding a (non alternative) channel
1070 pos = sname.rfind(':')
1072 if sname[pos-1] == ':'
1074 sname = sname[:pos+1]
1076 list.append(getConfigListEntry(_("Record on"), NoSave(ConfigSelection(choices = [(sname, ServiceReference(args[0]).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))]))))
1077 self["config"].setList(list)
1080 if self["config"].isChanged():
1081 self.session.openWithCallback(
1084 _("Really close without saving settings?")
1089 def cancelConfirm(self, ret):
1101 def addAutotimerFromSearchString(session, match):
1102 from AutoTimerComponent import AutoTimerComponent
1103 from AutoTimerImporter import AutoTimerImporter
1104 from plugin import autotimer
1106 # Create instance if needed
1107 if autotimer is None:
1108 from AutoTimer import AutoTimer
1109 autotimer = AutoTimer()
1112 session.openWithCallback(
1116 autotimer.getUniqueId(),
1121 match, # Proposed Match
1122 None, # Proposed Begin
1123 None, # Proposed End
1124 None, # Proposed Disabled
1125 None, # Proposed ServiceReference
1126 None, # Proposed afterEvent
1127 None, # Proposed justplay
1128 None, # Proposed dirname, can we get anything useful here?
1132 def addAutotimerFromEvent(session, evt = None, service = None):
1133 from AutoTimerComponent import AutoTimerComponent
1134 from AutoTimerImporter import AutoTimerImporter
1135 from plugin import autotimer
1137 # Create instance if needed
1138 if autotimer is None:
1139 from AutoTimer import AutoTimer
1140 autotimer = AutoTimer()
1143 match = evt and evt.getEventName() or ""
1144 name = match or "New AutoTimer"
1146 if service is not None:
1147 service = str(service)
1148 myref = eServiceReference(service)
1149 if not (myref.flags & eServiceReference.isGroup):
1150 # strip all after last :
1151 pos = service.rfind(':')
1153 if service[pos-1] == ':'
1155 service = service[:pos+1]
1157 sref = ServiceReference(myref)
1159 # timespan defaults to +- 1h
1160 begin = evt.getBeginTime()-3600
1161 end = begin + evt.getDuration()+7200
1165 # XXX: we might want to make sure that we actually collected any data because the importer does not do so :-)
1167 session.openWithCallback(
1171 autotimer.getUniqueId(),
1176 match, # Proposed Match
1177 begin, # Proposed Begin
1179 None, # Proposed Disabled
1180 sref, # Proposed ServiceReference
1181 None, # Proposed afterEvent
1182 None, # Proposed justplay
1183 None, # Proposed dirname, can we get anything useful here?
1187 def addAutotimerFromService(session, service = None):
1188 from AutoTimerComponent import AutoTimerComponent
1189 from AutoTimerImporter import AutoTimerImporter
1190 from plugin import autotimer
1192 # Create instance if needed
1193 if autotimer is None:
1194 from AutoTimer import AutoTimer
1195 autotimer = AutoTimer()
1198 serviceHandler = eServiceCenter.getInstance()
1199 info = serviceHandler.info(service)
1201 match = info and info.getName(service) or ""
1202 name = match or "New AutoTimer"
1203 sref = info and info.getInfoString(service, iServiceInformation.sServiceref)
1205 # strip all after last :
1206 pos = sref.rfind(':')
1208 if sref[pos-1] == ':'
1212 sref = ServiceReference(sref)
1214 begin = info.getInfo(service, iServiceInformation.sTimeCreate)
1215 end = begin + info.getLength(service)
1219 from os.path import dirname
1220 path = dirname(service.getPath())
1224 tags = info.getInfoString(service, iServiceInformation.sTags)
1225 tags = tags and tags.split(' ') or []
1227 # XXX: we might want to make sure that we actually collected any data because the importer does not do so :-)
1229 session.openWithCallback(
1233 autotimer.getUniqueId(),
1238 match, # Proposed Match
1239 begin, # Proposed Begin
1241 None, # Proposed Disabled
1242 sref, # Proposed ServiceReference
1243 None, # Proposed afterEvent
1244 None, # Proposed justplay
1245 path, # Proposed dirname
1246 tags # Proposed tags
1249 def importerCallback(ret):
1253 session.openWithCallback(
1259 # Remove instance if not running in background
1260 if not config.plugins.autotimer.autopoll.value:
1261 from plugin import autotimer
1264 def editorCallback(ret):
1266 from plugin import autotimer
1268 # Create instance if needed (should have been created by addAutotimerFrom* above though)
1269 if autotimer is None:
1270 from AutoTimer import AutoTimer
1271 autotimer = AutoTimer()
1277 autotimer.writeXml()
1279 # Remove instance if not running in background
1280 if not config.plugins.autotimer.autopoll.value: