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