Merge branch 'master' of fraxinas@git.opendreambox.org:/git/enigma2
authorFraxinas <andreas.frisch@multimedia-labs.de>
Thu, 29 Jan 2009 10:44:53 +0000 (11:44 +0100)
committerFraxinas <andreas.frisch@multimedia-labs.de>
Thu, 29 Jan 2009 10:44:53 +0000 (11:44 +0100)
35 files changed:
Navigation.py
keymapparser.py
lib/actions/parseactions.py
lib/dvb/epgcache.cpp
lib/nav/core.cpp
lib/nav/core.h
lib/nav/pcore.cpp
lib/nav/pcore.h
lib/python/Components/Console.py
lib/python/Components/Converter/EventTime.py
lib/python/Components/Converter/MovieInfo.py
lib/python/Components/Converter/ServicePosition.py
lib/python/Components/Converter/ServiceTime.py
lib/python/Components/Element.py
lib/python/Components/Harddisk.py
lib/python/Components/MovieList.py
lib/python/Components/NimManager.py
lib/python/Components/Renderer/Canvas.py
lib/python/Components/Renderer/PositionGauge.py
lib/python/Components/UsageConfig.py
lib/python/Components/config.py
lib/python/Plugins/DemoPlugins/TestPlugin/plugin.py
lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py
lib/python/Plugins/SystemPlugins/Satfinder/plugin.py
lib/python/Plugins/SystemPlugins/Videomode/VideoHardware.py
lib/python/Plugins/SystemPlugins/Videomode/plugin.py
lib/python/Screens/ChannelSelection.py
lib/python/Screens/InfoBarGenerics.py
lib/python/Screens/Setup.py
lib/python/Screens/TimerEdit.py
lib/python/Tools/LoadPixmap.py
lib/python/enigma_python.i
lib/python/python.h
mytest.py
skin.py

index 715e886..2ca87f6 100644 (file)
@@ -87,7 +87,7 @@ class Navigation:
                if ref:
                        if ref.flags & eServiceReference.isGroup:
                                ref = getBestPlayableServiceReference(ref, eServiceReference(), simulate)
-                       service = ref and self.pnav and self.pnav.recordService(ref)
+                       service = ref and self.pnav and self.pnav.recordService(ref, simulate)
                        if service is None:
                                print "record returned non-zero"
                return service
@@ -96,8 +96,8 @@ class Navigation:
                ret = self.pnav and self.pnav.stopRecordService(service)
                return ret
 
-       def getRecordings(self):
-               return self.pnav and self.pnav.getRecordings()
+       def getRecordings(self, simulate=False):
+               return self.pnav and self.pnav.getRecordings(simulate)
 
        def getCurrentService(self):
                if not self.currentlyPlayingService:
index 5023e94..63bca0f 100644 (file)
@@ -1,11 +1,18 @@
 import enigma
 import xml.etree.cElementTree
 
-from keyids import KEYIDS;
+from keyids import KEYIDS
 
 # these are only informational (for help)...
 from Tools.KeyBindings import addKeyBinding
 
+class KeymapError(Exception):
+    def __init__(self, message):
+        self.message = message
+
+    def __str__(self):
+        return self.message
+
 def parseKeys(context, filename, actionmap, device, keys):
        for x in keys.findall("key"):
                get_attr = x.attrib.get
@@ -29,12 +36,12 @@ def parseKeys(context, filename, actionmap, device, keys):
                        elif id[1] == 'd':
                                keyid = int(id[2:]) | 0x8000
                        else:
-                               raise "key id '" + str(id) + "' is neither hex nor dec"
+                               raise KeymapError("key id '" + str(id) + "' is neither hex nor dec")
                else:
                        try:
                                keyid = KEYIDS[id]
                        except:
-                               raise "key id '" + str(id) + "' is illegal"
+                               raise KeymapError("key id '" + str(id) + "' is illegal")
 #                              print context + "::" + mapto + " -> " + device + "." + hex(keyid)
                actionmap.bindKey(filename, device, keyid, flags, context, mapto)
                addKeyBinding(filename, keyid, context, mapto, flags)
@@ -48,7 +55,7 @@ def readKeymap(filename):
        try:
                dom = xml.etree.cElementTree.parse(source)
        except:
-               raise "keymap %s not well-formed." % filename
+               raise KeymapError("keymap %s not well-formed." % filename)
 
        keymap = dom.getroot()
 
index 4ab71af..2462a75 100644 (file)
@@ -65,7 +65,7 @@ def do_file(f, mode):
                                        except:
                                                pass
                                
-                                       raise "action enum must be simple."
+                                       raise Exception("action enum must be simple.")
                        
                                counter = 0
                        
@@ -82,7 +82,7 @@ def do_file(f, mode):
                                        
                                        if counter:
                                                if t != ",":
-                                                       raise "no comma"
+                                                       raise Exception("no comma")
                                                t = tokens.next()
                                
                                        if firsthit:
