From e036edce6af01b5c1322943104b33d70fb845b13 Mon Sep 17 00:00:00 2001 From: WorldTeacher Date: Tue, 18 Mar 2025 13:52:29 +0100 Subject: [PATCH] add logging capabilities, display code, overtime getter --- pyproject.toml | 1 + src/display.py | 27 +++++++++++++++++++++ src/management.py | 60 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 src/display.py create mode 100644 src/management.py diff --git a/pyproject.toml b/pyproject.toml index b3f76a4..52e6772 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,5 +6,6 @@ readme = "README.md" requires-python = ">=3.13" dependencies = [ "cryptography>=44.0.2", + "loguru>=0.7.3", "playwright>=1.50.0", ] diff --git a/src/display.py b/src/display.py new file mode 100644 index 0000000..72b6b4c --- /dev/null +++ b/src/display.py @@ -0,0 +1,27 @@ +from mfrc522 import SimpleMFRC522 +from RPLCD.i2c import CharLCD +from RPi import GPIO + + +class Display: + def __init__(self, i2c_address=0x27, cols=16, rows=2): + self.lcd = CharLCD( + i2c_expander="PCF8574", + address=i2c_address, + port=1, + cols=cols, + rows=rows, + backlight_enabled=True, + ) + GPIO.setmode(GPIO.BCM) + + def display_message(self, message1, message2=None): + """Display a message on the LCD.""" + self.lcd.clear() + self.lcd.write_string(message1) + if message2: + self.lcd.crlf() # Move to the second line + self.lcd.write_string(message2) + + def cleanup(self): + GPIO.cleanup() diff --git a/src/management.py b/src/management.py new file mode 100644 index 0000000..3b496dd --- /dev/null +++ b/src/management.py @@ -0,0 +1,60 @@ +import re +from playwright.sync_api import Playwright, sync_playwright, expect +import time + +import loguru +import sys + +log = loguru.logger +log.remove() +log.add("management.log", rotation="1 week", retention="1 month") +log.add(sys.stdout) + + +def run(playwright: Playwright) -> None: + browser = playwright.chromium.launch(headless=False) + context = browser.new_context() + page = context.new_page() + page.goto("https://lsf.ph-freiburg.de/qisfsvfr/rds?state=user&type=0") + page.get_by_label("Benutzerkennung").click() + page.get_by_label("Benutzerkennung").fill(USER) + page.get_by_label("Passwort").click() + page.get_by_label("Passwort").fill(PASSWORD) + page.get_by_role("button", name="Anmelden").click() + page.get_by_role("link", name="Zeiterfassung").click() + page.locator("#makronavigation").get_by_role("link", name="Zeiterfassung").click() + time.sleep(1) + get_overtime(page) + + context.close() + browser.close() + + +def get_overtime(page): + table = ( + page.get_by_role("cell", name="Überstunden:", exact=False) + .get_by_role("table") + .first + ) + rows = table.locator("tr").all() + + # Extract data from each row + for row in rows: + cells = row.locator("td").all_text_contents() + celltext = " ".join(cells) + if "Aktuell" in celltext and "Stunden" in celltext: + continue + elif "Aktuell" in celltext: + # get the time, can be negative or positive with : for hh:mm + # regex to find the time in the string + match = re.search(r"[-+]?\d{1,3}:\d{2}", celltext) + if match: + # Extract the time string + time_str = match.group() + return time_str + else: + return 0 + + +with sync_playwright() as playwright: + run(playwright)