from db.models import ManaboxExportData, UploadHistory import pandas as pd from io import StringIO import uuid from sqlalchemy.orm import Session from db.utils import db_transaction from exceptions import FailedUploadException import logging logger = logging.getLogger(__name__) class UploadObject: def __init__(self, content: bytes = None, upload_id: str = None, filename: str = None, df: pd.DataFrame = None): self.content = content self.upload_id = upload_id self.filename = filename self.df = df class UploadService: def __init__(self, db: Session): self.db = db def _content_to_df(self, content: bytes) -> pd.DataFrame: df = pd.read_csv(StringIO(content.decode('utf-8'))) df.columns = df.columns.str.lower().str.replace(' ', '_') return df def _create_upload_id(self) -> str: return str(uuid.uuid4()) def _prepare_manabox_df(self, content: bytes, upload_id: str) -> pd.DataFrame: df = self._content_to_df(content) df['upload_id'] = upload_id df['box_id'] = None return df def _create_file_upload_record(self, upload_id: str, filename: str) -> UploadHistory: file_upload_record = UploadHistory( id = str(uuid.uuid4()), upload_id = upload_id, filename = filename, status = "pending" ) self.db.add(file_upload_record) return file_upload_record def _update_manabox_data(self, df: pd.DataFrame) -> bool: for index, row in df.iterrows(): try: add_row = ManaboxExportData( id = str(uuid.uuid4()), upload_id = row['upload_id'], box_id = row['box_id'], name = row['name'], set_code = row['set_code'], set_name = row['set_name'], collector_number = row['collector_number'], foil = row['foil'], rarity = row['rarity'], quantity = row['quantity'], manabox_id = row['manabox_id'], scryfall_id = row['scryfall_id'], purchase_price = row['purchase_price'], misprint = row['misprint'], altered = row['altered'], condition = row['condition'], language = row['language'], purchase_price_currency = row['purchase_price_currency'] ) self.db.add(add_row) except Exception as e: logger.error(f"Error adding row to ManaboxExportData") return False return True def process_manabox_upload(self, content: bytes, filename: str): upload = UploadObject(content=content, filename=filename) upload.upload_id = self._create_upload_id() upload.df = self._prepare_manabox_df(upload.content, upload.upload_id) with db_transaction(self.db): file_upload_record = self._create_file_upload_record(upload.upload_id, upload.filename) if not self._update_manabox_data(upload.df): # set upload to failed file_upload_record.status = "failed" raise FailedUploadException(file_upload_record) else: # set upload_history status to success file_upload_record.status = "success" return {"message": f"Manabox upload successful. Upload ID: {upload.upload_id}"}, upload.upload_id