I'm not sure why you're changing the Screens/Setup.py API by renaming setupdom() and changing the set of methods in Setup, especially things like renaming refill() to reloadList() and removing addItems().
I'm not sure why in Screens/Setup.py, loadSetupDOM() (aka setupdom()) isn't written as something like:
Code: Select all
__setupdoms = {}
def setupdom(setup=None, plugin=None):
global __setupdoms
if plugin:
src = resolveFilename(SCOPE_CURRENT_PLUGIN, plugin + "/setup.xml")
msg = " from plugin '%s'" % plugin
else:
src = resolveFilename(SCOPE_SKIN, "setup.xml")
msg = ""
print "[Setup] XML source file: '%s'" % src
print "[Setup] XML menu '%s'%s" % (setup, msg)
if src in __setupdoms:
return __setupdoms[src]
try:
setupfile = open(src, "r")
setupdom = xml.etree.cElementTree.parse(setupfile)
setupfile.close()
except IOError:
print "[Setup] ERROR: Unable to access XML file '%s'!" % src
setupdom = xml.etree.cElementTree.fromstring("<setupxml></setupxml>")
__setupdoms[src] = setupdom
return setupdom
To make it more backward-compatible, you could test the last modified time of the setup.xml file against the modified timestamp saved in __setupdoms. Entries in __setupdoms would then be a tuple (or something) like: (dom, modifiedtime).
In Screens/Setup.py:
Code: Select all
###
### Should the isinstance also cover TrueFalse, OnOff, EnableDisable?
###
if isinstance(self.item[1], ConfigYesNo) or isinstance(self.item[1], ConfigSelection):
I can't see why
Code: Select all
isinstance(self.item[1], ConfigBoolean)
wouldn't be better. The Fine Manual says of isinstance(): "Return true if the object argument is an instance of the classinfo argument, or of a (direct, indirect or virtual) subclass thereof."
In Screens/Setup.py:
Code: Select all
###
### Should the other queued tasks also be removed?
###
I don't know what that refers to.
I'm not sure why a whole bunch of lines in the imports in Screens/Setup.py are swapped around so much. It makes it harder to see what the actual differences are. Moving the Tools.Directories import to after all the Component imports makes sense, and the line is being changed anyway.
In Screens/Recordings.py there seem to be further changes to the class API I can't see a clear motivation for (like ok() -> keyOK()).
In Screens/Recordings.py, pathStatus(), the test of the pathname against "/media" is not a correct test of whether the the path is on flash. "/media" isn't the flash device, it's an in-memory tmpfs filesystem:
Code: Select all
tmpfs on /media type tmpfs (rw,relatime,size=64k)
The flash device is mounted on '/':
Code: Select all
ubi0:rootfs on / type ubifs (rw,relatime)
This means that the test on the device of "/media" will stop the path being set to "/media", but not, say, to "/".
Code: Select all
>>> "%04x" % os.stat("/media/hdd/movie").st_dev
'0801'
>>> "%04x" % os.stat("/media").st_dev
'000d'
>>> "%04x" % os.stat("/").st_dev
'000b'
>>>
IIRC, the paths in these config variables have been put through "os.path.realpath()" so pathname prefixes should work, so using os.stat() to compare devices would be unnecessary (and harder to get right). Testing for path.startswith("/") would also be unnecessary. In this pathStatus(), using path.startswith("/") would actually break the device-based test. The enigma2 binary runs with its current directory as "/home/root", so if in pathStatus(), path is set to "../../media", path.startswith("/") will fail, and self.status will remain set to PATH_OK, even though the object of path is "/media".
I'd have thought that it might be better to use the user's setting of "Root directory" instead of (or as well as) "/media" to restrict the folders in these path configs. Otherwise recording directories could be set to places that the media player can't get to without changing "Root directory".
It would be a good idea to continue to apply the existing "/media" restriction to "Root directory", though.
I suggest that error messages be handled slightly differently and the scope of the translation function _() be more carefully used.
so:
Code: Select all
ERRMSGS = {
PATH_OK: "",
PATH_READONLY: "Directory '%s' not writable!",
PATH_FLASH: "Flash directory '%s' not allowed!"
}
becomes:
Code: Select all
ERRMSGS = {
PATH_OK: "",
PATH_READONLY: _("Directory '%s' not writable!"),
PATH_FLASH: _("Flash directory '%s' not allowed!")
}
Code: Select all
self.session.open(MessageBox, _(self.ERRMSGS.get(self.status, "") + "\n\nPlease select a writable directory.") % self["config"].getCurrent()[1].value, type=MessageBox.TYPE_ERROR)
becomes:
Code: Select all
self.session.open(MessageBox, _(self.ERRMSGS.get(self.status, _("Unknown error on %s"))) % self["config"].getCurrent()[1].value + _("\n\nPlease select a writable directory."), type=MessageBox.TYPE_ERROR)
and:
Code: Select all
self.footnote = _(self.ERRMSGS.get(self.status, "Unexpected issue with '%s'!") % path)
becomes:
Code: Select all
self.footnote = self.ERRMSGS.get(self.status, _("Unexpected issue with '%s'!")) % path
In general, things like:
aren't going to do what you intend. They need to be:
I can't do any testing, because more is involved than just the two posted files.