Add code python-syntax-checker and other github actions

This commit is contained in:
Ircama 2023-07-27 05:17:05 +02:00
parent bfd8e4a402
commit 604745de2d
4 changed files with 206 additions and 61 deletions

68
.github/workflows/codeql-analysis.yml vendored Normal file
View file

@ -0,0 +1,68 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ master ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ master ]
schedule:
- cron: '39 8 * * 0'
jobs:
analyze:
permissions: write-all
name: Analyze
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
language: [ 'python' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Checkout repository
uses: actions/checkout@v2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1

View file

@ -0,0 +1,40 @@
# from https://docs.github.com/en/actions/guides/building-and-testing-python
name: Python syntax checker
on: [push]
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
# version range and latest minor release (possibly 3.9.1)
python-version: ['3.7', '3.8', '3.9', '3.10', '3.x']
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install flake8
# next line is alternative to the previous one, for future use of pytest
# pip install flake8 pytest
# next line is for future use of requirements file
# if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F72,F82 --show-source --statistics
# next lines is for future use of more accurate statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
# flake8 . --count --exit-zero --max-complexity=40 --max-line-length=127 --statistics
# next lines is for future use of pytest
#- name: Test with pytest
# run: |
# pytest

26
.github/workflows/stale.yml vendored Normal file
View file

@ -0,0 +1,26 @@
name: Mark stale issues and automatically close them
on:
schedule:
- cron: '00 23 * * *'
jobs:
stale:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v4 # https://github.com/actions/stale
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'This issue becomed stale because of no feedback for 30 days. Remove the stale label or add a comment; otherwise, this will be automatically closed in 60 days.'
stale-pr-message: 'This PR becomed stale because of no feedback for 60 days.'
days-before-stale: 30
days-before-close: 60
close-issue-message: 'This issue was closed because it has been stalled for 60 days with no activity.'
days-before-pr-close: -1
any-of-labels: answered,needs-rebase,inactive,Awaiting-Response,question,invalid,duplicate,wontfix
exempt-all-pr-assignees: true

View file

@ -37,10 +37,10 @@ class EpsonPrinter:
"First TI received time": [173, 172] "First TI received time": [173, 172]
}, },
"ink_replacement_counters": { "ink_replacement_counters": {
"Black": { "1B": 242, "1S": 208, "1L": 209}, "Black": {"1B": 242, "1S": 208, "1L": 209},
"Yellow": { "1B": 248, "1S": 246, "1L": 247}, "Yellow": {"1B": 248, "1S": 246, "1L": 247},
"Magenta": { "1B": 251, "1S": 249, "1L": 250}, "Magenta": {"1B": 251, "1S": 249, "1L": 250},
"Cyan": { "1B": 245, "1S": 243, "1L": 244}, "Cyan": {"1B": 245, "1S": 243, "1L": 244},
}, },
"last_printer_fatal_errors": [60, 203, 204, 205, 206, 0x01d3], "last_printer_fatal_errors": [60, 203, 204, 205, 206, 0x01d3],
}, },
@ -62,12 +62,12 @@ class EpsonPrinter:
}, },
"last_printer_fatal_errors": [0x3B, 0xC0, 0xC1, 0xC2, 0xC3, 0x5C], "last_printer_fatal_errors": [0x3B, 0xC0, 0xC1, 0xC2, 0xC3, 0x5C],
"ink_replacement_counters": { "ink_replacement_counters": {
"Black": { "1S": 0x66, "2S": 0x67, "3S": 0x62}, "Black": {"1S": 0x66, "2S": 0x67, "3S": 0x62},
"Yellow": { "1S": 0x70, "2S": 0x71, "3S": 0xAB}, "Yellow": {"1S": 0x70, "2S": 0x71, "3S": 0xAB},
"Magenta": { "1S": 0x68, "2S": 0x69, "3S": 0x63}, "Magenta": {"1S": 0x68, "2S": 0x69, "3S": 0x63},
"Cyan": { "1S": 0x6C, "2S": 0x6D, "3S": 0x65}, "Cyan": {"1S": 0x6C, "2S": 0x6D, "3S": 0x65},
"Light magenta": { "1S": 0x6A, "2S": 0x6B, "3S": 0x64}, "Light magenta": {"1S": 0x6A, "2S": 0x6B, "3S": 0x64},
"Light cyan": { "1S": 0x6E, "2S": 0x6F, "3S": 0x9B}, "Light cyan": {"1S": 0x6E, "2S": 0x6F, "3S": 0x9B},
}, },
"serial_number": range(0xE7, 0xF0), "serial_number": range(0xE7, 0xF0),
# untested # untested
@ -135,7 +135,7 @@ class EpsonPrinter:
}, },
"XP-630": { "XP-630": {
"read_key": [40, 9], "read_key": [40, 9],
"write_key": b'Irisgarm', # (Iris graminea with typo?) "write_key": b'Irisgarm', # (Iris graminea with typo?)
# to be completed # to be completed
}, },
"XP-700": { "XP-700": {
@ -148,7 +148,7 @@ class EpsonPrinter:
}, },
"XP-830": { "XP-830": {
"read_key": [40, 9], "read_key": [40, 9],
"write_key": b'Irisgarm', # (Iris graminea with typo?) "write_key": b'Irisgarm', # (Iris graminea with typo?)
"addr_waste": ( # To be changed "addr_waste": ( # To be changed
0x10, 0x11, # '>H' "main pad counter" Max: 0x2102 (8450) 0x10, 0x11, # '>H' "main pad counter" Max: 0x2102 (8450)
@ -214,8 +214,8 @@ class EpsonPrinter:
self, self,
printer_model: printer_model:
str, hostname: str, str, hostname: str,
debug: bool=False, debug: bool = False,
dry_run: bool=False) -> None: dry_run: bool = False) -> None:
"""Initialise printer model.""" """Initialise printer model."""
for printer_name, printer_data in self.PRINTER_CONFIG.copy().items(): for printer_name, printer_data in self.PRINTER_CONFIG.copy().items():
if "alias" in printer_data: if "alias" in printer_data:
@ -243,9 +243,9 @@ class EpsonPrinter:
"""Return list of valid printers.""" """Return list of valid printers."""
return { return {
printer_name printer_name
for printer_name in self.PRINTER_CONFIG.keys() for printer_name in self.PRINTER_CONFIG.keys()
if "read_key" in self.PRINTER_CONFIG[printer_name] and if "read_key" in self.PRINTER_CONFIG[printer_name]
"write_key" in self.PRINTER_CONFIG[printer_name] and "write_key" in self.PRINTER_CONFIG[printer_name]
} }
@property @property
@ -276,10 +276,10 @@ class EpsonSession(easysnmp.Session):
def __init__( def __init__(
self, self,
printer: EpsonPrinter, printer: EpsonPrinter,
community: str="public", community: str = "public",
version: int=1, version: int = 1,
debug: bool=False, debug: bool = False,
dry_run: bool=False dry_run: bool = False
) -> None: ) -> None:
"""Initialise session.""" """Initialise session."""
self.printer = printer self.printer = printer
@ -292,8 +292,8 @@ class EpsonSession(easysnmp.Session):
def eeprom_oid_read_address( def eeprom_oid_read_address(
self, self,
oid: int, oid: int,
msb: int=0, msb: int = 0,
label: str="unknown method") -> str: label: str = "unknown method") -> str:
"""Return address for reading from EEPROM for specified OID.""" """Return address for reading from EEPROM for specified OID."""
if oid > 255: if oid > 255:
msb = oid // 256 msb = oid // 256
@ -312,8 +312,8 @@ class EpsonSession(easysnmp.Session):
self, self,
oid: int, oid: int,
value: Any, value: Any,
msb: int=0, msb: int = 0,
label: str="unknown method") -> str: label: str = "unknown method") -> str:
"""Return address for writing to EEPROM for specified OID.""" """Return address for writing to EEPROM for specified OID."""
if oid > 255: if oid > 255:
msb = oid // 256 msb = oid // 256
@ -347,7 +347,7 @@ class EpsonSession(easysnmp.Session):
def read_eeprom( def read_eeprom(
self, self,
oid: int, oid: int,
label: str="unknown method") -> str: label: str = "unknown method") -> str:
"""Read EEPROM data.""" """Read EEPROM data."""
response = self.read_value( response = self.read_value(
self.eeprom_oid_read_address(oid, label=label)) self.eeprom_oid_read_address(oid, label=label))
@ -372,7 +372,7 @@ class EpsonSession(easysnmp.Session):
def read_eeprom_many( def read_eeprom_many(
self, self,
oids: list, oids: list,
label: str="unknown method"): label: str = "unknown method"):
"""Read EEPROM data with multiple values.""" """Read EEPROM data with multiple values."""
return [self.read_eeprom(oid, label=label) for oid in oids] return [self.read_eeprom(oid, label=label) for oid in oids]
@ -380,7 +380,7 @@ class EpsonSession(easysnmp.Session):
self, self,
oid: int, oid: int,
value: int, value: int,
label: str="unknown method") -> None: label: str = "unknown method") -> None:
"""Write value to OID with specified type to EEPROM.""" """Write value to OID with specified type to EEPROM."""
oid_string = self.eeprom_oid_write_address(oid, value, label=label) oid_string = self.eeprom_oid_write_address(oid, value, label=label)
try: try:
@ -444,8 +444,10 @@ class EpsonSession(easysnmp.Session):
buf = buf[length:] buf = buf[length:]
if self.debug: if self.debug:
print("Processing status - ftype", hex(ftype), print(
"length:", length, "item:", item.hex(' ')) "Processing status - ftype", hex(ftype),
"length:", length, "item:", item.hex(' ')
)
if ftype == 0x0f: # ink if ftype == 0x0f: # ink
colourlen = item[0] colourlen = item[0]
@ -460,7 +462,7 @@ class EpsonSession(easysnmp.Session):
name = colour_ids[colour] name = colour_ids[colour]
else: else:
name = "0x%X" % colour name = "0x%X" % colour
inks.append((colour, level, name)) inks.append((colour, level, name))
data_set["ink_level"] = inks data_set["ink_level"] = inks
@ -523,7 +525,7 @@ class EpsonSession(easysnmp.Session):
if item == b'\x81': if item == b'\x81':
data_set["cancel_code"] = "Request" data_set["cancel_code"] = "Request"
elif ftype == 0x37: # Maintenance box information elif ftype == 0x37: # Maintenance box information
i = 1 i = 1
for j in range(item[0]): for j in range(item[0]):
if item[i] == 0: if item[i] == 0:
@ -550,11 +552,11 @@ class EpsonSession(easysnmp.Session):
data_set["unknown"].append((hex(ftype), item)) data_set["unknown"].append((hex(ftype), item))
return data_set return data_set
def get_snmp_info(self, mib_name: str=None) -> str: def get_snmp_info(self, mib_name: str = None) -> str:
"""Return general SNMP information of printer.""" """Return general SNMP information of printer."""
sys_info = {} sys_info = {}
if mib_name and mib_name in self.printer.snmp_info.keys(): if mib_name and mib_name in self.printer.snmp_info.keys():
snmp_info = { mib_name: self.printer.snmp_info[mib_name] } snmp_info = {mib_name: self.printer.snmp_info[mib_name]}
else: else:
snmp_info = self.printer.snmp_info snmp_info = self.printer.snmp_info
for name, oid in snmp_info.items(): for name, oid in snmp_info.items():
@ -581,12 +583,12 @@ class EpsonSession(easysnmp.Session):
self.printer.parm["serial_number"], label="serial_number") self.printer.parm["serial_number"], label="serial_number")
) )
def get_stats(self, stat_name: str=None) -> str: def get_stats(self, stat_name: str = None) -> str:
"""Return printer statistics.""" """Return printer statistics."""
if "stats" not in self.printer.parm: if "stats" not in self.printer.parm:
return None return None
if stat_name and stat_name in self.printer.parm["stats"].keys(): if stat_name and stat_name in self.printer.parm["stats"].keys():
stat_info = { stat_name: self.printer.parm["stats"][stat_name] } stat_info = {stat_name: self.printer.parm["stats"][stat_name]}
else: else:
stat_info = self.printer.parm["stats"] stat_info = self.printer.parm["stats"]
stats_result = {} stats_result = {}
@ -643,11 +645,15 @@ class EpsonSession(easysnmp.Session):
if "ink_replacement_counters" not in self.printer.parm: if "ink_replacement_counters" not in self.printer.parm:
return None return None
irc = { irc = {
(color, counter, int(self.read_eeprom( (
value, label="ink_replacement_counters"), 16)) color,
for color, data in self.printer.parm[ counter,
"ink_replacement_counters"].items() int(self.read_eeprom(value, label="ink_replacement_counters"),
for counter, value in data.items() 16),
)
for color, data in self.printer.parm[
"ink_replacement_counters"].items()
for counter, value in data.items()
} }
return irc return irc
@ -656,10 +662,14 @@ class EpsonSession(easysnmp.Session):
result = self.read_value(f"{self.printer.eeprom_link}.115.116.1.0.1") result = self.read_value(f"{self.printer.eeprom_link}.115.116.1.0.1")
if not result: if not result:
return None return None
if self.debug: if self.debug:
print(textwrap.fill("PRINTER_STATUS: " + print(
bytes([ord(i) for i in result]).hex(" "), textwrap.fill(
initial_indent='', subsequent_indent=' ') "PRINTER_STATUS: " + bytes(
[ord(i) for i in result]).hex(" "),
initial_indent="",
subsequent_indent=" ",
)
) )
return self.status_parser(bytes([ord(i) for i in result])) return self.status_parser(bytes([ord(i) for i in result]))
@ -668,13 +678,12 @@ class EpsonSession(easysnmp.Session):
if "main_waste" not in self.printer.parm: if "main_waste" not in self.printer.parm:
return None return None
results = [] results = []
level = self.read_eeprom_many( level = self.read_eeprom_many(
self.printer.parm["main_waste"]["oids"], label="main_waste") self.printer.parm["main_waste"]["oids"], label="main_waste")
level_b10 = int("".join(reversed(level)), 16) level_b10 = int("".join(reversed(level)), 16)
results.append( results.append(
round(level_b10 / self.printer.parm["main_waste"]["divider"], round(level_b10 / self.printer.parm["main_waste"]["divider"], 2)
2)
) )
if "borderless_waste" in self.printer.parm: if "borderless_waste" in self.printer.parm:
@ -718,13 +727,13 @@ class EpsonSession(easysnmp.Session):
def write_first_ti_received_time( def write_first_ti_received_time(
self, year: int, month: int, day: int) -> None: self, year: int, month: int, day: int) -> None:
"""Update first TI received time""" """Update first TI received time"""
b = self.printer.parm["stats"]["First TI received time"][0] msb = self.printer.parm["stats"]["First TI received time"][0]
l = self.printer.parm["stats"]["First TI received time"][1] lsb = self.printer.parm["stats"]["First TI received time"][1]
n = (year - 2000) * 16 * 32 + 32 * month + day n = (year - 2000) * 16 * 32 + 32 * month + day
if self.debug: if self.debug:
print("FTRT:", hex(n // 256), hex(n % 256), "=", n // 256, n % 256) print("FTRT:", hex(n // 256), hex(n % 256), "=", n // 256, n % 256)
self.write_eeprom(b, n // 256, label="First TI received time") self.write_eeprom(msb, n // 256, label="First TI received time")
self.write_eeprom(l, n % 256, label="First TI received time") self.write_eeprom(lsb, n % 256, label="First TI received time")
def brute_force_read_key( def brute_force_read_key(
self, minimum: int = 0x00, maximum: int = 0xFF self, minimum: int = 0x00, maximum: int = 0xFF
@ -748,7 +757,6 @@ if __name__ == "__main__":
import argparse import argparse
from pprint import pprint from pprint import pprint
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
epilog='Epson Printer Configuration accessed via SNMP (TCP/IP)') epilog='Epson Printer Configuration accessed via SNMP (TCP/IP)')
@ -758,7 +766,7 @@ if __name__ == "__main__":
dest='model', dest='model',
action="store", action="store",
help='Printer model. Example: -m XP-205' help='Printer model. Example: -m XP-205'
' (use ? to print all supported models)', ' (use ? to print all supported models)',
required=True) required=True)
parser.add_argument( parser.add_argument(
'-a', '-a',
@ -781,7 +789,7 @@ if __name__ == "__main__":
type=str, type=str,
nargs=1, nargs=1,
help='Print specific information.' help='Print specific information.'
' (Use ? to list all available queries)') ' (Use ? to list all available queries)')
parser.add_argument( parser.add_argument(
'--reset_waste_ink', '--reset_waste_ink',
dest='reset_waste_ink', dest='reset_waste_ink',
@ -872,28 +880,31 @@ if __name__ == "__main__":
if ret: if ret:
pprint(ret) pprint(ret)
else: else:
print("No information returned." print(
" Check printer definition.") "No information returned."
" Check printer definition."
)
else: else:
print("Option error: unavailable query.\n" + print(
"Option error: unavailable query.\n" +
textwrap.fill( textwrap.fill(
"Available queries: " + "Available queries: " +
", ".join(printer.list_methods), ", ".join(printer.list_methods),
initial_indent='', subsequent_indent=' ' initial_indent='', subsequent_indent=' '
) + "\n" + ) + "\n" +
( (
( (
textwrap.fill( textwrap.fill(
"Available statistics: " + "Available statistics: " +
", ".join(printer.parm["stats"].keys()), ", ".join(printer.parm["stats"].keys()),
initial_indent='', subsequent_indent=' ' initial_indent='', subsequent_indent=' '
) + "\n" ) + "\n"
) if "stats" in printer.parm else "" ) if "stats" in printer.parm else ""
) + ) +
textwrap.fill( textwrap.fill(
"Available SNMP elements: " + "Available SNMP elements: " +
", ".join(printer.snmp_info.keys()), ", ".join(printer.snmp_info.keys()),
initial_indent='', subsequent_indent=' ' initial_indent='', subsequent_indent=' '
) )
) )
if args.info or not print_opt: if args.info or not print_opt: