import sys import datetime import requests import threading import time import json import usb.core import usb.util from PyQt6 import QtWidgets, uic, QtGui, QtCore from PyQt6.QtCore import pyqtSignal as Signal, pyqtSlot as Slot from queue import Queue from requests.adapters import HTTPAdapter, Retry from usbcardreader import UsbCardReader app = QtWidgets.QApplication(sys.argv) with open('config.json', 'r') as f: config = json.load(f) session = requests.Session() session.post(config['host'] + '/api/login', {'email':config['login'], 'password': config['password']}) retries = Retry(total=10, backoff_factor=1, status_forcelist=[ 500, 502, 503, 504 ],) session.mount('https://', HTTPAdapter(max_retries=retries)) last_card = 0 last_time = datetime.datetime.now() racers = [] log = [] with open('log.json', 'r') as f: log = json.loads(f.read()) queue = Queue() class Worker(QtCore.QThread): returned_state = Signal(str) def __init__(self): super().__init__() self.returned_state.connect(self.handle_returned_state) self.worker_thread = threading.Thread(target=self.worker) self.worker_thread.start() def worker(self): while True: item = queue.get() log.append({ 'url': item['url'], 'json': item['json'], }) with open('log.json', 'w') as f: f.write(json.dumps(log)) response = session.post(item['url'], json=item['json']) if response.status_code == 200: if item.get('on_success'): item['on_success']() if item.get('message'): self.returned_state.emit(f'{item['message']}') else: if item.get('failed'): self.returned_state.emit(f'{item['failed']}') print(item, response) def handle_returned_state(self, state): mb = QtWidgets.QMessageBox(text=f"{state}") mb.exec() worker = Worker() def register_racer(): card_id = last_card index = window.racers.currentIndex() if not index.data(): mb = QtWidgets.QMessageBox(text='Prosím vyberte závodníka!') mb.exec() return racer_id = int(index.data().split(' ')[-1]) try: starting_number = max(filter(lambda r: r['starting_number'], racers), key=lambda racer: racer['starting_number'])['starting_number'] + 1 except ValueError: starting_number = 1 racer = list(filter(lambda x: x['racer_id'] == racer_id, racers))[0] def update_racer(): racer['card_id'] = card_id racer['starting_number'] = starting_number racer['started'] = False updateRacers() queue.put({ 'url': config['host'] + '/api/card/register', 'json': {'racer_id': racer_id, 'starting_number': starting_number, 'card_id': card_id, 'time': datetime.datetime.now().strftime('%d.%m.%Y %H:%M:%S.%f')}, 'message': f"Úspěšné zaregistrování závodníka {racer['first_name']} {racer['last_name']} se startovním číslem {starting_number}!", 'failed': f"Neúspěšná registrace závodníka {racer['first_name']} {racer['last_name']}", 'on_success': update_racer, }) model = QtGui.QStandardItemModel() def updateRacers(): model.clear() for racer in racers: if racer['starting_number'] or racer['card_id']: continue item = QtGui.QStandardItem(f"{racer['last_name']} {racer['first_name']} {racer['date_of_birth']} {racer['racer_id']}") model.appendRow(item) updateRacers() def reload_racers(): global racers response = session.get(config['host'] + '/api/racers') racers = response.json() updateRacers() reload_racers() def findByCard(card_id): for racer in racers: if racer['card_id'] == card_id: return racer def updateLastCard(card_id): global last_card, last_time if card_id == last_card and datetime.datetime.now() - last_time < datetime.timedelta(seconds=15): return time = last_time = datetime.datetime.now() last_card = card_id window.lastCard.setText(str(card_id)) racer = findByCard(card_id) if racer: if racer['started']: racer = list(filter(lambda x: x['card_id'] == card_id, racers))[0] def update_racer(): starting_number = racer['starting_number'] racer_id = racer['racer_id'] racer['card_id'] = None queue.put({ 'url': config['host'] + '/api/card/unregister', 'json': {'racer_id': racer_id, 'starting_number': starting_number, 'card_id': card_id, 'time': time.strftime('%d.%m.%Y %H:%M:%S.%f')}, 'message': f"Úspěšné odhlášení závodníka {starting_number}!", 'failed': f"Neúspěšné odhlášení karty závodníka {starting_number}", 'on_success': update_racer, }) else: def update_racer(): racer['started'] = True queue.put({ 'url': config['host'] + '/api/station/register', 'json': {'card_id': card_id, 'time': time.strftime('%d.%m.%Y %H:%M:%S.%f'), 'station_id': 1}, 'message': f"Úspěšné odstartování závodníka {racer['starting_number']}!", 'failed': f"Núspěšné odstartování závodníka {racer['starting_number']}, prosím registraci opakujte!", 'on_success': update_racer, }) UsbCardReader(updateLastCard) window = uic.loadUi("registrace.ui") window.racers.setModel(model) window.register_racer.clicked.connect(register_racer) window.reload_racers.clicked.connect(reload_racers) window.show() app.exec()