[RecordTimer] fix repeat timer issue.
[vuplus_dvbapp] / lib / python / Screens / TimerEntry.py
1 from Screen import Screen
2 import ChannelSelection
3 from ServiceReference import ServiceReference
4 from Components.config import config, ConfigSelection, ConfigText, ConfigSubList, ConfigDateTime, ConfigClock, ConfigYesNo, getConfigListEntry
5 from Components.ActionMap import NumberActionMap
6 from Components.ConfigList import ConfigListScreen
7 from Components.MenuList import MenuList
8 from Components.Button import Button
9 from Components.Label import Label
10 from Components.Pixmap import Pixmap
11 from Components.SystemInfo import SystemInfo
12 from Components.UsageConfig import defaultMoviePath
13 from Screens.MovieSelection import getPreferredTagEditor
14 from Screens.LocationBox import MovieLocationBox
15 from Screens.ChoiceBox import ChoiceBox
16 from Screens.MessageBox import MessageBox
17 from RecordTimer import AFTEREVENT
18 from enigma import eEPGCache, eServiceReference
19 from time import localtime, mktime, time, strftime
20 from datetime import datetime
21
22 class TimerEntry(Screen, ConfigListScreen):
23         def __init__(self, session, timer):
24                 Screen.__init__(self, session)
25                 self.timer = timer
26
27                 self.entryDate = None
28                 self.entryService = None
29
30                 self["oktext"] = Label(_("OK"))
31                 self["canceltext"] = Label(_("Cancel"))
32                 self["ok"] = Pixmap()
33                 self["cancel"] = Pixmap()
34
35                 self.createConfig()
36
37                 self["actions"] = NumberActionMap(["SetupActions", "GlobalActions", "PiPSetupActions"],
38                 {
39                         "ok": self.keySelect,
40                         "save": self.keyGo,
41                         "cancel": self.keyCancel,
42                         "volumeUp": self.incrementStart,
43                         "volumeDown": self.decrementStart,
44                         "size+": self.incrementEnd,
45                         "size-": self.decrementEnd
46                 }, -2)
47
48                 self.list = []
49                 ConfigListScreen.__init__(self, self.list, session = session)
50                 self.createSetup("config")
51
52         def createConfig(self):
53                         justplay = self.timer.justplay
54
55                         afterevent = {
56                                 AFTEREVENT.NONE: "nothing",
57                                 AFTEREVENT.DEEPSTANDBY: "deepstandby",
58                                 AFTEREVENT.STANDBY: "standby",
59                                 AFTEREVENT.AUTO: "auto"
60                                 }[self.timer.afterEvent]
61
62                         weekday_table = ("mon", "tue", "wed", "thu", "fri", "sat", "sun")
63
64                         # calculate default values
65                         day = []
66                         weekday = 0
67                         for x in (0, 1, 2, 3, 4, 5, 6):
68                                 day.append(0)
69                         if self.timer.repeated: # repeated
70                                 type = "repeated"
71                                 if (self.timer.repeated == 31): # Mon-Fri
72                                         repeated = "weekdays"
73                                 elif (self.timer.repeated == 127): # daily
74                                         repeated = "daily"
75                                 else:
76                                         flags = self.timer.repeated
77                                         repeated = "user"
78                                         count = 0
79                                         for x in (0, 1, 2, 3, 4, 5, 6):
80                                                 if flags == 1: # weekly
81                                                         print "Set to weekday " + str(x)
82                                                         weekday = x
83                                                 if flags & 1 == 1: # set user defined flags
84                                                         day[x] = 1
85                                                         count += 1
86                                                 else:
87                                                         day[x] = 0
88                                                 flags = flags >> 1
89                                         if count == 1:
90                                                 repeated = "weekly"
91                         else: # once
92                                 type = "once"
93                                 repeated = None
94                                 weekday = (int(strftime("%w", localtime(self.timer.begin))) - 1) % 7
95                                 day[weekday] = 1
96
97                         timer_choices = [("zap", _("zap"))]
98                         default = "zap"
99                         if SystemInfo["PVRSupport"]:
100                                 timer_choices.append(("record", _("record")))
101                                 default = {0: "record", 1: "zap"}[justplay]
102                         self.timerentry_justplay = ConfigSelection(choices = timer_choices, default = default)
103                         if SystemInfo["DeepstandbySupport"]:
104                                 shutdownString = _("go to deep standby")
105                         else:
106                                 shutdownString = _("shut down")
107                         self.timerentry_afterevent = ConfigSelection(choices = [("nothing", _("do nothing")), ("standby", _("go to standby")), ("deepstandby", shutdownString), ("auto", _("auto"))], default = afterevent)
108                         self.timerentry_type = ConfigSelection(choices = [("once",_("once")), ("repeated", _("repeated"))], default = type)
109                         self.timerentry_name = ConfigText(default = self.timer.name, visible_width = 50, fixed_size = False)
110                         self.timerentry_description = ConfigText(default = self.timer.description, visible_width = 50, fixed_size = False)
111                         self.timerentry_tags = self.timer.tags[:]
112                         self.timerentry_tagsset = ConfigSelection(choices = [not self.timerentry_tags and "None" or " ".join(self.timerentry_tags)])
113
114                         self.timerentry_repeated = ConfigSelection(default = repeated, choices = [("daily", _("daily")), ("weekly", _("weekly")), ("weekdays", _("Mon-Fri")), ("user", _("user defined"))])
115                         
116                         self.timerentry_date = ConfigDateTime(default = self.timer.begin, formatstring = _("%d.%B %Y"), increment = 86400)
117                         self.timerentry_starttime = ConfigClock(default = self.timer.begin)
118                         self.timerentry_endtime = ConfigClock(default = self.timer.end)
119                         self.timerentry_showendtime = ConfigSelection(default = ((self.timer.end - self.timer.begin) > 4), choices = [(True, _("yes")), (False, _("no"))])
120
121                         default = self.timer.dirname or defaultMoviePath()
122                         tmp = config.movielist.videodirs.value
123                         if default not in tmp:
124                                 tmp.append(default)
125                         self.timerentry_dirname = ConfigSelection(default = default, choices = tmp)
126
127                         self.timerentry_repeatedbegindate = ConfigDateTime(default = self.timer.repeatedbegindate, formatstring = _("%d.%B %Y"), increment = 86400)
128
129                         self.timerentry_weekday = ConfigSelection(default = weekday_table[weekday], choices = [("mon",_("Monday")), ("tue", _("Tuesday")), ("wed",_("Wednesday")), ("thu", _("Thursday")), ("fri", _("Friday")), ("sat", _("Saturday")), ("sun", _("Sunday"))])
130
131                         self.timerentry_day = ConfigSubList()
132                         for x in (0, 1, 2, 3, 4, 5, 6):
133                                 self.timerentry_day.append(ConfigYesNo(default = day[x]))
134
135                         # FIXME some service-chooser needed here
136                         servicename = "N/A"
137                         try: # no current service available?
138                                 servicename = str(self.timer.service_ref.getServiceName())
139                         except:
140                                 pass
141                         if not servicename:
142                                 servicename = "N/A"
143                         self.timerentry_service_ref = self.timer.service_ref
144                         self.timerentry_service = ConfigSelection([servicename])
145
146         def createSetup(self, widget):
147                 self.list = []
148                 self.list.append(getConfigListEntry(_("Name"), self.timerentry_name))
149                 self.list.append(getConfigListEntry(_("Description"), self.timerentry_description))
150                 self.timerJustplayEntry = getConfigListEntry(_("Timer Type"), self.timerentry_justplay)
151                 self.list.append(self.timerJustplayEntry)
152                 self.timerTypeEntry = getConfigListEntry(_("Repeat Type"), self.timerentry_type)
153                 self.list.append(self.timerTypeEntry)
154
155                 if self.timerentry_type.value == "once":
156                         self.frequencyEntry = None
157                 else: # repeated
158                         self.frequencyEntry = getConfigListEntry(_("Repeats"), self.timerentry_repeated)
159                         self.list.append(self.frequencyEntry)
160                         self.repeatedbegindateEntry = getConfigListEntry(_("Starting on"), self.timerentry_repeatedbegindate)
161                         self.list.append(self.repeatedbegindateEntry)
162                         if self.timerentry_repeated.value == "daily":
163                                 pass
164                         if self.timerentry_repeated.value == "weekdays":
165                                 pass
166                         if self.timerentry_repeated.value == "weekly":
167                                 self.list.append(getConfigListEntry(_("Weekday"), self.timerentry_weekday))
168
169                         if self.timerentry_repeated.value == "user":
170                                 self.list.append(getConfigListEntry(_("Monday"), self.timerentry_day[0]))
171                                 self.list.append(getConfigListEntry(_("Tuesday"), self.timerentry_day[1]))
172                                 self.list.append(getConfigListEntry(_("Wednesday"), self.timerentry_day[2]))
173                                 self.list.append(getConfigListEntry(_("Thursday"), self.timerentry_day[3]))
174                                 self.list.append(getConfigListEntry(_("Friday"), self.timerentry_day[4]))
175                                 self.list.append(getConfigListEntry(_("Saturday"), self.timerentry_day[5]))
176                                 self.list.append(getConfigListEntry(_("Sunday"), self.timerentry_day[6]))
177
178                 self.entryDate = getConfigListEntry(_("Date"), self.timerentry_date)
179                 if self.timerentry_type.value == "once":
180                         self.list.append(self.entryDate)
181                 
182                 self.entryStartTime = getConfigListEntry(_("StartTime"), self.timerentry_starttime)
183                 self.list.append(self.entryStartTime)
184                 
185                 self.entryShowEndTime = getConfigListEntry(_("Set End Time"), self.timerentry_showendtime)
186                 if self.timerentry_justplay.value == "zap":
187                         self.list.append(self.entryShowEndTime)
188                 self.entryEndTime = getConfigListEntry(_("EndTime"), self.timerentry_endtime)
189                 if self.timerentry_justplay.value != "zap" or self.timerentry_showendtime.value:
190                         self.list.append(self.entryEndTime)
191
192                 self.channelEntry = getConfigListEntry(_("Channel"), self.timerentry_service)
193                 self.list.append(self.channelEntry)
194
195                 self.dirname = getConfigListEntry(_("Location"), self.timerentry_dirname)
196                 self.tagsSet = getConfigListEntry(_("Tags"), self.timerentry_tagsset)
197                 if self.timerentry_justplay.value != "zap":
198                         if config.usage.setup_level.index >= 2: # expert+
199                                 self.list.append(self.dirname)
200                         if getPreferredTagEditor():
201                                 self.list.append(self.tagsSet)
202                         self.list.append(getConfigListEntry(_("After event"), self.timerentry_afterevent))
203
204                 self[widget].list = self.list
205                 self[widget].l.setList(self.list)
206
207         def newConfig(self):
208                 print "newConfig", self["config"].getCurrent()
209                 if self["config"].getCurrent() in (self.timerTypeEntry, self.timerJustplayEntry, self.frequencyEntry, self.entryShowEndTime):
210                         self.createSetup("config")
211
212         def keyLeft(self):
213                 if self["config"].getCurrent() in (self.channelEntry, self.tagsSet):
214                         self.keySelect()
215                 else:
216                         ConfigListScreen.keyLeft(self)
217                         self.newConfig()
218
219         def keyRight(self):
220                 if self["config"].getCurrent() in (self.channelEntry, self.tagsSet):
221                         self.keySelect()
222                 else:
223                         ConfigListScreen.keyRight(self)
224                         self.newConfig()
225
226         def keySelect(self):
227                 cur = self["config"].getCurrent()
228                 if cur == self.channelEntry:
229                         self.session.openWithCallback(
230                                 self.finishedChannelSelection,
231                                 ChannelSelection.SimpleChannelSelection,
232                                 _("Select channel to record from")
233                         )
234                 elif config.usage.setup_level.index >= 2 and cur == self.dirname:
235                         self.session.openWithCallback(
236                                 self.pathSelected,
237                                 MovieLocationBox,
238                                 _("Choose target folder"),
239                                 self.timerentry_dirname.value,
240                                 minFree = 100 # We require at least 100MB free space
241                         )
242                 elif getPreferredTagEditor() and cur == self.tagsSet:
243                         self.session.openWithCallback(
244                                 self.tagEditFinished,
245                                 getPreferredTagEditor(),
246                                 self.timerentry_tags
247                         )
248                 else:
249                         self.keyGo()
250
251         def finishedChannelSelection(self, *args):
252                 if args:
253                         self.timerentry_service_ref = ServiceReference(args[0])
254                         self.timerentry_service.setCurrentText(self.timerentry_service_ref.getServiceName())
255                         self["config"].invalidate(self.channelEntry)
256                         
257         def getTimestamp(self, date, mytime):
258                 d = localtime(date)
259                 dt = datetime(d.tm_year, d.tm_mon, d.tm_mday, mytime[0], mytime[1])
260                 return int(mktime(dt.timetuple()))
261
262         def getBeginEnd(self):
263                 date = self.timerentry_date.value
264                 endtime = self.timerentry_endtime.value
265                 starttime = self.timerentry_starttime.value
266
267                 begin = self.getTimestamp(date, starttime)
268                 end = self.getTimestamp(date, endtime)
269
270                 # if the endtime is less than the starttime, add 1 day.
271                 if end < begin:
272                         end += 86400
273                 return begin, end
274
275         def selectChannelSelector(self, *args):
276                 self.session.openWithCallback(
277                                 self.finishedChannelSelectionCorrection,
278                                 ChannelSelection.SimpleChannelSelection,
279                                 _("Select channel to record from")
280                         )
281
282         def finishedChannelSelectionCorrection(self, *args):
283                 if args:
284                         self.finishedChannelSelection(*args)
285                         self.keyGo()
286
287         def keyGo(self, result = None):
288                 if not self.timerentry_service_ref.isRecordable():
289                         self.session.openWithCallback(self.selectChannelSelector, MessageBox, _("You didn't select a channel to record from."), MessageBox.TYPE_ERROR)
290                         return
291                 self.timer.name = self.timerentry_name.value
292                 self.timer.description = self.timerentry_description.value
293                 self.timer.justplay = self.timerentry_justplay.value == "zap"
294                 if self.timerentry_justplay.value == "zap":
295                         if not self.timerentry_showendtime.value:
296                                 self.timerentry_endtime.value = self.timerentry_starttime.value
297                 self.timer.resetRepeated()
298                 self.timer.afterEvent = {
299                         "nothing": AFTEREVENT.NONE,
300                         "deepstandby": AFTEREVENT.DEEPSTANDBY,
301                         "standby": AFTEREVENT.STANDBY,
302                         "auto": AFTEREVENT.AUTO
303                         }[self.timerentry_afterevent.value]
304                 self.timer.service_ref = self.timerentry_service_ref
305                 self.timer.tags = self.timerentry_tags
306
307                 if self.timer.dirname or self.timerentry_dirname.value != defaultMoviePath():
308                         self.timer.dirname = self.timerentry_dirname.value
309                         config.movielist.last_timer_videodir.value = self.timer.dirname
310                         config.movielist.last_timer_videodir.save()
311
312                 if self.timerentry_type.value == "once":
313                         self.timer.begin, self.timer.end = self.getBeginEnd()
314                 if self.timerentry_type.value == "repeated":
315                         if self.timerentry_repeated.value == "daily":
316                                 for x in (0, 1, 2, 3, 4, 5, 6):
317                                         self.timer.setRepeated(x)
318
319                         if self.timerentry_repeated.value == "weekly":
320                                 self.timer.setRepeated(self.timerentry_weekday.index)
321
322                         if self.timerentry_repeated.value == "weekdays":
323                                 for x in (0, 1, 2, 3, 4):
324                                         self.timer.setRepeated(x)
325
326                         if self.timerentry_repeated.value == "user":
327                                 for x in (0, 1, 2, 3, 4, 5, 6):
328                                         if self.timerentry_day[x].value:
329                                                 self.timer.setRepeated(x)
330
331                         self.timer.repeatedbegindate = self.getTimestamp(self.timerentry_repeatedbegindate.value, self.timerentry_starttime.value)
332                         if self.timer.repeated:
333                                 self.timer.begin = self.getTimestamp(self.timerentry_repeatedbegindate.value, self.timerentry_starttime.value)
334                                 self.timer.end = self.getTimestamp(self.timerentry_repeatedbegindate.value, self.timerentry_endtime.value)
335                         else:
336                                 self.timer.begin = self.getTimestamp(time.time(), self.timerentry_starttime.value)
337                                 self.timer.end = self.getTimestamp(time.time(), self.timerentry_endtime.value)
338
339                         # when a timer end is set before the start, add 1 day
340                         if self.timer.end < self.timer.begin:
341                                 self.timer.end += 86400
342
343                 if self.timer.eit is not None:
344                         event = eEPGCache.getInstance().lookupEventId(self.timer.service_ref.ref, self.timer.eit)
345                         if event:
346                                 n = event.getNumOfLinkageServices()
347                                 if n > 1:
348                                         tlist = []
349                                         ref = self.session.nav.getCurrentlyPlayingServiceReference()
350                                         parent = self.timer.service_ref.ref
351                                         selection = 0
352                                         for x in range(n):
353                                                 i = event.getLinkageService(parent, x)
354                                                 if i.toString() == ref.toString():
355                                                         selection = x
356                                                 tlist.append((i.getName(), i))
357                                         self.session.openWithCallback(self.subserviceSelected, ChoiceBox, title=_("Please select a subservice to record..."), list = tlist, selection = selection)
358                                         return
359                                 elif n > 0:
360                                         parent = self.timer.service_ref.ref
361                                         self.timer.service_ref = ServiceReference(event.getLinkageService(parent, 0))
362                 self.saveTimer()
363                 self.close((True, self.timer))
364
365         def incrementStart(self):
366                 self.timerentry_starttime.increment()
367                 self["config"].invalidate(self.entryStartTime)
368
369         def decrementStart(self):
370                 self.timerentry_starttime.decrement()
371                 self["config"].invalidate(self.entryStartTime)
372
373         def incrementEnd(self):
374                 if self.entryEndTime is not None:
375                         self.timerentry_endtime.increment()
376                         self["config"].invalidate(self.entryEndTime)
377
378         def decrementEnd(self):
379                 if self.entryEndTime is not None:
380                         self.timerentry_endtime.decrement()
381                         self["config"].invalidate(self.entryEndTime)
382
383         def subserviceSelected(self, service):
384                 if not service is None:
385                         self.timer.service_ref = ServiceReference(service[1])
386                 self.saveTimer()
387                 self.close((True, self.timer))
388
389         def saveTimer(self):
390                 self.session.nav.RecordTimer.saveTimer()
391
392         def keyCancel(self):
393                 self.close((False,))
394
395         def pathSelected(self, res):
396                 if res is not None:
397                         if config.movielist.videodirs.value != self.timerentry_dirname.choices:
398                                 self.timerentry_dirname.setChoices(config.movielist.videodirs.value, default=res)
399                         self.timerentry_dirname.value = res
400
401         def tagEditFinished(self, ret):
402                 if ret is not None:
403                         self.timerentry_tags = ret
404                         self.timerentry_tagsset.setChoices([not ret and "None" or " ".join(ret)])
405                         self["config"].invalidate(self.tagsSet)
406
407 class TimerLog(Screen):
408         def __init__(self, session, timer):
409                 Screen.__init__(self, session)
410                 self.timer = timer;
411                 self.log_entries = self.timer.log_entries[:]
412
413                 self.fillLogList()
414
415                 self["loglist"] = MenuList(self.list)
416                 self["logentry"] = Label()
417
418                 self["key_red"] = Button(_("Delete entry"))
419                 self["key_green"] = Button()
420                 self["key_yellow"] = Button("")
421                 self["key_blue"] = Button(_("Clear log"))
422
423                 self.onShown.append(self.updateText)
424
425                 self["actions"] = NumberActionMap(["OkCancelActions", "DirectionActions", "ColorActions"],
426                 {
427                         "ok": self.keyClose,
428                         "cancel": self.keyClose,
429                         "up": self.up,
430                         "down": self.down,
431                         "left": self.left,
432                         "right": self.right,
433                         "red": self.deleteEntry,
434                         "blue": self.clearLog
435                 }, -1)
436
437         def deleteEntry(self):
438                 cur = self["loglist"].getCurrent()
439                 if cur is None:
440                         return 
441                 self.log_entries.remove(cur[1])
442                 self.fillLogList()
443                 self["loglist"].l.setList(self.list)
444                 self.updateText()
445
446         def fillLogList(self):
447                 self.list = [(str(strftime("%Y-%m-%d %H-%M", localtime(x[0])) + " - " + x[2]), x) for x in self.log_entries]
448
449         def clearLog(self):
450                 self.log_entries = []
451                 self.fillLogList()
452                 self["loglist"].l.setList(self.list)
453                 self.updateText()
454
455         def keyClose(self):
456                 if self.timer.log_entries != self.log_entries:
457                         self.timer.log_entries = self.log_entries
458                         self.close((True, self.timer))
459                 else:
460                         self.close((False,))
461
462         def up(self):
463                 self["loglist"].instance.moveSelection(self["loglist"].instance.moveUp)
464                 self.updateText()
465
466         def down(self):
467                 self["loglist"].instance.moveSelection(self["loglist"].instance.moveDown)
468                 self.updateText()
469
470         def left(self):
471                 self["loglist"].instance.moveSelection(self["loglist"].instance.pageUp)
472                 self.updateText()
473
474         def right(self):
475                 self["loglist"].instance.moveSelection(self["loglist"].instance.pageDown)
476                 self.updateText()
477
478         def updateText(self):
479                 if self.list:
480                         self["logentry"].setText(str(self["loglist"].getCurrent()[1][2]))
481                 else:
482                         self["logentry"].setText("")