-import time
-#from time import datetime
-from Tools import Directories, Notifications, ASCIItranslit
-
-from Components.config import config
-import timer
-import xml.etree.cElementTree
-
from enigma import eEPGCache, getBestPlayableServiceReference, \
eServiceReference, iRecordableService, quitMainloop
-from Screens.MessageBox import MessageBox
+from Components.config import config
+from Components.UsageConfig import defaultMoviePath
from Components.TimerSanityCheck import TimerSanityCheck
-import NavigationInstance
+from Screens.MessageBox import MessageBox
import Screens.Standby
-
-from time import localtime
-
+from Tools import Directories, Notifications, ASCIItranslit
from Tools.XMLTools import stringToXML
+
+import timer
+import xml.etree.cElementTree
+import NavigationInstance
from ServiceReference import ServiceReference
+from time import localtime, strftime, ctime, time
+from bisect import insort
+
+import os
+
# ok, for descriptions etc we have:
# service reference (to get the service name)
# name (title)
DEEPSTANDBY = 2
AUTO = 3
+def findSafeRecordPath(dirname):
+ if not dirname:
+ return None
+
+ from Components import Harddisk
+ dirname = os.path.realpath(dirname)
+ mountpoint = Harddisk.findMountPoint(dirname)
+ if mountpoint in ('/', '/media'):
+ print '[RecordTimer] media is not mounted:', dirname
+ return None
+ if not os.path.isdir(dirname):
+ try:
+ os.makedirs(dirname)
+ except Exception, ex:
+ print '[RecordTimer] Failed to create dir "%s":' % dirname, ex
+ return None
+
+ return dirname
+
# please do not translate log messages
class RecordTimerEntry(timer.TimerEntry, object):
######### the following static methods and members are only in use when the box is in (soft) standby
recordings = NavigationInstance.instance.getRecordings()
if not recordings: # no more recordings exist
rec_time = NavigationInstance.instance.RecordTimer.getNextRecordingTime()
- if rec_time > 0 and (rec_time - time.time()) < 360:
- print "another recording starts in", rec_time - time.time(), "seconds... do not shutdown yet"
+ if rec_time > 0 and (rec_time - time()) < 360:
+ print "another recording starts in", rec_time - time(), "seconds... do not shutdown yet"
else:
print "no starting records in the next 360 seconds... immediate shutdown"
RecordTimerEntry.shutdown() # immediate shutdown
Notifications.AddNotification(Screens.Standby.TryQuitMainloop, 1, onSessionOpenCallback=RecordTimerEntry.stopTryQuitMainloop, default_yes = default_yes)
#################################################################
- def __init__(self, serviceref, begin, end, name, description, eit, disabled = False, justplay = False, afterEvent = AFTEREVENT.AUTO, checkOldTimers = False, dirname = None, tags = None):
+ def __init__(self, serviceref, begin, end, name, description, eit, disabled = False, justplay = False, afterEvent = AFTEREVENT.AUTO, checkOldTimers = False, dirname = None, tags = None, descramble = True, record_ecm = False, filename = None):
timer.TimerEntry.__init__(self, int(begin), int(end))
if checkOldTimers == True:
- if self.begin < time.time() - 1209600:
- self.begin = int(time.time())
+ if self.begin < time() - 1209600:
+ self.begin = int(time())
if self.end < self.begin:
self.end = self.begin
assert isinstance(serviceref, ServiceReference)
- self.service_ref = serviceref
+ if serviceref.isRecordable():
+ self.service_ref = serviceref
+ else:
+ self.service_ref = ServiceReference(None)
self.eit = eit
self.dontSave = False
self.name = name
self.autoincreasetime = 3600 * 24 # 1 day
self.tags = tags or []
+ self.descramble = descramble
+ self.record_ecm = record_ecm
+
self.log_entries = []
self.resetState()
-
+
+ self.Filename = filename
+ self.pvrConvert = False
+
def log(self, code, msg):
- self.log_entries.append((int(time.time()), code, msg))
+ self.log_entries.append((int(time()), code, msg))
print "[TIMER]", msg
def calculateFilename(self):
+ if self.Filename:
+ self.log(0, "Filename calculated as: '%s'" % self.Filename)
+ return
+
service_name = self.service_ref.getServiceName()
- begin_date = time.strftime("%Y%m%d %H%M", time.localtime(self.begin))
+ begin_date = strftime("%Y%m%d %H%M", localtime(self.begin))
+ begin_shortdate = strftime("%Y%m%d", localtime(self.begin))
print "begin_date: ", begin_date
print "service_name: ", service_name
filename = begin_date + " - " + service_name
if self.name:
- filename += " - " + self.name
+ if config.usage.setup_level.index >= 2: # expert+
+ if config.recording.filename_composition.value == "short":
+ filename = begin_shortdate + " - " + self.name
+ elif config.recording.filename_composition.value == "long":
+ filename += " - " + self.name + " - " + self.description
+ else:
+ filename += " - " + self.name # standard
+ else:
+ filename += " - " + self.name
if config.recording.ascii_filenames.value:
filename = ASCIItranslit.legacyEncode(filename)
- if self.dirname and not Directories.fileExists(self.dirname, 'w'):
- self.dirnameHadToFallback = True
- self.Filename = Directories.getRecordingFilename(filename, None)
+ if not self.dirname:
+ dirname = findSafeRecordPath(defaultMoviePath())
else:
- self.Filename = Directories.getRecordingFilename(filename, self.dirname)
+ dirname = findSafeRecordPath(self.dirname)
+ if dirname is None:
+ dirname = findSafeRecordPath(defaultMoviePath())
+ self.dirnameHadToFallback = True
+
+ if not dirname:
+ return None
+
+ self.Filename = Directories.getRecordingFilename(filename, dirname)
self.log(0, "Filename calculated as: '%s'" % self.Filename)
#begin_date + " - " + service_name + description)
+ return self.Filename
def tryPrepare(self):
if self.justplay:
return True
else:
- self.calculateFilename()
+ if not self.calculateFilename():
+ self.do_backoff()
+ self.start_prepare = time() + self.backoff
+ return False
+
rec_ref = self.service_ref and self.service_ref.ref
if rec_ref and rec_ref.flags & eServiceReference.isGroup:
rec_ref = getBestPlayableServiceReference(rec_ref, eServiceReference())
if event_id is None:
event_id = -1
- prep_res=self.record_service.prepare(self.Filename + ".ts", self.begin, self.end, event_id, self.name.replace("\n", ""), self.description.replace("\n", ""), ' '.join(self.tags))
+ prep_res=self.record_service.prepare(self.Filename + ".ts", self.begin, self.end, event_id, self.name.replace("\n", ""), self.description.replace("\n", ""), ' '.join(self.tags), bool(self.descramble), bool(self.record_ecm))
if prep_res:
if prep_res == -255:
self.log(4, "failed to write meta information")
# we must calc nur start time before stopRecordService call because in Screens/Standby.py TryQuitMainloop tries to get
# the next start time in evEnd event handler...
self.do_backoff()
- self.start_prepare = time.time() + self.backoff
+ self.start_prepare = time() + self.backoff
NavigationInstance.instance.stopRecordService(self.record_service)
self.record_service = None
if next_state == self.StatePrepared:
if self.tryPrepare():
self.log(6, "prepare ok, waiting for begin")
+ # create file to "reserve" the filename
+ # because another recording at the same time on another service can try to record the same event
+ # i.e. cable / sat.. then the second recording needs an own extension... when we create the file
+ # here than calculateFilename is happy
+ if not self.justplay:
+ open(self.Filename + ".ts", "w").close()
# fine. it worked, resources are allocated.
self.next_activation = self.begin
self.backoff = 0
self.log(13, "start record returned %d" % record_res)
self.do_backoff()
# retry
- self.begin = time.time() + self.backoff
+ self.begin = time() + self.backoff
return False
return True
self.record_service = None
if self.afterEvent == AFTEREVENT.STANDBY:
if not Screens.Standby.inStandby: # not already in standby
- Notifications.AddNotificationWithCallback(self.sendStandbyNotification, MessageBox, _("A finished record timer wants to set your\nDreambox to standby. Do that now?"), timeout = 20)
+ Notifications.AddNotificationWithCallback(self.sendStandbyNotification, MessageBox, _("A finished record timer wants to set your\nSTB to standby. Do that now?"), timeout = 20)
elif self.afterEvent == AFTEREVENT.DEEPSTANDBY:
if not Screens.Standby.inTryQuitMainloop: # not a shutdown messagebox is open
if Screens.Standby.inStandby: # in standby
RecordTimerEntry.TryQuitMainloop() # start shutdown handling without screen
else:
- Notifications.AddNotificationWithCallback(self.sendTryQuitMainloopNotification, MessageBox, _("A finished record timer wants to shut down\nyour Dreambox. Shutdown now?"), timeout = 20)
+ Notifications.AddNotificationWithCallback(self.sendTryQuitMainloopNotification, MessageBox, _("A finished record timer wants to shut down\nyour STB. Shutdown now?"), timeout = 20)
return True
def setAutoincreaseEnd(self, entry = None):
if not self.autoincrease:
return False
if entry is None:
- new_end = int(time.time()) + self.autoincreasetime
+ new_end = int(time()) + self.autoincreasetime
else:
new_end = entry.begin -30
timersanitycheck = TimerSanityCheck(NavigationInstance.instance.RecordTimer.timer_list, dummyentry)
if not timersanitycheck.check():
simulTimerList = timersanitycheck.getSimulTimerList()
- new_end = simulTimerList[1].begin
- del simulTimerList
- new_end -= 30 # 30 Sekunden Prepare-Zeit lassen
- del dummyentry
- if new_end <= time.time():
+ if simulTimerList is not None and len(simulTimerList) > 1:
+ new_end = simulTimerList[1].begin
+ new_end -= 30 # 30 Sekunden Prepare-Zeit lassen
+ if new_end <= time():
return False
self.end = new_end
return True
-
-
+
def sendStandbyNotification(self, answer):
if answer:
Notifications.AddNotification(Screens.Standby.Standby)
self.backoff = 0
if int(old_prepare) != int(self.start_prepare):
- self.log(15, "record time changed, start prepare is now: %s" % time.ctime(self.start_prepare))
+ self.log(15, "record time changed, start prepare is now: %s" % ctime(self.start_prepare))
def gotRecordEvent(self, record, event):
# TODO: this is not working (never true), please fix. (comparing two swig wrapped ePtrs)
# that in our state, with also keeping the possibility to re-try.
# TODO: this has to be done.
elif event == iRecordableService.evStart:
+ if self.pvrConvert:
+ return
+
text = _("A record has been started:\n%s") % self.name
if self.dirnameHadToFallback:
text = '\n'.join((text, _("Please note that the previously selected media could not be accessed and therefore the default directory is being used instead.")))
record_service = property(lambda self: self.__record_service, setRecordService)
+ def isUsbRecordingPath(self):
+ dirname = None
+
+ if self.dirname:
+ dirname = findSafeRecordPath(self.dirname)
+
+ if dirname is None:
+ dirname = findSafeRecordPath(defaultMoviePath())
+
+ from Components import Harddisk
+ return Harddisk.isUsbStorage(dirname)
+
def createTimer(xml):
begin = int(xml.get("begin"))
end = int(xml.get("end"))
self.loadTimer()
except IOError:
print "unable to load timers from file!"
-
+
+ def doActivate(self, w):
+ if w.state == RecordTimerEntry.StateWaiting:
+ from Components.SystemInfo import SystemInfo
+ if SystemInfo.get("DisableUsbRecord", True) and w.isUsbRecordingPath():
+ service_name = w.service_ref.getServiceName()
+ self.timer_list.remove(w)
+ if w.dontSave is False:
+ w.resetState()
+ w.disable()
+ self.addTimerEntry(w)
+ Notifications.AddNotification(MessageBox, _("Can not recording on a USB storage.\nService name : %s"% service_name), MessageBox.TYPE_ERROR)
+ return
+
+ # when activating a timer which has already passed,
+ # simply abort the timer. don't run trough all the stages.
+ if w.shouldSkip():
+ w.state = RecordTimerEntry.StateEnded
+ else:
+ # when active returns true, this means "accepted".
+ # otherwise, the current state is kept.
+ # the timer entry itself will fix up the delay then.
+ if w.activate():
+ w.state += 1
+
+ self.timer_list.remove(w)
+
+ # did this timer reached the last state?
+ if w.state < RecordTimerEntry.StateEnded:
+ # no, sort it into active list
+ insort(self.timer_list, w)
+ else:
+ # yes. Process repeated, and re-add.
+ if w.repeated:
+ w.processRepeated()
+ w.state = RecordTimerEntry.StateWaiting
+ self.addTimerEntry(w)
+ else:
+ insort(self.processed_timers, w)
+
+ self.stateChanged(w)
+
def isRecording(self):
isRunning = False
for timer in self.timer_list:
checkit = True
for timer in root.findall("timer"):
newTimer = createTimer(timer)
- if (self.record(newTimer, True, True) is not None) and (checkit == True):
+ if (self.record(newTimer, True, dosave=False) is not None) and (checkit == True):
from Tools.Notifications import AddPopup
from Screens.MessageBox import MessageBox
AddPopup(_("Timer overlap in timers.xml detected!\nPlease recheck it!"), type = MessageBox.TYPE_ERROR, timeout = 0, id = "TimerLoadFailed")
file.close()
def getNextZapTime(self):
- now = time.time()
+ now = time()
for timer in self.timer_list:
if not timer.justplay or timer.begin < now:
continue
return -1
def getNextRecordingTime(self):
- now = time.time()
+ now = time()
for timer in self.timer_list:
- print "timer", timer
next_act = timer.getNextActivation()
if timer.justplay or next_act < now:
continue
return -1
def isNextRecordAfterEventActionAuto(self):
- now = time.time()
+ now = time()
t = None
for timer in self.timer_list:
if timer.justplay or timer.begin < now:
chktimecmp_end = chktimecmp + (duration / 60)
time = localtime(x.begin)
for y in (0, 1, 2, 3, 4, 5, 6):
- if x.repeated & (2 ** y) and (x.begin <= begin or begin <= x.begin <= end):
+ if x.repeated & (1 << y) and (x.begin <= begin or begin <= x.begin <= end):
timecmp = y * 1440 + time.tm_hour * 60 + time.tm_min
if timecmp <= chktimecmp < (timecmp + ((x.end - x.begin) / 60)):
time_match = ((timecmp + ((x.end - x.begin) / 60)) - chktimecmp) * 60