95 lines
2.2 KiB
Python
95 lines
2.2 KiB
Python
from django.tasks import task
|
|
from games.models import EventGame
|
|
from submissions.models import ImageCrop, SubmissionFile, OCRStatus
|
|
from submissions.services.aandt_sync import sync_event_game_scopes
|
|
|
|
from PIL import Image
|
|
import pytesseract
|
|
|
|
|
|
def _process_ocr_file(obj, file, crop: ImageCrop | None = None) -> bool:
|
|
if obj.ocr_status != OCRStatus.TO_PROCESS:
|
|
return False
|
|
|
|
obj.ocr_status = OCRStatus.PROCESSING
|
|
obj.save(update_fields=["ocr_status"])
|
|
|
|
try:
|
|
image = Image.open(file)
|
|
|
|
if crop:
|
|
image = image.crop((crop.x1, crop.y1, crop.x2, crop.y2))
|
|
|
|
obj.ocr_raw_data = pytesseract.image_to_string(image)
|
|
obj.ocr_status = OCRStatus.PROCESSED
|
|
|
|
except Exception as e:
|
|
obj.ocr_status = OCRStatus.ERROR
|
|
raise e
|
|
|
|
finally:
|
|
obj.save(update_fields=["ocr_status", "ocr_raw_data"])
|
|
|
|
return True
|
|
|
|
|
|
@task
|
|
def process_submission_files():
|
|
"""Process uploaded submission files (OCR, validation, etc.)"""
|
|
for file in SubmissionFile.objects.filter(ocr_status=OCRStatus.TO_PROCESS):
|
|
process_submission_file.enqueue(str(file.id))
|
|
|
|
|
|
@task
|
|
def process_submission_file(file_id: str):
|
|
file = SubmissionFile.objects.filter(id=file_id).first()
|
|
|
|
if not file:
|
|
return
|
|
|
|
_process_ocr_file(file, file.file)
|
|
|
|
process_crops.enqueue(file_id)
|
|
|
|
|
|
@task
|
|
def process_crops(file_id: str):
|
|
file = SubmissionFile.objects.filter(id=file_id).first()
|
|
|
|
if not file:
|
|
return
|
|
|
|
for crop in file.crops.all():
|
|
process_crop.enqueue(str(crop.id))
|
|
|
|
|
|
@task
|
|
def process_crop(crop_id: str):
|
|
crop = ImageCrop.objects.filter(id=crop_id).first()
|
|
|
|
if not crop:
|
|
return
|
|
|
|
_process_ocr_file(crop, crop.submission_file.file, crop=crop)
|
|
|
|
|
|
@task
|
|
def sync_all_event_games_task():
|
|
"""Queue a Scope sync for every EventGame with an AAndT token configured."""
|
|
event_games = EventGame.objects.exclude(apibot_token__isnull=True).exclude(
|
|
apibot_token=""
|
|
)
|
|
|
|
for event_game in event_games:
|
|
sync_event_game_scopes_task.enqueue(event_game.id)
|
|
|
|
|
|
@task
|
|
def sync_event_game_scopes_task(event_game_id: int):
|
|
event_game = EventGame.objects.filter(id=event_game_id).first()
|
|
|
|
if not event_game:
|
|
return
|
|
|
|
sync_event_game_scopes(event_game)
|