Skip to content

Commit

Permalink
[Recording/Timeshift] modify code to use main setup.xml file.
Browse files Browse the repository at this point in the history
  • Loading branch information
Andy Blackburn committed Oct 4, 2012
1 parent 47d9c68 commit 3177f5e
Show file tree
Hide file tree
Showing 7 changed files with 673 additions and 511 deletions.
4 changes: 2 additions & 2 deletions data/menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,11 @@ self.session.open(SABnzbdSetupScreen)
<item level="2" text="uShare setup" entryID="netushare_setup"><screen module="NetworkSetup" screen="NetworkuShare"/></item>
</menu>
<item level="1" entryID="onlineupdate_setup"><setup id="softwareupdate"/></item>
<item level="0" text="Recording settings" entryID="recording_setup"><screen module="Recordings_Timershift" screen="RecordingSettings" /></item>
<item level="0" text="Recording settings" entryID="recording_setup"><screen module="Recordings" screen="RecordingSettings" /></item>
<item level="1" entryID="rfmod_setup" requires="RfModulator"><setup id="RFmod"/></item>
<item level="0" text="Skin setup" entryID="skin_setup"><screen module="SkinSelector" screen="SkinSelector"/></item>
<item level="2" entryID="subtitle_setup"><setup id="subtitlesetup" /></item>
<item level="0" text="Timeshift settings" entryID="timshift_setup"><screen module="Recordings_Timershift" screen="TimeshiftSettings" /></item>
<item level="0" text="Timeshift settings" entryID="timshift_setup"><screen module="Timershift" screen="TimeshiftSettings" /></item>
<item level="0" entryID="time_setup"><setup id="time"/></item>
<menu level="2" text="User interface" entryID="osd_setup" requires="OsdMenu">
<id val="osd_menu" />
Expand Down
18 changes: 10 additions & 8 deletions data/setup.xml
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@
<item level="1" text="EPG language selection 1" description="Configure the primary EPG language.">config.autolanguage.audio_epglanguage</item>
<item level="1" text="EPG language selection 2" description="Configure the secundary EPG language.">config.autolanguage.audio_epglanguage_alternative</item>
</setup>
<setup key="recording" title="Record">
<setup key="recording" title="Recording settings">
<item level="1" text="Recordings always have priority" description="When enabled, a recording is allowed to interrupt live tv, when there are no free tuners.">config.recording.asktozap</item>
<item level="0" text="Margin before record (minutes)" description="When nonzero, a recording will start earlier than the starting time as indicated by the EPG.">config.recording.margin_before</item>
<item level="0" text="Margin after record (minutes)" description="When nonzero, a recording will stop later than the ending time as indicated by the EPG.">config.recording.margin_after</item>
Expand All @@ -139,6 +139,8 @@
<item level="2" text="Custom skip time for '1'/'3'-keys" description="Configure the skip time interval on the '1'/'3'-keys.">config.seek.selfdefined_13</item>
<item level="2" text="Custom skip time for '4'/'6'-keys" description="Configure the skip time interval on the '4'/'6'-keys.">config.seek.selfdefined_46</item>
<item level="2" text="Custom skip time for '7'/'9'-keys" description="Configure the skip time interval on the '7'/'9'-keys.">config.seek.selfdefined_79</item>
<item level="2" text="Seekbar activation" description="Select seekbar to be activated by arrow L/R (long) or &lt;&lt; &gt;&gt; (long).">config.seek.baractivation</item>
<item level="2" text="Seekbar sensibility" description="Set the jump-size of the seekbar.">config.seek.sensibility</item>
<item level="2" text="Fast forward speeds" description="Configure the possible fast forward speeds.">config.seek.speeds_forward</item>
<item level="2" text="Rewind speeds" description="Configure the possible rewind speeds.">config.seek.speeds_backward</item>
<item level="2" text="Slow motion speeds" description="Configure the slow motion speeds.">config.seek.speeds_slowmotion</item>
Expand Down Expand Up @@ -232,13 +234,13 @@
<item level="2" text="Maximum space used (MB):" description="If logs are using the set maximum space used the eldest will be deleted.">config.crash.sizeloglimit</item>
</setup>
<setup key="timeshift" title="Timeshift settings">
<item level="1" text="Permanent Timeshift enable">config.timeshift.enabled</item>
<item level="2" text="Permanent Timeshift max events" requires="config.timeshift.enabled">config.timeshift.maxevents</item>
<item level="2" text="Permanent Timeshift max length" requires="config.timeshift.enabled">config.timeshift.maxlength</item>
<item level="2" text="Permanent Timeshift start delay" requires="config.timeshift.enabled">config.timeshift.startdelay</item>
<item level="2" text="Timeshift-save action on zap" requires="config.timeshift.enabled">config.timeshift.favoriteSaveAction</item>
<item level="2" text="Stop timeshift while recording?" requires="config.timeshift.enabled">config.timeshift.stopwhilerecording</item>
<item level="2" text="Use PTS seekbar while timeshifting?" requires="config.timeshift.enabled">config.timeshift.showinfobar</item>
<item level="1" text="Permanent Timeshift enable" description="Enable or disable Permanent Timeshift. When activated, you can wind back until the time you zapped to a channel, and you can make recordings in retrospect.">config.timeshift.enabled</item>
<item level="2" text="Permanent Timeshift max events" description="Set the maximum number of events (programs) that timeshift may handle." requires="config.timeshift.enabled">config.timeshift.maxevents</item>
<item level="2" text="Permanent Timeshift max length" description="Set the maximum length a timeshift file may be." requires="config.timeshift.enabled">config.timeshift.maxlength</item>
<item level="2" text="Permanent Timeshift start delay" description="Timeshift will only start when the start delay time has passed. This prevents numurous very short files when zapping." requires="config.timeshift.enabled">config.timeshift.startdelay</item>
<item level="2" text="Timeshift-save action on zap" description="Select if timeshift must continue when set to record." requires="config.timeshift.enabled">config.timeshift.favoriteSaveAction</item>
<item level="2" text="Stop timeshift while recording?" description="Set what the required action must be when zapping while a timeshift has been set as recording." requires="config.timeshift.enabled">config.timeshift.stopwhilerecording</item>
<item level="2" text="Use PTS seekbar while timeshifting?" description="If set to 'yes' a special seekbar is available during timeshift." requires="config.timeshift.enabled">config.timeshift.showinfobar</item>
</setup>
<setup key="epgsingle" title="ChannelEPG settings">
<item level="2" text="Sort list by" description="You can have the list sorted by time or alphanumerical.">config.epgselection.sort</item>
Expand Down
2 changes: 1 addition & 1 deletion lib/python/Screens/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
installdir = $(pkglibdir)/python/Screens

