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.Button import Button
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 len(excludes[0]) or len(excludes[1]) \
146 or len(excludes[2]) or len(excludes[3]) \
147 or len(includes[0]) or len(includes[1]) \
148 or len(includes[2]) or len(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 len(self.services) or len(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))
184 self.justplay = NoSave(ConfigSelection(choices = [("zap", _("zap")), ("record", _("record"))], default = {0: "record", 1: "zap"}[int(timer.justplay)]))
187 now = [x for x in localtime()]
188 if timer.hasTimespan():
190 now[3] = timer.timespan[0][0]
191 now[4] = timer.timespan[0][1]
193 now[3] = timer.timespan[1][0]
194 now[4] = timer.timespan[1][1]
204 self.timespan = NoSave(ConfigEnableDisable(default = default))
205 self.timespanbegin = NoSave(ConfigClock(default = begin))
206 self.timespanend = NoSave(ConfigClock(default = end))
208 # Services have their own Screen
211 if timer.hasOffset():
213 begin = timer.getOffsetBegin()
214 end = timer.getOffsetEnd()
219 self.offset = NoSave(ConfigEnableDisable(default = default))
220 self.offsetbegin = NoSave(ConfigNumber(default = begin))
221 self.offsetend = NoSave(ConfigNumber(default = end))
224 if timer.hasAfterEvent():
227 AFTEREVENT.NONE: "nothing",
228 AFTEREVENT.DEEPSTANDBY: "deepstandby",
229 AFTEREVENT.STANDBY: "standby",
230 AFTEREVENT.AUTO: "auto"
231 }[timer.afterevent[0][0]]
234 self.afterevent = NoSave(ConfigSelection(choices = [
235 ("default", _("standard")), ("nothing", _("do nothing")),
236 ("standby", _("go to standby")),
237 ("deepstandby", _("go to deep standby")),
238 ("auto", _("auto"))], default = default))
240 # AfterEvent (Timespan)
241 if timer.hasAfterEvent() and timer.afterevent[0][1][0] is not None:
243 now[3] = timer.afterevent[0][1][0][0]
244 now[4] = timer.afterevent[0][1][0][1]
246 now[3] = timer.afterevent[0][1][1][0]
247 now[4] = timer.afterevent[0][1][1][1]
257 self.afterevent_timespan = NoSave(ConfigEnableDisable(default = default))
258 self.afterevent_timespanbegin = NoSave(ConfigClock(default = begin))
259 self.afterevent_timespanend = NoSave(ConfigClock(default = end))
262 self.enabled = NoSave(ConfigYesNo(default = timer.enabled))
265 if timer.hasDuration():
267 duration = timer.getDuration()
271 self.duration = NoSave(ConfigEnableDisable(default = default))
272 self.durationlength = NoSave(ConfigNumber(default = duration))
275 if timer.hasCounter():
276 default = timer.matchCount
279 self.counter = NoSave(ConfigNumber(default = default))
280 self.counterLeft = NoSave(ConfigNumber(default = timer.matchLeft))
281 default = timer.getCounterFormatString()
282 selection = [("", _("Never")), ("%m", _("Monthly")), ("%U", _("Weekly (Sunday)")), ("%W", _("Weekly (Monday)"))]
283 if default not in ('', '%m', '%U', '%W'):
284 selection.append((default, _("Custom (%s)") % (default)))
285 self.counterFormatString = NoSave(ConfigSelection(selection, default = default))
287 # Avoid Duplicate Description
288 self.avoidDuplicateDescription = NoSave(ConfigSelection([
290 ("1", _("On same service")),
291 ("2", _("On any service")),
293 default = str(timer.getAvoidDuplicateDescription())
297 if timer.hasDestination():
302 self.useDestination = NoSave(ConfigYesNo(default = default))
304 default = timer.destination or Directories.resolveFilename(Directories.SCOPE_HDD)
305 choices = config.movielist.videodirs.value
307 if default not in choices:
308 choices.append(default)
309 self.destination = NoSave(ConfigSelection(default = default, choices = choices))
312 self.timerentry_tags = timer.tags
313 self.tags = NoSave(ConfigSelection(choices = [len(self.timerentry_tags) == 0 and _("None") or ' '.join(self.timerentry_tags)]))
315 def pathSelected(self, res):
317 if res not in self.destination.choices:
318 self.destination.choices.append(res)
319 self.destination.description[res] = res
320 self.destination.value = res
322 def chooseDestination(self):
323 from Screens.LocationBox import MovieLocationBox
325 self.session.openWithCallback(
328 _("Choose target folder"),
329 self.destination.value,
330 minFree = 100 # Same requirement as in Screens.TimerEntry
333 def tagEditFinished(self, ret):
335 self.timerentry_tags = ret
336 self.tags.setChoices([len(ret) == 0 and _("None") or ' '.join(ret)])
338 def chooseTags(self):
339 preferredTagEditor = getPreferredTagEditor()
340 if preferredTagEditor:
341 self.session.openWithCallback(
342 self.tagEditFinished,
347 class AutoTimerEditor(Screen, ConfigListScreen, AutoTimerEditorBase):
350 skin = """<screen name="AutoTimerEdit" title="Edit AutoTimer" position="75,155" size="565,280">
351 <widget name="config" position="5,5" size="555,225" scrollbarMode="showOnDemand" />
352 <ePixmap position="0,235" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
353 <ePixmap position="140,235" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
354 <ePixmap position="280,235" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
355 <ePixmap position="420,235" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
356 <widget name="key_red" position="0,235" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
357 <widget name="key_green" position="140,235" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
358 <widget name="key_yellow" position="280,235" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
359 <widget name="key_blue" position="420,235" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
362 def __init__(self, session, timer, editingDefaults = False):
363 Screen.__init__(self, session)
365 AutoTimerEditorBase.__init__(self, timer, editingDefaults)
368 self.setup_title = _("AutoTimer Editor")
369 self.onChangedEntry = []
371 # We might need to change shown items, so add some notifiers
372 self.timespan.addNotifier(self.reloadList, initial_call = False)
373 self.offset.addNotifier(self.reloadList, initial_call = False)
374 self.duration.addNotifier(self.reloadList, initial_call = False)
375 self.afterevent.addNotifier(self.reloadList, initial_call = False)
376 self.afterevent_timespan.addNotifier(self.reloadList, initial_call = False)
377 self.counter.addNotifier(self.reloadList, initial_call = False)
378 self.useDestination.addNotifier(self.reloadList, initial_call = False)
382 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
385 self["key_red"] = Button(_("Cancel"))
386 self["key_green"] = Button(_("OK"))
387 self["key_yellow"] = Button()
388 self["key_blue"] = Button()
391 self.renameServiceButton()
392 self.renameFilterButton()
395 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
397 "cancel": self.cancel,
398 "save": self.maybeSave,
400 "yellow": self.editFilter,
401 "blue": self.editServices
408 self.onLayoutFinish.append(self.setCustomTitle)
410 def setCustomTitle(self):
411 self.setTitle(_("Edit AutoTimer"))
413 def renameFilterButton(self):
415 self["key_yellow"].setText(_("Edit Filters"))
417 self["key_yellow"].setText(_("Add Filters"))
419 def renameServiceButton(self):
420 if self.serviceRestriction:
421 self["key_blue"].setText(_("Edit Services"))
423 self["key_blue"].setText(_("Add Services"))
426 for x in self.onChangedEntry:
432 def getCurrentEntry(self):
433 return self["config"].getCurrent()[0]
435 def getCurrentValue(self):
436 return str(self["config"].getCurrent()[1].getText())
438 def createSummary(self):
442 # First three entries are only showed when not editing defaults
444 if not self.editingDefaults:
446 getConfigListEntry(_("Enabled"), self.enabled),
447 getConfigListEntry(_("Description"), self.name),
448 getConfigListEntry(_("Match Title"), self.match),
452 getConfigListEntry(_("EPG Encoding"), self.encoding),
453 getConfigListEntry(_("Search Type"), self.searchType),
454 getConfigListEntry(_("Search strictness"), self.searchCase),
455 getConfigListEntry(_("Timer Type"), self.justplay),
456 getConfigListEntry(_("Only match during Timespan"), self.timespan)
459 # Only allow editing timespan when it's enabled
460 if self.timespan.value:
462 getConfigListEntry(_("Begin of Timespan"), self.timespanbegin),
463 getConfigListEntry(_("End of Timespan"), self.timespanend)
466 list.append(getConfigListEntry(_("Custom offset"), self.offset))
468 # Only allow editing offsets when it's enabled
469 if self.offset.value:
471 getConfigListEntry(_("Offset before recording (in m)"), self.offsetbegin),
472 getConfigListEntry(_("Offset after recording (in m)"), self.offsetend)
475 list.append(getConfigListEntry(_("Set maximum Duration"), self.duration))
477 # Only allow editing maxduration when it's enabled
478 if self.duration.value:
479 list.append(getConfigListEntry(_("Maximum Duration (in m)"), self.durationlength))
481 list.append(getConfigListEntry(_("After event"), self.afterevent))
483 # Only allow setting afterevent timespan when afterevent is active
484 if self.afterevent.value != "default":
485 list.append(getConfigListEntry(_("Execute after Event during Timespan"), self.afterevent_timespan))
487 # Only allow editing timespan when it's enabled
488 if self.afterevent_timespan.value:
490 getConfigListEntry(_("Begin of after Event Timespan"), self.afterevent_timespanbegin),
491 getConfigListEntry(_("End of after Event Timespan"), self.afterevent_timespanend)
494 list.append(getConfigListEntry(_("Record a maximum of x times"), self.counter))
496 # Only allow setting matchLeft when counting hits
497 if self.counter.value:
498 if not self.editingDefaults:
499 list.append(getConfigListEntry(_("Ammount of recordings left"), self.counterLeft))
500 list.append(getConfigListEntry(_("Reset Count"), self.counterFormatString))
502 list.append(getConfigListEntry(_("Require Description to be unique"), self.avoidDuplicateDescription))
504 # We always add this option though its expert only in enigma2
505 list.append(getConfigListEntry(_("Use a custom location"), self.useDestination))
506 if self.useDestination.value:
507 list.append(getConfigListEntry(_("Custom Location"), self.destination))
509 list.append(getConfigListEntry(_("Tags"), self.tags))
513 def reloadList(self, value):
515 self["config"].setList(self.list)
517 def editFilter(self):
518 self.session.openWithCallback(
519 self.editFilterCallback,
520 AutoTimerFilterEditor,
526 def editFilterCallback(self, ret):
528 self.filterSet = ret[0]
529 self.excludes = ret[1]
530 self.includes = ret[2]
531 self.renameFilterButton()
533 def editServices(self):
534 self.session.openWithCallback(
535 self.editServicesCallback,
536 AutoTimerServiceEditor,
537 self.serviceRestriction,
542 def editServicesCallback(self, ret):
544 self.serviceRestriction = ret[0]
545 self.services = ret[1][0]
546 self.bouquets = ret[1][1]
547 self.renameServiceButton()
550 cur = self["config"].getCurrent()
552 if cur == self.destination:
553 self.chooseDestination()
554 elif cur == self.tags:
557 ConfigListScreen.keyOK(self)
560 if self["config"].isChanged():
561 self.session.openWithCallback(
564 _("Really close without saving settings?")
569 def cancelConfirm(self, ret):
574 if self.editingDefaults:
577 # Check if any match is set
578 if not self.match.value.strip():
581 _("The match attribute is mandatory."),
582 type = MessageBox.TYPE_ERROR,
585 # Check if we have a trailing whitespace
586 elif self.match.value[-1:] == " ":
587 self.session.openWithCallback(
590 _('You entered "%s" as Text to match.\nDo you want to remove trailing whitespaces?') % (self.match.value)
596 def saveCallback(self, ret):
599 self.match.value = self.match.value.rstrip()
601 # Don't to anything if MessageBox was canceled!
605 self.timer.match = self.match.value
608 self.timer.name = self.name.value.strip() or self.timer.match
611 self.timer.encoding = self.encoding.value
614 self.timer.searchType = self.searchType.value
615 self.timer.searchCase = self.searchCase.value
618 self.timer.enabled = self.enabled.value
621 self.timer.justplay = self.justplay.value == "zap"
624 if self.timespan.value:
625 start = self.timespanbegin.value
626 end = self.timespanend.value
627 self.timer.timespan = (start, end)
629 self.timer.timespan = None
632 if self.serviceRestriction:
633 self.timer.services = self.services
634 self.timer.bouquets = self.bouquets
636 self.timer.services = None
637 self.timer.bouquets = None
640 if self.offset.value:
641 self.timer.offset = (self.offsetbegin.value*60, self.offsetend.value*60)
643 self.timer.offset = None
646 if self.afterevent.value == "default":
647 self.timer.afterevent = []
650 "nothing": AFTEREVENT.NONE,
651 "deepstandby": AFTEREVENT.DEEPSTANDBY,
652 "standby": AFTEREVENT.STANDBY,
653 "auto": AFTEREVENT.AUTO
654 }[self.afterevent.value]
655 # AfterEvent Timespan
656 if self.afterevent_timespan.value:
657 start = self.afterevent_timespanbegin.value
658 end = self.afterevent_timespanend.value
659 self.timer.afterevent = [(afterevent, (start, end))]
661 self.timer.afterevent = [(afterevent, None)]
664 if self.duration.value:
665 self.timer.maxduration = self.durationlength.value*60
667 self.timer.maxduration = None
671 self.timer.exclude = self.excludes
672 self.timer.include = self.includes
674 self.timer.exclude = None
675 self.timer.include = None
678 if self.counter.value:
679 self.timer.matchCount = self.counter.value
680 if self.counterLeft.value <= self.counter.value:
681 self.timer.matchLeft = self.counterLeft.value
683 self.timer.matchLeft = self.counter.value
684 if self.counterFormatString.value:
685 self.timer.matchFormatString = self.counterFormatString.value
687 self.timer.matchFormatString = ''
689 self.timer.matchCount = 0
690 self.timer.matchLeft = 0
691 self.timer.matchFormatString = ''
693 self.timer.avoidDuplicateDescription = int(self.avoidDuplicateDescription.value)
695 if self.useDestination.value:
696 self.timer.destination = self.destination.value
698 self.timer.destination = None
700 self.timer.tags = self.timerentry_tags
703 self.close(self.timer)
705 class AutoTimerFilterEditor(Screen, ConfigListScreen):
706 """Edit AutoTimer Filter"""
708 skin = """<screen name="AutoFilterEditor" title="Edit AutoTimer Filters" position="75,150" size="565,245">
709 <widget name="config" position="5,5" size="555,200" scrollbarMode="showOnDemand" />
710 <ePixmap position="5,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
711 <ePixmap position="145,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
712 <ePixmap position="285,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
713 <ePixmap position="425,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
714 <widget name="key_red" position="5,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
715 <widget name="key_green" position="145,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
716 <widget name="key_yellow" position="285,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
717 <widget name="key_blue" position="425,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
720 def __init__(self, session, filterset, excludes, includes):
721 Screen.__init__(self, session)
724 self.setup_title = _("AutoTimer Filters")
725 self.onChangedEntry = []
727 self.typeSelection = NoSave(ConfigSelection(choices = [
728 ("title", _("in Title")),
729 ("short", _("in Shortdescription")),
730 ("desc", _("in Description")),
731 ("day", _("on Weekday"))]
733 self.typeSelection.addNotifier(self.refresh, initial_call = False)
735 self.enabled = NoSave(ConfigEnableDisable(default = filterset))
737 self.excludes = excludes
738 self.includes = includes
742 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
745 self["key_red"] = Button(_("Cancel"))
746 self["key_green"] = Button(_("Save"))
747 self["key_yellow"] = Button(_("delete"))
748 self["key_blue"] = Button(_("New"))
751 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
753 "cancel": self.cancel,
755 "yellow": self.remove,
763 self.onLayoutFinish.append(self.setCustomTitle)
765 def setCustomTitle(self):
766 self.setTitle(_("Edit AutoTimer Filters"))
770 for x in self.onChangedEntry:
776 def getCurrentEntry(self):
777 return self["config"].getCurrent()[0]
779 def getCurrentValue(self):
780 return str(self["config"].getCurrent()[1].getText())
782 def createSummary(self):
785 def saveCurrent(self):
786 del self.excludes[self.idx][:]
787 del self.includes[self.idx][:]
789 # Warning, accessing a ConfigListEntry directly might be considered evil!
792 for item in self["config"].getList()[:]:
794 # Skip empty entries (and those which are no filters)
795 if item[1].value == "" or idx < 2:
797 elif idx < self.lenExcludes:
798 self.excludes[self.idx].append(item[1].value.encode("UTF-8"))
800 self.includes[self.idx].append(item[1].value.encode("UTF-8"))
802 def refresh(self, *args, **kwargs):
806 self["config"].setList(self.list)
808 def reloadList(self):
810 getConfigListEntry(_("Enable Filtering"), self.enabled),
811 getConfigListEntry(_("Filter"), self.typeSelection)
814 if self.typeSelection.value == "day":
817 # Weekdays are presented as ConfigSelection
819 getConfigListEntry(_("Exclude"), NoSave(ConfigSelection(choices = weekdays, default = x)))
820 for x in self.excludes[3]
822 self.lenExcludes = len(self.list)
824 getConfigListEntry(_("Include"), NoSave(ConfigSelection(choices = weekdays, default = x)))
825 for x in self.includes[3]
828 elif self.typeSelection.value == "title":
830 elif self.typeSelection.value == "short":
832 else: # self.typeSelection.value == "desc":
836 getConfigListEntry(_("Exclude"), NoSave(ExtendedConfigText(default = x, fixed_size = False)))
837 for x in self.excludes[self.idx]
839 self.lenExcludes = len(self.list)
841 getConfigListEntry(_("Include"), NoSave(ExtendedConfigText(default = x, fixed_size = False)))
842 for x in self.includes[self.idx]
846 idx = self["config"].getCurrentIndex()
848 if idx < self.lenExcludes:
849 self.lenExcludes -= 1
851 list = self["config"].getList()
852 list.remove(self["config"].getCurrent())
853 self["config"].setList(list)
856 self.session.openWithCallback(
859 _("Select type of Filter"),
866 def typeSelected(self, ret):
868 list = self["config"].getList()
871 pos = self.lenExcludes
872 self.lenExcludes += 1
878 if self.typeSelection.value == "day":
879 entry = getConfigListEntry(text, NoSave(ConfigSelection(choices = weekdays)))
881 entry = getConfigListEntry(text, NoSave(ExtendedConfigText(fixed_size = False)))
883 list.insert(pos, entry)
884 self["config"].setList(list)
887 if self["config"].isChanged():
888 self.session.openWithCallback(
891 _("Really close without saving settings?")
896 def cancelConfirm(self, ret):
909 class AutoTimerServiceEditor(Screen, ConfigListScreen):
910 """Edit allowed Services of a AutoTimer"""
912 skin = """<screen name="AutoTimerServiceEditor" title="Edit AutoTimer Services" position="75,150" size="565,245">
913 <widget name="config" position="5,5" size="555,200" scrollbarMode="showOnDemand" />
914 <ePixmap position="5,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
915 <ePixmap position="145,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
916 <ePixmap position="285,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
917 <ePixmap position="425,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
918 <widget name="key_red" position="5,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
919 <widget name="key_green" position="145,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
920 <widget name="key_yellow" position="285,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
921 <widget name="key_blue" position="425,205" zPosition="5" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
924 def __init__(self, session, servicerestriction, servicelist, bouquetlist):
925 Screen.__init__(self, session)
928 self.setup_title = _("AutoTimer Services")
929 self.onChangedEntry = []
936 self.enabled = NoSave(ConfigEnableDisable(default = servicerestriction))
937 self.typeSelection = NoSave(ConfigSelection(choices = [
938 ("channels", _("Channels")),
939 ("bouquets", _("Bouquets"))]
941 self.typeSelection.addNotifier(self.refresh, initial_call = False)
945 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
948 self["key_red"] = Button(_("Cancel"))
949 self["key_green"] = Button(_("OK"))
950 self["key_yellow"] = Button(_("delete"))
951 self["key_blue"] = Button(_("New"))
954 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
956 "cancel": self.cancel,
958 "yellow": self.remove,
966 self.onLayoutFinish.append(self.setCustomTitle)
968 def setCustomTitle(self):
969 self.setTitle(_("Edit AutoTimer Services"))
971 def saveCurrent(self):
972 del self.services[self.idx][:]
974 # Warning, accessing a ConfigListEntry directly might be considered evil!
976 myl = self["config"].getList()[:]
980 self.services[self.idx].append(item[1].value)
982 def refresh(self, *args, **kwargs):
986 self["config"].setList(self.list)
988 def reloadList(self):
990 getConfigListEntry(_("Enable Service Restriction"), self.enabled),
991 getConfigListEntry(_("Editing"), self.typeSelection)
994 if self.typeSelection.value == "channels":
996 else: # self.typeSelection.value == "bouquets":
1000 getConfigListEntry(_("Record on"), NoSave(ConfigSelection(choices = [(str(x), ServiceReference(str(x)).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))])))
1001 for x in self.services[self.idx]
1005 for x in self.onChangedEntry:
1011 def getCurrentEntry(self):
1012 return self["config"].getCurrent()[0]
1014 def getCurrentValue(self):
1015 return str(self["config"].getCurrent()[1].getText())
1017 def createSummary(self):
1021 if self["config"].getCurrentIndex() != 0:
1022 list = self["config"].getList()
1023 list.remove(self["config"].getCurrent())
1024 self["config"].setList(list)
1027 if self.typeSelection.value == "channels":
1028 self.session.openWithCallback(
1029 self.finishedServiceSelection,
1030 SimpleChannelSelection,
1031 _("Select channel to record on")
1033 else: # self.typeSelection.value == "bouquets":
1034 self.session.openWithCallback(
1035 self.finishedServiceSelection,
1036 SimpleBouquetSelection,
1037 _("Select bouquet to record on")
1040 def finishedServiceSelection(self, *args):
1042 list = self["config"].getList()
1043 sname = args[0].toString()
1045 if self.typeSelection.value == "channels":
1046 # strip all after last : when adding a channel
1047 pos = sname.rfind(':')
1049 sname = sname[:pos+1]
1051 list.append(getConfigListEntry(_("Record on"), NoSave(ConfigSelection(choices = [(sname, ServiceReference(args[0]).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))]))))
1052 self["config"].setList(list)
1055 if self["config"].isChanged():
1056 self.session.openWithCallback(
1059 _("Really close without saving settings?")
1064 def cancelConfirm(self, ret):
1076 def addAutotimerFromEvent(session, evt = None, service = None):
1077 from AutoTimerComponent import AutoTimerComponent
1078 from AutoTimerImporter import AutoTimerImporter
1079 from plugin import autotimer
1081 # Create instance if needed
1082 if autotimer is None:
1083 from AutoTimer import AutoTimer
1084 autotimer = AutoTimer()
1087 match = evt and evt.getEventName() or ""
1088 name = match or "New AutoTimer"
1090 if service is not None:
1091 service = str(service)
1092 # strip all after last :
1093 pos = service.rfind(':')
1095 service = service[:pos+1]
1097 sref = ServiceReference(service)
1099 # timespan defaults to +- 1h
1100 begin = evt.getBeginTime()-3600
1101 end = begin + evt.getDuration()+7200
1105 # XXX: we might want to make sure that we actually collected any data because the importer does not do so :-)
1107 session.openWithCallback(
1111 autotimer.getUniqueId(),
1116 match, # Proposed Match
1117 begin, # Proposed Begin
1119 None, # Proposed Disabled
1120 sref, # Proposed ServiceReference
1121 None, # Proposed afterEvent
1122 None, # Proposed justplay
1123 None, # Proposed dirname, can we get anything useful here?
1127 def addAutotimerFromService(session, service = None):
1128 from AutoTimerComponent import AutoTimerComponent
1129 from AutoTimerImporter import AutoTimerImporter
1130 from plugin import autotimer
1132 # Create instance if needed
1133 if autotimer is None:
1134 from AutoTimer import AutoTimer
1135 autotimer = AutoTimer()
1138 serviceHandler = eServiceCenter.getInstance()
1139 info = serviceHandler.info(service)
1141 match = info and info.getName(service) or ""
1142 name = match or "New AutoTimer"
1143 sref = info and info.getInfoString(service, iServiceInformation.sServiceref)
1145 # strip all after last :
1146 pos = sref.rfind(':')
1150 sref = ServiceReference(sref)
1152 begin = info.getInfo(service, iServiceInformation.sTimeCreate)
1153 end = begin + info.getLength(service)
1157 from os.path import dirname
1158 path = dirname(service.getPath())
1162 tags = info.getInfoString(service, iServiceInformation.sTags)
1163 tags = tags and tags.split(' ') or []
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 path, # Proposed dirname
1184 tags # Proposed tags
1187 def importerCallback(ret):
1191 session.openWithCallback(
1197 # Remove instance if not running in background
1198 if not config.plugins.autotimer.autopoll.value:
1199 from plugin import autotimer
1202 def editorCallback(ret):
1204 from plugin import autotimer
1206 # Create instance if needed (should have been created by addAutotimerFrom* above though)
1207 if autotimer is None:
1208 from AutoTimer import AutoTimer
1209 autotimer = AutoTimer()
1215 autotimer.writeXml()
1217 # Remove instance if not running in background
1218 if not config.plugins.autotimer.autopoll.value: