add logging capabilities, display code, overtime getter
This commit is contained in:
@@ -6,5 +6,6 @@ readme = "README.md"
|
|||||||
requires-python = ">=3.13"
|
requires-python = ">=3.13"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cryptography>=44.0.2",
|
"cryptography>=44.0.2",
|
||||||
|
"loguru>=0.7.3",
|
||||||
"playwright>=1.50.0",
|
"playwright>=1.50.0",
|
||||||
]
|
]
|
||||||
|
|||||||
27
src/display.py
Normal file
27
src/display.py
Normal file
@@ -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()
|
||||||
60
src/management.py
Normal file
60
src/management.py
Normal file
@@ -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)
|
||||||
Reference in New Issue
Block a user