install_PYTHON = \
Recordings_Timershift.py LogManager.py CCcamInfo.py OScamInfo.py SkinSelector.py OSD.py \
Recordings.py Timershift.py LogManager.py CCcamInfo.py OScamInfo.py SkinSelector.py OSD.py \
\
AudioSelection.py ChannelSelection.py ClockDisplay.py ConfigMenu.py CopyFiles.py InfoBar.py \
Menu.py MessageBox.py Screen.py ServiceScan.py TimerEdit.py \
Expand Down
318 changes: 318 additions & 0 deletions lib/python/Screens/Recordings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,318 @@
from Screens.Screen import Screen
from Screens.LocationBox import MovieLocationBox, TimeshiftLocationBox
from Screens.MessageBox import MessageBox
from Components.Label import Label
from Components.config import config, configfile, ConfigYesNo, ConfigNothing, ConfigSelection, getConfigListEntry
from Components.ConfigList import ConfigListScreen
from Components.ActionMap import ActionMap
from Components.Pixmap import Pixmap
from Tools.Directories import fileExists
from Components.UsageConfig import preferredPath
from Components.Sources.Boolean import Boolean
from Components.Sources.StaticText import StaticText
from Components.SystemInfo import SystemInfo

from enigma import eEnv
import xml.etree.cElementTree

