231 lines
7.0 KiB
Python
231 lines
7.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Fix MTG sets endpoint - File-based changes only.
|
|
|
|
This script:
|
|
1. Reorders routes in card_router.py so /sets comes before /{card_name}
|
|
2. Adds image_url column to MtgSet model
|
|
3. Updates service layer to return image_url
|
|
"""
|
|
|
|
import re
|
|
from pathlib import Path
|
|
|
|
|
|
def fix_route_ordering():
|
|
"""Reorder routes in card_router.py so /sets comes before /{card_name}."""
|
|
route_file = Path('/home/wall-o/projects/mtgonline/backend/app/routers/card_router.py')
|
|
content = route_file.read_text()
|
|
|
|
# Find the current route order
|
|
# The issue: /{card_name} is defined before /sets
|
|
# We need to move /sets and /sets/{set_code} before /{card_name}
|
|
|
|
# Current order (problematic):
|
|
# 1. /search
|
|
# 2. /{card_name}
|
|
# 3. /set/{set_code}
|
|
# 4. /types
|
|
# 5. /rarities
|
|
# 6. /sets
|
|
# 7. /sets/{set_code}
|
|
# 8. /statistics
|
|
|
|
# New order (correct):
|
|
# 1. /search
|
|
# 2. /set/{set_code}
|
|
# 3. /types
|
|
# 4. /rarities
|
|
# 5. /sets
|
|
# 6. /sets/{set_code}
|
|
# 7. /statistics
|
|
# 8. /{card_name} (wildcard last)
|
|
|
|
# Extract route blocks using regex
|
|
# Pattern to find decorator + function
|
|
pattern = r'(@router\.\w+\([^)]+\)\s*\nasync def \w+.*?)(?=@router\.\w+\(|$)'
|
|
|
|
matches = re.findall(pattern, content, re.DOTALL)
|
|
|
|
# Identify each route
|
|
routes = {}
|
|
for match in matches:
|
|
# Extract route path
|
|
route_match = re.search(r'@router\.(\w+)\(([^)]+)\)', match)
|
|
if route_match:
|
|
method = route_match.group(1)
|
|
args = route_match.group(2)
|
|
routes[f"{method}:{args}"] = match
|
|
|
|
print("Current routes:")
|
|
for key in routes:
|
|
print(f" {key}")
|
|
|
|
# Define the correct order
|
|
correct_order = [
|
|
"get:/search",
|
|
"get:/set/{set_code}",
|
|
"get:/types",
|
|
"get:/rarities",
|
|
"get:/sets",
|
|
"get:/sets/{set_code}",
|
|
"get:/statistics",
|
|
"get:/{card_name}",
|
|
]
|
|
|
|
# Verify all routes are present
|
|
for route_key in correct_order:
|
|
if route_key not in routes:
|
|
print(f"✗ Missing route: {route_key}")
|
|
return False
|
|
|
|
print("✓ All routes found")
|
|
|
|
# Rebuild the file content
|
|
new_content = content[:content.index('@router.get("/search")')]
|
|
|
|
for route_key in correct_order:
|
|
new_content += routes[route_key]
|
|
|
|
# Add the router variable
|
|
new_content += "\n\nrouter = APIRouter(prefix=\"/mtg/cards\", tags=[\"MTG Cards\"])\n"
|
|
|
|
route_file.write_text(new_content)
|
|
print("✓ Routes reordered")
|
|
|
|
|
|
def update_mtg_set_model():
|
|
"""Update MtgSet model to include image_url."""
|
|
model_file = Path('/home/wall-o/projects/mtgonline/backend/app/models/mtg_models.py')
|
|
content = model_file.read_text()
|
|
|
|
# Add image_url column after mtgo_code
|
|
if 'image_url' in content:
|
|
print("✓ image_url already in MtgSet model")
|
|
return
|
|
|
|
# Find the Mtgo_code line
|
|
insert_point = "mtgo_code = Column(String(10), nullable=True)"
|
|
new_column = '\n image_url = Column(Text, nullable=True)'
|
|
|
|
content = content.replace(insert_point, insert_point + new_column)
|
|
model_file.write_text(content)
|
|
print("✓ image_url added to MtgSet model")
|
|
|
|
|
|
def update_service_layer():
|
|
"""Update service layer to return image_url."""
|
|
service_file = Path('/home/wall-o/projects/mtgonline/backend/app/services/card_database.py')
|
|
content = service_file.read_text()
|
|
|
|
if 'image_url' not in content:
|
|
# Update get_sets() function
|
|
old_get_sets = ''' stmt = select(MtgSet).order_by(MtgSet.release_date.desc())
|
|
result = await db.execute(stmt)
|
|
rows = result.fetchall()
|
|
|
|
return [
|
|
{
|
|
"id": s.id,
|
|
"code": s.code,
|
|
"name": s.name,
|
|
"release_date": s.release_date.isoformat() if s.release_date else None,
|
|
"total_size": s.total_size,
|
|
"base_set_size": s.base_set_size,
|
|
}
|
|
for s in rows
|
|
]'''
|
|
|
|
new_get_sets = ''' stmt = select(MtgSet).order_by(MtgSet.release_date.desc())
|
|
result = await db.execute(stmt)
|
|
rows = result.fetchall()
|
|
|
|
return [
|
|
{
|
|
"id": s.id,
|
|
"code": s.code,
|
|
"name": s.name,
|
|
"release_date": s.release_date.isoformat() if s.release_date else None,
|
|
"total_size": s.total_size,
|
|
"base_set_size": s.base_set_size,
|
|
"image_url": s.image_url,
|
|
}
|
|
for s in rows
|
|
]'''
|
|
|
|
if old_get_sets in content:
|
|
content = content.replace(old_get_sets, new_get_sets)
|
|
print("✓ Updated get_sets() to include image_url")
|
|
|
|
# Update get_set_by_code() function
|
|
old_get_by_code = ''' return {
|
|
"id": mtg_set.id,
|
|
"code": mtg_set.code,
|
|
"name": mtg_set.name,
|
|
"type": mtg_set.type,
|
|
"release_date": mtg_set.release_date.isoformat() if mtg_set.release_date else None,
|
|
"base_set_size": mtg_set.base_set_size,
|
|
"total_size": mtg_set.total_size,
|
|
"is_foil_only": mtg_set.is_foil_only,
|
|
"is_non_foil_only": mtg_set.is_non_foil_only,
|
|
"digital": mtg_set.digital,
|
|
"icon_svg_url": mtg_set.icon_svg_url,
|
|
"parent_code": mtg_set.parent_code,
|
|
"mtgo_code": mtg_set.mtgo_code,
|
|
}'''
|
|
|
|
new_get_by_code = ''' return {
|
|
"id": mtg_set.id,
|
|
"code": mtg_set.code,
|
|
"name": mtg_set.name,
|
|
"type": mtg_set.type,
|
|
"release_date": mtg_set.release_date.isoformat() if mtg_set.release_date else None,
|
|
"base_set_size": mtg_set.base_set_size,
|
|
"total_size": mtg_set.total_size,
|
|
"is_foil_only": mtg_set.is_foil_only,
|
|
"is_non_foil_only": mtg_set.is_non_foil_only,
|
|
"digital": mtg_set.digital,
|
|
"icon_svg_url": mtg_set.icon_svg_url,
|
|
"parent_code": mtg_set.parent_code,
|
|
"mtgo_code": mtg_set.mtgo_code,
|
|
"image_url": mtg_set.image_url,
|
|
}'''
|
|
|
|
if old_get_by_code in content:
|
|
content = content.replace(old_get_by_code, new_get_by_code)
|
|
print("✓ Updated get_set_by_code() to include image_url")
|
|
|
|
service_file.write_text(content)
|
|
|
|
|
|
def main():
|
|
"""Run all file-based fixes."""
|
|
print("=== MTG SETS ENDPOINT FIX (FILE CHANGES) ===\n")
|
|
|
|
# 1. Fix route ordering
|
|
print("1. Route Reordering")
|
|
fix_route_ordering()
|
|
print()
|
|
|
|
# 2. Update model
|
|
print("2. Model Update")
|
|
update_mtg_set_model()
|
|
print()
|
|
|
|
# 3. Update service layer
|
|
print("3. Service Layer Update")
|
|
update_service_layer()
|
|
print()
|
|
|
|
print("=== FILE CHANGES COMPLETE ===")
|
|
print("\nNext steps:")
|
|
print("1. Add image_url column to mtg_sets table in database")
|
|
print("2. Restart the backend Docker container")
|
|
print("3. Test /api/mtg/cards/sets endpoint")
|
|
print("4. Run refresh_mtg.py to populate image_url data")
|
|
print("5. Test /api/mtg/cards/sets/{set_code} endpoint")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|