From f54997fce98f79977df7cb9bd938b91376e4cec7 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 11:01:08 +0200 Subject: [PATCH 001/401] [VideoMode] - remove unused About import --- lib/python/Screens/VideoMode.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/python/Screens/VideoMode.py b/lib/python/Screens/VideoMode.py index f3b735d0f5e..8a8a642327a 100644 --- a/lib/python/Screens/VideoMode.py +++ b/lib/python/Screens/VideoMode.py @@ -4,7 +4,6 @@ from Screens.Screen import Screen from Screens.ChannelSelection import FLAG_IS_DEDICATED_3D -from Components.About import about from Components.ActionMap import ActionMap from Components.SystemInfo import SystemInfo from Components.ConfigList import ConfigListScreen From 7501402b3ccd3bbbd2d3865bd517d9396b27c537 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 11:13:39 +0200 Subject: [PATCH 002/401] [UserInterfacePositioner] - remove unused imports ConfigText & Pixmap --- lib/python/Screens/UserInterfacePositioner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Screens/UserInterfacePositioner.py b/lib/python/Screens/UserInterfacePositioner.py index e97f495fe0c..58ac9772874 100644 --- a/lib/python/Screens/UserInterfacePositioner.py +++ b/lib/python/Screens/UserInterfacePositioner.py @@ -1,7 +1,7 @@ from Screens.MessageBox import MessageBox from Screens.Screen import Screen from Components.ActionMap import ActionMap -from Components.config import config, configfile, ConfigSubsection, getConfigListEntry, ConfigSelectionNumber, ConfigSelection, ConfigSlider, ConfigYesNo, NoSave, ConfigNumber, ConfigText +from Components.config import config, configfile, ConfigSubsection, getConfigListEntry, ConfigSelectionNumber, ConfigSelection, ConfigSlider, ConfigYesNo, NoSave, ConfigNumber from Components.ConfigList import ConfigListScreen from Components.SystemInfo import SystemInfo from Components.Sources.StaticText import StaticText From 0135105ca8f9732d24952c3f69e09a78f2e8465a Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 11:16:37 +0200 Subject: [PATCH 003/401] [UserInterfacePositioner] - remove unused import ConfigSubsection --- lib/python/Screens/UserInterfacePositioner.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Screens/UserInterfacePositioner.py b/lib/python/Screens/UserInterfacePositioner.py index 58ac9772874..743db44bb2b 100644 --- a/lib/python/Screens/UserInterfacePositioner.py +++ b/lib/python/Screens/UserInterfacePositioner.py @@ -1,7 +1,7 @@ from Screens.MessageBox import MessageBox from Screens.Screen import Screen from Components.ActionMap import ActionMap -from Components.config import config, configfile, ConfigSubsection, getConfigListEntry, ConfigSelectionNumber, ConfigSelection, ConfigSlider, ConfigYesNo, NoSave, ConfigNumber +from Components.config import config, configfile, getConfigListEntry, ConfigSelectionNumber, ConfigSelection, ConfigSlider, ConfigYesNo, NoSave, ConfigNumber from Components.ConfigList import ConfigListScreen from Components.SystemInfo import SystemInfo from Components.Sources.StaticText import StaticText From df0d06953634d54eaee389ee51b800f1b3d92ceb Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 11:19:44 +0200 Subject: [PATCH 004/401] [TimerEntry] - remove unused Screen import --- lib/python/Screens/TimerEntry.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/python/Screens/TimerEntry.py b/lib/python/Screens/TimerEntry.py index 8f7cb749301..fc18eb09f53 100644 --- a/lib/python/Screens/TimerEntry.py +++ b/lib/python/Screens/TimerEntry.py @@ -3,7 +3,6 @@ from enigma import eEPGCache -from Screens.Screen import Screen import Screens.ChannelSelection from ServiceReference import ServiceReference from Components.config import config, ConfigSelection, ConfigText, ConfigYesNo From e02a0ba2fe53699f157a05387a45dd4e301f2453 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 11:21:26 +0200 Subject: [PATCH 005/401] [TimerEdit] - silence PEP8 --- lib/python/Screens/TimerEdit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Screens/TimerEdit.py b/lib/python/Screens/TimerEdit.py index 019f12cb35a..7a6856a5952 100644 --- a/lib/python/Screens/TimerEdit.py +++ b/lib/python/Screens/TimerEdit.py @@ -13,7 +13,7 @@ from Screens.ChoiceBox import ChoiceBox from Screens.MessageBox import MessageBox from Screens.ParentalControlSetup import ProtectedScreen -from Screens.InputBox import PinInput +from Screens.InputBox import PinInput # noqa: F401 from ServiceReference import ServiceReference from Screens.TimerEntry import TimerEntry, TimerLog from Screens.Setup import Setup From e792af9bb6bdfba085fd938a65d1be9c308516c4 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 11:22:20 +0200 Subject: [PATCH 006/401] [TaskView] - silence PEP8 --- lib/python/Screens/TaskView.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Screens/TaskView.py b/lib/python/Screens/TaskView.py index e906ec0d788..1620dc71a69 100644 --- a/lib/python/Screens/TaskView.py +++ b/lib/python/Screens/TaskView.py @@ -1,5 +1,5 @@ from Components.ActionMap import ActionMap -from Components.config import config, ConfigSubsection, ConfigSelection, getConfigListEntry +from Components.config import config, ConfigSubsection, ConfigSelection, getConfigListEntry # noqa: F401 from Components.ConfigList import ConfigListScreen from Components.Sources.Progress import Progress from Components.Sources.StaticText import StaticText From 63caa218af9ba18df81333ed08102a52dcf0b10e Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 11:29:41 +0200 Subject: [PATCH 007/401] [Standby] - consolidate imports, fix over ident & PEP8 --- lib/python/Screens/Standby.py | 46 ++++++++++++++++------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/lib/python/Screens/Standby.py b/lib/python/Screens/Standby.py index f43b6ff1827..c4511cbd1f4 100644 --- a/lib/python/Screens/Standby.py +++ b/lib/python/Screens/Standby.py @@ -1,7 +1,7 @@ from os import path from time import time -from enigma import eDVBVolumecontrol, eTimer, eDVBLocalTimeHandler, eServiceReference, eStreamServer +from enigma import eDVBVolumecontrol, eTimer, eDVBLocalTimeHandler, eServiceReference, eStreamServer, iRecordableService, quitMainloop from boxbranding import getMachineBrand, getMachineName, getBoxType, getBrandOEM from Components.ActionMap import ActionMap @@ -11,9 +11,11 @@ import Components.ParentalControl from Components.SystemInfo import SystemInfo from Components.Sources.StreamService import StreamServiceList +from Components.Task import job_manager from GlobalActions import globalActionMap import Screens.InfoBar from Screens.Screen import Screen, ScreenSummary +from Screens.MessageBox import MessageBox import Tools.Notifications inStandby = None @@ -196,12 +198,6 @@ class StandbySummary(ScreenSummary): """ -from enigma import quitMainloop, iRecordableService -from Screens.MessageBox import MessageBox -from time import time -from Components.Task import job_manager - - class QuitMainloopScreen(Screen): def __init__(self, session, retvalue=1): self.skin = """ @@ -301,23 +297,23 @@ def getRecordEvent(self, recservice, event): self.stopTimer() def sendCEC(self): - print("[Standby][sendCEC] entered ") - import struct - from enigma import eHdmiCEC - physicaladdress = eHdmiCEC.getInstance().getPhysicalAddress() - msgaddress = 0x0f # use broadcast for active source command - cmd0 = 0x9d # 157 sourceinactive - data0 = struct.pack("BB", int(physicaladdress // 256), int(physicaladdress % 256)) - data0 = data0.decode("UTF-8", "ignore") - cmd1 = 0x44 # 68 keypoweroff - data1 = struct.pack("B", 0x6c) - data1 = data1.decode("UTF-8", "ignore") - cmd2 = 0x36 # 54 standby - data2 = "" - eHdmiCEC.getInstance().sendMessage(msgaddress, cmd0, data0, len(data0)) - eHdmiCEC.getInstance().sendMessage(msgaddress, cmd1, data1, len(data1)) - eHdmiCEC.getInstance().sendMessage(msgaddress, cmd2, data2, len(data2)) - print("[Standby][sendCEC] departed ") + print("[Standby][sendCEC] entered ") + import struct + from enigma import eHdmiCEC # noqa: E402 + physicaladdress = eHdmiCEC.getInstance().getPhysicalAddress() + msgaddress = 0x0f # use broadcast for active source command + cmd0 = 0x9d # 157 sourceinactive + data0 = struct.pack("BB", int(physicaladdress // 256), int(physicaladdress % 256)) + data0 = data0.decode("UTF-8", "ignore") + cmd1 = 0x44 # 68 keypoweroff + data1 = struct.pack("B", 0x6c) + data1 = data1.decode("UTF-8", "ignore") + cmd2 = 0x36 # 54 standby + data2 = "" + eHdmiCEC.getInstance().sendMessage(msgaddress, cmd0, data0, len(data0)) + eHdmiCEC.getInstance().sendMessage(msgaddress, cmd1, data1, len(data1)) + eHdmiCEC.getInstance().sendMessage(msgaddress, cmd2, data2, len(data2)) + print("[Standby][sendCEC] departed ") def close(self, value): if self.connected: @@ -339,7 +335,7 @@ def close(self, value): # set LCDminiTV off / fix a deep-standby-crash on some boxes / gb4k print("[Standby] LCDminiTV off") setLCDMiniTVMode("0") - if getBoxType() == "vusolo4k": #workaround for white display flash + if getBoxType() == "vusolo4k": # workaround for white display flash f = open("/proc/stb/fp/oled_brightness", "w") f.write("0") f.close() From a5fb265eaab8cce6bd033dfb53f35b7d7510da41 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 11:33:08 +0200 Subject: [PATCH 008/401] [SoftwareUpdate] - silence PEP8 --- lib/python/Screens/SoftwareUpdate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Screens/SoftwareUpdate.py b/lib/python/Screens/SoftwareUpdate.py index 8aaa463fffb..09925b638c1 100644 --- a/lib/python/Screens/SoftwareUpdate.py +++ b/lib/python/Screens/SoftwareUpdate.py @@ -393,7 +393,7 @@ def doSettingsBackup(self): self.showJobView(job) def doImageBackup(self): - backup = None + backup = None # noqa: F841 from Plugins.SystemPlugins.ViX.ImageManager import ImageBackup self.ImageBackup = ImageBackup(self.session, True) Components.Task.job_manager.AddJob(self.ImageBackup.createBackupJob()) From da6cdbd4a4a13413c3b6e3ca37454f41ee0ee70d Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 11:34:33 +0200 Subject: [PATCH 009/401] [Screen] - silence PEP8 --- lib/python/Screens/Screen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Screens/Screen.py b/lib/python/Screens/Screen.py index 48593471f16..45fa50592b8 100644 --- a/lib/python/Screens/Screen.py +++ b/lib/python/Screens/Screen.py @@ -1,6 +1,6 @@ from enigma import eRCInput, eTimer, eWindow # , getDesktop -from skin import GUI_SKIN_ID, applyAllAttributes +from skin import GUI_SKIN_ID, applyAllAttributes # noqa: F401 GUI_SKIN_ID used by debug from Components.config import config from Components.GUIComponent import GUIComponent from Components.Sources.Source import Source From 7280b62a2d5b0f604555075bb3a87d821a67fe49 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 11:38:12 +0200 Subject: [PATCH 010/401] [ParentalControlSetup] - silence PEP8 --- lib/python/Screens/ParentalControlSetup.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/python/Screens/ParentalControlSetup.py b/lib/python/Screens/ParentalControlSetup.py index 167c2e2d917..8dc9776d8ba 100644 --- a/lib/python/Screens/ParentalControlSetup.py +++ b/lib/python/Screens/ParentalControlSetup.py @@ -1,8 +1,8 @@ -from operator import itemgetter +from operator import itemgetter # noqa: F401 -from Components.config import config, getConfigListEntry, ConfigNothing, NoSave, ConfigPIN, configfile +from Components.config import config, getConfigListEntry, ConfigNothing, NoSave, ConfigPIN, configfile # noqa: F401 from Components.ConfigList import ConfigListScreen -from Screens.ChoiceBox import ChoiceBox +from Screens.ChoiceBox import ChoiceBox # noqa: F401 from Screens.InputBox import PinInput from Screens.MessageBox import MessageBox from Screens.Screen import Screen From d9365c784572bcf44ed8ad7000276c3eeb2a04dd Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 11:52:30 +0200 Subject: [PATCH 011/401] [MovieSelection] - silence some PEP8 --- lib/python/Screens/MovieSelection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Screens/MovieSelection.py b/lib/python/Screens/MovieSelection.py index 6206d5b3eb6..4c76b6f04a8 100644 --- a/lib/python/Screens/MovieSelection.py +++ b/lib/python/Screens/MovieSelection.py @@ -2084,7 +2084,7 @@ def renameCallback(self, renameList, newname): else: metafile = open(meta, "r+") sid = metafile.readline() - oldtitle = metafile.readline() #noqa: F841 # local variable 'oldtitle' is assigned to but never used. Must be to skip a line. + oldtitle = metafile.readline() # noqa: F841 # local variable 'oldtitle' is assigned to but never used. Must be to skip a line. rest = metafile.read() metafile.seek(0) metafile.write("%s%s\n%s" % (sid, newname, rest)) From 28e81b19938476243134195ca0fde5c2c8ab4a95 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 11:56:59 +0200 Subject: [PATCH 012/401] [VieoFinetune] - replace variable l with offset, silence some PEP8 --- .../SystemPlugins/VideoTune/VideoFinetune.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/lib/python/Plugins/SystemPlugins/VideoTune/VideoFinetune.py b/lib/python/Plugins/SystemPlugins/VideoTune/VideoFinetune.py index c31479e4470..8b0c9b56cbf 100644 --- a/lib/python/Plugins/SystemPlugins/VideoTune/VideoFinetune.py +++ b/lib/python/Plugins/SystemPlugins/VideoTune/VideoFinetune.py @@ -140,7 +140,7 @@ def testpic_brightness(self): xres, yres = getDesktop(0).size().width(), getDesktop(0).size().height() - bbw, bbh = xres // 192, yres // 192 + # bbw, bbh = xres // 192, yres // 192 c.fill(0, 0, xres, yres, RGB(0, 0, 0)) for i in range(15): @@ -178,11 +178,9 @@ def testpic_contrast(self): xres, yres = getDesktop(0).size().width(), getDesktop(0).size().height() - bbw, bbh = xres // 192, yres // 192 + # bbw, bbh = xres // 192, yres // 192 c.fill(0, 0, xres, yres, RGB(0, 0, 0)) - bbw = xres // 192 - bbh = yres // 192 c.fill(0, 0, xres, yres, RGB(255, 255, 255)) for i in range(15): @@ -319,18 +317,18 @@ def testpic_gamma(self): for y in range(0, height, 4): c.fill(offset_x, offset_y + y, width // 2, 2, RGB(255, 255, 255)) - l = 0 + offset = 0 fnt = gFont("Regular", height // 14) import math for i in range(1, 15): y = i * height // 14 - h = y - l + h = y - offset gamma = 0.6 + i * 0.2 col = int(math.pow(.5, 1.0 / gamma) * 256.0) - c.fill(offset_x + width // 2, offset_y + l, width // 2, h, RGB(col, col, col)) + c.fill(offset_x + width // 2, offset_y + offset, width // 2, h, RGB(col, col, col)) - c.writeText(offset_x + width // 2, offset_y + l, width // 2, h, RGB(0, 0, 0), RGB(col, col, col), fnt, "%1.2f" % gamma, RT_WRAP | RT_HALIGN_RIGHT) - l = y + c.writeText(offset_x + width // 2, offset_y + offset, width // 2, h, RGB(0, 0, 0), RGB(col, col, col), fnt, "%1.2f" % gamma, RT_WRAP | RT_HALIGN_RIGHT) + offset = y c.flush() From 3b7d80dd8ff2bf7c71edc44c6c718c11cc85b87a Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 11:58:16 +0200 Subject: [PATCH 013/401] [VideoEnhancement] - silence PEP8 --- lib/python/Plugins/SystemPlugins/VideoEnhancement/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Plugins/SystemPlugins/VideoEnhancement/plugin.py b/lib/python/Plugins/SystemPlugins/VideoEnhancement/plugin.py index f176792100b..c73bdf70ca9 100644 --- a/lib/python/Plugins/SystemPlugins/VideoEnhancement/plugin.py +++ b/lib/python/Plugins/SystemPlugins/VideoEnhancement/plugin.py @@ -11,7 +11,7 @@ from Screens.MessageBox import MessageBox from Screens.Screen import Screen -from . import VideoEnhancement +from . import VideoEnhancement # noqa: F401 class VideoEnhancementSetup(ConfigListScreen, Screen): From 0a5e00d715c4ed16cde0e3736c5eb729c2dd2ff2 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 11:59:59 +0200 Subject: [PATCH 014/401] [VideoEnhancement] - silence PEP8 on variable x --- .../Plugins/SystemPlugins/VideoEnhancement/VideoEnhancement.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Plugins/SystemPlugins/VideoEnhancement/VideoEnhancement.py b/lib/python/Plugins/SystemPlugins/VideoEnhancement/VideoEnhancement.py index 80c15bb1e03..3725fc17919 100644 --- a/lib/python/Plugins/SystemPlugins/VideoEnhancement/VideoEnhancement.py +++ b/lib/python/Plugins/SystemPlugins/VideoEnhancement/VideoEnhancement.py @@ -267,7 +267,7 @@ def setDynamic_contrast(config): config.pep.dynamic_contrast = NoSave(ConfigNothing()) try: - x = config.av.scaler_sharpness + x = config.av.scaler_sharpness # noqa: F841 except NameError: if os_path.exists("/proc/stb/vmpeg/0/pep_scaler_sharpness"): def setScaler_sharpness(config): From cd31afa03f52f91f9cef55097b7c5eff4575a5d3 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 12:01:44 +0200 Subject: [PATCH 015/401] [ViX][ui] - silence PEP8 --- lib/python/Plugins/SystemPlugins/ViX/ui.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Plugins/SystemPlugins/ViX/ui.py b/lib/python/Plugins/SystemPlugins/ViX/ui.py index 8163201059c..f7cee81dcd1 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/ui.py +++ b/lib/python/Plugins/SystemPlugins/ViX/ui.py @@ -46,7 +46,7 @@ class VIXMenu(Screen, ProtectedScreen): 22, # fonts 300, # itemHeight 5, 360, 600, 50, 22, # status - ] + ] # noqa: E124 def __init__(self, session, args=0): Screen.__init__(self, session) @@ -81,7 +81,7 @@ def __init__(self, session, args=0): "7": self.go, "8": self.go, "9": self.go, - }, -1) + }, -1) # noqa: E123 self.onLayoutFinish.append(self.layoutFinished) self.onChangedEntry = [] self["menu"].onSelectionChanged.append(self.selectionChanged) From c5ac1a9f8be50ec936a86767e666d097c322bf9d Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 12:04:55 +0200 Subject: [PATCH 016/401] [ViX][SwapManager] - silence PEP8 --- .../Plugins/SystemPlugins/ViX/SwapManager.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/lib/python/Plugins/SystemPlugins/ViX/SwapManager.py b/lib/python/Plugins/SystemPlugins/ViX/SwapManager.py index 01e781f5350..b050995f607 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/SwapManager.py +++ b/lib/python/Plugins/SystemPlugins/ViX/SwapManager.py @@ -60,9 +60,7 @@ def startSwap2(self, result=None, retval=None, extra_args=None): # lets find sw devicelist = [] for p in harddiskmanager.getMountedPartitions(): d = path.normpath(p.mountpoint) - if (path.exists(p.mountpoint) and p.mountpoint != "/" - and not p.mountpoint.startswith("/media/net/") - and not p.mountpoint.startswith("/media/autofs/")): + if (path.exists(p.mountpoint) and p.mountpoint != "/" and not p.mountpoint.startswith("/media/net/") and not p.mountpoint.startswith("/media/autofs/")): devicelist.append((p.description, d)) if len(devicelist): for device in devicelist: @@ -127,7 +125,7 @@ class VIXSwap(Screen): 160, 150, 220, 30, 20, 160, 200, 100, 30, 20, 160, 200, 100, 30, 20, - ] + ] # noqa: E124 def __init__(self, session): Screen.__init__(self, session) @@ -348,12 +346,12 @@ def createDel2(self, result, retval, extra_args=None): self.Console.ePopen("rm " + self.swap_Fname, self.createDel3) def createDel3(self, result, retval, extra_args=None): - print("[SwapManager][createDel3] delete swap, retval, result", retval, " ", result) - if config.swapmanager.swapautostart.value: - config.swapmanager.swapautostart.setValue(False) - config.swapmanager.swapautostart.save() - configfile.save() - self.updateSwap() + print("[SwapManager][createDel3] delete swap, retval, result", retval, " ", result) + if config.swapmanager.swapautostart.value: + config.swapmanager.swapautostart.setValue(False) + config.swapmanager.swapautostart.save() + configfile.save() + self.updateSwap() def doCreateSwap(self): supported_filesystems = frozenset(("ext4", "ext3")) From f66aa256c01318bbbf47c11d8f34335e6948f28f Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 12:09:50 +0200 Subject: [PATCH 017/401] [ViX][SoftcamManager] - silence some PEP8 --- .../Plugins/SystemPlugins/ViX/SoftcamManager.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/python/Plugins/SystemPlugins/ViX/SoftcamManager.py b/lib/python/Plugins/SystemPlugins/ViX/SoftcamManager.py index a562f68b9c6..c05f1dd83e9 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/SoftcamManager.py +++ b/lib/python/Plugins/SystemPlugins/ViX/SoftcamManager.py @@ -73,7 +73,7 @@ def spinnerSkin(skinName): """, 484, 150, 460, 60, 20, - ] + ] # noqa: E124 class VIXSoftcamManager(Screen): @@ -113,7 +113,7 @@ class VIXSoftcamManager(Screen): 40, 215, 170, 30, 22, # lab2 225, 216, 240, 100, 20, # activecam 25, - ] + ] # noqa: E124 def __init__(self, session): Screen.__init__(self, session) @@ -570,7 +570,7 @@ class VIXSoftcamLog(Screen): """, 560, 400, 0, 0, 560, 400, 14, - ] + ] # noqa: E124 def __init__(self, session): self.session = session @@ -584,14 +584,13 @@ def __init__(self, session): else: softcamlog = "" self["list"] = ScrollLabel(str(softcamlog)) - self["setupActions"] = ActionMap( - ["SetupActions", "ColorActions", "DirectionActions"], - { + self["setupActions"] = ActionMap(["SetupActions", "ColorActions", "DirectionActions"], + { "cancel": self.cancel, "ok": self.cancel, "up": self["list"].pageUp, "down": self["list"].pageDown - }, -2) + }, -2) # noqa: E123 def cancel(self): self.close() From 1881cd3dd22120a1f5a9303c9d79eb7637eb6073 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 12:12:07 +0200 Subject: [PATCH 018/401] [ViX][RestoreWizard] - silence some PEP8 --- lib/python/Plugins/SystemPlugins/ViX/RestoreWizard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Plugins/SystemPlugins/ViX/RestoreWizard.py b/lib/python/Plugins/SystemPlugins/ViX/RestoreWizard.py index fdfe977768f..864746f3b0b 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/RestoreWizard.py +++ b/lib/python/Plugins/SystemPlugins/ViX/RestoreWizard.py @@ -328,7 +328,7 @@ def doRestorePlugins2(self, result, retval, extra_args): devmounts = [] self.plugfile = self.plugfiles[3] for dir in ["/media/%s/%s" % (media, self.plugfile) for media in listdir("/media/") if path.isdir(path.join("/media/", media)) and path.exists("/media/%s/%s" % (media, self.plugfile))]: - if media not in ("autofs", "net"): + if media not in ("autofs", "net"): # noqa: F821 devmounts.append(dir) if len(devmounts): for x in devmounts: From e2f9d6cb536c48bd7db7fa6ecb26fddef56e2d30 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 12:13:20 +0200 Subject: [PATCH 019/401] [ViX][MountManager] - silence some PEP8 --- lib/python/Plugins/SystemPlugins/ViX/MountManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Plugins/SystemPlugins/ViX/MountManager.py b/lib/python/Plugins/SystemPlugins/ViX/MountManager.py index 6ec967a0ae8..011b79328a8 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/MountManager.py +++ b/lib/python/Plugins/SystemPlugins/ViX/MountManager.py @@ -226,7 +226,7 @@ class VIXDevicesPanel(Screen): 140, 0, 140, 40, 20, 280, 0, 140, 40, 20, 420, 0, 140, 40, 20, - ] + ] # noqa: E124 def __init__(self, session): Screen.__init__(self, session) @@ -377,7 +377,7 @@ class DeviceMountSetup(Screen, ConfigListScreen): 140, 0, 140, 40, 20, 0, 50, 560, 275, 26, 20, # config 0, 365, 560, 20, 18, - ] + ] # noqa: E124 def __init__(self, session): Screen.__init__(self, session) From ba7e3e1ca71ceb749587ceccf741c17aac828c28 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 12:15:12 +0200 Subject: [PATCH 020/401] [ViX][ImageManager] - silence some PEP8 --- lib/python/Plugins/SystemPlugins/ViX/ImageManager.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/python/Plugins/SystemPlugins/ViX/ImageManager.py b/lib/python/Plugins/SystemPlugins/ViX/ImageManager.py index c4e76d5c187..4d60979a26f 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/ImageManager.py +++ b/lib/python/Plugins/SystemPlugins/ViX/ImageManager.py @@ -165,7 +165,7 @@ class VIXImageManager(Screen): 10, 105, 540, 260, 20, # list 10, 370, 400, 30, 20, # backupstatus 26, - ] + ] # noqa: E124 def __init__(self, session): Screen.__init__(self, session) @@ -892,7 +892,7 @@ class ImageBackup(Screen): 0, 50, 560, 50, 18, # lab1 10, 105, 540, 260, 20, # list 26, - ] + ] # noqa: E124 def __init__(self, session, updatebackup=False): Screen.__init__(self, session) @@ -1588,7 +1588,7 @@ class ImageManagerDownload(Screen): 0, 50, 560, 50, 18, # lab1 10, 105, 540, 260, 20, # list 26, - ] + ] # noqa: E124 def __init__(self, session, BackupDirectory, imagefeed): Screen.__init__(self, session) From 7d7d7cc7940e1baf6eb7ba8bebc91c00298aa47d Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 12:16:02 +0200 Subject: [PATCH 021/401] [ViX][IPKInstaller] - silence some PEP8 --- lib/python/Plugins/SystemPlugins/ViX/IPKInstaller.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Plugins/SystemPlugins/ViX/IPKInstaller.py b/lib/python/Plugins/SystemPlugins/ViX/IPKInstaller.py index 1b5b03dceea..e9d8fd72994 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/IPKInstaller.py +++ b/lib/python/Plugins/SystemPlugins/ViX/IPKInstaller.py @@ -40,7 +40,7 @@ class VIXIPKInstaller(Screen): 0, 50, 560, 50, 18, # lab1 10, 105, 540, 260, 20, # list 26, - ] + ] # noqa: E124 def __init__(self, session): Screen.__init__(self, session) @@ -185,7 +185,7 @@ class IpkgInstaller(Screen): 5, 50, 540, 360, 20, # list 0, 410, 560, 2, 5, 420, 550, 30, 22, - ] + ] # noqa: E124 def __init__(self, session, list): Screen.__init__(self, session) From 09aad1da931889f22ce7fe1a72fec4a6a5d21ce9 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 12:19:10 +0200 Subject: [PATCH 022/401] [ViX][BackupManager] - silence some PEP8 --- .../Plugins/SystemPlugins/ViX/BackupManager.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/python/Plugins/SystemPlugins/ViX/BackupManager.py b/lib/python/Plugins/SystemPlugins/ViX/BackupManager.py index 26fbe7064e1..57f8b0c3410 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/BackupManager.py +++ b/lib/python/Plugins/SystemPlugins/ViX/BackupManager.py @@ -167,7 +167,7 @@ class VIXBackupManager(Screen): 10, 105, 540, 260, 20, # list 10, 370, 400, 30, 20, # backupstatus 26, - ] + ] # noqa: E124 def __init__(self, session): Screen.__init__(self, session) @@ -656,8 +656,8 @@ def Stage3Complete(self, result, retval, extra_args): devmounts = [] self.plugfile = self.plugfiles[3] # print("[BackupManager] self.plugfile, self.plugfiles", self.plugfile, self.plugfiles) - for dir in ["/media/%s/%s" % (media, self.plugfile) for media in listdir("/media/") if path.isdir(path.join("/media/", media)) and path.exists("/media/%s/%s" % (media, self.plugfile))]: # noqa: F821 - if media not in ("autofs", "net"): + for dir in ["/media/%s/%s" % (media, self.plugfile) for media in listdir("/media/") if path.isdir(path.join("/media/", media)) and path.exists("/media/%s/%s" % (media, self.plugfile))]: + if media not in ("autofs", "net"): # noqa: F821 devmounts.append(dir) if len(devmounts): for x in devmounts: @@ -776,7 +776,7 @@ class BackupSelection(Screen): 140, 0, 140, 40, 20, 280, 0, 140, 40, 20, 5, 50, 550, 250, 25, 19, - ] + ] # noqa: E124 def __init__(self, session): Screen.__init__(self, session) @@ -976,7 +976,7 @@ class VIXBackupManagerMenu(Setup): 0, 50, 300, 20, 20, # footnote 0, 90, 560, 375, 25, 19, # config 0, 75, 560, 75, 18, # description - ] + ] # noqa: E124 def __init__(self, session, setup, plugin=None, PluginLanguageDomain=None): Setup.__init__(self, session, setup, plugin, PluginLanguageDomain) @@ -1014,7 +1014,7 @@ class VIXBackupManagerLogView(TextBox): """, 560, 400, 0, 0, 560, 400, 16, - ] + ] # noqa: E124 def __init__(self, session, filename): TextBox.__init__(self, session, label="list") @@ -1094,7 +1094,7 @@ def BackuponTimer(self): self.backuptimer.stop() now = int(time()) wake = self.getBackupTime() - atLeast = 0 # If we're close enough, we're okay... + atLeast = 0 # noqa: F841 if we're close enough, we're okay... if wake - now < 60: print("[BackupManager] Backup onTimer occured at", strftime("%c", localtime(now))) from Screens.Standby import inStandby From 39aa6d499f01e2b51202dce89e3d5c1b8bca0f0f Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 14:18:03 +0200 Subject: [PATCH 023/401] [ConfigList] fix PEP8 ambiguous variable l --- lib/python/Components/ConfigList.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/python/Components/ConfigList.py b/lib/python/Components/ConfigList.py index b92c32d76b2..f87de314e64 100644 --- a/lib/python/Components/ConfigList.py +++ b/lib/python/Components/ConfigList.py @@ -16,7 +16,7 @@ class ConfigList(GUIComponent): def __init__(self, list, session=None): GUIComponent.__init__(self) - self.l = eListboxPythonConfigContent() + self.l = eListboxPythonConfigContent() # noqa: E741 seperation = parameters.get("ConfigListSeperator", applySkinFactor(200)) self.l.setSeperation(seperation) height, space = parameters.get("ConfigListSlider", applySkinFactor(17, 0)) @@ -106,11 +106,11 @@ def preWidgetRemove(self, instance): instance.selectionChanged.get().remove(self.selectionChanged) instance.setContent(None) - def setList(self, l): - self.__list = l + def setList(self, configList): + self.__list = configList self.l.setList(self.__list) - if l is not None: - for x in l: + if configList is not None: + for x in configList: assert len(x) < 2 or isinstance(x[1], ConfigElement), "[ConfigList] Error: Entry in ConfigList '%s' must be a ConfigElement!" % str(x[1]) def getList(self): From 3bdab7d346139646f6c9e4967ddd6cacb492ebc4 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 14:20:39 +0200 Subject: [PATCH 024/401] [ConverterRotator] fix PEP8 noise --- lib/python/Components/Converter/ConverterRotator.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/python/Components/Converter/ConverterRotator.py b/lib/python/Components/Converter/ConverterRotator.py index 66bcde363ff..dabb965b4e4 100644 --- a/lib/python/Components/Converter/ConverterRotator.py +++ b/lib/python/Components/Converter/ConverterRotator.py @@ -56,8 +56,8 @@ def changed(self, what, parent=None): upstream = upstream.source if len(self.sourceList): self.mainstream = self.sourceList.pop(0)[0] - #if what[0] == self.CHANGED_POLL and \ - # self.poll_enabled and \ - # not self.sourceList[self.sourceIndex][1]: - # return + # if what[0] == self.CHANGED_POLL and \ + # self.poll_enabled and \ + # not self.sourceList[self.sourceIndex][1]: + # return self.downstream_elements.changed(what) From 110e57318d1899acdabb480f2523a829b2070de2 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 14:22:08 +0200 Subject: [PATCH 025/401] [CpuUsage] fix indent PEP8 --- lib/python/Components/Converter/CpuUsage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/Converter/CpuUsage.py b/lib/python/Components/Converter/CpuUsage.py index c9f82fd3c9c..bbd242d087b 100644 --- a/lib/python/Components/Converter/CpuUsage.py +++ b/lib/python/Components/Converter/CpuUsage.py @@ -40,7 +40,7 @@ def __init__(self, type): if pos == -1: break if pos < len(self.sfmt) - 1 and self.sfmt[pos + 1].isdigit() and int(self.sfmt[pos + 1]) > cpus: - self.sfmt = self.sfmt.replace("$" + self.sfmt[pos + 1], "n/a") + self.sfmt = self.sfmt.replace("$" + self.sfmt[pos + 1], "n/a") pos += 1 def doSuspend(self, suspended): From 077c26443e0ba4f51c195332d031af3ae37d5173 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 14:22:52 +0200 Subject: [PATCH 026/401] [ConverterRotator] fix PEP8 noise --- lib/python/Components/Converter/HddState.py | 23 +++++++++++---------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/lib/python/Components/Converter/HddState.py b/lib/python/Components/Converter/HddState.py index 42bcdee7c4e..028842ba09f 100644 --- a/lib/python/Components/Converter/HddState.py +++ b/lib/python/Components/Converter/HddState.py @@ -7,17 +7,18 @@ from skin import parameters from enigma import eTimer - -#*************************************************************** -# internalAll/internalHDD/internalSSD/external - disk type -# Example : internalAll -# or all type - internal and external -# Example : -# noLetterName - do not print a letter "I"(internal)/"S"(SSD)/"E"(external) -# Example : noLetterName -# allVisible - show "Disk state: standby " when use noLetterName -# Example : noLetterName,allVisible -#*************************************************************** +''' + *************************************************************** + internalAll/internalHDD/internalSSD/external - disk type + Example : internalAll + or all type - internal and external + Example : + noLetterName - do not print a letter "I"(internal)/"S"(SSD)/"E"(external) + Example : noLetterName + allVisible - show "Disk state: standby " when use noLetterName + Example : noLetterName,allVisible + *************************************************************** +''' class HddState(Converter): From 4fccd2decad553d95f3880de24fe6ca6cc0ce654 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 14:24:54 +0200 Subject: [PATCH 027/401] [LayoutInfo] convert from spaces to Tabs --- lib/python/Components/Converter/LayoutInfo.py | 393 ++++++++---------- 1 file changed, 182 insertions(+), 211 deletions(-) diff --git a/lib/python/Components/Converter/LayoutInfo.py b/lib/python/Components/Converter/LayoutInfo.py index b3bdd88f9b8..6e0d4d1c637 100644 --- a/lib/python/Components/Converter/LayoutInfo.py +++ b/lib/python/Components/Converter/LayoutInfo.py @@ -4,217 +4,188 @@ from Components.Element import cached from Components.Converter.Poll import Poll -SIZE_UNITS = ['B', - 'KB', - 'MB', - 'GB', - 'TB', - 'PB', - 'EB'] +SIZE_UNITS = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB'] class LayoutInfo(Poll, Converter): - HDDTEMP = 0 - LOADAVG = 1 - MEMTOTAL = 2 - MEMFREE = 3 - SWAPTOTAL = 4 - SWAPFREE = 5 - USBINFO = 6 - HDDINFO = 7 - FLASHINFO = 8 - - def __init__(self, type): - Converter.__init__(self, type) - Poll.__init__(self) - type = type.split(',') - self.shortFormat = 'Short' in type - self.fullFormat = 'Full' in type - if 'HddTemp' in type: - self.type = self.HDDTEMP - elif 'LoadAvg' in type: - self.type = self.LOADAVG - elif 'MemTotal' in type: - self.type = self.MEMTOTAL - elif 'MemFree' in type: - self.type = self.MEMFREE - elif 'SwapTotal' in type: - self.type = self.SWAPTOTAL - elif 'SwapFree' in type: - self.type = self.SWAPFREE - elif 'UsbInfo' in type: - self.type = self.USBINFO - elif 'HddInfo' in type: - self.type = self.HDDINFO - else: - self.type = self.FLASHINFO - if self.type in (self.FLASHINFO, self.HDDINFO, self.USBINFO): - self.poll_interval = 5000 - else: - self.poll_interval = 1600 - self.poll_enabled = True - - @cached - def getText(self): - text = 'N/A' - if self.type == self.HDDTEMP: - text = self.getHddTemp() - elif self.type == self.LOADAVG: - text = self.getLoadAvg() - else: - entry = {self.MEMTOTAL: ('Mem', 'Ram'), - self.MEMFREE: ('Mem', 'Ram'), - self.SWAPTOTAL: ('Swap', 'Swap'), - self.SWAPFREE: ('Swap', 'Swap'), - self.USBINFO: ('/media/usb', 'USB'), - self.HDDINFO: ('/media/hdd', 'HDD'), - self.FLASHINFO: ('/', 'Flash')}[self.type] - if self.type in (self.USBINFO, self.HDDINFO, self.FLASHINFO): - list = self.getDiskInfo(entry[0]) - else: - list = self.getMemInfo(entry[0]) - if list[0] == 0: - text = '%s: N/A' % entry[1] - elif self.shortFormat: - text = '%s%%' % (list[3]) - elif self.fullFormat: - text = '%s: %s Free:%s Used:%s (%s%%)' % (entry[1], - self.getSizeStr(list[0]), - self.getSizeStr(list[2]), - self.getSizeStr(list[1]), - list[3]) - else: - text = '%s: %s Used:%s Free:%s' % (entry[1], - self.getSizeStr(list[0]), - self.getSizeStr(list[1]), - self.getSizeStr(list[2])) - return text - - @cached - def getValue(self): - result = 0 - if self.type in (self.MEMTOTAL, - self.MEMFREE, - self.SWAPTOTAL, - self.SWAPFREE): - entry = {self.MEMTOTAL: 'Mem', - self.MEMFREE: 'Mem', - self.SWAPTOTAL: 'Swap', - self.SWAPFREE: 'Swap'}[self.type] - result = self.getMemInfo(entry)[3] - elif self.type in (self.USBINFO, self.HDDINFO, self.FLASHINFO): - path = {self.USBINFO: '/media/usb', - self.HDDINFO: '/media/hdd', - self.FLASHINFO: '/'}[self.type] - result = self.getDiskInfo(path)[3] - return result - - text = property(getText) - value = property(getValue) - range = 100 - - def getHddTemp(self): - textvalue = 'No info' - info = '0' - try: - out_line = popen('hddtemp -n -q /dev/sda').readline() - info = 'Hdd C:' + out_line[:4] - textvalue = info - except: - pass - - return textvalue - - def getLoadAvg(self): - textvalue = 'No info' - info = '0' - try: - out_line = popen('cat /proc/loadavg').readline() - info = 'loadavg:' + out_line[:15] - textvalue = info - except: - pass - - return textvalue - - def getMemInfo(self, value): - result = [0, - 0, - 0, - 0] - try: - check = 0 - fd = open('/proc/meminfo') - for line in fd: - if value + 'Total' in line: - check += 1 - result[0] = int(line.split()[1]) * 1024 - elif value + 'Free' in line: - check += 1 - result[2] = int(line.split()[1]) * 1024 - if check > 1: - if result[0] > 0: - result[1] = result[0] - result[2] - result[3] = result[1] * 100 // result[0] - break - - fd.close() - except: - pass - - return result - - def getDiskInfo(self, path): - - def isMountPoint(): - try: - fd = open('/proc/mounts', 'r') - for line in fd: - l = line.split() - if len(l) > 1 and l[1] == path: - return True - - fd.close() - except: - return None - - return False - - result = [0, - 0, - 0, - 0] - if isMountPoint(): - try: - st = statvfs(path) - except: - st = None - - if st is not None and 0 not in (st.f_bsize, st.f_blocks): - result[0] = st.f_bsize * st.f_blocks - result[2] = st.f_bsize * st.f_bavail - result[1] = result[0] - result[2] - result[3] = result[1] * 100 // result[0] - return result - - def getSizeStr(self, value, u=0): - fractal = 0 - if value >= 1024: - fmt = '%(size)u.%(frac)d %(unit)s' - while value >= 1024 and u < len(SIZE_UNITS): - value, mod = divmod(value, 1024) - fractal = mod * 10 // 1024 - u += 1 - - else: - fmt = '%(size)u %(unit)s' - return fmt % {'size': value, - 'frac': fractal, - 'unit': SIZE_UNITS[u]} - - def doSuspend(self, suspended): - if suspended: - self.poll_enabled = False - else: - self.downstream_elements.changed((self.CHANGED_POLL,)) - self.poll_enabled = True + HDDTEMP = 0 + LOADAVG = 1 + MEMTOTAL = 2 + MEMFREE = 3 + SWAPTOTAL = 4 + SWAPFREE = 5 + USBINFO = 6 + HDDINFO = 7 + FLASHINFO = 8 + + def __init__(self, type): + Converter.__init__(self, type) + Poll.__init__(self) + type = type.split(',') + self.shortFormat = 'Short' in type + self.fullFormat = 'Full' in type + if 'HddTemp' in type: + self.type = self.HDDTEMP + elif 'LoadAvg' in type: + self.type = self.LOADAVG + elif 'MemTotal' in type: + self.type = self.MEMTOTAL + elif 'MemFree' in type: + self.type = self.MEMFREE + elif 'SwapTotal' in type: + self.type = self.SWAPTOTAL + elif 'SwapFree' in type: + self.type = self.SWAPFREE + elif 'UsbInfo' in type: + self.type = self.USBINFO + elif 'HddInfo' in type: + self.type = self.HDDINFO + else: + self.type = self.FLASHINFO + if self.type in (self.FLASHINFO, self.HDDINFO, self.USBINFO): + self.poll_interval = 5000 + else: + self.poll_interval = 1600 + self.poll_enabled = True + + @cached + def getText(self): + text = 'N/A' + if self.type == self.HDDTEMP: + text = self.getHddTemp() + elif self.type == self.LOADAVG: + text = self.getLoadAvg() + else: + entry = {self.MEMTOTAL: ('Mem', 'Ram'), + self.MEMFREE: ('Mem', 'Ram'), + self.SWAPTOTAL: ('Swap', 'Swap'), + self.SWAPFREE: ('Swap', 'Swap'), + self.USBINFO: ('/media/usb', 'USB'), + self.HDDINFO: ('/media/hdd', 'HDD'), + self.FLASHINFO: ('/', 'Flash')}[self.type] + if self.type in (self.USBINFO, self.HDDINFO, self.FLASHINFO): + list = self.getDiskInfo(entry[0]) + else: + list = self.getMemInfo(entry[0]) + if list[0] == 0: + text = '%s: N/A' % entry[1] + elif self.shortFormat: + text = '%s%%' % (list[3]) + elif self.fullFormat: + text = '%s: %s Free:%s Used:%s (%s%%)' % (entry[1], self.getSizeStr(list[0]), self.getSizeStr(list[2]), self.getSizeStr(list[1]), list[3]) + else: + text = '%s: %s Used:%s Free:%s' % (entry[1], self.getSizeStr(list[0]), self.getSizeStr(list[1]), self.getSizeStr(list[2])) + return text + + @cached + def getValue(self): + result = 0 + if self.type in (self.MEMTOTAL, + self.MEMFREE, + self.SWAPTOTAL, + self.SWAPFREE): + entry = {self.MEMTOTAL: 'Mem', + self.MEMFREE: 'Mem', + self.SWAPTOTAL: 'Swap', + self.SWAPFREE: 'Swap'}[self.type] + result = self.getMemInfo(entry)[3] + elif self.type in (self.USBINFO, self.HDDINFO, self.FLASHINFO): + path = {self.USBINFO: '/media/usb', + self.HDDINFO: '/media/hdd', + self.FLASHINFO: '/'}[self.type] + result = self.getDiskInfo(path)[3] + return result + + text = property(getText) # noqa: F821 + value = property(getValue) # noqa: F821 + range = 100 + + def getHddTemp(self): + textvalue = 'No info' + info = '0' + try: + out_line = popen('hddtemp -n -q /dev/sda').readline() + info = 'Hdd C:' + out_line[:4] + textvalue = info + except: + pass + return textvalue + + def getLoadAvg(self): + textvalue = 'No info' + info = '0' + try: + out_line = popen('cat /proc/loadavg').readline() + info = 'loadavg:' + out_line[:15] + textvalue = info + except: + pass + return textvalue + + def getMemInfo(self, value): + result = [0, 0, 0, 0] + try: + check = 0 + fd = open('/proc/meminfo') + for line in fd: + if value + 'Total' in line: + check += 1 + result[0] = int(line.split()[1]) * 1024 + elif value + 'Free' in line: + check += 1 + result[2] = int(line.split()[1]) * 1024 + if check > 1: + if result[0] > 0: + result[1] = result[0] - result[2] + result[3] = result[1] * 100 // result[0] + break + fd.close() + except: + pass + return result + + def getDiskInfo(self, path): + + def isMountPoint(): + try: + fd = open('/proc/mounts', 'r') + for line in fd: + partLine = line.split() + if len(partLine) > 1 and partLine[1] == path: + return True + fd.close() + except: + return None + return False + + result = [0, 0, 0, 0] + if isMountPoint(): + try: + st = statvfs(path) + except: + st = None + if st is not None and 0 not in (st.f_bsize, st.f_blocks): + result[0] = st.f_bsize * st.f_blocks + result[2] = st.f_bsize * st.f_bavail + result[1] = result[0] - result[2] + result[3] = result[1] * 100 // result[0] + return result + + def getSizeStr(self, value, u=0): + fractal = 0 + if value >= 1024: + fmt = '%(size)u.%(frac)d %(unit)s' + while value >= 1024 and u < len(SIZE_UNITS): + value, mod = divmod(value, 1024) + fractal = mod * 10 // 1024 + u += 1 + else: + fmt = '%(size)u %(unit)s' + return fmt % {'size': value, 'frac': fractal, 'unit': SIZE_UNITS[u]} + + def doSuspend(self, suspended): + if suspended: + self.poll_enabled = False + else: + self.downstream_elements.changed((self.CHANGED_POLL,)) + self.poll_enabled = True From ed91d6da72624bcbddcae533e65708da933675ef Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 14:26:56 +0200 Subject: [PATCH 028/401] [MovieReference] PEP8 --- .../Components/Converter/MovieReference.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/python/Components/Converter/MovieReference.py b/lib/python/Components/Converter/MovieReference.py index 4705c5c22f4..1c1d2928f0b 100644 --- a/lib/python/Components/Converter/MovieReference.py +++ b/lib/python/Components/Converter/MovieReference.py @@ -1,11 +1,13 @@ -# Movie Selection: -# -# -# -# Movie Player Infobar: -# -# -# +''' + Movie Selection: + + + + Movie Player Infobar: + + + +''' from enigma import iServiceInformation, eServiceReference, iPlayableServicePtr From d662c24e07723e3c4e16a72215162dcb20b8a8ba Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 14:31:42 +0200 Subject: [PATCH 029/401] [RemainingToText] PEP8 --- lib/python/Components/Converter/RemainingToText.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/Converter/RemainingToText.py b/lib/python/Components/Converter/RemainingToText.py index 2632f112854..056691389b0 100644 --- a/lib/python/Components/Converter/RemainingToText.py +++ b/lib/python/Components/Converter/RemainingToText.py @@ -95,7 +95,7 @@ def getText(self): else: (duration, remaining) = self.source.time - l = duration # Length + l = duration # noqa: E741 Length p = elapsed # Position r = remaining # Remaining From 515d829ca73b1750602742a17e40c48ded215cef Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 14:33:09 +0200 Subject: [PATCH 030/401] [ServiceName2] PEP8 --- lib/python/Components/Converter/ServiceName2.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/python/Components/Converter/ServiceName2.py b/lib/python/Components/Converter/ServiceName2.py index c5865bac6b5..fccdba6a4f4 100644 --- a/lib/python/Components/Converter/ServiceName2.py +++ b/lib/python/Components/Converter/ServiceName2.py @@ -233,7 +233,7 @@ def getTransponderInfo(self, info, ref, fmt): elif type == 'IP-TV': return _("Streaming") else: - fmt = ["O ", "s ", "M ", "F ", "p ", "Y ", "f"] #(orbital_position frequency polarization symbol_rate fec) + fmt = ["O ", "s ", "M ", "F ", "p ", "Y ", "f"] # (orbital_position frequency polarization symbol_rate fec) for line in fmt: f = line[:1] if f == 't': # %t - tuner_type (dvb-s/s2/c/t) @@ -296,12 +296,12 @@ def getTransponderInfo(self, info, ref, fmt): elif f == 'r': # %r - rolloff (dvb-s2) if not self.isStream: x = self.tpdata.get('rolloff') - if not x is None: + if x is not None: result += x in range(3) and {0: '0.35', 1: '0.25', 2: '0.20'}[x] or '' elif f == 'o': # %o - pilot (dvb-s2) if not self.isStream: x = self.tpdata.get('pilot') - if not x is None: + if x is not None: result += x in range(3) and {0: 'Off', 1: 'On', 2: 'Auto'}[x] or '' elif f == 'c': # %c - constellation (dvb-t) if type == 'DVB-T': From 625f6b0e3097ea24a5708c7ff574638de47b8771 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 14:43:03 +0200 Subject: [PATCH 031/401] [Task] PEP8 --- lib/python/Components/Task.py | 92 +++++++++++++++++------------------ 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/lib/python/Components/Task.py b/lib/python/Components/Task.py index a82f0571b47..fefc840a64b 100644 --- a/lib/python/Components/Task.py +++ b/lib/python/Components/Task.py @@ -432,38 +432,38 @@ def getPendingJobs(self): return list # some examples: -#class PartitionExistsPostcondition: -# def __init__(self, device): -# self.device = device -# -# def check(self, task): -# return access(self.device + "part1", F_OK) -# -#class CreatePartitionTask(Task): -# def __init__(self, device): -# Task.__init__(self, "Creating partition") -# self.device = device -# self.setTool("/sbin/sfdisk") -# self.args += ["-f", self.device + "disc"] -# self.initial_input = "0,\n;\n;\n;\ny\n" -# self.postconditions.append(PartitionExistsPostcondition(self.device)) -# -#class CreateFilesystemTask(Task): -# def __init__(self, device, partition = 1, largefile = True): -# Task.__init__(self, "Creating filesystem") -# self.setTool("/sbin/mkfs.ext") -# if largefile: -# self.args += ["-T", "largefile"] -# self.args.append("-m0") -# self.args.append(device + "part%d" % partition) -# -#class FilesystemMountTask(Task): -# def __init__(self, device, partition = 1, filesystem = "ext3"): -# Task.__init__(self, "Mounting filesystem") -# self.setTool("/bin/mount") -# if filesystem is not None: -# self.args += ["-t", filesystem] -# self.args.append(device + "part%d" % partition) +# class PartitionExistsPostcondition: +# def __init__(self, device): +# self.device = device +# +# def check(self, task): +# return access(self.device + "part1", F_OK) +# +# class CreatePartitionTask(Task): +# def __init__(self, device): +# Task.__init__(self, "Creating partition") +# self.device = device +# self.setTool("/sbin/sfdisk") +# self.args += ["-f", self.device + "disc"] +# self.initial_input = "0,\n;\n;\n;\ny\n" +# self.postconditions.append(PartitionExistsPostcondition(self.device)) +# +# class CreateFilesystemTask(Task): +# def __init__(self, device, partition = 1, largefile = True): +# Task.__init__(self, "Creating filesystem") +# self.setTool("/sbin/mkfs.ext") +# if largefile: +# self.args += ["-T", "largefile"] +# self.args.append("-m0") +# self.args.append(device + "part%d" % partition) +# +# class FilesystemMountTask(Task): +# def __init__(self, device, partition = 1, filesystem = "ext3"): +# Task.__init__(self, "Mounting filesystem") +# self.setTool("/bin/mount") +# if filesystem is not None: +# self.args += ["-t", filesystem] +# self.args.append(device + "part%d" % partition) class Condition: @@ -567,20 +567,20 @@ def getErrorMessage(self, task): def check(self, task): return (self.exception is None) or (self.exception == 0) -#class HDDInitJob(Job): -# def __init__(self, device): -# Job.__init__(self, _("Initialize Harddisk")) -# self.device = device -# self.fromDescription(self.createDescription()) -# -# def fromDescription(self, description): -# self.device = description["device"] -# self.addTask(CreatePartitionTask(self.device)) -# self.addTask(CreateFilesystemTask(self.device)) -# self.addTask(FilesystemMountTask(self.device)) -# -# def createDescription(self): -# return {"device": self.device} +# class HDDInitJob(Job): +# def __init__(self, device): +# Job.__init__(self, _("Initialize Harddisk")) +# self.device = device +# self.fromDescription(self.createDescription()) +# +# def fromDescription(self, description): +# self.device = description["device"] +# self.addTask(CreatePartitionTask(self.device)) +# self.addTask(CreateFilesystemTask(self.device)) +# self.addTask(FilesystemMountTask(self.device)) +# +# def createDescription(self): +# return {"device": self.device} job_manager = JobManager() From 640097fa35b65696bc6330e400eae4d00abc46ba Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Tue, 24 Oct 2023 12:47:01 +0000 Subject: [PATCH 032/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Components/Task.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/python/Components/Task.py b/lib/python/Components/Task.py index fefc840a64b..43c8ef9587d 100644 --- a/lib/python/Components/Task.py +++ b/lib/python/Components/Task.py @@ -435,10 +435,10 @@ def getPendingJobs(self): # class PartitionExistsPostcondition: # def __init__(self, device): # self.device = device -# +# # def check(self, task): # return access(self.device + "part1", F_OK) -# +# # class CreatePartitionTask(Task): # def __init__(self, device): # Task.__init__(self, "Creating partition") @@ -447,7 +447,7 @@ def getPendingJobs(self): # self.args += ["-f", self.device + "disc"] # self.initial_input = "0,\n;\n;\n;\ny\n" # self.postconditions.append(PartitionExistsPostcondition(self.device)) -# +# # class CreateFilesystemTask(Task): # def __init__(self, device, partition = 1, largefile = True): # Task.__init__(self, "Creating filesystem") @@ -456,7 +456,7 @@ def getPendingJobs(self): # self.args += ["-T", "largefile"] # self.args.append("-m0") # self.args.append(device + "part%d" % partition) -# +# # class FilesystemMountTask(Task): # def __init__(self, device, partition = 1, filesystem = "ext3"): # Task.__init__(self, "Mounting filesystem") @@ -572,13 +572,13 @@ def check(self, task): # Job.__init__(self, _("Initialize Harddisk")) # self.device = device # self.fromDescription(self.createDescription()) -# +# # def fromDescription(self, description): # self.device = description["device"] # self.addTask(CreatePartitionTask(self.device)) # self.addTask(CreateFilesystemTask(self.device)) # self.addTask(FilesystemMountTask(self.device)) -# +# # def createDescription(self): # return {"device": self.device} From 6819d0950b9b389cd101aae081740a5b76f55876 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 15:24:37 +0200 Subject: [PATCH 033/401] [EpgBouquetList] PEP8 --- lib/python/Components/EpgBouquetList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/EpgBouquetList.py b/lib/python/Components/EpgBouquetList.py index 2f0aa60c9e7..1e680282765 100644 --- a/lib/python/Components/EpgBouquetList.py +++ b/lib/python/Components/EpgBouquetList.py @@ -11,7 +11,7 @@ class EPGBouquetList(GUIComponent): def __init__(self, graphic=False): GUIComponent.__init__(self) self.graphic = graphic - self.l = eListboxPythonMultiContent() + self.l = eListboxPythonMultiContent() # noqa: E741 self.l.setBuildFunc(self.buildEntry) self.onSelChanged = [] From 077d3d64a12caa49c87bd4b24dec36eed465babb Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 15:25:31 +0200 Subject: [PATCH 034/401] [EpgListGrid] PEP8 --- lib/python/Components/EpgListGrid.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/python/Components/EpgListGrid.py b/lib/python/Components/EpgListGrid.py index a575f612ad9..25bd8315727 100644 --- a/lib/python/Components/EpgListGrid.py +++ b/lib/python/Components/EpgListGrid.py @@ -828,11 +828,11 @@ def snapshotTimers(self, startTime, endTime): if (startTime <= timer.end or timer.repeated) and timer.begin < endTime: serviceref = timer.service_ref.ref.toCompareString() serviceref = "1" + serviceref[4:] if serviceref[:4] in config.recording.setstreamto1.value else serviceref # converts 4097, 5001, 5002 to 1 - l = self.filteredTimerList.get(serviceref) - if l is None: - self.filteredTimerList[serviceref] = l = [timer] + srefl = self.filteredTimerList.get(serviceref) + if srefl is None: + self.filteredTimerList[serviceref] = srefl = [timer] else: - l.append(timer) + srefl.append(timer) def getChannelNumber(self, service): if service.ref and "0:0:0:0:0:0:0:0:0" not in service.ref.toString(): @@ -854,7 +854,7 @@ def __init__(self, epgConfig, graphic): GUIComponent.__init__(self) self.epgConfig = epgConfig self.graphic = graphic - self.l = eListboxPythonMultiContent() + self.l = eListboxPythonMultiContent() # noqa: E741 self.l.setSelectionClip(eRect(0, 0, 0, 0)) self.itemHeight = 30 self.timelineDate = None @@ -958,7 +958,7 @@ def setEntries(self, list, timelineNow, timeLines, force): bgpng = self.timelineDate if bgpng is not None and self.graphic: backColor = None - backColorSel = None + # backColorSel = None res.append(MultiContentEntryPixmapAlphaBlend( pos=(0, 0), size=(serviceRect.width(), self.listHeight), @@ -984,7 +984,7 @@ def setEntries(self, list, timelineNow, timeLines, force): xpos = 0 if bgpng is not None and self.graphic: backColor = None - backColorSel = None + # backColorSel = None res.append(MultiContentEntryPixmapAlphaBlend( pos=(serviceRect.width(), 0), size=(eventRect.width(), self.listHeight), From 6314561cf53e9692335d51a36d49cc5e4a86876c Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 15:26:26 +0200 Subject: [PATCH 035/401] [EpgListBase] PEP8 --- lib/python/Components/EpgListBase.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/EpgListBase.py b/lib/python/Components/EpgListBase.py index f8b333ef8d1..ad6ad675f4f 100644 --- a/lib/python/Components/EpgListBase.py +++ b/lib/python/Components/EpgListBase.py @@ -16,7 +16,7 @@ def __init__(self, session, selChangedCB=None): self.onSelChanged = [] if selChangedCB is not None: self.onSelChanged.append(selChangedCB) - self.l = eListboxPythonMultiContent() + self.l = eListboxPythonMultiContent() # noqa: E741 self.epgcache = eEPGCache.getInstance() # Load the common clock icons. From d892aba1b308e4411a9e776500dcada9411d48aa Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 15:27:25 +0200 Subject: [PATCH 036/401] [EpgListMulti] use variable name not l PEP8 --- lib/python/Components/EpgListMulti.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/python/Components/EpgListMulti.py b/lib/python/Components/EpgListMulti.py index d75859f5dd0..cbc1dbeccfb 100644 --- a/lib/python/Components/EpgListMulti.py +++ b/lib/python/Components/EpgListMulti.py @@ -118,11 +118,11 @@ def snapshotTimers(self, startTime): for x in timerList: if x.end >= startTime: service = ":".join(x.service_ref.ref.toString().split(':')[:11]) - l = self.filteredTimerList.get(service) - if l is None: - self.filteredTimerList[service] = l = [x] + srefl = self.filteredTimerList.get(service) + if srefl is None: + self.filteredTimerList[service] = srefl = [x] else: - l.append(x) + srefl.append(x) if x.begin > startTime + 6 * 3600: break From 176a5c1fbdcefdf93bd05e76f243a65a93438b78 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 15:28:18 +0200 Subject: [PATCH 037/401] [FileList] use variable name other than l PEP8 --- lib/python/Components/FileList.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/python/Components/FileList.py b/lib/python/Components/FileList.py index 48e64a40f9e..dbafa1cdfd6 100644 --- a/lib/python/Components/FileList.py +++ b/lib/python/Components/FileList.py @@ -143,11 +143,11 @@ def getSelection(self): return self.l.getCurrentSelection()[0] def getCurrentEvent(self): - l = self.l.getCurrentSelection() - if not l or l[0][1] is True: + currl = self.l.getCurrentSelection() + if not currl or currl[0][1] is True: return None else: - return self.serviceHandler.info(l[0][0]).getEvent(l[0][0]) + return self.serviceHandler.info(currl[0][0]).getEvent(currl[0][0]) def getFileList(self): return self.list From 0bf3f736fc875e782dd6a1985403279d7aa067de Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 15:28:45 +0200 Subject: [PATCH 038/401] [Harddisk] PEP8 --- lib/python/Components/Harddisk.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Components/Harddisk.py b/lib/python/Components/Harddisk.py index 0d1f468eb1f..76764cacb7f 100644 --- a/lib/python/Components/Harddisk.py +++ b/lib/python/Components/Harddisk.py @@ -669,10 +669,10 @@ def enumerateBlockDevices(self): # # print("[Harddisk] DEBUG: Device '%s' (%s) has removable media." % (device, physicalDevice)) try: open(ospath.join("/dev", device), "r").close() - mediumFound = True # Check for medium. + mediumFound = True # noqa: F841 Check for medium set for debug. except (IOError, OSError) as err: if err.errno in (123, 159): # ENOMEDIUM - No medium found. (123 = Common Linux, 159 = MIPS Linux) - mediumFound = False + mediumFound = False # noqa: F841 set for Debug else: print("[Harddisk] Error: Device '%s' (%s) media availability test failed:" % (device, physicalDevice), err) continue From 729e66d8355e40bb51ab94ab5ae570530ccccfb6 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 15:29:24 +0200 Subject: [PATCH 039/401] [HdmiCec] PEP8 --- lib/python/Components/HdmiCec.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/HdmiCec.py b/lib/python/Components/HdmiCec.py index 2da82fc4588..356e24af081 100644 --- a/lib/python/Components/HdmiCec.py +++ b/lib/python/Components/HdmiCec.py @@ -552,7 +552,7 @@ def sendMessage(self, msgaddress, message): def sendMsgQ(self): if len(self.queue): (msgaddress, cmd, data) = self.queue.pop(0) - CECcmd = cmdList.get(cmd, "") + CECcmd = cmdList.get(cmd, "") # noqa: F841 # print("[HdmiCEC][sendMsgQ1]: msgaddress=%s, CECcmd=%s cmd=%X,data=%s \n" % (msgaddress, CECcmd, cmd, data)) eHdmiCEC.getInstance().sendMessage(msgaddress, cmd, data, len(data)) self.wait.start(int(config.hdmicec.minimum_send_interval.value), True) From d99fb8ebba3f5dead5cbe68d8d99a1bda11dc3ac Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 15:29:45 +0200 Subject: [PATCH 040/401] [InputDevice] PEP8 --- lib/python/Components/InputDevice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/InputDevice.py b/lib/python/Components/InputDevice.py index fd4fa8a9532..c4481cd857e 100644 --- a/lib/python/Components/InputDevice.py +++ b/lib/python/Components/InputDevice.py @@ -141,7 +141,7 @@ def createConfig(self, *args): for device in sorted(iter(iInputDevices.Devices.keys())): # print("[InputDevice][createConfig]", sorted(iter(iInputDevices.Devices.keys()))) self.currentDevice = device - #print("[InputDevice] creating config entry for device: %s -> %s " % (self.currentDevice, iInputDevices.Devices[device]["name"])) + # print("[InputDevice] creating config entry for device: %s -> %s " % (self.currentDevice, iInputDevices.Devices[device]["name"])) self.setupConfigEntries(self.currentDevice) self.remapRemoteControl(self.currentDevice) self.currentDevice = "" From 7b7c740a70d5693e0caa21af1d8c21e492eac665 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 15:30:11 +0200 Subject: [PATCH 041/401] [MediaPlayer] use named variable rather than l PEP8 --- lib/python/Components/MediaPlayer.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/python/Components/MediaPlayer.py b/lib/python/Components/MediaPlayer.py index fbb88bd85f8..eec62df1400 100644 --- a/lib/python/Components/MediaPlayer.py +++ b/lib/python/Components/MediaPlayer.py @@ -106,12 +106,12 @@ def getCurrentIndex(self): return self.currPlaying def getCurrentEvent(self): - l = self.l.getCurrentSelection() - return l and self.serviceHandler.info(l[0]).getEvent(l[0]) + currl = self.l.getCurrentSelection() + return currl and self.serviceHandler.info(currl[0]).getEvent(currl[0]) def getCurrent(self): - l = self.l.getCurrentSelection() - return l and l[0] + currl = self.l.getCurrentSelection() + return currl and currl[0] def getServiceRefList(self): return [x[0] for x in self.list] From 828db3d92cac31b86a5df4d6b57ab4ce2f50f523 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 15:35:22 +0200 Subject: [PATCH 042/401] [TimerSanityCheck] PEP8 --- lib/python/Components/TimerSanityCheck.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/python/Components/TimerSanityCheck.py b/lib/python/Components/TimerSanityCheck.py index 47be68cb35c..3e04c948055 100644 --- a/lib/python/Components/TimerSanityCheck.py +++ b/lib/python/Components/TimerSanityCheck.py @@ -73,7 +73,7 @@ def checkTimerlist(self, ext_timer=None): if ext_timer and isinstance(ext_timer, RecordTimer.RecordTimerEntry): self.newtimer = ext_timer - #GML:1 - A timer which has already ended (happens during start-up check) can't clash!! + # GML:1 - A timer which has already ended (happens during start-up check) can't clash!! # # NOTE: that when adding a timer it also cannot clash with: # o any timers which run before the latest period of no timers running @@ -223,9 +223,9 @@ def checkTimerlist(self, ext_timer=None): else: fakeRecResult = -1 # TODO - #if fakeRecResult == -6 and len(NavigationInstance.instance.getRecordings(True)) < 2: - # print "[TimerSanityCheck] less than two timers in the simulated recording list - timer conflict is not plausible - ignored !" - # fakeRecResult = 0 + # if fakeRecResult == -6 and len(NavigationInstance.instance.getRecordings(True)) < 2: + # print "[TimerSanityCheck] less than two timers in the simulated recording list - timer conflict is not plausible - ignored !" + # fakeRecResult = 0 if not fakeRecResult: # tune okay if hasattr(fakeRecService, 'frontendInfo'): feinfo = fakeRecService.frontendInfo() From 71e7544d05c5aa8372aef79989c5f62932f6c7eb Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 15:40:54 +0200 Subject: [PATCH 043/401] [Timeshift] PEP8 --- lib/python/Components/Timeshift.py | 44 +++++++++++++++--------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/lib/python/Components/Timeshift.py b/lib/python/Components/Timeshift.py index e60c3791b18..9c20ae8f618 100644 --- a/lib/python/Components/Timeshift.py +++ b/lib/python/Components/Timeshift.py @@ -408,7 +408,7 @@ def stopTimeshiftcheckTimeshiftRunningCallback(self, answer): ts = self.getTimeshift() if ts and ts.isTimeshiftEnabled(): # print("[Timeshift]TEST5") - was_enabled = ts.isTimeshiftEnabled() # "was_enabled" assigned but not used? This code is nonsense. + was_enabled = ts.isTimeshiftEnabled() # noqa: F841 "was_enabled" assigned but not used? This code is nonsense. if answer and ts: # print("[Timeshift]TEST6") if int(config.timeshift.startdelay.value): @@ -465,19 +465,19 @@ def checkTimeshiftRunning(self, returnFunction): # print("[Timeshift]TEST3") message = _("You have chosen to save the current timeshift event, but the event has not yet finished\nWhat do you want to do ?") choice = [ - (_("Save timeshift as movie and stop recording"), "savetimeshift"), - (_("Save timeshift as movie and continue recording"), "savetimeshiftandrecord"), - (_("Cancel save timeshift as movie"), "noSave"), - (_("Nothing, just leave this menu"), "no")] + (_("Save timeshift as movie and stop recording"), "savetimeshift"), + (_("Save timeshift as movie and continue recording"), "savetimeshiftandrecord"), + (_("Cancel save timeshift as movie"), "noSave"), + (_("Nothing, just leave this menu"), "no")] self.session.openWithCallback(boundFunction(self.checkTimeshiftRunningCallback, returnFunction), MessageBox, message, simple=True, list=choice) else: # print("[Timeshift]TEST4") message = _("You seem to be in timeshift, Do you want to leave timeshift? Streams & IPTV not fully supported!") choice = [ - (_("Yes, but save timeshift as movie and stop recording"), "savetimeshift"), - (_("Yes, but save timeshift as movie and continue recording"), "savetimeshiftandrecord"), - (_("Yes, but don't save timeshift as movie"), "noSave"), - (_("No"), "no")] + (_("Yes, but save timeshift as movie and stop recording"), "savetimeshift"), + (_("Yes, but save timeshift as movie and continue recording"), "savetimeshiftandrecord"), + (_("Yes, but don't save timeshift as movie"), "noSave"), + (_("No"), "no")] self.session.openWithCallback(boundFunction(self.checkTimeshiftRunningCallback, returnFunction), MessageBox, message, simple=True, list=choice) else: # print("[Timeshift]TEST5") @@ -593,9 +593,9 @@ def saveTimeshiftEventPopup(self): if statinfo.st_mtime < (time() - 5.0): # Get Event Info from meta file readmetafile = open("%s%s.meta" % (config.usage.timeshift_path.value, filename), "r") - servicerefname = readmetafile.readline()[0:-1] # local variable 'servicerefname' is assigned to but never used + servicerefname = readmetafile.readline()[0:-1] # noqa: F841 local variable 'servicerefname' is assigned to but never used eventname = readmetafile.readline()[0:-1] - description = readmetafile.readline()[0:-1] # local variable 'description' is assigned to but never used + description = readmetafile.readline()[0:-1] # noqa: F841 local variable 'description' is assigned to but never used begintime = readmetafile.readline()[0:-1] readmetafile.close() @@ -777,7 +777,7 @@ def SaveTimeshift(self, timeshiftfile=None, mergelater=False): # Get Event Info from meta file if os.path.exists("%s.ts.meta" % fullname): readmetafile = open("%s.ts.meta" % fullname, "r") - servicerefname = readmetafile.readline()[0:-1] # local variable 'servicerefname' is assigned to but never used + servicerefname = readmetafile.readline()[0:-1] # noqa: F841 local variable 'servicerefname' is assigned to but never used eventname = readmetafile.readline()[0:-1] readmetafile.close() else: @@ -813,16 +813,16 @@ def ptsCleanTimeshiftFolder(self): # print("[Timeshift]filename:", filename) statinfo = os.stat("%s%s" % (config.usage.timeshift_path.value, filename)) # if no write for 3 sec = stranded timeshift if statinfo.st_mtime < (time() - 3.0): - # try: - # print("[Timeshift][TimeShift] Erasing stranded timeshift %s" % filename) + # try: + # print("[Timeshift][TimeShift] Erasing stranded timeshift %s" % filename) self.BgFileEraser.erase("%s%s" % (config.usage.timeshift_path.value, filename)) - # Delete Meta and EIT File too - # if filename.startswith("pts_livebuffer_") is True: - # self.BgFileEraser.erase("%s%s.meta" % (config.usage.timeshift_path.value, filename)) - # self.BgFileEraser.erase("%s%s.eit" % (config.usage.timeshift_path.value, filename)) - # except: - # print("[Timeshift][TimeShift] IO-Error while cleaning Timeshift Folder ...") + # Delete Meta and EIT File too + # if filename.startswith("pts_livebuffer_") is True: + # self.BgFileEraser.erase("%s%s.meta" % (config.usage.timeshift_path.value, filename)) + # self.BgFileEraser.erase("%s%s.eit" % (config.usage.timeshift_path.value, filename)) + # except: + # print("[Timeshift][TimeShift] IO-Error while cleaning Timeshift Folder ...") def ptsGetEventInfo(self): event = None @@ -1001,7 +1001,7 @@ def ptsCreateAPSCFiles(self, filename): if fileExists(filename + ".meta", "r"): # Get Event Info from meta file readmetafile = open(filename + ".meta", "r") - servicerefname = readmetafile.readline()[0:-1] # local variable 'servicerefname' is assigned to but never used + servicerefname = readmetafile.readline()[0:-1] # noqa: F841 local variable 'servicerefname' is assigned to but never used eventname = readmetafile.readline()[0:-1] readmetafile.close() else: @@ -1299,7 +1299,7 @@ def ptsTimerEntryStateChange(self, timer): self.ptsFrontpanelActions("start") # This will already be set if it needs to be set and otherwise it must # *not* be set. - # config.timeshift.isRecording.value = True + # config.timeshift.isRecording.value = True def ptsLiveTVStatus(self): service = self.session.nav.getCurrentService() From c9ef68d15c5e152f53465efc102eb2315c4ba8c8 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 16:05:39 +0200 Subject: [PATCH 044/401] [CutlistEditor][ui] PEP8 --- lib/python/Plugins/Extensions/CutListEditor/ui.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/python/Plugins/Extensions/CutListEditor/ui.py b/lib/python/Plugins/Extensions/CutListEditor/ui.py index 0bab3b180f8..d6258b64055 100644 --- a/lib/python/Plugins/Extensions/CutListEditor/ui.py +++ b/lib/python/Plugins/Extensions/CutListEditor/ui.py @@ -2,16 +2,16 @@ from Screens.MessageBox import MessageBox from Components.ServicePosition import ServicePositionGauge from Components.ActionMap import HelpableActionMap -from Components.MultiContent import MultiContentEntryText +from Components.MultiContent import MultiContentEntryText # noqa: F401 from Components.ServiceEventTracker import ServiceEventTracker, InfoBarBase from Components.VideoWindow import VideoWindow from Components.Label import Label from Components.config import config, ConfigSubsection, ConfigYesNo from Screens.InfoBarGenerics import InfoBarSeek, InfoBarCueSheetSupport -from enigma import getDesktop, gFont, iPlayableService, RT_HALIGN_RIGHT +from enigma import getDesktop, gFont, iPlayableService, RT_HALIGN_RIGHT # noqa: F401 from Screens.FixedMenu import FixedMenu from Screens.HelpMenu import HelpableScreen -from ServiceReference import ServiceReference +from ServiceReference import ServiceReference # noqa: F401 from Components.Sources.List import List from Components.Console import Console from Screens.ChoiceBox import ChoiceBox From 028865c9070b77ea638384c4205bd43144f60e8e Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 16:07:37 +0200 Subject: [PATCH 045/401] [DVDBurn][DVDTitle] use variable name not l PEP8 --- lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py b/lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py index 573c97d3242..e24b5416fe8 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py +++ b/lib/python/Plugins/Extensions/DVDBurn/DVDTitle.py @@ -96,8 +96,7 @@ def formatDVDmenuText(self, template, track): template = template.replace("$A", audiostring) if template.find("$l") >= 0: - l = self.length - lengthstring = "%d:%02d:%02d" % (l / 3600, l % 3600 / 60, l % 60) + lengthstring = "%d:%02d:%02d" % (self.length / 3600, self.length % 3600 / 60, self.length % 60) template = template.replace("$l", lengthstring) if self.timeCreate: template = template.replace("$Y", str(self.timeCreate[0])) From da348bbbab8cab599823de96b002e8a4d5330f3f Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 16:09:46 +0200 Subject: [PATCH 046/401] [DVDBurn][ProjectSettings] use r option in pattern matching PEP8 --- .../Extensions/DVDBurn/ProjectSettings.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py b/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py index 534d78327fe..5c8d5d3dd99 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py +++ b/lib/python/Plugins/Extensions/DVDBurn/ProjectSettings.py @@ -23,27 +23,27 @@ def __init__(self, session, scope, configRef): currDir = "/" if self.scope == "project": currDir = self.getDir() - pattern = "(?i)^.*\.(ddvdp\.xml)" + pattern = r"(?i)^.*\.(ddvdp\.xml)" elif self.scope == "menutemplate": currDir = self.getDir() - pattern = "(?i)^.*\.(ddvdm\.xml)" + pattern = r"(?i)^.*\.(ddvdm\.xml)" if self.scope == "menubg": currDir = self.getDir(configRef.value) - pattern = "(?i)^.*\.(jpeg|jpg|jpe|png|bmp)" + pattern = r"(?i)^.*\.(jpeg|jpg|jpe|png|bmp)" elif self.scope == "menuaudio": currDir = self.getDir(configRef.value) - pattern = "(?i)^.*\.(mp2|m2a|ac3)" + pattern = r"(?i)^.*\.(mp2|m2a|ac3)" elif self.scope == "vmgm": currDir = self.getDir(configRef.value) - pattern = "(?i)^.*\.(mpg|mpeg)" + pattern = r"(?i)^.*\.(mpg|mpeg)" elif self.scope == "font_face": currDir = self.getDir(configRef.value, resolveFilename(SCOPE_FONTS)) - pattern = "(?i)^.*\.(ttf)" + pattern = r"(?i)^.*\.(ttf)" elif self.scope == "isopath": currDir = configRef.value elif self.scope == "image": currDir = resolveFilename(SCOPE_HDD) - pattern = "(?i)^.*\.(iso)" + pattern = r"(?i)^.*\.(iso)" self.filelist = FileList(currDir, matchingPattern=pattern) self["filelist"] = self.filelist @@ -53,7 +53,7 @@ def __init__(self, session, scope, configRef): "save": self.ok, "ok": self.ok, "cancel": self.exit - }) + }) # noqa: E123 self["key_red"] = StaticText(_("Cancel")) self["key_green"] = StaticText(_("OK")) self.onLayoutFinish.append(self.layoutFinished) From 42cf0fe1842d2408fa655add85eadbe64a141f67 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 16:13:04 +0200 Subject: [PATCH 047/401] [MediaPlayer][plugin] PEP8 --- .../Plugins/Extensions/MediaPlayer/plugin.py | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py index 44e3350e224..966ef6f8c87 100644 --- a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py @@ -128,7 +128,7 @@ def __init__(self, session, args=None): # 'None' is magic to start at the list of mountpoints defaultDir = config.mediaplayer.defaultDir.getValue() - self.filelist = FileList(defaultDir, matchingPattern="(?i)^.*\.(dts|mp3|wav|wave|wv|oga|ogg|flac|m4a|mp2|m2a|wma|ac3|mka|aac|ape|alac|mpg|vob|m4v|mkv|avi|divx|dat|flv|mp4|mov|wmv|asf|3gp|3g2|mpeg|mpe|rm|rmvb|ogm|ogv|m2ts|mts|ts|m3u|e2pls|pls|amr|au|mid|pva|wtv)", useServiceRef=True, additionalExtensions="4098:m3u 4098:e2pls 4098:pls") + self.filelist = FileList(defaultDir, matchingPattern=r"(?i)^.*\.(dts|mp3|wav|wave|wv|oga|ogg|flac|m4a|mp2|m2a|wma|ac3|mka|aac|ape|alac|mpg|vob|m4v|mkv|avi|divx|dat|flv|mp4|mov|wmv|asf|3gp|3g2|mpeg|mpe|rm|rmvb|ogm|ogv|m2ts|mts|ts|m3u|e2pls|pls|amr|au|mid|pva|wtv)", useServiceRef=True, additionalExtensions="4098:m3u 4098:e2pls 4098:pls") self["filelist"] = self.filelist self.playlist = MyPlayList() @@ -1135,16 +1135,16 @@ def prevBouquet(self): class MediaPlayerLCDScreen(Screen): skin = ( - """ - - - - """, - """ - - - - """) + """ + + + + """, + """ + + + + """) def __init__(self, session, parent): Screen.__init__(self, session) From 589d781b14a471a7479c30cabc7d48c0fd1356eb Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 16:14:17 +0200 Subject: [PATCH 048/401] [PicturePlayer][plugin] PEP8 --- lib/python/Plugins/Extensions/PicturePlayer/plugin.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py index 7df9a4cbe64..7b3d4ee37dc 100644 --- a/lib/python/Plugins/Extensions/PicturePlayer/plugin.py +++ b/lib/python/Plugins/Extensions/PicturePlayer/plugin.py @@ -39,7 +39,7 @@ def checkFile(self, file): paths_to_scan=[ ScanPath(path="DCIM", with_subdirs=True), ScanPath(path="", with_subdirs=False), - ], + ], # noqa: E123 name="Pictures", description=_("View photos..."), openfnc=filescan_open, @@ -54,5 +54,5 @@ def Plugins(**kwargs): PluginDescriptor(name=_("Picture player"), where=PluginDescriptor.WHERE_FILESCAN, needsRestart=False, fnc=filescan)] else: return \ - [PluginDescriptor(name=_("Picture player"), description=_("fileformats (BMP, PNG, JPG, GIF)"), icon="pictureplayer.png", where=PluginDescriptor.WHERE_PLUGINMENU, needsRestart=False, fnc=main), - PluginDescriptor(name=_("Picture player"), where=PluginDescriptor.WHERE_FILESCAN, needsRestart=False, fnc=filescan)] + [PluginDescriptor(name=_("Picture player"), description=_("fileformats (BMP, PNG, JPG, GIF)"), icon="pictureplayer.png", where=PluginDescriptor.WHERE_PLUGINMENU, needsRestart=False, fnc=main), + PluginDescriptor(name=_("Picture player"), where=PluginDescriptor.WHERE_FILESCAN, needsRestart=False, fnc=filescan)] From dbbfc1a03617c0cd5c2d139e9bd0b68142141f6d Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 16:16:23 +0200 Subject: [PATCH 049/401] [PicturePlayer][ui] PEP8 --- lib/python/Plugins/Extensions/PicturePlayer/ui.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Plugins/Extensions/PicturePlayer/ui.py b/lib/python/Plugins/Extensions/PicturePlayer/ui.py index 8c134b952a8..0b905d9ae2c 100644 --- a/lib/python/Plugins/Extensions/PicturePlayer/ui.py +++ b/lib/python/Plugins/Extensions/PicturePlayer/ui.py @@ -69,7 +69,7 @@ def __init__(self, session): if not pathExists(currDir): currDir = "/" - self.filelist = FileList(currDir, matchingPattern="(?i)^.*\.(jpeg|jpg|jpe|png|bmp|gif|svg)") + self.filelist = FileList(currDir, matchingPattern=r"(?i)^.*\.(jpeg|jpg|jpe|png|bmp|gif|svg)") self["filelist"] = self.filelist self["filelist"].onSelectionChanged.append(self.selectionChanged) @@ -493,7 +493,7 @@ def setPicloadConf(self): self.start_decode() def setConf(self, retval=None): - sc = getScale() + # sc = getScale() # 0=Width 1=Height 2=Aspect 3=use_cache 4=resize_type 5=Background(#AARRGGBB) self.picload.setPara([self["pic"].instance.size().width(), self["pic"].instance.size().height(), 1, 1, 0, int(config.pic.resize.value), self.bgcolor, config.pic.autoOrientation.value]) From 48a488a0aaca70a506abaaa6aa889f5cdedcf546 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 16:19:03 +0200 Subject: [PATCH 050/401] [Animations][plugin] don't use l variable PEP8 --- .../Plugins/SystemPlugins/AnimationSetup/plugin.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/python/Plugins/SystemPlugins/AnimationSetup/plugin.py b/lib/python/Plugins/SystemPlugins/AnimationSetup/plugin.py index 533b43ada8e..5ae052e3523 100644 --- a/lib/python/Plugins/SystemPlugins/AnimationSetup/plugin.py +++ b/lib/python/Plugins/SystemPlugins/AnimationSetup/plugin.py @@ -15,7 +15,7 @@ g_default = { "current": 0, "speed": 20, - } + } # noqa: E123 g_max_speed = 30 g_animation_paused = False @@ -51,7 +51,7 @@ def __init__(self, session): "yellow": self.keyYellow, "red": self.keyRed, "cancel": self.keyRed, - }, -2) + }, -2) # noqa: E123 self["key_red"] = StaticText(_("Cancel")) self["key_green"] = StaticText(_("Save")) self["key_yellow"] = StaticText(_("Default")) @@ -155,20 +155,20 @@ def __init__(self, session): "ok": self.ok, "yellow": self.config, "blue": self.preview - }, -3) + }, -3) # noqa: E123 self["list"] = MenuList(self.animationList) self.onLayoutFinish.append(self.layoutFinished) def layoutFinished(self): - l = [] + lani = [] for x in self.animationSetupItems: key = x.get("idx", 0) name = x.get("name", "??") if key == config.misc.window_animation_default.value: name = "* %s" % (name) - l.append((name, key)) + lani.append((name, key)) - self["list"].setList(l) + self["list"].setList(lani) def ok(self): current = self["list"].getCurrent() From 9f629d4c1cfbcfc2756618466457db0e7d3fb878 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 16:21:49 +0200 Subject: [PATCH 051/401] [FastChannelChange][plugin] PEP8 --- .../SystemPlugins/FastChannelChange/plugin.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/python/Plugins/SystemPlugins/FastChannelChange/plugin.py b/lib/python/Plugins/SystemPlugins/FastChannelChange/plugin.py index 4c9e8fb0fa0..8d74b3f03cf 100644 --- a/lib/python/Plugins/SystemPlugins/FastChannelChange/plugin.py +++ b/lib/python/Plugins/SystemPlugins/FastChannelChange/plugin.py @@ -211,7 +211,7 @@ def enableEventTracker(self, activate): iPlayableService.evEnd: self.getEvEnd, iPlayableService.evTunedIn: self.getEvTunedIn, iPlayableService.evTuneFailed: self.getEvTuneFailed - }) + }) # noqa: E123 elif self.__event_tracker: # run ServiceEventTracker.__del_event() @@ -567,19 +567,19 @@ def Plugins(**kwargs): PluginDescriptor(name="FCCSupport", description="Fast Channel Change support", where=[PluginDescriptor.WHERE_SESSIONSTART], - fnc=FCCSupportInit)) + fnc=FCCSupportInit)) # noqa: E122 list.append( PluginDescriptor(name="FCCExtensionMenu", description="Fast Channel Change menu", where=[PluginDescriptor.WHERE_EXTENSIONSINGLE], - fnc=addExtentions)) + fnc=addExtentions)) # noqa: E122 list.append( PluginDescriptor(name=_("FCCSetup"), description=_("Fast Channel Change setup"), - where=[PluginDescriptor.WHERE_MENU], - needsRestart=False, - fnc=main)) + where=[PluginDescriptor.WHERE_MENU], # noqa: E122 + needsRestart=False, # noqa: E122 + fnc=main)) # noqa: E122 return list From fb93157107a60da2a5fe6f0b44c93cbb9faaf206 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 16:23:24 +0200 Subject: [PATCH 052/401] [OpentvZapper][opentv_zapper] PEP8 --- .../Plugins/SystemPlugins/OpentvZapper/opentv_zapper.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Plugins/SystemPlugins/OpentvZapper/opentv_zapper.py b/lib/python/Plugins/SystemPlugins/OpentvZapper/opentv_zapper.py index 900926c2434..71475748318 100644 --- a/lib/python/Plugins/SystemPlugins/OpentvZapper/opentv_zapper.py +++ b/lib/python/Plugins/SystemPlugins/OpentvZapper/opentv_zapper.py @@ -607,8 +607,8 @@ def writeLamedb5(self, path, transponders, filename="lamedb5"): pass if "t2mi_plp_id" in transponder and "t2mi_pid" in transponder: t2mi = ',T2MI:%d:%d' % ( - transponder["t2mi_plp_id"], - transponder["t2mi_pid"]) + transponder["t2mi_plp_id"], # noqa: E122 + transponder["t2mi_pid"]) # noqa: E122 lamedblist.append("s:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d%s%s\n" % (transponder["frequency"], transponder["symbol_rate"], From fd2c4ad31ecd01712c7df9f77ca06e51e93972b5 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 16:24:40 +0200 Subject: [PATCH 053/401] [Satfinder][plugin] PEP8 --- lib/python/Plugins/SystemPlugins/Satfinder/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py b/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py index 7ede92e2d63..a1744d5fbf4 100644 --- a/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py +++ b/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py @@ -8,7 +8,7 @@ from Plugins.Plugin import PluginDescriptor from Screens.MessageBox import MessageBox from Screens.ScanSetup import ScanSetup, buildTerTransponder -from Screens.Screen import Screen # for services found class +from Screens.Screen import Screen # noqa: F401 for services found class from Screens.ServiceScan import ServiceScan from Tools.Transponder import getChannelNumber, channel2frequency from Tools.BoundFunction import boundFunction From d1257f8c43f8d90ac8714d49c1bfb319921c0972 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 16:28:45 +0200 Subject: [PATCH 054/401] [Network] PEP8 --- lib/python/Components/Network.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/Network.py b/lib/python/Components/Network.py index 59df199a75e..70eecc555d2 100644 --- a/lib/python/Components/Network.py +++ b/lib/python/Components/Network.py @@ -1,7 +1,7 @@ from os import listdir, path, system import re import netifaces as ni -from socket import * # 'from socket import *' used; unable to detect undefined names +from socket import * # noqa: F401,F403 'from socket import *' used; unable to detect undefined names from Components.Console import Console from Components.PluginComponent import plugins From b317328c7b832945a164a19a83b4fd46bdb392d4 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 16:29:33 +0200 Subject: [PATCH 055/401] [PackageInfo] PEP8 --- lib/python/Components/PackageInfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/PackageInfo.py b/lib/python/Components/PackageInfo.py index fae814a3d4f..c5f7df325ec 100644 --- a/lib/python/Components/PackageInfo.py +++ b/lib/python/Components/PackageInfo.py @@ -65,7 +65,7 @@ def startElement(self, name, attrs): self.printError("file tag with no name attribute") else: if "directory" not in attrs: - directory = self.directory # what is this? Variable assigned, not used. Is this supposed to be attrs["directory"] = self.directory? + directory = self.directory # noqa: F841 - PackageInfo only use by unused SoftwareManager plugin type = attrs["type"] if type not in self.validFileTypes: self.printError("file tag with invalid type attribute") From 62ea2e571af246e7301880e3432f8236e87e09f0 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 16:32:13 +0200 Subject: [PATCH 056/401] [Canvas] don,t use variable l PEP8 --- lib/python/Components/Renderer/Canvas.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/python/Components/Renderer/Canvas.py b/lib/python/Components/Renderer/Canvas.py index aef12e9726f..aca79ed7145 100644 --- a/lib/python/Components/Renderer/Canvas.py +++ b/lib/python/Components/Renderer/Canvas.py @@ -29,17 +29,17 @@ def pull_updates(self): self.draw_count = len(list[1]) def draw(self, list): - for l in list: - if l[0] == 1: - self.instance.fillRect(eRect(l[1], l[2], l[3], l[4]), gRGB(l[5])) - elif l[0] == 2: - self.instance.writeText(eRect(l[1], l[2], l[3], l[4]), gRGB(l[5]), gRGB(l[6]), l[7], l[8], l[9]) - elif l[0] == 3: - self.instance.drawLine(l[1], l[2], l[3], l[4], gRGB(l[5])) - elif l[0] == 4: - self.instance.drawRotatedLine(l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8], gRGB(l[9])) + for element in list: + if element[0] == 1: + self.instance.fillRect(eRect(element[1], element[2], element[3], element[4]), gRGB(element[5])) + elif element[0] == 2: + self.instance.writeText(eRect(element[1], element[2], element[3], element[4]), gRGB(element[5]), gRGB(element[6]), element[7], element[8], element[9]) + elif element[0] == 3: + self.instance.drawLine(element[1], element[2], element[3], element[4], gRGB(element[5])) + elif element[0] == 4: + self.instance.drawRotatedLine(element[1], element[2], element[3], element[4], element[5], element[6], element[7], element[8], gRGB(element[9])) else: - print("drawlist entry:", l) + print("drawlist entry:", element) raise RuntimeError("invalid drawlist entry") def changed(self, what): From 371a58bc30df24b7c57e7a48a878b6b48d9d1984 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 16:34:58 +0200 Subject: [PATCH 057/401] [AnalogClockLCD] don,t use l variable PEP8 --- lib/python/Components/Renderer/AnalogClockLCD.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/python/Components/Renderer/AnalogClockLCD.py b/lib/python/Components/Renderer/AnalogClockLCD.py index 3b6ca7af3af..eaa96d14d0a 100644 --- a/lib/python/Components/Renderer/AnalogClockLCD.py +++ b/lib/python/Components/Renderer/AnalogClockLCD.py @@ -57,16 +57,16 @@ def hand(self, opt): height = self.positionheight r = (width // 2) r1 = (height // 2) - l = self.linesize + len = self.linesize if opt == 'sec': - l = self.linesize + len = self.linesize self.fColor = self.fColors elif opt == 'min': - l = self.linesize + len = self.linesize self.fColor = self.fColorm else: self.fColor = self.fColorh - (endX, endY,) = self.calc(self.forend, l, r, r1) + (endX, endY,) = self.calc(self.forend, len, r, r1) self.line_draw(r, r1, endX, endY) def line_draw(self, x0, y0, x1, y1): From 03e68d62293696a66d65e6cc708c52f0944acf66 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 16:42:40 +0200 Subject: [PATCH 058/401] [Scanner] don,t use l variable PEP8 --- lib/python/Components/Scanner.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/python/Components/Scanner.py b/lib/python/Components/Scanner.py index 01501a9de72..76be5b9f30f 100644 --- a/lib/python/Components/Scanner.py +++ b/lib/python/Components/Scanner.py @@ -174,11 +174,10 @@ def scanDevice(mountpoint): scanner = [] for p in plugins.getPlugins(PluginDescriptor.WHERE_FILESCAN): - l = p() - if not isinstance(l, list): - l = [l] - scanner += l - + scanDev = p() + if not isinstance(scanDev, list): + scanDev = [scanDev] + scanner += scanDev print("[Scanner] ", scanner) res = {} @@ -227,11 +226,11 @@ def openList(session, files): scanner = [] for p in plugins.getPlugins(PluginDescriptor.WHERE_FILESCAN): - l = p() - if not isinstance(l, list): - scanner.append(l) + scanDev = p() + if not isinstance(scanDev, list): + scanner.append(scanDev) else: - scanner += l + scanner += scanDev print("[Scanner] ", scanner) From 820ee2a029aec7085ad2cb6e434ab90d3304acf7 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 16:55:01 +0200 Subject: [PATCH 059/401] [OscamInfo] some cleanup PEP8 --- lib/python/Screens/OScamInfo.py | 41 ++++++++++++--------------------- 1 file changed, 15 insertions(+), 26 deletions(-) diff --git a/lib/python/Screens/OScamInfo.py b/lib/python/Screens/OScamInfo.py index 6427b8bf0fe..2d5f7da8c5b 100644 --- a/lib/python/Screens/OScamInfo.py +++ b/lib/python/Screens/OScamInfo.py @@ -245,10 +245,10 @@ def readXML(self, typ): for client in clients: name = client.attrib["name"] proto = client.attrib["protocol"] - if "au" in client.attrib: - au = client.attrib["au"] - else: - au = "" + # au = client.attrib["au"] if "au" in client.attrib else "" + # login = client.find("times").attrib["login"] + # online = client.find("times").attrib["online"] + # port = client.find("connection").attrib["port"] caid = client.find("request").attrib["caid"] srvid = client.find("request").attrib["srvid"] if "ecmtime" in client.find("request").attrib: @@ -261,21 +261,13 @@ def readXML(self, typ): ecmtime = _("n/a") srvname = client.find("request").text if srvname is not None: - if ":" in srvname: - srvname_short = srvname.split(":")[1].strip() - else: - srvname_short = srvname - else: - srvname_short = _("n/a") - login = client.find("times").attrib["login"] - online = client.find("times").attrib["online"] + srvname_short = srvname.split(":")[1].strip() if ":" in srvname else srvname if proto.lower() == "dvbapi": ip = "" else: ip = client.find("connection").attrib["ip"] if ip == "0.0.0.0": ip = "" - port = client.find("connection").attrib["port"] connstatus = client.find("connection").text if name != "" and name != "anonymous" and proto != "": try: @@ -423,7 +415,6 @@ def __init__(self, list, itemH=30): class OscamInfoMenu(Screen): def __init__(self, session): Screen.__init__(self, session) - NAMEBIN = check_NAMEBIN() NAMEBIN2 = check_NAMEBIN2() self.setTitle(_("%s Info - Main Menu" % NAMEBIN2)) self.menu = [_("Show Ecm info"), _("Show Clients"), _("Show Readers/Proxies"), _("Show Log"), _("Card info (CCcam-Reader)"), _("Ecm Statistics"), _("Setup")] @@ -585,7 +576,6 @@ def buildMenu(self, mlist): return menuentries def showMenu(self): - NAMEBIN = check_NAMEBIN() entr = self.buildMenu(self.menu) self["mainmenu"].l.setList(entr) self["mainmenu"].moveToIndex(0) @@ -626,7 +616,7 @@ def buildListEntry(self, listentry): def showData(self): dataECM = self.getECMInfo(self.ecminfo) out = [] - y = 0 + # y = 0 for i in dataECM: out.append(self.buildListEntry(i)) self["output"].l.setItemHeight(int(30 * f)) @@ -814,7 +804,6 @@ def buildLogListEntry(self, listentry): return res def showData(self): - NAMEBIN = check_NAMEBIN() NAMEBIN2 = check_NAMEBIN2() if self.firstrun: data = self.webif_data @@ -1133,15 +1122,15 @@ def showData(self): if dataWebif[0]: dataReader = ElementTree.XML(dataWebif[1]) rdr = dataReader.find("reader") -# emms = rdr.find("emmstats") -# if "totalwritten" in emms.attrib: -# emm_wri = emms.attrib["totalwritten"] -# if "totalskipped" in emms.attrib: -# emm_ski = emms.attrib["totalskipped"] -# if "totalblocked" in emms.attrib: -# emm_blk = emms.attrib["totalblocked"] -# if "totalerror" in emms.attrib: -# emm_err = emms.attrib["totalerror"] + # emms = rdr.find("emmstats") + # if "totalwritten" in emms.attrib: + # emm_wri = emms.attrib["totalwritten"] + # if "totalskipped" in emms.attrib: + # emm_ski = emms.attrib["totalskipped"] + # if "totalblocked" in emms.attrib: + # emm_blk = emms.attrib["totalblocked"] + # if "totalerror" in emms.attrib: + # emm_err = emms.attrib["totalerror"] ecmstat = rdr.find("ecmstats") totalecm = ecmstat.attrib["totalecm"] From 268d831e3b40ad7457c21c4f975ee55d355d4b7b Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 17:22:49 +0200 Subject: [PATCH 060/401] [ServicePosition] don,t use l variable PEP8 --- lib/python/Components/ServicePosition.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/python/Components/ServicePosition.py b/lib/python/Components/ServicePosition.py index 15fb48c722c..d0eaf6cfdd6 100644 --- a/lib/python/Components/ServicePosition.py +++ b/lib/python/Components/ServicePosition.py @@ -21,7 +21,7 @@ def __init__(self, navcore, type): }) self.type = type self.relative_base = 0 -# self.setType(type) + # self.setType(type) def newService(self): self.setType(self.type) @@ -57,19 +57,19 @@ def update(self): if seek is not None: if self.type != self.TYPE_RELATIVE: if self.type == self.TYPE_LENGTH: - l = self.get(self.TYPE_LENGTH) + argument = self.get(self.TYPE_LENGTH) elif self.type == self.TYPE_POSITION: - l = self.get(self.TYPE_POSITION) + argument = self.get(self.TYPE_POSITION) elif self.type == self.TYPE_REMAINING: - l = self.get(self.TYPE_LENGTH) - self.get(self.TYPE_POSITION) + argument = self.get(self.TYPE_LENGTH) - self.get(self.TYPE_POSITION) - self.setText("%d:%02d" % (l // 60, l % 60)) + self.setText("%d:%02d" % (argument // 60, argument % 60)) else: - l = self.get(self.TYPE_POSITION) - if l != -1: - l += self.relative_base + argument = self.get(self.TYPE_POSITION) + if argument != -1: + argument += self.relative_base try: - t = time.localtime(l) + t = time.localtime(argument) timestr = "%2d:%02d:%02d" % (t.tm_hour, t.tm_min, t.tm_sec) except ValueError: timestr = "" From b5b29f01c4f882f41a7a5990707e20d28b8b8d30 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 17:23:22 +0200 Subject: [PATCH 061/401] [ServiceList] some cleanup PEP8 --- lib/python/Components/ServiceList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 4e065ebef70..3948a08e799 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -27,7 +27,7 @@ class ServiceList(GUIComponent): def __init__(self, serviceList): self.serviceList = serviceList GUIComponent.__init__(self) - self.l = eListboxServiceContent() + self.l = eListboxServiceContent() # noqa: E741 pic = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/folder.png")) pic and self.l.setPixmap(self.l.picFolder, pic) From 72d53fc28177d79c3cd3f06ef3d133589a4ef49d Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 17:24:37 +0200 Subject: [PATCH 062/401] [HelpMenuList] don,t use l variable PEP8 --- lib/python/Components/Sources/HelpMenuList.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/python/Components/Sources/HelpMenuList.py b/lib/python/Components/Sources/HelpMenuList.py index 0a61c7faa12..08e8cd5ad23 100644 --- a/lib/python/Components/Sources/HelpMenuList.py +++ b/lib/python/Components/Sources/HelpMenuList.py @@ -237,12 +237,12 @@ def _sortHeadingsAlpha(self, a): def ok(self): # a list entry has a "private" tuple as first entry... - l = self.getCurrent() - if l is None: + listEntry = self.getCurrent() + if listEntry is None: return # ...containing (Actionmap, Context, Action, keydata). # we returns this tuple to the callback. - self.callback(l[0], l[1], l[2]) + self.callback(listEntry[0], listEntry[1], listEntry[2]) def handleButton(self, keyId, flag): if keyId not in self.skipKeys: From caa907cc60a05ba6cad57279951f9f50c2e5d8d6 Mon Sep 17 00:00:00 2001 From: Twol Date: Tue, 24 Oct 2023 17:26:50 +0200 Subject: [PATCH 063/401] [Task] import os.F_OK cleanup PEP8 --- lib/python/Components/Task.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/Task.py b/lib/python/Components/Task.py index 43c8ef9587d..b8f3c6733f9 100644 --- a/lib/python/Components/Task.py +++ b/lib/python/Components/Task.py @@ -1,6 +1,6 @@ # A Job consists of many "Tasks". # A task is the run of an external tool, with proper methods for failure handling -from os import access, environ, path as ospath, pathsep, statvfs, F_OK, X_OK, W_OK +from os import access, environ, path as ospath, pathsep, statvfs, X_OK, W_OK from Tools.CList import CList From bea8197de0b58bd56b81812261a54a10df0857af Mon Sep 17 00:00:00 2001 From: Huevos Date: Tue, 24 Oct 2023 21:31:17 +0200 Subject: [PATCH 064/401] [PluginComponent] add sanity text in removePlugin https://github.com/OpenPLi/enigma2/commit/97f97f2def18c383f769ff42a438c4fa850e7ed1 --- lib/python/Components/PluginComponent.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/python/Components/PluginComponent.py b/lib/python/Components/PluginComponent.py index 0b04be850b0..27a731b133b 100644 --- a/lib/python/Components/PluginComponent.py +++ b/lib/python/Components/PluginComponent.py @@ -36,7 +36,8 @@ def removePlugin(self, plugin): if plugin in self.pluginList: self.pluginList.remove(plugin) for x in plugin.where: - self.plugins[x].remove(plugin) + if x in self.plugins: + self.plugins[x].remove(plugin) if x == PluginDescriptor.WHERE_AUTOSTART: plugin(reason=1) From 11ec8c6241f9ced234693f10f83fb96611e2eefb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=CC=88rg=20Bleyel?= Date: Tue, 28 Dec 2021 15:18:19 +0100 Subject: [PATCH 065/401] [ServiceName2] remove duplicate code --- lib/python/Components/Converter/ServiceName2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/Converter/ServiceName2.py b/lib/python/Components/Converter/ServiceName2.py index fccdba6a4f4..5801186bff4 100644 --- a/lib/python/Components/Converter/ServiceName2.py +++ b/lib/python/Components/Converter/ServiceName2.py @@ -532,7 +532,7 @@ def getText(self): return bouq elif self.type == self.PROVIDER: if self.isStream: - if self.refstr and ('%3a//' in self.refstr or '%3a//' in self.refstr): + if self.refstr and ('%3a//' in self.refstr): return self.getIPTVProvider(self.refstr) return self.getIPTVProvider(refstr) else: From 803d932bcc4541cf6339206ff8b58df6e1f173e4 Mon Sep 17 00:00:00 2001 From: Huevos Date: Tue, 24 Oct 2023 22:01:33 +0200 Subject: [PATCH 066/401] [Satfinder] unused import --- lib/python/Plugins/SystemPlugins/Satfinder/plugin.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py b/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py index a1744d5fbf4..437fa3f6651 100644 --- a/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py +++ b/lib/python/Plugins/SystemPlugins/Satfinder/plugin.py @@ -8,7 +8,6 @@ from Plugins.Plugin import PluginDescriptor from Screens.MessageBox import MessageBox from Screens.ScanSetup import ScanSetup, buildTerTransponder -from Screens.Screen import Screen # noqa: F401 for services found class from Screens.ServiceScan import ServiceScan from Tools.Transponder import getChannelNumber, channel2frequency from Tools.BoundFunction import boundFunction From e2d4ee76b160198bbcd8f5d0d8fa43e05a3419da Mon Sep 17 00:00:00 2001 From: Huevos Date: Tue, 24 Oct 2023 22:05:44 +0200 Subject: [PATCH 067/401] [opentv_zapper] attempt to solve indent Thanks @LraiZer --- .../Plugins/SystemPlugins/OpentvZapper/opentv_zapper.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Plugins/SystemPlugins/OpentvZapper/opentv_zapper.py b/lib/python/Plugins/SystemPlugins/OpentvZapper/opentv_zapper.py index 71475748318..705485f650f 100644 --- a/lib/python/Plugins/SystemPlugins/OpentvZapper/opentv_zapper.py +++ b/lib/python/Plugins/SystemPlugins/OpentvZapper/opentv_zapper.py @@ -607,8 +607,8 @@ def writeLamedb5(self, path, transponders, filename="lamedb5"): pass if "t2mi_plp_id" in transponder and "t2mi_pid" in transponder: t2mi = ',T2MI:%d:%d' % ( - transponder["t2mi_plp_id"], # noqa: E122 - transponder["t2mi_pid"]) # noqa: E122 + transponder["t2mi_plp_id"], + transponder["t2mi_pid"]) lamedblist.append("s:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d%s%s\n" % (transponder["frequency"], transponder["symbol_rate"], From 4f1d59cef572f9a21e781e24b9301a91d887741b Mon Sep 17 00:00:00 2001 From: Twol Date: Wed, 25 Oct 2023 07:31:55 +0200 Subject: [PATCH 068/401] SoftwareManagement - remove unused historical plugin --- .../SoftwareManager/BackupRestore.py | 335 --- .../SoftwareManager/ImageWizard.py | 123 - .../SystemPlugins/SoftwareManager/Makefile.am | 21 - .../SoftwareManager/SoftwareTools.py | 277 --- .../SystemPlugins/SoftwareManager/__init__.py | 0 .../SoftwareManager/imagewizard.xml | 103 - .../SystemPlugins/SoftwareManager/install.png | Bin 2176 -> 0 bytes .../SoftwareManager/installable.png | Bin 1399 -> 0 bytes .../SoftwareManager/installed.png | Bin 2092 -> 0 bytes .../SoftwareManager/meta/Makefile.am | 5 - .../meta/plugin_softwaremanager.xml | 22 - .../meta/softwaremanager_de.jpg | Bin 95517 -> 0 bytes .../meta/softwaremanager_en.jpg | Bin 91769 -> 0 bytes .../SystemPlugins/SoftwareManager/noprev.png | Bin 1467 -> 0 bytes .../SystemPlugins/SoftwareManager/plugin.py | 2013 ----------------- .../SystemPlugins/SoftwareManager/remove.png | Bin 2238 -> 0 bytes .../SystemPlugins/SoftwareManager/update.png | Bin 3630 -> 0 bytes .../SystemPlugins/SoftwareManager/upgrade.png | Bin 2640 -> 0 bytes .../SoftwareManager/upgradeable.png | Bin 2092 -> 0 bytes 19 files changed, 2899 deletions(-) delete mode 100644 lib/python/Plugins/SystemPlugins/SoftwareManager/BackupRestore.py delete mode 100644 lib/python/Plugins/SystemPlugins/SoftwareManager/ImageWizard.py delete mode 100644 lib/python/Plugins/SystemPlugins/SoftwareManager/Makefile.am delete mode 100644 lib/python/Plugins/SystemPlugins/SoftwareManager/SoftwareTools.py delete mode 100644 lib/python/Plugins/SystemPlugins/SoftwareManager/__init__.py delete mode 100644 lib/python/Plugins/SystemPlugins/SoftwareManager/imagewizard.xml delete mode 100644 lib/python/Plugins/SystemPlugins/SoftwareManager/install.png delete mode 100644 lib/python/Plugins/SystemPlugins/SoftwareManager/installable.png delete mode 100644 lib/python/Plugins/SystemPlugins/SoftwareManager/installed.png delete mode 100644 lib/python/Plugins/SystemPlugins/SoftwareManager/meta/Makefile.am delete mode 100644 lib/python/Plugins/SystemPlugins/SoftwareManager/meta/plugin_softwaremanager.xml delete mode 100644 lib/python/Plugins/SystemPlugins/SoftwareManager/meta/softwaremanager_de.jpg delete mode 100644 lib/python/Plugins/SystemPlugins/SoftwareManager/meta/softwaremanager_en.jpg delete mode 100644 lib/python/Plugins/SystemPlugins/SoftwareManager/noprev.png delete mode 100644 lib/python/Plugins/SystemPlugins/SoftwareManager/plugin.py delete mode 100644 lib/python/Plugins/SystemPlugins/SoftwareManager/remove.png delete mode 100644 lib/python/Plugins/SystemPlugins/SoftwareManager/update.png delete mode 100644 lib/python/Plugins/SystemPlugins/SoftwareManager/upgrade.png delete mode 100644 lib/python/Plugins/SystemPlugins/SoftwareManager/upgradeable.png diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/BackupRestore.py b/lib/python/Plugins/SystemPlugins/SoftwareManager/BackupRestore.py deleted file mode 100644 index 34d1b7a8526..00000000000 --- a/lib/python/Plugins/SystemPlugins/SoftwareManager/BackupRestore.py +++ /dev/null @@ -1,335 +0,0 @@ -from os import path, makedirs, listdir, stat, rename, remove -from datetime import date - -from Screens.Screen import Screen -from Screens.MessageBox import MessageBox -from Screens.Console import Console -from Components.ActionMap import ActionMap, NumberActionMap -from Components.Sources.StaticText import StaticText -from Components.MenuList import MenuList -from Components.config import configfile, ConfigSubsection, ConfigText, ConfigLocations -from Components.config import config -from Components.ConfigList import ConfigListScreen -from Components.FileList import MultiFileSelectList -from Plugins.Plugin import PluginDescriptor -from enigma import eTimer, eEnv, eEPGCache -from Tools.Directories import * - - -config.plugins.configurationbackup = ConfigSubsection() -config.plugins.configurationbackup.backuplocation = ConfigText(default='/media/hdd/', visible_width=50, fixed_size=False) -config.plugins.configurationbackup.backupdirs = ConfigLocations(default=[eEnv.resolve('${sysconfdir}/enigma2/'), '/etc/network/interfaces', '/etc/wpa_supplicant.conf', '/etc/wpa_supplicant.ath0.conf', '/etc/wpa_supplicant.wlan0.conf', '/etc/resolv.conf', '/etc/default_gw', '/etc/hostname']) - - -def getBackupPath(): - backuppath = config.plugins.configurationbackup.backuplocation.value - if backuppath.endswith('/'): - return backuppath + 'backup' - else: - return backuppath + '/backup' - - -def getBackupFilename(): - return "enigma2settingsbackup.tar.gz" - - -class BackupScreen(ConfigListScreen, Screen): - skin = """ - - - """ - - def __init__(self, session, runBackup=False): - Screen.__init__(self, session) - self.session = session - self.runBackup = runBackup - self["actions"] = ActionMap(["WizardActions", "DirectionActions"], - { - "ok": self.close, - "back": self.close, - "cancel": self.close, - }, -1) - self.finished_cb = None - self.backuppath = getBackupPath() - self.backupfile = getBackupFilename() - self.fullbackupfilename = self.backuppath + "/" + self.backupfile - self.list = [] - ConfigListScreen.__init__(self, self.list) - self.onLayoutFinish.append(self.layoutFinished) - if self.runBackup: - self.onShown.append(self.doBackup) - - def layoutFinished(self): - self.setWindowTitle() - - def setWindowTitle(self): - self.setTitle(_("Backup is running...")) - - def doBackup(self): - configfile.save() - if config.plugins.softwaremanager.epgcache.value: - eEPGCache.getInstance().save() - try: - if not path.exists(self.backuppath): - makedirs(self.backuppath) - self.backupdirs = ' '.join(config.plugins.configurationbackup.backupdirs.value) - if path.exists(self.fullbackupfilename): - dt = str(date.fromtimestamp(stat(self.fullbackupfilename).st_ctime)) - self.newfilename = self.backuppath + "/" + dt + '-' + self.backupfile - if path.exists(self.newfilename): - remove(self.newfilename) - rename(self.fullbackupfilename, self.newfilename) - if self.finished_cb: - self.session.openWithCallback(self.finished_cb, Console, title=_("Backup is running..."), cmdlist=["tar -czvf " + self.fullbackupfilename + " " + self.backupdirs], finishedCallback=self.backupFinishedCB, closeOnSuccess=True) - else: - self.session.open(Console, title=_("Backup is running..."), cmdlist=["tar -czvf " + self.fullbackupfilename + " " + self.backupdirs], finishedCallback=self.backupFinishedCB, closeOnSuccess=True) - except OSError: - if self.finished_cb: - self.session.openWithCallback(self.finished_cb, MessageBox, _("Sorry, your backup destination is not writeable.\nPlease select a different one."), MessageBox.TYPE_INFO, timeout=10) - else: - self.session.openWithCallback(self.backupErrorCB, MessageBox, _("Sorry, your backup destination is not writeable.\nPlease select a different one."), MessageBox.TYPE_INFO, timeout=10) - - def backupFinishedCB(self, retval=None): - self.close(True) - - def backupErrorCB(self, retval=None): - self.close(False) - - def runAsync(self, finished_cb): - self.finished_cb = finished_cb - self.doBackup() - - -class BackupSelection(Screen): - skin = """ - - - - - - - - - """ - - def __init__(self, session): - Screen.__init__(self, session) - self["key_red"] = StaticText(_("Cancel")) - self["key_green"] = StaticText(_("Save")) - self["key_yellow"] = StaticText() - - self.selectedFiles = config.plugins.configurationbackup.backupdirs.value - defaultDir = '/' - inhibitDirs = ["/bin", "/boot", "/dev", "/autofs", "/lib", "/proc", "/sbin", "/sys", "/hdd", "/tmp", "/mnt", "/media"] - self.filelist = MultiFileSelectList(self.selectedFiles, defaultDir, inhibitDirs=inhibitDirs) - self["checkList"] = self.filelist - - self["actions"] = ActionMap(["DirectionActions", "OkCancelActions", "ShortcutActions"], - { - "cancel": self.exit, - "red": self.exit, - "yellow": self.changeSelectionState, - "green": self.saveSelection, - "ok": self.okClicked, - "left": self.left, - "right": self.right, - "down": self.down, - "up": self.up - }, -1) - if not self.selectionChanged in self["checkList"].onSelectionChanged: - self["checkList"].onSelectionChanged.append(self.selectionChanged) - self.onLayoutFinish.append(self.layoutFinished) - - def layoutFinished(self): - idx = 0 - self["checkList"].moveToIndex(idx) - self.setWindowTitle() - self.selectionChanged() - - def setWindowTitle(self): - self.setTitle(_("Select files/folders to backup")) - - def selectionChanged(self): - current = self["checkList"].getCurrent()[0] - if current[2] is True: - self["key_yellow"].setText(_("Deselect")) - else: - self["key_yellow"].setText(_("Select")) - - def up(self): - self["checkList"].up() - - def down(self): - self["checkList"].down() - - def left(self): - self["checkList"].pageUp() - - def right(self): - self["checkList"].pageDown() - - def changeSelectionState(self): - self["checkList"].changeSelectionState() - self.selectedFiles = self["checkList"].getSelectedList() - - def saveSelection(self): - self.selectedFiles = self["checkList"].getSelectedList() - config.plugins.configurationbackup.backupdirs.value = self.selectedFiles - config.plugins.configurationbackup.backupdirs.save() - config.plugins.configurationbackup.save() - config.save() - self.close(None) - - def exit(self): - self.close(None) - - def okClicked(self): - if self.filelist.canDescent(): - self.filelist.descent() - - -class RestoreMenu(Screen): - skin = """ - - - - - - - - - """ - - def __init__(self, session, plugin_path): - Screen.__init__(self, session) - self.skin_path = plugin_path - - self["key_red"] = StaticText(_("Cancel")) - self["key_green"] = StaticText(_("Restore")) - self["key_yellow"] = StaticText(_("Delete")) - - self.sel = [] - self.val = [] - self.entry = False - self.exe = False - - self.path = "" - - self["actions"] = NumberActionMap(["SetupActions"], - { - "ok": self.KeyOk, - "cancel": self.keyCancel - }, -1) - - self["shortcuts"] = ActionMap(["ShortcutActions"], - { - "red": self.keyCancel, - "green": self.KeyOk, - "yellow": self.deleteFile, - }) - self.flist = [] - self["filelist"] = MenuList(self.flist) - self.fill_list() - self.onLayoutFinish.append(self.layoutFinished) - - def layoutFinished(self): - self.setWindowTitle() - - def setWindowTitle(self): - self.setTitle(_("Restore backups")) - - def fill_list(self): - self.flist = [] - self.path = getBackupPath() - if not path.exists(self.path): - makedirs(self.path) - for file in listdir(self.path): - if file.endswith(".tar.gz"): - self.flist.append(file) - self.entry = True - self.flist.sort(reverse=True) - self["filelist"].l.setList(self.flist) - - def KeyOk(self): - if (self.exe == False) and (self.entry == True): - self.sel = self["filelist"].getCurrent() - if self.sel: - self.val = self.path + "/" + self.sel - self.session.openWithCallback(self.startRestore, MessageBox, _("Are you sure you want to restore\nthe following backup:\n%s\nYour receiver will restart after the backup has been restored!") % self.sel) - - def keyCancel(self): - self.close() - - def startRestore(self, ret=False): - if ret: - self.exe = True - self.session.open(Console, title=_("Restoring..."), cmdlist=["tar -xzvf " + self.path + "/" + self.sel + " -C /", "killall -9 enigma2"]) - - def deleteFile(self): - if (self.exe == False) and (self.entry == True): - self.sel = self["filelist"].getCurrent() - if self.sel: - self.val = self.path + "/" + self.sel - self.session.openWithCallback(self.startDelete, MessageBox, _("Are you sure you want to delete\nthe following backup:\n") + self.sel) - - def startDelete(self, ret=False): - if ret: - self.exe = True - print("removing:", self.val) - if path.exists(self.val): - remove(self.val) - self.exe = False - self.fill_list() - - -class RestoreScreen(ConfigListScreen, Screen): - skin = """ - - - """ - - def __init__(self, session, runRestore=False): - Screen.__init__(self, session) - self.session = session - self.runRestore = runRestore - self["actions"] = ActionMap(["WizardActions", "DirectionActions"], - { - "ok": self.close, - "back": self.close, - "cancel": self.close, - }, -1) - self.finished_cb = None - self.backuppath = getBackupPath() - self.backupfile = getBackupFilename() - self.fullbackupfilename = self.backuppath + "/" + self.backupfile - self.list = [] - ConfigListScreen.__init__(self, self.list) - self.onLayoutFinish.append(self.layoutFinished) - if self.runRestore: - self.onShown.append(self.doRestore) - - def layoutFinished(self): - self.setWindowTitle() - - def setWindowTitle(self): - self.setTitle(_("Restoring...")) - - def doRestore(self): - if path.exists("/proc/stb/vmpeg/0/dst_width"): - restorecmdlist = ["tar -xzvf " + self.fullbackupfilename + " -C /", "echo 0 > /proc/stb/vmpeg/0/dst_height", "echo 0 > /proc/stb/vmpeg/0/dst_left", "echo 0 > /proc/stb/vmpeg/0/dst_top", "echo 0 > /proc/stb/vmpeg/0/dst_width", "killall -9 enigma2"] - else: - restorecmdlist = ["tar -xzvf " + self.fullbackupfilename + " -C /", "killall -9 enigma2"] - if self.finished_cb: - self.session.openWithCallback(self.finished_cb, Console, title=_("Restoring..."), cmdlist=restorecmdlist) - else: - self.session.open(Console, title=_("Restoring..."), cmdlist=restorecmdlist) - - def backupFinishedCB(self, retval=None): - self.close(True) - - def backupErrorCB(self, retval=None): - self.close(False) - - def runAsync(self, finished_cb): - self.finished_cb = finished_cb - self.doRestore() diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/ImageWizard.py b/lib/python/Plugins/SystemPlugins/SoftwareManager/ImageWizard.py deleted file mode 100644 index 0a95118247e..00000000000 --- a/lib/python/Plugins/SystemPlugins/SoftwareManager/ImageWizard.py +++ /dev/null @@ -1,123 +0,0 @@ -from os import access, W_OK, R_OK - -from enigma import eEnv - -from Screens.WizardLanguage import WizardLanguage -from Screens.Wizard import wizardManager -from Screens.Rc import Rc -from Tools.Directories import fileExists, resolveFilename, SCOPE_PLUGINS -from Components.Pixmap import Pixmap -from Components.config import config, ConfigSubsection, ConfigText, ConfigLocations, ConfigBoolean -from Components.Harddisk import harddiskmanager - - -config.misc.firstrun = ConfigBoolean(default=True) -config.plugins.configurationbackup = ConfigSubsection() -config.plugins.configurationbackup.backuplocation = ConfigText(default='/media/hdd/', visible_width=50, fixed_size=False) -config.plugins.configurationbackup.backupdirs = ConfigLocations(default=[eEnv.resolve('${sysconfdir}/enigma2/'), '/etc/network/interfaces', '/etc/wpa_supplicant.conf', '/etc/wpa_supplicant.ath0.conf', '/etc/wpa_supplicant.wlan0.conf', '/etc/resolv.conf', '/etc/default_gw', '/etc/hostname']) - - -backupfile = "enigma2settingsbackup.tar.gz" - - -def checkConfigBackup(): - parts = [(r.description, r.mountpoint) for r in harddiskmanager.getMountedPartitions(onlyhotplug=False)] - for x in parts: - if x[1] == '/': - parts.remove(x) - if len(parts): - for x in parts: - if x[1].endswith('/'): - fullbackupfile = x[1] + 'backup/' + backupfile - if fileExists(fullbackupfile): - config.plugins.configurationbackup.backuplocation.value = str(x[1]) - config.plugins.configurationbackup.backuplocation.save() - config.plugins.configurationbackup.save() - return x - else: - fullbackupfile = x[1] + '/backup/' + backupfile - if fileExists(fullbackupfile): - config.plugins.configurationbackup.backuplocation.value = str(x[1]) - config.plugins.configurationbackup.backuplocation.save() - config.plugins.configurationbackup.save() - return x - return None - - -def checkBackupFile(): - backuplocation = config.plugins.configurationbackup.backuplocation.value - if backuplocation.endswith('/'): - fullbackupfile = backuplocation + 'backup/' + backupfile - if fileExists(fullbackupfile): - return True - else: - return False - else: - fullbackupfile = backuplocation + '/backup/' + backupfile - if fileExists(fullbackupfile): - return True - else: - return False - - -if checkConfigBackup() is None: - backupAvailable = 0 -else: - backupAvailable = 1 - - -class ImageWizard(WizardLanguage, Rc): - skin = """ - - - - - - - - - - - - - - - """ - - def __init__(self, session): - self.xmlfile = resolveFilename(SCOPE_PLUGINS, "SystemPlugins/SoftwareManager/imagewizard.xml") - WizardLanguage.__init__(self, session, showSteps=False, showStepSlider=False) - Rc.__init__(self) - self.session = session - self["wizard"] = Pixmap() - self.selectedDevice = None - - def markDone(self): - pass - - def listDevices(self): - list = [(r.description, r.mountpoint) for r in harddiskmanager.getMountedPartitions(onlyhotplug=False)] - for x in list: - result = access(x[1], W_OK) and access(x[1], R_OK) - if result is False or x[1] == '/': - list.remove(x) - for x in list: - if x[1].startswith('/autofs/'): - list.remove(x) - return list - - def deviceSelectionMade(self, index): - self.deviceSelect(index) - - def deviceSelectionMoved(self): - self.deviceSelect(self.selection) - - def deviceSelect(self, device): - self.selectedDevice = device - config.plugins.configurationbackup.backuplocation.value = self.selectedDevice - config.plugins.configurationbackup.backuplocation.save() - config.plugins.configurationbackup.save() - - -if config.misc.firstrun.value: - wizardManager.registerWizard(ImageWizard, backupAvailable, priority=10) diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/Makefile.am b/lib/python/Plugins/SystemPlugins/SoftwareManager/Makefile.am deleted file mode 100644 index 2267b81ae7c..00000000000 --- a/lib/python/Plugins/SystemPlugins/SoftwareManager/Makefile.am +++ /dev/null @@ -1,21 +0,0 @@ -installdir = $(pkglibdir)/python/Plugins/SystemPlugins/SoftwareManager - -SUBDIRS = meta - -install_PYTHON = \ - __init__.py \ - plugin.py \ - BackupRestore.py \ - ImageWizard.py \ - SoftwareTools.py - -dist_install_DATA = \ - imagewizard.xml \ - installable.png \ - installed.png \ - install.png \ - noprev.png \ - remove.png \ - update.png \ - upgradeable.png \ - upgrade.png diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/SoftwareTools.py b/lib/python/Plugins/SystemPlugins/SoftwareManager/SoftwareTools.py deleted file mode 100644 index 294715406c0..00000000000 --- a/lib/python/Plugins/SystemPlugins/SoftwareManager/SoftwareTools.py +++ /dev/null @@ -1,277 +0,0 @@ -# -*- coding: iso-8859-1 -*- -from time import time -from boxbranding import getImageVersion - -from enigma import eConsoleAppContainer - -from Components.Console import Console -from Components.PackageInfo import PackageInfoHandler -from Components.Language import language -from Components.Sources.List import List -from Components.Ipkg import IpkgComponent -from Components.Network import iNetwork -from Tools.Directories import resolveFilename, SCOPE_METADIR -from boxbranding import getBoxType - - -class SoftwareTools(PackageInfoHandler): - lastDownloadDate = None - NetworkConnectionAvailable = None - list_updating = False - available_updates = 0 - available_updatelist = [] - available_packetlist = [] - installed_packetlist = {} - - def __init__(self): - aboutInfo = getImageVersion() - if aboutInfo.startswith("dev-"): - self.ImageVersion = 'Experimental' - else: - self.ImageVersion = 'Stable' - self.language = language.getLanguage()[:2] # getLanguage returns e.g. "fi_FI" for "language_country" - PackageInfoHandler.__init__(self, self.statusCallback, neededTag='ALL_TAGS', neededFlag=self.ImageVersion) - self.directory = resolveFilename(SCOPE_METADIR) - self.list = List([]) - self.NotifierCallback = None - self.Console = Console() - self.UpdateConsole = Console() - self.cmdList = [] - self.unwanted_extensions = ('-dbg', '-dev', '-doc', '-staticdev', '-src') - self.ipkg = IpkgComponent() - self.ipkg.addCallback(self.ipkgCallback) - - def statusCallback(self, status, progress): - pass - - def startSoftwareTools(self, callback=None): - if callback is not None: - self.NotifierCallback = callback - iNetwork.checkNetworkState(self.checkNetworkCB) - - def checkNetworkCB(self, data): - if data is not None: - if data <= 2: - self.NetworkConnectionAvailable = True - self.getUpdates() - else: - self.NetworkConnectionAvailable = False - self.getUpdates() - - def getUpdates(self, callback=None): - if self.lastDownloadDate is None: - if self.NetworkConnectionAvailable: - self.lastDownloadDate = time() - if self.list_updating is False and callback is None: - self.list_updating = True - self.ipkg.startCmd(IpkgComponent.CMD_UPDATE) - elif self.list_updating is False and callback is not None: - self.list_updating = True - self.NotifierCallback = callback - self.ipkg.startCmd(IpkgComponent.CMD_UPDATE) - elif self.list_updating is True and callback is not None: - self.NotifierCallback = callback - else: - self.list_updating = False - if callback is not None: - callback(False) - elif self.NotifierCallback is not None: - self.NotifierCallback(False) - else: - if self.NetworkConnectionAvailable: - self.lastDownloadDate = time() - if self.list_updating is False and callback is None: - self.list_updating = True - self.ipkg.startCmd(IpkgComponent.CMD_UPDATE) - elif self.list_updating is False and callback is not None: - self.list_updating = True - self.NotifierCallback = callback - self.ipkg.startCmd(IpkgComponent.CMD_UPDATE) - elif self.list_updating is True and callback is not None: - self.NotifierCallback = callback - else: - if self.list_updating and callback is not None: - self.NotifierCallback = callback - self.startIpkgListAvailable() - else: - self.list_updating = False - if callback is not None: - callback(False) - elif self.NotifierCallback is not None: - self.NotifierCallback(False) - - def ipkgCallback(self, event, param): - if event == IpkgComponent.EVENT_ERROR: - self.list_updating = False - if self.NotifierCallback is not None: - self.NotifierCallback(False) - elif event == IpkgComponent.EVENT_DONE: - if self.list_updating: - self.startIpkgListAvailable() - pass - - def startIpkgListAvailable(self, callback=None): - if callback is not None: - self.list_updating = True - if self.list_updating: - if not self.UpdateConsole: - self.UpdateConsole = Console() - cmd = self.ipkg.ipkg + " list" - self.UpdateConsole.ePopen(cmd, self.IpkgListAvailableCB, callback) - - def IpkgListAvailableCB(self, result, retval, extra_args=None): - (callback) = extra_args or None - if result: - if self.list_updating: - self.available_packetlist = [] - for x in result.splitlines(): - tokens = x.split(' - ') - name = tokens[0].strip() - if not any(name.endswith(x) for x in self.unwanted_extensions): - l = len(tokens) - version = l > 1 and tokens[1].strip() or "" - descr = l > 2 and tokens[2].strip() or "" - self.available_packetlist.append([name, version, descr]) - if callback is None: - self.startInstallMetaPackage() - else: - if self.UpdateConsole: - if not self.UpdateConsole.appContainers: - callback(True) - else: - self.list_updating = False - if self.UpdateConsole: - if not self.UpdateConsole.appContainers: - if callback is not None: - callback(False) - - def startInstallMetaPackage(self, callback=None): - if callback is not None: - self.list_updating = True - if self.list_updating: - if self.NetworkConnectionAvailable: - if not self.UpdateConsole: - self.UpdateConsole = Console() - cmd = self.ipkg.ipkg + " install enigma2-meta enigma2-plugins-meta enigma2-skins-meta" - self.UpdateConsole.ePopen(cmd, self.InstallMetaPackageCB, callback) - else: - self.InstallMetaPackageCB(True) - - def InstallMetaPackageCB(self, result, retval=None, extra_args=None): - (callback) = extra_args or None - if result: - self.fillPackagesIndexList() - if callback is None: - self.startIpkgListInstalled() - else: - if self.UpdateConsole: - if not self.UpdateConsole.appContainers: - callback(True) - else: - self.list_updating = False - if self.UpdateConsole: - if not self.UpdateConsole.appContainers: - if callback is not None: - callback(False) - - def startIpkgListInstalled(self, callback=None): - if callback is not None: - self.list_updating = True - if self.list_updating: - if not self.UpdateConsole: - self.UpdateConsole = Console() - cmd = self.ipkg.ipkg + " list_installed" - self.UpdateConsole.ePopen(cmd, self.IpkgListInstalledCB, callback) - - def IpkgListInstalledCB(self, result, retval, extra_args=None): - (callback) = extra_args or None - if result: - self.installed_packetlist = {} - for x in result.splitlines(): - tokens = x.split(' - ') - name = tokens[0].strip() - if not any(name.endswith(x) for x in self.unwanted_extensions): - l = len(tokens) - version = l > 1 and tokens[1].strip() or "" - self.installed_packetlist[name] = version - for package in self.packagesIndexlist[:]: - if not self.verifyPrerequisites(package[0]["prerequisites"]): - self.packagesIndexlist.remove(package) - for package in self.packagesIndexlist[:]: - attributes = package[0]["attributes"] - if "packagetype" in attributes: - if attributes["packagetype"] == "internal": - self.packagesIndexlist.remove(package) - if callback is None: - self.countUpdates() - else: - if self.UpdateConsole: - if not self.UpdateConsole.appContainers: - callback(True) - else: - self.list_updating = False - if self.UpdateConsole: - if not self.UpdateConsole.appContainers: - if callback is not None: - callback(False) - - def countUpdates(self, callback=None): - self.available_updates = 0 - self.available_updatelist = [] - for package in self.packagesIndexlist[:]: - attributes = package[0]["attributes"] - packagename = attributes["packagename"] - for x in self.available_packetlist: - if x[0] == packagename: - if packagename in self.installed_packetlist: - if self.installed_packetlist[packagename] != x[1]: - self.available_updates += 1 - self.available_updatelist.append([packagename]) - - self.list_updating = False - if self.UpdateConsole: - if not self.UpdateConsole.appContainers: - if callback is not None: - callback(True) - callback = None - elif self.NotifierCallback is not None: - self.NotifierCallback(True) - self.NotifierCallback = None - - def startIpkgUpdate(self, callback=None): - if not self.Console: - self.Console = Console() - cmd = self.ipkg.ipkg + " update" - self.Console.ePopen(cmd, self.IpkgUpdateCB, callback) - - def IpkgUpdateCB(self, result, retval, extra_args=None): - (callback) = extra_args or None - if result: - if self.Console: - if not self.Console.appContainers: - if callback is not None: - callback(True) - callback = None - - def cleanupSoftwareTools(self): - self.list_updating = False - if self.NotifierCallback is not None: - self.NotifierCallback = None - self.ipkg.stop() - if self.Console is not None: - self.Console.killAll() - if self.UpdateConsole is not None: - self.UpdateConsole.killAll() - - def verifyPrerequisites(self, prerequisites): - if "hardware" in prerequisites: - hardware_found = False - for hardware in prerequisites["hardware"]: - if hardware == getBoxType(): - hardware_found = True - if not hardware_found: - return False - return True - - -iSoftwareTools = SoftwareTools() diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/__init__.py b/lib/python/Plugins/SystemPlugins/SoftwareManager/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/imagewizard.xml b/lib/python/Plugins/SystemPlugins/SoftwareManager/imagewizard.xml deleted file mode 100644 index 374a915c64a..00000000000 --- a/lib/python/Plugins/SystemPlugins/SoftwareManager/imagewizard.xml +++ /dev/null @@ -1,103 +0,0 @@ - - - - -from Plugins.SystemPlugins.SoftwareManager.ImageWizard import checkConfigBackup -self.backuppath = checkConfigBackup() -self.condition = (self.backuppath is not None and config.misc.firstrun.value) - - - - - - - -self.clearSelectedKeys() -self.selectKey("OK") - - - - - - - - - - - - - - - - - - - - - - - - - - - - -self.currStep = self.getStepWithID('backupresult') -self.afterAsyncCode() - - - - - -from Plugins.SystemPlugins.SoftwareManager.ImageWizard import checkBackupFile -self.backuppath = checkBackupFile() -self.condition = (self.backuppath is True) - - - - - - -from Plugins.SystemPlugins.SoftwareManager.ImageWizard import checkBackupFile -self.backuppath = checkBackupFile() -self.condition = (self.backuppath is False) - - - - - - - - - - - - - - - - - - - - - - - - - - - -from enigma import quitMainloop -quitMainloop(1) - - - - - - -self.condition = self.isLastWizard - - - - diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/install.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/install.png deleted file mode 100644 index 1287c35a683e69a7b5cb5d0f197dd339aac7ab84..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2176 zcmd^B`#aMOAO6~$;-TbhNOD{`B@{Yf+E7b#NbMqGB)l^l+sw=~M5&iOn94lr5k>JR zYKvvoT28aZT9l~eP|gae-pAwlJKoQAeeV1ET-SZwKit>-!>2G93D?pv(EtEID*ypQ zZL;&fs}A18=yzLMH_4dbA3+Gg#uJD!X&AsK4tow`5s(s-fI(qm;>fsej5h#)f#74I z{+r^Bjg7kcySQukg64bz<2!LUIrSJBZ%a2s{pLrr< zj!sHReE@OOoDck`14wKGGF~bXUMNvsg9rj}N*g$-O_?ZEBMQ`U9F1#JdTHEkIZ|B` zPnX_jLKm7B3|i**>?#_xsr<6%Qm<{H7+NfGx+ZlkmAO}pcvZ?^)uYF5%OmfPCU6xr z!6&AC?(yQfV(r%=SqLWbmDAdlGrCmL`6}t1szkmzk++5POq1O88>wB3{7gIji59s- zhxBxNX1i_{PcN%OpUN|!b{J%L8q&IqYQ9<)_uG|7omgW3myH7Nm z>gwvs%F6Qc^3u}M!otGr?Ci|U%=Gm1M3Iu}A&Q2bW*WTXF<#IV3&f~|ATU%ROT3VW$ zo12=N8XFrM8XD^B>+9<3YHMq6-@aW_Q^RJntE#H5U%$>`u_`Jm%F4=0OG`^iO0HhL zT3lRQR8&-0SXfX{ke8R2o106g)3dX)sZ=V3LLrmML?V$uAmH(M91e%YVw01Tlai7W z6BFa(R$*hW|D{KIaAiC;{DJC!r7mr-T@CFg4$w;>`!J3ZEpgorsG7n z*p!m_3VU>(ABghC-*MI|d@8C|*ISIDt9Z?--emeV)5c$%JBMPAt+N>Oo;_*QEA*d= z>(5P-Xb<-B2%q1gC%meYRh63-`{zW~6577H1;vOTn^kY)=Eh?k_=WM>e?`AnM_i>M zX756i>eryQ-}?C`w+esoA!l2y_XAE@BoKgnFvx0S{v;f{F_f=GgmhnT7O73AKp5b9BpjBn_AcHhO}kK4Z^KXj>e-u>%A=$%-r`4bfecpsOTl%y8? za}S4waU&zXS+wZad%6-WiZ^%!dQa#&;_Pv+=I;-3n^b$;>;5=Lut0^)dfuHrY>XeU`Cpl?t<$6iYVMDaJ&^Ix-`cc~!aul^d7lxd683~K?dJ)P$3to&!t71krvK5$>nPp;zJ?4iH?jK?lmmRhMGwv`-Am9>GQ zGj|nzd^7IDy~mIQLYLKxF6r%szNlMp_n>nvEGt)!xm$-tCfsIFYrO+dp0@bEYRZ*& zc{`NhhP-NTrTpO-M4#GiT~?Z^mb4P-aKsmi(NU-EyBY``;Gx)4_O*Hei#5xEn$r<0 zy0J=$h#$jahH3@~2AE#TUe-GnJKAQ@&&D4 zlNK{JgKOSwZQ%Er5oVO<8pHkvcJkZC_%kpKBpChvh*EsIaq~+60{oG%2fop{{{WpL Bo*4iD diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/installable.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/installable.png deleted file mode 100644 index a9193039a0645d8ba9e45d7ce05b617cca944a17..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1399 zcmV--1&I2IP)^@R9Fe^mfdSyRTRb7o$q8O=_F~5F~nLFENG2wO^g*Ht%#PY zNvR=U~)5s))vc&j9QoS+BpT<>T?N1IYKA=v4*Vu@+q zjAk2@)}-#$eZ+8GJ7~rEC9tWW^ZHmh^);brLa+_3tpIF5T}A=UCzR!X8e6*6P9`Y~`=UPGaZeuMngQOHKopWLuF}bd7#axr zoei{U6=3JRstS{nv=aVFl{*_#C9V>bwnI6M`ll96{n0>>V4|2{@X|$8&I6Lu95y)O zu=QNVjw&KbjH>v)1gjzEiR$64K$aZQg=tm(XV`C&7$r#NssDg1%=xJD01KKLe1Rtu zn3?4N)Dn}H5Nvh^Y&r|N!p59pVa)(kU`4dC$#qgQQMBegRe`ZZPOGz${$gdfdg8^J zV~ZPB4OONVm}C_mg=kD8^mOPKZ`(M%C1RT8%o9t|$5sR+&>O7lE`3`M2u|H$g=Ti- zNm+_jP{G3wsQV5!iM)QIKy&`7Sv7}{f~PS-0_s)Wtu1wU)?0U+4F+6}#2SI6x&)1- zbryRbhU80LIc55 zkpCHdNR$>!nO4g0t_PO98yW~s2SaX>!BNfxT8ktuj#2BVq9U8z1ou{+Ij(Ucy8=Zm zV;ORgtd~!#fk3*A-F_0747w^*jjf41Ln8p5W9`~PtDram@F;O6^$qX0RwQinR@HNa z5M*?#eh1b8G4CUZqGJ}ihnQ<_Tg_B>X3Bdg-7*wb2))|B#GsIcCLIcPV9~XO6)?@+ z6!uJG%5k3s+eGrdZ4%Ntt2aq*mip=RlEJ+b4*Lqiu)`?==nmAk=j{r zQ4Cw!@ckgPn=o{X9&gYengi*T;4ODuzfp{nC~fgI74x=?@jlCX$`sd5&M9(pmu}Ym zAqlRTSs&3t>qXbEkJ#!aiJ}UGz0(4&w$AtJ2{O@w=M}w=k!jt|r%P44L-dE{z&KtH z{?yaDlc~K_M~sBqa(_3IbWcHY)febxQhJA{J4`Iw`6$TprT6?Y zD4|t!Bcz?dLE^|^#U*NIhAc#(I)wf{JqgvA29^O|MFcgf18zGdc@d&{UpGbG4oM99 zPRCY&U(uo)u}H(N8}H}HhV4LSR)k(WckO=7f&aGy{{r}KwNP75A0Ge!002ovPDHLk FV1m=Vl6wFE diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/installed.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/installed.png deleted file mode 100644 index 75dfc4f33a18dee2db7037662cfe93949b62f256..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2092 zcmd^A`#;l*AO0Y>PR?pX2*?eBZCv`*~jP*XwzHdtT2w$;r`1=HRaf0RWIe*jgd? z+30^OCAN>4Y3cfXQYFJtWS1acaws+!4?ul_aQI^gBGwO&#AAKJZujCZ0e~3b3Efi7zBu(B}ty&H{O=MKt5!CR}r41hRj#Bdvwe( zRnMDo$c!v=Ib04(k++Oiw2o1-iPLn;JmryR9Q^ij9NW+<>w+K6^)Xx7E?&hUQ5~78 zM`}4wtZhhYjYDwHEgqq4CYu58Ey8*V<=v+oip; zOMUB{%XG;f_HX_3Wv-+!J zZol)>VK?e1rkaZ_`H(s!)PX>+)5bksuu-KfborFmi*X;ud|<# zjPK=5^LJ3m#f*g=L~M4}{O+HflbNH7i(B7=D;j#2*Gz8(KI~_DKPzbyg7AA`)w7fB zOS6>LD*6o56z`h;;dMx5y7gUD$z=7+=4|s)(+K}V$SY#{U=k|zT5uh@d5PwgeT6=i zoACD&`az*7v6X{rb9iYPy12Ng`6SF=VKn3ACKpaoh_PE@7cV=*{#iBi9Vk= z&sadPcQQWh7U!{)YnIQqEZpSmmHe|;zOvWF7qZwtVwb@x9$4QmaNvOHD`4}q(0>^$ z=7H3~-4hF7>^j)C3HI{9%vBJ*4&D)fDf`JsPUw#TfCxZFI=bwi|IY)s2qd-kd!Yeg z1$DLUUdgs6sJSU7FrOxNZ>&$$a5|;kd8n8s-Lj!lE2{(kawhO-WlwNLsw3*O=utp$rjNgQi+Xn)U1^G@u7);l{$Ne~fN`!K|1)5D4zp+fiLMs5*QZvyT6qnxu!f&8mqCSoIJvBM9?a7;L?ubg68BCXS%##A*L-#bq$?P6w7WV_%PKUz5a0wDeRr=*0Cj==^oMz(O>7 zWy)K$b|laYkk@{&^gjO=z)I<*Z`(YeP$%9~NS$+6k%eMJ5)y$nSEvWx?j#^uz>|r! zm7P&Q0V5LJfb?pEn<#OkEvo-N>U2>hNeUW)X+_kAnVcA z{pHQ!C$U!|o%07&6lsCd{Fo4Rt|s}KrNN;4B{30WahL=32LHhpHepn$QxaSTRZto; z))Jnaes}fls#yzX2&v$wp4EVcm5(ze)l;83uE+&Kiq+;29y?nsf7Lc%)YLnDy{72* zmy<-9&!2bcxaF*w1Xn~rUV_LOeF>OCq1JHeVpELaDY5uEp4;p7rY?QuFcLPkogNjY z^-g_a%_nGFAqE*9Lh;PWZVOJ}$PgHcD>vcZR6e8-$F;T7_JJE0gb$vKoc-DlWcJiOv diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/meta/Makefile.am b/lib/python/Plugins/SystemPlugins/SoftwareManager/meta/Makefile.am deleted file mode 100644 index bf064c29470..00000000000 --- a/lib/python/Plugins/SystemPlugins/SoftwareManager/meta/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -installdir = $(datadir)/meta - -dist_install_DATA = plugin_softwaremanager.xml - -EXTRA_DIST = softwaremanager_en.jpg softwaremanager_de.jpg diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/meta/plugin_softwaremanager.xml b/lib/python/Plugins/SystemPlugins/SoftwareManager/meta/plugin_softwaremanager.xml deleted file mode 100644 index 0b0f7a67ce1..00000000000 --- a/lib/python/Plugins/SystemPlugins/SoftwareManager/meta/plugin_softwaremanager.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - Dream Multimedia - SoftwareManager - enigma2-plugin-systemplugins-softwaremanager - Software manager manages your receiver software - The software manager manages your receiver's software.\n - It's easy to update your receiver's software, install or remove plugins or even backup and restore your system settings. - - - - - - - - - diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/meta/softwaremanager_de.jpg b/lib/python/Plugins/SystemPlugins/SoftwareManager/meta/softwaremanager_de.jpg deleted file mode 100644 index 54e6419691606cf3a96a6d1a43cf6b85f9575c98..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 95517 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

M?EHm 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

rHS{?l4S3NIUhgT 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 diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/meta/softwaremanager_en.jpg b/lib/python/Plugins/SystemPlugins/SoftwareManager/meta/softwaremanager_en.jpg deleted file mode 100644 index 0832f0ac8c67922d440f87be026dbe7b2bc3c62e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 91769 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

HrPp=j8Zyn6^#P`ALf+k)c_bY)`?;+)@i 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 br%74` cache_ttl: - return 0 - else: - return 1 - - -def load_cache(cache_file): - #Does a pickle load - fd = open(cache_file) - cache_data = load(fd) - fd.close() - return cache_data - - -class UpdatePluginMenu(Screen): - skin = """ - - - - - - - {"template": [ - MultiContentEntryText(pos = (2, 2), size = (330, 24), flags = RT_HALIGN_LEFT, text = 1), # index 0 is the MenuText, - ], - "fonts": [gFont("Regular", 22)], - "itemHeight": 25 - } - - - - - {"template": [ - MultiContentEntryText(pos = (2, 2), size = (240, 300), flags = RT_HALIGN_CENTER|RT_VALIGN_CENTER|RT_WRAP, text = 2), # index 2 is the Description, - ], - "fonts": [gFont("Regular", 22)], - "itemHeight": 300 - } - - - - """ - - def __init__(self, session, args=0): - Screen.__init__(self, session) - Screen.setTitle(self, _("Software management")) - self.skin_path = plugin_path - self.menu = args - self.list = [] - self.oktext = _("\nPress OK on your remote control to continue.") - self.menutext = _("Press MENU on your remote control for additional options.") - self.infotext = _("Press INFO on your remote control for additional information.") - self.text = "" - self.backupdirs = ' '.join(config.plugins.configurationbackup.backupdirs.value) - if self.menu == 0: - print("building menu entries") - self.list.append(("install-extensions", _("Manage extensions"), _("\nManage extensions or plugins for your %s %s") % (getMachineBrand(), getMachineName()) + self.oktext, None)) - self.list.append(("software-update", _("Software update"), _("\nOnline update of your %s %s software.") % (getMachineBrand(), getMachineName()) + self.oktext, None)) - self.list.append(("software-restore", _("Software restore"), _("\nRestore your %s %s with a new firmware.") % (getMachineBrand(), getMachineName()) + self.oktext, None)) - self.list.append(("system-backup", _("Backup system settings"), _("\nBackup your %s %s settings.") % (getMachineBrand(), getMachineName()) + self.oktext + "\n\n" + self.infotext, None)) - self.list.append(("system-restore", _("Restore system settings"), _("\nRestore your %s %s settings.") % (getMachineBrand(), getMachineName()) + self.oktext, None)) - self.list.append(("ipkg-install", _("Install local extension"), _("\nScan for local extensions and install them.") + self.oktext, None)) - for p in plugins.getPlugins(PluginDescriptor.WHERE_SOFTWAREMANAGER): - if "SoftwareSupported" in p.fnc: - callFnc = p.fnc["SoftwareSupported"](None) - if callFnc is not None: - if "menuEntryName" in p.fnc: - menuEntryName = p.fnc["menuEntryName"](None) - else: - menuEntryName = _('Extended Software') - if "menuEntryDescription" in p.fnc: - menuEntryDescription = p.fnc["menuEntryDescription"](None) - else: - menuEntryDescription = _('Extended Software Plugin') - self.list.append(('default-plugin', menuEntryName, menuEntryDescription + self.oktext, callFnc)) - if config.usage.setup_level.index >= 2: # expert+ - self.list.append(("advanced", _("Advanced options"), _("\nAdvanced options and settings.") + self.oktext, None)) - elif self.menu == 1: - self.list.append(("advancedrestore", _("Advanced restore"), _("\nRestore your backups by date.") + self.oktext, None)) - self.list.append(("backuplocation", _("Select backup location"), _("\nSelect your backup device.\nCurrent device: ") + config.plugins.configurationbackup.backuplocation.value + self.oktext, None)) - self.list.append(("backupfiles", _("Select backup files"), _("Select files for backup.") + self.oktext + "\n\n" + self.infotext, None)) - if config.usage.setup_level.index >= 2: # expert+ - self.list.append(("ipkg-manager", _("Packet management"), _("\nView, install and remove available or installed packages.") + self.oktext, None)) - self.list.append(("ipkg-source", _("Select upgrade source"), _("\nEdit the upgrade source address.") + self.oktext, None)) - for p in plugins.getPlugins(PluginDescriptor.WHERE_SOFTWAREMANAGER): - if "AdvancedSoftwareSupported" in p.fnc: - callFnc = p.fnc["AdvancedSoftwareSupported"](None) - if callFnc is not None: - if "menuEntryName" in p.fnc: - menuEntryName = p.fnc["menuEntryName"](None) - else: - menuEntryName = _('Advanced software') - if "menuEntryDescription" in p.fnc: - menuEntryDescription = p.fnc["menuEntryDescription"](None) - else: - menuEntryDescription = _('Advanced software plugin') - self.list.append(('advanced-plugin', menuEntryName, menuEntryDescription + self.oktext, callFnc)) - - self["menu"] = List(self.list) - self["key_red"] = StaticText(_("Close")) - self["key_menu"] = StaticText(_("MENU")) - self["status"] = StaticText(self.menutext) - - self["shortcuts"] = NumberActionMap(["ShortcutActions", "WizardActions", "InfobarEPGActions", "MenuActions", "NumberActions"], - { - "ok": self.go, - "back": self.close, - "red": self.close, - "menu": self.handleMenu, - "showEventInfo": self.handleInfo, - "1": self.go, - "2": self.go, - "3": self.go, - "4": self.go, - "5": self.go, - "6": self.go, - "7": self.go, - "8": self.go, - "9": self.go, - }, -1) - self.onLayoutFinish.append(self.layoutFinished) - self.backuppath = getBackupPath() - self.backupfile = getBackupFilename() - self.fullbackupfilename = self.backuppath + "/" + self.backupfile - self.onShown.append(self.setWindowTitle) - self.onChangedEntry = [] - self["menu"].onSelectionChanged.append(self.selectionChanged) - - def createSummary(self): - from Screens.PluginBrowser import PluginBrowserSummary - return PluginBrowserSummary - - def selectionChanged(self): - item = self["menu"].getCurrent() - if item: - name = item[1] - desc = item[2] - else: - name = "-" - desc = "" - for cb in self.onChangedEntry: - cb(name, desc) - - def layoutFinished(self): - idx = 0 - self["menu"].index = idx - - def setWindowTitle(self): - self.setTitle(_("Software management")) - - def cleanup(self): - iSoftwareTools.cleanupSoftwareTools() - - def getUpdateInfos(self): - if iSoftwareTools.NetworkConnectionAvailable is True: - if iSoftwareTools.available_updates is not 0: - self.text = _("There are at least %s updates available.") % (str(iSoftwareTools.available_updates)) - else: - self.text = "" # _("There are no updates available.") - if iSoftwareTools.list_updating is True: - self.text += "\n" + _("A search for available updates is currently in progress.") - else: - self.text = _("No network connection available.") - self["status"].setText(self.text) - - def handleMenu(self): - self.session.open(SoftwareManagerSetup) - - def handleInfo(self): - current = self["menu"].getCurrent() - if current: - currentEntry = current[0] - if currentEntry in ("system-backup", "backupfiles"): - self.session.open(SoftwareManagerInfo, mode="backupinfo") - - def go(self, num=None): - if num is not None: - num -= 1 - if not num < self["menu"].count(): - return - self["menu"].setIndex(num) - current = self["menu"].getCurrent() - if current: - currentEntry = current[0] - if self.menu == 0: - if currentEntry == "software-update": - self.session.open(UpdatePlugin) - elif currentEntry == "software-restore": - self.session.open(ImageWizard) - elif currentEntry == "install-extensions": - self.session.open(PluginManager, self.skin_path) - elif currentEntry == "system-backup": - self.session.openWithCallback(self.backupDone, BackupScreen, runBackup=True) - elif currentEntry == "system-restore": - if os_path.exists(self.fullbackupfilename): - self.session.openWithCallback(self.startRestore, MessageBox, _("Are you sure you want to restore the backup?\nYour receiver will restart after the backup has been restored!")) - else: - self.session.open(MessageBox, _("Sorry, no backups found!"), MessageBox.TYPE_INFO, timeout=10) - elif currentEntry == "ipkg-install": - try: - from Plugins.Extensions.MediaScanner.plugin import main - main(self.session) - except: - self.session.open(MessageBox, _("Sorry, %s has not been installed!") % "MediaScanner", MessageBox.TYPE_INFO, timeout=10) - elif currentEntry == "default-plugin": - self.extended = current[3] - self.extended(self.session, None) - elif currentEntry == "advanced": - self.session.open(UpdatePluginMenu, 1) - elif self.menu == 1: - if currentEntry == "ipkg-manager": - self.session.open(PacketManager, self.skin_path) - elif currentEntry == "backuplocation": - parts = [(r.description, r.mountpoint, self.session) for r in harddiskmanager.getMountedPartitions(onlyhotplug=False)] - for x in parts: - if not access(x[1], F_OK | R_OK | W_OK) or x[1] == '/': - parts.remove(x) - if len(parts): - self.session.openWithCallback(self.backuplocation_choosen, ChoiceBox, title=_("Please select medium to use as backup location"), list=parts) - elif currentEntry == "backupfiles": - self.session.openWithCallback(self.backupfiles_choosen, BackupSelection) - elif currentEntry == "advancedrestore": - self.session.open(RestoreMenu, self.skin_path) - elif currentEntry == "ipkg-source": - self.session.open(IPKGMenu, self.skin_path) - elif currentEntry == "advanced-plugin": - self.extended = current[3] - self.extended(self.session, None) - - def backupfiles_choosen(self, ret): - self.backupdirs = ' '.join(config.plugins.configurationbackup.backupdirs.value) - config.plugins.configurationbackup.backupdirs.save() - config.plugins.configurationbackup.save() - config.save() - - def backuplocation_choosen(self, option): - oldpath = config.plugins.configurationbackup.backuplocation.value - if option is not None: - config.plugins.configurationbackup.backuplocation.value = str(option[1]) - config.plugins.configurationbackup.backuplocation.save() - config.plugins.configurationbackup.save() - config.save() - newpath = config.plugins.configurationbackup.backuplocation.value - if newpath != oldpath: - self.createBackupfolders() - - def createBackupfolders(self): - print("Creating backup folder if not already there...") - self.backuppath = getBackupPath() - try: - if not os_path.exists(self.backuppath): - makedirs(self.backuppath) - except OSError: - self.session.open(MessageBox, _("Sorry, your backup destination is not writeable.\nPlease select a different one."), MessageBox.TYPE_INFO, timeout=10) - - def backupDone(self, retval=None): - if retval is True: - self.session.open(MessageBox, _("Backup completed."), MessageBox.TYPE_INFO, timeout=10) - else: - self.session.open(MessageBox, _("Backup failed."), MessageBox.TYPE_INFO, timeout=10) - - def startRestore(self, ret=False): - if ret: - self.exe = True - self.session.open(RestoreScreen, runRestore=True) - - -class SoftwareManagerSetup(ConfigListScreen, Screen): - - skin = """ - - - - - - - - - - - - - """ - - def __init__(self, session, skin_path=None): - Screen.__init__(self, session) - self.session = session - self.skin_path = skin_path - if self.skin_path is None: - self.skin_path = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager") - - self.onChangedEntry = [] - self.setup_title = _("Software manager setup") - self.overwriteConfigfilesEntry = None - - self.list = [] - ConfigListScreen.__init__(self, self.list, session=session, on_change=self.changedEntry) - - self["actions"] = ActionMap(["SetupActions", "MenuActions"], - { - "cancel": self.keyCancel, - "save": self.apply, - "menu": self.closeRecursive, - }, -2) - - self["key_red"] = StaticText(_("Cancel")) - self["key_green"] = StaticText(_("OK")) - self["key_yellow"] = StaticText() - self["key_blue"] = StaticText() - self["introduction"] = StaticText() - - self.createSetup() - self.onLayoutFinish.append(self.layoutFinished) - - def layoutFinished(self): - self.setTitle(self.setup_title) - - def createSetup(self): - self.list = [] - self.overwriteConfigfilesEntry = getConfigListEntry(_("Overwrite configuration files?"), config.plugins.softwaremanager.overwriteConfigFiles) - self.list.append(self.overwriteConfigfilesEntry) - self.list.append(getConfigListEntry(_("show softwaremanager in plugin menu"), config.plugins.softwaremanager.onSetupMenu)) - self.list.append(getConfigListEntry(_("show softwaremanager on blue button"), config.plugins.softwaremanager.onBlueButton)) - self.list.append(getConfigListEntry(_("epg cache backup"), config.plugins.softwaremanager.epgcache)) - - self["config"].list = self.list - self["config"].l.setSeperation(400) - if not self.selectionChanged in self["config"].onSelectionChanged: - self["config"].onSelectionChanged.append(self.selectionChanged) - self.selectionChanged() - - def selectionChanged(self): - if self["config"].getCurrent() == self.overwriteConfigfilesEntry: - self["introduction"].setText(_("Overwrite configuration files during software upgrade?")) - else: - self["introduction"].setText("") - - def newConfig(self): - pass - - def keyLeft(self): - ConfigListScreen.keyLeft(self) - - def keyRight(self): - ConfigListScreen.keyRight(self) - - def confirm(self, confirmed): - if not confirmed: - print("not confirmed") - return - else: - self.keySave() - plugins.clearPluginList() - plugins.readPluginList(resolveFilename(SCOPE_PLUGINS)) - - def apply(self): - self.session.openWithCallback(self.confirm, MessageBox, _("Use these settings?"), MessageBox.TYPE_YESNO, timeout=20, default=True) - - 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?"), MessageBox.TYPE_YESNO, timeout=20, default=False) - else: - self.close() - - # for summary: - def changedEntry(self): - for x in self.onChangedEntry: - x() - self.selectionChanged() - - def getCurrentEntry(self): - return self["config"].getCurrent()[0] - - def getCurrentValue(self): - return str(self["config"].getCurrent()[1].value) - - def createSummary(self): - from Screens.Setup import SetupSummary - return SetupSummary - - -class SoftwareManagerInfo(Screen): - skin = """ - - - - - - - - - - - - {"template": [ - MultiContentEntryText(pos = (5, 0), size = (540, 26), font=0, flags = RT_HALIGN_LEFT | RT_HALIGN_CENTER, text = 0), # index 0 is the name - ], - "fonts": [gFont("Regular", 24),gFont("Regular", 22)], - "itemHeight": 26 - } - - - - - """ - - def __init__(self, session, skin_path=None, mode=None): - Screen.__init__(self, session) - self.session = session - self.mode = mode - self.skin_path = skin_path - if self.skin_path is None: - self.skin_path = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager") - - self["actions"] = ActionMap(["ShortcutActions", "WizardActions"], - { - "back": self.close, - "red": self.close, - }, -2) - - self.list = [] - self["list"] = List(self.list) - - self["key_red"] = StaticText(_("Close")) - self["key_green"] = StaticText() - self["key_yellow"] = StaticText() - self["key_blue"] = StaticText() - self["introduction"] = StaticText() - - self.onLayoutFinish.append(self.layoutFinished) - - def layoutFinished(self): - self.setTitle(_("Softwaremanager information")) - if self.mode is not None: - self.showInfos() - - def showInfos(self): - if self.mode == "backupinfo": - self.list = [] - backupfiles = config.plugins.configurationbackup.backupdirs.value - for entry in backupfiles: - self.list.append((entry,)) - self['list'].setList(self.list) - - -class PluginManager(Screen, PackageInfoHandler): - - skin = """ - - - - - - - - - - - - {"templates": - {"default": (51,[ - MultiContentEntryText(pos = (0, 1), size = (470, 24), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name - MultiContentEntryText(pos = (0, 25), size = (470, 24), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description - MultiContentEntryPixmapAlphaTest(pos = (475, 0), size = (48, 48), png = 5), # index 5 is the status pixmap - MultiContentEntryPixmapAlphaTest(pos = (0, 49), size = (550, 2), png = 6), # index 6 is the div pixmap - ]), - "category": (40,[ - MultiContentEntryText(pos = (30, 0), size = (500, 22), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name - MultiContentEntryText(pos = (30, 22), size = (500, 16), font=2, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the description - MultiContentEntryPixmapAlphaTest(pos = (0, 38), size = (550, 2), png = 3), # index 3 is the div pixmap - ]) - }, - "fonts": [gFont("Regular", 22),gFont("Regular", 20),gFont("Regular", 16)], - "itemHeight": 52 - } - - - - """ - - def __init__(self, session, plugin_path=None, args=None): - Screen.__init__(self, session) - Screen.setTitle(self, _("Extensions management")) - self.session = session - self.skin_path = plugin_path - if self.skin_path is None: - self.skin_path = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager") - - self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions", "InfobarEPGActions", "HelpActions"], - { - "ok": self.handleCurrent, - "back": self.exit, - "red": self.exit, - "green": self.handleCurrent, - "yellow": self.handleSelected, - "showEventInfo": self.handleSelected, - "displayHelp": self.handleHelp, - }, -1) - - self.list = [] - self.statuslist = [] - self.selectedFiles = [] - self.categoryList = [] - self.packetlist = [] - self["list"] = List(self.list) - self["key_red"] = StaticText(_("Close")) - self["key_green"] = StaticText("") - self["key_yellow"] = StaticText("") - self["key_blue"] = StaticText("") - self["status"] = StaticText("") - - self.cmdList = [] - self.oktext = _("\nAfter pressing OK, please wait!") - if not self.selectionChanged in self["list"].onSelectionChanged: - self["list"].onSelectionChanged.append(self.selectionChanged) - - self.currList = "" - self.currentSelectedTag = None - self.currentSelectedIndex = None - self.currentSelectedPackage = None - self.saved_currentSelectedPackage = None - self.restartRequired = False - - self.onShown.append(self.setWindowTitle) - self.onLayoutFinish.append(self.getUpdateInfos) - - def setWindowTitle(self): - self.setTitle(_("Extensions management")) - - def exit(self): - if self.currList == "packages": - self.currList = "category" - self.currentSelectedTag = None - self["list"].style = "category" - self['list'].setList(self.categoryList) - self["list"].setIndex(self.currentSelectedIndex) - self["list"].updateList(self.categoryList) - self.selectionChanged() - else: - iSoftwareTools.cleanupSoftwareTools() - self.prepareInstall() - if len(self.cmdList): - self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList) - else: - self.close() - - def handleHelp(self): - if self.currList != "status": - self.session.open(PluginManagerHelp, self.skin_path) - - def setState(self, status=None): - if status: - self.currList = "status" - self.statuslist = [] - self["key_green"].setText("") - self["key_blue"].setText("") - self["key_yellow"].setText("") - divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "div-h.png")) - if status == 'update': - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/upgrade.png")): - statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/upgrade.png")) - else: - statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png")) - self.statuslist.append((_("Updating software catalog"), '', _("Searching for available updates. Please wait..."), '', '', statuspng, divpng, None, '')) - elif status == 'sync': - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/upgrade.png")): - statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/upgrade.png")) - else: - statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png")) - self.statuslist.append((_("Package list update"), '', _("Searching for new installed or removed packages. Please wait..."), '', '', statuspng, divpng, None, '')) - elif status == 'error': - self["key_green"].setText(_("Continue")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/remove.png")): - statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/remove.png")) - else: - statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png")) - self.statuslist.append((_("Error"), '', _("An error occurred while downloading the packetlist. Please try again."), '', '', statuspng, divpng, None, '')) - self["list"].style = "default" - self['list'].setList(self.statuslist) - - def getUpdateInfos(self): - if iSoftwareTools.lastDownloadDate is not None and iSoftwareTools.NetworkConnectionAvailable is False: - self.rebuildList() - else: - self.setState('update') - iSoftwareTools.startSoftwareTools(self.getUpdateInfosCB) - - def getUpdateInfosCB(self, retval=None): - if retval is not None: - if retval is True: - if iSoftwareTools.available_updates is not 0: - self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + ' ' + _("updates available.")) - else: - self["status"].setText(_("There are no updates available.")) - self.rebuildList() - elif retval is False: - if iSoftwareTools.lastDownloadDate is None: - self.setState('error') - if iSoftwareTools.NetworkConnectionAvailable: - self["status"].setText(_("Updatefeed not available.")) - else: - self["status"].setText(_("No network connection available.")) - else: - iSoftwareTools.lastDownloadDate = time() - iSoftwareTools.list_updating = True - self.setState('update') - iSoftwareTools.getUpdates(self.getUpdateInfosCB) - - def rebuildList(self, retval=None): - if self.currentSelectedTag is None: - self.buildCategoryList() - else: - self.buildPacketList(self.currentSelectedTag) - - def selectionChanged(self): - current = self["list"].getCurrent() - self["status"].setText("") - if current: - if self.currList == "packages": - self["key_red"].setText(_("Back")) - if current[4] == 'installed': - self["key_green"].setText(_("Uninstall")) - elif current[4] == 'installable': - self["key_green"].setText(_("Install")) - if iSoftwareTools.NetworkConnectionAvailable is False: - self["key_green"].setText("") - elif current[4] == 'remove': - self["key_green"].setText(_("Undo uninstall")) - elif current[4] == 'install': - self["key_green"].setText(_("Undo install")) - if iSoftwareTools.NetworkConnectionAvailable is False: - self["key_green"].setText("") - self["key_yellow"].setText(_("View details")) - self["key_blue"].setText("") - if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0: - self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + ' ' + _("updates available.")) - elif len(self.selectedFiles) is not 0: - self["status"].setText(str(len(self.selectedFiles)) + ' ' + _("packages selected.")) - else: - self["status"].setText(_("There are currently no outstanding actions.")) - elif self.currList == "category": - self["key_red"].setText(_("Close")) - self["key_green"].setText("") - self["key_yellow"].setText("") - self["key_blue"].setText("") - if len(self.selectedFiles) == 0 and iSoftwareTools.available_updates is not 0: - self["status"].setText(_("There are at least ") + str(iSoftwareTools.available_updates) + ' ' + _("updates available.")) - self["key_yellow"].setText(_("Update")) - elif len(self.selectedFiles) is not 0: - self["status"].setText(str(len(self.selectedFiles)) + ' ' + _("packages selected.")) - self["key_yellow"].setText(_("Process")) - else: - self["status"].setText(_("There are currently no outstanding actions.")) - - def getSelectionState(self, detailsFile): - for entry in self.selectedFiles: - if entry[0] == detailsFile: - return True - return False - - def handleCurrent(self): - current = self["list"].getCurrent() - if current: - if self.currList == "category": - self.currentSelectedIndex = self["list"].index - selectedTag = current[2] - self.buildPacketList(selectedTag) - elif self.currList == "packages": - if current[7] is not '': - idx = self["list"].getIndex() - detailsFile = self.list[idx][1] - if self.list[idx][7]: - for entry in self.selectedFiles: - if entry[0] == detailsFile: - self.selectedFiles.remove(entry) - else: - alreadyinList = False - for entry in self.selectedFiles: - if entry[0] == detailsFile: - alreadyinList = True - if not alreadyinList: - if iSoftwareTools.NetworkConnectionAvailable is False and current[4] in ('installable', 'install'): - pass - else: - self.selectedFiles.append((detailsFile, current[4], current[3])) - self.currentSelectedPackage = ((detailsFile, current[4], current[3])) - if current[4] == 'installed': - self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'remove', True) - elif current[4] == 'installable': - if iSoftwareTools.NetworkConnectionAvailable: - self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'install', True) - elif current[4] == 'remove': - self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installed', False) - elif current[4] == 'install': - if iSoftwareTools.NetworkConnectionAvailable: - self.list[idx] = self.buildEntryComponent(current[0], current[1], current[2], current[3], 'installable', False) - self["list"].setList(self.list) - self["list"].setIndex(idx) - self["list"].updateList(self.list) - self.selectionChanged() - elif self.currList == "status": - iSoftwareTools.lastDownloadDate = time() - iSoftwareTools.list_updating = True - self.setState('update') - iSoftwareTools.getUpdates(self.getUpdateInfosCB) - - def handleSelected(self): - current = self["list"].getCurrent() - if current: - if self.currList == "packages": - if current[7] is not '': - detailsfile = iSoftwareTools.directory[0] + "/" + current[1] - if os_path.exists(detailsfile): - self.saved_currentSelectedPackage = self.currentSelectedPackage - self.session.openWithCallback(self.detailsClosed, PluginDetails, self.skin_path, current) - else: - self.session.open(MessageBox, _("Sorry, no details available!"), MessageBox.TYPE_INFO, timeout=10) - elif self.currList == "category": - self.prepareInstall() - if len(self.cmdList): - self.session.openWithCallback(self.runExecute, PluginManagerInfo, self.skin_path, self.cmdList) - - def detailsClosed(self, result=None): - if result is not None: - if result is not False: - self.setState('sync') - iSoftwareTools.lastDownloadDate = time() - for entry in self.selectedFiles: - if entry == self.saved_currentSelectedPackage: - self.selectedFiles.remove(entry) - iSoftwareTools.startIpkgListInstalled(self.rebuildList) - - def buildEntryComponent(self, name, details, description, packagename, state, selected=False): - divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "div-h.png")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/installed.png")): - installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/installed.png")) - else: - installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/installable.png")): - installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/installable.png")) - else: - installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/remove.png")): - removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/remove.png")) - else: - removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/install.png")): - installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/install.png")) - else: - installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png")) - if state == 'installed': - return name, details, description, packagename, state, installedpng, divpng, selected - elif state == 'installable': - return name, details, description, packagename, state, installablepng, divpng, selected - elif state == 'remove': - return name, details, description, packagename, state, removepng, divpng, selected - elif state == 'install': - return name, details, description, packagename, state, installpng, divpng, selected - - def buildPacketList(self, categorytag=None): - if categorytag is not None: - self.currList = "packages" - self.currentSelectedTag = categorytag - self.packetlist = [] - for package in iSoftwareTools.packagesIndexlist[:]: - prerequisites = package[0]["prerequisites"] - if "tag" in prerequisites: - for foundtag in prerequisites["tag"]: - if categorytag == foundtag: - attributes = package[0]["attributes"] - if "packagetype" in attributes: - if attributes["packagetype"] == "internal": - continue - self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]]) - else: - self.packetlist.append([attributes["name"], attributes["details"], attributes["shortdescription"], attributes["packagename"]]) - self.list = [] - for x in self.packetlist: - status = "" - name = x[0].strip() - details = x[1].strip() - description = x[2].strip() - if not description: - description = "No description available." - packagename = x[3].strip() - selectState = self.getSelectionState(details) - if packagename in iSoftwareTools.installed_packetlist: - if selectState: - status = "remove" - else: - status = "installed" - self.list.append(self.buildEntryComponent(name, _(details), _(description), packagename, status, selected=selectState)) - else: - if selectState: - status = "install" - else: - status = "installable" - self.list.append(self.buildEntryComponent(name, _(details), _(description), packagename, status, selected=selectState)) - if len(self.list): - self.list.sort(key=lambda x: x[0]) - self["list"].style = "default" - self['list'].setList(self.list) - self["list"].updateList(self.list) - self.selectionChanged() - - def buildCategoryList(self): - self.currList = "category" - self.categories = [] - self.categoryList = [] - for package in iSoftwareTools.packagesIndexlist[:]: - prerequisites = package[0]["prerequisites"] - if "tag" in prerequisites: - for foundtag in prerequisites["tag"]: - attributes = package[0]["attributes"] - if foundtag not in self.categories: - self.categories.append(foundtag) - self.categoryList.append(self.buildCategoryComponent(foundtag)) - self.categoryList.sort(key=lambda x: x[0]) - self["list"].style = "category" - self['list'].setList(self.categoryList) - self["list"].updateList(self.categoryList) - self.selectionChanged() - - def buildCategoryComponent(self, tag=None): - divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "div-h.png")) - if tag is not None: - if tag == 'System': - return _("System"), _("View list of available system extensions"), tag, divpng - elif tag == 'Skin': - return _("Skins"), _("View list of available skins"), tag, divpng - elif tag == 'Recording': - return _("Recordings"), _("View list of available recording extensions"), tag, divpng - elif tag == 'Network': - return _("Network"), _("View list of available networking extensions"), tag, divpng - elif tag == 'CI': - return _("Common Interface"), _("View list of available CommonInterface extensions"), tag, divpng - elif tag == 'Default': - return _("Default settings"), _("View list of available default settings"), tag, divpng - elif tag == 'SAT': - return _("Satellite equipment"), _("View list of available Satellite equipment extensions."), tag, divpng - elif tag == 'Software': - return _("Software"), _("View list of available software extensions"), tag, divpng - elif tag == 'Multimedia': - return _("Multimedia"), _("View list of available multimedia extensions."), tag, divpng - elif tag == 'Display': - return _("Display and user interface"), _("View list of available display and userinterface extensions."), tag, divpng - elif tag == 'EPG': - return _("Electronic Program Guide"), _("View list of available EPG extensions."), tag, divpng - elif tag == 'Communication': - return _("Communication"), _("View list of available communication extensions."), tag, divpng - else: # dynamically generate non existent tags - return str(tag), _("View list of available ") + str(tag) + ' ' + _("extensions."), tag, divpng - - def prepareInstall(self): - self.cmdList = [] - if iSoftwareTools.available_updates > 0: - self.cmdList.append((IpkgComponent.CMD_UPGRADE, {"test_only": False})) - if self.selectedFiles and len(self.selectedFiles): - for plugin in self.selectedFiles: - detailsfile = iSoftwareTools.directory[0] + "/" + plugin[0] - if os_path.exists(detailsfile): - iSoftwareTools.fillPackageDetails(plugin[0]) - self.package = iSoftwareTools.packageDetails[0] - if "attributes" in self.package[0]: - self.attributes = self.package[0]["attributes"] - if "needsRestart" in self.attributes: - self.restartRequired = True - if "package" in self.attributes: - self.packagefiles = self.attributes["package"] - if plugin[1] == 'installed': - if self.packagefiles: - for package in self.packagefiles[:]: - self.cmdList.append((IpkgComponent.CMD_REMOVE, {"package": package["name"]})) - else: - self.cmdList.append((IpkgComponent.CMD_REMOVE, {"package": plugin[2]})) - else: - if self.packagefiles: - for package in self.packagefiles[:]: - self.cmdList.append((IpkgComponent.CMD_INSTALL, {"package": package["name"]})) - else: - self.cmdList.append((IpkgComponent.CMD_INSTALL, {"package": plugin[2]})) - else: - if plugin[1] == 'installed': - self.cmdList.append((IpkgComponent.CMD_REMOVE, {"package": plugin[2]})) - else: - self.cmdList.append((IpkgComponent.CMD_INSTALL, {"package": plugin[2]})) - - def runExecute(self, result=None): - if result is not None: - if result[0] is True: - self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList=self.cmdList) - elif result[0] is False: - self.cmdList = result[1] - self.session.openWithCallback(self.runExecuteFinished, Ipkg, cmdList=self.cmdList) - else: - self.close() - - def runExecuteFinished(self): - self.reloadPluginlist() - if plugins.restartRequired or self.restartRequired: - self.session.openWithCallback(self.ExecuteReboot, MessageBox, _("Install or remove finished.") + " " + _("Do you want to reboot your receiver?"), MessageBox.TYPE_YESNO) - else: - self.selectedFiles = [] - self.restartRequired = False - self.detailsClosed(True) - - def ExecuteReboot(self, result): - if result: - self.session.open(TryQuitMainloop, retvalue=3) - else: - self.selectedFiles = [] - self.restartRequired = False - self.detailsClosed(True) - - def reloadPluginlist(self): - plugins.readPluginList(resolveFilename(SCOPE_PLUGINS)) - - -class PluginManagerInfo(Screen): - skin = """ - - - - - - - - {"template": [ - MultiContentEntryText(pos = (50, 0), size = (150, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name - MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state - MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap - MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap - ], - "fonts": [gFont("Regular", 24),gFont("Regular", 22)], - "itemHeight": 50 - } - - - - - """ - - def __init__(self, session, plugin_path, cmdlist=None): - Screen.__init__(self, session) - Screen.setTitle(self, _("Plugin manager activity information")) - self.session = session - self.skin_path = plugin_path - self.cmdlist = cmdlist - - self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"], - { - "ok": self.process_all, - "back": self.exit, - "red": self.exit, - "green": self.process_extensions, - }, -1) - - self.list = [] - self["list"] = List(self.list) - self["key_red"] = StaticText(_("Cancel")) - self["key_green"] = StaticText(_("Only extensions.")) - self["status"] = StaticText(_("Following tasks will be done after you press OK!")) - - self.onShown.append(self.setWindowTitle) - self.onLayoutFinish.append(self.rebuildList) - - def setWindowTitle(self): - self.setTitle(_("Plugin manager activity information")) - - def rebuildList(self): - self.list = [] - if self.cmdlist is not None: - for entry in self.cmdlist: - action = "" - info = "" - cmd = entry[0] - if cmd == 0: - action = 'install' - elif cmd == 2: - action = 'remove' - else: - action = 'upgrade' - args = entry[1] - if cmd == 0: - info = args['package'] - elif cmd == 2: - info = args['package'] - else: - info = _("%s %s software because updates are available.") % (getMachineBrand(), getMachineName()) - - self.list.append(self.buildEntryComponent(action, info)) - self['list'].setList(self.list) - self['list'].updateList(self.list) - - def buildEntryComponent(self, action, info): - divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "div-h.png")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/upgrade.png")): - upgradepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/upgrade.png")) - else: - upgradepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/install.png")): - installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/install.png")) - else: - installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/remove.png")): - removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/remove.png")) - else: - removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png")) - if action == 'install': - return _('Installing'), info, installpng, divpng - elif action == 'remove': - return _('Removing'), info, removepng, divpng - else: - return _('Upgrading'), info, upgradepng, divpng - - def exit(self): - self.close() - - def process_all(self): - self.close((True, None)) - - def process_extensions(self): - self.list = [] - if self.cmdlist is not None: - for entry in self.cmdlist: - cmd = entry[0] - if entry[0] in (0, 2): - self.list.append(entry) - self.close((False, self.list)) - - -class PluginManagerHelp(Screen): - skin = """ - - - - - - {"template": [ - MultiContentEntryText(pos = (50, 0), size = (540, 26), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name - MultiContentEntryText(pos = (50, 27), size = (540, 23), font=1, flags = RT_HALIGN_LEFT, text = 1), # index 1 is the state - MultiContentEntryPixmapAlphaTest(pos = (0, 1), size = (48, 48), png = 2), # index 2 is the status pixmap - MultiContentEntryPixmapAlphaTest(pos = (0, 48), size = (550, 2), png = 3), # index 3 is the div pixmap - ], - "fonts": [gFont("Regular", 24),gFont("Regular", 22)], - "itemHeight": 50 - } - - - - - """ - - def __init__(self, session, plugin_path): - Screen.__init__(self, session) - Screen.setTitle(self, _("Plugin manager help")) - self.session = session - self.skin_path = plugin_path - - self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"], - { - "back": self.exit, - "red": self.exit, - }, -1) - - self.list = [] - self["list"] = List(self.list) - self["key_red"] = StaticText(_("Close")) - self["status"] = StaticText(_("A small overview of the available icon states and actions.")) - - self.onShown.append(self.setWindowTitle) - self.onLayoutFinish.append(self.rebuildList) - - def setWindowTitle(self): - self.setTitle(_("Plugin manager help")) - - def rebuildList(self): - self.list = [] - self.list.append(self.buildEntryComponent('install')) - self.list.append(self.buildEntryComponent('installable')) - self.list.append(self.buildEntryComponent('installed')) - self.list.append(self.buildEntryComponent('remove')) - self['list'].setList(self.list) - self['list'].updateList(self.list) - - def buildEntryComponent(self, state): - divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "div-h.png")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/installed.png")): - installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/installed.png")) - else: - installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/installable.png")): - installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/installable.png")) - else: - installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/remove.png")): - removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/remove.png")) - else: - removepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png")) - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/install.png")): - installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/install.png")) - else: - installpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/install.png")) - - if state == 'installed': - return _('This plugin is installed.'), _('You can remove this plugin.'), installedpng, divpng - elif state == 'installable': - return _('This plugin is not installed.'), _('You can install this plugin.'), installablepng, divpng - elif state == 'install': - return _('This plugin will be installed.'), _('You can cancel the installation.'), installpng, divpng - elif state == 'remove': - return _('This plugin will be removed.'), _('You can cancel the removal.'), removepng, divpng - - def exit(self): - self.close() - - -class PluginDetails(Screen, PackageInfoHandler): - skin = """ - - - - - - - - - - - """ - - def __init__(self, session, plugin_path, packagedata=None): - Screen.__init__(self, session) - Screen.setTitle(self, _("Plugin details")) - self.skin_path = plugin_path - self.language = language.getLanguage()[:2] # getLanguage returns e.g. "fi_FI" for "language_country" - self.attributes = None - PackageInfoHandler.__init__(self, self.statusCallback) - self.directory = resolveFilename(SCOPE_METADIR) - if packagedata: - self.pluginname = packagedata[0] - self.details = packagedata[1] - self.pluginstate = packagedata[4] - self.statuspicinstance = packagedata[5] - self.divpicinstance = packagedata[6] - self.fillPackageDetails(self.details) - - self.thumbnail = "" - - self["shortcuts"] = ActionMap(["ShortcutActions", "WizardActions"], - { - "back": self.exit, - "red": self.exit, - "green": self.go, - "up": self.pageUp, - "down": self.pageDown, - "left": self.pageUp, - "right": self.pageDown, - }, -1) - - self["key_red"] = StaticText(_("Close")) - self["key_green"] = StaticText("") - self["author"] = StaticText() - self["statuspic"] = Pixmap() - self["divpic"] = Pixmap() - self["screenshot"] = Pixmap() - self["detailtext"] = ScrollLabel() - - self["statuspic"].hide() - self["screenshot"].hide() - self["divpic"].hide() - - self.package = self.packageDetails[0] - if "attributes" in self.package[0]: - self.attributes = self.package[0]["attributes"] - self.restartRequired = False - self.cmdList = [] - self.oktext = _("\nAfter pressing OK, please wait!") - self.picload = ePicLoad() - self.picload.PictureData.get().append(self.paintScreenshotPixmapCB) - self.onShown.append(self.setWindowTitle) - self.onLayoutFinish.append(self.setInfos) - - def setWindowTitle(self): - self.setTitle(_("Details for plugin: ") + self.pluginname) - - def exit(self): - self.close(False) - - def pageUp(self): - self["detailtext"].pageUp() - - def pageDown(self): - self["detailtext"].pageDown() - - def statusCallback(self, status, progress): - pass - - def setInfos(self): - if "screenshot" in self.attributes: - self.loadThumbnail(self.attributes) - - if "name" in self.attributes: - self.pluginname = self.attributes["name"] - else: - self.pluginname = _("unknown") - - if "author" in self.attributes: - self.author = self.attributes["author"] - else: - self.author = _("unknown") - - if "description" in self.attributes: - self.description = _(self.attributes["description"].replace("\\n", "\n")) - else: - self.description = _("No description available.") - - self["author"].setText(_("Author: ") + self.author) - self["detailtext"].setText(_(self.description)) - if self.pluginstate in ('installable', 'install'): - if iSoftwareTools.NetworkConnectionAvailable: - self["key_green"].setText(_("Install")) - else: - self["key_green"].setText("") - else: - self["key_green"].setText(_("Remove")) - - def loadThumbnail(self, entry): - thumbnailUrl = None - if "screenshot" in entry: - thumbnailUrl = entry["screenshot"] - if self.language == "de": - if thumbnailUrl[-7:] == "_en.jpg": - thumbnailUrl = thumbnailUrl[:-7] + "_de.jpg" - - if thumbnailUrl is not None: - self.thumbnail = "/tmp/" + thumbnailUrl.split('/')[-1] - print("[PluginDetails] downloading screenshot " + thumbnailUrl + " to " + self.thumbnail) - if iSoftwareTools.NetworkConnectionAvailable: - client.downloadPage(thumbnailUrl, self.thumbnail).addCallback(self.setThumbnail).addErrback(self.fetchFailed) - else: - self.setThumbnail(noScreenshot=True) - else: - self.setThumbnail(noScreenshot=True) - - def setThumbnail(self, noScreenshot=False): - if not noScreenshot: - filename = self.thumbnail - else: - filename = resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/noprev.png") - - sc = AVSwitch().getFramebufferScale() - self.picload.setPara((self["screenshot"].instance.size().width(), self["screenshot"].instance.size().height(), sc[0], sc[1], False, 1, "#00000000")) - self.picload.startDecode(filename) - - if self.statuspicinstance is not None: - self["statuspic"].instance.setPixmap(self.statuspicinstance.__deref__()) - self["statuspic"].show() - if self.divpicinstance is not None: - self["divpic"].instance.setPixmap(self.divpicinstance.__deref__()) - self["divpic"].show() - - def paintScreenshotPixmapCB(self, picInfo=None): - ptr = self.picload.getData() - if ptr is not None: - self["screenshot"].instance.setPixmap(ptr.__deref__()) - self["screenshot"].show() - else: - self.setThumbnail(noScreenshot=True) - - def go(self): - if "package" in self.attributes: - self.packagefiles = self.attributes["package"] - if "needsRestart" in self.attributes: - self.restartRequired = True - self.cmdList = [] - if self.pluginstate in ('installed', 'remove'): - if self.packagefiles: - for package in self.packagefiles[:]: - self.cmdList.append((IpkgComponent.CMD_REMOVE, {"package": package["name"]})) - if len(self.cmdList): - self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + self.pluginname + "\n" + self.oktext) - else: - if iSoftwareTools.NetworkConnectionAvailable: - if self.packagefiles: - for package in self.packagefiles[:]: - self.cmdList.append((IpkgComponent.CMD_INSTALL, {"package": package["name"]})) - if len(self.cmdList): - self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + self.pluginname + "\n" + self.oktext) - - def runUpgrade(self, result): - if result: - self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList=self.cmdList) - - def runUpgradeFinished(self): - self.reloadPluginlist() - if plugins.restartRequired or self.restartRequired: - self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Installation finished.") + " " + _("Do you want to reboot your receiver?"), MessageBox.TYPE_YESNO) - else: - self.close(True) - - def UpgradeReboot(self, result): - if result: - self.session.open(TryQuitMainloop, retvalue=3) - self.close(True) - - def runRemove(self, result): - if result: - self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList=self.cmdList) - - def runRemoveFinished(self): - self.close(True) - - def reloadPluginlist(self): - plugins.readPluginList(resolveFilename(SCOPE_PLUGINS)) - - def fetchFailed(self, string): - self.setThumbnail(noScreenshot=True) - print("[PluginDetails] fetch failed " + string.getErrorMessage()) - - -class IPKGMenu(Screen): - skin = """ - - - - - - - """ - - def __init__(self, session, plugin_path): - Screen.__init__(self, session) - Screen.setTitle(self, _("Select upgrade source to edit.")) - self.skin_path = plugin_path - - self["key_red"] = StaticText(_("Close")) - self["key_green"] = StaticText(_("Edit")) - - self.sel = [] - self.val = [] - self.entry = False - self.exe = False - - self.path = "" - - self["actions"] = NumberActionMap(["SetupActions"], - { - "ok": self.KeyOk, - "cancel": self.keyCancel - }, -1) - - self["shortcuts"] = ActionMap(["ShortcutActions"], - { - "red": self.keyCancel, - "green": self.KeyOk, - }) - self["filelist"] = MenuList([]) - self.fill_list() - self.onLayoutFinish.append(self.layoutFinished) - - def layoutFinished(self): - self.setWindowTitle() - - def setWindowTitle(self): - self.setTitle(_("Select upgrade source to edit.")) - - def fill_list(self): - flist = [] - self.path = '/etc/opkg/' - if not os_path.exists(self.path): - self.entry = False - return - for file in listdir(self.path): - if file.endswith(".conf"): - if file not in ('arch.conf', 'opkg.conf'): - flist.append(file) - self.entry = True - self["filelist"].l.setList(flist) - - def KeyOk(self): - if (self.exe == False) and (self.entry == True): - self.sel = self["filelist"].getCurrent() - self.val = self.path + self.sel - self.session.open(IPKGSource, self.val) - - def keyCancel(self): - self.close() - - def Exit(self): - self.close() - - -class IPKGSource(Screen): - skin = """ - - - - - - - """ - - def __init__(self, session, configfile=None): - Screen.__init__(self, session) - self.session = session - self.configfile = configfile - text = "" - if self.configfile: - try: - fp = file(configfile, 'r') - sources = fp.readlines() - if sources: - text = sources[0] - fp.close() - except IOError: - pass - - desk = getDesktop(0) - x = int(desk.size().width()) - y = int(desk.size().height()) - - self["key_red"] = StaticText(_("Cancel")) - self["key_green"] = StaticText(_("Save")) - - if y >= 720: - self["text"] = Input(text, maxSize=False, type=Input.TEXT) - else: - self["text"] = Input(text, maxSize=False, visible_width=55, type=Input.TEXT) - - self["actions"] = NumberActionMap(["WizardActions", "InputActions", "TextEntryActions", "KeyboardInputActions", "ShortcutActions"], - { - "ok": self.go, - "back": self.close, - "red": self.close, - "green": self.go, - "left": self.keyLeft, - "right": self.keyRight, - "home": self.keyHome, - "end": self.keyEnd, - "deleteForward": self.keyDeleteForward, - "deleteBackward": self.keyDeleteBackward, - "1": self.keyNumberGlobal, - "2": self.keyNumberGlobal, - "3": self.keyNumberGlobal, - "4": self.keyNumberGlobal, - "5": self.keyNumberGlobal, - "6": self.keyNumberGlobal, - "7": self.keyNumberGlobal, - "8": self.keyNumberGlobal, - "9": self.keyNumberGlobal, - "0": self.keyNumberGlobal - }, -1) - - self.onLayoutFinish.append(self.layoutFinished) - - def layoutFinished(self): - self.setWindowTitle() - self["text"].right() - - def setWindowTitle(self): - self.setTitle(_("Edit upgrade source url.")) - - def go(self): - text = self["text"].getText() - if text: - fp = file(self.configfile, 'w') - fp.write(text) - fp.write("\n") - fp.close() - self.close() - - def keyLeft(self): - self["text"].left() - - def keyRight(self): - self["text"].right() - - def keyHome(self): - self["text"].home() - - def keyEnd(self): - self["text"].end() - - def keyDeleteForward(self): - self["text"].delete() - - def keyDeleteBackward(self): - self["text"].deleteBackward() - - def keyNumberGlobal(self, number): - self["text"].number(number) - - -class PacketManager(Screen, NumericalTextInput): - skin = """ - - - - - - - - {"template": [ - MultiContentEntryText(pos = (5, 1), size = (440, 28), font=0, flags = RT_HALIGN_LEFT, text = 0), # index 0 is the name - MultiContentEntryText(pos = (5, 26), size = (440, 20), font=1, flags = RT_HALIGN_LEFT, text = 2), # index 2 is the description - MultiContentEntryPixmapAlphaTest(pos = (445, 2), size = (48, 48), png = 4), # index 4 is the status pixmap - MultiContentEntryPixmapAlphaTest(pos = (5, 50), size = (510, 2), png = 5), # index 4 is the div pixmap - ], - "fonts": [gFont("Regular", 22),gFont("Regular", 14)], - "itemHeight": 52 - } - - - """ - - def __init__(self, session, plugin_path, args=None): - Screen.__init__(self, session) - NumericalTextInput.__init__(self) - self.session = session - self.skin_path = plugin_path - - if config.usage.show_channel_jump_in_servicelist.value == "alpha": - self.setUseableChars(u'abcdefghijklmnopqrstuvwxyz1234567890') - else: - self.setUseableChars(u'1234567890abcdefghijklmnopqrstuvwxyz') - - self["shortcuts"] = NumberActionMap(["ShortcutActions", "WizardActions", "NumberActions", "InputActions", "InputAsciiActions", "KeyboardInputActions"], - { - "ok": self.go, - "back": self.exit, - "red": self.exit, - "green": self.reload, - "gotAsciiCode": self.keyGotAscii, - "1": self.keyNumberGlobal, - "2": self.keyNumberGlobal, - "3": self.keyNumberGlobal, - "4": self.keyNumberGlobal, - "5": self.keyNumberGlobal, - "6": self.keyNumberGlobal, - "7": self.keyNumberGlobal, - "8": self.keyNumberGlobal, - "9": self.keyNumberGlobal, - "0": self.keyNumberGlobal - }, -1) - - self.list = [] - self.statuslist = [] - self["list"] = List(self.list) - self["key_red"] = StaticText(_("Close")) - self["key_green"] = StaticText(_("Reload")) - - self.list_updating = True - self.packetlist = [] - self.installed_packetlist = {} - self.upgradeable_packages = {} - self.Console = Console() - self.cmdList = [] - self.cachelist = [] - self.cache_ttl = 86400 #600 is default, 0 disables, Seconds cache is considered valid (24h should be ok for caching ipkgs) - self.cache_file = eEnv.resolve('${libdir}/enigma2/python/Plugins/SystemPlugins/SoftwareManager/packetmanager.cache') # Path to cache directory - self.oktext = _("\nAfter pressing OK, please wait!") - self.unwanted_extensions = ('-dbg', '-dev', '-doc', '-staticdev', '-src', 'busybox') - - self.ipkg = IpkgComponent() - self.ipkg.addCallback(self.ipkgCallback) - self.onShown.append(self.setWindowTitle) - self.onLayoutFinish.append(self.rebuildList) - - rcinput = eRCInput.getInstance() - rcinput.setKeyboardMode(rcinput.kmAscii) - - def keyNumberGlobal(self, val): - key = self.getKey(val) - if key is not None: - keyvalue = key.encode("utf-8") - if len(keyvalue) == 1: - self.setNextIdx(keyvalue[0]) - - def keyGotAscii(self): - keyvalue = unichr(getPrevAsciiCode()).encode("utf-8") - if len(keyvalue) == 1: - self.setNextIdx(keyvalue[0]) - - def setNextIdx(self, char): - if char in ("0", "1", "a"): - self["list"].setIndex(0) - else: - idx = self.getNextIdx(char) - if idx and idx <= self["list"].count: - self["list"].setIndex(idx) - - def getNextIdx(self, char): - for idx, i in enumerate(self["list"].list): - if i[0] and (i[0][0] == char): - return idx - - def exit(self): - self.ipkg.stop() - if self.Console is not None: - self.Console.killAll() - rcinput = eRCInput.getInstance() - rcinput.setKeyboardMode(rcinput.kmNone) - self.close() - - def reload(self): - if os_path.exists(self.cache_file): - remove(self.cache_file) - self.list_updating = True - self.rebuildList() - - def setWindowTitle(self): - self.setTitle(_("Packet manager")) - - def setStatus(self, status=None): - if status: - self.statuslist = [] - divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "div-h.png")) - if status == 'update': - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/upgrade.png")): - statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/upgrade.png")) - else: - statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgrade.png")) - self.statuslist.append((_("Package list update"), '', _("Trying to download a new packetlist. Please wait..."), '', statuspng, divpng)) - self['list'].setList(self.statuslist) - elif status == 'error': - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/remove.png")): - statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/remove.png")) - else: - statuspng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/remove.png")) - self.statuslist.append((_("Error"), '', _("An error occurred while downloading the packetlist. Please try again."), '', statuspng, divpng)) - self['list'].setList(self.statuslist) - - def rebuildList(self): - self.setStatus('update') - self.inv_cache = 0 - self.vc = valid_cache(self.cache_file, self.cache_ttl) - if self.cache_ttl > 0 and self.vc != 0: - try: - self.buildPacketList() - except: - self.inv_cache = 1 - if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0: - self.run = 0 - self.ipkg.startCmd(IpkgComponent.CMD_UPDATE) - - def go(self, returnValue=None): - cur = self["list"].getCurrent() - if cur: - status = cur[3] - package = cur[0] - self.cmdList = [] - if status == 'installed': - self.cmdList.append((IpkgComponent.CMD_REMOVE, {"package": package})) - if len(self.cmdList): - self.session.openWithCallback(self.runRemove, MessageBox, _("Do you want to remove the package:\n") + package + "\n" + self.oktext) - elif status == 'upgradeable': - self.cmdList.append((IpkgComponent.CMD_INSTALL, {"package": package})) - if len(self.cmdList): - self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to upgrade the package:\n") + package + "\n" + self.oktext) - elif status == "installable": - self.cmdList.append((IpkgComponent.CMD_INSTALL, {"package": package})) - if len(self.cmdList): - self.session.openWithCallback(self.runUpgrade, MessageBox, _("Do you want to install the package:\n") + package + "\n" + self.oktext) - - def runRemove(self, result): - if result: - self.session.openWithCallback(self.runRemoveFinished, Ipkg, cmdList=self.cmdList) - - def runRemoveFinished(self): - self.session.openWithCallback(self.RemoveReboot, MessageBox, _("Remove finished.") + " " + _("Do you want to reboot your receiver?"), MessageBox.TYPE_YESNO) - - def RemoveReboot(self, result): - if result is None: - return - if result is False: - cur = self["list"].getCurrent() - if cur: - item = self['list'].getIndex() - self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installable') - self.cachelist[item] = [cur[0], cur[1], cur[2], 'installable'] - self['list'].setList(self.list) - write_cache(self.cache_file, self.cachelist) - self.reloadPluginlist() - if result: - self.session.open(TryQuitMainloop, retvalue=3) - - def runUpgrade(self, result): - if result: - self.session.openWithCallback(self.runUpgradeFinished, Ipkg, cmdList=self.cmdList) - - def runUpgradeFinished(self): - self.session.openWithCallback(self.UpgradeReboot, MessageBox, _("Upgrade finished.") + " " + _("Do you want to reboot your receiver?"), MessageBox.TYPE_YESNO) - - def UpgradeReboot(self, result): - if result is None: - return - if result is False: - cur = self["list"].getCurrent() - if cur: - item = self['list'].getIndex() - self.list[item] = self.buildEntryComponent(cur[0], cur[1], cur[2], 'installed') - self.cachelist[item] = [cur[0], cur[1], cur[2], 'installed'] - self['list'].setList(self.list) - write_cache(self.cache_file, self.cachelist) - self.reloadPluginlist() - if result: - self.session.open(TryQuitMainloop, retvalue=3) - - def ipkgCallback(self, event, param): - if event == IpkgComponent.EVENT_ERROR: - self.list_updating = False - self.setStatus('error') - elif event == IpkgComponent.EVENT_DONE: - if self.list_updating: - self.list_updating = False - if not self.Console: - self.Console = Console() - cmd = self.ipkg.ipkg + " list" - self.Console.ePopen(cmd, self.IpkgList_Finished) - pass - - def IpkgList_Finished(self, result, retval, extra_args=None): - result = result.replace('\n ', ' - ') - if result: - self.packetlist = [] - last_name = "" - for x in result.splitlines(): - if ' - ' in x: - tokens = x.split(' - ') - name = tokens[0].strip() - if name and not any(name.endswith(x) for x in self.unwanted_extensions): - l = len(tokens) - version = l > 1 and tokens[1].strip() or "" - descr = l > 2 and tokens[2].strip() or "" - if name == last_name: - continue - last_name = name - self.packetlist.append([name, version, descr]) - elif len(self.packetlist) > 0: - # no ' - ' in the text, assume that this is the description - # therefore add this text to the last packet description - last_packet = self.packetlist[-1] - last_packet[2] = last_packet[2] + x - self.packetlist[:-1] + last_packet - - if not self.Console: - self.Console = Console() - cmd = self.ipkg.ipkg + " list_installed" - self.Console.ePopen(cmd, self.IpkgListInstalled_Finished) - - def IpkgListInstalled_Finished(self, result, retval, extra_args=None): - if result: - self.installed_packetlist = {} - for x in result.splitlines(): - tokens = x.split(' - ') - name = tokens[0].strip() - if not any(name.endswith(x) for x in self.unwanted_extensions): - l = len(tokens) - version = l > 1 and tokens[1].strip() or "" - self.installed_packetlist[name] = version - if not self.Console: - self.Console = Console() - cmd = "opkg list-upgradable" - self.Console.ePopen(cmd, self.OpkgListUpgradeable_Finished) - - def OpkgListUpgradeable_Finished(self, result, retval, extra_args=None): - if result: - self.upgradeable_packages = {} - for x in result.splitlines(): - tokens = x.split(' - ') - name = tokens[0].strip() - if not any(name.endswith(x) for x in self.unwanted_extensions): - l = len(tokens) - version = l > 2 and tokens[2].strip() or "" - self.upgradeable_packages[name] = version - self.buildPacketList() - - def buildEntryComponent(self, name, version, description, state): - divpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "div-h.png")) - if not description: - description = "No description available." - if state == 'installed': - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/installed.png")): - installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/installed.png")) - else: - installedpng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installed.png")) - return name, version, _(description), state, installedpng, divpng - elif state == 'upgradeable': - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/upgradeable.png")): - upgradeablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/upgradeable.png")) - else: - upgradeablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/upgradeable.png")) - return name, version, _(description), state, upgradeablepng, divpng - else: - if os_path.exists(resolveFilename(SCOPE_CURRENT_SKIN, "icons/installable.png")): - installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/installable.png")) - else: - installablepng = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_PLUGIN, "SystemPlugins/SoftwareManager/installable.png")) - return name, version, _(description), state, installablepng, divpng - - def buildPacketList(self): - self.list = [] - self.cachelist = [] - if self.cache_ttl > 0 and self.vc != 0: - print('Loading packagelist cache from ', self.cache_file) - try: - self.cachelist = load_cache(self.cache_file) - if len(self.cachelist) > 0: - for x in self.cachelist: - self.list.append(self.buildEntryComponent(x[0], x[1], x[2], x[3])) - self['list'].setList(self.list) - except: - self.inv_cache = 1 - - if self.cache_ttl == 0 or self.inv_cache == 1 or self.vc == 0: - print('rebuilding fresh package list') - for x in self.packetlist: - status = "" - if x[0] in self.installed_packetlist: - if x[0] in self.upgradeable_packages: - status = "upgradeable" - else: - status = "installed" - else: - status = "installable" - self.list.append(self.buildEntryComponent(x[0], x[1], x[2], status)) - self.cachelist.append([x[0], x[1], x[2], status]) - write_cache(self.cache_file, self.cachelist) - self['list'].setList(self.list) - - def reloadPluginlist(self): - plugins.readPluginList(resolveFilename(SCOPE_PLUGINS)) - - -class IpkgInstaller(Screen): - skin = """ - - - - - - - - - - - - - """ - - def __init__(self, session, list): - Screen.__init__(self, session) - - self.list = SelectionList() - self["list"] = self.list - - p = 0 - if len(list): - p = list[0].rfind("/") - title = list[0][:p] - self.title = ("%s %s %s") % (_("Install extensions"), _("from"), title) - - for listindex in range(len(list)): - self.list.addSelection(list[listindex][p + 1:], list[listindex], listindex, False) - self.list.sort() - - self["key_red"] = StaticText(_("Close")) - self["key_green"] = StaticText(_("Install")) - self["key_yellow"] = StaticText() - self["key_blue"] = StaticText(_("Invert")) - self["introduction"] = StaticText(_("Press OK to toggle the selection.")) - - self["actions"] = ActionMap(["OkCancelActions", "ColorActions"], - { - "ok": self.list.toggleSelection, - "cancel": self.close, - "red": self.close, - "green": self.install, - "blue": self.list.toggleAllSelection - }, -1) - - def install(self): - list = self.list.getSelectionsList() - cmdList = [] - for item in list: - cmdList.append((IpkgComponent.CMD_INSTALL, {"package": item[1]})) - self.session.open(Ipkg, cmdList=cmdList) - - -def filescan_open(list, session, **kwargs): - filelist = [x.path for x in list] - session.open(IpkgInstaller, filelist) # list - - -def filescan(**kwargs): - from Components.Scanner import Scanner, ScanPath - return \ - Scanner(mimetypes=["application/x-debian-package"], - paths_to_scan=[ - ScanPath(path="ipk", with_subdirs=True), - ScanPath(path="", with_subdirs=False), - ], - name="Ipkg", - description=_("Install extensions."), - openfnc=filescan_open, ) - - -def UpgradeMain(session, **kwargs): - session.open(UpdatePluginMenu) - - -def startSetup(menuid): - if menuid == "setup" and config.plugins.softwaremanager.onSetupMenu.value: - return [(_("Software management"), UpgradeMain, "software_manager", 50)] - return [] - - -def Plugins(path, **kwargs): - global plugin_path - plugin_path = path - list = [ - PluginDescriptor(name=_("Software management"), description=_("Manage your %s %s's software") % (getMachineBrand(), getMachineName()), where=PluginDescriptor.WHERE_MENU, needsRestart=False, fnc=startSetup), - PluginDescriptor(name=_("Ipkg"), where=PluginDescriptor.WHERE_FILESCAN, needsRestart=False, fnc=filescan) - ] - if not config.plugins.softwaremanager.onSetupMenu.value and not config.plugins.softwaremanager.onBlueButton.value: - list.append(PluginDescriptor(name=_("Software management"), description=_("Manage your %s %s's software") % (getMachineBrand(), getMachineName()), where=PluginDescriptor.WHERE_PLUGINMENU, needsRestart=False, fnc=UpgradeMain)) - if config.plugins.softwaremanager.onBlueButton.value: - list.append(PluginDescriptor(name=_("Software management"), description=_("Manage your %s %s's software") % (getMachineBrand(), getMachineName()), where=PluginDescriptor.WHERE_EXTENSIONSMENU, needsRestart=False, fnc=UpgradeMain)) - return list diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/remove.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/remove.png deleted file mode 100644 index 4d00781e5f449a5416033ce4dd5af078b45e1ce1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2238 zcmd^B`9IT-1Afo(p45*LaGtb9YR;GyUsoIf6e$N5soU+|{^KoD@Wb4Ko#K@eO4 zBv?X6K;3go+Gly3^$}UEDMizD^>b`vyKkqRX3n`UU-09(ktQ5{rdH;*1kv{!-u^ zmOSPiHktZ(HRt70Y1QVt#+~I~OMv?7UpmkKf`MYDbK-gn2hBh^_>vN01%Ycj=egE5 zyvh0ws$oE5Z_fN8xWfZ?_<&S0u%8Sl#Q@Mii0(^C6|AyZsF3zu0ERnYTLUQL0aZMp zd`0RE9Z(~Pn?^%4iNbnhXb?*lktmOhRl^pE7==olrpRNSKpj%leO`;7441Z|$|7&+ zlIqW-u9(M;>R>Ytpkoi&CCEG8g}J1wVjrLMqnmr&QgFVf)6}=;3)qOndfeL`+mz3Km8-t_1Eg2e z*wpH@Zt%>VTI+kC?H_cw(%Zu7H+`~Ne{w(tG{Gjl)!|VWCcD?Of=w*$GqiD2GqHL) z#8Y#lxI7!YTr}$OavWPU>|4pY(ZPK;y%Suw5Lo;3pQgn)29Hud>!1C;g}uXA<_A?V zk)(v!FN^1Gj`T{ciV!>EN|LQxmUDFGEy z>il9n$?K6tFx@GrOrQ42KfTN4<9td??a3a_^QceiB|~IV*^!81?>Lf5wHH2=;#m_NzGv%v?eU_A%?vd$k^1F!u7lZ%RN zMyqn_f~}i_Jm0-|{(EI*o6Fr@er2e+2LM2TaEyb~Zv1}+;PgjC6##@#XoQtBs%Mp(Hw($c2`{IJMG}~|k_f)47i11CC+g|Z zv{N*pny#X-Oi?`}Q9Ijy4y50qC~Ta`m2;4}?UfsLW9w_=*GT>pOaQds z&lkxpw`}W^YSO3<^q4b58c#N*hWzFgn!E~nRD1n>@34hN9?>h9utl9>u_|i6)h!== z^g3uk^!T5TIZ(y>#V#wedri*LZSq<@N0jFJbxb;8=a(==M`72#ti>=~b+^2KYvp`> zX1J3r6|we2TKwg3&fDNN`$F27%4d=Bk`LCij?CzU>I0tCVONQH-lcl4fRC@yl3w%q z$Dg&y0m?W@?#PpZvZ3ssv&4;s93^U*^maq3xZTjP3f-q8&VmT3jao1KnnKM0(#Rlx zwD;YIZK!`tA6iMK?c$p>TfVahOL^aIIpG;QJ^j|^{R|-t*8lFcPMiX;M{dq5TkmF~ z18VEMLWE_ek*;j`=`kQ%6asArNF7ig5&&d3!`YdF^2%xli!C?n6h5z4lA$69;lzDf zVkTvhXql?Qy?&rYN#k-!%Ipyc_5mRcBtjO3y zOB7P<2@2tqi&)5yD*9AC3>YjQyzOHkN6%1HQtvELu`FJX=ye*K;tq_rSCiKNP77dMKvi~~KOC3tO+Z}TM9-$=`MRz0}Y3P!M=}$7%mhB*C zxnsV}DfZ-XZOP%x@0rL{?xAC`UJh^Knr0dtjnWg%(f%C@%%~IwrEyCZdG P_hSHPqywTH?tS||cNXQD diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/update.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/update.png deleted file mode 100644 index 0ece6c76a7a87233bb21644f2c0d68e0f8218eea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3630 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 AYXATM diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/upgrade.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/upgrade.png deleted file mode 100644 index 135058409c17f45c0da3e5de6c87163a828a311b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2640 zcmd^=i9geg1INFH#}Qq4a^$95dvY}Kw47UQm{5+DJ42Xjn=^9XMLH~a5&oZ+ec z4G}!t27kxL6(8v2j{)>ue4H^-NUW0^#scHy671KHfdT;NhndM;_|kFFmtR#X?nRH9 zF6%`%z?0hbEb>EI4y?j@jMF>fyTK2LA5oe8I_9NTC1cws?dX_3)0_c*Xpou?(ISue zfc_c!s7Bg4(=7ZA~9deUQr33a-EvjM=0P_k1tW@S~arcY5TG0P>j1 zk!>}t=#7(vu)ZHUCRvQN#v~?d=XfOU?Yx{~$kSo*bNZp;cT%5^9m_kAtCx=yUGhz^ zjZjn`)bXvJaUp5Q@S3fC)e5q9A;zOr!X>Xy2|>B(Oivkn#|^>#^>?ac)-=Skq-$-- ztKo}(<{-kYR#py2Tx9)qEkOVt$*JKty!8uiRVajvxnL6i{)dUQ9Dxn&L0^Z!>}h;j zVRmJogai>yD-O8V*s{5i-IIWGdO6nF9bomx*t8FkjoRXpz6P$1X?>dE1s}s(!~jt& zaWL^LvJsBARMdZ#*D|F54%dbgohmnlq#rA*N2!@m)(`fIJJ$fA_y^C6y~;+AxOONa zheJJmVt2y!WMRgysqIxy9!P8ex+GFK2@Q}KKEmv1|uav*!K^|8F1PCbiX8-cHQMH4_W;aw! zHK6D&29JR_JylQ+VpA>48eTHEUk_Y*aF0N7DrQPy7XVpLHO(+$S!Y_w2V7#Ox?Z7c z;e?cWTJdzn?}Dt#-TtpM$9N0VJ176g0uF9p{kVTcA~rJKkI&9B2nODQM6#4OD}2@A46AQkqg&&8XV0JJNp-rQz%cwZ`2@>D`eu}*k2=>6LK3WQBb@`Z zug#1DoAhz%0GIC=Ydq7i4i5#Dx^YVA*ji`nTGc6eh8^$vM>rh0*DRvdIJ+neA=G1! z8XaA~7cjw`iZr;H^=#Qt7_*x{VV~}Pm9!M}mp&A9jLXY}mf(eWCiW3@FVr%;`} zyAHPUqdqty$hTOy%H+?%C=^A`ZSdnDP$oY>|IP*mi-mG2hlU=L-sJ5QXKxM3(2MT7 zx0D=8sxE(?d2x=@S9=-aFg1GfRD5+Jy-smhrfz?idb{Ox5Q|UGeQ1MJ$i@>eqdCZx zAh7~b8$J~>#cB5A8h@ST!$*f7C1I_dP2*;mWpC=nddHg-z7ak_-O?odJ zbAl+USga2Md7xgr8+5Bb7OvG$Akk2eBOGX1I%zAx|KaXu6hB?S@lP_9vVbHP5kmIuW6~h&^^xZ71 zCCcyg*6Ft{7@bTMWEYWK$y$HT%fDn0##cory;bE?qP2|?hEw$9s>lr!{VsPxOP@cN zVwSe!s1aXTgbCB;(`-&u%}#(lC=!Y8edi;nawC)E z{E#fm&E^R4(5S@3f}M7h*7QwG{W?EqzdK9CH=4e;nN>ScdX>AGA<->fJ8ySgXqMA) zt`GC%MTC8mkx1hR>0;!C^DrgijmdQxd3kw7^xnVUhN{_WwLw!h}gtWXfJpk8-P=B> zdhe#Jn7n7@{(@uw%M$J0i8uu|VGo!;(gD@%=O=grvR_XUhAT8JQW|)m(58)auL_>i zr|mDHv*?c!r#QJHHpYn9ps&dF*Cn*icRyxsRf-BCIjc6I6X;Xqoqa3zY ztmcK>lGwxcad&mFb4w{G>F5&(F2a7ak(hmP=5|}w>(Ec?VdZX@=c5!zMcN)7VKN^E zI>A#}nY-oEvX7;xnSJ@+AE8$nJ!Xb`E*Z1^kKJAuCrYQT#Au$!z7pHXo^QEfqxwV= zzc>S1Y928g7oDcAtC*rfe1v87OUPO@HmzrCX8zKLc00;U2Cb_rbh0;QOerAXP340o z-R8v$aDil}TmjA37Bdv^9 zUB?dtMenkB$V&tBi-y3$ufC2+;nf5qJG)t4`X$VVTfp7^>#H0}%CtP@PQ(kP{}r1@5+ZMSZbN=wAAp3L!rmA-M*R=otb3OL diff --git a/lib/python/Plugins/SystemPlugins/SoftwareManager/upgradeable.png b/lib/python/Plugins/SystemPlugins/SoftwareManager/upgradeable.png deleted file mode 100644 index 1702177f7b6bc2ebbe2f00e5586cda197209d183..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2092 zcmd^A`8(7LAN|fumR!s2hKnp+B}I%S-Rw)F$WFG*WEo=%V;MV1lJ%01UG}AnvCB5| z+D#}KWH6U3$yiI4n3?bE{X5?CJfF{b&hz>Fc%E|-%}wv}aEWjM0Kj8tfUrDeh5rpF z>~uTLpKUoMVVu4l&I;>>3vmv>0J^SN7tBRNA7^)rCC1q`%%6;655GhZXtlt?K zUv`y50Yn~f%@erd#-p3deKYKLtt3f@chKt|P#Me_xUT>r0S5PBQ^IoG2snEy=dz^@k|Ve{fL>Xo!p!8LS&?lZD|Qs*Dq9tzRJvhF2He$`6eH$(7h;f<2!fx2;>+E1Dh@g1g_@2&DEZfyr1)zn87pYEm*@1^&f=Y2HG z8L=szL{?H=2}^cWGj1ZRYIuNsz9#C0qj z%E|vw!KZ_3&zpvw2%nHeZK2(t(-uJwBK1L9@eS`tuU4|kJ+n98!ORbooc1oum}iyq zv@ks0E&YYAHwIhrQqAjrOi$^ZU~9Oll1HK+i9Tc=XBkx%l{=A@@;(B;SS)u(Dy1>l zIbS2V&bWh~Q$Lg8S*FpulkZz29^QN{f5K$wM{@kIWb%+=#)w8rv&lQUZ*-?<`h;Y` z^xyIA$`v%dx(UDR&zC(CrQgn2FPz{Tw^V4%>_yh=$&<(xu&Vz^k-UXm{?R_ebX@@x zR#}l-Al4D1JhKwa0Ox1c#E4`CVox*!tQj1+n)U(#vQ7=d1~Pd;P#9#|ei$U<>#Q08ii`!vH*S`#9#wI(gpI7zpk`nA=%X@*Dy`D==qnGmzj^KN#Bpt zJ~ESZ5}MK>vZF7l$SP2-UyV$1Q*16*6` zbu0CC;x&r@BhKWM-{=eVk-v_oTSzSLI=_E-xfN_P@@A5aVjV+kAF-J;lPVlc#ng_N zF8b#8ovMYgG=A|-k=jeWWmeL7#|E#dS900n-rD*{p-pNUb{TW{#&!} zTn65VIruU|_XMlUl>ULH&dGx&Iy zoKeL~I}Z4<_<99^qtg=u-Hivvoq&lKd4b>iyRlV#G#6hj9Jp8kmo{UV{Am5UiF&3V zo7#j$AnD}gHR8V-te>pTHV!^5O~`b5<;c2%m{n{+YKEiTSW|@U={b1kh=n3JF3f{C zkQvP(&cZC6D^kQlI@kqZ4mwFlWCXZh59x6+-t&3`p z*xLVvm(t>GeEPCuJ4b}onIJ1XJNqr{@CmMfx%*|N5X;eOTBPi5e?GsfNcvUtiu(Y* z8eO}+G(|j|+tR$aFWqKZq=EUQVRVis8Rtz_*GYCTo*SPXtikN0&7Bm}-A9}G8>U8k z@+34EEl0luTDZCK^aHI>27T$~i{mLHL_t?#L|QKyHkZfNvHkV_2h7 zMsFq~&%gHUF2MqO15p{Y_PyY*!b*TFQ From af6c5f502097f470c10fe1abb15029b2a7d89f1f Mon Sep 17 00:00:00 2001 From: Twol Date: Wed, 25 Oct 2023 07:46:39 +0200 Subject: [PATCH 069/401] [Navigation] - rsolveF401 --- lib/python/Navigation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Navigation.py b/lib/python/Navigation.py index eeeb27a3e8f..ab8580aebb9 100644 --- a/lib/python/Navigation.py +++ b/lib/python/Navigation.py @@ -10,7 +10,7 @@ from Tools.StbHardware import getFPWasTimerWakeup import RecordTimer import PowerTimer -from ServiceReference import ServiceReference +from ServiceReference import ServiceReference # noqa: F401 import Screens.Standby import NavigationInstance from Screens.InfoBar import InfoBar From a6f7bfa08780d5fba14f3037910573c21c8559ae Mon Sep 17 00:00:00 2001 From: Twol Date: Wed, 25 Oct 2023 07:48:53 +0200 Subject: [PATCH 070/401] [TuneTest] - resolve bad comment PEP8 --- lib/python/Components/TuneTest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/TuneTest.py b/lib/python/Components/TuneTest.py index 80de8546b12..e82decbdb0f 100644 --- a/lib/python/Components/TuneTest.py +++ b/lib/python/Components/TuneTest.py @@ -80,7 +80,7 @@ def tuneCab(self, transponder): parm.modulation = transponder[2] parm.fec_inner = transponder[3] parm.inversion = transponder[4] - #parm.system = transponder[5] + # parm.system = transponder[5] self.tuneCabObj(parm) def tuneCabObj(self, transponderObj): From 5e46c5339b6cb380cdd5ecc1e2fec8c78933071f Mon Sep 17 00:00:00 2001 From: Twol Date: Wed, 25 Oct 2023 07:56:23 +0200 Subject: [PATCH 071/401] [UsageConfig] -remove unused time import, PEP8 comments --- lib/python/Components/UsageConfig.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/python/Components/UsageConfig.py b/lib/python/Components/UsageConfig.py index 8a42251da15..6f2f32882fd 100644 --- a/lib/python/Components/UsageConfig.py +++ b/lib/python/Components/UsageConfig.py @@ -1,7 +1,7 @@ +import io import locale import os import skin -from time import time from boxbranding import getBrandOEM, getDisplayType from enigma import eDVBDB, eEPGCache, setTunerTypePriorityOrder, setPreferredTuner, setSpinnerOnOff, setEnableTtCachingOnOff, eEnv, Misc_Options, eServiceEvent @@ -18,9 +18,6 @@ # getting a time-stamp prepended. # stderr expect unicode, not str, so we decode as utf-8 # -import io - - def raw_stderr_print(text): with io.open(2, mode="wt", closefd=False) as myerr: myerr.write(text) @@ -344,7 +341,7 @@ def wakeOnLANChanged(configElement): config.usage.wakeOnLAN = ConfigYesNo(default=False) config.usage.wakeOnLAN.addNotifier(wakeOnLANChanged) - #standby + # standby if getDisplayType() in ("textlcd7segment"): config.usage.blinking_display_clock_during_recording = ConfigSelection(default="Rec", choices=[ ("Rec", _("REC")), @@ -353,7 +350,7 @@ def wakeOnLANChanged(configElement): else: config.usage.blinking_display_clock_during_recording = ConfigYesNo(default=False) - #in use + # in use if getDisplayType() in ("textlcd"): config.usage.blinking_rec_symbol_during_recording = ConfigSelection(default="Channel", choices=[ ("Rec", _("REC Symbol")), From 683a03cfd8ac9353275799713cc11c5ef715dcd5 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Wed, 25 Oct 2023 06:00:08 +0000 Subject: [PATCH 072/401] PEP8 double aggressive E301 ~ E306 --- lib/python/Components/UsageConfig.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/python/Components/UsageConfig.py b/lib/python/Components/UsageConfig.py index 6f2f32882fd..d22caca7978 100644 --- a/lib/python/Components/UsageConfig.py +++ b/lib/python/Components/UsageConfig.py @@ -18,6 +18,8 @@ # getting a time-stamp prepended. # stderr expect unicode, not str, so we decode as utf-8 # + + def raw_stderr_print(text): with io.open(2, mode="wt", closefd=False) as myerr: myerr.write(text) From 53c10967f8dfbac98607fae04842f3b694c26ab1 Mon Sep 17 00:00:00 2001 From: Twol Date: Wed, 25 Oct 2023 08:48:47 +0200 Subject: [PATCH 073/401] [ServicePosition] use variable name to replace l --- .../Components/Converter/ServicePosition.py | 80 +++++++++---------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/lib/python/Components/Converter/ServicePosition.py b/lib/python/Components/Converter/ServicePosition.py index cec06a1e489..74c770d78bd 100644 --- a/lib/python/Components/Converter/ServicePosition.py +++ b/lib/python/Components/Converter/ServicePosition.py @@ -103,29 +103,29 @@ def getText(self): e = (self.length / 90000) - s return "%02d:%02d +%2dm" % (s / 60, s % 60, e / 60) - l = self.length + len = self.length p = self.position r = self.length - self.position # Remaining - if l < 0: + if len < 0: return "" if not self.detailed: - l /= 90000 + len /= 90000 p /= 90000 r /= 90000 if self.negate: - l = -l + len = -len if self.negate: p = -p if self.negate: r = -r - if l >= 0: + if len >= 0: sign_l = "" else: - l = -l + len = -len sign_l = "-" if p >= 0: @@ -152,7 +152,7 @@ def getText(self): if config.usage.swap_media_time_display_on_osd.value == "1": # Mins if self.type == self.TYPE_LENGTH: - return ngettext("%d Min", "%d Mins", (l / 60)) % (l / 60) + return ngettext("%d Min", "%d Mins", (len / 60)) % (len / 60) elif self.type == self.TYPE_POSITION: if config.usage.swap_time_remaining_on_osd.value == "1": # Elapsed return sign_p + ngettext("%d Min", "%d Mins", (p / 60)) % (p / 60) @@ -171,7 +171,7 @@ def getText(self): return sign_r + ngettext("%d Min", "%d Mins", (r / 60)) % (r / 60) elif config.usage.swap_media_time_display_on_osd.value == "2": # Mins Secs if self.type == self.TYPE_LENGTH: - return sign_l + "%d:%02d" % (l / 60, l % 60) + return sign_l + "%d:%02d" % (len / 60, len % 60) elif self.type == self.TYPE_POSITION: if config.usage.swap_time_remaining_on_osd.value == "1": # Elapsed return sign_p + "%d:%02d" % (p / 60, p % 60) @@ -190,7 +190,7 @@ def getText(self): return sign_r + "%d:%02d" % (r / 60, r % 60) elif config.usage.swap_media_time_display_on_osd.value == "3": # Hours Mins if self.type == self.TYPE_LENGTH: - return sign_l + "%d:%02d" % (l / 3600, l % 3600 / 60) + return sign_l + "%d:%02d" % (len / 3600, len % 3600 / 60) elif self.type == self.TYPE_POSITION: if config.usage.swap_time_remaining_on_osd.value == "1": # Elapsed return sign_p + "%d:%02d" % (p / 3600, p % 3600 / 60) @@ -209,7 +209,7 @@ def getText(self): return sign_r + "%d:%02d" % (r / 3600, r % 3600 / 60) elif config.usage.swap_media_time_display_on_osd.value == "4": # Hours Mins Secs if self.type == self.TYPE_LENGTH: - return sign_l + "%d:%02d:%02d" % (l / 3600, l % 3600 / 60, l % 60) + return sign_l + "%d:%02d:%02d" % (len / 3600, len % 3600 / 60, len % 60) elif self.type == self.TYPE_POSITION: if config.usage.swap_time_remaining_on_osd.value == "1": # Elapsed return sign_p + "%d:%02d:%02d" % (p / 3600, p % 3600 / 60, p % 60) @@ -228,39 +228,39 @@ def getText(self): return sign_r + "%d:%02d:%02d" % (r / 3600, r % 3600 / 60, r % 60) elif config.usage.swap_media_time_display_on_osd.value == "5": # Percentage if self.type == self.TYPE_LENGTH: - return sign_l + "%d:%02d" % (l / 3600, l % 3600 / 60) + return sign_l + "%d:%02d" % (len / 3600, len % 3600 / 60) elif self.type == self.TYPE_POSITION: if config.usage.swap_time_remaining_on_osd.value == "1": # Elapsed try: - return sign_p + "%d%%" % ((float(p + 0.0) / float(l + 0.0)) * 100) + return sign_p + "%d%%" % ((float(p + 0.0) / float(len + 0.0)) * 100) except: return "" elif config.usage.swap_time_remaining_on_osd.value == "2": # Elapsed & Remaining try: - return sign_p + "%d%% " % ((float(p + 0.0) / float(l + 0.0)) * 100) + sign_r + "%d%%" % ((float(r + 0.0) / float(l + 0.0)) * 100 + 1) + return sign_p + "%d%% " % ((float(p + 0.0) / float(len + 0.0)) * 100) + sign_r + "%d%%" % ((float(r + 0.0) / float(len + 0.0)) * 100 + 1) except: return "" elif config.usage.swap_time_remaining_on_osd.value == "3": # Remaining & Elapsed try: - return sign_r + "%d%% " % ((float(r + 0.0) / float(l + 0.0)) * 100 + 1) + sign_p + "%d%%" % ((float(p + 0.0) / float(l + 0.0)) * 100) + return sign_r + "%d%% " % ((float(r + 0.0) / float(len + 0.0)) * 100 + 1) + sign_p + "%d%%" % ((float(p + 0.0) / float(len + 0.0)) * 100) except: return "" else: try: - return sign_r + "%d%%" % ((float(p + 0.0) / float(l + 0.0)) * 100) + return sign_r + "%d%%" % ((float(p + 0.0) / float(len + 0.0)) * 100) except: return "" elif self.type == self.TYPE_REMAINING: if config.usage.swap_time_remaining_on_osd.value == "1": # Elapsed try: - return sign_p + "%d%%" % ((float(p + 0.0) / float(l + 0.0)) * 100) + return sign_p + "%d%%" % ((float(p + 0.0) / float(len + 0.0)) * 100) except: return "" elif config.usage.swap_time_remaining_on_osd.value == "2" or config.usage.swap_time_remaining_on_osd.value == "3": # Elapsed & Remaining return "" else: try: - return sign_r + "%d%%" % ((float(p + 0.0) / float(l + 0.0)) * 100) + return sign_r + "%d%%" % ((float(p + 0.0) / float(len + 0.0)) * 100) except: return "" @@ -269,14 +269,14 @@ def getText(self): if self.showHours: if self.showNoSeconds: if self.type == self.TYPE_LENGTH: - return sign_l + "%d:%02d" % (l / 3600, l % 3600 / 60) + return sign_l + "%d:%02d" % (len / 3600, len % 3600 / 60) elif self.type == self.TYPE_POSITION: return sign_p + "%d:%02d" % (p / 3600, p % 3600 / 60) elif self.type == self.TYPE_REMAINING: return sign_r + "%d:%02d" % (r / 3600, r % 3600 / 60) else: if self.type == self.TYPE_LENGTH: - return sign_l + "%d:%02d:%02d" % (l / 3600, l % 3600 / 60, l % 60) + return sign_l + "%d:%02d:%02d" % (len / 3600, len % 3600 / 60, len % 60) elif self.type == self.TYPE_POSITION: return sign_p + "%d:%02d:%02d" % (p / 3600, p % 3600 / 60, p % 60) elif self.type == self.TYPE_REMAINING: @@ -284,14 +284,14 @@ def getText(self): else: if self.showNoSeconds: if self.type == self.TYPE_LENGTH: - return ngettext("%d Min", "%d Mins", (l / 60)) % (l / 60) + return ngettext("%d Min", "%d Mins", (len / 60)) % (len / 60) elif self.type == self.TYPE_POSITION: return sign_p + ngettext("%d Min", "%d Mins", (p / 60)) % (p / 60) elif self.type == self.TYPE_REMAINING: return sign_r + ngettext("%d Min", "%d Mins", (r / 60)) % (r / 60) else: if self.type == self.TYPE_LENGTH: - return sign_l + "%d:%02d" % (l / 60, l % 60) + return sign_l + "%d:%02d" % (len / 60, len % 60) elif self.type == self.TYPE_POSITION: return sign_p + "%d:%02d" % (p / 60, p % 60) elif self.type == self.TYPE_REMAINING: @@ -299,14 +299,14 @@ def getText(self): else: if self.showHours: if self.type == self.TYPE_LENGTH: - return sign_l + "%d:%02d:%02d:%03d" % ((l / 3600 / 90000), (l / 90000) % 3600 / 60, (l / 90000) % 60, (l % 90000) / 90) + return sign_l + "%d:%02d:%02d:%03d" % ((len / 3600 / 90000), (len / 90000) % 3600 / 60, (len / 90000) % 60, (len % 90000) / 90) elif self.type == self.TYPE_POSITION: return sign_r + "%d:%02d:%02d:%03d" % ((r / 3600 / 90000), (r / 90000) % 3600 / 60, (r / 90000) % 60, (r % 90000) / 90) elif self.type == self.TYPE_REMAINING: return sign_p + "%d:%02d:%02d:%03d" % ((p / 3600 / 90000), (p / 90000) % 3600 / 60, (p / 90000) % 60, (p % 90000) / 90) else: if self.type == self.TYPE_LENGTH: - return sign_l + "%d:%02d:%03d" % ((l / 60 / 90000), (l / 90000) % 60, (l % 90000) / 90) + return sign_l + "%d:%02d:%03d" % ((len / 60 / 90000), (len / 90000) % 60, (len % 90000) / 90) elif self.type == self.TYPE_POSITION: return sign_p + "%d:%02d:%03d" % ((p / 60 / 90000), (p / 90000) % 60, (p % 90000) / 90) elif self.type == self.TYPE_REMAINING: @@ -321,7 +321,7 @@ def getText(self): sign_r = "+" if config.usage.swap_media_time_display_on_vfd.value == "1": # Mins if self.type == self.TYPE_VFD_LENGTH: - return ngettext("%d Min", "%d Mins", (l / 60)) % (l / 60) + return ngettext("%d Min", "%d Mins", (len / 60)) % (len / 60) elif self.type == self.TYPE_VFD_POSITION: if config.usage.swap_time_remaining_on_vfd.value == "1": # Elapsed return sign_p + ngettext("%d Min", "%d Mins", (p / 60)) % (p / 60) @@ -340,7 +340,7 @@ def getText(self): return sign_r + ngettext("%d Min", "%d Mins", (r / 60)) % (r / 60) elif config.usage.swap_media_time_display_on_vfd.value == "2": # Mins Secs if self.type == self.TYPE_VFD_LENGTH: - return sign_l + "%d:%02d" % (l / 60, l % 60) + return sign_l + "%d:%02d" % (len / 60, len % 60) elif self.type == self.TYPE_VFD_POSITION: if config.usage.swap_time_remaining_on_vfd.value == "1": # Elapsed return sign_p + "%d:%02d" % (p / 60, p % 60) @@ -359,7 +359,7 @@ def getText(self): return sign_r + "%d:%02d" % (r / 60, r % 60) elif config.usage.swap_media_time_display_on_vfd.value == "3": # Hours Mins if self.type == self.TYPE_VFD_LENGTH: - return sign_l + "%d:%02d" % (l / 3600, l % 3600 / 60) + return sign_l + "%d:%02d" % (len / 3600, len % 3600 / 60) elif self.type == self.TYPE_VFD_POSITION: if config.usage.swap_time_remaining_on_vfd.value == "1": # Elapsed return sign_p + "%d:%02d" % (p / 3600, p % 3600 / 60) @@ -378,7 +378,7 @@ def getText(self): return sign_r + "%d:%02d" % (r / 3600, r % 3600 / 60) elif config.usage.swap_media_time_display_on_vfd.value == "4": # Hours Mins Secs if self.type == self.TYPE_VFD_LENGTH: - return sign_l + "%d:%02d:%02d" % (l / 3600, l % 3600 / 60, l % 60) + return sign_l + "%d:%02d:%02d" % (len / 3600, len % 3600 / 60, len % 60) elif self.type == self.TYPE_VFD_POSITION: if config.usage.swap_time_remaining_on_vfd.value == "1": # Elapsed return sign_p + "%d:%02d:%02d" % (p / 3600, p % 3600 / 60, p % 60) @@ -397,39 +397,39 @@ def getText(self): return sign_r + "%d:%02d:%02d" % (r / 3600, r % 3600 / 60, r % 60) elif config.usage.swap_media_time_display_on_vfd.value == "5": # Percentage if self.type == self.TYPE_VFD_LENGTH: - return sign_l + "%d:%02d" % (l / 3600, l % 3600 / 60) + return sign_l + "%d:%02d" % (len / 3600, len % 3600 / 60) elif self.type == self.TYPE_VFD_POSITION: if config.usage.swap_time_remaining_on_vfd.value == "1": # Elapsed try: - return sign_p + "%d%%" % ((float(p + 0.0) / float(l + 0.0)) * 100) + return sign_p + "%d%%" % ((float(p + 0.0) / float(len + 0.0)) * 100) except: return "" elif config.usage.swap_time_remaining_on_vfd.value == "2": # Elapsed & Remaining try: - return sign_p + "%d%% " % ((float(p + 0.0) / float(l + 0.0)) * 100) + sign_r + "%d%%" % ((float(r + 0.0) / float(l + 0.0)) * 100 + 1) + return sign_p + "%d%% " % ((float(p + 0.0) / float(len + 0.0)) * 100) + sign_r + "%d%%" % ((float(r + 0.0) / float(len + 0.0)) * 100 + 1) except: return "" elif config.usage.swap_time_remaining_on_vfd.value == "3": # Remaining & Elapsed try: - return sign_r + "%d%% " % ((float(r + 0.0) / float(l + 0.0)) * 100 + 1) + sign_p + "%d%%" % ((float(p + 0.0) / float(l + 0.0)) * 100) + return sign_r + "%d%% " % ((float(r + 0.0) / float(len + 0.0)) * 100 + 1) + sign_p + "%d%%" % ((float(p + 0.0) / float(len + 0.0)) * 100) except: return "" else: try: - return sign_r + "%d%%" % ((float(p + 0.0) / float(l + 0.0)) * 100) + return sign_r + "%d%%" % ((float(p + 0.0) / float(len + 0.0)) * 100) except: return "" elif self.type == self.TYPE_VFD_REMAINING: if config.usage.swap_time_remaining_on_vfd.value == "1": # Elapsed try: - return sign_p + "%d%%" % ((float(p + 0.0) / float(l + 0.0)) * 100) + return sign_p + "%d%%" % ((float(p + 0.0) / float(len + 0.0)) * 100) except: return "" elif config.usage.swap_time_remaining_on_vfd.value == "2" or config.usage.swap_time_remaining_on_vfd.value == "3": # Elapsed & Remaining return "" else: try: - return sign_r + "%d%%" % ((float(p + 0.0) / float(l + 0.0)) * 100) + return sign_r + "%d%%" % ((float(p + 0.0) / float(len + 0.0)) * 100) except: return "" @@ -438,14 +438,14 @@ def getText(self): if self.showHours: if self.showNoSeconds: if self.type == self.TYPE_VFD_LENGTH: - return sign_l + "%d:%02d" % (l / 3600, l % 3600 / 60) + return sign_l + "%d:%02d" % (len / 3600, len % 3600 / 60) elif self.type == self.TYPE_VFD_POSITION: return sign_p + "%d:%02d" % (p / 3600, p % 3600 / 60) elif self.type == self.TYPE_REMAINING: return sign_r + "%d:%02d" % (r / 3600, r % 3600 / 60) else: if self.type == self.TYPE_VFD_LENGTH: - return sign_l + "%d:%02d:%02d" % (l / 3600, l % 3600 / 60, l % 60) + return sign_l + "%d:%02d:%02d" % (len / 3600, len % 3600 / 60, len % 60) elif self.type == self.TYPE_VFD_POSITION: return sign_p + "%d:%02d:%02d" % (p / 3600, p % 3600 / 60, p % 60) elif self.type == self.TYPE_REMAINING: @@ -453,14 +453,14 @@ def getText(self): else: if self.showNoSeconds: if self.type == self.TYPE_VFD_LENGTH: - return ngettext("%d Min", "%d Mins", (l / 60)) % (l / 60) + return ngettext("%d Min", "%d Mins", (len / 60)) % (len / 60) elif self.type == self.TYPE_VFD_POSITION: return sign_p + ngettext("%d Min", "%d Mins", (p / 60)) % (p / 60) elif self.type == self.TYPE_VFD_REMAINING: return sign_r + ngettext("%d Min", "%d Mins", (r / 60)) % (r / 60) else: if self.type == self.TYPE_VFD_LENGTH: - return sign_l + "%d:%02d" % (l / 60, l % 60) + return sign_l + "%d:%02d" % (len / 60, len % 60) elif self.type == self.TYPE_VFD_POSITION: return sign_p + "%d:%02d" % (p / 60, p % 60) elif self.type == self.TYPE_REMAINING: @@ -468,14 +468,14 @@ def getText(self): else: if self.showHours: if self.type == self.TYPE_VFD_LENGTH: - return sign_l + "%d:%02d:%02d:%03d" % ((l / 3600 / 90000), (l / 90000) % 3600 / 60, (l / 90000) % 60, (l % 90000) / 90) + return sign_l + "%d:%02d:%02d:%03d" % ((len / 3600 / 90000), (len / 90000) % 3600 / 60, (len / 90000) % 60, (len % 90000) / 90) elif self.type == self.TYPE_VFD_POSITION: return sign_r + "%d:%02d:%02d:%03d" % ((r / 3600 / 90000), (r / 90000) % 3600 / 60, (r / 90000) % 60, (r % 90000) / 90) elif self.type == self.TYPE_REMAINING: return sign_p + "%d:%02d:%02d:%03d" % ((p / 3600 / 90000), (p / 90000) % 3600 / 60, (p / 90000) % 60, (p % 90000) / 90) else: if self.type == self.TYPE_VFD_LENGTH: - return sign_l + "%d:%02d:%03d" % ((l / 60 / 90000), (l / 90000) % 60, (l % 90000) / 90) + return sign_l + "%d:%02d:%03d" % ((len / 60 / 90000), (len / 90000) % 60, (len % 90000) / 90) elif self.type == self.TYPE_VFD_POSITION: return sign_p + "%d:%02d:%03d" % ((p / 60 / 90000), (p / 90000) % 60, (p % 90000) / 90) elif self.type == self.TYPE_REMAINING: From 304226cb9df46c71d5ee01722d63c8ca4014a539 Mon Sep 17 00:00:00 2001 From: Twol Date: Wed, 25 Oct 2023 08:49:27 +0200 Subject: [PATCH 074/401] [MenuList] valid l use noqa --- lib/python/Components/MenuList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/MenuList.py b/lib/python/Components/MenuList.py index cc77325de33..9d312174524 100644 --- a/lib/python/Components/MenuList.py +++ b/lib/python/Components/MenuList.py @@ -5,7 +5,7 @@ class MenuList(GUIComponent): def __init__(self, list, enableWrapAround=True, content=eListboxPythonStringContent): GUIComponent.__init__(self) - self.l = content() + self.l = content() # noqa: E741 self.onSelectionChanged = [] self.setList(list) self.enableWrapAround = enableWrapAround From 155ae6c30a43e644d5415b90691def77b8c73806 Mon Sep 17 00:00:00 2001 From: Twol Date: Wed, 25 Oct 2023 08:49:47 +0200 Subject: [PATCH 075/401] [MovieList] mark valid l with noqa, use variable name for others --- lib/python/Components/MovieList.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/python/Components/MovieList.py b/lib/python/Components/MovieList.py index bec5ec90e19..e9e35870121 100644 --- a/lib/python/Components/MovieList.py +++ b/lib/python/Components/MovieList.py @@ -237,7 +237,7 @@ def __init__(self, root, sort_type=None, descr_state=None, allowCollections=Fals if config.usage.time.wide.value: self.dateWidth = int(self.dateWidth * 1.15) self.reloadDelayTimer = None - self.l = eListboxPythonMultiContent() + self.l = eListboxPythonMultiContent() # noqa: E741 self.tags = set() self.markList = [] self.allowCollections = allowCollections # used to disable collections when loaded by OpenWebIf @@ -603,12 +603,12 @@ def getCurrentIndex(self): return self.instance.getCurrentIndex() def getCurrentEvent(self): - l = self.l.getCurrentSelection() - return l and l[0] and l[1] and l[1].getEvent(l[0]) + currl = self.l.getCurrentSelection() + return currl and currl[0] and currl[1] and currl[1].getEvent(currl[0]) def getCurrent(self): - l = self.l.getCurrentSelection() - return l and l[0] + currl = self.l.getCurrentSelection() + return currl and currl[0] def getItem(self, index): if self.list: From 1c32c7dcbe61cb84430d4f3280eba3731ca90782 Mon Sep 17 00:00:00 2001 From: Twol Date: Wed, 25 Oct 2023 08:50:05 +0200 Subject: [PATCH 076/401] [PowerTimerList] valid l use noqa --- lib/python/Components/PowerTimerList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/PowerTimerList.py b/lib/python/Components/PowerTimerList.py index 3308d290f8c..c7ef3769f0c 100644 --- a/lib/python/Components/PowerTimerList.py +++ b/lib/python/Components/PowerTimerList.py @@ -125,7 +125,7 @@ def buildTimerEntry(self, timer, processed): def __init__(self, list): GUIComponent.__init__(self) self.onSelectionChanged = [] - self.l = eListboxPythonMultiContent() + self.l = eListboxPythonMultiContent() # noqa: E741 self.l.setBuildFunc(self.buildTimerEntry) self.serviceNameFont = gFont("Regular", 20) self.font = gFont("Regular", 18) From d2b4f42502a32cfb9d9ba763350bb367bd3cbe85 Mon Sep 17 00:00:00 2001 From: Twol Date: Wed, 25 Oct 2023 08:50:27 +0200 Subject: [PATCH 077/401] [TimerList] valid l use noqa --- lib/python/Components/TimerList.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Components/TimerList.py b/lib/python/Components/TimerList.py index e967a95df07..db32289f6e5 100644 --- a/lib/python/Components/TimerList.py +++ b/lib/python/Components/TimerList.py @@ -136,7 +136,7 @@ def addPicon(): def __init__(self, list): GUIComponent.__init__(self) self.onSelectionChanged = [] - self.l = eListboxPythonMultiContent() + self.l = eListboxPythonMultiContent() # noqa: E741 self.l.setBuildFunc(self.buildTimerEntry) self.serviceNameFont = gFont("Regular", 20) self.font = gFont("Regular", 18) @@ -149,7 +149,7 @@ def __init__(self, list): self.iconMargin = 4 self.satPosLeft = 160 self.iconWait = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/timer_wait.png")) - #currently intended that all icons have the same size + # currently intended that all icons have the same size self.iconWidth = self.iconWait.size().width() self.iconHeight = self.iconWait.size().height() self.iconRecording = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/timer_rec.png")) From e247bbd8b0c0881a00d1ac3210379d379866b9b9 Mon Sep 17 00:00:00 2001 From: Twol Date: Wed, 25 Oct 2023 09:08:52 +0200 Subject: [PATCH 078/401] [VolumeControl] valid l use noqa, remove unused variable oldvol --- lib/python/Components/VolumeControl.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/python/Components/VolumeControl.py b/lib/python/Components/VolumeControl.py index b4732ecebd7..17422a8d357 100644 --- a/lib/python/Components/VolumeControl.py +++ b/lib/python/Components/VolumeControl.py @@ -2,7 +2,7 @@ from Tools.Profile import profile from Screens.Volume import Volume from Screens.Mute import Mute -from GlobalActions import globalActionMap +from GlobalActions import globalActionMap # noqa: F401 from Components.config import config, ConfigSubsection, ConfigInteger import skin @@ -65,7 +65,6 @@ def volDown(self): self.setVolume(-1) def setVolume(self, direction): - oldvol = self.volctrl.getVolume() # local variable 'oldvol' is assigned to but never used if direction > 0: self.volctrl.volumeUp() else: From 28b12252a5da0772ee962382e2e351a04beb83be Mon Sep 17 00:00:00 2001 From: Twol Date: Wed, 25 Oct 2023 09:12:34 +0200 Subject: [PATCH 079/401] [config] use variable name instead of l --- lib/python/Components/config.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/python/Components/config.py b/lib/python/Components/config.py index 00ada7e1199..98aaab16812 100644 --- a/lib/python/Components/config.py +++ b/lib/python/Components/config.py @@ -1065,10 +1065,10 @@ def __init__(self, default): # dafault can either be a timestamp # or an (hours, minutes) tuple. if isinstance(default, tuple): - l = list(localtime()) - l[3] = default[0] # hours - l[4] = default[1] # minutes - default = int(mktime(tuple(l))) + itemList = list(localtime()) + itemList[3] = default[0] # hours + itemList[4] = default[1] # minutes + default = int(mktime(tuple(itemList))) t = localtime(default) ConfigSequence.__init__(self, seperator=":", limits=clock_limits, default=[t.tm_hour, t.tm_min]) @@ -2198,11 +2198,11 @@ def pickle(self): def unpickle(self, lines, base_file=True): tree = {} configbase = tree.setdefault("config", {}) - for l in lines: - if not l or l[0] == '#': + for element in lines: + if not element or element[0] == '#': continue - result = l.split('=', 1) + result = element.split('=', 1) if len(result) != 2: continue (name, val) = result From 9bfe549951208b857f45d76a40d4bddc16528455 Mon Sep 17 00:00:00 2001 From: Twol Date: Wed, 25 Oct 2023 09:15:49 +0200 Subject: [PATCH 080/401] [MovieSelection] unused variable playInForeground --- lib/python/Screens/MovieSelection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Screens/MovieSelection.py b/lib/python/Screens/MovieSelection.py index 4c76b6f04a8..e387dc5de3a 100644 --- a/lib/python/Screens/MovieSelection.py +++ b/lib/python/Screens/MovieSelection.py @@ -1207,7 +1207,7 @@ def callLater(self, function): def __evEOF(self): playInBackground = self.list.playInBackground - playInForeground = self.list.playInForeground + # playInForeground = self.list.playInForeground if not playInBackground: print("[MovieSelection] Not playing anything in background") return From 3ead2f4876d56d3aaba66fc84e4b15af219d33d6 Mon Sep 17 00:00:00 2001 From: Twol Date: Wed, 25 Oct 2023 09:23:55 +0200 Subject: [PATCH 081/401] [PowerTimerEntry] remove ActionMap entriesroot --- lib/python/Screens/PowerTimerEntry.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/python/Screens/PowerTimerEntry.py b/lib/python/Screens/PowerTimerEntry.py index 52adcc78aa5..cd6caf2447c 100644 --- a/lib/python/Screens/PowerTimerEntry.py +++ b/lib/python/Screens/PowerTimerEntry.py @@ -1,6 +1,5 @@ from Screens.TimerEntryBase import TimerEntryBase, TimerLogBase from Components.config import ConfigSelection, ConfigYesNo, ConfigInteger -from Components.ActionMap import HelpableActionMap, NumberActionMap from Components.SystemInfo import SystemInfo from PowerTimer import AFTEREVENT, TIMERTYPE from time import time From 1f0491bef993eda394e1b9523ee8f7a24138bf71 Mon Sep 17 00:00:00 2001 From: Twol Date: Wed, 25 Oct 2023 09:30:11 +0200 Subject: [PATCH 082/401] [Satconfig] remove NoSave --- lib/python/Screens/Satconfig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Screens/Satconfig.py b/lib/python/Screens/Satconfig.py index 5e47109a1f1..66c1d0d1e8c 100644 --- a/lib/python/Screens/Satconfig.py +++ b/lib/python/Screens/Satconfig.py @@ -8,7 +8,7 @@ from Components.Label import Label from Components.UsageConfig import showrotorpositionChoicesUpdate, preferredTunerChoicesUpdate from Components.SelectionList import SelectionList, SelectionEntryComponent -from Components.config import getConfigListEntry, config, ConfigNothing, ConfigBoolean, configfile, NoSave, ConfigSelection +from Components.config import getConfigListEntry, config, ConfigNothing, ConfigBoolean, configfile, ConfigSelection from Components.Sources.List import List from Components.Sources.StaticText import StaticText from Screens.MessageBox import MessageBox From ffb1edc3a0af6a1072005480a13ddee78c2edb93 Mon Sep 17 00:00:00 2001 From: Twol Date: Wed, 25 Oct 2023 09:33:20 +0200 Subject: [PATCH 083/401] [UserInterfacePositioner] remove pixmap --- lib/python/Screens/UserInterfacePositioner.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/python/Screens/UserInterfacePositioner.py b/lib/python/Screens/UserInterfacePositioner.py index 743db44bb2b..cf35ddc84ed 100644 --- a/lib/python/Screens/UserInterfacePositioner.py +++ b/lib/python/Screens/UserInterfacePositioner.py @@ -5,7 +5,6 @@ from Components.ConfigList import ConfigListScreen from Components.SystemInfo import SystemInfo from Components.Sources.StaticText import StaticText -from Components.Pixmap import Pixmap from Components.Console import Console from Tools.Directories import fileCheck, fileExists from enigma import getDesktop From 87526e5eab429ef8a264731e0cc5f384779ca319 Mon Sep 17 00:00:00 2001 From: Twol Date: Wed, 25 Oct 2023 12:23:58 +0200 Subject: [PATCH 084/401] [OscamInfo] cleanup --- lib/python/Screens/OScamInfo.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/python/Screens/OScamInfo.py b/lib/python/Screens/OScamInfo.py index 2d5f7da8c5b..56f3ffe81ed 100644 --- a/lib/python/Screens/OScamInfo.py +++ b/lib/python/Screens/OScamInfo.py @@ -1133,9 +1133,9 @@ def showData(self): # emm_err = emms.attrib["totalerror"] ecmstat = rdr.find("ecmstats") - totalecm = ecmstat.attrib["totalecm"] + # totalecm = ecmstat.attrib["totalecm"] ecmcount = ecmstat.attrib["count"] and int(ecmstat.attrib["count"]) or 0 - lastacc = ecmstat.attrib["lastaccess"] + # lastacc = ecmstat.attrib["lastaccess"] ecm = ecmstat.findall("ecm") if ecmcount > 0: for j in ecm: @@ -1143,7 +1143,7 @@ def showData(self): channel = j.attrib["channelname"] avgtime = j.attrib["avgtime"] lasttime = j.attrib["lasttime"] - retcode = j.attrib["rc"] + # retcode = j.attrib["rc"] rcs = j.attrib["rcs"] num = j.text if rcs == "found": From c4fad0ef21d49e3dfbe56ed1bbac0146290e121d Mon Sep 17 00:00:00 2001 From: openvix-build Date: Wed, 25 Oct 2023 13:10:34 +0000 Subject: [PATCH 085/401] openvix: developer 6.4.009.004 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 20f7f713d44..aea54ab19cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1187,3 +1187,4 @@ openvix: developer 6.4.008.013 openvix: developer 6.4.009.001 openvix: developer 6.4.009.002 openvix: developer 6.4.009.003 +openvix: developer 6.4.009.004 From 56a51a84e06f371e60c2cc1cee78b31994f8901b Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Thu, 26 Oct 2023 08:56:28 +0300 Subject: [PATCH 086/401] fix ePythonStringContent to handle correct text offset --- lib/python/Components/TimerList.py | 50 +++++++++++++++++------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/lib/python/Components/TimerList.py b/lib/python/Components/TimerList.py index db32289f6e5..117d360e4d2 100644 --- a/lib/python/Components/TimerList.py +++ b/lib/python/Components/TimerList.py @@ -8,7 +8,7 @@ from Components.Renderer.Picon import getPiconName from skin import parseFont, parseScale from Tools.Alternatives import GetWithAlternative -from Tools.Directories import resolveFilename, SCOPE_CURRENT_SKIN +from Tools.Directories import resolveFilename, SCOPE_GUISKIN from Tools.FuzzyDate import FuzzyTime from Tools.LoadPixmap import LoadPixmap from Tools.TextBoundary import getTextBoundarySize @@ -49,12 +49,12 @@ def addPicon(): backcolor=None, backcolor_sel=None, flags=BT_SCALE | BT_KEEP_ASPECT_RATIO | BT_ALIGN_CENTER)) return piconWidth - colX = 0 + colX = self.sidesMargin if config.usage.timerlist_showpicons.value: colX += addPicon() - res.append((eListboxPythonMultiContent.TYPE_TEXT, colX + self.iconWidth + self.iconMargin, 0, nameWidth, self.rowSplit, 2, RT_HALIGN_LEFT | RT_VALIGN_BOTTOM, timer.name)) - res.append((eListboxPythonMultiContent.TYPE_TEXT, width - serviceNameWidth, 0, serviceNameWidth, self.rowSplit, 0, RT_HALIGN_RIGHT | RT_VALIGN_BOTTOM, serviceName)) + res.append((eListboxPythonMultiContent.TYPE_TEXT, colX + self.sidesMargin + self.iconWidth + self.iconMargin, 0, nameWidth, self.rowSplit, 2, RT_HALIGN_LEFT | RT_VALIGN_BOTTOM, timer.name)) + res.append((eListboxPythonMultiContent.TYPE_TEXT, width - serviceNameWidth - self.sidesMargin, 0, serviceNameWidth, self.rowSplit, 0, RT_HALIGN_RIGHT | RT_VALIGN_BOTTOM, serviceName)) begin = FuzzyTime(timer.begin) if timer.repeated: @@ -74,7 +74,7 @@ def addPicon(): else: repeatedtext = ", ".join(repeatedtext) if self.iconRepeat: - res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, colX + self.iconMargin, self.rowSplit + (self.itemHeight - self.rowSplit - self.iconHeight) // 2, self.iconWidth, self.iconHeight, self.iconRepeat)) + res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, colX + self.sidesMargin + self.iconMargin // 2, self.rowSplit + (self.itemHeight - self.rowSplit - self.iconHeight) // 2, self.iconWidth, self.iconHeight, self.iconRepeat)) else: repeatedtext = begin[0] # date if timer.justplay: @@ -120,16 +120,16 @@ def addPicon(): state = _("done!") icon = self.iconDone - icon and res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, colX + self.iconMargin // 2, (self.rowSplit - self.iconHeight) // 2, self.iconWidth, self.iconHeight, icon)) + icon and res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, colX + self.sidesMargin + self.iconMargin // 2, (self.rowSplit - self.iconHeight) // 2, self.iconWidth, self.iconHeight, icon)) orbpos = self.getOrbitalPos(timer.service_ref) orbposWidth = getTextBoundarySize(self.instance, self.font, self.l.getItemSize(), orbpos).width() - res.append((eListboxPythonMultiContent.TYPE_TEXT, colX + self.satPosLeft, self.rowSplit, orbposWidth, self.itemHeight - self.rowSplit, 1, RT_HALIGN_LEFT | RT_VALIGN_TOP, orbpos)) - res.append((eListboxPythonMultiContent.TYPE_TEXT, colX + self.iconWidth + self.iconMargin, self.rowSplit, self.satPosLeft - self.iconWidth - self.iconMargin, self.itemHeight - self.rowSplit, 1, RT_HALIGN_LEFT | RT_VALIGN_TOP, state)) - res.append((eListboxPythonMultiContent.TYPE_TEXT, colX + self.satPosLeft + orbposWidth, self.rowSplit, width - self.satPosLeft - orbposWidth - colX, self.itemHeight - self.rowSplit, 1, RT_HALIGN_RIGHT | RT_VALIGN_TOP, text)) + res.append((eListboxPythonMultiContent.TYPE_TEXT, colX + self.sidesMargin + self.satPosLeft, self.rowSplit, orbposWidth, self.itemHeight - self.rowSplit, 1, RT_HALIGN_LEFT | RT_VALIGN_TOP, orbpos)) + res.append((eListboxPythonMultiContent.TYPE_TEXT, colX + self.sidesMargin + self.iconWidth + self.iconMargin, self.rowSplit, self.satPosLeft - self.iconWidth - self.iconMargin, self.itemHeight - self.rowSplit, 1, RT_HALIGN_LEFT | RT_VALIGN_TOP, state)) + res.append((eListboxPythonMultiContent.TYPE_TEXT, colX + self.sidesMargin + self.satPosLeft + orbposWidth, self.rowSplit, width - self.satPosLeft - orbposWidth - colX - self.sidesMargin*2, self.itemHeight - self.rowSplit, 1, RT_HALIGN_RIGHT | RT_VALIGN_TOP, text)) - line = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "div-h.png")) - res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, 0, height - 2, width, 2, line)) + if self.sepLinePixmap: + res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, 0, height - 2, width, 2, self.sepLinePixmap)) return res @@ -145,21 +145,23 @@ def __init__(self, list): self.l.setList(list) self.listCount = len(list) # used by pager self.itemHeight = 50 + self.sidesMargin = 0 self.rowSplit = 25 self.iconMargin = 4 self.satPosLeft = 160 - self.iconWait = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/timer_wait.png")) - # currently intended that all icons have the same size + self.sepLinePixmap = None + self.iconWait = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/timer_wait.png")) + #currently intended that all icons have the same size self.iconWidth = self.iconWait.size().width() self.iconHeight = self.iconWait.size().height() - self.iconRecording = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/timer_rec.png")) - self.iconPrepared = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/timer_prep.png")) - self.iconDone = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/timer_done.png")) - self.iconRepeat = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/timer_rep.png")) - self.iconZapped = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/timer_zap.png")) - self.iconDisabled = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/timer_off.png")) - self.iconFailed = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/timer_failed.png")) - self.iconAutoTimer = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/timer_autotimer.png")) + self.iconRecording = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/timer_rec.png")) + self.iconPrepared = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/timer_prep.png")) + self.iconDone = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/timer_done.png")) + self.iconRepeat = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/timer_rep.png")) + self.iconZapped = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/timer_zap.png")) + self.iconDisabled = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/timer_off.png")) + self.iconFailed = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/timer_failed.png")) + self.iconAutoTimer = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/timer_autotimer.png")) try: from Plugins.SystemPlugins.IceTV import loadIceTVIcon self.iconIceTVTimer = loadIceTVIcon("timer_icetv.png") @@ -187,6 +189,12 @@ def iconMargin(value): def satPosLeft(value): self.satPosLeft = parseScale(value) + + def sidesMargin(value): + self.sidesMargin = parseScale(value) + + def sepLinePixmap(value): + self.sepLinePixmap = LoadPixmap(resolveFilename(SCOPE_GUISKIN, value)) for (attrib, value) in self.skinAttributes[:]: try: From 249a6fde16682e189914882e9aff7b20c6342148 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Thu, 26 Oct 2023 08:53:33 +0300 Subject: [PATCH 087/401] fix ePythonStringContent to handle correct text offset --- lib/gui/elistboxcontent.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/gui/elistboxcontent.cpp b/lib/gui/elistboxcontent.cpp index 3f68334da68..ed13c38a388 100644 --- a/lib/gui/elistboxcontent.cpp +++ b/lib/gui/elistboxcontent.cpp @@ -287,13 +287,15 @@ void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style, { const char *string = PyUnicode_Check(item) ? PyUnicode_AsUTF8(item) : ""; ePoint text_offset = offset; + ePoint style_text_offset = ePoint(0, 0); if (gray) painter.setForegroundColor(gRGB(0x808080)); int flags = 0; if (local_style) { - text_offset += local_style->m_text_offset; + style_text_offset = local_style->m_text_offset; + text_offset += style_text_offset; if (local_style->m_valign == eListboxStyle::alignTop) flags |= gPainter::RT_VALIGN_TOP; @@ -312,7 +314,8 @@ void eListboxPythonStringContent::paint(gPainter &painter, eWindowStyle &style, flags |= gPainter::RT_HALIGN_BLOCK; } - painter.renderText(eRect(text_offset, m_itemsize), string, flags, border_color, border_size); + // Here we have to compensate the local style text offset from both sides + painter.renderText(eRect(text_offset.x(), text_offset.y(), m_itemsize.width() - style_text_offset.x()*2, m_itemsize.height() - style_text_offset.y()*2), string, flags, border_color, border_size); } } From 6e73da2e5253cce56abedead21c62ec3124d9982 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Thu, 26 Oct 2023 15:01:49 +0300 Subject: [PATCH 088/401] - added new addon for dynamic button sequences --- .../Components/Addons/ButtonSequence.py | 104 ++++++++++++++++++ lib/python/Components/Addons/GUIAddon.py | 10 +- lib/python/Components/Element.py | 3 + 3 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 lib/python/Components/Addons/ButtonSequence.py diff --git a/lib/python/Components/Addons/ButtonSequence.py b/lib/python/Components/Addons/ButtonSequence.py new file mode 100644 index 00000000000..a7bee57f1bb --- /dev/null +++ b/lib/python/Components/Addons/ButtonSequence.py @@ -0,0 +1,104 @@ +from Components.Addons.GUIAddon import GUIAddon + +from enigma import eListbox, eListboxPythonMultiContent, BT_ALIGN_CENTER, BT_VALIGN_CENTER + +from skin import parseScale, applySkinFactor + +from Components.MultiContent import MultiContentEntryPixmapAlphaBlend +from Components.Sources.List import List +from Components.Sources.Boolean import Boolean +from Components.Sources.StaticText import StaticText + +from Tools.Directories import resolveFilename, SCOPE_GUISKIN +from Tools.LoadPixmap import LoadPixmap + + +class ButtonSequence(GUIAddon): + def __init__(self): + GUIAddon.__init__(self) + self.l = eListboxPythonMultiContent() # noqa: E741 + self.l.setBuildFunc(self.buildEntry) + self.l.setItemHeight(36) + self.l.setItemWidth(36) + self.spacing = applySkinFactor(10) + self.orientations = {"orHorizontal": eListbox.orHorizontal, "orVertical": eListbox.orVertical} + self.orientation = eListbox.orHorizontal + self.pixmaps = {} + + def onContainerShown(self): + for x, val in self.sources.items(): + if self.constructButtonSequence not in val.onChanged: + val.onChanged.append(self.constructButtonSequence) + self.constructButtonSequence() + + GUI_WIDGET = eListbox + + def updateAddon(self, sequence): + l_list = [] + l_list.append((sequence,)) + self.l.setList(l_list) + + def buildEntry(self, sequence): + xPos = self.instance.size().width() + yPos = 0 + + + res = [None] + + for x in sequence: + if x in self.pixmaps: + pic = LoadPixmap(resolveFilename(SCOPE_GUISKIN, self.pixmaps[x])) + if pic: + pixd_size = pic.size() + pixd_width = pixd_size.width() + pixd_height = pixd_size.height() + res.append(MultiContentEntryPixmapAlphaBlend( + pos=(xPos - pixd_width, yPos), + size=(pixd_width, pixd_height), + png=pic, + backcolor=None, backcolor_sel=None, flags=BT_ALIGN_CENTER)) + xPos -= pixd_width + self.spacing + return res + + + def postWidgetCreate(self, instance): + instance.setSelectionEnable(False) + instance.setContent(self.l) + instance.allowNativeKeys(False) + + + def constructButtonSequence(self): + sequence = [] + for x, val in self.sources.items(): + if isinstance(val, Boolean) and val.boolean: + if x not in sequence: + sequence.append(x) + elif isinstance(val, StaticText) and val.text: + if x not in sequence: + sequence.append(x) + + self.updateAddon(sequence) + + def applySkin(self, desktop, parent): + attribs = [] + for (attrib, value) in self.skinAttributes[:]: + if attrib == "pixmaps": + self.pixmaps = dict(item.split(':') for item in value.split(',')) + elif attrib == "itemHeight": + self.l.setItemHeight(parseScale(value)) + elif attrib == "itemWidth": + self.l.setItemWidth(parseScale(value)) + elif attrib == "spacing": + self.spacing = parseScale(value) + elif attrib == "orientation": + self.orientation = self.orientations.get(value, self.orientations["orHorizontal"]) + if self.orientation == eListbox.orHorizontal: + self.instance.setOrientation(eListbox.orVertical) + self.l.setOrientation(eListbox.orVertical) + else: + self.instance.setOrientation(eListbox.orHorizontal) + self.l.setOrientation(eListbox.orHorizontal) + else: + attribs.append((attrib, value)) + self.skinAttributes = attribs + return GUIAddon.applySkin(self, desktop, parent) diff --git a/lib/python/Components/Addons/GUIAddon.py b/lib/python/Components/Addons/GUIAddon.py index 4257ac526d4..2ecedaf23ec 100644 --- a/lib/python/Components/Addons/GUIAddon.py +++ b/lib/python/Components/Addons/GUIAddon.py @@ -4,9 +4,17 @@ class GUIAddon(GUIComponent): def __init__(self): GUIComponent.__init__(self) + self.sources = {} def connectRelatedElement(self, relatedElementName, container): - self.source = container[relatedElementName] + relatedElementNames = relatedElementName.split(",") + if len(relatedElementNames) == 1: + self.source = container[relatedElementName] + elif len(relatedElementNames) > 1: + for x in relatedElementNames: + x = x.strip() + if x in container: + self.sources[x] = container[x] container.onShow.append(self.onContainerShown) def onContainerShown(self): diff --git a/lib/python/Components/Element.py b/lib/python/Components/Element.py index 10c841bd539..80e11fa8c12 100644 --- a/lib/python/Components/Element.py +++ b/lib/python/Components/Element.py @@ -44,6 +44,7 @@ def __init__(self): self.source = None self.__suspended = True self.cache = None + self.onChanged = [] def connectDownstream(self, downstream): self.downstream_elements.append(downstream) @@ -90,6 +91,8 @@ def changed(self, *args, **kwargs): self.cache = {} self.downstream_elements.changed(*args, **kwargs) self.cache = None + for x in self.onChanged: + x() def setSuspend(self, suspended): changed = self.__suspended != suspended From f9a9542ac03e0b01954d7b3eaa19fe4e70feeb50 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Thu, 26 Oct 2023 17:05:25 +0300 Subject: [PATCH 089/401] - add onChanged event to VariableText so to work with addons --- lib/python/Components/VariableText.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/python/Components/VariableText.py b/lib/python/Components/VariableText.py index 407ef8dacaa..46b151d7c5b 100644 --- a/lib/python/Components/VariableText.py +++ b/lib/python/Components/VariableText.py @@ -5,6 +5,7 @@ def __init__(self): object.__init__(self) self.message = "" self.instance = None + self.onChanged = [] def setText(self, text): try: @@ -14,6 +15,8 @@ def setText(self, text): except: self.message = "" self.instance.setText(self.message or "") + for x in self.onChanged: + x() def setMarkedPos(self, pos): if self.instance: From 4c46bcf0ac1857699fc5fb161bf2735c67c9fcc4 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Thu, 26 Oct 2023 17:20:44 +0300 Subject: [PATCH 090/401] - added alignment possibility to the ButtonSequence --- lib/python/Components/Addons/ButtonSequence.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/python/Components/Addons/ButtonSequence.py b/lib/python/Components/Addons/ButtonSequence.py index a7bee57f1bb..8ba134866d7 100644 --- a/lib/python/Components/Addons/ButtonSequence.py +++ b/lib/python/Components/Addons/ButtonSequence.py @@ -23,6 +23,7 @@ def __init__(self): self.spacing = applySkinFactor(10) self.orientations = {"orHorizontal": eListbox.orHorizontal, "orVertical": eListbox.orVertical} self.orientation = eListbox.orHorizontal + self.alignment = "left" self.pixmaps = {} def onContainerShown(self): @@ -39,7 +40,7 @@ def updateAddon(self, sequence): self.l.setList(l_list) def buildEntry(self, sequence): - xPos = self.instance.size().width() + xPos = self.instance.size().width() if self.alignment == "right" else 0 yPos = 0 @@ -52,12 +53,16 @@ def buildEntry(self, sequence): pixd_size = pic.size() pixd_width = pixd_size.width() pixd_height = pixd_size.height() + pic_x_pos = (xPos - pixd_width) if self.alignment == "right" else xPos res.append(MultiContentEntryPixmapAlphaBlend( - pos=(xPos - pixd_width, yPos), + pos=(pic_x_pos, yPos), size=(pixd_width, pixd_height), png=pic, backcolor=None, backcolor_sel=None, flags=BT_ALIGN_CENTER)) - xPos -= pixd_width + self.spacing + if self.alignment == "right": + xPos -= pixd_width + self.spacing + else: + xPos += pixd_width + self.spacing return res @@ -90,6 +95,8 @@ def applySkin(self, desktop, parent): self.l.setItemWidth(parseScale(value)) elif attrib == "spacing": self.spacing = parseScale(value) + elif attrib == "alignment": + self.alignment = value elif attrib == "orientation": self.orientation = self.orientations.get(value, self.orientations["orHorizontal"]) if self.orientation == eListbox.orHorizontal: From e3e4a9e2a481fa395cd62ca5ad620873a1b55f3d Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Thu, 26 Oct 2023 14:42:21 +0000 Subject: [PATCH 091/401] PEP8 double aggressive E22, E224, E241, E242 and E27 --- lib/python/Components/TimerList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/TimerList.py b/lib/python/Components/TimerList.py index 117d360e4d2..5ce93355ed7 100644 --- a/lib/python/Components/TimerList.py +++ b/lib/python/Components/TimerList.py @@ -126,7 +126,7 @@ def addPicon(): orbposWidth = getTextBoundarySize(self.instance, self.font, self.l.getItemSize(), orbpos).width() res.append((eListboxPythonMultiContent.TYPE_TEXT, colX + self.sidesMargin + self.satPosLeft, self.rowSplit, orbposWidth, self.itemHeight - self.rowSplit, 1, RT_HALIGN_LEFT | RT_VALIGN_TOP, orbpos)) res.append((eListboxPythonMultiContent.TYPE_TEXT, colX + self.sidesMargin + self.iconWidth + self.iconMargin, self.rowSplit, self.satPosLeft - self.iconWidth - self.iconMargin, self.itemHeight - self.rowSplit, 1, RT_HALIGN_LEFT | RT_VALIGN_TOP, state)) - res.append((eListboxPythonMultiContent.TYPE_TEXT, colX + self.sidesMargin + self.satPosLeft + orbposWidth, self.rowSplit, width - self.satPosLeft - orbposWidth - colX - self.sidesMargin*2, self.itemHeight - self.rowSplit, 1, RT_HALIGN_RIGHT | RT_VALIGN_TOP, text)) + res.append((eListboxPythonMultiContent.TYPE_TEXT, colX + self.sidesMargin + self.satPosLeft + orbposWidth, self.rowSplit, width - self.satPosLeft - orbposWidth - colX - self.sidesMargin * 2, self.itemHeight - self.rowSplit, 1, RT_HALIGN_RIGHT | RT_VALIGN_TOP, text)) if self.sepLinePixmap: res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, 0, height - 2, width, 2, self.sepLinePixmap)) From 3676bd14b4992bc0e23990fafa45c8ffdbd04ba5 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Thu, 26 Oct 2023 14:43:01 +0000 Subject: [PATCH 092/401] PEP8 double aggressive E301 ~ E306 --- lib/python/Components/Addons/ButtonSequence.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/python/Components/Addons/ButtonSequence.py b/lib/python/Components/Addons/ButtonSequence.py index 8ba134866d7..8b09b1bce5b 100644 --- a/lib/python/Components/Addons/ButtonSequence.py +++ b/lib/python/Components/Addons/ButtonSequence.py @@ -43,7 +43,6 @@ def buildEntry(self, sequence): xPos = self.instance.size().width() if self.alignment == "right" else 0 yPos = 0 - res = [None] for x in sequence: @@ -65,13 +64,11 @@ def buildEntry(self, sequence): xPos += pixd_width + self.spacing return res - def postWidgetCreate(self, instance): instance.setSelectionEnable(False) instance.setContent(self.l) instance.allowNativeKeys(False) - def constructButtonSequence(self): sequence = [] for x, val in self.sources.items(): From 1af7e1d6e3653e886da52fe3957d8e6ad1fa4bdb Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Thu, 26 Oct 2023 14:43:17 +0000 Subject: [PATCH 093/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Components/TimerList.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Components/TimerList.py b/lib/python/Components/TimerList.py index 5ce93355ed7..2b0167616c7 100644 --- a/lib/python/Components/TimerList.py +++ b/lib/python/Components/TimerList.py @@ -189,10 +189,10 @@ def iconMargin(value): def satPosLeft(value): self.satPosLeft = parseScale(value) - + def sidesMargin(value): self.sidesMargin = parseScale(value) - + def sepLinePixmap(value): self.sepLinePixmap = LoadPixmap(resolveFilename(SCOPE_GUISKIN, value)) From 6d007a039437b8accfb0c3f8e8f3729672e91434 Mon Sep 17 00:00:00 2001 From: Huevos Date: Thu, 26 Oct 2023 22:50:32 +0200 Subject: [PATCH 094/401] [listboxservice] when searching markers don't stop on numbered markers --- lib/service/listboxservice.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 895fac20e18..44751c34199 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -204,14 +204,14 @@ int eListboxServiceContent::getPrevMarkerPos() { --i; --index; - if (!(i->flags & eServiceReference::isMarker && !(i->flags & eServiceReference::isInvisible))) + if (!(i->flags & eServiceReference::isMarker && !(i->flags & eServiceReference::isNumberedMarker) && !(i->flags & eServiceReference::isInvisible))) break; } while (index) { --i; --index; - if (i->flags & eServiceReference::isMarker && !(i->flags & eServiceReference::isInvisible)) + if (i->flags & eServiceReference::isMarker && !(i->flags & eServiceReference::isNumberedMarker) && !(i->flags & eServiceReference::isInvisible)) break; } return cursorResolve(index); @@ -227,7 +227,7 @@ int eListboxServiceContent::getNextMarkerPos() { ++i; ++index; - if (i->flags & eServiceReference::isMarker && !(i->flags & eServiceReference::isInvisible)) + if (i->flags & eServiceReference::isMarker && !(i->flags & eServiceReference::isNumberedMarker) && !(i->flags & eServiceReference::isInvisible)) break; } return cursorResolve(index); From 1e6bd36e5d24398c2aad694898eb9f6ed9d5cc13 Mon Sep 17 00:00:00 2001 From: openvix-build Date: Thu, 26 Oct 2023 20:56:32 +0000 Subject: [PATCH 095/401] openvix: developer 6.4.009.005 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index aea54ab19cf..e4e698e6296 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1188,3 +1188,4 @@ openvix: developer 6.4.009.001 openvix: developer 6.4.009.002 openvix: developer 6.4.009.003 openvix: developer 6.4.009.004 +openvix: developer 6.4.009.005 From e849c500bcde1a8d1053adbd643ee08e7b2a2518 Mon Sep 17 00:00:00 2001 From: Huevos Date: Fri, 27 Oct 2023 13:39:10 +0200 Subject: [PATCH 096/401] Revert "[listboxservice] when searching markers don't stop on numbered markers" This reverts commit 6d007a039437b8accfb0c3f8e8f3729672e91434. --- lib/service/listboxservice.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 44751c34199..895fac20e18 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -204,14 +204,14 @@ int eListboxServiceContent::getPrevMarkerPos() { --i; --index; - if (!(i->flags & eServiceReference::isMarker && !(i->flags & eServiceReference::isNumberedMarker) && !(i->flags & eServiceReference::isInvisible))) + if (!(i->flags & eServiceReference::isMarker && !(i->flags & eServiceReference::isInvisible))) break; } while (index) { --i; --index; - if (i->flags & eServiceReference::isMarker && !(i->flags & eServiceReference::isNumberedMarker) && !(i->flags & eServiceReference::isInvisible)) + if (i->flags & eServiceReference::isMarker && !(i->flags & eServiceReference::isInvisible)) break; } return cursorResolve(index); @@ -227,7 +227,7 @@ int eListboxServiceContent::getNextMarkerPos() { ++i; ++index; - if (i->flags & eServiceReference::isMarker && !(i->flags & eServiceReference::isNumberedMarker) && !(i->flags & eServiceReference::isInvisible)) + if (i->flags & eServiceReference::isMarker && !(i->flags & eServiceReference::isInvisible)) break; } return cursorResolve(index); From 41320646128af00497778a216f39dcd57074bf88 Mon Sep 17 00:00:00 2001 From: Huevos Date: Fri, 27 Oct 2023 14:23:42 +0200 Subject: [PATCH 097/401] [listboxservice] fix searching for prev/next visible marker --- lib/service/listboxservice.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 895fac20e18..e0e970536b8 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -200,20 +200,28 @@ int eListboxServiceContent::getPrevMarkerPos() return 0; list::iterator i(m_cursor); int index = m_cursor_number; - while (index) // Skip precending markers + + // if the search is starting part way through a section return to the start of the current section + while (index) { --i; --index; - if (!(i->flags & eServiceReference::isMarker && !(i->flags & eServiceReference::isInvisible))) + if (i->flags == eServiceReference::isMarker) break; } + + // if the search started from part way through the current section return now because this is the previous visible marker + if (cursorResolve(index) + 1 != cursorResolve(m_cursor_number)) return cursorResolve(index); + + // search for visible marker index of previous section while (index) { --i; --index; - if (i->flags & eServiceReference::isMarker && !(i->flags & eServiceReference::isInvisible)) + if (i->flags == eServiceReference::isMarker) break; } + return cursorResolve(index); } @@ -227,7 +235,7 @@ int eListboxServiceContent::getNextMarkerPos() { ++i; ++index; - if (i->flags & eServiceReference::isMarker && !(i->flags & eServiceReference::isInvisible)) + if (i->flags == eServiceReference::isMarker) break; } return cursorResolve(index); From c5bdf8ac02c29de17f2cff2572c0668a6a8d3015 Mon Sep 17 00:00:00 2001 From: openvix-build Date: Fri, 27 Oct 2023 12:28:25 +0000 Subject: [PATCH 098/401] openvix: developer 6.4.009.006 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index e4e698e6296..4c9e5fbfc51 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1189,3 +1189,4 @@ openvix: developer 6.4.009.002 openvix: developer 6.4.009.003 openvix: developer 6.4.009.004 openvix: developer 6.4.009.005 +openvix: developer 6.4.009.006 From ad53728c8ed1ef59e3c27b6103d93f2755ac7a84 Mon Sep 17 00:00:00 2001 From: Twol Date: Fri, 27 Oct 2023 15:52:54 +0200 Subject: [PATCH 099/401] [OScamInfo] - cleanup PEP --- lib/python/Screens/OScamInfo.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/python/Screens/OScamInfo.py b/lib/python/Screens/OScamInfo.py index 56f3ffe81ed..e14db42b43d 100644 --- a/lib/python/Screens/OScamInfo.py +++ b/lib/python/Screens/OScamInfo.py @@ -137,17 +137,17 @@ def getUserData(self): elif "httpport" in i.lower(): port = i.split("=")[1].strip() elif "httpallowed" in i.lower(): - # Once we encounter a httpallowed statement, we have to assume oscam/ncam webif is blocking us ... - blocked = True + # Once we encounter a httpallowed statement, we have to assume oscam/ncam webif is blocking us allowed = i.split("=")[1].strip() - if "::1" in allowed or "127.0.0.1" in allowed or "0.0.0.0-255.255.255.255" in allowed: - # ... until we find either 127.0.0.1 or ::1 in allowed list - blocked = False if "::1" not in allowed: ipconfigured = False - - ret = [user, pwd, port, ipconfigured] # 127.0.0.1 gets 403 in oscam webif so ignore block fix later - + if "::1" in allowed or "127.0.0.1" in allowed or "0.0.0.0-255.255.255.255" in allowed: + # ... until we find either 127.0.0.1 or ::1 in allowed list + blocked = False # noqa: F841 + else: + blocked = True + if not blocked: + ret = [user, pwd, port, ipconfigured] return ret def openWebIF(self, part=None, reader=None): From 63b4c86010af020c00358f8d442d3cf4e46a8f80 Mon Sep 17 00:00:00 2001 From: Twol Date: Fri, 27 Oct 2023 15:53:58 +0200 Subject: [PATCH 100/401] [TimerList] - cleanup PEP --- lib/python/Components/TimerList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/TimerList.py b/lib/python/Components/TimerList.py index 2b0167616c7..fd9fe9303a9 100644 --- a/lib/python/Components/TimerList.py +++ b/lib/python/Components/TimerList.py @@ -151,7 +151,7 @@ def __init__(self, list): self.satPosLeft = 160 self.sepLinePixmap = None self.iconWait = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/timer_wait.png")) - #currently intended that all icons have the same size + # currently intended that all icons have the same size self.iconWidth = self.iconWait.size().width() self.iconHeight = self.iconWait.size().height() self.iconRecording = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/timer_rec.png")) From db265e8c8eaa0acd847abcac82e6e99cca16501e Mon Sep 17 00:00:00 2001 From: Twol Date: Fri, 27 Oct 2023 15:55:41 +0200 Subject: [PATCH 101/401] [WirelessLan][plugin] - cleanup PEP --- lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py b/lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py index d93894ab2b9..351cd6fd1cc 100644 --- a/lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py +++ b/lib/python/Plugins/SystemPlugins/WirelessLan/plugin.py @@ -320,8 +320,8 @@ def buildEntryComponent(self, essid, bssid, encrypted, iface, maxrate, signal, f return essid, bssid, _("Signal: ") + str(signal), _("Max. bitrate: ") + str(maxrate), _("Encrypted: ") + encryption, _("Interface: ") + str(iface), frequency_norm, self.divpng def updateAPList(self): - newList = [] - newList = self.getAccessPoints(refresh=True) + # newList = [] + # newList = self.getAccessPoints(refresh=True) # noqa: F841 self.newAPList = [] tmpList = [] currentListEntry = None From 317f9c4b0ed90de3fc1ad70283d512236838fabc Mon Sep 17 00:00:00 2001 From: Twol Date: Fri, 27 Oct 2023 16:28:06 +0200 Subject: [PATCH 102/401] [NetworkSetup] - cleanup - remove six - only import plugins etc once - improve code/messages for enable/disable Adapters in Wizard & initialised image --- lib/python/Screens/NetworkSetup.py | 250 +++++++++++++---------------- 1 file changed, 113 insertions(+), 137 deletions(-) diff --git a/lib/python/Screens/NetworkSetup.py b/lib/python/Screens/NetworkSetup.py index a8310a83d46..a00e9dcb2c4 100644 --- a/lib/python/Screens/NetworkSetup.py +++ b/lib/python/Screens/NetworkSetup.py @@ -1,11 +1,9 @@ -import six - from os import system, path as os_path, unlink, rename import netifaces as ni from random import Random import string import time - +import glob from enigma import eTimer, eConsoleAppContainer from boxbranding import getBoxType, getMachineBrand, getMachineName, getImageType, getImageVersion @@ -29,16 +27,29 @@ from Screens.Setup import Setup from Screens.Standby import TryQuitMainloop from Screens.TextBox import TextBox -from Tools.Directories import fileExists, resolveFilename, SCOPE_PLUGINS, SCOPE_CURRENT_SKIN +from Tools.Directories import fileExists, isPluginInstalled, resolveFilename, SCOPE_CURRENT_SKIN, SCOPE_PLUGINS from Tools.LoadPixmap import LoadPixmap +networkWizard = False +XML_networkWizard = False +wirelessLan = False + +if os_path.exists(resolveFilename(SCOPE_PLUGINS, "SystemPlugins/NetworkWizard/networkwizard.xml")): + XML_networkWizard = True +if isPluginInstalled("NetworkWizard"): + networkWizard = True + from Plugins.SystemPlugins.NetworkWizard.NetworkWizard import NetworkWizard +if isPluginInstalled("WirelessLan"): + wirelessLan = True + from Plugins.SystemPlugins.WirelessLan.Wlan import brcmWLConfig, iStatus, wpaSupplicant + from Plugins.SystemPlugins.WirelessLan.plugin import WlanScan, WlanStatus + # Define a function to determine whether a service is configured to # start at boot time. # This checks for a start file in rc2.d (rc4.d might be more # appropriate, but historically it's been rc2.d, so...). # -import glob def ServiceIsEnabled(service_name): @@ -113,7 +124,6 @@ def doInstall(self, callback, pkgname): self.ConsoleB.ePopen("/usr/bin/opkg install " + pkgname, callback) def checkNetworkState(self, str, retval, extra_args): - str = six.ensure_str(str) if "Collected errors" in str: self.session.openWithCallback(self.close, MessageBox, _("A background update check is in progress, please wait a few minutes and then try again."), type=MessageBox.TYPE_INFO, timeout=10, close_on_any_key=True) elif not str: @@ -159,7 +169,7 @@ def __init__(self, session): Screen.__init__(self, session) HelpableScreen.__init__(self) self.setTitle(_("Device")) - + # print("[NetworkSetup][NetworkAdapterSelection]") self.wlan_errortext = _("No working wireless network adapter found.\nPlease verify that you have attached a compatible WLAN device and your network is configured correctly.") self.lan_errortext = _("No working local network adapter found.\nPlease verify that you have attached a network cable and your network is configured correctly.") self.oktext = _("Press OK on your remote control to continue.") @@ -174,22 +184,22 @@ def __init__(self, session): self["introduction"] = StaticText(self.edittext) self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", - { - "cancel": (self.close, _("Exit network interface list")), - "ok": (self.okbuttonClick, _("Select interface")), - }) + { + "cancel": (self.close, _("Exit network interface list")), + "ok": (self.okbuttonClick, _("Select interface")), + }) self["ColorActions"] = HelpableActionMap(self, "ColorActions", - { - "red": (self.close, _("Exit network interface list")), - "green": (self.okbuttonClick, _("Select interface")), - "blue": (self.openNetworkWizard, _("Use the network wizard to configure selected network adapter")), - }) + { + "red": (self.close, _("Exit network interface list")), + "green": (self.okbuttonClick, _("Select interface")), + "blue": (self.openNetworkWizard, _("Use the network wizard to configure selected network adapter")), + }) self["DefaultInterfaceAction"] = HelpableActionMap(self, "ColorActions", - { - "yellow": (self.setDefaultInterface, [_("Set interface as the default Interface"), _("* Only available if more than one interface is active.")]), - }) + { + "yellow": (self.setDefaultInterface, [_("Set interface as the default Interface"), _("* Only available if more than one interface is active.")]), + }) self.adapters = [(iNetwork.getFriendlyAdapterName(x), x) for x in iNetwork.getAdapterList()] @@ -295,7 +305,7 @@ def updateList(self): active_int = False self.list.append(self.buildInterfaceList(x[1], _(x[0]), default_int, active_int)) - if os_path.exists(resolveFilename(SCOPE_PLUGINS, "SystemPlugins/NetworkWizard/networkwizard.xml")): + if XML_networkWizard: self["key_blue"].setText(_("Network wizard")) self["list"].list = self.list @@ -350,15 +360,12 @@ def restartfinishedCB(self, data): self.session.open(MessageBox, _("Finished configuring your network"), type=MessageBox.TYPE_INFO, timeout=10, default=False) def openNetworkWizard(self): - if os_path.exists(resolveFilename(SCOPE_PLUGINS, "SystemPlugins/NetworkWizard/networkwizard.xml")): - try: - from Plugins.SystemPlugins.NetworkWizard.NetworkWizard import NetworkWizard - except ImportError: - self.session.open(MessageBox, _("The network wizard extension is not installed!\nPlease install it."), type=MessageBox.TYPE_INFO, timeout=10) - else: - selection = self["list"].getCurrent() - if selection is not None: - self.session.openWithCallback(self.AdapterSetupClosed, NetworkWizard, selection[0]) + if networkWizard and XML_networkWizard: + selection = self["list"].getCurrent() + if selection is not None: + self.session.openWithCallback(self.AdapterSetupClosed, NetworkWizard, selection[0]) + else: + self.session.open(MessageBox, _("The network wizard extension is not installed!\nPlease install it."), type=MessageBox.TYPE_INFO, timeout=10) class NameserverSetup(ConfigListScreen, HelpableScreen, Screen): @@ -368,7 +375,7 @@ def __init__(self, session): self.setTitle(_("Nameserver Settings")) self.skinName = ["NameserverSetup", "Setup"] self.backupNameserverList = iNetwork.getNameserverList()[:] - print("[NameserverSetup] backup-list:%s" % self.backupNameserverList) + # print("[NetworkSetup][NameserverSetup] backup-list:%s" % self.backupNameserverList) self["key_yellow"] = StaticText(_("Add")) self["key_blue"] = StaticText(_("Delete")) @@ -376,7 +383,7 @@ def __init__(self, session): { "yellow": (self.add, _("Add a nameserver entry")), "blue": (self.remove, _("Remove a nameserver entry")), - }) + }) # noqa: E123 ConfigListScreen.__init__(self, [], session=session, on_change=self.changedEntry, fullUI=True) self.createConfig() self.createSetup() @@ -386,7 +393,7 @@ def createConfig(self): self.nameserverEntries = [NoSave(ConfigIP(default=nameserver)) for nameserver in self.nameservers] def createSetup(self): - self["config"].list = [getConfigListEntry(_("Nameserver %d") % (i + 1), x) for i, x in enumerate(self.nameserverEntries)] + self["config"].list = [getConfigListEntry(_("Nameserver %d") % (i+1), x) for i, x in enumerate(self.nameserverEntries)] # noqa: E226 def keySave(self): iNetwork.clearNameservers() @@ -423,6 +430,7 @@ class NetworkMacSetup(ConfigListScreen, HelpableScreen, Screen): def __init__(self, session): Screen.__init__(self, session) HelpableScreen.__init__(self) + # print("[NetworkSetup][NetworkMacSetup]") self.skinName = ["NetworkMacSetup", "Setup"] self.setTitle(_("MAC Address Settings")) ifacex = "wlan0" @@ -484,7 +492,7 @@ class AdapterSetup(ConfigListScreen, HelpableScreen, Screen): def __init__(self, session, networkinfo=None, essid=None): Screen.__init__(self, session) HelpableScreen.__init__(self) - + # print("[NetworkSetup][AdapterSetup] ") if isinstance(networkinfo, (list, tuple)): self.iface = networkinfo[0] self.essid = networkinfo[1] @@ -496,16 +504,16 @@ def __init__(self, session, networkinfo=None, essid=None): self.extended = None self.applyConfigRef = None - self.finished_cb = None + self.finished_cb = None # switch used by Wizard/NetworkWizard to control Wizard process self.oktext = _("Press OK on your remote control to continue.") self.oldInterfaceState = iNetwork.getAdapterAttribute(self.iface, "up") self.createConfig() self["ColorActions"] = HelpableActionMap(self, "ColorActions", - { - "blue": (self.KeyBlue, _("Open nameserver configuration")), - }) + { + "blue": (self.KeyBlue, _("Open nameserver configuration")), + }) ConfigListScreen.__init__(self, [], session=session, on_change=self.newConfig, fullUI=True) @@ -529,7 +537,7 @@ def __init__(self, session, networkinfo=None, essid=None): self["Adaptertext"] = StaticText(_("Network:")) self["Adapter"] = StaticText() - self["introduction2"] = StaticText(_("Press OK to activate the settings.")) + self["introduction2"] = StaticText(_("Enter adapter settings or disable adapter, then Save to action changed setup.")) self["key_blue"] = StaticText(_("Edit DNS")) def layoutFinished(self): @@ -578,10 +586,8 @@ def createConfig(self): if iNetwork.isWirelessInterface(self.iface): driver = iNetwork.detectWlanModule(self.iface) if driver in ("brcm-wl", ): - from Plugins.SystemPlugins.WirelessLan.Wlan import brcmWLConfig self.ws = brcmWLConfig() else: - from Plugins.SystemPlugins.WirelessLan.Wlan import wpaSupplicant self.ws = wpaSupplicant() self.encryptionlist = [] self.encryptionlist.append(("Unencrypted", _("Unencrypted"))) @@ -643,7 +649,6 @@ def createSetup(self): self.extended = callFnc if "configStrings" in p.fnc: self.configStrings = p.fnc["configStrings"] - isExistBcmWifi = os_path.exists("/tmp/bcm/" + self.iface) if not isExistBcmWifi: self.hiddenSSID = getConfigListEntry(_("Hidden network"), config.plugins.wlan.hiddenessid) @@ -681,7 +686,11 @@ def newConfig(self): def keySave(self): self.hideInputHelp() if self["config"].isChanged(): - self.session.openWithCallback(self.keySaveConfirm, MessageBox, (_("Are you sure you want to activate this network configuration?\n\n") + self.oktext)) + # print("[NetworkSetup][AdapterSetup][keySave] interface value", self.activateInterfaceEntry.value) + if self.activateInterfaceEntry.value: + self.session.openWithCallback(self.keySaveConfirm, MessageBox, (_("Are you sure you want to activate this network configuration?\n\n") + self.oktext)) + else: + self.session.openWithCallback(self.keySaveConfirm, MessageBox, (_("Are you sure you want to disable this network configuration?\n\n") + self.oktext)) else: if self.finished_cb: self.finished_cb() @@ -728,7 +737,6 @@ def applyConfig(self, ret=False): iNetwork.setAdapterAttribute(self.iface, "gateway", self.gatewayConfigEntry.value) else: iNetwork.removeAdapterAttribute(self.iface, "gateway") - if self.extended is not None and self.configStrings is not None: iNetwork.setAdapterAttribute(self.iface, "configStrings", self.configStrings(self.iface)) self.ws.writeConfig(self.iface) @@ -736,7 +744,7 @@ def applyConfig(self, ret=False): if self.activateInterfaceEntry.value is False: iNetwork.deactivateInterface(self.iface, self.deactivateInterfaceCB) iNetwork.writeNetworkConfig() - self.applyConfigRef = self.session.openWithCallback(self.applyConfigfinishedCB, MessageBox, _("Please wait while your network configuration is activated..."), type=MessageBox.TYPE_INFO, enable_input=False) + self.applyConfigRef = self.session.openWithCallback(self.applyConfigfinishedCB, MessageBox, _("Please wait while your network configuration is deactivated..."), type=MessageBox.TYPE_INFO, enable_input=False) else: if self.oldInterfaceState is False: iNetwork.activateInterface(self.iface, self.deactivateInterfaceCB) @@ -765,15 +773,16 @@ def getInterfacesDataAvail(self, data): def applyConfigfinishedCB(self, data): if data is True: - if self.finished_cb: + if self.finished_cb: # switch set by Wizard/NetworkWizard to control return to wizard self.session.openWithCallback(lambda x: self.finished_cb(), MessageBox, _("Your network configuration has been activated."), type=MessageBox.TYPE_INFO, timeout=10) + elif self.activateInterfaceEntry.value is False: # if not wizard check for disable/enable Adapter + self.session.openWithCallback(self.ConfigfinishedCB, MessageBox, _("Your network configuration has been disabled."), type=MessageBox.TYPE_INFO, timeout=10) else: self.session.openWithCallback(self.ConfigfinishedCB, MessageBox, _("Your network configuration has been activated."), type=MessageBox.TYPE_INFO, timeout=10) def ConfigfinishedCB(self, data): - if data is not None: - if data is True: - self.close("ok") + if data is not None and data: + self.close('ok') def keyCancelConfirm(self, result): if not result: @@ -791,11 +800,11 @@ def keyCancel(self): self.close("cancel") def keyCancelCB(self, data): - if data is not None: - if data is True: - self.close("cancel") + if data is not None and data: + self.close("cancel") - def runAsync(self, finished_cb): + def runAsync(self, finished_cb): # Async used by Wizard/NetworkWizard to control Wizard code flow + # print("[NetworkSetup][AdapterSetup][runAsync1] finished_cb", finished_cb) self.finished_cb = finished_cb self.keySave() @@ -848,23 +857,23 @@ def __init__(self, session, iface=None): self.missingwlanplugintxt = _("The wireless LAN plugin is not installed!\nPlease install it.") self["WizardActions"] = HelpableActionMap(self, "WizardActions", - { - "up": (self.up, _("Move up to previous entry")), - "down": (self.down, _("Move down to next entry")), - "left": (self.left, _("Move up to first entry")), - "right": (self.right, _("Move down to last entry")), - }) + { + "up": (self.up, _("Move up to previous entry")), + "down": (self.down, _("Move down to next entry")), + "left": (self.left, _("Move up to first entry")), + "right": (self.right, _("Move down to last entry")), + }) self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", - { - "cancel": (self.close, _("Exit network adapter setup menu")), - "ok": (self.ok, _("Select menu entry")), - }) + { + "cancel": (self.close, _("Exit network adapter setup menu")), + "ok": (self.ok, _("Select menu entry")), + }) self["ColorActions"] = HelpableActionMap(self, "ColorActions", - { - "red": (self.close, _("Exit network adapter setup menu")), - }) + { + "red": (self.close, _("Exit network adapter setup menu")), + }) self["actions"] = NumberActionMap(["WizardActions", "ShortcutActions"], { @@ -875,7 +884,7 @@ def __init__(self, session, iface=None): "red": self.close, "left": self.left, "right": self.right, - }, -2) + }, -2) # noqa: E123 self.updateStatusbar() self.onClose.append(self.cleanup) @@ -893,7 +902,7 @@ def queryWirelessDevice(self, iface): else: try: system("ifconfig %s up" % iface) - wlanresponse = list(Cell.all(iface)) # what is this? local variable 'wlanresponse' is assigned to but never used + wlanresponse = list(Cell.all(iface)) # noqa: F841 call to check setup except IOError as err: error_no, error_str = err.args if error_no in (errno.EOPNOTSUPP, errno.ENODEV, errno.EPERM): @@ -908,15 +917,10 @@ def ok(self): self.cleanup() if self["menulist"].getCurrent()[1] == "edit": if iNetwork.isWirelessInterface(self.iface): - try: - from Plugins.SystemPlugins.WirelessLan.plugin import WlanScan - except ImportError: - self.session.open(MessageBox, self.missingwlanplugintxt, type=MessageBox.TYPE_INFO, timeout=10) + if wirelessLan and self.queryWirelessDevice(self.iface): + self.session.openWithCallback(self.AdapterSetupClosed, AdapterSetup, self.iface) else: - if self.queryWirelessDevice(self.iface): - self.session.openWithCallback(self.AdapterSetupClosed, AdapterSetup, self.iface) - else: - self.showErrorMessage() # Display Wlan not available Message + self.showErrorMessage() # Display Wlan not available Message else: self.session.openWithCallback(self.AdapterSetupClosed, AdapterSetup, self.iface) if self["menulist"].getCurrent()[1] == "test": @@ -926,29 +930,18 @@ def ok(self): if self["menulist"].getCurrent()[1] == 'mac': self.session.open(NetworkMacSetup) if self["menulist"].getCurrent()[1] == "scanwlan": - try: - from Plugins.SystemPlugins.WirelessLan.plugin import WlanScan - except ImportError: - self.session.open(MessageBox, self.missingwlanplugintxt, type=MessageBox.TYPE_INFO, timeout=10) + if wirelessLan and self.queryWirelessDevice(self.iface): + self.session.openWithCallback(self.WlanScanClosed, WlanScan, self.iface) else: - if self.queryWirelessDevice(self.iface): - self.session.openWithCallback(self.WlanScanClosed, WlanScan, self.iface) - else: - self.showErrorMessage() # Display Wlan not available Message + self.showErrorMessage() # Display Wlan not available Message if self["menulist"].getCurrent()[1] == "wlanstatus": - try: - from Plugins.SystemPlugins.WirelessLan.plugin import WlanStatus - except ImportError: - self.session.open(MessageBox, self.missingwlanplugintxt, type=MessageBox.TYPE_INFO, timeout=10) + if wirelessLan and self.queryWirelessDevice(self.iface): + self.session.openWithCallback(self.WlanStatusClosed, WlanStatus, self.iface) else: - if self.queryWirelessDevice(self.iface): - self.session.openWithCallback(self.WlanStatusClosed, WlanStatus, self.iface) - else: - self.showErrorMessage() # Display Wlan not available Message + self.showErrorMessage() # Display Wlan not available Message if self["menulist"].getCurrent()[1] == "lanrestart": self.session.openWithCallback(self.restartLan, MessageBox, (_("Are you sure you want to restart your network interfaces?\n\n") + self.oktext)) if self["menulist"].getCurrent()[1] == "openwizard": - from Plugins.SystemPlugins.NetworkWizard.NetworkWizard import NetworkWizard self.session.openWithCallback(self.AdapterSetupClosed, NetworkWizard, self.iface) if self["menulist"].getCurrent()[1][0] == "extendedSetup": self.extended = self["menulist"].getCurrent()[1][2] @@ -1008,13 +1001,11 @@ def updateStatusbar(self, data=None): if iNetwork.isWirelessInterface(self.iface): self["devicepic"].setPixmapNum(1) - try: - from Plugins.SystemPlugins.WirelessLan.Wlan import iStatus - except: + if wirelessLan: + iStatus.getDataForInterface(self.iface, self.getInfoCB) + else: self["statuspic"].setPixmapNum(1) self["statuspic"].show() - else: - iStatus.getDataForInterface(self.iface, self.getInfoCB) else: iNetwork.getLinkState(self.iface, self.dataAvail) self["devicepic"].setPixmapNum(0) @@ -1048,25 +1039,23 @@ def genMainMenu(self): self.extendedSetup = ("extendedSetup", menuEntryDescription, self.extended) menu.append((menuEntryName, self.extendedSetup)) - if os_path.exists(resolveFilename(SCOPE_PLUGINS, "SystemPlugins/NetworkWizard/networkwizard.xml")): + if XML_networkWizard: menu.append((_("Network wizard"), "openwizard")) - # kernel_ver = about.getKernelVersionString() - # if kernel_ver <= "3.5.0": + # kernel_ver = about.getKernelVersionString() + # if kernel_ver <= "3.5.0": menu.append((_("Network MAC settings"), "mac")) return menu def AdapterSetupClosed(self, *ret): if ret is not None and len(ret): if ret[0] == "ok" and (iNetwork.isWirelessInterface(self.iface) and iNetwork.getAdapterAttribute(self.iface, "up") is True): - try: - from Plugins.SystemPlugins.WirelessLan.plugin import WlanStatus - except ImportError: - self.session.open(MessageBox, self.missingwlanplugintxt, type=MessageBox.TYPE_INFO, timeout=10) - else: + if wirelessLan: if self.queryWirelessDevice(self.iface): self.session.openWithCallback(self.WlanStatusClosed, WlanStatus, self.iface) else: self.showErrorMessage() # Display Wlan not available Message + else: + self.session.open(MessageBox, self.missingwlanplugintxt, type=MessageBox.TYPE_INFO, timeout=10) else: self.updateStatusbar() else: @@ -1074,7 +1063,6 @@ def AdapterSetupClosed(self, *ret): def WlanStatusClosed(self, *ret): if ret is not None and len(ret): - from Plugins.SystemPlugins.WirelessLan.Wlan import iStatus iStatus.stopWlanConsole() self.updateStatusbar() @@ -1082,7 +1070,6 @@ def WlanScanClosed(self, *ret): if ret[0] is not None: self.session.openWithCallback(self.AdapterSetupClosed, AdapterSetup, self.iface, ret[0]) else: - from Plugins.SystemPlugins.WirelessLan.Wlan import iStatus iStatus.stopWlanConsole() self.updateStatusbar() @@ -1105,7 +1092,6 @@ def restartfinishedCB(self, data): self.session.open(MessageBox, _("Your network has finished restarting"), type=MessageBox.TYPE_INFO, timeout=10, default=False) def dataAvail(self, data): - data = six.ensure_str(data) self.LinkState = None for line in data.splitlines(): line = line.strip() @@ -1128,11 +1114,7 @@ def cleanup(self): iNetwork.stopDeactivateInterfaceConsole() iNetwork.stopActivateInterfaceConsole() iNetwork.stopPingConsole() - try: - from Plugins.SystemPlugins.WirelessLan.Wlan import iStatus - except ImportError: - pass - else: + if wirelessLan: iStatus.stopWlanConsole() def getInfoCB(self, data, status): @@ -1495,15 +1477,13 @@ def setLabels(self): def getLinkState(self, iface): if iface in iNetwork.wlan_interfaces: - try: - from Plugins.SystemPlugins.WirelessLan.Wlan import iStatus - except: + if wirelessLan: + iStatus.getDataForInterface(self.iface, self.getInfoCB) + else: self["Network"].setForegroundColorNum(1) self["Network"].setText(_("disconnected")) self["NetworkInfo_Check"].setPixmapNum(1) self["NetworkInfo_Check"].show() - else: - iStatus.getDataForInterface(self.iface, self.getInfoCB) else: iNetwork.getLinkState(iface, self.LinkStatedataAvail) @@ -1578,11 +1558,7 @@ def getInfoCB(self, data, status): def cleanup(self): iNetwork.stopLinkStateConsole() iNetwork.stopDNSConsole() - try: - from Plugins.SystemPlugins.WirelessLan.Wlan import iStatus - except ImportError: - pass - else: + if wirelessLan: iStatus.stopWlanConsole() @@ -1599,23 +1575,23 @@ def __init__(self, session): self["introduction"] = StaticText() self["WizardActions"] = HelpableActionMap(self, "WizardActions", - { - "up": (self.up, _("Move up to previous entry")), - "down": (self.down, _("Move down to next entry")), - "left": (self.left, _("Move up to first entry")), - "right": (self.right, _("Move down to last entry")), - }) + { + "up": (self.up, _("Move up to previous entry")), + "down": (self.down, _("Move down to next entry")), + "left": (self.left, _("Move up to first entry")), + "right": (self.right, _("Move down to last entry")), + }) self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions", - { - "cancel": (self.close, _("Exit mounts setup menu")), - "ok": (self.ok, _("Select menu entry")), - }) + { + "cancel": (self.close, _("Exit mounts setup menu")), + "ok": (self.ok, _("Select menu entry")), + }) self["ColorActions"] = HelpableActionMap(self, "ColorActions", - { - "red": (self.close, _("Exit networkadapter setup menu")), - }) + { + "red": (self.close, _("Exit networkadapter setup menu")), + }) self["actions"] = NumberActionMap(["WizardActions", "ShortcutActions"], { @@ -1626,7 +1602,7 @@ def __init__(self, session): "red": self.close, "left": self.left, "right": self.right, - }, -2) + }, -2) # noqa: E123 if self.selectionChanged not in self["menulist"].onSelectionChanged: self["menulist"].onSelectionChanged.append(self.selectionChanged) From 99aa70845f7830b7dc17b2080f985f15905c9758 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Fri, 27 Oct 2023 14:30:22 +0000 Subject: [PATCH 103/401] PEP8 double aggressive E22, E224, E241, E242 and E27 --- lib/python/Screens/NetworkSetup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Screens/NetworkSetup.py b/lib/python/Screens/NetworkSetup.py index a00e9dcb2c4..cceebb0a6ac 100644 --- a/lib/python/Screens/NetworkSetup.py +++ b/lib/python/Screens/NetworkSetup.py @@ -393,7 +393,7 @@ def createConfig(self): self.nameserverEntries = [NoSave(ConfigIP(default=nameserver)) for nameserver in self.nameservers] def createSetup(self): - self["config"].list = [getConfigListEntry(_("Nameserver %d") % (i+1), x) for i, x in enumerate(self.nameserverEntries)] # noqa: E226 + self["config"].list = [getConfigListEntry(_("Nameserver %d") % (i + 1), x) for i, x in enumerate(self.nameserverEntries)] # noqa: E226 def keySave(self): iNetwork.clearNameservers() From 8fb4fcbb9ef1011edb4c5b0f00bca6dbd7b35ed6 Mon Sep 17 00:00:00 2001 From: Orlandoxx <95180049+Orlandoxx@users.noreply.github.com> Date: Sat, 28 Oct 2023 11:24:29 +0300 Subject: [PATCH 104/401] Updated Finnish (fi.po) translation Added latest changes. --- po/fi.po | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/po/fi.po b/po/fi.po index da6df2390b9..dd9f1356e0b 100644 --- a/po/fi.po +++ b/po/fi.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: enigma2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-27 23:35+0000\n" -"PO-Revision-Date: 2023-10-20 19:33+0300\n" +"PO-Revision-Date: 2023-10-28 11:23+0300\n" "Last-Translator: Orlandox\n" "Language-Team: timoj/Kojo/Samzam/Orlandox\n" "Language: fi\n" @@ -2240,7 +2240,7 @@ msgid "" "Are you sure you want to activate this network configuration?\n" "\n" msgstr "" -"Haluatko aktivoida nämä verkkoasetukset?\n" +"Haluatko varmasti aktivoida tämän verkkomäärityksen?\n" "\n" msgid "" @@ -13540,7 +13540,7 @@ msgstr "" "Suomenkielinen käännös: timoj, Kojo, Samzam, Orlandox\n" "\n" "Ylläpito : Orlandox\n" -"20.10.2023\n" +"28.10.2023\n" "http://www.huoltovalikko.com" msgid "TS file is too large for ISO9660 level 1!" @@ -18331,7 +18331,7 @@ msgid "Checking softcams..." msgstr "Tarkistetaan softcameja..." msgid "Choose IPK folder" -msgstr "Valitse IPK kansio" +msgstr "Valitse IPK-kansio" msgid "Choose files" msgstr "Valitse tiedostot" @@ -19104,3 +19104,19 @@ msgstr "Striimin välitys -portti" msgid "The port of the streamrelay server that is used to descramble services that can only be decrypted via streamrelay" msgstr "Striimin välitys -palvelimen portti, jota käytetään sellaisten palvelujen salauksen purkamiseen, joiden salaus voidaan purkaa vain striimin välityksen kautta" + +msgid "Enter adapter settings or disable adapter, then Save to action changed setup." +msgstr "Syötä sovittimen asetukset tai poista sovitin käytöstä ja sitten Tallenna toimintoon muutettu asetus." + +msgid "" +"Are you sure you want to disable this network configuration?\n" +"\n" +msgstr "" +"Haluatko varmasti poistaa tämän verkkomäärityksen käytöstä?\n" +"\n" + +msgid "Please wait while your network configuration is deactivated..." +msgstr "Odota, verkkoasetuksia poistetaan käytöstä..." + +msgid "Your network configuration has been disabled." +msgstr "Verkkoasetukset on poistettu käytöstä." From 4dc2380f2ff4a4518ad733c8ae8daab3bfca024e Mon Sep 17 00:00:00 2001 From: Huevos Date: Sat, 28 Oct 2023 13:01:23 +0200 Subject: [PATCH 105/401] [BackManager] remove pointless skin This falls back to "Setup" and every skin has that. If not it will fall back to emergency skin. --- .../SystemPlugins/ViX/BackupManager.py | 36 +------------------ 1 file changed, 1 insertion(+), 35 deletions(-) diff --git a/lib/python/Plugins/SystemPlugins/ViX/BackupManager.py b/lib/python/Plugins/SystemPlugins/ViX/BackupManager.py index 57f8b0c3410..080f1b6b0b6 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/BackupManager.py +++ b/lib/python/Plugins/SystemPlugins/ViX/BackupManager.py @@ -944,43 +944,9 @@ def closeRecursive(self): class VIXBackupManagerMenu(Setup): - skin = [""" - - - - - - - - - - - - - - - - - """, - 560, 550, # screen - 0, 0, 140, 40, # colors - 140, 0, 140, 40, - 280, 0, 140, 40, - 420, 0, 140, 40, - 0, 0, 140, 40, 20, - 140, 0, 140, 40, 20, - 280, 0, 140, 40, 20, - 420, 0, 140, 40, 20, - 450, 510, # HelpWindow - 0, 500, 35, 25, # VKeyIcon - 0, 50, 300, 20, 20, # footnote - 0, 90, 560, 375, 25, 19, # config - 0, 75, 560, 75, 18, # description - ] # noqa: E124 - def __init__(self, session, setup, plugin=None, PluginLanguageDomain=None): - Setup.__init__(self, session, setup, plugin, PluginLanguageDomain) self.skinName = "VIXBackupManagerMenu" + Setup.__init__(self, session, setup, plugin, PluginLanguageDomain) self["actions2"] = ActionMap( ["SetupActions", "ColorActions", "VirtualKeyboardActions", "MenuActions"], From 907fd162204905717914a39644a4f38092f315b1 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sat, 28 Oct 2023 13:39:31 +0200 Subject: [PATCH 106/401] [ScriptRunner] add menu key --- lib/python/Plugins/SystemPlugins/ViX/ScriptRunner.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/python/Plugins/SystemPlugins/ViX/ScriptRunner.py b/lib/python/Plugins/SystemPlugins/ViX/ScriptRunner.py index ad9619b5f66..80e508c92c4 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/ScriptRunner.py +++ b/lib/python/Plugins/SystemPlugins/ViX/ScriptRunner.py @@ -46,6 +46,7 @@ def __init__(self, session, list=None): self.skinName = ["VIXScriptRunner", "IpkgInstaller"] self["key_green"] = StaticText(_("Run")) + self["key_menu"] = StaticText(_("MENU")) # hook for automatic menu key self["myactions"] = ActionMap( ["MenuActions"], From f01ee8cdc81c9c9e4a86c54949a87a52d5072fb0 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sun, 29 Oct 2023 01:02:26 +0200 Subject: [PATCH 107/401] [PLiExtraInfo] display frequency as human readable --- lib/python/Components/Converter/PliExtraInfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/Converter/PliExtraInfo.py b/lib/python/Components/Converter/PliExtraInfo.py index b237d6faa9b..b1c70bc7f6c 100644 --- a/lib/python/Components/Converter/PliExtraInfo.py +++ b/lib/python/Components/Converter/PliExtraInfo.py @@ -119,7 +119,7 @@ def __init__(self, type): "ServiceInfo": ( "ProviderName", "TunerSystem", - "TransponderFrequency", + "TransponderFrequencyMHz", "TransponderPolarization", "TransponderSymbolRate", "TransponderFEC", From f778dc5d01872e0682c651c131b30afcb449f798 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sun, 29 Oct 2023 01:03:10 +0200 Subject: [PATCH 108/401] [OScamInfo] fix crash --- lib/python/Screens/OScamInfo.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/python/Screens/OScamInfo.py b/lib/python/Screens/OScamInfo.py index e14db42b43d..76a7743a078 100644 --- a/lib/python/Screens/OScamInfo.py +++ b/lib/python/Screens/OScamInfo.py @@ -260,6 +260,7 @@ def readXML(self, typ): else: ecmtime = _("n/a") srvname = client.find("request").text + srvname_short = _("n/a") if srvname is not None: srvname_short = srvname.split(":")[1].strip() if ":" in srvname else srvname if proto.lower() == "dvbapi": From 100ffe95db0e4a381de059900599ef710303f15d Mon Sep 17 00:00:00 2001 From: openvix-build Date: Sat, 28 Oct 2023 23:06:46 +0000 Subject: [PATCH 109/401] openvix: developer 6.4.009.007 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 4c9e5fbfc51..1c0f9d43d8a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1190,3 +1190,4 @@ openvix: developer 6.4.009.003 openvix: developer 6.4.009.004 openvix: developer 6.4.009.005 openvix: developer 6.4.009.006 +openvix: developer 6.4.009.007 From 6374cdf31e762b187c65051c58782c61d88446d4 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sun, 29 Oct 2023 02:02:05 +0200 Subject: [PATCH 110/401] [FCC] skip stream relay --- lib/python/Plugins/SystemPlugins/FastChannelChange/plugin.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/python/Plugins/SystemPlugins/FastChannelChange/plugin.py b/lib/python/Plugins/SystemPlugins/FastChannelChange/plugin.py index 8d74b3f03cf..e919d848302 100644 --- a/lib/python/Plugins/SystemPlugins/FastChannelChange/plugin.py +++ b/lib/python/Plugins/SystemPlugins/FastChannelChange/plugin.py @@ -3,6 +3,7 @@ from Plugins.Plugin import PluginDescriptor from Screens.Screen import Screen from Screens.InfoBar import InfoBar +from Screens.InfoBarGenerics import whitelist from Components.config import config, getConfigListEntry, ConfigSubsection, ConfigYesNo, ConfigSelection from Components.ConfigList import ConfigListScreen from Components.Sources.StaticText import StaticText @@ -247,6 +248,9 @@ def isPlayableFCC(self, sref): elif int(sref.getData(0)) in (2, 10): # is RADIO? playable = False + elif sref.toString() in whitelist.streamrelay: + playable = False + return playable def getZapUpDownList(self): From 4a320e04e5e30534c59aec7bec4a3811d081b575 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sun, 29 Oct 2023 18:09:10 +0200 Subject: [PATCH 111/401] First version of color buttons addon widget --- .../Components/Addons/ColorButtonsSequence.py | 142 ++++++++++++++++++ lib/python/Components/Addons/GUIAddon.py | 2 + 2 files changed, 144 insertions(+) create mode 100644 lib/python/Components/Addons/ColorButtonsSequence.py diff --git a/lib/python/Components/Addons/ColorButtonsSequence.py b/lib/python/Components/Addons/ColorButtonsSequence.py new file mode 100644 index 00000000000..f90b6dc3ec6 --- /dev/null +++ b/lib/python/Components/Addons/ColorButtonsSequence.py @@ -0,0 +1,142 @@ +from Components.Addons.GUIAddon import GUIAddon + +from enigma import eLabel, eListbox, eListboxPythonMultiContent, BT_ALIGN_CENTER, BT_VALIGN_CENTER, RT_VALIGN_CENTER, RT_HALIGN_LEFT, eSize, getDesktop, gFont + +from skin import parseScale, parseColor, parseFont, applySkinFactor + +from Components.MultiContent import MultiContentEntryPixmapAlphaBlend +from Components.Label import Label + +from Tools.Directories import resolveFilename, SCOPE_GUISKIN +from Tools.LoadPixmap import LoadPixmap + + +class ColorButtonsSequence(GUIAddon): + def __init__(self): + GUIAddon.__init__(self) + self.foreColor = 0xffffff + self.font = gFont("Regular", 18) + self.l = eListboxPythonMultiContent() # noqa: E741 + self.l.setBuildFunc(self.buildEntry) + self.l.setItemHeight(35) + self.l.setItemWidth(35) + self.spacingButtons = applySkinFactor(40) + self.spacingPixmapText = applySkinFactor(10) + self.layoutStyle = "fixed" + self.colorIndicatorStyle = "pixmap" + self.orientations = {"orHorizontal": eListbox.orHorizontal, "orVertical": eListbox.orVertical} + self.orientation = eListbox.orHorizontal + self.alignment = "left" + self.pixmaps = {} + self.colors = {} + self.textRenderer = Label("") + + def onContainerShown(self): + for x, val in self.sources.items(): + if self.constructButtonSequence not in val.onChanged: + val.onChanged.append(self.constructButtonSequence) + if self.layoutStyle == "fluid": + self.textRenderer.GUIcreate(self.relatedScreen.instance) + self.constructButtonSequence() + + GUI_WIDGET = eListbox + + def updateAddon(self, sequence): + l_list = [] + l_list.append((sequence,)) + self.l.setList(l_list) + + def buildEntry(self, sequence): + width = self.instance.size().width() + height = self.instance.size().height() + xPos = width if self.alignment == "right" else 0 + yPos = 0 + sectorWidth = width // len(sequence) + + res = [None] + + for x, val in sequence.items(): + if x in self.pixmaps: + pic = LoadPixmap(resolveFilename(SCOPE_GUISKIN, self.pixmaps[x])) + if pic: + pixd_size = pic.size() + pixd_width = pixd_size.width() + pixd_height = pixd_size.height() + pic_x_pos = (xPos - pixd_width) if self.alignment == "right" else xPos + res.append(MultiContentEntryPixmapAlphaBlend( + pos=(pic_x_pos, yPos), + size=(pixd_width, height), + png=pic, + backcolor=None, backcolor_sel=None, flags=BT_ALIGN_CENTER)) + if self.alignment == "right": + xPos -= pixd_width + self.spacingPixmapText + else: + xPos += pixd_width + self.spacingPixmapText + buttonText = val.text + if self.layoutStyle == "fluid": + textWidth = self._calcTextWidth(buttonText, font=self.font, size=eSize(self.getDesktopWith() // 3, 0)) + else: + textWidth = sectorWidth - self.spacingButtons - self.spacingPixmapText - pixd_width + res.append((eListboxPythonMultiContent.TYPE_TEXT, xPos, yPos, textWidth, height - 2, 0, RT_HALIGN_LEFT | RT_VALIGN_CENTER, buttonText)) + xPos += textWidth + self.spacingButtons + + return res + + def postWidgetCreate(self, instance): + instance.setSelectionEnable(False) + instance.setContent(self.l) + instance.allowNativeKeys(False) + + def constructButtonSequence(self): + sequence = {} + for x, val in self.sources.items(): + if val.text: + sequence[x] = val + + self.updateAddon(sequence) + + def applySkin(self, desktop, parent): + attribs = [] + for (attrib, value) in self.skinAttributes[:]: + if attrib == "pixmaps": + self.pixmaps = dict(item.split(':') for item in value.split(',')) + elif attrib == "itemHeight": + self.l.setItemHeight(parseScale(value)) + elif attrib == "itemWidth": + self.l.setItemWidth(parseScale(value)) + elif attrib == "spacingButtons": + self.spacingButtons = parseScale(value) + elif attrib == "spacingPixmapText": + self.spacingPixmapText = parseScale(value) + elif attrib == "layoutStyle": + self.layoutStyle = value + elif attrib == "alignment": + self.alignment = value + elif attrib == "orientation": + self.orientation = self.orientations.get(value, self.orientations["orHorizontal"]) + if self.orientation == eListbox.orHorizontal: + self.instance.setOrientation(eListbox.orVertical) + self.l.setOrientation(eListbox.orVertical) + else: + self.instance.setOrientation(eListbox.orHorizontal) + self.l.setOrientation(eListbox.orHorizontal) + elif attrib == "font": + self.font = parseFont(value, ((1, 1), (1, 1))) + elif attrib == "foregroundColor": + self.foreColor = parseColor(value).argb() + else: + attribs.append((attrib, value)) + self.skinAttributes = attribs + self.l.setFont(0, self.font) + return GUIAddon.applySkin(self, desktop, parent) + + def _calcTextWidth(self, text, font=None, size=None): + if size: + self.textRenderer.instance.resize(size) + if font: + self.textRenderer.instance.setFont(font) + self.textRenderer.text = text + return self.textRenderer.instance.calculateSize().width() + + def getDesktopWith(self): + return getDesktop(0).size().width() diff --git a/lib/python/Components/Addons/GUIAddon.py b/lib/python/Components/Addons/GUIAddon.py index 2ecedaf23ec..236605486cc 100644 --- a/lib/python/Components/Addons/GUIAddon.py +++ b/lib/python/Components/Addons/GUIAddon.py @@ -5,6 +5,7 @@ class GUIAddon(GUIComponent): def __init__(self): GUIComponent.__init__(self) self.sources = {} + self.relatedScreen = None def connectRelatedElement(self, relatedElementName, container): relatedElementNames = relatedElementName.split(",") @@ -16,6 +17,7 @@ def connectRelatedElement(self, relatedElementName, container): if x in container: self.sources[x] = container[x] container.onShow.append(self.onContainerShown) + self.relatedScreen = container def onContainerShown(self): pass From 0f67fd068cba24abfdb1c00bae5b2d2c5bfbd4ab Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sun, 29 Oct 2023 18:15:12 +0200 Subject: [PATCH 112/401] add a init value for pixmap width to 0 if there is no pixmaps --- lib/python/Components/Addons/ColorButtonsSequence.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/python/Components/Addons/ColorButtonsSequence.py b/lib/python/Components/Addons/ColorButtonsSequence.py index f90b6dc3ec6..b67e5b08747 100644 --- a/lib/python/Components/Addons/ColorButtonsSequence.py +++ b/lib/python/Components/Addons/ColorButtonsSequence.py @@ -54,7 +54,8 @@ def buildEntry(self, sequence): sectorWidth = width // len(sequence) res = [None] - + pixd_width = 0 + for x, val in sequence.items(): if x in self.pixmaps: pic = LoadPixmap(resolveFilename(SCOPE_GUISKIN, self.pixmaps[x])) From eb3d3c987b3a1facfde0d4cbeb9125cc80672170 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sun, 29 Oct 2023 16:57:33 +0000 Subject: [PATCH 113/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Components/Addons/ColorButtonsSequence.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/python/Components/Addons/ColorButtonsSequence.py b/lib/python/Components/Addons/ColorButtonsSequence.py index b67e5b08747..58a84ff5c21 100644 --- a/lib/python/Components/Addons/ColorButtonsSequence.py +++ b/lib/python/Components/Addons/ColorButtonsSequence.py @@ -55,7 +55,7 @@ def buildEntry(self, sequence): res = [None] pixd_width = 0 - + for x, val in sequence.items(): if x in self.pixmaps: pic = LoadPixmap(resolveFilename(SCOPE_GUISKIN, self.pixmaps[x])) @@ -130,7 +130,7 @@ def applySkin(self, desktop, parent): self.skinAttributes = attribs self.l.setFont(0, self.font) return GUIAddon.applySkin(self, desktop, parent) - + def _calcTextWidth(self, text, font=None, size=None): if size: self.textRenderer.instance.resize(size) @@ -138,6 +138,6 @@ def _calcTextWidth(self, text, font=None, size=None): self.textRenderer.instance.setFont(font) self.textRenderer.text = text return self.textRenderer.instance.calculateSize().width() - + def getDesktopWith(self): return getDesktop(0).size().width() From 19e21d7511a808bd3e8a5252905537e1c1abe669 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sun, 29 Oct 2023 19:31:34 +0200 Subject: [PATCH 114/401] [Added] Possibility to define colors for button text [Updated] Logic for fixed layout updated --- .../Components/Addons/ColorButtonsSequence.py | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/lib/python/Components/Addons/ColorButtonsSequence.py b/lib/python/Components/Addons/ColorButtonsSequence.py index 58a84ff5c21..3a40e3b8db2 100644 --- a/lib/python/Components/Addons/ColorButtonsSequence.py +++ b/lib/python/Components/Addons/ColorButtonsSequence.py @@ -35,8 +35,7 @@ def onContainerShown(self): for x, val in self.sources.items(): if self.constructButtonSequence not in val.onChanged: val.onChanged.append(self.constructButtonSequence) - if self.layoutStyle == "fluid": - self.textRenderer.GUIcreate(self.relatedScreen.instance) + self.textRenderer.GUIcreate(self.relatedScreen.instance) self.constructButtonSequence() GUI_WIDGET = eListbox @@ -52,11 +51,15 @@ def buildEntry(self, sequence): xPos = width if self.alignment == "right" else 0 yPos = 0 sectorWidth = width // len(sequence) + minSectorWidth = width // 4 res = [None] pixd_width = 0 for x, val in sequence.items(): + textColor = self.foreColor + if x in self.colors: + textColor = parseColor(self.colors[x]).argb() if x in self.pixmaps: pic = LoadPixmap(resolveFilename(SCOPE_GUISKIN, self.pixmaps[x])) if pic: @@ -73,13 +76,14 @@ def buildEntry(self, sequence): xPos -= pixd_width + self.spacingPixmapText else: xPos += pixd_width + self.spacingPixmapText - buttonText = val.text - if self.layoutStyle == "fluid": - textWidth = self._calcTextWidth(buttonText, font=self.font, size=eSize(self.getDesktopWith() // 3, 0)) - else: - textWidth = sectorWidth - self.spacingButtons - self.spacingPixmapText - pixd_width - res.append((eListboxPythonMultiContent.TYPE_TEXT, xPos, yPos, textWidth, height - 2, 0, RT_HALIGN_LEFT | RT_VALIGN_CENTER, buttonText)) - xPos += textWidth + self.spacingButtons + buttonText = val.text + textWidth = self._calcTextWidth(buttonText, font=self.font, size=eSize(self.getDesktopWith() // 3, 0)) + if self.layoutStyle != "fluid": + if textWidth < (minSectorWidth - self.spacingButtons - self.spacingPixmapText - pixd_width): + textWidth = minSectorWidth - self.spacingButtons - self.spacingPixmapText - pixd_width + + res.append((eListboxPythonMultiContent.TYPE_TEXT, xPos, yPos, textWidth, height - 2, 0, RT_HALIGN_LEFT | RT_VALIGN_CENTER, buttonText, textColor if not pic else self.foreColor)) + xPos += textWidth + self.spacingButtons return res @@ -125,12 +129,14 @@ def applySkin(self, desktop, parent): self.font = parseFont(value, ((1, 1), (1, 1))) elif attrib == "foregroundColor": self.foreColor = parseColor(value).argb() + elif attrib == "textColors": + self.colors = dict(item.split(':') for item in value.split(',')) else: attribs.append((attrib, value)) self.skinAttributes = attribs self.l.setFont(0, self.font) return GUIAddon.applySkin(self, desktop, parent) - + def _calcTextWidth(self, text, font=None, size=None): if size: self.textRenderer.instance.resize(size) @@ -138,6 +144,6 @@ def _calcTextWidth(self, text, font=None, size=None): self.textRenderer.instance.setFont(font) self.textRenderer.text = text return self.textRenderer.instance.calculateSize().width() - + def getDesktopWith(self): return getDesktop(0).size().width() From 5add5dcf1b3434f50b351474a0c40fa45b95a6cf Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sun, 29 Oct 2023 17:46:03 +0000 Subject: [PATCH 115/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Components/Addons/ColorButtonsSequence.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Components/Addons/ColorButtonsSequence.py b/lib/python/Components/Addons/ColorButtonsSequence.py index 3a40e3b8db2..305242a3602 100644 --- a/lib/python/Components/Addons/ColorButtonsSequence.py +++ b/lib/python/Components/Addons/ColorButtonsSequence.py @@ -136,7 +136,7 @@ def applySkin(self, desktop, parent): self.skinAttributes = attribs self.l.setFont(0, self.font) return GUIAddon.applySkin(self, desktop, parent) - + def _calcTextWidth(self, text, font=None, size=None): if size: self.textRenderer.instance.resize(size) @@ -144,6 +144,6 @@ def _calcTextWidth(self, text, font=None, size=None): self.textRenderer.instance.setFont(font) self.textRenderer.text = text return self.textRenderer.instance.calculateSize().width() - + def getDesktopWith(self): return getDesktop(0).size().width() From e8694aee11be6039de9b0017c581d77623469496 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Mon, 30 Oct 2023 00:09:13 +0200 Subject: [PATCH 116/401] [Added] Supressions of warnings if the component is used only in the addon [Added] Added logic to switch to fluid layout if there is not enough space for fixed layout [Fixed] Exceptions on some screens --- .../Components/Addons/ColorButtonsSequence.py | 34 ++++++++++++------- lib/python/Components/Addons/GUIAddon.py | 8 +++-- lib/python/Screens/Screen.py | 3 +- 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/lib/python/Components/Addons/ColorButtonsSequence.py b/lib/python/Components/Addons/ColorButtonsSequence.py index 305242a3602..aa44ffc045e 100644 --- a/lib/python/Components/Addons/ColorButtonsSequence.py +++ b/lib/python/Components/Addons/ColorButtonsSequence.py @@ -33,10 +33,10 @@ def __init__(self): def onContainerShown(self): for x, val in self.sources.items(): - if self.constructButtonSequence not in val.onChanged: - val.onChanged.append(self.constructButtonSequence) + if self.constructColorButtonSequence not in val.onChanged: + val.onChanged.append(self.constructColorButtonSequence) self.textRenderer.GUIcreate(self.relatedScreen.instance) - self.constructButtonSequence() + self.constructColorButtonSequence() GUI_WIDGET = eListbox @@ -76,14 +76,24 @@ def buildEntry(self, sequence): xPos -= pixd_width + self.spacingPixmapText else: xPos += pixd_width + self.spacingPixmapText - buttonText = val.text - textWidth = self._calcTextWidth(buttonText, font=self.font, size=eSize(self.getDesktopWith() // 3, 0)) + if hasattr(val, "text"): + buttonText = val.text + else: + buttonText = "" + + if buttonText: + textWidth = self._calcTextWidth(buttonText, font=self.font, size=eSize(self.getDesktopWith() // 3, 0)) + else: + textWidth = 0 if self.layoutStyle != "fluid": if textWidth < (minSectorWidth - self.spacingButtons - self.spacingPixmapText - pixd_width): textWidth = minSectorWidth - self.spacingButtons - self.spacingPixmapText - pixd_width - - res.append((eListboxPythonMultiContent.TYPE_TEXT, xPos, yPos, textWidth, height - 2, 0, RT_HALIGN_LEFT | RT_VALIGN_CENTER, buttonText, textColor if not pic else self.foreColor)) - xPos += textWidth + self.spacingButtons + if buttonText: + res.append((eListboxPythonMultiContent.TYPE_TEXT, xPos, yPos, textWidth, height - 2, 0, RT_HALIGN_LEFT | RT_VALIGN_CENTER, buttonText, textColor if not pic else self.foreColor)) + xPos += textWidth + self.spacingButtons + if xPos > width and self.layoutStyle != "fluid": + self.layoutStyle = "fluid" + return self.buildEntry(sequence) return res @@ -92,10 +102,10 @@ def postWidgetCreate(self, instance): instance.setContent(self.l) instance.allowNativeKeys(False) - def constructButtonSequence(self): + def constructColorButtonSequence(self): sequence = {} for x, val in self.sources.items(): - if val.text: + if hasattr(val, "text") and val.text: sequence[x] = val self.updateAddon(sequence) @@ -136,7 +146,7 @@ def applySkin(self, desktop, parent): self.skinAttributes = attribs self.l.setFont(0, self.font) return GUIAddon.applySkin(self, desktop, parent) - + def _calcTextWidth(self, text, font=None, size=None): if size: self.textRenderer.instance.resize(size) @@ -144,6 +154,6 @@ def _calcTextWidth(self, text, font=None, size=None): self.textRenderer.instance.setFont(font) self.textRenderer.text = text return self.textRenderer.instance.calculateSize().width() - + def getDesktopWith(self): return getDesktop(0).size().width() diff --git a/lib/python/Components/Addons/GUIAddon.py b/lib/python/Components/Addons/GUIAddon.py index 236605486cc..c5714058cde 100644 --- a/lib/python/Components/Addons/GUIAddon.py +++ b/lib/python/Components/Addons/GUIAddon.py @@ -13,11 +13,13 @@ def connectRelatedElement(self, relatedElementName, container): self.source = container[relatedElementName] elif len(relatedElementNames) > 1: for x in relatedElementNames: - x = x.strip() if x in container: - self.sources[x] = container[x] + component = container[x] + self.sources[x] = component + if isinstance(component, GUIComponent) and x not in container.handledWidgets: + container.handledWidgets.append(x) container.onShow.append(self.onContainerShown) self.relatedScreen = container def onContainerShown(self): - pass + pass \ No newline at end of file diff --git a/lib/python/Screens/Screen.py b/lib/python/Screens/Screen.py index 45fa50592b8..b3536a9544f 100644 --- a/lib/python/Screens/Screen.py +++ b/lib/python/Screens/Screen.py @@ -50,6 +50,7 @@ def __init__(self, session, parent=None, mandatoryWidgets=None): self["title"] = StaticText() # DEBUG: Hack to support for some summary screens. self.screenPath = "" # This is the current screen path without the title. self.screenTitle = "" # This is the current screen title without the path. + self.handledWidgets = [] def __repr__(self): return str(type(self)) @@ -262,7 +263,7 @@ def createGUIScreen(self, parent, desktop, updateonly=False): if depr: print("[Screen] WARNING: OBSOLETE COMPONENT '%s' USED IN SKIN. USE '%s' INSTEAD!" % (key, depr[0])) print("[Screen] OBSOLETE COMPONENT WILL BE REMOVED %s, PLEASE UPDATE!" % depr[1]) - elif not depr: + elif not depr and key not in self.handledWidgets: print("[Screen] Warning: Skin is missing element '%s' in %s." % (key, str(self))) for w in self.additionalWidgets: if not updateonly: From 36683daf1c0b1d6c3d2e6e07aedf8d31d0068099 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sun, 29 Oct 2023 22:36:00 +0000 Subject: [PATCH 117/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Components/Addons/ColorButtonsSequence.py | 6 +++--- lib/python/Components/Addons/GUIAddon.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/python/Components/Addons/ColorButtonsSequence.py b/lib/python/Components/Addons/ColorButtonsSequence.py index aa44ffc045e..1fac14e56c6 100644 --- a/lib/python/Components/Addons/ColorButtonsSequence.py +++ b/lib/python/Components/Addons/ColorButtonsSequence.py @@ -80,7 +80,7 @@ def buildEntry(self, sequence): buttonText = val.text else: buttonText = "" - + if buttonText: textWidth = self._calcTextWidth(buttonText, font=self.font, size=eSize(self.getDesktopWith() // 3, 0)) else: @@ -146,7 +146,7 @@ def applySkin(self, desktop, parent): self.skinAttributes = attribs self.l.setFont(0, self.font) return GUIAddon.applySkin(self, desktop, parent) - + def _calcTextWidth(self, text, font=None, size=None): if size: self.textRenderer.instance.resize(size) @@ -154,6 +154,6 @@ def _calcTextWidth(self, text, font=None, size=None): self.textRenderer.instance.setFont(font) self.textRenderer.text = text return self.textRenderer.instance.calculateSize().width() - + def getDesktopWith(self): return getDesktop(0).size().width() diff --git a/lib/python/Components/Addons/GUIAddon.py b/lib/python/Components/Addons/GUIAddon.py index c5714058cde..f1264cc34ed 100644 --- a/lib/python/Components/Addons/GUIAddon.py +++ b/lib/python/Components/Addons/GUIAddon.py @@ -22,4 +22,4 @@ def connectRelatedElement(self, relatedElementName, container): self.relatedScreen = container def onContainerShown(self): - pass \ No newline at end of file + pass From 8badb0286ecf24930a538187b2f6f60b7fc73102 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Mon, 30 Oct 2023 11:31:32 +0200 Subject: [PATCH 118/401] - fixed validation of mandatory widgets when using addons --- lib/python/skin.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/python/skin.py b/lib/python/skin.py index 8786606e583..2098834cb92 100644 --- a/lib/python/skin.py +++ b/lib/python/skin.py @@ -1429,6 +1429,10 @@ def recurseNamelessPanel(panel): source = widget.get("source", None) if source is not None: widgetSet.add(source) + addonConnection = widget.get("connection", None) + if addonConnection is not None: + for x in addonConnection.split(","): + widgetSet.add(x) panels = element.findall("panel") if panels is not None: for panel in panels: From bfa9f51923ff86e14eae33f6d5a0a09fb2eaed8a Mon Sep 17 00:00:00 2001 From: openvix-build Date: Mon, 30 Oct 2023 22:30:20 +0000 Subject: [PATCH 119/401] openvix: developer 6.4.009.008 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 1c0f9d43d8a..8b4bb7bf131 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1191,3 +1191,4 @@ openvix: developer 6.4.009.004 openvix: developer 6.4.009.005 openvix: developer 6.4.009.006 openvix: developer 6.4.009.007 +openvix: developer 6.4.009.008 From 71059ef5749ddda38e44a8721b8a7dfe1e2992f5 Mon Sep 17 00:00:00 2001 From: Orlandoxx <95180049+Orlandoxx@users.noreply.github.com> Date: Tue, 31 Oct 2023 06:53:20 +0200 Subject: [PATCH 120/401] Updated fi.po Fixed --- po/fi.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/po/fi.po b/po/fi.po index dd9f1356e0b..82cfbe830d5 100644 --- a/po/fi.po +++ b/po/fi.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: enigma2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-27 23:35+0000\n" -"PO-Revision-Date: 2023-10-28 11:23+0300\n" +"PO-Revision-Date: 2023-10-31 06:51+0200\n" "Last-Translator: Orlandox\n" "Language-Team: timoj/Kojo/Samzam/Orlandox\n" "Language: fi\n" @@ -9628,8 +9628,8 @@ msgstr "Muuta tallennuksen päättymisaika" msgid "Choose CCcam-Reader" msgstr "Valitse CCcam-lukija" -msgid "Please choose an extension" -msgstr "Valitse laajennus" +msgid "Please choose an extension..." +msgstr "Valitse laajennus..." msgid "Choose reader" msgstr "Valitse lukija" @@ -13540,7 +13540,7 @@ msgstr "" "Suomenkielinen käännös: timoj, Kojo, Samzam, Orlandox\n" "\n" "Ylläpito : Orlandox\n" -"28.10.2023\n" +"31.10.2023\n" "http://www.huoltovalikko.com" msgid "TS file is too large for ISO9660 level 1!" From 4af40b92b738902c04cc878e2aa754ddf2dce9d1 Mon Sep 17 00:00:00 2001 From: Taapat Date: Mon, 30 Oct 2023 21:43:21 +0200 Subject: [PATCH 121/401] Fix saving the set range in ProgressBar When setting the progress bar range, it is set in eSlider but not stored in instance variables. It does not allow to get the correct range using the ProgressBar method getRange or property range. Therefore, when setting the range, also stores it in instance variables. --- lib/python/Components/ProgressBar.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Components/ProgressBar.py b/lib/python/Components/ProgressBar.py index a41da2926cb..49c976e41ba 100644 --- a/lib/python/Components/ProgressBar.py +++ b/lib/python/Components/ProgressBar.py @@ -19,9 +19,9 @@ def postWidgetCreate(self, instance): instance.setRange(self.__start, self.__end) def setRange(self, range): - (__start, __end) = range if self.instance is not None: - self.instance.setRange(__start, __end) + self.__start, self.__end = range + self.instance.setRange(self.__start, self.__end) def getRange(self): return self.__start, self.__end From 647d797747f1d12ea466430b3d97afa0494ab18f Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Wed, 1 Nov 2023 08:33:17 +0200 Subject: [PATCH 122/401] - fixed exception due to unbound variable used --- .../Components/Addons/ColorButtonsSequence.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/python/Components/Addons/ColorButtonsSequence.py b/lib/python/Components/Addons/ColorButtonsSequence.py index 1fac14e56c6..005fc9b6892 100644 --- a/lib/python/Components/Addons/ColorButtonsSequence.py +++ b/lib/python/Components/Addons/ColorButtonsSequence.py @@ -46,6 +46,9 @@ def updateAddon(self, sequence): self.l.setList(l_list) def buildEntry(self, sequence): + res = [None] + if len(sequence) == 0: + return res width = self.instance.size().width() height = self.instance.size().height() xPos = width if self.alignment == "right" else 0 @@ -53,7 +56,7 @@ def buildEntry(self, sequence): sectorWidth = width // len(sequence) minSectorWidth = width // 4 - res = [None] + pic = None pixd_width = 0 for x, val in sequence.items(): @@ -65,7 +68,6 @@ def buildEntry(self, sequence): if pic: pixd_size = pic.size() pixd_width = pixd_size.width() - pixd_height = pixd_size.height() pic_x_pos = (xPos - pixd_width) if self.alignment == "right" else xPos res.append(MultiContentEntryPixmapAlphaBlend( pos=(pic_x_pos, yPos), @@ -80,7 +82,7 @@ def buildEntry(self, sequence): buttonText = val.text else: buttonText = "" - + if buttonText: textWidth = self._calcTextWidth(buttonText, font=self.font, size=eSize(self.getDesktopWith() // 3, 0)) else: @@ -88,9 +90,9 @@ def buildEntry(self, sequence): if self.layoutStyle != "fluid": if textWidth < (minSectorWidth - self.spacingButtons - self.spacingPixmapText - pixd_width): textWidth = minSectorWidth - self.spacingButtons - self.spacingPixmapText - pixd_width - if buttonText: - res.append((eListboxPythonMultiContent.TYPE_TEXT, xPos, yPos, textWidth, height - 2, 0, RT_HALIGN_LEFT | RT_VALIGN_CENTER, buttonText, textColor if not pic else self.foreColor)) - xPos += textWidth + self.spacingButtons + + res.append((eListboxPythonMultiContent.TYPE_TEXT, xPos, yPos, textWidth, height - 2, 0, RT_HALIGN_LEFT | RT_VALIGN_CENTER, buttonText, textColor if not pic else self.foreColor)) + xPos += textWidth + self.spacingButtons if xPos > width and self.layoutStyle != "fluid": self.layoutStyle = "fluid" return self.buildEntry(sequence) @@ -146,7 +148,7 @@ def applySkin(self, desktop, parent): self.skinAttributes = attribs self.l.setFont(0, self.font) return GUIAddon.applySkin(self, desktop, parent) - + def _calcTextWidth(self, text, font=None, size=None): if size: self.textRenderer.instance.resize(size) @@ -154,6 +156,6 @@ def _calcTextWidth(self, text, font=None, size=None): self.textRenderer.instance.setFont(font) self.textRenderer.text = text return self.textRenderer.instance.calculateSize().width() - + def getDesktopWith(self): return getDesktop(0).size().width() From a06ac47d55d2d638989822d847ace9c42fb10154 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Wed, 1 Nov 2023 08:35:08 +0200 Subject: [PATCH 123/401] added check for empty text --- lib/python/Components/Addons/ColorButtonsSequence.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/python/Components/Addons/ColorButtonsSequence.py b/lib/python/Components/Addons/ColorButtonsSequence.py index 005fc9b6892..bd5c8284973 100644 --- a/lib/python/Components/Addons/ColorButtonsSequence.py +++ b/lib/python/Components/Addons/ColorButtonsSequence.py @@ -90,9 +90,9 @@ def buildEntry(self, sequence): if self.layoutStyle != "fluid": if textWidth < (minSectorWidth - self.spacingButtons - self.spacingPixmapText - pixd_width): textWidth = minSectorWidth - self.spacingButtons - self.spacingPixmapText - pixd_width - - res.append((eListboxPythonMultiContent.TYPE_TEXT, xPos, yPos, textWidth, height - 2, 0, RT_HALIGN_LEFT | RT_VALIGN_CENTER, buttonText, textColor if not pic else self.foreColor)) - xPos += textWidth + self.spacingButtons + if buttonText: + res.append((eListboxPythonMultiContent.TYPE_TEXT, xPos, yPos, textWidth, height - 2, 0, RT_HALIGN_LEFT | RT_VALIGN_CENTER, buttonText, textColor if not pic else self.foreColor)) + xPos += textWidth + self.spacingButtons if xPos > width and self.layoutStyle != "fluid": self.layoutStyle = "fluid" return self.buildEntry(sequence) From f2ebb842def9b02c32f9809a1e4ced1b4e3e68da Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Wed, 1 Nov 2023 08:18:41 +0000 Subject: [PATCH 124/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Components/Addons/ColorButtonsSequence.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/python/Components/Addons/ColorButtonsSequence.py b/lib/python/Components/Addons/ColorButtonsSequence.py index bd5c8284973..54965090f75 100644 --- a/lib/python/Components/Addons/ColorButtonsSequence.py +++ b/lib/python/Components/Addons/ColorButtonsSequence.py @@ -82,7 +82,7 @@ def buildEntry(self, sequence): buttonText = val.text else: buttonText = "" - + if buttonText: textWidth = self._calcTextWidth(buttonText, font=self.font, size=eSize(self.getDesktopWith() // 3, 0)) else: @@ -148,7 +148,7 @@ def applySkin(self, desktop, parent): self.skinAttributes = attribs self.l.setFont(0, self.font) return GUIAddon.applySkin(self, desktop, parent) - + def _calcTextWidth(self, text, font=None, size=None): if size: self.textRenderer.instance.resize(size) @@ -156,6 +156,6 @@ def _calcTextWidth(self, text, font=None, size=None): self.textRenderer.instance.setFont(font) self.textRenderer.text = text return self.textRenderer.instance.calculateSize().width() - + def getDesktopWith(self): return getDesktop(0).size().width() From 5b4cc0542c229372119b05463322c6992381d7f7 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Tue, 31 Oct 2023 21:01:18 +0200 Subject: [PATCH 125/401] made 320 markers editable/deletable via bouquet edit mode --- lib/service/listboxservice.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index e0e970536b8..f980bb5af62 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -390,7 +390,7 @@ void eListboxServiceContent::cursorHome() m_cursor_number = 0; while (m_cursor != m_list.end()) { - if (!((m_hide_number_marker && (m_cursor->flags & eServiceReference::isNumberedMarker)) || (m_cursor->flags & eServiceReference::isInvisible))) + if (!((m_marked.empty() && m_hide_number_marker && (m_cursor->flags & eServiceReference::isNumberedMarker)) || (m_cursor->flags & eServiceReference::isInvisible))) break; m_cursor++; m_cursor_number++; @@ -478,7 +478,7 @@ int eListboxServiceContent::cursorMove(int count) m_listbox->entryChanged(cursorResolve(m_cursor_number)); } ++m_cursor_number; - if (!(m_hide_number_marker && m_cursor->flags & eServiceReference::isNumberedMarker) && !(m_cursor->flags & eServiceReference::isInvisible)) + if (!(m_marked.empty() && m_hide_number_marker && m_cursor->flags & eServiceReference::isNumberedMarker) && !(m_cursor->flags & eServiceReference::isInvisible)) --count; } } @@ -494,12 +494,12 @@ int eListboxServiceContent::cursorMove(int count) m_listbox->entryChanged(cursorResolve(m_cursor_number)); } --m_cursor_number; - if (!(m_hide_number_marker && m_cursor->flags & eServiceReference::isNumberedMarker) && !(m_cursor->flags & eServiceReference::isInvisible)) + if (!(m_marked.empty() && m_hide_number_marker && m_cursor->flags & eServiceReference::isNumberedMarker) && !(m_cursor->flags & eServiceReference::isInvisible)) ++count; } while (m_cursor != m_list.end()) { - if (!((m_hide_number_marker && (m_cursor->flags & eServiceReference::isNumberedMarker)) || (m_cursor->flags & eServiceReference::isInvisible))) + if (!((m_marked.empty() && m_hide_number_marker && (m_cursor->flags & eServiceReference::isNumberedMarker)) || (m_cursor->flags & eServiceReference::isInvisible))) break; m_cursor++; m_cursor_number++; @@ -529,7 +529,7 @@ int eListboxServiceContent::cursorResolve(int cursorPosition) if (count == cursorPosition) break; count++; - if ((m_hide_number_marker && (i->flags & eServiceReference::isNumberedMarker)) || (i->flags & eServiceReference::isInvisible)) + if ((m_marked.empty() && m_hide_number_marker && (i->flags & eServiceReference::isNumberedMarker)) || (i->flags & eServiceReference::isInvisible)) continue; strippedCursor++; } @@ -572,7 +572,7 @@ int eListboxServiceContent::size() int size = 0; for (list::iterator i(m_list.begin()); i != m_list.end(); ++i) { - if ((m_hide_number_marker && (i->flags & eServiceReference::isNumberedMarker)) || (i->flags & eServiceReference::isInvisible)) + if ((m_marked.empty() && m_hide_number_marker && (i->flags & eServiceReference::isNumberedMarker)) || (i->flags & eServiceReference::isInvisible)) continue; size++; } From a5d21982a8dc820f0ace88847e45270f56199775 Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 1 Nov 2023 16:39:12 +0100 Subject: [PATCH 126/401] [ColorButtonsSequence] Get itemHieght and width from the widget, reather than extra attributes --- lib/python/Components/Addons/ColorButtonsSequence.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/python/Components/Addons/ColorButtonsSequence.py b/lib/python/Components/Addons/ColorButtonsSequence.py index 54965090f75..48fd009e799 100644 --- a/lib/python/Components/Addons/ColorButtonsSequence.py +++ b/lib/python/Components/Addons/ColorButtonsSequence.py @@ -36,6 +36,8 @@ def onContainerShown(self): if self.constructColorButtonSequence not in val.onChanged: val.onChanged.append(self.constructColorButtonSequence) self.textRenderer.GUIcreate(self.relatedScreen.instance) + self.l.setItemHeight(self.instance.size().height()) + self.l.setItemWidth(self.instance.size().width()) self.constructColorButtonSequence() GUI_WIDGET = eListbox @@ -117,10 +119,6 @@ def applySkin(self, desktop, parent): for (attrib, value) in self.skinAttributes[:]: if attrib == "pixmaps": self.pixmaps = dict(item.split(':') for item in value.split(',')) - elif attrib == "itemHeight": - self.l.setItemHeight(parseScale(value)) - elif attrib == "itemWidth": - self.l.setItemWidth(parseScale(value)) elif attrib == "spacingButtons": self.spacingButtons = parseScale(value) elif attrib == "spacingPixmapText": From 1bef98a9a6028390a3736aeb186de3a672e96a01 Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 1 Nov 2023 16:43:04 +0100 Subject: [PATCH 127/401] [LayoutInfo] fix indent --- lib/python/Components/Converter/LayoutInfo.py | 92 +++++++++---------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/lib/python/Components/Converter/LayoutInfo.py b/lib/python/Components/Converter/LayoutInfo.py index 6e0d4d1c637..525a02ac623 100644 --- a/lib/python/Components/Converter/LayoutInfo.py +++ b/lib/python/Components/Converter/LayoutInfo.py @@ -48,53 +48,53 @@ def __init__(self, type): self.poll_interval = 1600 self.poll_enabled = True - @cached - def getText(self): - text = 'N/A' - if self.type == self.HDDTEMP: - text = self.getHddTemp() - elif self.type == self.LOADAVG: - text = self.getLoadAvg() + @cached + def getText(self): + text = 'N/A' + if self.type == self.HDDTEMP: + text = self.getHddTemp() + elif self.type == self.LOADAVG: + text = self.getLoadAvg() + else: + entry = {self.MEMTOTAL: ('Mem', 'Ram'), + self.MEMFREE: ('Mem', 'Ram'), + self.SWAPTOTAL: ('Swap', 'Swap'), + self.SWAPFREE: ('Swap', 'Swap'), + self.USBINFO: ('/media/usb', 'USB'), + self.HDDINFO: ('/media/hdd', 'HDD'), + self.FLASHINFO: ('/', 'Flash')}[self.type] + if self.type in (self.USBINFO, self.HDDINFO, self.FLASHINFO): + list = self.getDiskInfo(entry[0]) + else: + list = self.getMemInfo(entry[0]) + if list[0] == 0: + text = '%s: N/A' % entry[1] + elif self.shortFormat: + text = '%s%%' % (list[3]) + elif self.fullFormat: + text = '%s: %s Free:%s Used:%s (%s%%)' % (entry[1], self.getSizeStr(list[0]), self.getSizeStr(list[2]), self.getSizeStr(list[1]), list[3]) else: - entry = {self.MEMTOTAL: ('Mem', 'Ram'), - self.MEMFREE: ('Mem', 'Ram'), - self.SWAPTOTAL: ('Swap', 'Swap'), - self.SWAPFREE: ('Swap', 'Swap'), - self.USBINFO: ('/media/usb', 'USB'), - self.HDDINFO: ('/media/hdd', 'HDD'), - self.FLASHINFO: ('/', 'Flash')}[self.type] - if self.type in (self.USBINFO, self.HDDINFO, self.FLASHINFO): - list = self.getDiskInfo(entry[0]) - else: - list = self.getMemInfo(entry[0]) - if list[0] == 0: - text = '%s: N/A' % entry[1] - elif self.shortFormat: - text = '%s%%' % (list[3]) - elif self.fullFormat: - text = '%s: %s Free:%s Used:%s (%s%%)' % (entry[1], self.getSizeStr(list[0]), self.getSizeStr(list[2]), self.getSizeStr(list[1]), list[3]) - else: - text = '%s: %s Used:%s Free:%s' % (entry[1], self.getSizeStr(list[0]), self.getSizeStr(list[1]), self.getSizeStr(list[2])) - return text - - @cached - def getValue(self): - result = 0 - if self.type in (self.MEMTOTAL, - self.MEMFREE, - self.SWAPTOTAL, - self.SWAPFREE): - entry = {self.MEMTOTAL: 'Mem', - self.MEMFREE: 'Mem', - self.SWAPTOTAL: 'Swap', - self.SWAPFREE: 'Swap'}[self.type] - result = self.getMemInfo(entry)[3] - elif self.type in (self.USBINFO, self.HDDINFO, self.FLASHINFO): - path = {self.USBINFO: '/media/usb', - self.HDDINFO: '/media/hdd', - self.FLASHINFO: '/'}[self.type] - result = self.getDiskInfo(path)[3] - return result + text = '%s: %s Used:%s Free:%s' % (entry[1], self.getSizeStr(list[0]), self.getSizeStr(list[1]), self.getSizeStr(list[2])) + return text + + @cached + def getValue(self): + result = 0 + if self.type in (self.MEMTOTAL, + self.MEMFREE, + self.SWAPTOTAL, + self.SWAPFREE): + entry = {self.MEMTOTAL: 'Mem', + self.MEMFREE: 'Mem', + self.SWAPTOTAL: 'Swap', + self.SWAPFREE: 'Swap'}[self.type] + result = self.getMemInfo(entry)[3] + elif self.type in (self.USBINFO, self.HDDINFO, self.FLASHINFO): + path = {self.USBINFO: '/media/usb', + self.HDDINFO: '/media/hdd', + self.FLASHINFO: '/'}[self.type] + result = self.getDiskInfo(path)[3] + return result text = property(getText) # noqa: F821 value = property(getValue) # noqa: F821 From 9fd3615b45e2223e82aa67d28092a13b0d38ddda Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 1 Nov 2023 17:16:48 +0100 Subject: [PATCH 128/401] [ColorButtonsSequence] foregroundColor, fall back to the listbox default if no color is supplied by the widget --- lib/python/Components/Addons/ColorButtonsSequence.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/python/Components/Addons/ColorButtonsSequence.py b/lib/python/Components/Addons/ColorButtonsSequence.py index 48fd009e799..894a49c040a 100644 --- a/lib/python/Components/Addons/ColorButtonsSequence.py +++ b/lib/python/Components/Addons/ColorButtonsSequence.py @@ -14,7 +14,7 @@ class ColorButtonsSequence(GUIAddon): def __init__(self): GUIAddon.__init__(self) - self.foreColor = 0xffffff + self.foreColor = None self.font = gFont("Regular", 18) self.l = eListboxPythonMultiContent() # noqa: E741 self.l.setBuildFunc(self.buildEntry) @@ -93,7 +93,10 @@ def buildEntry(self, sequence): if textWidth < (minSectorWidth - self.spacingButtons - self.spacingPixmapText - pixd_width): textWidth = minSectorWidth - self.spacingButtons - self.spacingPixmapText - pixd_width if buttonText: - res.append((eListboxPythonMultiContent.TYPE_TEXT, xPos, yPos, textWidth, height - 2, 0, RT_HALIGN_LEFT | RT_VALIGN_CENTER, buttonText, textColor if not pic else self.foreColor)) + if textColor is not None: + res.append((eListboxPythonMultiContent.TYPE_TEXT, xPos, yPos, textWidth, height - 2, 0, RT_HALIGN_LEFT | RT_VALIGN_CENTER, buttonText, textColor)) + else: + res.append((eListboxPythonMultiContent.TYPE_TEXT, xPos, yPos, textWidth, height - 2, 0, RT_HALIGN_LEFT | RT_VALIGN_CENTER, buttonText)) xPos += textWidth + self.spacingButtons if xPos > width and self.layoutStyle != "fluid": self.layoutStyle = "fluid" From 9f7102896b4b6039acf052d671dbd751c1cf93ac Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 1 Nov 2023 20:48:54 +0100 Subject: [PATCH 129/401] [ColorButtonsSequence] Arithmetic: skip graphic margin if no graphic --- lib/python/Components/Addons/ColorButtonsSequence.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Components/Addons/ColorButtonsSequence.py b/lib/python/Components/Addons/ColorButtonsSequence.py index 894a49c040a..c591b2cf8af 100644 --- a/lib/python/Components/Addons/ColorButtonsSequence.py +++ b/lib/python/Components/Addons/ColorButtonsSequence.py @@ -90,8 +90,8 @@ def buildEntry(self, sequence): else: textWidth = 0 if self.layoutStyle != "fluid": - if textWidth < (minSectorWidth - self.spacingButtons - self.spacingPixmapText - pixd_width): - textWidth = minSectorWidth - self.spacingButtons - self.spacingPixmapText - pixd_width + if textWidth < (minSectorWidth - self.spacingButtons - (self.spacingPixmapText if pic else 0) - pixd_width): + textWidth = minSectorWidth - self.spacingButtons - (self.spacingPixmapText if pic else 0) - pixd_width if buttonText: if textColor is not None: res.append((eListboxPythonMultiContent.TYPE_TEXT, xPos, yPos, textWidth, height - 2, 0, RT_HALIGN_LEFT | RT_VALIGN_CENTER, buttonText, textColor)) From c74c68e56ca507a87bb552eaf3f4156c91a8a812 Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 1 Nov 2023 20:56:10 +0100 Subject: [PATCH 130/401] [ButtonSequence] Get itemHieght and width from the widget, reather than extra attributes --- lib/python/Components/Addons/ButtonSequence.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/python/Components/Addons/ButtonSequence.py b/lib/python/Components/Addons/ButtonSequence.py index 8b09b1bce5b..e3658680983 100644 --- a/lib/python/Components/Addons/ButtonSequence.py +++ b/lib/python/Components/Addons/ButtonSequence.py @@ -30,6 +30,8 @@ def onContainerShown(self): for x, val in self.sources.items(): if self.constructButtonSequence not in val.onChanged: val.onChanged.append(self.constructButtonSequence) + self.l.setItemHeight(self.instance.size().height()) + self.l.setItemWidth(self.instance.size().width()) self.constructButtonSequence() GUI_WIDGET = eListbox @@ -86,10 +88,6 @@ def applySkin(self, desktop, parent): for (attrib, value) in self.skinAttributes[:]: if attrib == "pixmaps": self.pixmaps = dict(item.split(':') for item in value.split(',')) - elif attrib == "itemHeight": - self.l.setItemHeight(parseScale(value)) - elif attrib == "itemWidth": - self.l.setItemWidth(parseScale(value)) elif attrib == "spacing": self.spacing = parseScale(value) elif attrib == "alignment": From ef8fd6ef2d6f86d9a8d98a6467305a92df50e952 Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 1 Nov 2023 21:04:41 +0100 Subject: [PATCH 131/401] [ColorButtonSequence] change "spacingButtons" attribute ... ... to "spacing" so it matches the attributes in ButtonSequence. --- lib/python/Components/Addons/ColorButtonsSequence.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/Addons/ColorButtonsSequence.py b/lib/python/Components/Addons/ColorButtonsSequence.py index c591b2cf8af..7fd9b1fd7d6 100644 --- a/lib/python/Components/Addons/ColorButtonsSequence.py +++ b/lib/python/Components/Addons/ColorButtonsSequence.py @@ -122,7 +122,7 @@ def applySkin(self, desktop, parent): for (attrib, value) in self.skinAttributes[:]: if attrib == "pixmaps": self.pixmaps = dict(item.split(':') for item in value.split(',')) - elif attrib == "spacingButtons": + elif attrib == "spacing": self.spacingButtons = parseScale(value) elif attrib == "spacingPixmapText": self.spacingPixmapText = parseScale(value) From 8120372f97cac704b307d85c6e4ece90d977d9cc Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 1 Nov 2023 21:27:38 +0100 Subject: [PATCH 132/401] [AUTOMATICBUTTONSGUIDE] add document --- doc/AUTOMATICBUTTONS | 98 ++++++++++++++++++++++++++++++++++++++++++++ doc/BUTTONGUIDE | 8 ++++ 2 files changed, 106 insertions(+) create mode 100644 doc/AUTOMATICBUTTONS diff --git a/doc/AUTOMATICBUTTONS b/doc/AUTOMATICBUTTONS new file mode 100644 index 00000000000..9e13dc339a3 --- /dev/null +++ b/doc/AUTOMATICBUTTONS @@ -0,0 +1,98 @@ +Automatic button bar +==================== + +There are two parts to this. + 1) The colour button bar, which shows a combination of graphic and text. + 2) Action button graphics that advise the user of availability of certain buttons (e.g. MENU, HELP, INFO, TEXT, etc). + +For each of the above types we just add one simple widget to our main template in skin.xml and the buttons appear +in the screens correctly as if we had added them manually to every single screen. + +========================================================================================================================================================================= + +1) Colour buttons. Add the following widget to skin.xml (in the main template or similar). + + + +Attributes: + connection: comma separated list of the buttons this widget will control. + pixmaps: comma separated list that contains "key_name" then a ":" then the path to the graphic to be used. + spacing: is the spacing between the text and the next button. + spacingPixmapText: is the spacing between the graphic and the text. + +By default the foreground text color will be the same as the default listbox text color. But this can be altered for each +button with the "textColors" attribute. + textColors="key_red:buttonred,key_green:buttongreen,key_yellow:buttonyellow,key_blue:buttonblue" + textColors: comma separated list that contains "key_name" then a ":" then the name the color to be used. Color names as declared in the section of skin.xml. + +Example widget with colored text: + + + +It is also possible to have colored text and no graphics: + + + +========================================================================================================================================================================= + +2) Action buttons. Add the following widget to skin.xml (in the main template or similar). + + + +Attributes: + connection: comma separated list of the buttons this widget will control. + pixmaps: comma separated list that contains "key_name" then a ":" then the path to the graphic to be used. + spacing: is the spacing between the text and the next button. + +In "connection" and "pixmap" add the buttons you want this widget to display. + +There must be hooks in the Python code for the buttons to display. Hooks look like the following: + +self["key_menu"] = StaticText(_("MENU")) +self["key_previous"] = StaticText(_("PREVIOUS")) +self["key_next"] = StaticText(_("NEXT")) + +========================================================================================================================================================================= diff --git a/doc/BUTTONGUIDE b/doc/BUTTONGUIDE index 279d475a7fe..83e0073ef9a 100644 --- a/doc/BUTTONGUIDE +++ b/doc/BUTTONGUIDE @@ -4,6 +4,14 @@ Proposal for Standardised and Uniform Buttons in Enigma2 Written by IanSav - 12-Feb-2018 Updated by IanSav - 14-Feb-2018 +PLEASE NOTE: +============ + +01-Nov-2023 + +For fully automatic buttons controlled by one simple widget using StaticText, +Label or Button modules please see the AUTOMATICBUTTONS document. + INTRODUCTION: ============= From ecb601373c93e85ddeb8e4a9e4edb96cf3e670f0 Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 1 Nov 2023 21:33:56 +0100 Subject: [PATCH 133/401] Update DOC --- doc/AUTOMATICBUTTONS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/AUTOMATICBUTTONS b/doc/AUTOMATICBUTTONS index 9e13dc339a3..fdefc5cf5b8 100644 --- a/doc/AUTOMATICBUTTONS +++ b/doc/AUTOMATICBUTTONS @@ -23,7 +23,7 @@ in the screens correctly as if we had added them manually to every single screen transparent="1" alignment="left" zPosition="2" - spacingButtons="10" + spacing="10" spacingPixmapText="10" /> Attributes: @@ -51,7 +51,7 @@ Example widget with colored text: transparent="1" alignment="left" zPosition="2" - spacingButtons="10" + spacing="10" spacingPixmapText="10" /> It is also possible to have colored text and no graphics: @@ -67,7 +67,7 @@ It is also possible to have colored text and no graphics: transparent="1" alignment="left" zPosition="2" - spacingButtons="0" /> + spacing="10" /> ========================================================================================================================================================================= From c78d597024bc50261f81674fc0cea8ede242ea80 Mon Sep 17 00:00:00 2001 From: openvix-build Date: Wed, 1 Nov 2023 21:30:54 +0000 Subject: [PATCH 134/401] openvix: developer 6.4.009.009 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 8b4bb7bf131..f1c45798e8b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1192,3 +1192,4 @@ openvix: developer 6.4.009.005 openvix: developer 6.4.009.006 openvix: developer 6.4.009.007 openvix: developer 6.4.009.008 +openvix: developer 6.4.009.009 From 89e6661740707ecb5a04905055c2cb70f45d3a52 Mon Sep 17 00:00:00 2001 From: openvix-build Date: Sun, 5 Nov 2023 02:35:18 +0000 Subject: [PATCH 135/401] openvix: developer 6.4.009.010 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index f1c45798e8b..1a0b1bf924f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1193,3 +1193,4 @@ openvix: developer 6.4.009.006 openvix: developer 6.4.009.007 openvix: developer 6.4.009.008 openvix: developer 6.4.009.009 +openvix: developer 6.4.009.010 From 1733594db68db89f7a8f188cfeabe70d141be384 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sun, 5 Nov 2023 12:49:26 +0100 Subject: [PATCH 136/401] [PositionerSetup] add missing button hooks --- lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py b/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py index fa83b8eebde..ccd55145777 100644 --- a/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py +++ b/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py @@ -187,6 +187,9 @@ def __init__(self, session, feid): self["key_yellow"] = self.yellow self.blue = Button("") self["key_blue"] = self.blue + + self["key_info"] = StaticText(_("INFO")) + self["key_menu"] = StaticText(_("MENU")) self.list = [] self["list"] = ConfigList(self.list) From 22dd527e025dd90e3300c76ce578c4e6fc7ad7e5 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sun, 5 Nov 2023 12:50:19 +0100 Subject: [PATCH 137/401] [menu.xml] disable "netafp", not currently built --- data/menu.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/menu.xml b/data/menu.xml index 1c4f8de43b8..a7dd4973813 100644 --- a/data/menu.xml +++ b/data/menu.xml @@ -120,7 +120,7 @@ self.session.openWithCallback(msgClosed, EpgDeleteMsg)

- + From 24bf091dd1575be0bddd47bd54c9029831f6454e Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sun, 5 Nov 2023 11:52:36 +0000 Subject: [PATCH 138/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py b/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py index ccd55145777..f8d369922d9 100644 --- a/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py +++ b/lib/python/Plugins/SystemPlugins/PositionerSetup/plugin.py @@ -187,7 +187,7 @@ def __init__(self, session, feid): self["key_yellow"] = self.yellow self.blue = Button("") self["key_blue"] = self.blue - + self["key_info"] = StaticText(_("INFO")) self["key_menu"] = StaticText(_("MENU")) From b081cb9d64aac4b69962380be0cbe6e30be168fa Mon Sep 17 00:00:00 2001 From: Twol Date: Sun, 5 Nov 2023 13:43:07 +0100 Subject: [PATCH 139/401] [InfoBarGenerics] - update showSystemMenu & showNetworkMounts to use key(thanks Huevos) --- lib/python/Screens/InfoBarGenerics.py | 30 ++++++++++++--------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index f2e6941f50f..4d29a532dbb 100644 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -1531,26 +1531,22 @@ def toggleAspectRatio(self): self.session.open(MessageBox, _("AV aspect is %s." % ASPECT_MSG[config.av.aspect.value]), MessageBox.TYPE_INFO, timeout=5, simple=True) def showSystemMenu(self): - menulist = mdom.getroot().findall('menu') - for item in menulist: - if item.attrib['entryID'] == 'setup_selection': - menulist = item.findall('menu') - for item in menulist: - if item.attrib['entryID'] == 'system_selection': - menu = item - assert menu.tag == "menu", "root element in menu must be 'menu'!" - self.session.openWithCallback(self.mainMenuClosed, Menu, menu) + menulist = mdom.getroot().findall("menu") + for menuItem in menulist: + if menuItem.get("key") == "setup": + menulist2= menuItem.findall("menu") + for menuItems in menulist2: + if menuItems.get('key') == "system": + self.session.openWithCallback(self.mainMenuClosed, Menu, menuItems) def showNetworkMounts(self): menulist = mdom.getroot().findall('menu') - for item in menulist: - if item.attrib['entryID'] == 'setup_selection': - menulist = item.findall('menu') - for item in menulist: - if item.attrib['entryID'] == 'network_menu': - menu = item - assert menu.tag == "menu", "root element in menu must be 'menu'!" - self.session.openWithCallback(self.mainMenuClosed, Menu, menu) + for menuItem in menulist: + if menuItem.get('key') == "setup": + menulist2 = menuItem.findall('menu') + for menuItems in menulist2: + if menuItems.get('key') == "network": + self.session.openWithCallback(self.mainMenuClosed, Menu, menuItems) def showRFSetup(self): self.session.openWithCallback(self.mainMenuClosed, Setup, 'RFmod') From 4385c6cec7c80719337afbd956849d3710845299 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sun, 5 Nov 2023 12:45:30 +0000 Subject: [PATCH 140/401] PEP8 double aggressive E22, E224, E241, E242 and E27 --- lib/python/Screens/InfoBarGenerics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index 4d29a532dbb..08e886639ea 100644 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -1534,7 +1534,7 @@ def showSystemMenu(self): menulist = mdom.getroot().findall("menu") for menuItem in menulist: if menuItem.get("key") == "setup": - menulist2= menuItem.findall("menu") + menulist2 = menuItem.findall("menu") for menuItems in menulist2: if menuItems.get('key') == "system": self.session.openWithCallback(self.mainMenuClosed, Menu, menuItems) From 1f68fc53510e3e3f07f528c25d6237fc5b34548a Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sun, 5 Nov 2023 12:46:05 +0000 Subject: [PATCH 141/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Screens/InfoBarGenerics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index 08e886639ea..2531296c20f 100644 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -1537,7 +1537,7 @@ def showSystemMenu(self): menulist2 = menuItem.findall("menu") for menuItems in menulist2: if menuItems.get('key') == "system": - self.session.openWithCallback(self.mainMenuClosed, Menu, menuItems) + self.session.openWithCallback(self.mainMenuClosed, Menu, menuItems) def showNetworkMounts(self): menulist = mdom.getroot().findall('menu') From baf7b49723031a3de2dbe71ea3e84ec8ed321efb Mon Sep 17 00:00:00 2001 From: openvix-build Date: Sun, 5 Nov 2023 14:15:53 +0000 Subject: [PATCH 142/401] openvix: developer 6.4.009.011 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 1a0b1bf924f..e714fee93e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1194,3 +1194,4 @@ openvix: developer 6.4.009.007 openvix: developer 6.4.009.008 openvix: developer 6.4.009.009 openvix: developer 6.4.009.010 +openvix: developer 6.4.009.011 From 3ad3138a9c12201735751d32f044df63ed70533f Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sun, 5 Nov 2023 22:36:45 +0200 Subject: [PATCH 143/401] [Added] Dynamic size of timer icons in epg screens [Added] Margin for Single Epg --- lib/python/Components/EpgListGrid.py | 21 +++++++++++++-------- lib/python/Components/EpgListSingle.py | 23 ++++++++++++++++------- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/lib/python/Components/EpgListGrid.py b/lib/python/Components/EpgListGrid.py index 25bd8315727..b4b20c2af3d 100644 --- a/lib/python/Components/EpgListGrid.py +++ b/lib/python/Components/EpgListGrid.py @@ -648,31 +648,36 @@ def buildEntry(self, service, serviceName, events, picon, channel): flags=BT_SCALE)) # Recording icons. - if timerIcon is not None and ewidth > 23: + if timerIcon is not None and ewidth > timerIcon.size().width(): if config.epgselection.grid.rec_icon_height.value != "hide": - clockSize = applySkinFactor(17) + pix_size = timerIcon.size() + pix_width = pix_size.width() + pix_height = pix_size.height() if config.epgselection.grid.rec_icon_height.value == "middle": - recIconHeight = top + (height - clockSize) // 2 + recIconHeight = top + (height - pix_height) // 2 elif config.epgselection.grid.rec_icon_height.value == "top": recIconHeight = top + 3 else: - recIconHeight = top + height - clockSize + recIconHeight = top + height - pix_height - applySkinFactor(5) if matchType == 0: pos = (left + xpos + ewidth - applySkinFactor(10), recIconHeight) else: - pos = (left + xpos + ewidth - clockSize, recIconHeight) + pos = (left + xpos + ewidth - pix_width - applySkinFactor(5), recIconHeight) res.append(MultiContentEntryPixmapAlphaBlend( - pos=pos, size=(clockSize, clockSize), + pos=pos, size=(pix_width, pix_height), png=timerIcon)) if autoTimerIcon: + pix_size = autoTimerIcon.size() + pix_width = pix_size.width() + pix_height = pix_size.height() res.append(MultiContentEntryPixmapAlphaBlend( - pos=(pos[0] - clockSize, pos[1]), size=(clockSize, clockSize), + pos=(pos[0] - pix_width - applySkinFactor(5) , pos[1]), size=(pix_width, pix_height), png=autoTimerIcon)) return res def getSelectionPosition(self): _, sely = EPGListBase.getSelectionPosition(self) - return self.selectionRect.left() + self.selectionRect.width(), sely + return self.selectionRect.left() + self.selectionRect.width() + self.instance.position().x(), sely def refreshSelection(self): events = self.selectedService and self.selectedService[2] # (service, serviceName, events, picon) diff --git a/lib/python/Components/EpgListSingle.py b/lib/python/Components/EpgListSingle.py index 8ffc50bb0e3..1af1b1d0d15 100644 --- a/lib/python/Components/EpgListSingle.py +++ b/lib/python/Components/EpgListSingle.py @@ -1,7 +1,7 @@ from time import localtime, time, strftime from enigma import eEPGCache, eListboxPythonMultiContent, gFont, eRect, RT_HALIGN_LEFT, RT_HALIGN_RIGHT, RT_VALIGN_CENTER -from skin import parameters, parseFont, applySkinFactor +from skin import parameters, parseFont, parseScale, applySkinFactor from Components.config import config from Components.EpgListBase import EPGListBase @@ -18,6 +18,7 @@ def __init__(self, session, epgConfig, selChangedCB=None): self.epgConfig = epgConfig self.eventFontName = "Regular" self.eventFontSize = applySkinFactor(19) + self.sidesMargin = 0 self.l.setBuildFunc(self.buildEntry) def applySkin(self, desktop, screen): @@ -28,6 +29,8 @@ def applySkin(self, desktop, screen): font = parseFont(value, ((1, 1), (1, 1))) self.eventFontName = font.family self.eventFontSize = font.pointSize + elif attrib == "sidesMargin": + self.sidesMargin = parseScale(value) else: attribs.append((attrib, value)) self.skinAttributes = attribs @@ -57,13 +60,14 @@ def recalcEntrySize(self): dateW = int(fontSize * dateScale) timesW = int(fontSize * timesScale) left, dateWidth, sepWidth, timesWidth, breakWidth = parameters.get("EPGSingleColumnSpecs", (0, dateW, 5, timesW, 20)) + left += self.sidesMargin if config.usage.time.wide.value: timesWidth = int(timesWidth * wideScale) self._weekdayRect = eRect(left, 0, dateWidth, height) left += dateWidth + sepWidth self._datetimeRect = eRect(left, 0, timesWidth, height) left += timesWidth + breakWidth - self._descrRect = eRect(left, 0, width - left, height) + self._descrRect = eRect(left, 0, width - left - self.sidesMargin, height) self.showend = True # This is not an unused variable. It is a flag used by EPGSearch plugin def buildEntry(self, service, eventId, beginTime, duration, eventName): @@ -83,12 +87,17 @@ def buildEntry(self, service, eventId, beginTime, duration, eventName): ] eventW = r3.width() if timerIcon: - clockSize = applySkinFactor(17) - eventW -= clockSize - res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, r3.left() + r3.width() - clockSize, (r3.height() - clockSize) // 2, clockSize, clockSize, timerIcon)) + pix_size = timerIcon.size() + pix_width = pix_size.width() + pix_height = pix_size.height() + eventW -= pix_width + res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, r3.left() + r3.width() - pix_width, (r3.height() - pix_height) // 2, pix_width, pix_height, timerIcon)) if autoTimerIcon: - eventW -= clockSize - res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, r3.left() + r3.width() - clockSize * 2, (r3.height() - clockSize) // 2, clockSize, clockSize, autoTimerIcon)) + pix_size = autoTimerIcon.size() + pix_width = pix_size.width() + pix_height = pix_size.height() + eventW -= pix_width + res.append((eListboxPythonMultiContent.TYPE_PIXMAP_ALPHABLEND, r3.left() + r3.width() - pix_width * 2 - 10, (r3.height() - pix_height) // 2, pix_width, pix_height, autoTimerIcon)) res.append((eListboxPythonMultiContent.TYPE_TEXT, r3.left(), r3.top(), eventW, r3.height(), 0, RT_HALIGN_LEFT | RT_VALIGN_CENTER, eventName)) return res From 6c2232df8479ffc0798b5f5fd33d3d286769f4f3 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sun, 5 Nov 2023 20:50:28 +0000 Subject: [PATCH 144/401] PEP8 double aggressive E20 and E211 --- lib/python/Components/EpgListGrid.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/EpgListGrid.py b/lib/python/Components/EpgListGrid.py index b4b20c2af3d..17faffc5e6f 100644 --- a/lib/python/Components/EpgListGrid.py +++ b/lib/python/Components/EpgListGrid.py @@ -671,7 +671,7 @@ def buildEntry(self, service, serviceName, events, picon, channel): pix_width = pix_size.width() pix_height = pix_size.height() res.append(MultiContentEntryPixmapAlphaBlend( - pos=(pos[0] - pix_width - applySkinFactor(5) , pos[1]), size=(pix_width, pix_height), + pos=(pos[0] - pix_width - applySkinFactor(5), pos[1]), size=(pix_width, pix_height), png=autoTimerIcon)) return res From 75f11ff0b43843338dea8ba6e387e43b6916cbd0 Mon Sep 17 00:00:00 2001 From: Betacentauri Date: Sat, 4 Nov 2023 15:24:05 +0100 Subject: [PATCH 145/401] [CI] Fix descrambling when using tuner B-H This doesn't fix VU problem with second fbc tuner! --- lib/dvb_ci/descrambler.cpp | 20 ++++++++++++----- lib/dvb_ci/descrambler.h | 2 +- lib/dvb_ci/dvbci.cpp | 22 ++++++++++++++++++ lib/dvb_ci/dvbci.h | 3 +++ lib/dvb_ci/dvbci_ccmgr.cpp | 46 ++++++++++++++++++++++++++++++++++++-- lib/dvb_ci/dvbci_ccmgr.h | 8 +++++++ 6 files changed, 93 insertions(+), 8 deletions(-) diff --git a/lib/dvb_ci/descrambler.cpp b/lib/dvb_ci/descrambler.cpp index b89b55db55d..3d38fef9056 100644 --- a/lib/dvb_ci/descrambler.cpp +++ b/lib/dvb_ci/descrambler.cpp @@ -45,6 +45,9 @@ int descrambler_set_key(int desc_fd, int index, int parity, unsigned char *data) { struct ca_descr_data d; + if (desc_fd < 0) + return -1; + d.index = index; d.parity = (enum ca_descr_parity)parity; d.data_type = CA_DATA_KEY; @@ -75,6 +78,9 @@ int descrambler_set_pid(int desc_fd, int index, int enable, int pid) struct ca_pid p; unsigned int flags = 0x80; + if (desc_fd < 0) + return -1; + if (index) flags |= 0x40; @@ -92,20 +98,24 @@ int descrambler_set_pid(int desc_fd, int index, int enable, int pid) return 0; } -int descrambler_init(void) +int descrambler_init(uint8_t ca_demux_id) { int desc_fd; - const char *filename = "/dev/dvb/adapter0/ca0"; - desc_fd = open(filename, O_RDWR); + std::string filename = "/dev/dvb/adapter0/ca" + std::to_string(ca_demux_id); + + desc_fd = open(filename.c_str(), O_RDWR); if (desc_fd == -1) { - eWarning("[CI descrambler] can not open %s", filename); + eWarning("[CI descrambler] can not open %s", filename.c_str()); } + eDebug("[CI descrambler] using ca device %s", filename.c_str()); return desc_fd; } void descrambler_deinit(int desc_fd) { - close(desc_fd); + if (desc_fd >= 0) + close(desc_fd); + desc_fd = -1; } diff --git a/lib/dvb_ci/descrambler.h b/lib/dvb_ci/descrambler.h index 85e6c56393d..d202137ab2d 100644 --- a/lib/dvb_ci/descrambler.h +++ b/lib/dvb_ci/descrambler.h @@ -1,7 +1,7 @@ #ifndef __DESCR_H_ #define __DESCR_H_ -int descrambler_init(void); +int descrambler_init(uint8_t ca_demux_id); void descrambler_deinit(int desc_fd); int descrambler_set_key(int desc_fd, int index, int parity, unsigned char *data); int descrambler_set_pid(int desc_fd, int index, int enable, int pid); diff --git a/lib/dvb_ci/dvbci.cpp b/lib/dvb_ci/dvbci.cpp index 42b59b69ccd..e39dac2a01b 100644 --- a/lib/dvb_ci/dvbci.cpp +++ b/lib/dvb_ci/dvbci.cpp @@ -789,7 +789,10 @@ void eDVBCIInterfaces::gotPMT(eDVBServicePMTHandler *pmthandler) { eTrace("[CI] check slot %d %d %d", tmp->getSlotID(), tmp->running_services.empty(), canDescrambleMultipleServices(tmp)); if (tmp->running_services.empty() || canDescrambleMultipleServices(tmp)) + { + tmp->setCADemuxID(pmthandler); tmp->sendCAPMT(pmthandler); + } tmp = tmp->linked_next; } } @@ -1242,6 +1245,7 @@ eDVBCISlot::eDVBCISlot(eMainloop *context, int nr) { char configStr[255]; slotid = nr; + m_ca_demux_id = -1; m_context = context; state = stateDisabled; snprintf(configStr, 255, "config.ci.%d.enabled", slotid); @@ -1489,6 +1493,24 @@ int eDVBCISlot::cancelEnq() return 0; } +int eDVBCISlot::setCADemuxID(eDVBServicePMTHandler *pmthandler) +{ + ePtr demux; + uint8_t dmx_id; + + if (!pmthandler->getDataDemux(demux)) + { + if (!demux->getCADemuxID(dmx_id)) + { + m_ca_demux_id = dmx_id; + eDebug("[CI] Slot %d: CA demux_id = %d", getSlotID(), m_ca_demux_id); + } + else + m_ca_demux_id = -1; + } + return 0; +} + int eDVBCISlot::sendCAPMT(eDVBServicePMTHandler *pmthandler, const std::vector &ids) { if (!ca_manager) diff --git a/lib/dvb_ci/dvbci.h b/lib/dvb_ci/dvbci.h index a21b6f924dd..95c76ab4cac 100644 --- a/lib/dvb_ci/dvbci.h +++ b/lib/dvb_ci/dvbci.h @@ -66,6 +66,7 @@ class eDVBCISlot: public iObject, public sigc::trackable bool user_mapped; void data(int); bool plugged; + int16_t m_ca_demux_id; eMainloop *m_context; eDVBCIApplicationManagerSession *getAppManager() { return application_manager; } @@ -82,6 +83,7 @@ class eDVBCISlot: public iObject, public sigc::trackable int cancelEnq(); int getMMIState(); int sendCAPMT(eDVBServicePMTHandler *ptr, const std::vector &caids=std::vector()); + int setCADemuxID(eDVBServicePMTHandler *pmthandler); void removeService(uint16_t program_number=0xFFFF); int setSource(const std::string &source); int setClockRate(const std::string &rate); @@ -106,6 +108,7 @@ class eDVBCISlot: public iObject, public sigc::trackable int getSlotID(); int getNumOfServices(); int getVersion(); + int16_t getCADemuxID() { return m_ca_demux_id; }; }; struct CIPmtHandler diff --git a/lib/dvb_ci/dvbci_ccmgr.cpp b/lib/dvb_ci/dvbci_ccmgr.cpp index bf03719f306..298b8aeb09f 100644 --- a/lib/dvb_ci/dvbci_ccmgr.cpp +++ b/lib/dvb_ci/dvbci_ccmgr.cpp @@ -18,7 +18,10 @@ eDVBCICcSession::eDVBCICcSession(eDVBCISlot *slot, int version): uint8_t buf[32], host_id[8]; m_slot->setCCManager(this); - m_descrambler_fd = descrambler_init(); + m_descrambler_fd = -1; + m_current_ca_demux_id = 0; + m_descrambler_new_key = false; + parameter_init(m_dh_p, m_dh_g, m_dh_q, m_s_key, m_key_data, m_iv); m_ci_elements.init(); @@ -114,6 +117,9 @@ void eDVBCICcSession::send(const unsigned char *tag, const void *data, int len) void eDVBCICcSession::addProgram(uint16_t program_number, std::vector& pids) { + // first open ca device and set descrambler key if it's not set yet + set_descrambler_key(); + eDebugNoNewLineStart("[CI CC] SESSION(%d)/ADD PROGRAM %04x: ", session_nb, program_number); for (std::vector::iterator it = pids.begin(); it != pids.end(); ++it) eDebugNoNewLine("%02x ", *it); @@ -745,12 +751,48 @@ void eDVBCICcSession::check_new_key() if (slot != 0 && slot != 1) slot = 1; - descrambler_set_key(m_descrambler_fd, m_slot->getSlotID(), slot, dec); + memcpy(m_descrambler_key_iv, dec, 32); + m_descrambler_odd_even = slot; + m_descrambler_new_key = true; + + set_descrambler_key(); m_ci_elements.invalidate(KP); m_ci_elements.invalidate(KEY_REGISTER); } +/* Opens /dev/caX device if it's not open yet. + * If ca demux has changed close current /dev/caX device and open new ca device. + * Sets new key or old one if /dev/caX device has changed */ +void eDVBCICcSession::set_descrambler_key() +{ + eDebug("[CI RCC] set_descrambler_key"); + bool set_key = (m_current_ca_demux_id != m_slot->getCADemuxID()); + + if (m_descrambler_fd != -1 && m_current_ca_demux_id != m_slot->getCADemuxID()) + { + descrambler_deinit(m_descrambler_fd); + m_descrambler_fd = descrambler_init(m_slot->getCADemuxID()); + m_current_ca_demux_id = m_slot->getCADemuxID(); + } + + if (m_descrambler_fd == -1 && m_slot->getCADemuxID() > -1) + { + m_descrambler_fd = descrambler_init(m_slot->getCADemuxID()); + m_current_ca_demux_id = m_slot->getCADemuxID(); + } + + if (m_descrambler_fd != -1 && (set_key || m_descrambler_new_key)) + { + eDebug("[CI RCC] setting key: new ca device: %d, new key: %d", set_key, m_descrambler_new_key); + descrambler_set_key(m_descrambler_fd, m_slot->getSlotID(), m_descrambler_odd_even, m_descrambler_key_iv); + if (m_descrambler_new_key) + { + m_descrambler_new_key = false; + } + } +} + void eDVBCICcSession::generate_key_seed() { SHA256_CTX sha; diff --git a/lib/dvb_ci/dvbci_ccmgr.h b/lib/dvb_ci/dvbci_ccmgr.h index 61efe6a75e6..102aa7b84f8 100644 --- a/lib/dvb_ci/dvbci_ccmgr.h +++ b/lib/dvb_ci/dvbci_ccmgr.h @@ -16,6 +16,7 @@ class eDVBCICcSession: public eDVBCISession { eDVBCISlot *m_slot; int m_descrambler_fd; + uint8_t m_current_ca_demux_id; // CI+ credentials enum @@ -240,6 +241,11 @@ class eDVBCICcSession: public eDVBCISession uint8_t m_key_data[16]; uint8_t m_iv[16]; + /* descrambler key */ + bool m_descrambler_new_key; + uint8_t m_descrambler_key_iv[32]; + uint8_t m_descrambler_odd_even; + int receivedAPDU(const unsigned char *tag, const void *data, int len); int doAction(); @@ -278,6 +284,8 @@ class eDVBCICcSession: public eDVBCISession bool ci_element_set_certificate(unsigned int id, X509 *cert); bool ci_element_set_hostid_from_certificate(unsigned int id, X509 *cert); + void set_descrambler_key(); + public: eDVBCICcSession(eDVBCISlot *tslot, int version); ~eDVBCICcSession(); From 69051d3303635463858902b7a182f26606d6efd4 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Mon, 6 Nov 2023 18:22:57 +0200 Subject: [PATCH 146/401] [Added] Added spaceLeft for movieList [Fixed] Some positioning issues in several screens --- lib/python/Components/MovieList.py | 38 +++++++++++++++------------- lib/python/Components/ServiceList.py | 2 +- lib/python/Screens/MovieSelection.py | 2 +- 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/lib/python/Components/MovieList.py b/lib/python/Components/MovieList.py index e9e35870121..172d8e88a7d 100644 --- a/lib/python/Components/MovieList.py +++ b/lib/python/Components/MovieList.py @@ -230,6 +230,7 @@ def __init__(self, root, sort_type=None, descr_state=None, allowCollections=Fals self.pbarColourPlayRec = 0xffc71d self.partIconeShift = None self.spaceRight = 2 + self.spaceLeft= 2 self.spaceIconeText = 2 self.iconsWidth = 22 self.durationWidth = 160 @@ -376,6 +377,9 @@ def spaceIconeText(value): def iconsWidth(value): self.iconsWidth = parseScale(value) + + def spaceLeft(value): + self.spaceLeft = parseScale(value) def spaceRight(value): self.spaceRight = parseScale(value) @@ -443,24 +447,24 @@ def buildMovieListEntry(self, serviceref, info, begin, data): if serviceref.flags & eServiceReference.isGroup: # Collection - res.append(MultiContentEntryPixmapAlphaBlend(pos=(0, 0), size=(col0iconSize, self.itemHeight), png=self.iconCollection, flags=BT_ALIGN_CENTER)) + res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft, 0), size=(col0iconSize, self.itemHeight), png=self.iconCollection, flags=BT_ALIGN_CENTER)) if self.getCurrent() in self.markList: - res.append(MultiContentEntryPixmapAlphaBlend(pos=(0, 0), size=(col0iconSize, self.itemHeight), png=self.iconMarked)) - res.append(MultiContentEntryText(pos=(col0iconSize + space, 0), size=(width - 220, self.itemHeight), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=data.txt)) + res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft, 0), size=(col0iconSize, self.itemHeight), png=self.iconMarked)) + res.append(MultiContentEntryText(pos=(self.spaceLeft + col0iconSize + space, 0), size=(width - 220, self.itemHeight), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=data.txt)) recordingCount = ngettext("%d Recording", "%d Recordings", data.collectionCount) % data.collectionCount res.append(MultiContentEntryText(pos=(width - 220 - r, 0), size=(220, self.itemHeight), font=1, flags=RT_HALIGN_RIGHT | RT_VALIGN_CENTER, text=recordingCount)) return res if serviceref.flags & eServiceReference.mustDescent: # Directory if data.txt == ".Trash": - res.append(MultiContentEntryPixmapAlphaBlend(pos=(0, 0), size=(col0iconSize, self.itemHeight), png=self.iconTrash, flags=BT_ALIGN_CENTER)) - res.append(MultiContentEntryText(pos=(col0iconSize + space, 0), size=(width - 145, self.itemHeight), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=_("Deleted items"))) + res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft, 0), size=(col0iconSize, self.itemHeight), png=self.iconTrash, flags=BT_ALIGN_CENTER)) + res.append(MultiContentEntryText(pos=(self.spaceLeft + col0iconSize + space, 0), size=(width - 145, self.itemHeight), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=_("Deleted items"))) res.append(MultiContentEntryText(pos=(width - 145 - r, 0), size=(145, self.itemHeight), font=1, flags=RT_HALIGN_RIGHT | RT_VALIGN_CENTER, text=_("Trash can"))) return res - res.append(MultiContentEntryPixmapAlphaBlend(pos=(0, 0), size=(col0iconSize, self.itemHeight), png=self.iconFolder, flags=BT_ALIGN_CENTER)) + res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft, 0), size=(col0iconSize, self.itemHeight), png=self.iconFolder, flags=BT_ALIGN_CENTER)) if self.getCurrent() in self.markList: - res.append(MultiContentEntryPixmapAlphaBlend(pos=(0, 0), size=(col0iconSize, self.itemHeight), png=self.iconMarked)) - res.append(MultiContentEntryText(pos=(col0iconSize + space, 0), size=(width - 145, self.itemHeight), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=data.txt)) + res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft, 0), size=(col0iconSize, self.itemHeight), png=self.iconMarked)) + res.append(MultiContentEntryText(pos=(self.spaceLeft + col0iconSize + space, 0), size=(width - 145, self.itemHeight), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=data.txt)) res.append(MultiContentEntryText(pos=(width - 145 - r, 0), size=(145, self.itemHeight), font=1, flags=RT_HALIGN_RIGHT | RT_VALIGN_CENTER, text=_("Directory"))) return res if data.dirty: @@ -518,25 +522,25 @@ def addProgress(): if data: if switch == 'i' and data.icon is not None: if self.partIconeShift is None: - res.append(MultiContentEntryPixmapAlphaBlend(pos=(colX, 0), size=(iconSize, ih), png=data.icon, flags=BT_ALIGN_CENTER)) + res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft + colX, 0), size=(iconSize, ih), png=data.icon, flags=BT_ALIGN_CENTER)) else: - res.append(MultiContentEntryPixmapAlphaBlend(pos=(colX, self.partIconeShift), size=(iconSize, data.icon.size().height()), png=data.icon)) + res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft + colX, self.partIconeShift), size=(iconSize, data.icon.size().height()), png=data.icon)) elif switch in ('p', 's'): if data.part > 0: pbarY = (self.itemHeight - self.pbarHeight) // 2 if self.pbarShift is None else self.pbarShift - res.append(MultiContentEntryProgress(pos=(colX, pbarY), size=(iconSize, self.pbarHeight), percent=data.part, borderWidth=2, foreColor=data.partcol, foreColorSelected=None, backColor=None, backColorSelected=None)) + res.append(MultiContentEntryProgress(pos=(self.spaceLeft + colX, pbarY), size=(iconSize, self.pbarHeight), percent=data.part, borderWidth=2, foreColor=data.partcol, foreColorSelected=None, backColor=None, backColorSelected=None)) elif data.icon is not None: if self.pbarShift is None: - res.append(MultiContentEntryPixmapAlphaBlend(pos=(colX, 0), size=(iconSize, ih), png=data.icon, flags=BT_ALIGN_CENTER)) + res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft + colX, 0), size=(iconSize, ih), png=data.icon, flags=BT_ALIGN_CENTER)) else: - res.append(MultiContentEntryPixmapAlphaBlend(pos=(colX, self.pbarShift), size=(iconSize, self.pbarHeight), png=data.icon)) + res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft + colX, self.pbarShift), size=(iconSize, self.pbarHeight), png=data.icon)) return iconSize if piconWidth > 0: # Picon if data and data.picon is not None: res.append(MultiContentEntryPixmapAlphaBlend( - pos=(colX, 0), size=(piconWidth, ih), + pos=(self.spaceLeft + colX, 0), size=(piconWidth, ih), png=data.picon, backcolor=None, backcolor_sel=None, flags=BT_SCALE | BT_KEEP_ASPECT_RATIO | BT_HALIGN_CENTER | BT_VALIGN_CENTER)) colX += piconWidth @@ -545,11 +549,11 @@ def addProgress(): # The selection mark floats over the top of the first column if self.getCurrent() in self.markList: - res.append(MultiContentEntryPixmapAlphaBlend(pos=(0, 0), size=(colX, self.itemHeight), png=self.iconMarked)) + res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft, 0), size=(colX, self.itemHeight), png=self.iconMarked)) colX += space # Recording name - res.append(MultiContentEntryText(pos=(colX, 0), size=(width - iconSize - space - durationWidth - dateWidth - r - colX, ih), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=data.txt)) + res.append(MultiContentEntryText(pos=(self.spaceLeft + colX, 0), size=(width - iconSize - space - durationWidth - dateWidth - r - colX, ih), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=data.txt)) colX = width - iconSize - space - durationWidth - dateWidth - r if piconWidth > 0: @@ -561,7 +565,7 @@ def addProgress(): length = data.len if length > 0: length = ngettext("%d Min", "%d Mins", (length // 60)) % (length // 60) - res.append(MultiContentEntryText(pos=(colX, 0), size=(durationWidth, ih), font=1, flags=RT_HALIGN_RIGHT | RT_VALIGN_CENTER, text=length)) + res.append(MultiContentEntryText(pos=(self.spaceLeft + colX, 0), size=(durationWidth, ih), font=1, flags=RT_HALIGN_RIGHT | RT_VALIGN_CENTER, text=length)) # Date begin_string = "" diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 3948a08e799..78e3fe38cf3 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -336,7 +336,7 @@ def getSelectionPosition(self): sely = self.instance.position().y() + self.ItemHeight * index if sely >= self.instance.position().y() + self.listHeight: sely -= self.listHeight - return self.listWidth, sely + return self.listWidth + self.instance.position().x(), sely def setFontsize(self): self.ServiceNumberFont = gFont(self.ServiceNameFontName, self.ServiceNameFontSize + config.usage.servicenum_fontsize.value) diff --git a/lib/python/Screens/MovieSelection.py b/lib/python/Screens/MovieSelection.py index e387dc5de3a..79c7d846acd 100644 --- a/lib/python/Screens/MovieSelection.py +++ b/lib/python/Screens/MovieSelection.py @@ -391,7 +391,7 @@ class MovieContextMenu(Screen, ProtectedScreen): # Contract: On OK returns a callable object (e.g. delete) def __init__(self, session, csel, currentSelection): Screen.__init__(self, session) - self.skinName = "Setup" + self.skinName = ["MovieContextMenu", "Setup"] self.setup_title = _("Movie List Setup") Screen.setTitle(self, _(self.setup_title)) From 03ca548ef5d459d9b9ddc61b3bd1c24402a6b1ff Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Mon, 6 Nov 2023 19:32:45 +0000 Subject: [PATCH 147/401] PEP8 double aggressive E22, E224, E241, E242 and E27 --- lib/python/Components/MovieList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/MovieList.py b/lib/python/Components/MovieList.py index 172d8e88a7d..4107305de02 100644 --- a/lib/python/Components/MovieList.py +++ b/lib/python/Components/MovieList.py @@ -230,7 +230,7 @@ def __init__(self, root, sort_type=None, descr_state=None, allowCollections=Fals self.pbarColourPlayRec = 0xffc71d self.partIconeShift = None self.spaceRight = 2 - self.spaceLeft= 2 + self.spaceLeft = 2 self.spaceIconeText = 2 self.iconsWidth = 22 self.durationWidth = 160 From 55e13af59f1f5e8bb1cf9f9f9d4f5e25db3d76a0 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Mon, 6 Nov 2023 19:33:22 +0000 Subject: [PATCH 148/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Components/MovieList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/MovieList.py b/lib/python/Components/MovieList.py index 4107305de02..029110734cc 100644 --- a/lib/python/Components/MovieList.py +++ b/lib/python/Components/MovieList.py @@ -377,7 +377,7 @@ def spaceIconeText(value): def iconsWidth(value): self.iconsWidth = parseScale(value) - + def spaceLeft(value): self.spaceLeft = parseScale(value) From f57c2f745622433f517280bb506c14125d58ea51 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Tue, 7 Nov 2023 11:25:37 +0200 Subject: [PATCH 149/401] [Removed] Unused imports --- lib/python/Components/Addons/ButtonSequence.py | 2 +- lib/python/Components/Addons/ColorButtonsSequence.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/python/Components/Addons/ButtonSequence.py b/lib/python/Components/Addons/ButtonSequence.py index e3658680983..80282c800aa 100644 --- a/lib/python/Components/Addons/ButtonSequence.py +++ b/lib/python/Components/Addons/ButtonSequence.py @@ -1,6 +1,6 @@ from Components.Addons.GUIAddon import GUIAddon -from enigma import eListbox, eListboxPythonMultiContent, BT_ALIGN_CENTER, BT_VALIGN_CENTER +from enigma import eListbox, eListboxPythonMultiContent, BT_ALIGN_CENTER from skin import parseScale, applySkinFactor diff --git a/lib/python/Components/Addons/ColorButtonsSequence.py b/lib/python/Components/Addons/ColorButtonsSequence.py index 7fd9b1fd7d6..160d4218cec 100644 --- a/lib/python/Components/Addons/ColorButtonsSequence.py +++ b/lib/python/Components/Addons/ColorButtonsSequence.py @@ -1,6 +1,6 @@ from Components.Addons.GUIAddon import GUIAddon -from enigma import eLabel, eListbox, eListboxPythonMultiContent, BT_ALIGN_CENTER, BT_VALIGN_CENTER, RT_VALIGN_CENTER, RT_HALIGN_LEFT, eSize, getDesktop, gFont +from enigma import eListbox, eListboxPythonMultiContent, BT_ALIGN_CENTER, RT_VALIGN_CENTER, RT_HALIGN_LEFT, eSize, getDesktop, gFont from skin import parseScale, parseColor, parseFont, applySkinFactor @@ -55,7 +55,6 @@ def buildEntry(self, sequence): height = self.instance.size().height() xPos = width if self.alignment == "right" else 0 yPos = 0 - sectorWidth = width // len(sequence) minSectorWidth = width // 4 pic = None From 785a23b5b67752e77279ae3655f3499ad3c8bdf8 Mon Sep 17 00:00:00 2001 From: Orlandoxx <95180049+Orlandoxx@users.noreply.github.com> Date: Tue, 7 Nov 2023 16:42:05 +0200 Subject: [PATCH 150/401] Updated Finnish (fi.po) translation. Added a missing translation. --- po/fi.po | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/po/fi.po b/po/fi.po index 82cfbe830d5..879b7b76f35 100644 --- a/po/fi.po +++ b/po/fi.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: enigma2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-27 23:35+0000\n" -"PO-Revision-Date: 2023-10-31 06:51+0200\n" +"PO-Revision-Date: 2023-11-07 16:38+0200\n" "Last-Translator: Orlandox\n" "Language-Team: timoj/Kojo/Samzam/Orlandox\n" "Language: fi\n" @@ -9628,6 +9628,9 @@ msgstr "Muuta tallennuksen päättymisaika" msgid "Choose CCcam-Reader" msgstr "Valitse CCcam-lukija" +msgid "Please choose an extension" +msgstr "Valitse laajennus" + msgid "Please choose an extension..." msgstr "Valitse laajennus..." @@ -13540,7 +13543,7 @@ msgstr "" "Suomenkielinen käännös: timoj, Kojo, Samzam, Orlandox\n" "\n" "Ylläpito : Orlandox\n" -"31.10.2023\n" +"07.11.2023\n" "http://www.huoltovalikko.com" msgid "TS file is too large for ISO9660 level 1!" From 60ae24d263da31eaa469e8b1da3a4ec448164df0 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sun, 5 Nov 2023 21:56:24 +0100 Subject: [PATCH 151/401] =?UTF-8?q?=EF=BB=BF[Addons]=20Unused=20imports?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/python/Components/Addons/ButtonSequence.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/python/Components/Addons/ButtonSequence.py b/lib/python/Components/Addons/ButtonSequence.py index 80282c800aa..c58339e261b 100644 --- a/lib/python/Components/Addons/ButtonSequence.py +++ b/lib/python/Components/Addons/ButtonSequence.py @@ -5,7 +5,6 @@ from skin import parseScale, applySkinFactor from Components.MultiContent import MultiContentEntryPixmapAlphaBlend -from Components.Sources.List import List from Components.Sources.Boolean import Boolean from Components.Sources.StaticText import StaticText From 657c17073cc63be7d6dd6a245f6339c280981b6e Mon Sep 17 00:00:00 2001 From: s3n0 Date: Fri, 3 Nov 2023 16:02:01 +0100 Subject: [PATCH 152/401] dividing by zero This is a quick solution to the error when dividing by zero, in a certain situation (the difference of equal heights gives zero). The problem is solved in the same way in the OpenATV source code: https://github.com/openatv/enigma2/blob/3f897f5a60903e6fc2f757fd288c8ba203aff71d/lib/python/Components/ScrollLabel.py#L225C3-L225C101 ``` < 399.8945> 11:37:30.0423 Traceback (most recent call last): < 399.8946> 11:37:30.0423 File "/usr/lib/enigma2/python/Plugins/Extensions/ChocholousekPicons/plugin.py", line 1774, in logWindowUpdate < 399.9004> 11:37:30.0481 self['logWindow'].lastPage() < 399.9007> 11:37:30.0484 File "/usr/lib/enigma2/python/Components/ScrollLabel.py", line 146, in lastPage < 399.9012> 11:37:30.0489 File "/usr/lib/enigma2/python/Components/ScrollLabel.py", line 153, in updateScrollbar < 399.9015> 11:37:30.0495 ZeroDivisionError: integer division or modulo by zero < 399.9020> 11:37:30.0497 [ePyObject] (CallObject(>,()) failed) ``` ``` < 310.2158> 14:49:01.9647 Traceback (most recent call last): < 310.2160> 14:49:01.9649 File "/usr/lib/enigma2/python/Plugins/Extensions/ChocholousekPicons/plugin.py", line 1774, in logWindowUpdate < 310.2266> 14:49:01.9755 self['logWindow'].lastPage() < 310.2271> 14:49:01.9760 File "/usr/lib/enigma2/python/Components/ScrollLabel.py", line 146, in lastPage < 310.2281> 14:49:01.9770 self.updateScrollbar() < 310.2285> 14:49:01.9774 File "/usr/lib/enigma2/python/Components/ScrollLabel.py", line 153, in updateScrollbar < 310.2296> 14:49:01.9785 start = (100 - vis) * self.curPos // (self.TotalTextHeight - self.pageHeight) < 310.2310> 14:49:01.9799 ~~~~~~~~~~~~~~~~~~~~~~~~~~^^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ < 310.2312> 14:49:01.9801 ZeroDivisionError: integer division or modulo by zero < 310.2313> 14:49:01.9802 [ePyObject] (CallObject(>,()) failed) ``` --- lib/python/Components/ScrollLabel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/ScrollLabel.py b/lib/python/Components/ScrollLabel.py index 8ac4a4ed5f1..02b50c7092f 100644 --- a/lib/python/Components/ScrollLabel.py +++ b/lib/python/Components/ScrollLabel.py @@ -150,7 +150,7 @@ def isAtLastPage(self): def updateScrollbar(self): vis = max(100 * self.pageHeight // self.TotalTextHeight, 3) - start = (100 - vis) * self.curPos // (self.TotalTextHeight - self.pageHeight) + start = (100 - vis) * self.curPos // ((self.TotalTextHeight - self.pageHeight) or 1) self.scrollbar.setStartEnd(start, start + vis) def GUIcreate(self, parent): From f3c23c9196e73310527e107ad5c35358ac247c29 Mon Sep 17 00:00:00 2001 From: openvix-build Date: Wed, 8 Nov 2023 00:52:25 +0000 Subject: [PATCH 153/401] openvix: developer 6.4.009.012 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index e714fee93e8..3cb5a0d6f89 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1195,3 +1195,4 @@ openvix: developer 6.4.009.008 openvix: developer 6.4.009.009 openvix: developer 6.4.009.010 openvix: developer 6.4.009.011 +openvix: developer 6.4.009.012 From a93b7c5293edaeef83de73abc664c0291767f081 Mon Sep 17 00:00:00 2001 From: Rob van der Does Date: Wed, 8 Nov 2023 17:18:57 +0100 Subject: [PATCH 154/401] [Translations] Update Dutch (NL) translation. --- po/nl.po | 1175 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 609 insertions(+), 566 deletions(-) diff --git a/po/nl.po b/po/nl.po index 0569c5685f0..86af50e5f73 100644 --- a/po/nl.po +++ b/po/nl.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: ViX\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-09-21 00:52+0000\n" -"PO-Revision-Date: 2023-09-21 12:39+0200\n" +"POT-Creation-Date: 2023-11-08 01:01+0000\n" +"PO-Revision-Date: 2023-11-08 17:17+0100\n" "Last-Translator: Rob van der Does \n" "Language-Team: Andy Blackburn, Rob van der Does\n" "Language: nl\n" @@ -13,7 +13,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-SourceCharset: iso-8859-15\n" -"X-Generator: Poedit 3.3.2\n" +"X-Generator: Poedit 3.4.1\n" #, python-format msgid "" @@ -30,35 +30,6 @@ msgstr "" "\n" "(verzoek tot afsluiten veranderd naar stand-by omdat er een stream-klant actief is.)" -msgid "" -"\n" -"Advanced options and settings." -msgstr "" -"\n" -"Geavanceerde opties en instellingen." - -msgid "" -"\n" -"After pressing OK, please wait!" -msgstr "" -"\n" -"Druk op OK en een ogenblik geduld!" - -#, python-format -msgid "" -"\n" -"Backup your %s %s settings." -msgstr "" -"\n" -"Maak een back-up van de instellingen van uw %s %s." - -msgid "" -"\n" -"Edit the upgrade source address." -msgstr "" -"\n" -"Wijzig het bronadres voor upgrades ." - msgid "" "\n" "It contains other items." @@ -66,14 +37,6 @@ msgstr "" "\n" "Het bevat andere items." -#, python-format -msgid "" -"\n" -"Manage extensions or plugins for your %s %s" -msgstr "" -"\n" -"Beheer extensies en plugins voor uw %s %s" - msgid "" "\n" "One is a directory that isn't empty." @@ -87,21 +50,6 @@ msgstr[1] "" "\n" "Er zijn mappen die niet leeg zijn." -#, python-format -msgid "" -"\n" -"Online update of your %s %s software." -msgstr "" -"\n" -"Online bijwerken van uw %s %s software." - -msgid "" -"\n" -"Press OK on your remote control to continue." -msgstr "" -"\n" -"Druk op OK om door te gaan." - msgid "" "\n" "Recording in progress." @@ -109,45 +57,6 @@ msgstr "" "\n" "Opname is bezig." -#, python-format -msgid "" -"\n" -"Restore your %s %s settings." -msgstr "" -"\n" -"De instellingen van uw %s %s terugplaatsen." - -#, python-format -msgid "" -"\n" -"Restore your %s %s with a new firmware." -msgstr "" -"\n" -"Plaats nieuwe firmware in uw %s %s." - -msgid "" -"\n" -"Restore your backups by date." -msgstr "" -"\n" -"Zet de back-up van een bepaalde datum terug." - -msgid "" -"\n" -"Scan for local extensions and install them." -msgstr "" -"\n" -"Zoek naar lokale extensies en installeer die." - -msgid "" -"\n" -"Select your backup device.\n" -"Current device: " -msgstr "" -"\n" -"Kies een back-up medium.\n" -"Huidig medium: " - #, python-format msgid "" "\n" @@ -156,13 +65,6 @@ msgstr "" "\n" "Timer '%s' uitgeschakeld!" -msgid "" -"\n" -"View, install and remove available or installed packages." -msgstr "" -"\n" -"Bekijk, installeer en verwijder beschikbare of geïnstalleerde pakketten." - msgid " " msgstr " " @@ -1078,10 +980,6 @@ msgstr "%s %s ir muis" msgid "%s %s remote control (native)" msgstr "%s %s afstandsbediening" -#, python-format -msgid "%s %s software because updates are available." -msgstr "%s %s software want er zijn updates beschikbaar." - #, python-format msgid "%s ( %s Cards )" msgstr "%s ( %s kaarten )" @@ -1187,7 +1085,7 @@ msgid "" msgstr "" "'Opslaan' verandert de actieve taal.\n" "'Voeg taal toe' of 'MENU' voegt additionele taal toe.\n" -"'Verwijder taal' verwijdert alle talen behalve Engels en de actieve taal OF de geselecteerde taal." +"'Verwijder taal' verwijdert alle talen behalve Engels en de actieve taal OF de geselecteerde taal" msgid "(All readers)" msgstr "(Alle lezers)" @@ -1697,9 +1595,6 @@ msgstr "Een herhalende timer of eenmalig?" msgid "A required tool (%s) was not found." msgstr "Een benodigd hulpmiddel (%s) is niet gevonden." -msgid "A search for available updates is currently in progress." -msgstr "Bezig met zoeken naar updates." - msgid "" "A second configured interface has been found.\n" "\n" @@ -1725,9 +1620,6 @@ msgstr "" "Een slaaptimer wil uw %s %s uitschakelen.\n" "Doorgaan?" -msgid "A small overview of the available icon states and actions." -msgstr "Een klein overzicht van gebruikte icoon-statussen en acties." - msgid "" "A timer failed to record!\n" "Disable TV and try again?\n" @@ -2031,15 +1923,6 @@ msgstr "Geavanceerd" msgid "Advanced options" msgstr "Geavanceerde opties" -msgid "Advanced restore" -msgstr "Geavanceerd herstellen" - -msgid "Advanced software" -msgstr "Geavanceerde software" - -msgid "Advanced software plugin" -msgstr "Geavanceerde software plugin" - msgid "Advanced video enhancement setup" msgstr "Geavanceerde videoverbeteringsinstellingen" @@ -2241,9 +2124,6 @@ msgstr "Alternatieve radiomodus" msgid "Alternative services tuner priority" msgstr "Alternatieve tunerprioriteit" -msgid "Always ask" -msgstr "Altijd vragen" - msgid "Always hide infobar" msgstr "Informatiebalk altijd verbergen" @@ -2265,9 +2145,6 @@ msgstr "Amerikaanse sporten" msgid "An empty filename is illegal." msgstr "Een lege bestandsnaam is ongeldig." -msgid "An error occurred while downloading the packetlist. Please try again." -msgstr "Er is een fout opgetreden bij het downloaden van de pakketlijst. Probeer het nogmaals." - msgid "An unknown error occurred!" msgstr "Er is een onbekende fout opgetreden!" @@ -2337,13 +2214,6 @@ msgstr "" "Wilt u deze netwerkconfiguratie nu activeren?\n" "\n" -msgid "" -"Are you sure you want to delete\n" -"the following backup:\n" -msgstr "" -"Weet u zeker dat u de volgende\n" -"back-up wilt verwijderen:\n" - msgid "Are you sure you want to delete all the selected logs:\n" msgstr "Weet u zeker dat u alle geselecteerde logs wilt verwijderen:\n" @@ -2363,6 +2233,13 @@ msgstr "" "Weet u zeker dat u dit wilt verwijderen:\n" " " +msgid "" +"Are you sure you want to disable this network configuration?\n" +"\n" +msgstr "" +"Wilt u deze netwerkconfiguratie nu uitschakelen?\n" +"\n" + msgid "" "Are you sure you want to download this image:\n" " " @@ -2402,25 +2279,6 @@ msgstr "" "Weet u zeker dat u de netwerk interface wilt herstarten?\n" "\n" -#, python-format -msgid "" -"Are you sure you want to restore\n" -"the following backup:\n" -"%s\n" -"Your receiver will restart after the backup has been restored!" -msgstr "" -"Weet u zeker dat u de volgende\n" -"back-up wilt flashen:\n" -"%s\n" -"Uw ontvanger zal herstarten nadat de back-up is teruggeplaatst!" - -msgid "" -"Are you sure you want to restore the backup?\n" -"Your receiver will restart after the backup has been restored!" -msgstr "" -"Weet u zeker dat u de back-up wilt flashen?\n" -"Uw ontvanger zal herstarten als het proces gereed is!" - msgid "" "Are you sure you want to restore this backup:\n" " " @@ -2543,9 +2401,6 @@ msgstr "Australisch" msgid "Austria" msgstr "Austria" -msgid "Author: " -msgstr "Auteur: " - msgid "Authoring mode" msgstr "Bewerkingswijze" @@ -2748,9 +2603,6 @@ msgstr "Back-up gereed." msgid "Backup complete..." msgstr "Back-up gereed." -msgid "Backup completed." -msgstr "Back-up gereed." - msgid "Backup confirmation" msgstr "Back-up bevestiging" @@ -2760,9 +2612,6 @@ msgstr "Back-up gemaakt" msgid "Backup failed - e. g. wrong backup destination or no space left on backup device." msgstr "Back-up mislukt - mogelijk a.g.v. verkeerde bestemming of te weinig ruimte op het back-up medium." -msgid "Backup failed." -msgstr "Back-up is mislukt." - msgid "" "Backup in progress,\n" "Please wait for it to finish, before trying again." @@ -2770,9 +2619,6 @@ msgstr "" "Back- up bezig.\n" "Wacht tot deze gereed is alvorens opnieuw te proberen." -msgid "Backup is running..." -msgstr "Back-up wordt uitgevoerd..." - msgid "Backup location" msgstr "Back-up locatie" @@ -2785,9 +2631,6 @@ msgstr "Back-up manager instellingen" msgid "Backup prefix" msgstr "Back-up voorvoegsel" -msgid "Backup system settings" -msgstr "Back-up uw instellingen" - msgid "Backup/Flash/ReBoot system image." msgstr "Backup/Flash/Reboot system image." @@ -3811,9 +3654,6 @@ msgstr "Common interface toewijzing" msgid "Common options" msgstr "Algemene instellingen" -msgid "Communication" -msgstr "Communicatie" - msgid "Comoros" msgstr "Comoros" @@ -4167,15 +4007,15 @@ msgstr "Verbinden" msgid "Connect to a wireless network" msgstr "Verbind met een draadloos netwerk" -msgid "Connected" -msgstr "Verbonden" - msgid "Connected clients" msgstr "Verbonden klanten" msgid "Connected satellites" msgstr "Verbonden satellieten" +msgid "Connected through another tuner" +msgstr "Verbonden door een andere tuner" + msgid "Connected to" msgstr "Verbonden met" @@ -4206,9 +4046,6 @@ msgstr "De inhoud past niet op een DVD!" msgid "Context" msgstr "Inhoud" -msgid "Continue" -msgstr "Doorgaan" - msgid "Continue playback" msgstr "Afspelen wordt hervat" @@ -4841,9 +4678,6 @@ msgstr "Default poort is '%d'. Pas aan indien gewenst." msgid "Default recording type" msgstr "Standaard opname type" -msgid "Default settings" -msgstr "Standaard instellingen" - #, python-format msgid "Default: '%s'." msgstr "Standaard: '%s'." @@ -5029,9 +4863,6 @@ msgstr "Beschrijving" msgid "Deselect" msgstr "Deselecteer" -msgid "Details for plugin: " -msgstr "Details voor plugin: " - msgid "Detect next boxes before standby" msgstr "Detecteert volgende apparaten alvorens naar stand-by te gaan" @@ -5135,24 +4966,24 @@ msgid "Directory %s does not exist." msgstr "Map %s bestaat niet." #, python-format -msgid "Directory '%s' does not exist!" -msgstr "Map '%s' bestaat niet!" +msgid "Directory '%s' does not exist." +msgstr "Map '%s' bestaat niet." #, python-format -msgid "Directory '%s' is not hard links capable!" -msgstr "In map '%s' kunnen geen harde links worden geschreven!" +msgid "Directory '%s' is not hard links capable." +msgstr "In map '%s' kunnen geen harde links worden geschreven." #, python-format -msgid "Directory '%s' not valid. Partition must be ext or nfs" -msgstr "Map '%s' is niet geldig. Partities moeten EXT of NFS geformatteerd zijn" +msgid "Directory '%s' not valid. Partition must be ext or nfs." +msgstr "Map '%s' is niet geldig. Partities moeten EXT of NFS geformatteerd zijn." #, python-format -msgid "Directory '%s' not writable!" -msgstr "In map '%s' kan niet worden geschreven!" +msgid "Directory '%s' not writable." +msgstr "In map '%s' kan niet worden geschreven." #, python-format -msgid "Directory '%s' not writeable!" -msgstr "In map '%s' kan niet worden geschreven!" +msgid "Directory '%s' not writeable." +msgstr "In map '%s' kan niet worden geschreven." msgid "Directory browser" msgstr "Bestandsverkenner" @@ -5211,9 +5042,6 @@ msgstr "Toon >16:9 materiaal als" msgid "Display Skin" msgstr "Display Skin" -msgid "Display and user interface" -msgstr "Scherm- en gebruikersinterface" - msgid "Display message before playing next movie" msgstr "Toon een bericht alvorens de volgende film te spelen" @@ -5367,9 +5195,6 @@ msgstr "" msgid "Do you want to install plugins" msgstr "Wilt u het plugins installeren" -msgid "Do you want to install the package:\n" -msgstr "Wilt u het volgende pakket installeren:\n" - msgid "Do you want to play DVD in drive?" msgstr "Wilt u de DVD in de speler afspelen?" @@ -5380,12 +5205,6 @@ msgstr "Wilt u de DVD bekijken alvorens te schrijven?" msgid "Do you want to reboot your %s %s" msgstr "Wilt u uw %s %s opnieuw opstarten?" -msgid "Do you want to reboot your receiver?" -msgstr "Wilt u uw ontvanger opnieuw opstarten?" - -msgid "Do you want to remove the package:\n" -msgstr "Wilt u het volgende pakket verwijderen:\n" - msgid "Do you want to restart GUI now ?" msgstr "Wilt u de gebruikersinterface nu opnieuw starten?" @@ -5408,9 +5227,6 @@ msgstr "Wilt u het afspelen vervolgen?" msgid "Do you want to update your %s %s?" msgstr "Wilt u uw %s %s updaten?" -msgid "Do you want to upgrade the package:\n" -msgstr "Wilt u een upgrade van het volgende pakket:\n" - msgid "Documentary" msgstr "Dcumentaire" @@ -5686,9 +5502,6 @@ msgstr "Bewerk de netwerkinstellingen van uw %s %s.\n" msgid "Edit title" msgstr "Wijzig titel" -msgid "Edit upgrade source url." -msgstr "Upgrade url bewerken." - msgid "Education" msgstr "Opleiding" @@ -5713,9 +5526,6 @@ msgstr "Verstreken" msgid "Elapsed & Remaining" msgstr "Verstreken en resterend" -msgid "Electronic Program Guide" -msgstr "Elektronische programmagids" - msgid "Empty slot" msgstr "Leeg slot" @@ -5937,6 +5747,9 @@ msgstr "Voer PIN in" msgid "Enter a number to jump to a service/channel" msgstr "Geef kanaalnummer in om naar te springen" +msgid "Enter adapter settings or disable adapter, then Save to action changed setup." +msgstr "Stel de adapter in of schakel deze uit en sla de wijziging op." + msgid "Enter if you are in the east or west hemisphere." msgstr "Geef aan of u op het westelijke of het oostelijke halfrond bent." @@ -6232,14 +6045,6 @@ msgstr "Uitgebreide instellingen..." msgid "Extended Shares" msgstr "Extended Shares" -# -msgid "Extended Software" -msgstr "Uitgebreide software" - -# -msgid "Extended Software Plugin" -msgstr "Uitgebreide software plugin" - msgid "Extended info" msgstr "Uitgebreide info" @@ -6252,8 +6057,8 @@ msgstr "Uitgebreide instellingen..." msgid "Extensions" msgstr "Extensies" -msgid "Extensions management" -msgstr "Applicatiebeheer" +msgid "Extensions menu" +msgstr "Extensie menu" msgid "Extensive search" msgstr "Uitgebreid zoeken" @@ -6615,9 +6420,6 @@ msgstr "Volk" msgid "Folkloric" msgstr "Folklore" -msgid "Following tasks will be done after you press OK!" -msgstr "Nadat u op OK drukt worden de volgende taken uitgevoerd!" - msgid "Font size" msgstr "Lettergrootte" @@ -7860,21 +7662,12 @@ msgstr "Installeer IPK's in uw tmp map." msgid "Install Plugins" msgstr "Installeer plugins" -msgid "Install a new image with a USB stick" -msgstr "Installeer een nieuwe image met een USB-stick" - -msgid "Install a new image with your web browser" -msgstr "Installeer een nieuwe image met uw browser" - msgid "Install channel list" msgstr "Installeer kanaallijst" msgid "Install confirmation" msgstr "Installeer bevestiging" -msgid "Install extensions" -msgstr "Installeer extensies" - msgid "Install extensions." msgstr "Installeer extensies." @@ -7884,15 +7677,9 @@ msgstr "Installeer LCD-Picons in" msgid "Install local extension" msgstr "Installeer lokale extensie" -msgid "Install or remove finished." -msgstr "Installeren of verwijderen voltooid." - msgid "Install picons on" msgstr "Installeer picons op" -msgid "Installation finished." -msgstr "Installatie mislukt." - #, python-format msgid "Installed:\t%s\n" msgstr "Geïnstalleerd:\t%s\n" @@ -8621,16 +8408,9 @@ msgstr "Mali" msgid "Malta" msgstr "Malta" -msgid "Manage extensions" -msgstr "Beheer van extensies" - msgid "Manage settings backup." msgstr "Beheer settings back-ups." -#, python-format -msgid "Manage your %s %s's software" -msgstr "Beheer de software van uw %s %s" - msgid "Manage your devices mount points." msgstr "Beheer hoe uw apparaten gemount zijn." @@ -9141,9 +8921,6 @@ msgstr "Multiboot FOUT! - geen STARTUP in bootpartitie." msgid "Multiboot only able to restore this backup to mmc slot1" msgstr "Multiboot kan deze back-up alleen maar herstellen van mmc slot1" -msgid "Multimedia" -msgstr "Multimedia" - msgid "Multiple service support" msgstr "Geschikt voor meervoudig decoderen" @@ -9464,9 +9241,6 @@ msgstr "Geen actief kanaal gevonden." msgid "No age block" msgstr "Geen leeftijdsblokkering" -msgid "No backup needed" -msgstr "Geen back-up nodig" - msgid "No card inserted!" msgstr "Geen kaart geplaatst!" @@ -9542,9 +9316,6 @@ msgstr "" msgid "No delay" msgstr "Geen vertraging" -msgid "No description available." -msgstr "Geen beschrijving beschikbaar." - msgid "No displayable files on this medium found!" msgstr "Geen weer te geven bestanden op dit medium gevonden!" @@ -9569,9 +9340,6 @@ msgstr "Geen images gevonden op de gekozen server... Controleer wachtwoord indie msgid "No module found" msgstr "Geen module gevonden" -msgid "No network connection available." -msgstr "Geen netwerkverbinding beschikbaar." - msgid "No networks found" msgstr "Geen netwerken gevonden" @@ -9651,15 +9419,6 @@ msgstr "" msgid "No, but restart from the beginning" msgstr "Nee, vanaf begin herstarten" -msgid "No, do nothing." -msgstr "Nee, geen actie." - -msgid "No, just start my %s %s" -msgstr "Nee, uitsluitend %s %s starten" - -msgid "No, never" -msgstr "Nee, nooit" - msgid "No, scan later manually" msgstr "Nee, later handmatig zoeken" @@ -9798,9 +9557,6 @@ msgstr "OK (lang) toets" msgid "OK button (short)" msgstr "OK (kort) toets" -msgid "OK, guide me through the upgrade process" -msgstr "OK, mij tijdens de software update begeleiden" - msgid "OK, to perform a restore" msgstr "JA, voer een herstelactie uit" @@ -9894,9 +9650,6 @@ msgstr "Uitsluitend actief in stand-by" msgid "Only change this setting if you are using a SCR device that has been reprogrammed with a custom programmer. For further information check with the person that reprogrammed the device." msgstr "Verander deze instelling alleen als u een SCR-apparaat gebruikt dat geprogrammeerd is met een aangepaste 'programmer'. Voor meer informatie overleg met degene die de aanpassing heeft gedaan." -msgid "Only extensions." -msgstr "Alleen extensies." - msgid "Only free scan" msgstr "Alleen ongecodeerde zenders scannen" @@ -10041,12 +9794,6 @@ msgstr "Output" msgid "Overwrite Recovery" msgstr "Overschrijf Recovery" -msgid "Overwrite configuration files during software upgrade?" -msgstr "Overschrijven configuratiebestanden tijdens de upgrade?" - -msgid "Overwrite configuration files?" -msgstr "Configuratiebestanden overschrijven?" - msgid "PAGE UP/DOWN" msgstr "PAGINA OP/NEER" @@ -10144,12 +9891,6 @@ msgstr "Pakketlijst vernieuwen" msgid "Packages" msgstr "Pakketten" -msgid "Packet management" -msgstr "Pakketbeheer" - -msgid "Packet manager" -msgstr "Pakketbeheer" - msgid "Page down" msgstr "Pagina naar beneden" @@ -10402,6 +10143,12 @@ msgstr "Speel vorige" msgid "Play recorded movies" msgstr "Speel opnames af" +msgid "Play service with streamrelay" +msgstr "Speel service met streamrelay" + +msgid "Play service without streamrelay" +msgstr "Speel service zonder streamrelay" + #, python-format msgid "Play the %d marked recordings" msgstr "Speel de %d geselecteerde opnames af" @@ -10437,6 +10184,9 @@ msgstr "Wijzig de eindtijd van de opname" msgid "Please choose an extension" msgstr "Kies een extensie" +msgid "Please choose an extension..." +msgstr "Kies een extensie..." + msgid "" "Please configure or verify your Nameservers by filling out the required values.\n" "When you are ready press OK to continue." @@ -10457,9 +10207,6 @@ msgstr "Verbind uw ontvanger met het internet" msgid "Please do not change any values unless you know what you are doing!" msgstr "Wijzig hier geen instellingen tenzij u precies weet wat u doet!" -msgid "Please enter a folder that contains some packages." -msgstr "Kies een folder die plugins bevat." - msgid "Please enter a name for the new bouquet" msgstr "Voer de naam voor uw nieuwe favorietenlijst in" @@ -10529,18 +10276,18 @@ msgstr "Selecteer een subkanaal voor opname..." msgid "Please select a subservice..." msgstr "Selecteer een subkanaal..." -msgid "Please select an acceptable directory." -msgstr "Kies een bruikbare map." +msgid "Please select a valid directory." +msgstr "Kies een geldige map." msgid "Please select device to use as SWAP file location." msgstr "Kies het medium voor het SWAP-bestand." +msgid "Please select folder that contains .ipk packages." +msgstr "Kies een folder die .ipk pakketen bevat." + msgid "Please select medium to be scanned" msgstr "Selecteer het te scannen medium" -msgid "Please select medium to use as backup location" -msgstr "Selecteer het te gebruiken medium als back-up lokatie" - msgid "Please select the default action of the EPG button" msgstr "Kies de standaard actie voor de EPG-toets" @@ -10696,6 +10443,9 @@ msgstr "Een ogenblikje geduld; uw netwerk wordt getest..." msgid "Please wait while your network configuration is activated..." msgstr "Een ogenblikje geduld; uw netwerk wordt opnieuw gestart..." +msgid "Please wait while your network configuration is deactivated..." +msgstr "Even tot uw netwerkconfiguratie uitgeschakeld is..." + #, python-format msgid "Please wait, initialising %s." msgstr "Even geduld, %s wordt geïnitialiseerd." @@ -10718,21 +10468,12 @@ msgstr "Pluginbrowser" msgid "Plugin browser settings" msgstr "Pluginbrowser instellingen" -msgid "Plugin details" -msgstr "Plugin details" - msgid "Plugin install" msgstr "Plugin installeren" msgid "Plugin listing failed - e. g. wrong backup destination or no space left on backup device." msgstr "Plugin-lijst mislukt - mogelijk a.g.v. een verkeerde back-up locatie of te weinig ruimte op het medium." -msgid "Plugin manager activity information" -msgstr "Pluginmanager activiteitinformatie" - -msgid "Plugin manager help" -msgstr "Pluginmanager helpfunctie" - msgid "Plugins" msgstr "Applicaties" @@ -10952,12 +10693,6 @@ msgstr "Druk op 'Menu' om een opslagruimte te kiezen" msgid "Press GREEN (Reboot) to switch images, YELLOW (Delete) to erase an image or BLUE (Restore) to restore all deleted images." msgstr "Druk op GROEN (Reboot) om van image te veranderen, op GEEL (Verwijder) om een image te verwijderen of op BLAUW (Herstel) om alle images te herstellen." -msgid "Press INFO on your remote control for additional information." -msgstr "Druk op INFO voor aanvullende informatie." - -msgid "Press MENU on your remote control for additional options." -msgstr "Druk op MENU voor extra opties." - msgid "Press OK" msgstr "Druk op OK" @@ -10968,9 +10703,6 @@ msgstr "Druk op de OK toets om door te gaan." msgid "Press OK to activate the selected%s skin." msgstr "Druk op OK om de geselecteerde%s skin te activeren." -msgid "Press OK to activate the settings." -msgstr "Druk op OK om instellingen te activeren." - msgid "Press OK to edit the settings." msgstr "Druk op OK om instellingen te wijzigen." @@ -11055,9 +10787,6 @@ msgstr "" "Probleem met verkrijgen updatelijst.\n" "Als dit probleem aanhoudt kunt u het forum raadplegen" -msgid "Process" -msgstr "Proces" - #, python-format msgid "Processor temp:\t%s" msgstr "Processortemp:\t%s" @@ -11534,9 +11263,6 @@ msgstr "Relevante PIDs routering" msgid "Religion" msgstr "Religie" -msgid "Reload" -msgstr "Herlaad" - msgid "Reload blacklists" msgstr "Herlaad zwarte lijst" @@ -11654,9 +11380,6 @@ msgstr "Verwijder voltooide timers na X dagen" msgid "Remove finished timers after (days)" msgstr "Verwijder voltooide timers na X dagen" -msgid "Remove finished." -msgstr "Verwijderen voltooid." - msgid "Remove from parental protection" msgstr "Verwijder van kinderslot" @@ -11850,9 +11573,6 @@ msgstr "Flash" msgid "Restore Confirmation" msgstr "Bevestig herstellen" -msgid "Restore backups" -msgstr "Back-ups terugzetten" - msgid "Restore confirmation" msgstr "Herstel bevestiging" @@ -11865,9 +11585,6 @@ msgstr "Herstel standaard waardes" msgid "Restore deleted user bouquets" msgstr "Herstel verwijderde favorietenlijsten" -msgid "Restore system settings" -msgstr "Instellingen terugzetten" - msgid "Restore wizard" msgstr "Herstel-wizard" @@ -11880,9 +11597,6 @@ msgstr "Bezig plugins te installeren; dit kan lang duren..." msgid "Restoring plugins..." msgstr "Plaatst plugins terug..." -msgid "Restoring..." -msgstr "Bezig met terugzetten..." - msgid "Restricted 18+" msgstr "18+" @@ -12154,9 +11868,6 @@ msgstr "Satelliet" msgid "Satellite dish settings" msgstr "Schotelinstellingen" -msgid "Satellite equipment" -msgstr "Satelliet apparatuur" - msgid "Satellite equipment setup" msgstr "Apparatuurinstellingen" @@ -12400,13 +12111,6 @@ msgstr "Zoekt" msgid "Searching east ..." msgstr "Zoekt oost..." -# -msgid "Searching for available updates. Please wait..." -msgstr "Zoekt naar beschikbare updates. Even wachten..." - -msgid "Searching for new installed or removed packages. Please wait..." -msgstr "Zoeken naar nieuw geïnstalleerde of verwijderde pakketten. Even wachten..." - msgid "Searching west ..." msgstr "Zoekt west..." @@ -12608,12 +12312,6 @@ msgstr "Kies een image om te flashen." msgid "Select audio track" msgstr "Kies audiospoor" -msgid "Select backup files" -msgstr "Kies back-up bestanden" - -msgid "Select backup location" -msgstr "Kies een back-up lokatie" - msgid "Select channel from history" msgstr "Kies het kanaal uit geschiedenis" @@ -12641,17 +12339,14 @@ msgstr "Selecteer bestemming voor:" msgid "Select extra packages folder" msgstr "Kies de folder met extra plugins" -msgid "Select files for backup." -msgstr "Selecteer bestanden voor back-up." - msgid "Select files/folders to backup" msgstr "Kies bestanden/mappen voor de back-up" msgid "Select first service in bouquet" msgstr "Selecteer eerste kanaal in boeket" -msgid "Select folder that contains plugins" -msgstr "Kies de folder met plugins" +msgid "Select folder containing plugins(.ipk) and Save" +msgstr "Kies de folder met plugins (.ipk) en sla op" msgid "Select horizontal resolution:" msgstr "Selecteer horizontale resolutie:" @@ -12815,12 +12510,6 @@ msgstr "Configureer type afstandsbediening" msgid "Select to restore all deleted images" msgstr "Kies alle verwijderde images te herstellen" -msgid "Select upgrade source" -msgstr "Kies de upgrade-bron" - -msgid "Select upgrade source to edit." -msgstr "Kies de te wijzigen upgrade-bron." - msgid "Select video input with up/down buttons" msgstr "Selecteer video-ingang met de omhoog/omlaag toetsen" @@ -13808,9 +13497,6 @@ msgstr "Skin:\t%s" msgid "SkinSelector: Restart GUI" msgstr "SkinSelector: Herstart GUI" -msgid "Skins" -msgstr "Skins" - msgid "Skip back" msgstr "Achteruit springen" @@ -13982,31 +13668,15 @@ msgstr "SoftcamScript schakelt cam-herstart in/uit" msgid "SoftcamScript select camscript" msgstr "SoftcamScript kies cam script" -msgid "Software" -msgstr "Software" - msgid "Software Update" msgstr "Software-update" -# -msgid "Software management" -msgstr "Softwarebeheer" - -msgid "Software manager setup" -msgstr "Softwarebeheer instellingen" - -msgid "Software restore" -msgstr "Software herstellen" - msgid "Software update" msgstr "Software-update" msgid "Software update settings" msgstr "Software-update instellingen" -msgid "Softwaremanager information" -msgstr "Sofwarebeheer informatie" - msgid "Solomon Islands" msgstr "Solomon Islands" @@ -14052,22 +13722,12 @@ msgstr "MiniDLNA configuratie ontbreekt" msgid "Sorry your uShare config is missing" msgstr "Configuratie van uShare ontbreekt" -#, python-format -msgid "Sorry, %s has not been installed!" -msgstr "Sorry, %s is niet geïnstalleerd!" - msgid "Sorry, but the file is not compatible with this image version." msgstr "Het bestand is niet verenigbaar met deze versie van de firmware." msgid "Sorry, but the restore failed." msgstr "Het terugplaatsen is mislukt." -msgid "Sorry, no backups found!" -msgstr "Sorry, geen back-up gevonden!" - -msgid "Sorry, no details available!" -msgstr "Sorry, geen details beschikbaar!" - msgid "Sorry, no physical devices that supports SWAP attached. Can't create SWAP file on network or fat32 file-systems." msgstr "Er is geen medium dat SWAP-bestanden ondersteunt. Een SWAP-bestand kan niet op een netwerk of een FAT32 systeem worden geplaatst." @@ -14077,13 +13737,6 @@ msgstr "Er is niet genoeg vrij RAM en er is geen medium dat SWAP-bestanden onder msgid "Sorry, this tuner is in use." msgstr "Deze tuner is niet beschikbaar." -msgid "" -"Sorry, your backup destination is not writeable.\n" -"Please select a different one." -msgstr "" -"Uw back-up bestemming kan niet beschreven worden.\n" -"Kies een andere." - msgid "Sort" msgstr "Sorteer" @@ -14409,6 +14062,12 @@ msgstr "Stream-klanten" msgid "Streaming Clients Info" msgstr "Stream-klanten info" +msgid "Streamrelay port" +msgstr "Streamrelay poort" + +msgid "Streamrelay url" +msgstr "Streamrelay url" + msgid "Strict DLNA" msgstr "Strict DLNA" @@ -14872,6 +14531,9 @@ msgstr "" "De IMDb-plugin is niet geïnstalleerd!\n" "Installeer die." +msgid "The IP address of the streamrelay server that is used to descramble services that can only be decrypted via streamrelay" +msgstr "Het IP-adres van de streamrelay server die wordt gebruikt om te services te descramblen waarbij dat alleen via een streamrelay kan." + msgid "" "The Linux kernel has changed, an update is not permitted. \n" "Install latest image using USB stick or Image Manager." @@ -14905,9 +14567,6 @@ msgstr "" msgid "The backup creates a snapshot of the image exactly as it is at the current instant." msgstr "De back-up maakt een exact snapshot van het image zoals het op dit moment is." -msgid "The backup failed. Please choose a different backup location." -msgstr "Back-up is mislukt. Kies een andere back-up lokatie." - msgid "The backup location does not have enough free space." msgstr "De back-up locatie heeft onvoldoende ruimte." @@ -14976,6 +14635,9 @@ msgstr "Het pad %s bestaat al." msgid "The pin code you entered is wrong." msgstr "De ingevoerde pincode is onjuist." +msgid "The port of the streamrelay server that is used to descramble services that can only be decrypted via streamrelay" +msgstr "De poort van de streamrelay server die wordt gebruikt om te services te descramblen waarbij dat alleen via een streamrelay kan." + #, python-format msgid "The results have been written to %s." msgstr "De resultaten zijn bewaard op %s." @@ -15016,9 +14678,6 @@ msgid "" "Please install it." msgstr "De WiFi-plugin is niet geïnstalleerd. Deze plugin eerst installeren." -msgid "The wizard can backup your current settings. Do you want to do a backup now?" -msgstr "De wizard kan uw huidige settings opslaan. Wilt u nu een back-up maken?" - msgid "The wizard is finished now, and will reboot." msgstr "De wizard is nu gereed; de stb zal herstarten." @@ -15028,25 +14687,12 @@ msgstr "De wizard is nu gereed." msgid "Theater" msgstr "Theater" -msgid "There are at least " -msgstr "Er zijn ten minste " - -#, python-format -msgid "There are at least %s updates available." -msgstr "Er zijn minstens %s updates beschikbaar." - -msgid "There are currently no outstanding actions." -msgstr "Er zijn geen uitstaande acties." - msgid "There are no saved playlists to delete!" msgstr "Er zijn geen playlists om te verwijderen!" msgid "There are no saved playlists to load!" msgstr "Er zijn geen playlists om te laden!" -msgid "There are no updates available." -msgstr "Er zijn momenteel geen updates beschikbaar." - msgid "There has been an error, please try again later. If this issue persists, please check openvix.co.uk or world-of-satellite.com" msgstr "Er is een fout opgetreden. Als het probleem aanhoudt, controleert u op openvix.co.uk of op world-of-satellite.com wat er aan de hand is" @@ -15293,18 +14939,6 @@ msgstr "Hiermee stelt u de onderdrukking in van valse digitale contouren, die he msgid "This option sets up the picture sharpness, used when the picture is being upscaled." msgstr "Hiermee stelt u de beeldscherpte in als het beeld moet worden opgeschaald." -msgid "This plugin is installed." -msgstr "Deze plugin is geïnstalleerd." - -msgid "This plugin is not installed." -msgstr "Deze plugin is niet geïnstalleerd." - -msgid "This plugin will be installed." -msgstr "Deze plugin wordt geïnstalleerd." - -msgid "This plugin will be removed." -msgstr "Deze plugin wordt verwijderd." - msgid "This setting allows the tuner configuration to be a duplication of how another tuner is already configured." msgstr "Deze instelling maakt het mogelijk de instelling van een andere tuner te kopieren." @@ -15687,9 +15321,6 @@ msgstr "Probeert gebruikte transponders op het kabelnetwerk te vinden. Even wach msgid "Try to find used transponders in terrestrial network... please wait..." msgstr "Probeert gebruikte transponders op het terrestrische netwerk te vinden. Even wachten..." -msgid "Trying to download a new packetlist. Please wait..." -msgstr "Probeert een nieuwe pakketlijst te downloaden. Even wachten..." - msgid "Tue" msgstr "Di" @@ -15860,13 +15491,6 @@ msgstr "Niet gedefinieerd" msgid "Undetermined" msgstr "Onbepaald" -msgid "Undo install" -msgstr "Installatie ongedaan maken" - -# -msgid "Undo uninstall" -msgstr "Ongedaan" - msgid "Unencrypted" msgstr "Niet-encrypted" @@ -15882,10 +15506,6 @@ msgstr "Unicable-vertraging na aanpassen voltage vóór de schakelopdracht" msgid "Unicable delay after last diseqc command" msgstr "Unicable-vertraging na laatste DiSEqC opdracht" -# -msgid "Uninstall" -msgstr "De-installeer" - msgid "United Arab Emirates" msgstr "United Arab Emirates" @@ -15971,25 +15591,15 @@ msgstr "Bezig met update pakketten..." msgid "Updated: %s" msgstr "Geüpdatet: %s" -# -msgid "Updatefeed not available." -msgstr "Updatefeed niet beschikbaar." - msgid "Updating Cache" msgstr "Bezig cache te updaten" -msgid "Updating cache" -msgstr "Bezig cache te updaten" - msgid "Updating cache, please wait..." msgstr "Bezig cache te updaten, even wachten..." msgid "Updating mount locations..." msgstr "Mount-locaties worden geüpdatet..." -msgid "Updating software catalog" -msgstr "Softwarecatalogus wordt geupdate" - msgid "Upgrade and reboot system" msgstr "Upgrade en herstart system" @@ -16178,9 +15788,6 @@ msgstr "Start de wizard voor basisinstellingen" msgid "Use these input device settings?" msgstr "Deze instellingen gebruiken?" -msgid "Use these settings?" -msgstr "Deze settings gebruiken?" - msgid "Use this video enhancement settings?" msgstr "Gebruik deze videoverbetering instellingen?" @@ -16418,52 +16025,9 @@ msgstr "Bekijk opname..." msgid "View Video CD..." msgstr "Bekijk video CD..." -msgid "View details" -msgstr "Bekijk details" - msgid "View extensions" msgstr "Toon extensies" -msgid "View list of available " -msgstr "Bekijk de lijst met beschikbare " - -msgid "View list of available CommonInterface extensions" -msgstr "Bekijk de lijst met beschikbare commonInterface extensies" - -msgid "View list of available EPG extensions." -msgstr "Bekijk de lijst met beschikbare EPG-extensies." - -# -msgid "View list of available Satellite equipment extensions." -msgstr "Bekijk de lijst met beschikbare satellietapparatuur extensies." - -msgid "View list of available communication extensions." -msgstr "Bekijk de lijst met beschikbare communicatie extensies." - -msgid "View list of available default settings" -msgstr "Bekijk de lijst met beschikbare standaardinstellingen" - -msgid "View list of available display and userinterface extensions." -msgstr "Bekijk de lijst met beschikbare scherm en gebruikersinterface extensies." - -msgid "View list of available multimedia extensions." -msgstr "Bekijk de lijst van beschikbare multimedia extensies." - -msgid "View list of available networking extensions" -msgstr "Bekijk de lijst met beschikbare netwerk extensies" - -msgid "View list of available recording extensions" -msgstr "Bekijk de lijst met beschikbare opname extensies" - -msgid "View list of available skins" -msgstr "Bekijk de lijst met beschikbare skins" - -msgid "View list of available software extensions" -msgstr "Bekijk de lijst met beschikbare software extensies" - -msgid "View list of available system extensions" -msgstr "Bekijk de lijst met beschikbare systeem extensies" - msgid "View mode" msgstr "Bekijkmodus" @@ -16733,9 +16297,6 @@ msgstr "" "\n" "Ga naar het einde, druk op OK, selecteer 'end cut'. Eenvoudiger kan niet." -msgid "Welcome to the image upgrade wizard. The wizard will assist you in upgrading the firmware of your %s %s by providing a backup facility for your current settings and a short explanation of how to upgrade your firmware." -msgstr "Welkom bij de software-updatewizard. De wizard biedt u hulp bij het vernieuwen van de software in uw %s %s door het maken van een back-up van uw huidige instellingen en geeft u een korte uitleg over dit proces." - msgid "" "Welcome to the restore wizard.\n" "\n" @@ -16989,9 +16550,6 @@ msgstr "Als de ontvanger uit stand-by komt, zal ook de TV aangezet worden." msgid "When tuned to a service the system will normally scan the transponder for any changes and save them. Only set to 'yes' if you're absolutely sure of what you're doing." msgstr "Als uw ontvanger op een kanaal is afgestemd, wordt normaal gesproken de transponder gescand op veranderingen. Schakel dit alleen uit, als u zeker bent van wat u doet." -msgid "Where do you want to backup your settings?" -msgstr "Waar wilt u de instellingen opslaan?" - msgid "Where should the recording be saved?" msgstr "Waar moet de opname opgeslagen worden?" @@ -17142,18 +16700,12 @@ msgstr "Ja (sla index op in tuner instellingen)" msgid "Yes to all" msgstr "Ja op alles" -msgid "Yes, always" -msgstr "Ja, altijd" - msgid "Yes, and delete this movie" msgstr "Ja en verwijder dit bestand" msgid "Yes, and return to the movie list" msgstr "Ja, en keer terug naar de opnamelijst" -msgid "Yes, backup my settings!" -msgstr "Ja, mijn instellingen opslaan!" - msgid "Yes, but don't save timeshift as movie" msgstr "Ja, maar sla timeshift niet op als opname" @@ -17175,18 +16727,12 @@ msgstr "Ja, voer nu de automatische zoekfunctie uit" msgid "Yes, do another manual scan now" msgstr "Ja, ik wil nogmaals handmatig zoeken" -msgid "Yes, restore the settings now" -msgstr "Ja, de gegevens nu terugplaatsen" - msgid "Yes, show delete time" msgstr "Ja, toon verwijdertijd" msgid "Yes, show record time" msgstr "Ja, toon opnametijd" -msgid "Yes, shut down now." -msgstr "Ja, ik wil nu afsluiten." - msgid "Yesterday" msgstr "Gisteren" @@ -17214,29 +16760,17 @@ msgstr "U kunt MiniTV met en zonder OSD-menu tonen" msgid "You can Display PIP with or without OSD Menu" msgstr "U kubt PIP met en zonder OSD-menu tonen" -msgid "You can cancel the installation." -msgstr "Installatie kan worden geannuleerd." - -msgid "You can cancel the removal." -msgstr "Verwijderen kan worden geannuleerd." - msgid "You can continue watching TV while this is running." msgstr "U kunt doorgaan met TV kijken terwijl dit loopt." msgid "You can have the list sorted by time or alphanumerical." msgstr "U kunt de lijst op tijd of alfanumeriek sorteren." -msgid "You can install this plugin." -msgstr "Deze plugin kunt u installeren." - # #, python-format msgid "You can only burn %s %s recordings!" msgstr "U kunt alleen %s %s opnames schrijven!" -msgid "You can remove this plugin." -msgstr "Deze plugin kunt u verwijderen." - msgid "You cannot delete this!" msgstr "U kunt dit niet verwijderen!" @@ -17248,12 +16782,6 @@ msgid_plural "You have marked recordings" msgstr[0] "U heeft een gemarkeerde opname" msgstr[1] "U heeft gemarkeerde opnames" -msgid "You have chosen to backup your settings. Please press OK to start the backup now." -msgstr "U heeft gekozen een back-up van uw instellingen te maken. Druk op OK om te beginnen." - -msgid "You have chosen to restore your settings. Enigma2 will restart after restore. Please press OK to start the restore now." -msgstr "U heeft gekozen om uw instellingen te herstellen. Enigma2 zal herstarten na het herstel. Druk op OK om te beginnen met het herstel." - msgid "" "You have chosen to save the current timeshift event, but the event has not yet finished\n" "What do you want to do ?" @@ -17275,13 +16803,6 @@ msgstr "Wacht op %s!" msgid "You must switch to the service %s (%s - '%s')!\n" msgstr "U moet naar kanaal %s (%s - '%s') zappen!\n" -msgid "" -"You need a PC connected to your %s %s. If you need further instructions, please visit the website http://www.dm7025.de.\n" -"Your %s %s will now be halted. After you have performed the update instructions from the website, your new firmware will ask you to restore your settings." -msgstr "" -"U moet uw PC met uw %s %s verbinden. Voor meer informatie verwijzen wij u naar de website http://www.dm7025.de.\n" -"De %s %s word nu uitgeschakeld. Indien u deze aanwijzingen nauwgezet volgt, zal de %s %s u na de update vragen of u uw instellingen terug wilt plaatsen." - msgid "You seem to be in timeshft, the service will briefly stop as timeshift stops." msgstr "U bent in timeshift modus; het kanaal wordt even onderbroken als u timeshift stopt." @@ -17378,9 +16899,6 @@ msgstr "Uw %s %s wordt opnieuw gestart in herstelmodus" msgid "Your %s %s is shutting down" msgstr "Uw %s %s is aan het afsluiten" -msgid "Your %s %s is shutting down. Please wait..." -msgstr "Uw %s %s wordt nu afgesloten. Even wachten..." - #, python-format msgid "Your %s %s might be unusable now. Please consult the manual for further assistance before rebooting your %s %s." msgstr "Uw %s %s kan nu onbruikbaar zijn geworden. Raadpleeg voordat u uw %s %s herstart de handleiding." @@ -17422,9 +16940,6 @@ msgstr "" msgid "Your STB will restart after pressing OK on your remote control." msgstr "Als u op OK drukt zal uw ontvanger opnieuw opstarten." -msgid "Your backup succeeded. We will now continue to explain the further upgrade process." -msgstr "De back-up is geslaagd. U krijgt nu een korte uitleg over het vervolg van het updateproces." - msgid "Your collection exceeds the size of a single layer medium, you will need a blank dual layer DVD!" msgstr "Uw verzameling is groter dan wat erop een enkellaags medium past, u heeft een lege dubbellaags DVD nodig!" @@ -17480,6 +16995,9 @@ msgstr "" msgid "Your network configuration has been activated." msgstr "Configuratie van uw netwerk is geactiveerd." +msgid "Your network configuration has been disabled." +msgstr "Configuratie van uw netwerk is uitgeschakeld." + msgid "Your network has finished restarting" msgstr "Uw netwerk is opnieuw gestart" @@ -17985,9 +17503,6 @@ msgstr "ontspanning (6-14 jaar)" msgid "entertainment (general)" msgstr "ontspanning (algemeenr)" -msgid "epg cache backup" -msgstr "epg cache back-up" - msgid "equestrian" msgstr "ruitersport" @@ -18024,9 +17539,6 @@ msgstr "DVD-speler afsluiten of terug naar bestandslijst" msgid "experimental film/video" msgstr "experimentele film/video" -msgid "extensions." -msgstr "extensies." - msgid "extra wide" msgstr "extra breed" @@ -18096,9 +17608,6 @@ msgstr "vrij" msgid "free diskspace" msgstr "vrije ruimte" -msgid "from" -msgstr "van" - msgid "full" msgstr "vol" @@ -18465,9 +17974,6 @@ msgstr "origineel" msgid "original language" msgstr "originele taal" -msgid "packages selected." -msgstr "pakketten geselecteerd." - msgid "page left" msgstr "pagina links" @@ -18672,12 +18178,6 @@ msgstr "EPG details weergeven" msgid "show mediaplayer on mainmenu" msgstr "toon mediaplayer in hoofdmenu" -msgid "show softwaremanager in plugin menu" -msgstr "toon softwaremanager in pluginbrowser" - -msgid "show softwaremanager on blue button" -msgstr "toon softwaremanager onder blauwe knop" - msgid "show/game show (general)" msgstr "show/spelshow (algemeen)" @@ -18873,9 +18373,6 @@ msgstr "niet gepubliceerd" msgid "until standby/restart" msgstr "tot stand-by/herstart" -msgid "updates available." -msgstr "updates beschikbaar." - msgid "use best / controlled by HDMI" msgstr "use best / controlled by HDMI" @@ -19000,6 +18497,104 @@ msgstr "zapte" msgid "| separated list of prefixes you'd like to be removed from event names, separated with |, e.g. New:|Live:" msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, gescheiden door |, e.g. New:|Live:" +#~ msgid "" +#~ "\n" +#~ "Advanced options and settings." +#~ msgstr "" +#~ "\n" +#~ "Geavanceerde opties en instellingen." + +#~ msgid "" +#~ "\n" +#~ "After pressing OK, please wait!" +#~ msgstr "" +#~ "\n" +#~ "Druk op OK en een ogenblik geduld!" + +#, python-format +#~ msgid "" +#~ "\n" +#~ "Backup your %s %s settings." +#~ msgstr "" +#~ "\n" +#~ "Maak een back-up van de instellingen van uw %s %s." + +#~ msgid "" +#~ "\n" +#~ "Edit the upgrade source address." +#~ msgstr "" +#~ "\n" +#~ "Wijzig het bronadres voor upgrades ." + +#, python-format +#~ msgid "" +#~ "\n" +#~ "Manage extensions or plugins for your %s %s" +#~ msgstr "" +#~ "\n" +#~ "Beheer extensies en plugins voor uw %s %s" + +#, python-format +#~ msgid "" +#~ "\n" +#~ "Online update of your %s %s software." +#~ msgstr "" +#~ "\n" +#~ "Online bijwerken van uw %s %s software." + +#~ msgid "" +#~ "\n" +#~ "Press OK on your remote control to continue." +#~ msgstr "" +#~ "\n" +#~ "Druk op OK om door te gaan." + +#, python-format +#~ msgid "" +#~ "\n" +#~ "Restore your %s %s settings." +#~ msgstr "" +#~ "\n" +#~ "De instellingen van uw %s %s terugplaatsen." + +#, python-format +#~ msgid "" +#~ "\n" +#~ "Restore your %s %s with a new firmware." +#~ msgstr "" +#~ "\n" +#~ "Plaats nieuwe firmware in uw %s %s." + +#~ msgid "" +#~ "\n" +#~ "Restore your backups by date." +#~ msgstr "" +#~ "\n" +#~ "Zet de back-up van een bepaalde datum terug." + +#~ msgid "" +#~ "\n" +#~ "Scan for local extensions and install them." +#~ msgstr "" +#~ "\n" +#~ "Zoek naar lokale extensies en installeer die." + +#~ msgid "" +#~ "\n" +#~ "Select your backup device.\n" +#~ "Current device: " +#~ msgstr "" +#~ "\n" +#~ "Kies een back-up medium.\n" +#~ "Huidig medium: " + +#~ msgid "" +#~ "\n" +#~ "View, install and remove available or installed packages." +#~ msgstr "" +#~ "\n" +#~ "Bekijk, installeer en verwijder beschikbare of geïnstalleerde pakketten." + #, python-format #~ msgid "%.0f GB" #~ msgstr "%.0f GB" @@ -19028,6 +18623,10 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "%d.%03d GB" #~ msgstr "%d.%03d GB" +#, python-format +#~ msgid "%s %s software because updates are available." +#~ msgstr "%s %s software want er zijn updates beschikbaar." + #, python-format #~ msgid "%s GB" #~ msgstr "%s GB" @@ -19062,6 +18661,12 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "50 MB/s" #~ msgstr "50 MB/s" +#~ msgid "A search for available updates is currently in progress." +#~ msgstr "Bezig met zoeken naar updates." + +#~ msgid "A small overview of the available icon states and actions." +#~ msgstr "Een klein overzicht van gebruikte icoon-statussen en acties." + #~ msgid "AboutBoxInfo" #~ msgstr "About BoxInfo" @@ -19074,25 +18679,81 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Activate network adapter configuration" #~ msgstr "Start de netwerkadapter configuratie" +#~ msgid "Advanced restore" +#~ msgstr "Geavanceerd herstellen" + +#~ msgid "Advanced software" +#~ msgstr "Geavanceerde software" + +#~ msgid "Advanced software plugin" +#~ msgstr "Geavanceerde software plugin" + #~ msgid "Allow unstable (experimental) feeds" #~ msgstr "Accepteer onstabiele (experimentele) feeds" #~ msgid "Allows you to tag your image backup to a box. (default is box name/type)" #~ msgstr "U kunt de naam van de image back-ups aanpassen (standaard is stb name/type)." +#~ msgid "Always ask" +#~ msgstr "Altijd vragen" + +#~ msgid "An error occurred while downloading the packetlist. Please try again." +#~ msgstr "Er is een fout opgetreden bij het downloaden van de pakketlijst. Probeer het nogmaals." + #~ msgid "Android Mode" #~ msgstr "Android mode" +#~ msgid "" +#~ "Are you sure you want to delete\n" +#~ "the following backup:\n" +#~ msgstr "" +#~ "Weet u zeker dat u de volgende\n" +#~ "back-up wilt verwijderen:\n" + #, python-format #~ msgid "Are you sure you want to delete image slot %s ?" #~ msgstr "Weet u zeker dat u het image in slot %s wilt verwijderen?" +#, python-format +#~ msgid "" +#~ "Are you sure you want to restore\n" +#~ "the following backup:\n" +#~ "%s\n" +#~ "Your receiver will restart after the backup has been restored!" +#~ msgstr "" +#~ "Weet u zeker dat u de volgende\n" +#~ "back-up wilt flashen:\n" +#~ "%s\n" +#~ "Uw ontvanger zal herstarten nadat de back-up is teruggeplaatst!" + +#~ msgid "" +#~ "Are you sure you want to restore the backup?\n" +#~ "Your receiver will restart after the backup has been restored!" +#~ msgstr "" +#~ "Weet u zeker dat u de back-up wilt flashen?\n" +#~ "Uw ontvanger zal herstarten als het proces gereed is!" + +#~ msgid "Author: " +#~ msgstr "Auteur: " + #~ msgid "Background delete option" #~ msgstr "Verwijder op de achtergrond" #~ msgid "Background delete speed" #~ msgstr "Snelheid verwijderen op de achtergrond" +#~ msgid "Backup completed." +#~ msgstr "Back-up gereed." + +#~ msgid "Backup failed." +#~ msgstr "Back-up is mislukt." + +#~ msgid "Backup is running..." +#~ msgstr "Back-up wordt uitgevoerd..." + +#~ msgid "Backup system settings" +#~ msgstr "Back-up uw instellingen" + #, python-format #~ msgid "Build: %s" #~ msgstr "Build: %s" @@ -19122,12 +18783,21 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Collection" #~ msgstr "Collectie" +#~ msgid "Communication" +#~ msgstr "Communicatie" + #~ msgid "Configure on which devices the background delete option should be used." #~ msgstr "Geef aan op welk apparaat op de achtergrond bestanden mogen worden verwijderd." #~ msgid "Configure the speed of the background deletion process. Lower speed will consume less hard disk drive performance." #~ msgstr "Bepaal de snelheid waarmee bestanden op de achtergrond worden verwijderd. Een lage snelheid vergt minder prestaties van de schijf." +#~ msgid "Connected" +#~ msgstr "Verbonden" + +#~ msgid "Continue" +#~ msgstr "Doorgaan" + #~ msgid "Current CEC address" #~ msgstr "Huidig CEC adres" @@ -19135,9 +18805,18 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "D" #~ msgstr "3D" +#~ msgid "Default settings" +#~ msgstr "Standaard instellingen" + +#~ msgid "Details for plugin: " +#~ msgstr "Details voor plugin: " + #~ msgid "Device: none available" #~ msgstr "Apparaat: geen beschikbaar" +#~ msgid "Display and user interface" +#~ msgstr "Scherm- en gebruikersinterface" + #~ msgid "" #~ "Do you want to flash Recovery image?\n" #~ "This will change all eMMC slots." @@ -19145,6 +18824,18 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ "Wilt u het Recovery Image flashen?\n" #~ "Dit zal alle eMMC slots veranderen." +#~ msgid "Do you want to install the package:\n" +#~ msgstr "Wilt u het volgende pakket installeren:\n" + +#~ msgid "Do you want to reboot your receiver?" +#~ msgstr "Wilt u uw ontvanger opnieuw opstarten?" + +#~ msgid "Do you want to remove the package:\n" +#~ msgstr "Wilt u het volgende pakket verwijderen:\n" + +#~ msgid "Do you want to upgrade the package:\n" +#~ msgstr "Wilt u een upgrade van het volgende pakket:\n" + #~ msgid "DownLoad" #~ msgstr "DownLoad" @@ -19154,6 +18845,12 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "ERROR" #~ msgstr "FOUT" +#~ msgid "Edit upgrade source url." +#~ msgstr "Upgrade url bewerken." + +#~ msgid "Electronic Program Guide" +#~ msgstr "Elektronische programmagids" + #~ msgid "Enable Vu+ MultiBoot" #~ msgstr "Vu+ MultiBoot inschakelen" @@ -19179,6 +18876,17 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Exit network adapter configuration" #~ msgstr "Verlaat netwerkadapterconfiguratie" +# +#~ msgid "Extended Software" +#~ msgstr "Uitgebreide software" + +# +#~ msgid "Extended Software Plugin" +#~ msgstr "Uitgebreide software plugin" + +#~ msgid "Extensions management" +#~ msgstr "Applicatiebeheer" + #, fuzzy #~ msgid "F" #~ msgstr "F1" @@ -19191,6 +18899,9 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Flash directory '%s' not allowed!" #~ msgstr "Flash-map'%s' is niet toegestaan!" +#~ msgid "Following tasks will be done after you press OK!" +#~ msgstr "Nadat u op OK drukt worden de volgende taken uitgevoerd!" + #, fuzzy #~ msgid "G" #~ msgstr "GB" @@ -19246,6 +18957,21 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Init Vu+ MultiBoot" #~ msgstr "Init Vu+ MultiBoot" +#~ msgid "Install a new image with a USB stick" +#~ msgstr "Installeer een nieuwe image met een USB-stick" + +#~ msgid "Install a new image with your web browser" +#~ msgstr "Installeer een nieuwe image met uw browser" + +#~ msgid "Install extensions" +#~ msgstr "Installeer extensies" + +#~ msgid "Install or remove finished." +#~ msgstr "Installeren of verwijderen voltooid." + +#~ msgid "Installation finished." +#~ msgstr "Installatie mislukt." + #~ msgid "Instant recording..." #~ msgstr "Directe opname..." @@ -19256,33 +18982,91 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Last update: %s" #~ msgstr "Laatste update: %s" +#~ msgid "Manage extensions" +#~ msgstr "Beheer van extensies" + +#, python-format +#~ msgid "Manage your %s %s's software" +#~ msgstr "Beheer de software van uw %s %s" + #~ msgid "Max backups to keep (0==all)" #~ msgstr "Max aantal back-ups te bewaren (0==alle)" #~ msgid "Multiboot image manager" #~ msgstr "Multiboot image manager" +#~ msgid "Multimedia" +#~ msgstr "Multimedia" + #~ msgid "Namespace" #~ msgstr "Namespace" +#~ msgid "No backup needed" +#~ msgstr "Geen back-up nodig" + #~ msgid "No data received yet" #~ msgstr "Nog geen data ontvangen" +#~ msgid "No description available." +#~ msgstr "Geen beschrijving beschikbaar." + +#~ msgid "No network connection available." +#~ msgstr "Geen netwerkverbinding beschikbaar." + +#~ msgid "No, do nothing." +#~ msgstr "Nee, geen actie." + +#~ msgid "No, just start my %s %s" +#~ msgstr "Nee, uitsluitend %s %s starten" + +#~ msgid "No, never" +#~ msgstr "Nee, nooit" + #~ msgid "Note: slot list does not show current image or empty slots." #~ msgstr "Opm.: De slot-lijst toont het huidige image en lege slots niet." +#~ msgid "OK, guide me through the upgrade process" +#~ msgstr "OK, mij tijdens de software update begeleiden" + +#~ msgid "Only extensions." +#~ msgstr "Alleen extensies." + #~ msgid "Open infobar EPG..." #~ msgstr "Open Informatiebalk EPG..." #~ msgid "OpenTV download setup" #~ msgstr "OpenTV download instellingen" +#~ msgid "Overwrite configuration files during software upgrade?" +#~ msgstr "Overschrijven configuratiebestanden tijdens de upgrade?" + +#~ msgid "Overwrite configuration files?" +#~ msgstr "Configuratiebestanden overschrijven?" + #~ msgid "PID" #~ msgstr "PID" +#~ msgid "Packet management" +#~ msgstr "Pakketbeheer" + +#~ msgid "Packet manager" +#~ msgstr "Pakketbeheer" + #~ msgid "Perform a settings backup, making a backup before updating is strongly advised." #~ msgstr "Maak een settingsback-up; het maken van een back-up alvorens te updaten wordt sterk geadviseerd." +#~ msgid "Please select medium to use as backup location" +#~ msgstr "Selecteer het te gebruiken medium als back-up lokatie" + +#~ msgid "Plugin details" +#~ msgstr "Plugin details" + +#~ msgid "Plugin manager activity information" +#~ msgstr "Pluginmanager activiteitinformatie" + +#~ msgid "Plugin manager help" +#~ msgstr "Pluginmanager helpfunctie" + #~ msgid "Polarisation:" #~ msgstr "Polarisatie:" @@ -19299,15 +19083,30 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ "tenzij u eMMC-slots wilt herstellen .\n" #~ "Herstellen van eMMC slots kan 1 -> 5 minutes per slot duren." +#~ msgid "Press INFO on your remote control for additional information." +#~ msgstr "Druk op INFO voor aanvullende informatie." + +#~ msgid "Press MENU on your remote control for additional options." +#~ msgstr "Druk op MENU voor extra opties." + +#~ msgid "Press OK to activate the settings." +#~ msgstr "Druk op OK om instellingen te activeren." + #~ msgid "Press OK to set the MAC address." #~ msgstr "Druk op OK om MAC-adres in te stellen." +#~ msgid "Process" +#~ msgstr "Proces" + #~ msgid "Query before backup starts" #~ msgstr "Vraag alvorens back-up te starten" #~ msgid "Query before image backup starts" #~ msgstr "Vraag alvorens image back-up te starten" +#~ msgid "Reload" +#~ msgstr "Herlaad" + #, python-format #~ msgid "Removal of this slot will not show in %s Gui. Are you sure you want to delete image slot %s ?" #~ msgstr "Het verwijderen van dit slot zal niet zichtbaar zijn in de GUI van de %s. Weet u zeker dat u het image in slot %s wilt verwijderen?" @@ -19315,24 +19114,61 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Remove confirmation" #~ msgstr "Verwijder bevestiging" +#~ msgid "Remove finished." +#~ msgstr "Verwijderen voltooid." + +#~ msgid "Restore backups" +#~ msgstr "Back-ups terugzetten" + +#~ msgid "Restore system settings" +#~ msgstr "Instellingen terugzetten" + +#~ msgid "Restoring..." +#~ msgstr "Bezig met terugzetten..." + #~ msgid "SWAP place:" #~ msgstr "SWAP lokatie:" +#~ msgid "Satellite equipment" +#~ msgstr "Satelliet apparatuur" + #~ msgid "Scroll menu" #~ msgstr "Menu scrollen" +# +#~ msgid "Searching for available updates. Please wait..." +#~ msgstr "Zoekt naar beschikbare updates. Even wachten..." + +#~ msgid "Searching for new installed or removed packages. Please wait..." +#~ msgstr "Zoeken naar nieuw geïnstalleerde of verwijderde pakketten. Even wachten..." + #~ msgid "Select 'no' to flash a MultiBoot slot." #~ msgstr "Kies 'Nee' om een MultiBoot slot te flashen." #~ msgid "Select an image to flash:" #~ msgstr "Kies een image om te flashen:" +#~ msgid "Select backup files" +#~ msgstr "Kies back-up bestanden" + +#~ msgid "Select backup location" +#~ msgstr "Kies een back-up lokatie" + #~ msgid "Select between entering an IP address or a domain." #~ msgstr "Kies tussen ingave van IP-adres of domein." #~ msgid "Select directory for logfile" #~ msgstr "Kies map voor logbestand" +#~ msgid "Select files for backup." +#~ msgstr "Selecteer bestanden voor back-up." + +#~ msgid "Select upgrade source" +#~ msgstr "Kies de upgrade-bron" + +#~ msgid "Select upgrade source to edit." +#~ msgstr "Kies de te wijzigen upgrade-bron." + #~ msgid "Serv.Name" #~ msgstr "Serv.Naam" @@ -19355,6 +19191,42 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Skin Setup" #~ msgstr "Skin instellingen" +#~ msgid "Skins" +#~ msgstr "Skins" + +#~ msgid "Software" +#~ msgstr "Software" + +# +#~ msgid "Software management" +#~ msgstr "Softwarebeheer" + +#~ msgid "Software manager setup" +#~ msgstr "Softwarebeheer instellingen" + +#~ msgid "Software restore" +#~ msgstr "Software herstellen" + +#~ msgid "Softwaremanager information" +#~ msgstr "Sofwarebeheer informatie" + +#, python-format +#~ msgid "Sorry, %s has not been installed!" +#~ msgstr "Sorry, %s is niet geïnstalleerd!" + +#~ msgid "Sorry, no backups found!" +#~ msgstr "Sorry, geen back-up gevonden!" + +#~ msgid "Sorry, no details available!" +#~ msgstr "Sorry, geen details beschikbaar!" + +#~ msgid "" +#~ "Sorry, your backup destination is not writeable.\n" +#~ "Please select a different one." +#~ msgstr "" +#~ "Uw back-up bestemming kan niet beschreven worden.\n" +#~ "Kies een andere." + #~ msgid "Subtitle selection..." #~ msgstr "Ondertitel-selectie..." @@ -19374,6 +19246,9 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "TB" #~ msgstr "TB" +#~ msgid "The backup failed. Please choose a different backup location." +#~ msgstr "Back-up is mislukt. Kies een andere back-up lokatie." + #~ msgid "" #~ "The software management extension is not installed!\n" #~ "Please install it." @@ -19387,12 +19262,40 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "The timer file (timers.xml) is corrupt and could not be loaded." #~ msgstr "Het timer-bestand (timer.xml) is beschadigd en kan niet worden geladen." +#~ msgid "The wizard can backup your current settings. Do you want to do a backup now?" +#~ msgstr "De wizard kan uw huidige settings opslaan. Wilt u nu een back-up maken?" + +#~ msgid "There are at least " +#~ msgstr "Er zijn ten minste " + +#, python-format +#~ msgid "There are at least %s updates available." +#~ msgstr "Er zijn minstens %s updates beschikbaar." + +#~ msgid "There are currently no outstanding actions." +#~ msgstr "Er zijn geen uitstaande acties." + #~ msgid "There are no items currently available for this screen." #~ msgstr "Er zijn momenteel geen onderdelen beschikbaar voor dit scherm." +#~ msgid "There are no updates available." +#~ msgstr "Er zijn momenteel geen updates beschikbaar." + #~ msgid "This option allows you to disable sorting of the menus" #~ msgstr "Hier kunt u het sorteren van menu's inschakelen" +#~ msgid "This plugin is installed." +#~ msgstr "Deze plugin is geïnstalleerd." + +#~ msgid "This plugin is not installed." +#~ msgstr "Deze plugin is niet geïnstalleerd." + +#~ msgid "This plugin will be installed." +#~ msgstr "Deze plugin wordt geïnstalleerd." + +#~ msgid "This plugin will be removed." +#~ msgstr "Deze plugin wordt verwijderd." + #~ msgid "Time of backup to start" #~ msgstr "Tijd waarop back-up moet starten" @@ -19402,6 +19305,9 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Transponder Information" #~ msgstr "Transponderinformatie" +#~ msgid "Trying to download a new packetlist. Please wait..." +#~ msgstr "Probeert een nieuwe pakketlijst te downloaden. Even wachten..." + # #~ msgid "Tuning Info: Live Values" #~ msgstr "Tunerinfo: terugmeldingen" @@ -19419,12 +19325,36 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ "\n" #~ "Weet u zeker dat u door wil gaan?" +#~ msgid "Undo install" +#~ msgstr "Installatie ongedaan maken" + +# +#~ msgid "Undo uninstall" +#~ msgstr "Ongedaan" + +# +#~ msgid "Uninstall" +#~ msgstr "De-installeer" + #~ msgid "Update Interval" #~ msgstr "Updateinterval" +# +#~ msgid "Updatefeed not available." +#~ msgstr "Updatefeed niet beschikbaar." + +#~ msgid "Updating cache" +#~ msgstr "Bezig cache te updaten" + +#~ msgid "Updating software catalog" +#~ msgstr "Softwarecatalogus wordt geupdate" + #~ msgid "Use the cursor keys to select an installed image and then Erase button." #~ msgstr "Gebruik de pijlthestoetsen om een geinstalleerd image te kiezen en vervolgens de 'wis-toets'." +#~ msgid "Use these settings?" +#~ msgstr "Deze settings gebruiken?" + #~ msgid "Using fixed address" #~ msgstr "Gebruik een vast adres" @@ -19432,6 +19362,49 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "ViX version: %s" #~ msgstr "ViX versie: %s" +#~ msgid "View details" +#~ msgstr "Bekijk details" + +#~ msgid "View list of available " +#~ msgstr "Bekijk de lijst met beschikbare " + +#~ msgid "View list of available CommonInterface extensions" +#~ msgstr "Bekijk de lijst met beschikbare commonInterface extensies" + +#~ msgid "View list of available EPG extensions." +#~ msgstr "Bekijk de lijst met beschikbare EPG-extensies." + +# +#~ msgid "View list of available Satellite equipment extensions." +#~ msgstr "Bekijk de lijst met beschikbare satellietapparatuur extensies." + +#~ msgid "View list of available communication extensions." +#~ msgstr "Bekijk de lijst met beschikbare communicatie extensies." + +#~ msgid "View list of available default settings" +#~ msgstr "Bekijk de lijst met beschikbare standaardinstellingen" + +#~ msgid "View list of available display and userinterface extensions." +#~ msgstr "Bekijk de lijst met beschikbare scherm en gebruikersinterface extensies." + +#~ msgid "View list of available multimedia extensions." +#~ msgstr "Bekijk de lijst van beschikbare multimedia extensies." + +#~ msgid "View list of available networking extensions" +#~ msgstr "Bekijk de lijst met beschikbare netwerk extensies" + +#~ msgid "View list of available recording extensions" +#~ msgstr "Bekijk de lijst met beschikbare opname extensies" + +#~ msgid "View list of available skins" +#~ msgstr "Bekijk de lijst met beschikbare skins" + +#~ msgid "View list of available software extensions" +#~ msgstr "Bekijk de lijst met beschikbare software extensies" + +#~ msgid "View list of available system extensions" +#~ msgstr "Bekijk de lijst met beschikbare systeem extensies" + #~ msgid "Visual impaired commentary" #~ msgstr "Audiodescriptie voor slechtzienden" @@ -19452,12 +19425,61 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Vu+ MultiBoot Manager" #~ msgstr "Vu+ MultiBoot Manager" +#~ msgid "Welcome to the image upgrade wizard. The wizard will assist you in upgrading the firmware of your %s %s by providing a backup facility for your current settings and a short explanation of how to upgrade your firmware." +#~ msgstr "Welkom bij de software-updatewizard. De wizard biedt u hulp bij het vernieuwen van de software in uw %s %s door het maken van een back-up van uw huidige instellingen en geeft u een korte uitleg over dit proces." + #~ msgid "When enabled the feeds and software updates may contain unstable experimental versions. Enable this at your own risk." #~ msgstr "Indien geactiveerd kunnen feeds en software updates die onstabiele, experimentele versies bevatten, gebruikt worden. Inschakelen geschiedt op uw eigen risico." +#~ msgid "Where do you want to backup your settings?" +#~ msgstr "Waar wilt u de instellingen opslaan?" + +#~ msgid "Yes, always" +#~ msgstr "Ja, altijd" + +#~ msgid "Yes, backup my settings!" +#~ msgstr "Ja, mijn instellingen opslaan!" + +#~ msgid "Yes, restore the settings now" +#~ msgstr "Ja, de gegevens nu terugplaatsen" + +#~ msgid "Yes, shut down now." +#~ msgstr "Ja, ik wil nu afsluiten." + +#~ msgid "You can cancel the installation." +#~ msgstr "Installatie kan worden geannuleerd." + +#~ msgid "You can cancel the removal." +#~ msgstr "Verwijderen kan worden geannuleerd." + +#~ msgid "You can install this plugin." +#~ msgstr "Deze plugin kunt u installeren." + +#~ msgid "You can remove this plugin." +#~ msgstr "Deze plugin kunt u verwijderen." + +#~ msgid "You have chosen to backup your settings. Please press OK to start the backup now." +#~ msgstr "U heeft gekozen een back-up van uw instellingen te maken. Druk op OK om te beginnen." + +#~ msgid "You have chosen to restore your settings. Enigma2 will restart after restore. Please press OK to start the restore now." +#~ msgstr "U heeft gekozen om uw instellingen te herstellen. Enigma2 zal herstarten na het herstel. Druk op OK om te beginnen met het herstel." + #~ msgid "You have decided not to flash image." #~ msgstr "U heeft besloten geen image te flashen." +#~ msgid "" +#~ "You need a PC connected to your %s %s. If you need further instructions, please visit the website http://www.dm7025.de.\n" +#~ "Your %s %s will now be halted. After you have performed the update instructions from the website, your new firmware will ask you to restore your settings." +#~ msgstr "" +#~ "U moet uw PC met uw %s %s verbinden. Voor meer informatie verwijzen wij u naar de website http://www.dm7025.de.\n" +#~ "De %s %s word nu uitgeschakeld. Indien u deze aanwijzingen nauwgezet volgt, zal de %s %s u na de update vragen of u uw instellingen terug wilt plaatsen." + +#~ msgid "Your %s %s is shutting down. Please wait..." +#~ msgstr "Uw %s %s wordt nu afgesloten. Even wachten..." + +#~ msgid "Your backup succeeded. We will now continue to explain the further upgrade process." +#~ msgstr "De back-up is geslaagd. U krijgt nu een korte uitleg over het vervolg van het updateproces." + #~ msgid "[VuplusKexec][create Vu Multiboot environment] - Unable to complete, Vu+ Multiboot files missing" #~ msgstr "[VuplusKexec][creëer Vu Multiboot omgeving] - Kan niet vervolgen, Vu+ Multiboot bestanden ontbreken" @@ -19470,9 +19492,18 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "by date" #~ msgstr "op datum" +#~ msgid "epg cache backup" +#~ msgstr "epg cache back-up" + +#~ msgid "extensions." +#~ msgstr "extensies." + #~ msgid "flat alphabetic reverse" #~ msgstr "omgekeerd plat alfabetisch" +#~ msgid "from" +#~ msgstr "van" + #~ msgid "is strongly advised." #~ msgstr "wordt sterk aangeraden." @@ -19485,9 +19516,18 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "n/A" #~ msgstr "NVT" +#~ msgid "packages selected." +#~ msgstr "pakketten geselecteerd." + #~ msgid "reverse by date" #~ msgstr "omgekeerd chronologisch" +#~ msgid "show softwaremanager in plugin menu" +#~ msgstr "toon softwaremanager in pluginbrowser" + +#~ msgid "show softwaremanager on blue button" +#~ msgstr "toon softwaremanager onder blauwe knop" + #, python-format #~ msgid "slot%s - %s" #~ msgstr "slot%s - %s" @@ -19499,3 +19539,6 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #, python-format #~ msgid "slot%s - %s (current image)" #~ msgstr "slot%s - %s (huidige image)" + +#~ msgid "updates available." +#~ msgstr "updates beschikbaar." From 907aeee381a1bc4e856e511c1a2edc93e59bf078 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Thu, 9 Nov 2023 12:45:56 +0200 Subject: [PATCH 155/401] [Added] Resolution, framerate, videocodec for IPTV services in ServiceInfo screen --- .../Components/Converter/ServiceInfo.py | 121 +++++++++--------- lib/python/Screens/ServiceInfo.py | 5 +- 2 files changed, 64 insertions(+), 62 deletions(-) diff --git a/lib/python/Components/Converter/ServiceInfo.py b/lib/python/Components/Converter/ServiceInfo.py index d0e84873909..5f3654101e3 100644 --- a/lib/python/Components/Converter/ServiceInfo.py +++ b/lib/python/Components/Converter/ServiceInfo.py @@ -9,6 +9,55 @@ WIDESCREEN = [3, 4, 7, 8, 0xB, 0xC, 0xF, 0x10] +def getProcVal(pathname, base=10): + val = None + try: + f = open(pathname, "r") + val = int(f.read(), base) + f.close() + if val >= 2 ** 31: + val -= 2 ** 32 + except: + pass + return val + +def getVal(pathname, info, infoVal, base=10): + val = getProcVal(pathname, base=base) + return val if val is not None else info.getInfo(infoVal) + +def getValInt(pathname, info, infoVal, base=10, default=-1): + val = getVal(pathname, info, infoVal, base) + return val if val is not None else default + +def getValStr(pathname, info, infoVal, base=10, convert=lambda x: "%d" % x, instance=None): + val = getProcVal(pathname, base=base) + return convert(val) if val is not None else instance.getServiceInfoString(info, infoVal, convert) + +def getVideoHeight(info): + return getValInt("/proc/stb/vmpeg/0/yres", info, iServiceInformation.sVideoHeight, base=16) + +def getVideoHeightStr(info, convert=lambda x: "%d" % x if x > 0 else "?", instance=None): + return getValStr("/proc/stb/vmpeg/0/yres", info, iServiceInformation.sVideoHeight, base=16, convert=convert, instance=instance) + +def getVideoWidth(info): + return getValInt("/proc/stb/vmpeg/0/xres", info, iServiceInformation.sVideoWidth, base=16) + +def getVideoWidthStr(info, convert=lambda x: "%d" % x if x > 0 else "?", instance=None): + return getValStr("/proc/stb/vmpeg/0/xres", info, iServiceInformation.sVideoWidth, base=16, convert=convert, instance=instance) + +def getFrameRate(info): + return getValInt("/proc/stb/vmpeg/0/framerate", info, iServiceInformation.sFrameRate) + +def getFrameRateStr(info, convert=lambda x: "%d" % x if x > 0 else "", instance=None): + return getValStr("/proc/stb/vmpeg/0/framerate", info, iServiceInformation.sFrameRate, convert=convert, instance=instance) + +def getProgressive(info): + return getValInt("/proc/stb/vmpeg/0/progressive", info, iServiceInformation.sProgressive, default=0) + +def getProgressiveStr(info, convert=lambda x: "" if x else "i", instance=None): + return getValStr("/proc/stb/vmpeg/0/progressive", info, iServiceInformation.sProgressive, convert=convert, instance=instance) + + class ServiceInfo(Poll, Converter): HAS_TELETEXT = 1 IS_MULTICHANNEL = 2 @@ -117,54 +166,6 @@ def getServiceInfoString(self, info, what, convert=lambda x: "%d" % x): return info.getInfoString(what) return convert(v) - def _getProcVal(self, pathname, base=10): - val = None - try: - f = open(pathname, "r") - val = int(f.read(), base) - f.close() - if val >= 2 ** 31: - val -= 2 ** 32 - except: - pass - return val - - def _getVal(self, pathname, info, infoVal, base=10): - val = self._getProcVal(pathname, base=base) - return val if val is not None else info.getInfo(infoVal) - - def _getValInt(self, pathname, info, infoVal, base=10, default=-1): - val = self._getVal(pathname, info, infoVal, base) - return val if val is not None else default - - def _getValStr(self, pathname, info, infoVal, base=10, convert=lambda x: "%d" % x): - val = self._getProcVal(pathname, base=base) - return convert(val) if val is not None else self.getServiceInfoString(info, infoVal, convert) - - def _getVideoHeight(self, info): - return self._getValInt("/proc/stb/vmpeg/0/yres", info, iServiceInformation.sVideoHeight, base=16) - - def _getVideoHeightStr(self, info, convert=lambda x: "%d" % x if x > 0 else "?"): - return self._getValStr("/proc/stb/vmpeg/0/yres", info, iServiceInformation.sVideoHeight, base=16, convert=convert) - - def _getVideoWidth(self, info): - return self._getValInt("/proc/stb/vmpeg/0/xres", info, iServiceInformation.sVideoWidth, base=16) - - def _getVideoWidthStr(self, info, convert=lambda x: "%d" % x if x > 0 else "?"): - return self._getValStr("/proc/stb/vmpeg/0/xres", info, iServiceInformation.sVideoWidth, base=16, convert=convert) - - def _getFrameRate(self, info): - return self._getValInt("/proc/stb/vmpeg/0/framerate", info, iServiceInformation.sFrameRate) - - def _getFrameRateStr(self, info, convert=lambda x: "%d" % x if x > 0 else ""): - return self._getValStr("/proc/stb/vmpeg/0/framerate", info, iServiceInformation.sFrameRate, convert=convert) - - def _getProgressive(self, info): - return self._getValInt("/proc/stb/vmpeg/0/progressive", info, iServiceInformation.sProgressive, default=0) - - def _getProgressiveStr(self, info, convert=lambda x: "" if x else "i"): - return self._getValStr("/proc/stb/vmpeg/0/progressive", info, iServiceInformation.sProgressive, convert=convert) - @cached def getBoolean(self): service = self.source.service @@ -173,7 +174,7 @@ def getBoolean(self): return False video_height = None video_aspect = None - video_height = self._getVideoHeight(info) + video_height = getVideoHeight(info) video_aspect = info.getInfo(iServiceInformation.sAspect) if self.type == self.HAS_TELETEXT: tpid = info.getInfo(iServiceInformation.sTXTPID) @@ -241,7 +242,7 @@ def getBoolean(self): elif self.type == self.IS_4K: return video_height >= 1500 elif self.type == self.PROGRESSIVE: - return bool(self._getProgressive(info)) + return bool(getProgressive(info)) elif self.type == self.IS_SDR: return info.getInfo(iServiceInformation.sGamma) == 0 elif self.type == self.IS_HDR: @@ -267,9 +268,9 @@ def getText(self): if not info: return "" if self.type == self.XRES: - return self._getVideoWidthStr(info) + return getVideoWidthStr(info, instance=self) elif self.type == self.YRES: - return self._getVideoHeightStr(info) + return getVideoHeightStr(info, instance=self) elif self.type == self.APID: return self.getServiceInfoString(info, iServiceInformation.sAudioPID) elif self.type == self.VPID: @@ -287,9 +288,9 @@ def getText(self): elif self.type == self.SID: return self.getServiceInfoString(info, iServiceInformation.sSID) elif self.type == self.FRAMERATE: - return self._getFrameRateStr(info, convert=lambda x: "%d fps" % ((x + 500) // 1000)) + return getFrameRateStr(info, convert=lambda x: "%d fps" % ((x + 500) // 1000), instance=self) elif self.type == self.PROGRESSIVE: - return self._getProgressiveStr(info) + return getProgressiveStr(info, instance=self) elif self.type == self.TRANSFERBPS: return self.getServiceInfoString(info, iServiceInformation.sTransferBPS, lambda x: "%d kB/s" % (x // 1024)) elif self.type == self.HAS_HBBTV: @@ -319,15 +320,15 @@ def getText(self): out = "Freq: %s %s %s %s %s" % (frequency, polarization, sr_txt, symbolrate, fec) return out elif self.type == self.VIDEO_INFO: - progressive = self._getProgressiveStr(info) - fieldrate = self._getFrameRate(info) + progressive = getProgressiveStr(info, instance=self) + fieldrate = getFrameRate(info) if fieldrate > 0: if progressive == 'i': fieldrate *= 2 fieldrate = "%dHz" % ((fieldrate + 500) // 1000,) else: fieldrate = "" - return "%sx%s%s %s" % (self._getVideoWidthStr(info), self._getVideoHeightStr(info), progressive, fieldrate) + return "%sx%s%s %s" % (getVideoWidthStr(info, instance=self), getVideoHeightStr(info, instance=self), progressive, fieldrate) return "" text = property(getText) @@ -339,11 +340,11 @@ def getValue(self): if not info: return -1 if self.type == self.XRES: - return str(self._getVideoWidth(info)) + return str(getVideoWidth(info)) elif self.type == self.YRES: - return str(self._getVideoHeight(info)) + return str(getVideoHeight(info)) elif self.type == self.FRAMERATE: - return str(self._getFrameRate(self, info)) + return str(getFrameRate(self, info)) return -1 value = property(getValue) diff --git a/lib/python/Screens/ServiceInfo.py b/lib/python/Screens/ServiceInfo.py index 8c659beacb4..ca6ce171e06 100644 --- a/lib/python/Screens/ServiceInfo.py +++ b/lib/python/Screens/ServiceInfo.py @@ -172,9 +172,10 @@ def ShowServiceInformation(self): resolution = "-" if self.info: from Components.Converter.PliExtraInfo import codec_data + from Components.Converter.ServiceInfo import getVideoHeight, getVideoWidth videocodec = codec_data.get(self.info.getInfo(iServiceInformation.sVideoType), "N/A") - width = self.info.getInfo(iServiceInformation.sVideoWidth) - height = self.info.getInfo(iServiceInformation.sVideoHeight) + width = getVideoWidth(self.info) + height = getVideoHeight(self.info) if width > 0 and height > 0: fps = (self.info.getInfo(iServiceInformation.sFrameRate) + 500) // 1000 if fps in (0, -1): From ffe8f43fab817e8eeec52d1032a0d2401a775773 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Thu, 9 Nov 2023 10:56:19 +0000 Subject: [PATCH 156/401] PEP8 double aggressive E301 ~ E306 --- lib/python/Components/Converter/ServiceInfo.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/python/Components/Converter/ServiceInfo.py b/lib/python/Components/Converter/ServiceInfo.py index 5f3654101e3..7ad4773ac87 100644 --- a/lib/python/Components/Converter/ServiceInfo.py +++ b/lib/python/Components/Converter/ServiceInfo.py @@ -21,39 +21,50 @@ def getProcVal(pathname, base=10): pass return val + def getVal(pathname, info, infoVal, base=10): val = getProcVal(pathname, base=base) return val if val is not None else info.getInfo(infoVal) + def getValInt(pathname, info, infoVal, base=10, default=-1): val = getVal(pathname, info, infoVal, base) return val if val is not None else default + def getValStr(pathname, info, infoVal, base=10, convert=lambda x: "%d" % x, instance=None): val = getProcVal(pathname, base=base) return convert(val) if val is not None else instance.getServiceInfoString(info, infoVal, convert) + def getVideoHeight(info): return getValInt("/proc/stb/vmpeg/0/yres", info, iServiceInformation.sVideoHeight, base=16) + def getVideoHeightStr(info, convert=lambda x: "%d" % x if x > 0 else "?", instance=None): return getValStr("/proc/stb/vmpeg/0/yres", info, iServiceInformation.sVideoHeight, base=16, convert=convert, instance=instance) + def getVideoWidth(info): return getValInt("/proc/stb/vmpeg/0/xres", info, iServiceInformation.sVideoWidth, base=16) + def getVideoWidthStr(info, convert=lambda x: "%d" % x if x > 0 else "?", instance=None): return getValStr("/proc/stb/vmpeg/0/xres", info, iServiceInformation.sVideoWidth, base=16, convert=convert, instance=instance) + def getFrameRate(info): return getValInt("/proc/stb/vmpeg/0/framerate", info, iServiceInformation.sFrameRate) + def getFrameRateStr(info, convert=lambda x: "%d" % x if x > 0 else "", instance=None): return getValStr("/proc/stb/vmpeg/0/framerate", info, iServiceInformation.sFrameRate, convert=convert, instance=instance) + def getProgressive(info): return getValInt("/proc/stb/vmpeg/0/progressive", info, iServiceInformation.sProgressive, default=0) + def getProgressiveStr(info, convert=lambda x: "" if x else "i", instance=None): return getValStr("/proc/stb/vmpeg/0/progressive", info, iServiceInformation.sProgressive, convert=convert, instance=instance) From ab6f94e944a7c36a81a9e23d5b79a2a71db7aa2e Mon Sep 17 00:00:00 2001 From: Huevos Date: Thu, 9 Nov 2023 13:49:28 +0100 Subject: [PATCH 157/401] [Convertor] do not use "str" as a variable name --- lib/python/Components/Converter/Converter.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/python/Components/Converter/Converter.py b/lib/python/Components/Converter/Converter.py index b50fb3a50b7..712efb9c449 100644 --- a/lib/python/Components/Converter/Converter.py +++ b/lib/python/Components/Converter/Converter.py @@ -13,9 +13,9 @@ def __repr__(self): def handleCommand(self, cmd): self.source.handleCommand(cmd) - def appendToStringWithSeparator(self, str, part): - if str == "": - str = part + def appendToStringWithSeparator(self, text, part): + if text == "": + text = part else: - str = str + self.separatorChar + part - return str + text = f"{text} {self.separatorChar} {part}" + return text From b005f08779a7ab3f9ef9f85b2751f869d9bcd36d Mon Sep 17 00:00:00 2001 From: Ev0-BH Date: Thu, 9 Nov 2023 18:35:16 +0000 Subject: [PATCH 158/401] [ServiceInfo] Add Fix workaround for H.265 with Extplayer3 --- lib/python/Components/Converter/ServiceInfo.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/python/Components/Converter/ServiceInfo.py b/lib/python/Components/Converter/ServiceInfo.py index 7ad4773ac87..8c6f505c28f 100644 --- a/lib/python/Components/Converter/ServiceInfo.py +++ b/lib/python/Components/Converter/ServiceInfo.py @@ -267,7 +267,10 @@ def getBoolean(self): elif self.type == self.IS_VIDEO_AVC: return info.getInfo(iServiceInformation.sVideoType) == 1 elif self.type == self.IS_VIDEO_HEVC: - return info.getInfo(iServiceInformation.sVideoType) == 7 + if info.getInfoString(iServiceInformation.sServiceref).startswith("5002") and info.getInfo(iServiceInformation.sVideoType) == -1: + return 7 + else: + return info.getInfo(iServiceInformation.sVideoType) == 7 return False boolean = property(getBoolean) From 123b4725441047b008d2428a40b12b2b270cae86 Mon Sep 17 00:00:00 2001 From: openvix-build Date: Thu, 9 Nov 2023 23:09:31 +0000 Subject: [PATCH 159/401] openvix: developer 6.4.009.013 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 3cb5a0d6f89..94ddf8086b3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1196,3 +1196,4 @@ openvix: developer 6.4.009.009 openvix: developer 6.4.009.010 openvix: developer 6.4.009.011 openvix: developer 6.4.009.012 +openvix: developer 6.4.009.013 From 5df7a4eedf8c129724cffb99da80b633883c5d74 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sat, 11 Nov 2023 01:48:34 +0100 Subject: [PATCH 160/401] [InfoBarGenerics] sort whitelist --- lib/python/Screens/InfoBarGenerics.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index 2531296c20f..bb9842a8787 100644 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -941,8 +941,9 @@ def ToggleStreamrelay(self, service=None): whitelist.streamrelay.remove(servicestring) else: whitelist.streamrelay.append(servicestring) - if self.session.nav.getCurrentlyPlayingServiceReference() == service: - self.session.nav.restartService() + if self.session.nav.getCurrentlyPlayingServiceReference() == service: + self.session.nav.restartService() + whitelist.streamrelay.sort(key=lambda ref: ((x:=ref.split(":"))[6], x[5], x[4], x[3])) open('/etc/enigma2/whitelist_streamrelay', 'w').write('\n'.join(whitelist.streamrelay)) def queueChange(self): From 2d8c728aaac632c065367a2ea7f48ab6592db585 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sat, 11 Nov 2023 00:51:03 +0000 Subject: [PATCH 161/401] PEP8 double aggressive E22, E224, E241, E242 and E27 --- lib/python/Screens/InfoBarGenerics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index bb9842a8787..d87d43b4ea1 100644 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -943,7 +943,7 @@ def ToggleStreamrelay(self, service=None): whitelist.streamrelay.append(servicestring) if self.session.nav.getCurrentlyPlayingServiceReference() == service: self.session.nav.restartService() - whitelist.streamrelay.sort(key=lambda ref: ((x:=ref.split(":"))[6], x[5], x[4], x[3])) + whitelist.streamrelay.sort(key=lambda ref: ((x := ref.split(":"))[6], x[5], x[4], x[3])) open('/etc/enigma2/whitelist_streamrelay', 'w').write('\n'.join(whitelist.streamrelay)) def queueChange(self): From 2efad481631400b8a456cc096508ead5f617cda4 Mon Sep 17 00:00:00 2001 From: openvix-build Date: Sat, 11 Nov 2023 01:09:28 +0000 Subject: [PATCH 162/401] openvix: developer 6.4.009.014 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 94ddf8086b3..0a06f9ccfb4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1197,3 +1197,4 @@ openvix: developer 6.4.009.010 openvix: developer 6.4.009.011 openvix: developer 6.4.009.012 openvix: developer 6.4.009.013 +openvix: developer 6.4.009.014 From f010a2b6d0172dfc87486a6fdcd5791ab8040441 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sat, 11 Nov 2023 12:02:32 +0100 Subject: [PATCH 163/401] [MovieContextMenu] make "config" widget mandatory --- lib/python/Screens/MovieSelection.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Screens/MovieSelection.py b/lib/python/Screens/MovieSelection.py index 79c7d846acd..20dd339afc3 100644 --- a/lib/python/Screens/MovieSelection.py +++ b/lib/python/Screens/MovieSelection.py @@ -390,7 +390,7 @@ def selectionChanged(self): class MovieContextMenu(Screen, ProtectedScreen): # Contract: On OK returns a callable object (e.g. delete) def __init__(self, session, csel, currentSelection): - Screen.__init__(self, session) + Screen.__init__(self, session, mandatoryWidgets=["config"]) self.skinName = ["MovieContextMenu", "Setup"] self.setup_title = _("Movie List Setup") Screen.setTitle(self, _(self.setup_title)) From 061cf10c0e86ce068fa6d65af1dde6bd31505b5f Mon Sep 17 00:00:00 2001 From: Huevos Date: Sat, 11 Nov 2023 22:29:28 +0100 Subject: [PATCH 164/401] SecndInfoBar: fix indent --- lib/python/Screens/InfoBarGenerics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index d87d43b4ea1..cc9b4c50ac7 100644 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -840,7 +840,7 @@ def toggleShow(self): self.show() if self.secondInfoBarScreen: self.secondInfoBarScreen.hide() - self.secondInfoBarWasShown = False + self.secondInfoBarWasShown = False self.EventViewIsShown = False elif isStandardInfoBar(self) and config.usage.show_second_infobar.value == "EPG": self.showDefaultEPG() From 0ded40e19f740bca1d908339e954d46e4ae6e44d Mon Sep 17 00:00:00 2001 From: openvix-build Date: Sat, 11 Nov 2023 21:50:01 +0000 Subject: [PATCH 165/401] openvix: developer 6.4.009.015 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 0a06f9ccfb4..d459af3c7ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1198,3 +1198,4 @@ openvix: developer 6.4.009.011 openvix: developer 6.4.009.012 openvix: developer 6.4.009.013 openvix: developer 6.4.009.014 +openvix: developer 6.4.009.015 From 7100a11ccd2585cb053f1c94109c2203d6e3e773 Mon Sep 17 00:00:00 2001 From: betacentauri Date: Sun, 10 Apr 2016 12:18:54 +0200 Subject: [PATCH 166/401] Fix CI info CI info was not shown when debug log was disabled. Seperating debug from program logic. Signed-off-by: littlesat --- lib/mmi/mmi_ui.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/mmi/mmi_ui.cpp b/lib/mmi/mmi_ui.cpp index 432ffc344b4..1a2db82fca6 100644 --- a/lib/mmi/mmi_ui.cpp +++ b/lib/mmi/mmi_ui.cpp @@ -114,10 +114,8 @@ int eMMI_UI::processMMIData(int slot_id, const unsigned char *tag, const void *d memcpy(str, ((char*)d), textlen); str[textlen] = '\0'; mmiScreenAddText(slot_id, pos++, (char*)convertDVBUTF8(str).c_str()); - eDebugNoNewLineStart("[eMMI_UI] "); - while (textlen--) - eDebugNoNewLine("%c", *d++); - eDebugNoNewLine("\n"); + eDebug("[eMMI_UI] %s", str); + d += textlen; } mmiScreenFinish(slot_id); break; From 8c10fd1ce7f497b2e590b39ac9267ef7a7a515dc Mon Sep 17 00:00:00 2001 From: Betacentauri Date: Thu, 9 Nov 2023 16:23:56 +0100 Subject: [PATCH 167/401] Fix MMI text conversion don't use inline convertDVBUTF8 function as it does implicit char* to string conversion which is a problem as the string can contain \0 in the character encoding (e.g. 0x10, 0x00, 0x01 for ISO/IEC 8859-1) Thanks madface2000! --- lib/mmi/mmi_ui.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/lib/mmi/mmi_ui.cpp b/lib/mmi/mmi_ui.cpp index 1a2db82fca6..fd59e41916d 100644 --- a/lib/mmi/mmi_ui.cpp +++ b/lib/mmi/mmi_ui.cpp @@ -73,11 +73,12 @@ int eMMI_UI::processMMIData(int slot_id, const unsigned char *tag, const void *d eDebug("[eMMI_UI] %d bytes text", textlen); if ((d+textlen) > max) break; - char str[textlen + 1]; - memcpy(str, ((char*)d), textlen); + unsigned char str[textlen + 1]; + memcpy(str, ((unsigned char*)d), textlen); str[textlen] = '\0'; - eDebug("[eMMI_UI] enq-text: %s",str); - mmiScreenEnq(slot_id, blind, alen, (char*)convertDVBUTF8(str).c_str()); + std::string converted_str = convertDVBUTF8(str, textlen, -1, 1, 0); + eDebug("[eMMI_UI] enq-text: %s", converted_str.c_str()); + mmiScreenEnq(slot_id, blind, alen, (char*)converted_str.c_str()); break; } case 0x09: //Tmenu_last @@ -110,11 +111,12 @@ int eMMI_UI::processMMIData(int slot_id, const unsigned char *tag, const void *d eDebug("[eMMI_UI] %d bytes text", textlen); if ((d+textlen) > max) break; - char str[textlen + 1]; - memcpy(str, ((char*)d), textlen); + unsigned char str[textlen + 1]; + memcpy(str, ((unsigned char*)d), textlen); str[textlen] = '\0'; - mmiScreenAddText(slot_id, pos++, (char*)convertDVBUTF8(str).c_str()); - eDebug("[eMMI_UI] %s", str); + std::string converted_str = convertDVBUTF8(str, textlen, -1, 1, 0); + mmiScreenAddText(slot_id, pos++, (char*)converted_str.c_str()); + eDebug("[eMMI_UI] %s", converted_str.c_str()); d += textlen; } mmiScreenFinish(slot_id); From 7c394c3cde7c98eed7adfd57228a09b3701d443d Mon Sep 17 00:00:00 2001 From: Twol Date: Sun, 12 Nov 2023 08:38:38 +0100 Subject: [PATCH 168/401] [ServiceOrbitalPosition] add orbital position for streamrelay services, sequence imports --- .../Converter/ServiceOrbitalPosition.py | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/python/Components/Converter/ServiceOrbitalPosition.py b/lib/python/Components/Converter/ServiceOrbitalPosition.py index 707fd49d7c2..bbbd46babca 100644 --- a/lib/python/Components/Converter/ServiceOrbitalPosition.py +++ b/lib/python/Components/Converter/ServiceOrbitalPosition.py @@ -1,10 +1,9 @@ # -*- coding: utf-8 -*- -from Components.Converter.Converter import Converter - from enigma import iServiceInformation, iPlayableService, iPlayableServicePtr, eServiceCenter -from ServiceReference import resolveAlternate +from Components.Converter.Converter import Converter from Components.Element import cached +from ServiceReference import resolveAlternate class ServiceOrbitalPosition(Converter): @@ -57,7 +56,20 @@ def getText(self): return _("Stream") if refString.startswith("1:134:"): return _("Alternative") - return "" + elif info: + if "%3a//127" in info.getInfoString(iServiceInformation.sServiceref).lower(): + nmspc = info.getInfo(iServiceInformation.sNamespace) & 0xFFFFFFFF + namespace = "%08X" % nmspc + EW = "E" + orbpos = int(namespace[:4], 16) + if orbpos > 1800: + orbpos = 3600 - orbpos + EW = "W" + return "%s\xb0 %s" % (float(orbpos) / 10.0, EW) + else: + return "" + else: + return "" text = property(getText) From 2525e1c16d6e9b217e96232726a92dc6873bbe07 Mon Sep 17 00:00:00 2001 From: Twol Date: Sun, 12 Nov 2023 08:57:39 +0100 Subject: [PATCH 169/401] [PliExtraInfo] - add provider names for streamrelay services (Twol/Ev0) --- .../Components/Converter/PliExtraInfo.py | 43 ++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/lib/python/Components/Converter/PliExtraInfo.py b/lib/python/Components/Converter/PliExtraInfo.py index b1c70bc7f6c..1edd2e9ea5e 100644 --- a/lib/python/Components/Converter/PliExtraInfo.py +++ b/lib/python/Components/Converter/PliExtraInfo.py @@ -545,7 +545,7 @@ def createInfoString(self, fieldGroup, fedata, feraw, info): elif field == "TransponderModulationFEC": val = self.createModulation(fedata) + '-' + self.createFEC(fedata, feraw) elif field == "TransponderName": - val = self.createTransponderName(feraw) + val = self.createTransponderName(feraw, info) elif field == "ProviderName": val = self.createProviderName(info) elif field in ("NewLine", "NL"): @@ -618,25 +618,41 @@ def createTunerType(self, feraw): def createTunerSystem(self, fedata): return fedata.get("system") or "" - def createOrbPos(self, feraw): + def namespace(self, info): + if "%3a//127" in info.getInfoString(iServiceInformation.sServiceref).lower(): + nmspc = info.getInfo(iServiceInformation.sNamespace) & 0xFFFFFFFF + namespace = "%08X" % nmspc + orbpos = int(namespace[:4], 16) + if orbpos > 1800: + return str((float(3600 - orbpos)) / 10.0) + "\xb0" + "W" + elif orbpos > 0: + return str((float(orbpos)) / 10.0) + "\xb0" + "E" + else: + return "" + + + def createOrbPos(self, feraw, info): orbpos = feraw.get("orbital_position") if orbpos is not None: if orbpos > 1800: return str((float(3600 - orbpos)) / 10.0) + "\xb0" + "W" elif orbpos > 0: return str((float(orbpos)) / 10.0) + "\xb0" + "E" - return "" + else: + orbpos = self.namespace(info) + return orbpos - def createOrbPosOrTunerSystem(self, fedata, feraw): - orbpos = self.createOrbPos(feraw) + def createOrbPosOrTunerSystem(self, fedata, feraw, info): + orbpos = self.createOrbPos(feraw, info) if orbpos != "": return orbpos return self.createTunerSystem(fedata) - def createTransponderName(self, feraw): + def createTransponderName(self, feraw, info): orbpos = feraw.get("orbital_position") if orbpos is None: # Not satellite - return "" + orbpos = self.namespace(info) + return orbpos freq = feraw.get("frequency") if freq and freq < 10700000: # C-band if orbpos > 1800: @@ -744,7 +760,14 @@ def createTransponderName(self, feraw): return str((float(orbpos)) / 10.0) + "E" def createProviderName(self, info): - return info.getInfoString(iServiceInformation.sProvider) + refstr = info.getInfoString(iServiceInformation.sServiceref) + if "%3a//" in refstr.lower() and not "127.0.0.1" in refstr and not "0.0.0.0" in refstr and not "localhost" in refstr: + return "" + elif "%3a//127" in refstr and "17999" in refstr: + provider = self.namespace(info).replace("28.2\xb0E", "Sky UK").replace("19.2\xb0E", "Sky Deutschland").replace("13.0\xb0E", "Sky Italia") + return "%s" % provider + else: + return info.getInfoString(iServiceInformation.sProvider) def createMisPls(self, fedata): tmp = "" @@ -925,7 +948,7 @@ def getTextByType(self, textType): return self.createModulation(fedata) if textType == "OrbitalPosition": - return self.createOrbPos(feraw) + return self.createOrbPos(feraw, info) if textType == "TunerType": return self.createTunerType(feraw) @@ -934,7 +957,7 @@ def getTextByType(self, textType): return self.createTunerSystem(fedata) if self.type == "OrbitalPositionOrTunerSystem": - return self.createOrbPosOrTunerSystem(fedata, feraw) + return self.createOrbPosOrTunerSystem(fedata, feraw, info) if textType == "TerrestrialChannelNumber": return self.createChannelNumber(fedata, feraw) From caad10649f25a7deedf9fa559c717b73efe5697c Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sun, 12 Nov 2023 08:00:16 +0000 Subject: [PATCH 170/401] PEP8 double aggressive E301 ~ E306 --- lib/python/Components/Converter/PliExtraInfo.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/python/Components/Converter/PliExtraInfo.py b/lib/python/Components/Converter/PliExtraInfo.py index 1edd2e9ea5e..98b77b2f200 100644 --- a/lib/python/Components/Converter/PliExtraInfo.py +++ b/lib/python/Components/Converter/PliExtraInfo.py @@ -630,7 +630,6 @@ def namespace(self, info): else: return "" - def createOrbPos(self, feraw, info): orbpos = feraw.get("orbital_position") if orbpos is not None: From 03969eb0f7abb24b49da023c6ed0f19d17adf79f Mon Sep 17 00:00:00 2001 From: Twol Date: Sun, 12 Nov 2023 10:18:47 +0100 Subject: [PATCH 171/401] [PliExtraInfo] flake8 PEP --- lib/python/Components/Converter/PliExtraInfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/Converter/PliExtraInfo.py b/lib/python/Components/Converter/PliExtraInfo.py index 98b77b2f200..f3af58ec776 100644 --- a/lib/python/Components/Converter/PliExtraInfo.py +++ b/lib/python/Components/Converter/PliExtraInfo.py @@ -760,7 +760,7 @@ def createTransponderName(self, feraw, info): def createProviderName(self, info): refstr = info.getInfoString(iServiceInformation.sServiceref) - if "%3a//" in refstr.lower() and not "127.0.0.1" in refstr and not "0.0.0.0" in refstr and not "localhost" in refstr: + if "%3a//" in refstr.lower() and "127.0.0.1" not in refstr and "0.0.0.0" not in refstr and "localhost" not in refstr: return "" elif "%3a//127" in refstr and "17999" in refstr: provider = self.namespace(info).replace("28.2\xb0E", "Sky UK").replace("19.2\xb0E", "Sky Deutschland").replace("13.0\xb0E", "Sky Italia") From 495febe3b41e5198336823d690d036da69747fe9 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sun, 12 Nov 2023 14:28:47 +0100 Subject: [PATCH 172/401] [InfoBarGenerics] update whitelist sort --- lib/python/Screens/InfoBarGenerics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index cc9b4c50ac7..aa2a549be17 100644 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -943,7 +943,7 @@ def ToggleStreamrelay(self, service=None): whitelist.streamrelay.append(servicestring) if self.session.nav.getCurrentlyPlayingServiceReference() == service: self.session.nav.restartService() - whitelist.streamrelay.sort(key=lambda ref: ((x := ref.split(":"))[6], x[5], x[4], x[3])) + whitelist.streamrelay.sort(key=lambda ref: (int((x:=ref.split(":"))[6], 16), int(x[5], 16), int(x[4], 16), int(x[3], 16))) open('/etc/enigma2/whitelist_streamrelay', 'w').write('\n'.join(whitelist.streamrelay)) def queueChange(self): From d793b907c3dbbfb193506cc94ce048d57d8b75fa Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sun, 12 Nov 2023 13:30:25 +0000 Subject: [PATCH 173/401] PEP8 double aggressive E22, E224, E241, E242 and E27 --- lib/python/Screens/InfoBarGenerics.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index aa2a549be17..ffeec228db0 100644 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -943,7 +943,7 @@ def ToggleStreamrelay(self, service=None): whitelist.streamrelay.append(servicestring) if self.session.nav.getCurrentlyPlayingServiceReference() == service: self.session.nav.restartService() - whitelist.streamrelay.sort(key=lambda ref: (int((x:=ref.split(":"))[6], 16), int(x[5], 16), int(x[4], 16), int(x[3], 16))) + whitelist.streamrelay.sort(key=lambda ref: (int((x := ref.split(":"))[6], 16), int(x[5], 16), int(x[4], 16), int(x[3], 16))) open('/etc/enigma2/whitelist_streamrelay', 'w').write('\n'.join(whitelist.streamrelay)) def queueChange(self): From eb82886e34b4ff3b4e27297ea4c05905009efa9b Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sun, 12 Nov 2023 15:55:53 +0200 Subject: [PATCH 174/401] [Updated] EventName converter --- lib/python/Components/Converter/EventName.py | 38 +++++++++++++------- 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/lib/python/Components/Converter/EventName.py b/lib/python/Components/Converter/EventName.py index 006f5436227..a38e3ea1988 100644 --- a/lib/python/Components/Converter/EventName.py +++ b/lib/python/Components/Converter/EventName.py @@ -169,16 +169,16 @@ def __init__(self, type): if len(self.parts) > 1: self.type = self.FORMAT_STRING self.separatorChar = self.parts[0] - - for arg in args: - name, value = self.KEYWORDS.get(arg, ("Error", None)) - if name == "Error": - print("[EventName] ERROR: Unexpected / Invalid argument token '%s'!" % arg) - else: - setattr(self, name, value) - if self.separator is None: - default_sep = "SeparatorComma" if self.type == self.GENRELIST else "NotSeparated" - self.separator = self.KEYWORDS[default_sep][1] + else: + for arg in args: + name, value = self.KEYWORDS.get(arg, ("Error", None)) + if name == "Error": + print("[EventName] ERROR: Unexpected / Invalid argument token '%s'!" % arg) + else: + setattr(self, name, value) + if self.separator is None: + default_sep = "SeparatorComma" if self.type == self.GENRELIST else "NotSeparated" + self.separator = self.KEYWORDS[default_sep][1] def trimText(self, text): if self.trim: @@ -199,6 +199,8 @@ def formatDescription(self, description, extended): def getBoolean(self): event = self.source.event if event: + if self.type == self.NAME: + return bool(self.getText()) if self.type == self.PDC and event.getPdcPil(): return True return False @@ -283,7 +285,7 @@ def getText(self): if running_status in (6, 7): return _("Reserved for future use") return _("Undefined") - elif self.type in (self.NAME_NEXT, self.NAME_NEXT2) or self.type >= self.NEXT_DESCRIPTION: + elif self.type in (self.NAME_NEXT, self.NAME_NEXT2) or (self.type >= self.NEXT_DESCRIPTION and not self.type == self.FORMAT_STRING): try: reference = self.source.service info = reference and self.source.info @@ -329,7 +331,19 @@ def getText(self): duration_str = "%d min" % (duration / 60) start_time_str = "%2d:%02d" % (t_start.tm_hour, t_start.tm_min) end_time_str = "%2d:%02d" % (t_end.tm_hour, t_end.tm_min) - res_str = "%s - %s %s %s" % (start_time_str, end_time_str, self.separator, duration_str) + name = self.trimText(event.getEventName()) + res_str = "" + for x in self.parts[1:]: + if x == "NAME" and name: + res_str = self.appendToStringWithSeparator(res_str, name) + if x == "STARTTIME" and start_time_str: + res_str = self.appendToStringWithSeparator(res_str, start_time_str) + if x == "ENDTIME" and end_time_str: + res_str = self.appendToStringWithSeparator(res_str, end_time_str) + if x == "TIMERANGE" and start_time_str and end_time_str: + res_str = self.appendToStringWithSeparator(res_str, "%s - %s" % (start_time_str, end_time_str)) + if x == "DURATION" and duration_str: + res_str = self.appendToStringWithSeparator(res_str, duration_str) return res_str return "" From 2642aec8bc68f3d948d66654348f666f5e357b95 Mon Sep 17 00:00:00 2001 From: Orlandoxx <95180049+Orlandoxx@users.noreply.github.com> Date: Sun, 12 Nov 2023 19:26:36 +0200 Subject: [PATCH 175/401] Updated Finnish (fi.po) translation Some linguistic fixes. --- po/fi.po | 56 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/po/fi.po b/po/fi.po index 879b7b76f35..a2d131ea176 100644 --- a/po/fi.po +++ b/po/fi.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: enigma2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-27 23:35+0000\n" -"PO-Revision-Date: 2023-11-07 16:38+0200\n" +"PO-Revision-Date: 2023-11-12 19:00+0200\n" "Last-Translator: Orlandox\n" "Language-Team: timoj/Kojo/Samzam/Orlandox\n" "Language: fi\n" @@ -3180,7 +3180,7 @@ msgid "Channel" msgstr "Kanava" msgid "Channel EPG" -msgstr "KanavaEPG" +msgstr "Kanava-ohjelmaopas" msgid "Channel List" msgstr "Kanavalista" @@ -4633,7 +4633,7 @@ msgid "Delete Confirmation" msgstr "Poistamisen vahvistuskysely" msgid "Delete EPG Cache" -msgstr "Poista EPG" +msgstr "Poista ohjelmaopas" msgid "Delete Language(s)" msgstr "Poista kieli" @@ -6533,7 +6533,7 @@ msgid "Grey" msgstr "Harmaa" msgid "Grid EPG" -msgstr "Graafinen taulukko-ohjelmaopas" +msgstr "Taulukko-ohjelmaopas" msgid "Grow drop" msgstr "Kasvava pudotus" @@ -7201,13 +7201,13 @@ msgid "Infobar EPG" msgstr "Tietopalkki-ohjelmaopas" msgid "Infobar EPG activation" -msgstr "Hakupalkin aktivointi" +msgstr "Tietopalkki-ohjelmaopppan aktivointi" msgid "Infobar Grid EPG" -msgstr "Tietopalkin taulukko-EPG" +msgstr "Tietopalkin taulukko-ohjelmaopas" msgid "Infobar Single EPG" -msgstr "Tietopalkin yksittäinen EPG" +msgstr "Tietopalkin yksittäinen ohjelmaopas" msgid "Infobar fade-out speed" msgstr "Tietopalkin häivytysnopeus" @@ -7679,6 +7679,9 @@ msgctxt "third event: 'third' event label" msgid "Later" msgstr "Myöhemmin" +msgid "LATER" +msgstr "MYÖHEMMIN" + msgid "Latitude" msgstr "Leveysaste" @@ -7821,7 +7824,7 @@ msgid "Load" msgstr "Lataa" msgid "Load EPG Cache" -msgstr "Lataa EPG" +msgstr "Lataa ohjelmaopas" msgid "Load playlist" msgstr "Lataa soittolista" @@ -7830,7 +7833,7 @@ msgid "Load unlinked userbouquets" msgstr "Näytä piilotetut suosikkilistat" msgid "Load, Save & Delete EPG Cache" -msgstr "Lataa, Tallenna ja Poista EPG" +msgstr "Lataa, Tallenna ja Poista ohjelmaopas" msgid "Loading skin" msgstr "Ladataan teemaa" @@ -9014,6 +9017,9 @@ msgctxt "now/next: 'now' event label" msgid "Now" msgstr "Nyt" +msgid "NOW" +msgstr "NYT" + msgid "Now, use the contrast setting to turn up the brightness of the background as much as possible, but make sure that you can still see the difference between the two brightest levels of shades.If you have done that, press OK." msgstr "Säädä kontrastisäädöllä tausta mahdollisimman valkoiseksi. Varmista, että näet yhä kahden kirkkaimman sävyn eron. Kun olet tyytyväinen tulokseen, paina OK." @@ -9171,7 +9177,7 @@ msgid "Open bouquet list" msgstr "Avaa suosikkilistat" msgid "Open infobar EPG" -msgstr "Avaa tietopalkin EPG" +msgstr "Avaa tietopalkin ohjelmaopas" msgid "Open menu" msgstr "Avaa valikko" @@ -10250,7 +10256,7 @@ msgid "Protect movie list" msgstr "Suojaa tallennusvalikko" msgid "Protect on epg age" -msgstr "Suojaa epg" +msgstr "Suojaa ohjelmaopas" msgid "Protect plugin browser" msgstr "Suojaa lisäosavalikko" @@ -11216,7 +11222,7 @@ msgid "Save / Enter text and exit" msgstr "Tallenna ja poistu" msgid "Save EPG Cache" -msgstr "Tallenna EPG" +msgstr "Tallenna ohjelmaopas" msgid "Save all changed settings and exit" msgstr "Tallenna ja poistu" @@ -12240,7 +12246,7 @@ msgid "Show Ecm info" msgstr "Näytä ECM-tiedot" msgid "Show Grid EPG" -msgstr "Näytä taulukko-EPG" +msgstr "Näytä taulukko-ohjelmaopas" msgid "Show Log" msgstr "Näytä loki" @@ -12255,7 +12261,7 @@ msgid "Show MiniTV in the Front Display" msgstr "Näytä MiniTV etupaneelin näytössä" msgid "Show Multi EPG" -msgstr "Näytä Multi EPG" +msgstr "Näytä monikanavaohjelmaopas" msgid "Show OScam/Ncam Info in extensions?" msgstr "Näytä OScam/Ncam Info laajennusvalikossa?" @@ -12279,7 +12285,7 @@ msgid "Show SD as" msgstr "Näytä SD näin:" msgid "Show Single EPG" -msgstr "Näytä yksittäinen EPG" +msgstr "Näytä yksittäinen ohjelmaopas" msgid "Show Software Update in Extensions" msgstr "Näytä ohjelmapäivitys laajennuksissa" @@ -12408,7 +12414,7 @@ msgid "Show info line" msgstr "Näytä tietopalkki" msgid "Show infobar EPG" -msgstr "Tietopalkin EPG" +msgstr "Näytä tietopalkki-ohjelmaopas" msgid "Show infobar on channel change" msgstr "Näytä tietopalkki kanavaa vaihdettaessa" @@ -12513,7 +12519,7 @@ msgid "Show shutdown menu" msgstr "Näytä sammutusvalikko" msgid "Show single channel EPG" -msgstr "Näytä yhden kanavan EPG" +msgstr "Näytä yhden kanavan ohjelmaopas" msgid "Show single epg for current channel" msgstr "Näytä nykyisen kanavan ohjelmatiedot" @@ -13437,16 +13443,16 @@ msgid "Switch the PiP to the previous channel" msgstr "Vaihda PiP edelliselle kanavalle" msgid "Switch to Grid EPG" -msgstr "Vaihda taulukko-EPG:n" +msgstr "Vaihda taulukko-ohjelmaoppaaseen" msgid "Switch to HDMI in mode" msgstr "Vaihda HDMI In -tilaan" msgid "Switch to Multi EPG" -msgstr "Vaihda graafiseen EPG:n" +msgstr "Vaihda monikanavaohjelmaoppaaseen" msgid "Switch to Single EPG" -msgstr "Vaihda yksittäiseen-EPG:n" +msgstr "Vaihda yksittäiseen ohjelmaoppaaseen" msgid "Switch to TV mode" msgstr "Vaihda TV-tilaan" @@ -13543,7 +13549,7 @@ msgstr "" "Suomenkielinen käännös: timoj, Kojo, Samzam, Orlandox\n" "\n" "Ylläpito : Orlandox\n" -"07.11.2023\n" +"12.11.2023\n" "http://www.huoltovalikko.com" msgid "TS file is too large for ISO9660 level 1!" @@ -13656,7 +13662,7 @@ msgid "Text" msgstr "Teksti" msgid "Text Grid EPG" -msgstr "Teksti taulukko-ohjelmaopas" +msgstr "Tekstillinen taulukko-ohjelmaopas" msgid "Text View On" msgstr "Tekstinäkymä päällä" @@ -19123,3 +19129,9 @@ msgstr "Odota, verkkoasetuksia poistetaan käytöstä..." msgid "Your network configuration has been disabled." msgstr "Verkkoasetukset on poistettu käytöstä." + +msgid "Reception" +msgstr "Vastaanotto" + +msgid "Transmission" +msgstr "Lähetys" From 783ef157f07eeab9c725b9bff415ecef5b404fc7 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sun, 12 Nov 2023 18:55:53 +0200 Subject: [PATCH 176/401] [Added] Alternative two line visual mode in ServiceList --- lib/python/Components/ServiceList.py | 22 +- lib/python/Components/UsageConfig.py | 2 +- lib/service/listboxservice.cpp | 1015 +++++++++++++++++--------- lib/service/listboxservice.h | 8 +- 4 files changed, 702 insertions(+), 345 deletions(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 78e3fe38cf3..1b438431c11 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -27,7 +27,7 @@ class ServiceList(GUIComponent): def __init__(self, serviceList): self.serviceList = serviceList GUIComponent.__init__(self) - self.l = eListboxServiceContent() # noqa: E741 + self.l = eListboxServiceContent() pic = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/folder.png")) pic and self.l.setPixmap(self.l.picFolder, pic) @@ -55,6 +55,18 @@ def __init__(self, serviceList): pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/record.png")) pic and self.l.setPixmap(self.l.picRecord, pic) + + # Icons for two lines alternative mode + pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/ico_hd-fs8.png")) + pic and self.l.setPixmap(self.l.picHD, pic) + pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/ico_sd-fs8.png")) + pic and self.l.setPixmap(self.l.picSD, pic) + pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/ico_uhd-fs8.png")) + pic and self.l.setPixmap(self.l.pic4K, pic) + pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/ico_catchup-fs8.png")) + pic and self.l.setPixmap(self.l.picCatchup, pic) + pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/ico_altref-fs8.png")) + pic and self.l.setPixmap(self.l.picBackup, pic) self.root = None self.mode = self.MODE_NORMAL @@ -431,9 +443,12 @@ def setMode(self, mode): self.setItemsPerPage() two_lines_val = int(config.usage.servicelist_twolines.value) show_two_lines = two_lines_val and mode == self.MODE_FAVOURITES - self.ItemHeight *= (2 if show_two_lines else 1) + if two_lines_val == 3: + self.ItemHeight = 86 + else: + self.ItemHeight *= (2 if show_two_lines else 1) self.l.setItemHeight(self.ItemHeight) - self.l.setVisualMode(eListboxServiceContent.visModeComplex) + self.l.setVisualMode(eListboxServiceContent.visModeComplex if two_lines_val < 3 else eListboxServiceContent.visSkinDefined) if config.usage.service_icon_enable.value: self.l.setGetPiconNameFunc(getPiconName) @@ -464,6 +479,7 @@ def setMode(self, mode): else: self.l.setElementPosition(self.l.celServiceEventProgressbar, eRect(0, 0, 0, 0)) self.l.setElementPosition(self.l.celServiceName, eRect(channelNumberWidth + channelNumberSpace, 0, rowWidth - (channelNumberWidth + channelNumberSpace), self.ItemHeight)) + self.l.setElementFont(self.l.celServiceName, self.ServiceNameFont) self.l.setElementFont(self.l.celServiceNumber, self.ServiceNumberFont) self.l.setElementFont(self.l.celServiceInfo, self.ServiceInfoFont) diff --git a/lib/python/Components/UsageConfig.py b/lib/python/Components/UsageConfig.py index d22caca7978..e9ed9f5861a 100644 --- a/lib/python/Components/UsageConfig.py +++ b/lib/python/Components/UsageConfig.py @@ -53,7 +53,7 @@ def alternativeNumberModeChange(configElement): refreshServiceList() config.usage.alternative_number_mode.addNotifier(alternativeNumberModeChange) - config.usage.servicelist_twolines = ConfigSelection(default="0", choices=[("0", _("None")), ("1", _("two lines")), ("2", _("two lines and next event"))]) + config.usage.servicelist_twolines = ConfigSelection(default="0", choices=[("0", _("None")), ("1", _("two lines")), ("2", _("two lines and next event")), ("3", _("two lines alternative"))]) config.usage.servicelist_twolines.addNotifier(refreshServiceList) config.usage.hide_number_markers = ConfigYesNo(default=True) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index f980bb5af62..51c594fd0a2 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -13,6 +13,45 @@ ePyObject eListboxServiceContent::m_GetPiconNameFunc; +std::string toLower(std::string& data) { + std::string data_tmp = data; + std::transform(data_tmp.begin(), data_tmp.end(), data_tmp.begin(), tolower); + return data_tmp; +} + +// Next two functions are used for finding correct recording in case of dynamic iptv service url +void join(const std::vector& v, char c, std::string& s) { + + s.clear(); + + for (std::vector::const_iterator p = v.begin(); + p != v.end(); ++p) { + s += *p; + if (p != v.end() - 1) + s += c; + } +} + +bool compareServices(const eServiceReference &ref1, const eServiceReference &ref2) { + eServiceReference r_i = ref1; + std::vector ref_split = split(r_i.toString(), ":"); + std::vector s_split = split(ref2.toString(), ":"); + + if (ref_split[1] == "7" || s_split[1] == "7") { + return ref1 == ref2; + } + + std::vector ref_split_r(ref_split.begin(), ref_split.begin() + 10); + std::string ref_s; + join(ref_split_r, ':', ref_s); + + std::vector s_split_r(s_split.begin(), s_split.begin() + 10); + std::string s_s; + join(s_split_r, ':', s_s); + + return ref_s == s_s; +} + void eListboxServiceContent::addService(const eServiceReference &service, bool beforeCurrent) { if (beforeCurrent && m_size) @@ -280,14 +319,14 @@ int eListboxServiceContent::markedQueryNext(eServiceReference &ref) int eListboxServiceContent::lookupService(const eServiceReference &ref) { - /* shortcut for cursor */ + /* shortcut for cursor */ if (ref == *m_cursor) return m_cursor_number; - /* otherwise, search in the list.. */ + /* otherwise, search in the list.. */ int index = 0; for (list::const_iterator i(m_list.begin()); i != m_list.end(); ++i, ++index); - /* this is ok even when the index was not found. */ + /* this is ok even when the index was not found. */ return index; } @@ -620,24 +659,23 @@ bool eListboxServiceContent::checkServiceIsRecorded(eServiceReference ref) { ePtr db; ePtr res; - if (eDVBResourceManager::getInstance(res) == -1) - { - return false; - } - if (res->getChannelList(db) < 0) - { - return false; - } + eDVBResourceManager::getInstance(res); + res->getChannelList(db); eBouquet *bouquet = NULL; if (!db->getBouquet(ref, bouquet)) { - for (std::list::iterator i(bouquet->m_services.begin()); i != bouquet->m_services.end(); ++i) - if (*i == it->second) + for (std::list::iterator i(bouquet->m_services.begin()); i != bouquet->m_services.end(); ++i){ + if (compareServices(*i, it->second)) return true; + return false; + } } } - else if (ref == it->second) - return true; + else { + if (compareServices(ref, it->second)) + return true; + return false; + } } return false; } @@ -733,8 +771,22 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const ePtr service_info; m_service_center->info(*m_cursor, service_info); eServiceReference ref = *m_cursor; + std::string orig_ref_str = ref.toString(); + std::string service_res_str = toLower(split(orig_ref_str, ":")[2]); + //eDebug("[eListboxServiceContent] service_res_str = %s", service_res_str.c_str()); + bool isBackupAvailable = false; + int catchUpDays = 0; + if (orig_ref_str.find("@") != std::string::npos) { + isBackupAvailable = true; + } + + if (orig_ref_str.find("|<|") != std::string::npos) { + catchUpDays = std::stoi(split(split(orig_ref_str, "|<|")[1], "@")[0]); + } + bool isMarker = ref.flags & eServiceReference::isMarker; - bool isPlayable = !(ref.flags & eServiceReference::isDirectory || isMarker); + bool isDirectory = ref.flags & eServiceReference::isDirectory; + bool isPlayable = !(isDirectory || isMarker); bool isRecorded = m_record_indicator_mode && isPlayable && checkServiceIsRecorded(ref); ePtr evt, evt_next; bool serviceAvail = true; @@ -772,420 +824,703 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const painter.setForegroundColor(gRGB(0xb40431)); } - int xoffset=0; // used as offset when painting the folder/marker symbol or the serviceevent progress + int xoffset=0, xoffs=0; // used as offset when painting the folder/marker symbol or the serviceevent progress int nameLeft=0, nameWidth=0, nameYoffs=0, nextYoffs=0; // used as temporary values for 'show two lines' option + std::string text = ""; + time_t now = time(0); std::string event_name = "", next_event_name = ""; - int event_begin = 0, event_duration = 0; + int event_begin = 0, event_duration = 0, xlpos = m_itemsize.width(), ctrlHeight=m_itemheight, yoffs=0; bool is_event = isPlayable && service_info && !service_info->getEvent(*m_cursor, evt); - if (is_event) - { - event_name = evt->getEventName(); - event_begin = evt->getBeginTime(); - event_duration = evt->getDuration(); - if (m_show_two_lines == 2 && event_begin > 0 && !service_info->getEvent(*m_cursor, evt_next, (event_begin + event_duration))) - next_event_name = evt_next->getEventName(); - } + if (m_visual_mode == visSkinDefined) { + if (is_event){ + event_name = evt->getEventName(); + } + if (!event_name.empty()) { + ctrlHeight = m_itemheight/2; + yoffs = 5; + } + if (!isMarker && !isDirectory) { + ePtr &pixmap = + service_res_str == "1f" ? m_pixmaps[pic4K] : + (service_res_str == "19" || service_res_str == "11") ? m_pixmaps[picHD] : m_pixmaps[picSD]; + + if (pixmap) + { + eSize pixmap_size = pixmap->size(); + xlpos -= 15 + pixmap_size.width(); + eRect res_area = eRect(xlpos, offset.y() + yoffs + (ctrlHeight - pixmap_size.height())/2, pixmap_size.width(), pixmap_size.height()); + painter.clip(res_area); + painter.blit(pixmap, ePoint(res_area.left(), res_area.top()), res_area, gPainter::BT_ALPHABLEND); + painter.clippop(); + } - for (int e = 0; e != celServiceTypePixmap; ++e) - { - if (m_element_font[e]) - { - int flags=gPainter::RT_VALIGN_CENTER; - int yoffs = 0; - eRect area = m_element_position[e]; - std::string text = ""; - switch (e) + int orbpos = m_cursor->getUnsignedData(4) >> 16; + const char *filename = ref.path.c_str(); + ePtr &pixmap_system = + (m_cursor->flags & eServiceReference::isGroup) ? m_pixmaps[picServiceGroup] : + (strstr(filename, "://")) ? m_pixmaps[picStream] : + (orbpos == 0xFFFF) ? m_pixmaps[picDVB_C] : + (orbpos == 0xEEEE) ? m_pixmaps[picDVB_T] : m_pixmaps[picDVB_S]; + + if (pixmap_system) { - case celServiceNumber: + eSize pixmap_size = pixmap_system->size(); + xlpos -= 15 + pixmap_size.width(); + eRect area = eRect(xlpos, offset.y() + yoffs + (ctrlHeight - pixmap_size.height())/2, pixmap_size.width(), pixmap_size.height()); + painter.clip(area); + painter.blit(pixmap_system, ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.clippop(); + } + + if (m_pixmaps[picCrypto] && service_info && service_info->isCrypted()) { - if (area.width() <= 0) - continue; // no point in going on if we won't paint anything + eSize pixmap_size = m_pixmaps[picCrypto]->size(); + xlpos -= 15 + pixmap_size.width(); + eRect area = eRect(xlpos, offset.y() + yoffs + (ctrlHeight - pixmap_size.height())/2, pixmap_size.width(), pixmap_size.height()); + painter.clip(area); + painter.blit(m_pixmaps[picCrypto], ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.clippop(); + } - if( m_cursor->getChannelNum() == 0 ) - continue; + if (m_pixmaps[picBackup] && isBackupAvailable) + { + eSize pixmap_size = m_pixmaps[picBackup]->size(); + xlpos -= 15 + pixmap_size.width(); + eRect area = eRect(xlpos, offset.y() + yoffs + (ctrlHeight - pixmap_size.height())/2, pixmap_size.width(), pixmap_size.height()); + painter.clip(area); + painter.blit(m_pixmaps[picBackup], ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.clippop(); + } - char buffer[15]; - snprintf(buffer, sizeof(buffer), "%d", m_cursor->getChannelNum() ); - text = buffer; - flags|=gPainter::RT_HALIGN_RIGHT; - if (isPlayable && serviceFallback && selected && m_color_set[serviceSelectedFallback]) - painter.setForegroundColor(m_color[serviceSelectedFallback]); - break; + if (m_pixmaps[picCatchup] && catchUpDays > 0) + { + eSize pixmap_size = m_pixmaps[picCatchup]->size(); + xlpos -= 15 + pixmap_size.width(); + eRect area = eRect(xlpos, offset.y() + yoffs + (ctrlHeight - pixmap_size.height())/2, pixmap_size.width(), pixmap_size.height()); + painter.clip(area); + painter.blit(m_pixmaps[picCatchup], ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.clippop(); } - case celServiceName: + + if (m_pixmaps[picRecord] && isRecorded) { - if (service_info) - service_info->getName(*m_cursor, text); - if (!isPlayable) - { - area.setWidth(area.width() + m_element_position[celServiceEventProgressbar].width() + m_nonplayable_margins); - if (m_element_position[celServiceEventProgressbar].left() == 0) - area.setLeft(0); - if (m_element_position[celServiceNumber].width() && m_element_position[celServiceEventProgressbar].left() == m_element_position[celServiceNumber].width() + m_nonplayable_margins) - area.setLeft(m_element_position[celServiceNumber].width() + m_nonplayable_margins); - } - if (!(m_record_indicator_mode == 3 && isRecorded) && isPlayable && serviceFallback && selected && m_color_set[serviceSelectedFallback]) - painter.setForegroundColor(m_color[serviceSelectedFallback]); - break; + eSize pixmap_size = m_pixmaps[picRecord]->size(); + xlpos -= 15 + pixmap_size.width(); + eRect area = eRect(xlpos, offset.y() + yoffs + (ctrlHeight - pixmap_size.height())/2, pixmap_size.width(), pixmap_size.height()); + painter.clip(area); + painter.blit(m_pixmaps[picRecord], ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.clippop(); } - case celServiceInfo: + } + ePtr piconPixmap; + bool isPIconSVG = false; + if (isPlayable && PyCallable_Check(m_GetPiconNameFunc)) + { + ePyObject pArgs = PyTuple_New(1); + PyTuple_SET_ITEM(pArgs, 0, PyUnicode_FromString(ref.toString().c_str())); + ePyObject pRet = PyObject_CallObject(m_GetPiconNameFunc, pArgs); + Py_DECREF(pArgs); + if (pRet) { - if (!event_name.empty()) + if (PyUnicode_Check(pRet)) { - text = event_name; - std::replace(text.begin(), text.end(), '\n', ' '); - if (serviceAvail) - { - if (!selected && m_color_set[eventForeground]) - { - painter.setForegroundColor(m_color[eventForeground]); - EventProgressbarColor = m_color[eventForeground]; - } - else if (selected && m_color_set[eventForegroundSelected]) - { - painter.setForegroundColor(m_color[eventForegroundSelected]); - EventProgressbarColor = m_color[eventForegroundSelected]; - } - else - painter.setForegroundColor(gRGB(0xe7b53f)); - - if (serviceFallback && !selected && m_color_set[eventForegroundFallback]) // fallback receiver - { - painter.setForegroundColor(m_color[eventForegroundFallback]); - EventProgressbarColor = m_color[eventForegroundFallback]; - } - else if (serviceFallback && selected && m_color_set[eventForegroundSelectedFallback]) - { - painter.setForegroundColor(m_color[eventForegroundSelectedFallback]); - EventProgressbarColor = m_color[eventForegroundSelectedFallback]; - } + std::string piconFilename = PyUnicode_AsUTF8(pRet); + if (endsWith(piconFilename, ".svg")) { + isPIconSVG = true; } - break; + if (!piconFilename.empty()) + loadImage(piconPixmap, piconFilename.c_str(), 0, isPIconSVG ? 125 : 0); } - continue; + Py_DECREF(pRet); + } + } + xoffs = xoffset + 16; + if (PyCallable_Check(m_GetPiconNameFunc) and (piconPixmap)) + { + eRect piconArea = eRect(xoffs, offset.y(), 125, m_itemheight); + /* PIcons are usually about 100:60. Make it a + * bit wider in case the icons are diffently + * shaped, and to add a bit of margin between + * icon and text. */ + int pflags = gPainter::BT_ALPHABLEND | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER; + if (!isPIconSVG) { + pflags = gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER; } - case celServiceNextInfo: + if (piconPixmap) { - if (!next_event_name.empty()) + painter.clip(piconArea); + if (isPIconSVG) { + painter.blit(piconPixmap, + eRect(xoffs, offset.y(), 125, m_itemheight), + eRect(), + pflags + ); + } else { + painter.blitScale(piconPixmap, + eRect(xoffs, offset.y(), 125, m_itemheight), + piconArea, + pflags); + } + painter.clippop(); + } + } + + if (isMarker || isDirectory) { + ePtr &pixmap_mDir = isMarker ? m_pixmaps[picMarker] : isDirectory ? m_pixmaps[picFolder] : m_pixmaps[picElements]; + if (pixmap_mDir) { + eSize pixmap_size = pixmap_mDir->size(); + eRect area = eRect(xoffs, offset.y() + (ctrlHeight - pixmap_size.height())/2, pixmap_size.width(), pixmap_size.height()); + painter.clip(area); + painter.blit(pixmap_mDir, ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.clippop(); + + xoffs += pixmap_size.width() + 16 + 8; + } + } else { + xoffs += 125 + 16 + 8; + } + + // channel number + name + if (service_info) + service_info->getName(ref, text); + if (!isMarker && !isDirectory) { + std::string chNum = ""; + if (m_cursor->getChannelNum() != 0) { + char buffer[15]; + snprintf(buffer, sizeof(buffer), "%d", m_cursor->getChannelNum() ); + chNum = buffer; + } + if (chNum != "") text = chNum + " • " + text; + } + + ePtr para = new eTextPara(eRect(0, 0, m_itemsize.width(), m_itemheight/2)); + para->setFont(m_element_font[celServiceName]); + para->renderString(text.c_str()); + eRect bbox = para->getBoundBox(); + painter.renderPara(para, ePoint(xoffs, offset.y() + yoffs + ((ctrlHeight - bbox.height())/2))); + + // event name + if (is_event) + { + event_name = evt->getEventName(); + event_begin = evt->getBeginTime(); + event_duration = evt->getDuration(); + int timeLeft = event_begin + event_duration - now; + + if (!event_name.empty()) + { + //--------------------------------------------------- Event Progressbar ----------------------------------------------------------------- + int pb_xpos = xoffs; + int pb_ypos = offset.y() + m_itemheight/2 + (m_itemheight/2 - m_progressbar_height - 2 * m_progressbar_border_width) / 2; + int pb_width = 75 - 2 * m_progressbar_border_width; + gRGB ProgressbarBorderColor = 0xdfdfdf; + int evt_done = pb_width * (now - event_begin) / event_duration; + + // the progress data... + eRect tmp = eRect(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width, evt_done, m_progressbar_height); + ePtr &pixmap = m_pixmaps[picServiceEventProgressbar]; + if (pixmap) { + painter.clip(tmp); + painter.blit(pixmap, ePoint(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width), tmp, gPainter::BT_ALPHABLEND); + painter.clippop(); + } + else { + if (!selected && m_color_set[serviceEventProgressbarColor]) + painter.setForegroundColor(m_color[serviceEventProgressbarColor]); + else if (selected && m_color_set[serviceEventProgressbarColorSelected]) + painter.setForegroundColor(m_color[serviceEventProgressbarColorSelected]); + else if (m_show_two_lines == 2) + painter.setForegroundColor(EventProgressbarColor); + painter.fill(tmp); + } + + // the progressbar border + if (!selected) { + if (m_color_set[serviceEventProgressbarBorderColor]) + ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColor]; + else if (m_color_set[eventborderForeground]) + ProgressbarBorderColor = m_color[eventborderForeground]; + } + else { /* !selected */ + if (m_color_set[serviceEventProgressbarBorderColorSelected]) + ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColorSelected]; + else if (m_color_set[eventborderForegroundSelected]) + ProgressbarBorderColor = m_color[eventborderForegroundSelected]; + } + painter.setForegroundColor(ProgressbarBorderColor); + + if (m_progressbar_border_width) + { + painter.fill(eRect(pb_xpos, pb_ypos, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); + painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width + m_progressbar_height, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); + painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); + painter.fill(eRect(pb_xpos + m_progressbar_border_width + pb_width, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); + } + else + painter.fill(eRect(pb_xpos + evt_done, pb_ypos, pb_width - evt_done, m_progressbar_height)); + + xoffs += pb_width + 16; + + //------------------------------------------------- Event Name + Remaining ---------------------------------------------------- + text = event_name; + std::replace(text.begin(), text.end(), '\n', ' '); + if (serviceAvail) { - text = m_next_title + next_event_name; - std::replace(text.begin(), text.end(), '\n', ' '); - if (serviceAvail) + if (!selected && m_color_set[eventForeground]) { - if (!selected && m_color_set[eventNextForeground]) - painter.setForegroundColor(m_color[eventNextForeground]); - else if (selected && m_color_set[eventNextForegroundSelected]) - painter.setForegroundColor(m_color[eventNextForegroundSelected]); - else - painter.setForegroundColor(gRGB(0x787878)); + painter.setForegroundColor(m_color[eventForeground]); + EventProgressbarColor = m_color[eventForeground]; + } + else if (selected && m_color_set[eventForegroundSelected]) + { + painter.setForegroundColor(m_color[eventForegroundSelected]); + EventProgressbarColor = m_color[eventForegroundSelected]; + } + else + painter.setForegroundColor(gRGB(0xe7b53f)); - if (serviceFallback && !selected && m_color_set[eventNextForegroundFallback]) // fallback receiver - painter.setForegroundColor(m_color[eventNextForegroundFallback]); - else if (serviceFallback && selected && m_color_set[eventNextForegroundSelectedFallback]) - painter.setForegroundColor(m_color[eventNextForegroundSelectedFallback]); + if (serviceFallback && !selected && m_color_set[eventForegroundFallback]) // fallback receiver + { + painter.setForegroundColor(m_color[eventForegroundFallback]); + EventProgressbarColor = m_color[eventForegroundFallback]; + } + else if (serviceFallback && selected && m_color_set[eventForegroundSelectedFallback]) + { + painter.setForegroundColor(m_color[eventForegroundSelectedFallback]); + EventProgressbarColor = m_color[eventForegroundSelectedFallback]; } - break; } - continue; + + //------------------------------------------------ Event remaining ------------------------------------------------------------------------ + std::string timeLeft_str = ""; + char buffer[15]; + snprintf(buffer, sizeof(buffer), "+%d min", timeLeft/60 ); + timeLeft_str = buffer; + ePtr paraLeft = new eTextPara(eRect(0, 0, m_itemsize.width(), m_itemheight/2)); + paraLeft->setFont(m_element_font[celServiceInfo]); + paraLeft->renderString(timeLeft_str.c_str()); + eRect bboxtLeft = paraLeft->getBoundBox(); + painter.renderPara(paraLeft, ePoint(m_itemsize.width() - bboxtLeft.width() - 15, offset.y() - 2 + m_itemheight/2 + ((m_itemheight/2 - bboxtLeft.height())/2))); + + //------------------------------------------------- Event name ------------------------------------------------------------------------------ + ePtr para = new eTextPara(eRect(0, 0, m_itemsize.width() - xoffs - bboxtLeft.width() - 25, m_itemheight/2)); + para->setFont(m_element_font[celServiceInfo]); + para->renderString(text.c_str()); + eRect bbox = para->getBoundBox(); + painter.renderPara(para, ePoint(xoffs, offset.y() - 2 + m_itemheight/2 + ((m_itemheight/2 - bbox.height())/2))); } - case celServiceEventProgressbar: + } + } else { + if (is_event) + { + event_name = evt->getEventName(); + event_begin = evt->getBeginTime(); + event_duration = evt->getDuration(); + if (m_show_two_lines == 2 && event_begin > 0 && !service_info->getEvent(*m_cursor, evt_next, (event_begin + event_duration))) + next_event_name = evt_next->getEventName(); + } + + for (int e = 0; e != celServiceTypePixmap; ++e) + { + if (m_element_font[e]) { - if (area.width() > 0 && is_event) + int flags=gPainter::RT_VALIGN_CENTER; + int yoffs = 0; + eRect area = m_element_position[e]; + std::string text = ""; + switch (e) + { + case celServiceNumber: { + if (area.width() <= 0) + continue; // no point in going on if we won't paint anything + + if( m_cursor->getChannelNum() == 0 ) + continue; + char buffer[15]; - snprintf(buffer, sizeof(buffer), "%d %%", (int)(100 * (now - event_begin) / event_duration)); + snprintf(buffer, sizeof(buffer), "%d", m_cursor->getChannelNum() ); text = buffer; flags|=gPainter::RT_HALIGN_RIGHT; + if (isPlayable && serviceFallback && selected && m_color_set[serviceSelectedFallback]) + painter.setForegroundColor(m_color[serviceSelectedFallback]); break; } - continue; - } - } - - eRect tmp = area; - int xoffs = 0; - ePtr piconPixmap; + case celServiceName: + { + if (service_info) + service_info->getName(*m_cursor, text); + if (!isPlayable) + { + area.setWidth(area.width() + m_element_position[celServiceEventProgressbar].width() + m_nonplayable_margins); + if (m_element_position[celServiceEventProgressbar].left() == 0) + area.setLeft(0); + if (m_element_position[celServiceNumber].width() && m_element_position[celServiceEventProgressbar].left() == m_element_position[celServiceNumber].width() + m_nonplayable_margins) + area.setLeft(m_element_position[celServiceNumber].width() + m_nonplayable_margins); + } + if (!(m_record_indicator_mode == 3 && isRecorded) && isPlayable && serviceFallback && selected && m_color_set[serviceSelectedFallback]) + painter.setForegroundColor(m_color[serviceSelectedFallback]); + break; + } + case celServiceInfo: + { + if (!event_name.empty()) + { + text = event_name; + std::replace(text.begin(), text.end(), '\n', ' '); + if (serviceAvail) + { + if (!selected && m_color_set[eventForeground]) + { + painter.setForegroundColor(m_color[eventForeground]); + EventProgressbarColor = m_color[eventForeground]; + } + else if (selected && m_color_set[eventForegroundSelected]) + { + painter.setForegroundColor(m_color[eventForegroundSelected]); + EventProgressbarColor = m_color[eventForegroundSelected]; + } + else + painter.setForegroundColor(gRGB(0xe7b53f)); - if (e == celServiceName) - { - //picon stuff - if (isPlayable && PyCallable_Check(m_GetPiconNameFunc)) + if (serviceFallback && !selected && m_color_set[eventForegroundFallback]) // fallback receiver + { + painter.setForegroundColor(m_color[eventForegroundFallback]); + EventProgressbarColor = m_color[eventForegroundFallback]; + } + else if (serviceFallback && selected && m_color_set[eventForegroundSelectedFallback]) + { + painter.setForegroundColor(m_color[eventForegroundSelectedFallback]); + EventProgressbarColor = m_color[eventForegroundSelectedFallback]; + } + } + break; + } + continue; + } + case celServiceNextInfo: { - ePyObject pArgs = PyTuple_New(1); - PyTuple_SET_ITEM(pArgs, 0, PyUnicode_FromString(ref.toString().c_str())); - ePyObject pRet = PyObject_CallObject(m_GetPiconNameFunc, pArgs); - Py_DECREF(pArgs); - if (pRet) + if (!next_event_name.empty()) { - if (PyUnicode_Check(pRet)) + text = m_next_title + next_event_name; + std::replace(text.begin(), text.end(), '\n', ' '); + if (serviceAvail) { - std::string piconFilename = PyUnicode_AsUTF8(pRet); - if (!piconFilename.empty()) - loadImage(piconPixmap, piconFilename.c_str()); + if (!selected && m_color_set[eventNextForeground]) + painter.setForegroundColor(m_color[eventNextForeground]); + else if (selected && m_color_set[eventNextForegroundSelected]) + painter.setForegroundColor(m_color[eventNextForegroundSelected]); + else + painter.setForegroundColor(gRGB(0x787878)); + + if (serviceFallback && !selected && m_color_set[eventNextForegroundFallback]) // fallback receiver + painter.setForegroundColor(m_color[eventNextForegroundFallback]); + else if (serviceFallback && selected && m_color_set[eventNextForegroundSelectedFallback]) + painter.setForegroundColor(m_color[eventNextForegroundSelectedFallback]); } - Py_DECREF(pRet); + break; } + continue; + } + case celServiceEventProgressbar: + { + if (area.width() > 0 && is_event) + { + char buffer[15]; + snprintf(buffer, sizeof(buffer), "%d %%", (int)(100 * (now - event_begin) / event_duration)); + text = buffer; + flags|=gPainter::RT_HALIGN_RIGHT; + break; + } + continue; + } } - xoffs = xoffset; - tmp.setWidth(((!isPlayable || m_column_width == -1 || (!piconPixmap && !m_column_width)) ? tmp.width() : m_column_width) - xoffs); - } - - ePtr para = new eTextPara(tmp); - para->setFont(m_element_font[e]); - para->renderString(text.c_str()); - if (e == celServiceName) - { - eRect bbox = para->getBoundBox(); + eRect tmp = area; + int xoffs = 0; + ePtr piconPixmap; - int servicenameWidth = ((!isPlayable || m_column_width == -1 || (!piconPixmap && !m_column_width)) ? bbox.width() : m_column_width); - m_element_position[celServiceInfo].setLeft(area.left() + servicenameWidth + m_items_distances + xoffs); - m_element_position[celServiceInfo].setTop(area.top()); - m_element_position[celServiceInfo].setWidth(area.width() - (servicenameWidth + m_items_distances + xoffs)); - m_element_position[celServiceInfo].setHeight(area.height()); - if (!next_event_name.empty()) - m_element_position[celServiceNextInfo].setHeight(area.height()); - nameLeft = area.left(); - nameWidth = area.width(); - - if (isPlayable) + if (e == celServiceName) { //picon stuff - if (PyCallable_Check(m_GetPiconNameFunc) and (m_column_width || piconPixmap)) + if (isPlayable && PyCallable_Check(m_GetPiconNameFunc)) { - eRect area = m_element_position[celServiceInfo]; - /* PIcons are usually about 100:60. Make it a - * bit wider in case the icons are diffently - * shaped, and to add a bit of margin between - * icon and text. */ - const int iconWidth = area.height() * 9 / (m_show_two_lines > 0 ? 10 : 5); - m_element_position[celServiceInfo].setLeft(area.left() + iconWidth); - m_element_position[celServiceInfo].setWidth(area.width() - iconWidth); - area = m_element_position[celServiceName]; - xoffs += iconWidth; - if (piconPixmap) + ePyObject pArgs = PyTuple_New(1); + PyTuple_SET_ITEM(pArgs, 0, PyUnicode_FromString(ref.toString().c_str())); + ePyObject pRet = PyObject_CallObject(m_GetPiconNameFunc, pArgs); + Py_DECREF(pArgs); + if (pRet) { - area.moveBy(offset); - painter.clip(area); - painter.blitScale(piconPixmap, - eRect(area.left(), area.top(), iconWidth, area.height()), - area, - gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER); - painter.clippop(); + if (PyUnicode_Check(pRet)) + { + std::string piconFilename = PyUnicode_AsUTF8(pRet); + if (!piconFilename.empty()) + loadImage(piconPixmap, piconFilename.c_str()); + } + Py_DECREF(pRet); } } + xoffs = xoffset; + tmp.setWidth(((!isPlayable || m_column_width == -1 || (!piconPixmap && !m_column_width)) ? tmp.width() : m_column_width) - xoffs); + } - //record icon stuff part1 - int rec_pixmap_xoffs = 0; - if (isRecorded && m_record_indicator_mode == 1 && m_pixmaps[picRecord]) - rec_pixmap_xoffs = m_pixmaps[picRecord]->size().width() + m_items_distances; + ePtr para = new eTextPara(tmp); + para->setFont(m_element_font[e]); + para->renderString(text.c_str()); - //service type marker stuff - if (m_servicetype_icon_mode) + if (e == celServiceName) + { + eRect bbox = para->getBoundBox(); + + int servicenameWidth = ((!isPlayable || m_column_width == -1 || (!piconPixmap && !m_column_width)) ? bbox.width() : m_column_width); + m_element_position[celServiceInfo].setLeft(area.left() + servicenameWidth + m_items_distances + xoffs); + m_element_position[celServiceInfo].setTop(area.top()); + m_element_position[celServiceInfo].setWidth(area.width() - (servicenameWidth + m_items_distances + xoffs)); + m_element_position[celServiceInfo].setHeight(area.height()); + if (!next_event_name.empty()) + m_element_position[celServiceNextInfo].setHeight(area.height()); + nameLeft = area.left(); + nameWidth = area.width(); + + if (isPlayable) { - int orbpos = m_cursor->getUnsignedData(4) >> 16; - const char *filename = ref.path.c_str(); - ePtr &pixmap = - (m_cursor->flags & eServiceReference::isGroup) ? m_pixmaps[picServiceGroup] : - (strstr(filename, "://")) ? m_pixmaps[picStream] : - (orbpos == 0xFFFF) ? m_pixmaps[picDVB_C] : - (orbpos == 0xEEEE) ? m_pixmaps[picDVB_T] : m_pixmaps[picDVB_S]; - if (pixmap) + //picon stuff + if (PyCallable_Check(m_GetPiconNameFunc) and (m_column_width || piconPixmap)) { - eSize pixmap_size = pixmap->size(); eRect area = m_element_position[celServiceInfo]; - m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances); + /* PIcons are usually about 100:60. Make it a + * bit wider in case the icons are diffently + * shaped, and to add a bit of margin between + * icon and text. */ + const int iconWidth = area.height() * 9 / (m_show_two_lines > 0 ? 10 : 5); + m_element_position[celServiceInfo].setLeft(area.left() + iconWidth); + m_element_position[celServiceInfo].setWidth(area.width() - iconWidth); + area = m_element_position[celServiceName]; + xoffs += iconWidth; + if (piconPixmap) + { + area.moveBy(offset); + painter.clip(area); + painter.blitScale(piconPixmap, + eRect(area.left(), area.top(), iconWidth, area.height()), + area, + gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER); + painter.clippop(); + } + } + + //record icon stuff part1 + int rec_pixmap_xoffs = 0; + if (isRecorded && m_record_indicator_mode == 1 && m_pixmaps[picRecord]) + rec_pixmap_xoffs = m_pixmaps[picRecord]->size().width() + m_items_distances; + + //service type marker stuff + if (m_servicetype_icon_mode) + { + int orbpos = m_cursor->getUnsignedData(4) >> 16; + const char *filename = ref.path.c_str(); + ePtr &pixmap = + (m_cursor->flags & eServiceReference::isGroup) ? m_pixmaps[picServiceGroup] : + (strstr(filename, "://")) ? m_pixmaps[picStream] : + (orbpos == 0xFFFF) ? m_pixmaps[picDVB_C] : + (orbpos == 0xEEEE) ? m_pixmaps[picDVB_T] : m_pixmaps[picDVB_S]; + if (pixmap) + { + eSize pixmap_size = pixmap->size(); + eRect area = m_element_position[celServiceInfo]; + m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); + m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances); + int offs = rec_pixmap_xoffs; + if (m_servicetype_icon_mode == 1) + { + area = m_element_position[celServiceName]; + offs = xoffs; + xoffs += pixmap_size.width() + m_items_distances; + } + else if (m_crypto_icon_mode == 1 && m_pixmaps[picCrypto]) + offs = offs + m_pixmaps[picCrypto]->size().width() + m_items_distances; + int correction = (!event_name.empty() && m_show_two_lines > 0 && m_servicetype_icon_mode == 2) ? (((area.height()/2) - pixmap_size.height()) / 2) + 2 : (area.height() - pixmap_size.height()) / 2; + area.moveBy(offset); + painter.clip(area); + painter.blit(pixmap, ePoint(area.left() + offs, offset.y() + correction), area, gPainter::BT_ALPHABLEND); + painter.clippop(); + } + } + + //crypto icon stuff + if (m_crypto_icon_mode && m_pixmaps[picCrypto]) + { + eSize pixmap_size = m_pixmaps[picCrypto]->size(); + eRect area = m_element_position[celServiceInfo]; int offs = rec_pixmap_xoffs; - if (m_servicetype_icon_mode == 1) + if (m_crypto_icon_mode == 1) { + m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); + m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances); area = m_element_position[celServiceName]; offs = xoffs; xoffs += pixmap_size.width() + m_items_distances; } - else if (m_crypto_icon_mode == 1 && m_pixmaps[picCrypto]) - offs = offs + m_pixmaps[picCrypto]->size().width() + m_items_distances; - int correction = (!event_name.empty() && m_show_two_lines > 0 && m_servicetype_icon_mode == 2) ? (((area.height()/2) - pixmap_size.height()) / 2) + 2 : (area.height() - pixmap_size.height()) / 2; + int correction = (!event_name.empty() && m_show_two_lines > 0 && m_crypto_icon_mode == 2) ? (((area.height()/2) - pixmap_size.height()) / 2) + 2 : (area.height() - pixmap_size.height()) / 2; area.moveBy(offset); - painter.clip(area); - painter.blit(pixmap, ePoint(area.left() + offs, offset.y() + correction), area, gPainter::BT_ALPHABLEND); - painter.clippop(); + if (service_info && service_info->isCrypted()) + { + if (m_crypto_icon_mode == 2) + { + m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); + m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances); + } + painter.clip(area); + painter.blit(m_pixmaps[picCrypto], ePoint(area.left() + offs, offset.y() + correction), area, gPainter::BT_ALPHABLEND); + painter.clippop(); + } } - } - //crypto icon stuff - if (m_crypto_icon_mode && m_pixmaps[picCrypto]) - { - eSize pixmap_size = m_pixmaps[picCrypto]->size(); - eRect area = m_element_position[celServiceInfo]; - int offs = rec_pixmap_xoffs; - if (m_crypto_icon_mode == 1) - { - m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances); - area = m_element_position[celServiceName]; - offs = xoffs; - xoffs += pixmap_size.width() + m_items_distances; - } - int correction = (!event_name.empty() && m_show_two_lines > 0 && m_crypto_icon_mode == 2) ? (((area.height()/2) - pixmap_size.height()) / 2) + 2 : (area.height() - pixmap_size.height()) / 2; - area.moveBy(offset); - if (service_info && service_info->isCrypted()) + //record icon stuff part2 + if (isRecorded && m_record_indicator_mode < 3 && m_pixmaps[picRecord]) { - if (m_crypto_icon_mode == 2) + eSize pixmap_size = m_pixmaps[picRecord]->size(); + eRect area = m_element_position[celServiceInfo]; + int offs = 0; + if (m_record_indicator_mode == 1) + { + m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); + m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances); + area = m_element_position[celServiceName]; + offs = xoffs; + xoffs += pixmap_size.width() + m_items_distances; + } + int correction = (!event_name.empty() && m_show_two_lines > 0 && m_record_indicator_mode == 2) ? (((area.height()/2) - pixmap_size.height()) / 2) + 2 : (area.height() - pixmap_size.height()) / 2; + area.moveBy(offset); + if (m_record_indicator_mode == 2) { m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances); } painter.clip(area); - painter.blit(m_pixmaps[picCrypto], ePoint(area.left() + offs, offset.y() + correction), area, gPainter::BT_ALPHABLEND); + painter.blit(m_pixmaps[picRecord], ePoint(area.left() + offs, offset.y() + correction), area, gPainter::BT_ALPHABLEND); painter.clippop(); } - } - - //record icon stuff part2 - if (isRecorded && m_record_indicator_mode < 3 && m_pixmaps[picRecord]) - { - eSize pixmap_size = m_pixmaps[picRecord]->size(); - eRect area = m_element_position[celServiceInfo]; - int offs = 0; - if (m_record_indicator_mode == 1) - { - m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances); - area = m_element_position[celServiceName]; - offs = xoffs; - xoffs += pixmap_size.width() + m_items_distances; - } - int correction = (!event_name.empty() && m_show_two_lines > 0 && m_record_indicator_mode == 2) ? (((area.height()/2) - pixmap_size.height()) / 2) + 2 : (area.height() - pixmap_size.height()) / 2; - area.moveBy(offset); - if (m_record_indicator_mode == 2) + if (m_show_two_lines > 0) { - m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances); + if(!next_event_name.empty()) + { + m_element_position[celServiceNextInfo].setLeft(nameLeft + xoffs); + m_element_position[celServiceNextInfo].setWidth(nameWidth - xoffs); + } + else + { + m_element_position[celServiceInfo].setLeft(nameLeft + xoffs); + m_element_position[celServiceInfo].setWidth(nameWidth - xoffs); + } } - painter.clip(area); - painter.blit(m_pixmaps[picRecord], ePoint(area.left() + offs, offset.y() + correction), area, gPainter::BT_ALPHABLEND); - painter.clippop(); } - if (m_show_two_lines > 0) + } + + if (flags & gPainter::RT_HALIGN_RIGHT) + para->realign(eTextPara::dirRight); + else if (flags & gPainter::RT_HALIGN_CENTER) + para->realign(eTextPara::dirCenter); + else if (flags & gPainter::RT_HALIGN_BLOCK) + para->realign(eTextPara::dirBlock); + + if (flags & gPainter::RT_VALIGN_CENTER) + { + eRect bbox = para->getBoundBox(); + if (!event_name.empty() && m_show_two_lines > 0 && (e == celServiceName || (!next_event_name.empty() && e == celServiceInfo))) { - if(!next_event_name.empty()) - { - m_element_position[celServiceNextInfo].setLeft(nameLeft + xoffs); - m_element_position[celServiceNextInfo].setWidth(nameWidth - xoffs); - } + yoffs = ((area.height()/2) - bbox.height()) / 2 - bbox.top(); + if (e == celServiceName) + nameYoffs = yoffs/2; else - { - m_element_position[celServiceInfo].setLeft(nameLeft + xoffs); - m_element_position[celServiceInfo].setWidth(nameWidth - xoffs); - } + nextYoffs = (area.height()/2) + (((area.height()/2) - bbox.height()) / 2) - (bbox.top() - nameYoffs); } + else if (!event_name.empty() && m_show_two_lines > 0 && ((next_event_name.empty() && e == celServiceInfo) || (!next_event_name.empty() && e == celServiceNextInfo))) + yoffs = (e == celServiceNextInfo ? nextYoffs : (area.height()/2) + (((area.height()/2) - bbox.height()) / 2) - (bbox.top() - nameYoffs)); + else + yoffs = (area.height() - bbox.height())/2 - bbox.top(); } - } - if (flags & gPainter::RT_HALIGN_RIGHT) - para->realign(eTextPara::dirRight); - else if (flags & gPainter::RT_HALIGN_CENTER) - para->realign(eTextPara::dirCenter); - else if (flags & gPainter::RT_HALIGN_BLOCK) - para->realign(eTextPara::dirBlock); - - if (flags & gPainter::RT_VALIGN_CENTER) + painter.renderPara(para, offset+ePoint(xoffs, yoffs)); + } + else if ((e == celFolderPixmap && m_cursor->flags & eServiceReference::isDirectory) || + (e == celMarkerPixmap && m_cursor->flags & eServiceReference::isMarker && + !(m_cursor->flags & eServiceReference::isNumberedMarker))) { - eRect bbox = para->getBoundBox(); - if (!event_name.empty() && m_show_two_lines > 0 && (e == celServiceName || (!next_event_name.empty() && e == celServiceInfo))) + ePtr &pixmap = + (e == celFolderPixmap) ? m_pixmaps[picFolder] : m_pixmaps[picMarker]; + if (pixmap) { - yoffs = ((area.height()/2) - bbox.height()) / 2 - bbox.top(); - if (e == celServiceName) - nameYoffs = yoffs/2; + eSize pixmap_size = pixmap->size(); + eRect area; + if (e == celFolderPixmap || m_element_position[celServiceNumber].width() < pixmap_size.width()) + { + area = m_element_position[celServiceName]; + if (m_element_position[celServiceEventProgressbar].left() == 0) + area.setLeft(0); + xoffset = pixmap_size.width() + m_items_distances; + } else - nextYoffs = (area.height()/2) + (((area.height()/2) - bbox.height()) / 2) - (bbox.top() - nameYoffs); + area = m_element_position[celServiceNumber]; + int correction = (area.height() - pixmap_size.height()) / 2; + area.moveBy(offset); + painter.clip(area); + painter.blit(pixmap, ePoint(area.left(), offset.y() + correction), area, gPainter::BT_ALPHABLEND); + painter.clippop(); } - else if (!event_name.empty() && m_show_two_lines > 0 && ((next_event_name.empty() && e == celServiceInfo) || (!next_event_name.empty() && e == celServiceNextInfo))) - yoffs = (e == celServiceNextInfo ? nextYoffs : (area.height()/2) + (((area.height()/2) - bbox.height()) / 2) - (bbox.top() - nameYoffs)); - else - yoffs = (area.height() - bbox.height())/2 - bbox.top(); } - - painter.renderPara(para, offset+ePoint(xoffs, yoffs)); } - else if ((e == celFolderPixmap && m_cursor->flags & eServiceReference::isDirectory) || - (e == celMarkerPixmap && m_cursor->flags & eServiceReference::isMarker && - !(m_cursor->flags & eServiceReference::isNumberedMarker))) + + eRect area = m_element_position[celServiceEventProgressbar]; + if (area.width() > 0 && evt && !m_element_font[celServiceEventProgressbar]) { - ePtr &pixmap = - (e == celFolderPixmap) ? m_pixmaps[picFolder] : m_pixmaps[picMarker]; - if (pixmap) - { - eSize pixmap_size = pixmap->size(); - eRect area; - if (e == celFolderPixmap || m_element_position[celServiceNumber].width() < pixmap_size.width()) - { - area = m_element_position[celServiceName]; - if (m_element_position[celServiceEventProgressbar].left() == 0) - area.setLeft(0); - xoffset = pixmap_size.width() + m_items_distances; - } - else - area = m_element_position[celServiceNumber]; - int correction = (area.height() - pixmap_size.height()) / 2; - area.moveBy(offset); - painter.clip(area); - painter.blit(pixmap, ePoint(area.left(), offset.y() + correction), area, gPainter::BT_ALPHABLEND); + int pb_xpos = area.left(); + int pb_ypos = offset.y() + (m_itemsize.height() - m_progressbar_height - 2 * m_progressbar_border_width) / 2; + int pb_width = area.width()- 2 * m_progressbar_border_width; + gRGB ProgressbarBorderColor = 0xdfdfdf; + int evt_done = pb_width * (now - event_begin) / event_duration; + + // the progress data... + eRect tmp = eRect(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width, evt_done, m_progressbar_height); + ePtr &pixmap = m_pixmaps[picServiceEventProgressbar]; + if (pixmap) { + painter.clip(tmp); + painter.blit(pixmap, ePoint(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width), tmp, gPainter::BT_ALPHABLEND); painter.clippop(); } - } - } + else { + if (!selected && m_color_set[serviceEventProgressbarColor]) + painter.setForegroundColor(m_color[serviceEventProgressbarColor]); + else if (selected && m_color_set[serviceEventProgressbarColorSelected]) + painter.setForegroundColor(m_color[serviceEventProgressbarColorSelected]); + else if (m_show_two_lines == 2) + painter.setForegroundColor(EventProgressbarColor); + painter.fill(tmp); + } - eRect area = m_element_position[celServiceEventProgressbar]; - if (area.width() > 0 && evt && !m_element_font[celServiceEventProgressbar]) - { - int pb_xpos = area.left(); - int pb_ypos = offset.y() + (m_itemsize.height() - m_progressbar_height - 2 * m_progressbar_border_width) / 2; - int pb_width = area.width()- 2 * m_progressbar_border_width; - gRGB ProgressbarBorderColor = 0xdfdfdf; - int evt_done = pb_width * (now - event_begin) / event_duration; - - // the progress data... - eRect tmp = eRect(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width, evt_done, m_progressbar_height); - ePtr &pixmap = m_pixmaps[picServiceEventProgressbar]; - if (pixmap) { - painter.clip(tmp); - painter.blit(pixmap, ePoint(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width), tmp, gPainter::BT_ALPHABLEND); - painter.clippop(); - } - else { - if (!selected && m_color_set[serviceEventProgressbarColor]) - painter.setForegroundColor(m_color[serviceEventProgressbarColor]); - else if (selected && m_color_set[serviceEventProgressbarColorSelected]) - painter.setForegroundColor(m_color[serviceEventProgressbarColorSelected]); - else if (m_show_two_lines == 2) - painter.setForegroundColor(EventProgressbarColor); - painter.fill(tmp); - } + // the progressbar border + if (!selected) { + if (m_color_set[serviceEventProgressbarBorderColor]) + ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColor]; + else if (m_color_set[eventborderForeground]) + ProgressbarBorderColor = m_color[eventborderForeground]; + } + else { /* !selected */ + if (m_color_set[serviceEventProgressbarBorderColorSelected]) + ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColorSelected]; + else if (m_color_set[eventborderForegroundSelected]) + ProgressbarBorderColor = m_color[eventborderForegroundSelected]; + } + painter.setForegroundColor(ProgressbarBorderColor); - // the progressbar border - if (!selected) { - if (m_color_set[serviceEventProgressbarBorderColor]) - ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColor]; - else if (m_color_set[eventborderForeground]) - ProgressbarBorderColor = m_color[eventborderForeground]; - } - else { /* !selected */ - if (m_color_set[serviceEventProgressbarBorderColorSelected]) - ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColorSelected]; - else if (m_color_set[eventborderForegroundSelected]) - ProgressbarBorderColor = m_color[eventborderForegroundSelected]; + painter.fill(eRect(pb_xpos, pb_ypos, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); + painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width + m_progressbar_height, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); + painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); + painter.fill(eRect(pb_xpos + m_progressbar_border_width + pb_width, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); } - painter.setForegroundColor(ProgressbarBorderColor); - - painter.fill(eRect(pb_xpos, pb_ypos, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); - painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width + m_progressbar_height, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); - painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); - painter.fill(eRect(pb_xpos + m_progressbar_border_width + pb_width, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); } } painter.clippop(); diff --git a/lib/service/listboxservice.h b/lib/service/listboxservice.h index 36d51362767..68d31a982e6 100644 --- a/lib/service/listboxservice.h +++ b/lib/service/listboxservice.h @@ -44,7 +44,8 @@ class eListboxServiceContent: public virtual iListboxContent enum { visModeSimple, - visModeComplex + visModeComplex, + visSkinDefined }; void setVisualMode(int mode); @@ -73,6 +74,11 @@ class eListboxServiceContent: public virtual iListboxContent picServiceEventProgressbar, picCrypto, picRecord, + pic4K, + picHD, + picSD, + picBackup, + picCatchup, picElements }; From 831269a50eee71bb22a7488159fd211f71e23c4b Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sun, 12 Nov 2023 19:12:01 +0200 Subject: [PATCH 177/401] [Added] Support for provider for IPTV services (sref starting with 1 or 4097) --- lib/dvb/metaparser.h | 2 +- lib/service/servicedvb.cpp | 14 ++++++++++++++ lib/service/servicemp3.cpp | 24 +++++++++++++++++++++++- lib/service/servicemp3.h | 1 + 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/lib/dvb/metaparser.h b/lib/dvb/metaparser.h index 8614f1a8199..45055a80617 100644 --- a/lib/dvb/metaparser.h +++ b/lib/dvb/metaparser.h @@ -40,7 +40,7 @@ class eDVBMetaParser eServiceReferenceDVB m_ref; int m_data_ok, m_time_create, m_packet_size, m_scrambled; - std::string m_name, m_description, m_tags, m_service_data; + std::string m_name, m_description, m_tags, m_service_data, m_prov; long long m_filesize, m_length; }; #endif diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index e5d97096bda..b8f0614ec37 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -388,6 +388,13 @@ RESULT eStaticServiceDVBPVRInformation::getName(const eServiceReference &ref, st } m_parser.m_name = name; } + if (!name.empty()) { + std::vector name_split = split(name, "|"); + name = name_split[0]; + if (name_split.size() > 1) { + m_parser.m_prov = name_split[1]; + } + } return 0; } @@ -460,6 +467,13 @@ std::string eStaticServiceDVBPVRInformation::getInfoString(const eServiceReferen return m_parser.m_ref.toString(); case iServiceInformation::sTags: return m_parser.m_tags; + case iServiceInformation::sProvider: + { + if (m_parser.m_prov.empty()) { + return ""; + } + return m_parser.m_prov; + } default: return ""; } diff --git a/lib/service/servicemp3.cpp b/lib/service/servicemp3.cpp index 2fa2523602c..03f3e6c0bed 100644 --- a/lib/service/servicemp3.cpp +++ b/lib/service/servicemp3.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -261,6 +262,10 @@ RESULT eStaticServiceMP3Info::getName(const eServiceReference &ref, std::string else name = ref.path; } + if (!name.empty()) { + std::vector name_split = split(name, "|"); + name = name_split[0]; + } return 0; } @@ -1199,6 +1204,14 @@ RESULT eServiceMP3::getName(std::string &name) } else name = title; + + if (!name.empty()) { + std::vector name_split = split(name, "|"); + name = name_split[0]; + if (name_split.size() > 1) { + m_prov = name_split[1]; + } + } return 0; } @@ -1326,7 +1339,16 @@ std::string eServiceMP3::getInfoString(int w) switch (w) { case sProvider: - return m_sourceinfo.is_streaming ? "IPTV" : "FILE"; + { + if (m_sourceinfo.is_streaming) { + if (m_prov.empty()) { + return "IPTV"; + } else { + return m_prov; + } + } + return "FILE"; + } case sServiceref: return m_ref.toString(); default: diff --git a/lib/service/servicemp3.h b/lib/service/servicemp3.h index 0043372a6d0..d4127adf2e5 100644 --- a/lib/service/servicemp3.h +++ b/lib/service/servicemp3.h @@ -297,6 +297,7 @@ class eServiceMP3: public iPlayableService, public iPauseableService, gdouble m_currentTrickRatio; friend class eServiceFactoryMP3; eServiceReference m_ref; + std::string m_prov; int m_buffer_size; int m_ignore_buffering_messages; bool m_is_live; From 639030fedf984cbdf0c32d7d8c70c034d7feba6f Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sun, 12 Nov 2023 19:21:47 +0200 Subject: [PATCH 178/401] [Fixed] Stream relay zap out and disabling services --- lib/python/Navigation.py | 13 ++++++++++++- lib/service/listboxservice.cpp | 12 +++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/lib/python/Navigation.py b/lib/python/Navigation.py index ab8580aebb9..eea310533b8 100644 --- a/lib/python/Navigation.py +++ b/lib/python/Navigation.py @@ -39,6 +39,7 @@ def __init__(self, nextRecordTimerAfterEventActionAuto=False, nextPowerManagerAf self.currentlyPlayingServiceReference = None self.currentlyPlayingServiceOrGroup = None self.currentlyPlayingService = None + self.currentServiceStreaming = False self.skipServiceReferenceReset = False self.RecordTimer = RecordTimer.RecordTimer() self.PowerTimer = PowerTimer.PowerTimer() @@ -114,7 +115,7 @@ def dispatchRecordEvent(self, rec_service, event): def restartService(self): self.playService(self.currentlyPlayingServiceOrGroup, forceRestart=True) - def playService(self, ref, checkParentalControl=True, forceRestart=False, adjust=True): + def playService(self, ref, checkParentalControl=True, forceRestart=False, adjust=True, fromTimer=False): oldref = self.currentlyPlayingServiceOrGroup if ref and oldref and ref == oldref and not forceRestart: print("[Navigation] ignore request to play already running service(1)") @@ -213,6 +214,14 @@ def playService(self, ref, checkParentalControl=True, forceRestart=False, adjust if config.usage.frontend_priority_dvbs.value != config.usage.frontend_priority.value: setPreferredTuner(int(config.usage.frontend_priority_dvbs.value)) setPriorityFrontend = True + if self.currentServiceStreaming and not fromTimer: + self.currentServiceStreaming = False + self.currentlyPlayingServiceReference = None + self.currentlyPlayingServiceOrGroup = None + print("[Navigation] Streamrelay was active -> delay the zap till tuner is freed") + self.retryServicePlayTimer = eTimer() + self.retryServicePlayTimer.callback.append(boundFunction(self.playService, ref, checkParentalControl, forceRestart, adjust, True)) + self.retryServicePlayTimer.start(100, True) if self.pnav.playService(playref): # print("[Navigation] Failed to start", playref) self.currentlyPlayingServiceReference = None @@ -225,6 +234,8 @@ def playService(self, ref, checkParentalControl=True, forceRestart=False, adjust self.skipServiceReferenceReset = False if setPriorityFrontend: setPreferredTuner(int(config.usage.frontend_priority.value)) + if playref.toString().find("127.0.0.1") > -1 and not self.currentServiceStreaming: + self.currentServiceStreaming = True return 0 elif oldref and InfoBarInstance and InfoBarInstance.servicelist.servicelist.setCurrent(oldref, adjust): self.currentlyPlayingServiceOrGroup = InfoBarInstance.servicelist.servicelist.getCurrent() diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 51c594fd0a2..2c84b2a4b73 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -796,7 +796,17 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (!marked && isPlayable && service_info && m_is_playable_ignore.valid()) { - isplayable_value = service_info->isPlayable(*m_cursor, m_is_playable_ignore); + eNavigation::getInstance()->getCurrentService(refCur); + ePtr tmp_info; + refCur->info(tmp_info); + std::string ref = tmp_info->getInfoString(iServiceInformation::sServiceref); + std::map, eServiceReference, std::less > recordedServices; + recordedServices = eNavigation::getInstance()->getRecordingsServices(); + if (ref.find("127.0.0.1") != std::string::npos && recordedServices.size() == 0) { + isplayable_value = 1; + } else { + isplayable_value = service_info->isPlayable(*m_cursor, m_is_playable_ignore); + } if (isplayable_value == 0) // service unavailable { From 0cd3834ff9c99f8e1361d3797efbabeb017b6f2f Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sun, 12 Nov 2023 19:30:03 +0200 Subject: [PATCH 179/401] [Fixed] Missing variable --- lib/service/listboxservice.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 2c84b2a4b73..cf13d5b9726 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -793,6 +793,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const bool serviceFallback = false; int isplayable_value; gRGB EventProgressbarColor = 0xe7b53f; + ePtr refCur; if (!marked && isPlayable && service_info && m_is_playable_ignore.valid()) { From 560a127a559cff3c3fe99245d57a4d7504be78d8 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sun, 12 Nov 2023 20:00:52 +0200 Subject: [PATCH 180/401] [Fixed] play condition --- .vscode/settings.json | 79 ++++++++++++++++++++++++++++++++++++++++ lib/python/Navigation.py | 2 +- 2 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000000..1be9fcb8f30 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,79 @@ +{ + "files.associations": { + "list": "cpp", + "algorithm": "cpp", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "charconv": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "compare": "cpp", + "concepts": "cpp", + "csignal": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "deque": "cpp", + "exception": "cpp", + "format": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "ios": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "iterator": "cpp", + "limits": "cpp", + "locale": "cpp", + "map": "cpp", + "memory": "cpp", + "mutex": "cpp", + "new": "cpp", + "optional": "cpp", + "ostream": "cpp", + "queue": "cpp", + "ranges": "cpp", + "ratio": "cpp", + "regex": "cpp", + "set": "cpp", + "span": "cpp", + "sstream": "cpp", + "stack": "cpp", + "stdexcept": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "string": "cpp", + "system_error": "cpp", + "thread": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "typeinfo": "cpp", + "unordered_map": "cpp", + "utility": "cpp", + "vector": "cpp", + "xfacet": "cpp", + "xhash": "cpp", + "xiosbase": "cpp", + "xlocale": "cpp", + "xlocbuf": "cpp", + "xlocinfo": "cpp", + "xlocmes": "cpp", + "xlocmon": "cpp", + "xlocnum": "cpp", + "xloctime": "cpp", + "xmemory": "cpp", + "xstring": "cpp", + "xtr1common": "cpp", + "xtree": "cpp", + "xutility": "cpp" + } +} \ No newline at end of file diff --git a/lib/python/Navigation.py b/lib/python/Navigation.py index eea310533b8..b39e43f5a00 100644 --- a/lib/python/Navigation.py +++ b/lib/python/Navigation.py @@ -222,7 +222,7 @@ def playService(self, ref, checkParentalControl=True, forceRestart=False, adjust self.retryServicePlayTimer = eTimer() self.retryServicePlayTimer.callback.append(boundFunction(self.playService, ref, checkParentalControl, forceRestart, adjust, True)) self.retryServicePlayTimer.start(100, True) - if self.pnav.playService(playref): + elif self.pnav.playService(playref): # print("[Navigation] Failed to start", playref) self.currentlyPlayingServiceReference = None self.currentlyPlayingServiceOrGroup = None From 56719330e0b58c7d78d156aa4a7c5ea4884d3c7e Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Mon, 13 Nov 2023 00:56:06 +0000 Subject: [PATCH 181/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Components/ServiceList.py | 2 +- lib/python/Navigation.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 1b438431c11..1f117482e36 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -55,7 +55,7 @@ def __init__(self, serviceList): pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/record.png")) pic and self.l.setPixmap(self.l.picRecord, pic) - + # Icons for two lines alternative mode pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/ico_hd-fs8.png")) pic and self.l.setPixmap(self.l.picHD, pic) diff --git a/lib/python/Navigation.py b/lib/python/Navigation.py index b39e43f5a00..ee4b70daf53 100644 --- a/lib/python/Navigation.py +++ b/lib/python/Navigation.py @@ -218,7 +218,7 @@ def playService(self, ref, checkParentalControl=True, forceRestart=False, adjust self.currentServiceStreaming = False self.currentlyPlayingServiceReference = None self.currentlyPlayingServiceOrGroup = None - print("[Navigation] Streamrelay was active -> delay the zap till tuner is freed") + print("[Navigation] Streamrelay was active -> delay the zap till tuner is freed") self.retryServicePlayTimer = eTimer() self.retryServicePlayTimer.callback.append(boundFunction(self.playService, ref, checkParentalControl, forceRestart, adjust, True)) self.retryServicePlayTimer.start(100, True) From d0aa7c7585f3751e02ee468c149ded91214dd1c4 Mon Sep 17 00:00:00 2001 From: Huevos Date: Mon, 13 Nov 2023 01:51:28 +0100 Subject: [PATCH 182/401] [PLiExtraInfo] tweak for SR --- .../Components/Converter/PliExtraInfo.py | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/python/Components/Converter/PliExtraInfo.py b/lib/python/Components/Converter/PliExtraInfo.py index f3af58ec776..2a3b1a517e6 100644 --- a/lib/python/Components/Converter/PliExtraInfo.py +++ b/lib/python/Components/Converter/PliExtraInfo.py @@ -562,7 +562,7 @@ def createInfoString(self, fieldGroup, fedata, feraw, info): def createStreamURLInfo(self, info): refstr = info.getInfoString(iServiceInformation.sServiceref) if "%3a//" in refstr.lower(): - return refstr.split(":")[10].replace("%3a", ":").replace("%3A", ":") + return refstr.replace("%3a", ":").replace("%3A", ":").split("://")[1].split("/")[0].split('@')[-1] return "" def createFrequency(self, fedata): @@ -618,28 +618,30 @@ def createTunerType(self, feraw): def createTunerSystem(self, fedata): return fedata.get("system") or "" - def namespace(self, info): - if "%3a//127" in info.getInfoString(iServiceInformation.sServiceref).lower(): - nmspc = info.getInfo(iServiceInformation.sNamespace) & 0xFFFFFFFF - namespace = "%08X" % nmspc - orbpos = int(namespace[:4], 16) + def formatOrbPos(self, orbpos): + if isinstance(orbpos, int) and 0 <= orbpos <= 3600: # sanity if orbpos > 1800: return str((float(3600 - orbpos)) / 10.0) + "\xb0" + "W" - elif orbpos > 0: + else: return str((float(orbpos)) / 10.0) + "\xb0" + "E" + return "" + + def getOrbPosFromInfo(self, info): + if "%3a//127" in info.getInfoString(iServiceInformation.sServiceref).lower(): + return (x:=info.getInfo(iServiceInformation.sNamespace)) and (x & 0xFFFFFFFF) >> 16 + + def createOrbPosFromInfo(self, info): + if (orbpos:=self.getOrbPosFromInfo(info)) is not None: + return self.formatOrbPos(orbpos) else: return "" def createOrbPos(self, feraw, info): orbpos = feraw.get("orbital_position") if orbpos is not None: - if orbpos > 1800: - return str((float(3600 - orbpos)) / 10.0) + "\xb0" + "W" - elif orbpos > 0: - return str((float(orbpos)) / 10.0) + "\xb0" + "E" + return self.formatOrbPos(orbpos) else: - orbpos = self.namespace(info) - return orbpos + return self.createOrbPosFromInfo(info) def createOrbPosOrTunerSystem(self, fedata, feraw, info): orbpos = self.createOrbPos(feraw, info) @@ -650,8 +652,9 @@ def createOrbPosOrTunerSystem(self, fedata, feraw, info): def createTransponderName(self, feraw, info): orbpos = feraw.get("orbital_position") if orbpos is None: # Not satellite - orbpos = self.namespace(info) - return orbpos + orbpos = self.getOrbPosFromInfo(info) # if internal stream try to get pos + if orbpos is None: + return "" freq = feraw.get("frequency") if freq and freq < 10700000: # C-band if orbpos > 1800: @@ -753,18 +756,15 @@ def createTransponderName(self, feraw, info): if orbpos in sat_names: return sat_names[orbpos] - elif orbpos > 1800: - return str((float(3600 - orbpos)) / 10.0) + "W" else: - return str((float(orbpos)) / 10.0) + "E" + return self.formatOrbPos(orbpos) def createProviderName(self, info): refstr = info.getInfoString(iServiceInformation.sServiceref) if "%3a//" in refstr.lower() and "127.0.0.1" not in refstr and "0.0.0.0" not in refstr and "localhost" not in refstr: return "" elif "%3a//127" in refstr and "17999" in refstr: - provider = self.namespace(info).replace("28.2\xb0E", "Sky UK").replace("19.2\xb0E", "Sky Deutschland").replace("13.0\xb0E", "Sky Italia") - return "%s" % provider + return {282: "Sky UK", 192: "Sky Deutschland", 130: "Sky Italia"}.get((pos:=self.getOrbPosFromInfo(info)), self.formatOrbPos(pos)) else: return info.getInfoString(iServiceInformation.sProvider) From 48a5a9c45b16f62cc70d90416db0e3dcaf25f397 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Mon, 13 Nov 2023 01:06:25 +0000 Subject: [PATCH 183/401] PEP8 double aggressive E22, E224, E241, E242 and E27 --- lib/python/Components/Converter/PliExtraInfo.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/python/Components/Converter/PliExtraInfo.py b/lib/python/Components/Converter/PliExtraInfo.py index 2a3b1a517e6..9d8cfd4bfad 100644 --- a/lib/python/Components/Converter/PliExtraInfo.py +++ b/lib/python/Components/Converter/PliExtraInfo.py @@ -628,10 +628,10 @@ def formatOrbPos(self, orbpos): def getOrbPosFromInfo(self, info): if "%3a//127" in info.getInfoString(iServiceInformation.sServiceref).lower(): - return (x:=info.getInfo(iServiceInformation.sNamespace)) and (x & 0xFFFFFFFF) >> 16 + return (x := info.getInfo(iServiceInformation.sNamespace)) and (x & 0xFFFFFFFF) >> 16 def createOrbPosFromInfo(self, info): - if (orbpos:=self.getOrbPosFromInfo(info)) is not None: + if (orbpos := self.getOrbPosFromInfo(info)) is not None: return self.formatOrbPos(orbpos) else: return "" @@ -764,7 +764,7 @@ def createProviderName(self, info): if "%3a//" in refstr.lower() and "127.0.0.1" not in refstr and "0.0.0.0" not in refstr and "localhost" not in refstr: return "" elif "%3a//127" in refstr and "17999" in refstr: - return {282: "Sky UK", 192: "Sky Deutschland", 130: "Sky Italia"}.get((pos:=self.getOrbPosFromInfo(info)), self.formatOrbPos(pos)) + return {282: "Sky UK", 192: "Sky Deutschland", 130: "Sky Italia"}.get((pos := self.getOrbPosFromInfo(info)), self.formatOrbPos(pos)) else: return info.getInfoString(iServiceInformation.sProvider) From e86bee714de08a4b4385fd22f08ca96298ab4064 Mon Sep 17 00:00:00 2001 From: Huevos Date: Mon, 13 Nov 2023 09:19:45 +0100 Subject: [PATCH 184/401] [ServiceList] reapply pep comment that was removed in error --- lib/python/Components/ServiceList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 1f117482e36..edad8d1b7df 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -27,7 +27,7 @@ class ServiceList(GUIComponent): def __init__(self, serviceList): self.serviceList = serviceList GUIComponent.__init__(self) - self.l = eListboxServiceContent() + self.l = eListboxServiceContent() # noqa: E741 pic = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/folder.png")) pic and self.l.setPixmap(self.l.picFolder, pic) From 67d7ae132990855a623f33acfecb339683bb69e8 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Mon, 13 Nov 2023 10:17:44 +0200 Subject: [PATCH 185/401] - fixed exception when current item is None --- lib/python/Plugins/SystemPlugins/ViX/BackupManager.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/python/Plugins/SystemPlugins/ViX/BackupManager.py b/lib/python/Plugins/SystemPlugins/ViX/BackupManager.py index 080f1b6b0b6..b72eb87ce39 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/BackupManager.py +++ b/lib/python/Plugins/SystemPlugins/ViX/BackupManager.py @@ -815,7 +815,10 @@ def layoutFinished(self): self.selectionChanged() def selectionChanged(self): - current = self["checkList"].getCurrent()[0] + cursor = self["checkList"].getCurrent() + if not cursor: + return + current = cursor[0] if current[2] is True: self["key_yellow"].setText(_("Deselect")) else: From 6143c2f6d21923a7909c0f50a6e691ecd2676102 Mon Sep 17 00:00:00 2001 From: Huevos Date: Mon, 13 Nov 2023 13:55:14 +0100 Subject: [PATCH 186/401] [SessionObject] add module --- lib/python/Session.py | 10 ++++++++++ lib/python/StartEnigma.py | 3 +++ 2 files changed, 13 insertions(+) create mode 100644 lib/python/Session.py diff --git a/lib/python/Session.py b/lib/python/Session.py new file mode 100644 index 00000000000..6a5f8818be4 --- /dev/null +++ b/lib/python/Session.py @@ -0,0 +1,10 @@ +class SessionObject: + __session = None + + def setSession(self, Session): + SessionObject.__session = Session + + def getSession(self): + return self.__session + + session = property(getSession, setSession) diff --git a/lib/python/StartEnigma.py b/lib/python/StartEnigma.py index cf9c3a0fdf5..6e4bd9f88e7 100644 --- a/lib/python/StartEnigma.py +++ b/lib/python/StartEnigma.py @@ -324,6 +324,9 @@ def runScreenTest(): profile("Init:Session") nav = Navigation(config.misc.isNextRecordTimerAfterEventActionAuto.value, config.misc.isNextPowerTimerAfterEventActionAuto.value) session = Session(desktop=enigma.getDesktop(0), summary_desktop=enigma.getDesktop(1), navigation=nav) + from Session import SessionObject + so = SessionObject() + so.session = session profile("Init:Trashcan") import Tools.Trashcan From 8a6c26cd8967b9677f7faea6f2436ccd7370d65f Mon Sep 17 00:00:00 2001 From: Orlandoxx <95180049+Orlandoxx@users.noreply.github.com> Date: Mon, 13 Nov 2023 19:25:15 +0200 Subject: [PATCH 187/401] Updated Finnish (fi.po) translation Added missing new translation. --- po/fi.po | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/po/fi.po b/po/fi.po index a2d131ea176..0b500b364f6 100644 --- a/po/fi.po +++ b/po/fi.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: enigma2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-27 23:35+0000\n" -"PO-Revision-Date: 2023-11-12 19:00+0200\n" +"PO-Revision-Date: 2023-11-13 19:22+0200\n" "Last-Translator: Orlandox\n" "Language-Team: timoj/Kojo/Samzam/Orlandox\n" "Language: fi\n" @@ -13549,7 +13549,7 @@ msgstr "" "Suomenkielinen käännös: timoj, Kojo, Samzam, Orlandox\n" "\n" "Ylläpito : Orlandox\n" -"12.11.2023\n" +"13.11.2023\n" "http://www.huoltovalikko.com" msgid "TS file is too large for ISO9660 level 1!" @@ -17406,6 +17406,9 @@ msgstr "kaksi riviä" msgid "two lines and next event" msgstr "kaksi riviä ja seuraava ohjelma" +msgid "two lines alternative" +msgstr "kahden rivin vaihtoehto" + msgid "type" msgstr "DVB tyyppi" From 5e8375002b3e150ddeed643efbd6b5111d651cdb Mon Sep 17 00:00:00 2001 From: openvix-build Date: Mon, 13 Nov 2023 22:58:18 +0000 Subject: [PATCH 188/401] openvix: developer 6.4.010.001 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index d459af3c7ab..e7233494b27 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1199,3 +1199,4 @@ openvix: developer 6.4.009.012 openvix: developer 6.4.009.013 openvix: developer 6.4.009.014 openvix: developer 6.4.009.015 +openvix: developer 6.4.010.001 From 1e13933ca0fd6ddc31409a39014c3bba075617f8 Mon Sep 17 00:00:00 2001 From: Huevos Date: Tue, 14 Nov 2023 12:07:11 +0100 Subject: [PATCH 189/401] [python/Makefile] update --- lib/python/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/python/Makefile.am b/lib/python/Makefile.am index 1193a496c70..10ea22649ae 100644 --- a/lib/python/Makefile.am +++ b/lib/python/Makefile.am @@ -12,6 +12,7 @@ install_PYTHON = \ PowerTimer.py \ RecordTimer.py \ ServiceReference.py \ + Session.py \ skin.py \ StartEnigma.py \ timer.py \ From f149f552a81d1b15b3b0d32cb35088c871891dea Mon Sep 17 00:00:00 2001 From: openvix-build Date: Tue, 14 Nov 2023 14:45:15 +0000 Subject: [PATCH 190/401] openvix: developer 6.4.010.002 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index e7233494b27..4fc22879882 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1200,3 +1200,4 @@ openvix: developer 6.4.009.013 openvix: developer 6.4.009.014 openvix: developer 6.4.009.015 openvix: developer 6.4.010.001 +openvix: developer 6.4.010.002 From 50438657e13c7c16c97fe9e6ecc9fc6f888b9e58 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Tue, 14 Nov 2023 16:24:47 +0200 Subject: [PATCH 191/401] [Added] Options handling for new service list visual mode [Fixed] some alignments issues --- lib/python/Components/ServiceList.py | 31 +++--- lib/service/listboxservice.cpp | 156 ++++++++++++++------------- lib/service/listboxservice.h | 4 + 3 files changed, 105 insertions(+), 86 deletions(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index edad8d1b7df..5a0a2ad0b5e 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -27,7 +27,7 @@ class ServiceList(GUIComponent): def __init__(self, serviceList): self.serviceList = serviceList GUIComponent.__init__(self) - self.l = eListboxServiceContent() # noqa: E741 + self.l = eListboxServiceContent() pic = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/folder.png")) pic and self.l.setPixmap(self.l.picFolder, pic) @@ -55,8 +55,7 @@ def __init__(self, serviceList): pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/record.png")) pic and self.l.setPixmap(self.l.picRecord, pic) - - # Icons for two lines alternative mode + pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/ico_hd-fs8.png")) pic and self.l.setPixmap(self.l.picHD, pic) pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/ico_sd-fs8.png")) @@ -83,6 +82,7 @@ def __init__(self, serviceList): self.progressBarWidth = 52 self.progressPercentWidth = 0 self.fieldMargins = 10 + self.sidesMargin = 0 self.ItemHeight = None self.skinItemHeight = None @@ -209,6 +209,16 @@ def nonplayableMargins(value): def itemsDistances(value): self.l.setItemsDistances(parseScale(value)) + + def sidesMargin(value): + self.sidesMargin = parseScale(value) + + def textSeparator(value): + self.l.setTextSeparator(value) + def selectionPixmapLarge(value): + two_lines_val = int(config.usage.servicelist_twolines.value) + if two_lines_val: + self.l.setSelectionPicture(LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, value))) for (attrib, value) in self.skinAttributes[:]: try: @@ -443,10 +453,7 @@ def setMode(self, mode): self.setItemsPerPage() two_lines_val = int(config.usage.servicelist_twolines.value) show_two_lines = two_lines_val and mode == self.MODE_FAVOURITES - if two_lines_val == 3: - self.ItemHeight = 86 - else: - self.ItemHeight *= (2 if show_two_lines else 1) + self.ItemHeight *= (2 if show_two_lines else 1) self.l.setItemHeight(self.ItemHeight) self.l.setVisualMode(eListboxServiceContent.visModeComplex if two_lines_val < 3 else eListboxServiceContent.visSkinDefined) @@ -464,21 +471,21 @@ def setMode(self, mode): channelNumberWidth = config.usage.alternative_number_mode.value and getTextBoundarySize(self.instance, self.ServiceNumberFont, self.instance.size(), "0000").width() or getTextBoundarySize(self.instance, self.ServiceNumberFont, self.instance.size(), "00000").width() channelNumberSpace = self.fieldMargins - self.l.setElementPosition(self.l.celServiceNumber, eRect(0, 0, channelNumberWidth, self.ItemHeight)) + self.l.setElementPosition(self.l.celServiceNumber, eRect(self.sidesMargin, 0, channelNumberWidth, self.ItemHeight)) progressWidth = self.progressBarWidth if "perc" in config.usage.show_event_progress_in_servicelist.value: progressWidth = self.progressPercentWidth or self.progressBarWidth if "left" in config.usage.show_event_progress_in_servicelist.value: - self.l.setElementPosition(self.l.celServiceEventProgressbar, eRect(channelNumberWidth + channelNumberSpace, 0, progressWidth, self.ItemHeight)) - self.l.setElementPosition(self.l.celServiceName, eRect(channelNumberWidth + channelNumberSpace + progressWidth + self.fieldMargins, 0, rowWidth - (channelNumberWidth + channelNumberSpace + progressWidth + self.fieldMargins), self.ItemHeight)) + self.l.setElementPosition(self.l.celServiceEventProgressbar, eRect(channelNumberWidth + channelNumberSpace + self.sidesMargin, 0, progressWidth, self.ItemHeight)) + self.l.setElementPosition(self.l.celServiceName, eRect(channelNumberWidth + channelNumberSpace + progressWidth + self.fieldMargins + self.sidesMargin, 0, rowWidth - (channelNumberWidth + channelNumberSpace + progressWidth + self.fieldMargins), self.ItemHeight)) elif "right" in config.usage.show_event_progress_in_servicelist.value: self.l.setElementPosition(self.l.celServiceEventProgressbar, eRect(rowWidth - progressWidth, 0, progressWidth, self.ItemHeight)) - self.l.setElementPosition(self.l.celServiceName, eRect(channelNumberWidth + channelNumberSpace, 0, rowWidth - (channelNumberWidth + channelNumberSpace + progressWidth + self.fieldMargins), self.ItemHeight)) + self.l.setElementPosition(self.l.celServiceName, eRect(channelNumberWidth + channelNumberSpace + self.sidesMargin, 0, rowWidth - (channelNumberWidth + channelNumberSpace + progressWidth + self.fieldMargins), self.ItemHeight)) else: self.l.setElementPosition(self.l.celServiceEventProgressbar, eRect(0, 0, 0, 0)) - self.l.setElementPosition(self.l.celServiceName, eRect(channelNumberWidth + channelNumberSpace, 0, rowWidth - (channelNumberWidth + channelNumberSpace), self.ItemHeight)) + self.l.setElementPosition(self.l.celServiceName, eRect(channelNumberWidth + channelNumberSpace + self.sidesMargin, 0, rowWidth - (channelNumberWidth + channelNumberSpace + self.sidesMargin), self.ItemHeight)) self.l.setElementFont(self.l.celServiceName, self.ServiceNameFont) self.l.setElementFont(self.l.celServiceNumber, self.ServiceNumberFont) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index cf13d5b9726..e5a7cb0c187 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -382,7 +382,7 @@ void eListboxServiceContent::sort() DEFINE_REF(eListboxServiceContent); eListboxServiceContent::eListboxServiceContent() - :m_visual_mode(visModeSimple), m_size(0), m_current_marked(false), m_itemheight(25), m_hide_number_marker(false), m_show_two_lines(0), m_servicetype_icon_mode(0), m_crypto_icon_mode(0), m_record_indicator_mode(0), m_column_width(0), m_progressbar_height(6), m_progressbar_border_width(2), m_nonplayable_margins(10), m_items_distances(8) + :m_visual_mode(visModeSimple), m_size(0), m_current_marked(false), m_itemheight(25), m_hide_number_marker(false), m_show_two_lines(0), m_servicetype_icon_mode(0), m_crypto_icon_mode(0), m_record_indicator_mode(0), m_column_width(0), m_progressbar_height(6), m_progressbar_border_width(2), m_nonplayable_margins(10), m_items_distances(8), m_sides_margin(0) { memset(m_color_set, 0, sizeof(m_color_set)); cursorHome(); @@ -835,16 +835,18 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const painter.setForegroundColor(gRGB(0xb40431)); } - int xoffset=0, xoffs=0; // used as offset when painting the folder/marker symbol or the serviceevent progress + int xoffset=m_sides_margin, xoffs=0; // used as offset when painting the folder/marker symbol or the serviceevent progress int nameLeft=0, nameWidth=0, nameYoffs=0, nextYoffs=0; // used as temporary values for 'show two lines' option + if (m_separator == "") m_separator = " "; + std::string text = ""; time_t now = time(0); std::string event_name = "", next_event_name = ""; int event_begin = 0, event_duration = 0, xlpos = m_itemsize.width(), ctrlHeight=m_itemheight, yoffs=0; - bool is_event = isPlayable && service_info && !service_info->getEvent(*m_cursor, evt); + bool is_event = isPlayable && service_info && !service_info->getEvent(ref, evt); if (m_visual_mode == visSkinDefined) { if (is_event){ event_name = evt->getEventName(); @@ -869,24 +871,26 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } int orbpos = m_cursor->getUnsignedData(4) >> 16; - const char *filename = ref.path.c_str(); - ePtr &pixmap_system = - (m_cursor->flags & eServiceReference::isGroup) ? m_pixmaps[picServiceGroup] : - (strstr(filename, "://")) ? m_pixmaps[picStream] : - (orbpos == 0xFFFF) ? m_pixmaps[picDVB_C] : - (orbpos == 0xEEEE) ? m_pixmaps[picDVB_T] : m_pixmaps[picDVB_S]; - - if (pixmap_system) - { - eSize pixmap_size = pixmap_system->size(); - xlpos -= 15 + pixmap_size.width(); - eRect area = eRect(xlpos, offset.y() + yoffs + (ctrlHeight - pixmap_size.height())/2, pixmap_size.width(), pixmap_size.height()); - painter.clip(area); - painter.blit(pixmap_system, ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); - painter.clippop(); + if (m_servicetype_icon_mode) { + const char *filename = ref.path.c_str(); + ePtr &pixmap_system = + (m_cursor->flags & eServiceReference::isGroup) ? m_pixmaps[picServiceGroup] : + (strstr(filename, "://")) ? m_pixmaps[picStream] : + (orbpos == 0xFFFF) ? m_pixmaps[picDVB_C] : + (orbpos == 0xEEEE) ? m_pixmaps[picDVB_T] : m_pixmaps[picDVB_S]; + + if (pixmap_system) + { + eSize pixmap_size = pixmap_system->size(); + xlpos -= 15 + pixmap_size.width(); + eRect area = eRect(xlpos, offset.y() + yoffs + (ctrlHeight - pixmap_size.height())/2, pixmap_size.width(), pixmap_size.height()); + painter.clip(area); + painter.blit(pixmap_system, ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.clippop(); + } } - if (m_pixmaps[picCrypto] && service_info && service_info->isCrypted()) + if (m_crypto_icon_mode && m_pixmaps[picCrypto] && service_info && service_info->isCrypted()) { eSize pixmap_size = m_pixmaps[picCrypto]->size(); xlpos -= 15 + pixmap_size.width(); @@ -948,10 +952,10 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const Py_DECREF(pRet); } } - xoffs = xoffset + 16; - if (PyCallable_Check(m_GetPiconNameFunc) and (piconPixmap)) + xoffs = xoffset; + if (PyCallable_Check(m_GetPiconNameFunc)) { - eRect piconArea = eRect(xoffs, offset.y(), 125, m_itemheight); + eRect piconArea = eRect(xoffs, offset.y(), 125, m_itemheight);//m_element_position[celServiceInfo]; /* PIcons are usually about 100:60. Make it a * bit wider in case the icons are diffently * shaped, and to add a bit of margin between @@ -977,6 +981,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } painter.clippop(); } + xoffs += 125 + 16 + 8; } if (isMarker || isDirectory) { @@ -990,21 +995,21 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const xoffs += pixmap_size.width() + 16 + 8; } - } else { - xoffs += 125 + 16 + 8; } // channel number + name if (service_info) service_info->getName(ref, text); + if (!isMarker && !isDirectory) { std::string chNum = ""; - if (m_cursor->getChannelNum() != 0) { + eRect serviceNumberRect = m_element_position[celServiceNumber]; + if (serviceNumberRect.width() > 0 && m_cursor->getChannelNum() != 0) { char buffer[15]; snprintf(buffer, sizeof(buffer), "%d", m_cursor->getChannelNum() ); chNum = buffer; } - if (chNum != "") text = chNum + " • " + text; + if (chNum != "") text = chNum + m_separator + text; } ePtr para = new eTextPara(eRect(0, 0, m_itemsize.width(), m_itemheight/2)); @@ -1020,62 +1025,65 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const event_begin = evt->getBeginTime(); event_duration = evt->getDuration(); int timeLeft = event_begin + event_duration - now; + eRect progressBarRect = m_element_position[celServiceEventProgressbar]; if (!event_name.empty()) { //--------------------------------------------------- Event Progressbar ----------------------------------------------------------------- - int pb_xpos = xoffs; - int pb_ypos = offset.y() + m_itemheight/2 + (m_itemheight/2 - m_progressbar_height - 2 * m_progressbar_border_width) / 2; - int pb_width = 75 - 2 * m_progressbar_border_width; - gRGB ProgressbarBorderColor = 0xdfdfdf; - int evt_done = pb_width * (now - event_begin) / event_duration; - - // the progress data... - eRect tmp = eRect(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width, evt_done, m_progressbar_height); - ePtr &pixmap = m_pixmaps[picServiceEventProgressbar]; - if (pixmap) { - painter.clip(tmp); - painter.blit(pixmap, ePoint(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width), tmp, gPainter::BT_ALPHABLEND); - painter.clippop(); - } - else { - if (!selected && m_color_set[serviceEventProgressbarColor]) - painter.setForegroundColor(m_color[serviceEventProgressbarColor]); - else if (selected && m_color_set[serviceEventProgressbarColorSelected]) - painter.setForegroundColor(m_color[serviceEventProgressbarColorSelected]); - else if (m_show_two_lines == 2) - painter.setForegroundColor(EventProgressbarColor); - painter.fill(tmp); - } + if (progressBarRect.width() > 0) { + int pb_xpos = xoffs; + int pb_ypos = offset.y() + m_itemheight/2 + (m_itemheight/2 - m_progressbar_height - 2 * m_progressbar_border_width) / 2; + int pb_width = 75 - 2 * m_progressbar_border_width; + gRGB ProgressbarBorderColor = 0xdfdfdf; + int evt_done = pb_width * (now - event_begin) / event_duration; + + // the progress data... + eRect tmp = eRect(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width, evt_done, m_progressbar_height); + ePtr &pixmap = m_pixmaps[picServiceEventProgressbar]; + if (pixmap) { + painter.clip(tmp); + painter.blit(pixmap, ePoint(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width), tmp, gPainter::BT_ALPHABLEND); + painter.clippop(); + } + else { + if (!selected && m_color_set[serviceEventProgressbarColor]) + painter.setForegroundColor(m_color[serviceEventProgressbarColor]); + else if (selected && m_color_set[serviceEventProgressbarColorSelected]) + painter.setForegroundColor(m_color[serviceEventProgressbarColorSelected]); + else if (m_show_two_lines == 2) + painter.setForegroundColor(EventProgressbarColor); + painter.fill(tmp); + } - // the progressbar border - if (!selected) { - if (m_color_set[serviceEventProgressbarBorderColor]) - ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColor]; - else if (m_color_set[eventborderForeground]) - ProgressbarBorderColor = m_color[eventborderForeground]; - } - else { /* !selected */ - if (m_color_set[serviceEventProgressbarBorderColorSelected]) - ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColorSelected]; - else if (m_color_set[eventborderForegroundSelected]) - ProgressbarBorderColor = m_color[eventborderForegroundSelected]; - } - painter.setForegroundColor(ProgressbarBorderColor); + // the progressbar border + if (!selected) { + if (m_color_set[serviceEventProgressbarBorderColor]) + ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColor]; + else if (m_color_set[eventborderForeground]) + ProgressbarBorderColor = m_color[eventborderForeground]; + } + else { /* !selected */ + if (m_color_set[serviceEventProgressbarBorderColorSelected]) + ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColorSelected]; + else if (m_color_set[eventborderForegroundSelected]) + ProgressbarBorderColor = m_color[eventborderForegroundSelected]; + } + painter.setForegroundColor(ProgressbarBorderColor); - if (m_progressbar_border_width) - { - painter.fill(eRect(pb_xpos, pb_ypos, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); - painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width + m_progressbar_height, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); - painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); - painter.fill(eRect(pb_xpos + m_progressbar_border_width + pb_width, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); - } - else - painter.fill(eRect(pb_xpos + evt_done, pb_ypos, pb_width - evt_done, m_progressbar_height)); + if (m_progressbar_border_width) + { + painter.fill(eRect(pb_xpos, pb_ypos, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); + painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width + m_progressbar_height, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); + painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); + painter.fill(eRect(pb_xpos + m_progressbar_border_width + pb_width, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); + } + else + painter.fill(eRect(pb_xpos + evt_done, pb_ypos, pb_width - evt_done, m_progressbar_height)); - xoffs += pb_width + 16; + xoffs += pb_width + 16; + } - //------------------------------------------------- Event Name + Remaining ---------------------------------------------------- + //------------------------------------------------------- Event Name -------------------------------------------------------------------- text = event_name; std::replace(text.begin(), text.end(), '\n', ' '); if (serviceAvail) diff --git a/lib/service/listboxservice.h b/lib/service/listboxservice.h index 68d31a982e6..fd037c47c9a 100644 --- a/lib/service/listboxservice.h +++ b/lib/service/listboxservice.h @@ -102,8 +102,10 @@ class eListboxServiceContent: public virtual iListboxContent void setProgressbarBorderWidth(int value) { m_progressbar_border_width = value; } void setNonplayableMargins(int value) { m_nonplayable_margins = value; } void setItemsDistances(int value) { m_items_distances = value; } + void setSidesMargin(int value) { m_sides_margin = value; } void setNextTitle(const std::string &string) { m_next_title = string; } + void setTextSeparator(const std::string &string) { m_separator = string; } static void setGetPiconNameFunc(SWIG_PYOBJECT(ePyObject) func); @@ -198,8 +200,10 @@ class eListboxServiceContent: public virtual iListboxContent int m_progressbar_border_width; int m_nonplayable_margins; int m_items_distances; + int m_sides_margin; std::string m_next_title; + std::string m_separator; }; #endif From 7c732adcc33be2b023274d32207d4c68d961eb32 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Tue, 14 Nov 2023 16:34:21 +0200 Subject: [PATCH 192/401] [Fixed] missing qa supression [Fixed selectionPixmapLarge to not clear the image if not suplied --- lib/python/Components/ServiceList.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 5a0a2ad0b5e..8b3670269f5 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -27,7 +27,7 @@ class ServiceList(GUIComponent): def __init__(self, serviceList): self.serviceList = serviceList GUIComponent.__init__(self) - self.l = eListboxServiceContent() + self.l = eListboxServiceContent() # noqa: E741 pic = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/folder.png")) pic and self.l.setPixmap(self.l.picFolder, pic) @@ -218,7 +218,8 @@ def textSeparator(value): def selectionPixmapLarge(value): two_lines_val = int(config.usage.servicelist_twolines.value) if two_lines_val: - self.l.setSelectionPicture(LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, value))) + pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, value)) + pic and self.l.setSelectionPicture(pic) for (attrib, value) in self.skinAttributes[:]: try: From da7ff749c669701f37c4fe5ffae8d1dc1be6191e Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Tue, 14 Nov 2023 14:58:03 +0000 Subject: [PATCH 193/401] PEP8 double aggressive E225 ~ E228 and E231 --- lib/python/Components/ServiceList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 8b3670269f5..68db119be9b 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -27,7 +27,7 @@ class ServiceList(GUIComponent): def __init__(self, serviceList): self.serviceList = serviceList GUIComponent.__init__(self) - self.l = eListboxServiceContent() # noqa: E741 + self.l = eListboxServiceContent() # noqa: E741 pic = LoadPixmap(cached=True, path=resolveFilename(SCOPE_CURRENT_SKIN, "icons/folder.png")) pic and self.l.setPixmap(self.l.picFolder, pic) From ed44b080496165ececdbff324aed2b23883bac47 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Tue, 14 Nov 2023 14:58:14 +0000 Subject: [PATCH 194/401] PEP8 double aggressive E301 ~ E306 --- lib/python/Components/ServiceList.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 68db119be9b..d47393de069 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -215,6 +215,7 @@ def sidesMargin(value): def textSeparator(value): self.l.setTextSeparator(value) + def selectionPixmapLarge(value): two_lines_val = int(config.usage.servicelist_twolines.value) if two_lines_val: From e1ca03d563d0e8c336756b5283633fb56ab81b2e Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Tue, 14 Nov 2023 14:58:24 +0000 Subject: [PATCH 195/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Components/ServiceList.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index d47393de069..adbe6075abf 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -55,7 +55,7 @@ def __init__(self, serviceList): pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/record.png")) pic and self.l.setPixmap(self.l.picRecord, pic) - + pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/ico_hd-fs8.png")) pic and self.l.setPixmap(self.l.picHD, pic) pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/ico_sd-fs8.png")) @@ -209,10 +209,10 @@ def nonplayableMargins(value): def itemsDistances(value): self.l.setItemsDistances(parseScale(value)) - + def sidesMargin(value): self.sidesMargin = parseScale(value) - + def textSeparator(value): self.l.setTextSeparator(value) From 1547758e85700025590fa8362b1b4bad7382421c Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 15 Nov 2023 01:01:28 +0100 Subject: [PATCH 196/401] Revert "PEP8 double aggressive E22, E224, E241, E242 and E27" This reverts commit 48a5a9c45b16f62cc70d90416db0e3dcaf25f397. --- lib/python/Components/Converter/PliExtraInfo.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/python/Components/Converter/PliExtraInfo.py b/lib/python/Components/Converter/PliExtraInfo.py index 9d8cfd4bfad..2a3b1a517e6 100644 --- a/lib/python/Components/Converter/PliExtraInfo.py +++ b/lib/python/Components/Converter/PliExtraInfo.py @@ -628,10 +628,10 @@ def formatOrbPos(self, orbpos): def getOrbPosFromInfo(self, info): if "%3a//127" in info.getInfoString(iServiceInformation.sServiceref).lower(): - return (x := info.getInfo(iServiceInformation.sNamespace)) and (x & 0xFFFFFFFF) >> 16 + return (x:=info.getInfo(iServiceInformation.sNamespace)) and (x & 0xFFFFFFFF) >> 16 def createOrbPosFromInfo(self, info): - if (orbpos := self.getOrbPosFromInfo(info)) is not None: + if (orbpos:=self.getOrbPosFromInfo(info)) is not None: return self.formatOrbPos(orbpos) else: return "" @@ -764,7 +764,7 @@ def createProviderName(self, info): if "%3a//" in refstr.lower() and "127.0.0.1" not in refstr and "0.0.0.0" not in refstr and "localhost" not in refstr: return "" elif "%3a//127" in refstr and "17999" in refstr: - return {282: "Sky UK", 192: "Sky Deutschland", 130: "Sky Italia"}.get((pos := self.getOrbPosFromInfo(info)), self.formatOrbPos(pos)) + return {282: "Sky UK", 192: "Sky Deutschland", 130: "Sky Italia"}.get((pos:=self.getOrbPosFromInfo(info)), self.formatOrbPos(pos)) else: return info.getInfoString(iServiceInformation.sProvider) From 149737382539adda793b2b189027430d759bcf64 Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 15 Nov 2023 01:01:41 +0100 Subject: [PATCH 197/401] Revert "[PLiExtraInfo] tweak for SR" This reverts commit d0aa7c7585f3751e02ee468c149ded91214dd1c4. --- .../Components/Converter/PliExtraInfo.py | 40 +++++++++---------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/lib/python/Components/Converter/PliExtraInfo.py b/lib/python/Components/Converter/PliExtraInfo.py index 2a3b1a517e6..f3af58ec776 100644 --- a/lib/python/Components/Converter/PliExtraInfo.py +++ b/lib/python/Components/Converter/PliExtraInfo.py @@ -562,7 +562,7 @@ def createInfoString(self, fieldGroup, fedata, feraw, info): def createStreamURLInfo(self, info): refstr = info.getInfoString(iServiceInformation.sServiceref) if "%3a//" in refstr.lower(): - return refstr.replace("%3a", ":").replace("%3A", ":").split("://")[1].split("/")[0].split('@')[-1] + return refstr.split(":")[10].replace("%3a", ":").replace("%3A", ":") return "" def createFrequency(self, fedata): @@ -618,30 +618,28 @@ def createTunerType(self, feraw): def createTunerSystem(self, fedata): return fedata.get("system") or "" - def formatOrbPos(self, orbpos): - if isinstance(orbpos, int) and 0 <= orbpos <= 3600: # sanity + def namespace(self, info): + if "%3a//127" in info.getInfoString(iServiceInformation.sServiceref).lower(): + nmspc = info.getInfo(iServiceInformation.sNamespace) & 0xFFFFFFFF + namespace = "%08X" % nmspc + orbpos = int(namespace[:4], 16) if orbpos > 1800: return str((float(3600 - orbpos)) / 10.0) + "\xb0" + "W" - else: + elif orbpos > 0: return str((float(orbpos)) / 10.0) + "\xb0" + "E" - return "" - - def getOrbPosFromInfo(self, info): - if "%3a//127" in info.getInfoString(iServiceInformation.sServiceref).lower(): - return (x:=info.getInfo(iServiceInformation.sNamespace)) and (x & 0xFFFFFFFF) >> 16 - - def createOrbPosFromInfo(self, info): - if (orbpos:=self.getOrbPosFromInfo(info)) is not None: - return self.formatOrbPos(orbpos) else: return "" def createOrbPos(self, feraw, info): orbpos = feraw.get("orbital_position") if orbpos is not None: - return self.formatOrbPos(orbpos) + if orbpos > 1800: + return str((float(3600 - orbpos)) / 10.0) + "\xb0" + "W" + elif orbpos > 0: + return str((float(orbpos)) / 10.0) + "\xb0" + "E" else: - return self.createOrbPosFromInfo(info) + orbpos = self.namespace(info) + return orbpos def createOrbPosOrTunerSystem(self, fedata, feraw, info): orbpos = self.createOrbPos(feraw, info) @@ -652,9 +650,8 @@ def createOrbPosOrTunerSystem(self, fedata, feraw, info): def createTransponderName(self, feraw, info): orbpos = feraw.get("orbital_position") if orbpos is None: # Not satellite - orbpos = self.getOrbPosFromInfo(info) # if internal stream try to get pos - if orbpos is None: - return "" + orbpos = self.namespace(info) + return orbpos freq = feraw.get("frequency") if freq and freq < 10700000: # C-band if orbpos > 1800: @@ -756,15 +753,18 @@ def createTransponderName(self, feraw, info): if orbpos in sat_names: return sat_names[orbpos] + elif orbpos > 1800: + return str((float(3600 - orbpos)) / 10.0) + "W" else: - return self.formatOrbPos(orbpos) + return str((float(orbpos)) / 10.0) + "E" def createProviderName(self, info): refstr = info.getInfoString(iServiceInformation.sServiceref) if "%3a//" in refstr.lower() and "127.0.0.1" not in refstr and "0.0.0.0" not in refstr and "localhost" not in refstr: return "" elif "%3a//127" in refstr and "17999" in refstr: - return {282: "Sky UK", 192: "Sky Deutschland", 130: "Sky Italia"}.get((pos:=self.getOrbPosFromInfo(info)), self.formatOrbPos(pos)) + provider = self.namespace(info).replace("28.2\xb0E", "Sky UK").replace("19.2\xb0E", "Sky Deutschland").replace("13.0\xb0E", "Sky Italia") + return "%s" % provider else: return info.getInfoString(iServiceInformation.sProvider) From 7c74b780c3702ffb8db657414e2c393858351cf2 Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 15 Nov 2023 01:03:22 +0100 Subject: [PATCH 198/401] Revert "[PliExtraInfo] flake8 PEP" This reverts commit 03969eb0f7abb24b49da023c6ed0f19d17adf79f. --- lib/python/Components/Converter/PliExtraInfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/Converter/PliExtraInfo.py b/lib/python/Components/Converter/PliExtraInfo.py index f3af58ec776..98b77b2f200 100644 --- a/lib/python/Components/Converter/PliExtraInfo.py +++ b/lib/python/Components/Converter/PliExtraInfo.py @@ -760,7 +760,7 @@ def createTransponderName(self, feraw, info): def createProviderName(self, info): refstr = info.getInfoString(iServiceInformation.sServiceref) - if "%3a//" in refstr.lower() and "127.0.0.1" not in refstr and "0.0.0.0" not in refstr and "localhost" not in refstr: + if "%3a//" in refstr.lower() and not "127.0.0.1" in refstr and not "0.0.0.0" in refstr and not "localhost" in refstr: return "" elif "%3a//127" in refstr and "17999" in refstr: provider = self.namespace(info).replace("28.2\xb0E", "Sky UK").replace("19.2\xb0E", "Sky Deutschland").replace("13.0\xb0E", "Sky Italia") From 64af63d9728d91e7fd87398050de14b435993414 Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 15 Nov 2023 01:03:44 +0100 Subject: [PATCH 199/401] Revert "PEP8 double aggressive E301 ~ E306" This reverts commit caad10649f25a7deedf9fa559c717b73efe5697c. --- lib/python/Components/Converter/PliExtraInfo.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/python/Components/Converter/PliExtraInfo.py b/lib/python/Components/Converter/PliExtraInfo.py index 98b77b2f200..1edd2e9ea5e 100644 --- a/lib/python/Components/Converter/PliExtraInfo.py +++ b/lib/python/Components/Converter/PliExtraInfo.py @@ -630,6 +630,7 @@ def namespace(self, info): else: return "" + def createOrbPos(self, feraw, info): orbpos = feraw.get("orbital_position") if orbpos is not None: From a51dcc0280a0176d45edec5d73becb98d9468bf2 Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 15 Nov 2023 01:03:58 +0100 Subject: [PATCH 200/401] Revert "[PliExtraInfo] - add provider names for streamrelay services (Twol/Ev0)" This reverts commit 2525e1c16d6e9b217e96232726a92dc6873bbe07. --- .../Components/Converter/PliExtraInfo.py | 43 +++++-------------- 1 file changed, 10 insertions(+), 33 deletions(-) diff --git a/lib/python/Components/Converter/PliExtraInfo.py b/lib/python/Components/Converter/PliExtraInfo.py index 1edd2e9ea5e..b1c70bc7f6c 100644 --- a/lib/python/Components/Converter/PliExtraInfo.py +++ b/lib/python/Components/Converter/PliExtraInfo.py @@ -545,7 +545,7 @@ def createInfoString(self, fieldGroup, fedata, feraw, info): elif field == "TransponderModulationFEC": val = self.createModulation(fedata) + '-' + self.createFEC(fedata, feraw) elif field == "TransponderName": - val = self.createTransponderName(feraw, info) + val = self.createTransponderName(feraw) elif field == "ProviderName": val = self.createProviderName(info) elif field in ("NewLine", "NL"): @@ -618,41 +618,25 @@ def createTunerType(self, feraw): def createTunerSystem(self, fedata): return fedata.get("system") or "" - def namespace(self, info): - if "%3a//127" in info.getInfoString(iServiceInformation.sServiceref).lower(): - nmspc = info.getInfo(iServiceInformation.sNamespace) & 0xFFFFFFFF - namespace = "%08X" % nmspc - orbpos = int(namespace[:4], 16) - if orbpos > 1800: - return str((float(3600 - orbpos)) / 10.0) + "\xb0" + "W" - elif orbpos > 0: - return str((float(orbpos)) / 10.0) + "\xb0" + "E" - else: - return "" - - - def createOrbPos(self, feraw, info): + def createOrbPos(self, feraw): orbpos = feraw.get("orbital_position") if orbpos is not None: if orbpos > 1800: return str((float(3600 - orbpos)) / 10.0) + "\xb0" + "W" elif orbpos > 0: return str((float(orbpos)) / 10.0) + "\xb0" + "E" - else: - orbpos = self.namespace(info) - return orbpos + return "" - def createOrbPosOrTunerSystem(self, fedata, feraw, info): - orbpos = self.createOrbPos(feraw, info) + def createOrbPosOrTunerSystem(self, fedata, feraw): + orbpos = self.createOrbPos(feraw) if orbpos != "": return orbpos return self.createTunerSystem(fedata) - def createTransponderName(self, feraw, info): + def createTransponderName(self, feraw): orbpos = feraw.get("orbital_position") if orbpos is None: # Not satellite - orbpos = self.namespace(info) - return orbpos + return "" freq = feraw.get("frequency") if freq and freq < 10700000: # C-band if orbpos > 1800: @@ -760,14 +744,7 @@ def createTransponderName(self, feraw, info): return str((float(orbpos)) / 10.0) + "E" def createProviderName(self, info): - refstr = info.getInfoString(iServiceInformation.sServiceref) - if "%3a//" in refstr.lower() and not "127.0.0.1" in refstr and not "0.0.0.0" in refstr and not "localhost" in refstr: - return "" - elif "%3a//127" in refstr and "17999" in refstr: - provider = self.namespace(info).replace("28.2\xb0E", "Sky UK").replace("19.2\xb0E", "Sky Deutschland").replace("13.0\xb0E", "Sky Italia") - return "%s" % provider - else: - return info.getInfoString(iServiceInformation.sProvider) + return info.getInfoString(iServiceInformation.sProvider) def createMisPls(self, fedata): tmp = "" @@ -948,7 +925,7 @@ def getTextByType(self, textType): return self.createModulation(fedata) if textType == "OrbitalPosition": - return self.createOrbPos(feraw, info) + return self.createOrbPos(feraw) if textType == "TunerType": return self.createTunerType(feraw) @@ -957,7 +934,7 @@ def getTextByType(self, textType): return self.createTunerSystem(fedata) if self.type == "OrbitalPositionOrTunerSystem": - return self.createOrbPosOrTunerSystem(fedata, feraw, info) + return self.createOrbPosOrTunerSystem(fedata, feraw) if textType == "TerrestrialChannelNumber": return self.createChannelNumber(fedata, feraw) From c3a3756b7704bc101796fe43e1778f856e08bdab Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 15 Nov 2023 01:08:40 +0100 Subject: [PATCH 201/401] [PliExtraInfo] clean url so it doesn't show passwords in the interface --- lib/python/Components/Converter/PliExtraInfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/Converter/PliExtraInfo.py b/lib/python/Components/Converter/PliExtraInfo.py index b1c70bc7f6c..ebc220e9d2e 100644 --- a/lib/python/Components/Converter/PliExtraInfo.py +++ b/lib/python/Components/Converter/PliExtraInfo.py @@ -562,7 +562,7 @@ def createInfoString(self, fieldGroup, fedata, feraw, info): def createStreamURLInfo(self, info): refstr = info.getInfoString(iServiceInformation.sServiceref) if "%3a//" in refstr.lower(): - return refstr.split(":")[10].replace("%3a", ":").replace("%3A", ":") + return refstr.replace("%3a", ":").replace("%3A", ":").split("://")[1].split("/")[0].split('@')[-1] return "" def createFrequency(self, fedata): From 9105bec868ed59964409a24350c5266e5117ed91 Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 15 Nov 2023 01:12:54 +0100 Subject: [PATCH 202/401] [PliExtraInfo] avoid duplicating east/west code --- lib/python/Components/Converter/PliExtraInfo.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/python/Components/Converter/PliExtraInfo.py b/lib/python/Components/Converter/PliExtraInfo.py index ebc220e9d2e..eacbfa58ac0 100644 --- a/lib/python/Components/Converter/PliExtraInfo.py +++ b/lib/python/Components/Converter/PliExtraInfo.py @@ -618,15 +618,18 @@ def createTunerType(self, feraw): def createTunerSystem(self, fedata): return fedata.get("system") or "" - def createOrbPos(self, feraw): - orbpos = feraw.get("orbital_position") - if orbpos is not None: + def formatOrbPos(self, orbpos): + if isinstance(orbpos, int) and 0 <= orbpos <= 3600: # sanity if orbpos > 1800: return str((float(3600 - orbpos)) / 10.0) + "\xb0" + "W" - elif orbpos > 0: + else: return str((float(orbpos)) / 10.0) + "\xb0" + "E" return "" + def createOrbPos(self, feraw): + orbpos = feraw.get("orbital_position") + return self.formatOrbPos(orbpos) + def createOrbPosOrTunerSystem(self, fedata, feraw): orbpos = self.createOrbPos(feraw) if orbpos != "": @@ -738,10 +741,8 @@ def createTransponderName(self, feraw): if orbpos in sat_names: return sat_names[orbpos] - elif orbpos > 1800: - return str((float(3600 - orbpos)) / 10.0) + "W" else: - return str((float(orbpos)) / 10.0) + "E" + return self.formatOrbPos(orbpos) def createProviderName(self, info): return info.getInfoString(iServiceInformation.sProvider) From a2a4be554c1018734228b4381479afb07d819946 Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 15 Nov 2023 01:40:26 +0100 Subject: [PATCH 203/401] [PliExtraInfo] add an alternative way to get transponder data (compatible with stream relay) --- lib/python/Components/Converter/PliExtraInfo.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/python/Components/Converter/PliExtraInfo.py b/lib/python/Components/Converter/PliExtraInfo.py index eacbfa58ac0..45e78ced76e 100644 --- a/lib/python/Components/Converter/PliExtraInfo.py +++ b/lib/python/Components/Converter/PliExtraInfo.py @@ -1,6 +1,6 @@ # shamelessly copied from pliExpertInfo (Vali, Mirakels, Littlesat) -from enigma import iServiceInformation, iPlayableService +from enigma import eServiceCenter, iServiceInformation, iPlayableService from Components.Converter.Converter import Converter from Components.Element import cached from Components.config import config @@ -9,6 +9,7 @@ from Tools.Hex2strColor import Hex2strColor from Components.Converter.Poll import Poll from skin import parameters +from Session import SessionObject caid_data = ( ("0x100", "0x1ff", "Seca", "S", True), @@ -885,6 +886,9 @@ def getTextByType(self, textType): feinfo = service.frontendInfo() if feinfo: self.feraw = feinfo.getAll(config.usage.infobar_frontend_source.value == "settings") + if not self.feraw: + serviceref = SessionObject().session.nav.getCurrentlyPlayingServiceReference() + self.feraw = serviceref and eServiceCenter.getInstance().info(serviceref).getInfoObject(serviceref, iServiceInformation.sTransponderData) if self.feraw: self.fedata = ConvertToHumanReadable(self.feraw) From efc22d824750f062dc7b6689d7820381a07093e5 Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 15 Nov 2023 01:41:46 +0100 Subject: [PATCH 204/401] [PliExtraInfo] add a temp workaround for stream relay provider names Requested by @Ev0 --- lib/python/Components/Converter/PliExtraInfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/Converter/PliExtraInfo.py b/lib/python/Components/Converter/PliExtraInfo.py index 45e78ced76e..ed277572299 100644 --- a/lib/python/Components/Converter/PliExtraInfo.py +++ b/lib/python/Components/Converter/PliExtraInfo.py @@ -746,7 +746,7 @@ def createTransponderName(self, feraw): return self.formatOrbPos(orbpos) def createProviderName(self, info): - return info.getInfoString(iServiceInformation.sProvider) + return info.getInfoString(iServiceInformation.sProvider) or self.feraw and {282: "BSkyB", 192: "SKY", 130: "SkyItalia"}.get(self.feraw.get("orbital_position"), "") def createMisPls(self, fedata): tmp = "" From 9ade30460394ff61c25c0fd6d828529921859ece Mon Sep 17 00:00:00 2001 From: openvix-build Date: Wed, 15 Nov 2023 01:08:26 +0000 Subject: [PATCH 205/401] openvix: developer 6.4.010.003 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 4fc22879882..c086970fef1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1201,3 +1201,4 @@ openvix: developer 6.4.009.014 openvix: developer 6.4.009.015 openvix: developer 6.4.010.001 openvix: developer 6.4.010.002 +openvix: developer 6.4.010.003 From 6fca70647cfae10389946c245e94ce309a85ab78 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Thu, 16 Nov 2023 08:54:41 +0200 Subject: [PATCH 206/401] [Added] switching the layout of the pager if total count of pages exceeds specified value --- lib/python/Components/Addons/Pager.py | 69 ++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/lib/python/Components/Addons/Pager.py b/lib/python/Components/Addons/Pager.py index e30c22cc4cc..942797eadd9 100644 --- a/lib/python/Components/Addons/Pager.py +++ b/lib/python/Components/Addons/Pager.py @@ -21,9 +21,14 @@ def __init__(self): self.spacing = applySkinFactor(5) self.picDotPage = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/dot.png")) self.picDotCurPage = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/dotfull.png")) + self.picShevronLeft = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/shevronleft.png")) + self.picShevronRight = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/shevronright.png")) + self.picShevronUp = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/shevronup.png")) + self.picShevronDown = LoadPixmap(resolveFilename(SCOPE_GUISKIN, "icons/shevrondown.png")) self.showIcons = "showAll" # can be "showAll", "onlyFirst", "onlyLast" self.orientations = {"orHorizontal": eListbox.orHorizontal, "orVertical": eListbox.orVertical} self.orientation = eListbox.orHorizontal + self.max_pages = 10 def onContainerShown(self): # disable listboxes default scrollbars @@ -51,7 +56,51 @@ def buildEntry(self, currentPage, pageCount): xPos = (width - width_dots) / 2 - pixd_width / 2 if self.showIcons == "showAll" else 0 yPos = (height - height_dots) / 2 - pixd_height / 2 if self.showIcons == "showAll" else 0 res = [None] - if pageCount > (0 if self.showIcons == "showAll" else -1): + if self.showIcons == "showAll" and pageCount > 0 and self.max_pages > 0 and pageCount > self.max_pages: + width_dots = pixd_width + (pixd_width + self.spacing) * (2 if currentPage > 0 and currentPage < pageCount else 1) + xPos = (width - width_dots) / 2 - pixd_width / 2 + yPos = (height - height_dots) / 2 - pixd_height / 2 + if self.orientation == eListbox.orHorizontal: + if currentPage > 0: + res.append(MultiContentEntryPixmapAlphaBlend( + pos=(xPos, 0), + size=(pixd_width, pixd_height), + png=self.picShevronLeft, + backcolor=None, backcolor_sel=None, flags=BT_ALIGN_CENTER)) + xPos += pixd_width + self.spacing + res.append(MultiContentEntryPixmapAlphaBlend( + pos=(xPos, 0), + size=(pixd_width, pixd_height), + png=self.picDotCurPage, + backcolor=None, backcolor_sel=None, flags=BT_ALIGN_CENTER)) + xPos += pixd_width + self.spacing + if currentPage < pageCount: + res.append(MultiContentEntryPixmapAlphaBlend( + pos=(xPos, 0), + size=(pixd_width, pixd_height), + png=self.picShevronRight, + backcolor=None, backcolor_sel=None, flags=BT_ALIGN_CENTER)) + else: + if currentPage > 0: + res.append(MultiContentEntryPixmapAlphaBlend( + pos=(0, yPos), + size=(pixd_width, pixd_height), + png=self.picShevronLeft, + backcolor=None, backcolor_sel=None, flags=BT_ALIGN_CENTER)) + yPos += pixd_height + self.spacing + res.append(MultiContentEntryPixmapAlphaBlend( + pos=(0, yPos), + size=(pixd_width, pixd_height), + png=self.picDotCurPage, + backcolor=None, backcolor_sel=None, flags=BT_ALIGN_CENTER)) + yPos += pixd_height + self.spacing + if currentPage < pageCount: + res.append(MultiContentEntryPixmapAlphaBlend( + pos=(0, yPos), + size=(pixd_width, pixd_height), + png=self.picShevronRight, + backcolor=None, backcolor_sel=None, flags=BT_ALIGN_CENTER)) + elif pageCount > (0 if self.showIcons == "showAll" else -1): pages = list(range(pageCount + 1)) # add option to show just first or last icon if self.showIcons == "onlyFirst": @@ -163,6 +212,22 @@ def applySkin(self, desktop, parent): pic = LoadPixmap(resolveFilename(SCOPE_GUISKIN, value)) if pic: self.picDotCurPage = pic + elif attrib == "picL": + pic = LoadPixmap(resolveFilename(SCOPE_GUISKIN, value)) + if pic: + self.picShevronLeft = pic + elif attrib == "picR": + pic = LoadPixmap(resolveFilename(SCOPE_GUISKIN, value)) + if pic: + self.picShevronRight = pic + elif attrib == "picU": + pic = LoadPixmap(resolveFilename(SCOPE_GUISKIN, value)) + if pic: + self.picShevronUp = pic + elif attrib == "picD": + pic = LoadPixmap(resolveFilename(SCOPE_GUISKIN, value)) + if pic: + self.picShevronDown = pic elif attrib == "itemHeight": self.l.setItemHeight(parseScale(value)) elif attrib == "itemWidth": @@ -171,6 +236,8 @@ def applySkin(self, desktop, parent): self.spacing = parseScale(value) elif attrib == "showIcons": self.showIcons = value + elif attrib == "maxPages": + self.max_pages = value elif attrib == "orientation": self.orientation = self.orientations.get(value, self.orientations["orHorizontal"]) if self.orientation == eListbox.orHorizontal: From e562f2536e869b917f2cd7febac68949102a93a5 Mon Sep 17 00:00:00 2001 From: Hains Date: Sun, 26 Dec 2021 17:03:43 +0100 Subject: [PATCH 207/401] VariableText.py: Cast self.message to unicode string File "/usr/lib/enigma2/python/Components/GUIComponent.py", line 106, in GUIcreate self.postWidgetCreate(self.instance) File "/usr/lib/enigma2/python/Components/VariableText.py", line 24, in postWidgetCreate instance.setText(self.message or "") TypeError: in method 'eLabel_setText', argument 2 of type 'std::string const &' --- lib/python/Components/VariableText.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/python/Components/VariableText.py b/lib/python/Components/VariableText.py index 46b151d7c5b..8b6c9ee4c34 100644 --- a/lib/python/Components/VariableText.py +++ b/lib/python/Components/VariableText.py @@ -28,7 +28,4 @@ def getText(self): text = property(getText, setText) def postWidgetCreate(self, instance): - try: - instance.setText(self.message or "") - except: - pass + instance.setText(str(self.message) or "") From 22ab4b496b770fc2041f330f7a1c975c5c5409b1 Mon Sep 17 00:00:00 2001 From: Dima73 Date: Wed, 8 Nov 2023 18:36:15 +0200 Subject: [PATCH 208/401] [VariableText] sanity check text 'str' type File "/usr/lib/enigma2/python/Components/VariableText.py", line 12, in setText TypeError: in method 'eLabel_setText', argument 2 of type 'std::string const &' --- lib/python/Components/VariableText.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/lib/python/Components/VariableText.py b/lib/python/Components/VariableText.py index 8b6c9ee4c34..04a2c225d24 100644 --- a/lib/python/Components/VariableText.py +++ b/lib/python/Components/VariableText.py @@ -8,13 +8,9 @@ def __init__(self): self.onChanged = [] def setText(self, text): - try: - self.message = text - if self.instance: - self.instance.setText(self.message or "") - except: - self.message = "" - self.instance.setText(self.message or "") + self.message = text + if self.instance: + self.instance.setText(str(self.message) or "") for x in self.onChanged: x() From 807ecad9ba242df65298932f2689258e32e86e38 Mon Sep 17 00:00:00 2001 From: Dima73 Date: Mon, 13 Nov 2023 17:31:21 +0200 Subject: [PATCH 209/401] [CI] fix utf-8 camname -thanks @Captain --- lib/dvb_ci/dvbci_appmgr.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/dvb_ci/dvbci_appmgr.cpp b/lib/dvb_ci/dvbci_appmgr.cpp index 96b832f8d0b..1eaedb784a1 100644 --- a/lib/dvb_ci/dvbci_appmgr.cpp +++ b/lib/dvb_ci/dvbci_appmgr.cpp @@ -3,6 +3,7 @@ #include #include #include +#include eDVBCIApplicationManagerSession::eDVBCIApplicationManagerSession(eDVBCISlot *tslot) { @@ -50,7 +51,12 @@ int eDVBCIApplicationManagerSession::receivedAPDU(const unsigned char *tag,const eDebugNoNewLine("\n"); m_app_name = str; - /* emit */ eDVBCI_UI::getInstance()->m_messagepump.send(eDVBCIInterfaces::Message(eDVBCIInterfaces::Message::appNameChanged, slot->getSlotID(), str)); + if (m_app_name.size() > 0 && !isUTF8(m_app_name)) + { + m_app_name = repairUTF8(m_app_name.c_str(), m_app_name.size()); + eDebug("[CI AM] fixed menu string: %s", m_app_name.c_str()); + } + /* emit */ eDVBCI_UI::getInstance()->m_messagepump.send(eDVBCIInterfaces::Message(eDVBCIInterfaces::Message::appNameChanged, slot->getSlotID(), m_app_name.c_str())); /* emit */ eDVBCI_UI::getInstance()->m_messagepump.send(eDVBCIInterfaces::Message(eDVBCIInterfaces::Message::slotStateChanged, slot->getSlotID(), 2)); break; From 313e84dcdcc604ef27951740de911c9af6210c52 Mon Sep 17 00:00:00 2001 From: WanWizard Date: Fri, 27 Oct 2023 14:21:03 +0100 Subject: [PATCH 210/401] skip non-utf8 entries when loading a playlist --- lib/python/Components/Playlist.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/python/Components/Playlist.py b/lib/python/Components/Playlist.py index eea2827cdd7..e9c6e17816b 100644 --- a/lib/python/Components/Playlist.py +++ b/lib/python/Components/Playlist.py @@ -52,10 +52,13 @@ def open(self, filename): except IOError: return None while True: - entry = file.readline().strip() - if entry == "": - break - self.addService(ServiceReference(entry)) + try: + entry = file.readline().strip() + if entry == "": + break + self.addService(ServiceReference(entry)) + except UnicodeDecodeError: + pass file.close() return self.list From cb682ab1599875f17c0d4022e3ce53d7c75218d2 Mon Sep 17 00:00:00 2001 From: openvix-build Date: Thu, 16 Nov 2023 10:51:43 +0000 Subject: [PATCH 211/401] openvix: developer 6.4.010.004 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index c086970fef1..3a9d8613bdb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1202,3 +1202,4 @@ openvix: developer 6.4.009.015 openvix: developer 6.4.010.001 openvix: developer 6.4.010.002 openvix: developer 6.4.010.003 +openvix: developer 6.4.010.004 From ea780f84877bc7a13ddf7f3281d1d9bf9183010e Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Thu, 16 Nov 2023 17:46:54 +0200 Subject: [PATCH 212/401] [Fixed] Wrong setting for servicelist [Fixed] MovieInfo converter formatted text [Added] Add recording service name to the formatted string --- lib/python/Components/Converter/MovieInfo.py | 28 +++++++++++--------- lib/python/Components/ServiceList.py | 2 +- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/lib/python/Components/Converter/MovieInfo.py b/lib/python/Components/Converter/MovieInfo.py index c742a1acd58..5ef8ac9f267 100644 --- a/lib/python/Components/Converter/MovieInfo.py +++ b/lib/python/Components/Converter/MovieInfo.py @@ -63,15 +63,16 @@ def __init__(self, type): self.type = self.FORMAT_STRING self.separatorChar = self.parts[0] - for arg in args: - name, value = self.KEYWORDS.get(arg, ("Error", None)) - if name == "Error": - print("[MovieInfo] ERROR: Unexpected / Invalid argument token '%s'!" % arg) - else: - setattr(self, name, value) - if ((name == "Error") or (type is None)): - print("[MovieInfo] Valid arguments are: ShortDescription|MetaDescription|FullDescription|RecordServiceName|RecordServiceRef|FileSize.") - print("[MovieInfo] Valid options for descriptions are: Separated|NotSeparated|Trimmed|NotTrimmed.") + if self.type != self.FORMAT_STRING: + for arg in args: + name, value = self.KEYWORDS.get(arg, ("Error", None)) + if name == "Error": + print("[MovieInfo] ERROR: Unexpected / Invalid argument token '%s'!" % arg) + else: + setattr(self, name, value) + if ((name == "Error") or (type is None)): + print("[MovieInfo] Valid arguments are: ShortDescription|MetaDescription|FullDescription|RecordServiceName|RecordServiceRef|FileSize.") + print("[MovieInfo] Valid options for descriptions are: Separated|NotSeparated|Trimmed|NotTrimmed.") def destroy(self): Converter.destroy(self) @@ -145,14 +146,17 @@ def getText(self): timeCreate = strftime("%A %d %b %Y", localtime(info.getInfo(service, iServiceInformation.sTimeCreate))) duration = "%d min" % (info.getLength(service) / 60) filesize = "%d MB" % (info.getInfoObject(service, iServiceInformation.sFileSize) / (1024 * 1024)) + rec_ref_str = info.getInfoString(service, iServiceInformation.sServiceref) res_str = "" for x in self.parts[1:]: - if x == "TIMECREATED" and timeCreate != '': + if x == "TIMECREATED" and timeCreate: res_str = self.appendToStringWithSeparator(res_str, timeCreate) - if x == "DURATION" and duration != '': + if x == "DURATION" and duration: res_str = self.appendToStringWithSeparator(res_str, duration) - if x == "FILESIZE" and filesize != '': + if x == "FILESIZE" and filesize: res_str = self.appendToStringWithSeparator(res_str, filesize) + if x == "RECSERVICE" and rec_ref_str: + res_str = self.appendToStringWithSeparator(res_str, rec_ref_str) return res_str return "" diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index adbe6075abf..07a0ac34d82 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -454,7 +454,7 @@ def setMode(self, mode): self.mode = mode self.setItemsPerPage() two_lines_val = int(config.usage.servicelist_twolines.value) - show_two_lines = two_lines_val and mode == self.MODE_FAVOURITES + show_two_lines = (two_lines_val and mode == self.MODE_FAVOURITES) or two_lines_val == 3 self.ItemHeight *= (2 if show_two_lines else 1) self.l.setItemHeight(self.ItemHeight) self.l.setVisualMode(eListboxServiceContent.visModeComplex if two_lines_val < 3 else eListboxServiceContent.visSkinDefined) From 9ea141a7dd7866138e7154c7e62d108d061f5b4d Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Thu, 16 Nov 2023 18:04:10 +0200 Subject: [PATCH 213/401] [Fixed] Record service name --- lib/python/Components/Converter/MovieInfo.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/python/Components/Converter/MovieInfo.py b/lib/python/Components/Converter/MovieInfo.py index 5ef8ac9f267..7088b34f25a 100644 --- a/lib/python/Components/Converter/MovieInfo.py +++ b/lib/python/Components/Converter/MovieInfo.py @@ -147,6 +147,7 @@ def getText(self): duration = "%d min" % (info.getLength(service) / 60) filesize = "%d MB" % (info.getInfoObject(service, iServiceInformation.sFileSize) / (1024 * 1024)) rec_ref_str = info.getInfoString(service, iServiceInformation.sServiceref) + rec_service_name = eServiceReference(rec_ref_str).getServiceName() res_str = "" for x in self.parts[1:]: if x == "TIMECREATED" and timeCreate: @@ -155,8 +156,8 @@ def getText(self): res_str = self.appendToStringWithSeparator(res_str, duration) if x == "FILESIZE" and filesize: res_str = self.appendToStringWithSeparator(res_str, filesize) - if x == "RECSERVICE" and rec_ref_str: - res_str = self.appendToStringWithSeparator(res_str, rec_ref_str) + if x == "RECSERVICE" and rec_service_name: + res_str = self.appendToStringWithSeparator(res_str, rec_service_name) return res_str return "" From 23b7fd20700b8e3b5613a43d969e64e3d2bd20ce Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Thu, 16 Nov 2023 19:56:13 +0200 Subject: [PATCH 214/401] [Fixed] EPG timer icons position --- lib/python/Components/EpgListGrid.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/EpgListGrid.py b/lib/python/Components/EpgListGrid.py index 17faffc5e6f..d6235ce7b94 100644 --- a/lib/python/Components/EpgListGrid.py +++ b/lib/python/Components/EpgListGrid.py @@ -660,7 +660,7 @@ def buildEntry(self, service, serviceName, events, picon, channel): else: recIconHeight = top + height - pix_height - applySkinFactor(5) if matchType == 0: - pos = (left + xpos + ewidth - applySkinFactor(10), recIconHeight) + pos = (left + xpos + ewidth - pix_width - applySkinFactor(5), recIconHeight) else: pos = (left + xpos + ewidth - pix_width - applySkinFactor(5), recIconHeight) res.append(MultiContentEntryPixmapAlphaBlend( From e3569394a687aa2d37f14ea7966dd59d51b5f43e Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Thu, 16 Nov 2023 21:07:21 +0200 Subject: [PATCH 215/401] [Fixed] new servicelist visual mode offset when have folder icon --- lib/service/listboxservice.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index e5a7cb0c187..9dcec0c3d46 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -955,7 +955,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const xoffs = xoffset; if (PyCallable_Check(m_GetPiconNameFunc)) { - eRect piconArea = eRect(xoffs, offset.y(), 125, m_itemheight);//m_element_position[celServiceInfo]; + eRect piconArea = eRect(xoffs, offset.y(), 125, m_itemheight); /* PIcons are usually about 100:60. Make it a * bit wider in case the icons are diffently * shaped, and to add a bit of margin between @@ -981,7 +981,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } painter.clippop(); } - xoffs += 125 + 16 + 8; + if (!(isMarker || isDirectory)) xoffs += 125 + 16 + 8; } if (isMarker || isDirectory) { From 8239ea6a211ff9e27d809b63ffe1c1917ca9fd5d Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Thu, 16 Nov 2023 22:06:21 +0200 Subject: [PATCH 216/401] [Fixed] ServiceList scaling and alignment --- lib/service/listboxservice.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 9dcec0c3d46..c770312faa3 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -987,14 +987,13 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (isMarker || isDirectory) { ePtr &pixmap_mDir = isMarker ? m_pixmaps[picMarker] : isDirectory ? m_pixmaps[picFolder] : m_pixmaps[picElements]; if (pixmap_mDir) { - eSize pixmap_size = pixmap_mDir->size(); - eRect area = eRect(xoffs, offset.y() + (ctrlHeight - pixmap_size.height())/2, pixmap_size.width(), pixmap_size.height()); + int pflags = gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER; + eRect area = eRect(xoffs, offset.y(), 125, m_itemheight); painter.clip(area); - painter.blit(pixmap_mDir, ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.blitScale(pixmap_mDir, eRect(xoffs, offset.y(), 125, m_itemheight), area, pflags); painter.clippop(); - - xoffs += pixmap_size.width() + 16 + 8; } + xoffs += 125 + 16 + 8; } // channel number + name @@ -1475,19 +1474,21 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const { eSize pixmap_size = pixmap->size(); eRect area; - if (e == celFolderPixmap || m_element_position[celServiceNumber].width() < pixmap_size.width()) + if (e == celFolderPixmap || m_element_position[celServiceNumber].width() < m_itemheight) { area = m_element_position[celServiceName]; if (m_element_position[celServiceEventProgressbar].left() == 0) area.setLeft(0); - xoffset = pixmap_size.width() + m_items_distances; + xoffset = m_itemheight + m_items_distances; } else area = m_element_position[celServiceNumber]; - int correction = (area.height() - pixmap_size.height()) / 2; area.moveBy(offset); painter.clip(area); - painter.blit(pixmap, ePoint(area.left(), offset.y() + correction), area, gPainter::BT_ALPHABLEND); + painter.blitScale(pixmap, + eRect(area.left(), offset.y(), m_itemheight, area.height()), + area, + gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER); painter.clippop(); } } From 6ad41004eef7aa13989a2aaad47c12516be44f04 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Thu, 16 Nov 2023 22:47:29 +0200 Subject: [PATCH 217/401] [Added] Compatibility of the ServiceList with pager --- lib/python/Components/Addons/Pager.py | 2 ++ lib/service/listboxservice.h | 3 +++ 2 files changed, 5 insertions(+) diff --git a/lib/python/Components/Addons/Pager.py b/lib/python/Components/Addons/Pager.py index 942797eadd9..d7f1486a22f 100644 --- a/lib/python/Components/Addons/Pager.py +++ b/lib/python/Components/Addons/Pager.py @@ -162,6 +162,8 @@ def getListCount(self): return self.source.listCount elif hasattr(self.source, 'list'): return len(self.source.list) + elif hasattr(self.source, 'l') and hasattr(self.source.l, 'getListSize'): + return self.source.l.getListSize() return 0 def getListItemSize(self): diff --git a/lib/service/listboxservice.h b/lib/service/listboxservice.h index fd037c47c9a..bd610a26560 100644 --- a/lib/service/listboxservice.h +++ b/lib/service/listboxservice.h @@ -28,6 +28,9 @@ class eListboxServiceContent: public virtual iListboxContent int getNextBeginningWithChar(char c); int getPrevMarkerPos(); int getNextMarkerPos(); + int getCurrentSelectionIndex() { return m_cursor_number; } + eSize getItemSize() { return m_itemsize; } + int getListSize() { return m_size; } /* support for marked services */ void initMarked(); From 6566d5fe6a175e1b496fd32b983d1acb590594f3 Mon Sep 17 00:00:00 2001 From: openvix-build Date: Thu, 16 Nov 2023 21:56:47 +0000 Subject: [PATCH 218/401] openvix: developer 6.4.010.005 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 3a9d8613bdb..d310498136b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1203,3 +1203,4 @@ openvix: developer 6.4.010.001 openvix: developer 6.4.010.002 openvix: developer 6.4.010.003 openvix: developer 6.4.010.004 +openvix: developer 6.4.010.005 From d6a7c4b994b7c5f6d7199812a94078ff76e6d77f Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Fri, 17 Nov 2023 10:36:35 +0200 Subject: [PATCH 219/401] [Fixed] markers icon stretching [Added] different modes of rendering markers --- lib/python/Components/ServiceList.py | 6 +++ lib/service/listboxservice.cpp | 70 +++++++++++++++++++++------- lib/service/listboxservice.h | 4 ++ 3 files changed, 63 insertions(+), 17 deletions(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 07a0ac34d82..fbda1734696 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -222,6 +222,12 @@ def selectionPixmapLarge(value): pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, value)) pic and self.l.setSelectionPicture(pic) + def markerLine(value): + self.l.setMarkerAsLine(parseScale(value)) + + def markerTextAlignment(value): + self.l.setMarkerTextAlignment(value) + for (attrib, value) in self.skinAttributes[:]: try: locals().get(attrib)(value) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index c770312faa3..35654ed42df 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -382,7 +382,7 @@ void eListboxServiceContent::sort() DEFINE_REF(eListboxServiceContent); eListboxServiceContent::eListboxServiceContent() - :m_visual_mode(visModeSimple), m_size(0), m_current_marked(false), m_itemheight(25), m_hide_number_marker(false), m_show_two_lines(0), m_servicetype_icon_mode(0), m_crypto_icon_mode(0), m_record_indicator_mode(0), m_column_width(0), m_progressbar_height(6), m_progressbar_border_width(2), m_nonplayable_margins(10), m_items_distances(8), m_sides_margin(0) + :m_visual_mode(visModeSimple), m_size(0), m_current_marked(false), m_itemheight(25), m_hide_number_marker(false), m_show_two_lines(0), m_servicetype_icon_mode(0), m_crypto_icon_mode(0), m_record_indicator_mode(0), m_column_width(0), m_progressbar_height(6), m_progressbar_border_width(2), m_nonplayable_margins(10), m_items_distances(8), m_sides_margin(0), m_marker_as_line(0) { memset(m_color_set, 0, sizeof(m_color_set)); cursorHome(); @@ -984,22 +984,49 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (!(isMarker || isDirectory)) xoffs += 125 + 16 + 8; } + // channel number + name + if (service_info) + service_info->getName(ref, text); + + ePtr paraName = new eTextPara(eRect(0, 0, m_itemsize.width(), m_itemheight/2)); + paraName->setFont(m_element_font[celServiceName]); + paraName->renderString(text.c_str()); + eRect bboxName = paraName->getBoundBox(); + + int xoffsMarker = 16 + 125 + 16 + 8; + int correction = 0; + if (!m_marker_alignment.empty() && m_marker_alignment == "center" && isMarker) { + xoffsMarker = (m_itemsize.width() - bboxName.width()) / 2; + correction = 16; + } + if (isMarker || isDirectory) { ePtr &pixmap_mDir = isMarker ? m_pixmaps[picMarker] : isDirectory ? m_pixmaps[picFolder] : m_pixmaps[picElements]; - if (pixmap_mDir) { - int pflags = gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER; - eRect area = eRect(xoffs, offset.y(), 125, m_itemheight); - painter.clip(area); - painter.blitScale(pixmap_mDir, eRect(xoffs, offset.y(), 125, m_itemheight), area, pflags); - painter.clippop(); + if (isDirectory || (isMarker && !m_marker_as_line)) { + if (pixmap_mDir) { + eSize pixmap_size = pixmap_mDir->size(); + if (pixmap_size.width() < 125 || pixmap_size.height() < m_itemheight){ + eRect area = eRect(xoffs, offset.y() + (ctrlHeight - pixmap_size.height())/2, pixmap_size.width(), pixmap_size.height()); + painter.clip(area); + painter.blit(pixmap_mDir, ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + } else { + int pflags = gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER; + eRect area = eRect(xoffs, offset.y(), 125, m_itemheight); + painter.clip(area); + painter.blitScale(pixmap_mDir, eRect(xoffs, offset.y(), 125, m_itemheight), area, pflags); + } + painter.clippop(); + } + } else if (isMarker && m_marker_as_line) { + eRect firstLineRect = eRect(xoffs, offset.y() + (m_itemheight - m_marker_as_line) / 2, xoffsMarker - 16 - 8 - xoffs - correction, m_marker_as_line); + painter.fill(firstLineRect); + int secondLineOffset = xoffsMarker + bboxName.width() + 16 + 8 - correction; + eRect secondLineRect = eRect(secondLineOffset, offset.y() + (m_itemheight - m_marker_as_line) / 2, m_itemsize.width() - secondLineOffset - 16 - 8, m_marker_as_line); + painter.fill(secondLineRect); } xoffs += 125 + 16 + 8; } - // channel number + name - if (service_info) - service_info->getName(ref, text); - if (!isMarker && !isDirectory) { std::string chNum = ""; eRect serviceNumberRect = m_element_position[celServiceNumber]; @@ -1015,7 +1042,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const para->setFont(m_element_font[celServiceName]); para->renderString(text.c_str()); eRect bbox = para->getBoundBox(); - painter.renderPara(para, ePoint(xoffs, offset.y() + yoffs + ((ctrlHeight - bbox.height())/2))); + painter.renderPara(para, ePoint(xoffsMarker - correction , offset.y() + yoffs + ((ctrlHeight - bbox.height())/2))); // event name if (is_event) @@ -1473,22 +1500,31 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (pixmap) { eSize pixmap_size = pixmap->size(); + bool notScale = (e == celMarkerPixmap) && (pixmap_size.width() < 125 || pixmap_size.height() < m_itemheight); eRect area; if (e == celFolderPixmap || m_element_position[celServiceNumber].width() < m_itemheight) { area = m_element_position[celServiceName]; if (m_element_position[celServiceEventProgressbar].left() == 0) area.setLeft(0); - xoffset = m_itemheight + m_items_distances; + if (notScale) + xoffset = pixmap_size.width() + m_items_distances; + else + xoffset = 125 + m_items_distances; } else area = m_element_position[celServiceNumber]; area.moveBy(offset); painter.clip(area); - painter.blitScale(pixmap, - eRect(area.left(), offset.y(), m_itemheight, area.height()), - area, - gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER); + if (notScale) { + int correction = (area.height() - pixmap_size.height()) / 2; + painter.blit(pixmap, ePoint(area.left(), offset.y() + correction), area, gPainter::BT_ALPHABLEND); + } else { + painter.blitScale(pixmap, + eRect(area.left(), offset.y(), m_itemheight, area.height()), + area, + gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER); + } painter.clippop(); } } diff --git a/lib/service/listboxservice.h b/lib/service/listboxservice.h index bd610a26560..38688738818 100644 --- a/lib/service/listboxservice.h +++ b/lib/service/listboxservice.h @@ -106,9 +106,11 @@ class eListboxServiceContent: public virtual iListboxContent void setNonplayableMargins(int value) { m_nonplayable_margins = value; } void setItemsDistances(int value) { m_items_distances = value; } void setSidesMargin(int value) { m_sides_margin = value; } + void setMarkerAsLine(int value) { m_marker_as_line = value; } void setNextTitle(const std::string &string) { m_next_title = string; } void setTextSeparator(const std::string &string) { m_separator = string; } + void setMarkerTextAlignment(const std::string &string) { m_marker_alignment = string; } // currently supports left and center static void setGetPiconNameFunc(SWIG_PYOBJECT(ePyObject) func); @@ -204,9 +206,11 @@ class eListboxServiceContent: public virtual iListboxContent int m_nonplayable_margins; int m_items_distances; int m_sides_margin; + int m_marker_as_line; std::string m_next_title; std::string m_separator; + std::string m_marker_alignment; }; #endif From 403c53af546e3f1a06136418f7f57fcdd47097e2 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Fri, 17 Nov 2023 12:40:29 +0000 Subject: [PATCH 220/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Components/ServiceList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index fbda1734696..ece3ec5c3d9 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -224,7 +224,7 @@ def selectionPixmapLarge(value): def markerLine(value): self.l.setMarkerAsLine(parseScale(value)) - + def markerTextAlignment(value): self.l.setMarkerTextAlignment(value) From e50f30e6a33dd7789666b267978d65c6f49239fa Mon Sep 17 00:00:00 2001 From: Huevos Date: Fri, 17 Nov 2023 23:35:16 +0100 Subject: [PATCH 221/401] [SoftcamManager] remove " " when key_yellow is supposed to display nothing. --- lib/python/Plugins/SystemPlugins/ViX/SoftcamManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Plugins/SystemPlugins/ViX/SoftcamManager.py b/lib/python/Plugins/SystemPlugins/ViX/SoftcamManager.py index c05f1dd83e9..616c807bec3 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/SoftcamManager.py +++ b/lib/python/Plugins/SystemPlugins/ViX/SoftcamManager.py @@ -191,7 +191,7 @@ def selectionChanged(self): else: self["key_green"].setText(_("Stop")) if self.currentactivecam.find(selcam) < 0: - self["key_yellow"].setText(" ") + self["key_yellow"].setText("") else: self["key_yellow"].setText(_("Restart")) From fc3ee2557cff7bddc54dde5f00fe4fc9f987820b Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sun, 19 Nov 2023 20:10:19 +0200 Subject: [PATCH 222/401] [ServiceList/lisboxservice] refactor two line mode More useful display. Not double height. And adjustable to some degree from the skin. --- lib/python/Components/ServiceList.py | 46 +++--- lib/python/Components/UsageConfig.py | 4 +- lib/service/listboxservice.cpp | 223 +++++++++++++++------------ lib/service/listboxservice.h | 9 +- 4 files changed, 160 insertions(+), 122 deletions(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index ece3ec5c3d9..487c2851f9d 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -1,5 +1,5 @@ from Components.GUIComponent import GUIComponent -from skin import parseColor, parseFont, parseScale +from skin import parseColor, parseFont, parseScale, applySkinFactor from enigma import eListboxServiceContent, eListbox, eServiceCenter, eServiceReference, gFont, eRect, eSize from Tools.LoadPixmap import LoadPixmap @@ -70,6 +70,7 @@ def __init__(self, serviceList): self.root = None self.mode = self.MODE_NORMAL self.listHeight = 0 + self.listHeightOrig = 0 self.listWidth = 0 self.ServiceNumberFontName = "Regular" self.ServiceNumberFontSize = 20 @@ -83,8 +84,8 @@ def __init__(self, serviceList): self.progressPercentWidth = 0 self.fieldMargins = 10 self.sidesMargin = 0 - self.ItemHeight = None - self.skinItemHeight = None + self.ItemHeight = 0 + self.ItemHeightTwoLine = applySkinFactor(58) self.onSelectionChanged = [] @@ -168,9 +169,6 @@ def picServiceEventProgressbar(value): pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, value)) pic and self.l.setPixmap(self.l.picServiceEventProgressbar, pic) - def serviceItemHeight(value): - self.skinItemHeight = parseScale(value) - def serviceNameFont(value): font = parseFont(value, ((1, 1), (1, 1))) self.ServiceNameFontName = font.family @@ -222,9 +220,18 @@ def selectionPixmapLarge(value): pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, value)) pic and self.l.setSelectionPicture(pic) + def itemHeightTwoLine(value): + self.ItemHeightTwoLine = parseScale(value) + + def itemHeight(value): + self.ItemHeight = parseScale(value) + def markerLine(value): self.l.setMarkerAsLine(parseScale(value)) + def markerLineColor(value): + self.l.setMarkerLineColor(parseColor(value)) + def markerTextAlignment(value): self.l.setMarkerTextAlignment(value) @@ -237,6 +244,7 @@ def markerTextAlignment(value): rc = GUIComponent.applySkin(self, desktop, parent) self.listHeight = self.instance.size().height() self.listWidth = self.instance.size().width() + self.listHeightOrig = self.listHeight self.setFontsize() self.setMode(self.mode) return rc @@ -353,10 +361,15 @@ def getCurrentIndex(self): def setItemsPerPage(self): numberOfRows = config.usage.serviceitems_per_page.value - itemHeight = (self.listHeight // numberOfRows if numberOfRows > 0 else self.skinItemHeight) or 28 - self.ItemHeight = itemHeight - self.l.setItemHeight(itemHeight) - if self.listHeight: + two_lines_val = int(config.usage.servicelist_twolines.value) + if two_lines_val == 1: + numberOfRows = numberOfRows // 2 + itemHeight = self.ItemHeight if not two_lines_val else self.ItemHeightTwoLine + if numberOfRows > 0: + itemHeight = self.listHeight // numberOfRows + self.ItemHeight = itemHeight + self.l.setItemHeight(itemHeight) + if self.listHeight and itemHeight: self.instance.resize(eSize(self.listWidth, self.listHeight // itemHeight * itemHeight)) def getSelectionPosition(self): @@ -460,10 +473,8 @@ def setMode(self, mode): self.mode = mode self.setItemsPerPage() two_lines_val = int(config.usage.servicelist_twolines.value) - show_two_lines = (two_lines_val and mode == self.MODE_FAVOURITES) or two_lines_val == 3 - self.ItemHeight *= (2 if show_two_lines else 1) - self.l.setItemHeight(self.ItemHeight) - self.l.setVisualMode(eListboxServiceContent.visModeComplex if two_lines_val < 3 else eListboxServiceContent.visSkinDefined) + self.l.setItemHeight(self.ItemHeight if two_lines_val == 0 else self.ItemHeightTwoLine) + self.l.setVisualMode(eListboxServiceContent.visModeComplex if two_lines_val == 0 else eListboxServiceContent.visSkinDefined) if config.usage.service_icon_enable.value: self.l.setGetPiconNameFunc(getPiconName) @@ -498,18 +509,13 @@ def setMode(self, mode): self.l.setElementFont(self.l.celServiceName, self.ServiceNameFont) self.l.setElementFont(self.l.celServiceNumber, self.ServiceNumberFont) self.l.setElementFont(self.l.celServiceInfo, self.ServiceInfoFont) - if show_two_lines and two_lines_val == 2: - self.l.setElementFont(self.l.celServiceNextInfo, self.ServiceNextInfoFont) - nextTitle = _("NEXT") + ": " - self.l.setNextTitle(nextTitle) if "perc" in config.usage.show_event_progress_in_servicelist.value: self.l.setElementFont(self.l.celServiceEventProgressbar, self.ServiceInfoFont) - self.l.setShowTwoLines(two_lines_val) self.l.setHideNumberMarker(config.usage.hide_number_markers.value) self.l.setServiceTypeIconMode(int(config.usage.servicetype_icon_mode.value)) self.l.setCryptoIconMode(int(config.usage.crypto_icon_mode.value)) self.l.setRecordIndicatorMode(int(config.usage.record_indicator_mode.value)) - self.l.setColumnWidth(-1 if show_two_lines else int(config.usage.servicelist_column.value)) + self.l.setColumnWidth(-1 if two_lines_val > 0 else int(config.usage.servicelist_column.value)) def selectionEnabled(self, enabled): if self.instance is not None: diff --git a/lib/python/Components/UsageConfig.py b/lib/python/Components/UsageConfig.py index e9ed9f5861a..e864f1db24d 100644 --- a/lib/python/Components/UsageConfig.py +++ b/lib/python/Components/UsageConfig.py @@ -53,7 +53,9 @@ def alternativeNumberModeChange(configElement): refreshServiceList() config.usage.alternative_number_mode.addNotifier(alternativeNumberModeChange) - config.usage.servicelist_twolines = ConfigSelection(default="0", choices=[("0", _("None")), ("1", _("two lines")), ("2", _("two lines and next event")), ("3", _("two lines alternative"))]) + config.usage.servicelist_twolines = ConfigSelection(default="0", choices=[("0", _("None")), ("1", _("two lines"))]) + if config.usage.servicelist_twolines.value not in ("0", "1"): + config.usage.servicelist_twolines.value = "1" config.usage.servicelist_twolines.addNotifier(refreshServiceList) config.usage.hide_number_markers = ConfigYesNo(default=True) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 35654ed42df..491d5c0789e 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -10,6 +10,8 @@ #include #include #include +#include +#include ePyObject eListboxServiceContent::m_GetPiconNameFunc; @@ -205,7 +207,6 @@ PyObject *eListboxServiceContent::getList() int eListboxServiceContent::getNextBeginningWithChar(char c) { -// printf("Char: %c\n", c); int index=0; for (list::iterator i(m_list.begin()); i != m_list.end(); ++i, ++index) { @@ -216,7 +217,7 @@ int eListboxServiceContent::getNextBeginningWithChar(char c) continue; // failed to find service handler } service_info->getName(*i, text); -// printf("%c\n", text.c_str()[0]); + int idx=0; int len=text.length(); while ( idx <= len ) @@ -239,9 +240,7 @@ int eListboxServiceContent::getPrevMarkerPos() return 0; list::iterator i(m_cursor); int index = m_cursor_number; - - // if the search is starting part way through a section return to the start of the current section - while (index) + while (index) // Find marker for this section { --i; --index; @@ -249,10 +248,11 @@ int eListboxServiceContent::getPrevMarkerPos() break; } - // if the search started from part way through the current section return now because this is the previous visible marker + //eDebug("[eListboxServiceContent] prevMarkerIndex= %i; curSelIndex= %i; index= %i", cursorResolve(prevMarkerIndex), cursorResolve(m_cursor_number), index); + + // if currently selected service is not the first after the marker found - return the found marker index if (cursorResolve(index) + 1 != cursorResolve(m_cursor_number)) return cursorResolve(index); - // search for visible marker index of previous section while (index) { --i; @@ -274,6 +274,7 @@ int eListboxServiceContent::getNextMarkerPos() { ++i; ++index; + if (i->flags == eServiceReference::isMarker) break; } @@ -319,14 +320,14 @@ int eListboxServiceContent::markedQueryNext(eServiceReference &ref) int eListboxServiceContent::lookupService(const eServiceReference &ref) { - /* shortcut for cursor */ + /* shortcut for cursor */ if (ref == *m_cursor) return m_cursor_number; - /* otherwise, search in the list.. */ + /* otherwise, search in the list.. */ int index = 0; for (list::const_iterator i(m_list.begin()); i != m_list.end(); ++i, ++index); - /* this is ok even when the index was not found. */ + /* this is ok even when the index was not found. */ return index; } @@ -382,7 +383,7 @@ void eListboxServiceContent::sort() DEFINE_REF(eListboxServiceContent); eListboxServiceContent::eListboxServiceContent() - :m_visual_mode(visModeSimple), m_size(0), m_current_marked(false), m_itemheight(25), m_hide_number_marker(false), m_show_two_lines(0), m_servicetype_icon_mode(0), m_crypto_icon_mode(0), m_record_indicator_mode(0), m_column_width(0), m_progressbar_height(6), m_progressbar_border_width(2), m_nonplayable_margins(10), m_items_distances(8), m_sides_margin(0), m_marker_as_line(0) + :m_visual_mode(visModeSimple), m_size(0), m_current_marked(false), m_itemheight(25), m_hide_number_marker(false), m_servicetype_icon_mode(0), m_crypto_icon_mode(0), m_record_indicator_mode(0), m_column_width(0), m_progressbar_height(6), m_progressbar_border_width(2), m_nonplayable_margins(10), m_items_distances(8), m_sides_margin(0), m_marker_as_line(0), m_markerline_color_set(0) { memset(m_color_set, 0, sizeof(m_color_set)); cursorHome(); @@ -517,7 +518,7 @@ int eListboxServiceContent::cursorMove(int count) m_listbox->entryChanged(cursorResolve(m_cursor_number)); } ++m_cursor_number; - if (!(m_marked.empty() && m_hide_number_marker && m_cursor->flags & eServiceReference::isNumberedMarker) && !(m_cursor->flags & eServiceReference::isInvisible)) + if (!(m_marked.empty() && m_hide_number_marker && (m_cursor->flags & eServiceReference::isNumberedMarker)) && !(m_cursor->flags & eServiceReference::isInvisible)) --count; } } @@ -533,7 +534,7 @@ int eListboxServiceContent::cursorMove(int count) m_listbox->entryChanged(cursorResolve(m_cursor_number)); } --m_cursor_number; - if (!(m_marked.empty() && m_hide_number_marker && m_cursor->flags & eServiceReference::isNumberedMarker) && !(m_cursor->flags & eServiceReference::isInvisible)) + if (!(m_marked.empty() && m_hide_number_marker && (m_cursor->flags & eServiceReference::isNumberedMarker)) && !(m_cursor->flags & eServiceReference::isInvisible)) ++count; } while (m_cursor != m_list.end()) @@ -585,7 +586,7 @@ int eListboxServiceContent::currentCursorSelectable() if (cursorValid()) { /* don't allow markers to be selected, unless we're in edit mode (because we want to provide some method to the user to remove a marker) */ - if (m_cursor->flags & eServiceReference::isMarker && m_marked.empty()) + if ((m_cursor->flags & eServiceReference::isMarker) && m_marked.empty()) return 0; else return 1; @@ -675,7 +676,7 @@ bool eListboxServiceContent::checkServiceIsRecorded(eServiceReference ref) if (compareServices(ref, it->second)) return true; return false; - } + } } return false; } @@ -767,13 +768,10 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (selected && (!local_style || !local_style->m_selection)) style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry); - /* get service information */ - ePtr service_info; - m_service_center->info(*m_cursor, service_info); eServiceReference ref = *m_cursor; std::string orig_ref_str = ref.toString(); std::string service_res_str = toLower(split(orig_ref_str, ":")[2]); - //eDebug("[eListboxServiceContent] service_res_str = %s", service_res_str.c_str()); + bool isBackupAvailable = false; int catchUpDays = 0; if (orig_ref_str.find("@") != std::string::npos) { @@ -783,11 +781,15 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (orig_ref_str.find("|<|") != std::string::npos) { catchUpDays = std::stoi(split(split(orig_ref_str, "|<|")[1], "@")[0]); } - + + + /* get service information */ + ePtr service_info; + m_service_center->info(ref, service_info); bool isMarker = ref.flags & eServiceReference::isMarker; bool isDirectory = ref.flags & eServiceReference::isDirectory; bool isPlayable = !(isDirectory || isMarker); - bool isRecorded = m_record_indicator_mode && isPlayable && checkServiceIsRecorded(ref); + bool isRecorded = isPlayable && checkServiceIsRecorded(ref); ePtr evt, evt_next; bool serviceAvail = true; bool serviceFallback = false; @@ -835,7 +837,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const painter.setForegroundColor(gRGB(0xb40431)); } - int xoffset=m_sides_margin, xoffs=0; // used as offset when painting the folder/marker symbol or the serviceevent progress + int xoffset=0, xoffs=0; // used as offset when painting the folder/marker symbol or the serviceevent progress int nameLeft=0, nameWidth=0, nameYoffs=0, nextYoffs=0; // used as temporary values for 'show two lines' option if (m_separator == "") m_separator = " "; @@ -859,7 +861,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const ePtr &pixmap = service_res_str == "1f" ? m_pixmaps[pic4K] : (service_res_str == "19" || service_res_str == "11") ? m_pixmaps[picHD] : m_pixmaps[picSD]; - + if (pixmap) { eSize pixmap_size = pixmap->size(); @@ -952,7 +954,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const Py_DECREF(pRet); } } - xoffs = xoffset; + xoffs = xoffset + 16; if (PyCallable_Check(m_GetPiconNameFunc)) { eRect piconArea = eRect(xoffs, offset.y(), 125, m_itemheight); @@ -1000,6 +1002,23 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const correction = 16; } + if (!isMarker && !isDirectory) { + std::string chNum = ""; + eRect serviceNumberRect = m_element_position[celServiceNumber]; + if (serviceNumberRect.width() > 0 && m_cursor->getChannelNum() != 0) { + char buffer[15]; + snprintf(buffer, sizeof(buffer), "%d", m_cursor->getChannelNum() ); + chNum = buffer; + } + if (chNum != "") text = chNum + m_separator + text; + } + + ePtr para = new eTextPara(eRect(0, 0, m_itemsize.width(), m_itemheight/2)); + para->setFont(m_element_font[celServiceName]); + para->renderString(text.c_str()); + eRect bbox = para->getBoundBox(); + painter.renderPara(para, ePoint(xoffsMarker - correction , offset.y() + yoffs + ((ctrlHeight - bbox.height())/2))); + if (isMarker || isDirectory) { ePtr &pixmap_mDir = isMarker ? m_pixmaps[picMarker] : isDirectory ? m_pixmaps[picFolder] : m_pixmaps[picElements]; if (isDirectory || (isMarker && !m_marker_as_line)) { @@ -1018,6 +1037,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const painter.clippop(); } } else if (isMarker && m_marker_as_line) { + if (m_markerline_color_set) painter.setForegroundColor(m_markerline_color); eRect firstLineRect = eRect(xoffs, offset.y() + (m_itemheight - m_marker_as_line) / 2, xoffsMarker - 16 - 8 - xoffs - correction, m_marker_as_line); painter.fill(firstLineRect); int secondLineOffset = xoffsMarker + bboxName.width() + 16 + 8 - correction; @@ -1027,23 +1047,6 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const xoffs += 125 + 16 + 8; } - if (!isMarker && !isDirectory) { - std::string chNum = ""; - eRect serviceNumberRect = m_element_position[celServiceNumber]; - if (serviceNumberRect.width() > 0 && m_cursor->getChannelNum() != 0) { - char buffer[15]; - snprintf(buffer, sizeof(buffer), "%d", m_cursor->getChannelNum() ); - chNum = buffer; - } - if (chNum != "") text = chNum + m_separator + text; - } - - ePtr para = new eTextPara(eRect(0, 0, m_itemsize.width(), m_itemheight/2)); - para->setFont(m_element_font[celServiceName]); - para->renderString(text.c_str()); - eRect bbox = para->getBoundBox(); - painter.renderPara(para, ePoint(xoffsMarker - correction , offset.y() + yoffs + ((ctrlHeight - bbox.height())/2))); - // event name if (is_event) { @@ -1052,7 +1055,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const event_duration = evt->getDuration(); int timeLeft = event_begin + event_duration - now; eRect progressBarRect = m_element_position[celServiceEventProgressbar]; - + if (!event_name.empty()) { //--------------------------------------------------- Event Progressbar ----------------------------------------------------------------- @@ -1076,8 +1079,6 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const painter.setForegroundColor(m_color[serviceEventProgressbarColor]); else if (selected && m_color_set[serviceEventProgressbarColorSelected]) painter.setForegroundColor(m_color[serviceEventProgressbarColorSelected]); - else if (m_show_two_lines == 2) - painter.setForegroundColor(EventProgressbarColor); painter.fill(tmp); } @@ -1159,15 +1160,16 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } } } else { + + // Single line mode goes here if (is_event) { event_name = evt->getEventName(); event_begin = evt->getBeginTime(); event_duration = evt->getDuration(); - if (m_show_two_lines == 2 && event_begin > 0 && !service_info->getEvent(*m_cursor, evt_next, (event_begin + event_duration))) - next_event_name = evt_next->getEventName(); } - + int xoffeset_marker = 0; + int marker_text_width = 0; for (int e = 0; e != celServiceTypePixmap; ++e) { if (m_element_font[e]) @@ -1175,7 +1177,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const int flags=gPainter::RT_VALIGN_CENTER; int yoffs = 0; eRect area = m_element_position[e]; - std::string text = ""; + std::string text = ""; switch (e) { case celServiceNumber: @@ -1208,6 +1210,16 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } if (!(m_record_indicator_mode == 3 && isRecorded) && isPlayable && serviceFallback && selected && m_color_set[serviceSelectedFallback]) painter.setForegroundColor(m_color[serviceSelectedFallback]); + if (!m_marker_alignment.empty() && m_marker_alignment == "center" && isMarker) { + ePtr paraName = new eTextPara(eRect(0, 0, m_itemsize.width(), m_itemheight/2)); + paraName->setFont(m_element_font[celServiceName]); + paraName->renderString(text.c_str()); + eRect bboxName = paraName->getBoundBox(); + xoffeset_marker = (m_itemsize.width() - bboxName.width()) / 2; + marker_text_width = bboxName.width(); + area.setLeft(xoffeset_marker); + area.setWidth(marker_text_width); + } break; } case celServiceInfo: @@ -1287,7 +1299,9 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const eRect tmp = area; int xoffs = 0; ePtr piconPixmap; - + bool isPIconSVG = false; + eRect p_area = m_element_position[celServiceInfo]; + const int iconWidth = (p_area.height() * 9 / 5) - m_items_distances; if (e == celServiceName) { //picon stuff @@ -1302,8 +1316,11 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (PyUnicode_Check(pRet)) { std::string piconFilename = PyUnicode_AsUTF8(pRet); + if (endsWith(piconFilename, ".svg")) { + isPIconSVG = true; + } if (!piconFilename.empty()) - loadImage(piconPixmap, piconFilename.c_str()); + loadImage(piconPixmap, piconFilename.c_str(), 0, isPIconSVG ? iconWidth : 0); } Py_DECREF(pRet); } @@ -1336,11 +1353,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (PyCallable_Check(m_GetPiconNameFunc) and (m_column_width || piconPixmap)) { eRect area = m_element_position[celServiceInfo]; - /* PIcons are usually about 100:60. Make it a - * bit wider in case the icons are diffently - * shaped, and to add a bit of margin between - * icon and text. */ - const int iconWidth = area.height() * 9 / (m_show_two_lines > 0 ? 10 : 5); + m_element_position[celServiceInfo].setLeft(area.left() + iconWidth); m_element_position[celServiceInfo].setWidth(area.width() - iconWidth); area = m_element_position[celServiceName]; @@ -1349,10 +1362,29 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const { area.moveBy(offset); painter.clip(area); - painter.blitScale(piconPixmap, - eRect(area.left(), area.top(), iconWidth, area.height()), - area, - gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER); + /* PIcons are usually about 100:60. Make it a + * bit wider in case the icons are diffently + * shaped, and to add a bit of margin between + * icon and text. */ + int pflags = gPainter::BT_ALPHABLEND | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER; + if (!isPIconSVG) { + pflags = gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER; + } + if (piconPixmap) + { + if (isPIconSVG) { + painter.blit(piconPixmap, + eRect(area.left(), area.top(), iconWidth, m_itemheight), + eRect(), + pflags + ); + } else { + painter.blitScale(piconPixmap, + eRect(area.left(), area.top() + 4, iconWidth, m_itemheight - 8), + area, + pflags); + } + } painter.clippop(); } } @@ -1377,7 +1409,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const eSize pixmap_size = pixmap->size(); eRect area = m_element_position[celServiceInfo]; m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances); + m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances * 2); int offs = rec_pixmap_xoffs; if (m_servicetype_icon_mode == 1) { @@ -1387,7 +1419,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } else if (m_crypto_icon_mode == 1 && m_pixmaps[picCrypto]) offs = offs + m_pixmaps[picCrypto]->size().width() + m_items_distances; - int correction = (!event_name.empty() && m_show_two_lines > 0 && m_servicetype_icon_mode == 2) ? (((area.height()/2) - pixmap_size.height()) / 2) + 2 : (area.height() - pixmap_size.height()) / 2; + int correction = (area.height() - pixmap_size.height()) / 2; area.moveBy(offset); painter.clip(area); painter.blit(pixmap, ePoint(area.left() + offs, offset.y() + correction), area, gPainter::BT_ALPHABLEND); @@ -1404,19 +1436,19 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (m_crypto_icon_mode == 1) { m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances); + m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances * 2); area = m_element_position[celServiceName]; offs = xoffs; xoffs += pixmap_size.width() + m_items_distances; } - int correction = (!event_name.empty() && m_show_two_lines > 0 && m_crypto_icon_mode == 2) ? (((area.height()/2) - pixmap_size.height()) / 2) + 2 : (area.height() - pixmap_size.height()) / 2; + int correction = (area.height() - pixmap_size.height()) / 2; area.moveBy(offset); if (service_info && service_info->isCrypted()) { if (m_crypto_icon_mode == 2) { m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances); + m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances * 2); } painter.clip(area); painter.blit(m_pixmaps[picCrypto], ePoint(area.left() + offs, offset.y() + correction), area, gPainter::BT_ALPHABLEND); @@ -1433,35 +1465,23 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (m_record_indicator_mode == 1) { m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances); + m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances * 2); area = m_element_position[celServiceName]; offs = xoffs; xoffs += pixmap_size.width() + m_items_distances; } - int correction = (!event_name.empty() && m_show_two_lines > 0 && m_record_indicator_mode == 2) ? (((area.height()/2) - pixmap_size.height()) / 2) + 2 : (area.height() - pixmap_size.height()) / 2; + int correction = (area.height() - pixmap_size.height()) / 2; area.moveBy(offset); if (m_record_indicator_mode == 2) { m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances); + m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances * 2); } painter.clip(area); painter.blit(m_pixmaps[picRecord], ePoint(area.left() + offs, offset.y() + correction), area, gPainter::BT_ALPHABLEND); painter.clippop(); } - if (m_show_two_lines > 0) - { - if(!next_event_name.empty()) - { - m_element_position[celServiceNextInfo].setLeft(nameLeft + xoffs); - m_element_position[celServiceNextInfo].setWidth(nameWidth - xoffs); - } - else - { - m_element_position[celServiceInfo].setLeft(nameLeft + xoffs); - m_element_position[celServiceInfo].setWidth(nameWidth - xoffs); - } - } + m_element_position[celServiceInfo].setWidth(m_element_position[celServiceInfo].width() - m_items_distances - m_sides_margin * 2); } } @@ -1475,15 +1495,8 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (flags & gPainter::RT_VALIGN_CENTER) { eRect bbox = para->getBoundBox(); - if (!event_name.empty() && m_show_two_lines > 0 && (e == celServiceName || (!next_event_name.empty() && e == celServiceInfo))) - { - yoffs = ((area.height()/2) - bbox.height()) / 2 - bbox.top(); - if (e == celServiceName) - nameYoffs = yoffs/2; - else - nextYoffs = (area.height()/2) + (((area.height()/2) - bbox.height()) / 2) - (bbox.top() - nameYoffs); - } - else if (!event_name.empty() && m_show_two_lines > 0 && ((next_event_name.empty() && e == celServiceInfo) || (!next_event_name.empty() && e == celServiceNextInfo))) + + if (!next_event_name.empty() && e == celServiceNextInfo) yoffs = (e == celServiceNextInfo ? nextYoffs : (area.height()/2) + (((area.height()/2) - bbox.height()) / 2) - (bbox.top() - nameYoffs)); else yoffs = (area.height() - bbox.height())/2 - bbox.top(); @@ -1497,7 +1510,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const { ePtr &pixmap = (e == celFolderPixmap) ? m_pixmaps[picFolder] : m_pixmaps[picMarker]; - if (pixmap) + if (pixmap && (isDirectory || (isMarker && !m_marker_as_line))) { eSize pixmap_size = pixmap->size(); bool notScale = (e == celMarkerPixmap) && (pixmap_size.width() < 125 || pixmap_size.height() < m_itemheight); @@ -1507,7 +1520,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const area = m_element_position[celServiceName]; if (m_element_position[celServiceEventProgressbar].left() == 0) area.setLeft(0); - if (notScale) + if (notScale) xoffset = pixmap_size.width() + m_items_distances; else xoffset = 125 + m_items_distances; @@ -1527,6 +1540,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } painter.clippop(); } + } } @@ -1544,7 +1558,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const ePtr &pixmap = m_pixmaps[picServiceEventProgressbar]; if (pixmap) { painter.clip(tmp); - painter.blit(pixmap, ePoint(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width), tmp, gPainter::BT_ALPHABLEND); + painter.blit(pixmap, ePoint(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width), tmp, gPainter::BT_ALPHATEST); painter.clippop(); } else { @@ -1552,8 +1566,6 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const painter.setForegroundColor(m_color[serviceEventProgressbarColor]); else if (selected && m_color_set[serviceEventProgressbarColorSelected]) painter.setForegroundColor(m_color[serviceEventProgressbarColorSelected]); - else if (m_show_two_lines == 2) - painter.setForegroundColor(EventProgressbarColor); painter.fill(tmp); } @@ -1572,10 +1584,25 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } painter.setForegroundColor(ProgressbarBorderColor); - painter.fill(eRect(pb_xpos, pb_ypos, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); - painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width + m_progressbar_height, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); - painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); - painter.fill(eRect(pb_xpos + m_progressbar_border_width + pb_width, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); + if (m_progressbar_border_width) + { + painter.fill(eRect(pb_xpos, pb_ypos, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); + painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width + m_progressbar_height, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); + painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); + painter.fill(eRect(pb_xpos + m_progressbar_border_width + pb_width, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); + } + else + painter.fill(eRect(pb_xpos + evt_done, pb_ypos, pb_width - evt_done, m_progressbar_height)); + + } + + if (isMarker && m_marker_as_line) { + if (m_markerline_color_set) painter.setForegroundColor(m_markerline_color); + eRect firstLineRect = eRect(m_sides_margin + xoffset + 16, offset.y() + (m_itemheight - m_marker_as_line) / 2, xoffeset_marker - 16 - 16 - m_sides_margin - xoffset, m_marker_as_line); + painter.fill(firstLineRect); + int secondLineOffset = xoffeset_marker + marker_text_width + 16; + eRect secondLineRect = eRect(secondLineOffset, offset.y() + (m_itemheight - m_marker_as_line) / 2, m_itemsize.width() - secondLineOffset - m_sides_margin - 16, m_marker_as_line); + painter.fill(secondLineRect); } } } diff --git a/lib/service/listboxservice.h b/lib/service/listboxservice.h index 38688738818..7a10dd807c1 100644 --- a/lib/service/listboxservice.h +++ b/lib/service/listboxservice.h @@ -96,7 +96,6 @@ class eListboxServiceContent: public virtual iListboxContent int getItemHeight() { return m_itemheight; } void setItemHeight(int height); void setHideNumberMarker(bool doHide) { m_hide_number_marker = doHide; } - void setShowTwoLines(int mode) { m_show_two_lines = mode; } void setServiceTypeIconMode(int mode) { m_servicetype_icon_mode = mode; } void setCryptoIconMode(int mode) { m_crypto_icon_mode = mode; } void setRecordIndicatorMode(int mode) { m_record_indicator_mode = mode; } @@ -108,9 +107,12 @@ class eListboxServiceContent: public virtual iListboxContent void setSidesMargin(int value) { m_sides_margin = value; } void setMarkerAsLine(int value) { m_marker_as_line = value; } - void setNextTitle(const std::string &string) { m_next_title = string; } void setTextSeparator(const std::string &string) { m_separator = string; } void setMarkerTextAlignment(const std::string &string) { m_marker_alignment = string; } // currently supports left and center + void setMarkerLineColor(const gRGB &col) { + m_markerline_color = col; + m_markerline_color_set = 1; + } static void setGetPiconNameFunc(SWIG_PYOBJECT(ePyObject) func); @@ -196,7 +198,6 @@ class eListboxServiceContent: public virtual iListboxContent int m_itemheight; bool m_hide_number_marker; - int m_show_two_lines; int m_servicetype_icon_mode; int m_crypto_icon_mode; int m_record_indicator_mode; @@ -207,6 +208,8 @@ class eListboxServiceContent: public virtual iListboxContent int m_items_distances; int m_sides_margin; int m_marker_as_line; + gRGB m_markerline_color; + int m_markerline_color_set; std::string m_next_title; std::string m_separator; From 6827e9d9326743aa5e97280e44eb1e43c7fe1b1d Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Mon, 20 Nov 2023 01:56:28 +0200 Subject: [PATCH 223/401] [Fixed] Alignment issues in ServiceList --- lib/python/Components/ServiceList.py | 3 +- lib/service/listboxservice.cpp | 44 ++++++++++++++-------------- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 487c2851f9d..b4ed7f63f2f 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -367,10 +367,9 @@ def setItemsPerPage(self): itemHeight = self.ItemHeight if not two_lines_val else self.ItemHeightTwoLine if numberOfRows > 0: itemHeight = self.listHeight // numberOfRows - self.ItemHeight = itemHeight self.l.setItemHeight(itemHeight) if self.listHeight and itemHeight: - self.instance.resize(eSize(self.listWidth, self.listHeight // itemHeight * itemHeight)) + self.instance.resize(eSize(self.listWidth, self.listHeightOrig // itemHeight * itemHeight)) def getSelectionPosition(self): # Adjust absolute index to index in displayed view diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 491d5c0789e..b9cd2aa249b 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -247,12 +247,13 @@ int eListboxServiceContent::getPrevMarkerPos() if (i->flags == eServiceReference::isMarker) break; } - + //eDebug("[eListboxServiceContent] prevMarkerIndex= %i; curSelIndex= %i; index= %i", cursorResolve(prevMarkerIndex), cursorResolve(m_cursor_number), index); - // if currently selected service is not the first after the marker found - return the found marker index - if (cursorResolve(index) + 1 != cursorResolve(m_cursor_number)) return cursorResolve(index); + // if currently selected service is not the first after the marker found - return the found marker index + if (cursorResolve(index) + 1 != cursorResolve(m_cursor_number)) return cursorResolve(index); + while (index) { --i; @@ -260,7 +261,7 @@ int eListboxServiceContent::getPrevMarkerPos() if (i->flags == eServiceReference::isMarker) break; } - + return cursorResolve(index); } @@ -676,7 +677,7 @@ bool eListboxServiceContent::checkServiceIsRecorded(eServiceReference ref) if (compareServices(ref, it->second)) return true; return false; - } + } } return false; } @@ -771,7 +772,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const eServiceReference ref = *m_cursor; std::string orig_ref_str = ref.toString(); std::string service_res_str = toLower(split(orig_ref_str, ":")[2]); - + bool isBackupAvailable = false; int catchUpDays = 0; if (orig_ref_str.find("@") != std::string::npos) { @@ -781,8 +782,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (orig_ref_str.find("|<|") != std::string::npos) { catchUpDays = std::stoi(split(split(orig_ref_str, "|<|")[1], "@")[0]); } - - + /* get service information */ ePtr service_info; m_service_center->info(ref, service_info); @@ -799,6 +799,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (!marked && isPlayable && service_info && m_is_playable_ignore.valid()) { + eNavigation::getInstance()->getCurrentService(refCur); ePtr tmp_info; refCur->info(tmp_info); @@ -858,10 +859,9 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const yoffs = 5; } if (!isMarker && !isDirectory) { - ePtr &pixmap = - service_res_str == "1f" ? m_pixmaps[pic4K] : - (service_res_str == "19" || service_res_str == "11") ? m_pixmaps[picHD] : m_pixmaps[picSD]; - + ePtr &pixmap = service_res_str == "1f" ? m_pixmaps[pic4K] : (service_res_str == "19" || service_res_str == "11") ? + m_pixmaps[picHD] : m_pixmaps[picSD]; + if (pixmap) { eSize pixmap_size = pixmap->size(); @@ -955,7 +955,8 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } } xoffs = xoffset + 16; - if (PyCallable_Check(m_GetPiconNameFunc)) + bool hasPicon = PyCallable_Check(m_GetPiconNameFunc); + if (hasPicon) { eRect piconArea = eRect(xoffs, offset.y(), 125, m_itemheight); /* PIcons are usually about 100:60. Make it a @@ -995,7 +996,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const paraName->renderString(text.c_str()); eRect bboxName = paraName->getBoundBox(); - int xoffsMarker = 16 + 125 + 16 + 8; + int xoffsMarker = xoffs + ((isDirectory || isMarker) ? ((hasPicon && isMarker ? 125 : m_itemheight) + 16 + 8) : 0); int correction = 0; if (!m_marker_alignment.empty() && m_marker_alignment == "center" && isMarker) { xoffsMarker = (m_itemsize.width() - bboxName.width()) / 2; @@ -1013,7 +1014,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (chNum != "") text = chNum + m_separator + text; } - ePtr para = new eTextPara(eRect(0, 0, m_itemsize.width(), m_itemheight/2)); + ePtr para = new eTextPara(eRect(0, 0, xlpos - xoffsMarker, m_itemheight/2)); para->setFont(m_element_font[celServiceName]); para->renderString(text.c_str()); eRect bbox = para->getBoundBox(); @@ -1044,7 +1045,6 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const eRect secondLineRect = eRect(secondLineOffset, offset.y() + (m_itemheight - m_marker_as_line) / 2, m_itemsize.width() - secondLineOffset - 16 - 8, m_marker_as_line); painter.fill(secondLineRect); } - xoffs += 125 + 16 + 8; } // event name @@ -1055,7 +1055,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const event_duration = evt->getDuration(); int timeLeft = event_begin + event_duration - now; eRect progressBarRect = m_element_position[celServiceEventProgressbar]; - + if (!event_name.empty()) { //--------------------------------------------------- Event Progressbar ----------------------------------------------------------------- @@ -1152,7 +1152,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const painter.renderPara(paraLeft, ePoint(m_itemsize.width() - bboxtLeft.width() - 15, offset.y() - 2 + m_itemheight/2 + ((m_itemheight/2 - bboxtLeft.height())/2))); //------------------------------------------------- Event name ------------------------------------------------------------------------------ - ePtr para = new eTextPara(eRect(0, 0, m_itemsize.width() - xoffs - bboxtLeft.width() - 25, m_itemheight/2)); + ePtr para = new eTextPara(eRect(0, 0, m_itemsize.width() - xoffs - bboxtLeft.width() - 25 - m_items_distances, m_itemheight/2)); para->setFont(m_element_font[celServiceInfo]); para->renderString(text.c_str()); eRect bbox = para->getBoundBox(); @@ -1160,7 +1160,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } } } else { - + // Single line mode goes here if (is_event) { @@ -1495,7 +1495,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (flags & gPainter::RT_VALIGN_CENTER) { eRect bbox = para->getBoundBox(); - + if (!next_event_name.empty() && e == celServiceNextInfo) yoffs = (e == celServiceNextInfo ? nextYoffs : (area.height()/2) + (((area.height()/2) - bbox.height()) / 2) - (bbox.top() - nameYoffs)); else @@ -1520,7 +1520,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const area = m_element_position[celServiceName]; if (m_element_position[celServiceEventProgressbar].left() == 0) area.setLeft(0); - if (notScale) + if (notScale) xoffset = pixmap_size.width() + m_items_distances; else xoffset = 125 + m_items_distances; @@ -1604,7 +1604,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const eRect secondLineRect = eRect(secondLineOffset, offset.y() + (m_itemheight - m_marker_as_line) / 2, m_itemsize.width() - secondLineOffset - m_sides_margin - 16, m_marker_as_line); painter.fill(secondLineRect); } - } + } } painter.clippop(); } From 945383d5dd410c2823e5beab909ea8896005df8c Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Mon, 20 Nov 2023 11:32:27 +0200 Subject: [PATCH 224/401] [Fixed/ServiceList] broken user number of rows [Fixed/ServiceList] Alignment of service title in single line mode --- lib/python/Components/ServiceList.py | 12 +++++-- lib/service/listboxservice.cpp | 54 ++++++++++++++++------------ 2 files changed, 41 insertions(+), 25 deletions(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index b4ed7f63f2f..94f939d5a07 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -86,6 +86,8 @@ def __init__(self, serviceList): self.sidesMargin = 0 self.ItemHeight = 0 self.ItemHeightTwoLine = applySkinFactor(58) + self.ItemHeightSkin = 0 + self.ItemHeightTwoLineSkin = applySkinFactor(58) self.onSelectionChanged = [] @@ -222,9 +224,11 @@ def selectionPixmapLarge(value): def itemHeightTwoLine(value): self.ItemHeightTwoLine = parseScale(value) + self.ItemHeightTwoLineSkin = self.ItemHeightTwoLine def itemHeight(value): self.ItemHeight = parseScale(value) + self.ItemHeightSkin = self.ItemHeight def markerLine(value): self.l.setMarkerAsLine(parseScale(value)) @@ -364,10 +368,14 @@ def setItemsPerPage(self): two_lines_val = int(config.usage.servicelist_twolines.value) if two_lines_val == 1: numberOfRows = numberOfRows // 2 - itemHeight = self.ItemHeight if not two_lines_val else self.ItemHeightTwoLine + itemHeight = self.ItemHeightSkin if not two_lines_val else self.ItemHeightTwoLineSkin if numberOfRows > 0: itemHeight = self.listHeight // numberOfRows - self.l.setItemHeight(itemHeight) + if two_lines_val: + self.ItemHeightTwoLine = itemHeight + else: + self.ItemHeight = itemHeight + self.l.setItemHeight(itemHeight) if self.listHeight and itemHeight: self.instance.resize(eSize(self.listWidth, self.listHeightOrig // itemHeight * itemHeight)) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index b9cd2aa249b..470f4844c6f 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -934,7 +934,8 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } ePtr piconPixmap; bool isPIconSVG = false; - if (isPlayable && PyCallable_Check(m_GetPiconNameFunc)) + bool hasPicon = PyCallable_Check(m_GetPiconNameFunc); + if (isPlayable && hasPicon) { ePyObject pArgs = PyTuple_New(1); PyTuple_SET_ITEM(pArgs, 0, PyUnicode_FromString(ref.toString().c_str())); @@ -955,7 +956,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } } xoffs = xoffset + 16; - bool hasPicon = PyCallable_Check(m_GetPiconNameFunc); + if (hasPicon) { eRect piconArea = eRect(xoffs, offset.y(), 125, m_itemheight); @@ -1168,6 +1169,10 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const event_begin = evt->getBeginTime(); event_duration = evt->getDuration(); } + bool hasPicons = PyCallable_Check(m_GetPiconNameFunc); + + eRect p_area = m_element_position[celServiceInfo]; + int iconWidth = p_area.height() * 9 / 5; int xoffeset_marker = 0; int marker_text_width = 0; for (int e = 0; e != celServiceTypePixmap; ++e) @@ -1300,12 +1305,10 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const int xoffs = 0; ePtr piconPixmap; bool isPIconSVG = false; - eRect p_area = m_element_position[celServiceInfo]; - const int iconWidth = (p_area.height() * 9 / 5) - m_items_distances; if (e == celServiceName) { //picon stuff - if (isPlayable && PyCallable_Check(m_GetPiconNameFunc)) + if (isPlayable && hasPicons) { ePyObject pArgs = PyTuple_New(1); PyTuple_SET_ITEM(pArgs, 0, PyUnicode_FromString(ref.toString().c_str())); @@ -1316,11 +1319,12 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (PyUnicode_Check(pRet)) { std::string piconFilename = PyUnicode_AsUTF8(pRet); - if (endsWith(piconFilename, ".svg")) { + if (endsWith(toLower(piconFilename), ".svg")) { isPIconSVG = true; } - if (!piconFilename.empty()) + if (!piconFilename.empty()) { loadImage(piconPixmap, piconFilename.c_str(), 0, isPIconSVG ? iconWidth : 0); + } } Py_DECREF(pRet); } @@ -1350,16 +1354,20 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (isPlayable) { //picon stuff - if (PyCallable_Check(m_GetPiconNameFunc) and (m_column_width || piconPixmap)) + if (hasPicons && (m_column_width || piconPixmap)) { eRect area = m_element_position[celServiceInfo]; - m_element_position[celServiceInfo].setLeft(area.left() + iconWidth); - m_element_position[celServiceInfo].setWidth(area.width() - iconWidth); + iconWidth = area.height() * 9 / 5; + + + m_element_position[celServiceInfo].setLeft(area.left() + iconWidth + m_items_distances); + m_element_position[celServiceInfo].setWidth(area.width() - iconWidth - m_items_distances); area = m_element_position[celServiceName]; - xoffs += iconWidth; + xoffs += iconWidth + m_items_distances; if (piconPixmap) { + area.moveBy(offset); painter.clip(area); /* PIcons are usually about 100:60. Make it a @@ -1374,13 +1382,13 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const { if (isPIconSVG) { painter.blit(piconPixmap, - eRect(area.left(), area.top(), iconWidth, m_itemheight), + eRect(area.left(), area.top(), iconWidth, area.height()), eRect(), pflags ); } else { painter.blitScale(piconPixmap, - eRect(area.left(), area.top() + 4, iconWidth, m_itemheight - 8), + eRect(area.left(), area.top(), iconWidth, area.height()), area, pflags); } @@ -1390,7 +1398,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } //record icon stuff part1 - int rec_pixmap_xoffs = 0; + int rec_pixmap_xoffs = m_items_distances; if (isRecorded && m_record_indicator_mode == 1 && m_pixmaps[picRecord]) rec_pixmap_xoffs = m_pixmaps[picRecord]->size().width() + m_items_distances; @@ -1408,8 +1416,6 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const { eSize pixmap_size = pixmap->size(); eRect area = m_element_position[celServiceInfo]; - m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances * 2); int offs = rec_pixmap_xoffs; if (m_servicetype_icon_mode == 1) { @@ -1419,6 +1425,8 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } else if (m_crypto_icon_mode == 1 && m_pixmaps[picCrypto]) offs = offs + m_pixmaps[picCrypto]->size().width() + m_items_distances; + m_element_position[celServiceInfo].setLeft(area.left() + offs + pixmap_size.width() + m_items_distances); + m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - offs - m_items_distances * 2); int correction = (area.height() - pixmap_size.height()) / 2; area.moveBy(offset); painter.clip(area); @@ -1447,8 +1455,8 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const { if (m_crypto_icon_mode == 2) { - m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances * 2); + m_element_position[celServiceInfo].setLeft(area.left() + offs + pixmap_size.width() + m_items_distances); + m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - offs - m_items_distances * 2); } painter.clip(area); painter.blit(m_pixmaps[picCrypto], ePoint(area.left() + offs, offset.y() + correction), area, gPainter::BT_ALPHABLEND); @@ -1461,7 +1469,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const { eSize pixmap_size = m_pixmaps[picRecord]->size(); eRect area = m_element_position[celServiceInfo]; - int offs = 0; + int offs = m_items_distances; if (m_record_indicator_mode == 1) { m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); @@ -1472,10 +1480,10 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } int correction = (area.height() - pixmap_size.height()) / 2; area.moveBy(offset); - if (m_record_indicator_mode == 2) + if (m_record_indicator_mode) { - m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances * 2); + m_element_position[celServiceInfo].setLeft(area.left() + offs + pixmap_size.width() + m_items_distances); + m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - offs - m_items_distances * 2); } painter.clip(area); painter.blit(m_pixmaps[picRecord], ePoint(area.left() + offs, offset.y() + correction), area, gPainter::BT_ALPHABLEND); @@ -1523,7 +1531,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (notScale) xoffset = pixmap_size.width() + m_items_distances; else - xoffset = 125 + m_items_distances; + xoffset = (hasPicons ? iconWidth : m_itemheight) + m_items_distances; } else area = m_element_position[celServiceNumber]; From 9f4229a7c3546d7dbf58cd0b94edbdb6773dbc55 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Mon, 20 Nov 2023 17:30:44 +0200 Subject: [PATCH 225/401] [Fixed][ServiceList] Alignment issues --- lib/service/listboxservice.cpp | 47 +++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 470f4844c6f..75306ed683b 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -1354,17 +1354,21 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (isPlayable) { //picon stuff - if (hasPicons && (m_column_width || piconPixmap)) - { + if (hasPicons || isDirectory || (isMarker && !m_marker_as_line)) { eRect area = m_element_position[celServiceInfo]; iconWidth = area.height() * 9 / 5; - m_element_position[celServiceInfo].setLeft(area.left() + iconWidth + m_items_distances); m_element_position[celServiceInfo].setWidth(area.width() - iconWidth - m_items_distances); - area = m_element_position[celServiceName]; + xoffs += iconWidth + m_items_distances; + } + + if (hasPicons && (m_column_width || piconPixmap)) + { + area = m_element_position[celServiceName]; + if (piconPixmap) { @@ -1401,7 +1405,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const int rec_pixmap_xoffs = m_items_distances; if (isRecorded && m_record_indicator_mode == 1 && m_pixmaps[picRecord]) rec_pixmap_xoffs = m_pixmaps[picRecord]->size().width() + m_items_distances; - + int serviceNameWidthCorr = 0; //service type marker stuff if (m_servicetype_icon_mode) { @@ -1419,14 +1423,24 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const int offs = rec_pixmap_xoffs; if (m_servicetype_icon_mode == 1) { + m_element_position[celServiceInfo].setLeft(area.left() + offs + pixmap_size.width() + m_items_distances); + m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - offs - m_items_distances * 2); area = m_element_position[celServiceName]; offs = xoffs; xoffs += pixmap_size.width() + m_items_distances; + serviceNameWidthCorr = servicenameWidth + m_items_distances; } - else if (m_crypto_icon_mode == 1 && m_pixmaps[picCrypto]) + else if (m_crypto_icon_mode == 1 && m_pixmaps[picCrypto]) { offs = offs + m_pixmaps[picCrypto]->size().width() + m_items_distances; - m_element_position[celServiceInfo].setLeft(area.left() + offs + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - offs - m_items_distances * 2); + m_element_position[celServiceInfo].setLeft(area.left() + offs + pixmap_size.width() + m_items_distances); + m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - offs - m_items_distances * 2); + serviceNameWidthCorr = servicenameWidth + m_items_distances; + } + if (m_servicetype_icon_mode == 2) { + m_element_position[celServiceInfo].setLeft(area.left() + offs + pixmap_size.width() + m_items_distances); + m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - offs - m_items_distances * 2); + } + int correction = (area.height() - pixmap_size.height()) / 2; area.moveBy(offset); painter.clip(area); @@ -1443,11 +1457,12 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const int offs = rec_pixmap_xoffs; if (m_crypto_icon_mode == 1) { - m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances * 2); area = m_element_position[celServiceName]; offs = xoffs; xoffs += pixmap_size.width() + m_items_distances; + m_element_position[celServiceInfo].setLeft(area.left() + offs + pixmap_size.width() + m_items_distances); + m_element_position[celServiceInfo].setWidth(area.width() - offs - pixmap_size.width() - m_items_distances * 2); + serviceNameWidthCorr = servicenameWidth + m_items_distances; } int correction = (area.height() - pixmap_size.height()) / 2; area.moveBy(offset); @@ -1472,15 +1487,16 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const int offs = m_items_distances; if (m_record_indicator_mode == 1) { - m_element_position[celServiceInfo].setLeft(area.left() + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - m_items_distances * 2); area = m_element_position[celServiceName]; offs = xoffs; xoffs += pixmap_size.width() + m_items_distances; + m_element_position[celServiceInfo].setLeft(area.left() + offs + pixmap_size.width() + m_items_distances); + m_element_position[celServiceInfo].setWidth(area.width() - offs - pixmap_size.width() - m_items_distances * 2); + serviceNameWidthCorr = servicenameWidth + m_items_distances; } int correction = (area.height() - pixmap_size.height()) / 2; area.moveBy(offset); - if (m_record_indicator_mode) + if (m_record_indicator_mode == 2) { m_element_position[celServiceInfo].setLeft(area.left() + offs + pixmap_size.width() + m_items_distances); m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - offs - m_items_distances * 2); @@ -1489,7 +1505,8 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const painter.blit(m_pixmaps[picRecord], ePoint(area.left() + offs, offset.y() + correction), area, gPainter::BT_ALPHABLEND); painter.clippop(); } - m_element_position[celServiceInfo].setWidth(m_element_position[celServiceInfo].width() - m_items_distances - m_sides_margin * 2); + m_element_position[celServiceInfo].setLeft(m_element_position[celServiceInfo].left() + serviceNameWidthCorr); + m_element_position[celServiceInfo].setWidth(m_element_position[celServiceInfo].width() - m_items_distances * (serviceNameWidthCorr > 0 ? 2 : 1) - m_sides_margin * 2); } } @@ -1531,7 +1548,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (notScale) xoffset = pixmap_size.width() + m_items_distances; else - xoffset = (hasPicons ? iconWidth : m_itemheight) + m_items_distances; + xoffset = m_itemheight + m_items_distances; } else area = m_element_position[celServiceNumber]; From 8ce1cb95bb86607995c951887dab5618154deee4 Mon Sep 17 00:00:00 2001 From: openvix-build Date: Mon, 20 Nov 2023 21:37:43 +0000 Subject: [PATCH 226/401] openvix: developer 6.4.010.006 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index d310498136b..f5424292e0c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1204,3 +1204,4 @@ openvix: developer 6.4.010.002 openvix: developer 6.4.010.003 openvix: developer 6.4.010.004 openvix: developer 6.4.010.005 +openvix: developer 6.4.010.006 From b83526e883262bac2b1103dfb117613bc99d7f35 Mon Sep 17 00:00:00 2001 From: Ev0-BH Date: Mon, 20 Nov 2023 12:12:14 +0000 Subject: [PATCH 227/401] [MediaPlayer] Fix constant spinner if enabling MediaPlayer in main menu --- lib/python/Plugins/Extensions/MediaPlayer/settings.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/python/Plugins/Extensions/MediaPlayer/settings.py b/lib/python/Plugins/Extensions/MediaPlayer/settings.py index 2eda3db2cf6..523b848308e 100644 --- a/lib/python/Plugins/Extensions/MediaPlayer/settings.py +++ b/lib/python/Plugins/Extensions/MediaPlayer/settings.py @@ -93,8 +93,6 @@ def initConfigList(self, element=None): self.list.append(getConfigListEntry(_("repeat playlist"), config.mediaplayer.repeat)) self.list.append(getConfigListEntry(_("save playlist on exit"), config.mediaplayer.savePlaylistOnExit)) self.list.append(getConfigListEntry(_("save last directory on exit"), config.mediaplayer.saveDirOnExit)) - if not config.mediaplayer.saveDirOnExit.value: - self.list.append(getConfigListEntry(_("start directory"), config.mediaplayer.defaultDir)) self.list.append(getConfigListEntry(_("sorting of playlists"), config.mediaplayer.sortPlaylists)) self.list.append(getConfigListEntry(_("Always hide infobar"), config.mediaplayer.alwaysHideInfoBar)) self.list.append(getConfigListEntry(_("show mediaplayer on mainmenu"), config.mediaplayer.onMainMenu)) From 0599c9c6bad1bb0561552d46d4d648d05acb5b50 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Tue, 21 Nov 2023 00:27:00 +0200 Subject: [PATCH 228/401] [Fixed] [ServiceList] Showing only the first recording in channel list --- lib/service/listboxservice.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 75306ed683b..d0d29906946 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -669,14 +669,12 @@ bool eListboxServiceContent::checkServiceIsRecorded(eServiceReference ref) for (std::list::iterator i(bouquet->m_services.begin()); i != bouquet->m_services.end(); ++i){ if (compareServices(*i, it->second)) return true; - return false; } } } else { if (compareServices(ref, it->second)) return true; - return false; } } return false; From 4a7f14698476e8af983b93caa9eb93ba0d6f36fd Mon Sep 17 00:00:00 2001 From: Huevos Date: Tue, 21 Nov 2023 13:39:39 +0100 Subject: [PATCH 229/401] [ServiceList] in two line mode respect ratio between single line and two line mode Includes sanity check to avoid potential ZeroDivisionError. --- lib/python/Components/ServiceList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 94f939d5a07..50840c9b5a6 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -367,7 +367,7 @@ def setItemsPerPage(self): numberOfRows = config.usage.serviceitems_per_page.value two_lines_val = int(config.usage.servicelist_twolines.value) if two_lines_val == 1: - numberOfRows = numberOfRows // 2 + numberOfRows = int(numberOfRows / ((self.ItemHeightTwoLineSkin / self.ItemHeightSkin)) if self.ItemHeightSkin and self.ItemHeightTwoLineSkin else 2) itemHeight = self.ItemHeightSkin if not two_lines_val else self.ItemHeightTwoLineSkin if numberOfRows > 0: itemHeight = self.listHeight // numberOfRows From 7e7bf34c78fa0675949cf2b5ad33610f535477d8 Mon Sep 17 00:00:00 2001 From: Huevos Date: Tue, 21 Nov 2023 14:51:42 +0100 Subject: [PATCH 230/401] [ServiceList] set default item height --- lib/python/Components/ServiceList.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 50840c9b5a6..eea1a3527f5 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -84,9 +84,9 @@ def __init__(self, serviceList): self.progressPercentWidth = 0 self.fieldMargins = 10 self.sidesMargin = 0 - self.ItemHeight = 0 + self.ItemHeight = applySkinFactor(36) self.ItemHeightTwoLine = applySkinFactor(58) - self.ItemHeightSkin = 0 + self.ItemHeightSkin = applySkinFactor(36) self.ItemHeightTwoLineSkin = applySkinFactor(58) self.onSelectionChanged = [] From bf05c0576bc2ce2b4ca42dbf53229c99f526425f Mon Sep 17 00:00:00 2001 From: Huevos Date: Tue, 21 Nov 2023 23:36:32 +0100 Subject: [PATCH 231/401] [ServiceList] fix loading double height pixmap Author: @DimitarCC --- lib/python/Components/ServiceList.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index eea1a3527f5..5e5508a8ab7 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -88,6 +88,8 @@ def __init__(self, serviceList): self.ItemHeightTwoLine = applySkinFactor(58) self.ItemHeightSkin = applySkinFactor(36) self.ItemHeightTwoLineSkin = applySkinFactor(58) + self.selectionPixmapSingle = None + self.selectionPixmapDouble = None self.onSelectionChanged = [] @@ -216,11 +218,11 @@ def sidesMargin(value): def textSeparator(value): self.l.setTextSeparator(value) + def selectionPixmap(value): + self.selectionPixmapSingle = value + def selectionPixmapLarge(value): - two_lines_val = int(config.usage.servicelist_twolines.value) - if two_lines_val: - pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, value)) - pic and self.l.setSelectionPicture(pic) + self.selectionPixmapDouble = value def itemHeightTwoLine(value): self.ItemHeightTwoLine = parseScale(value) @@ -482,6 +484,16 @@ def setMode(self, mode): two_lines_val = int(config.usage.servicelist_twolines.value) self.l.setItemHeight(self.ItemHeight if two_lines_val == 0 else self.ItemHeightTwoLine) self.l.setVisualMode(eListboxServiceContent.visModeComplex if two_lines_val == 0 else eListboxServiceContent.visSkinDefined) + + pic = None + if two_lines_val: + if self.selectionPixmapDouble: + pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, self.selectionPixmapDouble)) + else: + if self.selectionPixmapSingle: + pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, self.selectionPixmapSingle)) + + pic and hasattr(self.l, "setSelectionPicture") and self.l.setSelectionPicture(pic) if config.usage.service_icon_enable.value: self.l.setGetPiconNameFunc(getPiconName) From c2ae61ccf472dad0d35a0fd7e8ce31aab1618ed5 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Tue, 21 Nov 2023 22:38:59 +0000 Subject: [PATCH 232/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Components/ServiceList.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 5e5508a8ab7..f010a772b29 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -484,7 +484,7 @@ def setMode(self, mode): two_lines_val = int(config.usage.servicelist_twolines.value) self.l.setItemHeight(self.ItemHeight if two_lines_val == 0 else self.ItemHeightTwoLine) self.l.setVisualMode(eListboxServiceContent.visModeComplex if two_lines_val == 0 else eListboxServiceContent.visSkinDefined) - + pic = None if two_lines_val: if self.selectionPixmapDouble: @@ -492,7 +492,7 @@ def setMode(self, mode): else: if self.selectionPixmapSingle: pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, self.selectionPixmapSingle)) - + pic and hasattr(self.l, "setSelectionPicture") and self.l.setSelectionPicture(pic) if config.usage.service_icon_enable.value: From 4e130bb9859fbfeff95f30e756592bafe625af6a Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Wed, 22 Nov 2023 22:33:53 +0200 Subject: [PATCH 233/401] [Fixed] gap between name and directory icon in two lines mode --- lib/service/listboxservice.cpp | 54 +++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index d0d29906946..15c382d1991 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -1012,38 +1012,44 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } if (chNum != "") text = chNum + m_separator + text; } + ePtr &pixmap_mDir = isMarker ? m_pixmaps[picMarker] : isDirectory ? m_pixmaps[picFolder] : m_pixmaps[picElements];; + if (isMarker || isDirectory) { + if (isDirectory || (isMarker && !m_marker_as_line)) { + eSize pixmap_size = pixmap_mDir->size(); + if (pixmap_size.width() < 125 || pixmap_size.height() < m_itemheight) + xoffsMarker = xoffs + pixmap_size.width() + 16; + } + } ePtr para = new eTextPara(eRect(0, 0, xlpos - xoffsMarker, m_itemheight/2)); para->setFont(m_element_font[celServiceName]); para->renderString(text.c_str()); eRect bbox = para->getBoundBox(); - painter.renderPara(para, ePoint(xoffsMarker - correction , offset.y() + yoffs + ((ctrlHeight - bbox.height())/2))); + painter.renderPara(para, ePoint(xoffsMarker - correction, offset.y() + yoffs + ((ctrlHeight - bbox.height())/2))); - if (isMarker || isDirectory) { - ePtr &pixmap_mDir = isMarker ? m_pixmaps[picMarker] : isDirectory ? m_pixmaps[picFolder] : m_pixmaps[picElements]; - if (isDirectory || (isMarker && !m_marker_as_line)) { - if (pixmap_mDir) { - eSize pixmap_size = pixmap_mDir->size(); - if (pixmap_size.width() < 125 || pixmap_size.height() < m_itemheight){ - eRect area = eRect(xoffs, offset.y() + (ctrlHeight - pixmap_size.height())/2, pixmap_size.width(), pixmap_size.height()); - painter.clip(area); - painter.blit(pixmap_mDir, ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); - } else { - int pflags = gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER; - eRect area = eRect(xoffs, offset.y(), 125, m_itemheight); - painter.clip(area); - painter.blitScale(pixmap_mDir, eRect(xoffs, offset.y(), 125, m_itemheight), area, pflags); - } - painter.clippop(); + + if (isDirectory || (isMarker && !m_marker_as_line)) { + if (pixmap_mDir) { + eSize pixmap_size = pixmap_mDir->size(); + if (pixmap_size.width() < 125 || pixmap_size.height() < m_itemheight){ + eRect area = eRect(xoffs, offset.y() + (ctrlHeight - pixmap_size.height())/2, pixmap_size.width(), pixmap_size.height()); + painter.clip(area); + painter.blit(pixmap_mDir, ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + } else { + int pflags = gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER; + eRect area = eRect(xoffs, offset.y(), 125, m_itemheight); + painter.clip(area); + painter.blitScale(pixmap_mDir, eRect(xoffs, offset.y(), 125, m_itemheight), area, pflags); } - } else if (isMarker && m_marker_as_line) { - if (m_markerline_color_set) painter.setForegroundColor(m_markerline_color); - eRect firstLineRect = eRect(xoffs, offset.y() + (m_itemheight - m_marker_as_line) / 2, xoffsMarker - 16 - 8 - xoffs - correction, m_marker_as_line); - painter.fill(firstLineRect); - int secondLineOffset = xoffsMarker + bboxName.width() + 16 + 8 - correction; - eRect secondLineRect = eRect(secondLineOffset, offset.y() + (m_itemheight - m_marker_as_line) / 2, m_itemsize.width() - secondLineOffset - 16 - 8, m_marker_as_line); - painter.fill(secondLineRect); + painter.clippop(); } + } else if (isMarker && m_marker_as_line) { + if (m_markerline_color_set) painter.setForegroundColor(m_markerline_color); + eRect firstLineRect = eRect(xoffs, offset.y() + (m_itemheight - m_marker_as_line) / 2, xoffsMarker - 16 - 8 - xoffs - correction, m_marker_as_line); + painter.fill(firstLineRect); + int secondLineOffset = xoffsMarker + bboxName.width() + 16 + 8 - correction; + eRect secondLineRect = eRect(secondLineOffset, offset.y() + (m_itemheight - m_marker_as_line) / 2, m_itemsize.width() - secondLineOffset - 16 - 8, m_marker_as_line); + painter.fill(secondLineRect); } // event name From b4ddb5c3689f2a48b124074be3e8e21904e84046 Mon Sep 17 00:00:00 2001 From: Huevos Date: Thu, 23 Nov 2023 00:02:15 +0100 Subject: [PATCH 234/401] [ServiceList] tweak itemHeight --- lib/python/Components/ServiceList.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index f010a772b29..3e3eec6e890 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -84,9 +84,9 @@ def __init__(self, serviceList): self.progressPercentWidth = 0 self.fieldMargins = 10 self.sidesMargin = 0 - self.ItemHeight = applySkinFactor(36) + self.ItemHeight = applySkinFactor(28) self.ItemHeightTwoLine = applySkinFactor(58) - self.ItemHeightSkin = applySkinFactor(36) + self.ItemHeightSkin = applySkinFactor(28) self.ItemHeightTwoLineSkin = applySkinFactor(58) self.selectionPixmapSingle = None self.selectionPixmapDouble = None From ff10ea75044f3306d019cc77240c6ab13886f2cb Mon Sep 17 00:00:00 2001 From: openvix-build Date: Wed, 22 Nov 2023 23:10:07 +0000 Subject: [PATCH 235/401] openvix: developer 6.4.010.007 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index f5424292e0c..87df6b4a72c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1205,3 +1205,4 @@ openvix: developer 6.4.010.003 openvix: developer 6.4.010.004 openvix: developer 6.4.010.005 openvix: developer 6.4.010.006 +openvix: developer 6.4.010.007 From 3af84e3f82c448c4085b278a3b4b256528d1bc7f Mon Sep 17 00:00:00 2001 From: Huevos Date: Thu, 23 Nov 2023 14:08:14 +0100 Subject: [PATCH 236/401] [ServiceList] add serviceItemHeight for legacy compatibility --- lib/python/Components/ServiceList.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 3e3eec6e890..52460f9e528 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -241,6 +241,9 @@ def markerLineColor(value): def markerTextAlignment(value): self.l.setMarkerTextAlignment(value) + def serviceItemHeight(value): # for legacy support + itemHeight(value) + for (attrib, value) in self.skinAttributes[:]: try: locals().get(attrib)(value) From 53601fc8b239b325a0f9131bb350914805a7555f Mon Sep 17 00:00:00 2001 From: Huevos Date: Thu, 23 Nov 2023 15:30:57 +0100 Subject: [PATCH 237/401] [SeviceList] iterate with itemHeight first --- lib/python/Components/ServiceList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 52460f9e528..0741ca564cf 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -244,7 +244,7 @@ def markerTextAlignment(value): def serviceItemHeight(value): # for legacy support itemHeight(value) - for (attrib, value) in self.skinAttributes[:]: + for (attrib, value) in sorted(self.skinAttributes, key=lambda x: 1 if x[0] == "itemHeight" else 0): try: locals().get(attrib)(value) self.skinAttributes.remove((attrib, value)) From 8599107d92ba5b21582dd22672f98b0947951f52 Mon Sep 17 00:00:00 2001 From: Ev0-BH Date: Thu, 23 Nov 2023 15:02:31 +0000 Subject: [PATCH 238/401] [ServiceList] Fix for old 720 skins --- lib/python/Components/ServiceList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 0741ca564cf..a6efdda5daa 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -244,7 +244,7 @@ def markerTextAlignment(value): def serviceItemHeight(value): # for legacy support itemHeight(value) - for (attrib, value) in sorted(self.skinAttributes, key=lambda x: 1 if x[0] == "itemHeight" else 0): + for (attrib, value) in sorted(self.skinAttributes, key=lambda x: 0 if x[0] == "itemHeight" else 1): try: locals().get(attrib)(value) self.skinAttributes.remove((attrib, value)) From 723a08bb10c28fd5bf41f7ee3548df8a3295c481 Mon Sep 17 00:00:00 2001 From: Betacentauri Date: Tue, 14 Nov 2023 18:12:53 +0100 Subject: [PATCH 239/401] [CI] Add ressources for CI+ 1.4 compability --- lib/dvb_ci/dvbci_ccmgr.cpp | 2 ++ lib/dvb_ci/dvbci_resmgr.cpp | 8 +++++-- lib/dvb_ci/dvbci_session.cpp | 44 ++++++++++++++++++++++++++++++------ 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/lib/dvb_ci/dvbci_ccmgr.cpp b/lib/dvb_ci/dvbci_ccmgr.cpp index 298b8aeb09f..868f2b5bedc 100644 --- a/lib/dvb_ci/dvbci_ccmgr.cpp +++ b/lib/dvb_ci/dvbci_ccmgr.cpp @@ -34,6 +34,8 @@ eDVBCICcSession::eDVBCICcSession(eDVBCISlot *slot, int version): buf[31] = 0x01; // URI_PROTOCOL_V1 if (version == 2) buf[31] |= 0x02; // URI_PROTOCOL_V2 + if (version == 4) + buf[31] |= 0x04; // URI_PROTOCOL_V4 if (!m_ci_elements.set(URI_VERSIONS, buf, 32)) eWarning("[CI RCC] can not set uri_versions"); diff --git a/lib/dvb_ci/dvbci_resmgr.cpp b/lib/dvb_ci/dvbci_resmgr.cpp index 99bd8d194f0..23d39be5d39 100644 --- a/lib/dvb_ci/dvbci_resmgr.cpp +++ b/lib/dvb_ci/dvbci_resmgr.cpp @@ -84,11 +84,13 @@ int eDVBCIResourceManagerSession::doAction() {0x00, 0x01, 0x00, 0x41}, // res mgr 1 // {0x00, 0x01, 0x00, 0x42}, // res mgr 2 {0x00, 0x02, 0x00, 0x41}, // app mgr 1 -// {0x00, 0x02, 0x00, 0x42}, // app mgr 2 + {0x00, 0x02, 0x00, 0x42}, // app mgr 2 {0x00, 0x02, 0x00, 0x43}, // app mgr 3 + {0x00, 0x02, 0x00, 0x45}, // app mgr 5 {0x00, 0x03, 0x00, 0x41}, // ca mgr {0x00, 0x20, 0x00, 0x41}, // host ctrl 1 {0x00, 0x20, 0x00, 0x42}, // host ctrl 2 + {0x00, 0x20, 0x00, 0x43}, // host ctrl 3 {0x00, 0x24, 0x00, 0x41}, // datetime {0x00, 0x40, 0x00, 0x41}, // mmi // {0x00, 0x10, 0x00, 0x41}, @@ -96,9 +98,11 @@ int eDVBCIResourceManagerSession::doAction() {0x00, 0x41, 0x00, 0x42}, // app mmi 2 {0x00, 0x8c, 0x10, 0x01}, // content ctrl 1 {0x00, 0x8c, 0x10, 0x02}, // content ctrl 2 + {0x00, 0x8c, 0x10, 0x04}, // content ctrl 4 {0x00, 0x8d, 0x10, 0x01}, // Host lang ctrl {0x00, 0x8e, 0x10, 0x01}, // Cam upgrade - {0x00, 0x8f, 0x10, 0x01}, // operator profile + {0x00, 0x8f, 0x10, 0x01}, // operator profile 1 + {0x00, 0x8f, 0x10, 0x02}, // operator profile 2 // {0x00, 0x97, 0x10, 0x01}, // {0x00, 0x60, 0x60, 0x03}, // {0x00, 0x04, 0x10, 0x01}, diff --git a/lib/dvb_ci/dvbci_session.cpp b/lib/dvb_ci/dvbci_session.cpp index e39d1df50e7..4c1a5ca7957 100644 --- a/lib/dvb_ci/dvbci_session.cpp +++ b/lib/dvb_ci/dvbci_session.cpp @@ -151,21 +151,39 @@ void eDVBCISession::createSession(eDVBCISlot *slot, const unsigned char *resourc { case 0x00010041: session=new eDVBCIResourceManagerSession(slot->getVersion()); - eDebug("[CI SESS] RESOURCE MANAGER"); + eDebug("[CI SESS] RESOURCE MANAGER 1"); break; case 0x00020041: + session=new eDVBCIApplicationManagerSession(slot); + eDebug("[CI SESS] APPLICATION MANAGER 1"); + break; + case 0x00020042: + session=new eDVBCIApplicationManagerSession(slot); + eDebug("[CI SESS] APPLICATION MANAGER 2"); + break; case 0x00020043: session=new eDVBCIApplicationManagerSession(slot); - eDebug("[CI SESS] APPLICATION MANAGER"); + eDebug("[CI SESS] APPLICATION MANAGER 3"); + break; + case 0x00020045: + session=new eDVBCIApplicationManagerSession(slot); + eDebug("[CI SESS] APPLICATION MANAGER 5"); break; case 0x00030041: session = new eDVBCICAManagerSession(slot); eDebug("[CI SESS] CA MANAGER"); break; case 0x00200041: + session = new eDVBCIHostControlSession; + eDebug("[CI SESS] Host Control 1"); + break; case 0x00200042: session = new eDVBCIHostControlSession; - eDebug("[CI SESS] Host Control"); + eDebug("[CI SESS] Host Control 2"); + break; + case 0x00200043: + session = new eDVBCIHostControlSession; + eDebug("[CI SESS] Host Control 3"); break; case 0x00240041: session=new eDVBCIDateTimeSession; @@ -176,19 +194,27 @@ void eDVBCISession::createSession(eDVBCISlot *slot, const unsigned char *resourc eDebug("[CI SESS] MMI - create session"); break; case 0x00410041: + session = new eDVBCIApplicationMMISession; + eDebug("[CI SESS] Application MMI 1"); + break; case 0x00410042: session = new eDVBCIApplicationMMISession; - eDebug("[CI SESS] Application MMI"); + eDebug("[CI SESS] Application MMI 2"); break; case 0x008C1001: eDVBCIInterfaces::getInstance()->setCIPlusRouting(slot->getSlotID()); session = new eDVBCICcSession(slot, 1); - eDebug("[CI SESS] Content Control v1"); + eDebug("[CI SESS] Content Control 1"); break; case 0x008C1002: eDVBCIInterfaces::getInstance()->setCIPlusRouting(slot->getSlotID()); session = new eDVBCICcSession(slot, 2); - eDebug("[CI SESS] Content Control v2"); + eDebug("[CI SESS] Content Control 2"); + break; + case 0x008C1004: + eDVBCIInterfaces::getInstance()->setCIPlusRouting(slot->getSlotID()); + session = new eDVBCICcSession(slot, 4); + eDebug("[CI SESS] Content Control 4"); break; case 0x008D1001: session = new eDVBCIHostLanguageAndCountrySession; @@ -200,7 +226,11 @@ void eDVBCISession::createSession(eDVBCISlot *slot, const unsigned char *resourc break; case 0x008F1001: session = new eDVBCIOperatorProfileSession; - eDebug("[CI SESS] Operator Profile"); + eDebug("[CI SESS] Operator Profile 1"); + break; + case 0x008F1002: + session = new eDVBCIOperatorProfileSession; + eDebug("[CI SESS] Operator Profile 2"); break; case 0x00100041: // session=new eDVBCIAuthSession; From 6803aeebeabf43e8db42fc4b8537846c34d1279a Mon Sep 17 00:00:00 2001 From: Betacentauri Date: Tue, 14 Nov 2023 18:20:55 +0100 Subject: [PATCH 240/401] [CI] Operator profile don't send status request message right after session start as some modules open operator session, but don't seem to be able to handle operator messages as they just stop working after receiving the message(CANAL+ module). --- lib/dvb_ci/dvbci_operatorprofile.cpp | 4 ++-- lib/dvb_ci/dvbci_operatorprofile.h | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/dvb_ci/dvbci_operatorprofile.cpp b/lib/dvb_ci/dvbci_operatorprofile.cpp index 27ebc61b6da..a505459af66 100644 --- a/lib/dvb_ci/dvbci_operatorprofile.cpp +++ b/lib/dvb_ci/dvbci_operatorprofile.cpp @@ -20,7 +20,7 @@ int eDVBCIOperatorProfileSession::receivedAPDU(const unsigned char *tag,const vo { case 0x01: eDebug("operator_status"); - state=stateStarted; + state=stateStatus; break; case 0x03: eDebug("operator_nit"); @@ -46,7 +46,7 @@ int eDVBCIOperatorProfileSession::doAction() { switch (state) { - case stateStarted: + case stateStatusRequest: { const unsigned char tag[3]={0x9F, 0x9C, 0x00}; sendAPDU(tag); diff --git a/lib/dvb_ci/dvbci_operatorprofile.h b/lib/dvb_ci/dvbci_operatorprofile.h index 358c7e23a90..7f2f2bbc79c 100644 --- a/lib/dvb_ci/dvbci_operatorprofile.h +++ b/lib/dvb_ci/dvbci_operatorprofile.h @@ -6,7 +6,9 @@ class eDVBCIOperatorProfileSession: public eDVBCISession { enum { - stateFinal=statePrivate + stateStatusRequest=statePrivate, + stateStatus, + stateFinal }; int receivedAPDU(const unsigned char *tag, const void *data, int len); From 5eb5817a3fd3e3214b9685a0d261603be051360c Mon Sep 17 00:00:00 2001 From: Betacentauri Date: Sat, 18 Nov 2023 18:31:15 +0100 Subject: [PATCH 241/401] [CI] Fix URI_VERSIONS --- lib/dvb_ci/dvbci_ccmgr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/dvb_ci/dvbci_ccmgr.cpp b/lib/dvb_ci/dvbci_ccmgr.cpp index 868f2b5bedc..c74ae7e7658 100644 --- a/lib/dvb_ci/dvbci_ccmgr.cpp +++ b/lib/dvb_ci/dvbci_ccmgr.cpp @@ -32,9 +32,9 @@ eDVBCICcSession::eDVBCICcSession(eDVBCISlot *slot, int version): memset(buf, 0, 32); buf[31] = 0x01; // URI_PROTOCOL_V1 - if (version == 2) + if (version >= 2) buf[31] |= 0x02; // URI_PROTOCOL_V2 - if (version == 4) + if (version >= 4) buf[31] |= 0x04; // URI_PROTOCOL_V4 if (!m_ci_elements.set(URI_VERSIONS, buf, 32)) From f7e267d3ece2f20649287394acaef9a43ac1b1c1 Mon Sep 17 00:00:00 2001 From: Tony Whalley Date: Thu, 23 Nov 2023 16:03:11 +0100 Subject: [PATCH 242/401] [StartEnigma] check for translation.xml before call --- lib/python/StartEnigma.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/python/StartEnigma.py b/lib/python/StartEnigma.py index 6e4bd9f88e7..9372c0a7442 100644 --- a/lib/python/StartEnigma.py +++ b/lib/python/StartEnigma.py @@ -693,7 +693,8 @@ def RCSelectionChanged(configelement): print("[StartEnigma] Initialising KeymapParser.") from keymapparser import readKeymap # noqa: E402 readKeymap(config.usage.keymap.value) -readKeymap(config.usage.keytrans.value) +if osexists(config.usage.keytrans.value): + readKeymap(config.usage.keytrans.value) if VuRecovery: SystemInfo["Display"] = False From f814bda66e195277eadf14330d7251752b004f7a Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Fri, 24 Nov 2023 16:23:26 +0200 Subject: [PATCH 243/401] [Fixed][ServiceList] Missing icon for recording of stream relay channel --- lib/service/listboxservice.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 15c382d1991..38518f8ef6b 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -12,6 +12,7 @@ #include #include #include +#include ePyObject eListboxServiceContent::m_GetPiconNameFunc; @@ -51,6 +52,18 @@ bool compareServices(const eServiceReference &ref1, const eServiceReference &ref std::string s_s; join(s_split_r, ':', s_s); + if (ref_s == s_s) return true; + // Check is it having a localhost in the service reference. If it do probably a stream relay + // so use different logic + if (ref2.toString().find("127.0.0.1") != std::string::npos) { + std::string url_sr = s_split[s_split.size() - 2]; + std::vector sr_split = split(url_sr, "/"); + std::string ref_orig = sr_split.back(); + ref_orig = replace_all(ref_orig, "%3a", ":"); + //eDebug("Ref1: %s || Ref2: %s", ref_s.c_str(), ref_orig.c_str()); + return ref_s + ":" == ref_orig; + } + return ref_s == s_s; } From 9ea997bcc396c7bac93563203866b110b95e8436 Mon Sep 17 00:00:00 2001 From: openvix-build Date: Fri, 24 Nov 2023 14:42:50 +0000 Subject: [PATCH 244/401] openvix: developer 6.4.010.008 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 87df6b4a72c..7671ac992d1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1206,3 +1206,4 @@ openvix: developer 6.4.010.004 openvix: developer 6.4.010.005 openvix: developer 6.4.010.006 openvix: developer 6.4.010.007 +openvix: developer 6.4.010.008 From d39c95614fbcd9be1f29c07a7848df66303c634a Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sat, 25 Nov 2023 13:10:17 +0200 Subject: [PATCH 245/401] [Added] handling of stream relay channels properly in cpp --- lib/dvb/db.cpp | 29 +++++++++++++++++-- lib/dvb/dvb.cpp | 19 ++++++++++-- lib/dvb/dvb.h | 2 +- lib/dvb/pmt.cpp | 17 +++++++++++ .../Components/Converter/PliExtraInfo.py | 6 +--- .../Components/Converter/ServiceName.py | 19 ++++++++---- lib/python/Screens/ChannelSelection.py | 13 +++++++++ lib/service/listboxservice.cpp | 14 +-------- lib/service/servicedvb.cpp | 6 ++-- 9 files changed, 93 insertions(+), 32 deletions(-) diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp index a6f3df4a143..81a621a7e4e 100644 --- a/lib/dvb/db.cpp +++ b/lib/dvb/db.cpp @@ -17,6 +17,7 @@ #include #include #include +#include /* * Copyright (C) 2017 Marcus Metzler @@ -221,6 +222,24 @@ bool eDVBService::isCrypted() int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate) { + std::string sr_url = eConfigManager::getConfigValue("config.misc.softcam_streamrelay_url"); + sr_url = replace_all(replace_all(replace_all(sr_url, "[", ""), "]", ""), ", ", "."); + std::string sr_port = eConfigManager::getConfigValue("config.misc.softcam_streamrelay_port"); + eServiceReferenceDVB newRef; + ePtr refCur; + eNavigation::getInstance()->getCurrentService(refCur); + ePtr tmp_info; + refCur->info(tmp_info); + std::string ref_s = tmp_info->getInfoString(iServiceInformation::sServiceref); + if (ref_s.find(sr_url + "%3a" + sr_port) != std::string::npos) { + std::vector s_split = split(ref_s, ":"); + std::string url_sr = s_split[s_split.size() - 2]; + std::vector sr_split = split(url_sr, "/"); + std::string ref_orig = sr_split.back(); + ref_orig = replace_all(ref_orig, "%3a", ":"); + newRef = eServiceReferenceDVB(ref_orig); + } + ePtr res_mgr; bool remote_fallback_enabled = eConfigManager::getConfigBoolValue("config.usage.remote_fallback_enabled", false); @@ -228,13 +247,19 @@ int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReferenc eDebug("[eDVBService] isPlayble... no res manager!!"); else { - eDVBChannelID chid, chid_ignore; + eDVBChannelID chid, chid_ignore, chid_ignore_sr; int system; ((const eServiceReferenceDVB&)ref).getChannelID(chid); ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore); - if (res_mgr->canAllocateChannel(chid, chid_ignore, system, simulate)) + if (newRef) { + newRef.getChannelID(chid_ignore_sr); + } else { + chid_ignore_sr = eDVBChannelID(); + } + + if (res_mgr->canAllocateChannel(chid, chid_ignore, chid_ignore_sr, system, simulate)) { bool use_ci_assignment = eConfigManager::getConfigBoolValue("config.misc.use_ci_assignment", false); if (use_ci_assignment) diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index 254da63d77d..2116149fb5c 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -1438,7 +1438,7 @@ int tuner_type_channel_default(ePtr &channellist, const eDVBCha return 0; } -int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore, int &system, bool simulate) +int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID& ignore, const eDVBChannelID& ignoresr, int &system, bool simulate) { std::list &active_channels = simulate ? m_active_simulate_channels : m_active_channels; int ret = 0; @@ -1446,8 +1446,9 @@ int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, cons if (!simulate && m_cached_channel) { eDVBChannel *cache_chan = (eDVBChannel*)&(*m_cached_channel); - if(channelid==cache_chan->getChannelID()) + if(channelid==cache_chan->getChannelID()) { return tuner_type_channel_default(m_list, channelid, system); + } } /* first, check if a channel is already existing. */ @@ -1469,6 +1470,7 @@ int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, cons std::vector fcc_decremented_fe_usecounts; std::map fcc_chids; int apply_to_ignore = 0; + int apply_to_ignoresr = 0; if (!eFCCServiceManager::getFCCChannelID(fcc_chids)) { for (std::map::iterator i(fcc_chids.begin()); i != fcc_chids.end(); ++i) @@ -1515,6 +1517,18 @@ int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, cons } } + // For stream relayed channel make a check is it in the available channels and if it is ignore it + if (ignoresr) { + for (std::list::iterator i(active_channels.begin()); i != active_channels.end(); ++i) + { + if (i->m_channel_id == ignoresr) + { + apply_to_ignoresr = 1; + break; + } + } + } + for (std::list::iterator i(active_channels.begin()); i != active_channels.end(); ++i) { eSmartPtrList &frontends = simulate ? m_simulate_frontend : m_frontend; @@ -1528,6 +1542,7 @@ int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, cons // or 2 when the cached channel is not equal to the compared channel int check_usecount = channel == &(*m_cached_channel) ? 1 : 0; check_usecount += (apply_to_ignore+1) * 2; // one is used in eDVBServicePMTHandler and another is used in eDVBScan. + check_usecount += apply_to_ignoresr; //eDebug("[eDVBResourceManager] canAllocateChannel channel->getUseCount() : %d , check_usecount : %d (cached : %d)", channel->getUseCount(), check_usecount, channel == &(*m_cached_channel)); if (channel->getUseCount() == check_usecount) // channel only used once..(except fcc) { diff --git a/lib/dvb/dvb.h b/lib/dvb/dvb.h index 238c37d302e..3909c7a9099 100644 --- a/lib/dvb/dvb.h +++ b/lib/dvb/dvb.h @@ -216,7 +216,7 @@ class eDVBResourceManager: public iObject, public sigc::trackable }; RESULT connectChannelAdded(const sigc::slot &channelAdded, ePtr &connection); - int canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID &ignore, int &system, bool simulate=false); + int canAllocateChannel(const eDVBChannelID &channelid, const eDVBChannelID &ignore, const eDVBChannelID& ignoresr, int &system, bool simulate=false); /* allocate channel... */ RESULT allocateChannel(const eDVBChannelID &channelid, eUsePtr &channel, bool simulate=false); diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index b8c8da42944..d9a59a92880 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -955,6 +955,23 @@ int eDVBServicePMTHandler::tuneExt(eServiceReferenceDVB &ref, ePtr &s if (!simulate) { + // If is stream relay service then allocate the real channel so to provide correct frontend info + std::string s_ref = ref.toString(); + eDVBChannelID chid; + std::string sr_url = eConfigManager::getConfigValue("config.misc.softcam_streamrelay_url"); + sr_url = replace_all(replace_all(replace_all(sr_url, "[", ""), "]", ""), ", ", "."); + std::string sr_port = eConfigManager::getConfigValue("config.misc.softcam_streamrelay_port"); + if (s_ref.find(sr_url + "%3a" + sr_port) != std::string::npos) { + std::vector s_split = split(s_ref, ":"); + std::string url_sr = s_split[s_split.size() - 2]; + std::vector sr_split = split(url_sr, "/"); + std::string ref_orig = sr_split.back(); + ref_orig = replace_all(ref_orig, "%3a", ":"); + eServiceReferenceDVB newRef = eServiceReferenceDVB(ref_orig); + newRef.getChannelID(chid); + res = m_resourceManager->allocateChannel(chid, m_channel, simulate); + } + if (m_channel) { m_channel->connectStateChange( diff --git a/lib/python/Components/Converter/PliExtraInfo.py b/lib/python/Components/Converter/PliExtraInfo.py index ed277572299..1fbea57889a 100644 --- a/lib/python/Components/Converter/PliExtraInfo.py +++ b/lib/python/Components/Converter/PliExtraInfo.py @@ -1,6 +1,6 @@ # shamelessly copied from pliExpertInfo (Vali, Mirakels, Littlesat) -from enigma import eServiceCenter, iServiceInformation, iPlayableService +from enigma import iServiceInformation, iPlayableService from Components.Converter.Converter import Converter from Components.Element import cached from Components.config import config @@ -9,7 +9,6 @@ from Tools.Hex2strColor import Hex2strColor from Components.Converter.Poll import Poll from skin import parameters -from Session import SessionObject caid_data = ( ("0x100", "0x1ff", "Seca", "S", True), @@ -886,9 +885,6 @@ def getTextByType(self, textType): feinfo = service.frontendInfo() if feinfo: self.feraw = feinfo.getAll(config.usage.infobar_frontend_source.value == "settings") - if not self.feraw: - serviceref = SessionObject().session.nav.getCurrentlyPlayingServiceReference() - self.feraw = serviceref and eServiceCenter.getInstance().info(serviceref).getInfoObject(serviceref, iServiceInformation.sTransponderData) if self.feraw: self.fedata = ConvertToHumanReadable(self.feraw) diff --git a/lib/python/Components/Converter/ServiceName.py b/lib/python/Components/Converter/ServiceName.py index a664579609e..63f0ffef562 100644 --- a/lib/python/Components/Converter/ServiceName.py +++ b/lib/python/Components/Converter/ServiceName.py @@ -90,8 +90,8 @@ def getText(self): name = self.getName(service, info) numservice = self.source.serviceref num = self.getNumber(numservice, info) - provider = self.getProvider(service, info) - orbpos = self.getOrbitalPos(service, info) + orbpos, tp_data = self.getOrbitalPos(service, info) + provider = self.getProvider(service, info, tp_data) res_str = "" for x in self.parts[1:]: if x == "NUMBER" and num: @@ -124,10 +124,10 @@ def getNumber(self, ref, info): num = str(num) return num - def getProvider(self, ref, info): + def getProvider(self, ref, info, tp_data=None): if ref: - return info.getInfoString(ref, iServiceInformation.sProvider) - return info.getInfoString(iServiceInformation.sProvider) + return info.getInfoString(ref, iServiceInformation.sProvider) or tp_data and {282: "BSkyB", 192: "SKY", 130: "SkyItalia"}.get(tp_data["orbital_position"], "") + return info.getInfoString(iServiceInformation.sProvider) or tp_data and {282: "BSkyB", 192: "SKY", 130: "SkyItalia"}.get(tp_data["orbital_position"], "") def getOrbitalPos(self, ref, info): orbitalpos = "" @@ -135,6 +135,13 @@ def getOrbitalPos(self, ref, info): tp_data = info.getInfoObject(ref, iServiceInformation.sTransponderData) else: tp_data = info.getInfoObject(iServiceInformation.sTransponderData) + + if not tp_data and not ref: + service = self.source.service + if service: + feraw = service.frontendInfo() + tp_data = feraw and feraw.getAll(config.usage.infobar_frontend_source.value == "settings") + if tp_data is not None: try: position = tp_data["orbital_position"] @@ -144,4 +151,4 @@ def getOrbitalPos(self, ref, info): orbitalpos = "%.1f " % (float(position) / 10) + _("E") except: pass - return orbitalpos + return orbitalpos, tp_data diff --git a/lib/python/Screens/ChannelSelection.py b/lib/python/Screens/ChannelSelection.py index ca01a0fdd88..da43ccac407 100644 --- a/lib/python/Screens/ChannelSelection.py +++ b/lib/python/Screens/ChannelSelection.py @@ -61,6 +61,18 @@ FLAG_IS_DEDICATED_3D = 128 FLAG_CENTER_DVB_SUBS = 2048 # define in lib/dvb/idvb.h as dxNewFound = 64 and dxIsDedicated3D = 128 +def getStreamRelayRef(sref): + try: + if "http" in sref: + sr_port = config.misc.softcam_streamrelay_port.value + sr_ip = ".".join("%d" % d for d in config.misc.softcam_streamrelay_url.value) + sr_url = f"http%3a//{sr_ip}%3a{sr_port}/" + if sr_url in sref: + return sref.split(sr_url)[1].split(":")[0].replace("%3a", ":") + except Exception: + pass + return sref + class BouquetSelector(Screen): def __init__(self, session, bouquets, selectedFunc, enableWrapAround=True): @@ -2086,6 +2098,7 @@ def __evServiceStart(self): info = service.info() if info: refstr = info.getInfoString(iServiceInformation.sServiceref) + refstr = getStreamRelayRef(refstr) self.servicelist.setPlayableIgnoreService(eServiceReference(refstr)) def __evServiceEnd(self): diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 38518f8ef6b..61a8c68bd56 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -810,19 +810,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (!marked && isPlayable && service_info && m_is_playable_ignore.valid()) { - - eNavigation::getInstance()->getCurrentService(refCur); - ePtr tmp_info; - refCur->info(tmp_info); - std::string ref = tmp_info->getInfoString(iServiceInformation::sServiceref); - std::map, eServiceReference, std::less > recordedServices; - recordedServices = eNavigation::getInstance()->getRecordingsServices(); - if (ref.find("127.0.0.1") != std::string::npos && recordedServices.size() == 0) { - isplayable_value = 1; - } else { - isplayable_value = service_info->isPlayable(*m_cursor, m_is_playable_ignore); - } - + isplayable_value = service_info->isPlayable(*m_cursor, m_is_playable_ignore); if (isplayable_value == 0) // service unavailable { if (m_color_set[serviceNotAvail]) diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index b8f0614ec37..5d6684caaf4 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -108,7 +108,7 @@ int eStaticServiceDVBInformation::isPlayable(const eServiceReference &ref, const int system; ((const eServiceReferenceDVB&)ref).getChannelID(chid); ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore); - return res_mgr->canAllocateChannel(chid, chid_ignore, system); + return res_mgr->canAllocateChannel(chid, chid_ignore, eDVBChannelID(), system); } return 0; } @@ -253,7 +253,7 @@ int eStaticServiceDVBBouquetInformation::isPlayable(const eServiceReference &ref }; int system; ((const eServiceReferenceDVB&)*it).getChannelID(chid); - int tmp = res->canAllocateChannel(chid, chid_ignore, system, simulate); + int tmp = res->canAllocateChannel(chid, chid_ignore, eDVBChannelID(), system, simulate); if (prio_order == 127) // ignore dvb-type priority, try all alternatives one-by-one { if (((tmp > 0) || (!it->path.empty()))) @@ -2427,7 +2427,7 @@ bool eDVBServiceBase::tryFallbackTuner(eServiceReferenceDVB &service, bool &is_s service.getChannelID(chid); // this sets chid eServiceReferenceDVB().getChannelID(chid_ignore); // this sets chid_ignore - if(res_mgr->canAllocateChannel(chid, chid_ignore, system)) // this sets system + if(res_mgr->canAllocateChannel(chid, chid_ignore, eDVBChannelID(), system)) // this sets system return false; while((index = remote_fallback_url.find(':')) != std::string::npos) From 4a3ec3c771620a8fb18eecf3ba19401a3a2db1a2 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sat, 25 Nov 2023 11:39:20 +0000 Subject: [PATCH 246/401] PEP8 double aggressive E301 ~ E306 --- lib/python/Screens/ChannelSelection.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/python/Screens/ChannelSelection.py b/lib/python/Screens/ChannelSelection.py index da43ccac407..d5ea4804aa8 100644 --- a/lib/python/Screens/ChannelSelection.py +++ b/lib/python/Screens/ChannelSelection.py @@ -61,6 +61,7 @@ FLAG_IS_DEDICATED_3D = 128 FLAG_CENTER_DVB_SUBS = 2048 # define in lib/dvb/idvb.h as dxNewFound = 64 and dxIsDedicated3D = 128 + def getStreamRelayRef(sref): try: if "http" in sref: From f769102a6aca576f609fe5a879b508ed82010242 Mon Sep 17 00:00:00 2001 From: openvix-build Date: Sat, 25 Nov 2023 12:49:51 +0000 Subject: [PATCH 247/401] openvix: developer 6.4.010.009 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 7671ac992d1..cff209f2afd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1207,3 +1207,4 @@ openvix: developer 6.4.010.005 openvix: developer 6.4.010.006 openvix: developer 6.4.010.007 openvix: developer 6.4.010.008 +openvix: developer 6.4.010.009 From 25b91f8c73455fa7f7d51bef2bd83e3cb81e3e37 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sat, 25 Nov 2023 17:20:50 +0200 Subject: [PATCH 248/401] [Fixed] Recordings of stream relay channels not working --- lib/dvb/pmt.cpp | 22 +++++++++++++++++-- lib/dvb/pmt.h | 1 + .../Components/Converter/ServiceName.py | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index d9a59a92880..561c28b5fa0 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -795,7 +795,11 @@ int eDVBServicePMTHandler::compareAudioSubtitleCode(const std::string &subtitleT int eDVBServicePMTHandler::getChannel(eUsePtr &channel) { - channel = m_channel; + if (m_sr_channel) { + channel = m_sr_channel; + } else { + channel = m_channel; + } if (channel) return 0; else @@ -969,7 +973,21 @@ int eDVBServicePMTHandler::tuneExt(eServiceReferenceDVB &ref, ePtr &s ref_orig = replace_all(ref_orig, "%3a", ":"); eServiceReferenceDVB newRef = eServiceReferenceDVB(ref_orig); newRef.getChannelID(chid); - res = m_resourceManager->allocateChannel(chid, m_channel, simulate); + // Allocate the channel in different ptr so to not mess up original pvr channel info + res = m_resourceManager->allocateChannel(chid, m_sr_channel, simulate); + } + + + if (m_sr_channel) { + m_sr_channel->connectStateChange( + sigc::mem_fun(*this, &eDVBServicePMTHandler::channelStateChanged), + m_channelStateChanged_connection); + m_last_channel_state = -1; + channelStateChanged(m_sr_channel); + + m_sr_channel->connectEvent( + sigc::mem_fun(*this, &eDVBServicePMTHandler::channelEvent), + m_channelEvent_connection); } if (m_channel) diff --git a/lib/dvb/pmt.h b/lib/dvb/pmt.h index b9aec9a0cd3..f86d96ef490 100644 --- a/lib/dvb/pmt.h +++ b/lib/dvb/pmt.h @@ -57,6 +57,7 @@ class eDVBServicePMTHandler: public eDVBPMTParser eAUTable > m_OC; eUsePtr m_channel; + eUsePtr m_sr_channel; eUsePtr m_pvr_channel; ePtr m_resourceManager; ePtr m_demux, m_pvr_demux_tmp; diff --git a/lib/python/Components/Converter/ServiceName.py b/lib/python/Components/Converter/ServiceName.py index 63f0ffef562..d06bee3ef85 100644 --- a/lib/python/Components/Converter/ServiceName.py +++ b/lib/python/Components/Converter/ServiceName.py @@ -107,7 +107,7 @@ def getText(self): text = property(getText) def changed(self, what): - if what[0] != self.CHANGED_SPECIFIC or what[1] in (iPlayableService.evStart,): + if what[0] != self.CHANGED_SPECIFIC or what[1] in (iPlayableService.evStart, iPlayableService.evNewProgramInfo): Converter.changed(self, what) def getName(self, ref, info): From 82c987161a99a86c1f9a41381f894852d0c31d48 Mon Sep 17 00:00:00 2001 From: openvix-build Date: Sat, 25 Nov 2023 15:24:09 +0000 Subject: [PATCH 249/401] openvix: developer 6.4.010.010 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index cff209f2afd..06d8b15f1b5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1208,3 +1208,4 @@ openvix: developer 6.4.010.006 openvix: developer 6.4.010.007 openvix: developer 6.4.010.008 openvix: developer 6.4.010.009 +openvix: developer 6.4.010.010 From 3c08b894adc570323d846e72aa7b70ded010ae2b Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sat, 25 Nov 2023 19:23:50 +0200 Subject: [PATCH 250/401] [Added] Original provider name for SR channels [Updated] Some code optimizations --- lib/dvb/db.cpp | 17 ++++------------ lib/dvb/idvb.h | 20 +++++++++++++++++++ lib/dvb/pmt.cpp | 20 ++++++------------- .../Components/Converter/PliExtraInfo.py | 2 +- .../Components/Converter/ServiceName.py | 4 ++-- lib/service/servicedvb.cpp | 14 ++++++++++++- 6 files changed, 46 insertions(+), 31 deletions(-) diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp index 81a621a7e4e..c32c8145a44 100644 --- a/lib/dvb/db.cpp +++ b/lib/dvb/db.cpp @@ -222,23 +222,14 @@ bool eDVBService::isCrypted() int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate) { - std::string sr_url = eConfigManager::getConfigValue("config.misc.softcam_streamrelay_url"); - sr_url = replace_all(replace_all(replace_all(sr_url, "[", ""), "]", ""), ", ", "."); - std::string sr_port = eConfigManager::getConfigValue("config.misc.softcam_streamrelay_port"); - eServiceReferenceDVB newRef; + ServiceReferenceDVB newRef; ePtr refCur; eNavigation::getInstance()->getCurrentService(refCur); ePtr tmp_info; refCur->info(tmp_info); std::string ref_s = tmp_info->getInfoString(iServiceInformation::sServiceref); - if (ref_s.find(sr_url + "%3a" + sr_port) != std::string::npos) { - std::vector s_split = split(ref_s, ":"); - std::string url_sr = s_split[s_split.size() - 2]; - std::vector sr_split = split(url_sr, "/"); - std::string ref_orig = sr_split.back(); - ref_orig = replace_all(ref_orig, "%3a", ":"); - newRef = eServiceReferenceDVB(ref_orig); - } + eServiceReferenceDVB currentlyPlaying = eServiceReferenceDVB(ref_s); + bool res = currentlyPlaying.getSROriginal(newRef); ePtr res_mgr; bool remote_fallback_enabled = eConfigManager::getConfigBoolValue("config.usage.remote_fallback_enabled", false); @@ -253,7 +244,7 @@ int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReferenc ((const eServiceReferenceDVB&)ref).getChannelID(chid); ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore); - if (newRef) { + if (res) { newRef.getChannelID(chid_ignore_sr); } else { chid_ignore_sr = eDVBChannelID(); diff --git a/lib/dvb/idvb.h b/lib/dvb/idvb.h index d6a89945206..9c2fdcc87e0 100644 --- a/lib/dvb/idvb.h +++ b/lib/dvb/idvb.h @@ -12,6 +12,8 @@ #include #include #include +#include // access to python config +#include #define CAID_LIST std::list @@ -249,6 +251,24 @@ class eServiceReferenceDVB: public eServiceReference chid = eDVBChannelID(getDVBNamespace(), getTransportStreamID(), getOriginalNetworkID()); } + bool getSROriginal(eServiceReferenceDVB &sref) const + { + std::string s_ref = this->toString(); + std::string sr_url = eConfigManager::getConfigValue("config.misc.softcam_streamrelay_url"); + sr_url = replace_all(replace_all(replace_all(sr_url, "[", ""), "]", ""), ", ", "."); + std::string sr_port = eConfigManager::getConfigValue("config.misc.softcam_streamrelay_port"); + if (s_ref.find(sr_url + "%3a" + sr_port) != std::string::npos) { + std::vector s_split = split(s_ref, ":"); + std::string url_sr = s_split[s_split.size() - 2]; + std::vector sr_split = split(url_sr, "/"); + std::string ref_orig = sr_split.back(); + ref_orig = replace_all(ref_orig, "%3a", ":"); + sref = eServiceReferenceDVB(ref_orig); + return true; + } + return false; + } + eServiceReferenceDVB() :eServiceReference(eServiceReference::idDVB, 0) { diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index 561c28b5fa0..3dcb228f2fb 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -960,22 +960,14 @@ int eDVBServicePMTHandler::tuneExt(eServiceReferenceDVB &ref, ePtr &s if (!simulate) { // If is stream relay service then allocate the real channel so to provide correct frontend info - std::string s_ref = ref.toString(); eDVBChannelID chid; - std::string sr_url = eConfigManager::getConfigValue("config.misc.softcam_streamrelay_url"); - sr_url = replace_all(replace_all(replace_all(sr_url, "[", ""), "]", ""), ", ", "."); - std::string sr_port = eConfigManager::getConfigValue("config.misc.softcam_streamrelay_port"); - if (s_ref.find(sr_url + "%3a" + sr_port) != std::string::npos) { - std::vector s_split = split(s_ref, ":"); - std::string url_sr = s_split[s_split.size() - 2]; - std::vector sr_split = split(url_sr, "/"); - std::string ref_orig = sr_split.back(); - ref_orig = replace_all(ref_orig, "%3a", ":"); - eServiceReferenceDVB newRef = eServiceReferenceDVB(ref_orig); - newRef.getChannelID(chid); - // Allocate the channel in different ptr so to not mess up original pvr channel info + eServiceReferenceDVB sRelayOrigSref; + bool res = ref.getSROriginal(sRelayOrigSref); + + if (res) { + sRelayOrigSref.getChannelID(chid); res = m_resourceManager->allocateChannel(chid, m_sr_channel, simulate); - } + } if (m_sr_channel) { diff --git a/lib/python/Components/Converter/PliExtraInfo.py b/lib/python/Components/Converter/PliExtraInfo.py index 1fbea57889a..eacbfa58ac0 100644 --- a/lib/python/Components/Converter/PliExtraInfo.py +++ b/lib/python/Components/Converter/PliExtraInfo.py @@ -745,7 +745,7 @@ def createTransponderName(self, feraw): return self.formatOrbPos(orbpos) def createProviderName(self, info): - return info.getInfoString(iServiceInformation.sProvider) or self.feraw and {282: "BSkyB", 192: "SKY", 130: "SkyItalia"}.get(self.feraw.get("orbital_position"), "") + return info.getInfoString(iServiceInformation.sProvider) def createMisPls(self, fedata): tmp = "" diff --git a/lib/python/Components/Converter/ServiceName.py b/lib/python/Components/Converter/ServiceName.py index d06bee3ef85..a477b2796cd 100644 --- a/lib/python/Components/Converter/ServiceName.py +++ b/lib/python/Components/Converter/ServiceName.py @@ -126,8 +126,8 @@ def getNumber(self, ref, info): def getProvider(self, ref, info, tp_data=None): if ref: - return info.getInfoString(ref, iServiceInformation.sProvider) or tp_data and {282: "BSkyB", 192: "SKY", 130: "SkyItalia"}.get(tp_data["orbital_position"], "") - return info.getInfoString(iServiceInformation.sProvider) or tp_data and {282: "BSkyB", 192: "SKY", 130: "SkyItalia"}.get(tp_data["orbital_position"], "") + return info.getInfoString(ref, iServiceInformation.sProvider) + return info.getInfoString(iServiceInformation.sProvider) def getOrbitalPos(self, ref, info): orbitalpos = "" diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index 5d6684caaf4..c4b83cce605 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -2075,8 +2075,20 @@ std::string eDVBServicePlay::getInfoString(int w) switch (w) { case sProvider: + { if (!m_dvb_service) return ""; - return m_dvb_service->m_provider_name; + std::string prov = m_dvb_service->m_provider_name; + if (prov.empty()) { + eServiceReferenceDVB orig; + bool res = ((const eServiceReferenceDVB&)m_reference).getSROriginal(orig); + if (res) { + ePtr serviceOrig; + eDVBDB::getInstance()->getService(orig, serviceOrig); + return serviceOrig->m_provider_name; + } + } + return prov; + } case sServiceref: return m_reference.toString(); case sHBBTVUrl: From f632292d4cbf726380e2ea36e197bec59ec6c776 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sat, 25 Nov 2023 19:28:37 +0200 Subject: [PATCH 251/401] [Updated] variable names --- lib/dvb/db.cpp | 6 +++--- lib/service/servicedvb.cpp | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp index c32c8145a44..1de9c6c9b1d 100644 --- a/lib/dvb/db.cpp +++ b/lib/dvb/db.cpp @@ -222,14 +222,14 @@ bool eDVBService::isCrypted() int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate) { - ServiceReferenceDVB newRef; + ServiceReferenceDVB sRelayOrigSref; ePtr refCur; eNavigation::getInstance()->getCurrentService(refCur); ePtr tmp_info; refCur->info(tmp_info); std::string ref_s = tmp_info->getInfoString(iServiceInformation::sServiceref); eServiceReferenceDVB currentlyPlaying = eServiceReferenceDVB(ref_s); - bool res = currentlyPlaying.getSROriginal(newRef); + bool res = currentlyPlaying.getSROriginal(sRelayOrigSref); ePtr res_mgr; bool remote_fallback_enabled = eConfigManager::getConfigBoolValue("config.usage.remote_fallback_enabled", false); @@ -245,7 +245,7 @@ int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReferenc ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore); if (res) { - newRef.getChannelID(chid_ignore_sr); + sRelayOrigSref.getChannelID(chid_ignore_sr); } else { chid_ignore_sr = eDVBChannelID(); } diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index c4b83cce605..a8fae5d73cb 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -2079,12 +2079,12 @@ std::string eDVBServicePlay::getInfoString(int w) if (!m_dvb_service) return ""; std::string prov = m_dvb_service->m_provider_name; if (prov.empty()) { - eServiceReferenceDVB orig; - bool res = ((const eServiceReferenceDVB&)m_reference).getSROriginal(orig); + eServiceReferenceDVB sRelayOrigSref; + bool res = ((const eServiceReferenceDVB&)m_reference).getSROriginal(sRelayOrigSref); if (res) { - ePtr serviceOrig; - eDVBDB::getInstance()->getService(orig, serviceOrig); - return serviceOrig->m_provider_name; + ePtr sRelayServiceOrigSref; + eDVBDB::getInstance()->getService(sRelayOrigSref, sRelayServiceOrigSref); + return sRelayServiceOrigSref->m_provider_name; } } return prov; From d72a5e5c26fb39fc5e9739a405bc9dbce0d5403f Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sat, 25 Nov 2023 19:30:15 +0200 Subject: [PATCH 252/401] [Fixed] typo in variable --- lib/dvb/db.cpp | 2 +- lib/python/Components/EpgListGrid.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp index 1de9c6c9b1d..dbce0fc5db9 100644 --- a/lib/dvb/db.cpp +++ b/lib/dvb/db.cpp @@ -222,7 +222,7 @@ bool eDVBService::isCrypted() int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate) { - ServiceReferenceDVB sRelayOrigSref; + eServiceReferenceDVB sRelayOrigSref; ePtr refCur; eNavigation::getInstance()->getCurrentService(refCur); ePtr tmp_info; diff --git a/lib/python/Components/EpgListGrid.py b/lib/python/Components/EpgListGrid.py index d6235ce7b94..06ecea72d4d 100644 --- a/lib/python/Components/EpgListGrid.py +++ b/lib/python/Components/EpgListGrid.py @@ -573,6 +573,8 @@ def buildEntry(self, service, serviceName, events, picon, channel): borderRightPix = self.borderSelectedRightPix infoPix = self.selInfoPix bgpng = self.nowSelEvPix if isNow else self.selEvPix + if timer: + bgpng = self.recSelEvPix if timer.justplay == 0 and timer.always_zap == 0 else self.zapSelEvPix else: borderTopPix = self.borderTopPix borderLeftPix = self.borderLeftPix From fb3dd483d1ab8a1958decbdb9696007c5df5230f Mon Sep 17 00:00:00 2001 From: openvix-build Date: Sat, 25 Nov 2023 19:22:56 +0000 Subject: [PATCH 253/401] openvix: developer 6.4.010.011 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 06d8b15f1b5..30900d0eb26 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1209,3 +1209,4 @@ openvix: developer 6.4.010.007 openvix: developer 6.4.010.008 openvix: developer 6.4.010.009 openvix: developer 6.4.010.010 +openvix: developer 6.4.010.011 From 143cd2c3bf52b7128a9d67429b8ba0a91dddb1b3 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sat, 25 Nov 2023 23:11:32 +0200 Subject: [PATCH 254/401] [Fixed] Delay in loading transponder data for stream relay service --- lib/service/servicedvb.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index a8fae5d73cb..adc010aeb92 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -2113,6 +2113,11 @@ std::string eDVBServicePlay::getInfoString(int w) ePtr eDVBServicePlay::getTransponderData() { + eServiceReferenceDVB orig; + bool res = ((const eServiceReferenceDVB&)m_reference).getSROriginal(orig); + if (res) { + return eStaticServiceDVBInformation().getTransponderData(orig); + } return eStaticServiceDVBInformation().getTransponderData(m_reference); } From 1cbdfdcacd4b7f0038ac02b48190eede6905fc7c Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sun, 26 Nov 2023 11:55:39 +0200 Subject: [PATCH 255/401] [Fixed] Separator char for IPTV providers functionality --- lib/service/servicedvb.cpp | 2 +- lib/service/servicemp3.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index adc010aeb92..92440046aa9 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -389,7 +389,7 @@ RESULT eStaticServiceDVBPVRInformation::getName(const eServiceReference &ref, st m_parser.m_name = name; } if (!name.empty()) { - std::vector name_split = split(name, "|"); + std::vector name_split = split(name, "•"); name = name_split[0]; if (name_split.size() > 1) { m_parser.m_prov = name_split[1]; diff --git a/lib/service/servicemp3.cpp b/lib/service/servicemp3.cpp index 03f3e6c0bed..3aaaa9aeba5 100644 --- a/lib/service/servicemp3.cpp +++ b/lib/service/servicemp3.cpp @@ -263,7 +263,7 @@ RESULT eStaticServiceMP3Info::getName(const eServiceReference &ref, std::string name = ref.path; } if (!name.empty()) { - std::vector name_split = split(name, "|"); + std::vector name_split = split(name, "•"); name = name_split[0]; } return 0; @@ -1206,7 +1206,7 @@ RESULT eServiceMP3::getName(std::string &name) name = title; if (!name.empty()) { - std::vector name_split = split(name, "|"); + std::vector name_split = split(name, "•"); name = name_split[0]; if (name_split.size() > 1) { m_prov = name_split[1]; From 412ccbac8862ebede8f1f5349461de319a54965a Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sun, 26 Nov 2023 21:09:52 +0200 Subject: [PATCH 256/401] [Updated] stream relay handling. Removed double channel allocation --- lib/dvb/db.cpp | 18 +++------- lib/dvb/dvb.cpp | 10 ++++-- lib/dvb/dvb.h | 3 ++ lib/dvb/idvb.h | 29 +++++----------- lib/dvb/pmt.cpp | 48 ++++++++++++++------------ lib/python/Screens/ChannelSelection.py | 10 +++--- lib/python/ServiceReference.py | 31 ++++++++++++++--- lib/service/iservice.h | 2 ++ lib/service/servicedvb.cpp | 33 +++++++++++------- lib/service/servicemp3.cpp | 2 +- 10 files changed, 103 insertions(+), 83 deletions(-) diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp index dbce0fc5db9..2de494f2992 100644 --- a/lib/dvb/db.cpp +++ b/lib/dvb/db.cpp @@ -17,7 +17,6 @@ #include #include #include -#include /* * Copyright (C) 2017 Marcus Metzler @@ -222,15 +221,6 @@ bool eDVBService::isCrypted() int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate) { - eServiceReferenceDVB sRelayOrigSref; - ePtr refCur; - eNavigation::getInstance()->getCurrentService(refCur); - ePtr tmp_info; - refCur->info(tmp_info); - std::string ref_s = tmp_info->getInfoString(iServiceInformation::sServiceref); - eServiceReferenceDVB currentlyPlaying = eServiceReferenceDVB(ref_s); - bool res = currentlyPlaying.getSROriginal(sRelayOrigSref); - ePtr res_mgr; bool remote_fallback_enabled = eConfigManager::getConfigBoolValue("config.usage.remote_fallback_enabled", false); @@ -244,11 +234,11 @@ int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReferenc ((const eServiceReferenceDVB&)ref).getChannelID(chid); ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore); - if (res) { - sRelayOrigSref.getChannelID(chid_ignore_sr); - } else { + if (ignore.streamrelayOrigSref.empty()) { chid_ignore_sr = eDVBChannelID(); - } + } else { + chid_ignore_sr = chid_ignore; + } if (res_mgr->canAllocateChannel(chid, chid_ignore, chid_ignore_sr, system, simulate)) { diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index 2116149fb5c..556df0d0a1e 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -1161,7 +1161,11 @@ RESULT eDVBResourceManager::getChannelList(ePtr &list) if (!simulate) \ eDebug(x); \ } while(0) - +RESULT eDVBResourceManager::getActiveChannels(std::list &list) +{ + list = m_active_channels; + return 0; +} RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr &channel, bool simulate) { @@ -1517,7 +1521,7 @@ int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, cons } } - // For stream relayed channel make a check is it in the available channels and if it is ignore it + // For stream relayed channel make a check is it in the available channels and if it is ignore it if (ignoresr) { for (std::list::iterator i(active_channels.begin()); i != active_channels.end(); ++i) { @@ -2153,7 +2157,7 @@ RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtraddChannel(channelid, this); - + m_current_frontend_parameters = feparm; if (!m_frontend) diff --git a/lib/dvb/dvb.h b/lib/dvb/dvb.h index 3909c7a9099..9ab301a9648 100644 --- a/lib/dvb/dvb.h +++ b/lib/dvb/dvb.h @@ -168,6 +168,7 @@ class eDVBResourceManager: public iObject, public sigc::trackable void addAdapter(iDVBAdapter *adapter, bool front = false); void setUsbTuner(); +public: struct active_channel { eDVBChannelID m_channel_id; @@ -177,6 +178,7 @@ class eDVBResourceManager: public iObject, public sigc::trackable active_channel(const eDVBChannelID &chid, eDVBChannel *ch) : m_channel_id(chid), m_channel(ch) { } }; +private: std::list m_active_channels, m_active_simulate_channels; ePtr m_list; @@ -204,6 +206,7 @@ class eDVBResourceManager: public iObject, public sigc::trackable RESULT setChannelList(iDVBChannelList *list); RESULT getChannelList(ePtr &list); + RESULT getActiveChannels(std::list &list); enum { /* errNoFrontend = -1 replaced by more spcific messages */ diff --git a/lib/dvb/idvb.h b/lib/dvb/idvb.h index 9c2fdcc87e0..b323db4737d 100644 --- a/lib/dvb/idvb.h +++ b/lib/dvb/idvb.h @@ -12,8 +12,6 @@ #include #include #include -#include // access to python config -#include #define CAID_LIST std::list @@ -145,6 +143,13 @@ struct eDVBChannelID eTransportStreamID transport_stream_id; eOriginalNetworkID original_network_id; + std::string toString(void) const + { + char buf[30]; + sprintf(buf, "%x:%x:%x", transport_stream_id.get(), original_network_id.get(), dvbnamespace.get()); + return std::string(buf); + } + bool operator==(const eDVBChannelID &c) const { return dvbnamespace == c.dvbnamespace && @@ -213,7 +218,7 @@ class eServiceReferenceDVB: public eServiceReference int getSourceID() const { return data[7]; } void setSourceID(int sourceid) { data[7] = sourceid; } - + eServiceReferenceDVB getParentServiceReference() const { eServiceReferenceDVB tmp(*this); @@ -251,24 +256,6 @@ class eServiceReferenceDVB: public eServiceReference chid = eDVBChannelID(getDVBNamespace(), getTransportStreamID(), getOriginalNetworkID()); } - bool getSROriginal(eServiceReferenceDVB &sref) const - { - std::string s_ref = this->toString(); - std::string sr_url = eConfigManager::getConfigValue("config.misc.softcam_streamrelay_url"); - sr_url = replace_all(replace_all(replace_all(sr_url, "[", ""), "]", ""), ", ", "."); - std::string sr_port = eConfigManager::getConfigValue("config.misc.softcam_streamrelay_port"); - if (s_ref.find(sr_url + "%3a" + sr_port) != std::string::npos) { - std::vector s_split = split(s_ref, ":"); - std::string url_sr = s_split[s_split.size() - 2]; - std::vector sr_split = split(url_sr, "/"); - std::string ref_orig = sr_split.back(); - ref_orig = replace_all(ref_orig, "%3a", ":"); - sref = eServiceReferenceDVB(ref_orig); - return true; - } - return false; - } - eServiceReferenceDVB() :eServiceReference(eServiceReference::idDVB, 0) { diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index 3dcb228f2fb..25bdb2f79d1 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -795,6 +795,31 @@ int eDVBServicePMTHandler::compareAudioSubtitleCode(const std::string &subtitleT int eDVBServicePMTHandler::getChannel(eUsePtr &channel) { + if (!m_sr_channel && !m_reference.streamrelayOrigSref.empty()) + { + ePtr res_mgr; + if ( !eDVBResourceManager::getInstance( res_mgr ) ) + { + std::list list; + res_mgr->getActiveChannels(list); + if(list.size()) { + eServiceReferenceDVB sRelayOrigSref = eServiceReferenceDVB(m_reference.streamrelayOrigSref); + char buf[30]; + sprintf(buf, "%x:%x:%x", sRelayOrigSref.getTransportStreamID().get(), sRelayOrigSref.getOriginalNetworkID().get(), sRelayOrigSref.getDVBNamespace().get()); + std::string origChannelID = std::string(buf); + for (std::list::iterator i(list.begin()); i != list.end(); ++i) + { + std::string channelid = i->m_channel_id.toString(); + if (channelid == origChannelID) + { + m_sr_channel = i->m_channel; + break; + } + } + + } + } + } if (m_sr_channel) { channel = m_sr_channel; } else { @@ -959,29 +984,6 @@ int eDVBServicePMTHandler::tuneExt(eServiceReferenceDVB &ref, ePtr &s if (!simulate) { - // If is stream relay service then allocate the real channel so to provide correct frontend info - eDVBChannelID chid; - eServiceReferenceDVB sRelayOrigSref; - bool res = ref.getSROriginal(sRelayOrigSref); - - if (res) { - sRelayOrigSref.getChannelID(chid); - res = m_resourceManager->allocateChannel(chid, m_sr_channel, simulate); - } - - - if (m_sr_channel) { - m_sr_channel->connectStateChange( - sigc::mem_fun(*this, &eDVBServicePMTHandler::channelStateChanged), - m_channelStateChanged_connection); - m_last_channel_state = -1; - channelStateChanged(m_sr_channel); - - m_sr_channel->connectEvent( - sigc::mem_fun(*this, &eDVBServicePMTHandler::channelEvent), - m_channelEvent_connection); - } - if (m_channel) { m_channel->connectStateChange( diff --git a/lib/python/Screens/ChannelSelection.py b/lib/python/Screens/ChannelSelection.py index d5ea4804aa8..95d96644a6e 100644 --- a/lib/python/Screens/ChannelSelection.py +++ b/lib/python/Screens/ChannelSelection.py @@ -39,7 +39,7 @@ from Screens.ServiceInfo import ServiceInfo from Screens.TimerEntry import TimerEntry, addTimerFromEventSilent from Screens.VirtualKeyBoard import VirtualKeyBoard -from ServiceReference import ServiceReference +from ServiceReference import ServiceReference, getStreamRelayRef from Tools.Alternatives import GetWithAlternative from Tools.BoundFunction import boundFunction from Tools.Directories import sanitizeFilename @@ -2099,9 +2099,11 @@ def __evServiceStart(self): info = service.info() if info: refstr = info.getInfoString(iServiceInformation.sServiceref) - refstr = getStreamRelayRef(refstr) - self.servicelist.setPlayableIgnoreService(eServiceReference(refstr)) - + refstr, is_stream_relay = getStreamRelayRef(refstr) + ref = eServiceReference(refstr) + if is_stream_relay: + ref.setStreamRelayOriginalRef(refstr) + self.servicelist.setPlayableIgnoreService(ref) def __evServiceEnd(self): self.servicelist.setPlayableIgnoreService(eServiceReference()) diff --git a/lib/python/ServiceReference.py b/lib/python/ServiceReference.py index 7f8f025f1b4..d4eb2c218fb 100644 --- a/lib/python/ServiceReference.py +++ b/lib/python/ServiceReference.py @@ -1,15 +1,38 @@ -from enigma import eServiceReference, eServiceCenter, getBestPlayableServiceReference +from enigma import eServiceReference, eServiceCenter, getBestPlayableServiceReference, iServiceInformation import NavigationInstance +from Components.config import config # Global helper functions +def getStreamRelayRef(sref): + try: + if "http" in sref: + sr_port = config.misc.softcam_streamrelay_port.value + sr_ip = ".".join("%d" % d for d in config.misc.softcam_streamrelay_url.value) + sr_url = f"http%3a//{sr_ip}%3a{sr_port}/" + if sr_url in sref: + return sref.split(sr_url)[1].split(":")[0].replace("%3a", ":"), True + except Exception: + pass + return sref, False def getPlayingRef(): playingref = None - if NavigationInstance.instance: - playingref = NavigationInstance.instance.getCurrentlyPlayingServiceReference() + playsrv = getPlayingService() + info_s = playsrv and playsrv.info() + playref_str = info_s and info_s.getInfoString(iServiceInformation.sServiceref) or "" + if playref_str: + playref_str, is_stream_relay = getStreamRelayRef(playref_str) + playingref = eServiceReference(playref_str) + if is_stream_relay: + playingref.setStreamRelayOriginalRef(playref_str) return playingref or eServiceReference() - + +def getPlayingService(): + playingref = None + if NavigationInstance.instance: + playingref = NavigationInstance.instance.getCurrentService() + return playingref def isPlayableForCur(serviceref): info = eServiceCenter.getInstance().info(serviceref) diff --git a/lib/service/iservice.h b/lib/service/iservice.h index 7f2a44367fe..9608fdc4f57 100644 --- a/lib/service/iservice.h +++ b/lib/service/iservice.h @@ -54,9 +54,11 @@ class eServiceReference #ifndef SWIG int data[8]; std::string path; + std::string streamrelayOrigSref; #endif std::string getPath() const { return path; } void setPath( const std::string &n ) { path=n; } + void setStreamRelayOriginalRef( const std::string &n ) { streamrelayOrigSref=n; } unsigned int getUnsignedData(unsigned int num) const { diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index 92440046aa9..2155989b932 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -1896,6 +1896,14 @@ RESULT eDVBServicePlay::getName(std::string &name) eStaticServiceDVBInformation().getName(m_reference, name); else name = "DVB service"; + + if (!name.empty()) { + std::vector name_split = split(name, "•"); + name = name_split[0]; + if (name_split.size() > 1) { + m_dvb_service->m_provider_name = name_split[1]; + } + } return 0; } @@ -2056,6 +2064,10 @@ int eDVBServicePlay::getInfo(int w) case sTSID: return ((const eServiceReferenceDVB&)m_reference).getTransportStreamID().get(); case sNamespace: + // use origiginal namespace + if (!m_reference.streamrelayOrigSref.empty()){ + return ((const eServiceReferenceDVB&)eServiceReferenceDVB(m_reference.streamrelayOrigSref)).getDVBNamespace().get(); + } return ((const eServiceReferenceDVB&)m_reference).getDVBNamespace().get(); case sProvider: if (!m_dvb_service) return -1; @@ -2077,17 +2089,13 @@ std::string eDVBServicePlay::getInfoString(int w) case sProvider: { if (!m_dvb_service) return ""; - std::string prov = m_dvb_service->m_provider_name; - if (prov.empty()) { - eServiceReferenceDVB sRelayOrigSref; - bool res = ((const eServiceReferenceDVB&)m_reference).getSROriginal(sRelayOrigSref); - if (res) { - ePtr sRelayServiceOrigSref; - eDVBDB::getInstance()->getService(sRelayOrigSref, sRelayServiceOrigSref); - return sRelayServiceOrigSref->m_provider_name; - } + if(m_dvb_service->m_provider_name.empty() && !m_reference.streamrelayOrigSref.empty()) + { + ePtr sRelayServiceOrigSref; + eDVBDB::getInstance()->getService(eServiceReferenceDVB(m_reference.streamrelayOrigSref), sRelayServiceOrigSref); + m_dvb_service->m_provider_name = std::string(sRelayServiceOrigSref->m_provider_name); } - return prov; + return m_dvb_service->m_provider_name; } case sServiceref: return m_reference.toString(); @@ -2113,9 +2121,8 @@ std::string eDVBServicePlay::getInfoString(int w) ePtr eDVBServicePlay::getTransponderData() { - eServiceReferenceDVB orig; - bool res = ((const eServiceReferenceDVB&)m_reference).getSROriginal(orig); - if (res) { + if (!m_reference.streamrelayOrigSref.empty()) { + eServiceReferenceDVB orig = eServiceReferenceDVB(m_reference.streamrelayOrigSref); return eStaticServiceDVBInformation().getTransponderData(orig); } return eStaticServiceDVBInformation().getTransponderData(m_reference); diff --git a/lib/service/servicemp3.cpp b/lib/service/servicemp3.cpp index 3aaaa9aeba5..aeb1c0b33bf 100644 --- a/lib/service/servicemp3.cpp +++ b/lib/service/servicemp3.cpp @@ -265,7 +265,7 @@ RESULT eStaticServiceMP3Info::getName(const eServiceReference &ref, std::string if (!name.empty()) { std::vector name_split = split(name, "•"); name = name_split[0]; - } + } return 0; } From 304721c8b63da4bfeef55248d3dc14113ca4f41e Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sun, 26 Nov 2023 19:30:25 +0000 Subject: [PATCH 257/401] PEP8 double aggressive E301 ~ E306 --- lib/python/Screens/ChannelSelection.py | 1 + lib/python/ServiceReference.py | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/lib/python/Screens/ChannelSelection.py b/lib/python/Screens/ChannelSelection.py index 95d96644a6e..64236d687c5 100644 --- a/lib/python/Screens/ChannelSelection.py +++ b/lib/python/Screens/ChannelSelection.py @@ -2104,6 +2104,7 @@ def __evServiceStart(self): if is_stream_relay: ref.setStreamRelayOriginalRef(refstr) self.servicelist.setPlayableIgnoreService(ref) + def __evServiceEnd(self): self.servicelist.setPlayableIgnoreService(eServiceReference()) diff --git a/lib/python/ServiceReference.py b/lib/python/ServiceReference.py index d4eb2c218fb..46195f8d45f 100644 --- a/lib/python/ServiceReference.py +++ b/lib/python/ServiceReference.py @@ -4,6 +4,7 @@ # Global helper functions + def getStreamRelayRef(sref): try: if "http" in sref: @@ -16,6 +17,7 @@ def getStreamRelayRef(sref): pass return sref, False + def getPlayingRef(): playingref = None playsrv = getPlayingService() @@ -28,12 +30,14 @@ def getPlayingRef(): playingref.setStreamRelayOriginalRef(playref_str) return playingref or eServiceReference() + def getPlayingService(): playingref = None if NavigationInstance.instance: playingref = NavigationInstance.instance.getCurrentService() return playingref + def isPlayableForCur(serviceref): info = eServiceCenter.getInstance().info(serviceref) return info and info.isPlayable(serviceref, getPlayingRef()) From 885047b01878154d3f8615a808788c9764e06b8e Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sun, 26 Nov 2023 19:30:36 +0000 Subject: [PATCH 258/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/ServiceReference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/ServiceReference.py b/lib/python/ServiceReference.py index 46195f8d45f..135f34b8728 100644 --- a/lib/python/ServiceReference.py +++ b/lib/python/ServiceReference.py @@ -29,7 +29,7 @@ def getPlayingRef(): if is_stream_relay: playingref.setStreamRelayOriginalRef(playref_str) return playingref or eServiceReference() - + def getPlayingService(): playingref = None From 1b69ee68f07bbc5a84cc3c90b7cce32c08c4b2fa Mon Sep 17 00:00:00 2001 From: Huevos Date: Sun, 26 Nov 2023 22:05:40 +0100 Subject: [PATCH 259/401] Revert "PEP8 double aggressive W291 ~ W293 and W391" This reverts commit 885047b01878154d3f8615a808788c9764e06b8e. --- lib/python/ServiceReference.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/ServiceReference.py b/lib/python/ServiceReference.py index 135f34b8728..46195f8d45f 100644 --- a/lib/python/ServiceReference.py +++ b/lib/python/ServiceReference.py @@ -29,7 +29,7 @@ def getPlayingRef(): if is_stream_relay: playingref.setStreamRelayOriginalRef(playref_str) return playingref or eServiceReference() - + def getPlayingService(): playingref = None From 5f14fb9ad7237805e1e89f538ce424c036ab3426 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sun, 26 Nov 2023 22:05:48 +0100 Subject: [PATCH 260/401] Revert "PEP8 double aggressive E301 ~ E306" This reverts commit 304721c8b63da4bfeef55248d3dc14113ca4f41e. --- lib/python/Screens/ChannelSelection.py | 1 - lib/python/ServiceReference.py | 4 ---- 2 files changed, 5 deletions(-) diff --git a/lib/python/Screens/ChannelSelection.py b/lib/python/Screens/ChannelSelection.py index 64236d687c5..95d96644a6e 100644 --- a/lib/python/Screens/ChannelSelection.py +++ b/lib/python/Screens/ChannelSelection.py @@ -2104,7 +2104,6 @@ def __evServiceStart(self): if is_stream_relay: ref.setStreamRelayOriginalRef(refstr) self.servicelist.setPlayableIgnoreService(ref) - def __evServiceEnd(self): self.servicelist.setPlayableIgnoreService(eServiceReference()) diff --git a/lib/python/ServiceReference.py b/lib/python/ServiceReference.py index 46195f8d45f..d4eb2c218fb 100644 --- a/lib/python/ServiceReference.py +++ b/lib/python/ServiceReference.py @@ -4,7 +4,6 @@ # Global helper functions - def getStreamRelayRef(sref): try: if "http" in sref: @@ -17,7 +16,6 @@ def getStreamRelayRef(sref): pass return sref, False - def getPlayingRef(): playingref = None playsrv = getPlayingService() @@ -30,14 +28,12 @@ def getPlayingRef(): playingref.setStreamRelayOriginalRef(playref_str) return playingref or eServiceReference() - def getPlayingService(): playingref = None if NavigationInstance.instance: playingref = NavigationInstance.instance.getCurrentService() return playingref - def isPlayableForCur(serviceref): info = eServiceCenter.getInstance().info(serviceref) return info and info.isPlayable(serviceref, getPlayingRef()) From 7858eeb178c8252fed753d2b3ae88bb4130679d9 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sun, 26 Nov 2023 22:05:57 +0100 Subject: [PATCH 261/401] Revert "[Updated] stream relay handling. Removed double channel allocation" This reverts commit 412ccbac8862ebede8f1f5349461de319a54965a. --- lib/dvb/db.cpp | 18 +++++++--- lib/dvb/dvb.cpp | 10 ++---- lib/dvb/dvb.h | 3 -- lib/dvb/idvb.h | 29 +++++++++++----- lib/dvb/pmt.cpp | 48 ++++++++++++-------------- lib/python/Screens/ChannelSelection.py | 10 +++--- lib/python/ServiceReference.py | 31 +++-------------- lib/service/iservice.h | 2 -- lib/service/servicedvb.cpp | 33 +++++++----------- lib/service/servicemp3.cpp | 2 +- 10 files changed, 83 insertions(+), 103 deletions(-) diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp index 2de494f2992..dbce0fc5db9 100644 --- a/lib/dvb/db.cpp +++ b/lib/dvb/db.cpp @@ -17,6 +17,7 @@ #include #include #include +#include /* * Copyright (C) 2017 Marcus Metzler @@ -221,6 +222,15 @@ bool eDVBService::isCrypted() int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate) { + eServiceReferenceDVB sRelayOrigSref; + ePtr refCur; + eNavigation::getInstance()->getCurrentService(refCur); + ePtr tmp_info; + refCur->info(tmp_info); + std::string ref_s = tmp_info->getInfoString(iServiceInformation::sServiceref); + eServiceReferenceDVB currentlyPlaying = eServiceReferenceDVB(ref_s); + bool res = currentlyPlaying.getSROriginal(sRelayOrigSref); + ePtr res_mgr; bool remote_fallback_enabled = eConfigManager::getConfigBoolValue("config.usage.remote_fallback_enabled", false); @@ -234,11 +244,11 @@ int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReferenc ((const eServiceReferenceDVB&)ref).getChannelID(chid); ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore); - if (ignore.streamrelayOrigSref.empty()) { + if (res) { + sRelayOrigSref.getChannelID(chid_ignore_sr); + } else { chid_ignore_sr = eDVBChannelID(); - } else { - chid_ignore_sr = chid_ignore; - } + } if (res_mgr->canAllocateChannel(chid, chid_ignore, chid_ignore_sr, system, simulate)) { diff --git a/lib/dvb/dvb.cpp b/lib/dvb/dvb.cpp index 556df0d0a1e..2116149fb5c 100644 --- a/lib/dvb/dvb.cpp +++ b/lib/dvb/dvb.cpp @@ -1161,11 +1161,7 @@ RESULT eDVBResourceManager::getChannelList(ePtr &list) if (!simulate) \ eDebug(x); \ } while(0) -RESULT eDVBResourceManager::getActiveChannels(std::list &list) -{ - list = m_active_channels; - return 0; -} + RESULT eDVBResourceManager::allocateChannel(const eDVBChannelID &channelid, eUsePtr &channel, bool simulate) { @@ -1521,7 +1517,7 @@ int eDVBResourceManager::canAllocateChannel(const eDVBChannelID &channelid, cons } } - // For stream relayed channel make a check is it in the available channels and if it is ignore it + // For stream relayed channel make a check is it in the available channels and if it is ignore it if (ignoresr) { for (std::list::iterator i(active_channels.begin()); i != active_channels.end(); ++i) { @@ -2157,7 +2153,7 @@ RESULT eDVBChannel::setChannel(const eDVBChannelID &channelid, ePtraddChannel(channelid, this); - + m_current_frontend_parameters = feparm; if (!m_frontend) diff --git a/lib/dvb/dvb.h b/lib/dvb/dvb.h index 9ab301a9648..3909c7a9099 100644 --- a/lib/dvb/dvb.h +++ b/lib/dvb/dvb.h @@ -168,7 +168,6 @@ class eDVBResourceManager: public iObject, public sigc::trackable void addAdapter(iDVBAdapter *adapter, bool front = false); void setUsbTuner(); -public: struct active_channel { eDVBChannelID m_channel_id; @@ -178,7 +177,6 @@ class eDVBResourceManager: public iObject, public sigc::trackable active_channel(const eDVBChannelID &chid, eDVBChannel *ch) : m_channel_id(chid), m_channel(ch) { } }; -private: std::list m_active_channels, m_active_simulate_channels; ePtr m_list; @@ -206,7 +204,6 @@ class eDVBResourceManager: public iObject, public sigc::trackable RESULT setChannelList(iDVBChannelList *list); RESULT getChannelList(ePtr &list); - RESULT getActiveChannels(std::list &list); enum { /* errNoFrontend = -1 replaced by more spcific messages */ diff --git a/lib/dvb/idvb.h b/lib/dvb/idvb.h index b323db4737d..9c2fdcc87e0 100644 --- a/lib/dvb/idvb.h +++ b/lib/dvb/idvb.h @@ -12,6 +12,8 @@ #include #include #include +#include // access to python config +#include #define CAID_LIST std::list @@ -143,13 +145,6 @@ struct eDVBChannelID eTransportStreamID transport_stream_id; eOriginalNetworkID original_network_id; - std::string toString(void) const - { - char buf[30]; - sprintf(buf, "%x:%x:%x", transport_stream_id.get(), original_network_id.get(), dvbnamespace.get()); - return std::string(buf); - } - bool operator==(const eDVBChannelID &c) const { return dvbnamespace == c.dvbnamespace && @@ -218,7 +213,7 @@ class eServiceReferenceDVB: public eServiceReference int getSourceID() const { return data[7]; } void setSourceID(int sourceid) { data[7] = sourceid; } - + eServiceReferenceDVB getParentServiceReference() const { eServiceReferenceDVB tmp(*this); @@ -256,6 +251,24 @@ class eServiceReferenceDVB: public eServiceReference chid = eDVBChannelID(getDVBNamespace(), getTransportStreamID(), getOriginalNetworkID()); } + bool getSROriginal(eServiceReferenceDVB &sref) const + { + std::string s_ref = this->toString(); + std::string sr_url = eConfigManager::getConfigValue("config.misc.softcam_streamrelay_url"); + sr_url = replace_all(replace_all(replace_all(sr_url, "[", ""), "]", ""), ", ", "."); + std::string sr_port = eConfigManager::getConfigValue("config.misc.softcam_streamrelay_port"); + if (s_ref.find(sr_url + "%3a" + sr_port) != std::string::npos) { + std::vector s_split = split(s_ref, ":"); + std::string url_sr = s_split[s_split.size() - 2]; + std::vector sr_split = split(url_sr, "/"); + std::string ref_orig = sr_split.back(); + ref_orig = replace_all(ref_orig, "%3a", ":"); + sref = eServiceReferenceDVB(ref_orig); + return true; + } + return false; + } + eServiceReferenceDVB() :eServiceReference(eServiceReference::idDVB, 0) { diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index 25bdb2f79d1..3dcb228f2fb 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -795,31 +795,6 @@ int eDVBServicePMTHandler::compareAudioSubtitleCode(const std::string &subtitleT int eDVBServicePMTHandler::getChannel(eUsePtr &channel) { - if (!m_sr_channel && !m_reference.streamrelayOrigSref.empty()) - { - ePtr res_mgr; - if ( !eDVBResourceManager::getInstance( res_mgr ) ) - { - std::list list; - res_mgr->getActiveChannels(list); - if(list.size()) { - eServiceReferenceDVB sRelayOrigSref = eServiceReferenceDVB(m_reference.streamrelayOrigSref); - char buf[30]; - sprintf(buf, "%x:%x:%x", sRelayOrigSref.getTransportStreamID().get(), sRelayOrigSref.getOriginalNetworkID().get(), sRelayOrigSref.getDVBNamespace().get()); - std::string origChannelID = std::string(buf); - for (std::list::iterator i(list.begin()); i != list.end(); ++i) - { - std::string channelid = i->m_channel_id.toString(); - if (channelid == origChannelID) - { - m_sr_channel = i->m_channel; - break; - } - } - - } - } - } if (m_sr_channel) { channel = m_sr_channel; } else { @@ -984,6 +959,29 @@ int eDVBServicePMTHandler::tuneExt(eServiceReferenceDVB &ref, ePtr &s if (!simulate) { + // If is stream relay service then allocate the real channel so to provide correct frontend info + eDVBChannelID chid; + eServiceReferenceDVB sRelayOrigSref; + bool res = ref.getSROriginal(sRelayOrigSref); + + if (res) { + sRelayOrigSref.getChannelID(chid); + res = m_resourceManager->allocateChannel(chid, m_sr_channel, simulate); + } + + + if (m_sr_channel) { + m_sr_channel->connectStateChange( + sigc::mem_fun(*this, &eDVBServicePMTHandler::channelStateChanged), + m_channelStateChanged_connection); + m_last_channel_state = -1; + channelStateChanged(m_sr_channel); + + m_sr_channel->connectEvent( + sigc::mem_fun(*this, &eDVBServicePMTHandler::channelEvent), + m_channelEvent_connection); + } + if (m_channel) { m_channel->connectStateChange( diff --git a/lib/python/Screens/ChannelSelection.py b/lib/python/Screens/ChannelSelection.py index 95d96644a6e..d5ea4804aa8 100644 --- a/lib/python/Screens/ChannelSelection.py +++ b/lib/python/Screens/ChannelSelection.py @@ -39,7 +39,7 @@ from Screens.ServiceInfo import ServiceInfo from Screens.TimerEntry import TimerEntry, addTimerFromEventSilent from Screens.VirtualKeyBoard import VirtualKeyBoard -from ServiceReference import ServiceReference, getStreamRelayRef +from ServiceReference import ServiceReference from Tools.Alternatives import GetWithAlternative from Tools.BoundFunction import boundFunction from Tools.Directories import sanitizeFilename @@ -2099,11 +2099,9 @@ def __evServiceStart(self): info = service.info() if info: refstr = info.getInfoString(iServiceInformation.sServiceref) - refstr, is_stream_relay = getStreamRelayRef(refstr) - ref = eServiceReference(refstr) - if is_stream_relay: - ref.setStreamRelayOriginalRef(refstr) - self.servicelist.setPlayableIgnoreService(ref) + refstr = getStreamRelayRef(refstr) + self.servicelist.setPlayableIgnoreService(eServiceReference(refstr)) + def __evServiceEnd(self): self.servicelist.setPlayableIgnoreService(eServiceReference()) diff --git a/lib/python/ServiceReference.py b/lib/python/ServiceReference.py index d4eb2c218fb..7f8f025f1b4 100644 --- a/lib/python/ServiceReference.py +++ b/lib/python/ServiceReference.py @@ -1,38 +1,15 @@ -from enigma import eServiceReference, eServiceCenter, getBestPlayableServiceReference, iServiceInformation +from enigma import eServiceReference, eServiceCenter, getBestPlayableServiceReference import NavigationInstance -from Components.config import config # Global helper functions -def getStreamRelayRef(sref): - try: - if "http" in sref: - sr_port = config.misc.softcam_streamrelay_port.value - sr_ip = ".".join("%d" % d for d in config.misc.softcam_streamrelay_url.value) - sr_url = f"http%3a//{sr_ip}%3a{sr_port}/" - if sr_url in sref: - return sref.split(sr_url)[1].split(":")[0].replace("%3a", ":"), True - except Exception: - pass - return sref, False def getPlayingRef(): - playingref = None - playsrv = getPlayingService() - info_s = playsrv and playsrv.info() - playref_str = info_s and info_s.getInfoString(iServiceInformation.sServiceref) or "" - if playref_str: - playref_str, is_stream_relay = getStreamRelayRef(playref_str) - playingref = eServiceReference(playref_str) - if is_stream_relay: - playingref.setStreamRelayOriginalRef(playref_str) - return playingref or eServiceReference() - -def getPlayingService(): playingref = None if NavigationInstance.instance: - playingref = NavigationInstance.instance.getCurrentService() - return playingref + playingref = NavigationInstance.instance.getCurrentlyPlayingServiceReference() + return playingref or eServiceReference() + def isPlayableForCur(serviceref): info = eServiceCenter.getInstance().info(serviceref) diff --git a/lib/service/iservice.h b/lib/service/iservice.h index 9608fdc4f57..7f2a44367fe 100644 --- a/lib/service/iservice.h +++ b/lib/service/iservice.h @@ -54,11 +54,9 @@ class eServiceReference #ifndef SWIG int data[8]; std::string path; - std::string streamrelayOrigSref; #endif std::string getPath() const { return path; } void setPath( const std::string &n ) { path=n; } - void setStreamRelayOriginalRef( const std::string &n ) { streamrelayOrigSref=n; } unsigned int getUnsignedData(unsigned int num) const { diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index 2155989b932..92440046aa9 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -1896,14 +1896,6 @@ RESULT eDVBServicePlay::getName(std::string &name) eStaticServiceDVBInformation().getName(m_reference, name); else name = "DVB service"; - - if (!name.empty()) { - std::vector name_split = split(name, "•"); - name = name_split[0]; - if (name_split.size() > 1) { - m_dvb_service->m_provider_name = name_split[1]; - } - } return 0; } @@ -2064,10 +2056,6 @@ int eDVBServicePlay::getInfo(int w) case sTSID: return ((const eServiceReferenceDVB&)m_reference).getTransportStreamID().get(); case sNamespace: - // use origiginal namespace - if (!m_reference.streamrelayOrigSref.empty()){ - return ((const eServiceReferenceDVB&)eServiceReferenceDVB(m_reference.streamrelayOrigSref)).getDVBNamespace().get(); - } return ((const eServiceReferenceDVB&)m_reference).getDVBNamespace().get(); case sProvider: if (!m_dvb_service) return -1; @@ -2089,13 +2077,17 @@ std::string eDVBServicePlay::getInfoString(int w) case sProvider: { if (!m_dvb_service) return ""; - if(m_dvb_service->m_provider_name.empty() && !m_reference.streamrelayOrigSref.empty()) - { - ePtr sRelayServiceOrigSref; - eDVBDB::getInstance()->getService(eServiceReferenceDVB(m_reference.streamrelayOrigSref), sRelayServiceOrigSref); - m_dvb_service->m_provider_name = std::string(sRelayServiceOrigSref->m_provider_name); + std::string prov = m_dvb_service->m_provider_name; + if (prov.empty()) { + eServiceReferenceDVB sRelayOrigSref; + bool res = ((const eServiceReferenceDVB&)m_reference).getSROriginal(sRelayOrigSref); + if (res) { + ePtr sRelayServiceOrigSref; + eDVBDB::getInstance()->getService(sRelayOrigSref, sRelayServiceOrigSref); + return sRelayServiceOrigSref->m_provider_name; + } } - return m_dvb_service->m_provider_name; + return prov; } case sServiceref: return m_reference.toString(); @@ -2121,8 +2113,9 @@ std::string eDVBServicePlay::getInfoString(int w) ePtr eDVBServicePlay::getTransponderData() { - if (!m_reference.streamrelayOrigSref.empty()) { - eServiceReferenceDVB orig = eServiceReferenceDVB(m_reference.streamrelayOrigSref); + eServiceReferenceDVB orig; + bool res = ((const eServiceReferenceDVB&)m_reference).getSROriginal(orig); + if (res) { return eStaticServiceDVBInformation().getTransponderData(orig); } return eStaticServiceDVBInformation().getTransponderData(m_reference); diff --git a/lib/service/servicemp3.cpp b/lib/service/servicemp3.cpp index aeb1c0b33bf..3aaaa9aeba5 100644 --- a/lib/service/servicemp3.cpp +++ b/lib/service/servicemp3.cpp @@ -265,7 +265,7 @@ RESULT eStaticServiceMP3Info::getName(const eServiceReference &ref, std::string if (!name.empty()) { std::vector name_split = split(name, "•"); name = name_split[0]; - } + } return 0; } From 403732e75635eab3134c364a97c01a45d3086259 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sun, 26 Nov 2023 23:24:21 +0100 Subject: [PATCH 262/401] [StreamRelay] add adjustable delay --- data/setup.xml | 1 + lib/python/Components/UsageConfig.py | 1 + lib/python/Navigation.py | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/data/setup.xml b/data/setup.xml index 79a0f241d54..59bc420dd5f 100644 --- a/data/setup.xml +++ b/data/setup.xml @@ -24,6 +24,7 @@ config.streaming.descramble_client config.misc.softcam_streamrelay_url config.misc.softcam_streamrelay_port + config.misc.softcam_streamrelay_delay config.streaming.authentication config.usage.http_startdelay config.usage.wakeOnLAN diff --git a/lib/python/Components/UsageConfig.py b/lib/python/Components/UsageConfig.py index e864f1db24d..a52a5649d75 100644 --- a/lib/python/Components/UsageConfig.py +++ b/lib/python/Components/UsageConfig.py @@ -1139,6 +1139,7 @@ def setEpgLanguageAlternative(configElement): ("s", _("Restart softcam"))]) config.misc.softcam_streamrelay_url = ConfigIP(default=[127, 0, 0, 1], auto_jump=True) config.misc.softcam_streamrelay_port = ConfigInteger(default=17999, limits=(0, 65535)) + config.misc.softcam_streamrelay_delay = ConfigSelectionNumber(min=50, max=2000, stepwidth=50, default=100, wraparound=True) SystemInfo["OScamInstalled"] = False config.cccaminfo = ConfigSubsection() diff --git a/lib/python/Navigation.py b/lib/python/Navigation.py index ee4b70daf53..6871fa87f3e 100644 --- a/lib/python/Navigation.py +++ b/lib/python/Navigation.py @@ -221,7 +221,7 @@ def playService(self, ref, checkParentalControl=True, forceRestart=False, adjust print("[Navigation] Streamrelay was active -> delay the zap till tuner is freed") self.retryServicePlayTimer = eTimer() self.retryServicePlayTimer.callback.append(boundFunction(self.playService, ref, checkParentalControl, forceRestart, adjust, True)) - self.retryServicePlayTimer.start(100, True) + self.retryServicePlayTimer.start(config.misc.softcam_streamrelay_delay.value, True) elif self.pnav.playService(playref): # print("[Navigation] Failed to start", playref) self.currentlyPlayingServiceReference = None From ebff3b44d2a1a625eb75bd8c3523bc79a0eb0221 Mon Sep 17 00:00:00 2001 From: Orlandoxx <95180049+Orlandoxx@users.noreply.github.com> Date: Mon, 27 Nov 2023 07:05:26 +0200 Subject: [PATCH 263/401] Updated Finnish (fi.po) translation Added new "Streamrelay delay" & description. --- po/fi.po | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/po/fi.po b/po/fi.po index 0b500b364f6..6abe979f18f 100644 --- a/po/fi.po +++ b/po/fi.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: enigma2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-27 23:35+0000\n" -"PO-Revision-Date: 2023-11-13 19:22+0200\n" +"PO-Revision-Date: 2023-11-27 07:03+0200\n" "Last-Translator: Orlandox\n" "Language-Team: timoj/Kojo/Samzam/Orlandox\n" "Language: fi\n" @@ -7677,9 +7677,6 @@ msgstr "Myöhäis" msgctxt "third event: 'third' event label" msgid "Later" -msgstr "Myöhemmin" - -msgid "LATER" msgstr "MYÖHEMMIN" msgid "Latitude" @@ -8526,9 +8523,6 @@ msgstr "Ei saatavilla" msgid "n/a" msgstr "Ei saatavilla" -msgid "NEXT" -msgstr "SEURAAVA" - msgid "NFS" msgstr "NFS" @@ -8739,7 +8733,7 @@ msgstr "Seuraava" msgctxt "now/next: 'next' event label" msgid "Next" -msgstr "Seuraava" +msgstr "SEURAAVA" msgid "Nicaragua" msgstr "Nicaragua" @@ -9015,9 +9009,6 @@ msgstr "Ei mitään, sulje valikko" msgctxt "now/next: 'now' event label" msgid "Now" -msgstr "Nyt" - -msgid "NOW" msgstr "NYT" msgid "Now, use the contrast setting to turn up the brightness of the background as much as possible, but make sure that you can still see the difference between the two brightest levels of shades.If you have done that, press OK." @@ -13549,7 +13540,7 @@ msgstr "" "Suomenkielinen käännös: timoj, Kojo, Samzam, Orlandox\n" "\n" "Ylläpito : Orlandox\n" -"13.11.2023\n" +"27.11.2023\n" "http://www.huoltovalikko.com" msgid "TS file is too large for ISO9660 level 1!" @@ -19114,6 +19105,12 @@ msgstr "Striimin välitys -palvelimen IP-osoite, jota käytetään sellaisten pa msgid "Streamrelay port" msgstr "Striimin välitys -portti" +msgid "Streamrelay delay" +msgstr "Striimin välityksen viive" + +msgid "Delay when closing a streamrelay service before reallocating the tuner for another service." +msgstr "Viive striimin välitys -palvelun sulkemisessa ennen virittimen uudelleenallokointia toista palvelua varten." + msgid "The port of the streamrelay server that is used to descramble services that can only be decrypted via streamrelay" msgstr "Striimin välitys -palvelimen portti, jota käytetään sellaisten palvelujen salauksen purkamiseen, joiden salaus voidaan purkaa vain striimin välityksen kautta" From a2156e6feb7dc2169f8e5e3a1288799d9212a26e Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Mon, 27 Nov 2023 17:00:57 +0200 Subject: [PATCH 264/401] [Updated] [ServiceList] Single line mode handling --- lib/python/Components/ServiceList.py | 26 +- lib/service/listboxservice.cpp | 742 ++++++++++++--------------- lib/service/listboxservice.h | 8 +- 3 files changed, 333 insertions(+), 443 deletions(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index a6efdda5daa..7e54020ff87 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -487,7 +487,7 @@ def setMode(self, mode): two_lines_val = int(config.usage.servicelist_twolines.value) self.l.setItemHeight(self.ItemHeight if two_lines_val == 0 else self.ItemHeightTwoLine) self.l.setVisualMode(eListboxServiceContent.visModeComplex if two_lines_val == 0 else eListboxServiceContent.visSkinDefined) - + pic = None if two_lines_val: if self.selectionPixmapDouble: @@ -495,7 +495,7 @@ def setMode(self, mode): else: if self.selectionPixmapSingle: pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, self.selectionPixmapSingle)) - + pic and hasattr(self.l, "setSelectionPicture") and self.l.setSelectionPicture(pic) if config.usage.service_icon_enable.value: @@ -505,28 +505,11 @@ def setMode(self, mode): rowWidth = self.instance.size().width() - 30 # scrollbar is fixed 20 + 10 Extra marge - if mode == self.MODE_NORMAL or not config.usage.show_channel_numbers_in_servicelist.value: - channelNumberWidth = 0 - channelNumberSpace = 0 - else: - channelNumberWidth = config.usage.alternative_number_mode.value and getTextBoundarySize(self.instance, self.ServiceNumberFont, self.instance.size(), "0000").width() or getTextBoundarySize(self.instance, self.ServiceNumberFont, self.instance.size(), "00000").width() - channelNumberSpace = self.fieldMargins - - self.l.setElementPosition(self.l.celServiceNumber, eRect(self.sidesMargin, 0, channelNumberWidth, self.ItemHeight)) - progressWidth = self.progressBarWidth if "perc" in config.usage.show_event_progress_in_servicelist.value: progressWidth = self.progressPercentWidth or self.progressBarWidth - if "left" in config.usage.show_event_progress_in_servicelist.value: - self.l.setElementPosition(self.l.celServiceEventProgressbar, eRect(channelNumberWidth + channelNumberSpace + self.sidesMargin, 0, progressWidth, self.ItemHeight)) - self.l.setElementPosition(self.l.celServiceName, eRect(channelNumberWidth + channelNumberSpace + progressWidth + self.fieldMargins + self.sidesMargin, 0, rowWidth - (channelNumberWidth + channelNumberSpace + progressWidth + self.fieldMargins), self.ItemHeight)) - elif "right" in config.usage.show_event_progress_in_servicelist.value: - self.l.setElementPosition(self.l.celServiceEventProgressbar, eRect(rowWidth - progressWidth, 0, progressWidth, self.ItemHeight)) - self.l.setElementPosition(self.l.celServiceName, eRect(channelNumberWidth + channelNumberSpace + self.sidesMargin, 0, rowWidth - (channelNumberWidth + channelNumberSpace + progressWidth + self.fieldMargins), self.ItemHeight)) - else: - self.l.setElementPosition(self.l.celServiceEventProgressbar, eRect(0, 0, 0, 0)) - self.l.setElementPosition(self.l.celServiceName, eRect(channelNumberWidth + channelNumberSpace + self.sidesMargin, 0, rowWidth - (channelNumberWidth + channelNumberSpace + self.sidesMargin), self.ItemHeight)) + self.l.setElementPosition(self.l.celServiceEventProgressbar, eRect(0, 0, progressWidth, self.ItemHeight)) self.l.setElementFont(self.l.celServiceName, self.ServiceNameFont) self.l.setElementFont(self.l.celServiceNumber, self.ServiceNumberFont) @@ -538,6 +521,9 @@ def setMode(self, mode): self.l.setCryptoIconMode(int(config.usage.crypto_icon_mode.value)) self.l.setRecordIndicatorMode(int(config.usage.record_indicator_mode.value)) self.l.setColumnWidth(-1 if two_lines_val > 0 else int(config.usage.servicelist_column.value)) + self.l.setProgressBarMode(config.usage.show_event_progress_in_servicelist.value) + self.l.setChannelNumbersVisible(config.usage.show_channel_numbers_in_servicelist.value) + self.l.setAlternativeNumberingMode(config.usage.alternative_number_mode.value) def selectionEnabled(self, enabled): if self.instance is not None: diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 61a8c68bd56..667b007b2b4 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -811,6 +811,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (!marked && isPlayable && service_info && m_is_playable_ignore.valid()) { isplayable_value = service_info->isPlayable(*m_cursor, m_is_playable_ignore); + if (isplayable_value == 0) // service unavailable { if (m_color_set[serviceNotAvail]) @@ -844,6 +845,8 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const std::string text = ""; + bool hasChannelNumbers = m_chanel_number_visible; + time_t now = time(0); std::string event_name = "", next_event_name = ""; @@ -1005,8 +1008,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (!isMarker && !isDirectory) { std::string chNum = ""; - eRect serviceNumberRect = m_element_position[celServiceNumber]; - if (serviceNumberRect.width() > 0 && m_cursor->getChannelNum() != 0) { + if (hasChannelNumbers && m_cursor->getChannelNum() != 0) { char buffer[15]; snprintf(buffer, sizeof(buffer), "%d", m_cursor->getChannelNum() ); chNum = buffer; @@ -1052,6 +1054,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const eRect secondLineRect = eRect(secondLineOffset, offset.y() + (m_itemheight - m_marker_as_line) / 2, m_itemsize.width() - secondLineOffset - 16 - 8, m_marker_as_line); painter.fill(secondLineRect); } + // event name if (is_event) @@ -1168,6 +1171,10 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } else { // Single line mode goes here + if (service_info) + service_info->getName(ref, text); + + xoffs += m_sides_margin; if (is_event) { event_name = evt->getEventName(); @@ -1175,466 +1182,357 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const event_duration = evt->getDuration(); } bool hasPicons = PyCallable_Check(m_GetPiconNameFunc); + bool isAlternativeNumberingMode = m_alternative_numbering; + std::string eventProgressConfig = m_progress_mode; - eRect p_area = m_element_position[celServiceInfo]; - int iconWidth = p_area.height() * 9 / 5; - int xoffeset_marker = 0; - int marker_text_width = 0; - for (int e = 0; e != celServiceTypePixmap; ++e) - { - if (m_element_font[e]) - { - int flags=gPainter::RT_VALIGN_CENTER; - int yoffs = 0; - eRect area = m_element_position[e]; - std::string text = ""; - switch (e) - { - case celServiceNumber: - { - if (area.width() <= 0) - continue; // no point in going on if we won't paint anything + ePtr paraServiceName = new eTextPara(eRect(0, 0, m_itemsize.width(), m_itemheight)); + paraServiceName->setFont(m_element_font[celServiceName]); + paraServiceName->renderString(text.c_str()); + eRect bboxServiceName = paraServiceName->getBoundBox(); + + if (isDirectory || (isMarker && !m_marker_as_line)) { + ePtr &pixmap_mDir = isMarker ? m_pixmaps[picMarker] : isDirectory ? m_pixmaps[picFolder] : m_pixmaps[picElements];; + eSize pixmap_size = pixmap_mDir->size(); + if (pixmap_size.height() < m_itemheight){ + eRect area = eRect(xoffs, offset.y() + (ctrlHeight - pixmap_size.height())/2, pixmap_size.width(), pixmap_size.height()); + painter.clip(area); + painter.blit(pixmap_mDir, ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + } else { + int pflags = gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER; + eRect area = eRect(xoffs, offset.y(), m_itemheight, m_itemheight); + painter.clip(area); + painter.blitScale(pixmap_mDir, eRect(xoffs, offset.y(), m_itemheight, m_itemheight), area, pflags); + } + painter.clippop(); - if( m_cursor->getChannelNum() == 0 ) - continue; + painter.renderPara(paraServiceName, ePoint(xoffs + pixmap_size.width() + m_items_distances, offset.y() + ((ctrlHeight - bboxServiceName.height())/2))); - char buffer[15]; - snprintf(buffer, sizeof(buffer), "%d", m_cursor->getChannelNum() ); - text = buffer; - flags|=gPainter::RT_HALIGN_RIGHT; - if (isPlayable && serviceFallback && selected && m_color_set[serviceSelectedFallback]) - painter.setForegroundColor(m_color[serviceSelectedFallback]); - break; - } - case celServiceName: - { - if (service_info) - service_info->getName(*m_cursor, text); - if (!isPlayable) - { - area.setWidth(area.width() + m_element_position[celServiceEventProgressbar].width() + m_nonplayable_margins); - if (m_element_position[celServiceEventProgressbar].left() == 0) - area.setLeft(0); - if (m_element_position[celServiceNumber].width() && m_element_position[celServiceEventProgressbar].left() == m_element_position[celServiceNumber].width() + m_nonplayable_margins) - area.setLeft(m_element_position[celServiceNumber].width() + m_nonplayable_margins); - } - if (!(m_record_indicator_mode == 3 && isRecorded) && isPlayable && serviceFallback && selected && m_color_set[serviceSelectedFallback]) - painter.setForegroundColor(m_color[serviceSelectedFallback]); - if (!m_marker_alignment.empty() && m_marker_alignment == "center" && isMarker) { - ePtr paraName = new eTextPara(eRect(0, 0, m_itemsize.width(), m_itemheight/2)); - paraName->setFont(m_element_font[celServiceName]); - paraName->renderString(text.c_str()); - eRect bboxName = paraName->getBoundBox(); - xoffeset_marker = (m_itemsize.width() - bboxName.width()) / 2; - marker_text_width = bboxName.width(); - area.setLeft(xoffeset_marker); - area.setWidth(marker_text_width); - } - break; - } - case celServiceInfo: + } else if (isMarker && m_marker_as_line) { + int mTextLeft = (m_itemsize.width() - bboxServiceName.width())/2; + if (m_marker_alignment != "center") { + mTextLeft = 125 + m_items_distances; + } + painter.renderPara(paraServiceName, ePoint(mTextLeft, offset.y() + ((ctrlHeight - bboxServiceName.height())/2))); + + if (m_markerline_color_set) painter.setForegroundColor(m_markerline_color); + eRect firstLineRect = eRect(xoffs + m_items_distances, offset.y() + (m_itemheight - m_marker_as_line) / 2, mTextLeft - m_items_distances*2 - xoffs - 16, m_marker_as_line); + painter.fill(firstLineRect); + int secondLineOffset = mTextLeft + bboxServiceName.width() + m_items_distances + 16; + eRect secondLineRect = eRect(secondLineOffset, offset.y() + (m_itemheight - m_marker_as_line) / 2, m_itemsize.width() - secondLineOffset - m_items_distances - m_sides_margin, m_marker_as_line); + painter.fill(secondLineRect); + } + + if (!isDirectory && !isMarker) { + + ePtr paraCtrlText = new eTextPara(eRect(0, 0, m_itemsize.width(), m_itemheight)); + paraCtrlText->setFont(m_element_font[celServiceNumber]); + paraCtrlText->renderString((isAlternativeNumberingMode ? "0000" : "00000")); + eRect bboxCtrlText = paraCtrlText->getBoundBox(); + + if (hasChannelNumbers && m_cursor->getChannelNum() > 0) { + char buffer[15]; + snprintf(buffer, sizeof(buffer), "%d", m_cursor->getChannelNum() ); + std::string num = buffer; + ePtr para = new eTextPara(eRect(xoffs, 0, bboxCtrlText.width(), m_itemheight)); + para->setFont(m_element_font[celServiceNumber]); + para->renderString(num.c_str()); + eRect bbox = para->getBoundBox(); + painter.renderPara(para, ePoint(xoffs + (bboxCtrlText.width() - bbox.width()), offset.y() + (ctrlHeight - bbox.height())/2)); + xoffs += bboxCtrlText.width() + m_items_distances; + } + + eRect progressBarRect = m_element_position[celServiceEventProgressbar]; + + int pb_xpos = xoffs; + int pb_ypos = offset.y() + (m_itemheight - m_progressbar_height - 2 * m_progressbar_border_width) / 2; + int pb_width = progressBarRect.width() - 2 * m_progressbar_border_width; + gRGB ProgressbarBorderColor = 0xdfdfdf; + int evt_done = pb_width * (now - event_begin) / event_duration; + + if (eventProgressConfig == "barleft" || eventProgressConfig == "percleft") { + xoffs += progressBarRect.width() + m_items_distances; + } + + ePtr piconPixmap; + bool isPIconSVG = false; + int piconWidth = m_itemheight*1.67; + if (isPlayable && hasPicons) + { + ePyObject pArgs = PyTuple_New(1); + PyTuple_SET_ITEM(pArgs, 0, PyUnicode_FromString(ref.toString().c_str())); + ePyObject pRet = PyObject_CallObject(m_GetPiconNameFunc, pArgs); + Py_DECREF(pArgs); + if (pRet) { - if (!event_name.empty()) + if (PyUnicode_Check(pRet)) { - text = event_name; - std::replace(text.begin(), text.end(), '\n', ' '); - if (serviceAvail) - { - if (!selected && m_color_set[eventForeground]) - { - painter.setForegroundColor(m_color[eventForeground]); - EventProgressbarColor = m_color[eventForeground]; - } - else if (selected && m_color_set[eventForegroundSelected]) - { - painter.setForegroundColor(m_color[eventForegroundSelected]); - EventProgressbarColor = m_color[eventForegroundSelected]; - } - else - painter.setForegroundColor(gRGB(0xe7b53f)); - - if (serviceFallback && !selected && m_color_set[eventForegroundFallback]) // fallback receiver - { - painter.setForegroundColor(m_color[eventForegroundFallback]); - EventProgressbarColor = m_color[eventForegroundFallback]; - } - else if (serviceFallback && selected && m_color_set[eventForegroundSelectedFallback]) - { - painter.setForegroundColor(m_color[eventForegroundSelectedFallback]); - EventProgressbarColor = m_color[eventForegroundSelectedFallback]; - } + std::string piconFilename = PyUnicode_AsUTF8(pRet); + if (endsWith(piconFilename, ".svg")) { + isPIconSVG = true; } - break; + if (!piconFilename.empty()) + loadImage(piconPixmap, piconFilename.c_str(), 0, isPIconSVG ? piconWidth : 0); } - continue; + Py_DECREF(pRet); } - case celServiceNextInfo: - { - if (!next_event_name.empty()) - { - text = m_next_title + next_event_name; - std::replace(text.begin(), text.end(), '\n', ' '); - if (serviceAvail) - { - if (!selected && m_color_set[eventNextForeground]) - painter.setForegroundColor(m_color[eventNextForeground]); - else if (selected && m_color_set[eventNextForegroundSelected]) - painter.setForegroundColor(m_color[eventNextForegroundSelected]); - else - painter.setForegroundColor(gRGB(0x787878)); - - if (serviceFallback && !selected && m_color_set[eventNextForegroundFallback]) // fallback receiver - painter.setForegroundColor(m_color[eventNextForegroundFallback]); - else if (serviceFallback && selected && m_color_set[eventNextForegroundSelectedFallback]) - painter.setForegroundColor(m_color[eventNextForegroundSelectedFallback]); - } - break; - } - continue; + } + + if (hasPicons) { + eRect piconArea = eRect(xoffs, offset.y(), piconWidth, m_itemheight); + /* PIcons are usually about 100:60. Make it a + * bit wider in case the icons are diffently + * shaped, and to add a bit of margin between + * icon and text. */ + int pflags = gPainter::BT_ALPHABLEND | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER; + if (!isPIconSVG) { + pflags = gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER; } - case celServiceEventProgressbar: + if (piconPixmap) { - if (area.width() > 0 && is_event) - { - char buffer[15]; - snprintf(buffer, sizeof(buffer), "%d %%", (int)(100 * (now - event_begin) / event_duration)); - text = buffer; - flags|=gPainter::RT_HALIGN_RIGHT; - break; + painter.clip(piconArea); + if (isPIconSVG) { + painter.blit(piconPixmap, + eRect(xoffs, offset.y(), piconWidth, m_itemheight), + eRect(), + pflags + ); + } else { + painter.blitScale(piconPixmap, + eRect(xoffs, offset.y(), piconWidth, m_itemheight), + piconArea, + pflags); } - continue; - } + painter.clippop(); } + xoffs += piconWidth + m_items_distances; + } - eRect tmp = area; - int xoffs = 0; - ePtr piconPixmap; - bool isPIconSVG = false; - if (e == celServiceName) - { - //picon stuff - if (isPlayable && hasPicons) - { - ePyObject pArgs = PyTuple_New(1); - PyTuple_SET_ITEM(pArgs, 0, PyUnicode_FromString(ref.toString().c_str())); - ePyObject pRet = PyObject_CallObject(m_GetPiconNameFunc, pArgs); - Py_DECREF(pArgs); - if (pRet) - { - if (PyUnicode_Check(pRet)) - { - std::string piconFilename = PyUnicode_AsUTF8(pRet); - if (endsWith(toLower(piconFilename), ".svg")) { - isPIconSVG = true; - } - if (!piconFilename.empty()) { - loadImage(piconPixmap, piconFilename.c_str(), 0, isPIconSVG ? iconWidth : 0); - } - } - Py_DECREF(pRet); - } - } - xoffs = xoffset; - tmp.setWidth(((!isPlayable || m_column_width == -1 || (!piconPixmap && !m_column_width)) ? tmp.width() : m_column_width) - xoffs); - } + int orbpos = m_cursor->getUnsignedData(4) >> 16; + int iconSystemPosX = xoffs + m_items_distances; + int iconCryptoPosX = iconSystemPosX; + int iconRecordPosX = iconSystemPosX; + int iconOffsX = iconSystemPosX; + const char *filename = ref.path.c_str(); + ePtr &pixmap_system = + (m_cursor->flags & eServiceReference::isGroup) ? m_pixmaps[picServiceGroup] : + (strstr(filename, "://")) ? m_pixmaps[picStream] : + (orbpos == 0xFFFF) ? m_pixmaps[picDVB_C] : + (orbpos == 0xEEEE) ? m_pixmaps[picDVB_T] : m_pixmaps[picDVB_S]; - ePtr para = new eTextPara(tmp); - para->setFont(m_element_font[e]); - para->renderString(text.c_str()); + + eSize pixmap_system_size = eSize(); + eSize pixmap_crypto_size = eSize(); + eSize pixmap_rec_size = eSize(); + if (m_servicetype_icon_mode == 1 && pixmap_system) { + pixmap_system_size = pixmap_system->size(); + iconCryptoPosX += pixmap_system_size.width() + m_items_distances; + iconRecordPosX = iconCryptoPosX; + iconOffsX += pixmap_system_size.width() + m_items_distances; + } - if (e == celServiceName) - { - eRect bbox = para->getBoundBox(); - - int servicenameWidth = ((!isPlayable || m_column_width == -1 || (!piconPixmap && !m_column_width)) ? bbox.width() : m_column_width); - m_element_position[celServiceInfo].setLeft(area.left() + servicenameWidth + m_items_distances + xoffs); - m_element_position[celServiceInfo].setTop(area.top()); - m_element_position[celServiceInfo].setWidth(area.width() - (servicenameWidth + m_items_distances + xoffs)); - m_element_position[celServiceInfo].setHeight(area.height()); - if (!next_event_name.empty()) - m_element_position[celServiceNextInfo].setHeight(area.height()); - nameLeft = area.left(); - nameWidth = area.width(); - - if (isPlayable) - { - //picon stuff - if (hasPicons || isDirectory || (isMarker && !m_marker_as_line)) { - eRect area = m_element_position[celServiceInfo]; + + if (m_crypto_icon_mode == 1 && m_pixmaps[picCrypto]) { + pixmap_crypto_size = m_pixmaps[picCrypto]->size(); + iconRecordPosX += pixmap_crypto_size.width() + m_items_distances; + iconOffsX += pixmap_crypto_size.width() + m_items_distances; + } - iconWidth = area.height() * 9 / 5; + + if (isRecorded && m_record_indicator_mode == 1 && m_pixmaps[picRecord]) { + pixmap_rec_size = m_pixmaps[picRecord]->size(); + iconOffsX += pixmap_rec_size.width() + m_items_distances; + } - m_element_position[celServiceInfo].setLeft(area.left() + iconWidth + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - iconWidth - m_items_distances); + if (m_servicetype_icon_mode == 1 && pixmap_system) { + eRect area = eRect(iconSystemPosX, offset.y() + (ctrlHeight - pixmap_system_size.height())/2, pixmap_system_size.width(), pixmap_system_size.height()); + painter.clip(area); + painter.blit(pixmap_system, ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.clippop(); + } - xoffs += iconWidth + m_items_distances; - } - if (hasPicons && (m_column_width || piconPixmap)) - { - area = m_element_position[celServiceName]; - - if (piconPixmap) - { - - area.moveBy(offset); - painter.clip(area); - /* PIcons are usually about 100:60. Make it a - * bit wider in case the icons are diffently - * shaped, and to add a bit of margin between - * icon and text. */ - int pflags = gPainter::BT_ALPHABLEND | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER; - if (!isPIconSVG) { - pflags = gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER; - } - if (piconPixmap) - { - if (isPIconSVG) { - painter.blit(piconPixmap, - eRect(area.left(), area.top(), iconWidth, area.height()), - eRect(), - pflags - ); - } else { - painter.blitScale(piconPixmap, - eRect(area.left(), area.top(), iconWidth, area.height()), - area, - pflags); - } - } - painter.clippop(); - } - } + if (m_crypto_icon_mode == 1 && m_pixmaps[picCrypto] && service_info && service_info->isCrypted()) { + eRect area = eRect(iconCryptoPosX, offset.y() + (ctrlHeight - pixmap_crypto_size.height())/2, pixmap_crypto_size.width(), pixmap_crypto_size.height()); + painter.clip(area); + painter.blit(m_pixmaps[picCrypto], ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.clippop(); + } - //record icon stuff part1 - int rec_pixmap_xoffs = m_items_distances; - if (isRecorded && m_record_indicator_mode == 1 && m_pixmaps[picRecord]) - rec_pixmap_xoffs = m_pixmaps[picRecord]->size().width() + m_items_distances; - int serviceNameWidthCorr = 0; - //service type marker stuff - if (m_servicetype_icon_mode) - { - int orbpos = m_cursor->getUnsignedData(4) >> 16; - const char *filename = ref.path.c_str(); - ePtr &pixmap = - (m_cursor->flags & eServiceReference::isGroup) ? m_pixmaps[picServiceGroup] : - (strstr(filename, "://")) ? m_pixmaps[picStream] : - (orbpos == 0xFFFF) ? m_pixmaps[picDVB_C] : - (orbpos == 0xEEEE) ? m_pixmaps[picDVB_T] : m_pixmaps[picDVB_S]; - if (pixmap) - { - eSize pixmap_size = pixmap->size(); - eRect area = m_element_position[celServiceInfo]; - int offs = rec_pixmap_xoffs; - if (m_servicetype_icon_mode == 1) - { - m_element_position[celServiceInfo].setLeft(area.left() + offs + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - offs - m_items_distances * 2); - area = m_element_position[celServiceName]; - offs = xoffs; - xoffs += pixmap_size.width() + m_items_distances; - serviceNameWidthCorr = servicenameWidth + m_items_distances; - } - else if (m_crypto_icon_mode == 1 && m_pixmaps[picCrypto]) { - offs = offs + m_pixmaps[picCrypto]->size().width() + m_items_distances; - m_element_position[celServiceInfo].setLeft(area.left() + offs + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - offs - m_items_distances * 2); - serviceNameWidthCorr = servicenameWidth + m_items_distances; - } - if (m_servicetype_icon_mode == 2) { - m_element_position[celServiceInfo].setLeft(area.left() + offs + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - offs - m_items_distances * 2); - } - - int correction = (area.height() - pixmap_size.height()) / 2; - area.moveBy(offset); - painter.clip(area); - painter.blit(pixmap, ePoint(area.left() + offs, offset.y() + correction), area, gPainter::BT_ALPHABLEND); - painter.clippop(); - } - } - //crypto icon stuff - if (m_crypto_icon_mode && m_pixmaps[picCrypto]) - { - eSize pixmap_size = m_pixmaps[picCrypto]->size(); - eRect area = m_element_position[celServiceInfo]; - int offs = rec_pixmap_xoffs; - if (m_crypto_icon_mode == 1) - { - area = m_element_position[celServiceName]; - offs = xoffs; - xoffs += pixmap_size.width() + m_items_distances; - m_element_position[celServiceInfo].setLeft(area.left() + offs + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - offs - pixmap_size.width() - m_items_distances * 2); - serviceNameWidthCorr = servicenameWidth + m_items_distances; - } - int correction = (area.height() - pixmap_size.height()) / 2; - area.moveBy(offset); - if (service_info && service_info->isCrypted()) - { - if (m_crypto_icon_mode == 2) - { - m_element_position[celServiceInfo].setLeft(area.left() + offs + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - offs - m_items_distances * 2); - } - painter.clip(area); - painter.blit(m_pixmaps[picCrypto], ePoint(area.left() + offs, offset.y() + correction), area, gPainter::BT_ALPHABLEND); - painter.clippop(); - } - } + if (isRecorded && m_pixmaps[picRecord] && m_record_indicator_mode == 1) { + eRect area = eRect(iconRecordPosX, offset.y() + (ctrlHeight - pixmap_rec_size.height())/2, pixmap_rec_size.width(), pixmap_rec_size.height()); + painter.clip(area); + painter.blit(m_pixmaps[picRecord], ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.clippop(); + } - //record icon stuff part2 - if (isRecorded && m_record_indicator_mode < 3 && m_pixmaps[picRecord]) - { - eSize pixmap_size = m_pixmaps[picRecord]->size(); - eRect area = m_element_position[celServiceInfo]; - int offs = m_items_distances; - if (m_record_indicator_mode == 1) - { - area = m_element_position[celServiceName]; - offs = xoffs; - xoffs += pixmap_size.width() + m_items_distances; - m_element_position[celServiceInfo].setLeft(area.left() + offs + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - offs - pixmap_size.width() - m_items_distances * 2); - serviceNameWidthCorr = servicenameWidth + m_items_distances; - } - int correction = (area.height() - pixmap_size.height()) / 2; - area.moveBy(offset); - if (m_record_indicator_mode == 2) - { - m_element_position[celServiceInfo].setLeft(area.left() + offs + pixmap_size.width() + m_items_distances); - m_element_position[celServiceInfo].setWidth(area.width() - pixmap_size.width() - offs - m_items_distances * 2); - } - painter.clip(area); - painter.blit(m_pixmaps[picRecord], ePoint(area.left() + offs, offset.y() + correction), area, gPainter::BT_ALPHABLEND); - painter.clippop(); - } - m_element_position[celServiceInfo].setLeft(m_element_position[celServiceInfo].left() + serviceNameWidthCorr); - m_element_position[celServiceInfo].setWidth(m_element_position[celServiceInfo].width() - m_items_distances * (serviceNameWidthCorr > 0 ? 2 : 1) - m_sides_margin * 2); - } - } + xoffs = iconOffsX; - if (flags & gPainter::RT_HALIGN_RIGHT) - para->realign(eTextPara::dirRight); - else if (flags & gPainter::RT_HALIGN_CENTER) - para->realign(eTextPara::dirCenter); - else if (flags & gPainter::RT_HALIGN_BLOCK) - para->realign(eTextPara::dirBlock); + painter.renderPara(paraServiceName, ePoint(xoffs, offset.y() + (ctrlHeight - bboxServiceName.height())/2)); - if (flags & gPainter::RT_VALIGN_CENTER) - { - eRect bbox = para->getBoundBox(); - - if (!next_event_name.empty() && e == celServiceNextInfo) - yoffs = (e == celServiceNextInfo ? nextYoffs : (area.height()/2) + (((area.height()/2) - bbox.height()) / 2) - (bbox.top() - nameYoffs)); - else - yoffs = (area.height() - bbox.height())/2 - bbox.top(); - } + xoffs += bboxServiceName.width() + m_items_distances; - painter.renderPara(para, offset+ePoint(xoffs, yoffs)); + iconSystemPosX = xoffs + m_items_distances; + iconCryptoPosX = iconSystemPosX; + iconRecordPosX = iconSystemPosX; + iconOffsX = iconSystemPosX; + + if (m_servicetype_icon_mode == 2 && pixmap_system) { + pixmap_system_size = pixmap_system->size(); + iconCryptoPosX += pixmap_system_size.width() + m_items_distances; + iconRecordPosX = iconCryptoPosX; + iconOffsX += pixmap_system_size.width() + m_items_distances; + xoffs = iconOffsX; } - else if ((e == celFolderPixmap && m_cursor->flags & eServiceReference::isDirectory) || - (e == celMarkerPixmap && m_cursor->flags & eServiceReference::isMarker && - !(m_cursor->flags & eServiceReference::isNumberedMarker))) - { - ePtr &pixmap = - (e == celFolderPixmap) ? m_pixmaps[picFolder] : m_pixmaps[picMarker]; - if (pixmap && (isDirectory || (isMarker && !m_marker_as_line))) - { - eSize pixmap_size = pixmap->size(); - bool notScale = (e == celMarkerPixmap) && (pixmap_size.width() < 125 || pixmap_size.height() < m_itemheight); - eRect area; - if (e == celFolderPixmap || m_element_position[celServiceNumber].width() < m_itemheight) - { - area = m_element_position[celServiceName]; - if (m_element_position[celServiceEventProgressbar].left() == 0) - area.setLeft(0); - if (notScale) - xoffset = pixmap_size.width() + m_items_distances; - else - xoffset = m_itemheight + m_items_distances; - } - else - area = m_element_position[celServiceNumber]; - area.moveBy(offset); - painter.clip(area); - if (notScale) { - int correction = (area.height() - pixmap_size.height()) / 2; - painter.blit(pixmap, ePoint(area.left(), offset.y() + correction), area, gPainter::BT_ALPHABLEND); - } else { - painter.blitScale(pixmap, - eRect(area.left(), offset.y(), m_itemheight, area.height()), - area, - gPainter::BT_ALPHABLEND | gPainter::BT_KEEP_ASPECT_RATIO | gPainter::BT_HALIGN_CENTER | gPainter::BT_VALIGN_CENTER); - } - painter.clippop(); - } + + if (m_crypto_icon_mode == 2 && m_pixmaps[picCrypto] && service_info && service_info->isCrypted()) { + pixmap_crypto_size = m_pixmaps[picCrypto]->size(); + iconRecordPosX += pixmap_crypto_size.width() + m_items_distances; + iconOffsX += pixmap_crypto_size.width() + m_items_distances; + xoffs = iconOffsX; + } + + + if (isRecorded && m_record_indicator_mode == 2 && m_pixmaps[picRecord]) { + pixmap_rec_size = m_pixmaps[picRecord]->size(); + iconOffsX += pixmap_rec_size.width() + m_items_distances; + xoffs = iconOffsX; } - } - eRect area = m_element_position[celServiceEventProgressbar]; - if (area.width() > 0 && evt && !m_element_font[celServiceEventProgressbar]) - { - int pb_xpos = area.left(); - int pb_ypos = offset.y() + (m_itemsize.height() - m_progressbar_height - 2 * m_progressbar_border_width) / 2; - int pb_width = area.width()- 2 * m_progressbar_border_width; - gRGB ProgressbarBorderColor = 0xdfdfdf; - int evt_done = pb_width * (now - event_begin) / event_duration; - // the progress data... - eRect tmp = eRect(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width, evt_done, m_progressbar_height); - ePtr &pixmap = m_pixmaps[picServiceEventProgressbar]; - if (pixmap) { - painter.clip(tmp); - painter.blit(pixmap, ePoint(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width), tmp, gPainter::BT_ALPHATEST); + if (m_servicetype_icon_mode == 2 && pixmap_system) { + eRect area = eRect(iconSystemPosX, offset.y() + (ctrlHeight - pixmap_system_size.height())/2, pixmap_system_size.width(), pixmap_system_size.height()); + painter.clip(area); + painter.blit(pixmap_system, ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); painter.clippop(); } - else { - if (!selected && m_color_set[serviceEventProgressbarColor]) - painter.setForegroundColor(m_color[serviceEventProgressbarColor]); - else if (selected && m_color_set[serviceEventProgressbarColorSelected]) - painter.setForegroundColor(m_color[serviceEventProgressbarColorSelected]); - painter.fill(tmp); - } - // the progressbar border - if (!selected) { - if (m_color_set[serviceEventProgressbarBorderColor]) - ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColor]; - else if (m_color_set[eventborderForeground]) - ProgressbarBorderColor = m_color[eventborderForeground]; + + if (m_crypto_icon_mode == 2 && m_pixmaps[picCrypto] && service_info && service_info->isCrypted()) { + eRect area = eRect(iconCryptoPosX, offset.y() + (ctrlHeight - pixmap_crypto_size.height())/2, pixmap_crypto_size.width(), pixmap_crypto_size.height()); + painter.clip(area); + painter.blit(m_pixmaps[picCrypto], ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.clippop(); } - else { /* !selected */ - if (m_color_set[serviceEventProgressbarBorderColorSelected]) - ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColorSelected]; - else if (m_color_set[eventborderForegroundSelected]) - ProgressbarBorderColor = m_color[eventborderForegroundSelected]; + + + if (isRecorded && m_pixmaps[picRecord] && m_record_indicator_mode == 2) { + eRect area = eRect(iconRecordPosX, offset.y() + (ctrlHeight - pixmap_rec_size.height())/2, pixmap_rec_size.width(), pixmap_rec_size.height()); + painter.clip(area); + painter.blit(m_pixmaps[picRecord], ePoint(area.left(), area.top()), area, gPainter::BT_ALPHABLEND); + painter.clippop(); } - painter.setForegroundColor(ProgressbarBorderColor); - if (m_progressbar_border_width) - { - painter.fill(eRect(pb_xpos, pb_ypos, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); - painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width + m_progressbar_height, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); - painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); - painter.fill(eRect(pb_xpos + m_progressbar_border_width + pb_width, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); + if (eventProgressConfig == "barright" || eventProgressConfig == "percright") { + pb_xpos = m_itemsize.width() - progressBarRect.width() - m_items_distances*2 - m_sides_margin*2 - m_progressbar_border_width*2; } - else - painter.fill(eRect(pb_xpos + evt_done, pb_ypos, pb_width - evt_done, m_progressbar_height)); - } + if (is_event && !event_name.empty()) { + text = event_name; + std::replace(text.begin(), text.end(), '\n', ' '); + if (serviceAvail) + { + if (!selected && m_color_set[eventForeground]) + { + painter.setForegroundColor(m_color[eventForeground]); + EventProgressbarColor = m_color[eventForeground]; + } + else if (selected && m_color_set[eventForegroundSelected]) + { + painter.setForegroundColor(m_color[eventForegroundSelected]); + EventProgressbarColor = m_color[eventForegroundSelected]; + } + else + painter.setForegroundColor(gRGB(0xe7b53f)); - if (isMarker && m_marker_as_line) { - if (m_markerline_color_set) painter.setForegroundColor(m_markerline_color); - eRect firstLineRect = eRect(m_sides_margin + xoffset + 16, offset.y() + (m_itemheight - m_marker_as_line) / 2, xoffeset_marker - 16 - 16 - m_sides_margin - xoffset, m_marker_as_line); - painter.fill(firstLineRect); - int secondLineOffset = xoffeset_marker + marker_text_width + 16; - eRect secondLineRect = eRect(secondLineOffset, offset.y() + (m_itemheight - m_marker_as_line) / 2, m_itemsize.width() - secondLineOffset - m_sides_margin - 16, m_marker_as_line); - painter.fill(secondLineRect); + if (serviceFallback && !selected && m_color_set[eventForegroundFallback]) // fallback receiver + { + painter.setForegroundColor(m_color[eventForegroundFallback]); + EventProgressbarColor = m_color[eventForegroundFallback]; + } + else if (serviceFallback && selected && m_color_set[eventForegroundSelectedFallback]) + { + painter.setForegroundColor(m_color[eventForegroundSelectedFallback]); + EventProgressbarColor = m_color[eventForegroundSelectedFallback]; + } + } + + int eventTextWidth = (eventProgressConfig == "barright" || eventProgressConfig == "percright") ? + (pb_xpos - xoffs - m_items_distances*2 ) : (m_itemsize.width() - m_sides_margin*2 - xoffs - m_items_distances*2); + + ePtr para = new eTextPara(eRect(0, 0, eventTextWidth, m_itemheight)); + para->setFont(m_element_font[celServiceInfo]); + para->renderString(text.c_str()); + eRect bbox = para->getBoundBox(); + painter.renderPara(para, ePoint(xoffs, offset.y() + (m_itemheight - bbox.height())/2)); + + if (eventProgressConfig != "no" && !startsWith(eventProgressConfig, "perc")) { + // the progress data... + eRect tmp = eRect(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width, evt_done, m_progressbar_height); + ePtr &pixmap = m_pixmaps[picServiceEventProgressbar]; + if (pixmap) { + painter.clip(tmp); + painter.blit(pixmap, ePoint(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width), tmp, gPainter::BT_ALPHABLEND); + painter.clippop(); + } + else { + if (!selected && m_color_set[serviceEventProgressbarColor]) + painter.setForegroundColor(m_color[serviceEventProgressbarColor]); + else if (selected && m_color_set[serviceEventProgressbarColorSelected]) + painter.setForegroundColor(m_color[serviceEventProgressbarColorSelected]); + painter.fill(tmp); + } + + // the progressbar border + if (!selected) { + if (m_color_set[serviceEventProgressbarBorderColor]) + ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColor]; + else if (m_color_set[eventborderForeground]) + ProgressbarBorderColor = m_color[eventborderForeground]; + } + else { /* !selected */ + if (m_color_set[serviceEventProgressbarBorderColorSelected]) + ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColorSelected]; + else if (m_color_set[eventborderForegroundSelected]) + ProgressbarBorderColor = m_color[eventborderForegroundSelected]; + } + painter.setForegroundColor(ProgressbarBorderColor); + + if (m_progressbar_border_width) + { + painter.fill(eRect(pb_xpos, pb_ypos, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); + painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width + m_progressbar_height, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); + painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); + painter.fill(eRect(pb_xpos + m_progressbar_border_width + pb_width, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); + } + else + painter.fill(eRect(pb_xpos + evt_done, pb_ypos, pb_width - evt_done, m_progressbar_height)); + } + if (startsWith(eventProgressConfig, "perc") && is_event) { + if (!selected && m_color_set[eventForeground]) + painter.setForegroundColor(m_color[eventForeground]); + else if (selected && m_color_set[eventForegroundSelected]) + painter.setForegroundColor(m_color[eventForegroundSelected]); + else + painter.setForegroundColor(gRGB(0x787878)); + + if (isRecorded && m_record_indicator_mode == 3) { + painter.setForegroundColor(m_color[serviceRecorded]); + } + + char buffer[15]; + snprintf(buffer, sizeof(buffer), "%d %%", (int)(100 * (now - event_begin) / event_duration)); + std::string percent = buffer; + ePtr paraPerc = new eTextPara(eRect(pb_xpos, 0, progressBarRect.width(), m_itemheight)); + paraPerc->setFont(m_element_font[celServiceInfo]); + paraPerc->renderString(percent.c_str()); + eRect bboxPerc = paraPerc->getBoundBox(); + painter.renderPara(paraPerc, ePoint((progressBarRect.width() - bboxPerc.width())/(eventProgressConfig == "percright" ? 1 : 2), offset.y() + (ctrlHeight - bboxPerc.height())/2)); + } + } } } } painter.clippop(); -} +} \ No newline at end of file diff --git a/lib/service/listboxservice.h b/lib/service/listboxservice.h index 7a10dd807c1..d2f03c9c25d 100644 --- a/lib/service/listboxservice.h +++ b/lib/service/listboxservice.h @@ -106,10 +106,13 @@ class eListboxServiceContent: public virtual iListboxContent void setItemsDistances(int value) { m_items_distances = value; } void setSidesMargin(int value) { m_sides_margin = value; } void setMarkerAsLine(int value) { m_marker_as_line = value; } + void setChannelNumbersVisible(bool visible) { m_chanel_number_visible = visible; } + void setAlternativeNumberingMode(bool b) { m_alternative_numbering = b; } + void setProgressBarMode(std::string s) { m_progress_mode = s; } void setTextSeparator(const std::string &string) { m_separator = string; } void setMarkerTextAlignment(const std::string &string) { m_marker_alignment = string; } // currently supports left and center - void setMarkerLineColor(const gRGB &col) { + void setMarkerLineColor(const gRGB &col) { m_markerline_color = col; m_markerline_color_set = 1; } @@ -198,6 +201,8 @@ class eListboxServiceContent: public virtual iListboxContent int m_itemheight; bool m_hide_number_marker; + bool m_chanel_number_visible; + bool m_alternative_numbering; int m_servicetype_icon_mode; int m_crypto_icon_mode; int m_record_indicator_mode; @@ -214,6 +219,7 @@ class eListboxServiceContent: public virtual iListboxContent std::string m_next_title; std::string m_separator; std::string m_marker_alignment; + std::string m_progress_mode; }; #endif From b0942c3492fa21d5268cb60c77f41c7002fb1436 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Mon, 27 Nov 2023 17:02:15 +0200 Subject: [PATCH 265/401] [Fixed] cleanup unused variable. --- lib/python/Components/ServiceList.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 7e54020ff87..d7e29fa3801 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -503,8 +503,6 @@ def setMode(self, mode): else: self.l.setGetPiconNameFunc(None) - rowWidth = self.instance.size().width() - 30 # scrollbar is fixed 20 + 10 Extra marge - progressWidth = self.progressBarWidth if "perc" in config.usage.show_event_progress_in_servicelist.value: progressWidth = self.progressPercentWidth or self.progressBarWidth From ddac87a56bce2993b56197ee376e412dd5d90e12 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Mon, 27 Nov 2023 18:56:36 +0000 Subject: [PATCH 266/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Components/ServiceList.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index d7e29fa3801..e320cedf34d 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -487,7 +487,7 @@ def setMode(self, mode): two_lines_val = int(config.usage.servicelist_twolines.value) self.l.setItemHeight(self.ItemHeight if two_lines_val == 0 else self.ItemHeightTwoLine) self.l.setVisualMode(eListboxServiceContent.visModeComplex if two_lines_val == 0 else eListboxServiceContent.visSkinDefined) - + pic = None if two_lines_val: if self.selectionPixmapDouble: @@ -495,7 +495,7 @@ def setMode(self, mode): else: if self.selectionPixmapSingle: pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, self.selectionPixmapSingle)) - + pic and hasattr(self.l, "setSelectionPicture") and self.l.setSelectionPicture(pic) if config.usage.service_icon_enable.value: From 5052871b76586962940a68c35b0760c9ca7d131e Mon Sep 17 00:00:00 2001 From: Ev0-BH Date: Sun, 26 Nov 2023 23:51:47 +0000 Subject: [PATCH 267/401] [Nav] update SR delay --- data/setup.xml | 6 +++--- lib/python/Components/UsageConfig.py | 2 +- lib/python/Navigation.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/data/setup.xml b/data/setup.xml index 59bc420dd5f..8e1aa3107b2 100644 --- a/data/setup.xml +++ b/data/setup.xml @@ -22,9 +22,9 @@ config.streaming.stream_ecm config.streaming.descramble config.streaming.descramble_client - config.misc.softcam_streamrelay_url - config.misc.softcam_streamrelay_port - config.misc.softcam_streamrelay_delay + config.misc.softcam_streamrelay_url + config.misc.softcam_streamrelay_port + config.misc.softcam_streamrelay_delay config.streaming.authentication config.usage.http_startdelay config.usage.wakeOnLAN diff --git a/lib/python/Components/UsageConfig.py b/lib/python/Components/UsageConfig.py index a52a5649d75..c7edd38bfaf 100644 --- a/lib/python/Components/UsageConfig.py +++ b/lib/python/Components/UsageConfig.py @@ -1139,7 +1139,7 @@ def setEpgLanguageAlternative(configElement): ("s", _("Restart softcam"))]) config.misc.softcam_streamrelay_url = ConfigIP(default=[127, 0, 0, 1], auto_jump=True) config.misc.softcam_streamrelay_port = ConfigInteger(default=17999, limits=(0, 65535)) - config.misc.softcam_streamrelay_delay = ConfigSelectionNumber(min=50, max=2000, stepwidth=50, default=100, wraparound=True) + config.misc.softcam_streamrelay_delay = ConfigSelectionNumber(min=0, max=2000, stepwidth=50, default=100, wraparound=True) SystemInfo["OScamInstalled"] = False config.cccaminfo = ConfigSubsection() diff --git a/lib/python/Navigation.py b/lib/python/Navigation.py index 6871fa87f3e..39370253f83 100644 --- a/lib/python/Navigation.py +++ b/lib/python/Navigation.py @@ -214,7 +214,7 @@ def playService(self, ref, checkParentalControl=True, forceRestart=False, adjust if config.usage.frontend_priority_dvbs.value != config.usage.frontend_priority.value: setPreferredTuner(int(config.usage.frontend_priority_dvbs.value)) setPriorityFrontend = True - if self.currentServiceStreaming and not fromTimer: + if config.misc.softcam_streamrelay_delay.value and self.currentServiceStreaming and not fromTimer: self.currentServiceStreaming = False self.currentlyPlayingServiceReference = None self.currentlyPlayingServiceOrGroup = None From ef246bf71c34d9b40d05b091b456e66e91d23cdb Mon Sep 17 00:00:00 2001 From: openvix-build Date: Mon, 27 Nov 2023 21:45:12 +0000 Subject: [PATCH 268/401] openvix: developer 6.4.010.012 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 30900d0eb26..4f3f458368e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1210,3 +1210,4 @@ openvix: developer 6.4.010.008 openvix: developer 6.4.010.009 openvix: developer 6.4.010.010 openvix: developer 6.4.010.011 +openvix: developer 6.4.010.012 From 8ec9cafe062ac344f979088c317b2f8ea6be9a40 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Tue, 28 Nov 2023 11:56:43 +0200 Subject: [PATCH 269/401] [Added] ScreenHeader addon --- lib/python/Components/Addons/ScreenHeader.py | 101 +++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 lib/python/Components/Addons/ScreenHeader.py diff --git a/lib/python/Components/Addons/ScreenHeader.py b/lib/python/Components/Addons/ScreenHeader.py new file mode 100644 index 00000000000..135aef6884c --- /dev/null +++ b/lib/python/Components/Addons/ScreenHeader.py @@ -0,0 +1,101 @@ +from Components.Addons.GUIAddon import GUIAddon + +from enigma import eListbox, eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT, RT_VALIGN_CENTER + +from skin import applySkinFactor, parseFont, parseColor + +from Components.MultiContent import MultiContentEntryText +from Components.Sources.StaticText import StaticText + + + +class ScreenHeader(GUIAddon): + def __init__(self): + GUIAddon.__init__(self) + self.l = eListboxPythonMultiContent() # noqa: E741 + self.l.setBuildFunc(self.buildEntry) + self.l.setItemHeight(36) + self.l.setItemWidth(36) + self.orientation = eListbox.orHorizontal + self.titleFont = gFont("Regular", applySkinFactor(22)) + self.titleSingleFont = gFont("Regular", applySkinFactor(24)) + self.pathFont = gFont("Regular", applySkinFactor(16)) + self.titleForeground = 0xffffff + self.pathForeground = 0xffffff + self.backgroundColor = 0x000000 + + def onContainerShown(self): + for x, val in self.sources.items(): + if self.constructTitleItem not in val.onChanged: + val.onChanged.append(self.constructTitleItem) + self.l.setItemHeight(self.instance.size().height()) + self.l.setItemWidth(self.instance.size().width()) + self.constructTitleItem() + + GUI_WIDGET = eListbox + + def updateAddon(self, sequence): + l_list = [] + l_list.append((sequence,)) + self.l.setList(l_list) + + def buildEntry(self, sequence): + yPos = 0 + + res = [None] + isOneItem = len(sequence) == 1 + + for idx, x in enumerate(sequence): + foreColor = self.titleForeground if idx == 0 else self.pathForeground + if isOneItem: + itemHeight = self.instance.size().height() + if not isOneItem and idx == 0: + itemHeight = self.instance.size().height()*2 // 3 + elif idx == 1: + yPos = self.instance.size().height()*2 // 3 - 3 + itemHeight = self.instance.size().height() // 3 + res.append(MultiContentEntryText( + pos=(0, yPos), + size=(self.instance.size().width(), itemHeight), + font=2 if isOneItem and idx == 0 else idx, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, + text=x.text, + color=foreColor, color_sel=foreColor, + backcolor=self.backgroundColor, backcolor_sel=self.backgroundColor)) + return res + + def postWidgetCreate(self, instance): + instance.setSelectionEnable(False) + instance.setContent(self.l) + instance.allowNativeKeys(False) + + def constructTitleItem(self): + sequence = [] + for x, val in self.sources.items(): + if isinstance(val, StaticText) and val.text: + if val not in sequence: + sequence.append(val) + + self.updateAddon(sequence) + + def applySkin(self, desktop, parent): + attribs = [] + for (attrib, value) in self.skinAttributes[:]: + if attrib == "titleFont": + self.titleFont = parseFont(value, ((1, 1), (1, 1))) + if attrib == "titleSingleFont": + self.titleSingleFont = parseFont(value, ((1, 1), (1, 1))) + elif attrib == "pathFont": + self.pathFont = parseFont(value, ((1, 1), (1, 1))) + elif attrib == "titleForegroundColor": + self.titleForeground = parseColor(value).argb() + elif attrib == "pathForegroundColor": + self.pathForeground = parseColor(value).argb() + elif attrib == "backgroundColor": + self.backgroundColor = parseColor(value).argb() + else: + attribs.append((attrib, value)) + self.skinAttributes = attribs + self.l.setFont(0, self.titleFont) + self.l.setFont(1, self.pathFont) + self.l.setFont(2, self.titleSingleFont) + return GUIAddon.applySkin(self, desktop, parent) From 912033bf619f227036bfe48a9a6f94a96f45e29c Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Tue, 28 Nov 2023 10:39:40 +0000 Subject: [PATCH 270/401] PEP8 double aggressive E22, E224, E241, E242 and E27 --- lib/python/Components/Addons/ScreenHeader.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Components/Addons/ScreenHeader.py b/lib/python/Components/Addons/ScreenHeader.py index 135aef6884c..abb3d1c5eb6 100644 --- a/lib/python/Components/Addons/ScreenHeader.py +++ b/lib/python/Components/Addons/ScreenHeader.py @@ -50,9 +50,9 @@ def buildEntry(self, sequence): if isOneItem: itemHeight = self.instance.size().height() if not isOneItem and idx == 0: - itemHeight = self.instance.size().height()*2 // 3 + itemHeight = self.instance.size().height() * 2 // 3 elif idx == 1: - yPos = self.instance.size().height()*2 // 3 - 3 + yPos = self.instance.size().height() * 2 // 3 - 3 itemHeight = self.instance.size().height() // 3 res.append(MultiContentEntryText( pos=(0, yPos), From 5f7b6017b5f8ff8f0d49e949649128d6a049180d Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Tue, 28 Nov 2023 10:40:07 +0000 Subject: [PATCH 271/401] PEP8 double aggressive E301 ~ E306 --- lib/python/Components/Addons/ScreenHeader.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/python/Components/Addons/ScreenHeader.py b/lib/python/Components/Addons/ScreenHeader.py index abb3d1c5eb6..13534975c8f 100644 --- a/lib/python/Components/Addons/ScreenHeader.py +++ b/lib/python/Components/Addons/ScreenHeader.py @@ -8,7 +8,6 @@ from Components.Sources.StaticText import StaticText - class ScreenHeader(GUIAddon): def __init__(self): GUIAddon.__init__(self) From 8a0f52bceacfb14ad31c6dd88f4105d16879d7e9 Mon Sep 17 00:00:00 2001 From: openvix-build Date: Tue, 28 Nov 2023 21:42:43 +0000 Subject: [PATCH 272/401] openvix: developer 6.4.010.013 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 4f3f458368e..81b34c14c7d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1211,3 +1211,4 @@ openvix: developer 6.4.010.009 openvix: developer 6.4.010.010 openvix: developer 6.4.010.011 openvix: developer 6.4.010.012 +openvix: developer 6.4.010.013 From dcc96c22149b47faded63a9d2190e99e367d9f3c Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 29 Nov 2023 02:54:22 +0100 Subject: [PATCH 273/401] [MultiPixmap] add handling for widget size when calling skin.loadPixmap Without this svg graphics will be loaded at the size of the viewport, not the widget. --- lib/python/Components/Pixmap.py | 37 +++++++++++++-------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/lib/python/Components/Pixmap.py b/lib/python/Components/Pixmap.py index b636eb5dedf..cbda6030425 100644 --- a/lib/python/Components/Pixmap.py +++ b/lib/python/Components/Pixmap.py @@ -143,9 +143,11 @@ def doMove(self): class MultiPixmap(Pixmap): def __init__(self): Pixmap.__init__(self) + self.pixmapfiles = [] self.pixmaps = [] def applySkin(self, desktop, screen): + self.desktop = desktop if self.skinAttributes is not None: skin_path_prefix = getattr(screen, "skin_path", path) pixmap = None @@ -154,29 +156,16 @@ def applySkin(self, desktop, screen): if attrib == "pixmaps": pixmaps = value.split(',') for p in pixmaps: - pngfile = "" - if fileExists(resolveFilename(SCOPE_CURRENT_SKIN, p, path_prefix=skin_path_prefix)): - pngfile = resolveFilename(SCOPE_CURRENT_SKIN, p, path_prefix=skin_path_prefix) - elif fileExists(resolveFilename(SCOPE_SKIN_IMAGE, p, path_prefix=skin_path_prefix)): - pngfile = resolveFilename(SCOPE_SKIN_IMAGE, p, path_prefix=skin_path_prefix) - elif fileExists(resolveFilename(SCOPE_ACTIVE_LCDSKIN, p, path_prefix=skin_path_prefix)): - pngfile = resolveFilename(SCOPE_ACTIVE_LCDSKIN, p, path_prefix=skin_path_prefix) - if path.exists(pngfile): - self.pixmaps.append(loadPixmap(pngfile, desktop)) + if fileExists(pngfile := resolveFilename(SCOPE_CURRENT_SKIN, p, path_prefix=skin_path_prefix)) or fileExists(pngfile := resolveFilename(SCOPE_SKIN_IMAGE, p, path_prefix=skin_path_prefix)) or fileExists(pngfile := resolveFilename(SCOPE_ACTIVE_LCDSKIN, p, path_prefix=skin_path_prefix)): + self.pixmapfiles.append(pngfile) + else: + print("[MultiPixmap] file not exists", p) if not pixmap: - if fileExists(resolveFilename(SCOPE_CURRENT_SKIN, pixmaps[0], path_prefix=skin_path_prefix)): - pixmap = resolveFilename(SCOPE_CURRENT_SKIN, pixmaps[0], path_prefix=skin_path_prefix) - elif fileExists(resolveFilename(SCOPE_SKIN_IMAGE, pixmaps[0], path_prefix=skin_path_prefix)): - pixmap = resolveFilename(SCOPE_SKIN_IMAGE, pixmaps[0], path_prefix=skin_path_prefix) - elif fileExists(resolveFilename(SCOPE_ACTIVE_LCDSKIN, pixmaps[0], path_prefix=skin_path_prefix)): - pixmap = resolveFilename(SCOPE_ACTIVE_LCDSKIN, pixmaps[0], path_prefix=skin_path_prefix) + if fileExists(pngfile := resolveFilename(SCOPE_CURRENT_SKIN, pixmaps[0], path_prefix=skin_path_prefix)) or fileExists(pngfile := resolveFilename(SCOPE_SKIN_IMAGE, pixmaps[0], path_prefix=skin_path_prefix)) or fileExists(pngfile := resolveFilename(SCOPE_ACTIVE_LCDSKIN, pixmaps[0], path_prefix=skin_path_prefix)): + pixmap = pngfile elif attrib == "pixmap": - if fileExists(resolveFilename(SCOPE_CURRENT_SKIN, value, path_prefix=skin_path_prefix)): - pixmap = resolveFilename(SCOPE_CURRENT_SKIN, value, path_prefix=skin_path_prefix) - elif fileExists(resolveFilename(SCOPE_SKIN_IMAGE, value, path_prefix=skin_path_prefix)): - pixmap = resolveFilename(SCOPE_SKIN_IMAGE, value, path_prefix=skin_path_prefix) - elif fileExists(resolveFilename(SCOPE_ACTIVE_LCDSKIN, value, path_prefix=skin_path_prefix)): - pixmap = resolveFilename(SCOPE_ACTIVE_LCDSKIN, value, path_prefix=skin_path_prefix) + if fileExists(pngfile := resolveFilename(SCOPE_CURRENT_SKIN, value, path_prefix=skin_path_prefix)) or fileExists(pngfile := resolveFilename(SCOPE_SKIN_IMAGE, value, path_prefix=skin_path_prefix)) or fileExists(pngfile := resolveFilename(SCOPE_ACTIVE_LCDSKIN, value, path_prefix=skin_path_prefix)): + pixmap = pngfile else: attribs.append((attrib, value)) if pixmap: @@ -186,7 +175,11 @@ def applySkin(self, desktop, screen): def setPixmapNum(self, x): if self.instance: + if not self.pixmaps and self.pixmapfiles: + width, height = self.getSize() + for file in self.pixmapfiles: + self.pixmaps.append(loadPixmap(file, self.desktop, width, height)) if len(self.pixmaps) > x: self.instance.setPixmap(self.pixmaps[x]) else: - print("[Pixmap] setPixmapNum(%d) failed! defined pixmaps:" % x, self.pixmaps) + print("[MultiPixmap] setPixmapNum(%d) failed! defined pixmaps:" % x, self.pixmaps) From 64fee3cb3028e9013a9864ad1d9876b74cacaf68 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Wed, 29 Nov 2023 01:56:27 +0000 Subject: [PATCH 274/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Components/Pixmap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/Pixmap.py b/lib/python/Components/Pixmap.py index cbda6030425..facfec148e2 100644 --- a/lib/python/Components/Pixmap.py +++ b/lib/python/Components/Pixmap.py @@ -159,7 +159,7 @@ def applySkin(self, desktop, screen): if fileExists(pngfile := resolveFilename(SCOPE_CURRENT_SKIN, p, path_prefix=skin_path_prefix)) or fileExists(pngfile := resolveFilename(SCOPE_SKIN_IMAGE, p, path_prefix=skin_path_prefix)) or fileExists(pngfile := resolveFilename(SCOPE_ACTIVE_LCDSKIN, p, path_prefix=skin_path_prefix)): self.pixmapfiles.append(pngfile) else: - print("[MultiPixmap] file not exists", p) + print("[MultiPixmap] file not exists", p) if not pixmap: if fileExists(pngfile := resolveFilename(SCOPE_CURRENT_SKIN, pixmaps[0], path_prefix=skin_path_prefix)) or fileExists(pngfile := resolveFilename(SCOPE_SKIN_IMAGE, pixmaps[0], path_prefix=skin_path_prefix)) or fileExists(pngfile := resolveFilename(SCOPE_ACTIVE_LCDSKIN, pixmaps[0], path_prefix=skin_path_prefix)): pixmap = pngfile From d7bb3eba405f49e6ebaea90c7aeeabae66847802 Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 29 Nov 2023 11:32:03 +0100 Subject: [PATCH 275/401] [MultiPixmap] simplify --- lib/python/Components/Pixmap.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/lib/python/Components/Pixmap.py b/lib/python/Components/Pixmap.py index facfec148e2..14b0bfc71dd 100644 --- a/lib/python/Components/Pixmap.py +++ b/lib/python/Components/Pixmap.py @@ -155,16 +155,11 @@ def applySkin(self, desktop, screen): for (attrib, value) in self.skinAttributes: if attrib == "pixmaps": pixmaps = value.split(',') - for p in pixmaps: - if fileExists(pngfile := resolveFilename(SCOPE_CURRENT_SKIN, p, path_prefix=skin_path_prefix)) or fileExists(pngfile := resolveFilename(SCOPE_SKIN_IMAGE, p, path_prefix=skin_path_prefix)) or fileExists(pngfile := resolveFilename(SCOPE_ACTIVE_LCDSKIN, p, path_prefix=skin_path_prefix)): - self.pixmapfiles.append(pngfile) - else: - print("[MultiPixmap] file not exists", p) - if not pixmap: - if fileExists(pngfile := resolveFilename(SCOPE_CURRENT_SKIN, pixmaps[0], path_prefix=skin_path_prefix)) or fileExists(pngfile := resolveFilename(SCOPE_SKIN_IMAGE, pixmaps[0], path_prefix=skin_path_prefix)) or fileExists(pngfile := resolveFilename(SCOPE_ACTIVE_LCDSKIN, pixmaps[0], path_prefix=skin_path_prefix)): - pixmap = pngfile + self.pixmapfiles = [pngfile for p in pixmaps if (pngfile := self.checkPaths(p.strip(), skin_path_prefix))] + if not pixmap and self.pixmapfiles: + pixmap = self.pixmapfiles[0] elif attrib == "pixmap": - if fileExists(pngfile := resolveFilename(SCOPE_CURRENT_SKIN, value, path_prefix=skin_path_prefix)) or fileExists(pngfile := resolveFilename(SCOPE_SKIN_IMAGE, value, path_prefix=skin_path_prefix)) or fileExists(pngfile := resolveFilename(SCOPE_ACTIVE_LCDSKIN, value, path_prefix=skin_path_prefix)): + if (pngfile := self.checkPaths(value, skin_path_prefix)): pixmap = pngfile else: attribs.append((attrib, value)) @@ -173,6 +168,9 @@ def applySkin(self, desktop, screen): self.skinAttributes = attribs return GUIComponent.applySkin(self, desktop, screen) + def checkPaths(self, value, skin_path_prefix): + return (fileExists(pngfile := resolveFilename(SCOPE_CURRENT_SKIN, value, path_prefix=skin_path_prefix)) or fileExists(pngfile := resolveFilename(SCOPE_SKIN_IMAGE, value, path_prefix=skin_path_prefix)) or fileExists(pngfile := resolveFilename(SCOPE_ACTIVE_LCDSKIN, value, path_prefix=skin_path_prefix))) and pngfile + def setPixmapNum(self, x): if self.instance: if not self.pixmaps and self.pixmapfiles: From 2c36f656b98b6d6807e13719835a7e60d2ec9b38 Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 29 Nov 2023 12:27:10 +0100 Subject: [PATCH 276/401] [MultiPixmap] remove SKOPE_SKIN_IMAGE lookup This path is already handled by SCOPE_CURRENT_SKIN --- lib/python/Components/Pixmap.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Components/Pixmap.py b/lib/python/Components/Pixmap.py index 14b0bfc71dd..fbb55fb9c5e 100644 --- a/lib/python/Components/Pixmap.py +++ b/lib/python/Components/Pixmap.py @@ -4,7 +4,7 @@ from Components.ConditionalWidget import ConditionalWidget from Components.GUIComponent import GUIComponent -from Tools.Directories import resolveFilename, fileExists, SCOPE_SKIN_IMAGE, SCOPE_CURRENT_SKIN, SCOPE_ACTIVE_LCDSKIN +from Tools.Directories import resolveFilename, fileExists, SCOPE_CURRENT_SKIN, SCOPE_ACTIVE_LCDSKIN from skin import loadPixmap @@ -169,7 +169,7 @@ def applySkin(self, desktop, screen): return GUIComponent.applySkin(self, desktop, screen) def checkPaths(self, value, skin_path_prefix): - return (fileExists(pngfile := resolveFilename(SCOPE_CURRENT_SKIN, value, path_prefix=skin_path_prefix)) or fileExists(pngfile := resolveFilename(SCOPE_SKIN_IMAGE, value, path_prefix=skin_path_prefix)) or fileExists(pngfile := resolveFilename(SCOPE_ACTIVE_LCDSKIN, value, path_prefix=skin_path_prefix))) and pngfile + return (fileExists(pngfile := resolveFilename(SCOPE_CURRENT_SKIN, value, path_prefix=skin_path_prefix)) or fileExists(pngfile := resolveFilename(SCOPE_ACTIVE_LCDSKIN, value, path_prefix=skin_path_prefix))) and pngfile def setPixmapNum(self, x): if self.instance: From 019b9a616df92dbd81ff409059c5d9b14ed1227c Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Wed, 29 Nov 2023 13:35:37 +0200 Subject: [PATCH 277/401] [Fixed] overlapping variables in PLi --- lib/dvb/pmt.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index 3dcb228f2fb..fb7ea7e254e 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -962,9 +962,9 @@ int eDVBServicePMTHandler::tuneExt(eServiceReferenceDVB &ref, ePtr &s // If is stream relay service then allocate the real channel so to provide correct frontend info eDVBChannelID chid; eServiceReferenceDVB sRelayOrigSref; - bool res = ref.getSROriginal(sRelayOrigSref); + bool isStreamRelay = ref.getSROriginal(sRelayOrigSref); - if (res) { + if (isStreamRelay) { sRelayOrigSref.getChannelID(chid); res = m_resourceManager->allocateChannel(chid, m_sr_channel, simulate); } From 5b8148a15d892ed6cfe49d4ad38b10852cae1047 Mon Sep 17 00:00:00 2001 From: Huevos Date: Thu, 30 Nov 2023 10:16:21 +0100 Subject: [PATCH 278/401] [Navigation] simplify streamrelay shutdown timer --- lib/python/Navigation.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lib/python/Navigation.py b/lib/python/Navigation.py index 39370253f83..9e28db9f4d0 100644 --- a/lib/python/Navigation.py +++ b/lib/python/Navigation.py @@ -15,7 +15,7 @@ import NavigationInstance from Screens.InfoBar import InfoBar from Components.Sources.StreamService import StreamServiceList -from Screens.InfoBarGenerics import streamrelayChecker +from Screens.InfoBarGenerics import streamrelayChecker, whitelist # TODO: remove pNavgation, eNavigation and rewrite this stuff in python. @@ -39,7 +39,7 @@ def __init__(self, nextRecordTimerAfterEventActionAuto=False, nextPowerManagerAf self.currentlyPlayingServiceReference = None self.currentlyPlayingServiceOrGroup = None self.currentlyPlayingService = None - self.currentServiceStreaming = False + self.currentServiceIsStreamRelay = False self.skipServiceReferenceReset = False self.RecordTimer = RecordTimer.RecordTimer() self.PowerTimer = PowerTimer.PowerTimer() @@ -115,7 +115,7 @@ def dispatchRecordEvent(self, rec_service, event): def restartService(self): self.playService(self.currentlyPlayingServiceOrGroup, forceRestart=True) - def playService(self, ref, checkParentalControl=True, forceRestart=False, adjust=True, fromTimer=False): + def playService(self, ref, checkParentalControl=True, forceRestart=False, adjust=True): oldref = self.currentlyPlayingServiceOrGroup if ref and oldref and ref == oldref and not forceRestart: print("[Navigation] ignore request to play already running service(1)") @@ -214,13 +214,13 @@ def playService(self, ref, checkParentalControl=True, forceRestart=False, adjust if config.usage.frontend_priority_dvbs.value != config.usage.frontend_priority.value: setPreferredTuner(int(config.usage.frontend_priority_dvbs.value)) setPriorityFrontend = True - if config.misc.softcam_streamrelay_delay.value and self.currentServiceStreaming and not fromTimer: - self.currentServiceStreaming = False + if config.misc.softcam_streamrelay_delay.value and self.currentServiceIsStreamRelay: + self.currentServiceIsStreamRelay = False self.currentlyPlayingServiceReference = None self.currentlyPlayingServiceOrGroup = None print("[Navigation] Streamrelay was active -> delay the zap till tuner is freed") self.retryServicePlayTimer = eTimer() - self.retryServicePlayTimer.callback.append(boundFunction(self.playService, ref, checkParentalControl, forceRestart, adjust, True)) + self.retryServicePlayTimer.callback.append(boundFunction(self.playService, ref, checkParentalControl, forceRestart, adjust)) self.retryServicePlayTimer.start(config.misc.softcam_streamrelay_delay.value, True) elif self.pnav.playService(playref): # print("[Navigation] Failed to start", playref) @@ -234,8 +234,8 @@ def playService(self, ref, checkParentalControl=True, forceRestart=False, adjust self.skipServiceReferenceReset = False if setPriorityFrontend: setPreferredTuner(int(config.usage.frontend_priority.value)) - if playref.toString().find("127.0.0.1") > -1 and not self.currentServiceStreaming: - self.currentServiceStreaming = True + if self.currentlyPlayingServiceReference and self.currentlyPlayingServiceReference.toString() in whitelist.streamrelay: + self.currentServiceIsStreamRelay = True return 0 elif oldref and InfoBarInstance and InfoBarInstance.servicelist.servicelist.setCurrent(oldref, adjust): self.currentlyPlayingServiceOrGroup = InfoBarInstance.servicelist.servicelist.getCurrent() From 74aacac452c8cb6d528b5a540d40d569cdd6fa48 Mon Sep 17 00:00:00 2001 From: openvix-build Date: Thu, 30 Nov 2023 12:58:48 +0000 Subject: [PATCH 279/401] openvix: developer 6.4.010.014 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 81b34c14c7d..50af2e4cd31 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1212,3 +1212,4 @@ openvix: developer 6.4.010.010 openvix: developer 6.4.010.011 openvix: developer 6.4.010.012 openvix: developer 6.4.010.013 +openvix: developer 6.4.010.014 From 68bc0e543abf24379469965e57e8a822fadac307 Mon Sep 17 00:00:00 2001 From: Orlandoxx <95180049+Orlandoxx@users.noreply.github.com> Date: Fri, 1 Dec 2023 15:36:44 +0200 Subject: [PATCH 280/401] Updated Finnish (fi.po) translation. Updated setup.xml changes. --- po/fi.po | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/po/fi.po b/po/fi.po index 6abe979f18f..f9d851e7fee 100644 --- a/po/fi.po +++ b/po/fi.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: enigma2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-27 23:35+0000\n" -"PO-Revision-Date: 2023-11-27 07:03+0200\n" +"PO-Revision-Date: 2023-12-01 15:34+0200\n" "Last-Translator: Orlandox\n" "Language-Team: timoj/Kojo/Samzam/Orlandox\n" "Language: fi\n" @@ -13540,7 +13540,7 @@ msgstr "" "Suomenkielinen käännös: timoj, Kojo, Samzam, Orlandox\n" "\n" "Ylläpito : Orlandox\n" -"27.11.2023\n" +"01.12.2023\n" "http://www.huoltovalikko.com" msgid "TS file is too large for ISO9660 level 1!" @@ -19096,20 +19096,20 @@ msgstr "Toista kanava striimin välityksellä" msgid "Stream relay" msgstr "Striimin välitys" -msgid "Streamrelay url" +msgid "Stream Relay url" msgstr "Striimin välitys -url" msgid "The IP address of the streamrelay server that is used to descramble services that can only be decrypted via streamrelay" msgstr "Striimin välitys -palvelimen IP-osoite, jota käytetään sellaisten palvelujen salauksen purkamiseen, joiden salaus voidaan purkaa vain striimin välityksen kautta" -msgid "Streamrelay port" +msgid "Stream Relay port" msgstr "Striimin välitys -portti" -msgid "Streamrelay delay" +msgid "Stream Relay delay" msgstr "Striimin välityksen viive" -msgid "Delay when closing a streamrelay service before reallocating the tuner for another service." -msgstr "Viive striimin välitys -palvelun sulkemisessa ennen virittimen uudelleenallokointia toista palvelua varten." +msgid "Delay when closing a stream relay service before reallocating the tuner for another service. Using '0' is only recommended for boxes with multiple satellite tuners." +msgstr "Viive striimin välitys -palvelun sulkemisessa ennen virittimen uudelleenallokointia toista palvelua varten. 0:n käyttöä suositellaan vain bokseille, joissa on useita satelliittivirittimiä." msgid "The port of the streamrelay server that is used to descramble services that can only be decrypted via streamrelay" msgstr "Striimin välitys -palvelimen portti, jota käytetään sellaisten palvelujen salauksen purkamiseen, joiden salaus voidaan purkaa vain striimin välityksen kautta" From 548c0cbc4ac41fd037228646a84b4cf374dd4753 Mon Sep 17 00:00:00 2001 From: Orlandoxx <95180049+Orlandoxx@users.noreply.github.com> Date: Fri, 1 Dec 2023 18:33:00 +0200 Subject: [PATCH 281/401] Updated fi.po --- po/fi.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/po/fi.po b/po/fi.po index f9d851e7fee..eb3fd923714 100644 --- a/po/fi.po +++ b/po/fi.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: enigma2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-27 23:35+0000\n" -"PO-Revision-Date: 2023-12-01 15:34+0200\n" +"PO-Revision-Date: 2023-12-01 18:34+0200\n" "Last-Translator: Orlandox\n" "Language-Team: timoj/Kojo/Samzam/Orlandox\n" "Language: fi\n" @@ -19099,7 +19099,7 @@ msgstr "Striimin välitys" msgid "Stream Relay url" msgstr "Striimin välitys -url" -msgid "The IP address of the streamrelay server that is used to descramble services that can only be decrypted via streamrelay" +msgid "The IP address of the streamrelay server that is used to descramble services that can only be decrypted via stream relay" msgstr "Striimin välitys -palvelimen IP-osoite, jota käytetään sellaisten palvelujen salauksen purkamiseen, joiden salaus voidaan purkaa vain striimin välityksen kautta" msgid "Stream Relay port" @@ -19111,7 +19111,7 @@ msgstr "Striimin välityksen viive" msgid "Delay when closing a stream relay service before reallocating the tuner for another service. Using '0' is only recommended for boxes with multiple satellite tuners." msgstr "Viive striimin välitys -palvelun sulkemisessa ennen virittimen uudelleenallokointia toista palvelua varten. 0:n käyttöä suositellaan vain bokseille, joissa on useita satelliittivirittimiä." -msgid "The port of the streamrelay server that is used to descramble services that can only be decrypted via streamrelay" +msgid "The port of the streamrelay server that is used to descramble services that can only be decrypted via stream relay" msgstr "Striimin välitys -palvelimen portti, jota käytetään sellaisten palvelujen salauksen purkamiseen, joiden salaus voidaan purkaa vain striimin välityksen kautta" msgid "Enter adapter settings or disable adapter, then Save to action changed setup." From 7754112ebd363ace077e9d76704d7f1a21852aa4 Mon Sep 17 00:00:00 2001 From: Orlandoxx <95180049+Orlandoxx@users.noreply.github.com> Date: Fri, 1 Dec 2023 18:42:25 +0200 Subject: [PATCH 282/401] Updated fi.po --- po/fi.po | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/po/fi.po b/po/fi.po index eb3fd923714..6f27ab589e4 100644 --- a/po/fi.po +++ b/po/fi.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: enigma2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-27 23:35+0000\n" -"PO-Revision-Date: 2023-12-01 18:34+0200\n" +"PO-Revision-Date: 2023-12-01 18:40+0200\n" "Last-Translator: Orlandox\n" "Language-Team: timoj/Kojo/Samzam/Orlandox\n" "Language: fi\n" @@ -19099,8 +19099,8 @@ msgstr "Striimin välitys" msgid "Stream Relay url" msgstr "Striimin välitys -url" -msgid "The IP address of the streamrelay server that is used to descramble services that can only be decrypted via stream relay" -msgstr "Striimin välitys -palvelimen IP-osoite, jota käytetään sellaisten palvelujen salauksen purkamiseen, joiden salaus voidaan purkaa vain striimin välityksen kautta" +msgid "The IP address of the streamrelay server that is used to descramble services that can only be decrypted via stream relay." +msgstr "Striimin välitys -palvelimen IP-osoite, jota käytetään sellaisten palvelujen salauksen purkamiseen, joiden salaus voidaan purkaa vain striimin välityksen kautta." msgid "Stream Relay port" msgstr "Striimin välitys -portti" @@ -19111,8 +19111,8 @@ msgstr "Striimin välityksen viive" msgid "Delay when closing a stream relay service before reallocating the tuner for another service. Using '0' is only recommended for boxes with multiple satellite tuners." msgstr "Viive striimin välitys -palvelun sulkemisessa ennen virittimen uudelleenallokointia toista palvelua varten. 0:n käyttöä suositellaan vain bokseille, joissa on useita satelliittivirittimiä." -msgid "The port of the streamrelay server that is used to descramble services that can only be decrypted via stream relay" -msgstr "Striimin välitys -palvelimen portti, jota käytetään sellaisten palvelujen salauksen purkamiseen, joiden salaus voidaan purkaa vain striimin välityksen kautta" +msgid "The port of the streamrelay server that is used to descramble services that can only be decrypted via stream relay." +msgstr "Striimin välitys -palvelimen portti, jota käytetään sellaisten palvelujen salauksen purkamiseen, joiden salaus voidaan purkaa vain striimin välityksen kautta." msgid "Enter adapter settings or disable adapter, then Save to action changed setup." msgstr "Syötä sovittimen asetukset tai poista sovitin käytöstä ja sitten Tallenna toimintoon muutettu asetus." From 460c22a3d90e53bda1deb98e9f1e0fd0b621afa1 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sat, 2 Dec 2023 17:45:41 +0100 Subject: [PATCH 283/401] [setup.xml] fix SecondInfoBarSimple requiring a skin.parameter --- data/setup.xml | 2 +- lib/python/Components/UsageConfig.py | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/data/setup.xml b/data/setup.xml index 8e1aa3107b2..5de615fe2d4 100644 --- a/data/setup.xml +++ b/data/setup.xml @@ -52,7 +52,7 @@ config.usage.infobar_timeout config.usage.show_second_infobar - config.usage.second_infobar_simple + config.usage.second_infobar_simple config.usage.show_infobar_do_dimming config.usage.show_infobar_dimming_speed config.vixsettings.InfoBarEpg_mode diff --git a/lib/python/Components/UsageConfig.py b/lib/python/Components/UsageConfig.py index c7edd38bfaf..e423acd170d 100644 --- a/lib/python/Components/UsageConfig.py +++ b/lib/python/Components/UsageConfig.py @@ -109,11 +109,6 @@ def showsecondinfobarChanged(configElement): SystemInfo["InfoBarEpg"] = False config.usage.show_second_infobar.addNotifier(showsecondinfobarChanged) - try: - SystemInfo["SecondInfoBarSimple"] = skin.parameters.get("SecondInfoBarSimple", 0) > 0 - except Exception as err: - print("[UsageConfig] Error loading 'SecondInfoBarSimple' skin parameter! (%s)" % err) - SystemInfo["SecondInfoBarSimple"] = False config.usage.second_infobar_simple = ConfigBoolean(descriptions={False: _("Standard"), True: _("Simple")}, graphic=False) config.usage.infobar_frontend_source = ConfigSelection(default="tuner", choices=[("settings", _("Settings")), ("tuner", _("Tuner"))]) From b8fd66f69b013ca49b3ae60e94e70d9a6dbbf9be Mon Sep 17 00:00:00 2001 From: jbleyel Date: Tue, 22 Aug 2023 20:09:20 +0200 Subject: [PATCH 284/401] [Setup] createSetup add parameter for append and prepend items --- lib/python/Screens/Setup.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/python/Screens/Setup.py b/lib/python/Screens/Setup.py index 4f85501feea..b377271210b 100644 --- a/lib/python/Screens/Setup.py +++ b/lib/python/Screens/Setup.py @@ -58,11 +58,11 @@ def changedEntry(self): self.createSetup() ConfigListScreen.changedEntry(self) # force summary update immediately, not just on select/deselect - def createSetup(self): + def createSetup(self, appendItems=None, prependItems=None): oldList = self.list self.showDefaultChanged = False self.graphicSwitchChanged = False - self.list = [] + self.list = prependItems or [] title = None xmlData = setupDom(self.setup, self.plugin) for setup in xmlData.findall("setup"): @@ -76,6 +76,8 @@ def createSetup(self): # If this break is executed then there can only be one setup tag with this key. # This may not be appropriate if conditional setup blocks become available. break + if appendItems: + self.list += appendItems if title: title = dgettext(self.pluginLanguageDomain, title) if self.pluginLanguageDomain else _(title) self.setTitle(title if title else _("Setup")) From e3880f27b70a98fe36d8eea09c79f4052d314f50 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sun, 3 Dec 2023 09:19:12 +0200 Subject: [PATCH 285/401] [Updated] Make directory icon scale to fit the icon size --- lib/python/Components/MovieList.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Components/MovieList.py b/lib/python/Components/MovieList.py index 029110734cc..395aac80d3f 100644 --- a/lib/python/Components/MovieList.py +++ b/lib/python/Components/MovieList.py @@ -447,7 +447,7 @@ def buildMovieListEntry(self, serviceref, info, begin, data): if serviceref.flags & eServiceReference.isGroup: # Collection - res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft, 0), size=(col0iconSize, self.itemHeight), png=self.iconCollection, flags=BT_ALIGN_CENTER)) + res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft, 0), size=(col0iconSize, self.itemHeight), png=self.iconCollection, flags=BT_ALIGN_CENTER | BT_SCALE | BT_KEEP_ASPECT_RATIO)) if self.getCurrent() in self.markList: res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft, 0), size=(col0iconSize, self.itemHeight), png=self.iconMarked)) res.append(MultiContentEntryText(pos=(self.spaceLeft + col0iconSize + space, 0), size=(width - 220, self.itemHeight), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=data.txt)) @@ -461,7 +461,7 @@ def buildMovieListEntry(self, serviceref, info, begin, data): res.append(MultiContentEntryText(pos=(self.spaceLeft + col0iconSize + space, 0), size=(width - 145, self.itemHeight), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=_("Deleted items"))) res.append(MultiContentEntryText(pos=(width - 145 - r, 0), size=(145, self.itemHeight), font=1, flags=RT_HALIGN_RIGHT | RT_VALIGN_CENTER, text=_("Trash can"))) return res - res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft, 0), size=(col0iconSize, self.itemHeight), png=self.iconFolder, flags=BT_ALIGN_CENTER)) + res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft, 0), size=(col0iconSize, self.itemHeight), png=self.iconFolder, flags=BT_ALIGN_CENTER | BT_SCALE | BT_KEEP_ASPECT_RATIO)) if self.getCurrent() in self.markList: res.append(MultiContentEntryPixmapAlphaBlend(pos=(self.spaceLeft, 0), size=(col0iconSize, self.itemHeight), png=self.iconMarked)) res.append(MultiContentEntryText(pos=(self.spaceLeft + col0iconSize + space, 0), size=(width - 145, self.itemHeight), font=0, flags=RT_HALIGN_LEFT | RT_VALIGN_CENTER, text=data.txt)) From 98e1e3e62cc21b2ed329a740ae98419e91ea2ccb Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sun, 3 Dec 2023 10:52:59 +0200 Subject: [PATCH 286/401] [Fixed] [Pager] Wrong parsing of maxPages --- lib/python/Components/Addons/Pager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/Addons/Pager.py b/lib/python/Components/Addons/Pager.py index d7f1486a22f..f18b017b74b 100644 --- a/lib/python/Components/Addons/Pager.py +++ b/lib/python/Components/Addons/Pager.py @@ -237,7 +237,7 @@ def applySkin(self, desktop, parent): elif attrib == "spacing": self.spacing = parseScale(value) elif attrib == "showIcons": - self.showIcons = value + self.showIcons = parseScale(value) elif attrib == "maxPages": self.max_pages = value elif attrib == "orientation": From ca4852dbcd4911371d38a70e9b7a003c2901bb30 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sun, 3 Dec 2023 18:41:29 +0200 Subject: [PATCH 287/401] [Updated] ServiceName converter with tuner system --- .../Components/Converter/ServiceName.py | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/lib/python/Components/Converter/ServiceName.py b/lib/python/Components/Converter/ServiceName.py index a477b2796cd..3e711a21635 100644 --- a/lib/python/Components/Converter/ServiceName.py +++ b/lib/python/Components/Converter/ServiceName.py @@ -6,6 +6,7 @@ from ServiceReference import resolveAlternate from Components.Element import cached from Tools.Directories import fileExists +from Tools.Transponder import ConvertToHumanReadable class ServiceName(Converter): @@ -88,10 +89,11 @@ def getText(self): return service.toString() elif self.type == self.FORMAT_STRING: name = self.getName(service, info) - numservice = self.source.serviceref - num = self.getNumber(numservice, info) + numservice = hasattr(self.source, "serviceref") and self.source.serviceref + num = numservice and self.getNumber(numservice, info) or "" orbpos, tp_data = self.getOrbitalPos(service, info) provider = self.getProvider(service, info, tp_data) + tuner_system = self.getServiceSystem(service, info, tp_data) res_str = "" for x in self.parts[1:]: if x == "NUMBER" and num: @@ -102,6 +104,8 @@ def getText(self): res_str = self.appendToStringWithSeparator(res_str, orbpos) if x == "PROVIDER" and provider: res_str = self.appendToStringWithSeparator(res_str, provider) + if x == "TUNERSYSTEM" and tuner_system: + res_str = self.appendToStringWithSeparator(res_str, tuner_system) return res_str text = property(getText) @@ -136,12 +140,6 @@ def getOrbitalPos(self, ref, info): else: tp_data = info.getInfoObject(iServiceInformation.sTransponderData) - if not tp_data and not ref: - service = self.source.service - if service: - feraw = service.frontendInfo() - tp_data = feraw and feraw.getAll(config.usage.infobar_frontend_source.value == "settings") - if tp_data is not None: try: position = tp_data["orbital_position"] @@ -152,3 +150,19 @@ def getOrbitalPos(self, ref, info): except: pass return orbitalpos, tp_data + + def getServiceSystem(self, ref, info, feraw): + if ref: + sref = info.getInfoObject(ref, iServiceInformation.sServiceref) + else: + sref = info.getInfoObject(iServiceInformation.sServiceref) + + if not sref: + sref = ref.toString() + + if sref and "%3a//" in sref: + return "IPTV" + + fedata = ConvertToHumanReadable(feraw) + + return fedata.get("system") or "" From 50bb93b936d0b59fee62930ff91a7691a591266b Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sun, 3 Dec 2023 18:46:00 +0200 Subject: [PATCH 288/401] [Added] Enable blink option --- data/setup.xml | 1 + lib/python/Components/Converter/ConditionalShowHide.py | 3 ++- lib/python/Components/UsageConfig.py | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/data/setup.xml b/data/setup.xml index 5de615fe2d4..4911718c824 100644 --- a/data/setup.xml +++ b/data/setup.xml @@ -57,6 +57,7 @@ config.usage.show_infobar_dimming_speed config.vixsettings.InfoBarEpg_mode config.usage.show_spinner + config.usage.enable_blinking config.usage.jobtaskextensions config.usage.showdish config.misc.showrotorposition diff --git a/lib/python/Components/Converter/ConditionalShowHide.py b/lib/python/Components/Converter/ConditionalShowHide.py index b6b144e30d9..31456b70185 100644 --- a/lib/python/Components/Converter/ConditionalShowHide.py +++ b/lib/python/Components/Converter/ConditionalShowHide.py @@ -1,6 +1,7 @@ from enigma import eTimer from Components.Converter.Converter import Converter +from Components.config import config class ConditionalShowHide(Converter): @@ -8,7 +9,7 @@ def __init__(self, argstr): Converter.__init__(self, argstr) args = argstr.split(',') self.invert = "Invert" in args - self.blink = "Blink" in args + self.blink = "Blink" in args and config.usage.enable_blinking.value if self.blink: self.blinktime = len(args) == 2 and args[1].isdigit() and int(args[1]) or 500 self.timer = eTimer() diff --git a/lib/python/Components/UsageConfig.py b/lib/python/Components/UsageConfig.py index e423acd170d..ba3dc75ffe7 100644 --- a/lib/python/Components/UsageConfig.py +++ b/lib/python/Components/UsageConfig.py @@ -133,6 +133,7 @@ def showsecondinfobarChanged(configElement): print("[UserConfig] DEBUG: The 'show_menupath' setting of '%s' has been transferred to 'showScreenPath'." % config.usage.showScreenPath.value) # End of temporary code. config.usage.show_spinner = ConfigYesNo(default=True) + config.usage.enable_blinking = ConfigYesNo(default=True) config.usage.enable_tt_caching = ConfigYesNo(default=True) config.usage.sort_settings = ConfigYesNo(default=False) config.usage.sort_pluginlist = ConfigYesNo(default=True) From d7d17b5ee1b2a6ef384262f4c4c6754580d4d8a8 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sun, 3 Dec 2023 16:54:16 +0000 Subject: [PATCH 289/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Components/Converter/ServiceName.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/python/Components/Converter/ServiceName.py b/lib/python/Components/Converter/ServiceName.py index 3e711a21635..cd4f0941361 100644 --- a/lib/python/Components/Converter/ServiceName.py +++ b/lib/python/Components/Converter/ServiceName.py @@ -150,19 +150,19 @@ def getOrbitalPos(self, ref, info): except: pass return orbitalpos, tp_data - + def getServiceSystem(self, ref, info, feraw): if ref: sref = info.getInfoObject(ref, iServiceInformation.sServiceref) else: sref = info.getInfoObject(iServiceInformation.sServiceref) - + if not sref: sref = ref.toString() - + if sref and "%3a//" in sref: return "IPTV" - + fedata = ConvertToHumanReadable(feraw) return fedata.get("system") or "" From 44ba3497ee6ccef7b6b2260077403a55fa1bf574 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sun, 3 Dec 2023 18:14:45 +0100 Subject: [PATCH 290/401] [ServiceName.py] add sanity --- lib/python/Components/Converter/ServiceName.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/Converter/ServiceName.py b/lib/python/Components/Converter/ServiceName.py index cd4f0941361..c422f68c111 100644 --- a/lib/python/Components/Converter/ServiceName.py +++ b/lib/python/Components/Converter/ServiceName.py @@ -93,7 +93,7 @@ def getText(self): num = numservice and self.getNumber(numservice, info) or "" orbpos, tp_data = self.getOrbitalPos(service, info) provider = self.getProvider(service, info, tp_data) - tuner_system = self.getServiceSystem(service, info, tp_data) + tuner_system = service and info and self.getServiceSystem(service, info, tp_data) res_str = "" for x in self.parts[1:]: if x == "NUMBER" and num: From 9a62d367eb7f4550ddf6e2560a26051c2d9c18b6 Mon Sep 17 00:00:00 2001 From: Orlandoxx <95180049+Orlandoxx@users.noreply.github.com> Date: Sun, 3 Dec 2023 20:07:44 +0200 Subject: [PATCH 291/401] Updated Finnish (fi.po) translation. Added 'blinking' from setup.xml. --- po/fi.po | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/po/fi.po b/po/fi.po index 6f27ab589e4..e16eea13eda 100644 --- a/po/fi.po +++ b/po/fi.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: enigma2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-27 23:35+0000\n" -"PO-Revision-Date: 2023-12-01 18:40+0200\n" +"PO-Revision-Date: 2023-12-03 20:05+0200\n" "Last-Translator: Orlandox\n" "Language-Team: timoj/Kojo/Samzam/Orlandox\n" "Language: fi\n" @@ -13540,7 +13540,7 @@ msgstr "" "Suomenkielinen käännös: timoj, Kojo, Samzam, Orlandox\n" "\n" "Ylläpito : Orlandox\n" -"01.12.2023\n" +"03.12.2023\n" "http://www.huoltovalikko.com" msgid "TS file is too large for ISO9660 level 1!" @@ -19135,3 +19135,9 @@ msgstr "Vastaanotto" msgid "Transmission" msgstr "Lähetys" + +msgid "Enable blinking" +msgstr "Ota vilkkuminen käyttöön" + +msgid "Enable blinking for ui elements. For example for recording icon" +msgstr "Ota vilkkuminen käyttöön käyttöliittymäelementeissä. Esimerkiksi tallennuskuvakkeelle" From 4e15ddf4f6da20c0f81cbe3bca4b62c05e39f047 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sun, 3 Dec 2023 21:06:24 +0100 Subject: [PATCH 292/401] [StreamRelay] move to own class Contains code from OpenATV --- lib/python/Components/Converter/StreamInfo.py | 6 +- lib/python/Navigation.py | 8 +- .../SystemPlugins/FastChannelChange/plugin.py | 4 +- lib/python/Screens/ChannelSelection.py | 3 +- lib/python/Screens/InfoBarGenerics.py | 81 ++++++++++++------- lib/python/Screens/PictureInPicture.py | 4 +- 6 files changed, 63 insertions(+), 43 deletions(-) diff --git a/lib/python/Components/Converter/StreamInfo.py b/lib/python/Components/Converter/StreamInfo.py index 42e7ef3bc73..7d582bb1ec6 100644 --- a/lib/python/Components/Converter/StreamInfo.py +++ b/lib/python/Components/Converter/StreamInfo.py @@ -1,6 +1,6 @@ from Components.Converter.Converter import Converter from Components.Element import cached -from Screens.InfoBarGenerics import whitelist +from Screens.InfoBarGenerics import streamrelay import NavigationInstance from enigma import iPlayableService @@ -22,7 +22,7 @@ def streamtype(self): if playref: refstr = playref.toString() strtype = refstr.replace('%3a', ':') - if refstr in whitelist.streamrelay: + if refstr in streamrelay.data: return 'iCAM' elif strtype.startswith('1:0:'): if bool([1 for x in ('0.0.0.0:', '127.0.0.1:', 'localhost:') if x in strtype]): @@ -41,7 +41,7 @@ def streamurl(self): playref = NavigationInstance.instance.getCurrentlyPlayingServiceReference() if playref: refstr = playref.toString() - if refstr in whitelist.streamrelay: + if refstr in streamrelay.data: return 'Stream Relay' if '%3a' in refstr: strurl = refstr.split(':') diff --git a/lib/python/Navigation.py b/lib/python/Navigation.py index 9e28db9f4d0..16143821477 100644 --- a/lib/python/Navigation.py +++ b/lib/python/Navigation.py @@ -15,7 +15,7 @@ import NavigationInstance from Screens.InfoBar import InfoBar from Components.Sources.StreamService import StreamServiceList -from Screens.InfoBarGenerics import streamrelayChecker, whitelist +from Screens.InfoBarGenerics import streamrelay # TODO: remove pNavgation, eNavigation and rewrite this stuff in python. @@ -182,7 +182,7 @@ def playService(self, ref, checkParentalControl=True, forceRestart=False, adjust else: self.skipServiceReferenceReset = True self.currentlyPlayingServiceReference = playref - playref = streamrelayChecker(playref) + playref = streamrelay.streamrelayChecker(playref) self.currentlyPlayingServiceOrGroup = ref if InfoBarInstance and InfoBarInstance.servicelist.servicelist.setCurrent(ref, adjust): self.currentlyPlayingServiceOrGroup = InfoBarInstance.servicelist.servicelist.getCurrent() @@ -234,7 +234,7 @@ def playService(self, ref, checkParentalControl=True, forceRestart=False, adjust self.skipServiceReferenceReset = False if setPriorityFrontend: setPreferredTuner(int(config.usage.frontend_priority.value)) - if self.currentlyPlayingServiceReference and self.currentlyPlayingServiceReference.toString() in whitelist.streamrelay: + if self.currentlyPlayingServiceReference and self.currentlyPlayingServiceReference.toString() in streamrelay.data: self.currentServiceIsStreamRelay = True return 0 elif oldref and InfoBarInstance and InfoBarInstance.servicelist.servicelist.setCurrent(oldref, adjust): @@ -254,7 +254,7 @@ def recordService(self, ref, simulate=False): if ref: if ref.flags & eServiceReference.isGroup: ref = getBestPlayableServiceReference(ref, eServiceReference(), simulate) - ref = streamrelayChecker(ref) + ref = streamrelay.streamrelayChecker(ref) service = ref and self.pnav and self.pnav.recordService(ref, simulate) if service is None: print("[Navigation] record returned non-zero") diff --git a/lib/python/Plugins/SystemPlugins/FastChannelChange/plugin.py b/lib/python/Plugins/SystemPlugins/FastChannelChange/plugin.py index e919d848302..9e7f5d561a4 100644 --- a/lib/python/Plugins/SystemPlugins/FastChannelChange/plugin.py +++ b/lib/python/Plugins/SystemPlugins/FastChannelChange/plugin.py @@ -3,7 +3,7 @@ from Plugins.Plugin import PluginDescriptor from Screens.Screen import Screen from Screens.InfoBar import InfoBar -from Screens.InfoBarGenerics import whitelist +from Screens.InfoBarGenerics import streamrelay from Components.config import config, getConfigListEntry, ConfigSubsection, ConfigYesNo, ConfigSelection from Components.ConfigList import ConfigListScreen from Components.Sources.StaticText import StaticText @@ -248,7 +248,7 @@ def isPlayableFCC(self, sref): elif int(sref.getData(0)) in (2, 10): # is RADIO? playable = False - elif sref.toString() in whitelist.streamrelay: + elif sref.toString() in streamrelay.data: playable = False return playable diff --git a/lib/python/Screens/ChannelSelection.py b/lib/python/Screens/ChannelSelection.py index d5ea4804aa8..c86f4c4bd45 100644 --- a/lib/python/Screens/ChannelSelection.py +++ b/lib/python/Screens/ChannelSelection.py @@ -357,7 +357,8 @@ def toggleVBI(self): self.close() def toggleStreamrelay(self): - Screens.InfoBar.InfoBar.instance.ToggleStreamrelay(self.csel.getCurrentSelection()) + from Screens.InfoBarGenerics import streamrelay + streamrelay.toggle(self.session.nav, self.csel.getCurrentSelection()) self.close() def addCenterDVBSubsFlag(self): diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index ffeec228db0..0429141948d 100644 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -68,6 +68,7 @@ import datetime import pickle from gettext import dgettext +from re import match # hack alert! from Screens.Menu import MainMenu, Menu, mdom @@ -165,7 +166,6 @@ def updateresumePointCache(): class whitelist: vbi = [] - streamrelay = [] def reload_whitelist_vbi(): @@ -175,26 +175,58 @@ def reload_whitelist_vbi(): reload_whitelist_vbi() -def reload_streamrelay(): - whitelist.streamrelay = [line.strip() for line in open('/etc/enigma2/whitelist_streamrelay', 'r').readlines()] if os.path.isfile('/etc/enigma2/whitelist_streamrelay') else [] +class InfoBarStreamRelay: + FILENAME = "/etc/enigma2/whitelist_streamrelay" -reload_streamrelay() + def __init__(self): + self.__srefs = self.__sanitizeData(open(self.FILENAME, 'r').readlines()) if os.path.isfile(self.FILENAME) else [] -subservice_groupslist = None + def __sanitizeData(self, data): + return list(set([line.strip() for line in data if line and isinstance(line, str) and match("^(?:[0-9A-F]+[:]){10}$", line.strip())])) if isinstance(data, list) else [] + def __saveToFile(self): + self.__srefs.sort(key=lambda ref: (int((x := ref.split(":"))[6], 16), int(x[5], 16), int(x[4], 16), int(x[3], 16))) + open(self.FILENAME, 'w').write('\n'.join(self.__srefs)) + + def toggle(self, nav, service): + if (servicestring := (service and service.toString())): + if servicestring in self.__srefs: + self.__srefs.remove(servicestring) + else: + self.__srefs.append(servicestring) + if nav.getCurrentlyPlayingServiceReference() == service: + nav.restartService() + self.__saveToFile() + + def getData(self): + return self.__srefs + + def setData(self, data): + self.__srefs = self.__sanitizeData(data) + self.__saveToFile() + + data = property(getData, setData) + + def streamrelayChecker(self, playref): + playrefstring = playref.toString() + if '%3a//' not in playrefstring and playrefstring in self.__srefs: + url = "http://%s:%s/" % (config.misc.softcam_streamrelay_url.getHTML(), config.misc.softcam_streamrelay_port.value) + if "127.0.0.1" in url: + playrefmod = ":".join([("%x" % (int(x[1], 16) + 1)).upper() if x[0] == 6 else x[1] for x in enumerate(playrefstring.split(':'))]) + else: + playrefmod = playrefstring + playref = eServiceReference("%s%s%s:%s" % (playrefmod, url.replace(":", "%3a"), playrefstring.replace(":", "%3a"), ServiceReference(playref).getServiceName())) + print(f"[{self.__class__.__name__}] Play service {playref.toString()} via streamrelay") + return playref + + def checkService(self, service): + return service and service.toString() in self.__srefs -def streamrelayChecker(playref): - playrefstring = playref.toString() - if '%3a//' not in playrefstring and playrefstring in whitelist.streamrelay: - url = "http://%s:%s/" % (config.misc.softcam_streamrelay_url.getHTML(), config.misc.softcam_streamrelay_port.value) - if "127.0.0.1" in url: - playrefmod = ":".join([("%x" % (int(x[1], 16) + 1)).upper() if x[0] == 6 else x[1] for x in enumerate(playrefstring.split(':'))]) - else: - playrefmod = playrefstring - playref = eServiceReference("%s%s%s:%s" % (playrefmod, url.replace(":", "%3a"), playrefstring.replace(":", "%3a"), ServiceReference(playref).getServiceName())) - print("[Whitelist_StreamRelay] Play service via streamrelay as it is whitelisted as such", playref.toString()) - return playref + +streamrelay = InfoBarStreamRelay() + +subservice_groupslist = None def reload_subservice_groupslist(force=False): @@ -913,9 +945,6 @@ def checkHideVBI(self, service=None): return ".hidevbi." in servicepath.lower() return service and service.toString() in whitelist.vbi - def checkStreamrelay(self, service=None): - return (service or self.session.nav.getCurrentlyPlayingServiceReference()) and service.toString() in whitelist.streamrelay - def showHideVBI(self): if self.checkHideVBI(): self.hideVBILineScreen.show() @@ -933,18 +962,8 @@ def ToggleHideVBI(self, service=None): open('/etc/enigma2/whitelist_vbi', 'w').write('\n'.join(whitelist.vbi)) self.showHideVBI() - def ToggleStreamrelay(self, service=None): - service = service or self.session.nav.getCurrentlyPlayingServiceReference() - if service: - servicestring = service.toString() - if servicestring in whitelist.streamrelay: - whitelist.streamrelay.remove(servicestring) - else: - whitelist.streamrelay.append(servicestring) - if self.session.nav.getCurrentlyPlayingServiceReference() == service: - self.session.nav.restartService() - whitelist.streamrelay.sort(key=lambda ref: (int((x := ref.split(":"))[6], 16), int(x[5], 16), int(x[4], 16), int(x[3], 16))) - open('/etc/enigma2/whitelist_streamrelay', 'w').write('\n'.join(whitelist.streamrelay)) + def checkStreamrelay(self, service): + return streamrelay.checkService(service) def queueChange(self): self._waitForEventInfoTimer.stop() diff --git a/lib/python/Screens/PictureInPicture.py b/lib/python/Screens/PictureInPicture.py index f80fcaf3e40..628de6e9be2 100644 --- a/lib/python/Screens/PictureInPicture.py +++ b/lib/python/Screens/PictureInPicture.py @@ -218,8 +218,8 @@ def getModeName(self): def playService(self, service): if service is None: return False - from Screens.InfoBarGenerics import streamrelayChecker - ref = streamrelayChecker(self.resolveAlternatePipService(service)) + from Screens.InfoBarGenerics import streamrelay + ref = streamrelay.streamrelayChecker(self.resolveAlternatePipService(service)) if ref: if SystemInfo["CanNotDoSimultaneousTranscodeAndPIP"] and StreamServiceList: self.pipservice = None From 7837be48c6ee907b88db464e27aa9e4be4f72ed2 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sun, 3 Dec 2023 21:07:27 +0100 Subject: [PATCH 293/401] [StreamRelaySetup] add module Based on OpenATV code --- data/menu.xml | 1 + data/setup.xml | 8 +- lib/python/Screens/StreamRelaySetup.py | 108 +++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 lib/python/Screens/StreamRelaySetup.py diff --git a/data/menu.xml b/data/menu.xml index a7dd4973813..461f5bb8e76 100644 --- a/data/menu.xml +++ b/data/menu.xml @@ -149,6 +149,7 @@ self.session.open(SABnzbdSetupScreen) + diff --git a/data/setup.xml b/data/setup.xml index 4911718c824..6c916c8f820 100644 --- a/data/setup.xml +++ b/data/setup.xml @@ -22,15 +22,17 @@ config.streaming.stream_ecm config.streaming.descramble config.streaming.descramble_client - config.misc.softcam_streamrelay_url - config.misc.softcam_streamrelay_port - config.misc.softcam_streamrelay_delay config.streaming.authentication config.usage.http_startdelay config.usage.wakeOnLAN config.misc.usegstplaybin3 config.misc.RCSource + + config.misc.softcam_streamrelay_url + config.misc.softcam_streamrelay_port + config.misc.softcam_streamrelay_delay + config.usage.output_12V config.usage.frontend_priority diff --git a/lib/python/Screens/StreamRelaySetup.py b/lib/python/Screens/StreamRelaySetup.py new file mode 100644 index 00000000000..970be413259 --- /dev/null +++ b/lib/python/Screens/StreamRelaySetup.py @@ -0,0 +1,108 @@ +from Components.ActionMap import HelpableActionMap +from Components.config import ConfigNothing, NoSave +from Components.Sources.StaticText import StaticText +from Screens.InfoBarGenerics import streamrelay +from Screens.Setup import Setup + +from ServiceReference import ServiceReference + +class StreamRelaySetup(Setup): + def __init__(self, session): + self.serviceitems = [] + self.services = streamrelay.data[:] + Setup.__init__(self, session=session, setup="streamrelay") + self["key_yellow"] = StaticText() + self["key_blue"] = StaticText() + self["addActions"] = HelpableActionMap(self, ["ColorActions"], { + "yellow": (self.keyAddService, _("Play service with Stream Relay")) + }, prio=0, description=_("Stream Relay Setup Actions")) + self["removeActions"] = HelpableActionMap(self, ["ColorActions"], { + "blue": (self.keyRemoveService, _("Play service without Stream Relay")) + }, prio=0, description=_("Stream Relay Setup Actions")) + self["removeActions"].setEnabled(False) + + def layoutFinished(self): + Setup.layoutFinished(self) + self.createItems() + + def createItems(self): + self.serviceitems = [] + if self.services: + for serviceref in self.services: + service = ServiceReference(serviceref) + self.serviceitems.append(((service and service.getServiceName() or serviceref) + " " + self.formatOrbPos(serviceref), NoSave(ConfigNothing()), serviceref, self.getOrbPos(serviceref))) + self.serviceitems.sort(key=self.sort) + self.serviceitems.insert(0, ("**************************",)) + self.createSetup() + + def createSetup(self): + Setup.createSetup(self, appendItems=self.serviceitems) + + def selectionChanged(self): + self.updateButtons() + Setup.selectionChanged(self) + + def updateButtons(self): + if self.services and isinstance(self.getCurrentItem(), ConfigNothing): + self["removeActions"].setEnabled(True) + self["key_blue"].setText(_("Remove")) + else: + self["removeActions"].setEnabled(False) + self["key_blue"].setText("") + self["key_yellow"].setText(_("Add service")) + + def keySelect(self): + if not isinstance(self.getCurrentItem(), ConfigNothing): + Setup.keySelect(self) + + def keyMenu(self): + if not isinstance(self.getCurrentItem(), ConfigNothing): + Setup.keyMenu(self) + + def keyRemoveService(self): + currentItem = self.getCurrentItem() + if currentItem: + serviceref = self["config"].getCurrent()[2] + self.services.remove(serviceref) + index = self["config"].getCurrentIndex() + self.createItems() + self["config"].setCurrentIndex(index) + + def keyAddService(self): + def keyAddServiceCallback(*result): + if result: + service = ServiceReference(result[0]) + serviceref = str(service) + if serviceref not in self.services: + self.services.append(serviceref) + self.createItems() + self["config"].setCurrentIndex(2) + + from Screens.ChannelSelection import SimpleChannelSelection # deferred to avoid circular import + self.session.openWithCallback(keyAddServiceCallback, SimpleChannelSelection, _("Select"), currentBouquet=False) + + def keySave(self): + if streamrelay.data != self.services: + streamrelay.data = self.services + Setup.keySave(self) + self.close() + + def getOrbPos(self, sref): + orbpos = 0 + try: + orbpos = int(sref.split(":")[6], 16) >> 16 + except: + pass + return orbpos + + def formatOrbPos(self, sref): + orbpos = self.getOrbPos(sref) + if isinstance(orbpos, int) and 1 <= orbpos <= 3600: # sanity + if orbpos > 1800: + return str((float(3600 - orbpos)) / 10.0) + "\xb0" + "W" + else: + return str((float(orbpos)) / 10.0) + "\xb0" + "E" + return "" + + def sort(self, item): + return (item[3], item[0].lower() if item and item[0] and ord(item[0].lower()[0]) in range(97, 123) else f"zzzzz{item[0].lower()}") From 655e4fd52537e851ec37fbde68801927444f8cdd Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sun, 3 Dec 2023 20:10:10 +0000 Subject: [PATCH 294/401] PEP8 double aggressive E301 ~ E306 --- lib/python/Screens/StreamRelaySetup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/python/Screens/StreamRelaySetup.py b/lib/python/Screens/StreamRelaySetup.py index 970be413259..339c98f9fcb 100644 --- a/lib/python/Screens/StreamRelaySetup.py +++ b/lib/python/Screens/StreamRelaySetup.py @@ -6,6 +6,7 @@ from ServiceReference import ServiceReference + class StreamRelaySetup(Setup): def __init__(self, session): self.serviceitems = [] From 5aa6c7c818c650b04d65b6db3b3a7c0944d7285e Mon Sep 17 00:00:00 2001 From: openvix-build Date: Sun, 3 Dec 2023 20:17:07 +0000 Subject: [PATCH 295/401] openvix: developer 6.4.010.015 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 50af2e4cd31..b3fe77ec250 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1213,3 +1213,4 @@ openvix: developer 6.4.010.011 openvix: developer 6.4.010.012 openvix: developer 6.4.010.013 openvix: developer 6.4.010.014 +openvix: developer 6.4.010.015 From 085c57963dbf06c8b7cd6f920f2870fd7683986d Mon Sep 17 00:00:00 2001 From: Huevos Date: Sun, 3 Dec 2023 23:12:31 +0100 Subject: [PATCH 296/401] Revert "[Fixed] [Pager] Wrong parsing of maxPages" This reverts commit 98e1e3e62cc21b2ed329a740ae98419e91ea2ccb. --- lib/python/Components/Addons/Pager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/Addons/Pager.py b/lib/python/Components/Addons/Pager.py index f18b017b74b..d7f1486a22f 100644 --- a/lib/python/Components/Addons/Pager.py +++ b/lib/python/Components/Addons/Pager.py @@ -237,7 +237,7 @@ def applySkin(self, desktop, parent): elif attrib == "spacing": self.spacing = parseScale(value) elif attrib == "showIcons": - self.showIcons = parseScale(value) + self.showIcons = value elif attrib == "maxPages": self.max_pages = value elif attrib == "orientation": From 7343e4033af5e6e5c82c8862b5548931d938fdca Mon Sep 17 00:00:00 2001 From: Huevos Date: Sun, 3 Dec 2023 23:30:43 +0100 Subject: [PATCH 297/401] [Pager] typecast maxPages to int --- lib/python/Components/Addons/Pager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/Addons/Pager.py b/lib/python/Components/Addons/Pager.py index d7f1486a22f..6cc9e71b181 100644 --- a/lib/python/Components/Addons/Pager.py +++ b/lib/python/Components/Addons/Pager.py @@ -239,7 +239,7 @@ def applySkin(self, desktop, parent): elif attrib == "showIcons": self.showIcons = value elif attrib == "maxPages": - self.max_pages = value + self.max_pages = int(value) elif attrib == "orientation": self.orientation = self.orientations.get(value, self.orientations["orHorizontal"]) if self.orientation == eListbox.orHorizontal: From b1d949e92ef48f15f48a3ffec13655a66b19dd21 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sun, 3 Dec 2023 23:47:06 +0100 Subject: [PATCH 298/401] [setup.xml] update "two line" description --- data/setup.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/setup.xml b/data/setup.xml index 6c916c8f820..468c5cabbb9 100644 --- a/data/setup.xml +++ b/data/setup.xml @@ -112,7 +112,7 @@ config.usage.show_channel_jump_in_servicelist config.usage.show_event_progress_in_servicelist config.usage.show_channel_numbers_in_servicelist - config.usage.servicelist_twolines + config.usage.servicelist_twolines config.usage.crypto_icon_mode config.usage.servicetype_icon_mode config.usage.record_indicator_mode From a1ad916d41fddca7b1a7601a84bf4f61ea01c41f Mon Sep 17 00:00:00 2001 From: Orlandoxx <95180049+Orlandoxx@users.noreply.github.com> Date: Mon, 4 Dec 2023 07:21:56 +0200 Subject: [PATCH 299/401] Updated Finnish (fi.po) translation. Changes of stream relay & two lines. --- po/fi.po | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/po/fi.po b/po/fi.po index e16eea13eda..2139726dbbb 100644 --- a/po/fi.po +++ b/po/fi.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: enigma2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-27 23:35+0000\n" -"PO-Revision-Date: 2023-12-03 20:05+0200\n" +"PO-Revision-Date: 2023-12-04 07:19+0200\n" "Last-Translator: Orlandox\n" "Language-Team: timoj/Kojo/Samzam/Orlandox\n" "Language: fi\n" @@ -12554,8 +12554,8 @@ msgstr "Näytä lisäosien selain" msgid "Show the radio player" msgstr "Näytä radiosoitin" -msgid "Show the service information on two lines in the channel selection screen. You can choose between the current event description below the channel name, or the current event description next to the channel name, and the next event description on the second line." -msgstr "Näytä kanavan tiedot kahdella rivillä kanavan valintanäytöllä. Voit valita nykyisen ohjelmatiedon kanavan nimen alle tai nykyisen ohjelmatiedon kanavan nimen viereen ja seuraavan ohjelmatiedon toiselle riville." +msgid "Show the service information on two lines in the channel selection screen." +msgstr "Näytä kanavan tiedot kahdella rivillä kanavanvalintanäytössä." msgid "Show the tv player" msgstr "Näytä tv" @@ -13540,7 +13540,7 @@ msgstr "" "Suomenkielinen käännös: timoj, Kojo, Samzam, Orlandox\n" "\n" "Ylläpito : Orlandox\n" -"03.12.2023\n" +"04.12.2023\n" "http://www.huoltovalikko.com" msgid "TS file is too large for ISO9660 level 1!" @@ -19141,3 +19141,15 @@ msgstr "Ota vilkkuminen käyttöön" msgid "Enable blinking for ui elements. For example for recording icon" msgstr "Ota vilkkuminen käyttöön käyttöliittymäelementeissä. Esimerkiksi tallennuskuvakkeelle" + +msgid "Stream Relay Settings" +msgstr "Striimin välitysasetukset" + +msgid "Play service with Stream Relay" +msgstr "Toista kanava striimin välityksellä" + +msgid "Stream Relay Setup Actions" +msgstr "Striimin välitysasetustoiminnot" + +msgid "Play service without Stream Relay" +msgstr "Toista kanava ilman striimin välitystä" From 4e7d7d6df460b679a2e92c7bd511c647ffb42e9e Mon Sep 17 00:00:00 2001 From: Huevos Date: Mon, 4 Dec 2023 22:50:51 +0100 Subject: [PATCH 300/401] Add matching for record icon --- data/setup.xml | 1 + lib/python/Components/RecordingConfig.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/data/setup.xml b/data/setup.xml index 468c5cabbb9..1e71a1d121e 100644 --- a/data/setup.xml +++ b/data/setup.xml @@ -234,6 +234,7 @@ config.recording.keep_finished_timer_logs config.recording.offline_decode_delay config.recording.ecm_data + config.recording.record_icon_match config.usage.hdd_standby diff --git a/lib/python/Components/RecordingConfig.py b/lib/python/Components/RecordingConfig.py index e81c3936462..ede6a5867ba 100644 --- a/lib/python/Components/RecordingConfig.py +++ b/lib/python/Components/RecordingConfig.py @@ -1,4 +1,4 @@ -from Components.config import ConfigSelectionNumber, ConfigYesNo, ConfigSubsection, ConfigSelection, config +from Components.config import ConfigBoolean, ConfigSelectionNumber, ConfigYesNo, ConfigSubsection, ConfigSelection, config def InitRecordingConfig(): @@ -28,3 +28,4 @@ def InitRecordingConfig(): ("long", _("Long filenames"))]) config.recording.offline_decode_delay = ConfigSelectionNumber(min=1, max=10000, stepwidth=10, default=1000, wraparound=True) config.recording.ecm_data = ConfigSelection(choices=[("normal", _("normal")), ("descrambled+ecm", _("descramble and record ecm")), ("scrambled+ecm", _("don't descramble, record ecm"))], default="normal") + config.recording.record_icon_match = ConfigBoolean(descriptions={False: _("Sref only"), True: _("Sref + stream url")}, graphic=False) From e794957c05e4a6e51f6514aae0064ec4c9fbf00b Mon Sep 17 00:00:00 2001 From: Orlandoxx <95180049+Orlandoxx@users.noreply.github.com> Date: Tue, 5 Dec 2023 07:09:52 +0200 Subject: [PATCH 301/401] Updated Finnish(fi.po) translation. Added 'recording icon match'. --- po/fi.po | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/po/fi.po b/po/fi.po index 2139726dbbb..0e745a7d5ce 100644 --- a/po/fi.po +++ b/po/fi.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: enigma2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-27 23:35+0000\n" -"PO-Revision-Date: 2023-12-04 07:19+0200\n" +"PO-Revision-Date: 2023-12-05 07:08+0200\n" "Last-Translator: Orlandox\n" "Language-Team: timoj/Kojo/Samzam/Orlandox\n" "Language: fi\n" @@ -13540,7 +13540,7 @@ msgstr "" "Suomenkielinen käännös: timoj, Kojo, Samzam, Orlandox\n" "\n" "Ylläpito : Orlandox\n" -"04.12.2023\n" +"05.12.2023\n" "http://www.huoltovalikko.com" msgid "TS file is too large for ISO9660 level 1!" @@ -19153,3 +19153,15 @@ msgstr "Striimin välitysasetustoiminnot" msgid "Play service without Stream Relay" msgstr "Toista kanava ilman striimin välitystä" + +msgid "Record icon match" +msgstr "Tallennuskuvakkeen vastine" + +msgid "Select display of record icon based on 'sref only' or 'Sref + stream url' where applicable." +msgstr "Valitse tallennuskuvakkeen näyttö 'vain sref' tai 'Sref + striimin url' perusteella, jos mahdollista." + +msgid "Sref only" +msgstr "Vain Sref" + +msgid "Sref + stream url" +msgstr "Sref + striimin url" From 0f779e413f6a6ef3b6e92402520ccdaf127deaea Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Tue, 5 Dec 2023 00:52:29 +0200 Subject: [PATCH 302/401] [Added] Make rec icon match logic configurable --- lib/python/Components/ServiceList.py | 2 ++ lib/service/listboxservice.cpp | 17 ++++++++++------- lib/service/listboxservice.h | 2 ++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index e320cedf34d..d93549a6161 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -67,6 +67,8 @@ def __init__(self, serviceList): pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/ico_altref-fs8.png")) pic and self.l.setPixmap(self.l.picBackup, pic) + self.l.setAlternativeRecordMatching(config.recording.record_icon_match.value) + self.root = None self.mode = self.MODE_NORMAL self.listHeight = 0 diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 667b007b2b4..dc43b62e7ad 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -35,7 +35,7 @@ void join(const std::vector& v, char c, std::string& s) { } } -bool compareServices(const eServiceReference &ref1, const eServiceReference &ref2) { +bool compareServices(const eServiceReference &ref1, const eServiceReference &ref2, bool alternativeMatching) { eServiceReference r_i = ref1; std::vector ref_split = split(r_i.toString(), ":"); std::vector s_split = split(ref2.toString(), ":"); @@ -52,19 +52,22 @@ bool compareServices(const eServiceReference &ref1, const eServiceReference &ref std::string s_s; join(s_split_r, ':', s_s); - if (ref_s == s_s) return true; + if (!alternativeMatching) { + if (ref1 == ref2) return true; + } else { + if (ref_s == s_s) return true; + } // Check is it having a localhost in the service reference. If it do probably a stream relay - // so use different logic + // so use partial matching logic if (ref2.toString().find("127.0.0.1") != std::string::npos) { std::string url_sr = s_split[s_split.size() - 2]; std::vector sr_split = split(url_sr, "/"); std::string ref_orig = sr_split.back(); ref_orig = replace_all(ref_orig, "%3a", ":"); - //eDebug("Ref1: %s || Ref2: %s", ref_s.c_str(), ref_orig.c_str()); return ref_s + ":" == ref_orig; } - return ref_s == s_s; + return false; } void eListboxServiceContent::addService(const eServiceReference &service, bool beforeCurrent) @@ -680,13 +683,13 @@ bool eListboxServiceContent::checkServiceIsRecorded(eServiceReference ref) if (!db->getBouquet(ref, bouquet)) { for (std::list::iterator i(bouquet->m_services.begin()); i != bouquet->m_services.end(); ++i){ - if (compareServices(*i, it->second)) + if (compareServices(*i, it->second, m_alternative_record_match)) return true; } } } else { - if (compareServices(ref, it->second)) + if (compareServices(ref, it->second, m_alternative_record_match)) return true; } } diff --git a/lib/service/listboxservice.h b/lib/service/listboxservice.h index d2f03c9c25d..c06c167507b 100644 --- a/lib/service/listboxservice.h +++ b/lib/service/listboxservice.h @@ -109,6 +109,7 @@ class eListboxServiceContent: public virtual iListboxContent void setChannelNumbersVisible(bool visible) { m_chanel_number_visible = visible; } void setAlternativeNumberingMode(bool b) { m_alternative_numbering = b; } void setProgressBarMode(std::string s) { m_progress_mode = s; } + void setAlternativeRecordMatching(bool b) { m_alternative_record_match = b; } void setTextSeparator(const std::string &string) { m_separator = string; } void setMarkerTextAlignment(const std::string &string) { m_marker_alignment = string; } // currently supports left and center @@ -215,6 +216,7 @@ class eListboxServiceContent: public virtual iListboxContent int m_marker_as_line; gRGB m_markerline_color; int m_markerline_color_set; + bool m_alternative_record_match; std::string m_next_title; std::string m_separator; From b48ca235a4cd783e0753c4364089cec1be826990 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Tue, 5 Dec 2023 08:35:37 +0200 Subject: [PATCH 303/401] [Updated] Inverted the condition for match for rec icon --- lib/python/Components/ServiceList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index d93549a6161..5285a106828 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -67,7 +67,7 @@ def __init__(self, serviceList): pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/ico_altref-fs8.png")) pic and self.l.setPixmap(self.l.picBackup, pic) - self.l.setAlternativeRecordMatching(config.recording.record_icon_match.value) + self.l.setAlternativeRecordMatching(not config.recording.record_icon_match.value) self.root = None self.mode = self.MODE_NORMAL From 1057a23e2b1248715b43abb9f569757b7bbabd52 Mon Sep 17 00:00:00 2001 From: Rob van der Does Date: Tue, 5 Dec 2023 16:52:31 +0100 Subject: [PATCH 304/401] [Translations] Update Dutch (NL) translation. --- po/nl.po | 60 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 18 deletions(-) diff --git a/po/nl.po b/po/nl.po index 86af50e5f73..bca14d73dd7 100644 --- a/po/nl.po +++ b/po/nl.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: ViX\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-08 01:01+0000\n" -"PO-Revision-Date: 2023-11-08 17:17+0100\n" +"POT-Creation-Date: 2023-12-03 20:33+0000\n" +"PO-Revision-Date: 2023-12-05 16:50+0100\n" "Last-Translator: Rob van der Does \n" "Language-Team: Andy Blackburn, Rob van der Does\n" "Language: nl\n" @@ -4754,6 +4754,9 @@ msgstr "Vertraging in milliseconde voor het scrollen van tekst op het display be msgid "Delay time" msgstr "Vertragingstijd" +msgid "Delay when closing a stream relay service before reallocating the tuner for another service. Using '0' is only recommended for boxes with multiple satellite tuners." +msgstr "Vertraging na het sluiten van een streamrely-service voordat de tuner aan een andere service kan worden toegewezen. Het gebruik van \"0\" wordt alleen aanbevolen voor ontvangers met meerdere satelliettuners." + msgid "Delay:" msgstr "Vertraging:" @@ -5593,6 +5596,12 @@ msgstr "Schakel automatisch downloaden van OpenTV EPG in. Als er slechts één t msgid "Enable automatic collections" msgstr "Automatische collecties inschakelen" +msgid "Enable blinking" +msgstr "Schakel knipperen in" + +msgid "Enable blinking for ui elements. For example for recording icon" +msgstr "Schakel knipperen in voor verschillende GUI-elementen. Bij voorbeeld voor de opname-icoon." + msgid "Enable blinking rec symbol on the LCD Display" msgstr "Schakel knipperend opnamesymbool in op het LCD-scherm" @@ -10143,9 +10152,15 @@ msgstr "Speel vorige" msgid "Play recorded movies" msgstr "Speel opnames af" +msgid "Play service with Stream Relay" +msgstr "Speel service met streamrelay" + msgid "Play service with streamrelay" msgstr "Speel service met streamrelay" +msgid "Play service without Stream Relay" +msgstr "Speel service zonder streamrelay" + msgid "Play service without streamrelay" msgstr "Speel service zonder streamrelay" @@ -14047,6 +14062,21 @@ msgstr "Opgeslagen positie" msgid "Stream" msgstr "Stream" +msgid "Stream Relay Settings" +msgstr "Streamrelay instellingen" + +msgid "Stream Relay Setup Actions" +msgstr "Streamrelay instellingen" + +msgid "Stream Relay delay" +msgstr "Streamrelay vertraging" + +msgid "Stream Relay port" +msgstr "Streamrelay poort" + +msgid "Stream Relay url" +msgstr "Streamrelay url" + msgid "Stream request" msgstr "Stream-verzoek" @@ -14062,12 +14092,6 @@ msgstr "Stream-klanten" msgid "Streaming Clients Info" msgstr "Stream-klanten info" -msgid "Streamrelay port" -msgstr "Streamrelay poort" - -msgid "Streamrelay url" -msgstr "Streamrelay url" - msgid "Strict DLNA" msgstr "Strict DLNA" @@ -14531,8 +14555,8 @@ msgstr "" "De IMDb-plugin is niet geïnstalleerd!\n" "Installeer die." -msgid "The IP address of the streamrelay server that is used to descramble services that can only be decrypted via streamrelay" -msgstr "Het IP-adres van de streamrelay server die wordt gebruikt om te services te descramblen waarbij dat alleen via een streamrelay kan." +msgid "The IP address of the streamrelay server that is used to descramble services that can only be decrypted via stream relay." +msgstr "Het IP-adres van de streamrelay-server die wordt gebruikt om te services te descramblen waarbij dat alleen via een streamrelay kan." msgid "" "The Linux kernel has changed, an update is not permitted. \n" @@ -14635,8 +14659,8 @@ msgstr "Het pad %s bestaat al." msgid "The pin code you entered is wrong." msgstr "De ingevoerde pincode is onjuist." -msgid "The port of the streamrelay server that is used to descramble services that can only be decrypted via streamrelay" -msgstr "De poort van de streamrelay server die wordt gebruikt om te services te descramblen waarbij dat alleen via een streamrelay kan." +msgid "The port of the streamrelay server that is used to descramble services that can only be decrypted via stream relay." +msgstr "De poort van de streamrelay-server die wordt gebruikt om te services te descramblen waarbij dat alleen via een streamrelay kan." #, python-format msgid "The results have been written to %s." @@ -18256,9 +18280,6 @@ msgstr "stand-by " msgid "start cut here" msgstr "start knippen hier" -msgid "start directory" -msgstr "startmap" - msgid "stepsize" msgstr "stapgrootte" @@ -18328,9 +18349,6 @@ msgstr "waar" msgid "two lines" msgstr "twee regels" -msgid "two lines and next event" -msgstr "twee regels en volgende programma" - msgid "type" msgstr "type" @@ -19540,5 +19558,11 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "slot%s - %s (current image)" #~ msgstr "slot%s - %s (huidige image)" +#~ msgid "start directory" +#~ msgstr "startmap" + +#~ msgid "two lines and next event" +#~ msgstr "twee regels en volgende programma" + #~ msgid "updates available." #~ msgstr "updates beschikbaar." From c6f6678e3694570fb233d72f437864e9c6e0780b Mon Sep 17 00:00:00 2001 From: Huevos Date: Tue, 5 Dec 2023 22:04:02 +0100 Subject: [PATCH 305/401] [listboxservice] compareServices, avoid some false positives This problem occured when IPTV services were not using unique service references --- lib/service/listboxservice.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index dc43b62e7ad..91a971a9cf0 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -57,14 +57,14 @@ bool compareServices(const eServiceReference &ref1, const eServiceReference &ref } else { if (ref_s == s_s) return true; } - // Check is it having a localhost in the service reference. If it do probably a stream relay + // If "127.0.0.1" is in the service reference this is probably a stream relay // so use partial matching logic if (ref2.toString().find("127.0.0.1") != std::string::npos) { std::string url_sr = s_split[s_split.size() - 2]; std::vector sr_split = split(url_sr, "/"); std::string ref_orig = sr_split.back(); ref_orig = replace_all(ref_orig, "%3a", ":"); - return ref_s + ":" == ref_orig; + return r_i.toString() == ref_orig; } return false; From d7ce0078c030f98c5be9aeaee664a39291e60eaf Mon Sep 17 00:00:00 2001 From: Huevos Date: Tue, 5 Dec 2023 22:33:10 +0100 Subject: [PATCH 306/401] [config.recording.record_icon_match] convert to ConfigSelection --- lib/python/Components/RecordingConfig.py | 4 ++-- lib/python/Components/ServiceList.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/python/Components/RecordingConfig.py b/lib/python/Components/RecordingConfig.py index ede6a5867ba..e9dbc22eca5 100644 --- a/lib/python/Components/RecordingConfig.py +++ b/lib/python/Components/RecordingConfig.py @@ -1,4 +1,4 @@ -from Components.config import ConfigBoolean, ConfigSelectionNumber, ConfigYesNo, ConfigSubsection, ConfigSelection, config +from Components.config import ConfigSelectionNumber, ConfigYesNo, ConfigSubsection, ConfigSelection, config def InitRecordingConfig(): @@ -28,4 +28,4 @@ def InitRecordingConfig(): ("long", _("Long filenames"))]) config.recording.offline_decode_delay = ConfigSelectionNumber(min=1, max=10000, stepwidth=10, default=1000, wraparound=True) config.recording.ecm_data = ConfigSelection(choices=[("normal", _("normal")), ("descrambled+ecm", _("descramble and record ecm")), ("scrambled+ecm", _("don't descramble, record ecm"))], default="normal") - config.recording.record_icon_match = ConfigBoolean(descriptions={False: _("Sref only"), True: _("Sref + stream url")}, graphic=False) + config.recording.record_icon_match = ConfigSelection(default="Sref + stream url", choices=[("Sref only", _("Sref only")), ("Sref + stream url", _("Sref + stream url"))]) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 5285a106828..2388ddd76e1 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -67,7 +67,7 @@ def __init__(self, serviceList): pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/ico_altref-fs8.png")) pic and self.l.setPixmap(self.l.picBackup, pic) - self.l.setAlternativeRecordMatching(not config.recording.record_icon_match.value) + self.l.setAlternativeRecordMatching(config.recording.record_icon_match.value == "Sref + stream url") self.root = None self.mode = self.MODE_NORMAL From bb54282e1ef3396e12ddb33cd41b0f38efd8258d Mon Sep 17 00:00:00 2001 From: Ev0-BH Date: Wed, 6 Dec 2023 00:00:46 +0000 Subject: [PATCH 307/401] [ServiceList/setup.xml] Fix correct order for record_icon_match_value --- data/setup.xml | 2 +- lib/python/Components/ServiceList.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/setup.xml b/data/setup.xml index 1e71a1d121e..b32813e5b99 100644 --- a/data/setup.xml +++ b/data/setup.xml @@ -234,7 +234,7 @@ config.recording.keep_finished_timer_logs config.recording.offline_decode_delay config.recording.ecm_data - config.recording.record_icon_match + config.recording.record_icon_match config.usage.hdd_standby diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 2388ddd76e1..ee31b1dece9 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -67,7 +67,7 @@ def __init__(self, serviceList): pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, "icons/ico_altref-fs8.png")) pic and self.l.setPixmap(self.l.picBackup, pic) - self.l.setAlternativeRecordMatching(config.recording.record_icon_match.value == "Sref + stream url") + self.l.setAlternativeRecordMatching(config.recording.record_icon_match.value == "Sref only") self.root = None self.mode = self.MODE_NORMAL From 4ec6bfcf3bbc75f19574de9c42f24ba2c3841d22 Mon Sep 17 00:00:00 2001 From: openvix-build Date: Wed, 6 Dec 2023 01:31:27 +0000 Subject: [PATCH 308/401] openvix: developer 6.4.010.016 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index b3fe77ec250..d120c9b1221 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1214,3 +1214,4 @@ openvix: developer 6.4.010.012 openvix: developer 6.4.010.013 openvix: developer 6.4.010.014 openvix: developer 6.4.010.015 +openvix: developer 6.4.010.016 From e5c9917d3bb7ea260bdb9a9b70039d0b9a3e1e7b Mon Sep 17 00:00:00 2001 From: Orlandoxx <95180049+Orlandoxx@users.noreply.github.com> Date: Wed, 6 Dec 2023 06:38:11 +0200 Subject: [PATCH 309/401] Updated Finnish (fi.po) translation. Latest 'setup.xml' changes. --- po/fi.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/po/fi.po b/po/fi.po index 0e745a7d5ce..4a260ba6963 100644 --- a/po/fi.po +++ b/po/fi.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: enigma2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-27 23:35+0000\n" -"PO-Revision-Date: 2023-12-05 07:08+0200\n" +"PO-Revision-Date: 2023-12-06 06:36+0200\n" "Last-Translator: Orlandox\n" "Language-Team: timoj/Kojo/Samzam/Orlandox\n" "Language: fi\n" @@ -13540,7 +13540,7 @@ msgstr "" "Suomenkielinen käännös: timoj, Kojo, Samzam, Orlandox\n" "\n" "Ylläpito : Orlandox\n" -"05.12.2023\n" +"06.12.2023\n" "http://www.huoltovalikko.com" msgid "TS file is too large for ISO9660 level 1!" @@ -19157,8 +19157,8 @@ msgstr "Toista kanava ilman striimin välitystä" msgid "Record icon match" msgstr "Tallennuskuvakkeen vastine" -msgid "Select display of record icon based on 'sref only' or 'Sref + stream url' where applicable." -msgstr "Valitse tallennuskuvakkeen näyttö 'vain sref' tai 'Sref + striimin url' perusteella, jos mahdollista." +msgid "Select display of record icon based on 'Sref only' or 'Sref + Stream url' where applicable." +msgstr "Valitse tallennuskuvakkeen näyttö 'vain Sref' tai 'Sref + striimin url' perusteella, jos mahdollista." msgid "Sref only" msgstr "Vain Sref" From c2c4193802bf2d2afa9d2b4572f8e436eae8615a Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Wed, 6 Dec 2023 23:21:05 +0200 Subject: [PATCH 310/401] [Fixed] Not working selectionPixmap for ServiceList --- lib/gui/elistbox.cpp | 5 +++++ lib/gui/elistbox.h | 3 ++- lib/python/Components/ServiceList.py | 16 ---------------- lib/python/skin.py | 5 ++++- lib/service/listboxservice.cpp | 16 +++++++++------- 5 files changed, 20 insertions(+), 25 deletions(-) diff --git a/lib/gui/elistbox.cpp b/lib/gui/elistbox.cpp index 66d07d0006a..06b5f949deb 100644 --- a/lib/gui/elistbox.cpp +++ b/lib/gui/elistbox.cpp @@ -914,6 +914,11 @@ void eListbox::setSelectionPicture(ePtr &pm) m_style.m_selection = pm; } +void eListbox::setSelectionPictureLarge(ePtr &pm) +{ + m_style.m_selection_large = pm; +} + void eListbox::setSelectionBorderHidden() { m_style.m_border_set = 1; diff --git a/lib/gui/elistbox.h b/lib/gui/elistbox.h index 5157830900b..a96c4b9aad9 100644 --- a/lib/gui/elistbox.h +++ b/lib/gui/elistbox.h @@ -62,7 +62,7 @@ class iListboxContent: public iObject #ifndef SWIG struct eListboxStyle { - ePtr m_background, m_selection; + ePtr m_background, m_selection, m_selection_large; int m_transparent_background; int m_border_set; gRGB m_background_color, m_background_color_selected, m_foreground_color, m_foreground_color_selected, m_border_color; @@ -166,6 +166,7 @@ class eListbox: public eWidget void setBorderWidth(int size); void setBackgroundPicture(ePtr &pixmap); void setSelectionPicture(ePtr &pixmap); + void setSelectionPictureLarge(ePtr &pixmap); void setSelectionBorderHidden(); void setFont(gFont *font); diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index ee31b1dece9..8991c546fa6 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -220,12 +220,6 @@ def sidesMargin(value): def textSeparator(value): self.l.setTextSeparator(value) - def selectionPixmap(value): - self.selectionPixmapSingle = value - - def selectionPixmapLarge(value): - self.selectionPixmapDouble = value - def itemHeightTwoLine(value): self.ItemHeightTwoLine = parseScale(value) self.ItemHeightTwoLineSkin = self.ItemHeightTwoLine @@ -490,16 +484,6 @@ def setMode(self, mode): self.l.setItemHeight(self.ItemHeight if two_lines_val == 0 else self.ItemHeightTwoLine) self.l.setVisualMode(eListboxServiceContent.visModeComplex if two_lines_val == 0 else eListboxServiceContent.visSkinDefined) - pic = None - if two_lines_val: - if self.selectionPixmapDouble: - pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, self.selectionPixmapDouble)) - else: - if self.selectionPixmapSingle: - pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, self.selectionPixmapSingle)) - - pic and hasattr(self.l, "setSelectionPicture") and self.l.setSelectionPicture(pic) - if config.usage.service_icon_enable.value: self.l.setGetPiconNameFunc(getPiconName) else: diff --git a/lib/python/skin.py b/lib/python/skin.py index 2098834cb92..49ddf01cc47 100644 --- a/lib/python/skin.py +++ b/lib/python/skin.py @@ -393,7 +393,7 @@ def loadPixmap(path, desktop, width=0, height=0): return pixmap -def collectAttributes(skinAttributes, node, context, skinPath=None, ignore=(), filenames=frozenset(("pixmap", "pointer", "seek_pointer", "backgroundPixmap", "selectionPixmap", "sliderPixmap", "scrollbarSliderPicture", "scrollbarbackgroundPixmap", "scrollbarBackgroundPicture"))): +def collectAttributes(skinAttributes, node, context, skinPath=None, ignore=(), filenames=frozenset(("pixmap", "pointer", "seek_pointer", "backgroundPixmap", "selectionPixmap", "selectionPixmapLarge", "sliderPixmap", "scrollbarSliderPicture", "scrollbarbackgroundPixmap", "scrollbarBackgroundPicture"))): size = None pos = None font = None @@ -517,6 +517,9 @@ def backgroundPixmap(self, value): def selectionPixmap(self, value): self.guiObject.setSelectionPicture(loadPixmap(value, self.desktop)) + def selectionPixmapLarge(self, value): + self.guiObject.setSelectionPictureLarge(loadPixmap(value, self.desktop)) + def sliderPixmap(self, value): self.guiObject.setScrollbarPixmap(loadPixmap(value, self.desktop)) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 91a971a9cf0..edf62660e5d 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -36,8 +36,7 @@ void join(const std::vector& v, char c, std::string& s) { } bool compareServices(const eServiceReference &ref1, const eServiceReference &ref2, bool alternativeMatching) { - eServiceReference r_i = ref1; - std::vector ref_split = split(r_i.toString(), ":"); + std::vector ref_split = split(ref1.toString(), ":"); std::vector s_split = split(ref2.toString(), ":"); if (ref_split[1] == "7" || s_split[1] == "7") { @@ -64,7 +63,7 @@ bool compareServices(const eServiceReference &ref1, const eServiceReference &ref std::vector sr_split = split(url_sr, "/"); std::string ref_orig = sr_split.back(); ref_orig = replace_all(ref_orig, "%3a", ":"); - return r_i.toString() == ref_orig; + return ref1.toString() == ref_orig; } return false; @@ -770,19 +769,22 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const { if (local_style->m_background) painter.blit(local_style->m_background, offset, eRect(), gPainter::BT_ALPHABLEND); - else if (selected && !local_style->m_selection) + else if (selected && !local_style->m_selection && !local_style->m_selection_large) painter.clear(); } if (cursorValid()) { - if (selected && local_style && local_style->m_selection) + if (selected && local_style && local_style->m_selection && m_visual_mode != visSkinDefined){ painter.blit(local_style->m_selection, offset, eRect(), gPainter::BT_ALPHABLEND); + } + if (selected && local_style && local_style->m_selection_large && m_visual_mode == visSkinDefined){ + painter.blit(local_style->m_selection_large, offset, eRect(), gPainter::BT_ALPHABLEND); + } // Draw the frame for selected item here so to be under the content - if (selected && (!local_style || !local_style->m_selection)) + if (selected && (!local_style || (!local_style->m_selection && !local_style->m_selection_large))) style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry); - eServiceReference ref = *m_cursor; std::string orig_ref_str = ref.toString(); std::string service_res_str = toLower(split(orig_ref_str, ":")[2]); From 2ff80802ee3475813e6b91273a07f42fa012aa0d Mon Sep 17 00:00:00 2001 From: Tony Whalley Date: Thu, 7 Dec 2023 15:30:23 +0100 Subject: [PATCH 311/401] Softcam - rename menu to Softcam Management and move Softcam Script into this menu --- data/menu.xml | 10 ++++------ lib/python/Plugins/SystemPlugins/ViX/plugin.py | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/data/menu.xml b/data/menu.xml index 461f5bb8e76..f75119f78aa 100644 --- a/data/menu.xml +++ b/data/menu.xml @@ -144,17 +144,15 @@ self.session.open(SABnzbdSetupScreen) - - + + - + + - - - diff --git a/lib/python/Plugins/SystemPlugins/ViX/plugin.py b/lib/python/Plugins/SystemPlugins/ViX/plugin.py index 46b12e0a5e2..b0353113d59 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/plugin.py +++ b/lib/python/Plugins/SystemPlugins/ViX/plugin.py @@ -101,7 +101,7 @@ def SoftcamMenu(session, **kwargs): def SoftcamSetup(menuid): if menuid == "cam": - return [(_("Softcam manager"), SoftcamMenu, "softcamsetup", 1005)] + return [(_("Softcam Manager"), SoftcamMenu, "softcamsetup", 1005)] return [] From 874199edb797ef280ff68f3b6a8fc578b1265db5 Mon Sep 17 00:00:00 2001 From: Tony Whalley Date: Thu, 7 Dec 2023 15:35:10 +0100 Subject: [PATCH 312/401] [Element] - occasionally when running ImageManager there is no __suspended attribute on entry - so catch and report, this can catch other issues --- lib/python/Components/Element.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/lib/python/Components/Element.py b/lib/python/Components/Element.py index 80e11fa8c12..656d8c170ed 100644 --- a/lib/python/Components/Element.py +++ b/lib/python/Components/Element.py @@ -95,17 +95,20 @@ def changed(self, *args, **kwargs): x() def setSuspend(self, suspended): - changed = self.__suspended != suspended - if not self.__suspended and suspended: - self.doSuspend(1) - elif self.__suspended and not suspended: - self.doSuspend(0) - - self.__suspended = suspended - if changed: - for s in self.sources: - s.checkSuspend() - + try: + changed = self.__suspended != suspended + except AttributeError: + print("[Element][setSuspend]self.__suspended - No attribute __suspended") + else: + if not self.__suspended and suspended: + self.doSuspend(1) + elif self.__suspended and not suspended: + self.doSuspend(0) + + self.__suspended = suspended + if changed: + for s in self.sources: + s.checkSuspend() suspended = property(lambda self: self.__suspended, setSuspend) def checkSuspend(self): From 19653b44ae04aa5164ccd255ed6c76c82319f16c Mon Sep 17 00:00:00 2001 From: Tony Whalley Date: Thu, 7 Dec 2023 15:53:24 +0100 Subject: [PATCH 313/401] [TaskView] - while running ImageManager - crash at end of Backup in TaskView - so add a sanity check to prevent key_blue crash --- lib/python/Screens/TaskView.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/python/Screens/TaskView.py b/lib/python/Screens/TaskView.py index 1620dc71a69..0a70c12a6e5 100644 --- a/lib/python/Screens/TaskView.py +++ b/lib/python/Screens/TaskView.py @@ -121,9 +121,10 @@ def state_changed(self): self["summary_job_task"].text = j.getStatustext() if j.status in (j.FINISHED, j.FAILED): self.performAfterEvent() - self.backgroundable = False - self["key_blue"].setText("") - self["backgroundActions"].setEnabled(False) + if self.backgroundable: + self.backgroundable = False + self["key_blue"].setText("") + self["backgroundActions"].setEnabled(False) if j.status == j.FINISHED: self["key_green"].setText(_("OK")) self["okActions"].setEnabled(True) @@ -160,7 +161,7 @@ def performAfterEvent(self): return elif self.settings.afterEvent.value == "close" and self.job.status == self.job.FINISHED: self.close(False) - if self.settings.afterEvent.value == "deepstandby": + elif self.settings.afterEvent.value == "deepstandby": if not Screens.Standby.inTryQuitMainloop: Tools.Notifications.AddNotificationWithCallback(self.sendTryQuitMainloopNotification, MessageBox, _("A sleep timer wants to shut down\nyour %s %s. Proceed?") % (getMachineBrand(), getMachineName()), timeout=20) elif self.settings.afterEvent.value == "standby": From 21dc17f7766f908fe680e7b55795a5c5de7fadce Mon Sep 17 00:00:00 2001 From: Atef <31848885+atefganm@users.noreply.github.com> Date: Thu, 7 Dec 2023 19:09:29 +0300 Subject: [PATCH 314/401] whitespace cleanup --- lib/service/listboxservice.cpp | 32 ++++++++++++++++---------------- lib/service/listboxservice.h | 2 +- lib/service/servicedvb.cpp | 6 +++--- lib/service/servicedvd.cpp | 2 +- lib/service/servicets.cpp | 2 +- lib/service/servicewebts.cpp | 2 +- 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index edf62660e5d..e381991284a 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -262,13 +262,13 @@ int eListboxServiceContent::getPrevMarkerPos() if (i->flags == eServiceReference::isMarker) break; } - + //eDebug("[eListboxServiceContent] prevMarkerIndex= %i; curSelIndex= %i; index= %i", cursorResolve(prevMarkerIndex), cursorResolve(m_cursor_number), index); // if currently selected service is not the first after the marker found - return the found marker index if (cursorResolve(index) + 1 != cursorResolve(m_cursor_number)) return cursorResolve(index); - + while (index) { --i; @@ -276,7 +276,7 @@ int eListboxServiceContent::getPrevMarkerPos() if (i->flags == eServiceReference::isMarker) break; } - + return cursorResolve(index); } @@ -690,7 +690,7 @@ bool eListboxServiceContent::checkServiceIsRecorded(eServiceReference ref) else { if (compareServices(ref, it->second, m_alternative_record_match)) return true; - } + } } return false; } @@ -788,7 +788,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const eServiceReference ref = *m_cursor; std::string orig_ref_str = ref.toString(); std::string service_res_str = toLower(split(orig_ref_str, ":")[2]); - + bool isBackupAvailable = false; int catchUpDays = 0; if (orig_ref_str.find("@") != std::string::npos) { @@ -798,7 +798,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (orig_ref_str.find("|<|") != std::string::npos) { catchUpDays = std::stoi(split(split(orig_ref_str, "|<|")[1], "@")[0]); } - + /* get service information */ ePtr service_info; m_service_center->info(ref, service_info); @@ -866,9 +866,9 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const yoffs = 5; } if (!isMarker && !isDirectory) { - ePtr &pixmap = service_res_str == "1f" ? m_pixmaps[pic4K] : (service_res_str == "19" || service_res_str == "11") ? + ePtr &pixmap = service_res_str == "1f" ? m_pixmaps[pic4K] : (service_res_str == "19" || service_res_str == "11") ? m_pixmaps[picHD] : m_pixmaps[picSD]; - + if (pixmap) { eSize pixmap_size = pixmap->size(); @@ -963,7 +963,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } } xoffs = xoffset + 16; - + if (hasPicon) { eRect piconArea = eRect(xoffs, offset.y(), 125, m_itemheight); @@ -1026,7 +1026,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const eSize pixmap_size = pixmap_mDir->size(); if (pixmap_size.width() < 125 || pixmap_size.height() < m_itemheight) xoffsMarker = xoffs + pixmap_size.width() + 16; - } + } } ePtr para = new eTextPara(eRect(0, 0, xlpos - xoffsMarker, m_itemheight/2)); @@ -1035,7 +1035,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const eRect bbox = para->getBoundBox(); painter.renderPara(para, ePoint(xoffsMarker - correction, offset.y() + yoffs + ((ctrlHeight - bbox.height())/2))); - + if (isDirectory || (isMarker && !m_marker_as_line)) { if (pixmap_mDir) { eSize pixmap_size = pixmap_mDir->size(); @@ -1059,7 +1059,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const eRect secondLineRect = eRect(secondLineOffset, offset.y() + (m_itemheight - m_marker_as_line) / 2, m_itemsize.width() - secondLineOffset - 16 - 8, m_marker_as_line); painter.fill(secondLineRect); } - + // event name if (is_event) @@ -1069,7 +1069,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const event_duration = evt->getDuration(); int timeLeft = event_begin + event_duration - now; eRect progressBarRect = m_element_position[celServiceEventProgressbar]; - + if (!event_name.empty()) { //--------------------------------------------------- Event Progressbar ----------------------------------------------------------------- @@ -1174,7 +1174,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } } } else { - + // Single line mode goes here if (service_info) service_info->getName(ref, text); @@ -1393,7 +1393,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (m_crypto_icon_mode == 2 && m_pixmaps[picCrypto] && service_info && service_info->isCrypted()) { pixmap_crypto_size = m_pixmaps[picCrypto]->size(); - iconRecordPosX += pixmap_crypto_size.width() + m_items_distances; + iconRecordPosX += pixmap_crypto_size.width() + m_items_distances; iconOffsX += pixmap_crypto_size.width() + m_items_distances; xoffs = iconOffsX; } @@ -1537,7 +1537,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } } } - } + } } painter.clippop(); } \ No newline at end of file diff --git a/lib/service/listboxservice.h b/lib/service/listboxservice.h index c06c167507b..35f52659087 100644 --- a/lib/service/listboxservice.h +++ b/lib/service/listboxservice.h @@ -113,7 +113,7 @@ class eListboxServiceContent: public virtual iListboxContent void setTextSeparator(const std::string &string) { m_separator = string; } void setMarkerTextAlignment(const std::string &string) { m_marker_alignment = string; } // currently supports left and center - void setMarkerLineColor(const gRGB &col) { + void setMarkerLineColor(const gRGB &col) { m_markerline_color = col; m_markerline_color_set = 1; } diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index 92440046aa9..af3d3f68d90 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -2487,7 +2487,7 @@ bool eDVBServiceBase::tryFallbackTuner(eServiceReferenceDVB &service, bool &is_s service = eServiceReferenceDVB(remote_service_ref.str()); is_stream = true; - + // m_is_streamx = true; // used by decoder.cpp to stop tuxtxt logging on text pid for streams return true; @@ -3097,7 +3097,7 @@ void eDVBServicePlay::updateDecoder(bool sendSeekableStateChanged) { selectAudioStream(); } - + if (!(m_is_pvr || m_is_stream || m_timeshift_active)) m_decoder->setSyncPCR(pcrpid); else @@ -3644,7 +3644,7 @@ void eDVBServicePlay::newDVBSubtitlePage(const eDVBSubtitlePage &p) // Where subtitles are delivered out of sync with video, only treat subtitles in the past as having bad timing. // Those that are delivered too early are cached for displaying at the appropriate later time - // Note that this can be due to buggy drivers, as well as problems with the broadcast + // Note that this can be due to buggy drivers, as well as problems with the broadcast if (pos-p.m_show_time > 1800000 && (m_is_pvr || m_timeshift_enabled)) { // Subtitles delivered over 20 seconds too late diff --git a/lib/service/servicedvd.cpp b/lib/service/servicedvd.cpp index 707e0b54475..f00856221d9 100644 --- a/lib/service/servicedvd.cpp +++ b/lib/service/servicedvd.cpp @@ -1120,7 +1120,7 @@ void eServiceDVD::saveCuesheet() if (stat("/home/root", &st) == 0 && stat(filename.c_str(), &st) != 0) if (mkdir(filename.c_str(), 0755)) return; // cannot create directory so no point in trying to save cue data - + filename += "/"; if (m_ddvd_titlestring[0] != '\0') filename += m_ddvd_titlestring; diff --git a/lib/service/servicets.cpp b/lib/service/servicets.cpp index 419e6509e07..5131e868acd 100644 --- a/lib/service/servicets.cpp +++ b/lib/service/servicets.cpp @@ -258,7 +258,7 @@ RESULT eServiceTS::start() m_streamthread = new eStreamThread(); CONNECT(m_streamthread->m_event, eServiceTS::recv_event); m_decoder->pause(); - if (unpause() != 0) + if (unpause() != 0) return -1; m_event(this, evStart); return 0; diff --git a/lib/service/servicewebts.cpp b/lib/service/servicewebts.cpp index d4f027f83a9..552d20dd6fe 100644 --- a/lib/service/servicewebts.cpp +++ b/lib/service/servicewebts.cpp @@ -383,7 +383,7 @@ void eServiceWebTS::recv_event(int evt) m_decoder->pause(); m_event(this, evStart); m_decoder->play(); - + } bool wasnull = !m_audioInfo; m_streamthread->getAudioInfo(m_audioInfo); From 30e66803ebb632fd261ff8e162c61e39193f497c Mon Sep 17 00:00:00 2001 From: Huevos Date: Thu, 7 Dec 2023 21:29:01 +0100 Subject: [PATCH 315/401] [listboxservice] whitespace --- lib/service/listboxservice.cpp | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index e381991284a..5cd3f8db1dc 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -265,8 +265,8 @@ int eListboxServiceContent::getPrevMarkerPos() //eDebug("[eListboxServiceContent] prevMarkerIndex= %i; curSelIndex= %i; index= %i", cursorResolve(prevMarkerIndex), cursorResolve(m_cursor_number), index); - // if currently selected service is not the first after the marker found - return the found marker index - if (cursorResolve(index) + 1 != cursorResolve(m_cursor_number)) return cursorResolve(index); + // if currently selected service is not the first after the marker found - return the found marker index + if (cursorResolve(index) + 1 != cursorResolve(m_cursor_number)) return cursorResolve(index); while (index) @@ -1324,28 +1324,28 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const (orbpos == 0xFFFF) ? m_pixmaps[picDVB_C] : (orbpos == 0xEEEE) ? m_pixmaps[picDVB_T] : m_pixmaps[picDVB_S]; - + eSize pixmap_system_size = eSize(); eSize pixmap_crypto_size = eSize(); eSize pixmap_rec_size = eSize(); if (m_servicetype_icon_mode == 1 && pixmap_system) { pixmap_system_size = pixmap_system->size(); iconCryptoPosX += pixmap_system_size.width() + m_items_distances; - iconRecordPosX = iconCryptoPosX; + iconRecordPosX = iconCryptoPosX; iconOffsX += pixmap_system_size.width() + m_items_distances; } - + if (m_crypto_icon_mode == 1 && m_pixmaps[picCrypto]) { pixmap_crypto_size = m_pixmaps[picCrypto]->size(); - iconRecordPosX += pixmap_crypto_size.width() + m_items_distances; + iconRecordPosX += pixmap_crypto_size.width() + m_items_distances; iconOffsX += pixmap_crypto_size.width() + m_items_distances; } - + if (isRecorded && m_record_indicator_mode == 1 && m_pixmaps[picRecord]) { pixmap_rec_size = m_pixmaps[picRecord]->size(); - iconOffsX += pixmap_rec_size.width() + m_items_distances; + iconOffsX += pixmap_rec_size.width() + m_items_distances; } if (m_servicetype_icon_mode == 1 && pixmap_system) { @@ -1385,12 +1385,12 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (m_servicetype_icon_mode == 2 && pixmap_system) { pixmap_system_size = pixmap_system->size(); iconCryptoPosX += pixmap_system_size.width() + m_items_distances; - iconRecordPosX = iconCryptoPosX; + iconRecordPosX = iconCryptoPosX; iconOffsX += pixmap_system_size.width() + m_items_distances; xoffs = iconOffsX; } - + if (m_crypto_icon_mode == 2 && m_pixmaps[picCrypto] && service_info && service_info->isCrypted()) { pixmap_crypto_size = m_pixmaps[picCrypto]->size(); iconRecordPosX += pixmap_crypto_size.width() + m_items_distances; @@ -1398,11 +1398,11 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const xoffs = iconOffsX; } - + if (isRecorded && m_record_indicator_mode == 2 && m_pixmaps[picRecord]) { pixmap_rec_size = m_pixmaps[picRecord]->size(); iconOffsX += pixmap_rec_size.width() + m_items_distances; - xoffs = iconOffsX; + xoffs = iconOffsX; } @@ -1463,7 +1463,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } } - int eventTextWidth = (eventProgressConfig == "barright" || eventProgressConfig == "percright") ? + int eventTextWidth = (eventProgressConfig == "barright" || eventProgressConfig == "percright") ? (pb_xpos - xoffs - m_items_distances*2 ) : (m_itemsize.width() - m_sides_margin*2 - xoffs - m_items_distances*2); ePtr para = new eTextPara(eRect(0, 0, eventTextWidth, m_itemheight)); @@ -1521,11 +1521,11 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const painter.setForegroundColor(m_color[eventForegroundSelected]); else painter.setForegroundColor(gRGB(0x787878)); - + if (isRecorded && m_record_indicator_mode == 3) { painter.setForegroundColor(m_color[serviceRecorded]); } - + char buffer[15]; snprintf(buffer, sizeof(buffer), "%d %%", (int)(100 * (now - event_begin) / event_duration)); std::string percent = buffer; From 126035319f735571c3afea4e2ef88061ba6f061e Mon Sep 17 00:00:00 2001 From: Tony Whalley Date: Fri, 8 Dec 2023 10:21:13 +0100 Subject: [PATCH 316/401] [Videomode] - fps not reset on change whem Video settings Refresh rate set to Multi --- lib/python/Screens/VideoMode.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/lib/python/Screens/VideoMode.py b/lib/python/Screens/VideoMode.py index 8a8a642327a..41b8614e0b4 100644 --- a/lib/python/Screens/VideoMode.py +++ b/lib/python/Screens/VideoMode.py @@ -1,5 +1,5 @@ from os import path - +from boxbranding import getBoxType from enigma import iPlayableService, iServiceInformation, eTimer, eServiceCenter, eServiceReference, eDVBDB from Screens.Screen import Screen @@ -19,7 +19,7 @@ resolutionlabel = None previous = None isDedicated3D = False - +videomode = "/proc/stb/video/videomode_50hz" if getBoxType() in ("gbquad4k", "gbue4k") else "/proc/stb/video/videomode" class VideoSetup(ConfigListScreen, Screen): def __init__(self, session): @@ -297,7 +297,7 @@ def VideoChangeDetect(self): config_res = str(config.av.videomode[config_port].value[:-1]).replace("\n", "") config_pol = str(config.av.videomode[config_port].value[-1:]).replace("\n", "") config_rate = str(config.av.videorate[config_mode].value).replace("Hz", "").replace("\n", "") - with open("/proc/stb/video/videomode", "r") as fd: + with open(videomode, "r+") as fd: # GB4K can fail on initial open as r current_mode = fd.read()[:-1].replace("\n", "") if current_mode.upper() in ("PAL", "NTSC"): current_mode = current_mode.upper() @@ -330,11 +330,7 @@ def VideoChangeDetect(self): except Exception: pass if not video_height or not video_width or not video_pol or not video_rate: - service = self.session.nav.getCurrentService() - if service is not None: - info = service.info() - else: - info = None + info = None if self.session.nav.getCurrentService() is None else self.session.nav.getCurrentService().info() if info: video_height = int(info.getInfo(iServiceInformation.sVideoHeight)) video_width = int(info.getInfo(iServiceInformation.sVideoWidth)) @@ -428,9 +424,11 @@ def VideoChangeDetect(self): new_mode = config.av.autores_2160p30.value write_mode = new_mode else: + if video_rate == 25000: # videomode_25hz is not in proc and will be reset 2nd pass thru , so do it now. + new_rate = 50 if path.exists("/proc/stb/video/videomode_%shz" % new_rate) and config_rate == "multi": try: - with open("/proc/stb/video/videomode_%shz" % new_rate, "r") as fd: + with open("/proc/stb/video/videomode_%shz" % new_rate, "r+") as fd: multi_videomode = fd.read().replace("\n", "") if multi_videomode and (current_mode != multi_videomode): write_mode = multi_videomode @@ -442,8 +440,8 @@ def VideoChangeDetect(self): resolutionlabel["restxt"].setText(_("Video mode: %s") % write_mode) if config.av.autores.value != "disabled" and config.av.autores_label_timeout.value != "0": resolutionlabel.show() - print("[VideoMode] setMode - port: %s, mode: %s" % (config_port, write_mode)) - with open("/proc/stb/video/videomode", "w") as fd: + print("[VideoMode] setMode - port: %s, mode: %s" % (config.av.videoport.value, write_mode)) + with open(videomode, "w+") as fd: fd.write(write_mode) iAV.setAspect(config.av.aspect) iAV.setWss(config.av.wss) From 614d0f89de90e2f5df8f61dfbc32359ac2e89403 Mon Sep 17 00:00:00 2001 From: Tony Whalley Date: Fri, 8 Dec 2023 10:25:30 +0100 Subject: [PATCH 317/401] [Videomode] - fix possible key error, sequence imports --- lib/python/Screens/VideoMode.py | 64 +++++++++++++++++---------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/lib/python/Screens/VideoMode.py b/lib/python/Screens/VideoMode.py index 41b8614e0b4..34472fca482 100644 --- a/lib/python/Screens/VideoMode.py +++ b/lib/python/Screens/VideoMode.py @@ -2,19 +2,19 @@ from boxbranding import getBoxType from enigma import iPlayableService, iServiceInformation, eTimer, eServiceCenter, eServiceReference, eDVBDB -from Screens.Screen import Screen -from Screens.ChannelSelection import FLAG_IS_DEDICATED_3D from Components.ActionMap import ActionMap -from Components.SystemInfo import SystemInfo -from Components.ConfigList import ConfigListScreen +from Components.AVSwitch import iAVSwitch as iAV from Components.config import config, configfile, getConfigListEntry +from Components.ConfigList import ConfigListScreen from Components.Label import Label from Components.Pixmap import Pixmap -from Components.Sources.Boolean import Boolean from Components.ServiceEventTracker import ServiceEventTracker +from Components.Sources.Boolean import Boolean +from Components.SystemInfo import SystemInfo +from Screens.ChannelSelection import FLAG_IS_DEDICATED_3D +from Screens.Screen import Screen from Tools.Directories import isPluginInstalled from Tools.HardwareInfo import HardwareInfo -from Components.AVSwitch import iAVSwitch as iAV resolutionlabel = None previous = None @@ -293,10 +293,18 @@ def VideoChanged(self): def VideoChangeDetect(self): global resolutionlabel config_port = config.av.videoport.value - config_mode = str(config.av.videomode[config_port].value).replace("\n", "") - config_res = str(config.av.videomode[config_port].value[:-1]).replace("\n", "") - config_pol = str(config.av.videomode[config_port].value[-1:]).replace("\n", "") - config_rate = str(config.av.videorate[config_mode].value).replace("Hz", "").replace("\n", "") + print("[VideoMode][VideoChangeDetect] config.av.videomode keys", list(config.av.videomode.keys())) + try: + config_mode = str(config.av.videomode[config_port].value).replace("\n", "") + config_res = str(config.av.videomode[config_port].value[:-1]).replace("\n", "") + config_pol = str(config.av.videomode[config_port].value[-1:]).replace("\n", "") + config_rate = str(config.av.videorate[config_mode].value).replace("Hz", "").replace("\n", "") + print("[VideoMode][VideoChangeDetect] config_port, config_mode, config_res, config_pol, config_rate", config_port, " ", config_mode, " ", config_res, " ", config_pol, " ", config_rate) + except KeyError as e: + print("[VideoMode][VideoChangeDetect] config_port Keyerror use current values", e) + self.delay = False + self.detecttimer.stop() + return with open(videomode, "r+") as fd: # GB4K can fail on initial open as r current_mode = fd.read()[:-1].replace("\n", "") if current_mode.upper() in ("PAL", "NTSC"): @@ -305,30 +313,26 @@ def VideoChangeDetect(self): video_width = None video_pol = None video_rate = None - if path.exists("/proc/stb/vmpeg/0/yres"): + try: with open("/proc/stb/vmpeg/0/yres", "r") as fd: - try: - video_height = int(fd.read(), 16) - except Exception: - pass - if path.exists("/proc/stb/vmpeg/0/xres"): + video_height = int(fd.read(), 16) + except Exception: + pass + try: with open("/proc/stb/vmpeg/0/xres", "r") as fd: - try: - video_width = int(fd.read(), 16) - except Exception: - pass - if path.exists("/proc/stb/vmpeg/0/progressive"): + video_width = int(fd.read(), 16) + except Exception: + pass + try: with open("/proc/stb/vmpeg/0/progressive", "r") as fd: - try: - video_pol = "p" if int(fd.read(), 16) else "i" - except Exception: - pass - if path.exists("/proc/stb/vmpeg/0/framerate"): + video_pol = "p" if int(fd.read(), 16) else "i" + except Exception: + pass + try: with open("/proc/stb/vmpeg/0/framerate", "r") as fd: - try: - video_rate = int(fd.read()) - except Exception: - pass + video_rate = int(fd.read()) + except Exception: + pass if not video_height or not video_width or not video_pol or not video_rate: info = None if self.session.nav.getCurrentService() is None else self.session.nav.getCurrentService().info() if info: From 6fef39d100cbc17d2a3c687c65eda2ada58fc5fd Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Fri, 8 Dec 2023 09:28:04 +0000 Subject: [PATCH 318/401] PEP8 double aggressive E301 ~ E306 --- lib/python/Screens/VideoMode.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/python/Screens/VideoMode.py b/lib/python/Screens/VideoMode.py index 34472fca482..a8c1f3ca76d 100644 --- a/lib/python/Screens/VideoMode.py +++ b/lib/python/Screens/VideoMode.py @@ -21,6 +21,7 @@ isDedicated3D = False videomode = "/proc/stb/video/videomode_50hz" if getBoxType() in ("gbquad4k", "gbue4k") else "/proc/stb/video/videomode" + class VideoSetup(ConfigListScreen, Screen): def __init__(self, session): Screen.__init__(self, session) From e07c01b27ffd2257ea0f8ca463688df1807f4138 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Fri, 8 Dec 2023 09:28:14 +0000 Subject: [PATCH 319/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Screens/VideoMode.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Screens/VideoMode.py b/lib/python/Screens/VideoMode.py index a8c1f3ca76d..c754884026d 100644 --- a/lib/python/Screens/VideoMode.py +++ b/lib/python/Screens/VideoMode.py @@ -429,7 +429,7 @@ def VideoChangeDetect(self): new_mode = config.av.autores_2160p30.value write_mode = new_mode else: - if video_rate == 25000: # videomode_25hz is not in proc and will be reset 2nd pass thru , so do it now. + if video_rate == 25000: # videomode_25hz is not in proc and will be reset 2nd pass thru , so do it now. new_rate = 50 if path.exists("/proc/stb/video/videomode_%shz" % new_rate) and config_rate == "multi": try: From cc99fa9cf07e75cdd25e01b95dd354f125c72e01 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Wed, 6 Dec 2023 18:31:50 +0200 Subject: [PATCH 320/401] [Fixed] [ServiceList] Column mode --- lib/service/listboxservice.cpp | 65 ++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 5cd3f8db1dc..f776ce7e4bf 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -785,6 +785,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const // Draw the frame for selected item here so to be under the content if (selected && (!local_style || (!local_style->m_selection && !local_style->m_selection_large))) style.drawFrame(painter, eRect(offset, m_itemsize), eWindowStyle::frameListboxEntry); + eServiceReference ref = *m_cursor; std::string orig_ref_str = ref.toString(); std::string service_res_str = toLower(split(orig_ref_str, ":")[2]); @@ -843,7 +844,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const painter.setForegroundColor(gRGB(0xb40431)); } - int xoffset=0, xoffs=0; // used as offset when painting the folder/marker symbol or the serviceevent progress + int xoffset=0, xoffs=0, xoffs_col=0; // used as offset when painting the folder/marker symbol or the serviceevent progress int nameLeft=0, nameWidth=0, nameYoffs=0, nextYoffs=0; // used as temporary values for 'show two lines' option if (m_separator == "") m_separator = " "; @@ -1186,11 +1187,46 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const event_begin = evt->getBeginTime(); event_duration = evt->getDuration(); } + int orbpos = m_cursor->getUnsignedData(4) >> 16; + const char *filename = ref.path.c_str(); + + ePtr &pixmap_system = + (m_cursor->flags & eServiceReference::isGroup) ? m_pixmaps[picServiceGroup] : + (strstr(filename, "://")) ? m_pixmaps[picStream] : + (orbpos == 0xFFFF) ? m_pixmaps[picDVB_C] : + (orbpos == 0xEEEE) ? m_pixmaps[picDVB_T] : m_pixmaps[picDVB_S]; + + eSize pixmap_system_size = eSize(); + eSize pixmap_crypto_size = eSize(); + eSize pixmap_rec_size = eSize(); + + if (pixmap_system) { + pixmap_system_size = pixmap_system->size(); + } + + + if (m_pixmaps[picCrypto]) { + pixmap_crypto_size = m_pixmaps[picCrypto]->size(); + } + + + if (m_pixmaps[picRecord]) { + pixmap_rec_size = m_pixmaps[picRecord]->size(); + } + bool hasPicons = PyCallable_Check(m_GetPiconNameFunc); bool isAlternativeNumberingMode = m_alternative_numbering; std::string eventProgressConfig = m_progress_mode; + int serviceNameWidth = m_column_width > 0 && !isDirectory && !isMarker ? m_column_width : m_itemsize.width(); + bool shouldCorrect = serviceNameWidth >= m_column_width - pixmap_system_size.width()*3; + + if (m_servicetype_icon_mode == 2 && m_column_width > 0 && shouldCorrect) serviceNameWidth -= pixmap_system_size.width() + m_items_distances; + if (m_crypto_icon_mode == 2 && m_column_width > 0 && shouldCorrect) serviceNameWidth -= pixmap_crypto_size.width() + m_items_distances; + if (isRecorded && m_record_indicator_mode == 2 && m_column_width > 0 && shouldCorrect) serviceNameWidth -= pixmap_rec_size.width() + m_items_distances; + if ((m_servicetype_icon_mode == 2 || m_crypto_icon_mode == 2 || (isRecorded && m_record_indicator_mode == 2)) && m_column_width > 0) + serviceNameWidth -= m_items_distances; - ePtr paraServiceName = new eTextPara(eRect(0, 0, m_itemsize.width(), m_itemheight)); + ePtr paraServiceName = new eTextPara(eRect(0, 0, serviceNameWidth, m_itemheight)); paraServiceName->setFont(m_element_font[celServiceName]); paraServiceName->renderString(text.c_str()); eRect bboxServiceName = paraServiceName->getBoundBox(); @@ -1312,24 +1348,13 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const xoffs += piconWidth + m_items_distances; } - int orbpos = m_cursor->getUnsignedData(4) >> 16; int iconSystemPosX = xoffs + m_items_distances; int iconCryptoPosX = iconSystemPosX; int iconRecordPosX = iconSystemPosX; int iconOffsX = iconSystemPosX; - const char *filename = ref.path.c_str(); - ePtr &pixmap_system = - (m_cursor->flags & eServiceReference::isGroup) ? m_pixmaps[picServiceGroup] : - (strstr(filename, "://")) ? m_pixmaps[picStream] : - (orbpos == 0xFFFF) ? m_pixmaps[picDVB_C] : - (orbpos == 0xEEEE) ? m_pixmaps[picDVB_T] : m_pixmaps[picDVB_S]; - eSize pixmap_system_size = eSize(); - eSize pixmap_crypto_size = eSize(); - eSize pixmap_rec_size = eSize(); if (m_servicetype_icon_mode == 1 && pixmap_system) { - pixmap_system_size = pixmap_system->size(); iconCryptoPosX += pixmap_system_size.width() + m_items_distances; iconRecordPosX = iconCryptoPosX; iconOffsX += pixmap_system_size.width() + m_items_distances; @@ -1337,14 +1362,12 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (m_crypto_icon_mode == 1 && m_pixmaps[picCrypto]) { - pixmap_crypto_size = m_pixmaps[picCrypto]->size(); iconRecordPosX += pixmap_crypto_size.width() + m_items_distances; iconOffsX += pixmap_crypto_size.width() + m_items_distances; } if (isRecorded && m_record_indicator_mode == 1 && m_pixmaps[picRecord]) { - pixmap_rec_size = m_pixmaps[picRecord]->size(); iconOffsX += pixmap_rec_size.width() + m_items_distances; } @@ -1372,18 +1395,18 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } xoffs = iconOffsX; + xoffs_col = xoffs + m_column_width; painter.renderPara(paraServiceName, ePoint(xoffs, offset.y() + (ctrlHeight - bboxServiceName.height())/2)); - xoffs += bboxServiceName.width() + m_items_distances; + xoffs += std::min(serviceNameWidth, bboxServiceName.width()) + m_items_distances; - iconSystemPosX = xoffs + m_items_distances; + iconSystemPosX = xoffs; iconCryptoPosX = iconSystemPosX; iconRecordPosX = iconSystemPosX; iconOffsX = iconSystemPosX; if (m_servicetype_icon_mode == 2 && pixmap_system) { - pixmap_system_size = pixmap_system->size(); iconCryptoPosX += pixmap_system_size.width() + m_items_distances; iconRecordPosX = iconCryptoPosX; iconOffsX += pixmap_system_size.width() + m_items_distances; @@ -1392,7 +1415,6 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (m_crypto_icon_mode == 2 && m_pixmaps[picCrypto] && service_info && service_info->isCrypted()) { - pixmap_crypto_size = m_pixmaps[picCrypto]->size(); iconRecordPosX += pixmap_crypto_size.width() + m_items_distances; iconOffsX += pixmap_crypto_size.width() + m_items_distances; xoffs = iconOffsX; @@ -1400,7 +1422,6 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (isRecorded && m_record_indicator_mode == 2 && m_pixmaps[picRecord]) { - pixmap_rec_size = m_pixmaps[picRecord]->size(); iconOffsX += pixmap_rec_size.width() + m_items_distances; xoffs = iconOffsX; } @@ -1464,13 +1485,13 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } int eventTextWidth = (eventProgressConfig == "barright" || eventProgressConfig == "percright") ? - (pb_xpos - xoffs - m_items_distances*2 ) : (m_itemsize.width() - m_sides_margin*2 - xoffs - m_items_distances*2); + (pb_xpos - (m_column_width > 0 ? xoffs_col : xoffs) - m_items_distances*2 ) : (m_itemsize.width() - m_sides_margin*2 - (m_column_width > 0 ? xoffs_col : xoffs) - m_items_distances*2); ePtr para = new eTextPara(eRect(0, 0, eventTextWidth, m_itemheight)); para->setFont(m_element_font[celServiceInfo]); para->renderString(text.c_str()); eRect bbox = para->getBoundBox(); - painter.renderPara(para, ePoint(xoffs, offset.y() + (m_itemheight - bbox.height())/2)); + painter.renderPara(para, ePoint(m_column_width > 0 ? xoffs_col : xoffs, offset.y() + (m_itemheight - bbox.height())/2)); if (eventProgressConfig != "no" && !startsWith(eventProgressConfig, "perc")) { // the progress data... From 2427cacd437b098d634526db18efd583535a5f78 Mon Sep 17 00:00:00 2001 From: Huevos Date: Fri, 8 Dec 2023 15:33:02 +0100 Subject: [PATCH 321/401] [ChannelsImporter] allow repeats attempts if server is not available --- lib/python/Components/ChannelsImporter.py | 51 +++++++++++++++++++---- 1 file changed, 42 insertions(+), 9 deletions(-) diff --git a/lib/python/Components/ChannelsImporter.py b/lib/python/Components/ChannelsImporter.py index 6c0e94fa0cc..a05d4a9ab9b 100644 --- a/lib/python/Components/ChannelsImporter.py +++ b/lib/python/Components/ChannelsImporter.py @@ -20,6 +20,12 @@ def autostart(): if autoClientModeTimer is None: autoClientModeTimer = AutoClientModeTimer() +def getRemoteAddress(): + if config.clientmode.serverAddressType.value == "ip": + return "%d.%d.%d.%d" % (config.clientmode.serverIP.value[0], config.clientmode.serverIP.value[1], config.clientmode.serverIP.value[2], config.clientmode.serverIP.value[3]) + else: + return config.clientmode.serverDomain.value + class AutoClientModeTimer: instance = None @@ -27,9 +33,12 @@ class AutoClientModeTimer: def __init__(self): self.clientmodetimer = eTimer() self.clientmodetimer.callback.append(self.ClientModeonTimer) + self.autostartscantimer = eTimer() + self.autostartscantimer.callback.append(self.doautostartscan) self.clientmodeactivityTimer = eTimer() self.clientmodeactivityTimer.timeout.get().append(self.clientmodedatedelay) now = int(time()) + self.attempts = 0 self.doautostartscan() # import at boot time global ClientModeTime @@ -111,14 +120,41 @@ def ClientModeonTimer(self): self.clientmodedate(atLeast) def doClientMode(self, answer): + self.autostartscantimer.stop() + self.attempts = 0 now = int(time()) - self.timer = eTimer() - self.timer.callback.append(self.doautostartscan) print("[ClientModeScheduler][doClientMode] Running ClientMode", strftime("%c", localtime(now))) - self.timer.start(100, 1) + self.autostartscantimer.start(100, 1) def doautostartscan(self): - ChannelsImporter() + self.autostartscantimer.stop() + if self.checkFTPconnection(): + self.attempts = 0 + ChannelsImporter() + else: + if self.attempts < 5: + print("[ChannelsImporter] attempt %d failed. Retrying..." % (self.attempts + 1,)) + self.autostartscantimer.startLongTimer(10) + self.attempts += 1 + + + def checkFTPconnection(self): + print("[ChannelsImporter][checkFTPconnection] Testing FTP connection...") + try: + from ftplib import FTP + ftp = FTP() + ftp.set_pasv(config.clientmode.passive.value) + ftp.connect(host=getRemoteAddress(), port=config.clientmode.serverFTPPort.value, timeout=5) + result = ftp.login(user=config.clientmode.serverFTPusername.value, passwd=config.clientmode.serverFTPpassword.value) + ftp.quit() + if result.startswith("230"): + print("[ChannelsImporter][checkFTPconnection] FTP connection success:", result) + return True + print("[ChannelsImporter][checkFTPconnection] FTP connection failure:", result) + return False + except Exception as err: + print("[ChannelsImporter][checkFTPconnection] Error:", err) + return False def doneConfiguring(self): now = int(time()) @@ -320,10 +356,7 @@ def copyFile(self, source, dest): shutil.copy2(source, dest) def getRemoteAddress(self): - if config.clientmode.serverAddressType.value == "ip": - return "%d.%d.%d.%d" % (config.clientmode.serverIP.value[0], config.clientmode.serverIP.value[1], config.clientmode.serverIP.value[2], config.clientmode.serverIP.value[3]) - else: - return config.clientmode.serverDomain.value + return getRemoteAddress() def FTPdownloadFile(self, sourcefolder, sourcefile, destfile): print("[ChannelsImporter] Downloading remote file '%s'" % sourcefile) @@ -355,6 +388,6 @@ def forceSaveEPGonRemoteReceiver(self): except HTTPError as err: print("[ChannelsImporter][saveEPGonRemoteReceiver] ERROR:", err) except URLError as err: - print("[ChannelsImporter][saveEPGonRemoteReceiver] ERROR:", err.reason[0]) + print("[ChannelsImporter][saveEPGonRemoteReceiver] ERROR:", err.reason) except: print("[ChannelsImporter][saveEPGonRemoteReceiver] undefined error") From ee81c362daeb1f251a23b1f0a95596ae72864e30 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Fri, 8 Dec 2023 14:35:02 +0000 Subject: [PATCH 322/401] PEP8 double aggressive E301 ~ E306 --- lib/python/Components/ChannelsImporter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/ChannelsImporter.py b/lib/python/Components/ChannelsImporter.py index a05d4a9ab9b..115ca251679 100644 --- a/lib/python/Components/ChannelsImporter.py +++ b/lib/python/Components/ChannelsImporter.py @@ -20,6 +20,7 @@ def autostart(): if autoClientModeTimer is None: autoClientModeTimer = AutoClientModeTimer() + def getRemoteAddress(): if config.clientmode.serverAddressType.value == "ip": return "%d.%d.%d.%d" % (config.clientmode.serverIP.value[0], config.clientmode.serverIP.value[1], config.clientmode.serverIP.value[2], config.clientmode.serverIP.value[3]) @@ -137,7 +138,6 @@ def doautostartscan(self): self.autostartscantimer.startLongTimer(10) self.attempts += 1 - def checkFTPconnection(self): print("[ChannelsImporter][checkFTPconnection] Testing FTP connection...") try: From 534dcda469264717db7056c86ae0df27e9f99d4e Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Fri, 8 Dec 2023 14:35:12 +0000 Subject: [PATCH 323/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Components/ChannelsImporter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/ChannelsImporter.py b/lib/python/Components/ChannelsImporter.py index 115ca251679..a2ee8d7c9ae 100644 --- a/lib/python/Components/ChannelsImporter.py +++ b/lib/python/Components/ChannelsImporter.py @@ -137,7 +137,7 @@ def doautostartscan(self): print("[ChannelsImporter] attempt %d failed. Retrying..." % (self.attempts + 1,)) self.autostartscantimer.startLongTimer(10) self.attempts += 1 - + def checkFTPconnection(self): print("[ChannelsImporter][checkFTPconnection] Testing FTP connection...") try: From 492de4484d3cfe48b6eb20e9a9ef30e30275c701 Mon Sep 17 00:00:00 2001 From: Huevos Date: Fri, 8 Dec 2023 15:47:49 +0100 Subject: [PATCH 324/401] [listboxservice] fix compile warning --- lib/service/listboxservice.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index f776ce7e4bf..942b767de25 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -845,7 +845,6 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } int xoffset=0, xoffs=0, xoffs_col=0; // used as offset when painting the folder/marker symbol or the serviceevent progress - int nameLeft=0, nameWidth=0, nameYoffs=0, nextYoffs=0; // used as temporary values for 'show two lines' option if (m_separator == "") m_separator = " "; From a9b529b018d4de0b30350daac9ef01201e86cd3b Mon Sep 17 00:00:00 2001 From: Tony Whalley Date: Fri, 8 Dec 2023 20:41:23 +0100 Subject: [PATCH 325/401] [Videomode] - resolve GB4K initial open failure --- lib/python/Screens/VideoMode.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/python/Screens/VideoMode.py b/lib/python/Screens/VideoMode.py index c754884026d..e4b85c58a33 100644 --- a/lib/python/Screens/VideoMode.py +++ b/lib/python/Screens/VideoMode.py @@ -306,8 +306,12 @@ def VideoChangeDetect(self): self.delay = False self.detecttimer.stop() return - with open(videomode, "r+") as fd: # GB4K can fail on initial open as r - current_mode = fd.read()[:-1].replace("\n", "") + try: + with open(videomode, "r+") as fd: # GB4K can fail on initial open + current_mode = fd.read()[:-1].replace("\n", "") + except: + with open("/proc/stb/video/videomode", "r") as fd: + current_mode = fd.read()[:-1].replace("\n", "") if current_mode.upper() in ("PAL", "NTSC"): current_mode = current_mode.upper() video_height = None From c06f453ae2734edbd7fac585d01eb80e7678e5e0 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Fri, 8 Dec 2023 19:43:43 +0000 Subject: [PATCH 326/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Screens/VideoMode.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Screens/VideoMode.py b/lib/python/Screens/VideoMode.py index e4b85c58a33..34e64ea56c4 100644 --- a/lib/python/Screens/VideoMode.py +++ b/lib/python/Screens/VideoMode.py @@ -306,7 +306,7 @@ def VideoChangeDetect(self): self.delay = False self.detecttimer.stop() return - try: + try: with open(videomode, "r+") as fd: # GB4K can fail on initial open current_mode = fd.read()[:-1].replace("\n", "") except: From dba2cc8cd620e29a8d4212e275e1508d872e3a7d Mon Sep 17 00:00:00 2001 From: openvix-build Date: Fri, 8 Dec 2023 21:54:10 +0000 Subject: [PATCH 327/401] openvix: developer 6.4.010.017 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index d120c9b1221..078a5a11702 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1215,3 +1215,4 @@ openvix: developer 6.4.010.013 openvix: developer 6.4.010.014 openvix: developer 6.4.010.015 openvix: developer 6.4.010.016 +openvix: developer 6.4.010.017 From 3e38b27ec1b2d6719989ce898d3dc9627eef5489 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sat, 9 Dec 2023 13:14:16 +0200 Subject: [PATCH 328/401] [Added] [PliExtraInfo] Current Caid label [Fixed] [VAudioInfo] crash in maketrans due to wrong parameter --- .../Components/Converter/PliExtraInfo.py | 50 +++++++++++++------ lib/python/Components/Converter/VAudioInfo.py | 2 +- 2 files changed, 35 insertions(+), 17 deletions(-) diff --git a/lib/python/Components/Converter/PliExtraInfo.py b/lib/python/Components/Converter/PliExtraInfo.py index eacbfa58ac0..feccdf17d13 100644 --- a/lib/python/Components/Converter/PliExtraInfo.py +++ b/lib/python/Components/Converter/PliExtraInfo.py @@ -8,24 +8,25 @@ from Tools.GetEcmInfo import GetEcmInfo from Tools.Hex2strColor import Hex2strColor from Components.Converter.Poll import Poll +from Tools.Directories import pathExists from skin import parameters caid_data = ( - ("0x100", "0x1ff", "Seca", "S", True), - ("0x500", "0x5ff", "Via", "V", True), - ("0x600", "0x6ff", "Irdeto", "I", True), - ("0x900", "0x9ff", "NDS", "Nd", True), - ("0xb00", "0xbff", "Conax", "Co", True), - ("0xd00", "0xdff", "CryptoW", "Cw", True), - ("0xe00", "0xeff", "PowerVU", "P", False), - ("0x1000", "0x10FF", "Tandberg", "TB", False), - ("0x1700", "0x17ff", "Beta", "B", True), - ("0x1800", "0x18ff", "Nagra", "N", True), - ("0x2600", "0x2600", "Biss", "Bi", False), - ("0x2700", "0x2710", "Dre3", "D3", False), - ("0x4ae0", "0x4ae1", "Dre", "D", False), - ("0x4aee", "0x4aee", "BulCrypt", "B1", False), - ("0x5581", "0x5581", "BulCrypt", "B2", False) + ("0x100", "0x1ff", "Seca", "S", "SEC", True), + ("0x500", "0x5ff", "Via", "V", "VIA", True), + ("0x600", "0x6ff", "Irdeto", "I", "IRD", True), + ("0x900", "0x9ff", "NDS", "Nd", "NDS", True), + ("0xb00", "0xbff", "Conax", "Co", "CON", True), + ("0xd00", "0xdff", "CryptoW", "Cw", "CRW", True), + ("0xe00", "0xeff", "PowerVU", "P", "PV", False), + ("0x1000", "0x10FF", "Tandberg", "TB", "TAN", False), + ("0x1700", "0x17ff", "Beta", "B", "BET", True), + ("0x1800", "0x18ff", "Nagra", "N", "NAG", True), + ("0x2600", "0x2600", "Biss", "Bi", "BiSS", False), + ("0x2700", "0x2710", "Dre3", "D3", "DRE3", False), + ("0x4ae0", "0x4ae1", "Dre", "D", "DRE", False), + ("0x4aee", "0x4aee", "BulCrypt", "B1", "BUL", False), + ("0x5581", "0x5581", "BulCrypt", "B2", "BUL", False) ) # stream type to codec map @@ -237,13 +238,23 @@ def createCryptoBar(self, info): except: pass - if color != Hex2strColor(colors[2]) or caid_entry[4]: + if color != Hex2strColor(colors[2]) or caid_entry[5]: if res: res += " " res += color + caid_entry[3] res += Hex2strColor(colors[3]) # white (this acts like a color "reset" for following strings return res + + def createCurrentCaidLabel(self): + res = "" + if not pathExists("/tmp/ecm.info"): + return "FTA" + for caid_entry in caid_data: + if int(caid_entry[0], 16) <= int(self.current_caid, 16) <= int(caid_entry[1], 16): + res = caid_entry[4] + + return res def createCryptoSeca(self, info): available_caids = info.getInfoObject(iServiceInformation.sCAIDs) @@ -776,6 +787,13 @@ def getTextByType(self, textType): if not info: return "" + if textType == "CurrentCrypto": + if int(config.usage.show_cryptoinfo.value) > 0: + self.getCryptoInfo(info) + return self.createCurrentCaidLabel() + else: + return "" + if textType == "CryptoBar": if int(config.usage.show_cryptoinfo.value) > 0: self.getCryptoInfo(info) diff --git a/lib/python/Components/Converter/VAudioInfo.py b/lib/python/Components/Converter/VAudioInfo.py index be7671ca98f..b557a29a387 100644 --- a/lib/python/Components/Converter/VAudioInfo.py +++ b/lib/python/Components/Converter/VAudioInfo.py @@ -122,7 +122,7 @@ def getAudioCodec(self, info): return description_str def getAudioIcon(self, info): - description_str = self.get_short(self.getAudioCodec(info).translate(str.maketrans(None, ' .')).lower()) + description_str = self.get_short(self.getAudioCodec(info).translate(str.maketrans(' ', ' .')).lower()) return description_str def get_short(self, audioName): From 7031f48a89c2a9dfa7832f9cdb02581d4483872a Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sat, 9 Dec 2023 13:16:24 +0200 Subject: [PATCH 329/401] [Added] AudioIcon renderer --- lib/python/Components/Renderer/AudioIcon.py | 63 +++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 lib/python/Components/Renderer/AudioIcon.py diff --git a/lib/python/Components/Renderer/AudioIcon.py b/lib/python/Components/Renderer/AudioIcon.py new file mode 100644 index 00000000000..2021f9d2378 --- /dev/null +++ b/lib/python/Components/Renderer/AudioIcon.py @@ -0,0 +1,63 @@ +from Components.Renderer.Renderer import Renderer +from enigma import ePixmap +from Tools.Directories import fileExists, SCOPE_GUISKIN, resolveFilename +from Tools.LoadPixmap import LoadPixmap + +class AudioIcon(Renderer): + def __init__(self): + Renderer.__init__(self) + self.size = None + self.width = 51 + self.height = 30 + self.nameAudioCache = { } + self.pngname = "" + self.path = "" + + def applySkin(self, desktop, parent): + attribs = [ ] + for (attrib, value) in self.skinAttributes: + if attrib == "path": + self.path = value + if value.endswith("/"): + self.path = value + else: + self.path = value + "/" + else: + attribs.append((attrib,value)) + if attrib == "size": + value = value.split(',') + if len(value) == 2: + self.width = int(value[0]) + self.height = int(value[1]) + self.size = value[0] + "x" + value[1] + self.skinAttributes = attribs + return Renderer.applySkin(self, desktop, parent) + + GUI_WIDGET = ePixmap + + def changed(self, what): + if self.instance: + pngname = "" + if what[0] != self.CHANGED_CLEAR: + sname = self.source.text + pngname = self.nameAudioCache.get(sname, "") + if pngname == "": + pngname = self.findAudioIcon(sname) + if pngname != "": + self.nameAudioCache[sname] = pngname + if pngname == "": + self.instance.hide() + else: + self.instance.show() + if pngname != "" and self.pngname != pngname: + is_svg = pngname.endswith(".svg") + png = LoadPixmap(pngname, width=self.width, height=0 if is_svg else self.height) + self.instance.setPixmap(png) + self.pngname = pngname + + def findAudioIcon(self, audioName): + pngname = resolveFilename(SCOPE_GUISKIN, self.path + audioName + ".svg") + if fileExists(pngname): + return pngname + return "" + From 828fbae6fa30bf8a6f93033703b003c065e07093 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Sat, 9 Dec 2023 13:43:56 +0200 Subject: [PATCH 330/401] [Updated] Caid middle lenght names --- lib/python/Components/Converter/PliExtraInfo.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/python/Components/Converter/PliExtraInfo.py b/lib/python/Components/Converter/PliExtraInfo.py index feccdf17d13..dcba094c21b 100644 --- a/lib/python/Components/Converter/PliExtraInfo.py +++ b/lib/python/Components/Converter/PliExtraInfo.py @@ -12,16 +12,16 @@ from skin import parameters caid_data = ( - ("0x100", "0x1ff", "Seca", "S", "SEC", True), + ("0x100", "0x1ff", "Seca", "S", "SECA", True), ("0x500", "0x5ff", "Via", "V", "VIA", True), ("0x600", "0x6ff", "Irdeto", "I", "IRD", True), ("0x900", "0x9ff", "NDS", "Nd", "NDS", True), - ("0xb00", "0xbff", "Conax", "Co", "CON", True), + ("0xb00", "0xbff", "Conax", "Co", "CONAX", True), ("0xd00", "0xdff", "CryptoW", "Cw", "CRW", True), ("0xe00", "0xeff", "PowerVU", "P", "PV", False), - ("0x1000", "0x10FF", "Tandberg", "TB", "TAN", False), - ("0x1700", "0x17ff", "Beta", "B", "BET", True), - ("0x1800", "0x18ff", "Nagra", "N", "NAG", True), + ("0x1000", "0x10FF", "Tandberg", "TB", "TAND", False), + ("0x1700", "0x17ff", "Beta", "B", "BETA", True), + ("0x1800", "0x18ff", "Nagra", "N", "NAGRA", True), ("0x2600", "0x2600", "Biss", "Bi", "BiSS", False), ("0x2700", "0x2710", "Dre3", "D3", "DRE3", False), ("0x4ae0", "0x4ae1", "Dre", "D", "DRE", False), From 5e18311355966d506b4fe374f57672b08f1fb123 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sat, 9 Dec 2023 14:25:48 +0000 Subject: [PATCH 331/401] PEP8 double aggressive E20 and E211 --- lib/python/Components/Renderer/AudioIcon.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Components/Renderer/AudioIcon.py b/lib/python/Components/Renderer/AudioIcon.py index 2021f9d2378..6b98e67ba6a 100644 --- a/lib/python/Components/Renderer/AudioIcon.py +++ b/lib/python/Components/Renderer/AudioIcon.py @@ -9,12 +9,12 @@ def __init__(self): self.size = None self.width = 51 self.height = 30 - self.nameAudioCache = { } + self.nameAudioCache = {} self.pngname = "" self.path = "" def applySkin(self, desktop, parent): - attribs = [ ] + attribs = [] for (attrib, value) in self.skinAttributes: if attrib == "path": self.path = value From 746d3ea6023b6096b336a9a54e729771bc8ef703 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sat, 9 Dec 2023 14:25:59 +0000 Subject: [PATCH 332/401] PEP8 double aggressive E22, E224, E241, E242 and E27 --- lib/python/Components/Renderer/AudioIcon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/Renderer/AudioIcon.py b/lib/python/Components/Renderer/AudioIcon.py index 6b98e67ba6a..918b6ce8bc5 100644 --- a/lib/python/Components/Renderer/AudioIcon.py +++ b/lib/python/Components/Renderer/AudioIcon.py @@ -56,7 +56,7 @@ def changed(self, what): self.pngname = pngname def findAudioIcon(self, audioName): - pngname = resolveFilename(SCOPE_GUISKIN, self.path + audioName + ".svg") + pngname = resolveFilename(SCOPE_GUISKIN, self.path + audioName + ".svg") if fileExists(pngname): return pngname return "" From 187efa49f14b429a259b1a5352160fae3ac442bc Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sat, 9 Dec 2023 14:26:14 +0000 Subject: [PATCH 333/401] PEP8 double aggressive E225 ~ E228 and E231 --- lib/python/Components/Renderer/AudioIcon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/Renderer/AudioIcon.py b/lib/python/Components/Renderer/AudioIcon.py index 918b6ce8bc5..5581d828aab 100644 --- a/lib/python/Components/Renderer/AudioIcon.py +++ b/lib/python/Components/Renderer/AudioIcon.py @@ -23,7 +23,7 @@ def applySkin(self, desktop, parent): else: self.path = value + "/" else: - attribs.append((attrib,value)) + attribs.append((attrib, value)) if attrib == "size": value = value.split(',') if len(value) == 2: From 344c89cac6d8393403086a86951116730a0e2307 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sat, 9 Dec 2023 14:26:25 +0000 Subject: [PATCH 334/401] PEP8 double aggressive E301 ~ E306 --- lib/python/Components/Renderer/AudioIcon.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/python/Components/Renderer/AudioIcon.py b/lib/python/Components/Renderer/AudioIcon.py index 5581d828aab..f26608c176d 100644 --- a/lib/python/Components/Renderer/AudioIcon.py +++ b/lib/python/Components/Renderer/AudioIcon.py @@ -3,6 +3,7 @@ from Tools.Directories import fileExists, SCOPE_GUISKIN, resolveFilename from Tools.LoadPixmap import LoadPixmap + class AudioIcon(Renderer): def __init__(self): Renderer.__init__(self) From 11ab8a7c2486a97a832dc1cb931b43fc409de5aa Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sat, 9 Dec 2023 14:26:35 +0000 Subject: [PATCH 335/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Components/Converter/PliExtraInfo.py | 2 +- lib/python/Components/Renderer/AudioIcon.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/python/Components/Converter/PliExtraInfo.py b/lib/python/Components/Converter/PliExtraInfo.py index dcba094c21b..3853b78ac30 100644 --- a/lib/python/Components/Converter/PliExtraInfo.py +++ b/lib/python/Components/Converter/PliExtraInfo.py @@ -245,7 +245,7 @@ def createCryptoBar(self, info): res += Hex2strColor(colors[3]) # white (this acts like a color "reset" for following strings return res - + def createCurrentCaidLabel(self): res = "" if not pathExists("/tmp/ecm.info"): diff --git a/lib/python/Components/Renderer/AudioIcon.py b/lib/python/Components/Renderer/AudioIcon.py index f26608c176d..3b9300c4e60 100644 --- a/lib/python/Components/Renderer/AudioIcon.py +++ b/lib/python/Components/Renderer/AudioIcon.py @@ -57,8 +57,7 @@ def changed(self, what): self.pngname = pngname def findAudioIcon(self, audioName): - pngname = resolveFilename(SCOPE_GUISKIN, self.path + audioName + ".svg") + pngname = resolveFilename(SCOPE_GUISKIN, self.path + audioName + ".svg") if fileExists(pngname): return pngname return "" - From f42413890c955f135c4b98cac9fa86604b81b13e Mon Sep 17 00:00:00 2001 From: Orlandoxx <95180049+Orlandoxx@users.noreply.github.com> Date: Sat, 9 Dec 2023 21:44:10 +0200 Subject: [PATCH 336/401] Updated Finnish (fi.po) translation. Translated latest 'menu.xml' and ViX 'plugin.py' changes. --- po/fi.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/po/fi.po b/po/fi.po index 4a260ba6963..c0eb0eb7cca 100644 --- a/po/fi.po +++ b/po/fi.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: enigma2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-27 23:35+0000\n" -"PO-Revision-Date: 2023-12-06 06:36+0200\n" +"PO-Revision-Date: 2023-12-09 21:41+0200\n" "Last-Translator: Orlandox\n" "Language-Team: timoj/Kojo/Samzam/Orlandox\n" "Language: fi\n" @@ -12870,7 +12870,7 @@ msgstr "Softcam-asetukset" msgid "SoftcamCheck" msgstr "SoftCam:in tarkistus" -msgid "SoftcamManager" +msgid "Softcam Management" msgstr "Softcam hallinta" msgid "SoftcamScript enable/disable cam restart" @@ -13540,7 +13540,7 @@ msgstr "" "Suomenkielinen käännös: timoj, Kojo, Samzam, Orlandox\n" "\n" "Ylläpito : Orlandox\n" -"06.12.2023\n" +"09.12.2023\n" "http://www.huoltovalikko.com" msgid "TS file is too large for ISO9660 level 1!" @@ -18853,7 +18853,7 @@ msgstr "Koko: %sTt" msgid "Size: unavailable" msgstr "Koko: ei saatavilla" -msgid "Softcam manager" +msgid "Softcam Manager" msgstr "Softcam:n hallinnointi" msgid "Softcam manager settings" From 256310d2ef3a8322d41e731bd2fe9360cbb0866f Mon Sep 17 00:00:00 2001 From: openvix-build Date: Sat, 9 Dec 2023 22:20:37 +0000 Subject: [PATCH 337/401] openvix: developer 6.4.010.018 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 078a5a11702..1f50fac49b5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1216,3 +1216,4 @@ openvix: developer 6.4.010.014 openvix: developer 6.4.010.015 openvix: developer 6.4.010.016 openvix: developer 6.4.010.017 +openvix: developer 6.4.010.018 From 8bd9d72ed0598317ea880ba5bef8bfb4c8537b1a Mon Sep 17 00:00:00 2001 From: openvix-build Date: Sat, 9 Dec 2023 23:55:41 +0000 Subject: [PATCH 338/401] openvix: developer 6.4.010.019 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 1f50fac49b5..01fba4bdb28 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1217,3 +1217,4 @@ openvix: developer 6.4.010.015 openvix: developer 6.4.010.016 openvix: developer 6.4.010.017 openvix: developer 6.4.010.018 +openvix: developer 6.4.010.019 From a0c632a571bf73b0bd7b9ead70972c692dfdc569 Mon Sep 17 00:00:00 2001 From: Orlandoxx <95180049+Orlandoxx@users.noreply.github.com> Date: Sun, 10 Dec 2023 10:26:40 +0200 Subject: [PATCH 339/401] Updated fi.po Added "Softcam manager" translation. --- po/fi.po | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/po/fi.po b/po/fi.po index c0eb0eb7cca..1d0449ea6b2 100644 --- a/po/fi.po +++ b/po/fi.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: enigma2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-27 23:35+0000\n" -"PO-Revision-Date: 2023-12-09 21:41+0200\n" +"PO-Revision-Date: 2023-12-10 10:20+0200\n" "Last-Translator: Orlandox\n" "Language-Team: timoj/Kojo/Samzam/Orlandox\n" "Language: fi\n" @@ -13540,7 +13540,7 @@ msgstr "" "Suomenkielinen käännös: timoj, Kojo, Samzam, Orlandox\n" "\n" "Ylläpito : Orlandox\n" -"09.12.2023\n" +"10.12.2023\n" "http://www.huoltovalikko.com" msgid "TS file is too large for ISO9660 level 1!" @@ -18856,6 +18856,9 @@ msgstr "Koko: ei saatavilla" msgid "Softcam Manager" msgstr "Softcam:n hallinnointi" +msgid "Softcam manager" +msgstr "Softcam:n hallinnointi" + msgid "Softcam manager settings" msgstr "Softcam hallinnoinnin asetukset" From 8032d5c5592b7a25a0c2e28fe05a8996b59bf8a7 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Tue, 12 Dec 2023 08:44:29 +0200 Subject: [PATCH 340/401] [Fixed] Correct handling of selected index and list total count when there is hidden items. --- lib/service/listboxservice.cpp | 1 + lib/service/listboxservice.h | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 942b767de25..47869011567 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -118,6 +118,7 @@ void eListboxServiceContent::removeCurrent() void eListboxServiceContent::FillFinished() { m_size = m_list.size(); + m_size_visible = cursorResolve(m_size - 1) + 1; cursorHome(); if (m_listbox) diff --git a/lib/service/listboxservice.h b/lib/service/listboxservice.h index 35f52659087..a4fba48ce3d 100644 --- a/lib/service/listboxservice.h +++ b/lib/service/listboxservice.h @@ -28,9 +28,9 @@ class eListboxServiceContent: public virtual iListboxContent int getNextBeginningWithChar(char c); int getPrevMarkerPos(); int getNextMarkerPos(); - int getCurrentSelectionIndex() { return m_cursor_number; } + int getCurrentSelectionIndex() { return cursorResolve(m_cursor_number); } eSize getItemSize() { return m_itemsize; } - int getListSize() { return m_size; } + int getListSize() { return m_size_visible; } /* support for marked services */ void initMarked(); @@ -182,7 +182,7 @@ class eListboxServiceContent: public virtual iListboxContent list::iterator m_cursor, m_saved_cursor; int m_cursor_number, m_saved_cursor_number; - int m_size; + int m_size, m_size_visible; eSize m_itemsize; ePtr m_service_center; From b56bb3189deebbef6abdbe2b7121ed316285918c Mon Sep 17 00:00:00 2001 From: Huevos Date: Thu, 14 Dec 2023 11:13:51 +0100 Subject: [PATCH 341/401] [menu/setup] move playback settings to own screen --- data/menu.xml | 3 ++- data/setup.xml | 27 +++++++++++++++------------ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/data/menu.xml b/data/menu.xml index f75119f78aa..4183ed88ea3 100644 --- a/data/menu.xml +++ b/data/menu.xml @@ -162,7 +162,8 @@ self.session.open(SABnzbdSetupScreen) - + + diff --git a/data/setup.xml b/data/setup.xml index b32813e5b99..3ef3fef737b 100644 --- a/data/setup.xml +++ b/data/setup.xml @@ -199,7 +199,7 @@ config.autolanguage.audio_epglanguage config.autolanguage.audio_epglanguage_alternative - + config.usage.default_path config.usage.timer_path config.usage.instantrec_path @@ -210,15 +210,24 @@ config.recording.margin_after config.recording.split_programme_minutes config.usage.show_message_when_recording_starts - config.usage.leave_movieplayer_onExit + config.recording.ascii_filenames + config.recording.filename_composition + config.usage.timerlist_showpicons + config.usage.timerlist_finished_timer_position + config.recording.keep_timers + config.recording.keep_finished_timer_logs + config.recording.ecm_data + config.recording.record_icon_match + + config.usage.on_movie_start config.usage.on_movie_stop config.usage.on_movie_eof - config.usage.next_movie_msg - config.seek.on_pause config.seek.selfdefined_13 config.seek.selfdefined_46 config.seek.selfdefined_79 + config.usage.leave_movieplayer_onExit + config.seek.on_pause config.seek.baractivation config.seek.sensibility config.seek.speeds_forward @@ -226,15 +235,9 @@ config.seek.speeds_slowmotion config.seek.enter_forward config.seek.enter_backward - config.recording.ascii_filenames - config.recording.filename_composition - config.usage.timerlist_showpicons - config.usage.timerlist_finished_timer_position - config.recording.keep_timers - config.recording.keep_finished_timer_logs + config.usage.next_movie_msg config.recording.offline_decode_delay - config.recording.ecm_data - config.recording.record_icon_match + config.usage.hdd_standby From f985d3407b9ccccc6f8297818721fe092661b90b Mon Sep 17 00:00:00 2001 From: Huevos Date: Thu, 14 Dec 2023 12:45:43 +0100 Subject: [PATCH 342/401] [Recordings] instanciate "self.errorItem" before calling Setup.__init__() --- lib/python/Screens/Recordings.py | 2 +- lib/python/Screens/Timeshift.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Screens/Recordings.py b/lib/python/Screens/Recordings.py index c36e2cee52c..7dc637a65e7 100644 --- a/lib/python/Screens/Recordings.py +++ b/lib/python/Screens/Recordings.py @@ -16,9 +16,9 @@ def __init__(self, session): self.buildChoices("DefaultPath", config.usage.default_path, None) self.buildChoices("TimerPath", config.usage.timer_path, None) self.buildChoices("InstantPath", config.usage.instantrec_path, None) + self.errorItem = -1 Setup.__init__(self, session=session, setup="recording") self.greenText = self["key_green"].text - self.errorItem = -1 if self.getCurrentItem() in (config.usage.default_path, config.usage.timer_path, config.usage.instantrec_path): self.pathStatus(self.getCurrentValue()) diff --git a/lib/python/Screens/Timeshift.py b/lib/python/Screens/Timeshift.py index 195beb527df..febf5a54bc3 100644 --- a/lib/python/Screens/Timeshift.py +++ b/lib/python/Screens/Timeshift.py @@ -13,9 +13,9 @@ class TimeshiftSettings(Setup): def __init__(self, session): self.buildChoices("TimeshiftPath", config.usage.timeshift_path, None) + self.errorItem = -1 Setup.__init__(self, session=session, setup="timeshift") self.greenText = self["key_green"].text - self.errorItem = -1 if self.getCurrentItem() is config.usage.timeshift_path: self.pathStatus(self.getCurrentValue()) From fa40062d86cfb47f5a1e2e3b214645fed485d1d4 Mon Sep 17 00:00:00 2001 From: Huevos Date: Thu, 14 Dec 2023 12:46:39 +0100 Subject: [PATCH 343/401] [Recordings] remove MessageBoxes --- lib/python/Screens/Recordings.py | 7 ------- lib/python/Screens/Timeshift.py | 6 ------ 2 files changed, 13 deletions(-) diff --git a/lib/python/Screens/Recordings.py b/lib/python/Screens/Recordings.py index 7dc637a65e7..1878c0fbe54 100644 --- a/lib/python/Screens/Recordings.py +++ b/lib/python/Screens/Recordings.py @@ -3,7 +3,6 @@ from Components.config import config from Components.UsageConfig import preferredPath from Screens.LocationBox import MovieLocationBox -from Screens.MessageBox import MessageBox from Screens.Setup import Setup from Tools.Directories import fileExists import Components.Harddisk @@ -97,7 +96,6 @@ def selectionChanged(self): Setup.selectionChanged(self) else: self["config"].setCurrentIndex(self.errorItem) - self.errorMsg() def changedEntry(self): if self.getCurrentItem() in (config.usage.default_path, config.usage.timer_path, config.usage.instantrec_path): @@ -112,11 +110,6 @@ def keySelect(self): else: Setup.keySelect(self) - def errorMsg(self): - self.session.open(MessageBox, "%s\n\n%s" % (self.footnote, _("Please select a valid directory.")), type=MessageBox.TYPE_ERROR) - def keySave(self): if self.errorItem == -1: Setup.keySave(self) - else: - self.errorMsg() diff --git a/lib/python/Screens/Timeshift.py b/lib/python/Screens/Timeshift.py index febf5a54bc3..355f648234f 100644 --- a/lib/python/Screens/Timeshift.py +++ b/lib/python/Screens/Timeshift.py @@ -108,7 +108,6 @@ def selectionChanged(self): Setup.selectionChanged(self) else: self["config"].setCurrentIndex(self.errorItem) - self.errorMsg() def changedEntry(self): if self.getCurrentItem() is config.usage.timeshift_path: @@ -121,11 +120,6 @@ def keySelect(self): else: Setup.keySelect(self) - def errorMsg(self): - self.session.open(MessageBox, "%s\n\n%s" % (self.footnote, _("Please select a valid directory.")), type=MessageBox.TYPE_ERROR) - def keySave(self): if self.errorItem == -1: Setup.keySave(self) - else: - self.errorMsg() From 19d072af94dedb775841dd2260e28c5d7b7159cb Mon Sep 17 00:00:00 2001 From: Huevos Date: Thu, 14 Dec 2023 12:57:49 +0100 Subject: [PATCH 344/401] [Setup/Recording] only show additional options if location is valid --- data/setup.xml | 48 ++++++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/data/setup.xml b/data/setup.xml index 3ef3fef737b..b7415a03e67 100644 --- a/data/setup.xml +++ b/data/setup.xml @@ -201,23 +201,25 @@ config.usage.default_path - config.usage.timer_path - config.usage.instantrec_path - config.recording.setstreamto1 + config.usage.timer_path + config.usage.instantrec_path + + config.recording.setstreamto1 - config.recording.asktozap - config.recording.margin_before - config.recording.margin_after - config.recording.split_programme_minutes - config.usage.show_message_when_recording_starts - config.recording.ascii_filenames - config.recording.filename_composition - config.usage.timerlist_showpicons - config.usage.timerlist_finished_timer_position - config.recording.keep_timers - config.recording.keep_finished_timer_logs - config.recording.ecm_data - config.recording.record_icon_match + config.recording.asktozap + config.recording.margin_before + config.recording.margin_after + config.recording.split_programme_minutes + config.usage.show_message_when_recording_starts + config.recording.ascii_filenames + config.recording.filename_composition + config.usage.timerlist_showpicons + config.usage.timerlist_finished_timer_position + config.recording.keep_timers + config.recording.keep_finished_timer_logs + config.recording.ecm_data + config.recording.record_icon_match + config.usage.on_movie_start @@ -352,12 +354,14 @@ config.usage.timeshift_path - config.timeshift.startdelay - config.usage.check_timeshift - config.timeshift.favoriteSaveAction - config.timeshift.stopwhilerecording - config.timeshift.showinfobar - config.usage.timeshift_skipreturntolive + + config.timeshift.startdelay + config.usage.check_timeshift + config.timeshift.favoriteSaveAction + config.timeshift.stopwhilerecording + config.timeshift.showinfobar + config.usage.timeshift_skipreturntolive + config.epgselection.sort From 61c133ca2662aa94105b29fb8d3759224c08eb4f Mon Sep 17 00:00:00 2001 From: openvix-build Date: Thu, 14 Dec 2023 12:00:44 +0000 Subject: [PATCH 345/401] openvix: developer 6.4.011.001 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 01fba4bdb28..e861d29c07a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1218,3 +1218,4 @@ openvix: developer 6.4.010.016 openvix: developer 6.4.010.017 openvix: developer 6.4.010.018 openvix: developer 6.4.010.019 +openvix: developer 6.4.011.001 From 03e5e4242f092703f33e14ef5aef0add8fb26fe8 Mon Sep 17 00:00:00 2001 From: Orlandoxx <95180049+Orlandoxx@users.noreply.github.com> Date: Thu, 14 Dec 2023 18:44:01 +0200 Subject: [PATCH 346/401] Updated Finnish (fi.po) translation. Added 'Playback' changes. --- po/fi.po | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/po/fi.po b/po/fi.po index 1d0449ea6b2..ebbfe70aa80 100644 --- a/po/fi.po +++ b/po/fi.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: enigma2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-27 23:35+0000\n" -"PO-Revision-Date: 2023-12-10 10:20+0200\n" +"PO-Revision-Date: 2023-12-14 18:36+0200\n" "Last-Translator: Orlandox\n" "Language-Team: timoj/Kojo/Samzam/Orlandox\n" "Language: fi\n" @@ -10514,7 +10514,7 @@ msgid "Record time limited due to conflicting timer %s" msgstr "Ajastusaika rajoitettu, ristiriita ajastukseen %s" msgid "Recording" -msgstr "Tallenne" +msgstr "Tallennus" msgid "Recording & Playback" msgstr "Tallennus ja toisto" @@ -13540,7 +13540,7 @@ msgstr "" "Suomenkielinen käännös: timoj, Kojo, Samzam, Orlandox\n" "\n" "Ylläpito : Orlandox\n" -"10.12.2023\n" +"14.12.2023\n" "http://www.huoltovalikko.com" msgid "TS file is too large for ISO9660 level 1!" @@ -19168,3 +19168,6 @@ msgstr "Vain Sref" msgid "Sref + stream url" msgstr "Sref + striimin url" + +msgid "Playback" +msgstr "Toisto" From 867f07ae88a93ab3b9356d27d514b0de50b3b753 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Fri, 15 Dec 2023 11:46:06 +0200 Subject: [PATCH 347/401] [Added] Two lines and Next event mode [Added] Made some texts translatable [Updated] Some descriptions --- data/setup.xml | 10 +- lib/python/Components/ServiceList.py | 14 ++ lib/python/Components/UsageConfig.py | 14 +- lib/service/listboxservice.cpp | 207 +++++++++++++++++---------- lib/service/listboxservice.h | 7 +- 5 files changed, 161 insertions(+), 91 deletions(-) diff --git a/data/setup.xml b/data/setup.xml index b7415a03e67..09630474781 100644 --- a/data/setup.xml +++ b/data/setup.xml @@ -110,12 +110,12 @@ config.usage.panicbutton config.usage.hide_number_markers config.usage.show_channel_jump_in_servicelist - config.usage.show_event_progress_in_servicelist - config.usage.show_channel_numbers_in_servicelist config.usage.servicelist_twolines - config.usage.crypto_icon_mode - config.usage.servicetype_icon_mode - config.usage.record_indicator_mode + config.usage.show_event_progress_in_servicelist + config.usage.show_channel_numbers_in_servicelist + config.usage.crypto_icon_mode + config.usage.servicetype_icon_mode + config.usage.record_indicator_mode config.usage.service_icon_enable config.usage.servicelist_column config.usage.serviceitems_per_page diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 8991c546fa6..c927a7a7a13 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -397,6 +397,7 @@ def setFontsize(self): self.l.setElementFont(self.l.celServiceName, self.ServiceNameFont) self.l.setElementFont(self.l.celServiceNumber, self.ServiceNumberFont) self.l.setElementFont(self.l.celServiceInfo, self.ServiceInfoFont) + self.l.setElementFont(self.l.celServiceNextInfo, self.ServiceNextInfoFont) def postWidgetCreate(self, instance): instance.setWrapAround(True) @@ -484,6 +485,16 @@ def setMode(self, mode): self.l.setItemHeight(self.ItemHeight if two_lines_val == 0 else self.ItemHeightTwoLine) self.l.setVisualMode(eListboxServiceContent.visModeComplex if two_lines_val == 0 else eListboxServiceContent.visSkinDefined) + if two_lines_val: + timeText = _("%d min") + self.l.setTextTime(timeText) + + if two_lines_val > 1: + nextTitle = _("NEXT") + ": " + self.l.setNextTitle(nextTitle) + + self.l.setHasNextEvent(two_lines_val > 1) + if config.usage.service_icon_enable.value: self.l.setGetPiconNameFunc(getPiconName) else: @@ -498,8 +509,11 @@ def setMode(self, mode): self.l.setElementFont(self.l.celServiceName, self.ServiceNameFont) self.l.setElementFont(self.l.celServiceNumber, self.ServiceNumberFont) self.l.setElementFont(self.l.celServiceInfo, self.ServiceInfoFont) + self.l.setElementFont(self.l.celServiceNextInfo, self.ServiceNextInfoFont) + if "perc" in config.usage.show_event_progress_in_servicelist.value: self.l.setElementFont(self.l.celServiceEventProgressbar, self.ServiceInfoFont) + self.l.setHideNumberMarker(config.usage.hide_number_markers.value) self.l.setServiceTypeIconMode(int(config.usage.servicetype_icon_mode.value)) self.l.setCryptoIconMode(int(config.usage.crypto_icon_mode.value)) diff --git a/lib/python/Components/UsageConfig.py b/lib/python/Components/UsageConfig.py index ba3dc75ffe7..d627912b76a 100644 --- a/lib/python/Components/UsageConfig.py +++ b/lib/python/Components/UsageConfig.py @@ -53,19 +53,17 @@ def alternativeNumberModeChange(configElement): refreshServiceList() config.usage.alternative_number_mode.addNotifier(alternativeNumberModeChange) - config.usage.servicelist_twolines = ConfigSelection(default="0", choices=[("0", _("None")), ("1", _("two lines"))]) - if config.usage.servicelist_twolines.value not in ("0", "1"): - config.usage.servicelist_twolines.value = "1" + config.usage.servicelist_twolines = ConfigSelection(default="0", choices=[("0", _("None")), ("1", _("two lines")), ("2", _("two lines+next event"))]) config.usage.servicelist_twolines.addNotifier(refreshServiceList) config.usage.hide_number_markers = ConfigYesNo(default=True) config.usage.hide_number_markers.addNotifier(refreshServiceList) - config.usage.servicetype_icon_mode = ConfigSelection(default="0", choices=[("0", _("None")), ("1", _("Left from servicename")), ("2", _("Right from servicename"))]) + config.usage.servicetype_icon_mode = ConfigSelection(default="0", choices=[("0", _("None")), ("1", _("Left from servicename (only available in single line mode)")), ("2", _("Right from servicename"))]) config.usage.servicetype_icon_mode.addNotifier(refreshServiceList) - config.usage.crypto_icon_mode = ConfigSelection(default="0", choices=[("0", _("None")), ("1", _("Left from servicename")), ("2", _("Right from servicename"))]) + config.usage.crypto_icon_mode = ConfigSelection(default="0", choices=[("0", _("None")), ("1", _("Left from servicename (only available in single line mode)")), ("2", _("Right from servicename"))]) config.usage.crypto_icon_mode.addNotifier(refreshServiceList) - config.usage.record_indicator_mode = ConfigSelection(default="3", choices=[("0", _("None")), ("1", _("Left from servicename")), ("2", _("Right from servicename")), ("3", _("Red colored"))]) + config.usage.record_indicator_mode = ConfigSelection(default="3", choices=[("0", _("None")), ("1", _("Left from servicename (only available in single line mode)")), ("2", _("Right from servicename")), ("3", _("Red colored"))]) config.usage.record_indicator_mode.addNotifier(refreshServiceList) choicelist = [("-1", _("Disable"))] @@ -319,9 +317,9 @@ def showsecondinfobarChanged(configElement): config.usage.show_bouquetalways = ConfigYesNo(default=False) config.usage.show_event_progress_in_servicelist = ConfigSelection(default='barright', choices=[ ('barleft', _("Progress bar left")), - ('barright', _("Progress bar right")), + ('barright', _("Progress bar right (only available in single line mode)")), ('percleft', _("Percentage left")), - ('percright', _("Percentage right")), + ('percright', _("Percentage right (only available in single line mode)")), ('no', _("No"))]) config.usage.show_channel_numbers_in_servicelist = ConfigYesNo(default=True) config.usage.show_channel_jump_in_servicelist = ConfigSelection(default="alpha", choices=[ diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 47869011567..22266df131e 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -856,7 +856,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const time_t now = time(0); std::string event_name = "", next_event_name = ""; - int event_begin = 0, event_duration = 0, xlpos = m_itemsize.width(), ctrlHeight=m_itemheight, yoffs=0; + int event_begin = 0, event_duration = 0, xlpos = m_itemsize.width(), ctrlHeight=m_itemheight, yoffs=0, yoffs_orig=0; bool is_event = isPlayable && service_info && !service_info->getEvent(ref, evt); if (m_visual_mode == visSkinDefined) { if (is_event){ @@ -864,10 +864,11 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } if (!event_name.empty()) { ctrlHeight = m_itemheight/2; - yoffs = 5; + yoffs_orig = 5; + yoffs = m_has_next_event ? ctrlHeight - 2 : 5; } if (!isMarker && !isDirectory) { - ePtr &pixmap = service_res_str == "1f" ? m_pixmaps[pic4K] : (service_res_str == "19" || service_res_str == "11") ? + ePtr &pixmap = service_res_str == "1f" ? m_pixmaps[pic4K] : (service_res_str == "19" || service_res_str == "11") ? m_pixmaps[picHD] : m_pixmaps[picSD]; if (pixmap) @@ -1007,6 +1008,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const int xoffsMarker = xoffs + ((isDirectory || isMarker) ? ((hasPicon && isMarker ? 125 : m_itemheight) + 16 + 8) : 0); int correction = 0; + int service_name_end = 0; if (!m_marker_alignment.empty() && m_marker_alignment == "center" && isMarker) { xoffsMarker = (m_itemsize.width() - bboxName.width()) / 2; correction = 16; @@ -1034,8 +1036,8 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const para->setFont(m_element_font[celServiceName]); para->renderString(text.c_str()); eRect bbox = para->getBoundBox(); - painter.renderPara(para, ePoint(xoffsMarker - correction, offset.y() + yoffs + ((ctrlHeight - bbox.height())/2))); - + service_name_end = xoffsMarker - correction + bbox.width() + m_items_distances; + painter.renderPara(para, ePoint(xoffsMarker - correction, offset.y() + yoffs_orig + ((ctrlHeight - bbox.height())/2))); if (isDirectory || (isMarker && !m_marker_as_line)) { if (pixmap_mDir) { @@ -1061,7 +1063,6 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const painter.fill(secondLineRect); } - // event name if (is_event) { @@ -1070,59 +1071,64 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const event_duration = evt->getDuration(); int timeLeft = event_begin + event_duration - now; eRect progressBarRect = m_element_position[celServiceEventProgressbar]; + if (m_has_next_event && event_begin > 0 && !service_info->getEvent(*m_cursor, evt_next, (event_begin + event_duration))) + next_event_name = evt_next->getEventName(); if (!event_name.empty()) { //--------------------------------------------------- Event Progressbar ----------------------------------------------------------------- if (progressBarRect.width() > 0) { - int pb_xpos = xoffs; - int pb_ypos = offset.y() + m_itemheight/2 + (m_itemheight/2 - m_progressbar_height - 2 * m_progressbar_border_width) / 2; - int pb_width = 75 - 2 * m_progressbar_border_width; + int pb_yoffs_corr = m_itemheight/2; + if (m_has_next_event) pb_yoffs_corr = 5; + int pb_xpos = m_has_next_event ? (m_itemsize.width() - 15 - progressBarRect.width()) : xoffs; + int pb_ypos = offset.y() + pb_yoffs_corr + (m_itemheight/2 - m_progressbar_height - 2 * m_progressbar_border_width) / 2; + int pb_width = progressBarRect.width() - 2 * m_progressbar_border_width; gRGB ProgressbarBorderColor = 0xdfdfdf; int evt_done = pb_width * (now - event_begin) / event_duration; - // the progress data... - eRect tmp = eRect(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width, evt_done, m_progressbar_height); - ePtr &pixmap = m_pixmaps[picServiceEventProgressbar]; - if (pixmap) { - painter.clip(tmp); - painter.blit(pixmap, ePoint(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width), tmp, gPainter::BT_ALPHABLEND); - painter.clippop(); - } - else { - if (!selected && m_color_set[serviceEventProgressbarColor]) - painter.setForegroundColor(m_color[serviceEventProgressbarColor]); - else if (selected && m_color_set[serviceEventProgressbarColorSelected]) - painter.setForegroundColor(m_color[serviceEventProgressbarColorSelected]); - painter.fill(tmp); - } - - // the progressbar border - if (!selected) { - if (m_color_set[serviceEventProgressbarBorderColor]) - ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColor]; - else if (m_color_set[eventborderForeground]) - ProgressbarBorderColor = m_color[eventborderForeground]; - } - else { /* !selected */ - if (m_color_set[serviceEventProgressbarBorderColorSelected]) - ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColorSelected]; - else if (m_color_set[eventborderForegroundSelected]) - ProgressbarBorderColor = m_color[eventborderForegroundSelected]; - } - painter.setForegroundColor(ProgressbarBorderColor); + if (!startsWith(m_progress_mode, "perc")) { + // the progress data... + eRect tmp = eRect(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width, evt_done, m_progressbar_height); + ePtr &pixmap = m_pixmaps[picServiceEventProgressbar]; + if (pixmap) { + painter.clip(tmp); + painter.blit(pixmap, ePoint(pb_xpos + m_progressbar_border_width, pb_ypos + m_progressbar_border_width), tmp, gPainter::BT_ALPHABLEND); + painter.clippop(); + } + else { + if (!selected && m_color_set[serviceEventProgressbarColor]) + painter.setForegroundColor(m_color[serviceEventProgressbarColor]); + else if (selected && m_color_set[serviceEventProgressbarColorSelected]) + painter.setForegroundColor(m_color[serviceEventProgressbarColorSelected]); + painter.fill(tmp); + } - if (m_progressbar_border_width) - { - painter.fill(eRect(pb_xpos, pb_ypos, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); - painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width + m_progressbar_height, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); - painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); - painter.fill(eRect(pb_xpos + m_progressbar_border_width + pb_width, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); + // the progressbar border + if (!selected) { + if (m_color_set[serviceEventProgressbarBorderColor]) + ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColor]; + else if (m_color_set[eventborderForeground]) + ProgressbarBorderColor = m_color[eventborderForeground]; + } + else { /* !selected */ + if (m_color_set[serviceEventProgressbarBorderColorSelected]) + ProgressbarBorderColor = m_color[serviceEventProgressbarBorderColorSelected]; + else if (m_color_set[eventborderForegroundSelected]) + ProgressbarBorderColor = m_color[eventborderForegroundSelected]; + } + painter.setForegroundColor(ProgressbarBorderColor); + + if (m_progressbar_border_width) + { + painter.fill(eRect(pb_xpos, pb_ypos, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); + painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width + m_progressbar_height, pb_width + 2 * m_progressbar_border_width, m_progressbar_border_width)); + painter.fill(eRect(pb_xpos, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); + painter.fill(eRect(pb_xpos + m_progressbar_border_width + pb_width, pb_ypos + m_progressbar_border_width, m_progressbar_border_width, m_progressbar_height)); + } + else + painter.fill(eRect(pb_xpos + evt_done, pb_ypos, pb_width - evt_done, m_progressbar_height)); + if (!m_has_next_event) xoffs += pb_width + 16; } - else - painter.fill(eRect(pb_xpos + evt_done, pb_ypos, pb_width - evt_done, m_progressbar_height)); - - xoffs += pb_width + 16; } //------------------------------------------------------- Event Name -------------------------------------------------------------------- @@ -1155,27 +1161,86 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const } } - //------------------------------------------------ Event remaining ------------------------------------------------------------------------ - std::string timeLeft_str = ""; - char buffer[15]; - snprintf(buffer, sizeof(buffer), "+%d min", timeLeft/60 ); - timeLeft_str = buffer; - ePtr paraLeft = new eTextPara(eRect(0, 0, m_itemsize.width(), m_itemheight/2)); - paraLeft->setFont(m_element_font[celServiceInfo]); - paraLeft->renderString(timeLeft_str.c_str()); - eRect bboxtLeft = paraLeft->getBoundBox(); - painter.renderPara(paraLeft, ePoint(m_itemsize.width() - bboxtLeft.width() - 15, offset.y() - 2 + m_itemheight/2 + ((m_itemheight/2 - bboxtLeft.height())/2))); + eRect bboxtLeft = eRect(); + if (!m_has_next_event) { + //------------------------------------------------ Event remaining ------------------------------------------------------------------------ + std::string timeLeft_str = ""; + char buffer[15]; + snprintf(buffer, sizeof(buffer), ("%s" + m_text_time).c_str(), timeLeft == 0 ? "" : "+", timeLeft/60); + timeLeft_str = buffer; + ePtr paraLeft = new eTextPara(eRect(0, 0, m_itemsize.width(), m_itemheight/2)); + paraLeft->setFont(m_element_font[celServiceInfo]); + paraLeft->renderString(timeLeft_str.c_str()); + bboxtLeft = paraLeft->getBoundBox(); + painter.renderPara(paraLeft, ePoint(m_itemsize.width() - bboxtLeft.width() - 15, offset.y() - 2 + m_itemheight/2 + ((m_itemheight/2 - bboxtLeft.height())/2))); + } + + std::string percent = ""; + if (startsWith(m_progress_mode, "perc")) { + char buffer[15]; + snprintf(buffer, sizeof(buffer), "%d %%", (int)(100 * (now - event_begin) / event_duration)); + percent = buffer; + } //------------------------------------------------- Event name ------------------------------------------------------------------------------ - ePtr para = new eTextPara(eRect(0, 0, m_itemsize.width() - xoffs - bboxtLeft.width() - 25 - m_items_distances, m_itemheight/2)); - para->setFont(m_element_font[celServiceInfo]); - para->renderString(text.c_str()); - eRect bbox = para->getBoundBox(); - painter.renderPara(para, ePoint(xoffs, offset.y() - 2 + m_itemheight/2 + ((m_itemheight/2 - bbox.height())/2))); + if (m_has_next_event) { + ePtr para = new eTextPara(eRect(0, 0, m_itemsize.width() - xoffs - m_items_distances - 15, m_itemheight/2)); + para->setFont(m_element_font[celServiceInfo]); + para->renderString(text.c_str()); + eRect bbox = para->getBoundBox(); + painter.renderPara(para, ePoint(service_name_end, offset.y() + yoffs_orig + ((ctrlHeight - bbox.height())/2))); + + if (!percent.empty()) { + ePtr paraPrec = new eTextPara(eRect(0, 0, m_itemsize.width(), m_itemheight/2)); + paraPrec->setFont(m_element_font[celServiceInfo]); + paraPrec->renderString(percent.c_str()); + eRect bboxPerc = paraPrec->getBoundBox(); + painter.renderPara(paraPrec, ePoint(m_itemsize.width() - 15 - bboxPerc.width() , offset.y() + yoffs_orig + ((ctrlHeight - bboxPerc.height())/2))); + } + + if (!next_event_name.empty()) { + if (serviceAvail) + { + if (!selected && m_color_set[eventNextForeground]) + { + painter.setForegroundColor(m_color[eventNextForeground]); + EventProgressbarColor = m_color[eventNextForeground]; + } + else if (selected && m_color_set[eventNextForegroundSelected]) + { + painter.setForegroundColor(m_color[eventNextForegroundSelected]); + EventProgressbarColor = m_color[eventNextForegroundSelected]; + } + else + painter.setForegroundColor(gRGB(0xe7b53f)); + + if (serviceFallback && !selected && m_color_set[eventNextForegroundFallback]) // fallback receiver + { + painter.setForegroundColor(m_color[eventNextForegroundFallback]); + EventProgressbarColor = m_color[eventNextForegroundFallback]; + } + else if (serviceFallback && selected && m_color_set[eventNextForegroundSelectedFallback]) + { + painter.setForegroundColor(m_color[eventNextForegroundSelectedFallback]); + EventProgressbarColor = m_color[eventNextForegroundSelectedFallback]; + } + } + ePtr paraNext = new eTextPara(eRect(0, 0, xlpos - service_name_end - m_items_distances, m_itemheight/2)); + paraNext->setFont(m_element_font[celServiceNextInfo]); + paraNext->renderString((m_next_title + next_event_name).c_str()); + eRect bboxNext = paraNext->getBoundBox(); + painter.renderPara(paraNext, ePoint(xoffs, offset.y() - 2 + m_itemheight/2 + ((m_itemheight/2 - bboxNext.height())/2))); + } + } else { + ePtr para = new eTextPara(eRect(0, 0, m_itemsize.width() - xoffs - bboxtLeft.width() - 25 - m_items_distances, m_itemheight/2)); + para->setFont(m_element_font[celServiceInfo]); + para->renderString(((!percent.empty() ? (percent + m_separator) : "") + text).c_str()); + eRect bbox = para->getBoundBox(); + painter.renderPara(para, ePoint(xoffs, offset.y() - 2 + m_itemheight/2 + ((m_itemheight/2 - bbox.height())/2))); + } } } } else { - // Single line mode goes here if (service_info) service_info->getName(ref, text); @@ -1204,12 +1269,10 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const pixmap_system_size = pixmap_system->size(); } - if (m_pixmaps[picCrypto]) { pixmap_crypto_size = m_pixmaps[picCrypto]->size(); } - if (m_pixmaps[picRecord]) { pixmap_rec_size = m_pixmaps[picRecord]->size(); } @@ -1353,20 +1416,17 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const int iconRecordPosX = iconSystemPosX; int iconOffsX = iconSystemPosX; - if (m_servicetype_icon_mode == 1 && pixmap_system) { iconCryptoPosX += pixmap_system_size.width() + m_items_distances; iconRecordPosX = iconCryptoPosX; iconOffsX += pixmap_system_size.width() + m_items_distances; } - if (m_crypto_icon_mode == 1 && m_pixmaps[picCrypto]) { iconRecordPosX += pixmap_crypto_size.width() + m_items_distances; iconOffsX += pixmap_crypto_size.width() + m_items_distances; } - if (isRecorded && m_record_indicator_mode == 1 && m_pixmaps[picRecord]) { iconOffsX += pixmap_rec_size.width() + m_items_distances; } @@ -1378,7 +1438,6 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const painter.clippop(); } - if (m_crypto_icon_mode == 1 && m_pixmaps[picCrypto] && service_info && service_info->isCrypted()) { eRect area = eRect(iconCryptoPosX, offset.y() + (ctrlHeight - pixmap_crypto_size.height())/2, pixmap_crypto_size.width(), pixmap_crypto_size.height()); painter.clip(area); @@ -1386,7 +1445,6 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const painter.clippop(); } - if (isRecorded && m_pixmaps[picRecord] && m_record_indicator_mode == 1) { eRect area = eRect(iconRecordPosX, offset.y() + (ctrlHeight - pixmap_rec_size.height())/2, pixmap_rec_size.width(), pixmap_rec_size.height()); painter.clip(area); @@ -1413,20 +1471,17 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const xoffs = iconOffsX; } - if (m_crypto_icon_mode == 2 && m_pixmaps[picCrypto] && service_info && service_info->isCrypted()) { iconRecordPosX += pixmap_crypto_size.width() + m_items_distances; iconOffsX += pixmap_crypto_size.width() + m_items_distances; xoffs = iconOffsX; } - if (isRecorded && m_record_indicator_mode == 2 && m_pixmaps[picRecord]) { iconOffsX += pixmap_rec_size.width() + m_items_distances; xoffs = iconOffsX; } - if (m_servicetype_icon_mode == 2 && pixmap_system) { eRect area = eRect(iconSystemPosX, offset.y() + (ctrlHeight - pixmap_system_size.height())/2, pixmap_system_size.width(), pixmap_system_size.height()); painter.clip(area); @@ -1434,7 +1489,6 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const painter.clippop(); } - if (m_crypto_icon_mode == 2 && m_pixmaps[picCrypto] && service_info && service_info->isCrypted()) { eRect area = eRect(iconCryptoPosX, offset.y() + (ctrlHeight - pixmap_crypto_size.height())/2, pixmap_crypto_size.width(), pixmap_crypto_size.height()); painter.clip(area); @@ -1442,7 +1496,6 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const painter.clippop(); } - if (isRecorded && m_pixmaps[picRecord] && m_record_indicator_mode == 2) { eRect area = eRect(iconRecordPosX, offset.y() + (ctrlHeight - pixmap_rec_size.height())/2, pixmap_rec_size.width(), pixmap_rec_size.height()); painter.clip(area); diff --git a/lib/service/listboxservice.h b/lib/service/listboxservice.h index a4fba48ce3d..bfb277c2b57 100644 --- a/lib/service/listboxservice.h +++ b/lib/service/listboxservice.h @@ -110,10 +110,13 @@ class eListboxServiceContent: public virtual iListboxContent void setAlternativeNumberingMode(bool b) { m_alternative_numbering = b; } void setProgressBarMode(std::string s) { m_progress_mode = s; } void setAlternativeRecordMatching(bool b) { m_alternative_record_match = b; } + void setHasNextEvent(bool b) { m_has_next_event = b; } + void setNextTitle(const std::string &string) { m_next_title = string; } + void setTextTime(const std::string &string) { m_text_time = string; } void setTextSeparator(const std::string &string) { m_separator = string; } void setMarkerTextAlignment(const std::string &string) { m_marker_alignment = string; } // currently supports left and center - void setMarkerLineColor(const gRGB &col) { + void setMarkerLineColor(const gRGB &col) { m_markerline_color = col; m_markerline_color_set = 1; } @@ -217,7 +220,9 @@ class eListboxServiceContent: public virtual iListboxContent gRGB m_markerline_color; int m_markerline_color_set; bool m_alternative_record_match; + bool m_has_next_event; + std::string m_text_time; std::string m_next_title; std::string m_separator; std::string m_marker_alignment; From a57e0d04f3a35f292a410fb5379406ffc57a0176 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Fri, 15 Dec 2023 10:00:31 +0000 Subject: [PATCH 348/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Components/ServiceList.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index c927a7a7a13..b0c6a48b5ca 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -488,11 +488,11 @@ def setMode(self, mode): if two_lines_val: timeText = _("%d min") self.l.setTextTime(timeText) - + if two_lines_val > 1: nextTitle = _("NEXT") + ": " self.l.setNextTitle(nextTitle) - + self.l.setHasNextEvent(two_lines_val > 1) if config.usage.service_icon_enable.value: From dcecc7deba3a5f2281747348fbdf36f0ae5fd4df Mon Sep 17 00:00:00 2001 From: Rob van der Does Date: Fri, 15 Dec 2023 11:17:54 +0100 Subject: [PATCH 349/401] [Translations] Update Dutch (NL) translation. --- po/nl.po | 53 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/po/nl.po b/po/nl.po index bca14d73dd7..accbfb69fbb 100644 --- a/po/nl.po +++ b/po/nl.po @@ -3,8 +3,8 @@ msgid "" msgstr "" "Project-Id-Version: ViX\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-12-03 20:33+0000\n" -"PO-Revision-Date: 2023-12-05 16:50+0100\n" +"POT-Creation-Date: 2023-12-14 12:09+0000\n" +"PO-Revision-Date: 2023-12-15 11:16+0100\n" "Last-Translator: Rob van der Does \n" "Language-Team: Andy Blackburn, Rob van der Does\n" "Language: nl\n" @@ -10174,6 +10174,9 @@ msgstr "Speel de gemarkeerde opname af" msgid "Play the selected recording" msgstr "Speel de geselecteerde opname af" +msgid "Playback" +msgstr "Afspelen" + msgid "" "Playback information missing\n" "Playback aborted to avoid crash\n" @@ -10291,9 +10294,6 @@ msgstr "Selecteer een subkanaal voor opname..." msgid "Please select a subservice..." msgstr "Selecteer een subkanaal..." -msgid "Please select a valid directory." -msgstr "Kies een geldige map." - msgid "Please select device to use as SWAP file location." msgstr "Kies het medium voor het SWAP-bestand." @@ -11132,6 +11132,9 @@ msgstr "Ontvanger of driver ondersteunt geen FCC" msgid "Record" msgstr "Opname" +msgid "Record icon match" +msgstr "Opname-icoon overeenkomst" + msgid "Record next" msgstr "Neem volgende op" @@ -11148,9 +11151,6 @@ msgstr "Opnametijd beperkt vanwege conflicterende timer %s" msgid "Recording" msgstr "Opname" -msgid "Recording & Playback" -msgstr "Opname & afspelen" - msgid "Recording 4097, 5001 and 5002 streams not possible with external players, so convert recordings to servicetype 1." msgstr "Opname van 4097, 5001 en 5002 streams is niet mogelijk met externe spelers; converteer deze naar servicetype 1." @@ -11161,9 +11161,6 @@ msgstr "" "Opname van IPTV met systeemapp is ingeschakeld, timer afgelopen!\n" "Controleer deze!" -msgid "Recording and playback" -msgstr "Opname en afspelen" - msgid "Recording and playback settings" msgstr "Opname-en afspeelinstellingen" @@ -12351,6 +12348,9 @@ msgstr "Kies de standaard actie voor de INFO-toets" msgid "Select destination for:" msgstr "Selecteer bestemming voor:" +msgid "Select display of record icon based on 'Sref only' or 'Sref + Stream url' where applicable." +msgstr "Kies tussen tonen van opname-icoon op basis van 'alleen Sref' of 'Sref + stream url'." + msgid "Select extra packages folder" msgstr "Kies de folder met extra plugins" @@ -13331,8 +13331,8 @@ msgstr "Toon de pluginbrowser" msgid "Show the radio player" msgstr "Radioweergave modus" -msgid "Show the service information on two lines in the channel selection screen. You can choose between the current event description below the channel name, or the current event description next to the channel name, and the next event description on the second line." -msgstr "Toon de kanaalinformatie in twee regels in het kanaalselectiescherm. U kunt kiezen tussen de huidige programmabeschrijving onder de kanaalnaam of de huidige programmabeschrijving naast de kanaalnaam en het volgende programma de tweede regel." +msgid "Show the service information on two lines in the channel selection screen." +msgstr "Toon de kanaalinformatie op twee regels in de kanaallijst." msgid "Show the tv player" msgstr "TV-weergave modus" @@ -13653,6 +13653,12 @@ msgstr "Samenleving & cultuur" msgid "Softcam Actions" msgstr "Softcam acties" +msgid "Softcam Management" +msgstr "Softcambeheer" + +msgid "Softcam Manager" +msgstr "Softcammanager" + msgid "Softcam Script" msgstr "Softcam script" @@ -13674,9 +13680,6 @@ msgstr "Softcam stopt..." msgid "SoftcamCheck" msgstr "Softcamcontrole" -msgid "SoftcamManager" -msgstr "Softcammanager" - msgid "SoftcamScript enable/disable cam restart" msgstr "SoftcamScript schakelt cam-herstart in/uit" @@ -13866,6 +13869,12 @@ msgstr "sportmagazine" msgid "Sprache" msgstr "Taal" +msgid "Sref + stream url" +msgstr "Sref + stream url" + +msgid "Sref only" +msgstr "Alleen Sref" + msgid "Sri Lanka" msgstr "Sri Lanka" @@ -19073,6 +19082,9 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Perform a settings backup, making a backup before updating is strongly advised." #~ msgstr "Maak een settingsback-up; het maken van een back-up alvorens te updaten wordt sterk geadviseerd." +#~ msgid "Please select a valid directory." +#~ msgstr "Kies een geldige map." + #~ msgid "Please select medium to use as backup location" #~ msgstr "Selecteer het te gebruiken medium als back-up lokatie" @@ -19122,6 +19134,12 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Query before image backup starts" #~ msgstr "Vraag alvorens image back-up te starten" +#~ msgid "Recording & Playback" +#~ msgstr "Opname & afspelen" + +#~ msgid "Recording and playback" +#~ msgstr "Opname en afspelen" + #~ msgid "Reload" #~ msgstr "Herlaad" @@ -19206,6 +19224,9 @@ msgstr "| aparte lijst van voorvoegsels die u van namen wil verwijderen, geschei #~ msgid "Show /tmp/ecm.info" #~ msgstr "Toon /tmp/ecm.info" +#~ msgid "Show the service information on two lines in the channel selection screen. You can choose between the current event description below the channel name, or the current event description next to the channel name, and the next event description on the second line." +#~ msgstr "Toon de kanaalinformatie in twee regels in het kanaalselectiescherm. U kunt kiezen tussen de huidige programmabeschrijving onder de kanaalnaam of de huidige programmabeschrijving naast de kanaalnaam en het volgende programma de tweede regel." + #~ msgid "Skin Setup" #~ msgstr "Skin instellingen" From 56d4a67f7a7acb4af14459aa20eb3bd53380cfd0 Mon Sep 17 00:00:00 2001 From: Orlandoxx <95180049+Orlandoxx@users.noreply.github.com> Date: Fri, 15 Dec 2023 13:43:07 +0200 Subject: [PATCH 350/401] Updated Finnish (fi.po) translation. Added 'two lines' changes. --- po/fi.po | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/po/fi.po b/po/fi.po index ebbfe70aa80..3d8ca078d51 100644 --- a/po/fi.po +++ b/po/fi.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: enigma2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-27 23:35+0000\n" -"PO-Revision-Date: 2023-12-14 18:36+0200\n" +"PO-Revision-Date: 2023-12-15 13:41+0200\n" "Last-Translator: Orlandox\n" "Language-Team: timoj/Kojo/Samzam/Orlandox\n" "Language: fi\n" @@ -3638,11 +3638,11 @@ msgstr "Määrittää kuinka monta minuuttia päättyneiden ohjelmien ohjelmatie msgid "Configure how recording filenames are constructed." msgstr "Määritä tallenteiden tiedostonimien rakenne." -msgid "Configure if and how crypto icons will be shown in the channel selection list." -msgstr "Määrittää näytetäänkö/miten näytetään salauksen kuvakkeet kanavalistassa." +msgid "Configure if and how crypto icons will be shown in the channel selection list (left alignment only available in single line mode)." +msgstr "Määrittää näytetäänkö/miten näytetään salauksen kuvakkeet kanavalistassa (tasaus vasemmalle käytettävissä vain yksirivisessä tilassa)." -msgid "Configure if and how service type icons will be shown." -msgstr "Määritä näytetäänkö/miten näytetään kanavatyypin kuvakkeet." +msgid "Configure if and how service type icons will be shown (left alignment only available in single line mode)." +msgstr "Määritä näytetäänkö/miten näytetään kanavatyypin kuvakkeet (tasaus vasemmalle käytettävissä vain yksirivisessä tilassa)." msgid "Configure if and how the record indicator will be shown in the channel selection list." msgstr "Määrittää kuinka tallennuksen indikaattori näytetään kanavalistassa." @@ -7700,8 +7700,8 @@ msgstr "Libanon" msgid "Left" msgstr "Vasen" -msgid "Left from servicename" -msgstr "Kanavanimestä vasemmalle" +msgid "Left from servicename (only available in single line mode)" +msgstr "Kanavanimestä vasemmalle (käytettävissä vain yksirivisessä tilassa)" msgid "Left long" msgstr "Pitkä vasemmalle" @@ -8731,6 +8731,9 @@ msgstr "Uutiset/Ajankohtaisasiat/Sosiaalinen" msgid "Next" msgstr "Seuraava" +msgid "NEXT" +msgstr "SEURAAVA" + msgctxt "now/next: 'next' event label" msgid "Next" msgstr "SEURAAVA" @@ -9459,8 +9462,8 @@ msgstr "Prosenttia" msgid "Percentage left" msgstr "Prosentit vasemmalla" -msgid "Percentage right" -msgstr "Prosentit oikealla" +msgid "Percentage right (only available in single line mode)" +msgstr "Prosentit oikealla (käytettävissä vain yksirivisessä tilassa)" msgid "Perform a complete image backup before updating." msgstr "Suorita täydellinen image-varmuuskopiointi ennen päivitystä." @@ -10219,8 +10222,8 @@ msgstr "Etenemispalkki" msgid "Progress bar left" msgstr "Etenemispalkki vasemmalla" -msgid "Progress bar right" -msgstr "Etenemispalkki oikealla" +msgid "Progress bar right (only available in single line mode)" +msgstr "Etenemispalkki oikealla (käytettävissä vain yksirivisessä tilassa)" msgid "Prominent" msgstr "Kuuluisa" @@ -12101,8 +12104,8 @@ msgstr "Kellonaika, jolloin ajastuksen pitää käynnistyä." msgid "Set the time the timer must stop." msgstr "Kellonaika, jolloin ajastuksen pitää pysähtyä." -msgid "Set the type of the progress indication in the channel selection screen." -msgstr "Määritä ohjelman pituuden osoittamisen tyyppi kanavien valintalistassa." +msgid "Set the type of the progress indication in the channel selection screen (right alignment only available in single line mode)." +msgstr "Määritä ohjelman pituuden osoittamisen tyyppi kanavien valintalistassa (tasaus oikealle käytettävissä vain yksirivisessä tilassa)." msgid "Set to the desired primetime." msgstr "Asetettu parhaaseen katseluaikaan." @@ -13540,7 +13543,7 @@ msgstr "" "Suomenkielinen käännös: timoj, Kojo, Samzam, Orlandox\n" "\n" "Ylläpito : Orlandox\n" -"14.12.2023\n" +"15.12.2023\n" "http://www.huoltovalikko.com" msgid "TS file is too large for ISO9660 level 1!" @@ -17394,8 +17397,8 @@ msgstr "tosi" msgid "two lines" msgstr "kaksi riviä" -msgid "two lines and next event" -msgstr "kaksi riviä ja seuraava ohjelma" +msgid "two lines+next event" +msgstr "kaksi riviä + seuraava ohjelma" msgid "two lines alternative" msgstr "kahden rivin vaihtoehto" From bea824139b1ae528c868f1b16a5c44e2ae1b31f6 Mon Sep 17 00:00:00 2001 From: Tony Whalley Date: Fri, 15 Dec 2023 14:52:05 +0100 Subject: [PATCH 351/401] [Videomode] - fix Multi and bcm7252 GB4K --- lib/python/Screens/VideoMode.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/lib/python/Screens/VideoMode.py b/lib/python/Screens/VideoMode.py index 34e64ea56c4..723d139914f 100644 --- a/lib/python/Screens/VideoMode.py +++ b/lib/python/Screens/VideoMode.py @@ -19,7 +19,7 @@ resolutionlabel = None previous = None isDedicated3D = False -videomode = "/proc/stb/video/videomode_50hz" if getBoxType() in ("gbquad4k", "gbue4k") else "/proc/stb/video/videomode" +videomode = "/proc/stb/video/videomode" class VideoSetup(ConfigListScreen, Screen): @@ -306,12 +306,8 @@ def VideoChangeDetect(self): self.delay = False self.detecttimer.stop() return - try: - with open(videomode, "r+") as fd: # GB4K can fail on initial open - current_mode = fd.read()[:-1].replace("\n", "") - except: - with open("/proc/stb/video/videomode", "r") as fd: - current_mode = fd.read()[:-1].replace("\n", "") + with open(videomode, "r") as fd: + current_mode = fd.read()[:-1].replace("\n", "") if current_mode.upper() in ("PAL", "NTSC"): current_mode = current_mode.upper() video_height = None @@ -373,7 +369,6 @@ def VideoChangeDetect(self): new_rate = str((new_rate + 500) // 1000) else: new_rate = config_rate - if video_pol != -1: new_pol = str(video_pol) else: @@ -435,9 +430,9 @@ def VideoChangeDetect(self): else: if video_rate == 25000: # videomode_25hz is not in proc and will be reset 2nd pass thru , so do it now. new_rate = 50 - if path.exists("/proc/stb/video/videomode_%shz" % new_rate) and config_rate == "multi": - try: - with open("/proc/stb/video/videomode_%shz" % new_rate, "r+") as fd: + if path.exists("%s_%shz" % (videomode, new_rate)) and config_rate == "multi": + try: # gbuhd4k/gbue4k sometimes will 1st time fail on open + with open("%s_%shz" % (videomode, new_rate), "r") as fd: multi_videomode = fd.read().replace("\n", "") if multi_videomode and (current_mode != multi_videomode): write_mode = multi_videomode @@ -452,6 +447,9 @@ def VideoChangeDetect(self): print("[VideoMode] setMode - port: %s, mode: %s" % (config.av.videoport.value, write_mode)) with open(videomode, "w+") as fd: fd.write(write_mode) + # read_mode = fd.read().replace("\n", "") + # print("[VideoMode] fd.write_mode, read_mode", write_mode, " ", read_mode) + iAV.setAspect(config.av.aspect) iAV.setWss(config.av.wss) iAV.setPolicy43(config.av.policy_43) From 5677d1c38783c6c7059fe108420a36d118e7194d Mon Sep 17 00:00:00 2001 From: Tony Whalley Date: Fri, 15 Dec 2023 15:22:28 +0100 Subject: [PATCH 352/401] ServiceList - comment unused import getTextBoundarySize --- lib/python/Components/ServiceList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index b0c6a48b5ca..d26976e2587 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -3,7 +3,7 @@ from enigma import eListboxServiceContent, eListbox, eServiceCenter, eServiceReference, gFont, eRect, eSize from Tools.LoadPixmap import LoadPixmap -from Tools.TextBoundary import getTextBoundarySize +# from Tools.TextBoundary import getTextBoundarySize from Tools.Directories import resolveFilename, SCOPE_CURRENT_SKIN From e7a01488481afcb37a6b54e9a174fc86026e669c Mon Sep 17 00:00:00 2001 From: Tony Whalley Date: Fri, 15 Dec 2023 15:32:22 +0100 Subject: [PATCH 353/401] [Timeshift] remove unused import MessageBox --- lib/python/Screens/Timeshift.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/python/Screens/Timeshift.py b/lib/python/Screens/Timeshift.py index 355f648234f..f7478e50484 100644 --- a/lib/python/Screens/Timeshift.py +++ b/lib/python/Screens/Timeshift.py @@ -4,7 +4,6 @@ from Components.config import config from Screens.LocationBox import TimeshiftLocationBox -from Screens.MessageBox import MessageBox from Screens.Setup import Setup from Tools.Directories import fileExists import Components.Harddisk From 094fccc76ba034cf349c94fc468f66425b41f13a Mon Sep 17 00:00:00 2001 From: Tony Whalley Date: Fri, 15 Dec 2023 15:33:38 +0100 Subject: [PATCH 354/401] [VideoMode] - remove unused BoxBranding import --- lib/python/Screens/VideoMode.py | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/python/Screens/VideoMode.py b/lib/python/Screens/VideoMode.py index 723d139914f..70ac3ccf04e 100644 --- a/lib/python/Screens/VideoMode.py +++ b/lib/python/Screens/VideoMode.py @@ -1,5 +1,4 @@ from os import path -from boxbranding import getBoxType from enigma import iPlayableService, iServiceInformation, eTimer, eServiceCenter, eServiceReference, eDVBDB from Components.ActionMap import ActionMap From 18ee7454113c353297214451de3b9212cf24523f Mon Sep 17 00:00:00 2001 From: Betacentauri Date: Fri, 24 Nov 2023 21:24:44 +0100 Subject: [PATCH 355/401] [CI] Improve logging especially when 2 modules are used --- lib/dvb_ci/descrambler.cpp | 12 +-- lib/dvb_ci/descrambler.h | 2 +- lib/dvb_ci/dvbci.cpp | 58 ++++++------ lib/dvb_ci/dvbci_app_mmi.cpp | 6 +- lib/dvb_ci/dvbci_appmgr.cpp | 26 +++--- lib/dvb_ci/dvbci_cam_upgrade.cpp | 6 +- lib/dvb_ci/dvbci_camgr.cpp | 8 +- lib/dvb_ci/dvbci_ccmgr.cpp | 132 +++++++++++++-------------- lib/dvb_ci/dvbci_ccmgr_helper.cpp | 18 ++-- lib/dvb_ci/dvbci_ccmgr_helper.h | 2 +- lib/dvb_ci/dvbci_datetimemgr.cpp | 6 +- lib/dvb_ci/dvbci_hlcmgr.cpp | 10 +- lib/dvb_ci/dvbci_host_ctrl.cpp | 6 +- lib/dvb_ci/dvbci_mmi.cpp | 10 +- lib/dvb_ci/dvbci_operatorprofile.cpp | 16 ++-- lib/dvb_ci/dvbci_resmgr.cpp | 12 +-- lib/dvb_ci/dvbci_session.cpp | 69 +++++++------- 17 files changed, 199 insertions(+), 200 deletions(-) diff --git a/lib/dvb_ci/descrambler.cpp b/lib/dvb_ci/descrambler.cpp index 3d38fef9056..4e704ab8b20 100644 --- a/lib/dvb_ci/descrambler.cpp +++ b/lib/dvb_ci/descrambler.cpp @@ -55,7 +55,7 @@ int descrambler_set_key(int desc_fd, int index, int parity, unsigned char *data) d.data = data; if (ioctl(desc_fd, CA_SET_DESCR_DATA, &d) == -1) { - eWarning("[CI descrambler] set key failed"); + eWarning("[CI%d descrambler] set key failed", index); return -1; } @@ -66,7 +66,7 @@ int descrambler_set_key(int desc_fd, int index, int parity, unsigned char *data) d.data = data + 16; if (ioctl(desc_fd, CA_SET_DESCR_DATA, &d) == -1) { - eWarning("[CI descrambler] set iv failed"); + eWarning("[CI%d descrambler] set iv failed", index); return -1; } @@ -91,14 +91,14 @@ int descrambler_set_pid(int desc_fd, int index, int enable, int pid) p.index = flags; if (ioctl(desc_fd, CA_SET_PID, &p) == -1) { - eWarning("[CI descrambler] set pid failed"); + eWarning("[CI%d descrambler] set pid failed", index); return -1; } return 0; } -int descrambler_init(uint8_t ca_demux_id) +int descrambler_init(int slot, uint8_t ca_demux_id) { int desc_fd; @@ -106,9 +106,9 @@ int descrambler_init(uint8_t ca_demux_id) desc_fd = open(filename.c_str(), O_RDWR); if (desc_fd == -1) { - eWarning("[CI descrambler] can not open %s", filename.c_str()); + eWarning("[CI%d descrambler] can not open %s", slot, filename.c_str()); } - eDebug("[CI descrambler] using ca device %s", filename.c_str()); + eDebug("[CI%d descrambler] using ca device %s", slot, filename.c_str()); return desc_fd; } diff --git a/lib/dvb_ci/descrambler.h b/lib/dvb_ci/descrambler.h index d202137ab2d..ea232551576 100644 --- a/lib/dvb_ci/descrambler.h +++ b/lib/dvb_ci/descrambler.h @@ -1,7 +1,7 @@ #ifndef __DESCR_H_ #define __DESCR_H_ -int descrambler_init(uint8_t ca_demux_id); +int descrambler_init(int slot, uint8_t ca_demux_id); void descrambler_deinit(int desc_fd); int descrambler_set_key(int desc_fd, int index, int parity, unsigned char *data); int descrambler_set_pid(int desc_fd, int index, int enable, int pid); diff --git a/lib/dvb_ci/dvbci.cpp b/lib/dvb_ci/dvbci.cpp index e39dac2a01b..390e49687df 100644 --- a/lib/dvb_ci/dvbci.cpp +++ b/lib/dvb_ci/dvbci.cpp @@ -1159,7 +1159,7 @@ int eDVBCISlot::send(const unsigned char *data, size_t len) singleLock s(eDVBCIInterfaces::m_slot_lock); int res=0; unsigned int i; - eTraceNoNewLineStart("< "); + eTraceNoNewLineStart("[CI%d] < ", slotid); for(i = 0; i < len; i++) eTraceNoNewLine("%02x ",data[i]); eTraceNoNewLine("\n"); @@ -1181,7 +1181,7 @@ int eDVBCISlot::send(const unsigned char *data, size_t len) void eDVBCISlot::data(int what) { singleLock s(eDVBCIInterfaces::m_slot_lock); - eTrace("[CI] Slot %d what %d\n", getSlotID(), what); + eTrace("[CI%d] what %d\n", slotid, what); if(what == eSocketNotifier::Priority) { if(state != stateRemoved) { state = stateRemoved; @@ -1202,7 +1202,7 @@ void eDVBCISlot::data(int what) reset(); if(state != stateInserted) { - eDebug("[CI] ci inserted in slot %d", getSlotID()); + eDebug("[CI%d] ci inserted", slotid); state = stateInserted; /* emit */ eDVBCI_UI::getInstance()->m_messagepump.send(eDVBCIInterfaces::Message(eDVBCIInterfaces::Message::slotStateChanged, getSlotID(), 1)); notifier->setRequested(eSocketNotifier::Read|eSocketNotifier::Priority); @@ -1215,7 +1215,7 @@ void eDVBCISlot::data(int what) r = ::read(fd, data, 4096); if(r > 0) { int i; - eTraceNoNewLineStart("> "); + eTraceNoNewLineStart("[CI%d] > ", slotid); for(i=0;i= 0) @@ -1346,13 +1346,13 @@ void eDVBCISlot::determineCIVersion() char lv1Info[256] = { 0 }; if (ioctl(fd, 1, lv1Info) < 0) { - eTrace("[CI] Slot %d ioctl not supported: assume CI+ version 1", getSlotID()); + eTrace("[CI%d] ioctl not supported: assume CI+ version 1", slotid); m_ci_version = versionCIPlus1; return; } if (strlen(lv1Info) == 0) { - eTrace("[CI] Slot %d no LV1 info: assume CI+ version 1", getSlotID()); + eTrace("[CI%d] no LV1 info: assume CI+ version 1", slotid); m_ci_version = versionCIPlus1; return; } @@ -1375,12 +1375,12 @@ void eDVBCISlot::determineCIVersion() } if(!compatId) { - eTrace("[CI] Slot %d CI CAM detected", getSlotID()); + eTrace("[CI%d] CI CAM detected", slotid); m_ci_version = versionCI; return; } - eTrace("[CI] Slot %d CI+ compatibility ID: %s", getSlotID(), compatId); + eTrace("[CI%d] CI+ compatibility ID: %s", slotid, compatId); char *label, *id, flag = '+'; int version = versionCI; @@ -1397,7 +1397,7 @@ void eDVBCISlot::determineCIVersion() flag = *id++; version = strtol(id, 0, 0); - eDebug("[CI] Slot %d CI+ %c%d CAM detected", getSlotID(), flag, version); + eDebug("[CI%d] CI+ %c%d CAM detected", slotid, flag, version); break; } } @@ -1414,12 +1414,12 @@ int eDVBCISlot::getNumOfServices() int eDVBCISlot::reset() { - eDebug("[CI] Slot %d: reset requested", getSlotID()); + eDebug("[CI%d] reset requested", slotid); if (state == stateInvalid) { unsigned char buf[256]; - eDebug("[CI] flush"); + eDebug("[CI%d] flush", slotid); while(::read(fd, buf, 256)>0); state = stateResetted; } @@ -1437,7 +1437,7 @@ int eDVBCISlot::reset() int eDVBCISlot::startMMI() { - eDebug("[CI] Slot %d: startMMI()", getSlotID()); + eDebug("[CI%d] startMMI()", slotid); if(application_manager) application_manager->startMMI(); @@ -1447,7 +1447,7 @@ int eDVBCISlot::startMMI() int eDVBCISlot::stopMMI() { - eDebug("[CI] Slot %d: stopMMI()", getSlotID()); + eDebug("[CI%d] stopMMI()", slotid); if(mmi_session) mmi_session->stopMMI(); @@ -1457,7 +1457,7 @@ int eDVBCISlot::stopMMI() int eDVBCISlot::answerText(int answer) { - eDebug("[CI] Slot %d: answerText(%d)", getSlotID(), answer); + eDebug("[CI%d] answerText(%d)", slotid, answer); if(mmi_session) mmi_session->answerText(answer); @@ -1475,7 +1475,7 @@ int eDVBCISlot::getMMIState() int eDVBCISlot::answerEnq(char *value) { - eDebug("[CI] Slot %d: answerENQ(%s)", getSlotID(), value); + eDebug("[CI%d] answerENQ(%s)", slotid, value); if(mmi_session) mmi_session->answerEnq(value); @@ -1485,7 +1485,7 @@ int eDVBCISlot::answerEnq(char *value) int eDVBCISlot::cancelEnq() { - eDebug("[CI] Slot %d: cancelENQ", getSlotID()); + eDebug("[CI%d] cancelENQ", slotid); if(mmi_session) mmi_session->cancelEnq(); @@ -1503,7 +1503,7 @@ int eDVBCISlot::setCADemuxID(eDVBServicePMTHandler *pmthandler) if (!demux->getCADemuxID(dmx_id)) { m_ca_demux_id = dmx_id; - eDebug("[CI] Slot %d: CA demux_id = %d", getSlotID(), m_ca_demux_id); + eDebug("[CI%d] CA demux_id = %d", slotid, m_ca_demux_id); } else m_ca_demux_id = -1; @@ -1515,7 +1515,7 @@ int eDVBCISlot::sendCAPMT(eDVBServicePMTHandler *pmthandler, const std::vector &caids = ids.empty() ? ca_manager->getCAIDs() : ids; @@ -1539,7 +1539,7 @@ int eDVBCISlot::sendCAPMT(eDVBServicePMTHandler *pmthandler, const std::vectorsecond) && !sendEmpty ) { - eDebug("[CI] [eDVBCISlot] dont send self capmt version twice"); + eDebug("[CI%d] dont send self capmt version twice", slotid); return -1; } @@ -1550,15 +1550,15 @@ int eDVBCISlot::sendCAPMT(eDVBServicePMTHandler *pmthandler, const std::vectorgetSections().end() ) { - // eDebug("[CI] append"); + // eDebug("[CI%d] append", slotid); capmt.append(*i++); } capmt.writeToBuffer(raw_data); @@ -1586,7 +1586,7 @@ int eDVBCISlot::sendCAPMT(eDVBServicePMTHandler *pmthandler, const std::vectorgetSlotID(), session_nb, tag[0], tag[1], tag[2]); for (int i=0; igetSlotID(), tag[2]); break; } } @@ -27,7 +27,7 @@ int eDVBCIApplicationMMISession::doAction() switch (state) { default: - eWarning("[CI AMMI] unknown state"); + eWarning("[CI%d AMMI] unknown state", slot->getSlotID()); break; } diff --git a/lib/dvb_ci/dvbci_appmgr.cpp b/lib/dvb_ci/dvbci_appmgr.cpp index 1eaedb784a1..5c35566fe69 100644 --- a/lib/dvb_ci/dvbci_appmgr.cpp +++ b/lib/dvb_ci/dvbci_appmgr.cpp @@ -19,7 +19,7 @@ eDVBCIApplicationManagerSession::~eDVBCIApplicationManagerSession() int eDVBCIApplicationManagerSession::receivedAPDU(const unsigned char *tag,const void *data, int len) { - eTraceNoNewLine("[CI AM] SESSION(%d)/APP %02x %02x %02x: ", session_nb, tag[0], tag[1], tag[2]); + eTraceNoNewLine("[CI%d AM] SESSION(%d)/APP %02x %02x %02x: ", slot->getSlotID(), session_nb, tag[0], tag[1], tag[2]); for (int i=0; igetSlotID()); + eDebug("[CI%d AM] len: %d", slot->getSlotID(), len); + eDebug("[CI%d AM] application_type: %d", slot->getSlotID(), ((unsigned char*)data)[0]); + eDebug("[CI%d AM] application_manufacturer: %02x %02x", slot->getSlotID(), ((unsigned char*)data)[2], ((unsigned char*)data)[1]); + eDebug("[CI%d AM] manufacturer_code: %02x %02x", slot->getSlotID(), ((unsigned char*)data)[4],((unsigned char*)data)[3]); dl=((unsigned char*)data)[5]; if ((dl + 6) > len) { - eDebug("[CI AM] warning, invalid length (%d vs %d)", dl+6, len); + eDebug("[CI%d AM] warning, invalid length (%d vs %d)", slot->getSlotID(), dl+6, len); dl=len-6; } char str[dl + 1]; memcpy(str, ((char*)data) + 6, dl); str[dl] = '\0'; - eDebugNoNewLine("[CI AM] menu string: "); + eDebugNoNewLine("[CI%d AM] menu string: ", slot->getSlotID()); for (int i = 0; i < dl; ++i) eDebugNoNewLine("%c", ((unsigned char*)data)[i+6]); eDebugNoNewLine("\n"); @@ -54,7 +54,7 @@ int eDVBCIApplicationManagerSession::receivedAPDU(const unsigned char *tag,const if (m_app_name.size() > 0 && !isUTF8(m_app_name)) { m_app_name = repairUTF8(m_app_name.c_str(), m_app_name.size()); - eDebug("[CI AM] fixed menu string: %s", m_app_name.c_str()); + eDebug("[CI%d AM] fixed menu string: %s", slot->getSlotID(), m_app_name.c_str()); } /* emit */ eDVBCI_UI::getInstance()->m_messagepump.send(eDVBCIInterfaces::Message(eDVBCIInterfaces::Message::appNameChanged, slot->getSlotID(), m_app_name.c_str())); @@ -62,7 +62,7 @@ int eDVBCIApplicationManagerSession::receivedAPDU(const unsigned char *tag,const break; } default: - eWarning("[CI AM] unknown APDU tag 9F 80 %02x", tag[2]); + eWarning("[CI%d AM] unknown APDU tag 9F 80 %02x", slot->getSlotID(), tag[2]); break; } } @@ -81,11 +81,11 @@ int eDVBCIApplicationManagerSession::doAction() return 1; } case stateFinal: - eDebug("[CI AM] in final state."); + eDebug("[CI%d AM] in final state.", slot->getSlotID()); wantmenu = 0; if (wantmenu) { - eDebug("[CI AM] wantmenu: sending Tenter_menu"); + eDebug("[CI%d AM] wantmenu: sending Tenter_menu", slot->getSlotID()); const unsigned char tag[3]={0x9F, 0x80, 0x22}; // Tenter_menu sendAPDU(tag); wantmenu=0; @@ -99,7 +99,7 @@ int eDVBCIApplicationManagerSession::doAction() int eDVBCIApplicationManagerSession::startMMI() { - eDebug("[CI AM] in appmanager -> startmmi()"); + eDebug("[CI%d AM] in appmanager -> startmmi()", slot->getSlotID()); const unsigned char tag[3]={0x9F, 0x80, 0x22}; // Tenter_menu sendAPDU(tag); return 0; diff --git a/lib/dvb_ci/dvbci_cam_upgrade.cpp b/lib/dvb_ci/dvbci_cam_upgrade.cpp index 2d25906b649..6a2b24b0b0f 100644 --- a/lib/dvb_ci/dvbci_cam_upgrade.cpp +++ b/lib/dvb_ci/dvbci_cam_upgrade.cpp @@ -5,7 +5,7 @@ int eDVBCICAMUpgradeSession::receivedAPDU(const unsigned char *tag,const void *data, int len) { - eTraceNoNewLine("[CI CAMUP] SESSION(%d)/CAMUP %02x %02x %02x: ", session_nb, tag[0], tag[1], tag[2]); + eTraceNoNewLine("[CI%d CAMUP] SESSION(%d)/CAMUP %02x %02x %02x: ", slot->getSlotID(), session_nb, tag[0], tag[1], tag[2]); for (int i=0; igetSlotID(), tag[2]); break; } } @@ -27,7 +27,7 @@ int eDVBCICAMUpgradeSession::doAction() switch (state) { default: - eWarning("[CI CAMUP] unknown state"); + eWarning("[CI%d CAMUP] unknown state", slot->getSlotID()); break; } diff --git a/lib/dvb_ci/dvbci_camgr.cpp b/lib/dvb_ci/dvbci_camgr.cpp index c5b81def13e..7a8e334cab2 100644 --- a/lib/dvb_ci/dvbci_camgr.cpp +++ b/lib/dvb_ci/dvbci_camgr.cpp @@ -16,7 +16,7 @@ eDVBCICAManagerSession::~eDVBCICAManagerSession() int eDVBCICAManagerSession::receivedAPDU(const unsigned char *tag, const void *data, int len) { - eTraceNoNewLine("[CI CA] SESSION(%d)/CA %02x %02x %02x: ", session_nb, tag[0], tag[1], tag[2]); + eTraceNoNewLine("[CI%d CA] SESSION(%d)/CA %02x %02x %02x: ", slot->getSlotID(), session_nb, tag[0], tag[1], tag[2]); for (int i=0; igetSlotID()); for (int i=0; iexecuteRecheckPMTHandlersInMainloop(); break; default: - eWarning("[CI CA] unknown APDU tag 9F 80 %02x", tag[2]); + eWarning("[CI%d CA] unknown APDU tag 9F 80 %02x", slot->getSlotID(), tag[2]); break; } } @@ -56,7 +56,7 @@ int eDVBCICAManagerSession::doAction() return 0; } case stateFinal: - eWarning("[CI CA] stateFinal and action should not happen"); + eWarning("[CI%d CA] stateFinal and action should not happen", slot->getSlotID()); [[fallthrough]]; default: return 0; diff --git a/lib/dvb_ci/dvbci_ccmgr.cpp b/lib/dvb_ci/dvbci_ccmgr.cpp index c74ae7e7658..bff8ef35cbc 100644 --- a/lib/dvb_ci/dvbci_ccmgr.cpp +++ b/lib/dvb_ci/dvbci_ccmgr.cpp @@ -22,13 +22,13 @@ eDVBCICcSession::eDVBCICcSession(eDVBCISlot *slot, int version): m_current_ca_demux_id = 0; m_descrambler_new_key = false; - parameter_init(m_dh_p, m_dh_g, m_dh_q, m_s_key, m_key_data, m_iv); + parameter_init(m_slot->getSlotID(), m_dh_p, m_dh_g, m_dh_q, m_s_key, m_key_data, m_iv); m_ci_elements.init(); memset(buf, 0, 1); if (!m_ci_elements.set(STATUS_FIELD, buf, 1)) - eWarning("[CI RCC] can not set status"); + eWarning("[CI%d RCC] can not set status", m_slot->getSlotID()); memset(buf, 0, 32); buf[31] = 0x01; // URI_PROTOCOL_V1 @@ -38,7 +38,7 @@ eDVBCICcSession::eDVBCICcSession(eDVBCISlot *slot, int version): buf[31] |= 0x04; // URI_PROTOCOL_V4 if (!m_ci_elements.set(URI_VERSIONS, buf, 32)) - eWarning("[CI RCC] can not set uri_versions"); + eWarning("[CI%d RCC] can not set uri_versions", m_slot->getSlotID()); if (!get_authdata(host_id, m_dhsk, buf, m_slot->getSlotID(), m_akh_index)) { @@ -47,10 +47,10 @@ eDVBCICcSession::eDVBCICcSession(eDVBCISlot *slot, int version): } if (!m_ci_elements.set(AKH, buf, 32)) - eWarning("[CI RCC] can not set AKH"); + eWarning("[CI%d RCC] can not set AKH", m_slot->getSlotID()); if (!m_ci_elements.set(HOST_ID, host_id, 8)) - eWarning("[CI RCC] can not set host_id"); + eWarning("[CI%d RCC] can not set host_id", m_slot->getSlotID()); } eDVBCICcSession::~eDVBCICcSession() @@ -78,7 +78,7 @@ eDVBCICcSession::~eDVBCICcSession() int eDVBCICcSession::receivedAPDU(const unsigned char *tag, const void *data, int len) { - eTraceNoNewLineStart("[CI CC] SESSION(%d)/CC %02x %02x %02x: ", session_nb, tag[0], tag[1], tag[2]); + eTraceNoNewLineStart("[CI%d CC] SESSION(%d)/CC %02x %02x %02x: ", m_slot->getSlotID(), session_nb, tag[0], tag[1], tag[2]); for (int i=0; igetSlotID(), tag[2]); break; } } @@ -106,7 +106,7 @@ int eDVBCICcSession::doAction() case stateStarted: break; default: - eWarning("[CI CC] unknown state"); + eWarning("[CI%d CC] unknown state", m_slot->getSlotID()); break; } return 0; @@ -122,7 +122,7 @@ void eDVBCICcSession::addProgram(uint16_t program_number, std::vector& // first open ca device and set descrambler key if it's not set yet set_descrambler_key(); - eDebugNoNewLineStart("[CI CC] SESSION(%d)/ADD PROGRAM %04x: ", session_nb, program_number); + eDebugNoNewLineStart("[CI%d CC] SESSION(%d)/ADD PROGRAM %04x: ", m_slot->getSlotID(), session_nb, program_number); for (std::vector::iterator it = pids.begin(); it != pids.end(); ++it) eDebugNoNewLine("%02x ", *it); eDebugNoNewLine("\n"); @@ -133,7 +133,7 @@ void eDVBCICcSession::addProgram(uint16_t program_number, std::vector& void eDVBCICcSession::removeProgram(uint16_t program_number, std::vector& pids) { - eDebugNoNewLineStart("[CI CC] SESSION(%d)/REMOVE PROGRAM %04x: ", session_nb, program_number); + eDebugNoNewLineStart("[CI%d CC] SESSION(%d)/REMOVE PROGRAM %04x: ", m_slot->getSlotID(), session_nb, program_number); for (std::vector::iterator it = pids.begin(); it != pids.end(); ++it) eDebugNoNewLine("%02x ", *it); eDebugNoNewLine("\n"); @@ -160,7 +160,7 @@ void eDVBCICcSession::cc_data_req(const uint8_t *data, unsigned int len) if (len < 2) { - eWarning("[CI RCC] too short data"); + eWarning("[CI%d RCC] too short data", m_slot->getSlotID()); return; } @@ -177,7 +177,7 @@ void eDVBCICcSession::cc_data_req(const uint8_t *data, unsigned int len) unsigned int dest_len = sizeof(dest); if (dest_len < 2) { - eWarning("[CI RCC] not enough space"); + eWarning("[CI%d RCC] not enough space", m_slot->getSlotID()); return; } @@ -187,7 +187,7 @@ void eDVBCICcSession::cc_data_req(const uint8_t *data, unsigned int len) answ_len = data_req_loop(&dest[2], dest_len - 2, &data[rp], len - rp, dt_nr); if (answ_len <= 0) { - eWarning("[CI RCC] can not get data"); + eWarning("[CI%d RCC] can not get data", m_slot->getSlotID()); return; } @@ -218,7 +218,7 @@ void eDVBCICcSession::cc_sac_data_req(const uint8_t *data, unsigned int len) if (len < 10) return; - eTraceNoNewLineStart("[CI RCC] cc_sac_data_req: "); + eTraceNoNewLineStart("[CI%d RCC] cc_sac_data_req: ", m_slot->getSlotID()); traceHexdump(data, len); memcpy(tmp, data, 8); @@ -227,7 +227,7 @@ void eDVBCICcSession::cc_sac_data_req(const uint8_t *data, unsigned int len) if (!sac_check_auth(data, len)) { - eWarning("[CI RCC] check_auth of message failed"); + eWarning("[CI%d RCC] check_auth of message failed", m_slot->getSlotID()); return; } @@ -245,7 +245,7 @@ void eDVBCICcSession::cc_sac_data_req(const uint8_t *data, unsigned int len) if (len < rp + 1) { - eWarning("[CI RCC] check_auth of message too short"); + eWarning("[CI%d RCC] check_auth of message too short", m_slot->getSlotID()); return; } @@ -256,7 +256,7 @@ void eDVBCICcSession::cc_sac_data_req(const uint8_t *data, unsigned int len) if (dest_len < 10) { - eWarning("[CI RCC] not enough space"); + eWarning("[CI%d RCC] not enough space", m_slot->getSlotID()); return; } @@ -269,7 +269,7 @@ void eDVBCICcSession::cc_sac_data_req(const uint8_t *data, unsigned int len) answ_len = data_req_loop(&dest[pos], dest_len - 10, &data[rp], len - rp, dt_nr); if (answ_len <= 0) { - eWarning("[CI RCC] can not get data"); + eWarning("[CI%d RCC] can not get data", m_slot->getSlotID()); return; } pos += answ_len; @@ -284,11 +284,11 @@ void eDVBCICcSession::cc_sac_sync_req(const uint8_t *data, unsigned int len) unsigned int serial; int pos = 0; - eTraceNoNewLineStart("[CI RCC] cc_sac_sync_req: "); + eTraceNoNewLineStart("[CI%d RCC] cc_sac_sync_req: ", m_slot->getSlotID()); traceHexdump(data, len); serial = UINT32(data, 4); - eTrace("[CI RCC] serial %u\n", serial); + eTrace("[CI%d RCC] serial %u\n", m_slot->getSlotID(), serial); pos += BYTE32(&dest[pos], serial); pos += BYTE32(&dest[pos], 0x01000000); @@ -303,7 +303,7 @@ void eDVBCICcSession::cc_sac_send(const uint8_t *tag, uint8_t *data, unsigned in { if (pos < 8) { - eWarning("[CI RCC] too short data"); + eWarning("[CI%d RCC] too short data", m_slot->getSlotID()); return; } @@ -336,7 +336,7 @@ int eDVBCICcSession::data_get_loop(const uint8_t *data, unsigned int datalen, un if (pos + dt_len > datalen) return 0; - eTraceNoNewLineStart("[CI RCC] set element %d: ", dt_id); + eTraceNoNewLineStart("[CI%d RCC] set element %d: ", m_slot->getSlotID(), dt_id); traceHexdump(&data[pos], dt_len); m_ci_elements.set(dt_id, &data[pos], dt_len); @@ -367,14 +367,14 @@ int eDVBCICcSession::data_req_loop(uint8_t *dest, unsigned int dest_len, const u len = m_ci_elements.get_buf(NULL, dt_id); if ((len + 3) > dest_len) { - eWarning("[CI RCC] req element %d: not enough space", dt_id); + eWarning("[CI%d RCC] req element %d: not enough space", m_slot->getSlotID(), dt_id); return -1; } len = m_ci_elements.get_req(dest, dt_id); if (len > 0) { - eTraceNoNewLineStart("[CI RCC] req element %d: ", dt_id); + eTraceNoNewLineStart("[CI%d RCC] req element %d: ", m_slot->getSlotID(), dt_id); traceHexdump(&dest[3], len - 3); } @@ -423,7 +423,7 @@ int eDVBCICcSession::data_get_handle_new(unsigned int id) break; default: - eWarning("[CI RCC] unhandled id %u", id); + eWarning("[CI%d RCC] unhandled id %u", m_slot->getSlotID(), id); break; } @@ -446,10 +446,10 @@ int eDVBCICcSession::data_req_handle_new(unsigned int id) m_akh_index = 5; if (!m_ci_elements.set(AKH, akh, 32)) - eWarning("[CI RCC] can not set AKH in elements"); + eWarning("[CI%d RCC] can not set AKH in elements", m_slot->getSlotID()); if (!m_ci_elements.set(HOST_ID, host_id, 8)) - eWarning("[CI RCC] can not set host_id in elements"); + eWarning("[CI%d RCC] can not set host_id in elements", m_slot->getSlotID()); } break; } @@ -481,7 +481,7 @@ int eDVBCICcSession::compute_dh_key() int len = DH_size(m_dh); if (len > 256) { - eWarning("[CI RCC] too long shared key"); + eWarning("[CI%d RCC] too long shared key", m_slot->getSlotID()); return -1; } @@ -493,14 +493,14 @@ int eDVBCICcSession::compute_dh_key() BIGNUM *out = BN_new(); if (BN_cmp(BN_value_one(), bn_in) >= 0) - eWarning("[CI RCC] DHPM <= 1!!!"); + eWarning("[CI%d RCC] DHPM <= 1!!!", m_slot->getSlotID()); if (BN_cmp(bn_in, m_dh->p) >= 0) - eWarning("[CI RCC] DHPM >= dh_p!!!"); + eWarning("[CI%d RCC] DHPM >= dh_p!!!", m_slot->getSlotID()); BN_mod_exp(out, bn_in, m_dh->q, m_dh->p, ctx); if (BN_cmp(out, BN_value_one()) != 0) - eWarning("[CI RCC] DHPM ^ dh_q mod dh_p != 1!!!"); + eWarning("[CI%d RCC] DHPM ^ dh_q mod dh_p != 1!!!", m_slot->getSlotID()); BN_free(out); BN_CTX_free(ctx); @@ -509,11 +509,11 @@ int eDVBCICcSession::compute_dh_key() int codes = 0; int ok = DH_check_pub_key(m_dh, bn_in, &codes); if (ok == 0) - eDebug("[CI RCC] check_pub_key failed"); + eDebug("[CI%d RCC] check_pub_key failed", m_slot->getSlotID()); if (codes & DH_CHECK_PUBKEY_TOO_SMALL) - eDebug("[CI RCC] too small public key"); + eDebug("[CI%d RCC] too small public key", m_slot->getSlotID()); if (codes & DH_CHECK_PUBKEY_TOO_LARGE) - eDebug("[CI RCC] too large public key"); + eDebug("[CI%d RCC] too large public key", m_slot->getSlotID()); int gap = 256 - len; memset(m_dhsk, 0, gap); @@ -543,7 +543,7 @@ bool eDVBCICcSession::check_dh_challenge() m_akh_index = 5; - eDebug("[CI RCC] writing..."); + eDebug("[CI%d RCC] writing...", m_slot->getSlotID()); write_authdata(m_slot->getSlotID(), m_ci_elements.get_ptr(HOST_ID), m_dhsk, m_ci_elements.get_ptr(AKH)); return true; @@ -571,7 +571,7 @@ int eDVBCICcSession::generate_dh_key() len = BN_num_bytes(pub_key); if (len > 256) { - eWarning("[CI RCC] too long public key"); + eWarning("[CI%d RCC] too long public key", m_slot->getSlotID()); return -1; } @@ -581,12 +581,12 @@ int eDVBCICcSession::generate_dh_key() BIGNUM *out = BN_new(); if (BN_cmp(BN_value_one(), m_dh->pub_key) >= 0) - eWarning("[CI RCC] DHPH <= 1!!!"); + eWarning("[CI%d RCC] DHPH <= 1!!!", m_slot->getSlotID()); if (BN_cmp(m_dh->pub_key, m_dh->p) >= 0) - eWarning("[CI RCC] DHPH >= dh_p!!!"); + eWarning("[CI%d RCC] DHPH >= dh_p!!!", m_slot->getSlotID()); BN_mod_exp(out, m_dh->pub_key, m_dh->q, m_dh->p, ctx); if (BN_cmp(out, BN_value_one()) != 0) - eWarning("[CI RCC] DHPH ^ dh_q mod dh_p != 1!!!"); + eWarning("[CI%d RCC] DHPH ^ dh_q mod dh_p != 1!!!", m_slot->getSlotID()); BN_free(out); BN_CTX_free(ctx); @@ -639,7 +639,7 @@ int eDVBCICcSession::generate_sign_A() m_rsa_device_key = rsa_privatekey_open("/etc/ciplus/device.pem"); if (!m_rsa_device_key) { - eWarning("[CI RCC] can not read private key"); + eWarning("[CI%d RCC] can not read private key", m_slot->getSlotID()); return -1; } @@ -656,18 +656,18 @@ int eDVBCICcSession::restart_dh_challenge() if (!m_ci_elements.valid(AUTH_NONCE)) return -1; - //eDebug("[CI RCC] rechecking..."); + //eDebug("[CI%d RCC] rechecking...", m_slot->getSlotID()); m_root_ca_store = X509_STORE_new(); if (!m_root_ca_store) { - eWarning("[CI RCC] can not create root_ca"); + eWarning("[CI%d RCC] can not create root_ca", m_slot->getSlotID()); return -1; } if (X509_STORE_load_locations(m_root_ca_store, "/etc/ciplus/root.pem", NULL) != 1) { - eWarning("[CI RCC] can not load root_ca"); + eWarning("[CI%d RCC] can not load root_ca", m_slot->getSlotID()); return -1; } @@ -676,18 +676,18 @@ int eDVBCICcSession::restart_dh_challenge() if (!m_cust_cert || !m_device_cert) { - eWarning("[CI RCC] can not check loader certificates"); + eWarning("[CI%d RCC] can not check loader certificates", m_slot->getSlotID()); return -1; } if (!ci_element_set_certificate(HOST_BRAND_CERT, m_cust_cert)) - eWarning("[CI RCC] can not store brand certificate"); + eWarning("[CI%d RCC] can not store brand certificate", m_slot->getSlotID()); if (!ci_element_set_certificate(HOST_DEV_CERT, m_device_cert)) - eWarning("[CI RCC] can not store device certificate"); + eWarning("[CI%d RCC] can not store device certificate", m_slot->getSlotID()); if (!ci_element_set_hostid_from_certificate(HOST_ID, m_device_cert)) - eWarning("[CI RCC] can not store HOST_ID"); + eWarning("[CI%d RCC] can not store HOST_ID", m_slot->getSlotID()); m_ci_elements.invalidate(CICAM_ID); m_ci_elements.invalidate(DHPM); @@ -706,7 +706,7 @@ int eDVBCICcSession::generate_uri_confirm() uint8_t uck[32]; uint8_t uri_confirm[32]; - //eDebug("[CI RCC] uri_confirm..."); + //eDebug("[CI%d RCC] uri_confirm...", m_slot->getSlotID()); // UCK SHA256_Init(&sha); @@ -738,7 +738,7 @@ void eDVBCICcSession::check_new_key() if (!m_ci_elements.valid(KEY_REGISTER)) return; - //eDebug("[CI RCC] key checking..."); + //eDebug("[CI%d RCC] key checking...", m_slot->getSlotID()); kp = m_ci_elements.get_ptr(KP); m_ci_elements.get_buf(&slot, KEY_REGISTER); @@ -768,25 +768,25 @@ void eDVBCICcSession::check_new_key() * Sets new key or old one if /dev/caX device has changed */ void eDVBCICcSession::set_descrambler_key() { - eDebug("[CI RCC] set_descrambler_key"); + eDebug("[CI%d RCC] set_descrambler_key", m_slot->getSlotID()); bool set_key = (m_current_ca_demux_id != m_slot->getCADemuxID()); if (m_descrambler_fd != -1 && m_current_ca_demux_id != m_slot->getCADemuxID()) { descrambler_deinit(m_descrambler_fd); - m_descrambler_fd = descrambler_init(m_slot->getCADemuxID()); + m_descrambler_fd = descrambler_init(m_slot->getSlotID(), m_slot->getCADemuxID()); m_current_ca_demux_id = m_slot->getCADemuxID(); } if (m_descrambler_fd == -1 && m_slot->getCADemuxID() > -1) { - m_descrambler_fd = descrambler_init(m_slot->getCADemuxID()); + m_descrambler_fd = descrambler_init(m_slot->getSlotID(), m_slot->getCADemuxID()); m_current_ca_demux_id = m_slot->getCADemuxID(); } if (m_descrambler_fd != -1 && (set_key || m_descrambler_new_key)) { - eDebug("[CI RCC] setting key: new ca device: %d, new key: %d", set_key, m_descrambler_new_key); + eDebug("[CI%d RCC] setting key: new ca device: %d, new key: %d", m_slot->getSlotID(), set_key, m_descrambler_new_key); descrambler_set_key(m_descrambler_fd, m_slot->getSlotID(), m_descrambler_odd_even, m_descrambler_key_iv); if (m_descrambler_new_key) { @@ -841,7 +841,7 @@ bool eDVBCICcSession::sac_check_auth(const uint8_t *data, unsigned int len) if (len < 16) { - eWarning("[CI RCC] signature too short"); + eWarning("[CI%d RCC] signature too short", m_slot->getSlotID()); return false; } @@ -852,7 +852,7 @@ bool eDVBCICcSession::sac_check_auth(const uint8_t *data, unsigned int len) if (memcmp(&data[len - 16], calced_signature, 16)) { - eWarning("[CI RCC] signature wrong"); + eWarning("[CI%d RCC] signature wrong", m_slot->getSlotID()); return false; } @@ -895,14 +895,14 @@ X509 *eDVBCICcSession::import_ci_certificates(unsigned int id) if (!m_ci_elements.valid(id)) { - eWarning("[CI RCC] %u not valid", id); + eWarning("[CI%d RCC] %u not valid", m_slot->getSlotID(), id); return NULL; } cert = certificate_import_and_check(m_root_ca_store, m_ci_elements.get_ptr(id), m_ci_elements.get_buf(NULL, id)); if (!cert) { - eWarning("[CI RCC] can not verify certificate %u", id); + eWarning("[CI%d RCC] can not verify certificate %u", m_slot->getSlotID(), id); return NULL; } @@ -919,19 +919,19 @@ int eDVBCICcSession::check_ci_certificates() if ((m_ci_cust_cert = import_ci_certificates(CICAM_BRAND_CERT)) == NULL) { - eWarning("[CI RCC] can not import CICAM brand certificate"); + eWarning("[CI%d RCC] can not import CICAM brand certificate", m_slot->getSlotID()); return -1; } if ((m_ci_device_cert = import_ci_certificates(CICAM_DEV_CERT)) == NULL) { - eWarning("[CI RCC] can not import CICAM device certificate"); + eWarning("[CI%d RCC] can not import CICAM device certificate", m_slot->getSlotID()); return -1; } if (!ci_element_set_hostid_from_certificate(CICAM_ID, m_ci_device_cert)) { - eWarning("[CI RCC] can not store CICAM_ID"); + eWarning("[CI%d RCC] can not store CICAM_ID", m_slot->getSlotID()); return -1; } @@ -946,12 +946,12 @@ bool eDVBCICcSession::ci_element_set_certificate(unsigned int id, X509 *cert) cert_len = i2d_X509(cert, &cert_der); if (cert_len <= 0) { - eWarning("[CI RCC] can not encode certificate"); + eWarning("[CI%d RCC] can not encode certificate", m_slot->getSlotID()); return false; } if (!m_ci_elements.set(id, cert_der, cert_len)) { - eWarning("[CI RCC] can not store certificate id %u", id); + eWarning("[CI%d RCC] can not store certificate id %u", m_slot->getSlotID(), id); return false; } @@ -968,7 +968,7 @@ bool eDVBCICcSession::ci_element_set_hostid_from_certificate(unsigned int id, X5 if ((id != 5) && (id != 6)) { - eWarning("[CI RCC] wrong datatype_id %u for device id", id); + eWarning("[CI%d RCC] wrong datatype_id %u for device id", m_slot->getSlotID(), id); return false; } @@ -977,17 +977,17 @@ bool eDVBCICcSession::ci_element_set_hostid_from_certificate(unsigned int id, X5 if (strlen(hostid) != 16) { - eWarning("[CI RCC] bad device id"); + eWarning("[CI%d RCC] bad device id", m_slot->getSlotID()); return false; } - //eDebug("[CI RCC] DEVICE_ID: %s", hostid); + //eDebug("[CI%d RCC] DEVICE_ID: %s", m_slot->getSlotID(), hostid); str2bin(bin_hostid, hostid, 16); if (!m_ci_elements.set(id, bin_hostid, sizeof(bin_hostid))) { - eWarning("[CI RCC] can not store device id %u", id); + eWarning("[CI%d RCC] can not store device id %u", m_slot->getSlotID(), id); return false; } diff --git a/lib/dvb_ci/dvbci_ccmgr_helper.cpp b/lib/dvb_ci/dvbci_ccmgr_helper.cpp index 6e527f95401..7c78475af77 100644 --- a/lib/dvb_ci/dvbci_ccmgr_helper.cpp +++ b/lib/dvb_ci/dvbci_ccmgr_helper.cpp @@ -139,7 +139,7 @@ bool get_authdata(uint8_t *host_id, uint8_t *dhsk, uint8_t *akh, unsigned int sl fd = open(filename, O_RDONLY); if (fd <= 0) { - eDebug("[CI RCC] can not open %s", filename); + eDebug("[CI%d RCC] can not open %s", slot, filename); return false; } @@ -147,7 +147,7 @@ bool get_authdata(uint8_t *host_id, uint8_t *dhsk, uint8_t *akh, unsigned int sl { if (read(fd, chunk, sizeof(chunk)) != sizeof(chunk)) { - eDebug("[CI RCC] can not read auth_data"); + eDebug("[CI%d RCC] can not read auth_data", slot); close(fd); return false; } @@ -178,7 +178,7 @@ bool write_authdata(unsigned int slot, const uint8_t *host_id, const uint8_t *dh /* check if we got this pair already */ if (!memcmp(&buf[offset + 8 + 256], akh, 32)) { - eDebug("[CI RCC] data already stored"); + eDebug("[CI%d RCC] data already stored", slot); return true; } } @@ -196,25 +196,25 @@ bool write_authdata(unsigned int slot, const uint8_t *host_id, const uint8_t *dh memcpy(buf + 8 + 256, akh, 32); entries++; - eDebug("[CI RCC] %d entries for writing", entries); + eDebug("[CI%d RCC] %d entries for writing", slot, entries); get_authdata_filename(filename, sizeof(filename), slot); fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR); if (fd < 0) { - eWarning("[CI RCC] can not open %s", filename); + eWarning("[CI%d RCC] can not open %s", slot, filename); return false; } if (write(fd, buf, PAIR_SIZE * entries) != PAIR_SIZE * entries) - eWarning("[CI RCC] error in write"); + eWarning("[CI%d RCC] error in write", slot); close(fd); return true; } -bool parameter_init(uint8_t* dh_p, uint8_t* dh_g, uint8_t* dh_q, uint8_t* s_key, uint8_t* key_data, uint8_t* iv) +bool parameter_init(unsigned int slot, uint8_t* dh_p, uint8_t* dh_g, uint8_t* dh_q, uint8_t* s_key, uint8_t* key_data, uint8_t* iv) { int fd; unsigned char buf[592]; @@ -222,13 +222,13 @@ bool parameter_init(uint8_t* dh_p, uint8_t* dh_g, uint8_t* dh_q, uint8_t* s_key, fd = open("/etc/ciplus/param", O_RDONLY); if (fd <= 0) { - eDebug("[CI RCC] can not param file"); + eDebug("[CI%d RCC] can not param file", slot); return false; } if (read(fd, buf, sizeof(buf)) != sizeof(buf)) { - eDebug("[CI RCC] can not read parameters"); + eDebug("[CI%d RCC] can not read parameters", slot); close(fd); return false; } diff --git a/lib/dvb_ci/dvbci_ccmgr_helper.h b/lib/dvb_ci/dvbci_ccmgr_helper.h index b622eb8889c..bf79ed169af 100644 --- a/lib/dvb_ci/dvbci_ccmgr_helper.h +++ b/lib/dvb_ci/dvbci_ccmgr_helper.h @@ -13,7 +13,7 @@ int BYTE32(uint8_t *dest, uint32_t val); int BYTE16(uint8_t *dest, uint16_t val); bool get_authdata(uint8_t *host_id, uint8_t *dhsk, uint8_t *akh, unsigned int slot, unsigned int index); bool write_authdata(unsigned int slot, const uint8_t *host_id, const uint8_t *dhsk, const uint8_t *akh); -bool parameter_init(uint8_t* dh_p, uint8_t* dh_g, uint8_t* dh_q, uint8_t* s_key, uint8_t* key_data, uint8_t* iv); +bool parameter_init(unsigned int slot, uint8_t* dh_p, uint8_t* dh_g, uint8_t* dh_q, uint8_t* s_key, uint8_t* key_data, uint8_t* iv); RSA *rsa_privatekey_open(const char *filename); int verify_cb(int ok, X509_STORE_CTX *ctx); X509 *certificate_load_and_check(X509_STORE *store, const char *filename); diff --git a/lib/dvb_ci/dvbci_datetimemgr.cpp b/lib/dvb_ci/dvbci_datetimemgr.cpp index 9d753a77401..340b4b4f472 100644 --- a/lib/dvb_ci/dvbci_datetimemgr.cpp +++ b/lib/dvb_ci/dvbci_datetimemgr.cpp @@ -12,7 +12,7 @@ eDVBCIDateTimeSession::eDVBCIDateTimeSession(): int eDVBCIDateTimeSession::receivedAPDU(const unsigned char *tag,const void *data, int len) { - eTraceNoNewLine("[CI DT] SESSION(%d)/DATETIME %02x %02x %02x: ", session_nb, tag[0],tag[1], tag[2]); + eTraceNoNewLine("[CI%d DT] SESSION(%d)/DATETIME %02x %02x %02x: ", slot->getSlotID(), session_nb, tag[0],tag[1], tag[2]); for (int i=0; igetSlotID(), tag[2]); break; } } @@ -45,7 +45,7 @@ int eDVBCIDateTimeSession::doAction() sendDateTime(); return 0; case stateFinal: - eWarning("[CI DT] stateFinal and action should not happen"); + eWarning("[CI%d DT] stateFinal and action should not happen", slot->getSlotID()); [[fallthrough]]; default: return 0; diff --git a/lib/dvb_ci/dvbci_hlcmgr.cpp b/lib/dvb_ci/dvbci_hlcmgr.cpp index 2ae9dc46c05..bc2d7173a91 100644 --- a/lib/dvb_ci/dvbci_hlcmgr.cpp +++ b/lib/dvb_ci/dvbci_hlcmgr.cpp @@ -8,7 +8,7 @@ int eDVBCIHostLanguageAndCountrySession::receivedAPDU(const unsigned char *tag,c { int ret = 0; - eTraceNoNewLine("[CI HLC] SESSION(%d)/HLC %02x %02x %02x: ", session_nb, tag[0], tag[1], tag[2]); + eTraceNoNewLine("[CI%d HLC] SESSION(%d)/HLC %02x %02x %02x: ", slot->getSlotID(), session_nb, tag[0], tag[1], tag[2]); for (int i=0; igetSlotID()); state=stateCountryEnquiry; ret = 1; break; case 0x10: // language enquiry - eDebug("[CI HLC] Host language enquiry:"); + eDebug("[CI%d HLC] Host language enquiry:", slot->getSlotID()); state=stateLanguageEnquiry; ret = 1; break; default: - eWarning("[CI HLC] unknown APDU tag 9F 80 %02x", tag[2]); + eWarning("[CI%d HLC] unknown APDU tag 9F 80 %02x", slot->getSlotID(), tag[2]); state = stateFinal; break; } @@ -110,7 +110,7 @@ int eDVBCIHostLanguageAndCountrySession::doAction() break; } default: - eWarning("[CI HLC] unknown state"); + eWarning("[CI%d HLC] unknown state", slot->getSlotID()); break; } diff --git a/lib/dvb_ci/dvbci_host_ctrl.cpp b/lib/dvb_ci/dvbci_host_ctrl.cpp index 26ded0e101c..1062da71b1f 100644 --- a/lib/dvb_ci/dvbci_host_ctrl.cpp +++ b/lib/dvb_ci/dvbci_host_ctrl.cpp @@ -5,7 +5,7 @@ int eDVBCIHostControlSession::receivedAPDU(const unsigned char *tag,const void *data, int len) { - eTraceNoNewLine("[CI HCTRL] SESSION(%d)/HCTRL %02x %02x %02x: ", session_nb, tag[0], tag[1], tag[2]); + eTraceNoNewLine("[CI%d HCTRL] SESSION(%d)/HCTRL %02x %02x %02x: ", slot->getSlotID(), session_nb, tag[0], tag[1], tag[2]); for (int i=0; igetSlotID(), tag[2]); break; } } @@ -27,7 +27,7 @@ int eDVBCIHostControlSession::doAction() switch (state) { default: - eWarning("[CI HCTRL] unknown state"); + eWarning("[CI%d HCTRL] unknown state", slot->getSlotID()); break; } diff --git a/lib/dvb_ci/dvbci_mmi.cpp b/lib/dvb_ci/dvbci_mmi.cpp index 9e595d9cb6d..9e76fb95e6f 100644 --- a/lib/dvb_ci/dvbci_mmi.cpp +++ b/lib/dvb_ci/dvbci_mmi.cpp @@ -33,7 +33,7 @@ eDVBCIMMISession::~eDVBCIMMISession() int eDVBCIMMISession::receivedAPDU(const unsigned char *tag, const void *data, int len) { - eTraceNoNewLineStart("[CI MMI] SESSION(%d)/MMI %02x %02x %02x: ", session_nb, tag[0], tag[1],tag[2]); + eTraceNoNewLineStart("[CI%d MMI] SESSION(%d)/MMI %02x %02x %02x: ", slot->getSlotID(), session_nb, tag[0], tag[1],tag[2]); for (int i=0; igetSlotID()); unsigned char tag[]={0x9f, 0x88, 0x00}; unsigned char data[]={0x00}; @@ -99,7 +99,7 @@ int eDVBCIMMISession::stopMMI() int eDVBCIMMISession::answerText(int answer) { - eDebug("[CI MMI] eDVBCIMMISession::answerText(%d)",answer); + eDebug("[CI%d MMI] eDVBCIMMISession::answerText(%d)", slot->getSlotID(), answer); unsigned char tag[]={0x9f, 0x88, 0x0B}; unsigned char data[]={0x00}; @@ -112,7 +112,7 @@ int eDVBCIMMISession::answerText(int answer) int eDVBCIMMISession::answerEnq(char *answer) { unsigned int len = strlen(answer); - eDebug("[CI MMI] eDVBCIMMISession::answerEnq(%d bytes)", len); + eDebug("[CI%d MMI] eDVBCIMMISession::answerEnq(%d bytes)", slot->getSlotID(), len); unsigned char data[len+1]; data[0] = 0x01; // answer ok @@ -126,7 +126,7 @@ int eDVBCIMMISession::answerEnq(char *answer) int eDVBCIMMISession::cancelEnq() { - eDebug("[CI MMI] eDVBCIMMISession::cancelEnq()"); + eDebug("[CI%d MMI] eDVBCIMMISession::cancelEnq()", slot->getSlotID()); unsigned char tag[]={0x9f, 0x88, 0x08}; unsigned char data[]={0x00}; // canceled diff --git a/lib/dvb_ci/dvbci_operatorprofile.cpp b/lib/dvb_ci/dvbci_operatorprofile.cpp index a505459af66..8b3dc108b97 100644 --- a/lib/dvb_ci/dvbci_operatorprofile.cpp +++ b/lib/dvb_ci/dvbci_operatorprofile.cpp @@ -9,7 +9,7 @@ eDVBCIOperatorProfileSession::eDVBCIOperatorProfileSession() int eDVBCIOperatorProfileSession::receivedAPDU(const unsigned char *tag,const void *data, int len) { - eTraceNoNewLine("[CI OP] SESSION(%d)/OPERATOR %02x %02x %02x: ", session_nb, tag[0],tag[1], tag[2]); + eTraceNoNewLine("[CI%d OP] SESSION(%d)/OPERATOR %02x %02x %02x: ", slot->getSlotID(), session_nb, tag[0],tag[1], tag[2]); for (int i=0; igetSlotID()); state=stateStatus; break; case 0x03: - eDebug("operator_nit"); + eDebug("[CI%d OP] operator_nit", slot->getSlotID()); break; case 0x05: - eDebug("operator_info"); + eDebug("[CI%d OP] operator_info", slot->getSlotID()); break; case 0x07: - eDebug("operator_search_status"); + eDebug("[CI%d OP] operator_search_status", slot->getSlotID()); break; case 0x09: - eDebug("operator_tune"); + eDebug("[CI%d OP] operator_tune", slot->getSlotID()); break; default: - eWarning("[CI OP] unknown APDU tag 9F 9C %02x", tag[2]); + eWarning("[CI%d OP] unknown APDU tag 9F 9C %02x", slot->getSlotID(), tag[2]); break; } } @@ -55,7 +55,7 @@ int eDVBCIOperatorProfileSession::doAction() } case stateFinal: { - eWarning("[CI OP] stateFinal and action should not happen"); + eWarning("[CI%d OP] stateFinal and action should not happen", slot->getSlotID()); break; } default: diff --git a/lib/dvb_ci/dvbci_resmgr.cpp b/lib/dvb_ci/dvbci_resmgr.cpp index 23d39be5d39..17ab0902a86 100644 --- a/lib/dvb_ci/dvbci_resmgr.cpp +++ b/lib/dvb_ci/dvbci_resmgr.cpp @@ -6,7 +6,7 @@ int eDVBCIResourceManagerSession::receivedAPDU(const unsigned char *tag,const void *data, int len) { - eTraceNoNewLineStart("[CI RM] SESSION(%d) %02x %02x %02x: ", session_nb, tag[0], tag[1], tag[2]); + eTraceNoNewLineStart("[CI%d RM] SESSION(%d) %02x %02x %02x: ", slot->getSlotID(), session_nb, tag[0], tag[1], tag[2]); for (int i=0; igetSlotID()); state=stateProfileEnquiry; return 1; break; case 0x11: // Tprofile - eDebugNoNewLineStart("[CI RM] can do: "); + eDebugNoNewLineStart("[CI%d RM] can do: ", slot->getSlotID()); if (!len) eDebugNoNewLine("nothing"); else @@ -36,7 +36,7 @@ int eDVBCIResourceManagerSession::receivedAPDU(const unsigned char *tag,const vo state=stateFinal; break; default: - eWarning("[CI RM] unknown APDU tag 9F 80 %02x", tag[2]); + eWarning("[CI%d RM] unknown APDU tag 9F 80 %02x", slot->getSlotID(), tag[2]); } } @@ -63,7 +63,7 @@ int eDVBCIResourceManagerSession::doAction() } case stateProfileChange: { - eWarning("[CI RM] cannot deal with statProfileChange"); + eWarning("[CI%d RM] cannot deal with statProfileChange", slot->getSlotID()); break; } case stateProfileEnquiry: @@ -116,7 +116,7 @@ int eDVBCIResourceManagerSession::doAction() return 0; } case stateFinal: - eWarning("[CI RM] Should not happen: action on stateFinal"); + eWarning("[CI%d RM] Should not happen: action on stateFinal", slot->getSlotID()); default: break; } diff --git a/lib/dvb_ci/dvbci_session.cpp b/lib/dvb_ci/dvbci_session.cpp index 4c1a5ca7957..c8cc88638f6 100644 --- a/lib/dvb_ci/dvbci_session.cpp +++ b/lib/dvb_ci/dvbci_session.cpp @@ -97,7 +97,7 @@ void eDVBCISession::sendOpenSessionResponse(eDVBCISlot *slot, unsigned char sess { char pkt[6]; pkt[0]=session_status; - eDebug("[CI SESS] sendOpenSessionResponse"); + eDebug("[CI%d SESS] sendOpenSessionResponse", slot->getSlotID()); memcpy(pkt + 1, resource_identifier, 4); sendSPDU(slot, 0x92, pkt, 5, session_nb); } @@ -107,14 +107,12 @@ void eDVBCISession::recvCreateSessionResponse(const unsigned char *data) status = data[0]; state = stateStarted; action = 1; - eDebug("[CI SESS] create Session Response, status %x", status); } void eDVBCISession::recvCloseSessionRequest(const unsigned char *data) { state = stateInDeletion; action = 1; - eDebug("[CI SESS] close Session Request"); } void eDVBCISession::deleteSessions(const eDVBCISlot *slot) @@ -151,104 +149,104 @@ void eDVBCISession::createSession(eDVBCISlot *slot, const unsigned char *resourc { case 0x00010041: session=new eDVBCIResourceManagerSession(slot->getVersion()); - eDebug("[CI SESS] RESOURCE MANAGER 1"); + eDebug("[CI%d SESS] RESOURCE MANAGER 1", slot->getSlotID()); break; case 0x00020041: session=new eDVBCIApplicationManagerSession(slot); - eDebug("[CI SESS] APPLICATION MANAGER 1"); + eDebug("[CI%d SESS] APPLICATION MANAGER 1", slot->getSlotID()); break; case 0x00020042: session=new eDVBCIApplicationManagerSession(slot); - eDebug("[CI SESS] APPLICATION MANAGER 2"); + eDebug("[CI%d SESS] APPLICATION MANAGER 2", slot->getSlotID()); break; case 0x00020043: session=new eDVBCIApplicationManagerSession(slot); - eDebug("[CI SESS] APPLICATION MANAGER 3"); + eDebug("[CI%d SESS] APPLICATION MANAGER 3", slot->getSlotID()); break; case 0x00020045: session=new eDVBCIApplicationManagerSession(slot); - eDebug("[CI SESS] APPLICATION MANAGER 5"); + eDebug("[CI%d SESS] APPLICATION MANAGER 5", slot->getSlotID()); break; case 0x00030041: session = new eDVBCICAManagerSession(slot); - eDebug("[CI SESS] CA MANAGER"); + eDebug("[CI%d SESS] CA MANAGER", slot->getSlotID()); break; case 0x00200041: session = new eDVBCIHostControlSession; - eDebug("[CI SESS] Host Control 1"); + eDebug("[CI%d SESS] Host Control 1", slot->getSlotID()); break; case 0x00200042: session = new eDVBCIHostControlSession; - eDebug("[CI SESS] Host Control 2"); + eDebug("[CI%d SESS] Host Control 2", slot->getSlotID()); break; case 0x00200043: session = new eDVBCIHostControlSession; - eDebug("[CI SESS] Host Control 3"); + eDebug("[CI%d SESS] Host Control 3", slot->getSlotID()); break; case 0x00240041: session=new eDVBCIDateTimeSession; - eDebug("[CI SESS] DATE-TIME"); + eDebug("[CI%d SESS] DATE-TIME", slot->getSlotID()); break; case 0x00400041: session = new eDVBCIMMISession(slot); - eDebug("[CI SESS] MMI - create session"); + eDebug("[CI%d SESS] MMI - create session", slot->getSlotID()); break; case 0x00410041: session = new eDVBCIApplicationMMISession; - eDebug("[CI SESS] Application MMI 1"); + eDebug("[CI%d SESS] Application MMI 1", slot->getSlotID()); break; case 0x00410042: session = new eDVBCIApplicationMMISession; - eDebug("[CI SESS] Application MMI 2"); + eDebug("[CI%d SESS] Application MMI 2", slot->getSlotID()); break; case 0x008C1001: eDVBCIInterfaces::getInstance()->setCIPlusRouting(slot->getSlotID()); session = new eDVBCICcSession(slot, 1); - eDebug("[CI SESS] Content Control 1"); + eDebug("[CI%d SESS] Content Control 1", slot->getSlotID()); break; case 0x008C1002: eDVBCIInterfaces::getInstance()->setCIPlusRouting(slot->getSlotID()); session = new eDVBCICcSession(slot, 2); - eDebug("[CI SESS] Content Control 2"); + eDebug("[CI%d SESS] Content Control 2", slot->getSlotID()); break; case 0x008C1004: eDVBCIInterfaces::getInstance()->setCIPlusRouting(slot->getSlotID()); session = new eDVBCICcSession(slot, 4); - eDebug("[CI SESS] Content Control 4"); + eDebug("[CI%d SESS] Content Control 4", slot->getSlotID()); break; case 0x008D1001: session = new eDVBCIHostLanguageAndCountrySession; - eDebug("[CI SESS] Host Language & Country"); + eDebug("[CI%d SESS] Host Language & Country", slot->getSlotID()); break; case 0x008E1001: session = new eDVBCICAMUpgradeSession; - eDebug("[CI SESS] CAM Upgrade"); + eDebug("[CI%d SESS] CAM Upgrade", slot->getSlotID()); break; case 0x008F1001: session = new eDVBCIOperatorProfileSession; - eDebug("[CI SESS] Operator Profile 1"); + eDebug("[CI%d SESS] Operator Profile 1", slot->getSlotID()); break; case 0x008F1002: session = new eDVBCIOperatorProfileSession; - eDebug("[CI SESS] Operator Profile 2"); + eDebug("[CI%d SESS] Operator Profile 2", slot->getSlotID()); break; case 0x00100041: // session=new eDVBCIAuthSession; - eDebug("[CI SESS] AuthSession"); + eDebug("[CI%d SESS] AuthSession", slot->getSlotID()); [[fallthrough]]; default: - eDebug("[CI SESS] unknown resource type %02x %02x %02x %02x", resource_identifier[0], resource_identifier[1], resource_identifier[2],resource_identifier[3]); + eDebug("[CI%d SESS] unknown resource type %02x %02x %02x %02x", slot->getSlotID(), resource_identifier[0], resource_identifier[1], resource_identifier[2],resource_identifier[3]); session=0; status=0xF0; } if (!session) { - eWarning("[CI SESS] unknown session.. expect crash"); + eWarning("[CI%d SESS] unknown session.. expect crash", slot->getSlotID()); return; } - eDebug("[CI SESS] new session nb %d %p", session_nb, &(*session)); + eDebug("[CI%d SESS] new session nb %d %p", slot->getSlotID(), session_nb, &(*session)); session->session_nb = session_nb; if (session) @@ -293,9 +291,9 @@ void eDVBCISession::receiveData(eDVBCISlot *slot, const unsigned char *ptr, size unsigned char tag = *pkt++; int llen, hlen; - eDebug("[CI SESS] slot: %p",slot); + eDebug("[CI%d SESS] slot: %p", slot->getSlotID(), slot); - eTraceNoNewLineStart("[CI SESS]: "); + eTraceNoNewLineStart("[CI%d SESS]: ", slot->getSlotID()); for(unsigned int i=0;i= SLMS)) { - eWarning("[CI SESS] PROTOCOL: illegal session number %x", session_nb); + eWarning("[CI%d SESS] PROTOCOL: illegal session number %x", slot->getSlotID(), session_nb); return; } session=sessions[session_nb-1]; if (!session) { - eWarning("[CI SESS] PROTOCOL: data on closed session %x", session_nb); + eWarning("[CI%d SESS] PROTOCOL: data on closed session %x", slot->getSlotID(), session_nb); return; } @@ -341,14 +339,15 @@ void eDVBCISession::receiveData(eDVBCISlot *slot, const unsigned char *ptr, size case 0x90: break; case 0x94: + eDebug("[CI%d SESS] recvCreateSessionResponse, status %x", slot->getSlotID(), pkt[0]); session->recvCreateSessionResponse(pkt); break; case 0x95: - eDebug("[CI SESS] recvCloseSessionRequest"); + eDebug("[CI%d SESS] recvCloseSessionRequest", slot->getSlotID()); session->recvCloseSessionRequest(pkt); break; default: - eDebug("[CI SESS] INTERNAL: nyi, tag %02x.", tag); + eDebug("[CI%d SESS] INTERNAL: nyi, tag %02x.", slot->getSlotID(),tag); return; } } @@ -373,7 +372,7 @@ void eDVBCISession::receiveData(eDVBCISlot *slot, const unsigned char *ptr, size { if (((len-alen) > 0) && ((len - alen) < 3)) { - eDebug("[CI SESS] WORKAROUND: applying work around MagicAPDULength"); + eDebug("[CI%d SESS] WORKAROUND: applying work around MagicAPDULength", slot->getSlotID()); alen=len; } } @@ -384,7 +383,7 @@ void eDVBCISession::receiveData(eDVBCISlot *slot, const unsigned char *ptr, size } if (len) - eWarning("[CI SESS] PROTOCOL: warning, TL-Data has invalid length"); + eWarning("[CI%d SESS] PROTOCOL: warning, TL-Data has invalid length", slot->getSlotID()); } eDVBCISession::~eDVBCISession() From d05dcecd649717218cda6daf807b4a9a94c2ed03 Mon Sep 17 00:00:00 2001 From: Betacentauri Date: Fri, 24 Nov 2023 21:25:56 +0100 Subject: [PATCH 356/401] [CI] Set proper routing Change routing only once during initialization of CI module and revert back if CA manager hasn't set up routing in the meantime. --- lib/dvb_ci/dvbci.cpp | 62 ++++++++++++++++++++++++++------------ lib/dvb_ci/dvbci.h | 19 +++++++++--- lib/dvb_ci/dvbci_ccmgr.cpp | 2 ++ 3 files changed, 58 insertions(+), 25 deletions(-) diff --git a/lib/dvb_ci/dvbci.cpp b/lib/dvb_ci/dvbci.cpp index 390e49687df..320ef80fc2e 100644 --- a/lib/dvb_ci/dvbci.cpp +++ b/lib/dvb_ci/dvbci.cpp @@ -115,8 +115,6 @@ eDVBCIInterfaces::eDVBCIInterfaces() eDebug("[CI] Streaming CI finish interface not advertised, assuming \"tuner\" method"); } } - m_ciplus_routing_active = false; - m_ciplus_routing_tunernum = -1; run(); } @@ -626,6 +624,7 @@ void eDVBCIInterfaces::recheckPMTHandlers() ci_it->linked_next->setSource(ci_source.str()); } it->cislot = ci_it; + it->cislot->setCamMgrRoutingActive(true); eTrace("[CI] assigned!"); gotPMT(pmthandler); } @@ -1052,6 +1051,10 @@ int eDVBCIInterfaces::setCIClockRate(int slotid, const std::string &rate) (with correct caid) */ void eDVBCIInterfaces::setCIPlusRouting(int slotid) { + int ciplus_routing_tunernum; + std::string ciplus_routing_input; + std::string ciplus_routing_ci_input; + eDebug("[CI] setCIRouting slotid=%d", slotid); singleLock s(m_pmt_handler_lock); if (m_pmt_handlers.size() == 0) @@ -1059,12 +1062,14 @@ void eDVBCIInterfaces::setCIPlusRouting(int slotid) eDebug("[CI] setCIRouting no pmt handler available! Unplug/plug again the CI module."); return; } - if (m_ciplus_routing_active) + + eDVBCISlot *slot = getSlot(slotid); + if (slot->isCamMgrRoutingActive()) // CamMgr has already set up routing. Don't change that. { - eDebug("[CI] setCIRouting authentification of other module active. Unplug/plug again the CI module after first authentification was successful."); + eDebug("[CI] CamMgrRouting is active -> return"); return; } - eDVBCISlot *slot = getSlot(slotid); + PMTHandlerList::iterator it = m_pmt_handlers.begin(); while (it != m_pmt_handlers.end()) { @@ -1083,6 +1088,8 @@ void eDVBCIInterfaces::setCIPlusRouting(int slotid) if (tunernum < 0) continue; + ciplus_routing_tunernum = slot->getCIPlusRoutingTunerNum(); + // read and store old routing config char file_name[64]; char tmp[8]; @@ -1095,8 +1102,8 @@ void eDVBCIInterfaces::setCIPlusRouting(int slotid) rd = read(fd, tmp, 8); if (rd > 0) { - if (m_ciplus_routing_tunernum != tunernum) - m_ciplus_routing_input = std::string(tmp, rd-1); + if (ciplus_routing_tunernum != tunernum) + ciplus_routing_input = std::string(tmp, rd-1); } else continue; @@ -1112,8 +1119,8 @@ void eDVBCIInterfaces::setCIPlusRouting(int slotid) rd = read(fd, tmp, 8); if (rd > 0) { - if (m_ciplus_routing_tunernum != tunernum) - m_ciplus_routing_ci_input = std::string(tmp, rd-1); + if (ciplus_routing_tunernum != tunernum) + ciplus_routing_ci_input = std::string(tmp, rd-1); } else continue; @@ -1128,30 +1135,35 @@ void eDVBCIInterfaces::setCIPlusRouting(int slotid) setInputSource(tunernum, new_input_source.str()); slot->setSource(eDVBCISlot::getTunerLetter(tunernum)); - m_ciplus_routing_tunernum = tunernum; - m_ciplus_routing_active = true; + slot->setCIPlusRoutingParameter(tunernum, ciplus_routing_input, ciplus_routing_ci_input); + eDebug("[CI] CIRouting active slotid=%d tuner=%d old_input=%s old_ci_input=%s", slotid, tunernum, ciplus_routing_input.c_str(), ciplus_routing_ci_input.c_str()); break; ++it; } - eDebug("[CI] setCIRouting slotid=%d tuner=%d old_input=%s old_ci_input=%s", slotid, m_ciplus_routing_tunernum, m_ciplus_routing_input.c_str(), m_ciplus_routing_ci_input.c_str()); } void eDVBCIInterfaces::revertCIPlusRouting(int slotid) { eDVBCISlot *slot = getSlot(slotid); - eDebug("[CI] revertCIPlusRouting: active=%d slot=%d tuner=%d input=%s ci_input=%s", m_ciplus_routing_active, slotid, m_ciplus_routing_tunernum, m_ciplus_routing_input.c_str(), m_ciplus_routing_ci_input.c_str()); + int ciplus_routing_tunernum = slot->getCIPlusRoutingTunerNum(); + std::string ciplus_routing_input = slot->getCIPlusRoutingInput(); + std::string ciplus_routing_ci_input = slot->getCIPlusRoutingCIInput(); + + eDebug("[CI] revertCIPlusRouting: camMgrActive=%d ciRoutingActive=%d slot=%d tuner=%d input=%s ci_input=%s", slot->isCamMgrRoutingActive(), slot->ciplusRoutingDone(), slotid, ciplus_routing_tunernum, ciplus_routing_input.c_str(), ciplus_routing_ci_input.c_str()); - if(m_ciplus_routing_active) + if (slot->isCamMgrRoutingActive() || // CamMgr has set up routing. Don't revert that. + slot->ciplusRoutingDone()) // need to only run once during CI initialization { - slot->setSource(m_ciplus_routing_ci_input); - setInputSource(m_ciplus_routing_tunernum, m_ciplus_routing_input); + slot->setCIPlusRoutingDone(); + return; } - m_ciplus_routing_active = false; - m_ciplus_routing_tunernum = -1; - m_ciplus_routing_input = ""; - m_ciplus_routing_ci_input = ""; + + slot->setSource(ciplus_routing_ci_input); + setInputSource(ciplus_routing_tunernum, ciplus_routing_input); + + slot->setCIPlusRoutingDone(); } int eDVBCISlot::send(const unsigned char *data, size_t len) @@ -1245,8 +1257,11 @@ eDVBCISlot::eDVBCISlot(eMainloop *context, int nr) { char configStr[255]; slotid = nr; + m_isCamMgrRoutingActive = false; + m_ciPlusRoutingDone = false; m_ca_demux_id = -1; m_context = context; + m_ciplus_routing_tunernum = -1; state = stateDisabled; snprintf(configStr, 255, "config.ci.%d.enabled", slotid); bool enabled = eConfigManager::getConfigBoolValue(configStr, true); @@ -1412,6 +1427,13 @@ int eDVBCISlot::getNumOfServices() return running_services.size(); } +void eDVBCISlot::setCIPlusRoutingParameter(int tunernum, std::string ciplus_routing_input, std::string ciplus_routing_ci_input) +{ + m_ciplus_routing_tunernum = tunernum; + m_ciplus_routing_input = ciplus_routing_input; + m_ciplus_routing_ci_input = ciplus_routing_ci_input; +} + int eDVBCISlot::reset() { eDebug("[CI%d] reset requested", slotid); diff --git a/lib/dvb_ci/dvbci.h b/lib/dvb_ci/dvbci.h index 95c76ab4cac..7d06ed333ca 100644 --- a/lib/dvb_ci/dvbci.h +++ b/lib/dvb_ci/dvbci.h @@ -66,15 +66,28 @@ class eDVBCISlot: public iObject, public sigc::trackable bool user_mapped; void data(int); bool plugged; + bool m_isCamMgrRoutingActive; + bool m_ciPlusRoutingDone; int16_t m_ca_demux_id; eMainloop *m_context; + int m_ciplus_routing_tunernum; + std::string m_ciplus_routing_input; + std::string m_ciplus_routing_ci_input; eDVBCIApplicationManagerSession *getAppManager() { return application_manager; } eDVBCIMMISession *getMMIManager() { return mmi_session; } eDVBCICAManagerSession *getCAManager() { return ca_manager; } eDVBCICcSession *getCCManager() { return cc_manager; } - int getState() { return state; } + int getState() { return state; }; + void setCamMgrRoutingActive(bool active) { m_isCamMgrRoutingActive= active; }; + bool isCamMgrRoutingActive() { return m_isCamMgrRoutingActive; }; + bool ciplusRoutingDone() { return m_ciPlusRoutingDone; }; + void setCIPlusRoutingDone() { m_ciPlusRoutingDone = true; }; + int getCIPlusRoutingTunerNum() { return m_ciplus_routing_tunernum; }; + std::string getCIPlusRoutingInput() { return m_ciplus_routing_input; }; + std::string getCIPlusRoutingCIInput() { return m_ciplus_routing_ci_input; }; + void setCIPlusRoutingParameter(int tunernum, std::string ciplus_routing_input, std::string ciplus_routing_ci_input); int reset(); int startMMI(); int stopMMI(); @@ -163,10 +176,6 @@ class eDVBCIInterfaces: public eMainloop, private eThread eFixedMessagePump m_messagepump_main; // message handling in the e2 mainloop ePtr m_runTimer; // workaround to interrupt thread mainloop as some ci drivers don't implement poll properly static pthread_mutex_t m_pmt_handler_lock; - bool m_ciplus_routing_active; - int m_ciplus_routing_tunernum; - std::string m_ciplus_routing_input; - std::string m_ciplus_routing_ci_input; int sendCAPMT(int slot); diff --git a/lib/dvb_ci/dvbci_ccmgr.cpp b/lib/dvb_ci/dvbci_ccmgr.cpp index bff8ef35cbc..dcd368805ff 100644 --- a/lib/dvb_ci/dvbci_ccmgr.cpp +++ b/lib/dvb_ci/dvbci_ccmgr.cpp @@ -2,6 +2,7 @@ #include +#include #include #include #include @@ -757,6 +758,7 @@ void eDVBCICcSession::check_new_key() m_descrambler_odd_even = slot; m_descrambler_new_key = true; + eDVBCIInterfaces::getInstance()->revertCIPlusRouting(m_slot->getSlotID()); set_descrambler_key(); m_ci_elements.invalidate(KP); From 8aa92804cc512dd5069e0c5f2f3c65c1effc38d6 Mon Sep 17 00:00:00 2001 From: Betacentauri Date: Fri, 24 Nov 2023 21:27:24 +0100 Subject: [PATCH 357/401] [CI] Add Critical Security Update Version protocol from CI+ v1.4.3 spec --- lib/dvb_ci/dvbci_ccmgr.cpp | 9 ++++++++- lib/dvb_ci/dvbci_ccmgr.h | 4 +++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/dvb_ci/dvbci_ccmgr.cpp b/lib/dvb_ci/dvbci_ccmgr.cpp index dcd368805ff..61fc1ed8397 100644 --- a/lib/dvb_ci/dvbci_ccmgr.cpp +++ b/lib/dvb_ci/dvbci_ccmgr.cpp @@ -435,7 +435,7 @@ int eDVBCICcSession::data_req_handle_new(unsigned int id) { switch (id) { - case 22: + case AKH: { uint8_t akh[32], host_id[8]; @@ -454,6 +454,13 @@ int eDVBCICcSession::data_req_handle_new(unsigned int id) } break; } + case CRITICAL_SEC_UPDATE: + { + uint8_t csu[1]; + csu[0] = 0x00; + m_ci_elements.set(CRITICAL_SEC_UPDATE, csu, 1); + break; + } default: break; } diff --git a/lib/dvb_ci/dvbci_ccmgr.h b/lib/dvb_ci/dvbci_ccmgr.h index 102aa7b84f8..83edbd8a66f 100644 --- a/lib/dvb_ci/dvbci_ccmgr.h +++ b/lib/dvb_ci/dvbci_ccmgr.h @@ -50,7 +50,9 @@ class eDVBCICcSession: public eDVBCISession SRM_DATA = 31, SRM_CONFIRM = 32, - MAX_ELEMENTS = 33 + CRITICAL_SEC_UPDATE = 49, + + MAX_ELEMENTS = 50 }; struct ciplus_element From 1f1966e6083c4083fd6484f90a93749f07109eda Mon Sep 17 00:00:00 2001 From: Betacentauri Date: Fri, 24 Nov 2023 21:30:14 +0100 Subject: [PATCH 358/401] [CI] Fix not working second VU FBC tuner by using VU ioctl only for second FBC tuner. Special drivers are needed. --- lib/dvb_ci/descrambler.cpp | 108 ++++++++++++++++++++++++++++--------- lib/dvb_ci/descrambler.h | 4 +- lib/dvb_ci/dvbci.cpp | 42 ++++++++++++++- lib/dvb_ci/dvbci.h | 16 +++++- lib/dvb_ci/dvbci_ccmgr.cpp | 4 +- 5 files changed, 144 insertions(+), 30 deletions(-) diff --git a/lib/dvb_ci/descrambler.cpp b/lib/dvb_ci/descrambler.cpp index 4e704ab8b20..f7fea6ccfc7 100644 --- a/lib/dvb_ci/descrambler.cpp +++ b/lib/dvb_ci/descrambler.cpp @@ -6,6 +6,8 @@ #include #include +#include + #include #ifndef CA_SET_PID @@ -38,36 +40,94 @@ struct ca_descr_data { unsigned char *data; }; +struct vu_ca_descr_data { + int slot_id; + int fix1; // = 0x6f7c + int demux_id; + int tunernum; + int use_count; + int program_number; + int reserved1; + int fix2; // = 0x1 -> add pids + int video_pid; + int audio_pid; + int reserved2; + int fix3; // = 0x12345678 + int reserved3; + int key_register; + int use_aes; // 0x2 for AES + unsigned char key[16]; + unsigned char iv[16]; + int audio_number; + int audio_pids[16]; +}; + #define CA_SET_DESCR_DATA _IOW('o', 137, struct ca_descr_data) -int descrambler_set_key(int desc_fd, int index, int parity, unsigned char *data) +int descrambler_set_key(int& desc_fd, eDVBCISlot *slot, int parity, unsigned char *data) { - struct ca_descr_data d; - - if (desc_fd < 0) - return -1; - - d.index = index; - d.parity = (enum ca_descr_parity)parity; - d.data_type = CA_DATA_KEY; - d.length = 16; - d.data = data; - - if (ioctl(desc_fd, CA_SET_DESCR_DATA, &d) == -1) { - eWarning("[CI%d descrambler] set key failed", index); - return -1; + bool vuIoctlSuccess = false; + + if (slot->getTunerNum() > 7) // might be VU box with 2 FBC tuners -> try to use VU ioctl + { + struct vu_ca_descr_data d; + + d.slot_id = slot->getSlotID(); + d.fix1 = 0x6f7c; + d.demux_id = slot->getCADemuxID(); + d.tunernum = slot->getTunerNum(); + d.use_count = slot->getUseCount(); + d.program_number = slot->getProgramNumber(); + d.fix2 = 0x1; + d.video_pid = slot->getVideoPid(); + d.audio_pid = slot->getAudioPid(); + d.fix3 = 0x12345678; + d.key_register = parity; + d.use_aes = 0x2; // AES + memcpy(d.key, data, 16); + memcpy(d.iv, data + 16, 16); + d.audio_number = slot->getAudioNumber(); + memcpy(d.audio_pids, slot->getAudioPids(), 16*4); + + unsigned int ret = ioctl(slot->getFd(), 0x10, &d); + if (ret == 0) + { + vuIoctlSuccess = true; + descrambler_deinit(desc_fd); // don't set pids for VU ioctl + desc_fd = -1; + } + eDebug("[CI%d] descrambler_set_key vu ret %u", slot->getSlotID(), ret); } - d.index = index; - d.parity = (enum ca_descr_parity)parity; - d.data_type = CA_DATA_IV; - d.length = 16; - d.data = data + 16; - - if (ioctl(desc_fd, CA_SET_DESCR_DATA, &d) == -1) { - eWarning("[CI%d descrambler] set iv failed", index); - return -1; + if (!vuIoctlSuccess) + { + struct ca_descr_data d; + + if (desc_fd < 0) + return -1; + + d.index = slot->getSlotID(); + d.parity = (enum ca_descr_parity)parity; + d.data_type = CA_DATA_KEY; + d.length = 16; + d.data = data; + + if (ioctl(desc_fd, CA_SET_DESCR_DATA, &d) == -1) { + eWarning("[CI%d descrambler] set key failed", slot->getSlotID()); + return -1; + } + + d.index = slot->getSlotID(); + d.parity = (enum ca_descr_parity)parity; + d.data_type = CA_DATA_IV; + d.length = 16; + d.data = data + 16; + + if (ioctl(desc_fd, CA_SET_DESCR_DATA, &d) == -1) { + eWarning("[CI%d descrambler] set iv failed", slot->getSlotID()); + return -1; + } } return 0; diff --git a/lib/dvb_ci/descrambler.h b/lib/dvb_ci/descrambler.h index ea232551576..dfd3213d553 100644 --- a/lib/dvb_ci/descrambler.h +++ b/lib/dvb_ci/descrambler.h @@ -1,9 +1,11 @@ #ifndef __DESCR_H_ #define __DESCR_H_ +#include + int descrambler_init(int slot, uint8_t ca_demux_id); void descrambler_deinit(int desc_fd); -int descrambler_set_key(int desc_fd, int index, int parity, unsigned char *data); +int descrambler_set_key(int& desc_fd, eDVBCISlot *slot, int parity, unsigned char *data); int descrambler_set_pid(int desc_fd, int index, int enable, int pid); #endif diff --git a/lib/dvb_ci/dvbci.cpp b/lib/dvb_ci/dvbci.cpp index 320ef80fc2e..ef2955fb315 100644 --- a/lib/dvb_ci/dvbci.cpp +++ b/lib/dvb_ci/dvbci.cpp @@ -789,7 +789,7 @@ void eDVBCIInterfaces::gotPMT(eDVBServicePMTHandler *pmthandler) eTrace("[CI] check slot %d %d %d", tmp->getSlotID(), tmp->running_services.empty(), canDescrambleMultipleServices(tmp)); if (tmp->running_services.empty() || canDescrambleMultipleServices(tmp)) { - tmp->setCADemuxID(pmthandler); + tmp->setCaParameter(pmthandler); tmp->sendCAPMT(pmthandler); } tmp = tmp->linked_next; @@ -1515,10 +1515,16 @@ int eDVBCISlot::cancelEnq() return 0; } -int eDVBCISlot::setCADemuxID(eDVBServicePMTHandler *pmthandler) +int eDVBCISlot::setCaParameter(eDVBServicePMTHandler *pmthandler) { ePtr demux; + eDVBServicePMTHandler::program program; + eServiceReferenceDVB ref; uint8_t dmx_id; + eUsePtr channel; + ePtr frontend; + + eDebug("[CI%d] setCaParameter", slotid); if (!pmthandler->getDataDemux(demux)) { @@ -1530,6 +1536,38 @@ int eDVBCISlot::setCADemuxID(eDVBServicePMTHandler *pmthandler) else m_ca_demux_id = -1; } + + pmthandler->getServiceReference(ref); + m_program_number = ref.getServiceID().get(); + + pmthandler->getProgramInfo(program); + m_audio_number = program.audioStreams.size(); + + if (m_audio_number > 16) + m_audio_number = 16; + for(int i = 0; i < m_audio_number ; i++) + { + m_audio_pids[i] = program.audioStreams[i].pid; + } + + m_video_pid = program.videoStreams.empty()? 0 : program.videoStreams[0].pid; + m_audio_pid = program.audioStreams.empty()? 0 : program.audioStreams[program.defaultAudioStream].pid; + + m_tunernum = -1; + if (!pmthandler->getChannel(channel)) + { + if (!channel->getFrontend(frontend)) + { + eDVBFrontend *fe = (eDVBFrontend*) &(*frontend); + m_tunernum = fe->getSlotID(); + if (m_tunernum > 7 && !fe->is_FBCTuner()) // use vu ioctl only for second FBC tuner + { + m_tunernum = -1; + } + } + eDebug("[CI%d] tunernum = %d", slotid, m_tunernum); + } + return 0; } diff --git a/lib/dvb_ci/dvbci.h b/lib/dvb_ci/dvbci.h index 7d06ed333ca..cb4bb560ced 100644 --- a/lib/dvb_ci/dvbci.h +++ b/lib/dvb_ci/dvbci.h @@ -69,6 +69,12 @@ class eDVBCISlot: public iObject, public sigc::trackable bool m_isCamMgrRoutingActive; bool m_ciPlusRoutingDone; int16_t m_ca_demux_id; + uint16_t m_program_number; + int m_video_pid; + int m_audio_pid; + int m_audio_number; + int m_audio_pids[16]; + int m_tunernum; eMainloop *m_context; int m_ciplus_routing_tunernum; std::string m_ciplus_routing_input; @@ -96,7 +102,7 @@ class eDVBCISlot: public iObject, public sigc::trackable int cancelEnq(); int getMMIState(); int sendCAPMT(eDVBServicePMTHandler *ptr, const std::vector &caids=std::vector()); - int setCADemuxID(eDVBServicePMTHandler *pmthandler); + int setCaParameter(eDVBServicePMTHandler *pmthandler); void removeService(uint16_t program_number=0xFFFF); int setSource(const std::string &source); int setClockRate(const std::string &rate); @@ -118,10 +124,18 @@ class eDVBCISlot: public iObject, public sigc::trackable void setCAManager( eDVBCICAManagerSession *session ); void setCCManager( eDVBCICcSession *session ); + int getFd() { return fd; }; int getSlotID(); int getNumOfServices(); int getVersion(); int16_t getCADemuxID() { return m_ca_demux_id; }; + int getTunerNum() { return m_tunernum; }; + int getUseCount() { return use_count; }; + int getProgramNumber() { return (int)m_program_number; }; + int getVideoPid() { return m_video_pid; }; + int getAudioPid() { return m_audio_pid; }; + int getAudioNumber() { return m_audio_number; }; + int* getAudioPids() { return m_audio_pids; }; }; struct CIPmtHandler diff --git a/lib/dvb_ci/dvbci_ccmgr.cpp b/lib/dvb_ci/dvbci_ccmgr.cpp index 61fc1ed8397..f6124c71103 100644 --- a/lib/dvb_ci/dvbci_ccmgr.cpp +++ b/lib/dvb_ci/dvbci_ccmgr.cpp @@ -778,7 +778,7 @@ void eDVBCICcSession::check_new_key() void eDVBCICcSession::set_descrambler_key() { eDebug("[CI%d RCC] set_descrambler_key", m_slot->getSlotID()); - bool set_key = (m_current_ca_demux_id != m_slot->getCADemuxID()); + bool set_key = (m_current_ca_demux_id != m_slot->getCADemuxID()) || (m_slot->getTunerNum() > 7); if (m_descrambler_fd != -1 && m_current_ca_demux_id != m_slot->getCADemuxID()) { @@ -796,7 +796,7 @@ void eDVBCICcSession::set_descrambler_key() if (m_descrambler_fd != -1 && (set_key || m_descrambler_new_key)) { eDebug("[CI%d RCC] setting key: new ca device: %d, new key: %d", m_slot->getSlotID(), set_key, m_descrambler_new_key); - descrambler_set_key(m_descrambler_fd, m_slot->getSlotID(), m_descrambler_odd_even, m_descrambler_key_iv); + descrambler_set_key(m_descrambler_fd, m_slot, m_descrambler_odd_even, m_descrambler_key_iv); if (m_descrambler_new_key) { m_descrambler_new_key = false; From c5560ba6783f32ae750a07c83ab9181bd6bf9caf Mon Sep 17 00:00:00 2001 From: Betacentauri Date: Fri, 24 Nov 2023 21:31:48 +0100 Subject: [PATCH 359/401] [CI] Set descrambler key according to spec after sync message has arrived --- lib/dvb_ci/dvbci_ccmgr.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/dvb_ci/dvbci_ccmgr.cpp b/lib/dvb_ci/dvbci_ccmgr.cpp index f6124c71103..7b9f4229a48 100644 --- a/lib/dvb_ci/dvbci_ccmgr.cpp +++ b/lib/dvb_ci/dvbci_ccmgr.cpp @@ -297,6 +297,8 @@ void eDVBCICcSession::cc_sac_sync_req(const uint8_t *data, unsigned int len) /* status OK */ dest[pos++] = 0; + set_descrambler_key(); + cc_sac_send(sync_cnf_tag, dest, pos); } @@ -766,7 +768,6 @@ void eDVBCICcSession::check_new_key() m_descrambler_new_key = true; eDVBCIInterfaces::getInstance()->revertCIPlusRouting(m_slot->getSlotID()); - set_descrambler_key(); m_ci_elements.invalidate(KP); m_ci_elements.invalidate(KEY_REGISTER); From d1950d21615d92fd977d6292f02407fdc17b727a Mon Sep 17 00:00:00 2001 From: openvix-build Date: Fri, 15 Dec 2023 22:04:10 +0000 Subject: [PATCH 360/401] openvix: developer 6.4.011.002 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index e861d29c07a..ddf46934668 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1219,3 +1219,4 @@ openvix: developer 6.4.010.017 openvix: developer 6.4.010.018 openvix: developer 6.4.010.019 openvix: developer 6.4.011.001 +openvix: developer 6.4.011.002 From a4b683c8a98eb3deb9fd6ca2c1a20fd11c400cfc Mon Sep 17 00:00:00 2001 From: Huevos Date: Sat, 16 Dec 2023 15:05:30 +0100 Subject: [PATCH 361/401] [ServiceList] fix line 370 for now / next --- lib/python/Components/ServiceList.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index d26976e2587..c67a9724216 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -367,7 +367,7 @@ def getCurrentIndex(self): def setItemsPerPage(self): numberOfRows = config.usage.serviceitems_per_page.value two_lines_val = int(config.usage.servicelist_twolines.value) - if two_lines_val == 1: + if two_lines_val: numberOfRows = int(numberOfRows / ((self.ItemHeightTwoLineSkin / self.ItemHeightSkin)) if self.ItemHeightSkin and self.ItemHeightTwoLineSkin else 2) itemHeight = self.ItemHeightSkin if not two_lines_val else self.ItemHeightTwoLineSkin if numberOfRows > 0: @@ -482,8 +482,8 @@ def setMode(self, mode): self.mode = mode self.setItemsPerPage() two_lines_val = int(config.usage.servicelist_twolines.value) - self.l.setItemHeight(self.ItemHeight if two_lines_val == 0 else self.ItemHeightTwoLine) - self.l.setVisualMode(eListboxServiceContent.visModeComplex if two_lines_val == 0 else eListboxServiceContent.visSkinDefined) + self.l.setItemHeight(self.ItemHeight if not two_lines_val else self.ItemHeightTwoLine) + self.l.setVisualMode(eListboxServiceContent.visModeComplex if not two_lines_val else eListboxServiceContent.visSkinDefined) if two_lines_val: timeText = _("%d min") @@ -518,7 +518,7 @@ def setMode(self, mode): self.l.setServiceTypeIconMode(int(config.usage.servicetype_icon_mode.value)) self.l.setCryptoIconMode(int(config.usage.crypto_icon_mode.value)) self.l.setRecordIndicatorMode(int(config.usage.record_indicator_mode.value)) - self.l.setColumnWidth(-1 if two_lines_val > 0 else int(config.usage.servicelist_column.value)) + self.l.setColumnWidth(-1 if two_lines_val else int(config.usage.servicelist_column.value)) self.l.setProgressBarMode(config.usage.show_event_progress_in_servicelist.value) self.l.setChannelNumbersVisible(config.usage.show_channel_numbers_in_servicelist.value) self.l.setAlternativeNumberingMode(config.usage.alternative_number_mode.value) From 753c3ff87280a1c3fe421b51009a3656e080000d Mon Sep 17 00:00:00 2001 From: Orlandoxx <95180049+Orlandoxx@users.noreply.github.com> Date: Sat, 16 Dec 2023 21:19:06 +0200 Subject: [PATCH 362/401] Updated fi.po Corrected typo. --- po/fi.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/po/fi.po b/po/fi.po index 3d8ca078d51..3e1e891538b 100644 --- a/po/fi.po +++ b/po/fi.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: enigma2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-27 23:35+0000\n" -"PO-Revision-Date: 2023-12-15 13:41+0200\n" +"PO-Revision-Date: 2023-12-16 21:15+0200\n" "Last-Translator: Orlandox\n" "Language-Team: timoj/Kojo/Samzam/Orlandox\n" "Language: fi\n" @@ -8170,7 +8170,7 @@ msgid "Minimum age %d years" msgstr "Minimi-ikä %d vuotta" msgid "Minimum send interval" -msgstr "Minimi lähestysjakso" +msgstr "Minimi lähetysväli" msgid "Minority Sports" msgstr "Vähemmistöurheilu" @@ -13543,7 +13543,7 @@ msgstr "" "Suomenkielinen käännös: timoj, Kojo, Samzam, Orlandox\n" "\n" "Ylläpito : Orlandox\n" -"15.12.2023\n" +"16.12.2023\n" "http://www.huoltovalikko.com" msgid "TS file is too large for ISO9660 level 1!" From 9abf6bb2ecda17cd1d08ef81aeda9861e6b075c3 Mon Sep 17 00:00:00 2001 From: openvix-build Date: Sun, 17 Dec 2023 13:14:07 +0000 Subject: [PATCH 363/401] openvix: developer 6.4.011.003 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index ddf46934668..dc8d29a2b60 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1220,3 +1220,4 @@ openvix: developer 6.4.010.018 openvix: developer 6.4.010.019 openvix: developer 6.4.011.001 openvix: developer 6.4.011.002 +openvix: developer 6.4.011.003 From cb5824dfdc09874de2d1bf3c6e68d50411c39cc5 Mon Sep 17 00:00:00 2001 From: Orlandoxx <95180049+Orlandoxx@users.noreply.github.com> Date: Sun, 17 Dec 2023 18:11:24 +0200 Subject: [PATCH 364/401] Updated fi.po Corrected another typo. --- po/fi.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/po/fi.po b/po/fi.po index 3e1e891538b..ee6eabab7a8 100644 --- a/po/fi.po +++ b/po/fi.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: enigma2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-27 23:35+0000\n" -"PO-Revision-Date: 2023-12-16 21:15+0200\n" +"PO-Revision-Date: 2023-12-17 18:04+0200\n" "Last-Translator: Orlandox\n" "Language-Team: timoj/Kojo/Samzam/Orlandox\n" "Language: fi\n" @@ -7088,7 +7088,7 @@ msgid "Image Slot:\t%s" msgstr "Image-paikka:\t%s" msgid "Image View On" -msgstr "Jakonäkymä" +msgstr "Kuvanäkymä päälle" msgid "Image manager" msgstr "Imagen hallinnointi" @@ -13543,7 +13543,7 @@ msgstr "" "Suomenkielinen käännös: timoj, Kojo, Samzam, Orlandox\n" "\n" "Ylläpito : Orlandox\n" -"16.12.2023\n" +"17.12.2023\n" "http://www.huoltovalikko.com" msgid "TS file is too large for ISO9660 level 1!" From 11133a4e40274750d8df720dc6d181a8a0177636 Mon Sep 17 00:00:00 2001 From: Orlandoxx <95180049+Orlandoxx@users.noreply.github.com> Date: Mon, 18 Dec 2023 07:03:58 +0200 Subject: [PATCH 365/401] Updated Finnish (fi.po) translation. Shortened some lines. --- po/fi.po | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/po/fi.po b/po/fi.po index ee6eabab7a8..bf9fcf37e74 100644 --- a/po/fi.po +++ b/po/fi.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: enigma2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-12-27 23:35+0000\n" -"PO-Revision-Date: 2023-12-17 18:04+0200\n" +"PO-Revision-Date: 2023-12-18 06:59+0200\n" "Last-Translator: Orlandox\n" "Language-Team: timoj/Kojo/Samzam/Orlandox\n" "Language: fi\n" @@ -3639,13 +3639,13 @@ msgid "Configure how recording filenames are constructed." msgstr "Määritä tallenteiden tiedostonimien rakenne." msgid "Configure if and how crypto icons will be shown in the channel selection list (left alignment only available in single line mode)." -msgstr "Määrittää näytetäänkö/miten näytetään salauksen kuvakkeet kanavalistassa (tasaus vasemmalle käytettävissä vain yksirivisessä tilassa)." +msgstr "Määrittää näytetäänkö/miten näytetään salauksen kuvakkeet kanavalistassa (tasaus vasemmalle käytössä vain yksirivisessä tilassa)." msgid "Configure if and how service type icons will be shown (left alignment only available in single line mode)." -msgstr "Määritä näytetäänkö/miten näytetään kanavatyypin kuvakkeet (tasaus vasemmalle käytettävissä vain yksirivisessä tilassa)." +msgstr "Määritä näytetäänkö/miten näytetään kanavatyypin kuvakkeet (tasaus vasemmalle käytössä vain yksirivisessä tilassa)." -msgid "Configure if and how the record indicator will be shown in the channel selection list." -msgstr "Määrittää kuinka tallennuksen indikaattori näytetään kanavalistassa." +msgid "Configure if and how the record indicator will be shown in the channel selection list (left alignment only available in single line mode)." +msgstr "Määrittää kuinka tallennuksen indikaattori näytetään kanavalistassa (tasaus vasemmalle käytössä vain yksirivisessä tilassa)." msgid "Configure if and how wide the service name column will be shown in the channel selection list." msgstr "Määrittää kuinka leveänä kanavanimet näytetään kanavalistassa." @@ -7701,7 +7701,7 @@ msgid "Left" msgstr "Vasen" msgid "Left from servicename (only available in single line mode)" -msgstr "Kanavanimestä vasemmalle (käytettävissä vain yksirivisessä tilassa)" +msgstr "Kanavanimestä vasemmalle (käytössä vain yksirivisessä tilassa)" msgid "Left long" msgstr "Pitkä vasemmalle" @@ -9463,7 +9463,7 @@ msgid "Percentage left" msgstr "Prosentit vasemmalla" msgid "Percentage right (only available in single line mode)" -msgstr "Prosentit oikealla (käytettävissä vain yksirivisessä tilassa)" +msgstr "Prosentit oikealla (käytössä vain yksirivisessä tilassa)" msgid "Perform a complete image backup before updating." msgstr "Suorita täydellinen image-varmuuskopiointi ennen päivitystä." @@ -10223,7 +10223,7 @@ msgid "Progress bar left" msgstr "Etenemispalkki vasemmalla" msgid "Progress bar right (only available in single line mode)" -msgstr "Etenemispalkki oikealla (käytettävissä vain yksirivisessä tilassa)" +msgstr "Etenemispalkki oikealla (käytössä vain yksirivisessä tilassa)" msgid "Prominent" msgstr "Kuuluisa" @@ -12105,7 +12105,7 @@ msgid "Set the time the timer must stop." msgstr "Kellonaika, jolloin ajastuksen pitää pysähtyä." msgid "Set the type of the progress indication in the channel selection screen (right alignment only available in single line mode)." -msgstr "Määritä ohjelman pituuden osoittamisen tyyppi kanavien valintalistassa (tasaus oikealle käytettävissä vain yksirivisessä tilassa)." +msgstr "Määritä ohjelman pituuden osoittamisen tyyppi kanavien valintalistassa (tasaus oikealle käytössä vain yksirivisessä tilassa)." msgid "Set to the desired primetime." msgstr "Asetettu parhaaseen katseluaikaan." @@ -13261,16 +13261,16 @@ msgid "Stored position" msgstr "Sijainnin muistipaikka" msgid "Stream" -msgstr "Stream" +msgstr "Streami" msgid "Stream request" -msgstr "Streamin pyynti" +msgstr "Streamin pyyntö" msgid "Stream-tv" -msgstr "Stream" +msgstr "Streami-tv" msgid "Streaming" -msgstr "Stream" +msgstr "Streamaa" msgid "Streaming Clients" msgstr "Etäasiakkaat" @@ -13543,7 +13543,7 @@ msgstr "" "Suomenkielinen käännös: timoj, Kojo, Samzam, Orlandox\n" "\n" "Ylläpito : Orlandox\n" -"17.12.2023\n" +"18.12.2023\n" "http://www.huoltovalikko.com" msgid "TS file is too large for ISO9660 level 1!" From 59662a911f9fe1a3e81b97de58bb1e0148d16882 Mon Sep 17 00:00:00 2001 From: Huevos Date: Mon, 18 Dec 2023 10:58:12 +0100 Subject: [PATCH 366/401] [UsageConfig] update serviceList notifiers --- lib/python/Components/UsageConfig.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/python/Components/UsageConfig.py b/lib/python/Components/UsageConfig.py index d627912b76a..a8b09e284bb 100644 --- a/lib/python/Components/UsageConfig.py +++ b/lib/python/Components/UsageConfig.py @@ -54,26 +54,26 @@ def alternativeNumberModeChange(configElement): config.usage.alternative_number_mode.addNotifier(alternativeNumberModeChange) config.usage.servicelist_twolines = ConfigSelection(default="0", choices=[("0", _("None")), ("1", _("two lines")), ("2", _("two lines+next event"))]) - config.usage.servicelist_twolines.addNotifier(refreshServiceList) + config.usage.servicelist_twolines.addNotifier(refreshServiceList, initial_call=False, immediate_feedback=False) config.usage.hide_number_markers = ConfigYesNo(default=True) - config.usage.hide_number_markers.addNotifier(refreshServiceList) + config.usage.hide_number_markers.addNotifier(refreshServiceList, initial_call=False, immediate_feedback=False) config.usage.servicetype_icon_mode = ConfigSelection(default="0", choices=[("0", _("None")), ("1", _("Left from servicename (only available in single line mode)")), ("2", _("Right from servicename"))]) - config.usage.servicetype_icon_mode.addNotifier(refreshServiceList) + config.usage.servicetype_icon_mode.addNotifier(refreshServiceList, initial_call=False, immediate_feedback=False) config.usage.crypto_icon_mode = ConfigSelection(default="0", choices=[("0", _("None")), ("1", _("Left from servicename (only available in single line mode)")), ("2", _("Right from servicename"))]) - config.usage.crypto_icon_mode.addNotifier(refreshServiceList) + config.usage.crypto_icon_mode.addNotifier(refreshServiceList, initial_call=False, immediate_feedback=False) config.usage.record_indicator_mode = ConfigSelection(default="3", choices=[("0", _("None")), ("1", _("Left from servicename (only available in single line mode)")), ("2", _("Right from servicename")), ("3", _("Red colored"))]) - config.usage.record_indicator_mode.addNotifier(refreshServiceList) + config.usage.record_indicator_mode.addNotifier(refreshServiceList, initial_call=False, immediate_feedback=False) choicelist = [("-1", _("Disable"))] for i in range(0, 1300, 25): choicelist.append((str(i), ngettext("%d pixel wide", "%d pixels wide", i) % i)) config.usage.servicelist_column = ConfigSelection(default="-1", choices=choicelist) - config.usage.servicelist_column.addNotifier(refreshServiceList) + config.usage.servicelist_column.addNotifier(refreshServiceList, initial_call=False, immediate_feedback=False) config.usage.service_icon_enable = ConfigYesNo(default=False) - config.usage.service_icon_enable.addNotifier(refreshServiceList) + config.usage.service_icon_enable.addNotifier(refreshServiceList, initial_call=False, immediate_feedback=False) config.usage.servicelist_cursor_behavior = ConfigSelection(default="keep", choices=[ ("standard", _("Standard")), ("keep", _("Keep service")), @@ -327,8 +327,8 @@ def showsecondinfobarChanged(configElement): ("alpha", _("Alpha")), ("number", _("Number"))]) - config.usage.show_event_progress_in_servicelist.addNotifier(refreshServiceList) - config.usage.show_channel_numbers_in_servicelist.addNotifier(refreshServiceList) + config.usage.show_event_progress_in_servicelist.addNotifier(refreshServiceList, initial_call=False, immediate_feedback=False) + config.usage.show_channel_numbers_in_servicelist.addNotifier(refreshServiceList, initial_call=False, immediate_feedback=False) if SystemInfo["WakeOnLAN"]: def wakeOnLANChanged(configElement): From 38f13b319487915b246343bf0acffa5d2089fcc3 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Mon, 18 Dec 2023 19:19:01 +0200 Subject: [PATCH 367/401] [Fixed] service list allignment and colors --- lib/service/listboxservice.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 22266df131e..490bfc72fc9 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -1147,7 +1147,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const EventProgressbarColor = m_color[eventForegroundSelected]; } else - painter.setForegroundColor(gRGB(0xe7b53f)); + painter.setForegroundColor(gRGB(0x787878)); if (serviceFallback && !selected && m_color_set[eventForegroundFallback]) // fallback receiver { @@ -1184,7 +1184,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const //------------------------------------------------- Event name ------------------------------------------------------------------------------ if (m_has_next_event) { - ePtr para = new eTextPara(eRect(0, 0, m_itemsize.width() - xoffs - m_items_distances - 15, m_itemheight/2)); + ePtr para = new eTextPara(eRect(0, 0, m_itemsize.width() - service_name_end - m_items_distances - progressBarRect.width() - 15, m_itemheight/2)); para->setFont(m_element_font[celServiceInfo]); para->renderString(text.c_str()); eRect bbox = para->getBoundBox(); @@ -1212,7 +1212,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const EventProgressbarColor = m_color[eventNextForegroundSelected]; } else - painter.setForegroundColor(gRGB(0xe7b53f)); + painter.setForegroundColor(gRGB(0x787878)); if (serviceFallback && !selected && m_color_set[eventNextForegroundFallback]) // fallback receiver { @@ -1225,7 +1225,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const EventProgressbarColor = m_color[eventNextForegroundSelectedFallback]; } } - ePtr paraNext = new eTextPara(eRect(0, 0, xlpos - service_name_end - m_items_distances, m_itemheight/2)); + ePtr paraNext = new eTextPara(eRect(0, 0, xlpos - xoffs - m_items_distances, m_itemheight/2)); paraNext->setFont(m_element_font[celServiceNextInfo]); paraNext->renderString((m_next_title + next_event_name).c_str()); eRect bboxNext = paraNext->getBoundBox(); @@ -1523,7 +1523,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const EventProgressbarColor = m_color[eventForegroundSelected]; } else - painter.setForegroundColor(gRGB(0xe7b53f)); + painter.setForegroundColor(gRGB(0x787878)); if (serviceFallback && !selected && m_color_set[eventForegroundFallback]) // fallback receiver { From 5c50acb61529eae535ea94a2f2facdf6136e9a6c Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Mon, 18 Dec 2023 19:23:37 +0200 Subject: [PATCH 368/401] [Fixed] wrong set colors --- lib/service/listboxservice.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 490bfc72fc9..b80160e51ab 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -1147,7 +1147,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const EventProgressbarColor = m_color[eventForegroundSelected]; } else - painter.setForegroundColor(gRGB(0x787878)); + painter.setForegroundColor(gRGB(0xe7b53f)); if (serviceFallback && !selected && m_color_set[eventForegroundFallback]) // fallback receiver { @@ -1523,7 +1523,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const EventProgressbarColor = m_color[eventForegroundSelected]; } else - painter.setForegroundColor(gRGB(0x787878)); + painter.setForegroundColor(gRGB(0xe7b53f)); if (serviceFallback && !selected && m_color_set[eventForegroundFallback]) // fallback receiver { From 05f064bd13794e18b903be4405df6f2c73aeb409 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Tue, 19 Dec 2023 10:15:40 +0200 Subject: [PATCH 369/401] [Added] Separate color and font for remaining time in two line mode --- lib/python/Components/ServiceList.py | 31 +++++++++++---- lib/service/listboxservice.cpp | 57 +++++++++++++++++----------- lib/service/listboxservice.h | 5 +++ 3 files changed, 64 insertions(+), 29 deletions(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index c67a9724216..f80748582c4 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -82,6 +82,8 @@ def __init__(self, serviceList): self.ServiceInfoFontSize = 18 self.ServiceNextInfoFontName = "Regular" self.ServiceNextInfoFontSize = 15 + self.ServiceRemainingInfoFontName = "Regular" + self.ServiceRemainingInfoFontSize = 18 self.progressBarWidth = 52 self.progressPercentWidth = 0 self.fieldMargins = 10 @@ -119,6 +121,9 @@ def foregroundColorEvent(value): def foregroundColorNextEvent(value): self.l.setColor(eListboxServiceContent.eventNextForeground, parseColor(value)) + + def foregroundColorEventRemaining(value): + self.l.setColor(eListboxServiceContent.eventRemainingForeground, parseColor(value)) def colorServiceDescription(value): self.l.setColor(eListboxServiceContent.eventForeground, parseColor(value)) @@ -128,6 +133,9 @@ def foregroundColorEventSelected(value): def foregroundColorEventNextSelected(value): self.l.setColor(eListboxServiceContent.eventNextForegroundSelected, parseColor(value)) + + def foregroundColorEventRemainingSelected(value): + self.l.setColor(eListboxServiceContent.eventRemainingForegroundSelected, parseColor(value)) def colorServiceDescriptionSelected(value): self.l.setColor(eListboxServiceContent.eventForegroundSelected, parseColor(value)) @@ -170,6 +178,12 @@ def colorServiceNextDescriptionFallback(value): def colorServiceNextDescriptionSelectedFallback(value): self.l.setColor(eListboxServiceContent.eventNextForegroundSelectedFallback, parseColor(value)) + + def colorServiceRemainingDescriptionFallback(value): + self.l.setColor(eListboxServiceContent.eventRemainingForegroundFallback, parseColor(value)) + + def colorServiceRemainingDescriptionSelectedFallback(value): + self.l.setColor(eListboxServiceContent.eventRemainingForegroundSelectedFallback, parseColor(value)) def picServiceEventProgressbar(value): pic = LoadPixmap(resolveFilename(SCOPE_CURRENT_SKIN, value)) @@ -187,6 +201,11 @@ def serviceInfoFont(value): font = parseFont(value, ((5, 6), (1, 1))) self.ServiceNextInfoFontName = font.family self.ServiceNextInfoFontSize = font.pointSize + + def serviceRemainingInfoFont(value): + font = parseFont(value, ((1, 1), (1, 1))) + self.ServiceRemainingInfoFontName = font.family + self.ServiceRemainingInfoFontSize = font.pointSize def serviceNumberFont(value): font = parseFont(value, ((1, 1), (1, 1))) @@ -394,10 +413,14 @@ def setFontsize(self): self.ServiceNameFont = gFont(self.ServiceNameFontName, self.ServiceNameFontSize + config.usage.servicename_fontsize.value) self.ServiceInfoFont = gFont(self.ServiceInfoFontName, self.ServiceInfoFontSize + config.usage.serviceinfo_fontsize.value) self.ServiceNextInfoFont = gFont(self.ServiceNextInfoFontName, self.ServiceNextInfoFontSize + config.usage.serviceinfo_fontsize.value) + self.ServiceRemainingInfoFont = gFont(self.ServiceRemainingInfoFontName, self.ServiceRemainingInfoFontSize + config.usage.serviceinfo_fontsize.value) self.l.setElementFont(self.l.celServiceName, self.ServiceNameFont) self.l.setElementFont(self.l.celServiceNumber, self.ServiceNumberFont) self.l.setElementFont(self.l.celServiceInfo, self.ServiceInfoFont) self.l.setElementFont(self.l.celServiceNextInfo, self.ServiceNextInfoFont) + self.l.setElementFont(self.l.celServiceInfoRemainingTime, self.ServiceRemainingInfoFont) + if "perc" in config.usage.show_event_progress_in_servicelist.value: + self.l.setElementFont(self.l.celServiceEventProgressbar, self.ServiceInfoFont) def postWidgetCreate(self, instance): instance.setWrapAround(True) @@ -506,13 +529,7 @@ def setMode(self, mode): self.l.setElementPosition(self.l.celServiceEventProgressbar, eRect(0, 0, progressWidth, self.ItemHeight)) - self.l.setElementFont(self.l.celServiceName, self.ServiceNameFont) - self.l.setElementFont(self.l.celServiceNumber, self.ServiceNumberFont) - self.l.setElementFont(self.l.celServiceInfo, self.ServiceInfoFont) - self.l.setElementFont(self.l.celServiceNextInfo, self.ServiceNextInfoFont) - - if "perc" in config.usage.show_event_progress_in_servicelist.value: - self.l.setElementFont(self.l.celServiceEventProgressbar, self.ServiceInfoFont) + self.setFontsize() self.l.setHideNumberMarker(config.usage.hide_number_markers.value) self.l.setServiceTypeIconMode(int(config.usage.servicetype_icon_mode.value)) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index b80160e51ab..94b5995511c 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -1139,12 +1139,10 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (!selected && m_color_set[eventForeground]) { painter.setForegroundColor(m_color[eventForeground]); - EventProgressbarColor = m_color[eventForeground]; } else if (selected && m_color_set[eventForegroundSelected]) { painter.setForegroundColor(m_color[eventForegroundSelected]); - EventProgressbarColor = m_color[eventForegroundSelected]; } else painter.setForegroundColor(gRGB(0xe7b53f)); @@ -1152,29 +1150,13 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (serviceFallback && !selected && m_color_set[eventForegroundFallback]) // fallback receiver { painter.setForegroundColor(m_color[eventForegroundFallback]); - EventProgressbarColor = m_color[eventForegroundFallback]; } else if (serviceFallback && selected && m_color_set[eventForegroundSelectedFallback]) { painter.setForegroundColor(m_color[eventForegroundSelectedFallback]); - EventProgressbarColor = m_color[eventForegroundSelectedFallback]; } } - eRect bboxtLeft = eRect(); - if (!m_has_next_event) { - //------------------------------------------------ Event remaining ------------------------------------------------------------------------ - std::string timeLeft_str = ""; - char buffer[15]; - snprintf(buffer, sizeof(buffer), ("%s" + m_text_time).c_str(), timeLeft == 0 ? "" : "+", timeLeft/60); - timeLeft_str = buffer; - ePtr paraLeft = new eTextPara(eRect(0, 0, m_itemsize.width(), m_itemheight/2)); - paraLeft->setFont(m_element_font[celServiceInfo]); - paraLeft->renderString(timeLeft_str.c_str()); - bboxtLeft = paraLeft->getBoundBox(); - painter.renderPara(paraLeft, ePoint(m_itemsize.width() - bboxtLeft.width() - 15, offset.y() - 2 + m_itemheight/2 + ((m_itemheight/2 - bboxtLeft.height())/2))); - } - std::string percent = ""; if (startsWith(m_progress_mode, "perc")) { char buffer[15]; @@ -1204,12 +1186,10 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (!selected && m_color_set[eventNextForeground]) { painter.setForegroundColor(m_color[eventNextForeground]); - EventProgressbarColor = m_color[eventNextForeground]; } else if (selected && m_color_set[eventNextForegroundSelected]) { painter.setForegroundColor(m_color[eventNextForegroundSelected]); - EventProgressbarColor = m_color[eventNextForegroundSelected]; } else painter.setForegroundColor(gRGB(0x787878)); @@ -1217,12 +1197,10 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (serviceFallback && !selected && m_color_set[eventNextForegroundFallback]) // fallback receiver { painter.setForegroundColor(m_color[eventNextForegroundFallback]); - EventProgressbarColor = m_color[eventNextForegroundFallback]; } else if (serviceFallback && selected && m_color_set[eventNextForegroundSelectedFallback]) { painter.setForegroundColor(m_color[eventNextForegroundSelectedFallback]); - EventProgressbarColor = m_color[eventNextForegroundSelectedFallback]; } } ePtr paraNext = new eTextPara(eRect(0, 0, xlpos - xoffs - m_items_distances, m_itemheight/2)); @@ -1232,11 +1210,46 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const painter.renderPara(paraNext, ePoint(xoffs, offset.y() - 2 + m_itemheight/2 + ((m_itemheight/2 - bboxNext.height())/2))); } } else { + //------------------------------------------------ Event remaining ------------------------------------------------------------------------ + std::string timeLeft_str = ""; + char buffer[15]; + snprintf(buffer, sizeof(buffer), ("%s" + m_text_time).c_str(), timeLeft == 0 ? "" : "+", timeLeft/60); + timeLeft_str = buffer; + ePtr paraLeft = new eTextPara(eRect(0, 0, m_itemsize.width(), m_itemheight/2)); + paraLeft->setFont(m_element_font[celServiceInfoRemainingTime]); + paraLeft->renderString(timeLeft_str.c_str()); + eRect bboxtLeft = paraLeft->getBoundBox(); + ePtr para = new eTextPara(eRect(0, 0, m_itemsize.width() - xoffs - bboxtLeft.width() - 25 - m_items_distances, m_itemheight/2)); para->setFont(m_element_font[celServiceInfo]); para->renderString(((!percent.empty() ? (percent + m_separator) : "") + text).c_str()); eRect bbox = para->getBoundBox(); painter.renderPara(para, ePoint(xoffs, offset.y() - 2 + m_itemheight/2 + ((m_itemheight/2 - bbox.height())/2))); + + if (serviceAvail) + { + if (!selected && m_color_set[eventRemainingForeground]) + { + painter.setForegroundColor(m_color[eventRemainingForeground]); + } + else if (selected && m_color_set[eventRemainingForegroundSelected]) + { + painter.setForegroundColor(m_color[eventRemainingForegroundSelected]); + } + else + painter.setForegroundColor(gRGB(0x787878)); + + if (serviceFallback && !selected && m_color_set[eventRemainingForegroundFallback]) // fallback receiver + { + painter.setForegroundColor(m_color[eventRemainingForegroundFallback]); + } + else if (serviceFallback && selected && m_color_set[eventRemainingForegroundSelectedFallback]) + { + painter.setForegroundColor(m_color[eventRemainingForegroundSelectedFallback]); + } + } + + painter.renderPara(paraLeft, ePoint(m_itemsize.width() - bboxtLeft.width() - 15, offset.y() - 2 + m_itemheight/2 + ((m_itemheight/2 - bboxtLeft.height())/2))); } } } diff --git a/lib/service/listboxservice.h b/lib/service/listboxservice.h index bfb277c2b57..349a198a2e1 100644 --- a/lib/service/listboxservice.h +++ b/lib/service/listboxservice.h @@ -63,6 +63,7 @@ class eListboxServiceContent: public virtual iListboxContent celServiceInfo, // "now" event celServiceNextInfo, // "next" event celServiceTypePixmap, + celServiceInfoRemainingTime, celElements }; @@ -146,6 +147,10 @@ class eListboxServiceContent: public virtual iListboxContent serviceEventProgressbarBorderColor, serviceEventProgressbarBorderColorSelected, serviceRecorded, + eventRemainingForeground, + eventRemainingForegroundSelected, + eventRemainingForegroundFallback, + eventRemainingForegroundSelectedFallback, colorElements }; From 248e0b5be4a34252eda7e575da478dac5da88cc4 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Tue, 19 Dec 2023 08:39:01 +0000 Subject: [PATCH 370/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Components/ServiceList.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index f80748582c4..37b83b3bbae 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -121,7 +121,7 @@ def foregroundColorEvent(value): def foregroundColorNextEvent(value): self.l.setColor(eListboxServiceContent.eventNextForeground, parseColor(value)) - + def foregroundColorEventRemaining(value): self.l.setColor(eListboxServiceContent.eventRemainingForeground, parseColor(value)) @@ -133,7 +133,7 @@ def foregroundColorEventSelected(value): def foregroundColorEventNextSelected(value): self.l.setColor(eListboxServiceContent.eventNextForegroundSelected, parseColor(value)) - + def foregroundColorEventRemainingSelected(value): self.l.setColor(eListboxServiceContent.eventRemainingForegroundSelected, parseColor(value)) @@ -178,7 +178,7 @@ def colorServiceNextDescriptionFallback(value): def colorServiceNextDescriptionSelectedFallback(value): self.l.setColor(eListboxServiceContent.eventNextForegroundSelectedFallback, parseColor(value)) - + def colorServiceRemainingDescriptionFallback(value): self.l.setColor(eListboxServiceContent.eventRemainingForegroundFallback, parseColor(value)) @@ -201,7 +201,7 @@ def serviceInfoFont(value): font = parseFont(value, ((5, 6), (1, 1))) self.ServiceNextInfoFontName = font.family self.ServiceNextInfoFontSize = font.pointSize - + def serviceRemainingInfoFont(value): font = parseFont(value, ((1, 1), (1, 1))) self.ServiceRemainingInfoFontName = font.family From b983510adcac08b1fc7fa156596a90af40dbbf5c Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Tue, 19 Dec 2023 11:48:56 +0200 Subject: [PATCH 371/401] [Fixed] Wrong font usage for service number --- lib/python/Components/ServiceList.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index 37b83b3bbae..e00132486fa 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -409,7 +409,7 @@ def getSelectionPosition(self): return self.listWidth + self.instance.position().x(), sely def setFontsize(self): - self.ServiceNumberFont = gFont(self.ServiceNameFontName, self.ServiceNameFontSize + config.usage.servicenum_fontsize.value) + self.ServiceNumberFont = gFont(self.ServiceNumberFontName, self.ServiceNumberFontSize + config.usage.servicenum_fontsize.value) self.ServiceNameFont = gFont(self.ServiceNameFontName, self.ServiceNameFontSize + config.usage.servicename_fontsize.value) self.ServiceInfoFont = gFont(self.ServiceInfoFontName, self.ServiceInfoFontSize + config.usage.serviceinfo_fontsize.value) self.ServiceNextInfoFont = gFont(self.ServiceNextInfoFontName, self.ServiceNextInfoFontSize + config.usage.serviceinfo_fontsize.value) From 733b54c91418b2d29eb73cbed8a1c4fdf6c6aa03 Mon Sep 17 00:00:00 2001 From: openvix-build Date: Tue, 19 Dec 2023 14:05:38 +0000 Subject: [PATCH 372/401] openvix: developer 6.4.011.004 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index dc8d29a2b60..bb4a89278d7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1221,3 +1221,4 @@ openvix: developer 6.4.010.019 openvix: developer 6.4.011.001 openvix: developer 6.4.011.002 openvix: developer 6.4.011.003 +openvix: developer 6.4.011.004 From 6774c874a65368c39eb5646b8ce40d255b3c129b Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 20 Dec 2023 13:11:24 +0100 Subject: [PATCH 373/401] [Recordings] update config list after path status has been checked --- lib/python/Screens/Recordings.py | 1 + lib/python/Screens/Timeshift.py | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/python/Screens/Recordings.py b/lib/python/Screens/Recordings.py index 1878c0fbe54..2d50d16b46c 100644 --- a/lib/python/Screens/Recordings.py +++ b/lib/python/Screens/Recordings.py @@ -20,6 +20,7 @@ def __init__(self, session): self.greenText = self["key_green"].text if self.getCurrentItem() in (config.usage.default_path, config.usage.timer_path, config.usage.instantrec_path): self.pathStatus(self.getCurrentValue()) + self.changedEntry() def buildChoices(self, item, configEntry, path): configList = config.movielist.videodirs.value[:] diff --git a/lib/python/Screens/Timeshift.py b/lib/python/Screens/Timeshift.py index f7478e50484..304f17c9031 100644 --- a/lib/python/Screens/Timeshift.py +++ b/lib/python/Screens/Timeshift.py @@ -17,6 +17,7 @@ def __init__(self, session): self.greenText = self["key_green"].text if self.getCurrentItem() is config.usage.timeshift_path: self.pathStatus(self.getCurrentValue()) + self.changedEntry() def buildChoices(self, item, configEntry, path): configList = config.usage.allowed_timeshift_paths.value[:] From ac2a795473545e00337d3b705915b235eea2ef37 Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 20 Dec 2023 13:12:30 +0100 Subject: [PATCH 374/401] [Harddisk] add protection against a drive being unexpectedly removed --- lib/python/Components/Harddisk.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/python/Components/Harddisk.py b/lib/python/Components/Harddisk.py index 76764cacb7f..30c2c8a8218 100644 --- a/lib/python/Components/Harddisk.py +++ b/lib/python/Components/Harddisk.py @@ -716,7 +716,11 @@ def enumerateNetworkMounts(self): mountEntry = ospath.join("/media", entry) if not ospath.isdir(mountEntry): continue - mounts = listdir(mountEntry) + try: # protect against drive being removed unexpectedly + mounts = listdir(mountEntry) + except IOError as err: + print("[Harddisk] drive not accessible", err) + continue if len(mounts) > 0: for mount in mounts: mountDir = ospath.join(mountEntry, mount, "") From 746a82a46cb9459e9f6abeb956eff3e3864940c8 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Thu, 21 Dec 2023 12:25:00 +0200 Subject: [PATCH 375/401] [Fixed] [listboxservice] Logical mistake in next event rendering --- lib/service/listboxservice.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index 94b5995511c..a68f51f07a7 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -1076,11 +1076,14 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const if (!event_name.empty()) { + int pb_xpos = xoffs; //--------------------------------------------------- Event Progressbar ----------------------------------------------------------------- if (progressBarRect.width() > 0) { int pb_yoffs_corr = m_itemheight/2; if (m_has_next_event) pb_yoffs_corr = 5; - int pb_xpos = m_has_next_event ? (m_itemsize.width() - 15 - progressBarRect.width()) : xoffs; + if (m_has_next_event) { + pb_xpos = m_itemsize.width() - 15 - progressBarRect.width(); + } int pb_ypos = offset.y() + pb_yoffs_corr + (m_itemheight/2 - m_progressbar_height - 2 * m_progressbar_border_width) / 2; int pb_width = progressBarRect.width() - 2 * m_progressbar_border_width; gRGB ProgressbarBorderColor = 0xdfdfdf; @@ -1166,7 +1169,7 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const //------------------------------------------------- Event name ------------------------------------------------------------------------------ if (m_has_next_event) { - ePtr para = new eTextPara(eRect(0, 0, m_itemsize.width() - service_name_end - m_items_distances - progressBarRect.width() - 15, m_itemheight/2)); + ePtr para = new eTextPara(eRect(0, 0, pb_xpos - service_name_end - m_items_distances - 15, m_itemheight/2)); para->setFont(m_element_font[celServiceInfo]); para->renderString(text.c_str()); eRect bbox = para->getBoundBox(); From 9a962066b4daf941f7ac9b69d97e4fe9ae145975 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sat, 23 Dec 2023 16:34:10 +0100 Subject: [PATCH 376/401] [TimerEdit] use RecordingSettings module for editing recording setup --- lib/python/Screens/TimerEdit.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/python/Screens/TimerEdit.py b/lib/python/Screens/TimerEdit.py index 7a6856a5952..846ab4caf7f 100644 --- a/lib/python/Screens/TimerEdit.py +++ b/lib/python/Screens/TimerEdit.py @@ -15,8 +15,8 @@ from Screens.ParentalControlSetup import ProtectedScreen from Screens.InputBox import PinInput # noqa: F401 from ServiceReference import ServiceReference +from Screens.Recordings import RecordingSettings from Screens.TimerEntry import TimerEntry, TimerLog -from Screens.Setup import Setup from Tools.BoundFunction import boundFunction from Tools.FuzzyDate import FuzzyTime from time import time @@ -92,9 +92,8 @@ def onCreate(self): def createSetup(self): def onSetupClose(test=None): self.refill() - pass - self.session.openWithCallback(onSetupClose, Setup, 'recording') + self.session.openWithCallback(onSetupClose, RecordingSettings) def isProtected(self): return config.ParentalControl.setuppinactive.value and (not config.ParentalControl.config_sections.main_menu.value or hasattr(self.session, 'infobar') and self.session.infobar is None) and config.ParentalControl.config_sections.timer_menu.value and config.ParentalControl.servicepin[0].value From 3a57cb46b23025cdc88c6d78c820e5fe547e052e Mon Sep 17 00:00:00 2001 From: Tony Whalley Date: Tue, 26 Dec 2023 12:35:29 +0100 Subject: [PATCH 377/401] [C++ 17] change invocation check] --- configure.ac | 3 +- m4/ax_cxx_compile_stdcxx.m4 | 75 +++++++++++++++++++++++++++++----- m4/ax_cxx_compile_stdcxx_17.m4 | 35 ---------------- 3 files changed, 66 insertions(+), 47 deletions(-) delete mode 100644 m4/ax_cxx_compile_stdcxx_17.m4 diff --git a/configure.ac b/configure.ac index d9fbfb8d3bd..0df4240158a 100644 --- a/configure.ac +++ b/configure.ac @@ -554,8 +554,7 @@ AC_CHECK_FUNCS([klogctl]) ENIGMA2_CFLAGS="-fno-rtti -fno-exceptions -rdynamic -funwind-tables" AC_SUBST(ENIGMA2_CFLAGS) -AX_CXX_COMPILE_STDCXX_17([ext],[mandatory]) - +AX_CXX_COMPILE_STDCXX([17], [ext], [mandatory]) AX_CHECK_COMPILE_FLAG([-Wattribute-alias], [CXXFLAGS="$CXXFLAGS -Wattribute-alias"]) AX_CHECK_COMPILE_FLAG([-Wattribute-alias=1], [CXXFLAGS="$CXXFLAGS -Wattribute-alias=1"]) diff --git a/m4/ax_cxx_compile_stdcxx.m4 b/m4/ax_cxx_compile_stdcxx.m4 index 5a525e8d3d3..8edf5152ec7 100644 --- a/m4/ax_cxx_compile_stdcxx.m4 +++ b/m4/ax_cxx_compile_stdcxx.m4 @@ -10,8 +10,8 @@ # # Check for baseline language coverage in the compiler for the specified # version of the C++ standard. If necessary, add switches to CXX and -# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) -# or '14' (for the C++14 standard). +# CXXCPP to enable support. VERSION may be '11', '14', '17', or '20' for +# the respective C++ standard version. # # The second argument, if specified, indicates whether you insist on an # extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. @@ -36,13 +36,14 @@ # Copyright (c) 2016, 2018 Krzesimir Nowak # Copyright (c) 2019 Enji Cooper # Copyright (c) 2020 Jason Merrill +# Copyright (c) 2021 Jörn Heusipp # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 12 +#serial 18 dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro dnl (serial version number 13). @@ -51,6 +52,7 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], [$1], [14], [ax_cxx_compile_alternatives="14 1y"], [$1], [17], [ax_cxx_compile_alternatives="17 1z"], + [$1], [20], [ax_cxx_compile_alternatives="20"], [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl m4_if([$2], [], [], [$2], [ext], [], @@ -102,9 +104,18 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl dnl HP's aCC needs +std=c++11 according to: dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf dnl Cray's crayCC needs "-h std=c++11" + dnl MSVC needs -std:c++NN for C++17 and later (default is C++14) for alternative in ${ax_cxx_compile_alternatives}; do - for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do - cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}" MSVC; do + if test x"$switch" = xMSVC; then + dnl AS_TR_SH maps both `:` and `=` to `_` so -std:c++17 would collide + dnl with -std=c++17. We suffix the cache variable name with _MSVC to + dnl avoid this. + switch=-std:c++${alternative} + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_${switch}_MSVC]) + else + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + fi AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, $cachevar, [ac_save_CXX="$CXX" @@ -151,7 +162,6 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 ) - dnl Test body for checking C++14 support m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], @@ -159,12 +169,24 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 ) +dnl Test body for checking C++17 support + m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 ) +dnl Test body for checking C++20 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_20], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_20 +) + + dnl Tests for new features in C++11 m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ @@ -176,7 +198,11 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ #error "This is not a C++ compiler" -#elif __cplusplus < 201103L +// MSVC always sets __cplusplus to 199711L in older versions; newer versions +// only set it correctly if /Zc:__cplusplus is specified as well as a +// /std:c++NN switch: +// https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ +#elif __cplusplus < 201103L && !defined _MSC_VER #error "This is not a C++11 compiler" @@ -467,7 +493,7 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ #error "This is not a C++ compiler" -#elif __cplusplus < 201402L +#elif __cplusplus < 201402L && !defined _MSC_VER #error "This is not a C++14 compiler" @@ -591,7 +617,7 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ #error "This is not a C++ compiler" -#elif __cplusplus < 201703L +#elif __cplusplus < 201703L && !defined _MSC_VER #error "This is not a C++17 compiler" @@ -957,7 +983,36 @@ namespace cxx17 } // namespace cxx17 -#endif // __cplusplus < 201703L +#endif // __cplusplus < 201703L && !defined _MSC_VER ]]) + +dnl Tests for new features in C++20 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_20], [[ + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 202002L && !defined _MSC_VER + +#error "This is not a C++20 compiler" + +#else + +#include + +namespace cxx20 +{ + +// As C++20 supports feature test macros in the standard, there is no +// immediate need to actually test for feature availability on the +// Autoconf side. + +} // namespace cxx20 + +#endif // __cplusplus < 202002L && !defined _MSC_VER + +]]) diff --git a/m4/ax_cxx_compile_stdcxx_17.m4 b/m4/ax_cxx_compile_stdcxx_17.m4 deleted file mode 100644 index a6834171739..00000000000 --- a/m4/ax_cxx_compile_stdcxx_17.m4 +++ /dev/null @@ -1,35 +0,0 @@ -# ============================================================================= -# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_17.html -# ============================================================================= -# -# SYNOPSIS -# -# AX_CXX_COMPILE_STDCXX_17([ext|noext], [mandatory|optional]) -# -# DESCRIPTION -# -# Check for baseline language coverage in the compiler for the C++17 -# standard; if necessary, add switches to CXX and CXXCPP to enable -# support. -# -# This macro is a convenience alias for calling the AX_CXX_COMPILE_STDCXX -# macro with the version set to C++17. The two optional arguments are -# forwarded literally as the second and third argument respectively. -# Please see the documentation for the AX_CXX_COMPILE_STDCXX macro for -# more information. If you want to use this macro, you also need to -# download the ax_cxx_compile_stdcxx.m4 file. -# -# LICENSE -# -# Copyright (c) 2015 Moritz Klammler -# Copyright (c) 2016 Krzesimir Nowak -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 2 - -AX_REQUIRE_DEFINED([AX_CXX_COMPILE_STDCXX]) -AC_DEFUN([AX_CXX_COMPILE_STDCXX_17], [AX_CXX_COMPILE_STDCXX([17], [$1], [$2])]) From abc9fa0663c3a8cfb97e09cf60d31952dd90bd4f Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Wed, 27 Dec 2023 09:46:17 +0200 Subject: [PATCH 378/401] [Fixed] [listboxservice] zero column lenght not work --- lib/service/listboxservice.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/service/listboxservice.cpp b/lib/service/listboxservice.cpp index a68f51f07a7..2b975c9eea8 100644 --- a/lib/service/listboxservice.cpp +++ b/lib/service/listboxservice.cpp @@ -1296,15 +1296,17 @@ void eListboxServiceContent::paint(gPainter &painter, eWindowStyle &style, const bool hasPicons = PyCallable_Check(m_GetPiconNameFunc); bool isAlternativeNumberingMode = m_alternative_numbering; std::string eventProgressConfig = m_progress_mode; - int serviceNameWidth = m_column_width > 0 && !isDirectory && !isMarker ? m_column_width : m_itemsize.width(); + int serviceNameWidth = m_column_width > -1 && !isDirectory && !isMarker ? m_column_width : m_itemsize.width(); bool shouldCorrect = serviceNameWidth >= m_column_width - pixmap_system_size.width()*3; - if (m_servicetype_icon_mode == 2 && m_column_width > 0 && shouldCorrect) serviceNameWidth -= pixmap_system_size.width() + m_items_distances; - if (m_crypto_icon_mode == 2 && m_column_width > 0 && shouldCorrect) serviceNameWidth -= pixmap_crypto_size.width() + m_items_distances; - if (isRecorded && m_record_indicator_mode == 2 && m_column_width > 0 && shouldCorrect) serviceNameWidth -= pixmap_rec_size.width() + m_items_distances; - if ((m_servicetype_icon_mode == 2 || m_crypto_icon_mode == 2 || (isRecorded && m_record_indicator_mode == 2)) && m_column_width > 0) + if (m_servicetype_icon_mode == 2 && m_column_width > -1 && shouldCorrect) serviceNameWidth -= pixmap_system_size.width() + m_items_distances; + if (m_crypto_icon_mode == 2 && m_column_width > -1 && shouldCorrect) serviceNameWidth -= pixmap_crypto_size.width() + m_items_distances; + if (isRecorded && m_record_indicator_mode == 2 && m_column_width > -1 && shouldCorrect) serviceNameWidth -= pixmap_rec_size.width() + m_items_distances; + if ((m_servicetype_icon_mode == 2 || m_crypto_icon_mode == 2 || (isRecorded && m_record_indicator_mode == 2)) && m_column_width > -1) serviceNameWidth -= m_items_distances; + if (serviceNameWidth < 0) serviceNameWidth = 0; + ePtr paraServiceName = new eTextPara(eRect(0, 0, serviceNameWidth, m_itemheight)); paraServiceName->setFont(m_element_font[celServiceName]); paraServiceName->renderString(text.c_str()); From b24646d85ed8c5760a6c66dcf9766e40c59213a5 Mon Sep 17 00:00:00 2001 From: Dimitar Tsenev Date: Wed, 27 Dec 2023 15:33:10 +0200 Subject: [PATCH 379/401] [Fixed] Possible exception in stream relay handling code --- lib/dvb/db.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/dvb/db.cpp b/lib/dvb/db.cpp index dbce0fc5db9..fa9a705acbd 100644 --- a/lib/dvb/db.cpp +++ b/lib/dvb/db.cpp @@ -222,14 +222,19 @@ bool eDVBService::isCrypted() int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReference &ignore, bool simulate) { + bool isStreamRelayService = false; eServiceReferenceDVB sRelayOrigSref; ePtr refCur; eNavigation::getInstance()->getCurrentService(refCur); - ePtr tmp_info; - refCur->info(tmp_info); - std::string ref_s = tmp_info->getInfoString(iServiceInformation::sServiceref); - eServiceReferenceDVB currentlyPlaying = eServiceReferenceDVB(ref_s); - bool res = currentlyPlaying.getSROriginal(sRelayOrigSref); + if (refCur) { + ePtr tmp_info; + refCur->info(tmp_info); + std::string ref_s = tmp_info->getInfoString(iServiceInformation::sServiceref); + eServiceReferenceDVB currentlyPlaying = eServiceReferenceDVB(ref_s); + isStreamRelayService = currentlyPlaying.getSROriginal(sRelayOrigSref); + } else { + return 1; + } ePtr res_mgr; bool remote_fallback_enabled = eConfigManager::getConfigBoolValue("config.usage.remote_fallback_enabled", false); @@ -244,7 +249,7 @@ int eDVBService::isPlayable(const eServiceReference &ref, const eServiceReferenc ((const eServiceReferenceDVB&)ref).getChannelID(chid); ((const eServiceReferenceDVB&)ignore).getChannelID(chid_ignore); - if (res) { + if (isStreamRelayService) { sRelayOrigSref.getChannelID(chid_ignore_sr); } else { chid_ignore_sr = eDVBChannelID(); From 441835155daa4abae5ae6dd9c07e8bc40a00cda9 Mon Sep 17 00:00:00 2001 From: openvix-build Date: Thu, 28 Dec 2023 14:17:37 +0000 Subject: [PATCH 380/401] openvix: developer 6.4.011.005 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index bb4a89278d7..20c025c8b6c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1222,3 +1222,4 @@ openvix: developer 6.4.011.001 openvix: developer 6.4.011.002 openvix: developer 6.4.011.003 openvix: developer 6.4.011.004 +openvix: developer 6.4.011.005 From 45ebdb72ae4988811642878e8b4b6d3cf1dc762b Mon Sep 17 00:00:00 2001 From: openvix-build Date: Fri, 29 Dec 2023 15:42:44 +0000 Subject: [PATCH 381/401] openvix: developer 6.4.011.006 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 20c025c8b6c..3bac93f4547 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1223,3 +1223,4 @@ openvix: developer 6.4.011.002 openvix: developer 6.4.011.003 openvix: developer 6.4.011.004 openvix: developer 6.4.011.005 +openvix: developer 6.4.011.006 From 3ad33319afddf7af0ee64eedd814c5f6dcc25219 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sat, 30 Dec 2023 01:55:03 +0100 Subject: [PATCH 382/401] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1a2c7dd4de1..669570b590b 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ 1 - Install packages on your buildserver - sudo apt-get install -y autoconf automake bison bzip2 chrpath coreutils cpio curl cvs debianutils default-jre default-jre-headless diffstat flex g++ gawk gcc gcc-12 gcc-multilib g++-multilib gettext git git-core gzip help2man info iputils-ping java-common libc6-dev libegl1-mesa libglib2.0-dev libncurses5-dev libperl4-corelibs-perl libproc-processtable-perl libsdl1.2-dev libserf-dev libtool libxml2-utils make ncurses-bin patch perl pkg-config psmisc python3 python3-git python3-jinja2 python3-pexpect python3-pip python-setuptools qemu quilt socat sshpass subversion tar texi2html texinfo unzip wget xsltproc xterm xz-utils zip zlib1g-dev zstd fakeroot lz4 + sudo apt-get install -y autoconf automake bison bzip2 chrpath coreutils cpio curl cvs debianutils default-jre default-jre-headless diffstat flex g++ gawk gcc gcc-12 gcc-multilib g++-multilib gettext git git-core gzip help2man info iputils-ping java-common libc6-dev libegl1-mesa libglib2.0-dev libncurses5-dev libperl4-corelibs-perl libproc-processtable-perl libsdl1.2-dev libserf-dev libtool libxml2-utils make ncurses-bin patch perl pkg-config psmisc python3 python3-git python3-jinja2 python3-pexpect python3-pip python-setuptools qemu quilt socat sshpass subversion tar texi2html texinfo unzip wget xsltproc xterm xz-utils zip zlib1g-dev zstd fakeroot lz4 liblz4-tool ---------- 2 - Set python3 as preferred provider for python From 40d683806c947d58d51a9beb7dcf544be0967d8d Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 27 Dec 2023 11:01:32 +0100 Subject: [PATCH 383/401] [BoxInfo] remove temporary code, fixed at source --- lib/python/Components/SystemInfo.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/python/Components/SystemInfo.py b/lib/python/Components/SystemInfo.py index 7306d93ef04..3d76bcb6a6d 100644 --- a/lib/python/Components/SystemInfo.py +++ b/lib/python/Components/SystemInfo.py @@ -25,9 +25,6 @@ def __init__(self, root=""): item, value = [x.strip() for x in line.split("=", 1)] if item: self.immutableList.append(item) - # Temporary fix: some items that look like floats are not floats and should be handled as strings, e.g. python "3.10" should not be processed as "3.1". - if not (value.startswith("\"") or value.startswith("'")) and item in ("python", "imageversion", "imgversion"): - value = '"' + value + '"' # wrap it so it is treated as a string self.boxInfo[item] = self.processValue(value) # print("[SystemInfo] Enigma information file data loaded into BoxInfo.") else: From 56ed7db3e8b47f27a1b04a311714f4f0fb414590 Mon Sep 17 00:00:00 2001 From: Huevos Date: Wed, 27 Dec 2023 11:04:29 +0100 Subject: [PATCH 384/401] [BoxInfo] remove pointless code --- lib/python/Components/SystemInfo.py | 48 ++++++++--------------------- 1 file changed, 12 insertions(+), 36 deletions(-) diff --git a/lib/python/Components/SystemInfo.py b/lib/python/Components/SystemInfo.py index 3d76bcb6a6d..c1514b9fb05 100644 --- a/lib/python/Components/SystemInfo.py +++ b/lib/python/Components/SystemInfo.py @@ -31,41 +31,19 @@ def __init__(self, root=""): print("[BoxInfo] ERROR: %s is not available! The system is unlikely to boot or operate correctly." % file) def processValue(self, value): - if value is None: - pass - elif (value.startswith("\"") or value.startswith("'")) and value.endswith(value[0]): - value = value[1:-1] - elif value.startswith("(") and value.endswith(")"): - data = [] - for item in [x.strip() for x in value[1:-1].split(",")]: - data.append(self.processValue(item)) - value = tuple(data) - elif value.startswith("[") and value.endswith("]"): - data = [] - for item in [x.strip() for x in value[1:-1].split(",")]: - data.append(self.processValue(item)) - value = list(data) - elif value.upper() == "NONE": - value = None + if (value.startswith("\"") or value.startswith("'")) and value.endswith(value[0]): + return value[1:-1] elif value.upper() in ("FALSE", "NO", "OFF", "DISABLED"): - value = False + return False elif value.upper() in ("TRUE", "YES", "ON", "ENABLED"): - value = True - elif value.isdigit() or ((value[0:1] == "-" or value[0:1] == "+") and value[1:].isdigit()): - if value[0] != "0": # if this is zero padded it must be a string, so skip - value = int(value) - elif value.startswith("0x") or value.startswith("0X"): - value = int(value, 16) - elif value.startswith("0o") or value.startswith("0O"): - value = int(value, 8) - elif value.startswith("0b") or value.startswith("0B"): - value = int(value, 2) + return True + elif value.upper() == "NONE": + return None else: try: - value = float(value) - except ValueError: - pass - return value + return eval(value) + except: + return value def getEnigmaInfoList(self): return sorted(self.immutableList) @@ -78,12 +56,10 @@ def getItemsList(self): def getItem(self, item, default=None): if item in self.boxInfo: - value = self.boxInfo[item] + return self.boxInfo[item] elif item in SystemInfo: - value = SystemInfo[item] - else: - value = default - return value + return SystemInfo[item] + return default def setItem(self, item, value, immutable=False, forceOverride=False): if item in self.immutableList and not forceOverride: From aa7e15c0354a12cfb36f1314c68e139c220486a2 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sat, 30 Dec 2023 02:12:32 +0100 Subject: [PATCH 385/401] [BoxInfo] add checksum test --- lib/python/Components/SystemInfo.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/python/Components/SystemInfo.py b/lib/python/Components/SystemInfo.py index c1514b9fb05..5e1021c9bd0 100644 --- a/lib/python/Components/SystemInfo.py +++ b/lib/python/Components/SystemInfo.py @@ -1,4 +1,5 @@ from os import listdir +from hashlib import md5 from os.path import isfile, join as pathjoin from boxbranding import getBoxType, getBrandOEM, getDisplayType, getHaveAVJACK, getHaveHDMIinFHD, getHaveHDMIinHD, getHaveRCA, getHaveSCART, getHaveSCARTYUV, getHaveYUV, getImageType, getMachineBrand, getMachineBuild, getMachineMtdRoot, getMachineName from enigma import Misc_Options, eDVBCIInterfaces, eDVBResourceManager @@ -17,16 +18,22 @@ def __init__(self, root=""): self.boxInfo = {} file = root + pathjoin(resolveFilename(SCOPE_LIBDIR), "enigma.info") self.boxInfo["overrideactive"] = False # not currently used by us + self.boxInfo["checksumerror"] = True lines = fileReadLines(file) if lines: for line in lines: - if line.startswith("#") or line.strip() == "" or line.strip().lower().startswith("checksum") or "=" not in line: + if line.startswith("#") or line.strip() == "" or "=" not in line: continue item, value = [x.strip() for x in line.split("=", 1)] - if item: + if item.lower() == "checksum": + self.boxInfo["checksumerror"] = (i := lines.index(line)) < 1 or md5(bytearray("\n".join(lines[:i]) + "\n", "UTF-8", errors="ignore")).hexdigest() != value + elif item: self.immutableList.append(item) self.boxInfo[item] = self.processValue(value) - # print("[SystemInfo] Enigma information file data loaded into BoxInfo.") + if self.boxInfo["checksumerror"]: + print("[BoxInfo] Data integrity of %s could not be verified." % file) + # else: + # print("[SystemInfo] Enigma information file data loaded into BoxInfo.") else: print("[BoxInfo] ERROR: %s is not available! The system is unlikely to boot or operate correctly." % file) From db2ed19142ed73ed8868fb48a27dbb47512ecf84 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sat, 30 Dec 2023 03:10:03 +0100 Subject: [PATCH 386/401] Simplify some startswith/endswith --- lib/python/Components/About.py | 2 +- lib/python/Components/Renderer/Picon.py | 2 +- lib/python/Components/ServiceList.py | 2 +- lib/python/Components/SystemInfo.py | 2 +- lib/python/Components/Timeshift.py | 6 +++--- lib/python/Components/Timezones.py | 2 +- lib/python/Components/UsageConfig.py | 2 +- lib/python/Components/opkg.py | 2 +- lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py | 2 +- lib/python/Plugins/Extensions/DVDBurn/Process.py | 2 +- lib/python/Plugins/SystemPlugins/ViX/ImageManager.py | 2 +- lib/python/Plugins/SystemPlugins/ViX/SoftcamManager.py | 6 +++--- lib/python/Plugins/SystemPlugins/ViX/SwapManager.py | 2 +- lib/python/Screens/About.py | 2 +- lib/python/Screens/DVD.py | 2 +- lib/python/Screens/InfoBarGenerics.py | 4 ++-- lib/python/Screens/NetworkSetup.py | 6 +++--- lib/python/Screens/PluginBrowser.py | 4 ++-- lib/python/Tools/Trashcan.py | 3 +-- 19 files changed, 27 insertions(+), 28 deletions(-) diff --git a/lib/python/Components/About.py b/lib/python/Components/About.py index 7aef5d9f290..8542d46bcdb 100644 --- a/lib/python/Components/About.py +++ b/lib/python/Components/About.py @@ -122,7 +122,7 @@ def getCPUArch(): def getCPUString(): try: - return [x.split(": ")[1].split(" ")[0] for x in open("/proc/cpuinfo").readlines() if (x.startswith("system type") or x.startswith("model name") or x.startswith("Processor")) and len(x.split(": ")) > 1][0] + return [x.split(": ")[1].split(" ")[0] for x in open("/proc/cpuinfo").readlines() if x.startswith(("system type", "model name", "Processor")) and len(x.split(": ")) > 1][0] except: return _("unavailable") diff --git a/lib/python/Components/Renderer/Picon.py b/lib/python/Components/Renderer/Picon.py index be5698143a9..359a2116e00 100644 --- a/lib/python/Components/Renderer/Picon.py +++ b/lib/python/Components/Renderer/Picon.py @@ -67,7 +67,7 @@ def addSearchPath(self, value): if pathExists(value): if not value.endswith("/"): value += "/" - if not value.startswith("/media/net") and not value.startswith("/media/autofs") and value not in self.searchPaths: + if not value.startswith(("/media/net", "/media/autofs")) and value not in self.searchPaths: self.searchPaths.append(value) def getPiconName(self, serviceRef): diff --git a/lib/python/Components/ServiceList.py b/lib/python/Components/ServiceList.py index e00132486fa..253abe28dd2 100644 --- a/lib/python/Components/ServiceList.py +++ b/lib/python/Components/ServiceList.py @@ -291,7 +291,7 @@ def setCurrent(self, ref, adjust=True): from Components.ServiceEventTracker import InfoBarCount if adjust and config.usage.multibouquet.value and InfoBarCount == 1 and ref and ref.type != 8192: print("[servicelist] search for service in userbouquets") - isRadio = ref.toString().startswith("1:0:2:") or ref.toString().startswith("1:0:A:") + isRadio = ref.toString().startswith(("1:0:2:", "1:0:A:")) if self.serviceList: revert_mode = config.servicelist.lastmode.value revert_root = self.getRoot() diff --git a/lib/python/Components/SystemInfo.py b/lib/python/Components/SystemInfo.py index 5e1021c9bd0..1dc915e34e6 100644 --- a/lib/python/Components/SystemInfo.py +++ b/lib/python/Components/SystemInfo.py @@ -38,7 +38,7 @@ def __init__(self, root=""): print("[BoxInfo] ERROR: %s is not available! The system is unlikely to boot or operate correctly." % file) def processValue(self, value): - if (value.startswith("\"") or value.startswith("'")) and value.endswith(value[0]): + if value.startswith(("\"", "'")) and value.endswith(value[0]): return value[1:-1] elif value.upper() in ("FALSE", "NO", "OFF", "DISABLED"): return False diff --git a/lib/python/Components/Timeshift.py b/lib/python/Components/Timeshift.py index 9c20ae8f618..fd34e73db31 100644 --- a/lib/python/Components/Timeshift.py +++ b/lib/python/Components/Timeshift.py @@ -505,7 +505,7 @@ def checkTimeshiftRunningCallback(self, returnFunction, answer): def eraseTimeshiftFile(self): for filename in os.listdir(config.usage.timeshift_path.value): - if filename.startswith("timeshift.") and not filename.endswith(".del") and not filename.endswith(".copy"): + if filename.startswith("timeshift.") and not filename.endswith((".del", ".copy")): self.BgFileEraser.erase("%s%s" % (config.usage.timeshift_path.value, filename)) def autostartPermanentTimeshift(self): @@ -809,7 +809,7 @@ def ptsCleanTimeshiftFolder(self): return for filename in os.listdir(config.usage.timeshift_path.value): - if (filename.startswith("timeshift.") or filename.startswith("pts_livebuffer_")) and (filename.endswith(".del") is False and filename.endswith(".copy") is False): + if filename.startswith(("timeshift.", "pts_livebuffer_")) and not filename.endswith((".del", ".copy")): # print("[Timeshift]filename:", filename) statinfo = os.stat("%s%s" % (config.usage.timeshift_path.value, filename)) # if no write for 3 sec = stranded timeshift if statinfo.st_mtime < (time() - 3.0): @@ -883,7 +883,7 @@ def ptsCreateHardlink(self): # print("[Timeshift]ptsCreateHardlink") for filename in os.listdir(config.usage.timeshift_path.value): # if filename.startswith("timeshift") and not os.path.splitext(filename)[1]: - if filename.startswith("timeshift.") and not filename.endswith(".sc") and not filename.endswith(".del") and not filename.endswith(".copy") and not filename.endswith(".ap"): + if filename.startswith("timeshift.") and not filename.endswith((".sc", ".del", ".copy", ".ap")): if os.path.exists("%spts_livebuffer_%s.eit" % (config.usage.timeshift_path.value, self.pts_eventcount)): self.BgFileEraser.erase("%spts_livebuffer_%s.eit" % (config.usage.timeshift_path.value, self.pts_eventcount)) if os.path.exists("%spts_livebuffer_%s.meta" % (config.usage.timeshift_path.value, self.pts_eventcount)): diff --git a/lib/python/Components/Timezones.py b/lib/python/Components/Timezones.py index 16a9aad4a8b..53022792334 100644 --- a/lib/python/Components/Timezones.py +++ b/lib/python/Components/Timezones.py @@ -121,7 +121,7 @@ def loadTimezones(self): } for (root, dirs, files) in walk(TIMEZONE_DATA): base = root[len(TIMEZONE_DATA):] - if base.startswith("posix") or base.startswith("right"): # Skip these alternate copies of the time zone data if they exist. + if base.startswith(("posix", "right")): # Skip these alternate copies of the time zone data if they exist. continue if base == "": base = "Generic" diff --git a/lib/python/Components/UsageConfig.py b/lib/python/Components/UsageConfig.py index a8b09e284bb..17a2976f069 100644 --- a/lib/python/Components/UsageConfig.py +++ b/lib/python/Components/UsageConfig.py @@ -1157,7 +1157,7 @@ def setEpgLanguageAlternative(configElement): if softcam.lower().startswith("cccam"): config.cccaminfo.showInExtensions = ConfigYesNo(default=True) SystemInfo["CCcamInstalled"] = True - elif softcam.lower().startswith('oscam') or softcam.lower().startswith('ncam'): + elif softcam.lower().startswith(('oscam', 'ncam')): config.oscaminfo.showInExtensions = ConfigYesNo(default=True) SystemInfo["OScamInstalled"] = True diff --git a/lib/python/Components/opkg.py b/lib/python/Components/opkg.py index 141798d0283..cec8e747232 100644 --- a/lib/python/Components/opkg.py +++ b/lib/python/Components/opkg.py @@ -55,7 +55,7 @@ def enumPlugins(filter_start=''): def listsDirPath(): try: for line in open('/etc/opkg/opkg.conf', "r"): - if line.startswith('option lists_dir') or line.startswith('lists_dir'): + if line.startswith(('option lists_dir', 'lists_dir')): return line.replace('\n', '').split(' ')[2] except IOError: print("[Opkg] cannot open /etc/opkg/opkg.conf") diff --git a/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py b/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py index 85fca143a66..2c0d2e123ae 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py +++ b/lib/python/Plugins/Extensions/DVDBurn/DVDToolbox.py @@ -206,7 +206,7 @@ def processOutputLine(self, line): if line.startswith("- media is already formatted"): self.error = self.ERROR_ALREADYFORMATTED self.retryargs = ["-force"] - if line.startswith("- media is not blank") or line.startswith(" -format=full to perform full (lengthy) reformat;"): + if line.startswith(("- media is not blank", " -format=full to perform full (lengthy) reformat;")): self.error = self.ERROR_ALREADYFORMATTED self.retryargs = ["-blank"] if line.startswith(":-( mounted media doesn't appear to be"): diff --git a/lib/python/Plugins/Extensions/DVDBurn/Process.py b/lib/python/Plugins/Extensions/DVDBurn/Process.py index f28871620bc..d4f888146e8 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/Process.py +++ b/lib/python/Plugins/Extensions/DVDBurn/Process.py @@ -135,7 +135,7 @@ def processOutputLine(self, line): elif line.startswith(MSG_PROGRESS): progress = line[len(MSG_PROGRESS):] self.haveProgress(progress) - elif line.startswith(MSG_NEW_MP2) or line.startswith(MSG_NEW_AC3): + elif line.startswith((MSG_NEW_MP2, MSG_NEW_AC3)): try: self.currentPID = str(int(line.split(': PID 0x', 1)[1].split(' ', 1)[0], 16)) except ValueError: diff --git a/lib/python/Plugins/SystemPlugins/ViX/ImageManager.py b/lib/python/Plugins/SystemPlugins/ViX/ImageManager.py index 4d60979a26f..7f8e77897bc 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/ImageManager.py +++ b/lib/python/Plugins/SystemPlugins/ViX/ImageManager.py @@ -1789,7 +1789,7 @@ def keySave(self): def check_URL_format(self, configElement): if configElement.value: - configElement.value = "%s%s" % (not (configElement.value.startswith("http://") or configElement.value.startswith("https://") or configElement.value.startswith("ftp://")) and "http://" or "", configElement.value) + configElement.value = "%s%s" % (not configElement.value.startswith(("http://", "https://", "ftp://")) and "http://" or "", configElement.value) configElement.value = configElement.value.strip("/") # remove any trailing slash else: configElement.value = configElement.default diff --git a/lib/python/Plugins/SystemPlugins/ViX/SoftcamManager.py b/lib/python/Plugins/SystemPlugins/ViX/SoftcamManager.py index 616c807bec3..dc78b2a36e2 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/SoftcamManager.py +++ b/lib/python/Plugins/SystemPlugins/ViX/SoftcamManager.py @@ -357,7 +357,7 @@ def keyRestart(self, result, retval, extra_args): self.session.open(MessageBox, _("MGcamd can't run whilst CCcam is running."), MessageBox.TYPE_INFO, timeout=10, close_on_any_key=True) elif selectedcam.lower().startswith("scam"): self.session.openWithCallback(self.showActivecam, VIXStartCam, self.sel[0]) - elif not selectedcam.lower().startswith("cccam") or selectedcam.lower().startswith("oscam") or selectedcam.lower().startswith("ncam") or selectedcam.lower().startswith("mgcamd"): + elif not selectedcam.lower().startswith(("cccam", "oscam", "ncam", "mgcamd")): self.session.open(MessageBox, _("Found non-standard softcam, trying to start, this may fail."), MessageBox.TYPE_INFO, timeout=10, close_on_any_key=True) self.session.openWithCallback(self.showActivecam, VIXStartCam, self.sel[0]) @@ -751,7 +751,7 @@ def JobStart(self): now = datetime.now() output.write(now.strftime("%Y-%m-%d %H:%M") + ": " + softcamcheck + " running OK\n") output.close() - if softcamcheck.lower().startswith("oscam") or softcamcheck.lower().startswith("ncam"): + if softcamcheck.lower().startswith(("oscam", "ncam")): if path.exists("/tmp/status.html"): remove("/tmp/status.html") camconf = port = "" @@ -888,7 +888,7 @@ def JobStart(self): now = datetime.now() output.write(now.strftime("%Y-%m-%d %H:%M") + ": Couldn't find " + softcamcheck + " running, Starting " + softcamcheck + "\n") output.close() - if softcamcheck.lower().startswith("oscam") or softcamcheck.lower().startswith("ncam"): + if softcamcheck.lower().startswith(("oscam", "ncam")): self.Console.ePopen("ps.procps | grep softcams | grep -v grep | awk 'NR==1' | awk '{print $5}'| awk -F'[/]' '{print $4}' > /tmp/softcamRuningCheck.tmp") sleep(2) file = open("/tmp/softcamRuningCheck.tmp") diff --git a/lib/python/Plugins/SystemPlugins/ViX/SwapManager.py b/lib/python/Plugins/SystemPlugins/ViX/SwapManager.py index b050995f607..1f5a2d21917 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/SwapManager.py +++ b/lib/python/Plugins/SystemPlugins/ViX/SwapManager.py @@ -60,7 +60,7 @@ def startSwap2(self, result=None, retval=None, extra_args=None): # lets find sw devicelist = [] for p in harddiskmanager.getMountedPartitions(): d = path.normpath(p.mountpoint) - if (path.exists(p.mountpoint) and p.mountpoint != "/" and not p.mountpoint.startswith("/media/net/") and not p.mountpoint.startswith("/media/autofs/")): + if (path.exists(p.mountpoint) and p.mountpoint != "/" and not p.mountpoint.startswith(("/media/net/", "/media/autofs/"))): devicelist.append((p.description, d)) if len(devicelist): for device in devicelist: diff --git a/lib/python/Screens/About.py b/lib/python/Screens/About.py index 605b48199f7..ccc27d8de7e 100644 --- a/lib/python/Screens/About.py +++ b/lib/python/Screens/About.py @@ -312,7 +312,7 @@ def Stage1Complete(self, result, retval, extra_args=None): self.mountinfo = "" for line in result: self.parts = line.split() - if line and self.parts[0] and (self.parts[0].startswith("192") or self.parts[0].startswith("//192")): + if line and self.parts[0] and self.parts[0].startswith(("192", "//192"))): line = line.split() ipaddress = line[0] mounttotal = line[1] diff --git a/lib/python/Screens/DVD.py b/lib/python/Screens/DVD.py index 31730983e33..ee305d0f4cc 100644 --- a/lib/python/Screens/DVD.py +++ b/lib/python/Screens/DVD.py @@ -519,7 +519,7 @@ def FileBrowserClosed(self, val): if curref is None or curref != newref: if newref.toString().endswith("/VIDEO_TS") or newref.toString().endswith("/"): names = newref.toString().rsplit("/", 3) - if names[2].startswith("Disk ") or names[2].startswith("DVD "): + if names[2].startswith(("Disk ", "DVD ")): name = str(names[1]) + " - " + str(names[2]) else: name = names[2] diff --git a/lib/python/Screens/InfoBarGenerics.py b/lib/python/Screens/InfoBarGenerics.py index 0429141948d..361c88573c4 100644 --- a/lib/python/Screens/InfoBarGenerics.py +++ b/lib/python/Screens/InfoBarGenerics.py @@ -2154,7 +2154,7 @@ def skipString(skip): @staticmethod def generateSkipHelp(context): skipHelp = [] - for action in [act for ctx, act in getKeyBindingKeys(filterfn=lambda key: key[0] == context and (key[1].startswith("seek:") or key[1].startswith("seekdef:")))]: + for action in [act for ctx, act in getKeyBindingKeys(filterfn=lambda key: key[0] == context and (key[1].startswith(("seek:", "seekdef:"))))]: if action.startswith("seekdef:"): skipTime = boundFunction(InfoBarSeekActionMap.seekTime, action) else: @@ -2851,7 +2851,7 @@ def getOScamInfo(self): if pathExists('/usr/softcams/'): softcams = os.listdir('/usr/softcams/') for softcam in softcams: - if (softcam.lower().startswith('oscam') or softcam.lower().startswith('ncam')) and config.oscaminfo.showInExtensions.value: + if softcam.lower().startswith(('oscam', 'ncam')) and config.oscaminfo.showInExtensions.value: return [((boundFunction(self.getOSname), boundFunction(self.openOScamInfo), lambda: True), None)] or [] else: return [] diff --git a/lib/python/Screens/NetworkSetup.py b/lib/python/Screens/NetworkSetup.py index cceebb0a6ac..a85fa0c9e6e 100644 --- a/lib/python/Screens/NetworkSetup.py +++ b/lib/python/Screens/NetworkSetup.py @@ -2260,7 +2260,7 @@ def updateService(self): line = line[18:] line = (int(line) // 60) self["labtime"].setText(str(line)) - elif line.startswith("dyndns_system ") or line.startswith("#dyndns_system "): + elif line.startswith(("dyndns_system ", "#dyndns_system ")): if line.startswith("#"): line = line[15:] self["sactive"].hide() @@ -2320,7 +2320,7 @@ def updateList(self): line = (int(line[18:]) // 60) self.ina_period = NoSave(ConfigNumber(default=line)) # overwrite so we start with the correct defaults self.list.append(getConfigListEntry(_("Time update in minutes") + ":", self.ina_period)) - elif line.startswith("dyndns_system ") or line.startswith("#dyndns_system "): + elif line.startswith(("dyndns_system ", "#dyndns_system ")): if not line.startswith("#"): default = True line = line[14:] @@ -2352,7 +2352,7 @@ def keySave(self): # saveIna strview = (self.ina_period.value * 60) strview = str(strview) line = ("update_period_sec " + strview) - elif line.startswith("dyndns_system ") or line.startswith("#dyndns_system "): + elif line.startswith(("dyndns_system ", "#dyndns_system ")): if self.ina_sysactive.value: line = ("dyndns_system " + self.ina_system.value.strip()) else: diff --git a/lib/python/Screens/PluginBrowser.py b/lib/python/Screens/PluginBrowser.py index b6d3cb896ea..1e5f055d186 100644 --- a/lib/python/Screens/PluginBrowser.py +++ b/lib/python/Screens/PluginBrowser.py @@ -470,13 +470,13 @@ def runInstall(self, val): self.doRemove(self.installFinished, self["list"].l.getCurrentSelection()[0].name + " --force-remove --force-depends") def doRemove(self, callback, pkgname): - if pkgname.startswith('kernel-module-') or pkgname.startswith('enigma2-locale-'): + if pkgname.startswith(('kernel-module-', 'enigma2-locale-')): self.session.openWithCallback(callback, Console, cmdlist=[self.ipkg_remove + Ipkg.opkgExtraDestinations() + " " + pkgname, "sync"], closeOnSuccess=True) else: self.session.openWithCallback(callback, Console, cmdlist=[self.ipkg_remove + Ipkg.opkgExtraDestinations() + " " + self.PLUGIN_PREFIX + pkgname, "sync"], closeOnSuccess=True) def doInstall(self, callback, pkgname): - if pkgname.startswith('kernel-module-') or pkgname.startswith('enigma2-locale-'): + if pkgname.startswith(('kernel-module-', 'enigma2-locale-')): self.session.openWithCallback(callback, Console, cmdlist=[self.ipkg_install + " " + pkgname, "sync"], closeOnSuccess=True) else: self.session.openWithCallback(callback, Console, cmdlist=[self.ipkg_install + " " + self.PLUGIN_PREFIX + pkgname, "sync"], closeOnSuccess=True) diff --git a/lib/python/Tools/Trashcan.py b/lib/python/Tools/Trashcan.py index 473ff9ee546..d24a6d1bbb0 100644 --- a/lib/python/Tools/Trashcan.py +++ b/lib/python/Tools/Trashcan.py @@ -152,8 +152,7 @@ def work(self): if parts[1] == "/media/autofs": continue # skip network mounts unless the option to clean them is set - if (not config.usage.movielist_trashcan_network_clean.value and - (parts[1].startswith("/media/net") or parts[1].startswith("/media/autofs"))): + if not config.usage.movielist_trashcan_network_clean.value and parts[1].startswith(("/media/net", "/media/autofs")): continue # one trashcan in the root, one in movie subdirectory trashcanLocations.add(parts[1]) From bb32df11dc3846e3cd32df9648d45f9c043ede5e Mon Sep 17 00:00:00 2001 From: Huevos Date: Sat, 30 Dec 2023 03:35:13 +0100 Subject: [PATCH 387/401] [Picon] update for skipping 4k terminations --- lib/python/Components/Renderer/Picon.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/python/Components/Renderer/Picon.py b/lib/python/Components/Renderer/Picon.py index 359a2116e00..8a1954d2663 100644 --- a/lib/python/Components/Renderer/Picon.py +++ b/lib/python/Components/Renderer/Picon.py @@ -1,5 +1,5 @@ from os import listdir, path as ospath -import re +from re import sub from enigma import ePixmap, eServiceReference @@ -90,13 +90,11 @@ def getPiconName(self, serviceRef): pngname = self.findPicon("_".join(fields)) if not pngname: # picon by channel name name = sanitizeFilename(eServiceReference(serviceRef).getServiceName()) - name = re.sub("[^a-z0-9]", "", name.replace("&", "and").replace("+", "plus").replace("*", "star").lower()) - if len(name) > 0: - pngname = self.findPicon(name) - if not pngname and len(name) > 2 and name.endswith("hd"): - pngname = self.findPicon(name[:-2]) + name = sub("[^a-z0-9]", "", name.replace("&", "and").replace("+", "plus").replace("*", "star").lower()) + if name: + pngname = self.findPicon(name) or self.findPicon(sub("(fhd|uhd|hd|sd|4k)$", "", name).strip()) if not pngname and len(name) > 6: - series = re.sub(r"s[0-9]*e[0-9]*$", "", name) + series = sub(r"s[0-9]*e[0-9]*$", "", name) pngname = self.findPicon(series) return pngname From 9eaddc246b17224e06d60faabd6f4a4b93f8447a Mon Sep 17 00:00:00 2001 From: Huevos Date: Sat, 30 Dec 2023 03:41:26 +0100 Subject: [PATCH 388/401] [About] fix typo --- lib/python/Screens/About.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/python/Screens/About.py b/lib/python/Screens/About.py index ccc27d8de7e..a8ea1903dff 100644 --- a/lib/python/Screens/About.py +++ b/lib/python/Screens/About.py @@ -312,7 +312,7 @@ def Stage1Complete(self, result, retval, extra_args=None): self.mountinfo = "" for line in result: self.parts = line.split() - if line and self.parts[0] and self.parts[0].startswith(("192", "//192"))): + if line and self.parts[0] and self.parts[0].startswith(("192", "//192")): line = line.split() ipaddress = line[0] mounttotal = line[1] From 0fba247e7f5fc5714deabbcbe0828ce360b49be6 Mon Sep 17 00:00:00 2001 From: openvix-build Date: Sat, 30 Dec 2023 02:53:03 +0000 Subject: [PATCH 389/401] openvix: developer 6.4.011.007 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 3bac93f4547..045d459f0ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1224,3 +1224,4 @@ openvix: developer 6.4.011.003 openvix: developer 6.4.011.004 openvix: developer 6.4.011.005 openvix: developer 6.4.011.006 +openvix: developer 6.4.011.007 From 1802560575d97e2c24fab574168718411406e85a Mon Sep 17 00:00:00 2001 From: Huevos Date: Sat, 30 Dec 2023 10:23:15 +0100 Subject: [PATCH 390/401] [BoxInfo] revert some previous changes... don't use eval --- lib/python/Components/SystemInfo.py | 36 ++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/lib/python/Components/SystemInfo.py b/lib/python/Components/SystemInfo.py index 1dc915e34e6..e80d218f603 100644 --- a/lib/python/Components/SystemInfo.py +++ b/lib/python/Components/SystemInfo.py @@ -38,19 +38,39 @@ def __init__(self, root=""): print("[BoxInfo] ERROR: %s is not available! The system is unlikely to boot or operate correctly." % file) def processValue(self, value): - if value.startswith(("\"", "'")) and value.endswith(value[0]): - return value[1:-1] + if len(value) > 1 and value[0] in ("\"", "'") and value[-1] == value[0]): + value = value[1:-1] + elif value.startswith("(") and value.endswith(")"): + data = [] + for item in [x.strip() for x in value[1:-1].split(",")]: + data.append(self.processValue(item)) + value = tuple(data) + elif value.startswith("[") and value.endswith("]"): + data = [] + for item in [x.strip() for x in value[1:-1].split(",")]: + data.append(self.processValue(item)) + value = list(data) elif value.upper() in ("FALSE", "NO", "OFF", "DISABLED"): - return False + value = False elif value.upper() in ("TRUE", "YES", "ON", "ENABLED"): - return True + value = True elif value.upper() == "NONE": - return None + value = None + elif value.isdigit() or ((value[0:1] == "-" or value[0:1] == "+") and value[1:].isdigit()): + if value[0] != "0": # if this is zero padded it must be a string, so skip + value = int(value) + elif value.lower().startswith("0x"): + value = int(value, 16) + elif value.lower().startswith("0o"): + value = int(value, 8) + elif value.lower().startswith("0b"): + value = int(value, 2) else: try: - return eval(value) - except: - return value + value = float(value) + except ValueError: + pass + return value def getEnigmaInfoList(self): return sorted(self.immutableList) From 95b204520fa6302c2060f9b88d418b74041813dd Mon Sep 17 00:00:00 2001 From: Dimitrij Date: Wed, 22 Feb 2023 14:34:09 +0200 Subject: [PATCH 391/401] [frontend] fix dB tuner name VU+ Zero4K --- lib/dvb/frontend.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/dvb/frontend.cpp b/lib/dvb/frontend.cpp index 874f247e5ac..1e19f37ec22 100644 --- a/lib/dvb/frontend.cpp +++ b/lib/dvb/frontend.cpp @@ -1360,7 +1360,7 @@ void eDVBFrontend::calculateSignalQuality(int snr, int &signalquality, int &sign ret = snr; sat_max = 1620; } - else if (!strcmp(m_description, "Vuplus DVB-S NIM(Si2166)")) // VU+ Zero4K + else if (!strcmp(m_description, "Vuplus DVB-S NIM(SI2166)")) // VU+ Zero4K { ret = snr; } From c473a99512f74fe8f6685806ab6d6717c5bc17e0 Mon Sep 17 00:00:00 2001 From: Dima73 Date: Sun, 26 Feb 2023 08:56:39 +0200 Subject: [PATCH 392/401] [frontend] more calculate dB VU+ Zero4K --- lib/dvb/frontend.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/dvb/frontend.cpp b/lib/dvb/frontend.cpp index 1e19f37ec22..ed6977836d4 100644 --- a/lib/dvb/frontend.cpp +++ b/lib/dvb/frontend.cpp @@ -1362,7 +1362,7 @@ void eDVBFrontend::calculateSignalQuality(int snr, int &signalquality, int &sign } else if (!strcmp(m_description, "Vuplus DVB-S NIM(SI2166)")) // VU+ Zero4K { - ret = snr; + ret = snr / 40; } else if (!strncmp(m_description, "Si216", 5)) // New models with SI tuners { From a5a10a683d08e6a706d1285facd321f0ac09e227 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sun, 31 Dec 2023 03:05:50 +0100 Subject: [PATCH 393/401] Clean up boxbranding --- lib/python/Components/AVSwitch.py | 7 +- lib/python/Components/About.py | 13 +- lib/python/Components/FanControl.py | 8 +- lib/python/Components/InputDevice.py | 4 +- lib/python/Components/Ipkg.py | 4 +- lib/python/Components/Lcd.py | 16 +- lib/python/Components/OnlineUpdateCheck.py | 28 ++-- lib/python/Components/PackageInfo.py | 4 +- lib/python/Components/Renderer/LcdPicon.py | 4 +- .../Components/Renderer/RollerCharLCD.py | 6 +- lib/python/Components/SystemInfo.py | 114 +++++++++----- lib/python/Components/Timeshift.py | 7 +- lib/python/Components/UsageConfig.py | 11 +- .../Plugins/Extensions/DVDBurn/DVDProject.py | 4 +- .../Plugins/Extensions/DVDBurn/TitleList.py | 5 +- .../Plugins/Extensions/MediaPlayer/plugin.py | 3 +- .../SystemPlugins/AnimationSetup/plugin.py | 5 +- .../NetworkWizard/NetworkWizard.py | 4 +- .../SystemPlugins/SABnzbdSetup/plugin.py | 6 +- .../SystemPlugins/ViX/BackupManager.py | 18 +-- .../Plugins/SystemPlugins/ViX/ImageManager.py | 143 +++++++++--------- .../Plugins/SystemPlugins/ViX/MountManager.py | 7 +- .../SystemPlugins/ViX/RestoreWizard.py | 13 +- lib/python/PowerTimer.py | 16 +- lib/python/RecordTimer.py | 9 +- lib/python/Screens/About.py | 23 ++- lib/python/Screens/CronTimer.py | 4 +- lib/python/Screens/GitCommitInfo.py | 22 +-- lib/python/Screens/InputDeviceSetup.py | 10 +- lib/python/Screens/MultiBootSelector.py | 5 +- lib/python/Screens/NetworkSetup.py | 21 ++- lib/python/Screens/PluginBrowser.py | 7 +- lib/python/Screens/Satconfig.py | 3 +- lib/python/Screens/SoftwareUpdate.py | 24 +-- lib/python/Screens/Standby.py | 29 ++-- lib/python/Screens/TaskView.py | 6 +- lib/python/Screens/UserInterfacePositioner.py | 6 +- lib/python/Screens/VuWizard.py | 38 ++--- lib/python/Screens/Wizard.py | 4 +- lib/python/StartEnigma.py | 17 ++- lib/python/Tools/Downloader.py | 4 +- lib/python/Tools/HardwareInfo.py | 7 +- lib/python/Tools/Multiboot.py | 3 +- lib/python/Tools/Profile.py | 34 +++-- 44 files changed, 365 insertions(+), 361 deletions(-) diff --git a/lib/python/Components/AVSwitch.py b/lib/python/Components/AVSwitch.py index d93093ee60b..d85716e79a1 100644 --- a/lib/python/Components/AVSwitch.py +++ b/lib/python/Components/AVSwitch.py @@ -1,7 +1,6 @@ from os import path from enigma import eAVSwitch, getDesktop -from boxbranding import getBoxType, getBrandOEM from Components.config import ConfigBoolean, ConfigEnableDisable, ConfigNothing, ConfigSelection, ConfigSelectionNumber, ConfigSlider, ConfigSubDict, ConfigSubsection, ConfigYesNo, NoSave, config from Components.SystemInfo import SystemInfo @@ -143,7 +142,7 @@ def setMode(self, port, mode, rate, force=None): except (IOError, OSError): print("[AVSwitch] cannot open /proc/stb/video/videomode_24hz") - if getBrandOEM() in ("gigablue",): + if SystemInfo["brand"] in ("gigablue",): try: # use 50Hz mode (if available) for booting with open("/etc/videomode", "w") as fd: @@ -486,7 +485,7 @@ def setEDIDBypass(configElement): if SystemInfo["havecolorspace"]: def setHDMIColorspace(configElement): open(SystemInfo["havecolorspace"], "w").write(configElement.value) - if getBrandOEM() == "vuplus" and SystemInfo["HasMMC"]: + if SystemInfo["brand"] == "vuplus" and SystemInfo["HasMMC"]: choices = [ ("Edid(Auto)", _("Auto")), ("Hdmi_Rgb", _("RGB")), @@ -862,7 +861,7 @@ def setScaler_sharpness(configElement): open("/proc/stb/vmpeg/0/pep_apply", "w").write("1") except (IOError, OSError): print("[AVSwitch] couldn't write pep_scaler_sharpness") - if getBoxType() in ("gbquad", "gbquadplus"): + if SystemInfo["boxtype"] in ("gbquad", "gbquadplus"): config.av.scaler_sharpness = ConfigSlider(default=5, limits=(0, 26)) else: config.av.scaler_sharpness = ConfigSlider(default=13, limits=(0, 26)) diff --git a/lib/python/Components/About.py b/lib/python/Components/About.py index 8542d46bcdb..02ae0fa2f53 100644 --- a/lib/python/Components/About.py +++ b/lib/python/Components/About.py @@ -5,13 +5,11 @@ import fcntl import struct -from boxbranding import getDriverDate, getImageVersion, getMachineBuild, getBoxType - from enigma import getEnigmaVersionString def getVersionString(): - return getImageVersion() + return SystemInfo["imageversion"] def getFlashDateString(): @@ -23,7 +21,8 @@ def getFlashDateString(): def driversDate(): - return _formatDate(getDriverDate()) + from Components.SystemInfo import SystemInfo + return _formatDate(SystemInfo["driversdate"]) def getLastUpdate(): @@ -84,7 +83,8 @@ def getCPUSpeedMHzInt(): print("[About] getCPUSpeedMHzInt, /proc/cpuinfo not available") if cpu_speed == 0: - if getMachineBuild() in ("h7", "hd51", "sf4008", "osmio4k", "osmio4kplus", "osmini4k"): + from Components.SystemInfo import MODEL + if MODEL in ("h7", "hd51", "sf4008", "osmio4k", "osmio4kplus", "osmini4k"): try: import binascii with open("/sys/firmware/devicetree/base/cpus/cpu@0/clock-frequency", "rb") as f: @@ -113,7 +113,8 @@ def getCPUSpeedString(): def getCPUArch(): - if getBoxType() in ("osmio4k", ): + from Components.SystemInfo import MODEL + if MODEL.startswith("osmio4k"): return "ARM V7" if "ARM" in getCPUString(): return getCPUString() diff --git a/lib/python/Components/FanControl.py b/lib/python/Components/FanControl.py index 87774df5604..c2116754c16 100644 --- a/lib/python/Components/FanControl.py +++ b/lib/python/Components/FanControl.py @@ -5,7 +5,6 @@ import NavigationInstance from enigma import iRecordableService -from boxbranding import getBoxType class FanControl: @@ -66,12 +65,7 @@ def setPWM(fancontrol, fanid, configElement): for fanid in range(self.getFanCount()): fan = ConfigSubsection() fan.vlt = ConfigSlider(default=15, increment=5, limits=(0, 255)) - if getBoxType() == 'tm2t': - fan.pwm = ConfigSlider(default=150, increment=5, limits=(0, 255)) - if getBoxType() == 'tmsingle': - fan.pwm = ConfigSlider(default=100, increment=5, limits=(0, 255)) - else: - fan.pwm = ConfigSlider(default=50, increment=5, limits=(0, 255)) + fan.pwm = ConfigSlider(default=50, increment=5, limits=(0, 255)) fan.vlt_standby = ConfigSlider(default=5, increment=5, limits=(0, 255)) fan.pwm_standby = ConfigSlider(default=0, increment=5, limits=(0, 255)) fan.vlt.addNotifier(boundFunction(setVlt, self, fanid)) diff --git a/lib/python/Components/InputDevice.py b/lib/python/Components/InputDevice.py index c4481cd857e..2c7c46de66b 100644 --- a/lib/python/Components/InputDevice.py +++ b/lib/python/Components/InputDevice.py @@ -5,7 +5,7 @@ from enigma import eRCInput from keyids import KEYIDNAMES -from boxbranding import getBrandOEM +from Components.SystemInfo import SystemInfo from Components.config import config, ConfigInteger, ConfigSlider, ConfigSubsection, ConfigText, ConfigYesNo from Screens.Rc import RcPositions @@ -215,7 +215,7 @@ def remapRemoteControl(self, device): class RcTypeControl(): def __init__(self): self.boxType = "Default" - if path.exists('/proc/stb/ir/rc/type') and path.exists('/proc/stb/info/boxtype') and getBrandOEM() != 'gigablue': + if path.exists('/proc/stb/ir/rc/type') and path.exists('/proc/stb/info/boxtype') and SystemInfo["brand"] != 'gigablue': self.isSupported = True with open("/proc/stb/info/boxtype", "r") as fd: self.boxType = fd.read().strip() diff --git a/lib/python/Components/Ipkg.py b/lib/python/Components/Ipkg.py index 023bc0a5a59..1b11df1f533 100644 --- a/lib/python/Components/Ipkg.py +++ b/lib/python/Components/Ipkg.py @@ -3,7 +3,7 @@ from enigma import eConsoleAppContainer from Components.Harddisk import harddiskmanager from Tools.Directories import resolveFilename, SCOPE_LIBDIR -from boxbranding import getImageDistro +from Components.SystemInfo import SystemInfo opkgDestinations = [] opkgStatusPath = '' @@ -90,7 +90,7 @@ def runCmd(self, cmd): def startCmd(self, cmd, args=None): if cmd == self.CMD_UPDATE: for fn in listdir('/var/lib/opkg'): - if fn.startswith(getImageDistro()): + if fn.startswith(SystemInfo["distro"]): remove('/var/lib/opkg/' + fn) self.runCmdEx("update") elif cmd == self.CMD_UPGRADE: diff --git a/lib/python/Components/Lcd.py b/lib/python/Components/Lcd.py index 7c1e73d697d..2fb9294ac49 100644 --- a/lib/python/Components/Lcd.py +++ b/lib/python/Components/Lcd.py @@ -1,7 +1,5 @@ from sys import maxsize -from boxbranding import getBoxType, getDisplayType - from enigma import eDBoxLCD, eTimer, eActionMap from Components.config import config, ConfigSubsection, ConfigSelection, ConfigSlider, ConfigYesNo, ConfigNothing @@ -179,7 +177,7 @@ def standbyCounterChanged(dummy): def InitLcd(): if SystemInfo["HasNoDisplay"]: detected = False - elif getBoxType() in ('gbtrio4k',): + elif SystemInfo["boxtype"] in ('gbtrio4k',): detected = True else: detected = eDBoxLCD.getInstance().detected() @@ -411,14 +409,14 @@ def lcdLiveTvChanged(configElement): if "live_enable" in SystemInfo["LcdLiveTV"]: config.misc.standbyCounter.addNotifier(standbyCounterChangedLCDLiveTV, initial_call=False) - if SystemInfo["LCDMiniTV"] and getBoxType() not in ('gbquad4k', 'gbue4k'): + if SystemInfo["LCDMiniTV"] and SystemInfo["boxtype"] not in ('gbquad4k', 'gbue4k'): config.lcd.minitvmode = ConfigSelection([("0", _("normal")), ("1", _("MiniTV")), ("2", _("OSD")), ("3", _("MiniTV with OSD"))], "0") config.lcd.minitvmode.addNotifier(setLCDminitvmode) config.lcd.minitvpipmode = ConfigSelection([("0", _("off")), ("5", _("PIP")), ("7", _("PIP with OSD"))], "0") config.lcd.minitvpipmode.addNotifier(setLCDminitvpipmode) config.lcd.minitvfps = ConfigSlider(default=30, limits=(0, 30)) config.lcd.minitvfps.addNotifier(setLCDminitvfps) - elif can_lcdmodechecking and getBoxType() in ('gbquad4k', 'gbue4k'): + elif can_lcdmodechecking and SystemInfo["boxtype"] in ('gbquad4k', 'gbue4k'): # (0:normal, 1:video0, 2:fb, 3:vide0+fb, 4:video1, 5:vide0+video1, 6:video1+fb, 7:video0+video1+fb) config.lcd.minitvmode = ConfigSelection(default="0", choices=[ ("0", _("normal")), @@ -442,20 +440,20 @@ def lcdLiveTvChanged(configElement): config.lcd.minitvpipmode = ConfigNothing() config.lcd.minitvfps = ConfigNothing() - if SystemInfo["VFD_scroll_repeats"] and getDisplayType() not in ('7segment'): + if SystemInfo["VFD_scroll_repeats"] and SystemInfo["displaytype"] not in ('7segment'): def scroll_repeats(el): open(SystemInfo["VFD_scroll_repeats"], "w").write(el.value) choicelist = [("0", _("None")), ("1", _("1X")), ("2", _("2X")), ("3", _("3X")), ("4", _("4X")), ("500", _("Continues"))] config.usage.vfd_scroll_repeats = ConfigSelection(default="3", choices=choicelist) config.usage.vfd_scroll_repeats.addNotifier(scroll_repeats, immediate_feedback=False) - if SystemInfo["VFD_scroll_delay"] and getDisplayType() not in ('7segment'): + if SystemInfo["VFD_scroll_delay"] and SystemInfo["displaytype"] not in ('7segment'): def scroll_delay(el): open(SystemInfo["VFD_scroll_delay"], "w").write(str(el.value)) config.usage.vfd_scroll_delay = ConfigSlider(default=150, increment=10, limits=(0, 500)) config.usage.vfd_scroll_delay.addNotifier(scroll_delay, immediate_feedback=False) - if SystemInfo["VFD_initial_scroll_delay"] and getDisplayType() not in ('7segment'): + if SystemInfo["VFD_initial_scroll_delay"] and SystemInfo["displaytype"] not in ('7segment'): def initial_scroll_delay(el): open(SystemInfo["VFD_initial_scroll_delay"], "w").write(el.value) choicelist = [ @@ -466,7 +464,7 @@ def initial_scroll_delay(el): config.usage.vfd_initial_scroll_delay = ConfigSelection(default="1000", choices=choicelist) config.usage.vfd_initial_scroll_delay.addNotifier(initial_scroll_delay, immediate_feedback=False) - if SystemInfo["VFD_final_scroll_delay"] and getDisplayType() not in ('7segment'): + if SystemInfo["VFD_final_scroll_delay"] and SystemInfo["displaytype"] not in ('7segment'): def final_scroll_delay(el): open(SystemInfo["VFD_final_scroll_delay"], "w").write(el.value) choicelist = [ diff --git a/lib/python/Components/OnlineUpdateCheck.py b/lib/python/Components/OnlineUpdateCheck.py index 95f57f2091b..1fb5592bef4 100644 --- a/lib/python/Components/OnlineUpdateCheck.py +++ b/lib/python/Components/OnlineUpdateCheck.py @@ -1,10 +1,10 @@ from time import time -from boxbranding import getImageVersion, getImageBuild, getMachineBrand, getMachineName, getMachineBuild, getImageType, getBoxType, getFeedsUrl from enigma import eTimer from Components.About import about from Components.config import config from Components.Ipkg import IpkgComponent +from Components.SystemInfo import SystemInfo import Components.Task import socket @@ -80,7 +80,7 @@ def getFeedStatus(self): trafficLight = "unknown" if self.adapterAvailable(): if self.NetworkUp(): - if getImageType() == "release" and officialReleaseFeedsUri in getFeedsUrl(): # we know the network is good now so only do this check on release images where the release domain applies + if SystemInfo["imagetype"] == "release" and officialReleaseFeedsUri in SystemInfo["feedsurl"]: # we know the network is good now so only do this check on release images where the release domain applies try: print("[OnlineUpdateCheck][getFeedStatus] checking feeds state") req = Request("http://openvix.co.uk/TrafficLightState.php") @@ -98,11 +98,11 @@ def getFeedStatus(self): except: print("[OnlineUpdateCheck][getFeedStatus] ERROR:", sys.exc_info()[0]) trafficLight = -2 - if getImageType() == "developer" and "openvixdev" in getFeedsUrl(): + if SystemInfo["imagetype"] == "developer" and "openvixdev" in SystemInfo["feedsurl"]: print("[OnlineUpdateCheck][getFeedStatus] Official developer feeds") trafficLight = "developer" - elif officialReleaseFeedsUri not in getFeedsUrl(): # if not using official feeds mark as alien. There is no status test for alien feeds (including official developer feeds). - print("[OnlineUpdateCheck][getFeedStatus] Alien feeds url: %s" % getFeedsUrl()) + elif officialReleaseFeedsUri not in SystemInfo["feedsurl"]: # if not using official feeds mark as alien. There is no status test for alien feeds (including official developer feeds). + print("[OnlineUpdateCheck][getFeedStatus] Alien feeds url: %s" % SystemInfo["feedsurl"]) status = 0 trafficLight = "alien" config.softwareupdate.updateisunstable.value = status @@ -151,11 +151,11 @@ def getFeedsBool(self): def getFeedsErrorMessage(self): global error if self.feedstatus == -2: - return _("Your %s %s has no internet access, please check your network settings and make sure you have network cable connected and try again.") % (getMachineBrand(), getMachineName()) + return _("Your %s %s has no internet access, please check your network settings and make sure you have network cable connected and try again.") % (SystemInfo["displaybrand"], SystemInfo["machinename"]) elif self.feedstatus == -3: - return _("Your %s %s has no network access, please check your network settings and make sure you have network cable connected and try again.") % (getMachineBrand(), getMachineName()) + return _("Your %s %s has no network access, please check your network settings and make sure you have network cable connected and try again.") % (SystemInfo["displaybrand"], SystemInfo["machinename"]) elif self.feedstatus == 404: - return _("Your %s %s is not able to connect to the feeds, please try again later. If this persists please report on the OpenViX forum at world-of-satellite.com.") % (getMachineBrand(), getMachineName()) + return _("Your %s %s is not able to connect to the feeds, please try again later. If this persists please report on the OpenViX forum at world-of-satellite.com.") % (SystemInfo["displaybrand"], SystemInfo["machinename"]) elif self.feedstatus in ("updating", 403): return _("Sorry feeds are down for maintenance, please try again later. If this issue persists please check openvix.co.uk or world-of-satellite.com.") elif error: @@ -178,7 +178,7 @@ def ipkgCallback(self, event, param): self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE_LIST) elif self.ipkg.currentCommand == IpkgComponent.CMD_UPGRADE_LIST: self.total_packages = len(self.ipkg.getFetchedList()) - if self.total_packages and (getImageType() != "release" or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value) or config.softwareupdate.updateisunstable.value == 0): + if self.total_packages and (SystemInfo["imagetype"] != "release" or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value) or config.softwareupdate.updateisunstable.value == 0): print(("[OnlineUpdateCheck][ipkgCallback] %s Updates available" % self.total_packages)) config.softwareupdate.updatefound.setValue(True) pass @@ -249,7 +249,7 @@ def createCheckJob(self): def JobStart(self): config.softwareupdate.updatefound.setValue(False) - if (getImageType() != "release" and feedsstatuscheck.getFeedsBool() == "unknown") or (getImageType() == "release" and feedsstatuscheck.getFeedsBool() in ("stable", "unstable")): + if (SystemInfo["imagetype"] != "release" and feedsstatuscheck.getFeedsBool() == "unknown") or (SystemInfo["imagetype"] == "release" and feedsstatuscheck.getFeedsBool() in ("stable", "unstable")): print("[OnlineUpdateCheckPoller] Starting background check.") feedsstatuscheck.startCheck() else: @@ -266,7 +266,7 @@ def __init__(self): def getStableUpdateAvailable(self): if config.softwareupdate.updatefound.value and config.softwareupdate.check.value: - if getImageType() != "release" or config.softwareupdate.updateisunstable.value == 0: + if SystemInfo["imagetype"] != "release" or config.softwareupdate.updateisunstable.value == 0: print("[OnlineVersionCheck] New Release updates found") return True else: @@ -277,7 +277,7 @@ def getStableUpdateAvailable(self): def getUnstableUpdateAvailable(self): if config.softwareupdate.updatefound.value and config.softwareupdate.check.value: - if getImageType() != "release" or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value): + if SystemInfo["imagetype"] != "release" or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value): print("[OnlineVersionCheck] New Experimental updates found") return True else: @@ -300,7 +300,7 @@ def kernelMismatch(): print("[OnlineUpdateCheck][kernelMismatch] unable to retrieve kernel version from STB") return False - uri = "%s/%s/Packages.gz" % (getFeedsUrl(), getMachineBuild()) + uri = "%s/%s/Packages.gz" % (SystemInfo["feedsurl"], SystemInfo["model"]) try: req = Request(uri) d = urlopen(req) @@ -332,7 +332,7 @@ def kernelMismatch(): def statusMessage(): # returns message if status message is found, else False. # status-message.php goes in the root folder of the feeds webserver - uri = "http://%s/status-message.php?machine=%s&version=%s&build=%s" % (getFeedsUrl().split("/")[2], getBoxType(), getImageVersion(), getImageBuild()) + uri = "http://%s/status-message.php?machine=%s&version=%s&build=%s" % (SystemInfo["feedsurl"].split("/")[2], SystemInfo["boxtype"], SystemInfo["imageversion"], SystemInfo["imagebuild"]) try: req = Request(uri) d = urlopen(req) diff --git a/lib/python/Components/PackageInfo.py b/lib/python/Components/PackageInfo.py index c5f7df325ec..9632984a75d 100644 --- a/lib/python/Components/PackageInfo.py +++ b/lib/python/Components/PackageInfo.py @@ -3,7 +3,7 @@ from Components.NimManager import nimmanager from Components.Ipkg import IpkgComponent from Components.config import config, configfile -from boxbranding import getBoxType +from Components.SystemInfo import SystemInfo from enigma import eConsoleAppContainer, eDVBDB from os import listdir, path, system @@ -271,7 +271,7 @@ def prerequisiteMet(self, prerequisites): if "hardware" in prerequisites: hardware_found = False for hardware in prerequisites["hardware"]: - if hardware == getBoxType(): + if hardware == SystemInfo["boxtype"]: hardware_found = True if not hardware_found: return False diff --git a/lib/python/Components/Renderer/LcdPicon.py b/lib/python/Components/Renderer/LcdPicon.py index 970f9aced48..aef6c86ba6e 100644 --- a/lib/python/Components/Renderer/LcdPicon.py +++ b/lib/python/Components/Renderer/LcdPicon.py @@ -2,13 +2,13 @@ from Components.Renderer.Renderer import Renderer from enigma import ePixmap, ePicLoad from Tools.Directories import pathExists, SCOPE_CURRENT_SKIN, resolveFilename -from boxbranding import getDisplayType from Components.config import config +from Components.SystemInfo import SystemInfo from Components.Renderer.Picon import PiconLocator def useLcdPicons(): - return getDisplayType() in ('bwlcd255', 'bwlcd140', 'bwlcd128') or config.lcd.picon_pack.value + return SystemInfo["displaytype"] in ('bwlcd255', 'bwlcd140', 'bwlcd128') or config.lcd.picon_pack.value lcdPiconLocator = None diff --git a/lib/python/Components/Renderer/RollerCharLCD.py b/lib/python/Components/Renderer/RollerCharLCD.py index 87a733b5ec2..a646520352b 100644 --- a/lib/python/Components/Renderer/RollerCharLCD.py +++ b/lib/python/Components/Renderer/RollerCharLCD.py @@ -1,5 +1,4 @@ from enigma import eLabel, eTimer -from boxbranding import getBoxType from Components.config import config from Components.Renderer.Renderer import Renderer @@ -11,10 +10,7 @@ class RollerCharLCD(VariableText, Renderer): def __init__(self): Renderer.__init__(self) VariableText.__init__(self) - if getBoxType() in ('vuduo', 'sf4008'): - self.stringlength = 16 - else: - self.stringlength = 12 + self.stringlength = 12 GUI_WIDGET = eLabel diff --git a/lib/python/Components/SystemInfo.py b/lib/python/Components/SystemInfo.py index e80d218f603..1bd963ca772 100644 --- a/lib/python/Components/SystemInfo.py +++ b/lib/python/Components/SystemInfo.py @@ -1,7 +1,6 @@ from os import listdir from hashlib import md5 from os.path import isfile, join as pathjoin -from boxbranding import getBoxType, getBrandOEM, getDisplayType, getHaveAVJACK, getHaveHDMIinFHD, getHaveHDMIinHD, getHaveRCA, getHaveSCART, getHaveSCARTYUV, getHaveYUV, getImageType, getMachineBrand, getMachineBuild, getMachineMtdRoot, getMachineName from enigma import Misc_Options, eDVBCIInterfaces, eDVBResourceManager from Components.About import getChipSetString @@ -28,8 +27,7 @@ def __init__(self, root=""): if item.lower() == "checksum": self.boxInfo["checksumerror"] = (i := lines.index(line)) < 1 or md5(bytearray("\n".join(lines[:i]) + "\n", "UTF-8", errors="ignore")).hexdigest() != value elif item: - self.immutableList.append(item) - self.boxInfo[item] = self.processValue(value) + self.setItem(item, self.processValue(value), immutable=True) if self.boxInfo["checksumerror"]: print("[BoxInfo] Data integrity of %s could not be verified." % file) # else: @@ -38,7 +36,7 @@ def __init__(self, root=""): print("[BoxInfo] ERROR: %s is not available! The system is unlikely to boot or operate correctly." % file) def processValue(self, value): - if len(value) > 1 and value[0] in ("\"", "'") and value[-1] == value[0]): + if len(value) > 1 and value[0] in ("\"", "'") and value[-1] == value[0]: value = value[1:-1] elif value.startswith("(") and value.endswith(")"): data = [] @@ -121,8 +119,42 @@ def deleteItem(self, item, forceOverride=False): MACHINEBUILD = BoxInfo.getItem("machinebuild") +def getBoxType(): # this function mimics the function of the same name in branding module + if MACHINEBUILD == "sf8008": + boxtype = open("/proc/stb/info/type").read().strip() + if boxtype == "10": + return "sf8008s" + elif boxtype == "11": + return "sf8008t" + elif MACHINEBUILD == "sfx6008": + boxtype = open("/proc/stb/info/type").read().strip() + if boxtype == "10": + return "sfx6018" + return MACHINEBUILD + + +BoxInfo.setItem("boxtype", getBoxType(), immutable=True) + + +def getMachineName(): # this function mimics the function of the same name in branding module + if MACHINEBUILD == "sf8008": + boxtype = open("/proc/stb/info/type").read().strip() + if boxtype == "10": + return "SF8008 4K Single" + elif boxtype == "11": + return "SF8008 4K Twin" + elif MACHINEBUILD == "sfx6008": + boxtype = open("/proc/stb/info/type").read().strip() + if boxtype == "10": + return "SFX6018" + return DISPLAYMODEL + + +BoxInfo.setItem("machinename", getMachineName(), immutable=True) + + def getBoxDisplayName(): # This function returns a tuple like ("BRANDNAME", "BOXNAME") - return (DISPLAYBRAND, DISPLAYMODEL) + return (DISPLAYBRAND, SystemInfo["machinename"]) def getRCFile(ext): @@ -150,7 +182,7 @@ def setRCFile(source): SystemInfo["HasKexecUSB"] = False # This needs to be here so it can be reset by getMultibootslots! SystemInfo["HasKexecMultiboot"] = fileHas("/proc/cmdline", "kexec=1") # This needs to be here so it can be tested by getMultibootslots! from Tools.Multiboot import getMultibootslots # noqa: E402 # This import needs to be here to avoid a SystemInfo load loop! -SystemInfo["HasHiSi"] = pathExists("/proc/hisi") and getBoxType() not in ("vipertwin", "viper4kv20", "viper4kv40", "sfx6008", "sfx6018") # This needs to be for later checks +SystemInfo["HasHiSi"] = pathExists("/proc/hisi") and SystemInfo["boxtype"] not in ("vipertwin", "viper4kv20", "viper4kv40", "sfx6008", "sfx6018") # This needs to be for later checks SystemInfo["canMultiBoot"] = getMultibootslots() # SystemInfo["MBbootdevice"] = device set in Tools/Multiboot.py # SystemInfo["MultiBootSlot"] = current slot set in Tools/Multiboot.py @@ -174,14 +206,14 @@ def hasInitCam(): return bool([f for f in listdir("/etc/init.d") if f.startswith("softcam.") and f != "softcam.None"]) -SystemInfo["CanKexecVu"] = getBoxType() in ("vusolo4k", "vuduo4k", "vuduo4kse", "vuultimo4k", "vuuno4k", "vuuno4kse", "vuzero4k") and not SystemInfo["HasKexecMultiboot"] +SystemInfo["CanKexecVu"] = SystemInfo["boxtype"] in ("vusolo4k", "vuduo4k", "vuduo4kse", "vuultimo4k", "vuuno4k", "vuuno4kse", "vuzero4k") and not SystemInfo["HasKexecMultiboot"] SystemInfo["HasUsbhdd"] = {} SystemInfo["ArchIsARM"] = ARCHITECTURE.startswith(("arm", "cortex")) SystemInfo["ArchIsARM64"] = "64" in ARCHITECTURE SystemInfo["HasInitCam"] = hasInitCam() -SystemInfo["MachineBrand"] = getMachineBrand() -SystemInfo["MachineName"] = getMachineName() -SystemInfo["DeveloperImage"] = getImageType().lower() != "release" +SystemInfo["MachineBrand"] = DISPLAYBRAND +SystemInfo["MachineName"] = SystemInfo["machinename"] +SystemInfo["DeveloperImage"] = SystemInfo["imagetype"].lower() != "release" SystemInfo["CommonInterface"] = eDVBCIInterfaces.getInstance().getNumOfSlots() SystemInfo["CommonInterfaceCIDelay"] = fileCheck("/proc/stb/tsmux/rmx_delay") for cislot in range(0, SystemInfo["CommonInterface"]): @@ -189,22 +221,22 @@ def hasInitCam(): SystemInfo["CI%dRelevantPidsRoutingSupport" % cislot] = fileCheck("/proc/stb/tsmux/ci%d_relevant_pids_routing" % cislot) SystemInfo["NumVideoDecoders"] = getNumVideoDecoders() SystemInfo["Udev"] = not fileExists("/dev/.devfsd") -SystemInfo["HasFullHDSkinSupport"] = getBoxType() not in ("vipertwin",) -SystemInfo["PIPAvailable"] = getMachineBuild() not in ("i55plus") and SystemInfo["NumVideoDecoders"] > 1 +SystemInfo["HasFullHDSkinSupport"] = SystemInfo["boxtype"] not in ("vipertwin",) +SystemInfo["PIPAvailable"] = MODEL not in ("i55plus") and SystemInfo["NumVideoDecoders"] > 1 SystemInfo["CanMeasureFrontendInputPower"] = eDVBResourceManager.getInstance().canMeasureFrontendInputPower() SystemInfo["12V_Output"] = Misc_Options.getInstance().detected_12V_output() SystemInfo["ZapMode"] = fileCheck("/proc/stb/video/zapmode") or fileCheck("/proc/stb/video/zapping_mode") SystemInfo["NumFrontpanelLEDs"] = countFrontpanelLEDs() SystemInfo["FrontpanelDisplay"] = fileExists("/dev/dbox/oled0") or fileExists("/dev/dbox/lcd0") -SystemInfo["7segment"] = getDisplayType() in ("7segment") -SystemInfo["ConfigDisplay"] = SystemInfo["FrontpanelDisplay"] and getDisplayType() not in ("7segment") +SystemInfo["7segment"] = SystemInfo["displaytype"] in ("7segment") +SystemInfo["ConfigDisplay"] = SystemInfo["FrontpanelDisplay"] and SystemInfo["displaytype"] not in ("7segment") SystemInfo["LCDSKINSetup"] = pathExists("/usr/share/enigma2/display") and not SystemInfo["7segment"] SystemInfo["OledDisplay"] = fileExists("/dev/dbox/oled0") SystemInfo["LcdDisplay"] = fileExists("/dev/dbox/lcd0") -SystemInfo["LCDsymbol_hdd"] = getBoxType() in ("mutant51",) and fileCheck("/proc/stb/lcd/symbol_hdd") -SystemInfo["HasNoDisplay"] = getBoxType() in ("et4x00", "et5x00", "et6x00", "gb800se", "gb800solo", "gbx34k", "iqonios300hd", "mbmicro", "sf128", "sf138", "tmsingle", "tmnano2super", "tmnanose", "tmnanoseplus", "tmnanosem2", "tmnanosem2plus", "tmnanosecombo", "vusolo") -SystemInfo["DisplayLED"] = getBoxType() in ("gb800se", "gb800solo", "gbx1", "gbx2", "gbx3", "gbx3h") -SystemInfo["LEDButtons"] = False # getBoxType() == "vuultimo", For some reason this causes a cpp crash on vuultimo (which we no longer build). The cause needs investigating or the dead code in surrounding modules that this change causes should be removed. +SystemInfo["LCDsymbol_hdd"] = SystemInfo["boxtype"] in ("mutant51",) and fileCheck("/proc/stb/lcd/symbol_hdd") +SystemInfo["HasNoDisplay"] = SystemInfo["boxtype"] in ("et4x00", "et5x00", "et6x00", "gb800se", "gb800solo", "gbx34k", "iqonios300hd", "mbmicro", "sf128", "sf138", "tmsingle", "tmnano2super", "tmnanose", "tmnanoseplus", "tmnanosem2", "tmnanosem2plus", "tmnanosecombo", "vusolo") +SystemInfo["DisplayLED"] = SystemInfo["boxtype"] in ("gb800se", "gb800solo", "gbx1", "gbx2", "gbx3", "gbx3h") +SystemInfo["LEDButtons"] = False # SystemInfo["boxtype"] == "vuultimo", For some reason this causes a cpp crash on vuultimo (which we no longer build). The cause needs investigating or the dead code in surrounding modules that this change causes should be removed. SystemInfo["DeepstandbySupport"] = HardwareInfo().has_deepstandby() SystemInfo["Fan"] = fileCheck("/proc/stb/fp/fan") SystemInfo["FanPWM"] = SystemInfo["Fan"] and fileCheck("/proc/stb/fp/fan_pwm") @@ -218,35 +250,35 @@ def hasInitCam(): SystemInfo["Power24x7On"] = fileExists("/proc/stb/fp/power4x7on") SystemInfo["Power24x7Standby"] = fileExists("/proc/stb/fp/power4x7standby") SystemInfo["Power24x7Suspend"] = fileExists("/proc/stb/fp/power4x7suspend") -SystemInfo["WakeOnLAN"] = getBoxType() not in ("et8000", "et10000") and fileCheck("/proc/stb/power/wol") or fileCheck("/proc/stb/fp/wol") +SystemInfo["WakeOnLAN"] = SystemInfo["boxtype"] not in ("et8000", "et10000") and fileCheck("/proc/stb/power/wol") or fileCheck("/proc/stb/fp/wol") SystemInfo["hasHdmiCec"] = fileExists("/dev/hdmi_cec") or fileExists("/dev/misc/hdmi_cec0") -SystemInfo["HasExternalPIP"] = getMachineBuild() not in ("et9x00", "et6x00", "et5x00") and fileCheck("/proc/stb/vmpeg/1/external") +SystemInfo["HasExternalPIP"] = MODEL not in ("et9x00", "et6x00", "et5x00") and fileCheck("/proc/stb/vmpeg/1/external") SystemInfo["VideoDestinationConfigurable"] = fileExists("/proc/stb/vmpeg/0/dst_left") SystemInfo["hasPIPVisibleProc"] = fileCheck("/proc/stb/vmpeg/1/visible") -SystemInfo["VFD_scroll_repeats"] = not SystemInfo["7segment"] and getBoxType() not in ("et8500",) and fileCheck("/proc/stb/lcd/scroll_repeats") -SystemInfo["VFD_scroll_delay"] = not SystemInfo["7segment"] and getBoxType() not in ("et8500",) and fileCheck("/proc/stb/lcd/scroll_delay") -SystemInfo["VFD_initial_scroll_delay"] = not SystemInfo["7segment"] and getBoxType() not in ("et8500",) and fileCheck("/proc/stb/lcd/initial_scroll_delay") -SystemInfo["VFD_final_scroll_delay"] = not SystemInfo["7segment"] and getBoxType() not in ("et8500",) and fileCheck("/proc/stb/lcd/final_scroll_delay") +SystemInfo["VFD_scroll_repeats"] = not SystemInfo["7segment"] and SystemInfo["boxtype"] not in ("et8500",) and fileCheck("/proc/stb/lcd/scroll_repeats") +SystemInfo["VFD_scroll_delay"] = not SystemInfo["7segment"] and SystemInfo["boxtype"] not in ("et8500",) and fileCheck("/proc/stb/lcd/scroll_delay") +SystemInfo["VFD_initial_scroll_delay"] = not SystemInfo["7segment"] and SystemInfo["boxtype"] not in ("et8500",) and fileCheck("/proc/stb/lcd/initial_scroll_delay") +SystemInfo["VFD_final_scroll_delay"] = not SystemInfo["7segment"] and SystemInfo["boxtype"] not in ("et8500",) and fileCheck("/proc/stb/lcd/final_scroll_delay") SystemInfo["LcdLiveTV"] = fileCheck("/proc/stb/fb/sd_detach") or fileCheck("/proc/stb/lcd/live_enable") SystemInfo["LCDMiniTV"] = fileExists("/proc/stb/lcd/mode") -SystemInfo["LCDMiniTVPiP"] = SystemInfo["LCDMiniTV"] and getBoxType() != "gb800ueplus" +SystemInfo["LCDMiniTVPiP"] = SystemInfo["LCDMiniTV"] and SystemInfo["boxtype"] != "gb800ueplus" SystemInfo["LcdPowerOn"] = fileExists("/proc/stb/power/vfd") SystemInfo["FastChannelChange"] = False SystemInfo["3DMode"] = fileCheck("/proc/stb/fb/3dmode") or fileCheck("/proc/stb/fb/primary/3d") SystemInfo["3DZNorm"] = fileCheck("/proc/stb/fb/znorm") or fileCheck("/proc/stb/fb/primary/zoffset") -SystemInfo["Blindscan_t2_available"] = fileCheck("/proc/stb/info/vumodel") and getBoxType().startswith("vu") +SystemInfo["Blindscan_t2_available"] = fileCheck("/proc/stb/info/vumodel") and SystemInfo["boxtype"].startswith("vu") SystemInfo["HasTranscoding"] = pathExists("/proc/stb/encoder/0") or fileCheck("/dev/bcm_enc0") SystemInfo["HasH265Encoder"] = fileHas("/proc/stb/encoder/0/vcodec_choices", "h265") -SystemInfo["CanNotDoSimultaneousTranscodeAndPIP"] = getBoxType() in ("vusolo4k", "gbquad4k", "gbue4k") -SystemInfo["hasXcoreVFD"] = getBoxType() in ("osmega", "spycat4k", "spycat4kmini", "spycat4kcomb") and fileCheck("/sys/module/brcmstb_%s/parameters/pt6302_cgram" % getBoxType()) -SystemInfo["HasHDMIin"] = getHaveHDMIinHD() in ("True",) or getHaveHDMIinFHD() in ("True",) +SystemInfo["CanNotDoSimultaneousTranscodeAndPIP"] = SystemInfo["boxtype"] in ("vusolo4k", "gbquad4k", "gbue4k") +SystemInfo["hasXcoreVFD"] = SystemInfo["boxtype"] in ("osmega", "spycat4k", "spycat4kmini", "spycat4kcomb") and fileCheck("/sys/module/brcmstb_%s/parameters/pt6302_cgram" % SystemInfo["boxtype"]) +SystemInfo["HasHDMIin"] = SystemInfo["hdmifhdin"] or SystemInfo["hdmihdin"] SystemInfo["Has24hz"] = fileCheck("/proc/stb/video/videomode_24hz") -SystemInfo["canBackupEMC"] = getMachineBuild() in ("hd51", "h7") and ("disk.img", "%s" % SystemInfo["MBbootdevice"]) or getMachineBuild() in ("osmio4k", "osmio4kplus", "osmini4k") and ("emmc.img", "%s" % SystemInfo["MBbootdevice"]) or SystemInfo["HasHiSi"] and ("usb_update.bin", "none") -SystemInfo["canMode12"] = getMachineBuild() in ("hd51", "h7") and ("brcm_cma=440M@328M brcm_cma=192M@768M", "brcm_cma=520M@248M brcm_cma=200M@768M") -SystemInfo["HasMMC"] = fileHas("/proc/cmdline", "root=/dev/mmcblk") or "mmcblk" in getMachineMtdRoot() -SystemInfo["HasH9SD"] = getMachineBuild() in ("h9", "i55plus") and pathExists("/dev/mmcblk0p1") -SystemInfo["HasSDnomount"] = getMachineBuild() in ("h9", "i55plus") and (False, "none") or getMachineBuild() in ("multibox", "h9combo", "h9combose", "h9twin", "h9se", "pulse4kmini", "hd61", "pulse4k", "h11") and (True, "mmcblk0") -SystemInfo["CanProc"] = SystemInfo["HasMMC"] and getBrandOEM() != "vuplus" +SystemInfo["canBackupEMC"] = MODEL in ("hd51", "h7") and ("disk.img", "%s" % SystemInfo["MBbootdevice"]) or MODEL in ("osmio4k", "osmio4kplus", "osmini4k") and ("emmc.img", "%s" % SystemInfo["MBbootdevice"]) or SystemInfo["HasHiSi"] and ("usb_update.bin", "none") +SystemInfo["canMode12"] = MODEL in ("hd51", "h7") and ("brcm_cma=440M@328M brcm_cma=192M@768M", "brcm_cma=520M@248M brcm_cma=200M@768M") +SystemInfo["HasMMC"] = fileHas("/proc/cmdline", "root=/dev/mmcblk") or "mmcblk" in SystemInfo["mtdrootfs"] +SystemInfo["HasH9SD"] = MODEL in ("h9", "i55plus") and pathExists("/dev/mmcblk0p1") +SystemInfo["HasSDnomount"] = MODEL in ("h9", "i55plus") and (False, "none") or MODEL in ("multibox", "h9combo", "h9combose", "h9twin", "h9se", "pulse4kmini", "hd61", "pulse4k", "h11") and (True, "mmcblk0") +SystemInfo["CanProc"] = SystemInfo["HasMMC"] and SystemInfo["brand"] != "vuplus" SystemInfo["Canaudiosource"] = fileCheck("/proc/stb/hdmi/audio_source") SystemInfo["Can3DSurround"] = fileHas("/proc/stb/audio/3d_surround_choices", "none") and fileCheck("/proc/stb/audio/3d_surround") SystemInfo["Can3DSpeaker"] = fileHas("/proc/stb/audio/3d_surround_speaker_position_choices", "center") and fileCheck("/proc/stb/audio/3d_surround_speaker_position") @@ -273,11 +305,11 @@ def hasInitCam(): SystemInfo["Canedidchecking"] = fileCheck("/proc/stb/hdmi/bypass_edid_checking") SystemInfo["haveboxmode"] = fileCheck("/proc/stb/info/boxmode") SystemInfo["HasScaler_sharpness"] = pathExists("/proc/stb/vmpeg/0/pep_scaler_sharpness") -SystemInfo["hasJack"] = getHaveAVJACK() in ('True',) -SystemInfo["hasRCA"] = getHaveRCA() in ('True',) -SystemInfo["hasScart"] = getHaveSCART() in ('True',) -SystemInfo["hasScartYUV"] = getHaveSCARTYUV() in ('True',) -SystemInfo["hasYUV"] = getHaveYUV() in ('True',) +SystemInfo["hasJack"] = SystemInfo["avjack"] +SystemInfo["hasRCA"] = SystemInfo["rca"] +SystemInfo["hasScart"] = SystemInfo["scart"] +SystemInfo["hasScartYUV"] = SystemInfo["scartyuv"] +SystemInfo["hasYUV"] = SystemInfo["yuv"] SystemInfo["VideoModes"] = getChipSetString() in ( # 2160p and 1080p capable hardware... "5272s", "7251", "7251s", "7252", "7252s", "7278", "7366", "7376", "7444s", "72604", "3798mv200", "3798cv200", "3798mv200h", "3798mv300", "hi3798mv200", "hi3798mv200h", "hi3798mv200advca", "hi3798cv200", "hi3798mv300" ) and ( @@ -293,7 +325,7 @@ def hasInitCam(): {"720p", "1080i"} # Widescreen modes. ) -SystemInfo["FbcTunerPowerAlwaysOn"] = getBoxType() in ("vusolo4k", "vuduo4k", "vuduo4kse", "vuultimo4k", "vuuno4k", "vuuno4kse") +SystemInfo["FbcTunerPowerAlwaysOn"] = SystemInfo["boxtype"] in ("vusolo4k", "vuduo4k", "vuduo4kse", "vuultimo4k", "vuuno4k", "vuuno4kse") SystemInfo["HasPhysicalLoopthrough"] = ["Vuplus DVB-S NIM(AVL2108)", "GIGA DVB-S2 NIM (Internal)"] SystemInfo["HasFBCtuner"] = ["Vuplus DVB-C NIM(BCM3158)", "Vuplus DVB-C NIM(BCM3148)", "Vuplus DVB-S NIM(7376 FBC)", "Vuplus DVB-S NIM(45308X FBC)", "Vuplus DVB-S NIM(45208 FBC)", "DVB-S2 NIM(45208 FBC)", "DVB-S2X NIM(45308X FBC)", "DVB-S2 NIM(45308 FBC)", "DVB-C NIM(3128 FBC)", "BCM45208", "BCM45308X", "BCM3158"] SystemInfo["FCCactive"] = False diff --git a/lib/python/Components/Timeshift.py b/lib/python/Components/Timeshift.py index fd34e73db31..02ab05d5cbc 100644 --- a/lib/python/Components/Timeshift.py +++ b/lib/python/Components/Timeshift.py @@ -48,7 +48,6 @@ from Tools.TimeShift import CopyTimeshiftJob, MergeTimeshiftJob, CreateAPSCFilesJob from enigma import eBackgroundFileEraser, eTimer, eServiceCenter, iServiceInformation, iPlayableService, eEPGCache, eServiceReference -from boxbranding import getBoxType, getBrandOEM from time import time, localtime, strftime from random import randint @@ -435,13 +434,13 @@ def activateTimeshiftEnd(self, back=True): if seekable is not None: seekable.seekTo(-90000) # seek approx. 1 sec before end if back: - if getBrandOEM() == "xtrend": + if SystemInfo["brand"] == "xtrend": self.ts_rewind_timer.start(1000, 1) else: self.ts_rewind_timer.start(100, 1) def rewindService(self): - if getBrandOEM() in ("gigablue", "xp"): + if SystemInfo["brand"] in ("gigablue", "xp"): self.setSeekState(self.SEEK_STATE_PLAY) self.setSeekState(self.makeStateBackward(int(config.seek.enter_backward.value))) @@ -545,7 +544,7 @@ def activatePermanentTimeshift(self): self.stopTimeshiftcheckTimeshiftRunningCallback(True) ts = self.getTimeshift() if ts and not ts.startTimeshift(): - if (getBoxType() == "vuuno" or getBoxType() == "vuduo") and os.path.exists("/proc/stb/lcd/symbol_timeshift"): + if (SystemInfo["boxtype"] == "vuuno" or SystemInfo["boxtype"] == "vuduo") and os.path.exists("/proc/stb/lcd/symbol_timeshift"): if self.session.nav.RecordTimer.isRecording(): f = open("/proc/stb/lcd/symbol_timeshift", "w") f.write("0") diff --git a/lib/python/Components/UsageConfig.py b/lib/python/Components/UsageConfig.py index 17a2976f069..ad79d90fc99 100644 --- a/lib/python/Components/UsageConfig.py +++ b/lib/python/Components/UsageConfig.py @@ -2,7 +2,6 @@ import locale import os import skin -from boxbranding import getBrandOEM, getDisplayType from enigma import eDVBDB, eEPGCache, setTunerTypePriorityOrder, setPreferredTuner, setSpinnerOnOff, setEnableTtCachingOnOff, eEnv, Misc_Options, eServiceEvent @@ -31,7 +30,7 @@ def raw_stderr_print(text): def InitUsageConfig(): config.version = ConfigNumber(default=0) - if getBrandOEM() in ('vuplus', 'ini'): + if SystemInfo["brand"] in ('vuplus', 'ini'): config.misc.remotecontrol_text_support = ConfigYesNo(default=True) else: config.misc.remotecontrol_text_support = ConfigYesNo(default=False) @@ -340,7 +339,7 @@ def wakeOnLANChanged(configElement): config.usage.wakeOnLAN.addNotifier(wakeOnLANChanged) # standby - if getDisplayType() in ("textlcd7segment"): + if SystemInfo["displaytype"] in ("textlcd7segment"): config.usage.blinking_display_clock_during_recording = ConfigSelection(default="Rec", choices=[ ("Rec", _("REC")), ("RecBlink", _("Blinking REC")), @@ -349,12 +348,12 @@ def wakeOnLANChanged(configElement): config.usage.blinking_display_clock_during_recording = ConfigYesNo(default=False) # in use - if getDisplayType() in ("textlcd"): + if SystemInfo["displaytype"] in ("textlcd"): config.usage.blinking_rec_symbol_during_recording = ConfigSelection(default="Channel", choices=[ ("Rec", _("REC Symbol")), ("RecBlink", _("Blinking REC Symbol")), ("Channel", _("Channelname"))]) - if getDisplayType() in ("textlcd7segment"): + if SystemInfo["displaytype"] in ("textlcd7segment"): config.usage.blinking_rec_symbol_during_recording = ConfigSelection(default="Rec", choices=[ ("Rec", _("REC")), ("RecBlink", _("Blinking REC")), @@ -362,7 +361,7 @@ def wakeOnLANChanged(configElement): else: config.usage.blinking_rec_symbol_during_recording = ConfigYesNo(default=True) - if getDisplayType() in ("textlcd7segment"): + if SystemInfo["displaytype"] in ("textlcd7segment"): config.usage.show_in_standby = ConfigSelection(default="time", choices=[ ("time", _("Time")), ("nothing", _("Nothing"))]) diff --git a/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py b/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py index 567b0ae35cb..6049c984715 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py +++ b/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py @@ -1,8 +1,8 @@ import xml.dom.minidom -from boxbranding import getMachineBrand, getMachineName from Tools.Directories import fileExists from Components.config import ConfigSubsection, ConfigInteger, ConfigText, ConfigSelection, ConfigSequence, ConfigSubList +from Components.SystemInfo import getBoxDisplayName from . import DVDTitle from Tools.Directories import resolveFilename, SCOPE_PLUGINS, SCOPE_FONTS @@ -39,7 +39,7 @@ def __init__(self): self.target = None self.settings = ConfigSubsection() self.settings.name = ConfigText(fixed_size=False, visible_width=40) - self.settings.authormode = ConfigSelection(choices=[("menu_linked", _("Linked titles with a DVD menu")), ("just_linked", _("Direct playback of linked titles without menu")), ("menu_seperate", _("Seperate titles with a main menu")), ("data_ts", _("%s %s format data DVD (HDTV compatible)") % (getMachineBrand(), getMachineName()))]) + self.settings.authormode = ConfigSelection(choices=[("menu_linked", _("Linked titles with a DVD menu")), ("just_linked", _("Direct playback of linked titles without menu")), ("menu_seperate", _("Seperate titles with a main menu")), ("data_ts", _("%s %s format data DVD (HDTV compatible)") % getBoxDisplayName()))]) self.settings.titlesetmode = ConfigSelection(choices=[("single", _("Simple titleset (compatibility for legacy players)")), ("multi", _("Complex (allows mixing audio tracks and aspects)"))], default="multi") self.settings.output = ConfigSelection(choices=[("iso", _("Create DVD-ISO")), ("dvd", _("Burn DVD"))]) self.settings.isopath = ConfigText(fixed_size=False, visible_width=40) diff --git a/lib/python/Plugins/Extensions/DVDBurn/TitleList.py b/lib/python/Plugins/Extensions/DVDBurn/TitleList.py index 00b1acf3490..c6bd9814f26 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/TitleList.py +++ b/lib/python/Plugins/Extensions/DVDBurn/TitleList.py @@ -1,5 +1,3 @@ -from boxbranding import getMachineBrand, getMachineName - from . import DVDProject from . import TitleCutter from . import TitleProperties @@ -17,6 +15,7 @@ from Components.Sources.StaticText import StaticText from Components.Sources.Progress import Progress from Components.Label import MultiColorLabel +from Components.SystemInfo import getBoxDisplayName from Tools.Directories import resolveFilename, SCOPE_PLUGINS @@ -227,7 +226,7 @@ def selectedSource(self, source=None): if source is None: return None if not source.getPath().endswith(".ts"): - self.session.open(MessageBox, text=_("You can only burn %s %s recordings!") % (getMachineBrand(), getMachineName()), type=MessageBox.TYPE_ERROR) + self.session.open(MessageBox, text=_("You can only burn %s %s recordings!") % getBoxDisplayName(), type=MessageBox.TYPE_ERROR) return None t = self.project.addService(source) try: diff --git a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py index 966ef6f8c87..d9d5c43783c 100644 --- a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py @@ -1,7 +1,6 @@ from os import listdir, path as ospath, remove as osremove from time import strftime import random -from boxbranding import getMachineBrand, getMachineName from enigma import iPlayableService, eTimer, eServiceCenter, iServiceInformation, ePicLoad from Components.ActionMap import NumberActionMap, HelpableActionMap @@ -353,7 +352,7 @@ def __evAudioDecodeError(self): currPlay = self.session.nav.getCurrentService() sTagAudioCodec = currPlay.info().getInfoString(iServiceInformation.sTagAudioCodec) print("[__evAudioDecodeError] audio-codec %s can't be decoded by hardware" % sTagAudioCodec) - self.session.open(MessageBox, _("This %s %s cannot decode %s streams!") % (getMachineBrand(), getMachineName(), sTagAudioCodec), type=MessageBox.TYPE_INFO, timeout=20) + self.session.open(MessageBox, _("This %s %s cannot decode %s streams!") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"], sTagAudioCodec), type=MessageBox.TYPE_INFO, timeout=20) def __evVideoDecodeError(self): currPlay = self.session.nav.getCurrentService() diff --git a/lib/python/Plugins/SystemPlugins/AnimationSetup/plugin.py b/lib/python/Plugins/SystemPlugins/AnimationSetup/plugin.py index 5ae052e3523..be12e4a9ea0 100644 --- a/lib/python/Plugins/SystemPlugins/AnimationSetup/plugin.py +++ b/lib/python/Plugins/SystemPlugins/AnimationSetup/plugin.py @@ -5,12 +5,11 @@ from Components.MenuList import MenuList from Components.Sources.StaticText import StaticText from Components.config import config, ConfigNumber, ConfigSelectionNumber, getConfigListEntry +from Components.SystemInfo import SystemInfo from Plugins.Plugin import PluginDescriptor from enigma import setAnimation_current, setAnimation_speed -from boxbranding import getBrandOEM - # default = disabled g_default = { "current": 0, @@ -90,7 +89,7 @@ def makeConfigList(self): class AnimationSetupScreen(Screen): - if getBrandOEM() == 'gigablue': + if SystemInfo["brand"] == 'gigablue': animationSetupItems = [ {"idx": 0, "name": _("Disable Animations")}, {"idx": 1, "name": _("Simple fade")}, diff --git a/lib/python/Plugins/SystemPlugins/NetworkWizard/NetworkWizard.py b/lib/python/Plugins/SystemPlugins/NetworkWizard/NetworkWizard.py index fd6f3a3dc1c..b45be2f9b4a 100644 --- a/lib/python/Plugins/SystemPlugins/NetworkWizard/NetworkWizard.py +++ b/lib/python/Plugins/SystemPlugins/NetworkWizard/NetworkWizard.py @@ -1,12 +1,12 @@ from os import system from enigma import eTimer -from boxbranding import getMachineBrand, getMachineName from Components.config import config from Components.Label import Label from Components.Network import iNetwork from Components.Pixmap import Pixmap from Components.Sources.Boolean import Boolean +from Components.SystemInfo import getBoxDisplayName from Screens.MessageBox import MessageBox from Screens.Rc import Rc from Screens.WizardLanguage import WizardLanguage @@ -246,7 +246,7 @@ def checkWlanStateCB(self, data, status): if data is not None: if data is True: if status is not None: - text1 = _("Your %s %s is now ready to be used.\n\nYour internet connection is working now.\n\n") % (getMachineBrand(), getMachineName()) + text1 = _("Your %s %s is now ready to be used.\n\nYour internet connection is working now.\n\n") % getBoxDisplayName() text2 = _('Accesspoint:') + "\t" + str(status[self.selectedInterface]["accesspoint"]) + "\n" text3 = _('SSID:') + "\t" + str(status[self.selectedInterface]["essid"]) + "\n" text4 = _('Link quality:') + "\t" + str(status[self.selectedInterface]["quality"]) + "\n" diff --git a/lib/python/Plugins/SystemPlugins/SABnzbdSetup/plugin.py b/lib/python/Plugins/SystemPlugins/SABnzbdSetup/plugin.py index c1f8cf3fe71..5719b0fa10b 100644 --- a/lib/python/Plugins/SystemPlugins/SABnzbdSetup/plugin.py +++ b/lib/python/Plugins/SystemPlugins/SABnzbdSetup/plugin.py @@ -1,4 +1,3 @@ -from boxbranding import getMachineBrand, getMachineName import time from Screens.Screen import Screen @@ -7,6 +6,7 @@ from Components.Label import Label from Components.Sources.StaticText import StaticText from Components.ActionMap import ActionMap +from Components.SystemInfo import getBoxDisplayName from Tools.Directories import fileExists @@ -56,7 +56,7 @@ def InstallCheck(self): def InstalldataAvail(self, result, retval, extra_args): if not result: - restartbox = self.session.openWithCallback(self.InstallPackage, MessageBox, _('Your %s %s will be restarted after the installation of service.\n\nDo you want to install now ?') % (getMachineBrand(), getMachineName()), MessageBox.TYPE_YESNO) + restartbox = self.session.openWithCallback(self.InstallPackage, MessageBox, _('Your %s %s will be restarted after the installation of service.\n\nDo you want to install now ?') % getBoxDisplayName(), MessageBox.TYPE_YESNO) restartbox.setTitle(_('Ready to install "%s" ?') % self.service_name) else: self.updateService() @@ -83,7 +83,7 @@ def UninstallCheck(self): def UninstalldataAvail(self, result, retval, extra_args): if result: - restartbox = self.session.openWithCallback(self.RemovePackage, MessageBox, _('Your %s %s will be restarted after the removal of service\nDo you want to remove now ?') % (getMachineBrand(), getMachineName()), MessageBox.TYPE_YESNO) + restartbox = self.session.openWithCallback(self.RemovePackage, MessageBox, _('Your %s %s will be restarted after the removal of service\nDo you want to remove now ?') % getBoxDisplayName(), MessageBox.TYPE_YESNO) restartbox.setTitle(_('Ready to remove "%s" ?') % self.service_name) else: self.updateService() diff --git a/lib/python/Plugins/SystemPlugins/ViX/BackupManager.py b/lib/python/Plugins/SystemPlugins/ViX/BackupManager.py index b72eb87ce39..bd5540665e3 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/BackupManager.py +++ b/lib/python/Plugins/SystemPlugins/ViX/BackupManager.py @@ -5,7 +5,6 @@ import glob from enigma import eTimer, eEnv, eDVBDB, quitMainloop -from boxbranding import getImageType, getImageDistro, getImageVersion, getImageBuild, getImageDevBuild, getMachineBrand, getMachineMake, getMachineName from Components.About import about from Components.ActionMap import ActionMap from Components.Button import Button @@ -16,6 +15,7 @@ from Components.Label import Label from Components.MenuList import MenuList from Components.Sources.StaticText import StaticText +from Components.SystemInfo import SystemInfo import Components.Task from Screens.MessageBox import MessageBox from Screens.Screen import Screen @@ -27,7 +27,7 @@ SETTINGSRESTOREQUESTIONID = "RestoreSettingsNotification" PLUGINRESTOREQUESTIONID = "RestorePluginsNotification" NOPLUGINS = "NoPluginsNotification" -defaultprefix = getImageDistro()[4:] +defaultprefix = SystemInfo["distro"][4:] def getMountChoices(): @@ -581,7 +581,7 @@ def Stage3(self): self.kernelcheck = False AddPopupWithCallback( self.Stage6, - _("Your %s %s is not connected to a network. Please check your network settings and try again.") % (getMachineBrand(), getMachineName()), + _("Your %s %s is not connected to a network. Please check your network settings and try again.") % (SystemInfo["displaybrand"], SystemInfo["machinename"]), MessageBox.TYPE_INFO, 15, NOPLUGINS @@ -601,7 +601,7 @@ def Stage3(self): self.kernelcheck = False AddPopupWithCallback( self.Stage6, - _("Your %s %s is not connected to the Internet. Please check your network settings and try again.") % (getMachineBrand(), getMachineName()), + _("Your %s %s is not connected to the Internet. Please check your network settings and try again.") % (SystemInfo["displaybrand"], SystemInfo["machinename"]), MessageBox.TYPE_INFO, 15, NOPLUGINS @@ -1068,7 +1068,7 @@ def BackuponTimer(self): print("[BackupManager] Backup onTimer occured at", strftime("%c", localtime(now))) from Screens.Standby import inStandby if not inStandby and config.backupmanager.query.value: # Check for querying enabled - message = _("Your %s %s is about to run a backup of your settings and to detect your plugins.\nDo you want to allow this?") % (getMachineBrand(), getMachineName()) + message = _("Your %s %s is about to run a backup of your settings and to detect your plugins.\nDo you want to allow this?") % (SystemInfo["displaybrand"], SystemInfo["machinename"]) ybox = self.session.openWithCallback(self.doBackup, MessageBox, message, MessageBox.TYPE_YESNO, timeout=30) ybox.setTitle("Scheduled backup.") else: @@ -1343,12 +1343,12 @@ def Stage5(self): elif self.backuptype == self.TYPE_FACTORYRESET: backupType = "-FR-" imageSubBuild = "" - if getImageType() != "release": - imageSubBuild = ".%s" % getImageDevBuild() + if SystemInfo["imagetype"] != "release": + imageSubBuild = ".%s" % SystemInfo["imagedevbuild"] boxname = "" if config.backupmanager.showboxname.value: - boxname = "-" + getMachineMake() - self.Backupfile = self.BackupDirectory + config.backupmanager.folderprefix.value + boxname + "-" + getImageType()[0:3] + backupType + getImageVersion() + "." + getImageBuild() + imageSubBuild + "-" + backupdate.strftime("%Y%m%d-%H%M") + ".tar.gz" + boxname = "-" + SystemInfo["machinebuild"] + self.Backupfile = self.BackupDirectory + config.backupmanager.folderprefix.value + boxname + "-" + SystemInfo["imagetype"][0:3] + backupType + SystemInfo["imageversion"] + "." + SystemInfo["imagebuild"] + imageSubBuild + "-" + backupdate.strftime("%Y%m%d-%H%M") + ".tar.gz" with open(BackupFiles.tar_flist, "w") as tfl: # Need to create a list of what to backup, so that spaces and special characters don't get lost on, or mangle, the command line for fn in tmplist: tfl.write(fn + "\n") diff --git a/lib/python/Plugins/SystemPlugins/ViX/ImageManager.py b/lib/python/Plugins/SystemPlugins/ViX/ImageManager.py index 7f8e77897bc..e6b732514e5 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/ImageManager.py +++ b/lib/python/Plugins/SystemPlugins/ViX/ImageManager.py @@ -3,7 +3,6 @@ import json import tempfile -from boxbranding import getBoxType, getImageType, getImageDistro, getImageVersion, getImageBuild, getImageDevBuild, getImageFolder, getImageFileSystem, getBrandOEM, getMachineBrand, getMachineName, getMachineBuild, getMachineMake, getMachineMtdRoot, getMachineRootFile, getMachineMtdKernel, getMachineKernelFile, getMachineMKUBIFS, getMachineUBINIZE from enigma import eTimer, fbClass from os import path, stat, system, mkdir, makedirs, listdir, remove, rename, rmdir, sep as ossep, statvfs, chmod, walk from shutil import copy, copyfile, move, rmtree @@ -57,7 +56,7 @@ def __onPartitionChange(*args, **kwargs): config.imagemanager.backuplocation.setChoices(choices=choices, default=getMountDefault(choices)) -defaultprefix = getImageDistro() +defaultprefix = SystemInfo["distro"] config.imagemanager = ConfigSubsection() config.imagemanager.autosettingsbackup = ConfigYesNo(default=True) choices = getMountChoices() @@ -102,7 +101,7 @@ def __onPartitionChange(*args, **kwargs): rmtree(config.imagemanager.backuplocation.value + "imagebackups/imagerestore") except Exception: pass -TMPDIR = config.imagemanager.backuplocation.value + "imagebackups/" + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-mount" +TMPDIR = config.imagemanager.backuplocation.value + "imagebackups/" + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-mount" if path.exists(TMPDIR + "/root") and path.ismount(TMPDIR + "/root"): try: system("umount " + TMPDIR + "/root") @@ -329,9 +328,9 @@ def populate_List(self): try: if not path.exists(self.BackupDirectory): mkdir(self.BackupDirectory, 0o755) - if path.exists(self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup"): - system("swapoff " + self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup") - remove(self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup") + if path.exists(self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup"): + system("swapoff " + self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup") + remove(self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup") self.refreshList() except Exception: self["lab1"].setText(_("Device: ") + config.imagemanager.backuplocation.value + "\n" + _("There is a problem with this device. Please reformat it and try again.")) @@ -427,7 +426,7 @@ def getImages(files): def checkMachineNameInFilename(filename): return model in filename or "-" + device_name + "-" in filename - model = getMachineMake() + model = SystemInfo["machinebuild"] device_name = HardwareInfo().get_device_name() imagesFound = [] if config.imagemanager.extensive_location_search.value: @@ -503,9 +502,9 @@ def keyRestorez1(self, retval): def keyRestore1(self): self.HasSDmmc = False self.multibootslot = 1 - self.MTDKERNEL = getMachineMtdKernel() - self.MTDROOTFS = getMachineMtdRoot() - if getMachineMake() == "et8500" and path.exists("/proc/mtd"): + self.MTDKERNEL = SystemInfo["mtdkernel"] + self.MTDROOTFS = SystemInfo["mtdrootfs"] + if SystemInfo["machinebuild"] == "et8500" and path.exists("/proc/mtd"): self.dualboot = self.dualBoot() recordings = self.session.nav.getRecordings() if not recordings: @@ -540,7 +539,7 @@ def keyRestore2(self, retval): else: self.MTDROOTFS = SystemInfo["canMultiBoot"][self.multibootslot]["root"].split("/")[2] if SystemInfo["HasHiSi"] and SystemInfo["MultiBootSlot"] > 4 and self.multibootslot < 4: - self.session.open(MessageBox, _("ImageManager - %s - cannot flash eMMC slot from sd card slot.") % getBoxType(), MessageBox.TYPE_INFO, timeout=10) + self.session.open(MessageBox, _("ImageManager - %s - cannot flash eMMC slot from sd card slot.") % SystemInfo["boxtype"], MessageBox.TYPE_INFO, timeout=10) return if self.sel: if SystemInfo["MultiBootSlot"] != 0 and config.imagemanager.autosettingsbackup.value: @@ -568,12 +567,12 @@ def keyRestore3(self, *args, **kwargs): def keyRestore4(self, result, retval, extra_args=None): if retval == 0: self.session.openWithCallback(self.restore_infobox.close, MessageBox, _("Flash image unzip successful."), MessageBox.TYPE_INFO, timeout=4) - if getMachineMake() == "et8500" and self.dualboot: + if SystemInfo["machinebuild"] == "et8500" and self.dualboot: message = _("ET8500 Multiboot: Yes to restore OS1 No to restore OS2:\n ") + self.sel[1] ybox = self.session.openWithCallback(self.keyRestore5_ET8500, MessageBox, message) ybox.setTitle(_("ET8500 Image Restore")) else: - MAINDEST = "%s/%s" % (self.TEMPDESTROOT, getImageFolder()) + MAINDEST = "%s/%s" % (self.TEMPDESTROOT, SystemInfo["imagedir"]) if pathExists("%s/SDAbackup" % MAINDEST) and self.multibootslot != 1: self.session.open(MessageBox, _("Multiboot only able to restore this backup to mmc slot1"), MessageBox.TYPE_INFO, timeout=20) print("[ImageManager] SF8008 mmc restore to SDcard failed:\n", end=' ') @@ -592,14 +591,14 @@ def keyRestore5_ET8500(self, answer): self.keyRestore6(1) def keyRestore6(self, ret): - MAINDEST = "%s/%s" % (self.TEMPDESTROOT, getImageFolder()) + MAINDEST = "%s/%s" % (self.TEMPDESTROOT, SystemInfo["imagedir"]) print("[ImageManager] MAINDEST=%s" % MAINDEST) if ret == 0: CMD = "/usr/bin/ofgwrite -r -k '%s'" % MAINDEST # normal non multiboot receiver if SystemInfo["canMultiBoot"]: if self.multibootslot == 0 and SystemInfo["HasKexecMultiboot"]: # reset Vu Multiboot slot0 - kz0 = getMachineMtdKernel() - rz0 = getMachineMtdRoot() + kz0 = SystemInfo["mtdkernel"] + rz0 = SystemInfo["mtdrootfs"] CMD = "/usr/bin/ofgwrite -k%s -r%s '%s'" % (kz0, rz0, MAINDEST) # slot0 treat as kernel/root only multiboot receiver elif SystemInfo["HasHiSi"] and SystemInfo["canMultiBoot"][self.multibootslot]["rootsubdir"] is None: # sf8008 type receiver using SD card in multiboot CMD = "/usr/bin/ofgwrite -r%s -k%s -m0 '%s'" % (self.MTDROOTFS, self.MTDKERNEL, MAINDEST) @@ -608,7 +607,7 @@ def keyRestore6(self, ret): copyfile("/boot/STARTUP_%s" % self.multibootslot, "/boot/STARTUP") elif SystemInfo["HasKexecMultiboot"]: if SystemInfo["HasKexecUSB"] and "mmcblk" not in self.MTDROOTFS: - CMD = "/usr/bin/ofgwrite -r%s -kzImage -s'%s/linuxrootfs' -m%s '%s'" % (self.MTDROOTFS, getBoxType()[2:], self.multibootslot, MAINDEST) + CMD = "/usr/bin/ofgwrite -r%s -kzImage -s'%s/linuxrootfs' -m%s '%s'" % (self.MTDROOTFS, SystemInfo["boxtype"][2:], self.multibootslot, MAINDEST) else: CMD = "/usr/bin/ofgwrite -r%s -kzImage -m%s '%s'" % (self.MTDROOTFS, self.multibootslot, MAINDEST) print("[ImageManager] running commnd:%s slot = %s" % (CMD, self.multibootslot)) @@ -691,13 +690,13 @@ def VuKexecCopyimage(self): installedHDD = True break if installedHDD and pathExists("/media/hdd"): - if not pathExists("/media/hdd/%s" % getBoxType()): - mkdir("/media/hdd/%s" % getBoxType()) + if not pathExists("/media/hdd/%s" % SystemInfo["boxtype"]): + mkdir("/media/hdd/%s" % SystemInfo["boxtype"]) for slotnum in range(1, 4): if pathExists("/linuxrootfs%s" % slotnum): - if pathExists("/media/hdd/%s/linuxrootfs%s/" % (getBoxType(), slotnum)): - rmtree("/media/hdd/%s/linuxrootfs%s" % (getBoxType(), slotnum), ignore_errors=True) - Console().ePopen("cp -R /linuxrootfs%s . /media/hdd/%s/" % (slotnum, getBoxType())) + if pathExists("/media/hdd/%s/linuxrootfs%s/" % (SystemInfo["boxtype"], slotnum)): + rmtree("/media/hdd/%s/linuxrootfs%s" % (SystemInfo["boxtype"], slotnum), ignore_errors=True) + Console().ePopen("cp -R /linuxrootfs%s . /media/hdd/%s/" % (slotnum, SystemInfo["boxtype"])) if not installedHDD: self.session.open(MessageBox, _("ImageManager - no HDD unable to backup Vu Multiboot eMMC slots"), MessageBox.TYPE_INFO, timeout=5) self.multibootslot = 0 # set slot0 to be flashed @@ -817,7 +816,7 @@ def BackuponTimer(self): from Screens.Standby import inStandby if not inStandby and config.imagemanager.query.value: - message = _("Your %s %s is about to create a full image backup, this can take about 6 minutes to complete.\nDo you want to allow this?") % (getMachineBrand(), getMachineName()) + message = _("Your %s %s is about to create a full image backup, this can take about 6 minutes to complete.\nDo you want to allow this?") % (SystemInfo["displaybrand"], SystemInfo["machinename"]) ybox = self.session.openWithCallback(self.doBackup, MessageBox, message, MessageBox.TYPE_YESNO, timeout=30) ybox.setTitle("Scheduled backup.") else: @@ -903,28 +902,28 @@ def __init__(self, session, updatebackup=False): self.BackupDirectory = config.imagemanager.backuplocation.value + "imagebackups/" print("[ImageManager] Directory: " + self.BackupDirectory) self.BackupDate = strftime("%Y%m%d_%H%M%S", localtime()) - self.WORKDIR = self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-temp" - self.TMPDIR = self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-mount" + self.WORKDIR = self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-temp" + self.TMPDIR = self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-mount" backupType = "-" if updatebackup: backupType = "-SoftwareUpdate-" imageSubBuild = "" - if getImageType() != "release": - imageSubBuild = ".%s" % getImageDevBuild() - self.MAINDESTROOT = self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + backupType + getImageVersion() + "." + getImageBuild() + imageSubBuild + "-" + self.BackupDate - self.KERNELFILE = getMachineKernelFile() - self.ROOTFSFILE = getMachineRootFile() - self.MAINDEST = self.MAINDESTROOT + "/" + getImageFolder() + "/" + if SystemInfo["imagetype"] != "release": + imageSubBuild = ".%s" % SystemInfo["imagedevbuild"] + self.MAINDESTROOT = self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + backupType + SystemInfo["imageversion"] + "." + SystemInfo["imagebuild"] + imageSubBuild + "-" + self.BackupDate + self.KERNELFILE = SystemInfo["kernelfile"] + self.ROOTFSFILE = SystemInfo["rootfile"] + self.MAINDEST = self.MAINDESTROOT + "/" + SystemInfo["imagedir"] + "/" self.MAINDEST2 = self.MAINDESTROOT + "/" - self.MODEL = getMachineMake() - self.MCBUILD = getMachineBuild() - self.IMAGEDISTRO = getImageDistro() - self.DISTROVERSION = getImageVersion() - self.DISTROBUILD = getImageBuild() - self.KERNELBIN = getMachineKernelFile() - self.UBINIZE_ARGS = getMachineUBINIZE() - self.MKUBIFS_ARGS = getMachineMKUBIFS() - self.ROOTFSTYPE = getImageFileSystem().strip() + self.MODEL = SystemInfo["machinebuild"] + self.MCBUILD = SystemInfo["model"] + self.IMAGEDISTRO = SystemInfo["distro"] + self.DISTROVERSION = SystemInfo["imageversion"] + self.DISTROBUILD = SystemInfo["imagebuild"] + self.KERNELBIN = SystemInfo["kernelfile"] + self.UBINIZE_ARGS = SystemInfo["ubinize"] + self.MKUBIFS_ARGS = SystemInfo["mkubifs"] + self.ROOTFSTYPE = SystemInfo["imagefs"].strip() self.ROOTFSSUBDIR = "none" self.VuSlot0 = "" self.EMMCIMG = "none" @@ -938,8 +937,8 @@ def __init__(self, session, updatebackup=False): slot = SystemInfo["MultiBootSlot"] print("[ImageManager] slot: ", slot) if SystemInfo["HasKexecMultiboot"]: - self.MTDKERNEL = getMachineMtdKernel() if slot == 0 else SystemInfo["canMultiBoot"][slot]["kernel"] - self.MTDROOTFS = getMachineMtdRoot() if slot == 0 else SystemInfo["canMultiBoot"][slot]["root"].split("/")[2] + self.MTDKERNEL = SystemInfo["mtdkernel"] if slot == 0 else SystemInfo["canMultiBoot"][slot]["kernel"] + self.MTDROOTFS = SystemInfo["mtdrootfs"] if slot == 0 else SystemInfo["canMultiBoot"][slot]["root"].split("/")[2] self.VuSlot0 = "-VuSlot0" if slot == 0 else "" else: self.MTDKERNEL = SystemInfo["canMultiBoot"][slot]["kernel"].split("/")[2] @@ -950,9 +949,9 @@ def __init__(self, session, updatebackup=False): if SystemInfo["HasRootSubdir"] and slot != 0: self.ROOTFSSUBDIR = SystemInfo["canMultiBoot"][slot]["rootsubdir"] else: - self.MTDKERNEL = getMachineMtdKernel() - self.MTDROOTFS = getMachineMtdRoot() - if getMachineBuild() in ("gb7252", "gbx34k"): + self.MTDKERNEL = SystemInfo["mtdkernel"] + self.MTDROOTFS = SystemInfo["mtdrootfs"] + if SystemInfo["model"] in ("gb7252", "gbx34k"): self.GB4Kbin = "boot.bin" self.GB4Krescue = "rescue.bin" if "sda" in self.MTDKERNEL: @@ -1056,9 +1055,9 @@ def JobStart(self): try: if not path.exists(self.BackupDirectory): mkdir(self.BackupDirectory, 0o755) - if path.exists(self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup"): - system("swapoff " + self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup") - remove(self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup") + if path.exists(self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup"): + system("swapoff " + self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup") + remove(self.BackupDirectory + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup") except Exception as e: print(str(e)) print("[ImageManager] Device: " + config.imagemanager.backuplocation.value + ", i don't seem to have write access to this device.") @@ -1117,15 +1116,15 @@ def MemCheck(self): self.SwapCreated = True def MemCheck2(self): - self.ConsoleB.ePopen("dd if=/dev/zero of=" + self.swapdevice + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup bs=1024 count=61440", self.MemCheck3) + self.ConsoleB.ePopen("dd if=/dev/zero of=" + self.swapdevice + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup bs=1024 count=61440", self.MemCheck3) def MemCheck3(self, result, retval, extra_args=None): if retval == 0: - self.ConsoleB.ePopen("mkswap " + self.swapdevice + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup", self.MemCheck4) + self.ConsoleB.ePopen("mkswap " + self.swapdevice + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup", self.MemCheck4) def MemCheck4(self, result, retval, extra_args=None): if retval == 0: - self.ConsoleB.ePopen("swapon " + self.swapdevice + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup", self.MemCheck5) + self.ConsoleB.ePopen("swapon " + self.swapdevice + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup", self.MemCheck5) def MemCheck5(self, result, retval, extra_args=None): self.SwapCreated = True @@ -1172,7 +1171,7 @@ def doBackup2(self): if "jffs2" in self.ROOTFSTYPE.split(): print("[ImageManager] Stage2: JFFS2 Detected.") self.ROOTFSTYPE = "jffs2" - if getMachineBuild() == "gb800solo": + if SystemInfo["model"] == "gb800solo": JFFS2OPTIONS = " --disable-compressor=lzo -e131072 -l -p125829120" else: JFFS2OPTIONS = " --disable-compressor=lzo --eraseblock=0x20000 -n -l" @@ -1191,7 +1190,7 @@ def doBackup2(self): output.write("vol_flags=autoresize\n") self.commands.append("mount -o bind,ro / %s/root" % self.TMPDIR) - if getMachineBuild() in ("h9", "i55plus"): + if SystemInfo["model"] in ("h9", "i55plus"): with open("/proc/cmdline", "r") as z: if SystemInfo["HasMMC"] and "root=/dev/mmcblk0p1" in z.read(): self.ROOTFSTYPE = "tar.bz2" @@ -1214,7 +1213,7 @@ def doBackup2(self): self.commands.append('echo "' + _("Create:") + " logo dump" + '"') self.commands.append("dd if=/dev/mtd4 of=%s/logo.bin" % self.WORKDIR) else: - if not getMachineBuild() in ("h8"): + if not SystemInfo["model"] in ("h8"): self.MKUBIFS_ARGS = "-m 2048 -e 126976 -c 4096 -F" self.UBINIZE_ARGS = "-m 2048 -p 128KiB" self.commands.append("touch %s/root.ubi" % self.WORKDIR) @@ -1237,7 +1236,7 @@ def doBackup2(self): else: self.commands.append("/bin/tar -jcf %s/rootfs.tar.bz2 -C %s/root --exclude ./var/nmbd --exclude ./.resizerootfs --exclude ./.resize-rootfs --exclude ./.resize-linuxrootfs --exclude ./.resize-userdata --exclude ./var/lib/samba/private/msg.sock ." % (self.WORKDIR, self.TMPDIR)) self.commands.append("sync") - if getMachineBuild() in ("gb7252", "gbx34k"): + if SystemInfo["model"] in ("gb7252", "gbx34k"): self.commands.append("dd if=/dev/mmcblk0p1 of=%s/boot.bin" % self.WORKDIR) self.commands.append("dd if=/dev/mmcblk0p3 of=%s/rescue.bin" % self.WORKDIR) print("[ImageManager] Stage2: Create: boot dump boot.bin:", self.MODEL) @@ -1436,7 +1435,7 @@ def doBackup5(self): else: move("%s/vmlinux.gz" % self.WORKDIR, "%s/%s" % (self.MAINDEST, self.KERNELFILE)) self.h9root = False - if getMachineBuild() in ("h9", "i55plus"): + if SystemInfo["model"] in ("h9", "i55plus"): system("mv %s/fastboot.bin %s/fastboot.bin" % (self.WORKDIR, self.MAINDEST)) system("mv %s/bootargs.bin %s/bootargs.bin" % (self.WORKDIR, self.MAINDEST)) system("mv %s/pq_param.bin %s/pq_param.bin" % (self.WORKDIR, self.MAINDEST)) @@ -1454,18 +1453,18 @@ def doBackup5(self): else: move("%s/rootfs.%s" % (self.WORKDIR, self.ROOTFSTYPE), "%s/%s" % (self.MAINDEST, self.ROOTFSFILE)) - if getMachineBuild() in ("gb7252", "gbx34k"): + if SystemInfo["model"] in ("gb7252", "gbx34k"): move("%s/%s" % (self.WORKDIR, self.GB4Kbin), "%s/%s" % (self.MAINDEST, self.GB4Kbin)) move("%s/%s" % (self.WORKDIR, self.GB4Krescue), "%s/%s" % (self.MAINDEST, self.GB4Krescue)) system("cp -f /usr/share/gpt.bin %s/gpt.bin" % self.MAINDEST) print("[ImageManager] Stage5: Create: gpt.bin:", self.MODEL) with open(self.MAINDEST + "/imageversion", "w") as fileout: - line = defaultprefix + "-" + getMachineMake() + "-" + getImageType() + "-backup-" + getImageVersion() + "." + getImageBuild() + "-" + self.BackupDate + line = defaultprefix + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-backup-" + SystemInfo["imageversion"] + "." + SystemInfo["imagebuild"] + "-" + self.BackupDate fileout.write(line) - if getBrandOEM() == "vuplus": - if getMachineBuild() == "vuzero": + if SystemInfo["brand"] == "vuplus": + if SystemInfo["model"] == "vuzero": with open(self.MAINDEST + "/force.update", "w") as fileout: line = "This file forces the update." fileout.write(line) @@ -1474,8 +1473,8 @@ def doBackup5(self): with open(self.MAINDEST + "/reboot.update", "w") as fileout: line = "This file forces a reboot after the update." fileout.write(line) - elif getBrandOEM() in ("xtrend", "gigablue", "octagon", "odin", "xp", "ini"): - if getBrandOEM() in ("xtrend", "octagon", "odin", "ini"): + elif SystemInfo["brand"] in ("xtrend", "gigablue", "octagon", "odin", "xp", "ini"): + if SystemInfo["brand"] in ("xtrend", "octagon", "odin", "ini"): with open(self.MAINDEST + "/noforce", "w") as fileout: line = "rename this file to 'force' to force an update without confirmation" fileout.write(line) @@ -1497,12 +1496,12 @@ def doBackup5(self): fileout.write(line1) print("[ImageManager] Stage5: Removing Swap.") - if path.exists(self.swapdevice + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup"): - system("swapoff " + self.swapdevice + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup") - remove(self.swapdevice + config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-" + getImageType() + "-swapfile_backup") + if path.exists(self.swapdevice + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup"): + system("swapoff " + self.swapdevice + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup") + remove(self.swapdevice + config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-" + SystemInfo["imagetype"] + "-swapfile_backup") if path.exists(self.WORKDIR): rmtree(self.WORKDIR) - if (path.exists(self.MAINDEST + "/" + self.ROOTFSFILE) and path.exists(self.MAINDEST + "/" + self.KERNELFILE)) or (getMachineBuild() in ("h9", "i55plus") and self.h9root): + if (path.exists(self.MAINDEST + "/" + self.ROOTFSFILE) and path.exists(self.MAINDEST + "/" + self.KERNELFILE)) or (SystemInfo["model"] in ("h9", "i55plus") and self.h9root): for root, dirs, files in walk(self.MAINDEST): for momo in dirs: chmod(path.join(root, momo), 0o644) @@ -1537,7 +1536,7 @@ def BackupComplete(self, answer=None): try: if config.imagemanager.number_to_keep.value > 0 and path.exists(self.BackupDirectory): # !?! images = listdir(self.BackupDirectory) - patt = config.imagemanager.folderprefix.value + "-" + getMachineMake() + "-*.zip" + patt = config.imagemanager.folderprefix.value + "-" + SystemInfo["machinebuild"] + "-*.zip" emlist = [] for fil in images: if fnmatch.fnmatchcase(fil, patt): @@ -1595,7 +1594,7 @@ def __init__(self, session, BackupDirectory, imagefeed): self.setTitle(_("%s downloads") % imagefeed[DISTRO]) self.imagefeed = imagefeed self.BackupDirectory = BackupDirectory - self["lab1"] = Label(_("Select an image to download for %s:") % getMachineMake()) + self["lab1"] = Label(_("Select an image to download for %s:") % SystemInfo["machinebuild"]) self["key_red"] = Button(_("Close")) self["key_green"] = Button(_("Download")) self["ImageDown"] = ActionMap(["OkCancelActions", "ColorActions", "DirectionActions", "KeyboardInputActions", "MenuActions"], { @@ -1617,7 +1616,7 @@ def __init__(self, session, BackupDirectory, imagefeed): self.setIndex = 0 self.expanded = [] self["list"] = ChoiceList(list=[ChoiceEntryComponent("", ((_("No images found on the selected download server...if password check validity")), "Waiter"))]) - self.getImageDistro() + self.SystemInfo["distro"] def showError(self): self.session.open(MessageBox, self.msg, MessageBox.TYPE_ERROR) @@ -1634,12 +1633,12 @@ def getImageDistro(self): self.pausetimer.callback.append(self.showError) self.pausetimer.start(50, True) return - boxtype = getMachineMake() + boxtype = SystemInfo["machinebuild"] if self.imagefeed[ACTION] == "HardwareInfo": boxtype = HardwareInfo().get_device_name() print("[ImageManager1] boxtype:%s" % (boxtype)) if "dm800" in boxtype: - boxtype = getMachineMake() + boxtype = SystemInfo["machinebuild"] if not self.imagesList: # Legacy: self.imagefeed[URL] didn't contain "%s" where to insert the boxname. @@ -1724,7 +1723,7 @@ def keyDownload(self): self.expanded.remove(currentSelected[0][0]) else: self.expanded.append(currentSelected[0][0]) - self.getImageDistro() + self.SystemInfo["distro"] elif currentSelected[0][1] != "Waiter": self.sel = currentSelected[0][0] diff --git a/lib/python/Plugins/SystemPlugins/ViX/MountManager.py b/lib/python/Plugins/SystemPlugins/ViX/MountManager.py index 011b79328a8..9006fe4364a 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/MountManager.py +++ b/lib/python/Plugins/SystemPlugins/ViX/MountManager.py @@ -2,7 +2,6 @@ from os import mkdir, path, rename, statvfs, system import re -from boxbranding import getMachineBrand, getMachineName # , getMachineBuild from enigma import eTimer from Components.ActionMap import ActionMap @@ -398,7 +397,7 @@ def __init__(self, session): self.setconfTimer() def setconfTimer(self, result=None, retval=None, extra_args=None): - scanning = _("Please wait while scanning your %s %s devices...") % (getMachineBrand(), getMachineName()) + scanning = _("Please wait while scanning your %s %s devices...") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) self["lab1"].setText(scanning) self.activityTimer.start(10) @@ -424,9 +423,9 @@ def saveconfMounts(self): ybox.setTitle(_("Please wait.")) def delay(self, val): - message = _("The changes need a system restart to take effect.\nRestart your %s %s now?") % (getMachineBrand(), getMachineName()) + message = _("The changes need a system restart to take effect.\nRestart your %s %s now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) ybox = self.session.openWithCallback(self.restartBox, MessageBox, message, MessageBox.TYPE_YESNO) - ybox.setTitle(_("Restart %s %s.") % (getMachineBrand(), getMachineName())) + ybox.setTitle(_("Restart %s %s.") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"])) def addconfFstab(self, result=None, retval=None, extra_args=None): # print("[MountManager] RESULT:", result) diff --git a/lib/python/Plugins/SystemPlugins/ViX/RestoreWizard.py b/lib/python/Plugins/SystemPlugins/ViX/RestoreWizard.py index 864746f3b0b..3cfb1175555 100644 --- a/lib/python/Plugins/SystemPlugins/ViX/RestoreWizard.py +++ b/lib/python/Plugins/SystemPlugins/ViX/RestoreWizard.py @@ -1,5 +1,4 @@ from os import listdir, path, stat -from boxbranding import getMachineBrand, getMachineName, getImageDistro from .BackupManager import isRestorableSettings, isRestorablePlugins, isRestorableKernel from Components.About import about @@ -36,14 +35,14 @@ def __init__(self, session): self.Console = Console() def getTranslation(self, text): - return _(text).replace("%s %s", "%s %s" % (getMachineBrand(), getMachineName())) + return _(text).replace("%s %s", "%s %s" % (SystemInfo["MachineBrand"], SystemInfo["MachineName"])) def listDevices(self): devmounts = [] list = [] files = [] mtimes = [] - defaultprefix = getImageDistro()[4:] + defaultprefix = SystemInfo["distro"][4:] for dir in ["/media/%s/backup" % media for media in listdir("/media/") if path.isdir(path.join("/media/", media))]: # noqa: F821 devmounts.append(dir) @@ -160,7 +159,7 @@ def buildList(self, action): print("[RestoreWizard] Stage 6: No Network") self.didPluginRestore = True self.NextStep = "reboot" - self.buildListRef = self.session.openWithCallback(self.buildListfinishedCB, MessageBox, _("Your %s %s is not connected to the Internet. Please try using Backup manager to restore plugins later.") % (getMachineBrand(), getMachineName()), type=MessageBox.TYPE_INFO, timeout=30, wizard=True) + self.buildListRef = self.session.openWithCallback(self.buildListfinishedCB, MessageBox, _("Your %s %s is not connected to the Internet. Please try using Backup manager to restore plugins later.") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), type=MessageBox.TYPE_INFO, timeout=30, wizard=True) self.buildListRef.setTitle(_("Restore wizard")) elif self.feeds == "ERROR": self.NextStep = "pluginrestore" @@ -259,15 +258,15 @@ def doRestorePluginsTestComplete(self, result='', retval=None, extra_args=None): print("[RestoreWizard] Stage 4: Feeds Test Result", result) if result.find("wget returned 4") != -1: self.NextStep = "reboot" - self.buildListRef = self.session.openWithCallback(self.buildListfinishedCB, MessageBox, _("Your %s %s is not connected to a network. Please try using the Backup manager to restore plugins later when a network connection is available.") % (getMachineBrand(), getMachineName()), type=MessageBox.TYPE_INFO, timeout=30, wizard=True) + self.buildListRef = self.session.openWithCallback(self.buildListfinishedCB, MessageBox, _("Your %s %s is not connected to a network. Please try using the Backup manager to restore plugins later when a network connection is available.") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), type=MessageBox.TYPE_INFO, timeout=30, wizard=True) self.buildListRef.setTitle(_("Restore wizard")) elif result.find("wget returned 8") != -1: self.NextStep = "reboot" - self.buildListRef = self.session.openWithCallback(self.buildListfinishedCB, MessageBox, _("Your %s %s could not connect to the plugin feeds at this time. Please try using the Backup manager to restore plugins later.") % (getMachineBrand(), getMachineName()), type=MessageBox.TYPE_INFO, timeout=30, wizard=True) + self.buildListRef = self.session.openWithCallback(self.buildListfinishedCB, MessageBox, _("Your %s %s could not connect to the plugin feeds at this time. Please try using the Backup manager to restore plugins later.") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), type=MessageBox.TYPE_INFO, timeout=30, wizard=True) self.buildListRef.setTitle(_("Restore wizard")) elif result.find("bad address") != -1: self.NextStep = "reboot" - self.buildListRef = self.session.openWithCallback(self.buildListfinishedCB, MessageBox, _("Your %s %s is not connected to the Internet. Please try using the Backup manager to restore plugins later.") % (getMachineBrand(), getMachineName()), type=MessageBox.TYPE_INFO, timeout=30, wizard=True) + self.buildListRef = self.session.openWithCallback(self.buildListfinishedCB, MessageBox, _("Your %s %s is not connected to the Internet. Please try using the Backup manager to restore plugins later.") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), type=MessageBox.TYPE_INFO, timeout=30, wizard=True) self.buildListRef.setTitle(_("Restore wizard")) elif result.find("wget returned 1") != -1 or result.find("wget returned 255") != -1 or result.find("404 Not Found") != -1: self.NextStep = "reboot" diff --git a/lib/python/PowerTimer.py b/lib/python/PowerTimer.py index b00c7d55227..2bab472a8ec 100644 --- a/lib/python/PowerTimer.py +++ b/lib/python/PowerTimer.py @@ -3,11 +3,11 @@ from time import ctime, time from timer import Timer, TimerEntry -from boxbranding import getMachineBrand, getMachineName from enigma import eActionMap, quitMainloop from Components.config import config from Components.Harddisk import internalHDDNotSleeping +from Components.SystemInfo import SystemInfo from Components.TimerSanityCheck import TimerSanityCheck from Screens.MessageBox import MessageBox import Screens.Standby @@ -164,7 +164,7 @@ def activate(self): elif self.timerType == TIMERTYPE.STANDBY: if not Screens.Standby.inStandby: # not already in standby - Notifications.AddNotificationWithUniqueIDCallback(self.sendStandbyNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to set your\n%s %s to standby. Do that now?") % (getMachineBrand(), getMachineName()), timeout=180) + Notifications.AddNotificationWithUniqueIDCallback(self.sendStandbyNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to set your\n%s %s to standby. Do that now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), timeout=180) return True elif self.timerType == TIMERTYPE.AUTOSTANDBY: @@ -173,7 +173,7 @@ def activate(self): # retry return False if not Screens.Standby.inStandby: # not already in standby - Notifications.AddNotificationWithUniqueIDCallback(self.sendStandbyNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to set your\n%s %s to standby. Do that now?") % (getMachineBrand(), getMachineName()), timeout=180) + Notifications.AddNotificationWithUniqueIDCallback(self.sendStandbyNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to set your\n%s %s to standby. Do that now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), timeout=180) if self.autosleeprepeat == "once": eActionMap.getInstance().unbindAction('', self.keyPressed) return True @@ -213,7 +213,7 @@ def activate(self): quitMainloop(1) return True else: - Notifications.AddNotificationWithUniqueIDCallback(self.sendTryQuitMainloopNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to shutdown your %s %s.\nDo that now?") % (getMachineBrand(), getMachineName()), timeout=180) + Notifications.AddNotificationWithUniqueIDCallback(self.sendTryQuitMainloopNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to shutdown your %s %s.\nDo that now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), timeout=180) if self.autosleeprepeat == "once": eActionMap.getInstance().unbindAction('', self.keyPressed) return True @@ -234,7 +234,7 @@ def activate(self): if Screens.Standby.inStandby: # in standby quitMainloop(1) else: - Notifications.AddNotificationWithUniqueIDCallback(self.sendTryQuitMainloopNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to shutdown your %s %s.\nDo that now?") % (getMachineBrand(), getMachineName()), timeout=180) + Notifications.AddNotificationWithUniqueIDCallback(self.sendTryQuitMainloopNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to shutdown your %s %s.\nDo that now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), timeout=180) return True elif self.timerType == TIMERTYPE.REBOOT: @@ -246,7 +246,7 @@ def activate(self): if Screens.Standby.inStandby: # in standby quitMainloop(2) else: - Notifications.AddNotificationWithUniqueIDCallback(self.sendTryToRebootNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to reboot your %s %s.\nDo that now?") % (getMachineBrand(), getMachineName()), timeout=180) + Notifications.AddNotificationWithUniqueIDCallback(self.sendTryToRebootNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to reboot your %s %s.\nDo that now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), timeout=180) return True elif self.timerType == TIMERTYPE.RESTART: @@ -265,7 +265,7 @@ def activate(self): NavigationInstance.instance.PowerTimer.saveTimer() if self.afterEvent == AFTEREVENT.STANDBY: if not Screens.Standby.inStandby: # not already in standby - Notifications.AddNotificationWithUniqueIDCallback(self.sendStandbyNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to set your\n%s %s to standby. Do that now?") % (getMachineBrand(), getMachineName()), timeout=180) + Notifications.AddNotificationWithUniqueIDCallback(self.sendStandbyNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to set your\n%s %s to standby. Do that now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), timeout=180) elif self.afterEvent == AFTEREVENT.DEEPSTANDBY: if NavigationInstance.instance.RecordTimer.isRecording() or abs(NavigationInstance.instance.RecordTimer.getNextRecordingTime() - time()) <= 900 or abs(NavigationInstance.instance.RecordTimer.getNextZapTime() - time()) <= 900: self.do_backoff() @@ -275,7 +275,7 @@ def activate(self): if Screens.Standby.inStandby: # in standby quitMainloop(1) else: - Notifications.AddNotificationWithUniqueIDCallback(self.sendTryQuitMainloopNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to shutdown your %s %s.\nDo that now?") % (getMachineBrand(), getMachineName()), timeout=180) + Notifications.AddNotificationWithUniqueIDCallback(self.sendTryQuitMainloopNotification, "PT_StateChange", MessageBox, _("A finished powertimer wants to shutdown your %s %s.\nDo that now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), timeout=180) return True def setAutoincreaseEnd(self, entry=None): diff --git a/lib/python/RecordTimer.py b/lib/python/RecordTimer.py index a47b237a260..5dd8ee5099b 100644 --- a/lib/python/RecordTimer.py +++ b/lib/python/RecordTimer.py @@ -5,7 +5,6 @@ from time import localtime, strftime, ctime, time from enigma import eEPGCache, getBestPlayableServiceReference, eStreamServer, eServiceReference, iRecordableService, quitMainloop, eActionMap, setPreferredTuner, eServiceCenter -from boxbranding import getMachineBrand, getMachineName, getBoxType from Components.config import config import Components.ParentalControl from Components.UsageConfig import defaultMoviePath @@ -113,7 +112,7 @@ def findSafeRecordPath(dirname): "mbtwin": ("/proc/stb/lcd/symbol_circle", 4) } -SID_code_states = SID_symbol_states.setdefault(getBoxType(), (None, 0)) +SID_code_states = SID_symbol_states.setdefault(SystemInfo["boxtype"], (None, 0)) n_recordings = 0 # Must be when we start running... @@ -737,7 +736,7 @@ def activate(self): if self.afterEvent == AFTEREVENT.STANDBY or (not wasRecTimerWakeup and self.autostate and self.afterEvent == AFTEREVENT.AUTO) or self.wasInStandby: self.keypress() # this unbinds the keypress detection if not Screens.Standby.inStandby: # not already in standby - Notifications.AddNotificationWithCallback(self.sendStandbyNotification, MessageBox, _("A finished record timer wants to set your\n%s %s to standby. Do that now?") % (getMachineBrand(), getMachineName()), timeout=180) + Notifications.AddNotificationWithCallback(self.sendStandbyNotification, MessageBox, _("A finished record timer wants to set your\n%s %s to standby. Do that now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), timeout=180) elif self.afterEvent == AFTEREVENT.DEEPSTANDBY or (wasRecTimerWakeup and self.afterEvent == AFTEREVENT.AUTO and Screens.Standby.inStandby): if (abs(NavigationInstance.instance.RecordTimer.getNextRecordingTime() - time()) <= 900 or abs(NavigationInstance.instance.RecordTimer.getNextZapTime() - time()) <= 900) or NavigationInstance.instance.RecordTimer.getStillRecording(): print("[RecordTimer] Recording or Recording due is next 15 mins, not return to deepstandby") @@ -752,7 +751,7 @@ def activate(self): if int(ClientsStreaming("NUMBER").getText()) > 0: if not Screens.Standby.inStandby: # not already in standby Notifications.AddNotificationWithCallback(self.sendStandbyNotification, MessageBox, - _("A finished record timer wants to set your\n%s %s to standby. Do that now?") % (getMachineBrand(), getMachineName()) + _("A finished record timer wants to set your\n%s %s to standby. Do that now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) + _("\n(DeepStandby request changed to Standby owing to there being streaming clients.)"), timeout=180) return True @@ -760,7 +759,7 @@ def activate(self): if Screens.Standby.inStandby: # in standby quitMainloop(1) else: - Notifications.AddNotificationWithCallback(self.sendTryQuitMainloopNotification, MessageBox, _("A finished record timer wants to shut down\nyour %s %s. Shutdown now?") % (getMachineBrand(), getMachineName()), timeout=180) + Notifications.AddNotificationWithCallback(self.sendTryQuitMainloopNotification, MessageBox, _("A finished record timer wants to shut down\nyour %s %s. Shutdown now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), timeout=180) return True def keypress(self, key=None, flag=1): diff --git a/lib/python/Screens/About.py b/lib/python/Screens/About.py index a8ea1903dff..3401bd80f15 100644 --- a/lib/python/Screens/About.py +++ b/lib/python/Screens/About.py @@ -1,7 +1,6 @@ from os import listdir, path, popen from re import search from enigma import eTimer, getDesktop -from boxbranding import getMachineBrand, getMachineName, getImageVersion, getImageType, getImageBuild, getImageDevBuild from Components.About import about from Components.ActionMap import ActionMap from Components.Button import Button @@ -12,7 +11,7 @@ from Components.NimManager import nimmanager from Components.Pixmap import MultiPixmap from Components.Sources.StaticText import StaticText -from Components.SystemInfo import SystemInfo, BoxInfo +from Components.SystemInfo import SystemInfo from Screens.GitCommitInfo import CommitInfo from Screens.Screen import Screen, ScreenSummary from Screens.SoftwareUpdate import UpdatePlugin @@ -55,7 +54,7 @@ def __init__(self, session): def populate(self): AboutText = "" - AboutText += _("Model:\t%s %s\n") % (getMachineBrand(), getMachineName()) + AboutText += _("Model:\t%s %s\n") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) if about.getChipSetString() != _("unavailable"): if SystemInfo["HasHiSi"]: @@ -67,7 +66,7 @@ def populate(self): AboutText += _("CPU:\t%s %s %s\n") % (about.getCPUArch(), about.getCPUSpeedString(), about.getCpuCoresString()) - AboutText += _("SoC:\t%s\n") % BoxInfo.getItem("socfamily").upper() + AboutText += _("SoC:\t%s\n") % SystemInfo["socfamily"].upper() tempinfo = "" if path.exists("/proc/stb/sensors/temp0/value"): @@ -102,16 +101,16 @@ def populate(self): AboutText += _("Processor temp:\t%s") % tempinfo.replace("\n", "").replace(" ", "") + "\xb0" + "C\n" imageSubBuild = "" - if getImageType() != "release": - imageSubBuild = ".%s" % getImageDevBuild() - AboutText += _("Image:\t%s.%s%s (%s)\n") % (getImageVersion(), getImageBuild(), imageSubBuild, getImageType().title()) + if SystemInfo["imagetype"] != "release": + imageSubBuild = ".%s" % SystemInfo["imagedevbuild"] + AboutText += _("Image:\t%s.%s%s (%s)\n") % (SystemInfo["imageversion"], SystemInfo["imagebuild"], imageSubBuild, SystemInfo["imagetype"].title()) VuPlustxt = "Vu+ Multiboot - " if SystemInfo["HasKexecMultiboot"] else "" if fileHas("/proc/cmdline", "rootsubdir=linuxrootfs0"): AboutText += _("Boot Device: \tRecovery Slot\n") else: - if BoxInfo.getItem("mtdbootfs") != "" and " " not in BoxInfo.getItem("mtdbootfs"): - AboutText += _("Boot Device:\t%s%s\n") % (VuPlustxt, BoxInfo.getItem("mtdbootfs")) + if SystemInfo["mtdbootfs"] != "" and " " not in SystemInfo["mtdbootfs"]: + AboutText += _("Boot Device:\t%s%s\n") % (VuPlustxt, SystemInfo["mtdbootfs"]) if SystemInfo["HasH9SD"]: if "rootfstype=ext4" in open("/sys/firmware/devicetree/base/chosen/bootargs", "r").read(): @@ -132,7 +131,7 @@ def populate(self): bootmode = _("bootmode = %s") % GetCurrentImageMode() if SystemInfo["canMode12"] else "" AboutText += (_("Image Slot:\tStartup %s - %s %s") % (str(slot), part, bootmode)) + "\n" - if getMachineName() in ("ET8500") and path.exists("/proc/mtd"): + if SystemInfo["MachineName"] in ("ET8500") and path.exists("/proc/mtd"): self.dualboot = self.dualBoot() if self.dualboot: AboutText += _("ET8500 Multiboot: Installed\n") @@ -622,8 +621,8 @@ def __init__(self, session, parent): self.skinName = "AboutSummary" self.aboutText = [] self["AboutText"] = StaticText() - self.aboutText.append(_("OpenViX: %s") % getImageVersion() + "." + getImageBuild() + "\n") - self.aboutText.append(_("Model: %s %s\n") % (getMachineBrand(), getMachineName())) + self.aboutText.append(_("OpenViX: %s") % SystemInfo["imageversion"] + "." + SystemInfo["imagebuild"] + "\n") + self.aboutText.append(_("Model: %s %s\n") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"])) self.aboutText.append(_("Updated: %s") % about.getLastUpdate() + "\n") tempinfo = "" if path.exists("/proc/stb/sensors/temp0/value"): diff --git a/lib/python/Screens/CronTimer.py b/lib/python/Screens/CronTimer.py index df5b4674150..e94db87ab21 100644 --- a/lib/python/Screens/CronTimer.py +++ b/lib/python/Screens/CronTimer.py @@ -1,7 +1,6 @@ from os import system, listdir, rename, path, mkdir from time import sleep -from boxbranding import getImageType from Components.ActionMap import ActionMap from Components.config import getConfigListEntry, ConfigText, ConfigSelection, ConfigInteger, ConfigClock from Components.ConfigList import ConfigListScreen @@ -9,6 +8,7 @@ from Components.Label import Label from Components.Sources.List import List from Components.OnlineUpdateCheck import feedsstatuscheck +from Components.SystemInfo import SystemInfo from Screens.Screen import Screen from Screens.Setup import Setup from Screens.MessageBox import MessageBox @@ -67,7 +67,7 @@ def checkNetworkState(self, result, retval, extra_args): if 'Collected errors' in result: self.session.openWithCallback(self.close, MessageBox, _("A background update check is in progress, please wait a few minutes and try again."), type=MessageBox.TYPE_INFO, timeout=10, close_on_any_key=True) elif not result: - if (getImageType() != 'release' and feedsstatuscheck.getFeedsBool() != 'unknown') or (getImageType() == 'release' and feedsstatuscheck.getFeedsBool() not in ('stable', 'unstable')): + if (SystemInfo["imagetype"] != 'release' and feedsstatuscheck.getFeedsBool() != 'unknown') or (SystemInfo["imagetype"] == 'release' and feedsstatuscheck.getFeedsBool() not in ('stable', 'unstable')): self.session.openWithCallback(self.InstallPackageFailed, MessageBox, feedsstatuscheck.getFeedsErrorMessage(), type=MessageBox.TYPE_INFO, timeout=10, close_on_any_key=True) else: self.session.openWithCallback(self.InstallPackage, MessageBox, _('Ready to install "%s" ?') % self.service_name, MessageBox.TYPE_YESNO) diff --git a/lib/python/Screens/GitCommitInfo.py b/lib/python/Screens/GitCommitInfo.py index 67f32a55b69..7a89f93410c 100644 --- a/lib/python/Screens/GitCommitInfo.py +++ b/lib/python/Screens/GitCommitInfo.py @@ -2,10 +2,10 @@ from Components.Button import Button from Components.Label import Label from Components.ScrollLabel import ScrollLabel +from Components.SystemInfo import SystemInfo from Screens.Screen import Screen from enigma import eTimer -from boxbranding import getImageBuild, getImageDevBuild, getImageType from sys import modules from datetime import datetime from json import loads @@ -13,10 +13,10 @@ from urllib.request import urlopen, Request # raises ImportError in Python 2 from urllib.error import HTTPError, URLError # raises ImportError in Python 2 -if getImageType() == 'release': - ImageVer = "%03d" % int(getImageBuild()) +if SystemInfo["imagetype"] == 'release': + ImageVer = "%03d" % int(SystemInfo["imagebuild"]) else: - ImageVer = "%s.%s" % (getImageBuild(), getImageDevBuild()) + ImageVer = "%s.%s" % (SystemInfo["imagebuild"], SystemInfo["imagedevbuild"]) ImageVer = float(ImageVer) E2Branches = { @@ -27,7 +27,7 @@ project = 0 projects = [ ("https://api.github.com/repos/oe-alliance/oe-alliance-core/commits?sha=5.3", "OE-A Core"), - ("https://api.github.com/repos/OpenViX/enigma2/commits?sha=%s" % getattr(E2Branches, getImageType(), "Release"), "Enigma2"), + ("https://api.github.com/repos/OpenViX/enigma2/commits?sha=%s" % getattr(E2Branches, SystemInfo["imagetype"], "Release"), "Enigma2"), ("https://api.github.com/repos/OpenViX/skins/commits", "ViX Skins"), ("https://api.github.com/repos/oe-alliance/oe-alliance-plugins/commits", "OE-A Plugins"), ("https://api.github.com/repos/oe-alliance/AutoBouquetsMaker/commits", "AutoBouquetsMaker"), @@ -53,15 +53,15 @@ def readGithubCommitLogsSoftwareUpdate(): continue if c['commit']['message'].startswith('openvix:'): gitstart = False - if getImageType() == 'release' and c['commit']['message'].startswith('openvix: developer'): + if SystemInfo["imagetype"] == 'release' and c['commit']['message'].startswith('openvix: developer'): print('[GitCommitLog] Skipping developer line') continue - elif getImageType() != 'release' and c['commit']['message'].startswith('openvix: release'): + elif SystemInfo["imagetype"] != 'release' and c['commit']['message'].startswith('openvix: release'): print('[GitCommitLog] Skipping release line') continue tmp = c['commit']['message'].split(' ')[2].split('.') if len(tmp) > 2: - if getImageType() == 'release': + if SystemInfo["imagetype"] == 'release': releasever = tmp[2] releasever = "%03d" % int(releasever) else: @@ -112,15 +112,15 @@ def readGithubCommitLogs(): if c['commit']['message'].startswith('openvix:'): blockstart = False gitstart = False - if getImageType() == 'release' and c['commit']['message'].startswith('openvix: developer'): + if SystemInfo["imagetype"] == 'release' and c['commit']['message'].startswith('openvix: developer'): print('[GitCommitLog] Skipping developer line') continue - elif getImageType() == 'developer' and c['commit']['message'].startswith('openvix: release'): + elif SystemInfo["imagetype"] == 'developer' and c['commit']['message'].startswith('openvix: release'): print('[GitCommitLog] Skipping release line') continue tmp = c['commit']['message'].split(' ')[2].split('.') if len(tmp) > 2: - if getImageType() == 'release': + if SystemInfo["imagetype"] == 'release': releasever = tmp[2] releasever = "%03d" % int(releasever) else: diff --git a/lib/python/Screens/InputDeviceSetup.py b/lib/python/Screens/InputDeviceSetup.py index cb3a92f1692..d662e40a9da 100644 --- a/lib/python/Screens/InputDeviceSetup.py +++ b/lib/python/Screens/InputDeviceSetup.py @@ -7,9 +7,9 @@ from Components.config import config, ConfigYesNo, getConfigListEntry, ConfigSelection from Components.ConfigList import ConfigListScreen from Components.ActionMap import ActionMap, HelpableActionMap +from Components.SystemInfo import SystemInfo from Tools.Directories import resolveFilename, SCOPE_CURRENT_SKIN from Tools.LoadPixmap import LoadPixmap -from boxbranding import getBoxType, getMachineBrand, getMachineName, getMachineBuild class InputDeviceSelection(Screen, HelpableScreen): @@ -128,7 +128,7 @@ def __init__(self, session, device=None): self["introduction"] = StaticText() # for generating strings into .po only - devicenames = [_("%s %s front panel") % (getMachineBrand(), getMachineName()), _("%s %s remote control (native)") % (getMachineBrand(), getMachineName()), _("%s %s advanced remote control (native)") % (getMachineBrand(), getMachineName()), _("%s %s ir keyboard") % (getMachineBrand(), getMachineName()), _("%s %s ir mouse") % (getMachineBrand(), getMachineName())] # noqa: F841 + devicenames = [_("%s %s front panel") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), _("%s %s remote control (native)") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), _("%s %s advanced remote control (native)") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), _("%s %s ir keyboard") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), _("%s %s ir mouse") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"])] # noqa: F841 self.createSetup() self.onLayoutFinish.append(self.layoutFinished) @@ -217,7 +217,7 @@ def getCurrentValue(self): # required because getCurrentValue() in ConfigListSc class RemoteControlType(ConfigListScreen, Screen): odinRemote = "OdinM9" - if getBoxType() == "maram9": + if SystemInfo["boxtype"] == "maram9": odinRemote = "MaraM9" rcList = [ @@ -314,8 +314,8 @@ def __init__(self, session): self.getDefaultRcType() def getDefaultRcType(self): - boxtype = getMachineBuild() - procBoxtype = iRcTypeControl.getBoxType() + boxtype = SystemInfo["model"] + procBoxtype = iRcTypeControl.SystemInfo["boxtype"] print("[InputDevice] procBoxtype = %s, self.boxType = %s" % (procBoxtype, boxtype)) for x in self.defaultRcList: if x[0] in boxtype or x[0] in procBoxtype: diff --git a/lib/python/Screens/MultiBootSelector.py b/lib/python/Screens/MultiBootSelector.py index ab8d8b18669..78f87dd4524 100644 --- a/lib/python/Screens/MultiBootSelector.py +++ b/lib/python/Screens/MultiBootSelector.py @@ -2,7 +2,6 @@ import tempfile import struct -from boxbranding import getBoxType from Components.ActionMap import HelpableActionMap from Components.ChoiceList import ChoiceEntryComponent, ChoiceList from Components.Console import Console @@ -183,7 +182,7 @@ def addSTARTUPs(self, answer): if answer is False: self.close() else: - boxmodel = getBoxType()[2:] + boxmodel = SystemInfo["boxtype"][2:] for usbslot in range(hiKey + 1, hiKey + 5): STARTUP_usbslot = "kernel=%s/linuxrootfs%d/zImage root=%s rootsubdir=%s/linuxrootfs%d" % (boxmodel, usbslot, SystemInfo["VuUUIDSlot"][0], boxmodel, usbslot) # /STARTUP_ if boxmodel in ("duo4k"): @@ -197,7 +196,7 @@ def addSTARTUPs(self, answer): def KexecMountRet(self, result=None, retval=None, extra_args=None): self.device_uuid = "UUID=" + result.split("UUID=")[1].split(" ")[0].replace('"', '') - boxmodel = getBoxType()[2:] + boxmodel = SystemInfo["boxtype"][2:] # using UUID kernel=/linuxrootfs1/boot/zImage root=UUID="12c2025e-2969-4bd1-9e0c-da08b97d40ce" rootsubdir=linuxrootfs1 # using dev = "kernel=/linuxrootfs4/zImage root=/dev/%s rootsubdir=linuxrootfs4" % hdd[0] # /STARTUP_4 diff --git a/lib/python/Screens/NetworkSetup.py b/lib/python/Screens/NetworkSetup.py index a85fa0c9e6e..148358be2a3 100644 --- a/lib/python/Screens/NetworkSetup.py +++ b/lib/python/Screens/NetworkSetup.py @@ -5,7 +5,6 @@ import time import glob from enigma import eTimer, eConsoleAppContainer -from boxbranding import getBoxType, getMachineBrand, getMachineName, getImageType, getImageVersion from Components.ActionMap import ActionMap, NumberActionMap, HelpableActionMap from Components.config import config, ConfigSubsection, ConfigYesNo, ConfigIP, ConfigText, ConfigPassword, ConfigSelection, getConfigListEntry, ConfigNumber, ConfigLocations, NoSave, ConfigMacText @@ -94,7 +93,7 @@ def StartStopCallback(self, result=None, retval=None, extra_args=None): def removeComplete(self, result=None, retval=None, extra_args=None): if self.reboot_at_end: restartbox = self.session.openWithCallback(self.operationComplete, MessageBox, - _('Your %s %s needs to be restarted to complete the removal of %s\nDo you want to reboot now ?') % (getMachineBrand(), getMachineName(), self.getTitle()), MessageBox.TYPE_YESNO) + _('Your %s %s needs to be restarted to complete the removal of %s\nDo you want to reboot now ?') % (SystemInfo["MachineBrand"], SystemInfo["MachineName"], self.getTitle()), MessageBox.TYPE_YESNO) restartbox.setTitle(_("Reboot required")) else: self.operationComplete() @@ -102,7 +101,7 @@ def removeComplete(self, result=None, retval=None, extra_args=None): def installComplete(self, result=None, retval=None, extra_args=None): if self.reboot_at_end: restartbox = self.session.openWithCallback(self.operationComplete, MessageBox, - _('Your %s %s needs to be restarted to complete the installation of %s\nDo you want to reboot now ?') % (getMachineBrand(), getMachineName(), self.getTitle()), MessageBox.TYPE_YESNO) + _('Your %s %s needs to be restarted to complete the installation of %s\nDo you want to reboot now ?') % (SystemInfo["MachineBrand"], SystemInfo["MachineName"], self.getTitle()), MessageBox.TYPE_YESNO) restartbox.setTitle(_("Reboot required")) else: self.message.close() @@ -127,7 +126,7 @@ def checkNetworkState(self, str, retval, extra_args): if "Collected errors" in str: self.session.openWithCallback(self.close, MessageBox, _("A background update check is in progress, please wait a few minutes and then try again."), type=MessageBox.TYPE_INFO, timeout=10, close_on_any_key=True) elif not str: - if (getImageType() != "release" and feedsstatuscheck.getFeedsBool() not in ("unknown", "alien", "developer")) or (getImageType() == "release" and feedsstatuscheck.getFeedsBool() not in ("stable", "unstable", "alien", "developer")): + if (SystemInfo["imagetype"] != "release" and feedsstatuscheck.getFeedsBool() not in ("unknown", "alien", "developer")) or (SystemInfo["imagetype"] == "release" and feedsstatuscheck.getFeedsBool() not in ("stable", "unstable", "alien", "developer")): self.session.openWithCallback(self.InstallPackageFailed, MessageBox, feedsstatuscheck.getFeedsErrorMessage(), type=MessageBox.TYPE_INFO, timeout=10, close_on_any_key=True) else: mtext = _("Are you ready to install %s ?") % self.getTitle() @@ -965,11 +964,11 @@ def createSummary(self): def selectionChanged(self): if self["menulist"].getCurrent()[1] == "edit": - self["description"].setText(_("Edit the network configuration of your %s %s.\n") % (getMachineBrand(), getMachineName()) + self.oktext) + self["description"].setText(_("Edit the network configuration of your %s %s.\n") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) + self.oktext) if self["menulist"].getCurrent()[1] == "test": - self["description"].setText(_("Test the network configuration of your %s %s.\n") % (getMachineBrand(), getMachineName()) + self.oktext) + self["description"].setText(_("Test the network configuration of your %s %s.\n") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) + self.oktext) if self["menulist"].getCurrent()[1] == "dns": - self["description"].setText(_("Edit the Nameserver configuration of your %s %s.\n") % (getMachineBrand(), getMachineName()) + self.oktext) + self["description"].setText(_("Edit the Nameserver configuration of your %s %s.\n") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) + self.oktext) if self["menulist"].getCurrent()[1] == "scanwlan": self["description"].setText(_("Scan your network for wireless access points and connect to them using your selected wireless device.\n") + self.oktext) if self["menulist"].getCurrent()[1] == "wlanstatus": @@ -981,7 +980,7 @@ def selectionChanged(self): if self["menulist"].getCurrent()[1][0] == "extendedSetup": self["description"].setText(_(self["menulist"].getCurrent()[1][1]) + self.oktext) if self["menulist"].getCurrent()[1] == "mac": - self["description"].setText(_("Set the MAC address of your %s %s.\n") % (getMachineBrand(), getMachineName()) + self.oktext) + self["description"].setText(_("Set the MAC address of your %s %s.\n") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) + self.oktext) item = self["menulist"].getCurrent() if item: name = str(self["menulist"].getCurrent()[0]) @@ -2557,7 +2556,7 @@ def __init__(self, session): def updateList(self, ret=None): self.list = [] - self.ushare_user = NoSave(ConfigText(default=getBoxType(), fixed_size=False)) + self.ushare_user = NoSave(ConfigText(default=SystemInfo["boxtype"], fixed_size=False)) self.ushare_iface = NoSave(ConfigText(fixed_size=False)) self.ushare_port = NoSave(ConfigNumber()) self.ushare_telnetport = NoSave(ConfigNumber()) @@ -2922,7 +2921,7 @@ def __init__(self, session): def updateList(self, ret=None): self.list = [] - self.minidlna_name = NoSave(ConfigText(default=getBoxType(), fixed_size=False)) + self.minidlna_name = NoSave(ConfigText(default=SystemInfo["boxtype"], fixed_size=False)) self.minidlna_iface = NoSave(ConfigText(fixed_size=False)) self.minidlna_port = NoSave(ConfigNumber()) self.minidlna_serialno = NoSave(ConfigNumber()) @@ -3144,7 +3143,7 @@ def newRandom(self): self["config"].invalidateCurrent() def createSetup(self): - instructions = _("Setting a network password is mandatory in OpenViX %s if you wish to use network services. \nTo set a password using the virtual keyboard press the 'text' button on your remote control.") % getImageVersion() + instructions = _("Setting a network password is mandatory in OpenViX %s if you wish to use network services. \nTo set a password using the virtual keyboard press the 'text' button on your remote control.") % SystemInfo["imageversion"] self.list.append(getConfigListEntry(_('New password'), self.password, instructions)) self['config'].list = self.list diff --git a/lib/python/Screens/PluginBrowser.py b/lib/python/Screens/PluginBrowser.py index 1e5f055d186..263d9a1b7f0 100644 --- a/lib/python/Screens/PluginBrowser.py +++ b/lib/python/Screens/PluginBrowser.py @@ -1,7 +1,6 @@ from os import path, unlink from enigma import eConsoleAppContainer, eDVBDB, eTimer -from boxbranding import getImageType, getMachineBrand, getMachineName from Components.ActionMap import ActionMap, NumberActionMap from Components.Button import Button @@ -242,7 +241,7 @@ def delete(self): def download(self): config.misc.pluginbrowser.po.value = True if not (feedsstatuscheck.adapterAvailable() and feedsstatuscheck.NetworkUp()): - self.session.openWithCallback(self.close, MessageBox, _("Your %s %s has no %s access, please check your network settings and make sure you have network cable connected and try again.") % (getMachineBrand(), getMachineName(), feedsstatuscheck.adapterAvailable() and 'internet' or 'network'), type=MessageBox.TYPE_INFO, timeout=30, close_on_any_key=True) + self.session.openWithCallback(self.close, MessageBox, _("Your %s %s has no %s access, please check your network settings and make sure you have network cable connected and try again.") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"], feedsstatuscheck.adapterAvailable() and 'internet' or 'network'), type=MessageBox.TYPE_INFO, timeout=30, close_on_any_key=True) return if kernelMismatch(): self.session.openWithCallback(self.close, MessageBox, _("The Linux kernel has changed, plugins are not compatible. \nInstall latest image using USB stick or Image Manager."), type=MessageBox.TYPE_INFO, timeout=30, close_on_any_key=True) @@ -505,9 +504,9 @@ def startRun(self): self.listHeight = listsize.height() if self.type == self.DOWNLOAD: self.type = self.UPDATE - if (getImageType() != "release" and feedsstatuscheck.getFeedsBool() not in ("unknown", "alien", "developer")) or (getImageType() == "release" and feedsstatuscheck.getFeedsBool() not in ("stable", "unstable", "alien", "developer")): + if (SystemInfo["imagetype"] != "release" and feedsstatuscheck.getFeedsBool() not in ("unknown", "alien", "developer")) or (SystemInfo["imagetype"] == "release" and feedsstatuscheck.getFeedsBool() not in ("stable", "unstable", "alien", "developer")): self["text"].setText(feedsstatuscheck.getFeedsErrorMessage()) - elif getImageType() != 'release' or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value): + elif SystemInfo["imagetype"] != 'release' or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value): self["text"].setText(_("WARNING: feeds may be unstable.") + '\n' + _("Downloading plugin information. Please wait...")) self.container.execute(self.ipkg + " update") elif config.softwareupdate.updateisunstable.value == 1 and not config.softwareupdate.updatebeta.value: diff --git a/lib/python/Screens/Satconfig.py b/lib/python/Screens/Satconfig.py index 66c1d0d1e8c..624ec7b1e70 100644 --- a/lib/python/Screens/Satconfig.py +++ b/lib/python/Screens/Satconfig.py @@ -18,7 +18,6 @@ from Tools.BoundFunction import boundFunction from Tools.Directories import fileExists -from boxbranding import getImageType from time import mktime, localtime, time from datetime import datetime @@ -832,7 +831,7 @@ def okbuttonClick(self): recordings = self.session.nav.getRecordings() next_rec_time = self.session.nav.RecordTimer.getNextRecordingTime() if recordings or (next_rec_time and next_rec_time > 0 and (next_rec_time - time()) < 360): - if getImageType() == 'release': + if SystemInfo["imagetype"] == 'release': self.session.open(MessageBox, _("Recording(s) are in progress or coming up in few seconds!"), MessageBox.TYPE_INFO, timeout=5, enable_input=False) else: message = _("Recording(s) are in progress or coming up in few seconds!") diff --git a/lib/python/Screens/SoftwareUpdate.py b/lib/python/Screens/SoftwareUpdate.py index 09925b638c1..ea408bb8cde 100644 --- a/lib/python/Screens/SoftwareUpdate.py +++ b/lib/python/Screens/SoftwareUpdate.py @@ -1,6 +1,5 @@ from enigma import eTimer, eDVBDB -from boxbranding import getImageType, getMachineBrand, getMachineName from Components.ActionMap import ActionMap from Components.Button import Button from Components.config import config @@ -10,6 +9,7 @@ from Components.ScrollLabel import ScrollLabel # noqa: F401 from Components.Sources.StaticText import StaticText from Components.Slider import Slider +from Components.SystemInfo import SystemInfo import Components.Task from Screens.ChoiceBox import ChoiceBox from Screens.GitCommitInfo import CommitInfo, gitcommitinfo @@ -154,11 +154,11 @@ def checkNetworkState(self): self['tl_yellow'].show() else: self['tl_off'].show() - if (getImageType() != 'release' and self.trafficLight not in ("unknown", "alien", "developer")) or (getImageType() == 'release' and self.trafficLight not in ("stable", "unstable", "alien", "developer")): + if (SystemInfo["imagetype"] != 'release' and self.trafficLight not in ("unknown", "alien", "developer")) or (SystemInfo["imagetype"] == 'release' and self.trafficLight not in ("stable", "unstable", "alien", "developer")): self.session.openWithCallback(self.close, MessageBox, feedsstatuscheck.getFeedsErrorMessage(), type=MessageBox.TYPE_INFO, timeout=30, close_on_any_key=True) return else: - if getImageType() != 'release' or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value) or config.softwareupdate.updateisunstable.value == 0: + if SystemInfo["imagetype"] != 'release' or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value) or config.softwareupdate.updateisunstable.value == 0: if kernelMismatch(): self.session.openWithCallback(self.close, MessageBox, _("The Linux kernel has changed, an update is not permitted. \nInstall latest image using USB stick or Image Manager."), type=MessageBox.TYPE_INFO, timeout=30, close_on_any_key=True) return @@ -257,13 +257,13 @@ def ipkgCallback(self, event, param): self.ipkg.startCmd(IpkgComponent.CMD_UPGRADE_LIST) elif self.ipkg.currentCommand == IpkgComponent.CMD_UPGRADE_LIST: self.total_packages = None - if (getImageType() != 'release' or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value)) or config.softwareupdate.updateisunstable.value == 0: + if (SystemInfo["imagetype"] != 'release' or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value)) or config.softwareupdate.updateisunstable.value == 0: self.total_packages = len(self.ipkg.getFetchedList()) packagesMsg = "\n(" + (ngettext("%s updated package available", "%s updated packages available", self.total_packages) % self.total_packages) + ")" - if getImageType() != 'release' or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value): - message = _("The current update may be unstable.") + "\n" + _("Are you sure you want to update your %s %s?") % (getMachineBrand(), getMachineName()) + packagesMsg + if SystemInfo["imagetype"] != 'release' or (config.softwareupdate.updateisunstable.value == 1 and config.softwareupdate.updatebeta.value): + message = _("The current update may be unstable.") + "\n" + _("Are you sure you want to update your %s %s?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) + packagesMsg elif config.softwareupdate.updateisunstable.value == 0: - message = _("Do you want to update your %s %s?") % (getMachineBrand(), getMachineName()) + packagesMsg + message = _("Do you want to update your %s %s?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) + packagesMsg if self.total_packages: if self.total_packages > 150: message += " " + _("Reflash recommended!") @@ -315,14 +315,14 @@ def ipkgCallback(self, event, param): else: self.activityTimer.stop() self.activityslider.setValue(0) - error = _("Your %s %s might be unusable now. Please consult the manual for further assistance before rebooting your %s %s.") % (getMachineBrand(), getMachineName(), getMachineBrand(), getMachineName()) + error = _("Your %s %s might be unusable now. Please consult the manual for further assistance before rebooting your %s %s.") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"], SystemInfo["MachineBrand"], SystemInfo["MachineName"]) if self.packages == 0: if self.error != 0: error = _("Problem retrieving update list.\nIf this issue persists please check/report on forum") else: error = _("A background update check is in progress,\nplease wait a few minutes and try again.") if self.updating: - error = _("Update failed. Your %s %s does not have a working internet connection.") % (getMachineBrand(), getMachineName()) + error = _("Update failed. Your %s %s does not have a working internet connection.") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) self.status.setText(_("Error") + " - " + error) self["actions"].setEnabled(True) elif event == IpkgComponent.EVENT_LISTITEM: @@ -347,9 +347,9 @@ def startActualUpgrade(self, answer): if answer[1] == "menu": packagesMsg = "\n(%s " % self.total_packages + _("Packages") + ")" if config.softwareupdate.updateisunstable.value == 1: - message = _("The current update may be unstable.") + "\n" + _("Are you sure you want to update your %s %s?") % (getMachineBrand(), getMachineName()) + packagesMsg + message = _("The current update may be unstable.") + "\n" + _("Are you sure you want to update your %s %s?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) + packagesMsg elif config.softwareupdate.updateisunstable.value == 0: - message = _("Do you want to update your %s %s?") % (getMachineBrand(), getMachineName()) + packagesMsg + message = _("Do you want to update your %s %s?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) + packagesMsg choices = [(_("View the changes"), "changes"), (_("Upgrade and reboot system"), "cold")] if not self.SettingsBackupDone and not config.softwareupdate.autosettingsbackup.value and config.backupmanager.backuplocation.value: @@ -428,7 +428,7 @@ def showJobView(self, job): def exit(self): if not self.ipkg.isRunning(): if self.packages != 0 and self.error == 0 and self.channellist_only == 0: - self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished.") + " " + _("Do you want to reboot your %s %s") % (getMachineBrand(), getMachineName())) + self.session.openWithCallback(self.exitAnswer, MessageBox, _("Upgrade finished.") + " " + _("Do you want to reboot your %s %s") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"])) else: self.close() else: diff --git a/lib/python/Screens/Standby.py b/lib/python/Screens/Standby.py index c4511cbd1f4..c1b050ce245 100644 --- a/lib/python/Screens/Standby.py +++ b/lib/python/Screens/Standby.py @@ -3,7 +3,6 @@ from enigma import eDVBVolumecontrol, eTimer, eDVBLocalTimeHandler, eServiceReference, eStreamServer, iRecordableService, quitMainloop -from boxbranding import getMachineBrand, getMachineName, getBoxType, getBrandOEM from Components.ActionMap import ActionMap from Components.AVSwitch import AVSwitch from Components.config import config @@ -42,7 +41,7 @@ def setLCDMiniTVMode(value): class Standby2(Screen): def Power(self): - if getBrandOEM() in ('dinobot') or SystemInfo["HasHiSi"] or getBoxType() in ("sfx6008", "sfx6018"): + if SystemInfo["brand"] in ('dinobot') or SystemInfo["HasHiSi"] or SystemInfo["boxtype"] in ("sfx6008", "sfx6018"): try: open("/proc/stb/hdmi/output", "w").write("on") except: @@ -118,7 +117,7 @@ def __init__(self, session): self.avswitch.setInput("SCART") else: self.avswitch.setInput("AUX") - if getBrandOEM() in ('dinobot') or SystemInfo["HasHiSi"] or getBoxType() in ("sfx6008", "sfx6018"): + if SystemInfo["brand"] in ('dinobot') or SystemInfo["HasHiSi"] or SystemInfo["boxtype"] in ("sfx6008", "sfx6018"): try: open("/proc/stb/hdmi/output", "w").write("off") except: @@ -207,15 +206,15 @@ def __init__(self, session, retvalue=1): Screen.__init__(self, session) from Components.Label import Label text = { - QUIT_SHUTDOWN: _("Your %s %s is shutting down") % (getMachineBrand(), getMachineName()), - QUIT_REBOOT: _("Your %s %s is rebooting") % (getMachineBrand(), getMachineName()), - QUIT_RESTART: _("The user interface of your %s %s is restarting") % (getMachineBrand(), getMachineName()), - QUIT_ANDROID: _("Your %s %s is rebooting into Android Mode") % (getMachineBrand(), getMachineName()), - QUIT_MAINT: _("Your %s %s is rebooting into Recovery Mode") % (getMachineBrand(), getMachineName()), - QUIT_UPGRADE_FP: _("Your frontprocessor will be upgraded\nPlease wait until your %s %s reboots\nThis may take a few minutes") % (getMachineBrand(), getMachineName()), - QUIT_ERROR_RESTART: _("The user interface of your %s %s is restarting\ndue to an error in StartEnigma.py") % (getMachineBrand(), getMachineName()), - QUIT_UPGRADE_PROGRAM: _("Upgrade in progress\nPlease wait until your %s %s reboots\nThis may take a few minutes") % (getMachineBrand(), getMachineName()), - QUIT_IMAGE_RESTORE: _("Reflash in progress\nPlease wait until your %s %s reboots\nThis may take a few minutes") % (getMachineBrand(), getMachineName()) + QUIT_SHUTDOWN: _("Your %s %s is shutting down") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), + QUIT_REBOOT: _("Your %s %s is rebooting") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), + QUIT_RESTART: _("The user interface of your %s %s is restarting") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), + QUIT_ANDROID: _("Your %s %s is rebooting into Android Mode") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), + QUIT_MAINT: _("Your %s %s is rebooting into Recovery Mode") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), + QUIT_UPGRADE_FP: _("Your frontprocessor will be upgraded\nPlease wait until your %s %s reboots\nThis may take a few minutes") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), + QUIT_ERROR_RESTART: _("The user interface of your %s %s is restarting\ndue to an error in StartEnigma.py") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), + QUIT_UPGRADE_PROGRAM: _("Upgrade in progress\nPlease wait until your %s %s reboots\nThis may take a few minutes") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), + QUIT_IMAGE_RESTORE: _("Reflash in progress\nPlease wait until your %s %s reboots\nThis may take a few minutes") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) }.get(retvalue) self["text"] = Label(text) @@ -265,8 +264,8 @@ def __init__(self, session, retvalue=1, timeout=-1, default_yes=True): QUIT_ANDROID: _("Really reboot into Android Mode?"), QUIT_MAINT: _("Really reboot into Recovery Mode?"), QUIT_UPGRADE_FP: _("Really upgrade the frontprocessor and reboot now?"), - QUIT_UPGRADE_PROGRAM: _("Really upgrade your %s %s and reboot now?") % (getMachineBrand(), getMachineName()), - QUIT_IMAGE_RESTORE: _("Really reflash your %s %s and reboot now?") % (getMachineBrand(), getMachineName()) + QUIT_UPGRADE_PROGRAM: _("Really upgrade your %s %s and reboot now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), + QUIT_IMAGE_RESTORE: _("Really reflash your %s %s and reboot now?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) }.get(retvalue) if text: MessageBox.__init__(self, session, "%s\n%s" % (reason, text), type=MessageBox.TYPE_YESNO, timeout=timeout, default=default_yes) @@ -335,7 +334,7 @@ def close(self, value): # set LCDminiTV off / fix a deep-standby-crash on some boxes / gb4k print("[Standby] LCDminiTV off") setLCDMiniTVMode("0") - if getBoxType() == "vusolo4k": # workaround for white display flash + if SystemInfo["boxtype"] == "vusolo4k": # workaround for white display flash f = open("/proc/stb/fp/oled_brightness", "w") f.write("0") f.close() diff --git a/lib/python/Screens/TaskView.py b/lib/python/Screens/TaskView.py index 0a70c12a6e5..5c7601f8ea6 100644 --- a/lib/python/Screens/TaskView.py +++ b/lib/python/Screens/TaskView.py @@ -11,8 +11,6 @@ from Screens.MessageBox import MessageBox import Screens.Standby -from boxbranding import getMachineBrand, getMachineName - class JobView(InfoBarNotifications, ConfigListScreen, Screen): def __init__(self, session, job, parent=None, cancelable=True, backgroundable=True, afterEventChangeable=True, afterEvent="nothing"): @@ -163,10 +161,10 @@ def performAfterEvent(self): self.close(False) elif self.settings.afterEvent.value == "deepstandby": if not Screens.Standby.inTryQuitMainloop: - Tools.Notifications.AddNotificationWithCallback(self.sendTryQuitMainloopNotification, MessageBox, _("A sleep timer wants to shut down\nyour %s %s. Proceed?") % (getMachineBrand(), getMachineName()), timeout=20) + Tools.Notifications.AddNotificationWithCallback(self.sendTryQuitMainloopNotification, MessageBox, _("A sleep timer wants to shut down\nyour %s %s. Proceed?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), timeout=20) elif self.settings.afterEvent.value == "standby": if not Screens.Standby.inStandby: - Tools.Notifications.AddNotificationWithCallback(self.sendStandbyNotification, MessageBox, _("A sleep timer wants to set your\n%s %s to standby. Proceed?") % (getMachineBrand(), getMachineName()), timeout=20) + Tools.Notifications.AddNotificationWithCallback(self.sendStandbyNotification, MessageBox, _("A sleep timer wants to set your\n%s %s to standby. Proceed?") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]), timeout=20) def checkNotifications(self): InfoBarNotifications.checkNotifications(self) diff --git a/lib/python/Screens/UserInterfacePositioner.py b/lib/python/Screens/UserInterfacePositioner.py index cf35ddc84ed..9cca94abd89 100644 --- a/lib/python/Screens/UserInterfacePositioner.py +++ b/lib/python/Screens/UserInterfacePositioner.py @@ -11,8 +11,6 @@ from os import access, R_OK import traceback -from boxbranding import getBoxType - def getFilePath(setting): return "/proc/stb/fb/dst_%s" % (setting) @@ -48,7 +46,7 @@ def InitOsd(): config.osd.show3dextensions = ConfigYesNo(default=False) def set3DMode(configElement): - if SystemInfo["CanChange3DOsd"] and getBoxType() not in ('spycat'): + if SystemInfo["CanChange3DOsd"] and SystemInfo["boxtype"] not in ('spycat'): print('[UserInterfacePositioner] Setting 3D mode:', configElement.value) file3d = fileCheck('/proc/stb/fb/3dmode') or fileCheck('/proc/stb/fb/primary/3d') f = open(file3d, "w") @@ -57,7 +55,7 @@ def set3DMode(configElement): config.osd.threeDmode.addNotifier(set3DMode) def set3DZnorm(configElement): - if SystemInfo["CanChange3DOsd"] and getBoxType() not in ('spycat'): + if SystemInfo["CanChange3DOsd"] and SystemInfo["boxtype"] not in ('spycat'): print('[UserInterfacePositioner] Setting 3D depth:', configElement.value) f = open("/proc/stb/fb/znorm", "w") f.write('%d' % int(configElement.value)) diff --git a/lib/python/Screens/VuWizard.py b/lib/python/Screens/VuWizard.py index 89cf855e393..cd942efafda 100644 --- a/lib/python/Screens/VuWizard.py +++ b/lib/python/Screens/VuWizard.py @@ -1,9 +1,9 @@ import glob -from boxbranding import getBoxType, getMachineMtdKernel, getMachineMtdRoot from Components.config import config, configfile from Components.Console import Console from Components.Pixmap import Pixmap from Components.Sources.Boolean import Boolean +from Components.SystemInfo import SystemInfo from Screens.MessageBox import MessageBox from Screens.Rc import Rc from Screens.WizardLanguage import WizardLanguage @@ -43,11 +43,11 @@ "enigma2-locale", ] -STARTUP = "kernel=/zImage root=/dev/%s rootsubdir=linuxrootfs0" % getMachineMtdRoot() # /STARTUP -STARTUP_RECOVERY = "kernel=/zImage root=/dev/%s rootsubdir=linuxrootfs0" % getMachineMtdRoot() # /STARTUP_RECOVERY -STARTUP_1 = "kernel=/linuxrootfs1/zImage root=/dev/%s rootsubdir=linuxrootfs1" % getMachineMtdRoot() # /STARTUP_1 -STARTUP_2 = "kernel=/linuxrootfs2/zImage root=/dev/%s rootsubdir=linuxrootfs2" % getMachineMtdRoot() # /STARTUP_2 -STARTUP_3 = "kernel=/linuxrootfs3/zImage root=/dev/%s rootsubdir=linuxrootfs3" % getMachineMtdRoot() # /STARTUP_3 +STARTUP = "kernel=/zImage root=/dev/%s rootsubdir=linuxrootfs0" % SystemInfo["mtdrootfs"] # /STARTUP +STARTUP_RECOVERY = "kernel=/zImage root=/dev/%s rootsubdir=linuxrootfs0" % SystemInfo["mtdrootfs"] # /STARTUP_RECOVERY +STARTUP_1 = "kernel=/linuxrootfs1/zImage root=/dev/%s rootsubdir=linuxrootfs1" % SystemInfo["mtdrootfs"] # /STARTUP_1 +STARTUP_2 = "kernel=/linuxrootfs2/zImage root=/dev/%s rootsubdir=linuxrootfs2" % SystemInfo["mtdrootfs"] # /STARTUP_2 +STARTUP_3 = "kernel=/linuxrootfs3/zImage root=/dev/%s rootsubdir=linuxrootfs3" % SystemInfo["mtdrootfs"] # /STARTUP_3 class VuWizard(WizardLanguage, Rc): @@ -98,8 +98,8 @@ def welcomeAction(self, answer): with open("/STARTUP_3", 'w') as f: f.write(STARTUP_3) cmdlist = [] - cmdlist.append("dd if=/dev/%s of=/zImage" % getMachineMtdKernel()) # backup old kernel - cmdlist.append("dd if=/usr/bin/kernel_auto.bin of=/dev/%s" % getMachineMtdKernel()) # create new kernel + cmdlist.append("dd if=/dev/%s of=/zImage" % SystemInfo["mtdkernel"]) # backup old kernel + cmdlist.append("dd if=/usr/bin/kernel_auto.bin of=/dev/%s" % SystemInfo["mtdkernel"]) # create new kernel cmdlist.append("mv /usr/bin/STARTUP.cpio.gz /STARTUP.cpio.gz") # copy userroot routine for file in glob.glob("/media/*/vuplus/*/force.update", recursive=True): cmdlist.append("mv %s %s" % (file, file.replace("force.update", "noforce.update"))) # remove Vu force update(Vu+ Zero4k) @@ -111,21 +111,21 @@ def welcomeAction(self, answer): if xline.find("/media/hdd") != -1 and "ext4" in xline: hddExt4 = True break - if hddExt4 and pathExists("/media/hdd/%s/linuxrootfs1" % getBoxType()): + if hddExt4 and pathExists("/media/hdd/%s/linuxrootfs1" % SystemInfo["boxtype"]): self.Console.eBatch(cmdlist, self.eMMCload, debug=True) elif hddExt4: - if not pathExists("/media/hdd/%s" % getBoxType()): - cmdlist.append("mkdir /media/hdd/%s" % getBoxType()) + if not pathExists("/media/hdd/%s" % SystemInfo["boxtype"]): + cmdlist.append("mkdir /media/hdd/%s" % SystemInfo["boxtype"]) cmdlist.append("mkdir /tmp/mmc") - cmdlist.append("mount /dev/%s /tmp/mmc" % getMachineMtdRoot()) - cmdlist.append("rsync -aAXHS /tmp/mmc/ /media/hdd/%s/linuxrootfs1" % getBoxType()) + cmdlist.append("mount /dev/%s /tmp/mmc" % SystemInfo["mtdrootfs"]) + cmdlist.append("rsync -aAXHS /tmp/mmc/ /media/hdd/%s/linuxrootfs1" % SystemInfo["boxtype"]) cmdlist.append("umount /tmp/mmc") - cmdlist.append("cp /zImage /media/hdd/%s/linuxrootfs1/" % getBoxType()) + cmdlist.append("cp /zImage /media/hdd/%s/linuxrootfs1/" % SystemInfo["boxtype"]) self.Console.eBatch(cmdlist, self.eMMCload, debug=True) else: cmdlist.append("mkdir /tmp/mmc") cmdlist.append("mkdir /linuxrootfs1") - cmdlist.append("mount /dev/%s /tmp/mmc" % getMachineMtdRoot()) + cmdlist.append("mount /dev/%s /tmp/mmc" % SystemInfo["mtdrootfs"]) cmdlist.append("/bin/tar -jcf /tmp/linuxrootfs1.tar.bz2 -C /tmp/mmc --exclude ./var/nmbd --exclude ./.resizerootfs --exclude ./linuxrootfs* --exclude ./.resize-rootfs --exclude ./.resize-linuxrootfs --exclude ./.resize-userdata --exclude ./var/lib/samba/private/msg.sock .") cmdlist.append("/bin/tar -jxf /tmp/linuxrootfs1.tar.bz2 -C /linuxrootfs1 .") cmdlist.append("cp /zimage /linuxrootfs1/") @@ -137,11 +137,11 @@ def welcomeAction(self, answer): def eMMCload(self, *args, **kwargs): cmdlist = [] for eMMCslot in range(1, 4): - if pathExists("/media/hdd/%s/linuxrootfs%s" % (getBoxType(), eMMCslot)): - cmdlist.append("cp -R /media/hdd/%s/linuxrootfs%s . /" % (getBoxType(), eMMCslot)) - cmdlist.append("rm -r /media/hdd/%s/linuxrootfs%s" % (getBoxType(), eMMCslot)) + if pathExists("/media/hdd/%s/linuxrootfs%s" % (SystemInfo["boxtype"], eMMCslot)): + cmdlist.append("cp -R /media/hdd/%s/linuxrootfs%s . /" % (SystemInfo["boxtype"], eMMCslot)) + cmdlist.append("rm -r /media/hdd/%s/linuxrootfs%s" % (SystemInfo["boxtype"], eMMCslot)) if cmdlist: - cmdlist.append("rm -rf /media/hdd/%s" % getBoxType()) + cmdlist.append("rm -rf /media/hdd/%s" % SystemInfo["boxtype"]) self.Console.eBatch(cmdlist, self.reBoot, debug=False) else: self.reBoot() diff --git a/lib/python/Screens/Wizard.py b/lib/python/Screens/Wizard.py index 3be7ae13c25..11595c37f78 100644 --- a/lib/python/Screens/Wizard.py +++ b/lib/python/Screens/Wizard.py @@ -3,7 +3,6 @@ from enigma import eTimer, eEnv -from boxbranding import getMachineBrand, getMachineName from Components.ActionMap import NumberActionMap from Components.config import config, ConfigText, ConfigPassword, KEY_LEFT, KEY_RIGHT, KEY_0, KEY_DELETE, KEY_BACKSPACE, KEY_ASCII # noqa: F401 from Components.ConfigList import ConfigList @@ -11,6 +10,7 @@ from Components.Slider import Slider from Components.Sources.List import List from Components.Sources.StaticText import StaticText +from Components.SystemInfo import SystemInfo from Screens.MessageBox import MessageBox from Screens.Screen import Screen @@ -462,7 +462,7 @@ def runCode(self, code): return False def getTranslation(self, text): - return _(text).replace("%s %s", "%s %s" % (getMachineBrand(), getMachineName())) + return _(text).replace("%s %s", "%s %s" % (SystemInfo["MachineBrand"], SystemInfo["MachineName"])) def updateText(self, firstset=False): text = self.getTranslation(self.wizard[self.currStep]["text"]) diff --git a/lib/python/StartEnigma.py b/lib/python/StartEnigma.py index 9372c0a7442..de5c37acac8 100644 --- a/lib/python/StartEnigma.py +++ b/lib/python/StartEnigma.py @@ -4,7 +4,6 @@ from datetime import datetime from traceback import print_exc -from boxbranding import getImageArch, getImageBuild, getImageDevBuild, getImageType, getImageVersion from Tools.Profile import profile, profile_final import Tools.RedirectOutput # noqa: F401 # Don't remove this line. It may seem to do nothing, but if removed it will break output redirection for crash logs. import eConsoleImpl @@ -441,12 +440,14 @@ def runNextScreen(session, screensToRun, *result): profile("PYTHON_START") +from Components.SystemInfo import SystemInfo # noqa: E402 don't move this import + print("[StartEnigma] Starting Python Level Initialisation.") -print("[StartEnigma] Image Type -> '%s'" % getImageType()) -print("[StartEnigma] Image Version -> '%s'" % getImageVersion()) -print("[StartEnigma] Image Build -> '%s'" % getImageBuild()) -if getImageType() != "release": - print("[StartEnigma] Image DevBuild -> '%s'" % getImageDevBuild()) +print("[StartEnigma] Image Type -> '%s'" % SystemInfo["imagetype"]) +print("[StartEnigma] Image Version -> '%s'" % SystemInfo["imageversion"]) +print("[StartEnigma] Image Build -> '%s'" % SystemInfo["imagebuild"]) +if SystemInfo["imagetype"] != "release": + print("[StartEnigma] Image DevBuild -> '%s'" % SystemInfo["imagedevbuild"]) # SetupDevices sets up defaults:- language, keyboard, parental & expert config. @@ -457,7 +458,7 @@ def runNextScreen(session, screensToRun, *result): from Components.SetupDevices import InitSetupDevices # noqa: E402 InitSetupDevices() -if getImageArch() in ("aarch64"): +if SystemInfo["architecture"] in ("aarch64"): # something not right here from usb.backend import libusb1 # noqa: E402 libusb1.get_backend(find_library=lambda x: "/lib64/libusb-1.0.so.0") @@ -471,7 +472,7 @@ def runNextScreen(session, screensToRun, *result): print("[StartEnigma] Initialising InfoBar.") from Screens import InfoBar # noqa: E402 -from Components.SystemInfo import SystemInfo # noqa: E402 don't move this import +#from Components.SystemInfo import SystemInfo # noqa: E402 don't move this import VuRecovery = SystemInfo["HasKexecMultiboot"] and SystemInfo["MultiBootSlot"] == 0 # print("[StartEnigma] Is this VuRecovery?. Recovery = ", VuRecovery) diff --git a/lib/python/Tools/Downloader.py b/lib/python/Tools/Downloader.py index c6fa0b6db0c..50ff9714116 100644 --- a/lib/python/Tools/Downloader.py +++ b/lib/python/Tools/Downloader.py @@ -2,7 +2,7 @@ import requests from twisted.internet import reactor from urllib.request import urlopen, Request -from boxbranding import getMachineBrand, getMachineName +from Components.SystemInfo import SystemInfo from enigma import eTimer @@ -10,7 +10,7 @@ class DownloadWithProgress: def __init__(self, url, outputFile, *args, **kwargs): self.url = url self.outputFile = outputFile - self.userAgent = "%s %s HbbTV/1.1.1 (+PVR+RTSP+DL; Sonic; TV44; 1.32.455; 2.002) Bee/3.5" % (getMachineBrand(), getMachineName()) + self.userAgent = "%s %s HbbTV/1.1.1 (+PVR+RTSP+DL; Sonic; TV44; 1.32.455; 2.002) Bee/3.5" % (SystemInfo["MachineBrand"], SystemInfo["MachineName"]) self.totalSize = 0 self.progress = 0 self.progressCallback = None diff --git a/lib/python/Tools/HardwareInfo.py b/lib/python/Tools/HardwareInfo.py index 3ccc31b8ff2..6d58be5d8b4 100644 --- a/lib/python/Tools/HardwareInfo.py +++ b/lib/python/Tools/HardwareInfo.py @@ -1,4 +1,3 @@ -from boxbranding import getBoxType, getBrandOEM from Components.About import about @@ -45,10 +44,12 @@ def get_device_version(self): return HardwareInfo.device_version def has_hdmi(self): - return getBrandOEM() in ('xtrend', 'gigablue', 'dags', 'ixuss', 'odin', 'vuplus', 'ini', 'ebox', 'ceryon') or (getBoxType() in ('dm7020hd', 'dm800se', 'dm500hd', 'dm8000') and HardwareInfo.device_version is not None) + from Components.SystemInfo import SystemInfo + return SystemInfo["brand"] in ('xtrend', 'gigablue', 'dags', 'ixuss', 'odin', 'vuplus', 'ini', 'ebox', 'ceryon') or (SystemInfo["boxtype"] in ('dm7020hd', 'dm800se', 'dm500hd', 'dm8000') and HardwareInfo.device_version is not None) def has_deepstandby(self): - return getBoxType() != 'dm800' + # from Components.SystemInfo import SystemInfo + return True # SystemInfo["boxtype"] != 'dm800' def is_nextgen(self): if about.getCpuCoresInt() < 2 or about.getCPUSpeedMHzInt() < 750: diff --git a/lib/python/Tools/Multiboot.py b/lib/python/Tools/Multiboot.py index f4330a7bb74..14f1fd7be89 100644 --- a/lib/python/Tools/Multiboot.py +++ b/lib/python/Tools/Multiboot.py @@ -4,7 +4,6 @@ import tempfile from os import path, rmdir, rename, sep, stat -from boxbranding import getMachineMtdRoot from Components.Console import Console from Components.SystemInfo import SystemInfo, BoxInfo as BoxInfoRunningInstance, BoxInformation from Tools.Directories import fileHas, fileExists @@ -15,7 +14,7 @@ from PIL import ImageFont MbootList1 = ("/dev/mmcblk0p1", "/dev/mmcblk1p1", "/dev/mmcblk0p3", "/dev/mmcblk0p4", "/dev/mtdblock2", "/dev/block/by-name/bootoptions") -MbootList2 = ("/dev/%s" % getMachineMtdRoot(), ) # kexec kernel Vu+ multiboot +MbootList2 = ("/dev/%s" % SystemInfo["mtdrootfs"], ) # kexec kernel Vu+ multiboot class tmp: diff --git a/lib/python/Tools/Profile.py b/lib/python/Tools/Profile.py index 43c51061933..d4cf4234539 100644 --- a/lib/python/Tools/Profile.py +++ b/lib/python/Tools/Profile.py @@ -1,5 +1,5 @@ # the implementation here is a bit crappy. -from boxbranding import getBoxType, getMachineBuild +# from boxbranding import getBoxType, getMachineBuild import time from Tools.Directories import resolveFilename, SCOPE_CONFIG @@ -37,21 +37,23 @@ def profile(id): # GML: Set the device and format here...probably more could be added? # - box_type = getBoxType() - if box_type in ("odinm7", "odinm6", "xp1000s"): - dev_fmt = ("/dev/dbox/oled0", "%d") - elif box_type in ("gb800se", "gb800solo"): - dev_fmt = ("/dev/dbox/oled0", "%d \n") - elif box_type == "mbtwin": - dev_fmt = ("/dev/dbox/oled0", "%d%%") - elif box_type == "gb800seplus": - dev_fmt = ("/dev/mcu", "%d \n") - elif box_type == "ebox5000": - dev_fmt = ("/proc/progress", "%d"), - elif getMachineBuild() in ("inihdp", "inihdx"): - dev_fmt = ("/proc/vfd", "Loading %d%%\n") - else: - dev_fmt = ("/proc/progress", "%d \n") + # box_type = getBoxType() + # if box_type in ("odinm7", "odinm6", "xp1000s"): + # dev_fmt = ("/dev/dbox/oled0", "%d") + # elif box_type in ("gb800se", "gb800solo"): + # dev_fmt = ("/dev/dbox/oled0", "%d \n") + # elif box_type == "mbtwin": + # dev_fmt = ("/dev/dbox/oled0", "%d%%") + # elif box_type == "gb800seplus": + # dev_fmt = ("/dev/mcu", "%d \n") + # elif box_type == "ebox5000": + # dev_fmt = ("/proc/progress", "%d"), + # elif getMachineBuild() in ("inihdp", "inihdx"): + # dev_fmt = ("/proc/vfd", "Loading %d%%\n") + # else: + # dev_fmt = ("/proc/progress", "%d \n") + + dev_fmt = ("/proc/progress", "%d \n") (dev, fmt) = dev_fmt if profile_file: From 62eca7a8c2dd91258e5555ce9d5dba418cb9a536 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sun, 31 Dec 2023 02:07:03 +0000 Subject: [PATCH 394/401] PEP8 double aggressive E251 and E252 --- .../Plugins/Extensions/DVDBurn/DVDProject.py | 148 +++++++++--------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py b/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py index 6049c984715..75af6fccbbf 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py +++ b/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py @@ -40,26 +40,26 @@ def __init__(self): self.settings = ConfigSubsection() self.settings.name = ConfigText(fixed_size=False, visible_width=40) self.settings.authormode = ConfigSelection(choices=[("menu_linked", _("Linked titles with a DVD menu")), ("just_linked", _("Direct playback of linked titles without menu")), ("menu_seperate", _("Seperate titles with a main menu")), ("data_ts", _("%s %s format data DVD (HDTV compatible)") % getBoxDisplayName()))]) - self.settings.titlesetmode = ConfigSelection(choices=[("single", _("Simple titleset (compatibility for legacy players)")), ("multi", _("Complex (allows mixing audio tracks and aspects)"))], default="multi") - self.settings.output = ConfigSelection(choices=[("iso", _("Create DVD-ISO")), ("dvd", _("Burn DVD"))]) - self.settings.isopath = ConfigText(fixed_size=False, visible_width=40) - self.settings.dataformat = ConfigSelection(choices=[("iso9660_1", "ISO9660 Level 1"), ("iso9660_4", "ISO9660 version 2"), ("udf", "UDF")]) - self.settings.menutemplate = ConfigFilename() - self.settings.vmgm = ConfigFilename() - self.filekeys = ["vmgm", "isopath", "menutemplate"] - self.menutemplate = MenuTemplate() - self.error = "" - self.session = None + self.settings.titlesetmode=ConfigSelection(choices=[("single", _("Simple titleset (compatibility for legacy players)")), ("multi", _("Complex (allows mixing audio tracks and aspects)"))], default="multi") + self.settings.output=ConfigSelection(choices=[("iso", _("Create DVD-ISO")), ("dvd", _("Burn DVD"))]) + self.settings.isopath=ConfigText(fixed_size=False, visible_width=40) + self.settings.dataformat=ConfigSelection(choices=[("iso9660_1", "ISO9660 Level 1"), ("iso9660_4", "ISO9660 version 2"), ("udf", "UDF")]) + self.settings.menutemplate=ConfigFilename() + self.settings.vmgm=ConfigFilename() + self.filekeys=["vmgm", "isopath", "menutemplate"] + self.menutemplate=MenuTemplate() + self.error="" + self.session=None def addService(self, service): - title = DVDTitle.DVDTitle(self) + title=DVDTitle.DVDTitle(self) title.addService(service) self.titles.append(title) return title def saveProject(self, path): from Tools.XMLTools import stringToXML - list = ['\n', + list=['\n', '\n', '\t\n') list.append('\t\t\t\n') @@ -90,14 +90,14 @@ def saveProject(self, path): list.append('\t\n') list.append('\n') - name = self.settings.name.value - i = 0 - filename = path + name + ".ddvdp.xml" + name=self.settings.name.value + i=0 + filename=path + name + ".ddvdp.xml" while fileExists(filename): i += 1 - filename = path + name + str(i).zfill(3) + ".ddvdp.xml" + filename=path + name + str(i).zfill(3) + ".ddvdp.xml" try: - file = open(filename, "w") + file=open(filename, "w") for x in list: file.write(x) file.close() @@ -106,21 +106,21 @@ def saveProject(self, path): return filename def load(self, filename): - ret = self.loadProject(filename) + ret=self.loadProject(filename) if ret: - ret = self.menutemplate.loadTemplate(self.settings.menutemplate.value) + ret=self.menutemplate.loadTemplate(self.settings.menutemplate.value) self.error += self.menutemplate.error return ret def loadProject(self, filename): # try: if not fileExists(filename): - self.error = "xml file not found!" + self.error="xml file not found!" # raise AttributeError - file = open(filename, "r") - data = file.read().decode("utf-8").replace('&', "&").encode("ascii", 'xmlcharrefreplace') + file=open(filename, "r") + data=file.read().decode("utf-8").replace('&', "&").encode("ascii", 'xmlcharrefreplace') file.close() - projectfiledom = xml.dom.minidom.parseString(data) + projectfiledom=xml.dom.minidom.parseString(data) for node in projectfiledom.childNodes[0].childNodes: print("node:", node) if node.nodeType == xml.dom.minidom.Element.nodeType: @@ -130,13 +130,13 @@ def loadProject(self, filename): self.xmlGetTitleNodeRecursive(node) for key in self.filekeys: - val = self.settings.dict()[key].value + val=self.settings.dict()[key].value if not fileExists(val): if val[0] != "/": if key.find("font") == 0: - val = resolveFilename(SCOPE_FONTS) + val + val=resolveFilename(SCOPE_FONTS) + val else: - val = resolveFilename(SCOPE_PLUGINS) + "Extensions/DVDBurn/" + val + val=resolveFilename(SCOPE_PLUGINS) + "Extensions/DVDBurn/" + val if fileExists(val): self.settings.dict()[key].setValue(val) continue @@ -149,22 +149,22 @@ def loadProject(self, filename): def xmlAttributesToConfig(self, node, config): try: - i = 0 + i=0 # if node.attributes.length < len(config.dict())-1: # self.error = "project attributes missing" # raise AttributeError while i < node.attributes.length: - item = node.attributes.item(i) - key = str(item.name) + item=node.attributes.item(i) + key=str(item.name) try: - val = eval(item.nodeValue) + val=eval(item.nodeValue) except (NameError, SyntaxError): - val = str(item.nodeValue) + val=str(item.nodeValue) try: print("config[%s].setValue(%s)" % (key, val)) config.dict()[key].setValue(val) except KeyError: - self.error = "unknown attribute '%s'" % key + self.error="unknown attribute '%s'" % key print("KeyError", self.error) raise AttributeError i += 1 @@ -180,12 +180,12 @@ def xmlGetTitleNodeRecursive(self, node, title_idx=-1): if subnode.nodeType == xml.dom.minidom.Element.nodeType: if subnode.tagName == 'title': title_idx += 1 - title = DVDTitle.DVDTitle(self) + title=DVDTitle.DVDTitle(self) self.titles.append(title) self.xmlGetTitleNodeRecursive(subnode, title_idx) if subnode.tagName == 'path': print("path:", subnode.firstChild.data) - filename = subnode.firstChild.data + filename=subnode.firstChild.data self.titles[title_idx].addFile(str(filename)) if subnode.tagName == 'properties': self.xmlAttributesToConfig(node, self.titles[title_idx].properties) @@ -195,55 +195,55 @@ def xmlGetTitleNodeRecursive(self, node, title_idx=-1): print("audiotrack...", subnode.toxml()) def getSize(self): - totalsize = 0 + totalsize=0 for title in self.titles: totalsize += title.estimatedDiskspace return totalsize - size = property(getSize) + size=property(getSize) class MenuTemplate(DVDProject): def __init__(self): - self.settings = ConfigSubsection() - self.settings.titleformat = ConfigText(fixed_size=False, visible_width=40) - self.settings.subtitleformat = ConfigText(fixed_size=False, visible_width=40) - self.settings.menubg = ConfigFilename() - self.settings.menuaudio = ConfigFilename() - self.settings.dimensions = ConfigSequence(seperator=',', default=[576, 720], limits=[(352, 720), (480, 576)]) - self.settings.rows = ConfigInteger(default=4, limits=(1, 10)) - self.settings.cols = ConfigInteger(default=1, limits=(1, 4)) - self.settings.color_headline = ConfigColor() - self.settings.color_headline = ConfigColor() - self.settings.color_highlight = ConfigColor() - self.settings.color_button = ConfigColor() - self.settings.fontface_headline = ConfigFilename() - self.settings.fontface_title = ConfigFilename() - self.settings.fontface_subtitle = ConfigFilename() - self.settings.fontsize_headline = ConfigInteger(default=46, limits=(0, 199)) - self.settings.fontsize_title = ConfigInteger(default=24, limits=(0, 199)) - self.settings.fontsize_subtitle = ConfigInteger(default=14, limits=(0, 199)) - self.settings.margin_top = ConfigInteger(default=120, limits=(0, 500)) - self.settings.margin_bottom = ConfigInteger(default=40, limits=(0, 500)) - self.settings.margin_left = ConfigInteger(default=56, limits=(0, 500)) - self.settings.margin_right = ConfigInteger(default=56, limits=(0, 500)) - self.settings.space_rows = ConfigInteger(default=32, limits=(0, 500)) - self.settings.space_cols = ConfigInteger(default=24, limits=(0, 500)) - self.settings.prev_page_text = ConfigText(default="<<<", fixed_size=False) - self.settings.next_page_text = ConfigText(default=">>>", fixed_size=False) - self.settings.offset_headline = ConfigSequence(seperator=',', default=[0, 0], limits=[(-1, 500), (-1, 500)]) - self.settings.offset_title = ConfigSequence(seperator=',', default=[0, 0], limits=[(-1, 500), (-1, 500)]) - self.settings.offset_subtitle = ConfigSequence(seperator=',', default=[20, 0], limits=[(-1, 500), (-1, 500)]) - self.settings.offset_thumb = ConfigSequence(seperator=',', default=[40, 0], limits=[(-1, 500), (-1, 500)]) - self.settings.thumb_size = ConfigSequence(seperator=',', default=[200, 158], limits=[(0, 576), (-1, 720)]) - self.settings.thumb_border = ConfigInteger(default=2, limits=(0, 20)) - self.filekeys = ["menubg", "menuaudio", "fontface_headline", "fontface_title", "fontface_subtitle"] + self.settings=ConfigSubsection() + self.settings.titleformat=ConfigText(fixed_size=False, visible_width=40) + self.settings.subtitleformat=ConfigText(fixed_size=False, visible_width=40) + self.settings.menubg=ConfigFilename() + self.settings.menuaudio=ConfigFilename() + self.settings.dimensions=ConfigSequence(seperator=',', default=[576, 720], limits=[(352, 720), (480, 576)]) + self.settings.rows=ConfigInteger(default=4, limits=(1, 10)) + self.settings.cols=ConfigInteger(default=1, limits=(1, 4)) + self.settings.color_headline=ConfigColor() + self.settings.color_headline=ConfigColor() + self.settings.color_highlight=ConfigColor() + self.settings.color_button=ConfigColor() + self.settings.fontface_headline=ConfigFilename() + self.settings.fontface_title=ConfigFilename() + self.settings.fontface_subtitle=ConfigFilename() + self.settings.fontsize_headline=ConfigInteger(default=46, limits=(0, 199)) + self.settings.fontsize_title=ConfigInteger(default=24, limits=(0, 199)) + self.settings.fontsize_subtitle=ConfigInteger(default=14, limits=(0, 199)) + self.settings.margin_top=ConfigInteger(default=120, limits=(0, 500)) + self.settings.margin_bottom=ConfigInteger(default=40, limits=(0, 500)) + self.settings.margin_left=ConfigInteger(default=56, limits=(0, 500)) + self.settings.margin_right=ConfigInteger(default=56, limits=(0, 500)) + self.settings.space_rows=ConfigInteger(default=32, limits=(0, 500)) + self.settings.space_cols=ConfigInteger(default=24, limits=(0, 500)) + self.settings.prev_page_text=ConfigText(default="<<<", fixed_size=False) + self.settings.next_page_text=ConfigText(default=">>>", fixed_size=False) + self.settings.offset_headline=ConfigSequence(seperator=',', default=[0, 0], limits=[(-1, 500), (-1, 500)]) + self.settings.offset_title=ConfigSequence(seperator=',', default=[0, 0], limits=[(-1, 500), (-1, 500)]) + self.settings.offset_subtitle=ConfigSequence(seperator=',', default=[20, 0], limits=[(-1, 500), (-1, 500)]) + self.settings.offset_thumb=ConfigSequence(seperator=',', default=[40, 0], limits=[(-1, 500), (-1, 500)]) + self.settings.thumb_size=ConfigSequence(seperator=',', default=[200, 158], limits=[(0, 576), (-1, 720)]) + self.settings.thumb_border=ConfigInteger(default=2, limits=(0, 20)) + self.filekeys=["menubg", "menuaudio", "fontface_headline", "fontface_title", "fontface_subtitle"] from .TitleProperties import languageChoices - self.settings.menulang = ConfigSelection(choices=languageChoices.choices, default=languageChoices.choices[1][0]) - self.error = "" + self.settings.menulang=ConfigSelection(choices=languageChoices.choices, default=languageChoices.choices[1][0]) + self.error="" def loadTemplate(self, filename): - ret = DVDProject.loadProject(self, filename) - DVDProject.error = self.error + ret=DVDProject.loadProject(self, filename) + DVDProject.error=self.error return ret From 9970d542f066f482a8640bf94f7cd02416250622 Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sun, 31 Dec 2023 02:07:24 +0000 Subject: [PATCH 395/401] PEP8 double aggressive E22, E224, E241, E242 and E27 --- .../Plugins/Extensions/DVDBurn/DVDProject.py | 148 +++++++++--------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py b/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py index 75af6fccbbf..6049c984715 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py +++ b/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py @@ -40,26 +40,26 @@ def __init__(self): self.settings = ConfigSubsection() self.settings.name = ConfigText(fixed_size=False, visible_width=40) self.settings.authormode = ConfigSelection(choices=[("menu_linked", _("Linked titles with a DVD menu")), ("just_linked", _("Direct playback of linked titles without menu")), ("menu_seperate", _("Seperate titles with a main menu")), ("data_ts", _("%s %s format data DVD (HDTV compatible)") % getBoxDisplayName()))]) - self.settings.titlesetmode=ConfigSelection(choices=[("single", _("Simple titleset (compatibility for legacy players)")), ("multi", _("Complex (allows mixing audio tracks and aspects)"))], default="multi") - self.settings.output=ConfigSelection(choices=[("iso", _("Create DVD-ISO")), ("dvd", _("Burn DVD"))]) - self.settings.isopath=ConfigText(fixed_size=False, visible_width=40) - self.settings.dataformat=ConfigSelection(choices=[("iso9660_1", "ISO9660 Level 1"), ("iso9660_4", "ISO9660 version 2"), ("udf", "UDF")]) - self.settings.menutemplate=ConfigFilename() - self.settings.vmgm=ConfigFilename() - self.filekeys=["vmgm", "isopath", "menutemplate"] - self.menutemplate=MenuTemplate() - self.error="" - self.session=None + self.settings.titlesetmode = ConfigSelection(choices=[("single", _("Simple titleset (compatibility for legacy players)")), ("multi", _("Complex (allows mixing audio tracks and aspects)"))], default="multi") + self.settings.output = ConfigSelection(choices=[("iso", _("Create DVD-ISO")), ("dvd", _("Burn DVD"))]) + self.settings.isopath = ConfigText(fixed_size=False, visible_width=40) + self.settings.dataformat = ConfigSelection(choices=[("iso9660_1", "ISO9660 Level 1"), ("iso9660_4", "ISO9660 version 2"), ("udf", "UDF")]) + self.settings.menutemplate = ConfigFilename() + self.settings.vmgm = ConfigFilename() + self.filekeys = ["vmgm", "isopath", "menutemplate"] + self.menutemplate = MenuTemplate() + self.error = "" + self.session = None def addService(self, service): - title=DVDTitle.DVDTitle(self) + title = DVDTitle.DVDTitle(self) title.addService(service) self.titles.append(title) return title def saveProject(self, path): from Tools.XMLTools import stringToXML - list=['\n', + list = ['\n', '\n', '\t\n') list.append('\t\t\t\n') @@ -90,14 +90,14 @@ def saveProject(self, path): list.append('\t\n') list.append('\n') - name=self.settings.name.value - i=0 - filename=path + name + ".ddvdp.xml" + name = self.settings.name.value + i = 0 + filename = path + name + ".ddvdp.xml" while fileExists(filename): i += 1 - filename=path + name + str(i).zfill(3) + ".ddvdp.xml" + filename = path + name + str(i).zfill(3) + ".ddvdp.xml" try: - file=open(filename, "w") + file = open(filename, "w") for x in list: file.write(x) file.close() @@ -106,21 +106,21 @@ def saveProject(self, path): return filename def load(self, filename): - ret=self.loadProject(filename) + ret = self.loadProject(filename) if ret: - ret=self.menutemplate.loadTemplate(self.settings.menutemplate.value) + ret = self.menutemplate.loadTemplate(self.settings.menutemplate.value) self.error += self.menutemplate.error return ret def loadProject(self, filename): # try: if not fileExists(filename): - self.error="xml file not found!" + self.error = "xml file not found!" # raise AttributeError - file=open(filename, "r") - data=file.read().decode("utf-8").replace('&', "&").encode("ascii", 'xmlcharrefreplace') + file = open(filename, "r") + data = file.read().decode("utf-8").replace('&', "&").encode("ascii", 'xmlcharrefreplace') file.close() - projectfiledom=xml.dom.minidom.parseString(data) + projectfiledom = xml.dom.minidom.parseString(data) for node in projectfiledom.childNodes[0].childNodes: print("node:", node) if node.nodeType == xml.dom.minidom.Element.nodeType: @@ -130,13 +130,13 @@ def loadProject(self, filename): self.xmlGetTitleNodeRecursive(node) for key in self.filekeys: - val=self.settings.dict()[key].value + val = self.settings.dict()[key].value if not fileExists(val): if val[0] != "/": if key.find("font") == 0: - val=resolveFilename(SCOPE_FONTS) + val + val = resolveFilename(SCOPE_FONTS) + val else: - val=resolveFilename(SCOPE_PLUGINS) + "Extensions/DVDBurn/" + val + val = resolveFilename(SCOPE_PLUGINS) + "Extensions/DVDBurn/" + val if fileExists(val): self.settings.dict()[key].setValue(val) continue @@ -149,22 +149,22 @@ def loadProject(self, filename): def xmlAttributesToConfig(self, node, config): try: - i=0 + i = 0 # if node.attributes.length < len(config.dict())-1: # self.error = "project attributes missing" # raise AttributeError while i < node.attributes.length: - item=node.attributes.item(i) - key=str(item.name) + item = node.attributes.item(i) + key = str(item.name) try: - val=eval(item.nodeValue) + val = eval(item.nodeValue) except (NameError, SyntaxError): - val=str(item.nodeValue) + val = str(item.nodeValue) try: print("config[%s].setValue(%s)" % (key, val)) config.dict()[key].setValue(val) except KeyError: - self.error="unknown attribute '%s'" % key + self.error = "unknown attribute '%s'" % key print("KeyError", self.error) raise AttributeError i += 1 @@ -180,12 +180,12 @@ def xmlGetTitleNodeRecursive(self, node, title_idx=-1): if subnode.nodeType == xml.dom.minidom.Element.nodeType: if subnode.tagName == 'title': title_idx += 1 - title=DVDTitle.DVDTitle(self) + title = DVDTitle.DVDTitle(self) self.titles.append(title) self.xmlGetTitleNodeRecursive(subnode, title_idx) if subnode.tagName == 'path': print("path:", subnode.firstChild.data) - filename=subnode.firstChild.data + filename = subnode.firstChild.data self.titles[title_idx].addFile(str(filename)) if subnode.tagName == 'properties': self.xmlAttributesToConfig(node, self.titles[title_idx].properties) @@ -195,55 +195,55 @@ def xmlGetTitleNodeRecursive(self, node, title_idx=-1): print("audiotrack...", subnode.toxml()) def getSize(self): - totalsize=0 + totalsize = 0 for title in self.titles: totalsize += title.estimatedDiskspace return totalsize - size=property(getSize) + size = property(getSize) class MenuTemplate(DVDProject): def __init__(self): - self.settings=ConfigSubsection() - self.settings.titleformat=ConfigText(fixed_size=False, visible_width=40) - self.settings.subtitleformat=ConfigText(fixed_size=False, visible_width=40) - self.settings.menubg=ConfigFilename() - self.settings.menuaudio=ConfigFilename() - self.settings.dimensions=ConfigSequence(seperator=',', default=[576, 720], limits=[(352, 720), (480, 576)]) - self.settings.rows=ConfigInteger(default=4, limits=(1, 10)) - self.settings.cols=ConfigInteger(default=1, limits=(1, 4)) - self.settings.color_headline=ConfigColor() - self.settings.color_headline=ConfigColor() - self.settings.color_highlight=ConfigColor() - self.settings.color_button=ConfigColor() - self.settings.fontface_headline=ConfigFilename() - self.settings.fontface_title=ConfigFilename() - self.settings.fontface_subtitle=ConfigFilename() - self.settings.fontsize_headline=ConfigInteger(default=46, limits=(0, 199)) - self.settings.fontsize_title=ConfigInteger(default=24, limits=(0, 199)) - self.settings.fontsize_subtitle=ConfigInteger(default=14, limits=(0, 199)) - self.settings.margin_top=ConfigInteger(default=120, limits=(0, 500)) - self.settings.margin_bottom=ConfigInteger(default=40, limits=(0, 500)) - self.settings.margin_left=ConfigInteger(default=56, limits=(0, 500)) - self.settings.margin_right=ConfigInteger(default=56, limits=(0, 500)) - self.settings.space_rows=ConfigInteger(default=32, limits=(0, 500)) - self.settings.space_cols=ConfigInteger(default=24, limits=(0, 500)) - self.settings.prev_page_text=ConfigText(default="<<<", fixed_size=False) - self.settings.next_page_text=ConfigText(default=">>>", fixed_size=False) - self.settings.offset_headline=ConfigSequence(seperator=',', default=[0, 0], limits=[(-1, 500), (-1, 500)]) - self.settings.offset_title=ConfigSequence(seperator=',', default=[0, 0], limits=[(-1, 500), (-1, 500)]) - self.settings.offset_subtitle=ConfigSequence(seperator=',', default=[20, 0], limits=[(-1, 500), (-1, 500)]) - self.settings.offset_thumb=ConfigSequence(seperator=',', default=[40, 0], limits=[(-1, 500), (-1, 500)]) - self.settings.thumb_size=ConfigSequence(seperator=',', default=[200, 158], limits=[(0, 576), (-1, 720)]) - self.settings.thumb_border=ConfigInteger(default=2, limits=(0, 20)) - self.filekeys=["menubg", "menuaudio", "fontface_headline", "fontface_title", "fontface_subtitle"] + self.settings = ConfigSubsection() + self.settings.titleformat = ConfigText(fixed_size=False, visible_width=40) + self.settings.subtitleformat = ConfigText(fixed_size=False, visible_width=40) + self.settings.menubg = ConfigFilename() + self.settings.menuaudio = ConfigFilename() + self.settings.dimensions = ConfigSequence(seperator=',', default=[576, 720], limits=[(352, 720), (480, 576)]) + self.settings.rows = ConfigInteger(default=4, limits=(1, 10)) + self.settings.cols = ConfigInteger(default=1, limits=(1, 4)) + self.settings.color_headline = ConfigColor() + self.settings.color_headline = ConfigColor() + self.settings.color_highlight = ConfigColor() + self.settings.color_button = ConfigColor() + self.settings.fontface_headline = ConfigFilename() + self.settings.fontface_title = ConfigFilename() + self.settings.fontface_subtitle = ConfigFilename() + self.settings.fontsize_headline = ConfigInteger(default=46, limits=(0, 199)) + self.settings.fontsize_title = ConfigInteger(default=24, limits=(0, 199)) + self.settings.fontsize_subtitle = ConfigInteger(default=14, limits=(0, 199)) + self.settings.margin_top = ConfigInteger(default=120, limits=(0, 500)) + self.settings.margin_bottom = ConfigInteger(default=40, limits=(0, 500)) + self.settings.margin_left = ConfigInteger(default=56, limits=(0, 500)) + self.settings.margin_right = ConfigInteger(default=56, limits=(0, 500)) + self.settings.space_rows = ConfigInteger(default=32, limits=(0, 500)) + self.settings.space_cols = ConfigInteger(default=24, limits=(0, 500)) + self.settings.prev_page_text = ConfigText(default="<<<", fixed_size=False) + self.settings.next_page_text = ConfigText(default=">>>", fixed_size=False) + self.settings.offset_headline = ConfigSequence(seperator=',', default=[0, 0], limits=[(-1, 500), (-1, 500)]) + self.settings.offset_title = ConfigSequence(seperator=',', default=[0, 0], limits=[(-1, 500), (-1, 500)]) + self.settings.offset_subtitle = ConfigSequence(seperator=',', default=[20, 0], limits=[(-1, 500), (-1, 500)]) + self.settings.offset_thumb = ConfigSequence(seperator=',', default=[40, 0], limits=[(-1, 500), (-1, 500)]) + self.settings.thumb_size = ConfigSequence(seperator=',', default=[200, 158], limits=[(0, 576), (-1, 720)]) + self.settings.thumb_border = ConfigInteger(default=2, limits=(0, 20)) + self.filekeys = ["menubg", "menuaudio", "fontface_headline", "fontface_title", "fontface_subtitle"] from .TitleProperties import languageChoices - self.settings.menulang=ConfigSelection(choices=languageChoices.choices, default=languageChoices.choices[1][0]) - self.error="" + self.settings.menulang = ConfigSelection(choices=languageChoices.choices, default=languageChoices.choices[1][0]) + self.error = "" def loadTemplate(self, filename): - ret=DVDProject.loadProject(self, filename) - DVDProject.error=self.error + ret = DVDProject.loadProject(self, filename) + DVDProject.error = self.error return ret From f045617d107a0708839f311ec590182a9bc4775d Mon Sep 17 00:00:00 2001 From: openvix-bot Date: Sun, 31 Dec 2023 02:07:59 +0000 Subject: [PATCH 396/401] PEP8 double aggressive W291 ~ W293 and W391 --- lib/python/Components/SystemInfo.py | 4 ++-- lib/python/Tools/Profile.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/python/Components/SystemInfo.py b/lib/python/Components/SystemInfo.py index 1bd963ca772..33bf2e757c5 100644 --- a/lib/python/Components/SystemInfo.py +++ b/lib/python/Components/SystemInfo.py @@ -134,7 +134,7 @@ def getBoxType(): # this function mimics the function of the same name in brand BoxInfo.setItem("boxtype", getBoxType(), immutable=True) - + def getMachineName(): # this function mimics the function of the same name in branding module if MACHINEBUILD == "sf8008": @@ -151,7 +151,7 @@ def getMachineName(): # this function mimics the function of the same name in b BoxInfo.setItem("machinename", getMachineName(), immutable=True) - + def getBoxDisplayName(): # This function returns a tuple like ("BRANDNAME", "BOXNAME") return (DISPLAYBRAND, SystemInfo["machinename"]) diff --git a/lib/python/Tools/Profile.py b/lib/python/Tools/Profile.py index d4cf4234539..381ab6e874b 100644 --- a/lib/python/Tools/Profile.py +++ b/lib/python/Tools/Profile.py @@ -52,7 +52,7 @@ def profile(id): # dev_fmt = ("/proc/vfd", "Loading %d%%\n") # else: # dev_fmt = ("/proc/progress", "%d \n") - + dev_fmt = ("/proc/progress", "%d \n") (dev, fmt) = dev_fmt From 053c55105da3fe618f071f9e3bbf549b83c8cddd Mon Sep 17 00:00:00 2001 From: Huevos Date: Sun, 31 Dec 2023 03:26:53 +0100 Subject: [PATCH 397/401] Fix errors in last commit --- lib/python/Plugins/Extensions/DVDBurn/DVDProject.py | 2 +- lib/python/Plugins/Extensions/DVDBurn/TitleList.py | 2 +- lib/python/Plugins/Extensions/MediaPlayer/plugin.py | 2 +- lib/python/Screens/NetworkSetup.py | 1 + lib/python/Screens/PluginBrowser.py | 1 + 5 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py b/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py index 6049c984715..510ffc44033 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py +++ b/lib/python/Plugins/Extensions/DVDBurn/DVDProject.py @@ -39,7 +39,7 @@ def __init__(self): self.target = None self.settings = ConfigSubsection() self.settings.name = ConfigText(fixed_size=False, visible_width=40) - self.settings.authormode = ConfigSelection(choices=[("menu_linked", _("Linked titles with a DVD menu")), ("just_linked", _("Direct playback of linked titles without menu")), ("menu_seperate", _("Seperate titles with a main menu")), ("data_ts", _("%s %s format data DVD (HDTV compatible)") % getBoxDisplayName()))]) + self.settings.authormode = ConfigSelection(choices=[("menu_linked", _("Linked titles with a DVD menu")), ("just_linked", _("Direct playback of linked titles without menu")), ("menu_seperate", _("Seperate titles with a main menu")), ("data_ts", _("%s %s format data DVD (HDTV compatible)") % getBoxDisplayName())]) self.settings.titlesetmode = ConfigSelection(choices=[("single", _("Simple titleset (compatibility for legacy players)")), ("multi", _("Complex (allows mixing audio tracks and aspects)"))], default="multi") self.settings.output = ConfigSelection(choices=[("iso", _("Create DVD-ISO")), ("dvd", _("Burn DVD"))]) self.settings.isopath = ConfigText(fixed_size=False, visible_width=40) diff --git a/lib/python/Plugins/Extensions/DVDBurn/TitleList.py b/lib/python/Plugins/Extensions/DVDBurn/TitleList.py index c6bd9814f26..e2ad1a4f0d3 100644 --- a/lib/python/Plugins/Extensions/DVDBurn/TitleList.py +++ b/lib/python/Plugins/Extensions/DVDBurn/TitleList.py @@ -364,7 +364,7 @@ def titleEditDone(self, cutlist): t = self.current_edit_title t.titleEditDone(cutlist) if t.VideoType != 0: - self.session.openWithCallback(self.DVDformatCB, MessageBox, text=_("The DVD standard doesn't support H.264 (HDTV) video streams. Do you want to create a %s %s format data DVD (which will not play in stand-alone DVD players) instead?") % (getMachineBrand(), getMachineName()), type=MessageBox.TYPE_YESNO) + self.session.openWithCallback(self.DVDformatCB, MessageBox, text=_("The DVD standard doesn't support H.264 (HDTV) video streams. Do you want to create a %s %s format data DVD (which will not play in stand-alone DVD players) instead?") % getBoxDisplayName(), type=MessageBox.TYPE_YESNO) else: self.updateTitleList() diff --git a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py index d9d5c43783c..cf6a5bbadd0 100644 --- a/lib/python/Plugins/Extensions/MediaPlayer/plugin.py +++ b/lib/python/Plugins/Extensions/MediaPlayer/plugin.py @@ -358,7 +358,7 @@ def __evVideoDecodeError(self): currPlay = self.session.nav.getCurrentService() sTagVideoCodec = currPlay.info().getInfoString(iServiceInformation.sTagVideoCodec) print("[__evVideoDecodeError] video-codec %s can't be decoded by hardware" % sTagVideoCodec) - self.session.open(MessageBox, _("This %s %s cannot decode %s streams!") % (getMachineBrand(), getMachineName(), sTagVideoCodec), type=MessageBox.TYPE_INFO, timeout=20) + self.session.open(MessageBox, _("This %s %s cannot decode %s streams!") % (SystemInfo["MachineBrand"], SystemInfo["MachineName"], sTagVideoCodec), type=MessageBox.TYPE_INFO, timeout=20) def __evPluginError(self): currPlay = self.session.nav.getCurrentService() diff --git a/lib/python/Screens/NetworkSetup.py b/lib/python/Screens/NetworkSetup.py index 148358be2a3..2517fab93aa 100644 --- a/lib/python/Screens/NetworkSetup.py +++ b/lib/python/Screens/NetworkSetup.py @@ -19,6 +19,7 @@ from Components.PluginComponent import plugins from Components.Sources.StaticText import StaticText from Components.Sources.List import List +from Components.SystemInfo import SystemInfo from Plugins.Plugin import PluginDescriptor from Screens.HelpMenu import HelpableScreen from Screens.MessageBox import MessageBox diff --git a/lib/python/Screens/PluginBrowser.py b/lib/python/Screens/PluginBrowser.py index 263d9a1b7f0..23e5ae3a1cc 100644 --- a/lib/python/Screens/PluginBrowser.py +++ b/lib/python/Screens/PluginBrowser.py @@ -13,6 +13,7 @@ from Components.PluginComponent import plugins from Components.PluginList import PluginList, PluginEntryComponent, PluginCategoryComponent, PluginDownloadComponent from Components.Sources.StaticText import StaticText +from Components.SystemInfo import SystemInfo from Plugins.Plugin import PluginDescriptor from Screens.ChoiceBox import ChoiceBox from Screens.Console import Console From af36a39d374fe69d4a358ee34515ea39fb1a01e2 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sun, 31 Dec 2023 03:37:29 +0100 Subject: [PATCH 398/401] [About] add missing import --- lib/python/Components/About.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/python/Components/About.py b/lib/python/Components/About.py index 02ae0fa2f53..bf5a28f805a 100644 --- a/lib/python/Components/About.py +++ b/lib/python/Components/About.py @@ -9,6 +9,7 @@ def getVersionString(): + from Components.SystemInfo import SystemInfo return SystemInfo["imageversion"] From 2b74eb7a139a248351bb63db7f881161eb4166b2 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sun, 31 Dec 2023 03:39:48 +0100 Subject: [PATCH 399/401] Fix PEP warning --- lib/python/Components/SystemInfo.py | 2 +- lib/python/StartEnigma.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/python/Components/SystemInfo.py b/lib/python/Components/SystemInfo.py index 33bf2e757c5..fbb76948d1d 100644 --- a/lib/python/Components/SystemInfo.py +++ b/lib/python/Components/SystemInfo.py @@ -29,7 +29,7 @@ def __init__(self, root=""): elif item: self.setItem(item, self.processValue(value), immutable=True) if self.boxInfo["checksumerror"]: - print("[BoxInfo] Data integrity of %s could not be verified." % file) + print("[BoxInfo] Data integrity of %s could not be verified." % file) # else: # print("[SystemInfo] Enigma information file data loaded into BoxInfo.") else: diff --git a/lib/python/StartEnigma.py b/lib/python/StartEnigma.py index de5c37acac8..99ac6df74aa 100644 --- a/lib/python/StartEnigma.py +++ b/lib/python/StartEnigma.py @@ -472,7 +472,7 @@ def runNextScreen(session, screensToRun, *result): print("[StartEnigma] Initialising InfoBar.") from Screens import InfoBar # noqa: E402 -#from Components.SystemInfo import SystemInfo # noqa: E402 don't move this import +# from Components.SystemInfo import SystemInfo # noqa: E402 don't move this import VuRecovery = SystemInfo["HasKexecMultiboot"] and SystemInfo["MultiBootSlot"] == 0 # print("[StartEnigma] Is this VuRecovery?. Recovery = ", VuRecovery) From c229f928ec7ebb96005ed79fe78fdba89f1e910f Mon Sep 17 00:00:00 2001 From: openvix-build Date: Sun, 31 Dec 2023 02:43:17 +0000 Subject: [PATCH 400/401] openvix: developer 6.4.011.008 --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 045d459f0ed..323b860a581 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1225,3 +1225,4 @@ openvix: developer 6.4.011.004 openvix: developer 6.4.011.005 openvix: developer 6.4.011.006 openvix: developer 6.4.011.007 +openvix: developer 6.4.011.008 From 85d001562cdc5d039b45b51e52bdd915c2a574d0 Mon Sep 17 00:00:00 2001 From: Huevos Date: Sun, 31 Dec 2023 04:36:11 +0100 Subject: [PATCH 401/401] [DOC] add a doc --- doc/BOXINFO_BOXBRANDING | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 doc/BOXINFO_BOXBRANDING diff --git a/doc/BOXINFO_BOXBRANDING b/doc/BOXINFO_BOXBRANDING new file mode 100644 index 00000000000..481eb4b55d4 --- /dev/null +++ b/doc/BOXINFO_BOXBRANDING @@ -0,0 +1,29 @@ +getBoxType = boxtype (only in OpenViX) +getBrandOEM = brand +getDisplayType = displaytype +getHaveAVJACK = avjack +getHaveHDMIinFHD = hdmifhdin +getHaveHDMIinHD = hdmihdin +getHaveRCA = rca +getHaveSCART = scart +getHaveSCARTYUV = scartyuv +getHaveYUV = yuv +getImageType = imagetype +getMachineBrand = displaybrand +getMachineBuild = model +getMachineMtdRoot = mtdrootfs +getMachineName = machinename (only in OpenViX) or MachineName +getDriverDate = driversdate +getImageDistro = distro +getDisplayType = displaytype +getFeedsUrl = feedsurl +getImageBuild = imagebuild +getImageVersion = imageversion +getMachineMake = machinebuild +getImageDevBuild = imagedevbuild +getImageFolder = imagedir +getImageFileSystem = imagefs +getMachineMtdKernel = mtdkernel +getMachineKernelFile = kernelfile +getMachineUBINIZE = ubinize +getMachineMKUBIFS = mkubifs