class SetupSummary(Screen):
def __init__(self, session, parent):
Screen.__init__(self, session, parent = parent)
self["SetupTitle"] = StaticText(_(parent.setup_title))
self["SetupEntry"] = StaticText("")
self["SetupValue"] = StaticText("")
self.onShow.append(self.addWatcher)
self.onHide.append(self.removeWatcher)

def addWatcher(self):
self.parent.onChangedEntry.append(self.selectionChanged)
self.parent["config"].onSelectionChanged.append(self.selectionChanged)
self.selectionChanged()

def removeWatcher(self):
self.parent.onChangedEntry.remove(self.selectionChanged)
self.parent["config"].onSelectionChanged.remove(self.selectionChanged)

def selectionChanged(self):
self["SetupEntry"].text = self.parent.getCurrentEntry()
self["SetupValue"].text = self.parent.getCurrentValue()
if hasattr(self.parent,"getCurrentDescription"):
self.parent["description"].text = self.parent.getCurrentDescription()

class RecordingSettings(Screen,ConfigListScreen):
skin = """
<screen name="RecordPathsSettings" position="160,150" size="450,200" title="Recording paths">
<ePixmap pixmap="skin_default/buttons/red.png" position="10,0" size="140,40" alphatest="on" />
<ePixmap pixmap="skin_default/buttons/green.png" position="300,0" size="140,40" alphatest="on" />
<widget source="key_red" render="Label" position="10,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
<widget source="key_green" render="Label" position="300,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
<widget name="config" position="10,44" size="430,146" />
</screen>"""

def removeNotifier(self):
config.usage.setup_level.notifiers.remove(self.levelChanged)

def levelChanged(self, configElement):
list = []
self.refill(list)
self["config"].setList(list)

def refill(self, list):
xmldata = self.setupdom.getroot()
for x in xmldata.findall("setup"):
if x.get("key") != self.setup:
continue
self.addItems(list, x);
self.setup_title = x.get("title", "").encode("UTF-8")
self.seperation = int(x.get('separation', '0'))

def __init__(self, session):
from Components.Sources.StaticText import StaticText
Screen.__init__(self, session)
setupfile = file(eEnv.resolve('${datadir}/enigma2/setup.xml'), 'r')
self.setupdom = xml.etree.cElementTree.parse(setupfile)
setupfile.close()

self.skinName = "Setup"
self['footnote'] = Label()
self["HelpWindow"] = Pixmap()
self["HelpWindow"].hide()
self["VKeyIcon"] = Boolean(False)

self["key_red"] = StaticText(_("Cancel"))
self["key_green"] = StaticText(_("Save"))
self["description"] = Label(_(""))

self.onChangedEntry = [ ]
self.setup = "recording"
list = []
ConfigListScreen.__init__(self, list, session = session, on_change = self.changedEntry)
self.createSetup()

self["setupActions"] = ActionMap(["SetupActions", "ColorActions", "MenuActions"],
{
"green": self.keySave,
"red": self.keyCancel,
"cancel": self.keyCancel,
"ok": self.ok,
"menu": self.closeRecursive,
}, -2)
self.onLayoutFinish.append(self.layoutFinished)

def checkReadWriteDir(self, configele):
# print "checkReadWrite: ", configele.getValue()
if configele.getValue() in [x[0] for x in self.styles] or fileExists(configele.value, "w"):
configele.last_value = configele.getValue()
return True
else:
dir = configele.getValue()
configele.value = configele.last_value
self.session.open(
MessageBox,
_("The directory %s is not writable.\nMake sure you select a writable directory instead.")%dir,
type = MessageBox.TYPE_ERROR
)
return False

