diff --git a/data/setup.xml b/data/setup.xml
index 3d3f5584ec..d66455a528 100755
--- a/data/setup.xml
+++ b/data/setup.xml
@@ -206,6 +206,7 @@
- config.usage.default_path
- config.usage.timer_path
- config.usage.instantrec_path
+ - config.recording.setstreamto1
- config.recording.asktozap
- config.recording.margin_before
diff --git a/lib/dvb_ci/dvbci.cpp b/lib/dvb_ci/dvbci.cpp
index 9451d67abd..45c1db5579 100644
--- a/lib/dvb_ci/dvbci.cpp
+++ b/lib/dvb_ci/dvbci.cpp
@@ -1027,6 +1027,14 @@ PyObject *eDVBCIInterfaces::readCICaIds(int slotid)
return 0;
}
+int eDVBCIInterfaces::setCIEnabled(int slotid, bool enabled)
+{
+ eDVBCISlot *slot = getSlot(slotid);
+ if (slot)
+ return slot->setEnabled(enabled);
+ return -1;
+}
+
int eDVBCIInterfaces::setCIClockRate(int slotid, int rate)
{
singleLock s(m_slot_lock);
@@ -1231,6 +1239,20 @@ void eDVBCISlot::data(int what)
DEFINE_REF(eDVBCISlot);
eDVBCISlot::eDVBCISlot(eMainloop *context, int nr)
+{
+ char configStr[255];
+ slotid = nr;
+ m_context = context;
+ state = stateDisabled;
+ snprintf(configStr, 255, "config.ci.%d.enabled", slotid);
+ bool enabled = eConfigManager::getConfigBoolValue(configStr, true);
+ if (enabled)
+ openDevice();
+ else
+ /* emit */ eDVBCI_UI::getInstance()->m_messagepump.send(eDVBCIInterfaces::Message(eDVBCIInterfaces::Message::slotStateChanged, getSlotID(), 3)); // state disabled
+}
+
+void eDVBCISlot::openDevice()
{
char filename[128];
@@ -1244,9 +1266,7 @@ eDVBCISlot::eDVBCISlot(eMainloop *context, int nr)
plugged = true;
m_ci_version = versionUnknown;
- slotid = nr;
-
- sprintf(filename, "/dev/ci%d", nr);
+ sprintf(filename, "/dev/ci%d", slotid);
// possible_caids.insert(0x1702);
// possible_providers.insert(providerPair("PREMIERE", 0xC00000));
@@ -1259,7 +1279,7 @@ eDVBCISlot::eDVBCISlot(eMainloop *context, int nr)
if (fd >= 0)
{
- notifier = eSocketNotifier::create(context, fd, eSocketNotifier::Read | eSocketNotifier::Priority | eSocketNotifier::Write);
+ notifier = eSocketNotifier::create(m_context, fd, eSocketNotifier::Read | eSocketNotifier::Priority | eSocketNotifier::Write);
CONNECT(notifier->activated, eDVBCISlot::data);
} else
{
@@ -1273,7 +1293,16 @@ eDVBCISlot::~eDVBCISlot()
close(fd);
}
-void eDVBCISlot::setAppManager( eDVBCIApplicationManagerSession *session )
+void eDVBCISlot::closeDevice()
+{
+ close(fd);
+ fd = -1;
+ notifier->stop();
+ data(eSocketNotifier::Priority);
+ state = stateDisabled;
+}
+
+void eDVBCISlot::setAppManager(eDVBCIApplicationManagerSession *session)
{
singleLock s(eDVBCIInterfaces::m_slot_lock);
application_manager=session;
@@ -1607,4 +1636,22 @@ int eDVBCISlot::setClockRate(int rate)
return 0;
}
+int eDVBCISlot::setEnabled(bool enabled)
+{
+ eDebug("[CI] Slot: %d Enabled: %d, state %d", getSlotID(), enabled, state);
+ if (enabled && state != stateDisabled)
+ return 0;
+
+ if (!enabled && state == stateDisabled)
+ return 0;
+
+ if(enabled)
+ openDevice();
+ else {
+ closeDevice();
+ /* emit */ eDVBCI_UI::getInstance()->m_messagepump.send(eDVBCIInterfaces::Message(eDVBCIInterfaces::Message::slotStateChanged, getSlotID(), 3)); // state disabled
+ }
+ return 0;
+}
+
eAutoInitP0 init_eDVBCIInterfaces(eAutoInitNumbers::dvb, "CI Slots");
diff --git a/lib/dvb_ci/dvbci.h b/lib/dvb_ci/dvbci.h
index 48dc019b56..def59a6008 100644
--- a/lib/dvb_ci/dvbci.h
+++ b/lib/dvb_ci/dvbci.h
@@ -66,6 +66,7 @@ class eDVBCISlot: public iObject, public sigc::trackable
bool user_mapped;
void data(int);
bool plugged;
+ eMainloop *m_context;
eDVBCIApplicationManagerSession *getAppManager() { return application_manager; }
eDVBCIMMISession *getMMIManager() { return mmi_session; }
@@ -85,12 +86,15 @@ class eDVBCISlot: public iObject, public sigc::trackable
int setSource(const std::string &source);
int setClockRate(int);
void determineCIVersion();
+ int setEnabled(bool);
static std::string getTunerLetter(int tuner_no) { return std::string(1, char(65 + tuner_no)); }
public:
- enum {stateRemoved, stateInserted, stateInvalid, stateResetted};
+ enum {stateRemoved, stateInserted, stateInvalid, stateResetted, stateDisabled};
enum {versionUnknown = -1, versionCI = 0, versionCIPlus1 = 1, versionCIPlus2 = 2};
eDVBCISlot(eMainloop *context, int nr);
~eDVBCISlot();
+ void closeDevice();
+ void openDevice();
int send(const unsigned char *data, size_t len);
@@ -183,6 +187,7 @@ class eDVBCIInterfaces: public eMainloop, private eThread
void ciRemoved(eDVBCISlot *slot);
int getSlotState(int slot);
+ int setCIEnabled(int slot, bool enabled);
int reset(int slot);
int initialize(int slot);
int startMMI(int slot);
diff --git a/lib/dvb_ci/dvbci_ui.cpp b/lib/dvb_ci/dvbci_ui.cpp
index a7adc037b4..d6bb5e787a 100644
--- a/lib/dvb_ci/dvbci_ui.cpp
+++ b/lib/dvb_ci/dvbci_ui.cpp
@@ -96,5 +96,10 @@ int eDVBCI_UI::setClockRate(int slot, int rate)
return eDVBCIInterfaces::getInstance()->setCIClockRate(slot, rate);
}
+int eDVBCI_UI::setEnabled(int slot, bool enabled)
+{
+ return eDVBCIInterfaces::getInstance()->setCIEnabled(slot, enabled);
+}
+
//FIXME: correct "run/startlevel"
eAutoInitP0 init_dvbciui(eAutoInitNumbers::rc, "DVB-CI UI");
diff --git a/lib/dvb_ci/dvbci_ui.h b/lib/dvb_ci/dvbci_ui.h
index d08f257337..fea0964826 100644
--- a/lib/dvb_ci/dvbci_ui.h
+++ b/lib/dvb_ci/dvbci_ui.h
@@ -34,6 +34,7 @@ class eDVBCI_UI: public eMMI_UI
int answerEnq(int slot, char *val);
int cancelEnq(int slot);
int setClockRate(int slot, int rate);
+ int setEnabled(int slot, bool enabled);
};
#endif
diff --git a/lib/python/Components/EpgListGrid.py b/lib/python/Components/EpgListGrid.py
index 0c67b8c4be..8b94e531ed 100644
--- a/lib/python/Components/EpgListGrid.py
+++ b/lib/python/Components/EpgListGrid.py
@@ -527,7 +527,8 @@ def buildEntry(self, service, serviceName, events, picon, channel):
duration = ev[3]
xpos, ewidth = self.calcEventPosAndWidthHelper(stime, duration, start, end, width)
- serviceTimers = self.filteredTimerList.get(':'.join(service.split(':')[:11]))
+ serviceref = "1" + service[4:] if service[:4] in config.recording.setstreamto1.value else service # converts 4097, 5001, 5002 to 1
+ serviceTimers = self.filteredTimerList.get(':'.join(serviceref.split(':')[:11]))
if serviceTimers is not None:
timer, matchType = RecordTimer.isInTimerOnService(serviceTimers, stime, duration)
timerIcon, autoTimerIcon = self.getPixmapsForTimer(timer, matchType, selected)
@@ -821,6 +822,7 @@ def snapshotTimers(self, startTime, endTime):
# repeat timers represent all their future repetitions, so always include them
if (startTime <= timer.end or timer.repeated) and timer.begin < endTime:
serviceref = timer.service_ref.ref.toCompareString()
+ serviceref = "1" + serviceref[4:] if serviceref[:4] in config.recording.setstreamto1.value else serviceref # converts 4097, 5001, 5002 to 1
l = self.filteredTimerList.get(serviceref)
if l is None:
self.filteredTimerList[serviceref] = l = [timer]
diff --git a/lib/python/Components/RecordingConfig.py b/lib/python/Components/RecordingConfig.py
index a660ece264..a0cf76f8c3 100644
--- a/lib/python/Components/RecordingConfig.py
+++ b/lib/python/Components/RecordingConfig.py
@@ -5,6 +5,15 @@ def InitRecordingConfig():
config.recording = ConfigSubsection()
# actually this is "recordings always have priority". "Yes" does mean: don't ask. The RecordTimer will ask when value is 0.
config.recording.asktozap = ConfigYesNo(default=True)
+ config.recording.setstreamto1 = ConfigSelection(default=(), choices=[
+ ((), _("don't convert")),
+ (("4097",), _("4097 only")),
+ (("4097", "5001"), _("4097 + 5001")),
+ (("4097", "5001", "5002"), _("4097 + 5001 + 5002")),
+ (("4097", "5002"), _("4097 + 5002")),
+ (("5001",), _("5001 only")),
+ (("5001", "5002"), _("5001 + 5002")),
+ (("5002",), _("5002 only"))])
config.recording.margin_before = ConfigSelectionNumber(min=0, max=120, stepwidth=1, default=3, wraparound=True)
config.recording.margin_after = ConfigSelectionNumber(min=0, max=120, stepwidth=1, default=5, wraparound=True)
config.recording.split_programme_minutes = ConfigSelectionNumber(min=0, max=30, stepwidth=1, default=15, wraparound=True)
diff --git a/lib/python/Components/config.py b/lib/python/Components/config.py
index 3831a04f35..4a082d6a53 100644
--- a/lib/python/Components/config.py
+++ b/lib/python/Components/config.py
@@ -7,7 +7,7 @@
from Components.Harddisk import harddiskmanager
from Tools.LoadPixmap import LoadPixmap
from copy import copy as copy_copy
-from os import path as os_path
+from os import fsync, path as os_path, rename, sep
from time import localtime, strftime, mktime
ACTIONKEY_LEFT = 0
@@ -1908,7 +1908,7 @@ def removedMount(self, mp):
x[2] = False
def refreshMountpoints(self):
- self.mountpoints = [p.mountpoint for p in harddiskmanager.getMountedPartitions() if p.mountpoint != "/"]
+ self.mountpoints = [p.mountpoint for p in harddiskmanager.getMountedPartitions() if p.mountpoint != sep]
self.mountpoints.sort(key=lambda x: -len(x))
def checkChangedMountpoints(self):
@@ -1925,7 +1925,7 @@ def checkChangedMountpoints(self):
self.addedMount(x)
def getMountpoint(self, file):
- file = os_path.realpath(file) + "/"
+ file = os_path.realpath(file) + sep
for m in self.mountpoints:
if file.startswith(m):
return m
@@ -2231,18 +2231,17 @@ def unpickle(self, lines, base_file=True):
def saveToFile(self, filename):
text = self.pickle()
try:
- import os
- f = open(filename + ".writing", "w")
- f.write(text)
- f.flush()
- os.fsync(f.fileno())
- f.close()
- os.rename(filename + ".writing", filename)
+ with open(filename + ".writing", "w", encoding="UTF-8") as f:
+ f.write(text)
+ f.flush()
+ fsync(f.fileno())
+ rename(filename + ".writing", filename)
except IOError:
print("[Config] Couldn't write %s" % filename)
def loadFromFile(self, filename, base_file=True):
- self.unpickle(open(filename, "r"), base_file)
+ with open(filename, "r", encoding="UTF-8") as f:
+ self.unpickle(f, base_file)
config = Config()
diff --git a/lib/python/RecordTimer.py b/lib/python/RecordTimer.py
index 300d3683bb..cf0bf0cfc5 100644
--- a/lib/python/RecordTimer.py
+++ b/lib/python/RecordTimer.py
@@ -1,26 +1,26 @@
-from boxbranding import getMachineBrand, getMachineName
-import os
-from enigma import eEPGCache, getBestPlayableServiceReference, eStreamServer, eServiceReference, iRecordableService, quitMainloop, eActionMap, setPreferredTuner, eServiceCenter
+from os import access, fsync, makedirs, remove, rename, path as ospath, statvfs, W_OK
+from timer import Timer, TimerEntry
+import xml.etree.cElementTree
+from bisect import insort
+from sys import maxsize
+from time import localtime, strftime, ctime, time
+from enigma import eEPGCache, getBestPlayableServiceReference, eStreamServer, eServiceReference, iRecordableService, quitMainloop, eActionMap, setPreferredTuner, eServiceCenter
+from boxbranding import getMachineBrand, getMachineName
from Components.config import config
+import Components.ParentalControl
from Components.UsageConfig import defaultMoviePath
from Components.SystemInfo import SystemInfo
from Components.TimerSanityCheck import TimerSanityCheck
import Screens.InfoBar
-import Components.ParentalControl
from Screens.MessageBox import MessageBox
from Screens.PictureInPicture import PictureInPicture
import Screens.Standby
from Tools import Directories, Notifications, ASCIItranslit, Trashcan
from Tools.XMLTools import stringToXML
-from timer import Timer, TimerEntry
-import xml.etree.cElementTree
import NavigationInstance
-from time import localtime, strftime, ctime, time
-from bisect import insort
-from sys import maxsize
# ok, for descriptions etc we have:
# service reference (to get the service name)
@@ -85,14 +85,14 @@ def findSafeRecordPath(dirname):
if not dirname:
return None
from Components import Harddisk
- dirname = os.path.realpath(dirname)
+ dirname = ospath.realpath(dirname)
mountpoint = Harddisk.findMountPoint(dirname)
- if not os.path.ismount(mountpoint):
+ if not ospath.ismount(mountpoint):
print("[RecordTimer] media is not mounted:", dirname)
return None
- if not os.path.isdir(dirname):
+ if not ospath.isdir(dirname):
try:
- os.makedirs(dirname)
+ makedirs(dirname)
except Exception as ex:
print("[RecordTimer] Failed to create dir '%s':" % dirname, ex)
return None
@@ -124,8 +124,8 @@ def SetIconDisplay(nrec):
return
(wdev, max_states) = SID_code_states
if nrec == 0: # An absolute setting - clear it...
- f = open(wdev, 'w')
- f.write('0')
+ f = open(wdev, "w")
+ f.write("0")
f.close()
return
#
@@ -134,7 +134,7 @@ def SetIconDisplay(nrec):
sym = max_states
if sym < 0: # Sanity check - just in case...
sym = 0
- f = open(wdev, 'w')
+ f = open(wdev, "w")
f.write(str(sym))
f.close()
return
@@ -177,14 +177,14 @@ def RecordingsState(alter):
# type 2 = digital radio sound service
# type 10 = advanced codec digital radio sound service
-service_types_tv = '1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 22) || (type == 25) || (type == 134) || (type == 195)'
+service_types_tv = "1:7:1:0:0:0:0:0:0:0:(type == 1) || (type == 17) || (type == 22) || (type == 25) || (type == 134) || (type == 195)"
wasRecTimerWakeup = False
# please do not translate log messages
class RecordTimerEntry(TimerEntry):
- def __init__(self, serviceref, begin, end, name, description, eit, disabled=False, justplay=False, afterEvent=AFTEREVENT.AUTO, checkOldTimers=False, dirname=None, tags=None, descramble='notset', record_ecm='notset', isAutoTimer=False, always_zap=False, rename_repeat=True, conflict_detection=True, pipzap=False, autoTimerId=None):
+ def __init__(self, serviceref, begin, end, name, description, eit, disabled=False, justplay=False, afterEvent=AFTEREVENT.AUTO, checkOldTimers=False, dirname=None, tags=None, descramble="notset", record_ecm="notset", isAutoTimer=False, always_zap=False, rename_repeat=True, conflict_detection=True, pipzap=False, autoTimerId=None):
TimerEntry.__init__(self, int(begin), int(end))
if checkOldTimers:
if self.begin < time() - 1209600:
@@ -195,10 +195,14 @@ def __init__(self, serviceref, begin, end, name, description, eit, disabled=Fals
assert isinstance(serviceref, eServiceReference)
+ if serviceref and serviceref.toString()[:4] in config.recording.setstreamto1.value: # check if to convert IPTV services (4097, etc) to "1"
+ serviceref = eServiceReference("1" + serviceref.toString()[4:])
+
if serviceref and serviceref.isRecordable():
self.service_ref = serviceref
else:
self.service_ref = eServiceReference()
+ # print("[RecordTimer][RecordTimerEntry2] serviceref", self.service_ref)
self.eit = eit
self.dontSave = False
self.name = name
@@ -218,14 +222,14 @@ def __init__(self, serviceref, begin, end, name, description, eit, disabled=Fals
self.tags = tags or []
self.conflict_detection = conflict_detection
- if descramble == 'notset' and record_ecm == 'notset':
- if config.recording.ecm_data.value == 'descrambled+ecm':
+ if descramble == "notset" and record_ecm == "notset":
+ if config.recording.ecm_data.value == "descrambled+ecm":
self.descramble = True
self.record_ecm = True
- elif config.recording.ecm_data.value == 'scrambled+ecm':
+ elif config.recording.ecm_data.value == "scrambled+ecm":
self.descramble = False
self.record_ecm = True
- elif config.recording.ecm_data.value == 'normal':
+ elif config.recording.ecm_data.value == "normal":
self.descramble = True
self.record_ecm = False
else:
@@ -237,7 +241,7 @@ def __init__(self, serviceref, begin, end, name, description, eit, disabled=Fals
if SystemInfo["DVB-T_priority_tuner_available"] or SystemInfo["DVB-C_priority_tuner_available"] or SystemInfo["DVB-S_priority_tuner_available"] or SystemInfo["ATSC_priority_tuner_available"]:
rec_ref = self.service_ref and self.service_ref.ref
str_service = rec_ref and rec_ref.toString()
- if str_service and '%3a//' not in str_service and not str_service.rsplit(":", 1)[1].startswith("/"):
+ if str_service and "%3a//" not in str_service and not str_service.rsplit(":", 1)[1].startswith("/"):
type_service = rec_ref.getUnsignedData(4) >> 16
if type_service == 0xEEEE:
if SystemInfo["DVB-T_priority_tuner_available"] and config.usage.recording_frontend_priority_dvbt.value != "-2":
@@ -292,12 +296,12 @@ def freespace(self):
return False
self.MountPath = dirname
- mountwriteable = os.access(dirname, os.W_OK)
+ mountwriteable = access(dirname, W_OK)
if not mountwriteable:
self.log(0, ("Mount '%s' is not writeable." % dirname))
return False
- s = os.statvfs(dirname)
+ s = statvfs(dirname)
if (s.f_bavail * s.f_bsize) // 1000000 < 1024:
self.log(0, "Not enough free space to record")
return False
@@ -321,7 +325,7 @@ def calculateFilename(self, name=None):
filename = begin_date + " - " + service_name
if name:
if config.recording.filename_composition.value == "event":
- filename = name + ' - ' + begin_date + "_" + service_name
+ filename = name + " - " + begin_date + "_" + service_name
elif config.recording.filename_composition.value == "short":
filename = strftime("%Y%m%d", localtime(self.begin)) + " - " + name
elif config.recording.filename_composition.value == "long":
@@ -470,16 +474,14 @@ def _bouquet_search(self):
ChannelSelectionInstance.addToHistory(self.service_ref.ref)
NavigationInstance.instance.playService(self.service_ref.ref)
-# Report the tuner that the current recording is using
- def log_tuner(self, level, state):
-# If we have a Zap timer then the tuner is for the current service
- if self.justplay:
+ def log_tuner(self, level, state): # Report the tuner that the current recording is using
+ if self.justplay: # If we have a Zap timer then the tuner is for the current service
timer_rs = NavigationInstance.instance.getCurrentService()
else:
timer_rs = self.record_service
feinfo = timer_rs and hasattr(timer_rs, "frontendInfo") and timer_rs.frontendInfo()
fedata = feinfo and hasattr(feinfo, "getFrontendData") and feinfo.getFrontendData()
- tuner_info = fedata and "tuner_number" in fedata and chr(ord('A') + fedata.get("tuner_number")) or "(fallback) stream"
+ tuner_info = fedata and "tuner_number" in fedata and chr(ord("A") + fedata.get("tuner_number")) or "(fallback) stream"
self.log(level, "%s recording on tuner: %s" % (state, tuner_info))
def activate(self):
@@ -540,12 +542,14 @@ def activate(self):
return True
self.log(7, "prepare failed")
if eStreamServer.getInstance().getConnectedClients():
+ self.log(71, "eStreamerServer client - stop")
eStreamServer.getInstance().stopStream()
return False
if self.first_try_prepare or (self.ts_dialog is not None and not self.checkingTimeshiftRunning()):
self.first_try_prepare = False
cur_ref = NavigationInstance.instance.getCurrentlyPlayingServiceReference()
- if cur_ref and not cur_ref.getPath():
+ rec_ref = self.service_ref and self.service_ref.ref
+ if cur_ref and not cur_ref.getPath() or rec_ref.toString()[:4] in config.recording.setstreamto1.value: # "or" check if IPTV services (4097, etc)
if self.always_zap:
return False
if Screens.Standby.inStandby:
@@ -576,9 +580,9 @@ def activate(self):
# Both see the file as existing, but only one can delete it...
#
with wasrec_lock:
- if os.path.exists("/tmp/was_rectimer_wakeup") and not wasRecTimerWakeup:
+ if ospath.exists("/tmp/was_rectimer_wakeup") and not wasRecTimerWakeup:
wasRecTimerWakeup = int(open("/tmp/was_rectimer_wakeup", "r").read()) and True or False
- os.remove("/tmp/was_rectimer_wakeup")
+ remove("/tmp/was_rectimer_wakeup")
self.autostate = Screens.Standby.inStandby
@@ -609,7 +613,7 @@ def activate(self):
if cur_ref_group and cur_ref_group != self.service_ref.ref and self.InfoBarInstance and hasattr(self.InfoBarInstance.session, 'pipshown') and not Components.ParentalControl.parentalControl.isProtected(self.service_ref.ref):
if self.InfoBarInstance.session.pipshown:
hasattr(self.InfoBarInstance, "showPiP") and self.InfoBarInstance.showPiP()
- if hasattr(self.InfoBarInstance.session, 'pip'):
+ if hasattr(self.InfoBarInstance.session, "pip"):
del self.InfoBarInstance.session.pip
self.InfoBarInstance.session.pipshown = False
self.InfoBarInstance.session.pip = self.InfoBarInstance.session.instantiateDialog(PictureInPicture)
@@ -696,8 +700,8 @@ def activate(self):
return True
from Components.Converter.ClientsStreaming import ClientsStreaming
if (not Screens.Standby.inStandby and NavigationInstance.instance.getCurrentlyPlayingServiceReference() and
- ('0:0:0:0:0:0:0:0:0' in NavigationInstance.instance.getCurrentlyPlayingServiceReference().toString() or
- '4097:' in NavigationInstance.instance.getCurrentlyPlayingServiceReference().toString())
+ ("0:0:0:0:0:0:0:0:0" in NavigationInstance.instance.getCurrentlyPlayingServiceReference().toString() or
+ "4097:" in NavigationInstance.instance.getCurrentlyPlayingServiceReference().toString())
):
return True
@@ -734,7 +738,7 @@ def activate(self):
def keypress(self, key=None, flag=1):
if flag and self.wasInStandby:
self.wasInStandby = False
- eActionMap.getInstance().unbindAction('', self.keypress)
+ eActionMap.getInstance().unbindAction("", self.keypress)
def setAutoincreaseEnd(self, entry=None):
if not self.autoincrease:
@@ -858,9 +862,9 @@ def failureCB(self, answer):
self.log(13, "ok, zapped away")
#NavigationInstance.instance.stopUserServices()
self._bouquet_search()
- if not self.first_try_prepare and self.InfoBarInstance and hasattr(self.InfoBarInstance.session, 'pipshown') and self.InfoBarInstance.session.pipshown:
+ if not self.first_try_prepare and self.InfoBarInstance and hasattr(self.InfoBarInstance.session, "pipshown") and self.InfoBarInstance.session.pipshown:
hasattr(self.InfoBarInstance, "showPiP") and self.InfoBarInstance.showPiP()
- if hasattr(self.InfoBarInstance.session, 'pip'):
+ if hasattr(self.InfoBarInstance.session, "pip"):
del self.InfoBarInstance.session.pip
self.InfoBarInstance.session.pipshown = False
else:
@@ -907,13 +911,13 @@ def gotRecordEvent(self, record, event):
# we have record_service as property to automatically subscribe to record service events
def setRecordService(self, service):
if self.__record_service is not None:
-# print("[RecordTimer][remove callback]")
+ # print("[RecordTimer][remove callback]")
NavigationInstance.instance.record_event.remove(self.gotRecordEvent)
self.__record_service = service
if self.__record_service is not None:
-# print("[RecordTimer][add callback]")
+ # print("[RecordTimer][add callback]")
NavigationInstance.instance.record_event.append(self.gotRecordEvent)
record_service = property(lambda self: self.__record_service, setRecordService)
@@ -922,7 +926,8 @@ def setRecordService(self, service):
def createTimer(xml):
begin = int(xml.get("begin"))
end = int(xml.get("end"))
- serviceref = eServiceReference(str(xml.get("serviceref")))
+ pre_serviceref = xml.get("serviceref")
+ serviceref = eServiceReference("1" + pre_serviceref[4:]) if pre_serviceref[:4] in config.recording.setstreamto1.value else eServiceReference(pre_serviceref) # check if to convert IPTV services (4097, etc) to "1"
description = str(xml.get("description"))
repeated = str(xml.get("repeated"))
rename_repeat = int(xml.get("rename_repeat") or "1")
@@ -980,12 +985,13 @@ def __init__(self):
def doActivate(self, w, dosave=True):
# when activating a timer for servicetype 4097,
# and SystemApp has player enabled, then skip recording.
- if "4097:" in w.service_ref.toString() and Directories.isPluginInstalled("ServiceApp") and config.plugins.serviceapp.servicemp3.replace.value == True:
+ # Or always skip if in ("5001", "5002") as these cannot be recorded.
+ if w.service_ref.toString().startswith("4097:") and Directories.isPluginInstalled("ServiceApp") and config.plugins.serviceapp.servicemp3.replace.value == True or w.service_ref.toString()[:4] in ("5001", "5002"):
print("[RecordTimer][doActivate] found Serviceapp & player enabled - disable this timer recording")
w.state = RecordTimerEntry.StateEnded
from Tools.Notifications import AddPopup
from Screens.MessageBox import MessageBox
- AddPopup(_("Recording IPTV 4097 with systemapp enabled, timer ended!\nPlease recheck it!"), type=MessageBox.TYPE_ERROR, timeout=0, id="TimerRecordingFailed")
+ AddPopup(_("Recording IPTV with systemapp enabled, timer ended!\nPlease recheck it!"), type=MessageBox.TYPE_ERROR, timeout=0, id="TimerRecordingFailed")
# when activating a timer which has already passed,
# simply abort the timer. don't run trough all the stages.
elif w.shouldSkip():
@@ -1001,9 +1007,7 @@ def doActivate(self, w, dosave=True):
self.timer_list.remove(w)
except:
print("[RecordTimer] Remove list failed")
-
- # did this timer reached the last state?
- if w.state < RecordTimerEntry.StateEnded:
+ if w.state < RecordTimerEntry.StateEnded: # did this timer reached the last state?
# no, sort it into active list
insort(self.timer_list, w)
else:
@@ -1046,9 +1050,7 @@ def isRecording(self):
return True
return False
- # justLoad is passed on to record()
- #
- def loadTimer(self, justLoad=False):
+ def loadTimer(self, justLoad=False): # justLoad is passed on to record()
try:
file = open(self.Filename, 'r')
doc = xml.etree.cElementTree.parse(file)
@@ -1061,7 +1063,7 @@ def loadTimer(self, justLoad=False):
print("[RecordTimer] timers.xml failed to load!")
try:
- os.rename(self.Filename, self.Filename + "_old")
+ rename(self.Filename, self.Filename + "_old")
except (IOError, OSError):
print("[RecordTimer] renaming broken timer failed")
return
@@ -1174,9 +1176,9 @@ def saveTimer(self):
file.writelines(list)
file.flush()
- os.fsync(file.fileno())
+ fsync(file.fileno())
file.close()
- os.rename(self.Filename + ".writing", self.Filename)
+ rename(self.Filename + ".writing", self.Filename)
def getNextZapTime(self):
now = time()
@@ -1366,7 +1368,7 @@ def isInTimer(self, service, begin, duration):
for timer in self.timer_list:
# repeat timers represent all their future repetitions, so always include them
if (startAt <= timer.end or timer.repeated) and timer.begin < endAt:
- check = timer.service_ref.toCompareString() == refstr
+ check = timer.service_ref.toCompareString().split(":", 2)[2] == refstr.split(":", 2)[2]
if check:
matchType = RecordTimer.__checkTimer(timer, check_offset_time, begin, end, duration)
if matchType is not None:
@@ -1390,7 +1392,7 @@ def isInTimerOnService(serviceTimerList, begin, duration):
return returnValue or (None, None)
def removeEntry(self, entry):
- # print("[RecordTimer] Remove " + str(entry))
+ # print("[RecordTimer] Remove " + str(entry))
# avoid re-enqueuing
entry.repeated = False
diff --git a/lib/python/Screens/About.py b/lib/python/Screens/About.py
index 9be48f6ffe..8243dbe82c 100644
--- a/lib/python/Screens/About.py
+++ b/lib/python/Screens/About.py
@@ -332,7 +332,7 @@ def Stage1Complete(self, result, retval, extra_args=None):
if pathExists("/media/autofs"):
for entry in sorted(listdir("/media/autofs")):
mountEntry = path.join("/media/autofs", entry)
- self.mountinfo += _("\n %s is also enabled for autofs network mount" % (mountEntry))
+ self.mountinfo += _("\n %s is also enabled for autofs network mount") % (mountEntry)
if self.mountinfo:
self["mounts"].setText(self.mountinfo)
else:
diff --git a/lib/python/Screens/Ci.py b/lib/python/Screens/Ci.py
index 79d48d3e90..cadced46f0 100644
--- a/lib/python/Screens/Ci.py
+++ b/lib/python/Screens/Ci.py
@@ -13,10 +13,11 @@
forceNotShowCiMessages = False
-
def setCIBitrate(configElement):
eDVBCI_UI.getInstance().setClockRate(configElement.slotid, eDVBCI_UI.rateNormal if configElement.value == "no" else eDVBCI_UI.rateHigh)
+def setCIEnabled(configElement):
+ eDVBCI_UI.getInstance().setEnabled(configElement.slotid, configElement.value)
def setdvbCiDelay(configElement):
open(SystemInfo["CommonInterfaceCIDelay"], "w").write(configElement.value)
@@ -33,6 +34,9 @@ def InitCiConfig():
if SystemInfo["CommonInterface"]:
for slot in range(SystemInfo["CommonInterface"]):
config.ci.append(ConfigSubsection())
+ config.ci[slot].enabled = ConfigYesNo(default=True)
+ config.ci[slot].enabled.slotid = slot
+ config.ci[slot].enabled.addNotifier(setCIEnabled)
config.ci[slot].canDescrambleMultipleServices = ConfigSelection(choices=[("auto", _("auto")), ("no", _("no")), ("yes", _("yes"))], default="auto")
config.ci[slot].use_static_pin = ConfigYesNo(default=True)
config.ci[slot].static_pin = ConfigPIN(default=0)
@@ -433,6 +437,7 @@ def appendEntries(self, slot, state):
self.state[slot] = state
if self.slot > 1:
self.list.append(("**************************", ConfigNothing(), 3, slot))
+ self.list.append((_("CI %s enabled" % (slot)), config.ci[slot].enabled, -1, slot))
self.list.append((_("Reset"), ConfigNothing(), 0, slot))
self.list.append((_("Init"), ConfigNothing(), 1, slot))
@@ -443,7 +448,11 @@ def appendEntries(self, slot, state):
elif self.state[slot] == 2: #module ready
appname = eDVBCI_UI.getInstance().getAppName(slot)
self.list.append((appname, ConfigNothing(), 2, slot))
- self.list.append(getConfigListEntry(_("Set pin code persistent"), config.ci[slot].use_static_pin, 3, slot))
+ elif self.state[slot] == 3: # module disabled by the user
+ self.list.append((_("module disabled"), ConfigNothing(), 2, slot))
+ return
+
+ self.list.append(getConfigListEntry(_("Set persistent PIN code"), config.ci[slot].use_static_pin, 3, slot))
self.list.append((_("Enter persistent PIN code"), ConfigNothing(), 5, slot))
self.list.append((_("Reset persistent PIN code"), ConfigNothing(), 6, slot))
self.list.append(getConfigListEntry(_("Show CI messages"), config.ci[slot].show_ci_messages, 3, slot))
@@ -465,6 +474,7 @@ def updateState(self, slot):
if slot > 0:
slotidx += 1 #do not change separator
+ slotidx += 1 #do not change CI Enabled
slotidx += 1 #do not change Reset
slotidx += 1 #do not change Init
@@ -475,7 +485,11 @@ def updateState(self, slot):
elif state == 2: #module ready
appname = eDVBCI_UI.getInstance().getAppName(slot)
self.list[slotidx] = (appname, ConfigNothing(), 2, slot)
-
+ if len(self.list) <= slotidx + 1:
+ self.list = []
+ self.appendEntries(slot, state)
+ elif state == 3:
+ self.list = self.list[0:slotidx+1]
lst = self["entries"]
lst.list = self.list
lst.l.setList(self.list)