ai_giga_tcg/app/services/pull_sheet_service.py
2025-04-17 00:09:16 -04:00

91 lines
3.3 KiB
Python

from typing import List, Dict
import pandas as pd
from datetime import datetime
from pathlib import Path
from jinja2 import Environment, FileSystemLoader
from weasyprint import HTML
import logging
import asyncio
logger = logging.getLogger(__name__)
class PullSheetService:
def __init__(self):
self.template_dir = Path("app/data/assets/templates")
self.env = Environment(loader=FileSystemLoader(str(self.template_dir)))
self.template = self.env.get_template("pull_sheet.html")
self.output_dir = Path("app/data/cache/tcgplayer/pull_sheets")
self.output_dir.mkdir(parents=True, exist_ok=True)
async def generate_pull_sheet_pdf(self, csv_path: str) -> str:
"""Generate a PDF pull sheet from a CSV file.
Args:
csv_path: Path to the CSV file containing pull sheet data
Returns:
Path to the generated PDF file
"""
try:
# Read and process CSV data
items = await self._read_and_process_csv(csv_path)
# Prepare template data
template_data = {
'items': items,
'generation_date': datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
# Render HTML
html_content = self.template.render(**template_data)
# Generate PDF in a separate thread to avoid blocking
pdf_path = self.output_dir / f"pull_sheet_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf"
await asyncio.get_event_loop().run_in_executor(
None,
lambda: HTML(string=html_content).write_pdf(str(pdf_path))
)
return str(pdf_path)
except Exception as e:
logger.error(f"Error generating pull sheet PDF: {str(e)}")
raise
async def _read_and_process_csv(self, csv_path: str) -> List[Dict]:
"""Read and process CSV data using pandas.
Args:
csv_path: Path to the CSV file
Returns:
List of processed items
"""
# Read CSV into pandas DataFrame in a separate thread to avoid blocking
df = await asyncio.get_event_loop().run_in_executor(
None,
lambda: pd.read_csv(csv_path)
)
# Filter out the "Orders Contained in Pull Sheet" row
df = df[df['Product Line'] != 'Orders Contained in Pull Sheet:']
# Convert Set Release Date to datetime
df['Set Release Date'] = pd.to_datetime(df['Set Release Date'], format='%m/%d/%Y %H:%M:%S')
# 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])
# Convert to list of dictionaries
items = []
for _, row in df.iterrows():
items.append({
'product_name': row['Product Name'],
'condition': row['Condition'],
'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 else ''
})
return items