def createSetup(self):
self.styles = [ ("<default>", _("<Default movie location>")), ("<current>", _("<Current movielist location>")), ("<timer>", _("<Last timer location>")) ]
styles_keys = [x[0] for x in self.styles]
tmp = config.movielist.videodirs.getValue()
default = config.usage.default_path.getValue()
if default not in tmp:
tmp = tmp[:]
tmp.append(default)
# print "DefaultPath: ", default, tmp
self.default_dirname = ConfigSelection(default = default, choices = tmp)
tmp = config.movielist.videodirs.getValue()
default = config.usage.timer_path.getValue()
if default not in tmp and default not in styles_keys:
tmp = tmp[:]
tmp.append(default)
# print "TimerPath: ", default, tmp
self.timer_dirname = ConfigSelection(default = default, choices = self.styles+tmp)
tmp = config.movielist.videodirs.getValue()
default = config.usage.instantrec_path.getValue()
if default not in tmp and default not in styles_keys:
tmp = tmp[:]
tmp.append(default)
# print "InstantrecPath: ", default, tmp
self.instantrec_dirname = ConfigSelection(default = default, choices = self.styles+tmp)
self.default_dirname.addNotifier(self.checkReadWriteDir, initial_call=False, immediate_feedback=False)
self.timer_dirname.addNotifier(self.checkReadWriteDir, initial_call=False, immediate_feedback=False)
self.instantrec_dirname.addNotifier(self.checkReadWriteDir, initial_call=False, immediate_feedback=False)

list = []

if config.usage.setup_level.index >= 2:
self.default_entry = getConfigListEntry(_("Default movie location"), self.default_dirname, _("Set the default location for your recordings. Press 'OK' to add new locations, select left/right to select an existing location."))
list.append(self.default_entry)
self.timer_entry = getConfigListEntry(_("Timer record location"), self.timer_dirname, _("Set the default location for your timers. Press 'OK' to add new locations, select left/right to select an existing location."))
list.append(self.timer_entry)
self.instantrec_entry = getConfigListEntry(_("Instant record location"), self.instantrec_dirname, _("Set the default location for your instant recordings. Press 'OK' to add new locations, select left/right to select an existing location."))
list.append(self.instantrec_entry)
else:
self.default_entry = getConfigListEntry(_("Movie location"), self.default_dirname, _("Set the default location for your recordings. Press 'OK' to add new locations, select left/right to select an existing location."))
list.append(self.default_entry)

self.refill(list)
self["config"].setList(list)
if config.usage.sort_settings.getValue():
self["config"].list.sort()

def layoutFinished(self):
self.setTitle(_(self.setup_title))

# for summary:
def changedEntry(self):
self.item = self["config"].getCurrent()
if self["config"].getCurrent()[0] == _("Default movie location") or self["config"].getCurrent()[0] == _("Timer record location") or self["config"].getCurrent()[0] == _("Instant record location") or self["config"].getCurrent()[0] == _("Movie location"):
self.checkReadWriteDir(self["config"].getCurrent()[1])
for x in self.onChangedEntry:
x()
try:
if isinstance(self["config"].getCurrent()[1], ConfigYesNo) or isinstance(self["config"].getCurrent()[1], ConfigSelection):
self.createSetup()
except:
pass

def getCurrentEntry(self):
return self["config"].getCurrent() and self["config"].getCurrent()[0] or ""

def getCurrentValue(self):
return self["config"].getCurrent() and str(self["config"].getCurrent()[1].getText()) or ""

def getCurrentDescription(self):
return self["config"].getCurrent() and len(self["config"].getCurrent()) > 2 and self["config"].getCurrent()[2] or ""

