diff --git a/lcd4linux/src/Photoframe.py b/lcd4linux/src/Photoframe.py index 53a78f8..da247e5 100644 --- a/lcd4linux/src/Photoframe.py +++ b/lcd4linux/src/Photoframe.py @@ -1,11 +1,9 @@ -# -*- coding: UTF-8 -*- - from time import time, sleep from usb.core import find from usb.util import get_string from PIL import Image from struct import pack -from io import StringIO +from io import BytesIO def write_jpg2frame(dev, pic): @@ -20,85 +18,83 @@ def write_jpg2frame(dev, pic): endpoint = 0x02 # send to device in packages of = 2^16 psize = 65536 - for p in range(int(len(tdata) / psize)): + for p in range(len(tdata) // psize): pdata = tdata[p * psize:(p + 1) * psize] dev.write(endpoint, pdata) def get_known_devices(): - # Return a dict of photo frames - dlist = [] - # listed as: Name, idVendor, idProduct, [width , height - in pixel if applicable] - - # 0,1 Samsung SPF-75H/76H (23) - dlist.append({'name': "SPF75H/76H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x200f, 'width': 800, 'height': 480}) - dlist.append({'name': "SPF75H/76H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x200e}) - - # 2,3 Samsung SPF-87H (24) - dlist.append({'name': "SPF87H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2034, 'width': 800, 'height': 480}) - dlist.append({'name': "SPF87H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2033}) + # Return a list of supported photo frames. + # Each entry lists: Name, idVendor, idProduct, [width, height]. + return [ + # 0,1 Samsung SPF-75H/76H (23) + {'name': "SPF75H/76H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x200f, 'width': 800, 'height': 480}, + {'name': "SPF75H/76H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x200e}, - # 4,5 Samsung SPF-87Hold (25) - dlist.append({'name': "SPF87Hold Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2026, 'width': 800, 'height': 480}) - dlist.append({'name': "SPF87Hold Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2025}) + # 2,3 Samsung SPF-87H (24) + {'name': "SPF87H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2034, 'width': 800, 'height': 480}, + {'name': "SPF87H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2033}, - # 6,7 Samsung SPF-83H (26) - dlist.append({'name': "SPF83H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x200d, 'width': 800, 'height': 600}) - dlist.append({'name': "SPF83H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x200c}) + # 4,5 Samsung SPF-87Hold (25) + {'name': "SPF87Hold Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2026, 'width': 800, 'height': 480}, + {'name': "SPF87Hold Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2025}, - # 8,9 Samsung SPF-107H (27) - dlist.append({'name': "SPF107H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2036, 'width': 1024, 'height': 600}) - dlist.append({'name': "SPF107H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2035}) + # 6,7 Samsung SPF-83H (26) + {'name': "SPF83H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x200d, 'width': 800, 'height': 600}, + {'name': "SPF83H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x200c}, - # 10,11 Samsung SPF-105P (28) - dlist.append({'name': "SPF105P Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x201b, 'width': 1024, 'height': 600}) - dlist.append({'name': "SPF105P Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x201c}) + # 8,9 Samsung SPF-107H (27) + {'name': "SPF107H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2036, 'width': 1024, 'height': 600}, + {'name': "SPF107H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2035}, - # 12,13 Samsung SPF-85H/86H (29) - dlist.append({'name': "SPF85H/86H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2013, 'width': 800, 'height': 600}) - dlist.append({'name': "SPF85H/86H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2012}) + # 10,11 Samsung SPF-105P (28) + {'name': "SPF105P Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x201b, 'width': 1024, 'height': 600}, + {'name': "SPF105P Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x201c}, - # 14,15 Samsung SPF-72H (210) - dlist.append({'name': "SPF72H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x200b, 'width': 800, 'height': 480}) - dlist.append({'name': "SPF72H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x200a}) + # 12,13 Samsung SPF-85H/86H (29) + {'name': "SPF85H/86H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2013, 'width': 800, 'height': 600}, + {'name': "SPF85H/86H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2012}, - # 16,17 Samsung SPF-700T (211) - dlist.append({'name': "SPF700T Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2050, 'width': 800, 'height': 600}) - dlist.append({'name': "SPF700T Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x204f}) + # 14,15 Samsung SPF-72H (210) + {'name': "SPF72H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x200b, 'width': 800, 'height': 480}, + {'name': "SPF72H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x200a}, - # 18,19 Samsung SPF-85P/86P (212) - dlist.append({'name': "SPF85P/86P Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2017, 'width': 800, 'height': 600}) - dlist.append({'name': "SPF85P/86P Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2016}) + # 16,17 Samsung SPF-700T (211) + {'name': "SPF700T Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2050, 'width': 800, 'height': 600}, + {'name': "SPF700T Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x204f}, - # 20,21 Samsung SPF-107Hold (213) - dlist.append({'name': "SPF107Hold Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2028, 'width': 1024, 'height': 600}) - dlist.append({'name': "SPF107Hold Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2027}) + # 18,19 Samsung SPF-85P/86P (212) + {'name': "SPF85P/86P Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2017, 'width': 800, 'height': 600}, + {'name': "SPF85P/86P Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2016}, - # 22,23 Samsung SPF-1000P (214) - dlist.append({'name': "SPF1000P Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2040, 'width': 1024, 'height': 600}) - dlist.append({'name': "SPF1000P Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2039}) + # 20,21 Samsung SPF-107Hold (213) + {'name': "SPF107Hold Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2028, 'width': 1024, 'height': 600}, + {'name': "SPF107Hold Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2027}, - # 24,25 Samsung SPF-800P (215) - dlist.append({'name': "SPF800P Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2038, 'width': 800, 'height': 480}) - dlist.append({'name': "SPF800P Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2037}) + # 22,23 Samsung SPF-1000P (214) + {'name': "SPF1000P Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2040, 'width': 1024, 'height': 600}, + {'name': "SPF1000P Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2039}, - # 26,27 Samsung SPF-800W (216) - dlist.append({'name': "SPF800W Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x204c, 'width': 800, 'height': 600}) - dlist.append({'name': "SPF800W Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x204b}) + # 24,25 Samsung SPF-800P (215) + {'name': "SPF800P Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2038, 'width': 800, 'height': 480}, + {'name': "SPF800P Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2037}, - # 28,29 Samsung SPF-1000W (217) - dlist.append({'name': "SPF1000W Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x204e, 'width': 1024, 'height': 768}) - dlist.append({'name': "SPF1000W Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x204d}) + # 26,27 Samsung SPF-800W (216) + {'name': "SPF800W Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x204c, 'width': 800, 'height': 600}, + {'name': "SPF800W Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x204b}, - # Amazon Fire 7 (9th Generation 2019) - dlist.append({'name': "Amazon Fire 7 Mini Monitor", 'idVendor': 0x1949, 'idProduct': 0x03C3, 'width': 1024, 'height': 600}) - dlist.append({'name': "Amazon Fire 7 Mass Storage", 'idVendor': 0x1949, 'idProduct': 0x03C1}) + # 28,29 Samsung SPF-1000W (217) + {'name': "SPF1000W Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x204e, 'width': 1024, 'height': 768}, + {'name': "SPF1000W Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x204d}, - # Pearl DPF for Testing - dlist.append({'name': "Pearl DPF", 'idVendor': 0x1908, 'idProduct': 0x0102, 'width': 320, 'height': 240}) - dlist.append({'name': "Pearl DPF", 'idVendor': 0x1908, 'idProduct': 0x0102, 'width': 320, 'height': 240}) + # 30, 31 Amazon Fire 7 (9th Generation 2019) + {'name': "Amazon Fire 7 Mini Monitor", 'idVendor': 0x1949, 'idProduct': 0x03C3, 'width': 1024, 'height': 600}, + {'name': "Amazon Fire 7 Mass Storage", 'idVendor': 0x1949, 'idProduct': 0x03C1}, - return dlist + # 32, 33 Pearl DPF for Testing + {'name': "Pearl DPF", 'idVendor': 0x1908, 'idProduct': 0x0102, 'width': 320, 'height': 240}, + {'name': "Pearl DPF", 'idVendor': 0x1908, 'idProduct': 0x0102, 'width': 320, 'height': 240}, + ] def find_device(anzahl, device, device2): @@ -116,7 +112,7 @@ def find_device(anzahl, device, device2): except Exception: from traceback import format_exc print("[LCD4linux] find exception") - print("Error: %s" % format_exc()) + print(f"Error: {format_exc()}") d = None return d @@ -127,7 +123,7 @@ def init_device(anzahl, device0, device1): if dev is not None: # found it, trying to init it - print("[LCD4linux] Find frame device: %s" % dev) + print(f"[LCD4linux] Find frame device: {dev}") if dev.idProduct == device0["idProduct"]: print("[LCD4linux] init Device") frame_init(dev) @@ -212,7 +208,7 @@ def main(): # rotate # crop image = image.resize((800, 480)) - output = StringIO.StringIO() + output = BytesIO() image.save(output, "JPEG", quality=94) pic = output.getvalue() output.close() diff --git a/lcd4linux/src/WebConfigSite.py b/lcd4linux/src/WebConfigSite.py index 83cbe26..a0671e7 100644 --- a/lcd4linux/src/WebConfigSite.py +++ b/lcd4linux/src/WebConfigSite.py @@ -1,7 +1,7 @@ -# -*- coding: utf-8 -*- from glob import glob from os import stat from os.path import isfile, join, basename +from pathlib import Path from time import time from twisted.web import resource, http from html import unescape as _unescape @@ -18,8 +18,11 @@ from .configOptions import L1, L2, L3, L4 -DPKG = False -M = [_("OSD"), _("Screen"), _("Picture"), _("Weather"), _("Netatmo"), _("Popup-Text"), _("FritzCall"), _("Font"), _("Mail"), _("Calendar"), _("Remote Box"), _("WWW Converter"), _("WebIF"), _("MJPEG Stream"), _("Box-Skin-LCD"), _("Tuner"), _("Key"), _("BlueSound"), _("Sonos"), _("MusicCast")] +M = [ + _("OSD"), _("Screen"), _("Picture"), _("Weather"), _("Netatmo"), _("Popup-Text"), _("FritzCall"), _("Font"), _("Mail"), _("Calendar"), + _("Remote Box"), _("WWW Converter"), _("WebIF"), _("MJPEG Stream"), _("Box-Skin-LCD"), _("Tuner"), _("Key"), _("BlueSound"), _("Sonos"), + _("MusicCast") + ] Mode = "1" ModeOld = "" Element = "" @@ -29,28 +32,15 @@ L4LElement = L4Lelement() -def ensure_binary(s): - if isinstance(s, str): - return s.encode("utf-8") - return s - - -def ensure_str(s): - if isinstance(s, bytes): - return s.decode("utf-8") - return s - - def _exec(command): variable = command.split(" ", 1)[0] - exec("global %s;%s" % (variable, command)) + exec(f"global {variable};{command}") def _l(st): if isinstance(st, bytes): st = st.decode("utf-8", "ignore") - st = st.replace(" [ok]>", "").encode('ascii', 'xmlcharrefreplace') - return ensure_str(st) + return st.replace(" [ok]>", "").encode('ascii', 'xmlcharrefreplace').decode() def AktiveMode(Test, R): @@ -92,6 +82,13 @@ def restartTimer(self): self.StatusTimer.stop() self.StatusTimer.startLongTimer(60) + def sendTextFile(self, req, disposition, fileName): + req.setHeader('Content-type', 'text/plain') + req.setHeader('Content-Disposition', disposition) + req.setHeader('Content-Length', str(stat(fileName).st_size)) + req.setHeader('charset', 'UTF-8') + return Path(fileName).read_bytes() + def render_GET(self, request): L4logE("GET received", request.args) return self.action(request) @@ -102,12 +99,11 @@ def render_POST(self, request): def action(self, req): global Mode, ModeOld, Element, ElementList, ExeMode, StatusMode - IP = ensure_str(req.getClientIP()) - IP = IP.split(":")[-1] + IP = req.getClientIP() L4logE("IP1:", IP) if IP is None: L4logE("IP2:", req.client.host) - IP = None if IP.find(".") == -1 else req.client.host.split(":")[-1] + IP = req.client.host.split(":")[-1] if "." in req.client.host else None else: IP = IP.split(":")[-1] if IP is None: @@ -126,7 +122,7 @@ def action(self, req): if IP.startswith(x): Block = True break - if Block == True: + if Block is True: html = "" html += "\n" html += "\n" @@ -135,27 +131,29 @@ def action(self, req): html += "\n" html += "\n" html += "" - html += "Config-WebIF Access Deny ( IP: %s )
\n" % IP - html += "Please check Setting in Global > %s\n" % _l(_("WebIF IP Allow")) + html += f"Config-WebIF Access Deny ( IP: {IP} )
\n" + html += "Please check Setting in Global > {}\n".format(_l(_("WebIF IP Allow"))) html += "Default is: 127. 192.168. 172. 10.\n" html += "\n" html += "\n" - return ensure_binary(html) + return html.encode() + if len(L1) == 0: + ParseCode() req.setResponseCode(http.OK) req.setHeader('Content-type', 'text/html') req.setHeader('charset', 'UTF-8') - command = req.args.get(b"cmd", None) - _command = ensure_str(command[0]) if command != None else "" - ex = req.args.get(b"ex", None) - _ex = ensure_str(ex[0]) if ex != None else req.args.get(b"ex", None) - mo = req.args.get(b"Mode", None) - el = req.args.get(b"Element", None) + command = req.args.get(b"cmd") + _command = command[0].decode() if command else "" + ex = req.args.get(b"ex") + _ex = ex[0].decode() if ex else None + mo = req.args.get(b"Mode") + el = req.args.get(b"Element") self.restartTimer() - L4log("Command received %s" % (command), ex) + L4log(f"Command received '{command}', '{ex}'") if self.CurrentMode == ("-", "-"): self.CurrentMode = (getConfigStandby(), getisMediaPlayer()) - if mo is not None: - Mode = ensure_str(mo[0]) + if mo: + Mode = mo[0].decode() setConfigMode(True) if Mode in ["1", "2"]: setisMediaPlayer("") @@ -170,25 +168,19 @@ def action(self, req): self.resetWeb() getBilder() html = "" - if el is not None: - Element = ensure_str(el[0]) - if req.args.get(b"save.y", None) is not None: + if el: + Element = el[0].decode() + if req.args.get(b"save.y"): L4log("WebIF: save Config-File") LCD4linux.save() LCD4linux.saveToFile(LCD4config) ConfTimeCheck() - if req.args.get(b"download.y", None) is not None: + if req.args.get(b"download.y"): L4log("WebIF: download Config") req.setResponseCode(http.OK) lcd4config = resolveFilename(SCOPE_CONFIG) + "lcd4config" - req.setHeader('Content-type', 'text/plain') - req.setHeader('Content-Disposition', 'attachment;filename=lcd4config') - req.setHeader('Content-Length', str(stat(lcd4config).st_size)) - req.setHeader('charset', 'UTF-8') - with open(lcd4config) as f: - html = f.read() - return ensure_binary(html) - if req.args.get(b"upload.y", None) is not None: + return self.sendTextFile(req, 'attachment;filename=lcd4config', lcd4config) + if req.args.get(b"upload.y"): L4log("WebIF: upload Config") lcd4config = "/tmp/test" data = req.args[b"uploadName"][0] @@ -200,28 +192,21 @@ def action(self, req): else: L4log("WebIF: Error upload") html += "\n" - if req.args.get(b"logdel.y", None) is not None: + if req.args.get(b"logdel.y"): L4log("WebIF: delete Logfile") rmFile("/tmp/L4log.txt") - if req.args.get(b"logdownload.y", None) is not None: + if req.args.get(b"logdownload.y"): L4log("WebIF: download Logfile") lcd4config = "/tmp/L4log.txt" if isfile(lcd4config): - req.setResponseCode(http.OK) - req.setHeader('Content-type', 'text/plain') - req.setHeader('Content-Disposition', 'attachment;filename=l4log.txt') - req.setHeader('Content-Length', str(stat(lcd4config).st_size)) - req.setHeader('charset', 'UTF-8') - with open(lcd4config) as f: - html = f.read() - return ensure_binary(html) + return self.sendTextFile(req, 'attachment;filename=l4log.txt', lcd4config) if command is None: L4logE("no command") - elif _command == "exec" and ex is not None: - L4logE("exec: %s" % _ex) - exec(str(_ex)) # FIXME PY3 + elif _command == "exec" and ex: + L4logE(f"exec: {_ex}") + exec(_ex) elif _command == "enable": ExeMode = True elif _command == "status": @@ -241,16 +226,16 @@ def action(self, req): L4LElement.setRefresh() elif _command == "crashdel": rmFile(CrashFile) - elif _command == "add" and ex is not None: + elif _command == "add" and ex: L4LElement.web(_ex) - elif _command == "delete" and ex is not None: + elif _command == "delete" and ex: L4LElement.delete(_ex) elif _command == "refresh": L4LElement.setRefresh() elif _command == "hold": setScreenActive("0") setSaveEventListChanged(not getSaveEventListChanged()) - elif _command == "screen" and ex is not None: + elif _command == "screen" and ex: exs = _ex.split(",") if len(exs) == 1: L4LElement.setScreen(exs[0]) @@ -258,29 +243,29 @@ def action(self, req): L4LElement.setScreen(exs[0], exs[1]) elif len(exs) == 3: L4LElement.setScreen(exs[0], exs[1], exs[2] == "True") - elif _command == "brightness" and ex is not None: + elif _command == "brightness" and ex: exs = _ex.split(",") if len(exs) == 1: L4LElement.setBrightness(exs[0]) elif len(exs) == 2: L4LElement.setBrightness(exs[0], exs[1] == "True") - elif _command == "getbrightness" and ex is not None: + elif _command == "getbrightness" and ex: if int(_ex) < 1 or int(_ex) > 3: return "0" else: return str(L4LElement.getBrightness(int(_ex))) - elif _command == "getmjpeg" and ex is not None: + elif _command == "getmjpeg" and ex: if int(_ex) < 1 or int(_ex) > 3: return "0" else: return str(getMJPEGreader(_ex)) - elif _command == "getexec" and ex is not None: + elif _command == "getexec" and ex: L4logE("getexec", _ex) - _exec("getexec = %s" % _ex) # FIXME PY3 + _exec(f"getexec = {_ex}") return str(_ex) elif _command == "copyMP": for a in req.args.keys(): - _a = ensure_str(a) + _a = a.decode() if ".Standby" in _a: b = _a.replace(".Standby", ".MP") if (" " + b) in list(zip(*L3))[2]: @@ -295,7 +280,7 @@ def action(self, req): objb.value = obja.value elif _command == "copyIdle": for a in req.args.keys(): - _a = ensure_str(a) + _a = a.decode() if ".MP" in _a: b = _a.replace(".MP", ".Standby") if (" " + b) in list(zip(*L4))[2]: @@ -310,7 +295,7 @@ def action(self, req): objb.value = obja.value elif _command == "copyOn": for a in req.args.keys(): - _a = ensure_str(a) + _a = a.decode() if ".MP" in _a: b = _a.replace(".MP", ".") if (" " + b) in list(zip(*L2))[2]: @@ -329,51 +314,42 @@ def action(self, req): ##################### elif _command == "config": Cfritz = False - Cwetter = False +# Cwetter = False Cpicon = False Ccal = False Cwww = False for a in req.args.keys(): - _a = ensure_str(a) + _a = a.decode() if _a.find(".") > 0: val = req.args.get(a, "")[0] - val = ensure_str(val) -# ConfigSelection + val = val.decode() ConfObj = eval(_a) if isinstance(ConfObj, ConfigSelection): ConfObj.value = val - else: -# ConfigYesNo - if isinstance(ConfObj, ConfigYesNo): - val = req.args.get(a, "") - ConfObj.value = True if len(val) == 2 else False - else: -# ConfigText - if isinstance(ConfObj, ConfigText): - V = _l(val) - try: - V = _unescape(V) - except Exception: - L4log("WebIF Error: Parse Text") - ConfObj.value = V - else: -# ConfigSlider - if isinstance(ConfObj, ConfigSlider): - if val.isdigit(): - ConfObj.value = val - else: -# ConfigClock - if isinstance(ConfObj, ConfigClock): - t = val.split(":") - if len(t) == 2 and t[0].isdigit() and t[1].isdigit(): - ConfObj.value = [int(t[0]), int(t[1])] + elif isinstance(ConfObj, ConfigYesNo): + val = req.args.get(a, "") + ConfObj.value = True if len(val) == 2 else False + elif isinstance(ConfObj, ConfigText): + V = _l(val) + try: + V = _unescape(V) + except Exception: + L4log("WebIF Error: Parse Text") + ConfObj.value = V + elif isinstance(ConfObj, ConfigSlider): + if val.isdigit(): + ConfObj.value = val + elif isinstance(ConfObj, ConfigClock): + t = val.split(":") + if len(t) == 2 and t[0].isdigit() and t[1].isdigit(): + ConfObj.value = [int(t[0]), int(t[1])] if ConfObj.isChanged(): ConfObj.save() L4log("Changed", a) if _a.find("Fritz") > 0: Cfritz = True - elif _a.find("Wetter") > 0: - Cwetter = True +# elif _a.find("Wetter") > 0: +# Cwetter = True elif _a.find("Picon") > 0: Cpicon = True elif _a.find(".Cal") > 0 or _a.find(".MPCal") > 0 or _a.find(".StandbyCal") > 0: @@ -408,15 +384,14 @@ def action(self, req): if _a.find("BildFile") > 0: getBilder() if _a.find("WWW1") > 0: - if _a.find("WWW1url") > 0 or isfile(WWWpic % "1") == False: + if _a.find("WWW1url") > 0 or isfile(WWWpic % "1") is False: Cwww = True else: rmFile(WWWpic % "1p") if Cfritz: rmFile(PICfritz) - if Cwetter: -# resetWetter(None) # action after changing weather parameters - pass +# if Cwetter: +# resetWetter(None) # action after changing weather parameters if Cpicon: if len(LCD4linux.PiconCache.value) > 2: rmFiles(join(LCD4linux.PiconCache.value, "*.png")) @@ -443,16 +418,16 @@ def action(self, req): html += "function fensterchen() {\n" html += "fens1=window.open(\"\", \"Crashlog\",\"width=500,height=300,resizable=yes\");\n" for line in open(CrashFile).readlines(): - html += "fens1.document.write('%s');\n" % line.replace("\n", "
").replace("'", "\\'") + html += "fens1.document.write('{}');\n".format(line.replace("\n", "
").replace("'", "\\'")) html += "} \n" html += "\n" - if L4LElement.getRefresh() == True: + if L4LElement.getRefresh() is True: GI = getINFO().split() GR = min(int(float(GI[6])) + 1, 6) if len(GI) > 6 else 6 - html += "\n" % GR + html += f"\n" html += "LCD4linux\n" html += "" html += "\n" @@ -462,58 +437,82 @@ def action(self, req): html += "\n" html += "

\n" CCM = "#FFFFFF" if getConfigMode() is False else "#FFCC00" - html += "LCD4linux Config
%s\n" % (CCM, (Version if L4LElement.getVersion() is True else Version + "") + " (%s: Py" + ("3") + ")") % _l(_("Mode")) + html += ( + f"LCD4linux Config" + f"
{Version}\n" + ) if IP is None: - html += "
%s!" % _l(_("IP seurity not supported by Box")) + html += "
{}!".format(_l(_("IP seurity not supported by Box"))) html += "

\n" html += "

" - d = glob("%sdpf.*" % getTMPL()) + d = glob(f"{getTMPL()}dpf.*") if len(d) > 0: - html += "" % (basename(d[0]), time(), basename(d[0])) - d = glob("%sdpf2.*" % getTMPL()) + dpf1 = basename(d[0]) + html += ( + f"" + ) + d = glob(f"{getTMPL()}dpf2.*") if len(d) > 0: - html += "" % (basename(d[0]), basename(d[0]), time(), basename(d[0])) - d = glob("%sdpf3.*" % getTMPL()) + dpf2 = basename(d[0]) + html += ( + f"" + ) + d = glob(f"{getTMPL()}dpf3.*") if len(d) > 0: - html += "" % (basename(d[0]), basename(d[0]), time(), basename(d[0])) + dpf3 = basename(d[0]) + html += ( + f"" + ) html += "

\n" if isfile(CrashFile): html += "\n" - html += "
%s
\n" % _l(_("Crashlog")) + html += "{}
\n".format(_l(_("Crashlog"))) html += "\n" - html += "\n" % _l(_("Show")) - html += "\n" % _l(_("Delete")) + html += "\n".format(_l(_("Show"))) + html += "\n".format(_l(_("Delete"))) html += "
\n" html += "\n" html += "
\n" - html += "\n" % _l(_("Filename")) - html += "\n" % _l(_("Restore Config")) - html += "\n" % _l(_("Backup Config")) + html += "\n".format(_l(_("Filename"))) + html += "\n".format(_l(_("Restore Config"))) + html += "\n".format(_l(_("Backup Config"))) if isfile("/tmp/L4log.txt"): - html += "\n" % _l(_("Delete Logfile")) - html += "\n" % _l(_("Download Logfile")) - html += "\n" % _l(_("Save Config")) + html += "\n".format(_l(_("Delete Logfile"))) + html += "\n".format(_l(_("Download Logfile"))) + html += "\n".format(_l(_("Save Config"))) html += "
\n" - html += "
%s\n" % _l(_("Screen")) + html += "{}\n".format(_l(_("Screen"))) html += "\n" for i in range(1, 10): - html += "\n" % (i, AktiveScreen(str(i)), i) + html += ( + f"\n" + ) Aktiv = "checked" if getSaveEventListChanged() else "" - html += "" % ("unchecked") - html += "" % (_l(_("stop Screencycle")), "checked", Aktiv) + html += "".format("unchecked") + html += "".format(_l(_("stop Screencycle")), "checked", Aktiv) html += "
\n" html += "\n" html += "
" html += "
" - html += "%s \n" % _l(_("Mode")) - html += "\n" % (AktiveMode("1", _l(_("Global")))) - html += "\n" % (AktiveMode("2", _l(_("On")))) - html += "\n" % (AktiveMode("3", _l(_("Media")))) - html += "\n" % (AktiveMode("4", _l(_("Idle")))) - if LCD4linuxConfigweb.RestartGUI == True: - html += "%s" % _l(_("GUI Restart is required")) + html += "{} \n".format(_l(_("Mode"))) + html += "\n".format(*AktiveMode("1", _l(_("Global")))) + html += "\n".format(*AktiveMode("2", _l(_("On")))) + html += "\n".format(*AktiveMode("3", _l(_("Media")))) + html += "\n".format(*AktiveMode("4", _l(_("Idle")))) + if LCD4linuxConfigweb.RestartGUI is True: + html += "{}".format(_l(_("GUI Restart is required"))) if str(LCD4linux.Popup.value) != "0": - html += "\n" % (AktiveMode("5", "Popup-Text")) + html += "\n".format(*AktiveMode("5", "Popup-Text")) html += "
\n" if Mode != "5": if Mode == "1": @@ -533,7 +532,7 @@ def action(self, req): html += "" html += "
" html += "
" - html += "%s \n" % _l(_("Element")) + html += "{} \n".format(_l(_("Element"))) i = 0 ElementList = [] ElementText = "" @@ -541,7 +540,7 @@ def action(self, req): Conf = LL[2].strip() if Mode == "1": Conf = Conf[:13] - if ((not LL[1].startswith("-") and Mode != "1") or (Mode == "1" and Conf not in ElementList)) and LL[3] != 0: + if ((not LL[1].startswith("-") and Mode != "1") or (Mode == "1" and Conf not in ElementList)) and int(LL[3]) != 0: if Element == "" or ModeOld != Mode: Element = "other" ModeOld = Mode @@ -551,24 +550,24 @@ def action(self, req): if Mode != "1": ConfObj = eval(Conf) Curr = ConfObj.value - L4log("Curr = %s.value" % Conf, Curr) + L4log(f"Curr = {Conf}.value", Curr) if Curr != "0": Ec = "style=\"font-weight:bold;color:#CCFFBB\"" if Ec == "" else Ec.replace("=\"", "=\"font-weight:bold;") if Ea == "checked": - ElementText = (_l(_(LL[1])) if Mode != "1" else _l(M[LL[3] - 1])) - html += "\n" % (i, Conf, Ea, Ec, i, (_l(_(LL[1])) if Mode != "1" else _l(M[LL[3] - 1]))) + ElementText = (_l(_(LL[1])) if Mode != "1" else _l(M[int(LL[3]) - 1])) + html += f"\n" if str(LCD4linux.WebIfDesign.value) == "2": html += "
" Ea, Ec = AktiveElement("other") if Ea == "checked": ElementText = _l(_("other")) - html += "\n" % (0, "other", Ea, Ec, 0, _l(_("other"))) + html += f"\n" html += "
\n" if str(LCD4linux.WebIfDesign.value) == "2": html += "
" html += "
\n" if str(LCD4linux.WebIfDesign.value) == "2": - html += "
%s " % ElementText + html += f"
{ElementText} " html += "" AktCode = 0 isOn = False @@ -577,7 +576,7 @@ def action(self, req): for LL in L: Conf = LL[2].strip() ConfObj = eval(Conf) - if (Conf.startswith(Element) and (LL[3] == AktCode or AktCode == 0)) or (Element == "other" and LL[3] == 0): + if (Conf.startswith(Element) and (int(LL[3]) == AktCode or AktCode == 0)) or (Element == "other" and int(LL[3]) == 0): if Mode in "2": if "." in Conf: b = Conf.replace(".", ".MP") @@ -602,82 +601,71 @@ def action(self, req): if (" " + b) in list(zip(*L3))[2]: isMP = True if AktCode == 0: - AktCode = LL[3] + AktCode = int(LL[3]) Curr = ConfObj.value -# ConfigSelection html += "\n" if isinstance(ConfObj, ConfigSelection): - html += "\n" - else: -# ConfigYesNo - if isinstance(ConfObj, ConfigYesNo): - html += "\n" - else: -# ConfigText - if isinstance(ConfObj, ConfigText): - html += "\n" - else: -# ConfigSlider - if isinstance(ConfObj, ConfigSlider): - Min = ConfObj.min - Max = ConfObj.max - html += "\n" - else: -# ConfigClock - if isinstance(ConfObj, ConfigClock): - html += "\n" + elif isinstance(ConfObj, ConfigYesNo): + html += f"\n" + elif isinstance(ConfObj, ConfigText): + html += f"\n" + elif isinstance(ConfObj, ConfigSlider): + Min = ConfObj.min + Max = ConfObj.max + html += f"\n" + elif isinstance(ConfObj, ConfigClock): + html += f"\n" html += "
%s\n" % _l(_(LL[1])) - html += "{_l(_(LL[1]))}\n" + html += f"\n" html += "%s\n" % _l(_(LL[1])) - Aktiv = "checked" if Curr else "" - html += "" % (Conf, "unchecked") - html += "" % (Conf, "checked", Aktiv) - html += "%s\n" % _l(_(LL[1])) - html += "" % (Conf, _l(Curr)) if isinstance(ConfObj, ConfigPassword) else "" % (Conf, _l(Curr)) - html += "%s (%d - %d)\n" % (_l(_(LL[1])), Min, Max) - html += "" % (Conf, Curr) - html += "%s\n" % _l(_(LL[1])) - html += "" % (Conf, Curr[0], Curr[1]) - html += "{_l(_(LL[1]))}\n" + Aktiv = "checked" if Curr else "" + html += "".format(Conf, "unchecked") + html += "".format(Conf, "checked", Aktiv) + html += "{_l(_(LL[1]))}\n" + html += f"" if isinstance(ConfObj, ConfigPassword) else f"" + html += "{_l(_(LL[1]))} ({Min} - {Max})\n" + html += f"" + html += "{_l(_(LL[1]))}\n" + html += f'' + html += "
\n" html += "\n" - html += "\n" % _l(_("set Settings")) + html += "\n".format(_l(_("set Settings"))) if Element != "other": if Mode in ["3", "4"] and isOn: - html += "\n" % _l(_("copy to On")) + html += "\n".format(_l(_("copy to On"))) if Mode in ["2", "4"] and isMP: - html += "\n" % _l(_("copy to Media")) + html += "\n".format(_l(_("copy to Media"))) if Mode in ["2", "3"] and isSb: - html += "\n" % _l(_("copy to Idle")) + html += "\n".format(_l(_("copy to Idle"))) html += "
" if str(LCD4linux.WebIfDesign.value) == "2" else "\n" elif Mode == "5": html += "
\n" html += "
\n" - html += "" % _l(PopText[1]) + html += f"" html += "\n" - html += "\n" % _l(_("set Settings")) + html += "\n".format(_l(_("set Settings"))) html += "
\n" - - if ExeMode == True: + if ExeMode is True: html += "
\n" html += "
\n" html += "\n" html += "\n" - html += "\n" % _l(_("Exec")) + html += "\n".format(_l(_("Exec"))) html += "
\n" - if StatusMode == True: + if StatusMode is True: html += "
\n" - html += "Screen: %s
\n" % str(getScreenActive(True)) - html += "Hold/HoldKey: %s/%s
\n" % (str(getSaveEventListChanged()), str(L4LElement.getHoldKey())) - html += "Brightness org/set %s/%s
\n" % (str(L4LElement.getBrightness()), str(L4LElement.getBrightness(0, False))) - - html += "
%s (%s)" % (getINFO(), IP) + html += f"Screen: {str(getScreenActive(True))}
\n" + html += f"Hold/HoldKey: {str(getSaveEventListChanged())}/{str(L4LElement.getHoldKey())}
\n" + html += f"Brightness org/set {str(L4LElement.getBrightness())}/{str(L4LElement.getBrightness(0, False))}
\n" + html += f"
{getINFO()} ({IP})" html += "
Support & FAQ & Info & Donation" if len(L4LElement.get()) > 0: html += "\n" html += "

\n" - html += "\n" % _l(_("Show Externals")) + html += "\n".format(_l(_("Show Externals"))) html += "
\n" html += "\n" html += "\n" - return ensure_binary(html) + return html.encode() diff --git a/lcd4linux/src/WebSite.py b/lcd4linux/src/WebSite.py index 36fb27c..0752076 100644 --- a/lcd4linux/src/WebSite.py +++ b/lcd4linux/src/WebSite.py @@ -1,99 +1,81 @@ -# -*- coding: utf-8 -*- -from __future__ import division from os.path import isfile, getmtime from twisted.web import resource from .plugin import getConfigMode, getTMPL, LCD4linux -def ensure_str(s): - if isinstance(s, bytes): - return s.decode("utf-8") - return s - - -def ensure_binary(s): - if isinstance(s, str): - return s.encode("utf-8") - return s - - class LCD4linuxweb(resource.Resource): - title = "LCD4Linux Webinterface" isLeaf = False def __init__(self): self.HREF = "href=\"/lcd4linux/config\"" - def render(self, req): - req.setHeader('Content-type', 'text/html') - req.setHeader('charset', 'UTF-8') + def getRefreshMarkup(self): + webIfType = LCD4linux.WebIfType.value + if webIfType == "1": + result = (f"\n", "") + else: # "0" = Javascript with page reload, "01" = Javascript without page reload + refreshMeta = "\n" if webIfType == "0" else "" + result = (refreshMeta, " id=\"reloader{index}\" onload=\"setTimeout('document.getElementById(\\'reloader{index}\\').src=\\'/lcd4linux/{image}?\\'+new Date().getTime()', {delay})\"") + return result + + def renderPicture(self, filename, index, attributes, javaRefresh): + mtime = int(getmtime(f"{getTMPL()}{filename}")) + jr = javaRefresh.format(index=index, image=filename, delay=int(LCD4linux.WebIfRefresh.value) * 1000) if javaRefresh else "" + return f" \n" + + def render(self, request): + request.setHeader('Content-type', 'text/html') + request.setHeader('charset', 'UTF-8') # rendering server response - w = "" - command = req.args.get(b"width", None) + attributes = "" + command = request.args.get(b"width", None) if command is not None: - cmd = ensure_str(command[0]) - w += " width=\"%s\"" % cmd - command = req.args.get(b"hight", None) + cmd = command[0].decode() + attributes += f" width=\"{cmd}\"" + command = request.args.get(b"hight", None) if command is not None: - cmd = ensure_str(command[0]) - w += " height=\"%s\"" % cmd - html = "" - html += "\n" - html += "\n" - html += "\n" - html += "\n" - html += "\n" - html += "\n" - html += "" - if LCD4linux.WebIfType.value == "1": - JavaRefresh = "" - html += "\n" % LCD4linux.WebIfRefresh.value - else: - if LCD4linux.WebIfType.value == "0": - html += "\n" - JavaRefresh = " id=\"reloader%%d\" onload=\"setTimeout('document.getElementById(\\'reloader%%d\\').src=\\'/lcd4linux/%%s?\\'+new Date().getTime()', %d)\"" % (int(LCD4linux.WebIfRefresh.value) * 1000) + cmd = command[0].decode() + attributes += f" height=\"{cmd}\"" + html = ( + "" + "\n" + "\n" + "\n" + "\n" + "\n" + "\n" + "" + ) + refreshMeta, javaRefresh = self.getRefreshMarkup() + html += refreshMeta html += "LCD4linux\n" html += "" - html += "\n" % ("#666666" if getConfigMode() == True else "#000000") + html += f"\n" html += "
\n" - datei = req.args.get(b"file", None) - if datei is not None: - datei[0] = datei[0].decode("utf-8") - if isfile("%s%s" % (getTMPL(), datei[0])): - t = getmtime("%s%s" % (getTMPL(), datei[0])) - JR = "" if JavaRefresh == "" else JavaRefresh % (1, 1, datei[0]) - html += " \n" % (self.HREF, datei[0], t, JR, w) - elif isfile("%sdpf.jpg" % getTMPL()): - t = getmtime("%sdpf.jpg" % getTMPL()) - JR = "" if JavaRefresh == "" else JavaRefresh % (2, 2, "dpf.jpg") - html += " \n" % (self.HREF, t, JR, w) - elif isfile("%sdpf.png" % getTMPL()): - t = getmtime("%sdpf.png" % getTMPL()) - JR = "" if JavaRefresh == "" else JavaRefresh % (3, 3, "dpf.png") - html += " \n" % (self.HREF, t, JR, w) - elif isfile("%sdpf2.jpg" % getTMPL()): - t = getmtime("%sdpf2.jpg" % getTMPL()) - JR = "" if JavaRefresh == "" else JavaRefresh % (4, 4, "dpf2.jpg") - html += " \n" % (self.HREF, t, JR, w) - elif isfile("%sdpf2.png" % getTMPL()): - t = getmtime("%sdpf2.png" % getTMPL()) - JR = "" if JavaRefresh == "" else JavaRefresh % (5, 5, "dpf2.png") - html += " \n" % (self.HREF, t, JR, w) - elif isfile("%sdpf3.jpg" % getTMPL()): - t = getmtime("%sdpf3.jpg" % getTMPL()) - JR = "" if JavaRefresh == "" else JavaRefresh % (6, 6, "dpf3.jpg") - html += " \n" % (self.HREF, t, JR, w) - elif isfile("%sdpf3.png" % getTMPL()): - t = getmtime("%sdpf3.png" % getTMPL()) - JR = "" if JavaRefresh == "" else JavaRefresh % (7, 7, "dpf3.png") - html += " \n" % (self.HREF, t, JR, w) + requestedFile = request.args.get(b"file", None) + if requestedFile is not None: + requestedFile = [item.decode("utf-8") for item in requestedFile] + if requestedFile and isfile(f"{getTMPL()}{requestedFile[0]}"): + html += self.renderPicture(requestedFile[0], 1, attributes, javaRefresh) else: - html += "no Picture .... Config-WebIF" % self.HREF + for index, filename in enumerate([ + "dpf.jpg", + "dpf.png", + "dpf2.jpg", + "dpf2.png", + "dpf3.jpg", + "dpf3.png", + ], start=2): + if isfile(f"{getTMPL()}{filename}"): + html += self.renderPicture(filename, index, attributes, javaRefresh) + break + else: + html += f"no Picture .... Config-WebIF" html += "\n" html += "\n" html += "
\n" - return ensure_binary(html) + return html.encode() class LCD4linuxwebView(LCD4linuxweb): diff --git a/lcd4linux/src/__init__.py b/lcd4linux/src/__init__.py index c147b7f..c8c7092 100644 --- a/lcd4linux/src/__init__.py +++ b/lcd4linux/src/__init__.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from os import environ from gettext import gettext, dgettext, bindtextdomain from Components.Language import language @@ -24,4 +23,4 @@ def _(txt): localeInit() language.addCallback(localeInit) -__version__ = "5.0.40" +__version__ = "5.0.41" diff --git a/lcd4linux/src/bluesound.py b/lcd4linux/src/bluesound.py index 7b44e8a..eae119a 100644 --- a/lcd4linux/src/bluesound.py +++ b/lcd4linux/src/bluesound.py @@ -1,24 +1,17 @@ -# -*- coding: utf-8 -*- from urllib.request import urlopen from xml.etree.ElementTree import fromstring def parseXmlToJson(xml): - response = {} - for child in list(xml): - if len(list(child)) > 0: - response[child.tag] = parseXmlToJson(child) - else: - response[child.tag] = child.text or '' - return response + return {x.tag: parseXmlToJson(x) if len(x) > 0 else (x.text or "") for x in xml} class BlueSound: def __init__(self, ip): self.IP = ip - self.baseUrl = "http://" + ip + ":11000/" + self.baseUrl = f"http://{ip}:11000/" # NOSONAR - lokale BluOS-API bietet kein HTTPS - def Urlget(self, url): + def urlGet(self, url): f = urlopen(url, timeout=1) fr = f.read() fc = f.code @@ -26,16 +19,13 @@ def Urlget(self, url): return (fr, fc) def getStatus(self): + result = {} try: - content, resp = self.Urlget(self.baseUrl + "Status") + content, resp = self.urlGet(f"{self.baseUrl}Status") if resp == 200: - xml = fromstring(content) - r = parseXmlToJson(xml) - return r - else: - return {} + result = parseXmlToJson(fromstring(content)) except Exception: print("Bluesound Error") from traceback import format_exc - print("Error: %s" % format_exc()) - return {} + print(f"Error: {format_exc()}") + return result diff --git a/lcd4linux/src/configOptions.py b/lcd4linux/src/configOptions.py index e3ee5b6..7f9b333 100644 --- a/lcd4linux/src/configOptions.py +++ b/lcd4linux/src/configOptions.py @@ -541,6 +541,7 @@ ['self.list2', '- Weather Type', ' LCD4linux.WetterType', 28], ['self.list2', '- Color', ' LCD4linux.WetterColor', 28], ['self.list2', '- Shadow Edges', ' LCD4linux.WetterShadow', 28], + ['self.list2', '- Append Celsius sign', ' LCD4linux.WetterAppendC', 28], ['self.list2', '- Font', ' LCD4linux.WetterFont', 28], ['self.list2', 'Weather 2', ' LCD4linux.Wetter2', 29], ['self.list2', '- which LCD', ' LCD4linux.Wetter2LCD', 29], @@ -551,6 +552,7 @@ ['self.list2', '- Weather Type', ' LCD4linux.Wetter2Type', 29], ['self.list2', '- Color', ' LCD4linux.Wetter2Color', 29], ['self.list2', '- Shadow Edges', ' LCD4linux.Wetter2Shadow', 29], + ['self.list2', '- Append Celsius sign', ' LCD4linux.Wetter2AppendC', 29], ['self.list2', '- Font', ' LCD4linux.Wetter2Font', 29], ['self.list2', 'Meteo-Weather Station', ' LCD4linux.Meteo', 30], ['self.list2', '- which LCD', ' LCD4linux.MeteoLCD', 30], @@ -1173,6 +1175,7 @@ ['self.list3', '- Weather Type', ' LCD4linux.MPWetterType', 23], ['self.list3', '- Color', ' LCD4linux.MPWetterColor', 23], ['self.list3', '- Shadow Edges', ' LCD4linux.MPWetterShadow', 23], + ['self.list3', '- Append Celsius sign', ' LCD4linux.MPWetterAppendC', 23], ['self.list3', '- Font', ' LCD4linux.MPWetterFont', 23], ['self.list3', 'Weather 2', ' LCD4linux.MPWetter2', 24], ['self.list3', '- which LCD', ' LCD4linux.MPWetter2LCD', 24], @@ -1183,6 +1186,7 @@ ['self.list3', '- Weather Type', ' LCD4linux.MPWetter2Type', 24], ['self.list3', '- Color', ' LCD4linux.MPWetter2Color', 24], ['self.list3', '- Shadow Edges', ' LCD4linux.MPWetter2Shadow', 24], + ['self.list3', '- Append Celsius sign', ' LCD4linux.MPWetter2AppendC', 24], ['self.list3', '- Font', ' LCD4linux.MPWetter2Font', 24], ['self.list3', 'Meteo-Weather Station', ' LCD4linux.MPMeteo', 25], ['self.list3', '- which LCD', ' LCD4linux.MPMeteoLCD', 25], @@ -1634,6 +1638,7 @@ ['self.list4', '- Weather Type', ' LCD4linux.StandbyWetterType', 14], ['self.list4', '- Color', ' LCD4linux.StandbyWetterColor', 14], ['self.list4', '- Shadow Edges', ' LCD4linux.StandbyWetterShadow', 14], + ['self.list4', '- Append Celsius sign', ' LCD4linux.StandbyWetterAppendC', 14], ['self.list4', '- Font', ' LCD4linux.StandbyWetterFont', 14], ['self.list4', 'Weather 2', ' LCD4linux.StandbyWetter2', 15], ['self.list4', '- which LCD', ' LCD4linux.StandbyWetter2LCD', 15], @@ -1644,6 +1649,7 @@ ['self.list4', '- Weather Type', ' LCD4linux.StandbyWetter2Type', 15], ['self.list4', '- Color', ' LCD4linux.StandbyWetter2Color', 15], ['self.list4', '- Shadow Edges', ' LCD4linux.StandbyWetter2Shadow', 15], + ['self.list4', '- Append Celsius sign', ' LCD4linux.StandbyWetter2AppendC', 15], ['self.list4', '- Font', ' LCD4linux.StandbyWetter2Font', 15], ['self.list4', 'Meteo-Weather Station', ' LCD4linux.StandbyMeteo', 16], ['self.list4', '- which LCD', ' LCD4linux.StandbyMeteoLCD', 16], diff --git a/lcd4linux/src/dpf.py b/lcd4linux/src/dpf.py index 2eecafb..e264c63 100644 --- a/lcd4linux/src/dpf.py +++ b/lcd4linux/src/dpf.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- try: from . import dpflib except Exception: @@ -32,12 +31,11 @@ def showImage(dev, image): def open(usb): try: - d = dpflib.open(usb) -# d.setProperty(PROPERTY_ORIENTATION, 1) - print("[LCD4linux] open %s" % usb) + d = dpflib.open(usb) # d.setProperty(PROPERTY_ORIENTATION, 1) + print(f"[LCD4linux] open {usb}") except Exception: d = None - print("[LCD4linux] open Error: %s" % usb) + print(f"[LCD4linux] open Error: {usb}") return d diff --git a/lcd4linux/src/module.py b/lcd4linux/src/module.py index 27c75c6..3a64b12 100644 --- a/lcd4linux/src/module.py +++ b/lcd4linux/src/module.py @@ -1,10 +1,7 @@ -# -*- coding: utf-8 -*- -# external interface for LCD4linux # by joergm6 @ IHAD # for documentation look at IHAD Support Thread -from __future__ import print_function -from os import popen +from subprocess import getstatusoutput from os.path import isfile, exists @@ -26,16 +23,16 @@ def __init__(self): self.session = None def add(self, element, para): - print("[LCD4linuxE] Add: %s %s" % (element, para)) + print(f"[LCD4linuxE] Add: {element} {para}") if "%" in para.get("Align", ""): para["Align"] = ("0000" + para["Align"].replace("%", "00"))[-4:] - if para.get("Value", None) is not None: + if para.get("Value") is not None: para["Value"] = min(max(int(para["Value"]), 0), 100) L4Lelement.List[element] = para def delete(self, element): - print("[LCD4linuxE] Del: %s" % element) - if L4Lelement.List.get(element, None) is not None: + print(f"[LCD4linuxE] Del: {element}") + if L4Lelement.List.get(element) is not None: del L4Lelement.List[element] else: for x in list(L4Lelement.List): @@ -46,14 +43,12 @@ def show(self): print(L4Lelement.List) def get(self, element=None): - if element == None: - return L4Lelement.List - else: - return L4Lelement.List.get(element, {}) + return L4Lelement.List if element is None else L4Lelement.List.get(element, {}) def web(self, EX): try: - exec("self.add('%s)" % EX.replace(",", "',", 1)) + args = EX.replace(",", "',", 1) + exec(f"self.add('{args})") except Exception: print("[LCD4linuxE] Error: L4L Web-Elements") @@ -79,14 +74,14 @@ def getHold(self): return L4Lelement.Hold def setHold(self, H): - print("[LCD4linuxE] hold: %s" % H) + print(f"[LCD4linuxE] hold: {H}") L4Lelement.Hold = H def getHoldKey(self): return L4Lelement.HoldKey def setHoldKey(self, H=False): - print("[LCD4linuxE] holdkey: %s" % H) + print(f"[LCD4linuxE] holdkey: {H}") L4Lelement.HoldKey = H def getFont(self, F="0"): @@ -136,20 +131,12 @@ def getVersion(self): return L4Lelement.Version -def getstatusoutput(cmd): +def getStatusOutput(cmd): try: - pipe = popen('{ ' + cmd + '; } 2>&1', 'r') - text = pipe.read() - sts = pipe.close() - if sts is None: - sts = 0 - if text.endswith == '\n': - text = text[:-1] - except Exception: - sts = 1 - text = "- -" - print("[LCD4linux] Error on os-call") - return sts, text + return getstatusoutput(cmd) + except Exception as exc: + print(f"[LCD4linux] Error on system call: {exc}") + return 1, "- -" def L4LVtest(VV): @@ -163,7 +150,7 @@ def L4LVtest(VV): OX = "var" P = "dpkg" elif exists("/var/lib/dpkg/status"): - (r1, r2) = getstatusoutput("dpkg -s enigma2-plugin-extensions-lcd4linux | grep Version") + (r1, r2) = getStatusOutput("dpkg -s enigma2-plugin-extensions-lcd4linux | grep Version") if r1 == 0: OO = r2.strip().split()[1].startswith(VV[1:]) if OX != "": diff --git a/lcd4linux/src/ping.py b/lcd4linux/src/ping.py index a3c92e2..a6e9e3e 100644 --- a/lcd4linux/src/ping.py +++ b/lcd4linux/src/ping.py @@ -1,6 +1,3 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - """ A pure python ping implementation using raw sockets. @@ -218,12 +215,7 @@ __description__ = 'A pure python ICMP ping implementation using raw sockets.' -if sys.platform == "win32": - # On Windows, the best timer is time.clock() - default_timer = time.clock -else: - # On most other platforms the best timer is time.time() - default_timer = time.time +default_timer = getattr(time, 'perf_counter', time.time) NUM_PACKETS = 3 PACKET_SIZE = 64 @@ -240,14 +232,14 @@ class MyStats: - thisIP = "0.0.0.0" - pktsSent = 0 - pktsRcvd = 0 - minTime = 999999999 - maxTime = 0 - totTime = 0 - avrgTime = 0 - fracLoss = 1.0 + thisIP: str = "0.0.0.0" + pktsSent: int = 0 + pktsRcvd: int = 0 + minTime: float = 999999999.0 + maxTime: float = 0.0 + totTime: float = 0.0 + avrgTime: float = 0.0 + fracLoss: float = 1.0 myStats = MyStats # NOT Used globally anymore. @@ -262,8 +254,8 @@ def checksum(source_string): packed), but this works. Network data is big-endian, hosts are typically little-endian """ - countTo = (int(len(source_string) / 2)) * 2 - sum = 0 + countTo = (len(source_string) // 2) * 2 + total = 0 count = 0 # Handle bytes in pairs (decoding as short ints) loByte = 0 @@ -276,25 +268,24 @@ def checksum(source_string): loByte = source_string[count + 1] hiByte = source_string[count] try: # For Python3 - sum = sum + (hiByte * 256 + loByte) + total = total + (hiByte * 256 + loByte) except Exception: # For Python2 - sum = sum + ord(hiByte) * 256 + ord(loByte) + total = total + ord(hiByte) * 256 + ord(loByte) count += 2 # Handle last byte if applicable (odd-number of bytes) # Endianness should be irrelevant in this case if countTo < len(source_string): # Check for odd length loByte = source_string[len(source_string) - 1] try: # For Python3 - sum += loByte + total += loByte except Exception: # For Python2 - sum += ord(loByte) - sum &= 0xffffffff # Truncate sum to 32 bits (a variance from ping.c, which + total += ord(loByte) + total &= 0xffffffff # Truncate total to 32 bits (a variance from ping.c, which # uses signed ints, but overflow is unlikely in ping) - sum = (sum >> 16) + (sum & 0xffff) # Add high 16 bits to low 16 bits - sum += (sum >> 16) # Add carry from above (if any) - answer = ~sum & 0xffff # Invert and truncate to 16 bits - answer = socket.htons(answer) - return answer + total = (total >> 16) + (total & 0xffff) # Add high 16 bits to low 16 bits + total += (total >> 16) # Add carry from above (if any) + answer = ~total & 0xffff # Invert and truncate to 16 bits + return socket.htons(answer) # =============================================================================# @@ -306,9 +297,9 @@ def do_one(myStats, destIP, hostname, timeout, mySeqNumber, packet_size, quiet=F delay = None try: # One could use UDP here, but it's obscure mySocket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname("icmp")) - except socket.error as e: + except OSError as e: if not quiet: - print("failed. (socket error: '%s')" % e.args[1]) + print(f"failed. (socket error: '{e.args[1]}')") raise # raise the original error my_ID = os.getpid() & 0xFFFF @@ -327,16 +318,15 @@ def do_one(myStats, destIP, hostname, timeout, mySeqNumber, packet_size, quiet=F if recvTime: delay = (recvTime - sentTime) * 1000 if not quiet: - print("%d bytes from %s: icmp_seq=%d ttl=%d time=%d ms" % ( - dataSize, socket.inet_ntoa(struct.pack("!I", iphSrcIP)), icmpSeqNumber, iphTTL, delay) + print( + f"{dataSize} bytes from {socket.inet_ntoa(struct.pack('!I', iphSrcIP))}: " + f"icmp_seq={icmpSeqNumber} ttl={iphTTL} time={delay} ms" ) myStats.pktsRcvd += 1 # test = test +1 myStats.totTime += delay - if myStats.minTime > delay: - myStats.minTime = delay - if myStats.maxTime < delay: - myStats.maxTime = delay + myStats.minTime = min(myStats.minTime, delay) + myStats.maxTime = max(myStats.maxTime, delay) else: delay = None if not quiet: @@ -361,40 +351,31 @@ def send_one_ping(mySocket, destIP, myID, mySeqNumber, packet_size): "!BBHHH", ICMP_ECHO, 0, myChecksum, myID, mySeqNumber ) - padBytes = [] - startVal = 0x42 - # 'cose of the string/byte changes in python 2/3 we have - # to build the data differnely for different version + # Because of the string/byte changes in Python 2/3 we have + # to build the data differently for different version # or it will make packets with unexpected size. if sys.version[:1] == '2': - bytes = struct.calcsize("d") - data = ((packet_size - 8) - bytes) * "Q" + data = ((packet_size - 8) - struct.calcsize("d")) * "Q" data = struct.pack("d", default_timer()) + data else: - for i in range(startVal, startVal + (packet_size - 8)): - padBytes += [(i & 0xff)] # Keep chars in the 0-255 range - # data = bytes(padBytes) - data = bytearray(padBytes) + startVal = 0x42 + data = bytearray( + [(i & 0xff) for i in range(startVal, startVal + (packet_size - 8))] + ) # Calculate the checksum on the data and the dummy header. myChecksum = checksum(header + data) # Checksum is in network order # Now that we have the right checksum, we put that in. It's just easier # to make up a new header than to stuff it into the dummy. - header = struct.pack( - "!BBHHH", ICMP_ECHO, 0, myChecksum, myID, mySeqNumber - ) - + header = struct.pack("!BBHHH", ICMP_ECHO, 0, myChecksum, myID, mySeqNumber) packet = header + data - sendTime = default_timer() - try: mySocket.sendto(packet, (destIP, 1)) # Port number is irrelevant for ICMP - except socket.error as e: + except OSError as e: print(f"General failure ({e.args[1]})") return - return sendTime # =============================================================================# @@ -405,7 +386,6 @@ def receive_one_ping(mySocket, myID, timeout): Receive the ping from the socket. Timeout = in ms """ timeLeft = float(timeout) / 1000 - while True: # Loop while waiting for packet or timeout startedSelect = default_timer() whatReady = select.select([mySocket], [], [], timeLeft) @@ -420,21 +400,16 @@ def receive_one_ping(mySocket, myID, timeout): ipHeader = recPacket[:20] iphVersion, iphTypeOfSvc, iphLength, \ iphID, iphFlags, iphTTL, iphProtocol, \ - iphChecksum, iphSrcIP, iphDestIP = struct.unpack( - "!BBHHHBBHII", ipHeader - ) + iphChecksum, iphSrcIP, iphDestIP = struct.unpack("!BBHHHBBHII", ipHeader) icmpHeader = recPacket[20:28] icmpType, icmpCode, icmpChecksum, \ - icmpPacketID, icmpSeqNumber = struct.unpack( - "!BBHHH", icmpHeader - ) + icmpPacketID, icmpSeqNumber = struct.unpack("!BBHHH", icmpHeader) if icmpPacketID == myID: # Our packet dataSize = len(recPacket) - 28 # print (len(recPacket.encode())) return timeReceived, (dataSize + 8), iphSrcIP, icmpSeqNumber, iphTTL - timeLeft = timeLeft - howLongInSelect if timeLeft <= 0: return None, 0, 0, 0, 0 @@ -443,71 +418,46 @@ def receive_one_ping(mySocket, myID, timeout): def dump_stats(myStats): - """ - Show stats when pings are done - """ - print("\n----%s PYTHON PING Statistics----" % (myStats.thisIP)) - + # Show stats when pings are done + print(f"\n----{myStats.thisIP} PYTHON PING Statistics----") if myStats.pktsSent > 0: myStats.fracLoss = float(myStats.pktsSent - myStats.pktsRcvd) / myStats.pktsSent - - print("%d packets transmitted, %d packets received, %0.1f%% packet loss" % ( - myStats.pktsSent, myStats.pktsRcvd, 100.0 * myStats.fracLoss - )) - + print(f"{myStats.pktsSent} packets transmitted, {myStats.pktsRcvd} packets received, {100.0 * myStats.fracLoss:.1f}% packet loss") if myStats.pktsRcvd > 0: - print("round-trip (ms) min/avg/max = %d/%0.1f/%d" % ( - myStats.minTime, myStats.totTime / myStats.pktsRcvd, myStats.maxTime - )) - + print(f"round-trip (ms) min/avg/max = {myStats.minTime}/{(myStats.totTime / myStats.pktsRcvd):.1f}/{myStats.maxTime}") print("") # =============================================================================# def signal_handler(signum, frame): - """ - Handle exit via signals - """ + # Handle exit via signals # dump_stats() - print("\n(Terminated with signal %d)\n" % (signum)) + print(f"\n(Terminated with signal {signum})\n") sys.exit(0) # =============================================================================# def verbose_ping(hostname, timeout=WAIT_TIMEOUT, count=NUM_PACKETS, packet_size=PACKET_SIZE, path_finder=False): - """ - Send >count< ping to >destIP< with the given >timeout< and display - the result. - """ + # Send >count< ping to >destIP< with the given >timeout< and display the result. signal.signal(signal.SIGINT, signal_handler) # Handle Ctrl-C if hasattr(signal, "SIGBREAK"): -# Handle Ctrl-Break e.g. under Windows - signal.signal(signal.SIGBREAK, signal_handler) - + signal.signal(signal.SIGBREAK, signal_handler) # Handle Ctrl-Break e.g. under Windows myStats = MyStats() # Reset the stats - - mySeqNumber = 0 # Starting value - try: destIP = socket.gethostbyname(hostname) - print("\nPYTHON PING %s (%s): %d data bytes" % (hostname, destIP, packet_size)) + print(f"\nPYTHON PING {hostname} ({destIP}): {packet_size} data bytes") except socket.gaierror as e: - print("\nPYTHON PING: Unknown host: %s (%s)" % (hostname, e.args[1])) + print(f"\nPYTHON PING: Unknown host: {hostname} ({e.args[1]})") print() return myStats.thisIP = destIP - - for i in range(count): + for mySeqNumber in range(count): delay = do_one(myStats, destIP, hostname, timeout, mySeqNumber, packet_size) - if delay is None: delay = 0 - - mySeqNumber += 1 - # Pause for the remainder of the MAX_SLEEP period (if applicable) if (MAX_SLEEP > delay): time.sleep(float(MAX_SLEEP - delay) / 1000) @@ -539,7 +489,7 @@ def quiet_ping(hostname, timeout=WAIT_TIMEOUT, count=NUM_PACKETS, packet_size=PA mySeqNumber, packet_size, quiet=True) time.sleep(0.5) - for i in range(count): + for _ in range(count): delay = do_one(myStats, destIP, hostname, timeout, mySeqNumber, packet_size, quiet=True) @@ -556,6 +506,8 @@ def quiet_ping(hostname, timeout=WAIT_TIMEOUT, count=NUM_PACKETS, packet_size=PA myStats.fracLoss = float(myStats.pktsSent - myStats.pktsRcvd) / myStats.pktsSent if myStats.pktsRcvd > 0: myStats.avrgTime = myStats.totTime / myStats.pktsRcvd + else: + myStats.avrgTime = 0 # return tuple(max_rtt, min_rtt, avrg_rtt, percent_lost) return myStats.maxTime, myStats.minTime, myStats.avrgTime, myStats.fracLoss @@ -564,23 +516,14 @@ def quiet_ping(hostname, timeout=WAIT_TIMEOUT, count=NUM_PACKETS, packet_size=PA def main(): - parser = argparse.ArgumentParser(description=__description__) - parser.add_argument('-q', '--quiet', action='store_true', - help='quiet output') - parser.add_argument('-c', '--count', type=int, default=NUM_PACKETS, - help=('number of packets to be sent (default: %(default)s)')) - parser.add_argument('-W', '--timeout', type=float, default=WAIT_TIMEOUT, - help=('time to wait for a response in seoncds (default: %(default)s)')) - parser.add_argument('-s', '--packet-size', type=int, default=PACKET_SIZE, - help=('number of data bytes to be sent (default: %(default)s)')) + parser.add_argument('-q', '--quiet', action='store_true', help='quiet output') + parser.add_argument('-c', '--count', type=int, default=NUM_PACKETS, help=('number of packets to be sent (default: %(default)s)')) + parser.add_argument('-W', '--timeout', type=float, default=WAIT_TIMEOUT, help=('time to wait for a response in seoncds (default: %(default)s)')) + parser.add_argument('-s', '--packet-size', type=int, default=PACKET_SIZE, help=('number of data bytes to be sent (default: %(default)s)')) parser.add_argument('destination') args = parser.parse_args() - - ping = verbose_ping - if args.quiet: - ping = quiet_ping - + ping = quiet_ping if args.quiet else verbose_ping ping(args.destination, timeout=args.timeout * 1000, count=args.count, packet_size=args.packet_size) diff --git a/lcd4linux/src/plugin.py b/lcd4linux/src/plugin.py index 700dbb6..39b09a7 100644 --- a/lcd4linux/src/plugin.py +++ b/lcd4linux/src/plugin.py @@ -1,80 +1,72 @@ -# -*- coding: utf-8 -*-# - -# LCD4linux - Pearl DPF LCD Display, Samsung SPF-Line, Grautec-TFT, WLAN-LCDs, internes LCD über Skin -# -# written by joergm6 @ IHAD -# (Meteo-Station @ compilator) -# (dynamic scaling for rectangle analog clockfaces and -hands and tested by Mr.Servo @ OpenA.TV + Turbohai @ IHAD & OpenA.TV) -# (moon distance and moon illumination-ratio by Mr.Servo @ OpenA.TV) -# (new MSN-Weather and Open-Meteo forecasts by Mr.Servo @ OpenA.TV) -# the Yahoo+ system is uniformly valid for the weather iconssets of all weather services (by Mr.Servo @ OpenA.TV) -# -# This plugin is licensed under the The Non-Profit Open Software License version 3.0 (NPOSL-3.0) -# http://opensource.org/licenses/NPOSL-3.0 -# -# This plugin is NOT free software. It is open source, you are allowed to -# modify it (if you keep the license), but it may not be commercially -# distributed other than under the conditions noted above. -# Advertise with this Plugin is not allowed. -# For other uses, permission from the author is necessary. - -from __future__ import print_function, absolute_import, division +######################################################################################################### +# LCD4linux - Pearl DPF LCD Display, Samsung SPF-Line, Grautec-TFT, WLAN-LCDs, internes LCD über Skin # +# written by joergm6 @ IHAD # +# # +# This plugin is licensed under the The Non-Profit Open Software License version 3.0 (NPOSL-3.0) # +# https://opensource.org/licenses/NPOSL-3.0 # +# # +# This plugin is NOT free software. It is open source, you are allowed to modify it (if you keep the # +# license), but it may not be commercially distributed other than under the conditions noted above. # +# Advertise with this Plugin is not allowed. For other uses, permission from the author is necessary. # +######################################################################################################### # PYTHON IMPORTS from base64 import b64encode -from calendar import Calendar, mdays, weekday, weekheader, month_name +from calendar import Calendar, monthrange, weekheader, month_name from colorsys import rgb_to_hls, hls_to_rgb from ctypes.util import find_library from datetime import datetime, timedelta, date -from dateutil.parser import isoparse -from email import message_from_string +from email import message_from_bytes from email.header import decode_header from fcntl import ioctl from gc import enable, disable from glob import glob, iglob +from html import unescape +from http.server import HTTPServer, BaseHTTPRequestHandler from icalendar import vDatetime, Calendar as iCalendar from imaplib import IMAP4_SSL, IMAP4 -from math import pi, floor, cos -from mutagen.id3 import ID3 # type: ignore +from io import BytesIO +from json import loads +from math import pi, floor, cos, isclose +from mutagen.id3 import ID3 from mutagen.mp3 import MP3 from mutagen.flac import FLAC from mutagen.easyid3 import EasyID3 from locale import getlocale, setlocale, LC_ALL -from os import remove, statvfs, mkdir, rename, system, stat, symlink +from os import remove, mkdir, rename, system, stat, symlink from os.path import exists, islink, isdir, realpath, isfile, join, normpath, basename, getmtime, dirname, splitext from PIL import Image, ImageFont, ImageDraw, ImageColor, ImageEnhance from poplib import POP3_SSL, POP3 +from queue import Queue from random import shuffle, choice from re import findall, sub from requests import post, get, exceptions -from simplejson import loads -from six import BytesIO, ensure_binary, ensure_str, PY3 -from six.moves.queue import Queue -from six.moves.socketserver import ThreadingMixIn -from six.moves.urllib.parse import quote, urlparse, urlunparse -from six.moves.urllib.request import urlopen, Request, urlretrieve -from six.moves.BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler +from shutil import disk_usage from socket import setdefaulttimeout +from socketserver import ThreadingMixIn from struct import unpack from textwrap import TextWrapper, wrap from threading import Thread -from time import strftime, strptime, localtime, mktime, time, sleep, gmtime, timezone, altzone, daylight +from time import strftime, strptime, localtime, mktime, time, sleep, timezone, altzone, daylight from traceback import format_exc, print_stack -from twisted.internet.reactor import callInThread +from twisted.internet.reactor import callInThread, callFromThread +from twisted.internet.threads import deferToThread from unicodedata import normalize +from urllib.parse import quote, urlparse, urlunparse +from urllib.request import urlopen, Request, urlretrieve from usb import core from usb.backend.libusb1 import get_backend from xml.dom.minidom import parseString -from xml.etree.cElementTree import parse +from xml.etree.ElementTree import parse # ENIGMA IMPORTS -from enigma import eActionMap, iServiceInformation, iFrontendInformation, eDVBResourceManager, eDVBVolumecontrol, eTimer -from enigma import eEPGCache, eServiceReference, eServiceCenter, getDesktop, getEnigmaVersionString, eEnv, ePicLoad, iPlayableService +from enigma import eActionMap, iServiceInformation, iFrontendInformation, eDVBResourceManager, eDVBVolumecontrol, eTimer, eEPGCache +from enigma import eServiceReference, eServiceCenter, getDesktop, getEnigmaVersionString, eEnv, ePicLoad, iPlayableService, iDVBFrontend from Components.ActionMap import ActionMap from Components.AVSwitch import AVSwitch from Components.Button import Button -from Components.config import configfile, getConfigListEntry, ConfigPassword, ConfigYesNo, ConfigText, ConfigClock, ConfigSlider -from Components.config import config, Config, ConfigSelectionNumber, ConfigSelection, ConfigText +from Components.FileList import FileList +from Components.config import config, configfile, getConfigListEntry, Config, ConfigPassword, ConfigYesNo, ConfigText, ConfigClock, ConfigSelection, ConfigSelectionNumber, ConfigSlider from Components.ConfigList import ConfigListScreen from Components.Harddisk import harddiskmanager from Components.Input import Input @@ -86,7 +78,7 @@ from Components.Pixmap import Pixmap from Components.Renderer.Picon import getPiconName from Components.ServiceEventTracker import ServiceEventTracker -from Components.SystemInfo import SystemInfo +from Components.SystemInfo import SystemInfo, BoxInfo from Components.Sources.StaticText import StaticText from Plugins.Plugin import PluginDescriptor from Screens import Standby @@ -97,61 +89,19 @@ from Tools.BoundFunction import boundFunction from Tools.Directories import SCOPE_PLUGINS, SCOPE_CONFIG, SCOPE_FONTS, SCOPE_LIBDIR, SCOPE_SYSETC, resolveFilename - -try: - from Components.SystemInfo import BoxInfo - IMAGEDISTRO = BoxInfo.getItem("distro") - MODEL = BoxInfo.getItem("machinebuild") - ARCH = BoxInfo.getItem("architecture") -except Exception: - from boxbranding import getImageDistro, getBoxType, getImageArch - IMAGEDISTRO = getImageDistro() - MODEL = getBoxType() - ARCH = getImageArch() - - # PLUGIN IMPORTS -from . import Photoframe, dpf, _ # for localized messages +from . import Photoframe, dpf, __version__, _ # '_' for localized messages from .bluesound import BlueSound from .module import L4Lelement -from .myFileList import FileList as myFileList from .ping import quiet_ping from .utils import getIPTVProvider, getAudio from .ymc import YMC -from . import __version__ # DEPENDING IMPORTS & GLOBALS & INITIALIZATION -import ssl -try: - _create_unverified_https_context = ssl._create_unverified_context -except AttributeError: - pass -else: - ssl._create_default_https_context = _create_unverified_https_context - -if PY3: - from html import unescape as _unescape -else: - from HTMLParser import HTMLParser - _unescape = HTMLParser().unescape - -try: - from enigma import iDVBFrontend - feCable = iDVBFrontend.feCable - feSatellite = iDVBFrontend.feSatellite - feTerrestrial = iDVBFrontend.feTerrestrial - feok = True -except Exception: - feCable = 2 - feSatellite = 1 - feTerrestrial = 4 - feok = False - CrashFile = "/tmp/L4Lcrash.txt" pngutil = None try: if exists("/dev/lcd2"): - from fcntl import ioctl from pngutil import png_util pngutil = png_util.PNGUtil() pngutilconnect = pngutil.connect() @@ -177,16 +127,19 @@ parts = __version__.split(".") lenght = len(parts) -Version = "".join([f"{('V', '.', '-r')[idx]}{parts[idx]}" if idx < lenght else "" for idx in range(3)]) # fill up with '' if something is missing +Version = "".join([f"{('v', '.', '-r')[idx]}{parts[idx]}" if idx < lenght else "" for idx in range(3)]) # fill up with '' if something is missing +feCable = iDVBFrontend.feCable +feSatellite = iDVBFrontend.feSatellite +feTerrestrial = iDVBFrontend.feTerrestrial L4LElist = L4Lelement() L4LdoThread = True LCD4enigma2config = resolveFilename(SCOPE_CONFIG) # /etc/enigma2/ LCD4enigma2plugin = resolveFilename(SCOPE_PLUGINS) # /usr/lib/enigma2/python/Plugins/ LCD4lib = resolveFilename(SCOPE_LIBDIR) # /usr/lib/ LCD4etc = resolveFilename(SCOPE_SYSETC) # /etc/ -LCD4bin = "%s/" % eEnv.resolve("${bindir}") # /usr/bin/ -LCD4python = "%s/" % eEnv.resolve("${PYTHONPATH}") # /usr/lib/enigma2/python/ -LCD4share = "%s/" % eEnv.resolve("${datarootdir}") # /usr/share/ +LCD4bin = "{}/".format(eEnv.resolve("${bindir}")) # /usr/bin/ +LCD4python = "{}/".format(eEnv.resolve("${PYTHONPATH}")) # /usr/lib/enigma2/python/ +LCD4share = "{}/".format(eEnv.resolve("${datarootdir}")) # /usr/share/ LCD4picon = join(LCD4share, "enigma2/picon/") # /usr/share/enigma2/picon/ LCD4fonts = resolveFilename(SCOPE_FONTS) # /usr/share/fonts/ LCD4config = join(LCD4enigma2config, "lcd4config") # /etc/enigma2/lcd4config @@ -201,7 +154,7 @@ ClockBack = join(LCD4data, "PAclock2.png") Clock = join(LCD4data, "Clock") RecPic = join(LCD4data, "rec.png") -TMP = "%s/" % realpath("%stmp" % LCD4plugin) if islink("%stmp" % LCD4plugin) == True else "/tmp/" +TMP = "{}/".format(realpath(f"{LCD4plugin}tmp")) if islink(f"{LCD4plugin}tmp") is True else "/tmp/" TMPL = join(TMP, "lcd4linux/") xmlPIC = join(TMP, "l4ldisplay.png") xmlPICtmp = join(TMP, "l4ldisplaytmp.png") @@ -216,15 +169,15 @@ PIC3 = join(TMPL, "dpf3") PIC3tmp = join(TMPL, "dpf3tmp") PICcal = None -PICwetter = [None, None] +PICwetter: list[object] = [None, None] PICmeteo = join(TMPL, "dpfmeteo.png") PICfritz = join(TMPL, "dpffritz.png") -HTTPpic = "%sdpfhttp%%d.jpg" % TMPL -HTTPpictmp = "%sdpfhttptmp%%d.jpg" % TMPL +HTTPpic = f"{TMPL}dpfhttp%d.jpg" +HTTPpictmp = f"{TMPL}dpfhttptmp%d.jpg" TXTdemo = join(TMPL, "lcd4linux.demo") MP3tmp = join(TMPL, "id3coverart.jpg") GoogleCover = join(TMPL, "gcover.jpg") -WWWpic = "%swww%%s.jpg" % TMPL +WWWpic = f"{TMPL}www%s.jpg" LCDon = True ConfigMode = False ConfigStandby = False @@ -232,7 +185,28 @@ OSDon = 0 OSDtimer = -5 OSDdontshow = ["LCD4linux Settings", "Virtual Zap", "InfoBar", "Infobar", "SecondInfoBar", "FanControl2", "Mute", "LCD Text", "UnhandledKey", "QuickZap", "Volume", "PVRState"] -OSDdontskin = ["LCDdisplayFile", "VirtualZap", "InfoBar", "Infobar", "InfoBarSummary", "PictureInPicture", "SimpleSummary", "ScreenSummary", "TimeshiftState", "InfoScreen", "Standby", "EMCMediaCenter", "InfoBarMoviePlayerSummary", "PVRState", "ResolutionLabel", "WidgetBackground", "camodogFSScreen2", "camodogFSmini"] +# cspell: disable +OSDdontskin = [ + "LCDdisplayFile", + "VirtualZap", + "InfoBar", + "Infobar", + "InfoBarSummary", + "PictureInPicture", + "SimpleSummary", + "ScreenSummary", + "TimeshiftState", + "InfoScreen", + "Standby", + "EMCMediaCenter", + "InfoBarMoviePlayerSummary", + "PVRState", + "ResolutionLabel", + "WidgetBackground", + "camodogFSScreen2", + "camodogFSmini", +] +# cspell: enable wwwWetter = ["", ""] WetterType = "" WetterZoom = 0 @@ -242,6 +216,11 @@ OldWind = -88 OldMoonDist = -88 Oldillum = -88 +CELSIUS = _("C") +PERCENT = _("%") +MILLIMETER = _("mm") +KILOMETER = _("km") +DEGREE = _(b"\xc2\xb0".decode("utf-8")) # degree symbol '°', binary due to translation CalType = "" CalZoom = "" CalColor = "" @@ -289,7 +268,7 @@ Brief2 = Queue() Brief3 = Queue() MJPEG = ["0123", Queue(), Queue(), Queue()] -MJPEGserver = [None, None, None, None] +MJPEGserver: list[object | None] = [None, None, None, None] MJPEGreader = [0, 0, 0, 0] MJPEGrun = [0, 0, 0, 0] CPUtotal = 0 @@ -298,43 +277,102 @@ L4LMoon = (19, 0) INFO = "" WeekDays = [_("Mon"), _("Tue"), _("Wed"), _("Thur"), _("Fri"), _("Sat"), _("Sun")] -Farbe = [("black", _("black")), ("white", _("white")), - ("gray", _("gray")), ("silver", _("silver")), ("slategray", _("slategray")), - ("aquamarine", _("aquamarine")), - ("yellow", _("yellow")), ("greenyellow", _("greenyellow")), ("gold", _("gold")), - ("red", _("red")), ("tomato", _("tomato")), ("darkred", _("darkred")), ("indianred", _("indianred")), ("orange", _("orange")), ("darkorange", _("darkorange")), ("orangered", _("orangered")), - ("green", _("green")), ("lawngreen", _("lawngreen")), ("darkgreen", _("darkgreen")), ("lime", _("lime")), ("lightgreen", _("lightgreen")), - ("blue", _("blue")), ("blueviolet", _("blueviolet")), ("indigo", _("indigo")), ("darkblue", _("darkblue")), ("cadetblue", _("cadetblue")), ("cornflowerblue", _("cornflowerblue")), ("lightblue", _("lightblue")), - ("magenta", _("magenta")), ("violet", _("violet")), ("darkorchid", _("darkorchid")), ("deeppink", _("deeppink")), ("cyan", _("cyan")), - ("brown", _("brown")), ("sandybrown", _("sandybrown")), ("moccasin", _("moccasin")), ("rosybrown", _("rosybrown")), ("olive", _("olive")), +Farbe = [ + ("black", _("black")), ("white", _("white")), ("gray", _("gray")), ("silver", _("silver")), ("slategray", _("slategray")), + ("aquamarine", _("aquamarine")), ("yellow", _("yellow")), ("greenyellow", _("greenyellow")), ("gold", _("gold")), + ("red", _("red")), ("tomato", _("tomato")), ("darkred", _("darkred")), ("indianred", _("indianred")), ("orange", _("orange")), + ("darkorange", _("darkorange")), ("orangered", _("orangered")), ("green", _("green")), ("lawngreen", _("lawngreen")), + ("darkgreen", _("darkgreen")), ("lime", _("lime")), ("lightgreen", _("lightgreen")), ("blue", _("blue")), + ("blueviolet", _("blueviolet")), ("indigo", _("indigo")), ("darkblue", _("darkblue")), ("cadetblue", _("cadetblue")), + ("cornflowerblue", _("cornflowerblue")), ("lightblue", _("lightblue")), ("magenta", _("magenta")), ("violet", _("violet")), + ("darkorchid", _("darkorchid")), ("deeppink", _("deeppink")), ("cyan", _("cyan")), ("brown", _("brown")), + ("sandybrown", _("sandybrown")), ("moccasin", _("moccasin")), ("rosybrown", _("rosybrown")), ("olive", _("olive")) ] -ScreenSelect = [("0", _("off")), ("1", _("Screen 1")), ("2", _("Screen 2")), ("3", _("Screen 3")), ("12", _("Screen 1+2")), ("13", _("Screen 1+3")), ("23", _("Screen 2+3")), ("123", _("Screen 1+2+3")), ("4", _("Screen 4")), ("14", _("Screen 1+4")), ("24", _("Screen 2+4")), ("34", _("Screen 3+4")), ("124", _("Screen 1+2+4")), ("134", _("Screen 1+3+4")), ("234", _("Screen 2+3+4")), ("1234", _("Screen 1+2+3+4")), ("5", _("Screen 5")), ("6", _("Screen 6")), ("7", _("Screen 7")), ("8", _("Screen 8")), ("9", _("Screen 9")), ("12345", _("Screen 1-5")), ("123456", _("Screen 1-6")), ("1234567", _("Screen 1-7")), ("12345678", _("Screen 1-8")), ("123456789", _("Screen 1-9")), ("5678", _("Screen 5-8")), ("56789", _("Screen 5-9")), ("13579", _("Screen 1+3+5+7+9")), ("2468", _("Screen 2+4+6+8"))] -ScreenUse = [("1", _("Screen 1")), ("2", _("Screen 1-2")), ("3", _("Screen 1-3")), ("4", _("Screen 1-4")), ("5", _("Screen 1-5")), ("6", _("Screen 1-6")), ("7", _("Screen 1-7")), ("8", _("Screen 1-8")), ("9", _("Screen 1-9"))] -ScreenSet = [("1", _("Screen 1")), ("2", _("Screen 2")), ("3", _("Screen 3")), ("4", _("Screen 4")), ("5", _("Screen 5")), ("6", _("Screen 6")), ("7", _("Screen 7")), ("8", _("Screen 8")), ("9", _("Screen 9"))] +ScreenSelect = [ + ("0", _("off")), ("1", _("Screen 1")), ("2", _("Screen 2")), ("3", _("Screen 3")), ("12", _("Screen 1+2")), + ("13", _("Screen 1+3")), ("23", _("Screen 2+3")), ("123", _("Screen 1+2+3")), ("4", _("Screen 4")), ("14", _("Screen 1+4")), + ("24", _("Screen 2+4")), ("34", _("Screen 3+4")), ("124", _("Screen 1+2+4")), ("134", _("Screen 1+3+4")), + ("234", _("Screen 2+3+4")), ("1234", _("Screen 1+2+3+4")), ("5", _("Screen 5")), ("6", _("Screen 6")), ("7", _("Screen 7")), + ("8", _("Screen 8")), ("9", _("Screen 9")), ("12345", _("Screen 1-5")), ("123456", _("Screen 1-6")), + ("1234567", _("Screen 1-7")), ("12345678", _("Screen 1-8")), ("123456789", _("Screen 1-9")), ("5678", _("Screen 5-8")), + ("56789", _("Screen 5-9")), ("13579", _("Screen 1+3+5+7+9")), ("2468", _("Screen 2+4+6+8")) + ] +ScreenUse = [ + ("1", _("Screen 1")), ("2", _("Screen 1-2")), ("3", _("Screen 1-3")), ("4", _("Screen 1-4")), ("5", _("Screen 1-5")), + ("6", _("Screen 1-6")), ("7", _("Screen 1-7")), ("8", _("Screen 1-8")), ("9", _("Screen 1-9")) + ] +ScreenSet = [ + ("1", _("Screen 1")), ("2", _("Screen 2")), ("3", _("Screen 3")), ("4", _("Screen 4")), ("5", _("Screen 5")), + ("6", _("Screen 6")), ("7", _("Screen 7")), ("8", _("Screen 8")), ("9", _("Screen 9")) + ] OnOffSelect = [("0", _("off")), ("1", _("on"))] -TimeSelect = [("1", _("5s")), ("2", _("10s")), ("3", _("15s")), ("4", _("20s")), ("6", _("30s")), ("8", _("40s")), ("10", _("50s")), ("12", _("1min")), ("24", _("2min")), ("36", _("3min")), ("48", _("4min")), ("60", _("5min")), ("120", _("10min")), ("240", _("20min")), ("360", _("30min")), ("720", _("60min")), ("1440", _("2h")), ("2160", _("3h")), ("3600", _("5h"))] -LCDSelect = [("1", _("LCD 1")), ("2", _("LCD 2")), ("12", _("LCD 1+2")), ("3", _("LCD 3")), ("13", _("LCD 1+3")), ("23", _("LCD 2+3")), ("123", _("LCD 1+2+3"))] +TimeSelect = [ + ("1", _("5s")), ("2", _("10s")), ("3", _("15s")), ("4", _("20s")), ("6", _("30s")), ("8", _("40s")), ("10", _("50s")), + ("12", _("1min")), ("24", _("2min")), ("36", _("3min")), ("48", _("4min")), ("60", _("5min")), ("120", _("10min")), + ("240", _("20min")), ("360", _("30min")), ("720", _("60min")), ("1440", _("2h")), ("2160", _("3h")), ("3600", _("5h")) + ] +LCDSelect = [ + ("1", _("LCD 1")), ("2", _("LCD 2")), ("12", _("LCD 1+2")), ("3", _("LCD 3")), ("13", _("LCD 1+3")), + ("23", _("LCD 2+3")), ("123", _("LCD 1+2+3")) + ] LCDSwitchSelect = [("0", _("LCD 1-3")), ("1", _("LCD 1")), ("2", _("LCD 2")), ("3", _("LCD 3"))] LCDType = [ - ("11", _("Pearl (or compatible LCD) 320x240")), ("12", _("Pearl (or compatible LCD) 240x320")), ("121", _("Corby@Pearl 128x128")), ("122", _("AX206 (or compatible LCD) 480x320")), ("123", _("AX206 (or compatible LCD) 800x480")), - ("210", _("Samsung SPF-72H 800x480")), ("23", _("Samsung SPF-75H/76H 800x480")), ("24", _("Samsung SPF-87H 800x480")), ("25", _("Samsung SPF-87H old 800x480")), ("26", _("Samsung SPF-83H 800x600")), - ("29", _("Samsung SPF-85H/86H 800x600")), ("212", _("Samsung SPF-85P/86P 800x600")), ("28", _("Samsung SPF-105P 1024x600")), ("27", _("Samsung SPF-107H 1024x600")), ("213", _("Samsung SPF-107H old 1024x600")), - ("211", _("Samsung SPF-700T 800x600")), ("215", _("Samsung SPF-800P 800x480")), ("214", _("Samsung SPF-1000P 1024x600")), ("216", _("Samsung SPF-800W 800x600")), ("217", _("Samsung SPF-1000W 1024x768")), ("430", _("Internal TFT-LCD 400x240")), ("50", _("Internal Box-Skin-LCD")), - ("31", _("only Picture 320x240")), ("33", _("only Picture 800x480")), ("36", _("only Picture 800x600")), ("37", _("only Picture 1024x600")), ("320", _("only Picture Custom Size")), ("420", _("only Picture Custom Size 2")) -] + ("11", _("Pearl (or compatible LCD) 320x240")), ("12", _("Pearl (or compatible LCD) 240x320")), + ("121", _("Corby@Pearl 128x128")), ("122", _("AX206 (or compatible LCD) 480x320")), ("123", _("AX206 (or compatible LCD) 800x480")), + ("210", _("Samsung SPF-72H 800x480")), ("23", _("Samsung SPF-75H/76H 800x480")), ("24", _("Samsung SPF-87H 800x480")), + ("25", _("Samsung SPF-87H old 800x480")), ("26", _("Samsung SPF-83H 800x600")), ("29", _("Samsung SPF-85H/86H 800x600")), + ("212", _("Samsung SPF-85P/86P 800x600")), ("28", _("Samsung SPF-105P 1024x600")), ("27", _("Samsung SPF-107H 1024x600")), + ("213", _("Samsung SPF-107H old 1024x600")), ("211", _("Samsung SPF-700T 800x600")), ("215", _("Samsung SPF-800P 800x480")), + ("214", _("Samsung SPF-1000P 1024x600")), ("216", _("Samsung SPF-800W 800x600")), ("217", _("Samsung SPF-1000W 1024x768")), + ("430", _("Internal TFT-LCD 400x240")), ("50", _("Internal Box-Skin-LCD")), ("31", _("only Picture 320x240")), + ("33", _("only Picture 800x480")), ("36", _("only Picture 800x600")), ("37", _("only Picture 1024x600")), + ("320", _("only Picture Custom Size")), ("420", _("only Picture Custom Size 2")) + ] if PNGutilOK: LCDType.insert(14, ("930", _("Internal Vu+ Duo2 LCD 400x240"))) -xmlLCDType = [("96x64", _("96x64")), ("128x32", _("128x32")), ("128x64", _("128x64")), ("132x64", _("132x64")), ("220x176", _("220x176")), ("240x80", _("240x80")), ("255x64", _("255x64")), ("400x240", _("400x240")), ("480x320", _("480x320")), ("700x390", _("720x405")), ("800x480", _("800x480"))] -WetterType = [("12", _("2 Days 1 Line")), ("22", _("2 Days 2 Line")), ("1", _("4 Days 1 Line")), ("2", _("4 Days 2 Lines")), ("11", _("5 Days 1 Line")), ("21", _("5 Days 2 Lines")), ("3", _("Current")), ("4", _("Current Temperature (+C)")), ("41", _("Current Temperature (-C)")), ("5", _("4 Days Vertical View")), ("51", _("5 Days Vertical View"))] +xmlLCDType = [ + ("96x64", _("96x64")), ("128x32", _("128x32")), ("128x64", _("128x64")), ("132x64", _("132x64")), ("220x176", _("220x176")), + ("240x80", _("240x80")), ("255x64", _("255x64")), ("400x240", _("400x240")), ("480x320", _("480x320")), + ("700x390", _("720x405")), ("800x480", _("800x480")) + ] +WetterType = [ + ("12", _("2 Days 1 Line")), ("22", _("2 Days 2 Line")), ("1", _("4 Days 1 Line")), ("2", _("4 Days 2 Lines")), + ("11", _("5 Days 1 Line")), ("21", _("5 Days 2 Lines")), ("3", _("Current")), ("4", _("Current Temperature")), + ("5", _("4 Days Vertical View")), ("51", _("5 Days Vertical View")) + ] MeteoType = [("1", _("Current")), ("2", _("Current Temperature"))] -NetatmoType = [("THCPN", _("All")), ("T", _("Temperature")), ("TH", _("Temperature+Humidity")), ("TC", _("Temperature+Co2")), ("TCP", _("Temperature+Co2+Pressure"))] -NetatmoSelect = [("0", _("userdefined")), ("1", _("Module 1")), ("2", _("Module 2")), ("3", _("Module 3")), ("12", _("Module 1+2")), ("13", _("Module 1+3")), ("23", _("Module 2+3")), ("123", _("Module 1+2+3")), ("4", _("Module 4")), ("14", _("Module 1+4")), ("24", _("Module 2+4")), ("34", _("Module 3+4")), ("124", _("Module 1+2+4")), ("134", _("Module 1+3+4")), ("234", _("Module 2+3+4")), ("1234", _("Module 1-4")), ("5", _("Module 5")), ("12345", _("Module 1-5")), ("6", _("Module 6")), ("56", _("Module 5-6")), ("456", _("Module 4-6")), ("3456", _("Module 3-6")), ("23456", _("Module 2-6")), ("123456", _("Module 1-6"))] +NetatmoType = [ + ("THCPN", _("All")), ("T", _("Temperature")), ("TH", _("Temperature+Humidity")), + ("TC", _("Temperature+Co2")), ("TCP", _("Temperature+Co2+Pressure")) + ] +NetatmoSelect = [ + ("0", _("userdefined")), ("1", _("Module 1")), ("2", _("Module 2")), ("3", _("Module 3")), ("12", _("Module 1+2")), + ("13", _("Module 1+3")), ("23", _("Module 2+3")), ("123", _("Module 1+2+3")), ("4", _("Module 4")), + ("14", _("Module 1+4")), ("24", _("Module 2+4")), ("34", _("Module 3+4")), ("124", _("Module 1+2+4")), + ("134", _("Module 1+3+4")), ("234", _("Module 2+3+4")), ("1234", _("Module 1-4")), ("5", _("Module 5")), + ("12345", _("Module 1-5")), ("6", _("Module 6")), ("56", _("Module 5-6")), ("456", _("Module 4-6")), + ("3456", _("Module 3-6")), ("23456", _("Module 2-6")), ("123456", _("Module 1-6")) + ] CO2Type = [("0", _("Bar")), ("09", _("Bar+Value")), ("1", _("Knob")), ("19", _("Knob+Value"))] -ClockType = [("12", _("Time")), ("112", _("Date+Time")), ("1123", _("Date+Time+Weekday")), ("11", _("Date")), ("123", _("Time+Weekday")), ("13", _("Weekday")), ("4", _("Flaps Design Date")), ("41", _("Flaps Design Weekday")), ("51", _("Analog")), ("52", _("Analog+Date")), ("521", _("Analog+Date+Weekday")), ("521+", _("Analog+Date+Weekday 2"))] -AlignType = [("0", _("left")), ("1", _("center")), ("2", _("right")), ("0200", _("2%")), ("0300", _("3%")), ("0500", _("5%")), ("1000", _("10%")), ("1500", _("15%")), ("2000", _("20%")), ("2500", _("25%")), ("3000", _("30%")), ("3500", _("35%")), ("4000", _("40%")), ("4500", _("45%")), ("5000", _("50%")), ("5500", _("55%")), ("6000", _("60%")), ("6500", _("65%")), ("7000", _("70%")), ("7500", _("75%")), ("8000", _("80%")), ("8500", _("85%")), ("9000", _("90%")), ("9500", _("95%")), ("9700", _("97%")), ("9800", _("98%"))] -DescriptionType = [("10", _("Short")), ("12", _("Short (Extended)")), ("01", _("Extended")), ("21", _("Extended (Short)")), ("11", _("Short+Extended"))] +ClockType = [ + ("12", _("Time")), ("112", _("Date+Time")), ("1123", _("Date+Time+Weekday")), ("11", _("Date")), + ("123", _("Time+Weekday")), ("13", _("Weekday")), ("4", _("Flaps Design Date")), ("41", _("Flaps Design Weekday")), + ("51", _("Analog")), ("52", _("Analog+Date")), ("521", _("Analog+Date+Weekday")), ("521+", _("Analog+Date+Weekday 2")) + ] +AlignType = [ + ("0", _("left")), ("1", _("center")), ("2", _("right")), ("0200", _("2%")), ("0300", _("3%")), ("0500", _("5%")), + ("1000", _("10%")), ("1500", _("15%")), ("2000", _("20%")), ("2500", _("25%")), ("3000", _("30%")), ("3500", _("35%")), + ("4000", _("40%")), ("4500", _("45%")), ("5000", _("50%")), ("5500", _("55%")), ("6000", _("60%")), ("6500", _("65%")), + ("7000", _("70%")), ("7500", _("75%")), ("8000", _("80%")), ("8500", _("85%")), ("9000", _("90%")), ("9500", _("95%")), + ("9700", _("97%")), ("9800", _("98%")) + ] +DescriptionType = [ + ("10", _("Short")), ("12", _("Short (Extended)")), ("01", _("Extended")), ("21", _("Extended (Short)")), ("11", _("Short+Extended"))] CalType = [("9", _("no Calendar")), ("0", _("Month")), ("0A", _("Month+Header")), ("1", _("Week")), ("1A", _("Week+Header"))] -CalTypeE = [("0", _("no Dates")), ("D2", _("Dates compact 2 Lines")), ("D3", _("Dates compact 3 Lines")), ("C1", _("Dates 1 Line")), ("C3", _("Dates 3 Lines")), ("C5", _("Dates 5 Lines")), ("C9", _("Dates 9 Lines"))] +CalTypeE = [ + ("0", _("no Dates")), ("D2", _("Dates compact 2 Lines")), ("D3", _("Dates compact 3 Lines")), ("C1", _("Dates 1 Line")), + ("C3", _("Dates 3 Lines")), ("C5", _("Dates 5 Lines")), ("C9", _("Dates 9 Lines")) + ] CalLayout = [("0", _("Frame")), ("1", _("Underline")), ("2", _("Underline 2"))] CalListType = [("D", _("Dates compact")), ("D-", _("Dates compact no Icon")), ("C", _("Dates")), ("C-", _("Dates no Icon"))] FritzType = [("L", _("with Icon")), ("L-", _("no Icon")), ("TL", _("with Icon & Targetnumber")), ("TL-", _("no Icon, with Targetnumber"))] @@ -343,8 +381,14 @@ InfoCPU = [("0", _("no")), ("P", _("%")), ("L0", _("Load@1min")), ("L1", _("Load@5min")), ("PL0", _("% + Load@1min")), ("PL1", _("% + Load@5min"))] HddType = [("0", _("show run+sleep")), ("1", _("show run"))] MailType = [("A1", _("Always All")), ("A2", _("Always New")), ("B2", _("Only New"))] -MoonInfoSelect = [("000", _("off")), ("001", _("Distance only")), ("010", _("Illumination only")), ("100", _("Moonphase only")), ("011", _("Distance+Illumination")), ("101", _("Distance+Moonphase")), ("110", _("Illumination+Moonphase")), ("111", _("All Informations"))] -ProzentType = [("30", _("30%")), ("35", _("35%")), ("40", _("40%")), ("45", _("45%")), ("50", _("50%")), ("55", _("55%")), ("60", _("60%")), ("65", _("65%")), ("70", _("70%")), ("75", _("75%")), ("80", _("80%")), ("85", _("85%")), ("90", _("90%")), ("95", _("95%")), ("97", _("97%")), ("98", _("98%")), ("100", _("100%"))] +MoonInfoSelect = [ + ("000", _("off")), ("001", _("Distance only")), ("010", _("Illumination only")), ("100", _("Moonphase only")), + ("011", _("Distance+Illumination")), ("101", _("Distance+Moonphase")), ("110", _("Illumination+Moonphase")), ("111", _("All Informations"))] +ProzentType = [ + ("30", _("30%")), ("35", _("35%")), ("40", _("40%")), ("45", _("45%")), ("50", _("50%")), ("55", _("55%")), + ("60", _("60%")), ("65", _("65%")), ("70", _("70%")), ("75", _("75%")), ("80", _("80%")), ("85", _("85%")), + ("90", _("90%")), ("95", _("95%")), ("97", _("97%")), ("98", _("98%")), ("100", _("100%")) + ] WarningType = [("0", _("off")), ("2", _("2%")), ("3", _("3%")), ("5", _("5%")), ("10", _("10%")), ("15", _("15%")), ("20", _("20%")), ("25", _("25%"))] MailKonto = [("1", _("1")), ("2", _("1-2")), ("3", _("1-3")), ("4", _("1-4")), ("5", _("1-5"))] MailConnect = [("0", _("Pop3-SSL")), ("1", _("Pop3")), ("2", _("IMAP-SSL")), ("3", _("IMAP"))] @@ -356,24 +400,25 @@ FontType = [("0", _("Global")), ("1", _("1")), ("2", _("2")), ("3", _("3")), ("4", _("4")), ("5", _("5"))] DayType = [("0", _("all")), ("1", _("1")), ("2", _("2")), ("3", _("3")), ("7", _("7")), ("14", _("14")), ("30", _("30"))] RecordType = [("1", _("Corner")), ("1t", _("Corner+Timeshift")), ("2", _("Picon")), ("2t", _("Picon+Timeshift"))] -ProgressType = [("1", _("only Progress Bar")), -("2", _("with Remaining Minutes")), ("21", _("with Remaining Minutes (Size 1.5)")), ("22", _("with Remaining Minutes (Size 2)")), -("3", _("with Percent")), ("31", _("with Percent (Size 1.5)")), ("32", _("with Percent (Size 2)")), -("4", _("with Remaining Minutes (above)")), ("41", _("with Remaining Minutes (above/Size 1.5)")), ("42", _("with Remaining Minutes (above/Size 2)")), -("5", _("with Percent (above)")), ("51", _("with Percent (above/Size 1.5)")), ("52", _("with Percent (above/Size 2)")), -("6", _("with Remaining Minutes (below)")), ("61", _("with Remaining Minutes (below/Size 1.5)")), ("62", _("with Remaining Minutes (below/Size 2)")), -("7", _("with Percent (below)")), ("71", _("with Percent (below/Size 1.5)")), ("72", _("with Percent (below/Size 2)")), -("8", _("with Current 00:00")), ("81", _("with Current 00:00 (Size 1.5)")), ("82", _("with Current 00:00 (Size 2)")), -("9", _("with Current 00:00 (above)")), ("91", _("with Current 00:00 (above/Size 1.5)")), ("92", _("with Current 00:00 (above/Size 2)")), -("A", _("with Current 00:00 (below)")), ("A1", _("with Current 00:00 (below/Size 1.5)")), ("A2", _("with Current 00:00 (below/Size 2)")), -("B", _("with Percent Minutes / Total (above)")), ("B1", _("with Percent Minutes / Total (above/Size 1.5)")), ("B2", _("with Percent Minutes / Total (above/Size 2)")), -("C", _("with absolute Endtime")), ("C1", _("with absolute Endtime (Size 1.5)")), ("C2", _("with absolute Endtime (Size 2)")), -("D", _("with Minutes Total / Endtime (above)")), ("D1", _("with Minutes Total / Endtime (above/Size 1.5)")), ("D2", _("with Minutes Total / Endtime (above/Size 2)")), +ProgressType = [ + ("1", _("only Progress Bar")), + ("2", _("with Remaining Minutes")), ("21", _("with Remaining Minutes (Size 1.5)")), ("22", _("with Remaining Minutes (Size 2)")), + ("3", _("with Percent")), ("31", _("with Percent (Size 1.5)")), ("32", _("with Percent (Size 2)")), + ("4", _("with Remaining Minutes (above)")), ("41", _("with Remaining Minutes (above/Size 1.5)")), ("42", _("with Remaining Minutes (above/Size 2)")), + ("5", _("with Percent (above)")), ("51", _("with Percent (above/Size 1.5)")), ("52", _("with Percent (above/Size 2)")), + ("6", _("with Remaining Minutes (below)")), ("61", _("with Remaining Minutes (below/Size 1.5)")), ("62", _("with Remaining Minutes (below/Size 2)")), + ("7", _("with Percent (below)")), ("71", _("with Percent (below/Size 1.5)")), ("72", _("with Percent (below/Size 2)")), + ("8", _("with Current 00:00")), ("81", _("with Current 00:00 (Size 1.5)")), ("82", _("with Current 00:00 (Size 2)")), + ("9", _("with Current 00:00 (above)")), ("91", _("with Current 00:00 (above/Size 1.5)")), ("92", _("with Current 00:00 (above/Size 2)")), + ("A", _("with Current 00:00 (below)")), ("A1", _("with Current 00:00 (below/Size 1.5)")), ("A2", _("with Current 00:00 (below/Size 2)")), + ("B", _("with Percent Minutes / Total (above)")), ("B1", _("with Percent Minutes / Total (above/Size 1.5)")), ("B2", _("with Percent Minutes / Total (above/Size 2)")), + ("C", _("with absolute Endtime")), ("C1", _("with absolute Endtime (Size 1.5)")), ("C2", _("with absolute Endtime (Size 2)")), + ("D", _("with Minutes Total / Endtime (above)")), ("D1", _("with Minutes Total / Endtime (above/Size 1.5)")), ("D2", _("with Minutes Total / Endtime (above/Size 2)")), ] now = localtime() begin = mktime((now.tm_year, now.tm_mon, now.tm_mday, 6, 00, 0, now.tm_wday, now.tm_yday, now.tm_isdst)) # Find all directories "clock*" with result in a list, extract last two chars, extract integers, remove dupes, sort integers and convert it back to a list -FoundClockDir = list(map(str, sorted(set([int(i) for i in findall(r'\d+', str(list(map(lambda found: str(found)[-2:], glob("%s*" % Clock)))))])))) +FoundClockDir = list(map(str, sorted(set([int(i) for i in findall(r'\d+', str(list(map(lambda found: str(found)[-2:], glob(f"{Clock}*")))))])))) LCD4linux = Config() LCD4linux.Enable = ConfigYesNo(default=True) LCD4linux.L4LVersion = ConfigText(default="0.0r0", fixed_size=False) @@ -447,7 +492,6 @@ LCD4linux.WebIfDesign = ConfigSelection(choices=[("1", _("1 - normal")), ("2", _("2 - side by side"))], default="2") LCD4linux.WetterApi = ConfigSelection(choices=[("MSN", _("MSN")), ("OPENMETEO", _("Open-Meteo")), ("OPENWEATHER", _("OpenWeatherMap"))], default="MSN") LCD4linux.WetterApiKeyOpenWeatherMap = ConfigText(default="", fixed_size=False, visible_width=50) -LCD4linux.WetterApiKeyWeatherUnlocked = ConfigText(default="", fixed_size=False, visible_width=50) # TODO: deprecated, to be removed at next opportunity LCD4linux.WetterCity = ConfigText(default="Berlin", fixed_size=False) LCD4linux.WetterCoords = ConfigText(default="0,0", fixed_size=False) LCD4linux.Wetter2City = ConfigText(default="Berlin", fixed_size=False) @@ -520,8 +564,32 @@ LCD4linux.SizeW2 = ConfigSlider(default=800, increment=1, limits=(100, 2000)) LCD4linux.SizeH2 = ConfigSlider(default=600, increment=1, limits=(100, 1100)) LCD4linux.KeySwitch = ConfigYesNo(default=True) -LCD4linux.KeyScreen = ConfigSelection(choices=[("999", _("off")), ("163", _("2 x FastForwardKey")), ("208", _("2 x FastForwardKey Type 2")), ("1631", _("Long FastForwardKey")), ("2081", _("Long FastForwardKey Type 2")), ("358", _("2 x InfoKey")), ("3581", _("Long InfoKey")), ("113", _("2 x Mute"))], default="163") -LCD4linux.KeyOff = ConfigSelection(choices=[("999", _("off")), ("165", _("2 x FastBackwardKey")), ("168", _("2 x FastBackwardKey Type 2")), ("1651", _("Long FastBackwardKey")), ("1681", _("Long FastBackwardKey Type 2")), ("358", _("2 x InfoKey")), ("3581", _("Long InfoKey")), ("113", _("2 x Mute"))], default="165") +LCD4linux.KeyScreen = ConfigSelection( + choices=[ + ("999", _("off")), + ("163", _("2 x FastForwardKey")), + ("208", _("2 x FastForwardKey Type 2")), + ("1631", _("Long FastForwardKey")), + ("2081", _("Long FastForwardKey Type 2")), + ("358", _("2 x InfoKey")), + ("3581", _("Long InfoKey")), + ("113", _("2 x Mute")), + ], + default="163", +) +LCD4linux.KeyOff = ConfigSelection( + choices=[ + ("999", _("off")), + ("165", _("2 x FastBackwardKey")), + ("168", _("2 x FastBackwardKey Type 2")), + ("1651", _("Long FastBackwardKey")), + ("1681", _("Long FastBackwardKey Type 2")), + ("358", _("2 x InfoKey")), + ("3581", _("Long InfoKey")), + ("113", _("2 x Mute")), + ], + default="165", +) LCD4linux.Mail1Pop = ConfigText(default="", fixed_size=False, visible_width=50) LCD4linux.Mail1Connect = ConfigSelection(choices=MailConnect, default="0") LCD4linux.Mail1User = ConfigText(default="", fixed_size=False, visible_width=50) @@ -888,7 +956,7 @@ LCD4linux.TunerPos = ConfigSlider(default=0, increment=2, limits=(0, 1024)) LCD4linux.TunerAlign = ConfigSelection(choices=AlignType, default="0") LCD4linux.TunerSplit = ConfigYesNo(default=False) -LCD4linux.TunerType = ConfigSelection(choices=DirType + [("1", "%s x2" % _("horizontally"))], default="0") +LCD4linux.TunerType = ConfigSelection(choices=DirType + [("1", "{} x2".format(_("horizontally")))], default="0") LCD4linux.TunerActive = ConfigYesNo(default=False) LCD4linux.TunerFont = ConfigSelection(choices=FontType, default="0") LCD4linux.Vol = ConfigSelection(choices=ScreenSelect, default="0") @@ -928,7 +996,7 @@ LCD4linux.ExternalIpShadow = ConfigYesNo(default=False) LCD4linux.ExternalIpColor = ConfigSelection(choices=Farbe, default="white") LCD4linux.ExternalIpBackColor = ConfigSelection(choices=[("0", _("off"))] + Farbe, default="0") -LCD4linux.ExternalIpUrl = ConfigText(default="http://icanhazip.com", fixed_size=False, visible_width=50) +LCD4linux.ExternalIpUrl = ConfigText(default="https://icanhazip.com", fixed_size=False, visible_width=50) LCD4linux.RBox = ConfigSelection(choices=ScreenSelect, default="0") LCD4linux.RBoxLCD = ConfigSelection(choices=LCDSelect, default="1") LCD4linux.RBoxSize = ConfigSlider(default=15, increment=2, limits=(6, 100)) @@ -1035,6 +1103,7 @@ LCD4linux.WetterType = ConfigSelection(choices=WetterType, default="1") LCD4linux.WetterColor = ConfigSelection(choices=Farbe, default="white") LCD4linux.WetterShadow = ConfigYesNo(default=False) +LCD4linux.WetterAppendC = ConfigSelection(default=1, choices=[(0, _("No")), (1, _("Degree only")), (2, _("Celsius only")), (3, _("Degree and Celsius"))]) LCD4linux.WetterFont = ConfigSelection(choices=FontType, default="0") LCD4linux.Wetter2 = ConfigSelection(choices=ScreenSelect, default="0") LCD4linux.Wetter2LCD = ConfigSelection(choices=LCDSelect, default="1") @@ -1045,6 +1114,7 @@ LCD4linux.Wetter2Type = ConfigSelection(choices=WetterType, default="1") LCD4linux.Wetter2Color = ConfigSelection(choices=Farbe, default="white") LCD4linux.Wetter2Shadow = ConfigYesNo(default=False) +LCD4linux.Wetter2AppendC = ConfigSelection(default=0, choices=[(0, _("No")), (1, _("Degree only")), (2, _("Celsius only")), (3, _("Degree and Celsius"))]) LCD4linux.Wetter2Font = ConfigSelection(choices=FontType, default="0") LCD4linux.Meteo = ConfigSelection(choices=ScreenSelect, default="0") LCD4linux.MeteoLCD = ConfigSelection(choices=LCDSelect, default="1") @@ -1201,7 +1271,7 @@ LCD4linux.Text3BackColor = ConfigSelection(choices=[("0", _("off"))] + Farbe, default="0") LCD4linux.HTTP = ConfigSelection(choices=ScreenSelect, default="0") LCD4linux.HTTPLCD = ConfigSelection(choices=LCDSelect, default="1") -LCD4linux.HTTPURL = ConfigText(default="http://", fixed_size=False, visible_width=50) +LCD4linux.HTTPURL = ConfigText(default="https://", fixed_size=False, visible_width=50) LCD4linux.HTTPSize = ConfigSlider(default=20, increment=1, limits=(10, 300)) LCD4linux.HTTPPos = ConfigSlider(default=0, increment=2, limits=(0, 1024)) LCD4linux.HTTPAlign = ConfigSelection(choices=AlignType, default="0") @@ -1218,7 +1288,7 @@ LCD4linux.WWW1Size = ConfigSlider(default=200, increment=1, limits=(50, 1024)) LCD4linux.WWW1Pos = ConfigSlider(default=0, increment=2, limits=(0, 1024)) LCD4linux.WWW1Align = ConfigSelection(choices=AlignType, default="0") -LCD4linux.WWW1url = ConfigText(default="http://", fixed_size=False, visible_width=50) +LCD4linux.WWW1url = ConfigText(default="https://", fixed_size=False, visible_width=50) LCD4linux.WWW1w = ConfigSlider(default=800, increment=50, limits=(600, 2000)) LCD4linux.WWW1h = ConfigSlider(default=600, increment=50, limits=(100, 2000)) LCD4linux.WWW1CutX = ConfigSlider(default=0, increment=2, limits=(0, 1024)) @@ -1495,7 +1565,7 @@ LCD4linux.MPTunerPos = ConfigSlider(default=0, increment=2, limits=(0, 1024)) LCD4linux.MPTunerAlign = ConfigSelection(choices=AlignType, default="0") LCD4linux.MPTunerSplit = ConfigYesNo(default=False) -LCD4linux.MPTunerType = ConfigSelection(choices=DirType + [("1", "%s x2" % _("horizontally"))], default="0") +LCD4linux.MPTunerType = ConfigSelection(choices=DirType + [("1", "{} x2".format(_("horizontally")))], default="0") LCD4linux.MPTunerActive = ConfigYesNo(default=False) LCD4linux.MPTunerFont = ConfigSelection(choices=FontType, default="0") LCD4linux.MPInfo = ConfigSelection(choices=ScreenSelect, default="0") @@ -1593,6 +1663,7 @@ LCD4linux.MPWetterType = ConfigSelection(choices=WetterType, default="1") LCD4linux.MPWetterColor = ConfigSelection(choices=Farbe, default="white") LCD4linux.MPWetterShadow = ConfigYesNo(default=False) +LCD4linux.MPWetterAppendC = ConfigSelection(default=0, choices=[(0, _("No")), (1, _("Degree only")), (2, _("Celsius only")), (3, _("Degree and Celsius"))]) LCD4linux.MPWetterFont = ConfigSelection(choices=FontType, default="0") LCD4linux.MPWetter2 = ConfigSelection(choices=ScreenSelect, default="0") LCD4linux.MPWetter2LCD = ConfigSelection(choices=LCDSelect, default="1") @@ -1603,6 +1674,7 @@ LCD4linux.MPWetter2Type = ConfigSelection(choices=WetterType, default="1") LCD4linux.MPWetter2Color = ConfigSelection(choices=Farbe, default="white") LCD4linux.MPWetter2Shadow = ConfigYesNo(default=False) +LCD4linux.MPWetter2AppendC = ConfigSelection(default=0, choices=[(0, _("No")), (1, _("Degree only")), (2, _("Celsius only")), (3, _("Degree and Celsius"))]) LCD4linux.MPWetter2Font = ConfigSelection(choices=FontType, default="0") LCD4linux.MPMeteo = ConfigSelection(choices=ScreenSelect, default="0") LCD4linux.MPMeteoLCD = ConfigSelection(choices=LCDSelect, default="1") @@ -1941,7 +2013,7 @@ LCD4linux.StandbyTunerPos = ConfigSlider(default=0, increment=2, limits=(0, 1024)) LCD4linux.StandbyTunerAlign = ConfigSelection(choices=AlignType, default="0") LCD4linux.StandbyTunerSplit = ConfigYesNo(default=False) -LCD4linux.StandbyTunerType = ConfigSelection(choices=DirType + [("1", "%s x2" % _("horizontally"))], default="0") +LCD4linux.StandbyTunerType = ConfigSelection(choices=DirType + [("1", "{} x2".format(_("horizontally")))], default="0") LCD4linux.StandbyTunerActive = ConfigYesNo(default=False) LCD4linux.StandbyTunerFont = ConfigSelection(choices=FontType, default="0") LCD4linux.StandbyInfo = ConfigSelection(choices=ScreenSelect, default="0") @@ -2056,6 +2128,7 @@ LCD4linux.StandbyWetterType = ConfigSelection(choices=WetterType, default="1") LCD4linux.StandbyWetterColor = ConfigSelection(choices=Farbe, default="white") LCD4linux.StandbyWetterShadow = ConfigYesNo(default=False) +LCD4linux.StandbyWetterAppendC = ConfigSelection(default=0, choices=[(0, _("No")), (1, _("Degree only")), (2, _("Celsius only")), (3, _("Degree and Celsius"))]) LCD4linux.StandbyWetterFont = ConfigSelection(choices=FontType, default="0") LCD4linux.StandbyWetter2 = ConfigSelection(choices=ScreenSelect, default="0") LCD4linux.StandbyWetter2LCD = ConfigSelection(choices=LCDSelect, default="1") @@ -2066,6 +2139,7 @@ LCD4linux.StandbyWetter2Type = ConfigSelection(choices=WetterType, default="1") LCD4linux.StandbyWetter2Color = ConfigSelection(choices=Farbe, default="white") LCD4linux.StandbyWetter2Shadow = ConfigYesNo(default=False) +LCD4linux.StandbyWetter2AppendC = ConfigSelection(default=0, choices=[(0, _("No")), (1, _("Degree only")), (2, _("Celsius only")), (3, _("Degree and Celsius"))]) LCD4linux.StandbyWetter2Font = ConfigSelection(choices=FontType, default="0") LCD4linux.StandbyMeteo = ConfigSelection(choices=ScreenSelect, default="0") LCD4linux.StandbyMeteoLCD = ConfigSelection(choices=LCDSelect, default="1") @@ -2211,7 +2285,7 @@ LCD4linux.StandbyText3BackColor = ConfigSelection(choices=[("0", _("off"))] + Farbe, default="0") LCD4linux.StandbyHTTP = ConfigSelection(choices=ScreenSelect, default="0") LCD4linux.StandbyHTTPLCD = ConfigSelection(choices=LCDSelect, default="1") -LCD4linux.StandbyHTTPURL = ConfigText(default="http://", fixed_size=False, visible_width=50) +LCD4linux.StandbyHTTPURL = ConfigText(default="https://", fixed_size=False, visible_width=50) LCD4linux.StandbyHTTPSize = ConfigSlider(default=20, increment=1, limits=(10, 300)) LCD4linux.StandbyHTTPPos = ConfigSlider(default=0, increment=2, limits=(0, 1024)) LCD4linux.StandbyHTTPAlign = ConfigSelection(choices=AlignType, default="0") @@ -2224,7 +2298,7 @@ LCD4linux.StandbyWWW1Size = ConfigSlider(default=200, increment=1, limits=(50, 1024)) LCD4linux.StandbyWWW1Pos = ConfigSlider(default=0, increment=2, limits=(0, 1024)) LCD4linux.StandbyWWW1Align = ConfigSelection(choices=AlignType, default="0") -LCD4linux.StandbyWWW1url = ConfigText(default="http://", fixed_size=False, visible_width=50) +LCD4linux.StandbyWWW1url = ConfigText(default="https://", fixed_size=False, visible_width=50) LCD4linux.StandbyWWW1w = ConfigSlider(default=800, increment=50, limits=(600, 2000)) LCD4linux.StandbyWWW1h = ConfigSlider(default=600, increment=50, limits=(100, 2000)) LCD4linux.StandbyWWW1CutX = ConfigSlider(default=0, increment=2, limits=(0, 1024)) @@ -2420,28 +2494,31 @@ def getCallback(self): callback = property(getCallback) -def getFsize(text, f): - m1, m2 = f.getmetrics() - (w1, h1), (o1, o2) = f.font.getsize(text) - h1 = m1 + m2 - h = h1 + int(round(h1 / 33.)) - return w1, h +def getFsize(text, font): # Height is the line height of the font, not of the text. + left, top, right, bottom = font.getbbox(text) + ascent, descent = font.getmetrics() + height = ascent + descent + return right - left, height + round(height / 33.) + + +def getRainValue(text): # Strip the unit, e.g. "1.5mm" or "40%". + return float(sub(r"[^0-9.]", "", text) or "0") def Code_utf8(wert): - wert = "" if wert is None else _unescape(wert) - return wert.replace('\x86', '').replace('\x87', '') if PY3 else wert.replace('\xc2\x86', '').replace('\xc2\x87', '').decode("utf-8", "ignore") + wert = "" if wert is None else unescape(wert) + return wert.replace("\x86", "").replace("\x87", "") def L4log(nfo, wert=""): if str(LCD4linux.EnableEventLog.value) != "0": - print("[LCD4linux] %s %s" % (nfo, wert)) + print(f"[LCD4linux] {nfo} {wert}") if nfo and str(LCD4linux.EnableEventLog.value) != "3": try: with open("/tmp/L4log.txt", "a") as f: - f.write("%s %s %s\r\n" % (strftime("%H:%M:%S"), nfo, wert)) + f.write("{} {} {}\r\n".format(strftime("%H:%M:%S"), nfo, wert)) except OSError: - print("[LCD4linux] %s Logging-Error" % strftime("%H:%M:%S")) + print("[LCD4linux] {} Logging-Error".format(strftime("%H:%M:%S"))) def L4logE(nfo, wert=""): @@ -2555,15 +2632,19 @@ def getMJPEGreader(w): def setPopText(w): global PopText - PopText[0] = "%s%s" % (Code_utf8(_(strftime("%A"))), strftime(" %H:%M")) + PopText[0] = "{}{}".format(Code_utf8(_(strftime("%A"))), strftime(" %H:%M")) PopText[1] = Code_utf8(w) -def resetWetter(): +def resetWetter(w=None): global wwwWetter global PICwetter - wwwWetter = ["", ""] - PICwetter = [None, None] + if w: + wwwWetter[w] = "" + PICwetter[w] = None + else: + wwwWetter = ["", ""] + PICwetter = [None, None] def resetCal(): @@ -2580,12 +2661,12 @@ def L4LoadNewConfig(cfg): if isfile(LCD4default): LCD4linux.loadFromFile(LCD4default) L4log("Config-Load", cfg) - if MODEL == 'vuduo2': # due to 2 displays, LCD4linux is integrated in this boximage - LCD4linux.loadFromFile("%sdefault.vuduo2" % LCD4data) + if BoxInfo.getItem("machinebuild") == 'vuduo2': # due to 2 displays, LCD4linux is integrated in this boximage + LCD4linux.loadFromFile(f"{LCD4data}default.vuduo2") L4log("Config-Load for 'Vu+ duo²'", cfg) LCD4linux.loadFromFile(cfg) LCD4linux.load() - if LCD4linux.ConfigWriteAll.value == False: + if LCD4linux.ConfigWriteAll.value is False: LCD4linux.ConfigPath.value = P1 LCD4linux.PiconPath.value = P2 LCD4linux.PiconPathAlt.value = P3 @@ -2636,12 +2717,13 @@ def getTimeDiffUTC2(): def ConfTime(F, W): try: if exists(LCD4config) and W != [6, 0]: - if open(LCD4config, "r").read().find("config.%s=%d:%d\n" % (F, W[0], W[1])) == -1: - L4log("write alternate TimeConfig " + F, W) + entry = f"config.{F}={W[0]}:{W[1]}\n" + if open(LCD4config).read().find(entry) == -1: + L4log(f"write alternate TimeConfig {F}", W) with open(LCD4config, "a") as f: - f.write("config.%s=%d:%d\n" % (F, W[0], W[1])) + f.write(entry) except Exception: - L4log("Errot: write alternate TimeConfig " + F, W) + L4log(f"Errot: write alternate TimeConfig {F}", W) def ConfTimeCheck(): @@ -2657,13 +2739,13 @@ def ConfTimeCheck(): def ScaleGtoR(PROZ): if PROZ < 50: - R = max((255 * PROZ) / 50, 0) + R = max(int(255 * PROZ / 50), 0) G = 255 else: R = 255 - G = max((255 * (100 - PROZ)) / 50, 0) + G = max(int(255 * (100 - PROZ) / 50), 0) B = 0 - return "#%02x%02x%02x" % (R, G, B) + return f"#{R:02x}{G:02x}{B:02x}" def getDirection(angle): @@ -2683,11 +2765,105 @@ def getFeel(T, W): return 13.12 + 0.6215 * T - 11.37 * (W**0.16) + 0.3965 * T * (W**0.16) +# Media player queries, these run in a thread (deferToThread) and only return data. +def pingDevice(ip, timeout): + result = quiet_ping(ip, timeout) + if not result or result[2] <= 0.0: + result = quiet_ping(ip, timeout) + return bool(result) and result[2] > 0.0, str(result) + + +def querySonos(ip, pingTimeout, soco, socoIp, running): + tt = time() + result = {"soco": soco, "socoIp": socoIp, "ping": True, "pingResult": "", "state": None, "track": None, "volume": None, "error": None} + if soco is None or socoIp != ip: + result["socoIp"] = ip + L4log("Sonos Connect", ip) + try: + soco = SoCo(ip) + try: + soco = soco.group.coordinator + if ip not in str(soco): + L4log("Sonos Switched", soco) + except Exception: + L4log("Sonos Group-Coordinator Error") + except Exception: + L4log("Sonos Connect Error") + soco = None + result["soco"] = soco + try: + if pingTimeout > 0: + result["ping"], result["pingResult"] = pingDevice(ip, pingTimeout) + if (result["ping"] or not running) and soco is not None: + result["state"] = soco.get_current_transport_info().get("current_transport_state", "STOPPED") + if result["state"] == "PLAYING" and not soco.is_playing_tv: + result["track"] = soco.get_current_track_info() + result["volume"] = soco.volume + except Exception: + result["error"] = format_exc() + L4logE(f"Sonos RunTime: {time() - tt:.3f}") + return result + + +def queryYMCast(ip, pingTimeout, soco, socoIp, running): + tt = time() + result = {"soco": soco, "socoIp": socoIp, "ping": True, "pingResult": "", "info": None, "volume": 0, "mute": False, "error": None} + if soco is None or socoIp != ip: + result["socoIp"] = ip + L4log("MusicCast Connect", ip) + try: + soco = YMC(ip, L4logE) + except Exception: + L4log("YMCast Connect Error") + soco = None + result["soco"] = soco + try: + if pingTimeout > 0: + result["ping"], result["pingResult"] = pingDevice(ip, pingTimeout) + if (result["ping"] or not running) and soco is not None: + info = soco.getPlayInfo() or soco.getPlayInfo() + result["info"] = info + if info.get("playback", "") == "play": + status = soco.getStatus() + result["volume"] = status.get("volume", 0) + result["mute"] = status.get("mute", False) + except Exception: + result["error"] = format_exc() + L4logE(f"YMC RunTime: {time() - tt:.3f}") + return result + + +def queryBlue(ip, pingTimeout, soco, socoIp, running): + tt = time() + result = {"soco": soco, "socoIp": socoIp, "ping": True, "pingResult": "", "info": None, "image": "", "error": None} + if soco is None or socoIp != ip: + result["socoIp"] = ip + L4log("BlueSound Connect", ip) + try: + soco = BlueSound(ip) + except Exception: + L4log("BlueSound Connect Error") + soco = None + result["soco"] = soco + try: + if pingTimeout > 0: + result["ping"], result["pingResult"] = pingDevice(ip, pingTimeout) + if (result["ping"] or not running) and soco is not None: + info = soco.getStatus() or {} + result["info"] = info + image = info.get("image", "") + result["image"] = f"{soco.baseUrl}{image[1:]}" if image.startswith("/") else image + except Exception: + result["error"] = format_exc() + L4logE(f"BlueSound RunTime: {time() - tt:.3f}") + return result + + def getExternalIP(): try: req = Request(LCD4linux.ExternalIpUrl.value, data=None) response = urlopen(req, timeout=5) - return response.read() + return response.read().decode("utf-8", "ignore").strip() except Exception: L4logE("Error: getExternalIP", format_exc()) return "Error" @@ -2698,7 +2874,7 @@ def setFB2(value): def getFB2(check): - return isfile("/proc/stb/fb/sd_detach") and (LCD4linux.SwitchToFB2.value == True) if check else isfile("/proc/stb/fb/sd_detach") + return isfile("/proc/stb/fb/sd_detach") and (LCD4linux.SwitchToFB2.value is True) if check else isfile("/proc/stb/fb/sd_detach") def BRI(w1, w2): @@ -2719,7 +2895,7 @@ def virtBRI(LCD): def SensorRead(dat, isTemp=False): T = 0 - if isfile(dat) == True: + if isfile(dat) is True: lines = "" i = 0 with open(dat) as f: @@ -2729,13 +2905,13 @@ def SensorRead(dat, isTemp=False): sleep(0.01) curr = f.readline().strip() if len(curr) > 0: - lines += "%s\n" % curr + lines += f"{curr}\n" else: break if lines.find("temperature") >= 0: lines = lines[lines.find("temperature"):] hisitemp = findall(r"temperature\s*=\s*(\d+)", lines) - T = float(hisitemp[0]) if hisitemp else float("0" + sub(r"[^0-9^.]", "", lines)) + T = float(hisitemp[0]) if hisitemp else float(f'0{sub(r"[^0123456789^.]", "", lines)}') if isTemp and T > 1000.: T /= 1000. return round(T) @@ -2755,7 +2931,7 @@ def GetTempSensor(): try: Temp = SensorRead(ts, True) usable = float(Temp) > 10.0 and float(Temp) < 100.0 - L4logE("found Temp: '" + ts + "', raw data: '" + str(Temp) + "', ", "usable: " + str(usable)) + L4logE(f"found Temp: '{ts}', raw data: '{Temp}', ", f"usable: {usable}") if usable: return ts except Exception: @@ -2769,13 +2945,13 @@ def ICSdownloads(): global ICSdownrun global PICcal - L4logE("ICSdownloads... %s" % len(ICSlist)) - if (len(ICSlist) == 0 and LCD4linux.CalPlanerFS.value == False) or ICSdownrun == True: + L4logE(f"ICSdownloads... {len(ICSlist)}") + if (len(ICSlist) == 0 and LCD4linux.CalPlanerFS.value is False) or ICSdownrun is True: PICcal = None return ICSdownrun = True ICS.clear() - if LCD4linux.CalPlanerFS.value == True: + if LCD4linux.CalPlanerFS.value is True: try: from Plugins.Extensions.PlanerFS.PFSl4l import l4l_export liste = l4l_export().planerfs_liste @@ -2785,20 +2961,22 @@ def ICSdownloads(): liste = [] PlanerFSok = False L4logE("PlanerFS not registered") - if PlanerFSok == True: + if PlanerFSok is True: for Icomp in liste: DT = Icomp[0] L4logE(Icomp) - D = "%04d-%02d-%02d" % (DT.year, DT.month, DT.day) + D = f"{DT.year:04d}-{DT.month:02d}-{DT.day:02d}" if Icomp[4] == (0, 0): dateT = date(DT.year, DT.month, DT.day) else: DT = DT - timedelta(hours=getTimeDiffUTC()) - dateT = vDatetime.from_ical("%04d%02d%02dT%02d%02d00Z" % (DT.year, DT.month, DT.day, DT.hour, DT.minute)) + dateT = vDatetime.from_ical( + f"{DT.year:04d}{DT.month:02d}{DT.day:02d}T{DT.hour:02d}{DT.minute:02d}00Z" + ) if Icomp[6] == 0: dateS = Code_utf8(Icomp[1]) else: - dateS = "%s (%d)" % (Code_utf8(Icomp[1]), Icomp[6]) + dateS = f"{Code_utf8(Icomp[1])} ({Icomp[6]})" inew = [dateS, dateT, 4] Doppel = False if ICS.get(D, None) is None: @@ -2807,10 +2985,10 @@ def ICSdownloads(): for ii in ICS[D]: if ii[:2] == inew[:2]: Doppel = True - L4logE("ICS ignore %s" % inew) - if Doppel == False: + L4logE(f"ICS ignore {inew}") + if Doppel is False: ICS[D].append(inew) - L4logE("%s%s" % (D, inew)) + L4logE(f"{D}{inew}") for name in ICSlist: L4log("ICS read Col", name[1]) try: @@ -2824,13 +3002,13 @@ def ICSdownloads(): for Icomp in gcal.walk("VEVENT"): if Icomp.name == "VEVENT": rrule = str(Icomp.get("rrule", "")) - L4logE("%s - %s - %s" % (Icomp["dtstart"], Icomp.get('summary'), rrule)) + L4logE("{} - {} - {}".format(Icomp["dtstart"], Icomp.get('summary'), rrule)) if "UNTIL" in rrule or "INTERVAL" in rrule: y = {} for b in rrule.split(";"): if len(b.split("=")) > 1: y[b.split("=")[0]] = b.split("=")[1] - if y.get("UNTIL", "") != "" and y.get("UNTIL", "999999999") < "%4d%02d%02d" % (datetime.now().year, datetime.now().month, datetime.now().day): + if y.get("UNTIL", "") != "" and y.get("UNTIL", "999999999") < f"{datetime.now().year:04d}{datetime.now().month:02d}{datetime.now().day:02d}": L4logE("Until-Rule ignore", rrule) continue if int(y.get("INTERVAL", "1")) > 1: @@ -2845,8 +3023,9 @@ def ICSdownloads(): if "WEEKLY" in rrule: for i in range(1, 5): WEEKLY.append(Icomp.decoded("dtstart") + timedelta(i * 7)) - nextmonth = today + timedelta(mdays[today.month]) # 2012-01-23 - nextmonth2 = today + timedelta(mdays[today.month] - 3) # save Month+1 if days to long + days = monthrange(today.year, today.month)[1] + nextmonth = today + timedelta(days=days) # 2012-01-23 + nextmonth2 = today + timedelta(days=days - 3) # save Month+1 if days to long DTstart = str(Icomp.decoded("dtstart")) if DTstart.startswith(strftime("%Y-%m")) or DTstart.startswith(nextmonth.strftime("%Y-%m")) or DTstart.startswith(nextmonth2.strftime("%Y-%m")): D = DTstart[:10] @@ -2858,10 +3037,10 @@ def ICSdownloads(): for ii in ICS[D]: if ii[:2] == inew[:2]: Doppel = True - L4log("ICS ignore %s" % inew) - if Doppel == False: + L4log(f"ICS ignore {inew}") + if Doppel is False: ICS[D].append(inew) - L4log("%s%s" % (D, inew)) + L4log(f"{D}{inew}") for w in WEEKLY: D = str(w)[:10] if ICS.get(D, None) is None: @@ -2877,7 +3056,7 @@ def ICSdownloads(): except Exception: pass ICSlist = [] - L4logE("ICS laenge %s" % len(ICS)) + L4logE(f"ICS laenge {len(ICS)}") ICSdownrun = False PICcal = None @@ -2928,7 +3107,7 @@ def OSDclose(): global OSDon OSDon = 0 L4log("Screen close") - rmFile("%sdpfgrab.jpg" % TMPL) + rmFile(f"{TMPL}dpfgrab.jpg") if getFB2(False): setFB2("1") @@ -2955,7 +3134,7 @@ def L4L_replacement_Screen_show(self): ib = self["Title"].getText() L4log("Screen", ib) if ib not in OSDdontshow: - L4log("Open Screen:" + str(ib), "Skin:" + str(self.skinName)) + L4log(f"Open Screen:{ib}", f"Skin:{self.skinName}") OSDon = 3 if getFB2(True): setFB2("0") @@ -2982,24 +3161,24 @@ def L4L_replacement_Screen_show(self): def find_dev(Anzahl, idVendor, idProduct): gefunden = False if isfile("/proc/bus/usb/devices"): - i = open("/proc/bus/usb/devices", "r").read().lower() - pos = i.find("vendor=%04x prodid=%04x" % (idVendor, idProduct)) + i = open("/proc/bus/usb/devices").read().lower() + pos = i.find(f"vendor={idVendor:04x} prodid={idProduct:04x}") if pos > 0: if Anzahl == 2: - pos = i.find("vendor=%04x prodid=%04x" % (idVendor, idProduct), pos + 10) + pos = i.find(f"vendor={idVendor:04x} prodid={idProduct:04x}", pos + 10) if pos > 0: gefunden = True else: gefunden = True - elif USBok == True: + elif USBok is True: try: - L4logE("usb.core %s" % list(core.find(idVendor=idVendor, find_all=True))) + L4logE(f"usb.core {list(core.find(idVendor=idVendor, find_all=True))}") if len(list(core.find(idVendor=idVendor, idProduct=idProduct, find_all=True))) >= Anzahl: L4logE("usb.core find") gefunden = True except Exception: L4log("Error usb.core find") - L4log("%d. Vendor=%04x ProdID=%04x %s" % (Anzahl, idVendor, idProduct, gefunden)) + L4log(f"{Anzahl}. Vendor={idVendor:04x} ProdID={idProduct:04x} {gefunden}") return gefunden @@ -3008,7 +3187,7 @@ def find_dev2(idVendor, idProduct, idVendor2, idProduct2): try: if len(list(core.find(idVendor=idVendor, idProduct=idProduct, find_all=True)) + list(core.find(idVendor=idVendor2, idProduct=idProduct2, find_all=True))) >= 2: gefunden = True - L4log("Vendor=%04x ProdID=%04x or Vendor=%04x ProdID=%04x %s" % (idVendor, idProduct, idVendor2, idProduct2, gefunden)) + L4log(f"Vendor={idVendor:04x} ProdID={idProduct:04x} or Vendor={idVendor2:04x} ProdID={idProduct2:04x} {gefunden}") except Exception: L4log("Error usb.core2 find") return gefunden @@ -3027,17 +3206,11 @@ def getpiconres(x, y, full, picon, channelname, channelname2, P2, P2A, P2C): PD = "" PIC = [] PIC.append(join(P2, picon)) - if PY3: - name2 = "%s.png" % channelname.encode("latin-1", "ignore").decode("utf-8") - name4 = "%s.png" % channelname.encode("utf-8", "ignore").decode("utf-8") - name3 = "%s.png" % channelname2.replace('\x87', '').replace('\x86', '') - name = normalize('NFKD', channelname) - else: - name2 = "%s.png" % channelname.decode("utf-8").encode("latin-1", "ignore") - name4 = "%s.png" % channelname.decode("utf-8").encode("utf-8", "ignore") - name3 = "%s.png" % channelname2.replace('\xc2\x87', '').replace('\xc2\x86', '').decode("utf-8").encode("utf-8") - name = normalize('NFKD', channelname.decode('unicode-escape')) - name = "%s.png" % sub(r'[^a-z0-9]', '', str(name).replace('&', 'and').replace('+', 'plus').replace('*', 'star').lower()) + name2 = "{}.png".format(channelname.encode("latin-1", "ignore").decode("utf-8")) + name4 = "{}.png".format(channelname.encode("utf-8", "ignore").decode("utf-8")) + name3 = "{}.png".format(channelname2.replace('\x87', '').replace('\x86', '')) + name = normalize('NFKD', channelname) + name = "{}.png".format(sub(r'[^a-z0-9]', '', str(name).replace('&', 'and').replace('+', 'plus').replace('*', 'star').lower())) PIC.append(join(P2, name3)) PIC.append(join(P2, name2)) PIC.append(join(P2, name)) @@ -3064,7 +3237,7 @@ def getpiconres(x, y, full, picon, channelname, channelname2, P2, P2A, P2C): if len(P2A) > 3: PIC.append(join(P2A, picon)) PIC.append(join(P2, "picon_default.png")) - L4logE("Piconsearch %s" % PIC) + L4logE(f"Piconsearch {PIC}") for Pic in PIC: if isfile(Pic): PD = Pic @@ -3076,14 +3249,14 @@ def getpiconres(x, y, full, picon, channelname, channelname2, P2, P2A, P2C): if str(LCD4linux.PiconTransparenz.value) == "2": pil_image = pil_image.convert("RGBA") xx, yy = pil_image.size - if full == False: + if full is False: y = int(float(x) / xx * yy) if str(LCD4linux.BilderQuality.value) == "0": pil_image = pil_image.resize((x, y)) else: - pil_image = pil_image.resize((x, y), Image.Resampling.LANCZOS if PY3 else Image.ANTIALIAS) - s = statvfs(P2C) - if (s.f_bsize * s.f_bavail / 1024) < 100: + pil_image = pil_image.resize((x, y), Image.Resampling.LANCZOS) + usage = disk_usage(P2C) + if usage.free / 1024 < 100: L4log("Error: Cache Directory near full") return "" PD = join(P2C, basename(PD)) @@ -3156,36 +3329,30 @@ def writeHelligkeit(hell, night, STOP): return R AktHelligkeit = [h1, h2, h3] + L4LElist.getBrightness(0, False) L4LElist.resetBrightness([h1, h2, h3]) - L4log("write Bright: %s" % AktHelligkeit) - if SamsungDevice is not None and LCD4linux.LCDType1.value[0] == "1": - if dpf.setBacklight(SamsungDevice, h1 if h1 < 8 else 7) == False: - dpf.close(SamsungDevice) - SamsungDevice = None - if SamsungDevice2 is not None and LCD4linux.LCDType2.value[0] == "1": - if dpf.setBacklight(SamsungDevice2, h2 if h2 < 8 else 7) == False: - dpf.close(SamsungDevice2) - SamsungDevice2 = None - if SamsungDevice3 is not None and LCD4linux.LCDType3.value[0] == "1": - if dpf.setBacklight(SamsungDevice3, h3 if h3 < 8 else 7) == False: - dpf.close(SamsungDevice3) - SamsungDevice3 = None - if isfile("%sgrautec/settings/takeownership" % LCD4etc) and STOP == False: + L4log(f"write Bright: {AktHelligkeit}") + if SamsungDevice is not None and LCD4linux.LCDType1.value[0] == "1" and dpf.setBacklight(SamsungDevice, h1 if h1 < 8 else 7) is False: + dpf.close(SamsungDevice) + SamsungDevice = None + if SamsungDevice2 is not None and LCD4linux.LCDType2.value[0] == "1" and dpf.setBacklight(SamsungDevice2, h2 if h2 < 8 else 7) is False: + dpf.close(SamsungDevice2) + SamsungDevice2 = None + if SamsungDevice3 is not None and LCD4linux.LCDType3.value[0] == "1" and dpf.setBacklight(SamsungDevice3, h3 if h3 < 8 else 7) is False: + dpf.close(SamsungDevice3) + SamsungDevice3 = None + if isfile(f"{LCD4etc}grautec/settings/takeownership") and STOP is False: try: - if LCD4linux.LCDType1.value[0] == "4": - if isfile("/tmp/usbtft-brightness"): - open("/tmp/usbtft-brightness", "w").write(str(int(h1 * 6.3))) - elif isfile("/proc/stb/lcd/oled_brightness"): - open("/proc/stb/lcd/oled_brightness", "w").write(str(int(h1 * 25.5))) - if LCD4linux.LCDType2.value[0] == "4": - if isfile("/tmp/usbtft-brightness"): - open("/tmp/usbtft-brightness", "w").write(str(int(h2 * 6.3))) - elif isfile("/proc/stb/lcd/oled_brightness"): - open("/proc/stb/lcd/oled_brightness", "w").write(str(int(h2 * 25.5))) - if LCD4linux.LCDType3.value[0] == "4": - if isfile("/tmp/usbtft-brightness"): - open("/tmp/usbtft-brightness", "w").write(str(int(h3 * 6.3))) - elif isfile("/proc/stb/lcd/oled_brightness"): - open("/proc/stb/lcd/oled_brightness", "w").write(str(int(h3 * 25.5))) + if LCD4linux.LCDType1.value[0] == "4" and isfile("/tmp/usbtft-brightness"): + open("/tmp/usbtft-brightness", "w").write(str(int(h1 * 6.3))) + elif LCD4linux.LCDType1.value[0] == "4" and isfile("/proc/stb/lcd/oled_brightness"): + open("/proc/stb/lcd/oled_brightness", "w").write(str(int(h1 * 25.5))) + if LCD4linux.LCDType2.value[0] == "4" and isfile("/tmp/usbtft-brightness"): + open("/tmp/usbtft-brightness", "w").write(str(int(h2 * 6.3))) + elif LCD4linux.LCDType2.value[0] == "4" and isfile("/proc/stb/lcd/oled_brightness"): + open("/proc/stb/lcd/oled_brightness", "w").write(str(int(h2 * 25.5))) + if LCD4linux.LCDType3.value[0] == "4" and isfile("/tmp/usbtft-brightness"): + open("/tmp/usbtft-brightness", "w").write(str(int(h3 * 6.3))) + elif LCD4linux.LCDType3.value[0] == "4" and isfile("/proc/stb/lcd/oled_brightness"): + open("/proc/stb/lcd/oled_brightness", "w").write(str(int(h3 * 25.5))) except Exception: pass try: @@ -3198,7 +3365,7 @@ def writeHelligkeit(hell, night, STOP): LCDdisplay.setBright(h3) except Exception: L4logE("Error LCD:", format_exc()) - if PNGutilOK == True: + if PNGutilOK is True: H = -1 if LCD4linux.LCDType1.value[0] == "9": H = h1 @@ -3214,7 +3381,7 @@ def writeHelligkeit(hell, night, STOP): with open("/dev/lcd2", 'w') as led_fd: ioctl(led_fd, 0x10, H) except Exception as err: - L4log("Error LCD Communication: %s" % str(err)) + L4log(f"Error LCD Communication: {str(err)}") return R @@ -3222,15 +3389,15 @@ def doDPF(dev, im, s): global SamsungDevice global SamsungDevice2 global SamsungDevice3 - if dev == 1 and dpf.showImage(SamsungDevice, s.im[im]) == False: + if dev == 1 and dpf.showImage(SamsungDevice, s.im[im]) is False: L4log("Error writing DPF Device") dpf.close(SamsungDevice) SamsungDevice = None - elif dev == 2 and dpf.showImage(SamsungDevice2, s.im[im]) == False: + elif dev == 2 and dpf.showImage(SamsungDevice2, s.im[im]) is False: L4log("Error writing DPF2 Device") dpf.close(SamsungDevice2) SamsungDevice2 = None - elif dev == 3 and dpf.showImage(SamsungDevice3, s.im[im]) == False: + elif dev == 3 and dpf.showImage(SamsungDevice3, s.im[im]) is False: L4log("Error writing DPF3 Device") dpf.close(SamsungDevice3) SamsungDevice3 = None @@ -3240,57 +3407,57 @@ def writeLCD1(s, im, quality, SAVE=True): global SamsungDevice global MJPEGreader pic = None - if s.imWrite[im] == True: + if s.imWrite[im] is True: L4log("Ignore ImWrite", im) return s.imWrite[im] = True - if LCD4linux.LCDType1.value[0] in ["2", "3"] and virtBRI(1) not in [0, 10] and SAVE == True and LCD4linux.MJPEGvirtbri1.value == True: + if LCD4linux.LCDType1.value[0] in ["2", "3"] and virtBRI(1) not in [0, 10] and SAVE is True and LCD4linux.MJPEGvirtbri1.value is True: s.tmp[im] = ImageEnhance.Brightness(s.im[im]).enhance(virtBRI(1)) s.im[im] = s.tmp[im] - bild = "%s.png" % PICtmp + bild = f"{PICtmp}.png" if LCD4linux.LCDType1.value[0] == "1": if SamsungDevice is not None: L4log("writing to DPF Device") doDPF(1, im, s) - if "1" in LCD4linux.SavePicture.value and SAVE == True: + if "1" in LCD4linux.SavePicture.value and SAVE is True: if str(LCD4linux.LCDRotate1.value) != "0": s.im[im] = s.im[im].rotate(-int(LCD4linux.LCDRotate1.value), expand=True) try: s.im[im].save(bild, "PNG" if LCD4linux.BilderTyp.value == "png" else "JPEG") if isfile(bild): - rename(bild, "%s.png" % PIC) + rename(bild, f"{PIC}.png") except Exception as err: - L4log("Error write Picture: %s" % str(err)) + L4log(f"Error write Picture: {str(err)}") elif LCD4linux.LCDType1.value[0] == "3": L4log("writing Picture") try: - datei = "%s.%s" % (PICtmp, LCD4linux.BilderTyp.value) + datei = f"{PICtmp}.{LCD4linux.BilderTyp.value}" s.im[im].save(datei, "PNG" if LCD4linux.BilderTyp.value == "png" else "JPEG") if isfile(datei): - rename(datei, "%s.%s" % (PIC, LCD4linux.BilderTyp.value)) + rename(datei, f"{PIC}.{LCD4linux.BilderTyp.value}") except Exception as err: - L4log("Error write Picture: %s" % str(err)) + L4log(f"Error write Picture: {str(err)}") elif LCD4linux.LCDType1.value[0] == "4": L4log("writing TFT-LCD") try: s.im[im].save("/tmp/usbtft-bmp", "BMP") - if "1" in LCD4linux.SavePicture.value and SAVE == True: + if "1" in LCD4linux.SavePicture.value and SAVE is True: if str(LCD4linux.LCDRotate1.value) != "0": s.im[im] = s.im[im].rotate(-int(LCD4linux.LCDRotate1.value), expand=True) s.im[im].save(bild, "PNG" if LCD4linux.BilderTyp.value == "png" else "JPEG") if isfile(bild): - rename(bild, "%s.png" % PIC) + rename(bild, f"{PIC}.png") except Exception as err: - L4log("Error write Picture: %s" % str(err)) + L4log(f"Error write Picture: {str(err)}") elif LCD4linux.LCDType1.value[0] == "5": L4log("writing Internal-LCD") try: - if "1" in LCD4linux.SavePicture.value and SAVE == True: + if "1" in LCD4linux.SavePicture.value and SAVE is True: if str(LCD4linux.LCDRotate1.value) != "0": s.im[im] = s.im[im].rotate(-int(LCD4linux.LCDRotate1.value), expand=True) s.im[im].save(bild, "PNG" if LCD4linux.BilderTyp.value == "png" else "JPEG") if isfile(bild): - rename(bild, "%s.png" % PIC) + rename(bild, f"{PIC}.png") if int(LCD4linux.xmlOffset.value) != 0: MAX_W, MAX_H = s.im[im].size MAX_W += (int(LCD4linux.xmlOffset.value) * 2) @@ -3309,17 +3476,17 @@ def writeLCD1(s, im, quality, SAVE=True): if isfile(xmlPICtmp): rename(xmlPICtmp, xmlPIC) except Exception as err: - L4log("Error write Picture: %s" % str(err)) + L4log(f"Error write Picture: {str(err)}") elif LCD4linux.LCDType1.value[0] == "9": L4log("writing to Vu+ LCD") try: s.im[im].save(bild, "PNG") if isfile(bild): - rename(bild, "%s.png" % PIC) + rename(bild, f"{PIC}.png") except Exception as err: - L4log("Error write Picture: %s" % str(err)) + L4log(f"Error write Picture: {str(err)}") if pngutil and pngutilconnect != 0: - pngutil.send("%s.png" % PIC) + pngutil.send(f"{PIC}.png") else: L4log("Error no Vu+ connect") else: @@ -3333,20 +3500,20 @@ def writeLCD1(s, im, quality, SAVE=True): Photoframe.write_jpg2frame(SamsungDevice, pic) except Exception as err: SamsungDevice = None - L4log("Samsung 1 write Error: %s" % str(err)) - if "1" in LCD4linux.SavePicture.value and SAVE == True: + L4log(f"Samsung 1 write Error: {str(err)}") + if "1" in LCD4linux.SavePicture.value and SAVE is True: try: - datei = "%s.jpg" % PICtmp + datei = f"{PICtmp}.jpg" if str(LCD4linux.LCDRotate1.value) != "0": s.im[im] = s.im[im].rotate(-int(LCD4linux.LCDRotate1.value), expand=True) s.im[im].save(datei, "JPEG") elif pic is not None: open(datei, "wb").write(pic) if isfile(datei): - rename(datei, "%s.jpg" % PIC) + rename(datei, f"{PIC}.jpg") except Exception as err: - L4log("Error write Picture: %s" % str(err)) - if LCD4linux.MJPEGenable1.value == True: + L4log(f"Error write Picture: {str(err)}") + if LCD4linux.MJPEGenable1.value is True: if MJPEG[0][1] == "a": MJPEG_stop(1) sleep(0.5) @@ -3360,57 +3527,57 @@ def writeLCD2(s, im, quality, SAVE=True): global SamsungDevice2 global MJPEGreader pic = None - if s.imWrite[im] == True: + if s.imWrite[im] is True: L4log("Ignore ImWrite", im) return s.imWrite[im] = True - if LCD4linux.LCDType2.value[0] in ["2", "3"] and virtBRI(2) not in [0, 10] and SAVE == True and LCD4linux.MJPEGvirtbri2.value == True: + if LCD4linux.LCDType2.value[0] in ["2", "3"] and virtBRI(2) not in [0, 10] and SAVE is True and LCD4linux.MJPEGvirtbri2.value is True: s.tmp[im] = ImageEnhance.Brightness(s.im[im]).enhance(virtBRI(2)) s.im[im] = s.tmp[im] - bild = "%s.png" % PIC2tmp + bild = f"{PIC2tmp}.png" if LCD4linux.LCDType2.value[0] == "1": if SamsungDevice2 is not None: L4log("writing to DPF2 Device") doDPF(2, im, s) - if "2" in LCD4linux.SavePicture.value and SAVE == True: + if "2" in LCD4linux.SavePicture.value and SAVE is True: if str(LCD4linux.LCDRotate2.value) != "0": s.im[im] = s.im[im].rotate(-int(LCD4linux.LCDRotate2.value), expand=True) try: s.im[im].save(bild, "PNG" if LCD4linux.BilderTyp.value == "png" else "JPEG") if isfile(bild): - rename(bild, "%s.png" % PIC2) + rename(bild, f"{PIC2}.png") except Exception as err: - L4log("Error write Picture2: %s" % str(err)) + L4log(f"Error write Picture2: {str(err)}") elif LCD4linux.LCDType2.value[0] == "3": L4log("writing Picture2") try: - datei = "%s.%s" % (PIC2tmp, LCD4linux.BilderTyp.value) + datei = f"{PIC2tmp}.{LCD4linux.BilderTyp.value}" s.im[im].save(datei, "PNG" if LCD4linux.BilderTyp.value == "png" else "JPEG") if isfile(datei): - rename(datei, "%s.%s" % (PIC2, LCD4linux.BilderTyp.value)) + rename(datei, f"{PIC2}.{LCD4linux.BilderTyp.value}") except Exception as err: - L4log("Error write Picture2: %s" % str(err)) + L4log(f"Error write Picture2: {str(err)}") elif LCD4linux.LCDType2.value[0] == "4": L4log("writing TFT-LCD2") try: s.im[im].save("/tmp/usbtft-bmp", "BMP") - if "2" in LCD4linux.SavePicture.value and SAVE == True: + if "2" in LCD4linux.SavePicture.value and SAVE is True: if str(LCD4linux.LCDRotate2.value) != "0": s.im[im] = s.im[im].rotate(-int(LCD4linux.LCDRotate2.value), expand=True) s.im[im].save(bild, "PNG" if LCD4linux.BilderTyp.value == "png" else "JPEG") if isfile(bild): - rename(bild, "%s.png" % PIC2) + rename(bild, f"{PIC2}.png") except Exception as err: - L4log("Error write Picture2: %s" % str(err)) + L4log(f"Error write Picture2: {str(err)}") elif LCD4linux.LCDType2.value[0] == "5": L4log("writing Internal-LCD2") try: - if "2" in LCD4linux.SavePicture.value and SAVE == True: + if "2" in LCD4linux.SavePicture.value and SAVE is True: if str(LCD4linux.LCDRotate2.value) != "0": s.im[im] = s.im[im].rotate(-int(LCD4linux.LCDRotate2.value), expand=True) s.im[im].save(bild, "PNG" if LCD4linux.BilderTyp.value == "png" else "JPEG") if isfile(bild): - rename(bild, "%s.png" % PIC2) + rename(bild, f"{PIC2}.png") if int(LCD4linux.xmlOffset.value) != 0: MAX_W, MAX_H = s.im[im].size MAX_W += (int(LCD4linux.xmlOffset.value) * 2) @@ -3429,17 +3596,17 @@ def writeLCD2(s, im, quality, SAVE=True): if isfile(xmlPICtmp): rename(xmlPICtmp, xmlPIC) except Exception as err: - L4log("Error write Picture2: %s" % str(err)) + L4log(f"Error write Picture2: {str(err)}") elif LCD4linux.LCDType2.value[0] == "9": L4log("writing to Vu+ LCD2") try: s.im[im].save(bild, "PNG") if isfile(bild): - rename(bild, "%s.png" % PIC2) + rename(bild, f"{PIC2}.png") except Exception as err: - L4log("Error write Picture2: %s" % str(err)) + L4log(f"Error write Picture2: {str(err)}") if pngutil and pngutilconnect != 0: - pngutil.send("%s.png" % PIC2) + pngutil.send(f"{PIC2}.png") else: L4log("Error no Vu+ connect") else: @@ -3454,19 +3621,19 @@ def writeLCD2(s, im, quality, SAVE=True): except Exception: SamsungDevice2 = None L4log("Samsung 2 write Error") - if "2" in LCD4linux.SavePicture.value and SAVE == True: + if "2" in LCD4linux.SavePicture.value and SAVE is True: try: - datei = "%s.jpg" % PIC2tmp + datei = f"{PIC2tmp}.jpg" if str(LCD4linux.LCDRotate2.value) != "0": s.im[im] = s.im[im].rotate(-int(LCD4linux.LCDRotate2.value), expand=True) s.im[im].save(datei, "JPEG") elif pic is not None: open(datei, "wb").write(pic) if isfile(datei): - rename(datei, "%s.jpg" % PIC2) + rename(datei, f"{PIC2}.jpg") except Exception as err: - L4log("Error write Picture2: %s" % str(err)) - if LCD4linux.MJPEGenable2.value == True: + L4log(f"Error write Picture2: {str(err)}") + if LCD4linux.MJPEGenable2.value is True: if MJPEG[0][1] == "b": MJPEG_stop(2) sleep(0.5) @@ -3480,57 +3647,57 @@ def writeLCD3(s, im, quality, SAVE=True): global SamsungDevice3 global MJPEGreader pic = None - if s.imWrite[im] == True: + if s.imWrite[im] is True: L4log("Ignore ImWrite", im) return s.imWrite[im] = True - if LCD4linux.LCDType3.value[0] in ["2", "3"] and virtBRI(3) not in [0, 10] and SAVE == True and LCD4linux.MJPEGvirtbri3.value == True: + if LCD4linux.LCDType3.value[0] in ["2", "3"] and virtBRI(3) not in [0, 10] and SAVE is True and LCD4linux.MJPEGvirtbri3.value is True: s.tmp[im] = ImageEnhance.Brightness(s.im[im]).enhance(virtBRI(3)) s.im[im] = s.tmp[im] - bild = "%s.png" % PIC3tmp + bild = f"{PIC3tmp}.png" if LCD4linux.LCDType3.value[0] == "1": if SamsungDevice3 is not None: L4log("writing to DPF3 Device") doDPF(3, im, s) - if "3" in LCD4linux.SavePicture.value and SAVE == True: + if "3" in LCD4linux.SavePicture.value and SAVE is True: if str(LCD4linux.LCDRotate3.value) != "0": s.im[im] = s.im[im].rotate(-int(LCD4linux.LCDRotate3.value), expand=True) try: s.im[im].save(bild, "PNG" if LCD4linux.BilderTyp.value == "png" else "JPEG") if isfile(bild): - rename(bild, "%s.png" % PIC3) + rename(bild, f"{PIC3}.png") except Exception as err: - L4log("Error write Picture3: %s" % str(err)) + L4log(f"Error write Picture3: {str(err)}") elif LCD4linux.LCDType3.value[0] == "3": L4log("writing Picture3") try: - datei = "%s.%s" % (PIC3tmp, LCD4linux.BilderTyp.value) + datei = f"{PIC3tmp}.{LCD4linux.BilderTyp.value}" s.im[im].save(datei, "PNG" if LCD4linux.BilderTyp.value == "png" else "JPEG") if isfile(datei): - rename(datei, "%s.%s" % (PIC3, LCD4linux.BilderTyp.value)) + rename(datei, f"{PIC3}.{LCD4linux.BilderTyp.value}") except Exception as err: - L4log("Error write Picture3: %s" % str(err)) + L4log(f"Error write Picture3: {str(err)}") elif LCD4linux.LCDType3.value[0] == "4": L4log("writing TFT-LCD3") try: s.im[im].save("/tmp/usbtft-bmp", "BMP") - if "3" in LCD4linux.SavePicture.value and SAVE == True: + if "3" in LCD4linux.SavePicture.value and SAVE is True: if str(LCD4linux.LCDRotate3.value) != "0": s.im[im] = s.im[im].rotate(-int(LCD4linux.LCDRotate3.value), expand=True) s.im[im].save(bild, "PNG" if LCD4linux.BilderTyp.value == "png" else "JPEG") if isfile(bild): - rename(bild, "%s.png" % PIC3) + rename(bild, f"{PIC3}.png") except Exception as err: - L4log("Error write Picture3: %s" % str(err)) + L4log(f"Error write Picture3: {str(err)}") elif LCD4linux.LCDType3.value[0] == "5": L4log("writing Internal-LCD3") try: - if "3" in LCD4linux.SavePicture.value and SAVE == True: + if "3" in LCD4linux.SavePicture.value and SAVE is True: if str(LCD4linux.LCDRotate3.value) != "0": s.im[im] = s.im[im].rotate(-int(LCD4linux.LCDRotate3.value), expand=True) s.im[im].save(bild, "PNG" if LCD4linux.BilderTyp.value == "png" else "JPEG") if isfile(bild): - rename(bild, "%s.png" % PIC3) + rename(bild, f"{PIC3}.png") if int(LCD4linux.xmlOffset.value) != 0: MAX_W, MAX_H = s.im[im].size MAX_W += (int(LCD4linux.xmlOffset.value) * 2) @@ -3549,17 +3716,17 @@ def writeLCD3(s, im, quality, SAVE=True): if isfile(xmlPICtmp): rename(xmlPICtmp, xmlPIC) except Exception as err: - L4log("Error write Picture3: %s" % str(err)) + L4log(f"Error write Picture3: {str(err)}") elif LCD4linux.LCDType3.value[0] == "9": L4log("writing to Vu+ LCD3") try: s.im[im].save(bild, "PNG") if isfile(bild): - rename(bild, "%s.png" % PIC3) + rename(bild, f"{PIC3}.png") except Exception as err: - L4log("Error write Picture3: %s" % str(err)) + L4log(f"Error write Picture3: {str(err)}") if pngutil and pngutilconnect != 0: - pngutil.send("%s.png" % PIC3) + pngutil.send(f"{PIC3}.png") else: L4log("Error no Vu+ connect") else: @@ -3574,19 +3741,19 @@ def writeLCD3(s, im, quality, SAVE=True): except Exception: SamsungDevice3 = None L4log("Samsung 3 write Error") - if "3" in LCD4linux.SavePicture.value and SAVE == True: + if "3" in LCD4linux.SavePicture.value and SAVE is True: try: - datei = "%s.jpg" % PIC3tmp + datei = f"{PIC3tmp}.jpg" if str(LCD4linux.LCDRotate3.value) != "0": s.im[im] = s.im[im].rotate(-int(LCD4linux.LCDRotate3.value), expand=True) s.im[im].save(datei, "JPEG") elif pic is not None: open(datei, "wb").write(pic) if isfile(datei): - rename(datei, "%s.jpg" % PIC3) + rename(datei, f"{PIC3}.jpg") except Exception as err: - L4log("Error write Picture3: %s" % str(err)) - if LCD4linux.MJPEGenable3.value == True: + L4log(f"Error write Picture3: {str(err)}") + if LCD4linux.MJPEGenable3.value is True: if MJPEG[0][1] == "c": MJPEG_stop(3) sleep(0.5) @@ -3603,7 +3770,7 @@ def isMediaDisplay(player): def NextScreen(PRESS): global ScreenActive global ScreenTime - if SaveEventListChanged == True: + if SaveEventListChanged is True: L4logE("Event Change Aktive") return if (Standby.inStandby or ConfigStandby) and not isMediaDisplay(isMediaPlayer): @@ -3648,7 +3815,7 @@ def NextScreen(PRESS): ST = LCD4linux.ScreenTime9.value else: ST = "1" - if ScreenTime >= int(ST) and int(ST) > 0 or PRESS == True: + if ScreenTime >= int(ST) and int(ST) > 0 or PRESS is True: ScreenTime = 0 ScreenActive[0] = str(int(ScreenActive[0]) + 1) if (Standby.inStandby or ConfigStandby) and not isMediaDisplay(isMediaPlayer): @@ -3672,7 +3839,7 @@ def rglob(base, pattern): liste = [] liste.extend(glob(join(base, pattern))) dirs = _getDirs(base) - L4logE("Picturedirectorys %s" % dirs) + L4logE(f"Picturedirectorys {dirs}") if len(dirs): for d in dirs: liste.extend(rglob(join(base, d), pattern)) @@ -3705,13 +3872,13 @@ def getBilder(): if str(LCD4linux.MPBild2.value) != "0": BilderOrt[1] = LCD4linux.MPBild2File.value BilderOrt[2] = "" - L4logE("BilderOrt %s" % BilderOrt) + L4logE(f"BilderOrt {BilderOrt}") if isdir(BilderOrt[0]): L4log("read Pictures0") BilderIndex[0] = 0 - if LCD4linux.BilderRecursiv.value == False: + if LCD4linux.BilderRecursiv.value is False: for EXT in SuchExt: - Bilder[0] += glob(normpath(BilderOrt[0]) + "/" + EXT) + Bilder[0] += glob(f"{normpath(BilderOrt[0])}/{EXT}") else: for EXT in SuchExt: Bilder[0] += rglob(normpath(BilderOrt[0]), EXT) @@ -3719,13 +3886,13 @@ def getBilder(): shuffle(Bilder[0]) elif str(LCD4linux.BilderSort.value) == "1": Bilder[0].sort() - L4logE("Pictures %s" % Bilder[0]) + L4logE(f"Pictures {Bilder[0]}") if isdir(BilderOrt[1]): L4log("read Pictures1") BilderIndex[1] = 0 - if LCD4linux.BilderRecursiv.value == False: + if LCD4linux.BilderRecursiv.value is False: for EXT in SuchExt: - Bilder[1] += glob(normpath(BilderOrt[1]) + "/" + EXT) + Bilder[1] += glob(f"{normpath(BilderOrt[1])}/{EXT}") else: for EXT in SuchExt: Bilder[1] += rglob(normpath(BilderOrt[1]), EXT) @@ -3733,13 +3900,13 @@ def getBilder(): shuffle(Bilder[1]) elif str(LCD4linux.BilderSort.value) == "1": Bilder[1].sort() - L4logE("Pictures %s" % Bilder[1]) + L4logE(f"Pictures {Bilder[1]}") if isdir(BilderOrt[2]): L4log("read Pictures2") BilderIndex[2] = 0 - if LCD4linux.BilderRecursiv.value == False: + if LCD4linux.BilderRecursiv.value is False: for EXT in SuchExt: - Bilder[2] += glob(normpath(BilderOrt[2]) + "/" + EXT) + Bilder[2] += glob(f"{normpath(BilderOrt[2])}/{EXT}") else: for EXT in SuchExt: Bilder[2] += rglob(normpath(BilderOrt[2]), EXT) @@ -3747,14 +3914,14 @@ def getBilder(): shuffle(Bilder[2]) elif str(LCD4linux.BilderSort.value) == "1": Bilder[2].sort() - L4logE("Pictures %s" % Bilder[2]) + L4logE(f"Pictures {Bilder[2]}") def request_headers(boundary): return { 'Cache-Control': 'no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0', 'Connection': 'close', - 'Content-Type': 'multipart/x-mixed-replace; boundary=%s' % boundary, + 'Content-Type': f'multipart/x-mixed-replace; boundary={boundary}', 'Expires': 'Mon, 3 Jan 2000 12:34:56 GMT', 'Pragma': 'no-cache', } @@ -3954,19 +4121,19 @@ def MJPEG_serve3(port): def MJPEG_start(): global MJPEGreader - if LCD4linux.MJPEGenable1.value == True and MJPEG[0][1] == "1": + if LCD4linux.MJPEGenable1.value is True and MJPEG[0][1] == "1": MJPEG[0] = MJPEG[0].replace("1", "A") MJPEGreader[1] = 0 th1 = Thread(target=MJPEG_serve1, args=[int(LCD4linux.MJPEGport1.value)]) th1.setDaemon(True) th1.start() - if LCD4linux.MJPEGenable2.value == True and MJPEG[0][2] == "2": + if LCD4linux.MJPEGenable2.value is True and MJPEG[0][2] == "2": MJPEG[0] = MJPEG[0].replace("2", "B") MJPEGreader[2] = 0 th2 = Thread(target=MJPEG_serve2, args=[int(LCD4linux.MJPEGport2.value)]) th2.setDaemon(True) th2.start() - if LCD4linux.MJPEGenable3.value == True and MJPEG[0][3] == "3": + if LCD4linux.MJPEGenable3.value is True and MJPEG[0][3] == "3": MJPEG[0] = MJPEG[0].replace("3", "C") MJPEGreader[3] = 0 th3 = Thread(target=MJPEG_serve3, args=[int(LCD4linux.MJPEGport3.value)]) @@ -3974,6 +4141,11 @@ def MJPEG_start(): th3.start() +def MJPEG_restart(): # MJPEG_stop() waits 5 seconds, so it must not run in the main thread. + MJPEG_stop("") + MJPEG_start() + + def MJPEG_stop(force): global MJPEGrun stop = False @@ -3983,7 +4155,7 @@ def MJPEG_stop(force): try: if MJPEGserver[1] is not None: MJPEGrun[1] = 0 - if LCD4linux.LCDshutdown.value == True and force == 9: + if LCD4linux.LCDshutdown.value is True and force == 9: MAX_W, MAX_H = getResolution(LCD4linux.LCDType1.value, LCD4linux.LCDRotate1.value) MAX_W = int(MAX_W) MAX_H = int(MAX_H) @@ -4001,7 +4173,7 @@ def MJPEG_stop(force): try: if MJPEGserver[2] is not None: MJPEGrun[2] = 0 - if LCD4linux.LCDshutdown.value == True and force == 9: + if LCD4linux.LCDshutdown.value is True and force == 9: MAX_W, MAX_H = getResolution(LCD4linux.LCDType2.value, LCD4linux.LCDRotate2.value) MAX_W = int(MAX_W) MAX_H = int(MAX_H) @@ -4019,7 +4191,7 @@ def MJPEG_stop(force): try: if MJPEGserver[3] is not None: MJPEGrun[3] = 0 - if LCD4linux.LCDshutdown.value == True and force == 9: + if LCD4linux.LCDshutdown.value is True and force == 9: MAX_W, MAX_H = getResolution(LCD4linux.LCDType3.value, LCD4linux.LCDRotate3.value) MAX_W = int(MAX_W) MAX_H = int(MAX_H) @@ -4064,7 +4236,10 @@ def HTMLwwwConvertapiDownloadFinished(filename, result): def getHTMLwwwConvertapi(fn, www, pw, ph): filename = WWWpic % str(fn) - url = "http://do.convertapi.com/web2image?curl=%s&PageWidth=%d&PageHight=%d&outputformat=jpg&ApiKex=%s" % (www, pw, ph, LCD4linux.WwwApiKeyConvertapi.value) + url = ( + f"https://do.convertapi.com/web2image?curl={www}&PageWidth={pw}&PageHight={ph}" + f"&outputformat=jpg&ApiKex={LCD4linux.WwwApiKeyConvertapi.value}" + ) L4log("downloading HTMLwww from", url) callInThread(downloadPage, url, filename, boundFunction(HTMLwwwConvertapiDownloadFinished, filename), HTMLwwwConvertapiDownloadFailed) @@ -4087,9 +4262,9 @@ def getHTMLwww(fn, url): callInThread(downloadPage, url, filename, boundFunction(HTMLwwwDownloadFinished, filename), HTMLwwwDownloadFailed) -def Urlget(url, params, method, API): +def url_get(url, params, method, API): headers = {} - headers["Authorization"] = "Bearer " + API + headers["Authorization"] = f"Bearer {API}" if method == 'POST': headers["Content-type"] = "application/json" f = post(url, headers=headers, params=params) @@ -4108,54 +4283,54 @@ def getHTMLwwwCloudconvert(fn, www): try: for API in LCD4linux.WwwApiKeyCloudconvert.value.split(): dataget = {'url': www, 'output_format': 'jpg'} - content, resp = Urlget('https://api.cloudconvert.com/v2/capture-website', dataget, 'POST', API) - L4logE(content, "%s" % resp) + content, resp = url_get('https://api.cloudconvert.com/v2/capture-website', dataget, 'POST', API) + L4logE(content, f"{resp}") if resp == 201: break if resp == 201: r = loads(content) - content2, resp2 = Urlget(r['data']['links']['self'], {}, "GET", API) - L4logE(content2, "%s" % resp2) + content2, resp2 = url_get(r['data']['links']['self'], {}, "GET", API) + L4logE(content2, f"{resp2}") if resp2 == 200: - content3, resp3 = Urlget(r['data']['links']['self'], {}, "GET", API) - L4logE(content3, "%s" % resp3) + content3, resp3 = url_get(r['data']['links']['self'], {}, "GET", API) + L4logE(content3, f"{resp3}") r3 = loads(content3) i = 0 while r3['data']['status'] != 'finished' and i < 30: sleep(0.5) i += 1 - content3, resp3 = Urlget(r3['data']['links']['self'], {}, 'GET', API) - L4logE(content3, "%s" % resp3) + content3, resp3 = url_get(r3['data']['links']['self'], {}, 'GET', API) + L4logE(content3, f"{resp3}") r3 = loads(content3) if resp3 == 200 and i < 30: dataget = {"input": r3['data']['id']} - content4, resp4 = Urlget('https://api.cloudconvert.com/v2/export/url', dataget, 'POST', API) - L4logE(content4, "%s" % resp4) + content4, resp4 = url_get('https://api.cloudconvert.com/v2/export/url', dataget, 'POST', API) + L4logE(content4, f"{resp4}") r4 = loads(content4) i = 0 while r4['data']['status'] != 'finished' and i < 30: sleep(0.5) i += 1 - content4, resp4 = Urlget(r4['data']['links']['self'], {}, "GET", API) - L4logE("%s %s" % (content4, resp4)) + content4, resp4 = url_get(r4['data']['links']['self'], {}, "GET", API) + L4logE(f"{content4} {resp4}") r4 = loads(content4) if resp4 == 200 and i < 30: getHTMLwww(fn, r4['data']['result']['files'][0]['url']) else: - L4log("WWW Error4: %s %s" % (content4, resp4)) + L4log(f"WWW Error4: {content4} {resp4}") else: - L4log("WWW Error3: %s %s" % (content3, resp3)) + L4log(f"WWW Error3: {content3} {resp3}") else: - L4log("WWW Error2: %s %s" % (content2, resp2)) + L4log(f"WWW Error2: {content2} {resp2}") else: - L4log("WWW Error1: %s %s" % (content, resp)) + L4log(f"WWW Error1: {content} {resp}") except Exception: L4log("WWW Crash-Error") def xmlFind(Num): for i in xmlList: - if i.startswith("