data model change and some new services
This commit is contained in:
211
services/box.py
211
services/box.py
@@ -1,100 +1,135 @@
|
||||
from db.models import ManaboxExportData, Box, UploadHistory
|
||||
from db.models import Box, File, StagedFileProduct, Product, OpenBoxCard, OpenBox, Inventory
|
||||
from db.utils import db_transaction
|
||||
import uuid
|
||||
from uuid import uuid4 as uuid
|
||||
from datetime import datetime
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy.engine.result import Row
|
||||
|
||||
|
||||
|
||||
from schemas.box import CreateOpenBoxResponse, CreateSealedBoxResponse, CreateBoxResponse
|
||||
import logging
|
||||
from typing import Any
|
||||
from db.utils import db_transaction
|
||||
from services.inventory import InventoryService
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class BoxObject:
|
||||
def __init__(
|
||||
self, upload_id: str, set_name: str,
|
||||
set_code: str, cost: float = None, date_purchased: datetime = None,
|
||||
date_opened: datetime = None, box_id: str = None):
|
||||
self.upload_id = upload_id
|
||||
self.box_id = box_id if box_id else str(uuid.uuid4())
|
||||
self.set_name = set_name
|
||||
self.set_code = set_code
|
||||
self.cost = cost
|
||||
self.date_purchased = date_purchased
|
||||
self.date_opened = date_opened
|
||||
|
||||
class BoxService:
|
||||
def __init__(self, db: Session):
|
||||
def __init__(self, db: Session, inventory_service: InventoryService):
|
||||
self.db = db
|
||||
|
||||
def _validate_upload_id(self, upload_id: str):
|
||||
# check if upload_history status = 'success'
|
||||
if self.db.query(UploadHistory).filter(UploadHistory.upload_id == upload_id).first() is None:
|
||||
raise Exception(f"Upload ID {upload_id} not found")
|
||||
if self.db.query(UploadHistory).filter(UploadHistory.upload_id == upload_id).first().status != 'success':
|
||||
raise Exception(f"Upload ID {upload_id} not successful")
|
||||
# check if at least 1 row in manabox_export_data with upload_id
|
||||
if self.db.query(ManaboxExportData).filter(ManaboxExportData.upload_id == upload_id).first() is None:
|
||||
raise Exception(f"Upload ID {upload_id} has no data")
|
||||
|
||||
def _get_set_info(self, upload_id: str) -> list[Row[tuple[str, str]]]:
|
||||
# get distinct set_name, set_code from manabox_export_data for upload_id
|
||||
boxes = self.db.query(ManaboxExportData.set_name, ManaboxExportData.set_code).filter(ManaboxExportData.upload_id == upload_id).distinct().all()
|
||||
if not boxes or len(boxes) == 0:
|
||||
raise Exception(f"Upload ID {upload_id} has no data")
|
||||
return boxes
|
||||
|
||||
def _update_manabox_export_data_box_id(self, box: Box):
|
||||
# based on upload_id, set_name, set_code, update box_id in manabox_export_data for all rows where box id is null
|
||||
with db_transaction(self.db):
|
||||
self.db.query(ManaboxExportData).filter(
|
||||
ManaboxExportData.upload_id == box.upload_id).filter(
|
||||
ManaboxExportData.set_name == box.set_name).filter(
|
||||
ManaboxExportData.set_code == box.set_code).filter(
|
||||
ManaboxExportData.box_id == None).update({ManaboxExportData.box_id: box.id})
|
||||
self.inventory_service = inventory_service
|
||||
|
||||
def convert_upload_to_boxes(self, upload_id: str):
|
||||
self._validate_upload_id(upload_id)
|
||||
# get distinct set_name, set_code from manabox_export_data for upload_id
|
||||
box_set_info = self._get_set_info(upload_id)
|
||||
created_boxes = []
|
||||
# create boxes
|
||||
for box in box_set_info:
|
||||
box_obj = BoxObject(upload_id, set_name = box.set_name, set_code = box.set_code)
|
||||
new_box = self.create_box(box_obj)
|
||||
logger.info(f"Created box {new_box.id} for upload {upload_id}")
|
||||
self._update_manabox_export_data_box_id(new_box)
|
||||
created_boxes.append(new_box)
|
||||
def validate_file_ids(self, file_ids: list[str]):
|
||||
# check if all file_ids are valid
|
||||
for file_id in file_ids:
|
||||
if self.db.query(File).filter(File.id == file_id).first() is None:
|
||||
raise Exception(f"File ID {file_id} not found")
|
||||
|
||||
def get_staged_product_data(self, file_ids: list[str]) -> StagedFileProduct:
|
||||
staged_product_data = self.db.query(StagedFileProduct).filter(StagedFileProduct.file_id.in_(file_ids)).all()
|
||||
return staged_product_data
|
||||
|
||||
def aggregate_staged_product_data(self, staged_product_data: list[Row]) -> dict[Product, int]:
|
||||
product_data = {}
|
||||
for row in staged_product_data:
|
||||
product = self.db.query(Product).filter(Product.id == row.product_id).first()
|
||||
if product not in product_data:
|
||||
product_data[product] = 0
|
||||
product_data[product] += row.quantity
|
||||
return product_data
|
||||
|
||||
def find_product_for_box_data(self, create_box_data: dict[str, Any]) -> Product:
|
||||
existing_product = self.db.query(Product).filter(
|
||||
Product.name == create_box_data["name"], # TODO: needs complex enum
|
||||
Product.type == "box",
|
||||
Product.set_code == create_box_data["set_code"], # TODO: needs complex enum
|
||||
Product.set_name == create_box_data["set_name"], # TODO: needs complex enum
|
||||
Product.product_line == create_box_data["product_line"]).first()
|
||||
return existing_product
|
||||
|
||||
def create_product_for_box(self, create_box_data: dict[str, Any]) -> Product:
|
||||
product = Product(
|
||||
id=str(uuid()),
|
||||
name=create_box_data["name"],
|
||||
type="box",
|
||||
set_code=create_box_data["set_code"],
|
||||
set_name=create_box_data["set_name"],
|
||||
product_line=create_box_data["product_line"]
|
||||
)
|
||||
self.db.add(product)
|
||||
return product
|
||||
|
||||
def create_box_db(self, product: Product, create_box_data: dict[str, Any]) -> Box:
|
||||
box = Box(
|
||||
product_id=product.id,
|
||||
type=create_box_data["type"],
|
||||
sku=create_box_data["sku"],
|
||||
num_cards_expected=create_box_data["num_cards_expected"]
|
||||
)
|
||||
self.db.add(box)
|
||||
return box
|
||||
|
||||
def create_open_box(self, product: Product, create_box_data: dict[str, Any]) -> OpenBox:
|
||||
open_box = OpenBox(
|
||||
id = str(uuid()),
|
||||
product_id=product.id,
|
||||
num_cards_actual=create_box_data["num_cards_actual"],
|
||||
date_opened=datetime.strptime(create_box_data["date_opened"], "%Y-%m-%d")
|
||||
)
|
||||
self.db.add(open_box)
|
||||
return open_box
|
||||
|
||||
def add_products_to_open_box(self, open_box: OpenBox, product_data: dict[Product, int]) -> None:
|
||||
for product, quantity in product_data.items():
|
||||
open_box_card = OpenBoxCard(
|
||||
id=str(uuid()),
|
||||
open_box_id=open_box.id,
|
||||
card_id=product.id,
|
||||
quantity=quantity
|
||||
)
|
||||
self.db.add(open_box_card)
|
||||
|
||||
def format_response(self, open_box: OpenBox = None, inventory: Inventory = None) -> CreateBoxResponse:
|
||||
response = CreateBoxResponse(success=True)
|
||||
return response
|
||||
|
||||
def create_box(self, create_box_data: dict[str, Any], file_ids: list[str] = None) -> CreateBoxResponse:
|
||||
sealed = create_box_data["sealed"]
|
||||
assert isinstance(sealed, bool)
|
||||
if file_ids and not sealed:
|
||||
self.validate_file_ids(file_ids)
|
||||
staged_product_data = self.get_staged_product_data(file_ids)
|
||||
product_data = self.aggregate_staged_product_data(staged_product_data)
|
||||
elif file_ids and sealed:
|
||||
raise Exception("Cannot add cards with a sealed box")
|
||||
|
||||
return {"status": "success", "boxes": f"{[box.id for box in created_boxes]}"}
|
||||
# find product with all same box data
|
||||
existing_product = self.find_product_for_box_data(create_box_data)
|
||||
|
||||
if existing_product:
|
||||
box_product = existing_product
|
||||
|
||||
try:
|
||||
with db_transaction(self.db):
|
||||
if not existing_product:
|
||||
box_product = self.create_product_for_box(create_box_data)
|
||||
box = self.create_box_db(box_product, create_box_data)
|
||||
if not sealed:
|
||||
open_box = self.create_open_box(box_product, create_box_data)
|
||||
if file_ids:
|
||||
process_staged_products = self.inventory_service.process_staged_products(product_data)
|
||||
self.add_products_to_open_box(open_box, product_data)
|
||||
# should be the file service handling this but im about to die irl
|
||||
# update file id status to processed
|
||||
for file_id in file_ids:
|
||||
file = self.db.query(File).filter(File.id == file_id).first()
|
||||
file.status = "processed"
|
||||
self.db.add(file)
|
||||
return self.format_response(open_box=open_box)
|
||||
elif not file_ids and sealed:
|
||||
# add sealed box to inventory
|
||||
inventory = self.inventory_service.add_sealed_box_to_inventory(box_product, 1)
|
||||
return self.format_response(inventory=inventory)
|
||||
|
||||
|
||||
def create_box(self, box: BoxObject):
|
||||
with db_transaction(self.db):
|
||||
box_record = Box(
|
||||
id = box.box_id,
|
||||
upload_id = box.upload_id,
|
||||
set_name = box.set_name,
|
||||
set_code = box.set_code,
|
||||
cost = box.cost,
|
||||
date_purchased = box.date_purchased,
|
||||
date_opened = box.date_opened
|
||||
)
|
||||
self.db.add(box_record)
|
||||
return box_record
|
||||
|
||||
def get_box(self):
|
||||
pass
|
||||
|
||||
def delete_box(self, box_id: str):
|
||||
# delete box
|
||||
with db_transaction(self.db):
|
||||
self.db.query(Box).filter(Box.id == box_id).delete()
|
||||
# update manabox_export_data box_id to null
|
||||
with db_transaction(self.db):
|
||||
self.db.query(ManaboxExportData).filter(ManaboxExportData.box_id == box_id).update({ManaboxExportData.box_id: None})
|
||||
return {"status": "success", "box_id": box_id}
|
||||
|
||||
def update_box(self):
|
||||
pass
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error creating box: {str(e)}")
|
||||
raise e
|
75
services/file.py
Normal file
75
services/file.py
Normal file
@@ -0,0 +1,75 @@
|
||||
from sqlalchemy.orm import Session
|
||||
from db.utils import db_transaction
|
||||
from db.models import File, StagedFileProduct
|
||||
from schemas.file import FileMetadata, FileUploadResponse, GetPreparedFilesResponse, FileDeleteResponse
|
||||
import os
|
||||
from uuid import uuid4 as uuid
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class FileService:
|
||||
def __init__(self, db: Session):
|
||||
self.db = db
|
||||
|
||||
def _format_response(self, file: File) -> FileUploadResponse:
|
||||
response = FileUploadResponse(
|
||||
id = file.id,
|
||||
filename = file.filename,
|
||||
type = file.type,
|
||||
source = file.source,
|
||||
status = file.status,
|
||||
service = file.service,
|
||||
file_size_kb = file.filesize_kb,
|
||||
date_created=file.date_created,
|
||||
date_modified=file.date_modified
|
||||
)
|
||||
return response
|
||||
|
||||
def upload_file(self, content: bytes, filename: str, metadata: FileMetadata) -> FileUploadResponse:
|
||||
# Save file to database
|
||||
with db_transaction(self.db):
|
||||
file = File(
|
||||
id = str(uuid()),
|
||||
filename = filename,
|
||||
filepath = os.getcwd() + '/temp/' + filename, # TODO: config variable
|
||||
type = metadata.type,
|
||||
source = metadata.source,
|
||||
filesize_kb = round(len(content) / 1024,2),
|
||||
status = 'pending',
|
||||
service = metadata.service
|
||||
)
|
||||
self.db.add(file)
|
||||
# save file
|
||||
with open(file.filepath, 'wb') as f:
|
||||
f.write(content)
|
||||
response = self._format_response(file)
|
||||
return response
|
||||
|
||||
def get_file(self, file_id: str) -> File:
|
||||
return self.db.query(File).filter(File.id == file_id).first()
|
||||
|
||||
def get_prepared_files(self) -> list[FileUploadResponse]:
|
||||
files = self.db.query(File).filter(File.status == 'prepared').all()
|
||||
if len(files) == 0:
|
||||
raise Exception("No prepared files found")
|
||||
result = [self._format_response(file) for file in files]
|
||||
logger.debug(f"Prepared files: {result}")
|
||||
response = GetPreparedFilesResponse(files=result)
|
||||
return response
|
||||
|
||||
def get_staged_products(self, file_id: str) -> list[StagedFileProduct]:
|
||||
return self.db.query(StagedFileProduct).filter(StagedFileProduct.file_id == file_id).all()
|
||||
|
||||
def delete_file(self, file_id: str) -> FileDeleteResponse:
|
||||
file = self.get_file(file_id)
|
||||
staged_products = self.get_staged_products(file_id)
|
||||
if file:
|
||||
with db_transaction(self.db):
|
||||
self.db.delete(file)
|
||||
for staged_product in staged_products:
|
||||
self.db.delete(staged_product)
|
||||
return {"id": file_id, "status": "deleted"}
|
||||
else:
|
||||
raise Exception(f"File with id {file_id} not found")
|
28
services/inventory.py
Normal file
28
services/inventory.py
Normal file
@@ -0,0 +1,28 @@
|
||||
from sqlalchemy.orm import Session
|
||||
from db.models import Product, Inventory
|
||||
from schemas.inventory import UpdateInventoryResponse
|
||||
from db.utils import db_transaction
|
||||
|
||||
class InventoryService:
|
||||
def __init__(self, db: Session):
|
||||
self.db = db
|
||||
|
||||
def add_inventory(self, product: Product, quantity: int) -> Inventory:
|
||||
inventory = self.db.query(Inventory).filter(Inventory.product_id == product.id).first()
|
||||
if inventory is None:
|
||||
inventory = Inventory(product_id=product.id, quantity=quantity)
|
||||
self.db.add(inventory)
|
||||
else:
|
||||
inventory.quantity += quantity
|
||||
return inventory
|
||||
|
||||
def process_staged_products(self, product_data: dict[Product, int]) -> UpdateInventoryResponse:
|
||||
with db_transaction(self.db):
|
||||
for product, quantity in product_data.items():
|
||||
self.add_inventory(product, quantity)
|
||||
return UpdateInventoryResponse(success=True)
|
||||
|
||||
def add_sealed_box_to_inventory(self, product: Product, quantity: int) -> UpdateInventoryResponse:
|
||||
with db_transaction(self.db):
|
||||
inventory = self.add_inventory(product, quantity)
|
||||
return UpdateInventoryResponse(success=True)
|
100
services/old_box.py
Normal file
100
services/old_box.py
Normal file
@@ -0,0 +1,100 @@
|
||||
from db.models import ManaboxExportData, Box, UploadHistory
|
||||
from db.utils import db_transaction
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy.engine.result import Row
|
||||
|
||||
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class BoxObject:
|
||||
def __init__(
|
||||
self, upload_id: str, set_name: str,
|
||||
set_code: str, cost: float = None, date_purchased: datetime = None,
|
||||
date_opened: datetime = None, box_id: str = None):
|
||||
self.upload_id = upload_id
|
||||
self.box_id = box_id if box_id else str(uuid.uuid4())
|
||||
self.set_name = set_name
|
||||
self.set_code = set_code
|
||||
self.cost = cost
|
||||
self.date_purchased = date_purchased
|
||||
self.date_opened = date_opened
|
||||
|
||||
class BoxService:
|
||||
def __init__(self, db: Session):
|
||||
self.db = db
|
||||
|
||||
def _validate_upload_id(self, upload_id: str):
|
||||
# check if upload_history status = 'success'
|
||||
if self.db.query(UploadHistory).filter(UploadHistory.upload_id == upload_id).first() is None:
|
||||
raise Exception(f"Upload ID {upload_id} not found")
|
||||
if self.db.query(UploadHistory).filter(UploadHistory.upload_id == upload_id).first().status != 'success':
|
||||
raise Exception(f"Upload ID {upload_id} not successful")
|
||||
# check if at least 1 row in manabox_export_data with upload_id
|
||||
if self.db.query(ManaboxExportData).filter(ManaboxExportData.upload_id == upload_id).first() is None:
|
||||
raise Exception(f"Upload ID {upload_id} has no data")
|
||||
|
||||
def _get_set_info(self, upload_id: str) -> list[Row[tuple[str, str]]]:
|
||||
# get distinct set_name, set_code from manabox_export_data for upload_id
|
||||
boxes = self.db.query(ManaboxExportData.set_name, ManaboxExportData.set_code).filter(ManaboxExportData.upload_id == upload_id).distinct().all()
|
||||
if not boxes or len(boxes) == 0:
|
||||
raise Exception(f"Upload ID {upload_id} has no data")
|
||||
return boxes
|
||||
|
||||
def _update_manabox_export_data_box_id(self, box: Box):
|
||||
# based on upload_id, set_name, set_code, update box_id in manabox_export_data for all rows where box id is null
|
||||
with db_transaction(self.db):
|
||||
self.db.query(ManaboxExportData).filter(
|
||||
ManaboxExportData.upload_id == box.upload_id).filter(
|
||||
ManaboxExportData.set_name == box.set_name).filter(
|
||||
ManaboxExportData.set_code == box.set_code).filter(
|
||||
ManaboxExportData.box_id == None).update({ManaboxExportData.box_id: box.id})
|
||||
|
||||
def convert_upload_to_boxes(self, upload_id: str):
|
||||
self._validate_upload_id(upload_id)
|
||||
# get distinct set_name, set_code from manabox_export_data for upload_id
|
||||
box_set_info = self._get_set_info(upload_id)
|
||||
created_boxes = []
|
||||
# create boxes
|
||||
for box in box_set_info:
|
||||
box_obj = BoxObject(upload_id, set_name = box.set_name, set_code = box.set_code)
|
||||
new_box = self.create_box(box_obj)
|
||||
logger.info(f"Created box {new_box.id} for upload {upload_id}")
|
||||
self._update_manabox_export_data_box_id(new_box)
|
||||
created_boxes.append(new_box)
|
||||
|
||||
return {"status": "success", "boxes": f"{[box.id for box in created_boxes]}"}
|
||||
|
||||
|
||||
def create_box(self, box: BoxObject):
|
||||
with db_transaction(self.db):
|
||||
box_record = Box(
|
||||
id = box.box_id,
|
||||
upload_id = box.upload_id,
|
||||
set_name = box.set_name,
|
||||
set_code = box.set_code,
|
||||
cost = box.cost,
|
||||
date_purchased = box.date_purchased,
|
||||
date_opened = box.date_opened
|
||||
)
|
||||
self.db.add(box_record)
|
||||
return box_record
|
||||
|
||||
def get_box(self):
|
||||
pass
|
||||
|
||||
def delete_box(self, box_id: str):
|
||||
# delete box
|
||||
with db_transaction(self.db):
|
||||
self.db.query(Box).filter(Box.id == box_id).delete()
|
||||
# update manabox_export_data box_id to null
|
||||
with db_transaction(self.db):
|
||||
self.db.query(ManaboxExportData).filter(ManaboxExportData.box_id == box_id).update({ManaboxExportData.box_id: None})
|
||||
return {"status": "success", "box_id": box_id}
|
||||
|
||||
def update_box(self):
|
||||
pass
|
||||
|
136
services/product.py
Normal file
136
services/product.py
Normal file
@@ -0,0 +1,136 @@
|
||||
from sqlalchemy.orm import Session
|
||||
from db.utils import db_transaction
|
||||
from db.models import Product, File, CardManabox, Card, StagedFileProduct
|
||||
from io import StringIO
|
||||
import pandas as pd
|
||||
from services.file import FileService
|
||||
from uuid import uuid4 as uuid
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ManaboxRow:
|
||||
def __init__(self, row: pd.Series):
|
||||
self.name = row['name']
|
||||
self.set_code = row['set_code']
|
||||
self.set_name = row['set_name']
|
||||
self.collector_number = row['collector_number']
|
||||
self.foil = row['foil']
|
||||
self.rarity = row['rarity']
|
||||
self.manabox_id = row['manabox_id']
|
||||
self.scryfall_id = row['scryfall_id']
|
||||
self.condition = row['condition']
|
||||
self.language = row['language']
|
||||
self.quantity = row['quantity']
|
||||
|
||||
class ProductService:
|
||||
def __init__(self, db: Session, file_service: FileService):
|
||||
self.db = db
|
||||
self.file_service = file_service
|
||||
|
||||
def _format_manabox_df(self, df: pd.DataFrame) -> pd.DataFrame:
|
||||
# format columns
|
||||
df.columns = df.columns.str.lower()
|
||||
df.columns = df.columns.str.replace(' ', '_')
|
||||
return df
|
||||
|
||||
def _manabox_file_to_df(self, file: File) -> pd.DataFrame:
|
||||
with open(file.filepath, 'rb') as f:
|
||||
content = f.read()
|
||||
content = content.decode('utf-8')
|
||||
df = pd.read_csv(StringIO(content))
|
||||
df = self._format_manabox_df(df)
|
||||
return df
|
||||
|
||||
def create_staged_product(self, file: File, card_manabox:CardManabox, row: ManaboxRow) -> StagedFileProduct:
|
||||
staged_product = StagedFileProduct(
|
||||
id = str(uuid()),
|
||||
file_id = file.id,
|
||||
product_id = card_manabox.product_id,
|
||||
quantity = row.quantity
|
||||
)
|
||||
with db_transaction(self.db):
|
||||
self.db.add(staged_product)
|
||||
return staged_product
|
||||
|
||||
def create_card_manabox(self, manabox_row: ManaboxRow) -> CardManabox:
|
||||
card_manabox = CardManabox(
|
||||
product_id = str(uuid()),
|
||||
name = manabox_row.name,
|
||||
set_code = manabox_row.set_code,
|
||||
set_name = manabox_row.set_name,
|
||||
collector_number = manabox_row.collector_number,
|
||||
foil = manabox_row.foil,
|
||||
rarity = manabox_row.rarity,
|
||||
manabox_id = manabox_row.manabox_id,
|
||||
scryfall_id = manabox_row.scryfall_id,
|
||||
condition = manabox_row.condition,
|
||||
language = manabox_row.language
|
||||
)
|
||||
return card_manabox
|
||||
|
||||
def create_product(self, card_manabox: CardManabox) -> Product:
|
||||
product = Product(
|
||||
id = card_manabox.product_id,
|
||||
name = card_manabox.name,
|
||||
set_code = card_manabox.set_code,
|
||||
set_name = card_manabox.set_name,
|
||||
type = 'card',
|
||||
product_line = 'mtg'
|
||||
)
|
||||
return product
|
||||
|
||||
def create_card(self, card_manabox: CardManabox) -> Card:
|
||||
card = Card(
|
||||
product_id = card_manabox.product_id,
|
||||
number = card_manabox.collector_number,
|
||||
foil = card_manabox.foil,
|
||||
rarity = card_manabox.rarity,
|
||||
condition = card_manabox.condition,
|
||||
language = card_manabox.language,
|
||||
scryfall_id = card_manabox.scryfall_id,
|
||||
manabox_id = card_manabox.manabox_id
|
||||
)
|
||||
return card
|
||||
|
||||
def card_manabox_lookup_create_if_not_exist(self, manabox_row: ManaboxRow) -> CardManabox:
|
||||
# query based on all fields in manabox_row
|
||||
card_manabox = self.db.query(CardManabox).filter(
|
||||
CardManabox.name == manabox_row.name,
|
||||
CardManabox.set_code == manabox_row.set_code,
|
||||
CardManabox.set_name == manabox_row.set_name,
|
||||
CardManabox.collector_number == manabox_row.collector_number,
|
||||
CardManabox.foil == manabox_row.foil,
|
||||
CardManabox.rarity == manabox_row.rarity,
|
||||
CardManabox.manabox_id == manabox_row.manabox_id,
|
||||
CardManabox.scryfall_id == manabox_row.scryfall_id,
|
||||
CardManabox.condition == manabox_row.condition,
|
||||
CardManabox.language == manabox_row.language
|
||||
).first()
|
||||
if not card_manabox:
|
||||
# create new card_manabox, card, and product
|
||||
with db_transaction(self.db):
|
||||
card_manabox = self.create_card_manabox(manabox_row)
|
||||
product = self.create_product(card_manabox)
|
||||
card = self.create_card(card_manabox)
|
||||
self.db.add(card_manabox)
|
||||
self.db.add(product)
|
||||
self.db.add(card)
|
||||
return card_manabox
|
||||
|
||||
def bg_process_manabox_file(self, file_id: str):
|
||||
try:
|
||||
file = self.file_service.get_file(file_id)
|
||||
df = self._manabox_file_to_df(file)
|
||||
for index, row in df.iterrows():
|
||||
manabox_row = ManaboxRow(row)
|
||||
card_manabox = self.card_manabox_lookup_create_if_not_exist(manabox_row)
|
||||
staged_product = self.create_staged_product(file, card_manabox, row)
|
||||
# update file status
|
||||
with db_transaction(self.db):
|
||||
file.status = 'prepared'
|
||||
except Exception as e:
|
||||
with db_transaction(self.db):
|
||||
file.status = 'error'
|
||||
raise e
|
@@ -41,12 +41,14 @@ class UploadService:
|
||||
|
||||
return df
|
||||
|
||||
def _create_file_upload_record(self, upload_id: str, filename: str) -> UploadHistory:
|
||||
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"
|
||||
status = "pending",
|
||||
file_size_kb = file_size_kb,
|
||||
num_rows = num_rows
|
||||
)
|
||||
self.db.add(file_upload_record)
|
||||
return file_upload_record
|
||||
@@ -80,13 +82,14 @@ class UploadService:
|
||||
return False
|
||||
return True
|
||||
|
||||
def process_manabox_upload(self, content: bytes, filename: str):
|
||||
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_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"
|
||||
|
Reference in New Issue
Block a user