index 9bb8dfc..fdcbe0e 100644 (file)
@@ -2058,7 +2058,11 @@ PyObject *eEPGCache::search(ePyObject arg)
                        ePyObject obj = PyTuple_GET_ITEM(arg,0);
                        if (PyString_Check(obj))
                        {
+#if PY_VERSION_HEX < 0x02060000
                                argcount = PyString_GET_SIZE(obj);
+#else
+                               argcount = PyString_Size(obj);
+#endif
                                argstring = PyString_AS_STRING(obj);
                                for (int i=0; i < argcount; ++i)
                                        switch(argstring[i])
@@ -2156,7 +2160,11 @@ PyObject *eEPGCache::search(ePyObject arg)
                                {
                                        int casetype = PyLong_AsLong(PyTuple_GET_ITEM(arg, 4));
                                        const char *str = PyString_AS_STRING(obj);
+#if PY_VERSION_HEX < 0x02060000
                                        int textlen = PyString_GET_SIZE(obj);
+#else
+                                       int textlen = PyString_Size(obj);
+#endif
                                        if (querytype == 1)
                                                eDebug("lookup for events with '%s' as title(%s)", str, casetype?"ignore case":"case sensitive");
                                        else
@@ -2171,20 +2179,32 @@ PyObject *eEPGCache::search(ePyObject arg)
                                                        int title_len = data[5];
                                                        if ( querytype == 1 )
                                                        {
+                                                               int offs = 6;
+                                                               // skip DVB-Text Encoding!
+                                                               if (data[6] == 0x10)
+                                                               {
+                                                                       offs+=3;
+                                                                       title_len-=3;
+                                                               }
+                                                               else if(data[6] > 0 && data[6] < 0x20)
+                                                               {
+                                                                       offs+=1;
+                                                                       title_len-=1;
+                                                               }
                                                                if (title_len != textlen)
                                                                        continue;
                                                                if ( casetype )
                                                                {
-                                                                       if ( !strncasecmp((const char*)data+6, str, title_len) )
+                                                                       if ( !strncasecmp((const char*)data+offs, str, title_len) )
                                                                        {
-//                                                                             std::string s((const char*)data+6, title_len);
+//                                                                             std::string s((const char*)data+offs, title_len);
 //                                                                             eDebug("match1 %s %s", str, s.c_str() );
                                                                                descr[++descridx] = it->first;
                                                                        }
                                                                }
-                                                               else if ( !strncmp((const char*)data+6, str, title_len) )
+                                                               else if ( !strncmp((const char*)data+offs, str, title_len) )
                                                                {
-//                                                                     std::string s((const char*)data+6, title_len);
+//                                                                     std::string s((const char*)data+offs, title_len);
 //                                                                     eDebug("match2 %s %s", str, s.c_str() );
                                                                        descr[++descridx] = it->first;
                                                                }
index 062a7d0..90650f6 100644 (file)
@@ -72,7 +72,7 @@ RESULT eNavigation::stopService(void)
        return 0;
 }
 
-RESULT eNavigation::recordService(const eServiceReference &ref, ePtr<iRecordableService> &service)
+RESULT eNavigation::recordService(const eServiceReference &ref, ePtr<iRecordableService> &service, bool simulate)
 {
        assert(m_servicehandler);
        RESULT res = m_servicehandler->record(ref, service);
@@ -81,9 +81,14 @@ RESULT eNavigation::recordService(const eServiceReference &ref, ePtr<iRecordable
                service = 0;
        else
        {
-               ePtr<eConnection> conn;
-               service->connectEvent(slot(*this, &eNavigation::recordEvent), conn);
-               m_recordings[service]=conn;
+               if (simulate)
+                       m_simulate_recordings.insert(service);
+               else
+               {
+                       ePtr<eConnection> conn;
+                       service->connectEvent(slot(*this, &eNavigation::recordEvent), conn);
+                       m_recordings[service]=conn;
+               }
        }
        return res;
 }
@@ -91,26 +96,40 @@ RESULT eNavigation::recordService(const eServiceReference &ref, ePtr<iRecordable
 RESULT eNavigation::stopRecordService(ePtr<iRecordableService> &service)
 {
        service->stop();
-       std::map<ePtr<iRecordableService>, ePtr<eConnection> >::iterator it =
-               m_recordings.find(service);
-       if (it != m_recordings.end())
+       std::set<ePtr<iRecordableService> >::iterator it =
+               m_simulate_recordings.find(service);
+       if (it != m_simulate_recordings.end())
        {
-               m_recordings.erase(it);
-               /* send stop event */
-               m_record_event(service, iRecordableService::evEnd);
+               m_simulate_recordings.erase(it);
                return 0;
        }
+       else
+       {
+               std::map<ePtr<iRecordableService>, ePtr<eConnection> >::iterator it =
+                       m_recordings.find(service);
+               if (it != m_recordings.end())
+               {
+                       m_recordings.erase(it);
+                       /* send stop event */
+                       m_record_event(service, iRecordableService::evEnd);
+                       return 0;
+               }
+       }
 
        eDebug("try to stop non running recording!!");  // this should not happen
        return -1;
 }
 
-PyObject *eNavigation::getRecordings(void)
+PyObject *eNavigation::getRecordings(bool simulate)
 {
-       ePyObject result = PyList_New(m_recordings.size());
+       ePyObject result = PyList_New(simulate ? m_simulate_recordings.size() : m_recordings.size());
        int pos=0;
-       for (std::map<ePtr<iRecordableService>, ePtr<eConnection> >::iterator it(m_recordings.begin()); it != m_recordings.end(); ++it)
-               PyList_SET_ITEM(result, pos++, NEW_iRecordableServicePtr(it->first)); 
+       if (simulate)
+               for (std::set<ePtr<iRecordableService> >::iterator it(m_simulate_recordings.begin()); it != m_simulate_recordings.end(); ++it)
+                       PyList_SET_ITEM(result, pos++, NEW_iRecordableServicePtr(*it));
+       else
+               for (std::map<ePtr<iRecordableService>, ePtr<eConnection> >::iterator it(m_recordings.begin()); it != m_recordings.end(); ++it)
+                       PyList_SET_ITEM(result, pos++, NEW_iRecordableServicePtr(it->first)); 
        return result;
 }
 
index 01efe9a..9f7be88 100644 (file)
@@ -5,6 +5,7 @@
 #include <lib/service/iservice.h>
 #include <connection.h>
 #include <map>
+#include <set>
 
 class eNavigation: public iObject, public Object
 {
@@ -17,6 +18,8 @@ class eNavigation: public iObject, public Object
        void serviceEvent(iPlayableService* service, int event);
 
        std::map<ePtr<iRecordableService>, ePtr<eConnection>, std::less<iRecordableService*> > m_recordings;
+       std::set<ePtr<iRecordableService>, std::less<iRecordableService*> > m_simulate_recordings;
+
        Signal2<void,ePtr<iRecordableService>,int> m_record_event;
        void recordEvent(iRecordableService* service, int event);
 public:
@@ -28,9 +31,9 @@ public:
        RESULT getCurrentService(ePtr<iPlayableService> &service);
        RESULT stopService(void);
        
-       RESULT recordService(const eServiceReference &ref, ePtr<iRecordableService> &service);
+       RESULT recordService(const eServiceReference &ref, ePtr<iRecordableService> &service, bool simulate=false);
        RESULT stopRecordService(ePtr<iRecordableService> &service);
-       PyObject *getRecordings(void);
+       PyObject *getRecordings(bool simulate=false);
        
        RESULT pause(int p);
        eNavigation(iServiceHandler *serviceHandler);
index a6ed35f..b38e559 100644 (file)
@@ -37,9 +37,9 @@ RESULT pNavigation::stopService()
        return m_core->stopService();
 }
 
-RESULT pNavigation::recordService(const eServiceReference &ref, ePtr<iRecordableService> &service)
+RESULT pNavigation::recordService(const eServiceReference &ref, ePtr<iRecordableService> &service, bool simulate)
 {
-       return m_core->recordService(ref, service);
+       return m_core->recordService(ref, service, simulate);
 }
 
 RESULT pNavigation::stopRecordService(ePtr<iRecordableService> &service)
@@ -47,9 +47,9 @@ RESULT pNavigation::stopRecordService(ePtr<iRecordableService> &service)
        return m_core->stopRecordService(service);
 }
 
-PyObject *pNavigation::getRecordings(void)
+PyObject *pNavigation::getRecordings(bool simulate)
 {
-       return m_core->getRecordings();
+       return m_core->getRecordings(simulate);
 }
 
 void pNavigation::navEvent(int event)
index 1d314b1..c157e0d 100644 (file)
@@ -20,9 +20,9 @@ public:
        RESULT pause(int p);
        SWIG_VOID(RESULT) getCurrentService(ePtr<iPlayableService> &SWIG_OUTPUT);
 
-       SWIG_VOID(RESULT) recordService(const eServiceReference &ref, ePtr<iRecordableService> &SWIG_OUTPUT);
+       SWIG_VOID(RESULT) recordService(const eServiceReference &ref, ePtr<iRecordableService> &SWIG_OUTPUT, bool simulate);
        RESULT stopRecordService(ePtr<iRecordableService> &service);
-       PyObject *getRecordings(void);
+       PyObject *getRecordings(bool simulate=false);
 
 private:
        ePtr<eNavigation> m_core;
index 136d10d..f1f3fd9 100644 (file)
@@ -21,7 +21,9 @@ class Console(object):
                self.appContainers[name] = eConsoleAppContainer()
                self.appContainers[name].dataAvail.append(boundFunction(self.dataAvailCB,name))
                self.appContainers[name].appClosed.append(boundFunction(self.finishedCB,name))
-               retval = self.appContainers[name].execute(cmd)
+               if isinstance(cmd, str): # until .execute supports a better api
+                       cmd = [cmd]
+               retval = self.appContainers[name].execute(*cmd)
                if retval:
                        self.finishedCB(name, retval)
 
index 966f2ca..41f1ebf 100644 (file)
@@ -1,7 +1,7 @@
 from Converter import Converter
 from Poll import Poll
 from time import time
-from Components.Element import cached
+from Components.Element import cached, ElementError
 
 class EventTime(Poll, Converter, object):
        STARTTIME = 0
@@ -28,7 +28,7 @@ class EventTime(Poll, Converter, object):
                        self.poll_interval = 30*1000
                        self.poll_enabled = True
                else:
-                       raise str("'%s' is not <StartTime|EndTime|Remaining|Duration|Progress> for EventTime converter" % type)
+                       raise ElementError("'%s' is not <StartTime|EndTime|Remaining|Duration|Progress> for EventTime converter" % type)
 
        @cached
        def getTime(self):
index 068d24d..be28dcc 100644 (file)
@@ -1,5 +1,5 @@
 from Components.Converter.Converter import Converter
-from Components.Element import cached
+from Components.Element import cached, ElementError
 from enigma import iServiceInformation
 from ServiceReference import ServiceReference
 
@@ -16,7 +16,7 @@ class MovieInfo(Converter, object):
                elif type == "RecordServiceName":
                        self.type = self.MOVIE_REC_SERVICE_NAME
                else:
-                       raise str("'%s' is not <ShortDescription|MetaDescription|RecordServiceName> for MovieInfo converter" % type)
+                       raise ElementError("'%s' is not <ShortDescription|MetaDescription|RecordServiceName> for MovieInfo converter" % type)
                Converter.__init__(self, type)
 
        @cached
index d7a55da..2bcc549 100644 (file)
@@ -1,7 +1,7 @@
 from Converter import Converter
 from Poll import Poll
 from enigma import iPlayableService
-from Components.Element import cached
+from Components.Element import cached, ElementError
 
 class ServicePosition(Converter, Poll, object):
        TYPE_LENGTH = 0
@@ -35,7 +35,7 @@ class ServicePosition(Converter, Poll, object):
                elif type == "Gauge":
                        self.type = self.TYPE_GAUGE
                else:
-                       raise "type must be {Length|Position|Remaining|Gauge} with optional arguments {Negate|Detailed|ShowHours|NoSeconds}"
+                       raise ElementError("type must be {Length|Position|Remaining|Gauge} with optional arguments {Negate|Detailed|ShowHours|NoSeconds}")
 
                self.poll_enabled = self.type != self.TYPE_LENGTH
 
index 16bcae3..8996506 100644 (file)
@@ -1,5 +1,5 @@
 from Converter import Converter
-from Components.Element import cached
+from Components.Element import cached, ElementError
 from enigma import iServiceInformation
 
 class ServiceTime(Converter, object):
@@ -16,7 +16,7 @@ class ServiceTime(Converter, object):
                elif type == "Duration":
                        self.type = self.DURATION
                else:
-                       raise str("'%s' is not <StartTime|EndTime|Duration> for eEventTime converter" % type)
+                       raise ElementError("'%s' is not <StartTime|EndTime|Duration> for eEventTime converter" % type)
 
        @cached
        def getTime(self):
index 2af5779..f4a8f12 100644 (file)
@@ -16,6 +16,13 @@ def cached(f):
                return cache[name][1]
        return wrapper
 
+class ElementError(Exception):
+    def __init__(self, message):
+        self.message = message
+
+    def __str__(self):
+        return self.message
+
 class Element(object):
        CHANGED_DEFAULT = 0   # initial "pull" state
        CHANGED_ALL = 1       # really everything changed
index ad7f28d..1fc629a 100644 (file)
@@ -2,7 +2,8 @@ from os import system, listdir, statvfs, popen, makedirs, readlink, stat, major,
 from Tools.Directories import SCOPE_HDD, resolveFilename
 from Tools.CList import CList
 from SystemInfo import SystemInfo
-import string
+import string, time
+from Components.Console import Console
 
 def tryOpen(filename):
        try:
@@ -18,6 +19,8 @@ class Harddisk:
                tmp = procfile.readline().split(':')
                s_major = int(tmp[0])
                s_minor = int(tmp[1])
+               self.max_idle_time = 0
+               self.idle_running = False
                for disc in listdir("/dev/discs"):
                        path = readlink('/dev/discs/'+disc)
                        devidex = '/dev/discs/'+disc+'/'
@@ -28,6 +31,7 @@ class Harddisk:
                                self.devidex = devidex
                                self.devidex2 = devidex2
                                print "new Harddisk", device, '->', self.devidex, '->', self.devidex2
+                               self.startIdle()
                                break
 
        def __lt__(self, ob):
@@ -213,6 +217,64 @@ class Harddisk:
        def getDeviceName(self):
                return self.getDeviceDir() + "disc"
 
+       # the HDD idle poll daemon.
+       # as some harddrives have a buggy standby timer, we are doing this by hand here.
+       # first, we disable the hardware timer. then, we check every now and then if
+       # any access has been made to the disc. If there has been no access over a specifed time,
+       # we set the hdd into standby.
+       def readStats(self):
+               l = open("/sys/block/%s/stat" % self.device).read()
+               nr_read = int(l[:8].strip())
+               nr_write = int(l[4*9:4*9+8].strip())
+               return nr_read, nr_write
+
+       def startIdle(self):
+               self.last_access = time.time()
+               self.last_stat = 0
+               self.is_sleeping = False
+               from enigma import eTimer
+
+               # disable HDD standby timer
+               Console().ePopen(("hdparm", "hdparm", "-S0", (self.devidex + "disc")))
+               self.timer = eTimer()
+               self.timer.callback.append(self.runIdle)
+               self.idle_running = True
+               self.setIdleTime(self.max_idle_time) # kick the idle polling loop
+
+       def runIdle(self):
+               if not self.max_idle_time:
+                       return
+               t = time.time()
+
+               idle_time = t - self.last_access
+
+               l = sum(self.readStats())
+
+               if l != self.last_stat: # access
+                       self.last_stat = l
+                       self.last_access = t
+                       self.idle_time = 0
+                       self.is_sleeping = False
+
+               #print "[IDLE]", idle_time, self.max_idle_time, self.is_sleeping
+               if idle_time >= self.max_idle_time and not self.is_sleeping:
+                       self.setSleep()
+                       self.is_sleeping = True
+
+       def setSleep(self):
+               Console().ePopen(("hdparm", "hdparm", "-y", (self.devidex + "disc")))
+
+       def setIdleTime(self, idle):
+               self.max_idle_time = idle
+               if self.idle_running:
+                       if not idle:
+                               self.timer.stop()
+                       else:
+                               self.timer.start(idle * 250, False)  # poll 4 times per period.
+
+       def isSleeping(self):
+               return self.is_sleeping
+
 class Partition:
        def __init__(self, mountpoint, device = None, description = "", force_mounted = False):
                self.mountpoint = mountpoint
index 8568f3d..5c98e4b 100644 (file)
@@ -93,10 +93,7 @@ class MovieList(GUIComponent):
                if len > 0:
                        len = "%d:%02d" % (len / 60, len % 60)
                else:
-                       if config.usage.load_length_of_movies_in_moviellist.value:
-                               len = "?:??"
-                       else:
-                               len = "X:XX"
+                       len = ""
                
                res = [ None ]
                
index 1fcbda1..2692cb5 100644 (file)
@@ -14,8 +14,6 @@ from enigma import eDVBSatelliteEquipmentControl as secClass, \
 from time import localtime, mktime
 from datetime import datetime
 
-from sets import Set
-
 def getConfigSatlist(orbpos, satlist):
        default_orbpos = None
        for x in satlist:
@@ -123,7 +121,7 @@ class SecConfigure:
 
        def update(self):
                sec = secClass.getInstance()
-               self.configuredSatellites = Set()
+               self.configuredSatellites = set()
                sec.clear() ## this do unlinking NIMs too !!
                print "sec config cleared"
 
@@ -442,7 +440,7 @@ class SecConfigure:
 
        def __init__(self, nimmgr):
                self.NimManager = nimmgr
-               self.configuredSatellites = Set()
+               self.configuredSatellites = set()
                self.update()
 
 class NIM(object):
index bd7ffb5..acf0dbf 100644 (file)
@@ -35,7 +35,7 @@ class Canvas(Renderer):
                                self.instance.writeText(eRect(l[1], l[2], l[3], l[4]), gRGB(l[5]), gRGB(l[6]), l[7], l[8], l[9])
                        else:
                                print "drawlist entry:", l
-                               raise "invalid drawlist entry"
+                               raise RuntimeError("invalid drawlist entry")
 
        def changed(self, what):
                self.pull_updates()
index 5fa8c35..3f93d82 100644 (file)
@@ -50,9 +50,10 @@ class PositionGauge(Renderer):
                return self.__cutlist
        
        def setCutlist(self, cutlist):
-               self.__cutlist = cutlist
-               if self.instance is not None:
-                       self.instance.setInOutList(cutlist)
+               if self.__cutlist != cutlist:
+                       self.__cutlist = cutlist
+                       if self.instance is not None:
+                               self.instance.setInOutList(cutlist)
 
        cutlist = property(getCutlist, setCutlist)
 
index 2ea91ae..21e057f 100644 (file)
@@ -17,12 +17,12 @@ def InitUsageConfig():
        config.usage.show_infobar_on_zap = ConfigYesNo(default = True)
        config.usage.show_infobar_on_skip = ConfigYesNo(default = True)
        config.usage.show_infobar_on_event_change = ConfigYesNo(default = True)
-       config.usage.hdd_standby = ConfigSelection(default = "120", choices = [
-               ("0", _("no standby")), ("2", "10 " + _("seconds")), ("6", "30 " + _("seconds")),
-               ("12", "1 " + _("minute")), ("24", "2 " + _("minutes")),
-               ("60", "5 " + _("minutes")), ("120", "10 " + _("minutes")), ("240", "20 " + _("minutes")),
-               ("241", "30 " + _("minutes")), ("242", "1 " + _("hour")), ("244", "2 " + _("hours")),
-               ("248", "4 " + _("hours")) ])
+       config.usage.hdd_standby = ConfigSelection(default = "600", choices = [
+               ("0", _("no standby")), ("10", "10 " + _("seconds")), ("30", "30 " + _("seconds")),
+               ("60", "1 " + _("minute")), ("120", "2 " + _("minutes")),
+               ("300", "5 " + _("minutes")), ("600", "10 " + _("minutes")), ("1200", "20 " + _("minutes")),
+               ("1800", "30 " + _("minutes")), ("3600", "1 " + _("hour")), ("7200", "2 " + _("hours")),
+               ("14400", "4 " + _("hours")) ])
        config.usage.output_12V = ConfigSelection(default = "do not change", choices = [
                ("do not change", _("do not change")), ("off", _("off")), ("on", _("on")) ])
 
@@ -66,7 +66,7 @@ def InitUsageConfig():
 
        def setHDDStandby(configElement):
                for hdd in harddiskmanager.HDDList():
-                       os.system("hdparm -S%s %s" % (configElement.value, hdd[1].getDeviceName()))
+                       hdd[1].setIdleTime(int(configElement.value))
        config.usage.hdd_standby.addNotifier(setHDDStandby)
 
        def set12VOutput(configElement):
index a7724f4..6eeca69 100755 (executable)
@@ -629,11 +629,12 @@ class ConfigClock(ConfigSequence):
        def increment(self):
                # Check if Minutes maxed out
                if self._value[1] == 59:
-                       # Check if Hours not maxed out
+                       # Increment Hour, reset Minutes
                        if self._value[0] < 23:
-                               # Increment Hour, reset Minutes to 0
                                self._value[0] += 1
-                               self._value[1] = 0
+                       else:
+                               self._value[0] = 0
+                       self._value[1] = 0
                else:
                        # Increment Minutes
                        self._value[1] += 1
@@ -643,11 +644,12 @@ class ConfigClock(ConfigSequence):
        def decrement(self):
                # Check if Minutes is minimum
                if self._value[1] == 0:
-                       # Check if Hour is greater than 0
+                       # Decrement Hour, set Minutes to 59
                        if self._value[0] > 0:
-                               # Decrement Hour, set Minutes to 59
                                self._value[0] -= 1
-                               self._value[1] = 59
+                       else:
+                               self._value[0] = 23
+                       self._value[1] = 59
                else:
                        # Decrement Minutes
                        self._value[1] -= 1
index a63562c..69f935e 100644 (file)
@@ -51,7 +51,7 @@ class Test(Screen):
        def mycallback(self, answer):
                print "answer:", answer
                if answer:
-                       raise "test-crash"
+                       raise Exception("test-crash")
                self.close()
        
        def keyLeft(self):
index 19076ba..6d2ddce 100644 (file)
@@ -15,6 +15,7 @@ from Components.NimManager import nimmanager
 from Components.MenuList import MenuList
 from Components.config import ConfigSatlist, ConfigNothing, ConfigSelection, ConfigSubsection, KEY_LEFT, KEY_RIGHT, getConfigListEntry
 from Components.TuneTest import Tuner
+from Tools.Transponder import ConvertToHumanReadable
 
 from time import sleep
 
@@ -354,7 +355,7 @@ class PositionerSetup(Screen):
                self["snr_bar"].update()
                self["ber_bar"].update()
                self["lock_state"].update()
-               transponderdata = self.tuner.getTransponderData()
+               transponderdata = ConvertToHumanReadable(self.tuner.getTransponderData())
                self["frequency_value"].setText(str(transponderdata.get("frequency")))
                self["symbolrate_value"].setText(str(transponderdata.get("symbol_rate")))
                self["fec_value"].setText(str(transponderdata.get("fec_inner")))
@@ -499,29 +500,29 @@ class TunerScreen(ScanSetup):
                                else:
                                        pol = "??"
                                if x[4] == 0:
-                                       fec = "FEC_AUTO"
+                                       fec = "FEC Auto"
                                elif x[4] == 1:
-                                       fec = "FEC_1_2"
+                                       fec = "FEC 1/2"
                                elif x[4] == 2:
-                                       fec = "FEC_2_3"
+                                       fec = "FEC 2/3"
                                elif x[4] == 3:
-                                       fec = "FEC_3_4"
+                                       fec = "FEC 3/4"
                                elif x[4] == 4:
-                                       fec = "FEC_5_6"
+                                       fec = "FEC 5/6"
                                elif x[4] == 5:
-                                       fec = "FEC_7_8"
+                                       fec = "FEC 7/8"
                                elif x[4] == 6:
-                                       fec = "FEC_8_9"
+                                       fec = "FEC 8/9"
                                elif x[4] == 7:
-                                       fec = "FEC_3_5"
+                                       fec = "FEC 3/5"
                                elif x[4] == 8:
-                                       fec = "FEC_4_5"
+                                       fec = "FEC 4/5"
                                elif x[4] == 9:
-                                       fec = "FEC_9_10"
+                                       fec = "FEC 9/10"
                                elif x[4] == 15:
-                                       fec = "FEC_None"
+                                       fec = "FEC None"
                                else:
-                                       fec = "FEC_Unknown"
+                                       fec = "FEC Unknown"
                                tps.append(str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec)
                        tuning.transponder = ConfigSelection(choices=tps)
 
index 048bad9..8e14881 100644 (file)
@@ -168,29 +168,29 @@ class Satfinder(ScanSetup):
                                else:
                                        pol = "??"
                                if x[4] == 0:
-                                       fec = "FEC_AUTO"
+                                       fec = "FEC Auto"
                                elif x[4] == 1:
-                                       fec = "FEC_1_2"
+                                       fec = "FEC 1/2"
                                elif x[4] == 2:
-                                       fec = "FEC_2_3"
+                                       fec = "FEC 2/3"
                                elif x[4] == 3:
-                                       fec = "FEC_3_4"
+                                       fec = "FEC 3/4"
                                elif x[4] == 4:
-                                       fec = "FEC_5_6"
+                                       fec = "FEC 5/6"
                                elif x[4] == 5:
-                                       fec = "FEC_7_8"
+                                       fec = "FEC 7/8"
                                elif x[4] == 6:
-                                       fec = "FEC_8_9"
+                                       fec = "FEC 8/9"
                                elif x[4] == 7:
-                                       fec = "FEC_3_5"
+                                       fec = "FEC 3/5"
                                elif x[4] == 8:
-                                       fec = "FEC_4_5"
+                                       fec = "FEC 4/5"
                                elif x[4] == 9:
-                                       fec = "FEC_9_10"
+                                       fec = "FEC 9/10"
                                elif x[4] == 15:
-                                       fec = "FEC_None"
+                                       fec = "FEC None"
                                else:
-                                       fec = "FEC_Unknown"
+                                       fec = "FEC Unknown"
                                e = str(x[1]) + "," + str(x[2]) + "," + pol + "," + fec
                                if default is None:
                                        default = e
index 02fdf9a..7149504 100644 (file)
@@ -293,6 +293,7 @@ class VideoHardware:
 
                is_widescreen = force_widescreen or config.av.aspect.value in ["16_9", "16_10"]
                is_auto = config.av.aspect.value == "auto"
+               policy2 = "policy" # use main policy
 
                if is_widescreen:
                        if force_widescreen:
@@ -300,6 +301,7 @@ class VideoHardware:
                        else:
                                aspect = {"16_9": "16:9", "16_10": "16:10"}[config.av.aspect.value]
                        policy = {"pillarbox": "panscan", "panscan": "letterbox", "nonlinear": "nonlinear", "scale": "bestfit"}[config.av.policy_43.value]
+                       policy2 = {"letterbox": "letterbox", "panscan": "panscan", "scale": "bestfit"}[config.av.policy_169.value]
                elif is_auto:
                        aspect = "any"
                        policy = "bestfit"
@@ -312,10 +314,14 @@ class VideoHardware:
                else:
                        wss = "auto"
 
-               print "-> setting aspect, policy, wss", aspect, policy, wss
+               print "-> setting aspect, policy, policy2, wss", aspect, policy, policy2, wss
                open("/proc/stb/video/aspect", "w").write(aspect)
                open("/proc/stb/video/policy", "w").write(policy)
                open("/proc/stb/denc/0/wss", "w").write(wss)
+               try:
+                       open("/proc/stb/video/policy2", "w").write(policy2)
+               except IOError:
+                       pass
                self.updateSlowblank()
                self.updateFastblank()
 
index ab7aad7..30bdf79 100644 (file)
@@ -78,6 +78,7 @@ class VideoSetup(Screen, ConfigListScreen):
 
                if force_wide or config.av.aspect.value in ["16_9", "16_10"]:
                        self.list.append(getConfigListEntry(_("Display 4:3 content as"), config.av.policy_43))
+                       self.list.append(getConfigListEntry(_("Display >16:9 content as"), config.av.policy_169))
                elif config.av.aspect.value == "4_3":
                        self.list.append(getConfigListEntry(_("Display 16:9 content as"), config.av.policy_169))
 
index b203b24..ebfbe81 100644 (file)
@@ -76,7 +76,7 @@ def append_when_current_valid(current, menu, args, level = 0):
 class ChannelContextMenu(Screen):
        def __init__(self, session, csel):
                Screen.__init__(self, session)
-               #raise "we need a better summary screen here"
+               #raise Exception("we need a better summary screen here")
                self.csel = csel
                self.bsel = None
 
index 050e350..197594f 100644 (file)
@@ -1449,10 +1449,28 @@ class InfoBarInstantRecord:
 
                recording = RecordTimerEntry(serviceref, begin, end, name, description, eventid, dirname = config.movielist.last_videodir.value)
                recording.dontSave = True
-               recording.autoincrease = True
-               if recording.setAutoincreaseEnd():
-                       self.session.nav.RecordTimer.record(recording)
-                       self.recording.append(recording)
+               
+               if event is None or limitEvent == False:
+                       recording.autoincrease = True
+                       if recording.setAutoincreaseEnd():
+                               self.session.nav.RecordTimer.record(recording)
+                               self.recording.append(recording)
+               else:
+                               simulTimerList = self.session.nav.RecordTimer.record(recording)
+                               if simulTimerList is not None:  # conflict with other recording
+                                       name = simulTimerList[1].name
+                                       name_date = name + strftime(" %c", localtime(simulTimerList[1].begin))
+                                       print "[TIMER] conflicts with", name_date
+                                       recording.autoincrease = True   # start with max available length, then increment
+                                       if recording.setAutoincreaseEnd():
+                                               self.session.nav.RecordTimer.record(recording)
+                                               self.recording.append(recording)
+                                               self.session.open(MessageBox, _("Record time limited due to conflicting timer %s") % name_date, MessageBox.TYPE_INFO)
+                                       else:
+                                               self.session.open(MessageBox, _("Couldn't record due to conflicting timer %s") % name, MessageBox.TYPE_INFO)
+                                       recording.autoincrease = False
+                               else:
+                                       self.recording.append(recording)
 
        def isInstantRecordRunning(self):
                print "self.recording:", self.recording
index 35918b5..1d035b8 100644 (file)
@@ -19,6 +19,13 @@ except:
 setupdom = xml.etree.cElementTree.parse(setupfile)
 setupfile.close()
 
+class SetupError(Exception):
+    def __init__(self, message):
+        self.message = message
+
+    def __str__(self):
+        return self.message
+
 class SetupSummary(Screen):
        skin = """
        <screen position="6,0" size="120,64">
@@ -145,4 +152,4 @@ def getSetupTitle(id):
        for x in xmldata.findall("setup"):
                if x.get("key") == id:
                        return x.get("title", "").encode("UTF-8")
-       raise "unknown setup id '%s'!" % repr(id)
+       raise SetupError("unknown setup id '%s'!" % repr(id))
index 58cece6..bb2d3c7 100644 (file)
@@ -408,7 +408,7 @@ class TimerSanityConflict(Screen):
                                self["actions"].actions.update({"green":self.toggleTimer1})
                                self["key_green"].setText(_("Enable"))
                                self.key_green_choice = self.ENABLE
-                       elif self.timer[0].isRunning() and not timer[0].repeated and self.key_green_choice != self.EMPTY:
+                       elif self.timer[0].isRunning() and not self.timer[0].repeated and self.key_green_choice != self.EMPTY:
                                self.removeAction("green")
                                self["key_green"].setText(" ")
                                self.key_green_choice = self.EMPTY
@@ -428,7 +428,7 @@ class TimerSanityConflict(Screen):
                                        self["actions"].actions.update({"blue":self.toggleTimer2})
                                        self["key_blue"].setText(_("Enable"))
                                        self.key_blue_choice = self.ENABLE
-                               elif self.timer[x].isRunning() and not timer[x].repeated and self.key_blue_choice != self.EMPTY:
+                               elif self.timer[x].isRunning() and not self.timer[x].repeated and self.key_blue_choice != self.EMPTY:
                                        self.removeAction("blue")
                                        self["key_blue"].setText(" ")
                                        self.key_blue_choice = self.EMPTY
index 53e04e5..fff414a 100644 (file)
@@ -14,7 +14,7 @@ def LoadPixmap(path, desktop = None, cached = False):
                alpha = loadPNG(path + "a.png")
                ptr = loadJPG(path + "rgb.jpg", alpha)
        else:
-               raise "neither .png nor .jpg, please fix file extension"
+               raise Exception("neither .png nor .jpg, please fix file extension")
        if ptr and desktop:
                desktop.makeCompatiblePixmap(ptr)
 
index 8493637..bdf1b14 100644 (file)
@@ -288,7 +288,7 @@ PyObject *getBestPlayableServiceReference(const eServiceReference &bouquet_ref,
 PyObject *getBestPlayableServiceReference(const eServiceReference &bouquet_ref, const eServiceReference &ignore, bool simulate=false)
 {
        eStaticServiceDVBBouquetInformation info;
-       if (info.isPlayable(bouquet_ref, ignore))
+       if (info.isPlayable(bouquet_ref, ignore, simulate))
                return New_eServiceReference(info.getPlayableService());
        Py_INCREF(Py_None);
        return Py_None;
index f56d49b..52ec6c1 100644 (file)
@@ -24,6 +24,7 @@ public:
 #ifdef PYTHON_REFCOUNT_DEBUG
        inline ePyObject(PyObject *ob, const char *file, int line);
 #endif
+       inline ePyObject(PyVarObject *ob);
        inline ePyObject(PyDictObject *ob);
        inline ePyObject(PyTupleObject *ob);
        inline ePyObject(PyListObject *ob);
@@ -32,11 +33,13 @@ public:
        operator bool() { return !!m_ob; }
        ePyObject &operator=(const ePyObject &);
        ePyObject &operator=(PyObject *);
+       ePyObject &operator=(PyVarObject *ob) { return operator=((PyObject*)ob); }
        ePyObject &operator=(PyDictObject *ob) { return operator=((PyObject*)ob); }
        ePyObject &operator=(PyTupleObject *ob) { return operator=((PyObject*)ob); }
        ePyObject &operator=(PyListObject *ob) { return operator=((PyObject*)ob); }
        ePyObject &operator=(PyStringObject *ob) { return operator=((PyObject*)ob); }
        operator PyObject*();
+       operator PyVarObject*() { return (PyVarObject*)operator PyVarObject*(); }
        operator PyTupleObject*() { return (PyTupleObject*)operator PyObject*(); }
        operator PyListObject*() { return (PyListObject*)operator PyObject*(); }
        operator PyStringObject*() { return (PyStringObject*)operator PyObject*(); }
@@ -84,6 +87,14 @@ inline ePyObject::ePyObject(PyObject *ob, const char* file, int line)
 }
 #endif
 
+inline ePyObject::ePyObject(PyVarObject *ob)
+       :m_ob((PyObject*)ob)
+#ifdef PYTHON_REFCOUNT_DEBUG
+       ,m_file(0), m_line(0), m_from(0), m_to(0), m_erased(false)
+#endif
+{
+}
+
 inline ePyObject::ePyObject(PyDictObject *ob)
        :m_ob((PyObject*)ob)
 #ifdef PYTHON_REFCOUNT_DEBUG
index 014f94c..8f23bea 100644 (file)
--- a/mytest.py
+++ b/mytest.py
@@ -277,7 +277,7 @@ class Session:
 
        def open(self, screen, *arguments, **kwargs):
                if len(self.dialog_stack) and not self.in_exec:
-                       raise "modal open are allowed only from a screen which is modal!"
+                       raise RuntimeError("modal open are allowed only from a screen which is modal!")
                        # ...unless it's the very first screen.
 
                self.pushCurrent()
diff --git a/skin.py b/skin.py
index eae6ea4..03fe96b 100644 (file)
--- a/skin.py
+++ b/skin.py
@@ -274,7 +274,7 @@ def loadSingleSkinData(desktop, skin, path_prefix):
                                colorNames[name] = parseColor(color)
                                #print "Color:", name, color
                        else:
-                               raise ("need color and name, got %s %s" % (name, color))
+                               raise SkinError("need color and name, got %s %s" % (name, color))
 
        for c in skin.findall("fonts"):
                for font in c.findall("font"):
@@ -335,7 +335,7 @@ def loadSingleSkinData(desktop, skin, path_prefix):
                        try:
                                style.setColor(eWindowStyleSkinned.__dict__["col" + type], color)
                        except:
-                               raise ("Unknown color %s" % (type))
+                               raise SkinError("Unknown color %s" % (type))
                                #pass
 
                        #print "  color:", type, color