def pause(self, p):
return self.pnav.pause(p)
- def recordWithTimer(self, begin, end, ref, epg, description):
+ def recordWithTimer(self, ref, begin, end, name, description, eit):
if isinstance(ref, eServiceReference):
ref = ServiceReference.ServiceReference(ref)
- entry = RecordTimer.RecordTimerEntry(begin, end, ref, epg, description)
+ entry = RecordTimer.RecordTimerEntry(ref, begin, end, name, description, eit)
self.RecordTimer.record(entry)
return entry
from Tools.XMLTools import elementsWithTag
from ServiceReference import ServiceReference
+# ok, for descriptions etc we have:
+# service reference (to get the service name)
+# name (title)
+# description (description)
+# event data (ONLY for time adjustments etc.)
+
+
+# parses an event, and gives out a (begin, end, name, duration, eit)-tuple.
+def parseEvent(ev):
+ name = ev.getEventName()
+ description = ev.getShortDescription()
+ begin = ev.getBeginTime()
+ end = begin + ev.getDuration()
+ eit = None
+ return (begin, end, name, description, eit)
+
class RecordTimerEntry(timer.TimerEntry):
- def __init__(self, begin, end, serviceref, epg, description):
+ def __init__(self, serviceref, begin, end, name, description, eit):
timer.TimerEntry.__init__(self, int(begin), int(end))
assert isinstance(serviceref, ServiceReference)
self.service_ref = serviceref
- if epg is not None:
- self.epg_data = ""
- #str(epg.m_event_name)
- else:
- self.epg_data = ""
+ self.eit = eit
self.dontSave = False
+ self.name = name
self.description = description
self.timer = None
self.record_service = None
service_name = self.service_ref.getServiceName()
# begin_date = datetime.fromtimestamp(begin).strf...
begin_date = ""
- if self.epg_data is not None:
- description = " - " + self.epg_data
- else:
- description = ""
- print "begin_date: " + str(begin_date)
- print "service_name: " + str(service_name)
- print "description: " + str(description)
+ print "begin_date: ", begin_date
+ print "service_name: ", service_name
+ print "name:", self.name
+ print "description: ", self.description
+
self.Filename = Directories.getRecordingFilename(service_name)
#begin_date + " - " + service_name + description)
- # build filename from epg
-
- # pff das geht noch nicht...
-# if epg == None:
-# self.Filename = "recording.ts"
-# else:
-# self.Filename = "record_" + str(epg.m_event_name) + ".ts"
-#
-# print "------------ record filename: %s" % (self.Filename)
def tryPrepare(self):
self.calculateFilename()
f = open(self.Filename + ".ts.meta", "w")
f.write(str(self.service_ref) + "\n")
- f.write(self.epg_data + "\n")
+ f.write(self.name + "\n")
+ f.write(self.description + "\n")
+ f.write(str(self.begin) + "\n")
del f
return True
begin = int(xml.getAttribute("begin"))
end = int(xml.getAttribute("end"))
serviceref = ServiceReference(str(xml.getAttribute("serviceref")))
- description = xml.getAttribute("description")
- repeated = xml.getAttribute("repeated")
- epgdata = xml.getAttribute("epgdata")
- #filename = xml.getAttribute("filename")
- entry = RecordTimerEntry(begin, end, serviceref, epgdata, description)
+ description = xml.getAttribute("description").encode("utf-8")
+ repeated = xml.getAttribute("repeated").encode("utf-8")
+ eit = xml.getAttribute("eit").encode("utf-8")
+ name = xml.getAttribute("name").encode("utf-8")
+ #filename = xml.getAttribute("filename").encode("utf-8")
+ entry = RecordTimerEntry(serviceref, begin, end, name, description, eit)
entry.repeated = int(repeated)
return entry
try:
self.loadTimer()
- except:
+ except IOError:
print "unable to load timers from file!"
def isRecording(self):
t.setAttribute("end", str(timer.end))
t.setAttribute("serviceref", str(timer.service_ref))
t.setAttribute("repeated", str(timer.repeated))
- #t.setAttribute("epgdata", timer.)
- t.setAttribute("description", "no description") # timer.description)
+ t.setAttribute("name", timer.name)
+ t.setAttribute("description", timer.description)
+ t.setAttribute("eit", str(timer.eit))
+
root_element.appendChild(t)
t = doc.createTextNode("\n")
root_element.appendChild(t)
file = open(self.Filename, "w")
- doc.writexml(codecs.getwriter('UTF-8')(file))
+ doc.writexml(file)
file.write("\n")
file.close()
entry.repeated = False
- entry.repeated = False
-
if entry.state == timer.TimerEntry.StateRunning:
print "remove running timer."
entry.end = time.time()
case 2:
m_description = line;
break;
+ case 3:
+ m_time_create = atoi(line);
+ break;
default:
break;
}
eServiceReferenceDVB m_ref;
std::string m_name, m_description;
+ int m_time_create;
};
#endif
from HTMLComponent import *
from GUIComponent import *
+from Tools.FuzzyDate import FuzzyTime
-from enigma import eListboxPythonMultiContent, eListbox, gFont
+from enigma import eListboxPythonMultiContent, eListbox, gFont, iServiceInformation
from enigma import eServiceReference, eServiceCenter, \
eServiceCenterPtr, iListableServicePtr, \
len = "?:??"
res.append((0, 0, 400, 30, 0, RT_HALIGN_LEFT, info.getName(serviceref)))
- res.append((0, 30, 200, 20, 1, RT_HALIGN_LEFT, "Toller Film"))
- res.append((0, 50, 200, 20, 1, RT_HALIGN_LEFT, "Aufgenommen: irgendwann"))
+
+ description = info.getInfoString(serviceref, iServiceInformation.sDescription)
+ begin = info.getInfo(serviceref, iServiceInformation.sTimeCreate)
+
+ begin_string = ""
+ if begin > 0:
+ t = FuzzyTime(begin)
+ begin_string = t[0] + ", " + t[1]
+
+ res.append((0, 30, 200, 20, 1, RT_HALIGN_LEFT, description))
+ res.append((0, 50, 200, 20, 1, RT_HALIGN_LEFT, begin_string))
res.append((200, 50, 200, 20, 1, RT_HALIGN_RIGHT, len))
return res
def TimerEntryComponent(timer, processed):
res = [ timer ]
- print time.strftime("%c", time.localtime(timer.begin))
- print time.strftime("%c", time.localtime(timer.end))
-
res.append((0, 0, 400, 30, 0, RT_HALIGN_LEFT, timer.service_ref.getServiceName()))
repeatedtext = ""
days = [ "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" ]
else:
res.append((0, 30, 200, 20, 1, RT_HALIGN_LEFT, repeatedtext + ("%s, %s ... %s" % (FuzzyTime(timer.begin) + FuzzyTime(timer.end)[1:]))))
- res.append((300, 0, 200, 20, 1, RT_HALIGN_RIGHT, timer.description))
+ res.append((300, 0, 200, 20, 1, RT_HALIGN_RIGHT, timer.name))
if not processed:
if timer.state == TimerEntry.StateWait:
from Screens.EventView import EventView
from enigma import eServiceReference, eServiceEventPtr
from Screens.FixedMenu import FixedMenu
-from RecordTimer import RecordTimerEntry
+from RecordTimer import RecordTimerEntry, parseEvent
from TimerEdit import TimerEditList
from TimerEntry import TimerEntry
from ServiceReference import ServiceReference
self.session.open(EventView, event, self.currentService, self.eventViewCallback)
def timerAdd(self):
- epg = self["list"].getCurrent()
+ event = self["list"].getCurrent()
+
+ if event is None:
+ return
- if (epg == None):
- description = "unknown event"
- else:
- description = epg.getEventName()
- # FIXME we need a timestamp here:
- begin = epg.getBeginTime()
-
- print begin
- print epg.getDuration()
- end = begin + epg.getDuration()
-
-
# FIXME only works if already playing a service
serviceref = ServiceReference(self.session.nav.getCurrentlyPlayingServiceReference())
- newEntry = RecordTimerEntry(begin, end, serviceref, epg, description)
+ newEntry = RecordTimerEntry(serviceref, *parseEvent(event))
self.session.openWithCallback(self.timerEditFinished, TimerEntry, newEntry)
def timerEditFinished(self, answer):
from Components.ScrollLabel import ScrollLabel
from enigma import eServiceEventPtr
from ServiceReference import ServiceReference
-from RecordTimer import RecordTimerEntry
+from RecordTimer import RecordTimerEntry, parseEvent
from TimerEntry import TimerEntry
class EventView(Screen):
self.cbFunc(self.setEvent, +1)
def timerAdd(self):
- epg = self.event
-
- if (epg == None):
- description = "unknown event"
- else:
- description = epg.getEventName()
- # FIXME we need a timestamp here:
- begin = epg.getBeginTime()
-
- print begin
- print epg.getDuration()
- end = begin + epg.getDuration()
-
-
- # FIXME only works if already playing a service
- serviceref = ServiceReference(self.session.nav.getCurrentlyPlayingServiceReference())
-
- newEntry = RecordTimerEntry(begin, end, serviceref, epg, description)
+ newEntry = RecordTimerEntry(self.currentService, *parseEvent(self.event))
self.session.openWithCallback(self.timerEditFinished, TimerEntry, newEntry)
def timerEditFinished(self, answer):
}
self.setSeekState(lookup[self.seekstate]);
+from RecordTimer import parseEvent
+
class InfoBarInstantRecord:
"""Instant Record - handles the instantRecord action in order to
start/stop instant records"""
def startInstantRecording(self):
serviceref = self.session.nav.getCurrentlyPlayingServiceReference()
-
+
# try to get event info
- epg = None
+ event = None
try:
service = self.session.nav.getCurrentService()
info = service.info()
ev = info.getEvent(0)
- epg = ev
+ event = ev
except:
pass
+ if event is not None:
+ data = parseEvent(event)
+ data = (data[0], data[1] + 3600 * 10, data[2], data[3], data[4])
+ else:
+ data = (time.time(), time.time() + 3600 * 10, "instant record", "", None)
+
# fix me, description.
- self.recording = self.session.nav.recordWithTimer(time.time(), time.time() + 3600 * 10, serviceref, epg, "instant record")
+ self.recording = self.session.nav.recordWithTimer(serviceref, *data)
self.recording.dontSave = True
#self["BlinkingPoint"].setConnect(lambda: self.recording.isRunning())
from Components.Button import Button
from Components.TextInput import TextInput
from TimerEntry import TimerEntry
-from RecordTimer import RecordTimerEntry
+from RecordTimer import RecordTimerEntry, parseEvent
from time import *
from ServiceReference import ServiceReference
from Components.config import *
self["timerlist"].invalidate()
def addCurrentTimer(self):
- begin = time()
- end = time() + 60
-
- epg = None
- try:
- service = self.session.nav.getCurrentService()
+ event = None
+ service = self.session.nav.getCurrentService()
+ if service is not None:
info = service.info()
- ev = info.getEvent(0)
- epg = ev
- except:
- pass
-
- if (epg == None):
- description = "unknown event"
- else:
- description = ev.getEventName()
- # FIXME we need a timestamp here:
- begin = ev.getBeginTime()
-
- print begin
- print ev.getDuration()
- end = begin + ev.getDuration()
-
+ if info is not None:
+ event = info.getEvent(0)
# FIXME only works if already playing a service
serviceref = ServiceReference(self.session.nav.getCurrentlyPlayingServiceReference())
- self.addTimer(RecordTimerEntry(begin, end, serviceref, epg, description))
+ if event is None:
+ data = (int(time()), int(time() + 60), "unknown event", "", None)
+ else:
+ data = parseEvent(event)
+
+ self.addTimer(RecordTimerEntry(serviceref, *data))
def addTimer(self, timer):
self.session.openWithCallback(self.finishedAdd, TimerEntry, timer)
def leave(self):
self.session.nav.RecordTimer.saveTimer()
- self.close()
\ No newline at end of file
+ self.close()
repeated = 0
config.timerentry.type = configElement_nonSave("config.timerentry.type", configSelection, type, (_("once"), _("repeated")))
+ config.timerentry.name = configElement_nonSave("config.timerentry.name", configText, self.timer.name, (configText.extendableSize, self.keyRightCallback))
config.timerentry.description = configElement_nonSave("config.timerentry.description", configText, self.timer.description, (configText.extendableSize, self.keyRightCallback))
config.timerentry.repeated = configElement_nonSave("config.timerentry.repeated", configSelection, repeated, (_("daily"), _("weekly"), _("Mon-Fri"), _("user defined")))
def createSetup(self):
self.list = []
+ self.list.append(getConfigListEntry(_("Name"), config.timerentry.name))
self.list.append(getConfigListEntry(_("Description"), config.timerentry.description))
self.timerTypeEntry = getConfigListEntry(_("Timer Type"), config.timerentry.type)
self.list.append(self.timerTypeEntry)
return int(mktime(dt.timetuple()))
def keyGo(self):
+ self.timer.name = config.timerentry.name.value
self.timer.description = config.timerentry.description.value
self.timer.resetRepeated()
virtual SWIG_VOID(RESULT) getEvent(const eServiceReference &ref, ePtr<eServiceEvent> &SWIG_OUTPUT, time_t start_time=0);
// returns true when not implemented
virtual bool isPlayable(const eServiceReference &ref, const eServiceReference &ignore);
+
+ virtual int getInfo(const eServiceReference &ref, int w);
+ virtual std::string getInfoString(const eServiceReference &ref,int w);
};
TEMPLATE_TYPEDEF(ePtr<iStaticServiceInformation>, iStaticServiceInformationPtr);
sTSID,
sNamespace,
sProvider,
+
+ sDescription,
+ sTimeCreate, // unix time or string
};
enum { resNA = -1, resIsString = -2 };
TEMPLATE_TYPEDEF(ePtr<iSubserviceList>, iSubserviceListPtr);
+class iTimeshiftService: public iObject
+{
+public:
+ virtual RESULT startTimeshift()=0;
+ virtual RESULT stopTimeshift()=0;
+};
+
+TEMPLATE_TYPEDEF(ePtr<iTimeshiftService>, iTimeshiftServicePtr);
+
class iPlayableService: public iObject
{
friend class iServiceHandler;
virtual SWIG_VOID(RESULT) audioTracks(ePtr<iAudioTrackSelection> &SWIG_OUTPUT)=0;
virtual SWIG_VOID(RESULT) subServices(ePtr<iSubserviceList> &SWIG_OUTPUT)=0;
virtual SWIG_VOID(RESULT) frontendStatusInfo(ePtr<iFrontendStatusInformation> &SWIG_OUTPUT)=0;
+ virtual SWIG_VOID(RESULT) timeshift(ePtr<iTimeshiftService> &SWIG_OUTPUT)=0;
};
TEMPLATE_TYPEDEF(ePtr<iPlayableService>, iPlayableServicePtr);
return -1;
}
+int iStaticServiceInformation::getInfo(const eServiceReference &ref, int w)
+{
+ return -1;
+}
+
+std::string iStaticServiceInformation::getInfoString(const eServiceReference &ref, int w)
+{
+ return "";
+}
+
int iServiceInformation::getInfo(int w)
{
return -1;
eStaticServiceDVBPVRInformation(const eServiceReference &ref);
RESULT getName(const eServiceReference &ref, std::string &name);
int getLength(const eServiceReference &ref);
+
+ int getInfo(const eServiceReference &ref, int w);
+ std::string getInfoString(const eServiceReference &ref,int w);
};
DEFINE_REF(eStaticServiceDVBPVRInformation);
return len / 90000;
}
+int eStaticServiceDVBPVRInformation::getInfo(const eServiceReference &ref, int w)
+{
+ switch (w)
+ {
+ case iServiceInformation::sDescription:
+ return iServiceInformation::resIsString;
+ case iServiceInformation::sTimeCreate:
+ if (m_parser.m_time_create)
+ return m_parser.m_time_create;
+ else
+ return iServiceInformation::resNA;
+ default:
+ return iServiceInformation::resNA;
+ }
+}
+std::string eStaticServiceDVBPVRInformation::getInfoString(const eServiceReference &ref,int w)
+{
+ switch (w)
+ {
+ case iServiceInformation::sDescription:
+ return m_parser.m_description;
+ default:
+ return "";
+ }
+}
class eDVBPVRServiceOfflineOperations: public iServiceOfflineOperations
{
m_reference(ref), m_dvb_service(service), m_service_handler(0), m_is_paused(0)
{
m_is_pvr = !ref.path.empty();
+ m_timeshift_enabled = 0;
CONNECT(m_service_handler.serviceEvent, eDVBServicePlay::serviceEvent);
CONNECT(m_event_handler.m_eit_changed, eDVBServicePlay::gotNewEvent);
RESULT eDVBServicePlay::pause(ePtr<iPauseableService> &ptr)
{
- if (m_is_pvr)
+ if (!m_is_pvr)
{
- ptr = this;
- return 0;
+ ptr = 0;
+ return -1;
}
- ptr = 0;
- return -1;
+ ptr = this;
+ return 0;
}
RESULT eDVBServicePlay::setSlowMotion(int ratio)
return 0;
}
+RESULT eDVBServicePlay::timeshift(ePtr<iTimeshiftService> &ptr)
+{
+ if (m_timeshift_enabled || !m_is_pvr)
+ {
+ ptr = this;
+ return 0;
+ }
+ ptr = 0;
+ return -1;
+}
+
RESULT eDVBServicePlay::getName(std::string &name)
{
if (m_dvb_service)
return -1;
}
+RESULT eDVBServicePlay::startTimeshift()
+{
+ if (m_timeshift_enabled)
+ return -1;
+ eDebug("TIMESHIFT - start!");
+ return 0;
+}
+
+RESULT eDVBServicePlay::stopTimeshift()
+{
+ if (!m_timeshift_enabled)
+ return -1;
+ m_timeshift_enabled = 0;
+ eDebug("timeshift disabled");
+ return 0;
+}
+
DEFINE_REF(eDVBServicePlay)
eAutoInitPtr<eServiceFactoryDVB> init_eServiceFactoryDVB(eAutoInitNumbers::service+1, "eServiceFactoryDVB");
class eDVBServicePlay: public iPlayableService, public iPauseableService,
public iSeekableService, public Object, public iServiceInformation,
public iAudioTrackSelection, public iFrontendStatusInformation,
- public iSubserviceList
+ public iSubserviceList, public iTimeshiftService
{
DECLARE_REF(eDVBServicePlay);
public:
RESULT audioTracks(ePtr<iAudioTrackSelection> &ptr);
RESULT frontendStatusInfo(ePtr<iFrontendStatusInformation> &ptr);
RESULT subServices(ePtr<iSubserviceList> &ptr);
+ RESULT timeshift(ePtr<iTimeshiftService> &ptr);
// iPauseableService
RESULT pause();
int getNumberOfSubservices();
RESULT getSubservice(eServiceReference &subservice, unsigned int n);
+ // iTimeshiftService
+ RESULT startTimeshift();
+ RESULT stopTimeshift();
+
private:
friend class eServiceFactoryDVB;
eServiceReference m_reference;
void serviceEvent(int event);
Signal2<void,iPlayableService*,int> m_event;
- int m_is_pvr, m_is_paused;
+ int m_is_pvr, m_is_paused, m_timeshift_enabled;
int m_current_audio_stream;
int selectAudioStream(int n);
case eDVBServicePMTHandler::eventTuned:
{
eDebug("tuned..");
+ if (!m_record)
+ {
+ eDebug("Recording to %s...", m_filename.c_str());
+ ::remove(m_filename.c_str());
+ int fd = ::open(m_filename.c_str(), O_WRONLY|O_CREAT, 0644);
+ if (fd == -1)
+ {
+ eDebug("eDVBServiceRecord - can't open hardcoded recording file!");
+ return;
+// return -1;
+ }
+ ePtr<iDVBDemux> demux;
+ if (m_service_handler.getDemux(demux))
+ {
+ eDebug("eDVBServiceRecord - NO DEMUX available!");
+ return;
+// return -2;
+ }
+ demux->createTSRecorder(m_record);
+ if (!m_record)
+ {
+ eDebug("eDVBServiceRecord - no ts recorder available.");
+ return;
+// return -3;
+ }
+ m_record->setTargetFD(fd);
+ }
break;
}
case eDVBServicePMTHandler::eventNewProgramInfo:
{
m_filename = filename;
if (m_state == stateIdle)
- return m_service_handler.tune(m_ref);
+ doPrepare();
else
return -1;
}
/* allocate a ts recorder if we don't already have one. */
if (m_state == stateIdle)
{
- eDebug("Recording to %s...", m_filename.c_str());
- ::remove(m_filename.c_str());
- int fd = ::open(m_filename.c_str(), O_WRONLY|O_CREAT, 0644);
- if (fd == -1)
- {
- eDebug("eDVBServiceRecord - can't open hardcoded recording file!");
- return -1;
- }
- ePtr<iDVBDemux> demux;
- if (m_service_handler.getDemux(demux))
- {
- eDebug("eDVBServiceRecord - NO DEMUX available!");
- return -2;
- }
- demux->createTSRecorder(m_record);
- if (!m_record)
- {
- eDebug("eDVBServiceRecord - no ts recorder available.");
- return -3;
- }
- m_record->setTargetFD(fd);
m_pids_active.clear();
m_state = statePrepared;
- } else if ((m_state == statePrepared) || (m_state == stateRecording))
- {
- /* when we're already recording, we already have a recorder allocated. */
- assert(m_record);
+ m_service_handler.tune(m_ref);
}
return 0;
}
if (err)
return err;
+ if (!m_record)
+ {
+ eDebug("demux not available (tune failed?). cannot record.");
+ return -1;
+ }
eDebug("starting recording..");
eDVBServicePMTHandler::program program;
RESULT audioTracks(ePtr<iAudioTrackSelection> &ptr) { ptr = 0; return -1; }
RESULT frontendStatusInfo(ePtr<iFrontendStatusInformation> &ptr) { ptr = 0; return -1; }
RESULT subServices(ePtr<iSubserviceList> &ptr) { ptr = 0; return -1; }
-
+ RESULT timeshift(ePtr<iTimeshiftService> &ptr) { ptr = 0; return -1; }
+
// iPausableService
RESULT pause();
RESULT unpause();