color identity in pull sheet
This commit is contained in:
parent
fa089adb53
commit
7bc64115f2
@ -90,6 +90,12 @@ tr:hover {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.color-identity {
|
||||
width: 40px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.product-name {
|
||||
width: 200px;
|
||||
}
|
||||
@ -119,6 +125,7 @@ tbody tr:hover {
|
||||
<th class="set">Set</th>
|
||||
<th class="rarity">Rarity</th>
|
||||
<th class="card-number">Card #</th>
|
||||
<th class="color-identity">Colors</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -129,6 +136,7 @@ tbody tr:hover {
|
||||
<td class="set">{{ item.set }}</td>
|
||||
<td class="rarity">{{ item.rarity }}</td>
|
||||
<td class="card-number">{{ item.card_number }}</td>
|
||||
<td class="color-identity">{{ item.color_identity }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
@ -35,5 +35,6 @@ __all__ = [
|
||||
'OrderManagementService',
|
||||
'TCGPlayerInventoryService',
|
||||
'PricingService',
|
||||
'MarketplaceListingService'
|
||||
'MarketplaceListingService',
|
||||
'ScryfallService'
|
||||
]
|
11
app/services/external_api/scryfall/scryfall_service.py
Normal file
11
app/services/external_api/scryfall/scryfall_service.py
Normal file
@ -0,0 +1,11 @@
|
||||
from app.services.external_api.base_external_service import BaseExternalService
|
||||
|
||||
class ScryfallService(BaseExternalService):
|
||||
def __init__(self):
|
||||
super().__init__(base_url="https://api.scryfall.com/")
|
||||
|
||||
async def get_color_identity(self, scryfall_id: str) -> str:
|
||||
"""Get the color identity of a card from Scryfall API"""
|
||||
endpoint = f"cards/{scryfall_id}"
|
||||
results = await self._make_request("GET", endpoint)
|
||||
return results['color_identity']
|
@ -1,4 +1,5 @@
|
||||
from typing import List, Dict
|
||||
import json
|
||||
import pandas as pd
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
@ -9,7 +10,7 @@ import asyncio
|
||||
from app.schemas.file import FileInDB
|
||||
from app.services.base_service import BaseService
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.models.tcgplayer_products import TCGPlayerProduct, TCGPlayerGroup, MTGJSONSKU, MTGJSONCard
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -48,7 +49,7 @@ class PullSheetService(BaseService):
|
||||
"""
|
||||
try:
|
||||
# Read and process CSV data
|
||||
items = await self._read_and_process_csv(file.path)
|
||||
items = await self._read_and_process_csv(db, file.path)
|
||||
|
||||
# Prepare template data
|
||||
template_data = {
|
||||
@ -80,7 +81,50 @@ class PullSheetService(BaseService):
|
||||
logger.error(f"Error generating pull sheet PDF: {str(e)}")
|
||||
raise
|
||||
|
||||
async def _read_and_process_csv(self, csv_path: str) -> List[Dict]:
|
||||
async def _get_color_identity(self, db: Session, row: pd.Series) -> str:
|
||||
"""Get color identity from a row.
|
||||
|
||||
Args:
|
||||
row: pandas Series
|
||||
"""
|
||||
# get category id from set name
|
||||
group_id = db.query(TCGPlayerGroup).filter(TCGPlayerGroup.name == row['Set']).first().group_id
|
||||
# format number
|
||||
number = str(int(row['Number'])) if 'Number' in row and pd.notna(row['Number']) and '/' not in str(row['Number']) else str(row['Number']) if 'Number' in row and pd.notna(row['Number']) and '/' in str(row['Number']) else ''
|
||||
# get product info from category id
|
||||
product_id = db.query(TCGPlayerProduct).filter(TCGPlayerProduct.group_id == group_id).filter(TCGPlayerProduct.name == row['Product Name']).filter(TCGPlayerProduct.ext_number == number).filter(TCGPlayerProduct.ext_rarity == row['Rarity']).first().tcgplayer_product_id
|
||||
# get scryfall id from product id
|
||||
mtgjson_id = db.query(MTGJSONSKU).filter(MTGJSONSKU.tcgplayer_product_id == product_id).first().mtgjson_uuid
|
||||
scryfall_id = db.query(MTGJSONCard).filter(MTGJSONCard.mtgjson_uuid == mtgjson_id).first().scryfall_id
|
||||
# get color identity from scryfall
|
||||
scryfall_service = self.get_service('scryfall')
|
||||
color_identity = await scryfall_service.get_color_identity(scryfall_id)
|
||||
if color_identity is None:
|
||||
return '?'
|
||||
# color identity is str of json array, convert to human readable string of list
|
||||
color_identity = [str(color) for color in color_identity]
|
||||
# if color identity is empty, return C for colorless
|
||||
if not color_identity:
|
||||
return 'C'
|
||||
# ensure order, W > U > B > R > G
|
||||
color_identity = sorted(color_identity, key=lambda x: ['W', 'U', 'B', 'R', 'G'].index(x))
|
||||
color_identity = ''.join(color_identity)
|
||||
return color_identity
|
||||
|
||||
async def _update_row_color_identity(self, db: Session, row: pd.Series) -> pd.Series:
|
||||
"""Update color identity from a row.
|
||||
|
||||
Args:
|
||||
row: pandas Series
|
||||
"""
|
||||
# get color identity from row
|
||||
color_identity = await self._get_color_identity(db, row)
|
||||
# update row with color identity
|
||||
row['Color Identity'] = color_identity
|
||||
return row
|
||||
|
||||
|
||||
async def _read_and_process_csv(self, db: Session, csv_path: str) -> List[Dict]:
|
||||
"""Read and process CSV data using pandas.
|
||||
|
||||
Args:
|
||||
@ -104,6 +148,15 @@ class PullSheetService(BaseService):
|
||||
# Sort by Set Release Date (descending) and then Product Name (ascending)
|
||||
df = df.sort_values(['Set Release Date', 'Set', 'Product Name'], ascending=[False, True, True])
|
||||
|
||||
# Process color identities for all rows
|
||||
color_identities = []
|
||||
for _, row in df.iterrows():
|
||||
color_identity = await self._get_color_identity(db, row)
|
||||
color_identities.append(color_identity)
|
||||
|
||||
# Add color identity column to dataframe
|
||||
df['Color Identity'] = color_identities
|
||||
|
||||
# Convert to list of dictionaries
|
||||
items = []
|
||||
for _, row in df.iterrows():
|
||||
@ -113,7 +166,8 @@ class PullSheetService(BaseService):
|
||||
'quantity': str(int(row['Quantity'])), # Convert to string for template
|
||||
'set': row['Set'],
|
||||
'rarity': row['Rarity'],
|
||||
'card_number': str(int(row['Number'])) if 'Number' in row and pd.notna(row['Number']) and '/' not in str(row['Number']) else str(row['Number']) if 'Number' in row and pd.notna(row['Number']) and '/' in str(row['Number']) else ''
|
||||
'card_number': str(int(row['Number'])) if 'Number' in row and pd.notna(row['Number']) and '/' not in str(row['Number']) else str(row['Number']) if 'Number' in row and pd.notna(row['Number']) and '/' in str(row['Number']) else '',
|
||||
'color_identity': row['Color Identity']
|
||||
})
|
||||
|
||||
return items
|
@ -34,7 +34,8 @@ class ServiceManager:
|
||||
'inventory': 'app.services.inventory_service.InventoryService',
|
||||
'box': 'app.services.inventory_service.BoxService',
|
||||
'case': 'app.services.inventory_service.CaseService',
|
||||
'marketplace_listing': 'app.services.inventory_service.MarketplaceListingService'
|
||||
'marketplace_listing': 'app.services.inventory_service.MarketplaceListingService',
|
||||
'scryfall': 'app.services.external_api.scryfall.scryfall_service.ScryfallService'
|
||||
|
||||
}
|
||||
self._service_configs = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user