giga_tcg/services/upload.py

100 lines
3.8 KiB
Python

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, file_size_kb: float, num_rows: int) -> UploadHistory:
file_upload_record = UploadHistory(
id = str(uuid.uuid4()),
upload_id = upload_id,
filename = filename,
status = "pending",
file_size_kb = file_size_kb,
num_rows = num_rows
)
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, file_size_kb: float) -> dict:
upload = UploadObject(content=content, filename=filename)
upload.upload_id = self._create_upload_id()
upload.df = self._prepare_manabox_df(upload.content, upload.upload_id)
num_rows = len(upload.df)
with db_transaction(self.db):
file_upload_record = self._create_file_upload_record(upload.upload_id, upload.filename, file_size_kb, num_rows)
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