AutoTimer: update for italian translation
[enigma2-plugins.git] / autotimer / src / AutoTimerEditor.py
1 # -*- coding: UTF-8 -*-
2 # for localized messages
3 from . import _
4
5 # GUI (Screens)
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
12
13 # GUI (Summary)
14 from Screens.Setup import SetupSummary
15
16 # GUI (Components)
17 from Components.ActionMap import ActionMap
18 from Components.Sources.StaticText import StaticText
19
20 # Configuration
21 from Components.config import getConfigListEntry, ConfigEnableDisable, \
22         ConfigYesNo, ConfigText, ConfigClock, ConfigNumber, ConfigSelection, \
23         ConfigDateTime, config, NoSave
24
25 # Timer
26 from RecordTimer import AFTEREVENT
27
28 # Needed to convert our timestamp back and forth
29 from time import localtime, mktime
30
31 # Show ServiceName instead of ServiceReference
32 from ServiceReference import ServiceReference
33
34 # addAutotimerFromService, AutoTimerChannelSelection
35 from enigma import eServiceCenter, eServiceReference, iServiceInformation
36
37 # Default Record Directory
38 from Tools import Directories
39
40 # Tags
41 from Screens.MovieSelection import getPreferredTagEditor
42
43 weekdays = [
44         ("0", _("Monday")),
45         ("1", _("Tuesday")),
46         ("2", _("Wednesday")),
47         ("3", _("Thursday")),
48         ("4", _("Friday")),
49         ("5", _("Saturday")),
50         ("6", _("Sunday")),
51         ("weekend", _("Weekend")),
52         ("weekday", _("Weekday"))
53 ]
54
55 try:
56         from Plugins.SystemPlugins.vps import Vps
57 except ImportError as ie:
58         hasVps = False
59 else:
60         hasVps = True
61
62 class ExtendedConfigText(ConfigText):
63         def __init__(self, default = "", fixed_size = True, visible_width = False):
64                 ConfigText.__init__(self, default = default, fixed_size = fixed_size, visible_width = visible_width)
65
66                 # Workaround some characters currently not "typeable" using NumericalTextInput
67                 mapping = self.mapping
68                 if mapping:
69                         if "&" not in mapping[0]:
70                                 mapping[0] += "&"
71                         if ";" not in mapping[0]:
72                                 mapping[0] += ";"
73                         if "%" not in mapping[0]:
74                                 mapping[0] += "%"
75
76 class SimpleBouquetSelection(SimpleChannelSelection):
77         def __init__(self, session, title):
78                 SimpleChannelSelection.__init__(self, session, title)
79                 self.skinName = "SimpleChannelSelection"
80
81         def channelSelected(self):
82                 ref = self.getCurrentSelection()
83                 if (ref.flags & 7) == 7:
84                         self.close(ref)
85                 else:
86                         # We return the currently active path here
87                         # Asking the user if this is what he wants might be better though
88                         self.close(self.servicePath[-1])
89
90 class AutoTimerChannelSelection(SimpleChannelSelection):
91         def __init__(self, session, autotimer):
92                 SimpleChannelSelection.__init__(self, session, _("Channel Selection"))
93                 self.skinName = "SimpleChannelSelection"
94                 self.autotimer = autotimer
95
96                 self["ChannelSelectEPGActions"] = ActionMap(["ChannelSelectEPGActions"],
97                         {
98                                 "showEPGList": self.channelSelected
99                         }
100                 )
101
102         def channelSelected(self):
103                 ref = self.getCurrentSelection()
104                 if (ref.flags & 7) == 7:
105                         self.enterPath(ref)
106                 elif not (ref.flags & eServiceReference.isMarker):
107                         self.session.open(
108                                 AutoTimerEPGSelection,
109                                 ref
110                         )
111
112 class AutoTimerEPGSelection(EPGSelection):
113         def __init__(self, *args):
114                 EPGSelection.__init__(self, *args)
115                 self.skinName = "EPGSelection"
116
117         def infoKeyPressed(self):
118                 self.timerAdd()
119
120         def timerAdd(self):
121                 cur = self["list"].getCurrent()
122                 evt = cur[0]
123                 sref = cur[1]
124                 if not evt:
125                         return
126
127                 addAutotimerFromEvent(self.session, evt = evt, service = sref)
128
129         def onSelectionChanged(self):
130                 pass
131
132 class AutoTimerEditorBase:
133         """ Base Class for all Editors """
134         def __init__(self, timer, editingDefaults = False):
135                 # Keep Timer
136                 self.timer = timer
137                 self.editingDefaults = editingDefaults
138
139                 # See if we are filtering some strings
140                 excludes = (
141                         timer.getExcludedTitle(),
142                         timer.getExcludedShort(),
143                         timer.getExcludedDescription(),
144                         timer.getExcludedDays()
145                 )
146                 includes = (
147                         timer.getIncludedTitle(),
148                         timer.getIncludedShort(),
149                         timer.getIncludedDescription(),
150                         timer.getIncludedDays()
151                 )
152                 if excludes[0] or excludes[1] \
153                                 or excludes[2] or excludes[3] \
154                                 or includes[0] or includes[1] \
155                                 or includes[2] or includes[3]:
156                         self.filterSet = True
157                 else:
158                         self.filterSet = False
159                 self.excludes = excludes
160                 self.includes = includes
161
162                 # See if services are restricted
163                 self.services = timer.services
164                 self.bouquets = timer.bouquets
165                 if self.services or self.bouquets:
166                         self.serviceRestriction = True
167                 else:
168                         self.serviceRestriction = False
169
170                 self.createSetup(timer)
171
172         def createSetup(self, timer):
173                 # Name
174                 self.name = NoSave(ExtendedConfigText(default = timer.name, fixed_size = False))
175
176                 # Match
177                 self.match = NoSave(ExtendedConfigText(default = timer.match, fixed_size = False))
178
179                 # Encoding
180                 default = timer.encoding
181                 selection = ['UTF-8', 'ISO8859-15']
182                 if default not in selection:
183                         selection.append(default)
184                 self.encoding = NoSave(ConfigSelection(choices = selection, default = default))
185
186                 # ...
187                 self.searchType = NoSave(ConfigSelection(choices = [("partial", _("partial match")), ("exact", _("exact match"))], default = timer.searchType))
188                 self.searchCase = NoSave(ConfigSelection(choices = [("sensitive", _("case-sensitive search")), ("insensitive", _("case-insensitive search"))], default = timer.searchCase))
189
190                 # Alternatives override
191                 self.overrideAlternatives = NoSave(ConfigYesNo(default = timer.overrideAlternatives))
192
193                 # Justplay
194                 self.justplay = NoSave(ConfigSelection(choices = [("zap", _("zap")), ("record", _("record"))], default = {0: "record", 1: "zap"}[int(timer.justplay)]))
195
196                 # Timespan
197                 now = [x for x in localtime()]
198                 if timer.hasTimespan():
199                         default = True
200                         now[3] = timer.timespan[0][0]
201                         now[4] = timer.timespan[0][1]
202                         begin = mktime(now)
203                         now[3] = timer.timespan[1][0]
204                         now[4] = timer.timespan[1][1]
205                         end = mktime(now)
206                 else:
207                         default = False
208                         now[3] = 20
209                         now[4] = 15
210                         begin = mktime(now)
211                         now[3] = 23
212                         now[4] = 15
213                         end = mktime(now)
214                 self.timespan = NoSave(ConfigEnableDisable(default = default))
215                 self.timespanbegin = NoSave(ConfigClock(default = begin))
216                 self.timespanend = NoSave(ConfigClock(default = end))
217
218                 # Timeframe
219                 if timer.hasTimeframe():
220                         default = True
221                         begin = timer.getTimeframeBegin()
222                         end = timer.getTimeframeEnd()
223                 else:
224                         default = False
225                         now = [x for x in localtime()]
226                         now[3] = 0
227                         now[4] = 0
228                         begin = mktime(now)
229                         end = begin + 604800 # today + 7d
230                 self.timeframe = NoSave(ConfigEnableDisable(default = default))
231                 self.timeframebegin = NoSave(ConfigDateTime(begin, _("%d.%B %Y"), increment = 86400))
232                 self.timeframeend = NoSave(ConfigDateTime(end, _("%d.%B %Y"), increment = 86400))
233
234                 # Services have their own Screen
235
236                 # Offset
237                 if timer.hasOffset():
238                         default = True
239                         begin = timer.getOffsetBegin()
240                         end = timer.getOffsetEnd()
241                 else:
242                         default = False
243                         begin = 5
244                         end = 5
245                 self.offset = NoSave(ConfigEnableDisable(default = default))
246                 self.offsetbegin = NoSave(ConfigNumber(default = begin))
247                 self.offsetend = NoSave(ConfigNumber(default = end))
248
249                 # AfterEvent
250                 if timer.hasAfterEvent():
251                         default = {
252                                 None: "default",
253                                 AFTEREVENT.NONE: "nothing",
254                                 AFTEREVENT.DEEPSTANDBY: "deepstandby",
255                                 AFTEREVENT.STANDBY: "standby",
256                                 AFTEREVENT.AUTO: "auto"
257                         }[timer.afterevent[0][0]]
258                 else:
259                         default = "default"
260                 self.afterevent = NoSave(ConfigSelection(choices = [
261                         ("default", _("standard")), ("nothing", _("do nothing")),
262                         ("standby", _("go to standby")),
263                         ("deepstandby", _("go to deep standby")),
264                         ("auto", _("auto"))], default = default))
265
266                 # AfterEvent (Timespan)
267                 if timer.hasAfterEvent() and timer.afterevent[0][1][0] is not None:
268                         default = True
269                         now[3] = timer.afterevent[0][1][0][0]
270                         now[4] = timer.afterevent[0][1][0][1]
271                         begin = mktime(now)
272                         now[3] = timer.afterevent[0][1][1][0]
273                         now[4] = timer.afterevent[0][1][1][1]
274                         end = mktime(now)
275                 else:
276                         default = False
277                         now[3] = 23
278                         now[4] = 15
279                         begin = mktime(now)
280                         now[3] = 7
281                         now[4] = 0
282                         end = mktime(now)
283                 self.afterevent_timespan = NoSave(ConfigEnableDisable(default = default))
284                 self.afterevent_timespanbegin = NoSave(ConfigClock(default = begin))
285                 self.afterevent_timespanend = NoSave(ConfigClock(default = end))
286
287                 # Enabled
288                 self.enabled = NoSave(ConfigYesNo(default = timer.enabled))
289
290                 # Maxduration
291                 if timer.hasDuration():
292                         default = True
293                         duration = timer.getDuration()
294                 else:
295                         default = False
296                         duration =70
297                 self.duration = NoSave(ConfigEnableDisable(default = default))
298                 self.durationlength = NoSave(ConfigNumber(default = duration))
299
300                 # Counter
301                 if timer.hasCounter():
302                         default = timer.matchCount
303                 else:
304                         default = 0
305                 self.counter = NoSave(ConfigNumber(default = default))
306                 self.counterLeft = NoSave(ConfigNumber(default = timer.matchLeft))
307                 default = timer.getCounterFormatString()
308                 selection = [("", _("Never")), ("%m", _("Monthly")), ("%U", _("Weekly (Sunday)")), ("%W", _("Weekly (Monday)"))]
309                 if default not in ('', '%m', '%U', '%W'):
310                         selection.append((default, _("Custom (%s)") % (default)))
311                 self.counterFormatString = NoSave(ConfigSelection(selection, default = default))
312
313                 # Avoid Duplicate Description
314                 self.avoidDuplicateDescription = NoSave(ConfigSelection([
315                                 ("0", _("No")),
316                                 ("1", _("On same service")),
317                                 ("2", _("On any service")),
318                                 ("3", _("Any service/recording")),
319                         ],
320                         default = str(timer.getAvoidDuplicateDescription())
321                 ))
322
323                 # Custom Location
324                 if timer.hasDestination():
325                         default = True
326                 else:
327                         default = False
328
329                 self.useDestination = NoSave(ConfigYesNo(default = default))
330
331                 default = timer.destination or Directories.resolveFilename(Directories.SCOPE_HDD)
332                 choices = config.movielist.videodirs.value
333
334                 if default not in choices:
335                         choices.append(default)
336                 self.destination = NoSave(ConfigSelection(default = default, choices = choices))
337
338                 # Tags
339                 self.timerentry_tags = timer.tags
340                 self.tags = NoSave(ConfigSelection(choices = [len(self.timerentry_tags) == 0 and _("None") or ' '.join(self.timerentry_tags)]))
341
342                 # Vps
343                 self.vps_enabled = NoSave(ConfigYesNo(default = timer.vps_enabled))
344                 self.vps_overwrite = NoSave(ConfigYesNo(default = timer.vps_overwrite))
345
346         def pathSelected(self, res):
347                 if res is not None:
348                         # I'm pretty sure this will always fail
349                         if config.movielist.videodirs.value != self.destination.choices:
350                                         self.destination.setChoices(config.movielist.videodirs.value, default = res)
351                         self.destination.value = res
352
353         def chooseDestination(self):
354                 from Screens.LocationBox import MovieLocationBox
355
356                 self.session.openWithCallback(
357                         self.pathSelected,
358                         MovieLocationBox,
359                         _("Choose target folder"),
360                         self.destination.value,
361                         minFree = 100 # Same requirement as in Screens.TimerEntry
362                 )
363
364         def tagEditFinished(self, ret):
365                 if ret is not None:
366                         self.timerentry_tags = ret
367                         self.tags.setChoices([len(ret) == 0 and _("None") or ' '.join(ret)])
368
369         def chooseTags(self):
370                 preferredTagEditor = getPreferredTagEditor()
371                 if preferredTagEditor:
372                         self.session.openWithCallback(
373                                 self.tagEditFinished,
374                                 preferredTagEditor,
375                                 self.timerentry_tags
376                         )
377
378 class AutoTimerEditor(Screen, ConfigListScreen, AutoTimerEditorBase):
379         """Edit AutoTimer"""
380
381         skin = """<screen name="AutoTimerEditor" title="Edit AutoTimer" position="center,center" size="565,350">
382                 <ePixmap position="0,5" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
383                 <ePixmap position="140,5" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
384                 <ePixmap position="280,5" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
385                 <ePixmap position="420,5" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
386                 <widget source="key_red" render="Label" position="0,5" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
387                 <widget source="key_green" render="Label" position="140,5" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
388                 <widget source="key_yellow" render="Label" position="280,5" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
389                 <widget source="key_blue" render="Label" position="420,5" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
390                 <widget name="config" position="5,50" size="555,225" scrollbarMode="showOnDemand" />
391                 <ePixmap pixmap="skin_default/div-h.png" position="0,275" zPosition="1" size="565,2" />
392                 <widget source="help" render="Label" position="5,280" size="555,63" font="Regular;21" />
393         </screen>"""
394
395         def __init__(self, session, timer, editingDefaults = False):
396                 Screen.__init__(self, session)
397
398                 AutoTimerEditorBase.__init__(self, timer, editingDefaults)
399
400                 # Summary
401                 self.setup_title = _("AutoTimer Editor")
402                 self.onChangedEntry = []
403
404                 # We might need to change shown items, so add some notifiers
405                 self.timespan.addNotifier(self.reloadList, initial_call = False)
406                 self.timeframe.addNotifier(self.reloadList, initial_call = False)
407                 self.offset.addNotifier(self.reloadList, initial_call = False)
408                 self.duration.addNotifier(self.reloadList, initial_call = False)
409                 self.afterevent.addNotifier(self.reloadList, initial_call = False)
410                 self.afterevent_timespan.addNotifier(self.reloadList, initial_call = False)
411                 self.counter.addNotifier(self.reloadList, initial_call = False)
412                 self.useDestination.addNotifier(self.reloadList, initial_call = False)
413                 self.vps_enabled.addNotifier(self.reloadList, initial_call = False)
414
415                 self.refresh()
416                 self.initHelpTexts()
417
418                 # XXX: no help for numericaltextinput since it is shown on top of our help
419                 ConfigListScreen.__init__(self, self.list, on_change = self.changed)
420                 self["config"].onSelectionChanged.append(self.updateHelp)
421
422                 # Initialize Buttons
423                 self["key_red"] = StaticText(_("Cancel"))
424                 self["key_green"] = StaticText(_("OK"))
425                 self["key_yellow"] = StaticText()
426                 self["key_blue"] = StaticText()
427
428                 self["help"] = StaticText()
429
430                 # Set Button texts
431                 self.renameServiceButton()
432                 self.renameFilterButton()
433
434                 # Define Actions
435                 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
436                         {
437                                 "cancel": self.cancel,
438                                 "save": self.maybeSave,
439                                 "ok": self.ok,
440                                 "yellow": self.editFilter,
441                                 "blue": self.editServices
442                         }, -2
443                 )
444
445                 # Trigger change
446                 self.changed()
447
448                 self.onLayoutFinish.append(self.setCustomTitle)
449
450         def setCustomTitle(self):
451                 self.setTitle(_("Edit AutoTimer"))
452
453         def renameFilterButton(self):
454                 if self.filterSet:
455                         self["key_yellow"].text = _("edit filters")
456                 else:
457                         self["key_yellow"].text = _("add filters")
458
459         def renameServiceButton(self):
460                 if self.serviceRestriction:
461                         self["key_blue"].text = _("edit services")
462                 else:
463                         self["key_blue"].text = _("add services")
464
465         def updateHelp(self):
466                 cur = self["config"].getCurrent()
467                 if cur:
468                         self["help"].text = self.helpDict.get(cur[1], "")
469
470         def changed(self):
471                 for x in self.onChangedEntry:
472                         try:
473                                 x()
474                         except Exception:
475                                 pass
476
477         def getCurrentEntry(self):
478                 return self["config"].getCurrent()[0]
479
480         def getCurrentValue(self):
481                 return str(self["config"].getCurrent()[1].getText())
482
483         def createSummary(self):
484                 return SetupSummary
485
486         def initHelpTexts(self):
487                 self.helpDict = {
488                         self.enabled: _("Set this NO to disable this AutoTimer."),
489                         self.name: _("This is a name you can give the AutoTimer. It will be shown in the Overview and the Preview."),
490                         self.match: _("This is what will be looked for in event titles. Note that looking for e.g. german umlauts can be tricky as you have to know the encoding the channel uses."),
491                         self.encoding: _("Encoding the channel uses for it's EPG data. You only need to change this if you're searching for special characters like the german umlauts."),
492                         self.searchType: _("Select \"exact match\" to enforce \"Match title\" to match exactly or \"partial match\" if you only want to search for a part of the event title."),
493                         self.searchCase: _("Select whether or not you want to enforce case correctness."),
494                         self.justplay: _("Add zap timer instead of record timer?"),
495                         self.overrideAlternatives: _("With this option enabled the channel to record on can be changed to a alternative service it is restricted to."),
496                         self.timespan: _("Should this AutoTimer be restricted to a timespan?"),
497                         self.timespanbegin: _("Lower bound of timespan. Nothing before this time will be matched. Offsets are not taken into account!"),
498                         self.timespanend: _("Upper bound of timespan. Nothing after this time will be matched. Offsets are not taken into account!"),
499                         self.timeframe: _("By enabling this events will not be matched if they don't occur on certain dates."),
500                         self.timeframebegin: _("First day to match events. No event that begins before this date will be matched."),
501                         self.timeframeend: _("Last day to match events. Events have to begin before this date to be matched."),
502                         self.offset: _("Change default recording offset?"),
503                         self.offsetbegin: _("Time in minutes to prepend to recording."),
504                         self.offsetend: _("Time in minutes to append to recording."),
505                         self.duration: _("Should this AutoTimer only match up to a certain event duration?"),
506                         self.durationlength: _("Maximum event duration to match. If an event is longer than this amount of time (without offset) it won't be matched."),
507                         self.afterevent: _("Power state to change to after recordings. Select \"standard\" to not change the default behavior of enigma2 or values changed by yourself."),
508                         self.afterevent_timespan: _("Restrict \"after event\" to a certain timespan?"),
509                         self.afterevent_timespanbegin: _("Lower bound of timespan."),
510                         self.afterevent_timespanend: _("Upper bound of timespan."),
511                         self.counter: _("With this option you can restrict the AutoTimer to a certain amount of scheduled recordings. Set this to 0 to disable this functionality."),
512                         self.counterLeft: _("Number of scheduled recordings left."),
513                         self.counterFormatString: _("The counter can automatically be reset to the limit at certain intervals."),
514                         self.avoidDuplicateDescription: _("When this option is enabled the AutoTimer won't match events where another timer with the same description already exists in the timer list."),
515                         self.useDestination: _("Should timers created by this AutoTimer be recorded to a custom location?"),
516                         self.destination: _("Select the location to save the recording to."),
517                         self.tags: _("Tags the Timer/Recording will have."),
518                 }
519
520         def refresh(self):
521                 # First three entries are only showed when not editing defaults
522                 list = []
523                 if not self.editingDefaults:
524                         list.extend((
525                                 getConfigListEntry(_("Enabled"), self.enabled),
526                                 getConfigListEntry(_("Description"), self.name),
527                                 getConfigListEntry(_("Match title"), self.match),
528                         ))
529
530                 list.extend((
531                         getConfigListEntry(_("EPG encoding"), self.encoding),
532                         getConfigListEntry(_("Search type"), self.searchType),
533                         getConfigListEntry(_("Search strictness"), self.searchCase),
534                         getConfigListEntry(_("Timer type"), self.justplay),
535                         getConfigListEntry(_("Override found with alternative service"), self.overrideAlternatives),
536                         getConfigListEntry(_("Only match during timespan"), self.timespan)
537                 ))
538
539                 # Only allow editing timespan when it's enabled
540                 if self.timespan.value:
541                         list.extend((
542                                 getConfigListEntry(_("Begin of timespan"), self.timespanbegin),
543                                 getConfigListEntry(_("End of timespan"), self.timespanend)
544                         ))
545
546                 list.append(getConfigListEntry(_("Restrict to events on certain dates"), self.timeframe))
547
548                 # Only allow editing timeframe when it's enabled
549                 if self.timeframe.value:
550                         list.extend((
551                                 getConfigListEntry(_("Not before"), self.timeframebegin),
552                                 getConfigListEntry(_("Not after"), self.timeframeend)
553                         ))
554
555                 list.append(getConfigListEntry(_("Custom offset"), self.offset))
556
557                 # Only allow editing offsets when it's enabled
558                 if self.offset.value:
559                         list.extend((
560                                 getConfigListEntry(_("Offset before recording (in m)"), self.offsetbegin),
561                                 getConfigListEntry(_("Offset after recording (in m)"), self.offsetend)
562                         ))
563
564                 list.append(getConfigListEntry(_("Set maximum duration"), self.duration))
565
566                 # Only allow editing maxduration when it's enabled
567                 if self.duration.value:
568                         list.append(getConfigListEntry(_("Maximum duration (in m)"), self.durationlength))
569
570                 list.append(getConfigListEntry(_("After event"), self.afterevent))
571
572                 # Only allow setting afterevent timespan when afterevent is active
573                 if self.afterevent.value != "default":
574                         list.append(getConfigListEntry(_("Execute \"after event\" during timespan"), self.afterevent_timespan))
575
576                         # Only allow editing timespan when it's enabled
577                         if self.afterevent_timespan.value:
578                                 list.extend((
579                                         getConfigListEntry(_("Begin of \"after event\" timespan"), self.afterevent_timespanbegin),
580                                         getConfigListEntry(_("End of \"after event\" timespan"), self.afterevent_timespanend)
581                                 ))
582
583                 list.append(getConfigListEntry(_("Record a maximum of x times"), self.counter))
584
585                 # Only allow setting matchLeft when counting hits
586                 if self.counter.value:
587                         if not self.editingDefaults:
588                                 list.append(getConfigListEntry(_("Amount of recordings left"), self.counterLeft))
589                         list.append(getConfigListEntry(_("Reset count"), self.counterFormatString))
590
591                 list.append(getConfigListEntry(_("Require description to be unique"), self.avoidDuplicateDescription))
592
593                 # We always add this option though its expert only in enigma2
594                 list.append(getConfigListEntry(_("Use a custom location"), self.useDestination))
595                 if self.useDestination.value:
596                         list.append(getConfigListEntry(_("Custom location"), self.destination))
597
598                 list.append(getConfigListEntry(_("Tags"), self.tags))
599
600                 if hasVps:
601                         list.append(getConfigListEntry(_("Activate VPS"), self.vps_enabled))
602                         if self.vps_enabled.value:
603                                 list.append(getConfigListEntry(_("Control recording completely by service"), self.vps_overwrite))
604
605                 self.list = list
606
607         def reloadList(self, value):
608                 self.refresh()
609                 self["config"].setList(self.list)
610
611         def editFilter(self):
612                 self.session.openWithCallback(
613                         self.editFilterCallback,
614                         AutoTimerFilterEditor,
615                         self.filterSet,
616                         self.excludes,
617                         self.includes
618                 )
619
620         def editFilterCallback(self, ret):
621                 if ret:
622                         self.filterSet = ret[0]
623                         self.excludes = ret[1]
624                         self.includes = ret[2]
625                         self.renameFilterButton()
626
627         def editServices(self):
628                 self.session.openWithCallback(
629                         self.editServicesCallback,
630                         AutoTimerServiceEditor,
631                         self.serviceRestriction,
632                         self.services,
633                         self.bouquets
634                 )
635
636         def editServicesCallback(self, ret):
637                 if ret:
638                         self.serviceRestriction = ret[0]
639                         self.services = ret[1][0]
640                         self.bouquets = ret[1][1]
641                         self.renameServiceButton()
642
643         def keyLeft(self):
644                 cur = self["config"].getCurrent()
645                 cur = cur and cur[1]
646                 if cur == self.tags:
647                         self.chooseTags()
648                 else:
649                         ConfigListScreen.keyLeft(self)
650
651         def keyRight(self):
652                 cur = self["config"].getCurrent()
653                 cur = cur and cur[1]
654                 if cur == self.tags:
655                         self.chooseTags()
656                 else:
657                         ConfigListScreen.keyRight(self)
658
659         def ok(self):
660                 cur = self["config"].getCurrent()
661                 cur = cur and cur[1]
662                 if cur == self.destination:
663                         self.chooseDestination()
664                 elif cur == self.tags:
665                         self.chooseTags()
666                 else:
667                         ConfigListScreen.keyOK(self)
668
669         def cancel(self):
670                 if self["config"].isChanged():
671                         self.session.openWithCallback(
672                                 self.cancelConfirm,
673                                 MessageBox,
674                                 _("Really close without saving settings?")
675                         )
676                 else:
677                         self.close(None)
678
679         def cancelConfirm(self, ret):
680                 if ret:
681                         self.close(None)
682
683         def maybeSave(self):
684                 if self.editingDefaults:
685                         self.save()
686                         return
687                 # Check if any match is set
688                 if not self.match.value.strip():
689                         self.session.open(
690                                         MessageBox,
691                                         _("The match attribute is mandatory."),
692                                         type = MessageBox.TYPE_ERROR,
693                                         timeout = 5
694                         )
695                 # Check if we have a trailing whitespace
696                 elif self.match.value[-1:] == " ":
697                         self.session.openWithCallback(
698                                 self.saveCallback,
699                                 MessageBox,
700                                 _('You entered "%s" as Text to match.\nDo you want to remove trailing whitespaces?') % (self.match.value)
701                         )
702                 # Just save else
703                 else:
704                         self.save()
705
706         def saveCallback(self, ret):
707                 if ret is not None:
708                         if ret:
709                                 self.match.value = self.match.value.rstrip()
710                         self.save()
711                 # Don't to anything if MessageBox was canceled!
712
713         def save(self):
714                 # Match
715                 self.timer.match = self.match.value
716
717                 # Name
718                 self.timer.name = self.name.value.strip() or self.timer.match
719
720                 # Encoding
721                 self.timer.encoding = self.encoding.value
722
723                 # ...
724                 self.timer.searchType = self.searchType.value
725                 self.timer.searchCase = self.searchCase.value
726
727                 # Alternatives
728                 self.timer.overrideAlternatives = self.overrideAlternatives.value
729
730                 # Enabled
731                 self.timer.enabled = self.enabled.value
732
733                 # Justplay
734                 self.timer.justplay = self.justplay.value == "zap"
735
736                 # Timespan
737                 if self.timespan.value:
738                         start = self.timespanbegin.value
739                         end = self.timespanend.value
740                         self.timer.timespan = (start, end)
741                 else:
742                         self.timer.timespan = None
743
744                 # Timeframe
745                 if self.timeframe.value:
746                         start = self.timeframebegin.value
747                         end = self.timeframeend.value
748                         self.timer.timeframe = (start, end)
749                 else:
750                         self.timer.timeframe = None
751
752                 # Services
753                 if self.serviceRestriction:
754                         self.timer.services = self.services
755                         self.timer.bouquets = self.bouquets
756                 else:
757                         self.timer.services = None
758                         self.timer.bouquets = None
759
760                 # Offset
761                 if self.offset.value:
762                         self.timer.offset = (self.offsetbegin.value*60, self.offsetend.value*60)
763                 else:
764                         self.timer.offset = None
765
766                 # AfterEvent
767                 if self.afterevent.value == "default":
768                         self.timer.afterevent = []
769                 else:
770                         afterevent = {
771                                 "nothing": AFTEREVENT.NONE,
772                                 "deepstandby": AFTEREVENT.DEEPSTANDBY,
773                                 "standby": AFTEREVENT.STANDBY,
774                                 "auto": AFTEREVENT.AUTO
775                         }[self.afterevent.value]
776                         # AfterEvent Timespan
777                         if self.afterevent_timespan.value:
778                                 start = self.afterevent_timespanbegin.value
779                                 end = self.afterevent_timespanend.value
780                                 self.timer.afterevent = [(afterevent, (start, end))]
781                         else:
782                                 self.timer.afterevent = [(afterevent, None)]
783
784                 # Maxduration
785                 if self.duration.value:
786                         self.timer.maxduration = self.durationlength.value*60
787                 else:
788                         self.timer.maxduration = None
789
790                 # Ex-&Includes
791                 if self.filterSet:
792                         self.timer.exclude = self.excludes
793                         self.timer.include = self.includes
794                 else:
795                         self.timer.exclude = None
796                         self.timer.include = None
797
798                 # Counter
799                 if self.counter.value:
800                         self.timer.matchCount = self.counter.value
801                         if self.counterLeft.value <= self.counter.value:
802                                 self.timer.matchLeft = self.counterLeft.value
803                         else:
804                                 self.timer.matchLeft = self.counter.value
805                         if self.counterFormatString.value:
806                                 self.timer.matchFormatString = self.counterFormatString.value
807                         else:
808                                 self.timer.matchFormatString = ''
809                 else:
810                         self.timer.matchCount = 0
811                         self.timer.matchLeft = 0
812                         self.timer.matchFormatString = ''
813
814                 self.timer.avoidDuplicateDescription = int(self.avoidDuplicateDescription.value)
815
816                 if self.useDestination.value:
817                         self.timer.destination = self.destination.value
818                 else:
819                         self.timer.destination = None
820
821                 self.timer.tags = self.timerentry_tags
822
823                 self.timer.vps_enabled = self.vps_enabled.value
824                 self.timer.vps_overwrite = self.vps_overwrite.value
825
826                 # Close
827                 self.close(self.timer)
828
829 class AutoTimerFilterEditor(Screen, ConfigListScreen):
830         """Edit AutoTimer Filter"""
831
832         skin = """<screen name="AutoTimerFilterEditor" title="Edit AutoTimer Filters" position="center,center" size="565,280">
833                 <ePixmap position="0,0" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
834                 <ePixmap position="140,0" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
835                 <ePixmap position="280,0" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
836                 <ePixmap position="420,0" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
837                 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
838                 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
839                 <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
840                 <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
841                 <widget name="config" position="5,45" size="555,225" scrollbarMode="showOnDemand" />
842         </screen>"""
843
844         def __init__(self, session, filterset, excludes, includes):
845                 Screen.__init__(self, session)
846
847                 # Summary
848                 self.setup_title = _("AutoTimer Filters")
849                 self.onChangedEntry = []
850
851                 self.typeSelection = NoSave(ConfigSelection(choices = [
852                         ("title", _("in Title")),
853                         ("short", _("in Shortdescription")),
854                         ("desc", _("in Description")),
855                         ("day", _("on Weekday"))]
856                 ))
857                 self.typeSelection.addNotifier(self.refresh, initial_call = False)
858
859                 self.enabled = NoSave(ConfigEnableDisable(default = filterset))
860
861                 self.excludes = excludes
862                 self.includes = includes
863
864                 self.reloadList()
865
866                 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
867
868                 # Initialize Buttons
869                 self["key_red"] = StaticText(_("Cancel"))
870                 self["key_green"] = StaticText(_("Save"))
871                 self["key_yellow"] = StaticText(_("delete"))
872                 self["key_blue"] = StaticText(_("New"))
873
874                 # Define Actions
875                 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
876                         {
877                                 "cancel": self.cancel,
878                                 "save": self.save,
879                                 "yellow": self.remove,
880                                 "blue": self.new
881                         }
882                 )
883
884                 # Trigger change
885                 self.changed()
886
887                 self.onLayoutFinish.append(self.setCustomTitle)
888
889         def setCustomTitle(self):
890                 self.setTitle(_("Edit AutoTimer filters"))
891
892
893         def changed(self):
894                 for x in self.onChangedEntry:
895                         try:
896                                 x()
897                         except Exception:
898                                 pass
899
900         def getCurrentEntry(self):
901                 return self["config"].getCurrent()[0]
902
903         def getCurrentValue(self):
904                 return str(self["config"].getCurrent()[1].getText())
905
906         def createSummary(self):
907                 return SetupSummary
908
909         def saveCurrent(self):
910                 del self.excludes[self.idx][:]
911                 del self.includes[self.idx][:]
912
913                 # Warning, accessing a ConfigListEntry directly might be considered evil!
914
915                 idx = -1
916                 for item in self["config"].getList()[:]:
917                         idx += 1
918                         # Skip empty entries (and those which are no filters)
919                         if item[1].value == "" or idx < 2:
920                                 continue
921                         elif idx < self.lenExcludes:
922                                 self.excludes[self.idx].append(item[1].value.encode("UTF-8"))
923                         else:
924                                 self.includes[self.idx].append(item[1].value.encode("UTF-8"))
925
926         def refresh(self, *args, **kwargs):
927                 self.saveCurrent()
928
929                 self.reloadList()
930                 self["config"].setList(self.list)
931
932         def reloadList(self):
933                 self.list = [
934                         getConfigListEntry(_("Enable Filtering"), self.enabled),
935                         getConfigListEntry(_("Filter"), self.typeSelection)
936                 ]
937
938                 if self.typeSelection.value == "day":
939                         self.idx = 3
940
941                         # Weekdays are presented as ConfigSelection
942                         self.list.extend([
943                                 getConfigListEntry(_("Exclude"), NoSave(ConfigSelection(choices = weekdays, default = x)))
944                                         for x in self.excludes[3]
945                         ])
946                         self.lenExcludes = len(self.list)
947                         self.list.extend([
948                                 getConfigListEntry(_("Include"), NoSave(ConfigSelection(choices = weekdays, default = x)))
949                                         for x in self.includes[3]
950                         ])
951                         return
952                 elif self.typeSelection.value == "title":
953                         self.idx = 0
954                 elif self.typeSelection.value == "short":
955                         self.idx = 1
956                 else: # self.typeSelection.value == "desc":
957                         self.idx = 2
958
959                 self.list.extend([
960                         getConfigListEntry(_("Exclude"), NoSave(ExtendedConfigText(default = x, fixed_size = False)))
961                                 for x in self.excludes[self.idx]
962                 ])
963                 self.lenExcludes = len(self.list)
964                 self.list.extend([
965                         getConfigListEntry(_("Include"), NoSave(ExtendedConfigText(default = x, fixed_size = False)))
966                                 for x in self.includes[self.idx]
967                 ])
968
969         def remove(self):
970                 idx = self["config"].getCurrentIndex()
971                 if idx and idx > 1:
972                         if idx < self.lenExcludes:
973                                 self.lenExcludes -= 1
974
975                         list = self["config"].getList()
976                         list.remove(self["config"].getCurrent())
977                         self["config"].setList(list)
978
979         def new(self):
980                 self.session.openWithCallback(
981                         self.typeSelected,
982                         ChoiceBox,
983                         _("Select type of Filter"),
984                         [
985                                 (_("Exclude"), 0),
986                                 (_("Include"), 1),
987                         ]
988                 )
989
990         def typeSelected(self, ret):
991                 if ret is not None:
992                         list = self["config"].getList()
993
994                         if ret[1] == 0:
995                                 pos = self.lenExcludes
996                                 self.lenExcludes += 1
997                                 text = ret[0]
998                         else:
999                                 pos = len(self.list)
1000                                 text = ret[0]
1001
1002                         if self.typeSelection.value == "day":
1003                                 entry = getConfigListEntry(text, NoSave(ConfigSelection(choices = weekdays)))
1004                         else:
1005                                 entry = getConfigListEntry(text, NoSave(ExtendedConfigText(fixed_size = False)))
1006
1007                         list.insert(pos, entry)
1008                         self["config"].setList(list)
1009
1010         def cancel(self):
1011                 if self["config"].isChanged():
1012                         self.session.openWithCallback(
1013                                 self.cancelConfirm,
1014                                 MessageBox,
1015                                 _("Really close without saving settings?")
1016                         )
1017                 else:
1018                         self.close(None)
1019
1020         def cancelConfirm(self, ret):
1021                 if ret:
1022                         self.close(None)
1023
1024         def save(self):
1025                 self.refresh()
1026
1027                 self.close((
1028                         self.enabled.value,
1029                         self.excludes,
1030                         self.includes
1031                 ))
1032
1033 class AutoTimerServiceEditor(Screen, ConfigListScreen):
1034         """Edit allowed Services of a AutoTimer"""
1035
1036         skin = """<screen name="AutoTimerServiceEditor" title="Edit AutoTimer Services" position="center,center" size="565,280">
1037                 <ePixmap position="0,0" size="140,40" pixmap="skin_default/buttons/red.png" transparent="1" alphatest="on" />
1038                 <ePixmap position="140,0" size="140,40" pixmap="skin_default/buttons/green.png" transparent="1" alphatest="on" />
1039                 <ePixmap position="280,0" size="140,40" pixmap="skin_default/buttons/yellow.png" transparent="1" alphatest="on" />
1040                 <ePixmap position="420,0" size="140,40" pixmap="skin_default/buttons/blue.png" transparent="1" alphatest="on" />
1041                 <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
1042                 <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
1043                 <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
1044                 <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" valign="center" halign="center" font="Regular;21" transparent="1" foregroundColor="white" shadowColor="black" shadowOffset="-1,-1" />
1045                 <widget name="config" position="5,45" size="555,225" scrollbarMode="showOnDemand" />
1046         </screen>"""
1047
1048         def __init__(self, session, servicerestriction, servicelist, bouquetlist):
1049                 Screen.__init__(self, session)
1050
1051                 # Summary
1052                 self.setup_title = _("AutoTimer Services")
1053                 self.onChangedEntry = []
1054
1055                 self.services = (
1056                         servicelist[:],
1057                         bouquetlist[:]
1058                 )
1059
1060                 self.enabled = NoSave(ConfigEnableDisable(default = servicerestriction))
1061                 self.typeSelection = NoSave(ConfigSelection(choices = [
1062                         ("channels", _("Channels")),
1063                         ("bouquets", _("Bouquets"))]
1064                 ))
1065                 self.typeSelection.addNotifier(self.refresh, initial_call = False)
1066
1067                 self.reloadList()
1068
1069                 ConfigListScreen.__init__(self, self.list, session = session, on_change = self.changed)
1070
1071                 # Initialize Buttons
1072                 self["key_red"] = StaticText(_("Cancel"))
1073                 self["key_green"] = StaticText(_("OK"))
1074                 self["key_yellow"] = StaticText(_("delete"))
1075                 self["key_blue"] = StaticText(_("New"))
1076
1077                 # Define Actions
1078                 self["actions"] = ActionMap(["SetupActions", "ColorActions"],
1079                         {
1080                                 "cancel": self.cancel,
1081                                 "save": self.save,
1082                                 "yellow": self.remove,
1083                                 "blue": self.new
1084                         }
1085                 )
1086
1087                 # Trigger change
1088                 self.changed()
1089
1090                 self.onLayoutFinish.append(self.setCustomTitle)
1091
1092         def setCustomTitle(self):
1093                 self.setTitle(_("Edit AutoTimer services"))
1094
1095         def saveCurrent(self):
1096                 del self.services[self.idx][:]
1097
1098                 # Warning, accessing a ConfigListEntry directly might be considered evil!
1099
1100                 myl = self["config"].getList()[:]
1101                 myl.pop(0) # Enabled
1102                 myl.pop(0) # Type
1103                 for item in myl:
1104                         self.services[self.idx].append(item[1].value)
1105
1106         def refresh(self, *args, **kwargs):
1107                 self.saveCurrent()
1108
1109                 self.reloadList()
1110                 self["config"].setList(self.list)
1111
1112         def reloadList(self):
1113                 self.list = [
1114                         getConfigListEntry(_("Enable Service Restriction"), self.enabled),
1115                         getConfigListEntry(_("Editing"), self.typeSelection)
1116                 ]
1117
1118                 if self.typeSelection.value == "channels":
1119                         self.idx = 0
1120                 else: # self.typeSelection.value == "bouquets":
1121                         self.idx = 1
1122
1123                 self.list.extend([
1124                         getConfigListEntry(_("Record on"), NoSave(ConfigSelection(choices = [(str(x), ServiceReference(str(x)).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))])))
1125                                 for x in self.services[self.idx]
1126                 ])
1127
1128         def changed(self):
1129                 for x in self.onChangedEntry:
1130                         try:
1131                                 x()
1132                         except Exception:
1133                                 pass
1134
1135         def getCurrentEntry(self):
1136                 return self["config"].getCurrent()[0]
1137
1138         def getCurrentValue(self):
1139                 return str(self["config"].getCurrent()[1].getText())
1140
1141         def createSummary(self):
1142                 return SetupSummary
1143
1144         def remove(self):
1145                 idx = self["config"].getCurrentIndex()
1146                 if idx and idx > 1:
1147                         list = self["config"].getList()
1148                         list.remove(self["config"].getCurrent())
1149                         self["config"].setList(list)
1150
1151         def new(self):
1152                 if self.typeSelection.value == "channels":
1153                         self.session.openWithCallback(
1154                                 self.finishedServiceSelection,
1155                                 SimpleChannelSelection,
1156                                 _("Select channel to record on")
1157                         )
1158                 else: # self.typeSelection.value == "bouquets":
1159                         self.session.openWithCallback(
1160                                 self.finishedServiceSelection,
1161                                 SimpleBouquetSelection,
1162                                 _("Select bouquet to record on")
1163                         )
1164
1165         def finishedServiceSelection(self, *args):
1166                 if args:
1167                         list = self["config"].getList()
1168                         sname = args[0].toString()
1169
1170                         if self.typeSelection.value == "channels" and not (args[0].flags & eServiceReference.isGroup):
1171                                 # strip all after last : when adding a (non alternative) channel
1172                                 pos = sname.rfind(':')
1173                                 if pos != -1:
1174                                         if sname[pos-1] == ':':
1175                                                 pos -= 1
1176                                         sname = sname[:pos+1]
1177
1178                         list.append(getConfigListEntry(_("Record on"), NoSave(ConfigSelection(choices = [(sname, ServiceReference(args[0]).getServiceName().replace('\xc2\x86', '').replace('\xc2\x87', ''))]))))
1179                         self["config"].setList(list)
1180
1181         def cancel(self):
1182                 if self["config"].isChanged():
1183                         self.session.openWithCallback(
1184                                 self.cancelConfirm,
1185                                 MessageBox,
1186                                 _("Really close without saving settings?")
1187                         )
1188                 else:
1189                         self.close(None)
1190
1191         def cancelConfirm(self, ret):
1192                 if ret:
1193                         self.close(None)
1194
1195         def save(self):
1196                 self.refresh()
1197
1198                 self.close((
1199                         self.enabled.value,
1200                         self.services
1201                 ))
1202
1203 def addAutotimerFromSearchString(session, match):
1204         from AutoTimerComponent import preferredAutoTimerComponent
1205         from AutoTimerImporter import AutoTimerImporter
1206         from plugin import autotimer
1207
1208         # Create instance if needed
1209         if autotimer is None:
1210                 from AutoTimer import AutoTimer
1211                 autotimer = AutoTimer()
1212                 autotimer.readXml()
1213
1214         newTimer = autotimer.defaultTimer.clone()
1215         newTimer.id = autotimer.getUniqueId()
1216         newTimer.name = match
1217         newTimer.match = ''
1218         newTimer.enabled = True
1219
1220         session.openWithCallback(
1221                 importerCallback,
1222                 AutoTimerImporter,
1223                 newTimer,
1224                 match,          # Proposed Match
1225                 None,           # Proposed Begin
1226                 None,           # Proposed End
1227                 None,           # Proposed Disabled
1228                 None,           # Proposed ServiceReference
1229                 None,           # Proposed afterEvent
1230                 None,           # Proposed justplay
1231                 None,           # Proposed dirname, can we get anything useful here?
1232                 []                      # Proposed tags
1233         )
1234
1235 def addAutotimerFromEvent(session, evt = None, service = None):
1236         from AutoTimerComponent import preferredAutoTimerComponent
1237         from AutoTimerImporter import AutoTimerImporter
1238         from plugin import autotimer
1239
1240         # Create instance if needed
1241         if autotimer is None:
1242                 from AutoTimer import AutoTimer
1243                 autotimer = AutoTimer()
1244                 autotimer.readXml()
1245
1246         match = evt and evt.getEventName() or ""
1247         name = match or "New AutoTimer"
1248         sref = None
1249         if service is not None:
1250                 service = str(service)
1251                 myref = eServiceReference(service)
1252                 if not (myref.flags & eServiceReference.isGroup):
1253                         # strip all after last :
1254                         pos = service.rfind(':')
1255                         if pos != -1:
1256                                 if service[pos-1] == ':':
1257                                         pos -= 1
1258                                 service = service[:pos+1]
1259
1260                 sref = ServiceReference(myref)
1261         if evt:
1262                 # timespan defaults to +- 1h
1263                 begin = evt.getBeginTime()-3600
1264                 end = begin + evt.getDuration()+7200
1265         else:
1266                 begin = end = 0
1267
1268         # XXX: we might want to make sure that we actually collected any data because the importer does not do so :-)
1269
1270         newTimer = autotimer.defaultTimer.clone()
1271         newTimer.id = autotimer.getUniqueId()
1272         newTimer.name = name
1273         newTimer.match = ''
1274         newTimer.enabled = True
1275
1276         session.openWithCallback(
1277                 importerCallback,
1278                 AutoTimerImporter,
1279                 newTimer,
1280                 match,          # Proposed Match
1281                 begin,          # Proposed Begin
1282                 end,            # Proposed End
1283                 None,           # Proposed Disabled
1284                 sref,           # Proposed ServiceReference
1285                 None,           # Proposed afterEvent
1286                 None,           # Proposed justplay
1287                 None,           # Proposed dirname, can we get anything useful here?
1288                 []                      # Proposed tags
1289         )
1290
1291 def addAutotimerFromService(session, service = None):
1292         from AutoTimerComponent import preferredAutoTimerComponent
1293         from AutoTimerImporter import AutoTimerImporter
1294         from plugin import autotimer
1295
1296         # Create instance if needed
1297         if autotimer is None:
1298                 from AutoTimer import AutoTimer
1299                 autotimer = AutoTimer()
1300                 autotimer.readXml()
1301
1302         serviceHandler = eServiceCenter.getInstance()
1303         info = serviceHandler.info(service)
1304
1305         match = info and info.getName(service) or ""
1306         name = match or "New AutoTimer"
1307         sref = info and info.getInfoString(service, iServiceInformation.sServiceref)
1308         if sref:
1309                 # strip all after last :
1310                 pos = sref.rfind(':')
1311                 if pos != -1:
1312                         if sref[pos-1] == ':':
1313                                 pos -= 1
1314                         sref = sref[:pos+1]
1315
1316                 sref = ServiceReference(sref)
1317         if info:
1318                 begin = info.getInfo(service, iServiceInformation.sTimeCreate)
1319                 end = begin + info.getLength(service)
1320         else:
1321                 begin = end = 0
1322
1323         from os.path import dirname
1324         path = dirname(service.getPath())
1325         if not path == '/':
1326                 path += '/'
1327
1328         tags = info.getInfoString(service, iServiceInformation.sTags)
1329         tags = tags and tags.split(' ') or []
1330
1331         newTimer = autotimer.defaultTimer.clone()
1332         newTimer.id = autotimer.getUniqueId()
1333         newTimer.name = name
1334         newTimer.match = ''
1335         newTimer.enabled = True
1336
1337         # XXX: we might want to make sure that we actually collected any data because the importer does not do so :-)
1338
1339         session.openWithCallback(
1340                 importerCallback,
1341                 AutoTimerImporter,
1342                 newTimer,
1343                 match,          # Proposed Match
1344                 begin,          # Proposed Begin
1345                 end,            # Proposed End
1346                 None,           # Proposed Disabled
1347                 sref,           # Proposed ServiceReference
1348                 None,           # Proposed afterEvent
1349                 None,           # Proposed justplay
1350                 path,           # Proposed dirname
1351                 tags            # Proposed tags
1352         )
1353
1354 def importerCallback(ret):
1355         if ret:
1356                 ret, session = ret
1357
1358                 session.openWithCallback(
1359                         editorCallback,
1360                         AutoTimerEditor,
1361                         ret
1362                 )
1363
1364 def editorCallback(ret):
1365         if ret:
1366                 from plugin import autotimer
1367
1368                 if autotimer is None:
1369                         from AutoTimer import AutoTimer
1370                         autotimer = AutoTimer()
1371                         autotimer.readXml()
1372
1373                 autotimer.add(ret)
1374
1375                 # Save modified xml
1376                 autotimer.writeXml()
1377