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 = ExtendedConfigText(default = timer.name, fixed_size = False)
170 self.match = 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 = ConfigSelection(choices = selection, default = default)
180 self.searchType = ConfigSelection(choices = [("partial", _("partial match")), ("exact", _("exact match"))], default = timer.searchType)
181 self.searchCase = ConfigSelection(choices = [("sensitive", _("case-sensitive search")), ("insensitive", _("case-insensitive search"))], default = timer.searchCase)
184 self.justplay = 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 = ConfigEnableDisable(default = default)
205 self.timespanbegin = ConfigClock(default = begin)
206 self.timespanend = ConfigClock(default = end)
208 # Services have their own Screen
211 if timer.hasOffset():
213 begin = timer.getOffsetBegin()
214 end = timer.getOffsetEnd()
219 self.offset = ConfigEnableDisable(default = default)
220 self.offsetbegin = ConfigNumber(default = begin)
221 self.offsetend = 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 = ConfigSelection(choices = [("default", _("standard")), ("nothing", _("do nothing")), ("standby", _("go to standby")), ("deepstandby", _("go to deep standby")), ("auto", _("auto"))], default = default)
236 # AfterEvent (Timespan)
237 if timer.hasAfterEvent() and timer.afterevent[0][1][0] is not None:
239 now[3] = timer.afterevent[0][1][0][0]
240 now[4] = timer.afterevent[0][1][0][1]
242 now[3] = timer.afterevent[0][1][1][0]
243 now[4] = timer.afterevent[0][1][1][1]
253 self.afterevent_timespan = ConfigEnableDisable(default = default)
254 self.afterevent_timespanbegin = ConfigClock(default = begin)
255 self.afterevent_timespanend = ConfigClock(default = end)
258 self.enabled = ConfigYesNo(default = timer.enabled)
261 if timer.hasDuration():
263 duration = timer.getDuration()
267 self.duration = ConfigEnableDisable(default = default)
268 self.durationlength = ConfigNumber(default = duration)
271 if timer.hasCounter():
272 default = timer.matchCount
275 self.counter = ConfigNumber(default = default)
276 self.counterLeft = ConfigNumber(default = timer.matchLeft)
277 default = timer.getCounterFormatString()
278 selection = [("", _("Never")), ("%m", _("Monthly")), ("%U", _("Weekly (Sunday)")), ("%W", _("Weekly (Monday)"))]
279 if default not in ('', '%m', '%U', '%W'):
280 selection.append((default, _("Custom (%s)") % (default)))
281 self.counterFormatString = ConfigSelection(selection, default = default)
283 # Avoid Duplicate Description
284 self.avoidDuplicateDescription = ConfigSelection([
286 ("1", _("On same service")),
287 ("2", _("On any service")),
289 default = str(timer.getAvoidDuplicateDescription())
293 if timer.hasDestination():
298 self.useDestination = ConfigYesNo(default = default)
300 default = timer.destination or Directories.resolveFilename(Directories.SCOPE_HDD)
301 choices = config.movielist.videodirs.value
303 if default not in choices:
304 choices.append(default)
305 self.destination = ConfigSelection(default = default, choices = choices)
308 self.timerentry_tags = timer.tags
309 self.tags = ConfigSelection(choices = [len(self.timerentry_tags) == 0 and _("None") or ' '.join(self.timerentry_tags)])
311 def pathSelected(self, res):
313 if res not in self.destination.choices:
314 self.destination.choices.append(res)
315 self.destination.description[res] = res
316 self.destination.value = res
318 def chooseDestination(self):
319 from Screens.LocationBox import MovieLocationBox
321 self.session.openWithCallback(
324 _("Choose target folder"),
325 self.destination.value,
326 minFree = 100 # Same requirement as in Screens.TimerEntry
329 def tagEditFinished(self, ret):
331 self.timerentry_tags = ret
332 self.tags.setChoices([len(ret) == 0 and _("None") or ' '.join(ret)])
334 def chooseTags(self):
335 preferredTagEditor = getPreferredTagEditor()
336 if preferredTagEditor:
337 self.session.openWithCallback(
338 self.tagEditFinished,
343 class AutoTimerEditor(Screen, ConfigListScreen, AutoTimerEditorBase):
346 skin = """<screen name="AutoTimerEdit" title="Edit AutoTimer" position="75,155" size="565,280">
347 <widget name="config" position="5,5" size="555,225" scrollbarMode="showOnDemand" />
348 <ePixmap position="0,235" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
349 <ePixmap position="140,235" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
350 <ePixmap position="280,235" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
351 <ePixmap position="420,235" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
352 <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" />
353 <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" />
354 <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" />
355 <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" />
358 def __init__(self, session, timer, editingDefaults = False):
359 Screen.__init__(self, session)
361 AutoTimerEditorBase.__init__(self, timer, editingDefaults)
364 self.setup_title = _("AutoTimer Editor")
365 self.onChangedEntry = []
367 # We might need to change shown items, so add some notifiers
368 self.timespan.addNotifier(self.reloadList, initial_call = False)
369 self.offset.addNotifier(self.reloadList, initial_call = False)
370 self.duration.addNotifier(self.reloadList, initial_call = False)
371 self.afterevent.addNotifier(self.reloadList, initial_call = False)
372 self.afterevent_timespan.addNotifier(self.reloadList, initial_call = False)
373 self.counter.addNotifier(self.reloadList, initial_call = False)
374 self.useDestination.addNotifier(self.reloadList, initial_call = False)
378 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
381 self["key_red"] = Button(_("Cancel"))
382 self["key_green"] = Button(_("OK"))
383 self["key_yellow"] = Button()
384 self["key_blue"] = Button()
387 self.renameServiceButton()
388 self.renameFilterButton()
391 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
393 "cancel": self.cancel,
394 "save": self.maybeSave,
396 "yellow": self.editFilter,
397 "blue": self.editServices
404 self.onLayoutFinish.append(self.setCustomTitle)
406 def setCustomTitle(self):
407 self.setTitle(_("Edit AutoTimer"))
409 def renameFilterButton(self):
411 self["key_yellow"].setText(_("Edit Filters"))
413 self["key_yellow"].setText(_("Add Filters"))
415 def renameServiceButton(self):
416 if self.serviceRestriction:
417 self["key_blue"].setText(_("Edit Services"))
419 self["key_blue"].setText(_("Add Services"))
422 for x in self.onChangedEntry:
428 def getCurrentEntry(self):
429 return self["config"].getCurrent()[0]
431 def getCurrentValue(self):
432 return str(self["config"].getCurrent()[1].getText())
434 def createSummary(self):
438 # First three entries are only showed when not editing defaults
440 if not self.editingDefaults:
442 getConfigListEntry(_("Enabled"), self.enabled),
443 getConfigListEntry(_("Description"), self.name),
444 getConfigListEntry(_("Match Title"), self.match),
448 getConfigListEntry(_("EPG Encoding"), self.encoding),
449 getConfigListEntry(_("Search Type"), self.searchType),
450 getConfigListEntry(_("Search strictness"), self.searchCase),
451 getConfigListEntry(_("Timer Type"), self.justplay),
452 getConfigListEntry(_("Only match during Timespan"), self.timespan)
455 # Only allow editing timespan when it's enabled
456 if self.timespan.value:
458 getConfigListEntry(_("Begin of Timespan"), self.timespanbegin),
459 getConfigListEntry(_("End of Timespan"), self.timespanend)
462 self.list.append(getConfigListEntry(_("Custom offset"), self.offset))
464 # Only allow editing offsets when it's enabled
465 if self.offset.value:
467 getConfigListEntry(_("Offset before recording (in m)"), self.offsetbegin),
468 getConfigListEntry(_("Offset after recording (in m)"), self.offsetend)
471 self.list.append(getConfigListEntry(_("Set maximum Duration"), self.duration))
473 # Only allow editing maxduration when it's enabled
474 if self.duration.value:
475 self.list.append(getConfigListEntry(_("Maximum Duration (in m)"), self.durationlength))
477 self.list.append(getConfigListEntry(_("After event"), self.afterevent))
479 # Only allow setting afterevent timespan when afterevent is active
480 if self.afterevent.value != "default":
481 self.list.append(getConfigListEntry(_("Execute after Event during Timespan"), self.afterevent_timespan))
483 # Only allow editing timespan when it's enabled
484 if self.afterevent_timespan.value:
486 getConfigListEntry(_("Begin of after Event Timespan"), self.afterevent_timespanbegin),
487 getConfigListEntry(_("End of after Event Timespan"), self.afterevent_timespanend)
490 self.list.append(getConfigListEntry(_("Record a maximum of x times"), self.counter))
492 # Only allow setting matchLeft when counting hits
493 if self.counter.value:
494 if not self.editingDefaults:
495 self.list.append(getConfigListEntry(_("Ammount of recordings left"), self.counterLeft))
496 self.list.append(getConfigListEntry(_("Reset Count"), self.counterFormatString))
498 self.list.append(getConfigListEntry(_("Require Description to be unique"), self.avoidDuplicateDescription))
500 # We always add this option though its expert only in enigma2
501 self.list.append(getConfigListEntry(_("Use a custom location"), self.useDestination))
502 if self.useDestination.value:
503 self.list.append(getConfigListEntry(_("Custom Location"), self.destination))
505 self.list.append(getConfigListEntry(_("Tags"), self.tags))
507 def reloadList(self, value):
509 self["config"].setList(self.list)
511 def editFilter(self):
512 self.session.openWithCallback(
513 self.editFilterCallback,
514 AutoTimerFilterEditor,
520 def editFilterCallback(self, ret):
522 self.filterSet = ret[0]
523 self.excludes = ret[1]
524 self.includes = ret[2]
525 self.renameFilterButton()
527 def editServices(self):
528 self.session.openWithCallback(
529 self.editServicesCallback,
530 AutoTimerServiceEditor,
531 self.serviceRestriction,
536 def editServicesCallback(self, ret):
538 self.serviceRestriction = ret[0]
539 self.services = ret[1][0]
540 self.bouquets = ret[1][1]
541 self.renameServiceButton()
544 cur = self["config"].getCurrent()
546 if cur == self.destination:
547 self.chooseDestination()
548 elif cur == self.tags:
551 ConfigListScreen.keyOK(self)
554 if self["config"].isChanged():
555 self.session.openWithCallback(
558 _("Really close without saving settings?")
563 def cancelConfirm(self, ret):
568 if self.editingDefaults:
571 # Check if any match is set
572 if not self.match.value.strip():
575 _("The match attribute is mandatory."),
576 type = MessageBox.TYPE_ERROR,
579 # Check if we have a trailing whitespace
580 elif self.match.value[-1:] == " ":
581 self.session.openWithCallback(
584 _('You entered "%s" as Text to match.\nDo you want to remove trailing whitespaces?') % (self.match.value)
590 def saveCallback(self, ret):
593 self.match.value = self.match.value.rstrip()
595 # Don't to anything if MessageBox was canceled!
599 self.timer.match = self.match.value
602 self.timer.name = self.name.value.strip() or self.timer.match
605 self.timer.encoding = self.encoding.value
608 self.timer.searchType = self.searchType.value
609 self.timer.searchCase = self.searchCase.value
612 self.timer.enabled = self.enabled.value
615 self.timer.justplay = self.justplay.value == "zap"
618 if self.timespan.value:
619 start = self.timespanbegin.value
620 end = self.timespanend.value
621 self.timer.timespan = (start, end)
623 self.timer.timespan = None
626 if self.serviceRestriction:
627 self.timer.services = self.services
628 self.timer.bouquets = self.bouquets
630 self.timer.services = None
631 self.timer.bouquets = None
634 if self.offset.value:
635 self.timer.offset = (self.offsetbegin.value*60, self.offsetend.value*60)
637 self.timer.offset = None
640 if self.afterevent.value == "default":
641 self.timer.afterevent = []
644 "nothing": AFTEREVENT.NONE,
645 "deepstandby": AFTEREVENT.DEEPSTANDBY,
646 "standby": AFTEREVENT.STANDBY,
647 "auto": AFTEREVENT.AUTO
648 }[self.afterevent.value]
649 # AfterEvent Timespan
650 if self.afterevent_timespan.value:
651 start = self.afterevent_timespanbegin.value
652 end = self.afterevent_timespanend.value
653 self.timer.afterevent = [(afterevent, (start, end))]
655 self.timer.afterevent = [(afterevent, None)]
658 if self.duration.value:
659 self.timer.maxduration = self.durationlength.value*60
661 self.timer.maxduration = None
665 self.timer.exclude = self.excludes
666 self.timer.include = self.includes
668 self.timer.exclude = None
669 self.timer.include = None
672 if self.counter.value:
673 self.timer.matchCount = self.counter.value
674 if self.counterLeft.value <= self.counter.value:
675 self.timer.matchLeft = self.counterLeft.value
677 self.timer.matchLeft = self.counter.value
678 if self.counterFormatString.value:
679 self.timer.matchFormatString = self.counterFormatString.value
681 self.timer.matchFormatString = ''
683 self.timer.matchCount = 0
684 self.timer.matchLeft = 0
685 self.timer.matchFormatString = ''
687 self.timer.avoidDuplicateDescription = int(self.avoidDuplicateDescription.value)
689 if self.useDestination.value:
690 self.timer.destination = self.destination.value
692 self.timer.destination = None
694 self.timer.tags = self.timerentry_tags
697 self.close(self.timer)
699 class AutoTimerFilterEditor(Screen, ConfigListScreen):
700 """Edit AutoTimer Filter"""
702 skin = """<screen name="AutoFilterEditor" title="Edit AutoTimer Filters" position="75,150" size="565,245">
703 <widget name="config" position="5,5" size="555,200" scrollbarMode="showOnDemand" />
704 <ePixmap position="5,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
705 <ePixmap position="145,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
706 <ePixmap position="285,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
707 <ePixmap position="425,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
708 <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" />
709 <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" />
710 <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" />
711 <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" />
714 def __init__(self, session, filterset, excludes, includes):
715 Screen.__init__(self, session)
718 self.setup_title = _("AutoTimer Filters")
719 self.onChangedEntry = []
721 self.typeSelection = ConfigSelection(choices = [("title", _("in Title")), ("short", _("in Shortdescription")), ("desc", _("in Description")), ("day", _("on Weekday"))])
722 self.typeSelection.addNotifier(self.refresh, initial_call = False)
724 self.enabled = ConfigEnableDisable(default = filterset)
726 self.excludes = excludes
727 self.includes = includes
731 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
734 self["key_red"] = Button(_("Cancel"))
735 self["key_green"] = Button(_("Save"))
736 self["key_yellow"] = Button(_("delete"))
737 self["key_blue"] = Button(_("New"))
740 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
742 "cancel": self.cancel,
744 "yellow": self.remove,
752 self.onLayoutFinish.append(self.setCustomTitle)
754 def setCustomTitle(self):
755 self.setTitle(_("Edit AutoTimer Filters"))
759 for x in self.onChangedEntry:
765 def getCurrentEntry(self):
766 return self["config"].getCurrent()[0]
768 def getCurrentValue(self):
769 return str(self["config"].getCurrent()[1].getText())
771 def createSummary(self):
774 def saveCurrent(self):
775 del self.excludes[self.idx][:]
776 del self.includes[self.idx][:]
778 # Warning, accessing a ConfigListEntry directly might be considered evil!
781 for item in self["config"].getList()[:]:
783 # Skip empty entries (and those which are no filters)
784 if item[1].value == "" or idx < 2:
786 elif idx < self.lenExcludes:
787 self.excludes[self.idx].append(item[1].value.encode("UTF-8"))
789 self.includes[self.idx].append(item[1].value.encode("UTF-8"))
791 def refresh(self, *args, **kwargs):
795 self["config"].setList(self.list)
797 def reloadList(self):
799 getConfigListEntry(_("Enable Filtering"), self.enabled),
800 getConfigListEntry(_("Filter"), self.typeSelection)
803 if self.typeSelection.value == "day":
806 # Weekdays are presented as ConfigSelection
808 getConfigListEntry(_("Exclude"), ConfigSelection(choices = weekdays, default = x))
809 for x in self.excludes[3]
811 self.lenExcludes = len(self.list)
813 getConfigListEntry(_("Include"), ConfigSelection(choices = weekdays, default = x))
814 for x in self.includes[3]
817 elif self.typeSelection.value == "title":
819 elif self.typeSelection.value == "short":
821 else: # self.typeSelection.value == "desc":
825 getConfigListEntry(_("Exclude"), ExtendedConfigText(default = x, fixed_size = False))
826 for x in self.excludes[self.idx]
828 self.lenExcludes = len(self.list)
830 getConfigListEntry(_("Include"), ExtendedConfigText(default = x, fixed_size = False))
831 for x in self.includes[self.idx]
835 idx = self["config"].getCurrentIndex()
837 if idx < self.lenExcludes:
838 self.lenExcludes -= 1
840 list = self["config"].getList()
841 list.remove(self["config"].getCurrent())
842 self["config"].setList(list)
845 self.session.openWithCallback(
848 _("Select type of Filter"),
855 def typeSelected(self, ret):
857 list = self["config"].getList()
860 pos = self.lenExcludes
861 self.lenExcludes += 1
867 if self.typeSelection.value == "day":
868 entry = getConfigListEntry(text, ConfigSelection(choices = weekdays))
870 entry = getConfigListEntry(text, ExtendedConfigText(fixed_size = False))
872 list.insert(pos, entry)
873 self["config"].setList(list)
876 if self["config"].isChanged():
877 self.session.openWithCallback(
880 _("Really close without saving settings?")
885 def cancelConfirm(self, ret):
898 class AutoTimerServiceEditor(Screen, ConfigListScreen):
899 """Edit allowed Services of a AutoTimer"""
901 skin = """<screen name="AutoTimerServiceEditor" title="Edit AutoTimer Services" position="75,150" size="565,245">
902 <widget name="config" position="5,5" size="555,200" scrollbarMode="showOnDemand" />
903 <ePixmap position="5,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
904 <ePixmap position="145,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
905 <ePixmap position="285,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
906 <ePixmap position="425,205" zPosition="4" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
907 <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" />
908 <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" />
909 <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" />
910 <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" />
913 def __init__(self, session, servicerestriction, servicelist, bouquetlist):
914 Screen.__init__(self, session)
917 self.setup_title = _("AutoTimer Services")
918 self.onChangedEntry = []
925 self.enabled = ConfigEnableDisable(default = servicerestriction)
926 self.typeSelection = ConfigSelection(choices = [("channels", _("Channels")), ("bouquets", _("Bouquets"))])
927 self.typeSelection.addNotifier(self.refresh, initial_call = False)
931 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
934 self["key_red"] = Button(_("Cancel"))
935 self["key_green"] = Button(_("OK"))
936 self["key_yellow"] = Button(_("delete"))
937 self["key_blue"] = Button(_("New"))
940 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
942 "cancel": self.cancel,
944 "yellow": self.remove,
952 self.onLayoutFinish.append(self.setCustomTitle)
954 def setCustomTitle(self):
955 self.setTitle(_("Edit AutoTimer Services"))
957 def saveCurrent(self):
958 del self.services[self.idx][:]
960 # Warning, accessing a ConfigListEntry directly might be considered evil!
962 myl = self["config"].getList()[:]
966 self.services[self.idx].append(item[1].value)
968 def refresh(self, *args, **kwargs):
972 self["config"].setList(self.list)
974 def reloadList(self):
976 getConfigListEntry(_("Enable Service Restriction"), self.enabled),
977 getConfigListEntry(_("Editing"), self.typeSelection)
980 if self.typeSelection.value == "channels":
982 else: # self.typeSelection.value == "bouquets":
986 getConfigListEntry(_("Record on"), ConfigSelection(choices = [(str(x), ServiceReference(str(x)).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))]))
987 for x in self.services[self.idx]
991 for x in self.onChangedEntry:
997 def getCurrentEntry(self):
998 return self["config"].getCurrent()[0]
1000 def getCurrentValue(self):
1001 return str(self["config"].getCurrent()[1].getText())
1003 def createSummary(self):
1007 if self["config"].getCurrentIndex() != 0:
1008 list = self["config"].getList()
1009 list.remove(self["config"].getCurrent())
1010 self["config"].setList(list)
1013 if self.typeSelection.value == "channels":
1014 self.session.openWithCallback(
1015 self.finishedServiceSelection,
1016 SimpleChannelSelection,
1017 _("Select channel to record on")
1019 else: # self.typeSelection.value == "bouquets":
1020 self.session.openWithCallback(
1021 self.finishedServiceSelection,
1022 SimpleBouquetSelection,
1023 _("Select bouquet to record on")
1026 def finishedServiceSelection(self, *args):
1028 list = self["config"].getList()
1029 sname = args[0].toString()
1031 if self.typeSelection.value == "channels":
1032 # strip all after last : when adding a channel
1033 pos = sname.rfind(':')
1035 sname = sname[:pos+1]
1037 list.append(getConfigListEntry(_("Record on"), ConfigSelection(choices = [(sname, ServiceReference(args[0]).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))])))
1038 self["config"].setList(list)
1041 if self["config"].isChanged():
1042 self.session.openWithCallback(
1045 _("Really close without saving settings?")
1050 def cancelConfirm(self, ret):
1062 def addAutotimerFromEvent(session, evt = None, service = None):
1063 from AutoTimerComponent import AutoTimerComponent
1064 from AutoTimerImporter import AutoTimerImporter
1065 from plugin import autotimer
1067 # Create instance if needed
1068 if autotimer is None:
1069 from AutoTimer import AutoTimer
1070 autotimer = AutoTimer()
1073 match = evt and evt.getEventName() or ""
1074 name = match or "New AutoTimer"
1076 if service is not None:
1077 service = str(service)
1078 # strip all after last :
1079 pos = service.rfind(':')
1081 service = service[:pos+1]
1083 sref = ServiceReference(service)
1085 # timespan defaults to +- 1h
1086 begin = evt.getBeginTime()-3600
1087 end = begin + evt.getDuration()+7200
1091 # XXX: we might want to make sure that we actually collected any data because the importer does not do so :-)
1093 session.openWithCallback(
1097 autotimer.getUniqueId(),
1102 match, # Proposed Match
1103 begin, # Proposed Begin
1105 None, # Proposed Disabled
1106 sref, # Proposed ServiceReference
1107 None, # Proposed afterEvent
1108 None, # Proposed justplay
1109 None, # Proposed dirname, can we get anything useful here?
1113 def addAutotimerFromService(session, service = None):
1114 from AutoTimerComponent import AutoTimerComponent
1115 from AutoTimerImporter import AutoTimerImporter
1116 from plugin import autotimer
1118 # Create instance if needed
1119 if autotimer is None:
1120 from AutoTimer import AutoTimer
1121 autotimer = AutoTimer()
1124 serviceHandler = eServiceCenter.getInstance()
1125 info = serviceHandler.info(service)
1127 match = info and info.getName(service) or ""
1128 name = match or "New AutoTimer"
1129 sref = info and info.getInfoString(service, iServiceInformation.sServiceref)
1131 # strip all after last :
1132 pos = sref.rfind(':')
1136 sref = ServiceReference(sref)
1138 begin = info.getInfo(service, iServiceInformation.sTimeCreate)
1139 end = begin + info.getLength(service)
1143 from os.path import dirname
1144 path = dirname(service.getPath())
1148 tags = info.getInfoString(service, iServiceInformation.sTags)
1149 tags = tags and tags.split(' ') or []
1151 # XXX: we might want to make sure that we actually collected any data because the importer does not do so :-)
1153 session.openWithCallback(
1157 autotimer.getUniqueId(),
1162 match, # Proposed Match
1163 begin, # Proposed Begin
1165 None, # Proposed Disabled
1166 sref, # Proposed ServiceReference
1167 None, # Proposed afterEvent
1168 None, # Proposed justplay
1169 path, # Proposed dirname
1170 tags # Proposed tags
1173 def importerCallback(ret):
1177 session.openWithCallback(
1183 # Remove instance if not running in background
1184 if not config.plugins.autotimer.autopoll.value:
1185 from plugin import autotimer
1188 def editorCallback(ret):
1190 from plugin import autotimer
1192 # Create instance if needed (should have been created by addAutotimerFrom* above though)
1193 if autotimer is None:
1194 from AutoTimer import AutoTimer
1195 autotimer = AutoTimer()
1201 autotimer.writeXml()
1203 # Remove instance if not running in background
1204 if not config.plugins.autotimer.autopoll.value: