epgcache: add possibility to change the default epg cache read/write path
[enigma2.git] / lib / python / Plugins / SystemPlugins / DiseqcTester / plugin.py
old mode 100644 (file)
new mode 100755 (executable)
index 2c8c5c3..5b7edcf
@@ -1,6 +1,7 @@
 from Screens.Satconfig import NimSelection
 from Screens.Screen import Screen
 from Screens.TextBox import TextBox
+from Screens.MessageBox import MessageBox
 
 from Plugins.Plugin import PluginDescriptor
 
@@ -13,7 +14,8 @@ from Components.Sources.List import List
 from Components.Sources.Progress import Progress
 from Components.Sources.StaticText import StaticText
 from Components.ConfigList import ConfigListScreen
-from Components.config import getConfigListEntry, ConfigSelection
+from Components.config import getConfigListEntry, ConfigSelection, ConfigYesNo
+from Components.Harddisk import harddiskmanager
 
 import random
 
@@ -37,7 +39,7 @@ class ResultParser:
                elif self.type == self.TYPE_BYINDEX:
                        self.index = parameter
                        
-       def getTextualResultForIndex(self, index):
+       def getTextualResultForIndex(self, index, logfulltransponders = False):
                text = ""
                text += "%s:\n" % self.getTextualIndexRepresentation(index)
                
@@ -49,8 +51,10 @@ class ResultParser:
                percentsuccessful = round(countsuccessful / float(countall + 0.0001) * 100)
                text += "Tested %d transponders\n%d (%d %%) transponders succeeded\n%d (%d %%) transponders failed\n" % (countall, countsuccessful, percentsuccessful, countfailed, percentfailed)
                reasons = {}
+               completelist = []
                if countfailed > 0:
                        for transponder in failed:
+                               completelist.append({"transponder": transponder[0], "fedata": transponder[-1]})
                                reasons[transponder[2]] = reasons.get(transponder[2], [])
                                reasons[transponder[2]].append(transponder)
                                if transponder[2] == "pids_failed":
@@ -71,16 +75,35 @@ class ResultParser:
                                                text += "No transponder tuned"
                                        text += " ==> " + self.getTextualIndexRepresentation(self.getIndexForTransponder(transponder[0]))
                                        text += "\n"
+                                       if logfulltransponders:
+                                               text += str(transponder[1])
+                                               text += " ==> "
+                                               text += str(transponder[0])
+                                               text += "\n"
+                                       if reason == "pids_failed":
+                                               text += "(tsid, onid): "
+                                               text += str(transponder[3]['real'])
+                                               text += "(read from sat) != "
+                                               text += str(transponder[3]['expected'])
+                                               text += "(read from file)"
+                                               text += "\n"
+                                       text += "\n"
                if countsuccessful > 0:
                        text += "\n"
                        text += "Successfully tuned transponders' previous planes:\n" 
                        for transponder in successful:
+                               completelist.append({"transponder": transponder[0], "fedata": transponder[-1]})
                                if transponder[1] is not None:
                                        text += self.getTextualIndexRepresentation(self.getIndexForTransponder(transponder[1]))
                                else:
                                        text += "No transponder tuned"
                                text += " ==> " + self.getTextualIndexRepresentation(self.getIndexForTransponder(transponder[0]))
                                text += "\n"
+               
+               text += "------------------------------------------------\n"
+               text += "complete transponderlist:\n"
+               for entry in completelist:
+                       text += str(entry["transponder"]) + " -- " + str(entry["fedata"]) + "\n"
                return text
 
        def getTextualResult(self):
@@ -92,6 +115,22 @@ class ResultParser:
                                if index[2] == self.orbpos:
                                        text += self.getTextualResultForIndex(index)
                                        text += "\n-----------------------------------------------------\n"
+               elif self.type == self.TYPE_ALL:
+                       orderedResults = {}
+                       for index in self.results.keys():
+                               orbpos = index[2]
+                               orderedResults[orbpos] = orderedResults.get(orbpos, [])
+                               orderedResults[orbpos].append(index)
+                       ordered_orbpos = orderedResults.keys()
+                       ordered_orbpos.sort()
+                       for orbpos in ordered_orbpos:
+                               text += "\n*****************************************\n"
+                               text += "Orbital position %s:" % str(orbpos)
+                               text += "\n*****************************************\n"
+                               for index in orderedResults[orbpos]:
+                                       text += self.getTextualResultForIndex(index, logfulltransponders = True)
+                                       text += "\n-----------------------------------------------------\n"
+                       
                                
                return text
 
@@ -166,12 +205,13 @@ class DiseqcTester(Screen, TuneTest, ResultParser):
        TEST_TYPE_QUICK = 0
        TEST_TYPE_RANDOM = 1
        TEST_TYPE_COMPLETE = 2
-       def __init__(self, session, feid, test_type = TEST_TYPE_QUICK, loopsfailed = 3, loopssuccessful = 1):
+       def __init__(self, session, feid, test_type = TEST_TYPE_QUICK, loopsfailed = 3, loopssuccessful = 1, log = False):
                Screen.__init__(self, session)
                self.feid = feid
                self.test_type = test_type
                self.loopsfailed = loopsfailed
                self.loopssuccessful = loopssuccessful
+               self.log = log
                
                self["actions"] = NumberActionMap(["SetupActions"],
                {
@@ -241,7 +281,7 @@ class DiseqcTester(Screen, TuneTest, ResultParser):
                for sat in nimmanager.getSatListForNim(self.feid):
                        for transponder in nimmanager.getTransponders(sat[0]):
                                #print transponder
-                               mytransponder = (transponder[1] / 1000, transponder[2] / 1000, transponder[3], transponder[4], transponder[5], sat[0], None, None, transponder[10], transponder[11])
+                               mytransponder = (transponder[1] / 1000, transponder[2] / 1000, transponder[3], transponder[4], transponder[7], sat[0], transponder[5], transponder[6], transponder[8], transponder[9], transponder[10], transponder[11])
                                self.analyseTransponder(mytransponder)
 
        def getIndexForTransponder(self, transponder):
@@ -321,7 +361,39 @@ class DiseqcTester(Screen, TuneTest, ResultParser):
                        self["overall_progress"].setRange(len(self.randomkeys))
                        self["overall_progress"].setValue(self.myindex)
                        return self.randomkeys[0]
-               
+               elif self.test_type == self.TEST_TYPE_COMPLETE:
+                       keys = self.indexlist.keys()
+                       print "keys:", keys
+                       successorindex = {}
+                       for index in keys:
+                               successorindex[index] = []
+                               for otherindex in keys:
+                                       if otherindex != index:
+                                               successorindex[index].append(otherindex)
+                               random.shuffle(successorindex[index])
+                       self.keylist = []
+                       stop = False
+                       currindex = None
+                       while not stop:
+                               if currindex is None or len(successorindex[currindex]) == 0:
+                                       oldindex = currindex
+                                       for index in successorindex.keys():
+                                               if len(successorindex[index]) > 0:
+                                                       currindex = index
+                                                       self.keylist.append(currindex)
+                                                       break
+                                       if currindex == oldindex:
+                                               stop = True
+                               else:
+                                       currindex = successorindex[currindex].pop()
+                                       self.keylist.append(currindex)
+                       print "self.keylist:", self.keylist
+                       self.myindex = 0
+                       self["overall_progress"].setRange(len(self.keylist))
+                       self["overall_progress"].setValue(self.myindex)
+                       return self.keylist[0]
+
+                                       
        # after each index is finished, getNextIndex is called to get the next index to scan 
        def getNextIndex(self):
                # TODO use other function to scan more randomly
@@ -339,6 +411,15 @@ class DiseqcTester(Screen, TuneTest, ResultParser):
                        self.myindex += 1
                        keys = self.randomkeys
                        
+                       self["overall_progress"].setValue(self.myindex)
+                       if self.myindex < len(keys):
+                               return keys[self.myindex]
+                       else:
+                               return None
+               elif self.test_type == self.TEST_TYPE_COMPLETE:
+                       self.myindex += 1
+                       keys = self.keylist
+                       
                        self["overall_progress"].setValue(self.myindex)
                        if self.myindex < len(keys):
                                return keys[self.myindex]
@@ -350,14 +431,50 @@ class DiseqcTester(Screen, TuneTest, ResultParser):
        def getContinueScanning(self):
                if self.test_type == self.TEST_TYPE_QUICK or self.test_type == self.TEST_TYPE_RANDOM:
                        return (self.myindex < len(self.indexlist.keys()))
+               elif self.test_type == self.TEST_TYPE_COMPLETE:
+                       return (self.myindex < len(self.keylist))
                
        def addResult(self, index, status, failedTune, successfullyTune):
-               self.results[index] = self.results.get(index, {"failed": [], "successful": [], "status": None})
+               self.results[index] = self.results.get(index, {"failed": [], "successful": [], "status": None, "internalstatus": None})
                self.resultsstatus[status] = self.resultsstatus.get(status, [])
-               
-               self.results[index]["status"] = status
-               self.results[index]["failed"] = failedTune
-               self.results[index]["successful"] = successfullyTune
+
+               oldstatus = self.results[index]["internalstatus"]
+               if oldstatus is None:
+                       self.results[index]["status"] = status
+               elif oldstatus == "successful":
+                       if status == "failed":
+                               self.results[index]["status"] = "with_errors"
+                       elif status == "successful":
+                               self.results[index]["status"] = oldstatus
+                       elif status == "with_errors":
+                               self.results[index]["status"] = "with_errors"
+                       elif status == "not_tested":
+                               self.results[index]["status"] = oldstatus
+               elif oldstatus == "failed":
+                       if status == "failed":
+                               self.results[index]["status"] = oldstatus
+                       elif status == "successful":
+                               self.results[index]["status"] = "with_errors"
+                       elif status == "with_errors":
+                               self.results[index]["status"] = "with_errors"
+                       elif status == "not_tested":
+                               self.results[index]["status"] = oldstatus
+               elif oldstatus == "with_errors":
+                       if status == "failed":
+                               self.results[index]["status"] = oldstatus
+                       elif status == "successful":
+                               self.results[index]["status"] = oldstatus
+                       elif status == "with_errors":
+                               self.results[index]["status"] = oldstatus
+                       elif status == "not_tested":
+                               self.results[index]["status"] = oldstatus
+               elif oldstatus == "not_tested":
+                       self.results[index]["status"] = status
+                       
+               if self.results[index]["status"] != "working":
+                       self.results[index]["internalstatus"] = self.results[index]["status"] 
+               self.results[index]["failed"] = failedTune + self.results[index]["failed"]
+               self.results[index]["successful"] = successfullyTune + self.results[index]["successful"]
                
                self.resultsstatus[status].append(index)
        
@@ -366,7 +483,7 @@ class DiseqcTester(Screen, TuneTest, ResultParser):
                TuneTest.finishedChecking(self)
 
                if not self.results.has_key(self.currentlyTestedIndex):
-                       self.results[self.currentlyTestedIndex] = {"failed": [], "successful": [], "status": None}
+                       self.results[self.currentlyTestedIndex] = {"failed": [], "successful": [], "status": None, "internalstatus": None}
                
                if len(self.failedTune) > 0 and len(self.successfullyTune) > 0:
                        self.changeProgressListStatus(self.currentlyTestedIndex, "with errors")
@@ -378,11 +495,13 @@ class DiseqcTester(Screen, TuneTest, ResultParser):
                        self.addResult(self.currentlyTestedIndex, "untestable", self.failedTune, self.successfullyTune)
                elif len(self.failedTune) > 0:
                        self.changeProgressListStatus(self.currentlyTestedIndex, "failed")
-                       self["failed_counter"].setText(str(int(self["failed_counter"].getText()) + len(self.failedTune)))
+                       #self["failed_counter"].setText(str(int(self["failed_counter"].getText()) + len(self.failedTune)))
+                       self["failed_counter"].setText(str(int(self["failed_counter"].getText()) + 1))
                        self.addResult(self.currentlyTestedIndex, "failed", self.failedTune, self.successfullyTune)
                else:
                        self.changeProgressListStatus(self.currentlyTestedIndex, "successful")
-                       self["succeeded_counter"].setText(str(int(self["succeeded_counter"].getText()) + len(self.successfullyTune)))
+                       #self["succeeded_counter"].setText(str(int(self["succeeded_counter"].getText()) + len(self.successfullyTune)))
+                       self["succeeded_counter"].setText(str(int(self["succeeded_counter"].getText()) + 1))
                        self.addResult(self.currentlyTestedIndex, "successful", self.failedTune, self.successfullyTune)
                        
                        
@@ -401,6 +520,12 @@ class DiseqcTester(Screen, TuneTest, ResultParser):
                        self["progress_list"].setIndex(0)
                        print "results:", self.results
                        print "resultsstatus:", self.resultsstatus
+                       if self.log:
+                               file = open("/media/hdd/diseqctester.log", "w")
+                               self.setResultType(ResultParser.TYPE_ALL)
+                               file.write(self.getTextualResult())
+                               file.close()
+                               self.session.open(MessageBox, text=_("The results have been written to %s.") % "/media/hdd/diseqctester.log", type = MessageBox.TYPE_INFO)
 
        def go(self):
                self.running = True
@@ -426,6 +551,7 @@ class DiseqcTester(Screen, TuneTest, ResultParser):
                        #self.setResultParameter(index[2])
                        self.setResultType(ResultParser.TYPE_BYINDEX)
                        self.setResultParameter(index)
+                       #self.setResultType(ResultParser.TYPE_ALL)
                        self.session.open(TextBox, self.getTextualResult())
        
        def selectionChanged(self):
@@ -434,26 +560,36 @@ class DiseqcTester(Screen, TuneTest, ResultParser):
                        self["CmdText"].setText(_("Press OK to get further details for %s") % str(self["progress_list"].getCurrent()[1]))
 
 class DiseqcTesterTestTypeSelection(Screen, ConfigListScreen):
-       skin = """<screen position="80,95" size="560,412" title="DiSEqC Tester Test Settings">
-               <widget name="config" position="10,10" size="540,402" scrollbarMode="showOnDemand" />
-       </screen>
-       """
+
        def __init__(self, session, feid):
                Screen.__init__(self, session)
+               # for the skin: first try MediaPlayerSettings, then Setup, this allows individual skinning
+               self.skinName = ["DiseqcTesterTestTypeSelection", "Setup" ]
+               self.setup_title = _("DiSEqC-Tester settings")
+               self.onChangedEntry = [ ]
                self.feid = feid
                
                self.list = []
-               ConfigListScreen.__init__(self, self.list)
+               ConfigListScreen.__init__(self, self.list, session = self.session, on_change = self.changedEntry)
                
                self["actions"] = ActionMap(["SetupActions"],
-               {
-                       "cancel": self.keyCancel
-               }, -2)
+                       {
+                               "cancel": self.keyCancel,
+                               "save": self.keyOK,
+                               "ok": self.keyOK,
+                       }, -2)
+
+               self["key_red"] = StaticText(_("Cancel"))
+               self["key_green"] = StaticText(_("OK"))
                
                self.createSetup()
-               
+               self.onLayoutFinish.append(self.layoutFinished)
+
+       def layoutFinished(self):
+               self.setTitle(self.setup_title)
+
        def createSetup(self):
-               self.testtype = ConfigSelection(choices={"quick": _("Quick"), "random": _("Random")}, default = "quick")
+               self.testtype = ConfigSelection(choices={"quick": _("Quick"), "random": _("Random"), "complete": _("Complete")}, default = "quick")
                self.testtypeEntry = getConfigListEntry(_("Test Type"), self.testtype)
                self.list.append(self.testtypeEntry)
                
@@ -465,6 +601,11 @@ class DiseqcTesterTestTypeSelection(Screen, ConfigListScreen):
                self.loopssuccessfulEntry = getConfigListEntry(_("Stop testing plane after # successful transponders"), self.loopssuccessful)
                self.list.append(self.loopssuccessfulEntry)
                
+               self.log = ConfigYesNo(False)
+               if harddiskmanager.HDDCount() > 0:
+                       self.logEntry = getConfigListEntry(_("Log results to harddisk"), self.log)
+                       self.list.append(self.logEntry)
+                                       
                self["config"].list = self.list
                self["config"].l.setList(self.list)
                
@@ -477,11 +618,26 @@ class DiseqcTesterTestTypeSelection(Screen, ConfigListScreen):
                        testtype = DiseqcTester.TEST_TYPE_RANDOM
                elif self.testtype.getValue() == "complete":
                        testtype = DiseqcTester.TEST_TYPE_COMPLETE
-               self.session.open(DiseqcTester, feid = self.feid, test_type = testtype, loopsfailed = int(self.loopsfailed.value), loopssuccessful = int(self.loopssuccessful.value))
+               self.session.open(DiseqcTester, feid = self.feid, test_type = testtype, loopsfailed = int(self.loopsfailed.value), loopssuccessful = int(self.loopssuccessful.value), log = self.log.value)
        
        def keyCancel(self):
                self.close()
 
+       # for summary:
+       def changedEntry(self):
+               for x in self.onChangedEntry:
+                       x()
+
+       def getCurrentEntry(self):
+               return self["config"].getCurrent()[0]
+
+       def getCurrentValue(self):
+               return str(self["config"].getCurrent()[1].getText())
+
+       def createSummary(self):
+               from Screens.Setup import SetupSummary
+               return SetupSummary
+
 class DiseqcTesterNimSelection(NimSelection):
        skin = """
                <screen position="160,123" size="400,330" title="Choose Tuner">
@@ -508,7 +664,7 @@ class DiseqcTesterNimSelection(NimSelection):
        def showNim(self, nim):
                nimConfig = nimmanager.getNimConfig(nim.slot)
                if nim.isCompatible("DVB-S"):
-                       if nimConfig.configMode.value in ["loopthrough", "equal", "satposdepends", "nothing"]:
+                       if nimConfig.configMode.value in ("loopthrough", "equal", "satposdepends", "nothing"):
                                return False
                        if nimConfig.configMode.value == "simple":
                                if nimConfig.diseqcMode.value == "positioner":