initial commit
10
.gitignore
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# Python-generated files
|
||||
__pycache__/
|
||||
*.py[oc]
|
||||
build/
|
||||
dist/
|
||||
wheels/
|
||||
*.egg-info
|
||||
|
||||
# Virtual environments
|
||||
.venv
|
||||
1
.python-version
Normal file
@@ -0,0 +1 @@
|
||||
3.13
|
||||
9
README.md
Normal file
@@ -0,0 +1,9 @@
|
||||
Order of Operations:
|
||||
|
||||
- start program
|
||||
- check if adis is open (2 instances)
|
||||
- yes -> continue
|
||||
- no -> exit
|
||||
- await press of spacebar
|
||||
- take over control:
|
||||
-
|
||||
BIN
images/adis_empty_search.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
images/back.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
images/exemplar.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
images/exemplar_ident.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
6
images/hello.py
Normal file
@@ -0,0 +1,6 @@
|
||||
def main():
|
||||
print("Hello from magazinaenderung!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
BIN
images/info.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
images/loading.png
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
images/new_search.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
images/notation.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
images/print_ok.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
images/sacherschliessung.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
images/save.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
images/save_ok.png
Normal file
|
After Width: | Height: | Size: 773 B |
64
main.py
Normal file
@@ -0,0 +1,64 @@
|
||||
import keyboard
|
||||
from src.adischeck import is_adis_running, get_active_name, print_new_signature, adis_get_signature, adis_save_and_enter_exemplar, new_search, taskswitcher_name
|
||||
import pyautogui
|
||||
from src.database import Database
|
||||
import time
|
||||
import sys
|
||||
import clipboard
|
||||
|
||||
|
||||
catalogue_pid = None
|
||||
print_pid = None
|
||||
|
||||
database = Database()
|
||||
|
||||
def main():
|
||||
global catalogue_pid, print_pid
|
||||
if not is_adis_running():
|
||||
print("aDISCl is not running. Please start all required aDIS instances and try again.")
|
||||
return
|
||||
print("aDISCl is running. Proceeding to capture PIDs...")
|
||||
print("Press 'c' to capture the PID of the Catalogue aDIS instance.")
|
||||
keyboard.wait('c')
|
||||
#press backspace to clear any previous input
|
||||
catalogue_pid = get_active_name()
|
||||
print("Captured Catalogue PID:", catalogue_pid)
|
||||
pyautogui.hotkey("ctrl", "a") # Switch to the next aDIS instance
|
||||
pyautogui.hotkey("delete")
|
||||
# pyautogui.press("backspace")
|
||||
print("Press 'p' to capture the PID of the Print aDIS instance.")
|
||||
keyboard.wait('p')
|
||||
print_pid = get_active_name()
|
||||
print("Captured Print PID:", print_pid)
|
||||
pyautogui.hotkey("ctrl", "a") # Switch to the next aDIS instance
|
||||
pyautogui.hotkey("delete")
|
||||
|
||||
if catalogue_pid and print_pid:
|
||||
print("Both Catalogue and Print PIDs captured successfully.")
|
||||
print("Switching back to Catalogue aDIS instance...")
|
||||
taskswitcher_name(catalogue_pid) # Switch to Catalogue aDIS instance
|
||||
# pyautogui.hotkey("alt", "s") # Open the search dialog in Catalogue aDIS
|
||||
else:
|
||||
print("Failed to capture one or both PIDs. Please ensure you have the correct aDIS instances open.")
|
||||
print("Exiting the program.")
|
||||
sys.exit(1)
|
||||
while True:
|
||||
keyboard.wait('space')
|
||||
print("Space key pressed. Switching to Catalogue aDIS instance...")
|
||||
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()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
# time.sleep(5) # Wait for a few seconds before starting
|
||||
# print_new_signature("3 - PHFR: Katalog - aDIS/Client", "4 - PHFR(42): Exemplare - aDIS/Client", "004862920129")
|
||||
21
pyproject.toml
Normal file
@@ -0,0 +1,21 @@
|
||||
[project]
|
||||
name = "magazinaenderung"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.13"
|
||||
dependencies = [
|
||||
"clipboard>=0.0.4",
|
||||
"keyboard>=0.13.5",
|
||||
"opencv-python>=4.11.0.86",
|
||||
"psutil>=7.0.0",
|
||||
"pyautogui>=0.9.54",
|
||||
"pytesseract>=0.3.13",
|
||||
"pywin32>=310",
|
||||
"winregistry>=2.1.1",
|
||||
]
|
||||
|
||||
[dependency-groups]
|
||||
dev = [
|
||||
"nuitka>=2.7.10",
|
||||
]
|
||||
0
src/__init__.py
Normal file
209
src/adischeck.py
Normal file
@@ -0,0 +1,209 @@
|
||||
import keyboard
|
||||
import psutil
|
||||
import pygetwindow
|
||||
import pyautogui
|
||||
import time
|
||||
import clipboard
|
||||
from src.cursor import classify_cursor, get_current_hcursor
|
||||
|
||||
|
||||
def is_adis_running():
|
||||
|
||||
for proc in psutil.process_iter(['pid', 'name']):
|
||||
if proc.info['name'].startswith('aDISCl'):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
|
||||
|
||||
def get_active_name():
|
||||
#get the active window's name
|
||||
active_window = pygetwindow.getActiveWindow()
|
||||
if active_window is not None:
|
||||
return active_window.title
|
||||
return None
|
||||
|
||||
def taskswitcher():
|
||||
# Simulate Alt+Tab to switch tasks
|
||||
import pyautogui
|
||||
pyautogui.hotkey('alt', 'tab')
|
||||
|
||||
def taskswitcher_name(name):
|
||||
#switch to application with the given name
|
||||
import pygetwindow as gw
|
||||
try:
|
||||
window = gw.getWindowsWithTitle(name)[0]
|
||||
if window.isMinimized:
|
||||
window.restore() # Restore the window if it's minimized
|
||||
window.activate() # Bring the window to the foreground
|
||||
print(f"Switched to window: {name}")
|
||||
except IndexError:
|
||||
print(f"Window with title '{name}' not found. Please ensure the application is open.")
|
||||
|
||||
|
||||
def adis_get_signature():
|
||||
# get the current signature, create a new one and insert it into the needed places
|
||||
print("Getting current signature...")
|
||||
old_signature = None
|
||||
pyautogui.click(566,86)
|
||||
location_visible = False
|
||||
|
||||
time.sleep(5)
|
||||
while not location_visible:
|
||||
location = pyautogui.locateOnScreen('images/sacherschliessung.png', confidence=0.8, minSearchTime=1)
|
||||
if location is None:
|
||||
time.sleep(0.5)
|
||||
else:
|
||||
location_visible = True
|
||||
print("Found the Sacherschliessung button on the screen.")
|
||||
pyautogui.click(location)
|
||||
notation_visible = False
|
||||
while not notation_visible:
|
||||
notation = pyautogui.locateOnScreen('images/notation.png', confidence=0.8)
|
||||
if notation is None:
|
||||
time.sleep(0.5)
|
||||
else:
|
||||
notation_visible = True
|
||||
print("Found the Notation button on the screen.")
|
||||
pyautogui.click(notation)
|
||||
pyautogui.click(1216,665)
|
||||
#store text at mouse position
|
||||
pyautogui.hotkey('ctrl', 'a') # Select all text
|
||||
pyautogui.hotkey('ctrl', 'c')
|
||||
text = clipboard.paste()
|
||||
print("Text copied to clipboard:", text)
|
||||
return text
|
||||
|
||||
|
||||
def get_click_locations():
|
||||
while True:
|
||||
#if the user presses 'c', capture the current mouse position
|
||||
keyboard.wait('c')
|
||||
x, y = pyautogui.position()
|
||||
print(f"Captured mouse position: ({x}, {y})")
|
||||
# Store the position in a list or dictionary for later use
|
||||
with open('click_locations.txt', 'a') as f:
|
||||
f.write(f"{x}, {y}\n")
|
||||
print("Mouse position saved. Press 'c' again to capture another position or 'q' to quit.")
|
||||
if keyboard.is_pressed('q'):
|
||||
print("Exiting the position capture loop.")
|
||||
break
|
||||
|
||||
def save_part():
|
||||
save_location = None
|
||||
while save_location is None:
|
||||
save_location = pyautogui.locateOnScreen('images/save.png', confidence=0.8)
|
||||
if save_location is None:
|
||||
print("Save button not found, retrying...")
|
||||
time.sleep(1)
|
||||
else:
|
||||
print("Save button found, clicking...")
|
||||
pyautogui.click(save_location)
|
||||
time.sleep(1.5)
|
||||
|
||||
def commit_changes():
|
||||
pyautogui.keyDown("alt")
|
||||
pyautogui.press("b")
|
||||
time.sleep(0.6)
|
||||
pyautogui.press( "l") # Select all text
|
||||
pyautogui.keyUp("alt")
|
||||
time.sleep(1)
|
||||
while pyautogui.locateOnScreen('images/save_ok.png', confidence=0.6, minSearchTime=1) is None:
|
||||
time.sleep(1)
|
||||
save_ok = pyautogui.locateOnScreen('images/save_ok.png', confidence=0.6)
|
||||
pyautogui.click(save_ok)
|
||||
print("Changes committed successfully.")
|
||||
|
||||
def adis_save_and_enter_exemplar(new_signature):
|
||||
# Simulate the action of saving and entering the exemplar
|
||||
save_part()
|
||||
#move mouse down 300 px to be in scrollable area
|
||||
while pyautogui.locateOnScreen('images/exemplar.png', confidence=0.6, minSearchTime=1) is None:
|
||||
time.sleep(1)
|
||||
pyautogui.move(0, 300)
|
||||
print("Exemplar button found, continuing...")
|
||||
#scroll page down to the exemplar button
|
||||
pyautogui.scroll(-5000)
|
||||
pyautogui.click(499,974)
|
||||
|
||||
exemplar = pyautogui.locateOnScreen('images/exemplar.png', confidence=0.6)
|
||||
pyautogui.click(exemplar)
|
||||
time.sleep(1)
|
||||
while pyautogui.locateOnScreen('images/exemplar_ident.png', confidence=0.6, minSearchTime=1) is None:
|
||||
time.sleep(1)
|
||||
pyautogui.move(125,0)
|
||||
pyautogui.click()
|
||||
time.sleep(1)
|
||||
while pyautogui.locateOnScreen('images/save.png', confidence=0.6, minSearchTime=1) is None:
|
||||
time.sleep(1)
|
||||
pyautogui.click(1325,250)
|
||||
pyautogui.hotkey('ctrl', 'a') # Select all text
|
||||
pyautogui.typewrite(new_signature)
|
||||
save_part()
|
||||
|
||||
while pyautogui.locateOnScreen('images/back.png', confidence=0.6, minSearchTime=1) is None:
|
||||
time.sleep(1)
|
||||
pyautogui.doubleClick(585,357)
|
||||
time.sleep(0.2)
|
||||
pyautogui.hotkey('ctrl', 'c')
|
||||
time.sleep(0.2)
|
||||
text = clipboard.paste()
|
||||
print("Text copied to clipboard:", text)
|
||||
pyautogui.click(pyautogui.locateOnScreen('images/back.png', confidence=0.6))
|
||||
while pyautogui.locateOnScreen('images/info.png', confidence=0.6, minSearchTime=1) is None:
|
||||
time.sleep(1)
|
||||
time.sleep(1)
|
||||
print("Arrived at Info page, committing changes...")
|
||||
commit_changes()
|
||||
return text
|
||||
|
||||
def print_new_signature(catalogue_name:str, print_name:str, mednr:str):
|
||||
taskswitcher_name(print_name)
|
||||
time.sleep(1)
|
||||
#check if active window is named print_name
|
||||
active_window = get_active_name()
|
||||
if active_window != print_name:
|
||||
print(f"Active window is not '{print_name}', switching to it...")
|
||||
taskswitcher_name(print_name)
|
||||
time.sleep(2)
|
||||
pyautogui.click()
|
||||
print("Please press space to print the new signature.")
|
||||
# keyboard.wait('space') # Wait for the user to press space to print
|
||||
pyautogui.press('space') # Simulate pressing space to print
|
||||
|
||||
#sleep as long as the cursor is not arrow, ibeam or hand
|
||||
while True:
|
||||
cursor = get_current_hcursor()
|
||||
cursor_name = classify_cursor(cursor)
|
||||
if cursor_name in ['arrow', 'ibeam', 'hand']:
|
||||
print(f"Cursor is now {cursor_name}, proceeding...")
|
||||
break
|
||||
else:
|
||||
print(f"Cursor is {cursor_name}, waiting...")
|
||||
time.sleep(1)
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
taskswitcher_name(catalogue_name)
|
||||
|
||||
def new_search():
|
||||
pyautogui.hotkey("alt", "s")
|
||||
time.sleep(2)
|
||||
while True:
|
||||
if pyautogui.locateOnScreen('images/new_search.png', confidence=0.8, minSearchTime=1.5) is None:
|
||||
print("Searching")
|
||||
else:
|
||||
print("Found the New Search button, clicking...")
|
||||
break
|
||||
#press arrow up
|
||||
pyautogui.click(480,280)
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
time.sleep(5) # Wait for a few seconds before starting
|
||||
# commit_changes()
|
||||
#new_search()
|
||||
get_click_locations()
|
||||
94
src/cursor.py
Normal file
@@ -0,0 +1,94 @@
|
||||
import ctypes
|
||||
from ctypes import wintypes
|
||||
import time
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Helper definitions missing from ctypes.wintypes
|
||||
# ---------------------------------------------------------------------
|
||||
HCURSOR = wintypes.HANDLE
|
||||
|
||||
class POINT(ctypes.Structure):
|
||||
_fields_ = [("x", wintypes.LONG),
|
||||
("y", wintypes.LONG)]
|
||||
|
||||
class CURSORINFO(ctypes.Structure):
|
||||
_fields_ = [("cbSize", wintypes.DWORD),
|
||||
("flags", wintypes.DWORD),
|
||||
("hCursor", HCURSOR),
|
||||
("ptScreenPos", POINT)]
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Win-API bindings
|
||||
# ---------------------------------------------------------------------
|
||||
user32 = ctypes.WinDLL("user32", use_last_error=True)
|
||||
|
||||
GetCursorInfo = user32.GetCursorInfo
|
||||
GetCursorInfo.restype = wintypes.BOOL
|
||||
GetCursorInfo.argtypes = [ctypes.POINTER(CURSORINFO)]
|
||||
|
||||
LoadCursorW = user32.LoadCursorW
|
||||
LoadCursorW.restype = HCURSOR
|
||||
LoadCursorW.argtypes = [wintypes.HINSTANCE, wintypes.LPCWSTR]
|
||||
|
||||
# --- helper: C's MAKEINTRESOURCE -------------------------------
|
||||
def MAKEINTRESOURCE(i: int) -> wintypes.LPCWSTR:
|
||||
"""Cast an integer resource ID to LPCWSTR (same trick as MAKEINTRESOURCE)."""
|
||||
return ctypes.cast(ctypes.c_void_p(i & 0xFFFF), wintypes.LPCWSTR)
|
||||
|
||||
# Standard resource IDs (IDC_* values)
|
||||
IDC = {
|
||||
"arrow": 32512,
|
||||
"ibeam": 32513,
|
||||
"wait": 32514,
|
||||
"cross": 32515,
|
||||
"uparrow": 32516,
|
||||
"sizenwse": 32642,
|
||||
"sizenesw": 32643,
|
||||
"sizewe": 32644,
|
||||
"sizens": 32645,
|
||||
"sizeall": 32646,
|
||||
"no": 32648,
|
||||
"hand": 32649,
|
||||
"appstarting": 32650,
|
||||
"help": 32651,
|
||||
}
|
||||
|
||||
# Pre-load the handles for the standard cursors
|
||||
STANDARD_CURSORS = {
|
||||
name: LoadCursorW(None, MAKEINTRESOURCE(res_id))
|
||||
for name, res_id in IDC.items()
|
||||
}
|
||||
|
||||
CURSOR_SHOWING = 0x00000001
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Utility functions
|
||||
# ---------------------------------------------------------------------
|
||||
def get_current_hcursor() -> HCURSOR | None:
|
||||
"""Return the HCURSOR currently visible on screen, or None if none."""
|
||||
ci = CURSORINFO()
|
||||
ci.cbSize = ctypes.sizeof(ci)
|
||||
if GetCursorInfo(ctypes.byref(ci)) and ci.flags & CURSOR_SHOWING:
|
||||
return ci.hCursor
|
||||
return None
|
||||
|
||||
def classify_cursor(hcursor: HCURSOR) -> str:
|
||||
"""Translate an HCURSOR to a readable name."""
|
||||
for name, std_handle in STANDARD_CURSORS.items():
|
||||
if hcursor == std_handle:
|
||||
return name
|
||||
return "custom or unknown"
|
||||
|
||||
# ---------------------------------------------------------------------
|
||||
# Demo: watch the cursor and report changes for 10 s
|
||||
# ---------------------------------------------------------------------
|
||||
if __name__ == "__main__":
|
||||
print("Watching cursor for 10 seconds — move the mouse or open menus …")
|
||||
last = None
|
||||
t_end = time.time()
|
||||
while time.time() < t_end:
|
||||
cur = get_current_hcursor()
|
||||
if cur and cur != last:
|
||||
print("Now showing:", classify_cursor(cur))
|
||||
last = cur
|
||||
time.sleep(0.05)
|
||||
95
src/database.py
Normal file
@@ -0,0 +1,95 @@
|
||||
import sqlite3 as sql
|
||||
from src.utils import SignatureType
|
||||
MA_TABLE = """
|
||||
CREATE TABLE IF NOT EXISTS ma (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
old_signature TEXT NOT NULL UNIQUE,
|
||||
new_signature TEXT NOT NULL UNIQUE
|
||||
)"""
|
||||
MB_TABLE = """
|
||||
CREATE TABLE IF NOT EXISTS mb (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
old_signature TEXT NOT NULL,
|
||||
new_signature TEXT NOT NULL,
|
||||
UNIQUE(old_signature, new_signature)
|
||||
)"""
|
||||
MC_TABLE = """
|
||||
CREATE TABLE IF NOT EXISTS mc (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
old_signature TEXT NOT NULL,
|
||||
new_signature TEXT NOT NULL,
|
||||
UNIQUE(old_signature, new_signature)
|
||||
)"""
|
||||
|
||||
|
||||
class Database:
|
||||
def __init__(self) -> None:
|
||||
self.connection = sql.connect("adis.db")
|
||||
self.create_tables()
|
||||
|
||||
def create_tables(self) -> None:
|
||||
cursor = self.connection.cursor()
|
||||
cursor.execute(MA_TABLE)
|
||||
cursor.execute(MB_TABLE)
|
||||
cursor.execute(MC_TABLE)
|
||||
self.connection.commit()
|
||||
|
||||
def create_new_signature(self, table:str)->str:
|
||||
"""Create a new signature for the given table.
|
||||
The new signature is generated by using 01 / as prefix, then incrementing the number by 1 for each new entry."""
|
||||
cursor = self.connection.cursor()
|
||||
cursor.execute(f"SELECT COUNT(*) FROM {table}")
|
||||
count = cursor.fetchone()[0]
|
||||
signature_prefix = SignatureType.new_signature_prefix(table)
|
||||
new_signature = f"{signature_prefix}{count + 1}"
|
||||
return new_signature
|
||||
|
||||
def signature_exists(self, old_signature: str, table: str) -> bool:
|
||||
"""Check if a signature already exists in the specified table."""
|
||||
cursor = self.connection.cursor()
|
||||
cursor.execute(f"SELECT COUNT(*) FROM {table} WHERE old_signature = ?", (old_signature,))
|
||||
count = cursor.fetchone()[0]
|
||||
return count > 0
|
||||
|
||||
def insert_ma(self, old_signature: str) -> str|None:
|
||||
"""Insert an old signature into the ma table and return the new signature.
|
||||
New Signatures is generated by using 01 / as prefix, then incrementing the number by 1 for each new entry."""
|
||||
if self.signature_exists(old_signature, "ma"):
|
||||
print(f"Error: The old_signature '{old_signature}' already exists in the ma table.")
|
||||
return None
|
||||
new_signature = self.create_new_signature("ma")
|
||||
try:
|
||||
cursor = self.connection.cursor()
|
||||
cursor.execute("INSERT INTO ma (old_signature, new_signature) VALUES (?, ?)", (old_signature, new_signature))
|
||||
self.connection.commit()
|
||||
return new_signature
|
||||
except sql.IntegrityError:
|
||||
print(f"Error: The combination of old_signature '{old_signature}' and new_signature '{new_signature}' already exists.")
|
||||
return None
|
||||
|
||||
|
||||
def insert_mb(self, old_signature: str) -> str:
|
||||
"""Insert an old signature into the mb table and return the new signature.
|
||||
New Signatures is generated by using 02 / as prefix, then incrementing the number by 1 for each new entry."""
|
||||
new_signature = self.create_new_signature("mb")
|
||||
try:
|
||||
cursor = self.connection.cursor()
|
||||
cursor.execute("INSERT INTO mb (old_signature, new_signature) VALUES (?, ?)", (old_signature, new_signature))
|
||||
self.connection.commit()
|
||||
return new_signature
|
||||
except sql.IntegrityError:
|
||||
print(f"Error: The combination of old_signature '{old_signature}' and new_signature '{new_signature}' already exists.")
|
||||
return None
|
||||
|
||||
def insert_mc(self, old_signature: str) -> str:
|
||||
"""Insert an old signature into the mc table and return the new signature.
|
||||
New Signatures is generated by using 03 / as prefix, then incrementing the number by 1 for each new entry."""
|
||||
new_signature = self.create_new_signature("mc")
|
||||
try:
|
||||
cursor = self.connection.cursor()
|
||||
cursor.execute("INSERT INTO mc (old_signature, new_signature) VALUES (?, ?)", (old_signature, new_signature))
|
||||
self.connection.commit()
|
||||
return new_signature
|
||||
except sql.IntegrityError:
|
||||
print(f"Error: The combination of old_signature '{old_signature}' and new_signature '{new_signature}' already exists.")
|
||||
return None
|
||||
32
src/utils.py
Normal file
@@ -0,0 +1,32 @@
|
||||
import enum
|
||||
|
||||
class SignatureType(enum.Enum):
|
||||
MA = "ma"
|
||||
MB = "mb"
|
||||
MC = "mc"
|
||||
|
||||
@classmethod
|
||||
def from_string(cls, value: str) -> "SignatureType":
|
||||
"""Convert a string to a SignatureType enum."""
|
||||
match value.lower():
|
||||
case "ma":
|
||||
return cls.MA.value
|
||||
case "mb":
|
||||
return cls.MB.value
|
||||
case "mc":
|
||||
return cls.MC.value
|
||||
case _:
|
||||
raise ValueError(f"Unknown signature type: {value}")
|
||||
|
||||
@classmethod
|
||||
def new_signature_prefix(cls, value: str) -> str:
|
||||
"""Generate a new signature prefix based on the signature type."""
|
||||
match value.lower():
|
||||
case "ma":
|
||||
return "01/ "
|
||||
case "mb":
|
||||
return "02/ "
|
||||
case "mc":
|
||||
return "03/ "
|
||||
case _:
|
||||
raise ValueError(f"Unknown signature type: {value}")
|
||||