def ok(self):
currentry = self["config"].getCurrent()
self.lastvideodirs = config.movielist.videodirs.getValue()
self.lasttimeshiftdirs = config.usage.allowed_timeshift_paths.getValue()
if config.usage.setup_level.index >= 2:
txt = _("Default movie location")
else:
txt = _("Movie location")
if currentry == self.default_entry:
self.entrydirname = self.default_dirname
self.session.openWithCallback(
self.dirnameSelected,
MovieLocationBox,
txt,
preferredPath(self.default_dirname.getValue())
)
elif currentry == self.timer_entry:
self.entrydirname = self.timer_dirname
self.session.openWithCallback(
self.dirnameSelected,
MovieLocationBox,
_("New timers location"),
preferredPath(self.timer_dirname.getValue())
)
elif currentry == self.instantrec_entry:
self.entrydirname = self.instantrec_dirname
self.session.openWithCallback(
self.dirnameSelected,
MovieLocationBox,
_("Instant recordings location"),
preferredPath(self.instantrec_dirname.getValue())
)

def dirnameSelected(self, res):
if res is not None:
self.entrydirname.value = res
if config.movielist.videodirs.getValue() != self.lastvideodirs:
styles_keys = [x[0] for x in self.styles]
tmp = config.movielist.videodirs.getValue()
default = self.default_dirname.getValue()
if default not in tmp:
tmp = tmp[:]
tmp.append(default)
self.default_dirname.setChoices(tmp, default=default)
tmp = config.movielist.videodirs.getValue()
default = self.timer_dirname.getValue()
if default not in tmp and default not in styles_keys:
tmp = tmp[:]
tmp.append(default)
self.timer_dirname.setChoices(self.styles+tmp, default=default)
tmp = config.movielist.videodirs.getValue()
default = self.instantrec_dirname.getValue()
if default not in tmp and default not in styles_keys:
tmp = tmp[:]
tmp.append(default)
self.instantrec_dirname.setChoices(self.styles+tmp, default=default)
self.entrydirname.value = res
if self.entrydirname.last_value != res:
self.checkReadWriteDir(self.entrydirname)

def saveAll(self):
currentry = self["config"].getCurrent()
config.usage.default_path.value = self.default_dirname.getValue()
config.usage.timer_path.value = self.timer_dirname.getValue()
config.usage.instantrec_path.value = self.instantrec_dirname.getValue()
config.usage.default_path.save()
config.usage.timer_path.save()
config.usage.instantrec_path.save()
for x in self["config"].list:
x[1].save()
configfile.save()

# keySave and keyCancel are just provided in case you need them.
# you have to call them by yourself.
def keySave(self):
self.saveAll()
self.close()

def cancelConfirm(self, result):
if not result:
return
for x in self["config"].list:
x[1].cancel()
self.close()

def keyCancel(self):
if self["config"].isChanged():
self.session.openWithCallback(self.cancelConfirm, MessageBox, _("Really close without saving settings?"))
else:
self.close()

def createSummary(self):
return SetupSummary

def addItems(self, list, parentNode):
for x in parentNode:
if not x.tag:
continue
if x.tag == 'item':
item_level = int(x.get("level", 0))

if not self.levelChanged in config.usage.setup_level.notifiers:
config.usage.setup_level.notifiers.append(self.levelChanged)
self.onClose.append(self.removeNotifier)

if item_level > config.usage.setup_level.index:
continue

requires = x.get("requires")
if requires and requires.startswith('config.'):
item = eval(requires or "");
if item.getValue() and not item.getValue() == "0":
SystemInfo[requires] = True
else:
SystemInfo[requires] = False

if requires and not SystemInfo.get(requires, False):
continue;

item_text = _(x.get("text", "??").encode("UTF-8"))
item_description = _(x.get("description", " ").encode("UTF-8"))
b = eval(x.text or "");
if b == "":
continue
#add to configlist
item = b
# the first b is the item itself, ignored by the configList.
# the second one is converted to string.
if not isinstance(item, ConfigNothing):
list.append((item_text, item, item_description))

0 comments on commit 3177f5e

Please sign in to comment.