136 lines
5.2 KiB
Python
136 lines
5.2 KiB
Python
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 |