diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c78b8b7..6c98f26 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,25 +18,25 @@ on: jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-26.04 steps: - uses: actions/checkout@v3 with: fetch-depth: 0 - - name: Install python 3.11 + - name: Install python 3.14 uses: actions/setup-python@v4 with: - python-version: '3.11' + python-version: '3.14' - name: Install python packages run: | pip install flake8 - name: Install dev packages run: | - sudo apt install gettext python3.11-dev + sudo apt install gettext python3.14-dev libtirpc-dev - name: Build plugins env: - CC: "gcc-10" - CXX: "g++-10" + CC: "gcc-15" + CXX: "g++-15" run: | autoreconf -i ./configure CFLAGS=-I/usr/include/tirpc diff --git a/lcd4linux/src/Photoframe.py b/lcd4linux/src/Photoframe.py index e8f2137..53a78f8 100644 --- a/lcd4linux/src/Photoframe.py +++ b/lcd4linux/src/Photoframe.py @@ -5,7 +5,7 @@ from usb.util import get_string from PIL import Image from struct import pack -from six.moves import cStringIO as StringIO +from io import StringIO def write_jpg2frame(dev, pic): @@ -162,12 +162,12 @@ def frame_init(dev): def frame_switch(dev): # Switch device from Mass Storage to Mini Monitor - CTRL_TYPE_VENDOR = (2 << 5) - CTRL_IN = 0x80 - CTRL_RECIPIENT_DEVICE = 0 +# CTRL_TYPE_VENDOR = (2 << 5) +# CTRL_IN = 0x80 +# CTRL_RECIPIENT_DEVICE = 0 try: sleep(0.5) - s = "\x00" * 251 + # s = "\x00" * 251 dev.ctrl_transfer(0x00 | 0x80, 0x06, 0xfe, 0xfe, 0xfe) # dev.ctrl_transfer(0x00 | 0x80, 0x06, 0xfe, 0xfe, s, 0xfe ) # dev.ctrl_transfer(CTRL_TYPE_VENDOR | CTRL_IN | CTRL_RECIPIENT_DEVICE, 0x04, 0x00, 0x00, 1) diff --git a/lcd4linux/src/WebConfigSite.py b/lcd4linux/src/WebConfigSite.py index a5dbc97..83cbe26 100644 --- a/lcd4linux/src/WebConfigSite.py +++ b/lcd4linux/src/WebConfigSite.py @@ -1,16 +1,10 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import from glob import glob from os import stat from os.path import isfile, join, basename -from six import PY2, ensure_str, ensure_binary from time import time from twisted.web import resource, http -if PY2: - from HTMLParser import HTMLParser - _unescape = HTMLParser().unescape -else: - from html import unescape as _unescape +from html import unescape as _unescape from enigma import eTimer from Components.config import ConfigSelection, ConfigYesNo, ConfigText, ConfigSlider, ConfigClock, ConfigPassword @@ -35,16 +29,26 @@ 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): - if PY2: - exec(command) - else: - variable = command.split(" ", 1)[0] - exec("global %s;%s" % (variable, command)) + variable = command.split(" ", 1)[0] + exec("global %s;%s" % (variable, command)) def _l(st): - st = ensure_str(st, "utf-8", "ignore") + if isinstance(st, bytes): + st = st.decode("utf-8", "ignore") st = st.replace(" [ok]>", "").encode('ascii', 'xmlcharrefreplace') return ensure_str(st) @@ -181,7 +185,7 @@ def action(self, req): req.setHeader('Content-Disposition', 'attachment;filename=lcd4config') req.setHeader('Content-Length', str(stat(lcd4config).st_size)) req.setHeader('charset', 'UTF-8') - with open(lcd4config, "r") as f: + with open(lcd4config) as f: html = f.read() return ensure_binary(html) if req.args.get(b"upload.y", None) is not None: @@ -210,7 +214,7 @@ def action(self, req): 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, "r") as f: + with open(lcd4config) as f: html = f.read() return ensure_binary(html) if command is None: @@ -226,7 +230,7 @@ def action(self, req): V = _l(req.args.get(b"PopText", "")[0]) try: V = _unescape(V) - except Exception as e: + except Exception: L4log("WebIF Error: Parse Text") setPopText(V) L4LElement.setRefresh() @@ -334,31 +338,31 @@ def action(self, req): if _a.find(".") > 0: val = req.args.get(a, "")[0] val = ensure_str(val) -#ConfigSelection +# ConfigSelection ConfObj = eval(_a) if isinstance(ConfObj, ConfigSelection): ConfObj.value = val else: -#ConfigYesNo +# ConfigYesNo if isinstance(ConfObj, ConfigYesNo): val = req.args.get(a, "") ConfObj.value = True if len(val) == 2 else False else: -#ConfigText +# ConfigText if isinstance(ConfObj, ConfigText): V = _l(val) try: V = _unescape(V) - except Exception as e: + except Exception: L4log("WebIF Error: Parse Text") ConfObj.value = V else: -#ConfigSlider +# ConfigSlider if isinstance(ConfObj, ConfigSlider): if val.isdigit(): ConfObj.value = val else: -#ConfigClock +# ConfigClock if isinstance(ConfObj, ConfigClock): t = val.split(":") if len(t) == 2 and t[0].isdigit() and t[1].isdigit(): @@ -411,7 +415,7 @@ def action(self, req): if Cfritz: rmFile(PICfritz) if Cwetter: -# resetWetter(None) # action after changing weather parameters +# resetWetter(None) # action after changing weather parameters pass if Cpicon: if len(LCD4linux.PiconCache.value) > 2: @@ -438,7 +442,7 @@ def action(self, req): html += "\n" html += "