From 24b01273ad269a997ee5267f09b1149dc788f220 Mon Sep 17 00:00:00 2001 From: WorldTeacher Date: Tue, 8 Jul 2025 16:17:40 +0200 Subject: [PATCH] add yaml dependency, cli colors and translation file --- lang.txt | 1 + main.py | 54 +++++++++++++++++++++++++++++------------ pyproject.toml | 1 + src/adischeck.py | 13 +++++----- src/adischeck_online.py | 20 +++++++++++---- src/colors.py | 10 ++++++++ translation.yaml | 45 ++++++++++++++++++++++++++++++++++ uv.lock | 19 +++++++++++++++ 8 files changed, 136 insertions(+), 27 deletions(-) create mode 100644 lang.txt create mode 100644 src/colors.py create mode 100644 translation.yaml diff --git a/lang.txt b/lang.txt new file mode 100644 index 0000000..c42e816 --- /dev/null +++ b/lang.txt @@ -0,0 +1 @@ +de \ No newline at end of file diff --git a/main.py b/main.py index 43dc705..f378939 100644 --- a/main.py +++ b/main.py @@ -1,46 +1,70 @@ +import sys from src.adischeck import ( get_mednr_exempl, enter_print_mode, exit_print_mode, + is_adis_running, ) from src.adischeck_online import run, work_on_page import pyautogui from src.database import Database +from src.colors import bcolors import time +import yaml - +INACTIVITY_LIMIT = 5 * 60 # 5 minutes catalogue_pid = None print_pid = None database = Database() +lang = input("Enter language (de/en): ").strip().lower() +if lang not in ["de", "en"]: + print("Invalid language. Defaulting to English.") + lang = "en" +with open("lang.txt", "w", encoding="utf-8") as f: + f.write(lang) +sys_messages = yaml.safe_load(open(f"translation.yaml", "r", encoding="utf-8")) +print(bcolors.BOLD + bcolors.OKGREEN + sys_messages["start"][lang] + bcolors.ENDC) +adis_launch = time.time() page = run() +def start_instructions(): + print(bcolors.OKBLUE + sys_messages["adis_running"][lang] + bcolors.ENDC) + time.sleep(1) + print(bcolors.OKCYAN + sys_messages["log_in"][lang] + bcolors.ENDC) + time.sleep(1) + print(bcolors.OKCYAN + sys_messages["goto_exemplar"][lang] + bcolors.ENDC) + time.sleep(1) + print(bcolors.OKCYAN + sys_messages["ready_to_continue"][lang] + bcolors.ENDC) + time.sleep(1) + + def main(): - print("Starting the script...") + while not is_adis_running(): + print(sys_messages["waiting_for_adis"][lang], end="\r") + time.sleep(5) + start_instructions() + print(bcolors.WARNING + sys_messages["important"][lang] + bcolors.ENDC) + + print(sys_messages["explanation"][lang]) + input(sys_messages["start_run"][lang]) while True: mednr = get_mednr_exempl() print("Mednr:", mednr) pyautogui.hotkey("alt", "s") - work_on_page(page, mednr) + page_alive = work_on_page(page, mednr) + if page_alive is False: + print(bcolors.FAIL + sys_messages["page_dead"][lang] + bcolors.ENDC) + sys.exit(1) enter_print_mode() pyautogui.press("space") time.sleep(1) exit_print_mode() - # keyboard.wait('space') - # time.sleep(5) - # text = adis_get_signature() - # new = database.insert_ma(text) - # clipboard.copy(new) # Copy the new signature to clipboard - # print(text, new) - # pyautogui.hotkey('ctrl', 'v') # Select all text - # mednr = adis_save_and_enter_exemplar(new) # Example usage with a new signature - # print("finished main work, printing new signature") - # time.sleep(1) - # print_new_signature(catalogue_pid, print_pid, mednr) - # new_search() + print(bcolors.WARNING + sys_messages["timeout"][lang] + bcolors.ENDC) + sys.exit(0) if __name__ == "__main__": diff --git a/pyproject.toml b/pyproject.toml index 035ecdb..d7e3948 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,7 @@ dependencies = [ "pyperclip>=1.9.0", "pytesseract>=0.3.13", "pywin32>=310", + "pyyaml>=6.0.2", "winregistry>=2.1.1", ] diff --git a/src/adischeck.py b/src/adischeck.py index 6d6eff3..edc501c 100644 --- a/src/adischeck.py +++ b/src/adischeck.py @@ -6,6 +6,7 @@ import time import pyperclip as clipboard import getpixelcolor import pytesseract +import yaml # from src.cursor import classify_cursor, get_current_hcursor pytesseract.pytesseract.tesseract_cmd = r".\tesseract\tesseract.exe" @@ -232,18 +233,16 @@ def enter_print_mode(): def exit_print_mode(): - print("Exiting print mode...") + lang = open("lang.txt", "r", encoding="utf-8").read().strip() + sys_messages = yaml.safe_load(open(f"translation.yaml", "r", encoding="utf-8")) + print(sys_messages["exit_print_mode"][lang]) time.sleep(2) while getpixelcolor.pixel(1240, 971) != (192, 215, 242): - print("Not found") + print(sys_messages["print_exit_not_found"][lang]) time.sleep(1) - # while getpixelcolor.pixel(1240, 971) == (202, 202, 202): - # time.sleep(1) - # print("Process locked") - # time.sleep(1) pyautogui.click(1240, 971) # Click the print button - print("Exited print mode.") + print(sys_messages["exit_print_mode"][lang]) if __name__ == "__main__": diff --git a/src/adischeck_online.py b/src/adischeck_online.py index 35c94c9..9d112c3 100644 --- a/src/adischeck_online.py +++ b/src/adischeck_online.py @@ -4,7 +4,10 @@ from playwright.sync_api import Playwright, sync_playwright from playwright.sync_api import Page from src.database import Database +from src.colors import bcolors import pyperclip as clipboard +import yaml +import time def run(): browser = sync_playwright().start().chromium.launch(headless=False) @@ -19,10 +22,17 @@ def run(): page.get_by_role("textbox", name="Mediennummer").click() return page -def work_on_page(page: Page, mednr: str): +def work_on_page(page: Page, mednr: str) -> bool: + lang = open("lang.txt", "r", encoding="utf-8").read().strip() + sys_messages = yaml.safe_load(open(f"translation.yaml", "r", encoding="utf-8")) db = Database() page.get_by_role("textbox", name="Mediennummer").fill(mednr) page.get_by_text("Suche starten").nth(1).click() + time.sleep(1) + if page.get_by_role("main", name="Hauptbereich").is_visible(): + print(bcolors.FAIL + sys_messages["page_dead"][lang] + bcolors.ENDC) + return False + page.get_by_text("Ändern").nth(1).click() page.get_by_role("link", name="Sacherschließung").click() page.get_by_role("link", name="Notation, Genre, Signatur").click() @@ -30,12 +40,12 @@ def work_on_page(page: Page, mednr: str): page.locator("input[name=\"cellEditValue\\$7\"]").press("ControlOrMeta+a") page.locator("input[name=\"cellEditValue\\$7\"]").press("ControlOrMeta+c") signature = clipboard.paste() - print(signature) + print(bcolors.BOLD + bcolors.HEADER + f"{signature}" + bcolors.ENDC) new_signature = db.insert(signature) if new_signature is None: - print("Signature already exists in the database.") - return + print(bcolors.WARNING + sys_messages["signature_present"][lang] + bcolors.ENDC) + return True clipboard.copy(new_signature) page.locator("input[name=\"cellEditValue\\$7\"]").fill(new_signature) @@ -52,7 +62,7 @@ def work_on_page(page: Page, mednr: str): page.get_by_role("link", name="Ansigeln/Absigeln").click() page.get_by_role("button", name="Ok").click() - + return True diff --git a/src/colors.py b/src/colors.py new file mode 100644 index 0000000..6134513 --- /dev/null +++ b/src/colors.py @@ -0,0 +1,10 @@ +class bcolors: + HEADER = '\033[95m' + OKBLUE = '\033[94m' + OKCYAN = '\033[96m' + OKGREEN = '\033[92m' + WARNING = '\033[93m' + FAIL = '\033[91m' + ENDC = '\033[0m' + BOLD = '\033[1m' + UNDERLINE = '\033[4m' \ No newline at end of file diff --git a/translation.yaml b/translation.yaml new file mode 100644 index 0000000..7641600 --- /dev/null +++ b/translation.yaml @@ -0,0 +1,45 @@ +start: + en: Starting the script... + de: Programm gestartet... +waiting_for_adis: + en: Waiting for aDIS to start... + de: Warte auf aDIS... +adis_running: + en: aDIS is running, proceeding... + de: aDIS läuft, fortfahren... +log_in: + en: Please log in to the PHFR account... + de: Bitte melden Sie sich beim PHFR-Konto an... +goto_exemplar: + en: Navigating to the Exemplare page... + de: Navigiere zur Seite Exemplare... +ready_to_continue: + en: Ready to continue... + de: Bereit zum Fortfahren... +explanation: + en: The script is now ready. To use, please lay a book on the RFID reader and press Space. The script will then take over and returns the control once the book has been edited. Please keep the book on the RFID reader until the script finishes. + de: Das Skript ist jetzt bereit. Bitte legen Sie ein Buch auf den RFID-Leser und drücken Sie die Leertaste. Das Skript übernimmt dann und gibt die Kontrolle zurück, sobald das Buch bearbeitet wurde. Bitte lassen Sie das Buch auf dem RFID-Leser, bis das Skript fertig ist. + +signature_present: + en: Signature already exists in the database. + de: Signatur ist bereits in der Datenbank vorhanden. +exit_print_mode: + en: Exiting print mode... + de: Druckmodus verlassen... +print_exit_not_found: + en: Pixel not found, waiting... + de: Pixel nicht gefunden, warten... +important: + en: 'Important: If there is a break in between books of more than 5 minutes, please restart the script, as the webAdis session will expire.' + de: 'Wichtig: Wenn zwischen den Büchern eine Pause von mehr als 5 Minuten liegt, starten Sie das Skript bitte neu, da die WebAdis-Sitzung abläuft.' + +start_run: + en: Press Enter to start + de: Drücken Sie die Eingabetaste zum Starten + +timeout: + en: Timeout reached, stopping script... + de: Zeitüberschreitung erreicht, Skript wird gestoppt... +page_dead: + en: Page is dead, exiting... + de: Seite wurde nicht verwendet, Programm wird neu beendet... \ No newline at end of file diff --git a/uv.lock b/uv.lock index 2606ec1..41cbd0f 100644 --- a/uv.lock +++ b/uv.lock @@ -127,6 +127,7 @@ dependencies = [ { name = "pyperclip" }, { name = "pytesseract" }, { name = "pywin32" }, + { name = "pyyaml" }, { name = "winregistry" }, ] @@ -147,6 +148,7 @@ requires-dist = [ { name = "pyperclip", specifier = ">=1.9.0" }, { name = "pytesseract", specifier = ">=0.3.13" }, { name = "pywin32", specifier = ">=310" }, + { name = "pyyaml", specifier = ">=6.0.2" }, { name = "winregistry", specifier = ">=2.1.1" }, ] @@ -2968,6 +2970,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b4/f4/f785020090fb050e7fb6d34b780f2231f302609dc964672f72bfaeb59a28/pywin32-310-cp313-cp313-win_arm64.whl", hash = "sha256:e308f831de771482b7cf692a1f308f8fca701b2d8f9dde6cc440c7da17e47b33", size = 8458152 }, ] +[[package]] +name = "pyyaml" +version = "6.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, +] + [[package]] name = "rubicon-objc" version = "0.5.1"