Files
holy-flavor-rater/backend/api/management/commands/seed_legacy_flavors.py
T
2026-04-11 10:37:49 +02:00

170 lines
6.5 KiB
Python

import json
import os
import requests
from django.conf import settings
from django.core.management.base import BaseCommand
from django.utils.text import slugify
from api.models import Category, Flavor
class Command(BaseCommand):
help = "Adds legacy flavors from JSON files in the legacy/ folder"
def download_image(self, url, flavor_name):
if not url:
return None
try:
safe_name = slugify(flavor_name)
ext = url.split(".")[-1].split("?")[0].lower()
if ext not in ["jpg", "jpeg", "png", "webp", "gif"]:
ext = "png"
filename = f"legacy_{safe_name}.{ext}"
filepath = os.path.join(settings.MEDIA_ROOT, "flavors", filename)
os.makedirs(os.path.dirname(filepath), exist_ok=True)
response = requests.get(url, headers={"User-Agent": "Mozilla/5.0"}, timeout=10)
response.raise_for_status()
if os.path.exists(filepath):
os.remove(filepath)
with open(filepath, "wb") as f:
f.write(response.content)
return f"flavors/{filename}"
except Exception as e:
self.stdout.write(
self.style.WARNING(f"Failed to download image for {flavor_name}: {e}")
)
return None
def handle(self, *args, **options):
# We no longer delete everything to preserve user data like ratings
# Instead, we update existing entries.
cat_map = {
"energy": Category.objects.get_or_create(name="Energy", defaults={"slug": "energy"})[0],
"hydration": Category.objects.get_or_create(
name="Hydration", defaults={"slug": "hydration"}
)[0],
"iced-tea": Category.objects.get_or_create(
name="Iced Tea", defaults={"slug": "iced-tea"}
)[0],
"milkshake": Category.objects.get_or_create(
name="Milkshake", defaults={"slug": "milkshake"}
)[0],
"packs": Category.objects.get_or_create(
name="Packs and other", defaults={"slug": "packs-and-other"}
)[0],
}
legacy_dir = os.path.join(settings.BASE_DIR, "legacy")
if not os.path.exists(legacy_dir):
legacy_dir = os.path.join(settings.BASE_DIR, "..", "legacy")
if not os.path.exists(legacy_dir):
self.stdout.write(self.style.ERROR("Legacy directory not found."))
return
json_files = [f for f in os.listdir(legacy_dir) if f.endswith(".json")]
processed_count = 0
for json_file in json_files:
file_path = os.path.join(legacy_dir, json_file)
file_lower = json_file.lower()
# Determine category from filename
if "energy" in file_lower:
file_cat = cat_map["energy"]
elif "iced_tea" in file_lower or "iced-tea" in file_lower:
file_cat = cat_map["iced-tea"]
elif "hydration" in file_lower:
file_cat = cat_map["hydration"]
elif "milkshake" in file_lower:
file_cat = cat_map["milkshake"]
else:
file_cat = None
with open(file_path, encoding="utf-8") as f:
data_list = json.load(f)
for data in data_list:
name = data.get("Name")
desc = data.get("Beschreibung")
taste = data.get("Geschmack")
status_text = data.get("Status")
image_url = data.get("Bild_URL")
full_desc = f"**Geschmack:** {taste}\n\n{desc}\n\n**Status:** {status_text}"
# Determine final category
cat = file_cat
if not cat:
# Fallback to name/desc detection if filename was ambiguous
if "hydration" in name.lower() or "hydration" in desc.lower():
cat = cat_map["hydration"]
elif "iced tea" in name.lower() or "eistee" in name.lower():
cat = cat_map["iced-tea"]
elif "milkshake" in name.lower():
cat = cat_map["milkshake"]
elif any(
k in name.lower()
for k in [
"bundle",
"set",
"box",
"probe",
"sample",
"taster",
"shaker",
"starter",
]
):
cat = cat_map["packs"]
else:
cat = cat_map["energy"] # Ultimate fallback
# Try to find existing flavor by name and category regardless of legacy status
flavor = Flavor.objects.filter(name__iexact=name, category=cat).first()
# If it exists and is an active Shopify product, skip legacy processing
if flavor and not flavor.is_legacy:
self.stdout.write(f"Skipping active flavor: {name}")
continue
if not flavor:
flavor = Flavor(name=name, category=cat, is_legacy=True, external_id=None)
self.stdout.write(f"Adding new legacy flavor: {name}")
else:
self.stdout.write(f"Updating legacy flavor: {name}")
flavor.description = full_desc
flavor.is_available = False # Legacy is always unavailable via API
if image_url:
# Check if local file exists
file_exists = False
if flavor.image:
abs_path = os.path.join(settings.MEDIA_ROOT, flavor.image.name)
if os.path.exists(abs_path):
file_exists = True
# Download if missing OR if image_url changed
if not file_exists or flavor.image_url != image_url:
rel_path = self.download_image(image_url, name)
if rel_path:
flavor.image = rel_path
self.stdout.write(f" -> Updated image for: {name}")
flavor.image_url = image_url
flavor.save()
processed_count += 1
self.stdout.write(
self.style.SUCCESS(f"Finished! Processed {processed_count} legacy flavors.")
)