ifixkart-backend/index_media.py

166 lines
6.5 KiB
Python

import os
import sys
import uuid
import pymysql
import re
import ulid
import zipfile
import hashlib
from pathlib import Path
# Load env variables before importing app modules
env_path = "/var/www/fastapi/ifixkart/.env"
if os.path.exists(env_path):
with open(env_path, 'r') as f:
for line in f:
line = line.strip()
if line and not line.startswith('#') and '=' in line:
k, v = line.split('=', 1)
os.environ[k.strip()] = v.strip().strip("'").strip('"')
os.environ.setdefault("SECRET_KEY", "b39f1c7d2e8a4059a1e048f39572b810d7a64115e62c1490b6338fa82110c79e")
os.environ.setdefault("PUBLIC_API_KEY", "ifixkart-public-api-key-2026-secret-v1")
sys.path.insert(0, "/var/www/fastapi/ifixkart")
from app.services.migration_engine.media_resolver import MediaResolver
from app.services.migration_engine.storage_manager import StorageManager
conn = pymysql.connect(unix_socket='/var/run/mysqld/mysqld.sock', user='root', password='', database='ifixkartecommerce', autocommit=False)
cur = conn.cursor()
zip_path = "/var/www/html/DATASET/stress_L5_EXTREME_20260901_210610_media.zip"
if not os.path.exists(zip_path):
zip_path = "/mnt/fam/SERVER/IfixKartEcommerce/DATASET/stress_L5_EXTREME_20260901_210610_media.zip"
print(f"=== Extracting & Indexing Media Archive: {zip_path} ===")
extract_dir = "/var/www/fastapi/ifixkart/uploads/migrations/extreme_media_extract"
os.makedirs(extract_dir, exist_ok=True)
media_groups_dict, media_files_list = MediaResolver.process_zip_archive(zip_path, extract_dir)
print(f"Discovered {len(media_groups_dict)} media groups and {len(media_files_list)} media assets in archive.")
job_id = "extreme-stress-test-job"
job_dir = StorageManager.get_job_dir(job_id)
# Clear previous test data in media_groups & media_library if any
cur.execute("DELETE FROM media_library")
cur.execute("DELETE FROM media_groups")
media_group_id_map = {}
for m_key, m_info in media_groups_dict.items():
mg_id = str(ulid.ULID())
media_group_id_map[m_key] = mg_id
cur.execute(
"INSERT INTO media_groups (id, media_key, brand_name, model_name, variant_tag, source_type) VALUES (%s, %s, %s, %s, %s, %s)",
(mg_id, m_key, m_info.get("brand_name"), m_info.get("model_name"), m_info.get("variant_tag"), m_info.get("source_type", "FOLDER_PATH"))
)
asset_urls_by_key = {}
for asset in media_files_list:
m_key = asset.get("media_key")
mg_id = media_group_id_map.get(m_key)
if not mg_id:
continue
src_path = asset.get("local_path")
orig_name = asset.get("original_filename") or os.path.basename(src_path)
sha256 = asset.get("sha256_checksum")
with open(src_path, "rb") as f:
file_bytes = f.read()
storage_path, cdn_url, width, height = StorageManager.write_media_file_atomically(job_id, file_bytes, orig_name, sha256)
asset_id = str(ulid.ULID())
cur.execute(
"INSERT INTO media_library (id, media_group_id, original_filename, stored_filename, mime_type, file_size_bytes, width, height, sha256_checksum, cdn_url, thumbnail_url, storage_path) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",
(asset_id, mg_id, orig_name, os.path.basename(storage_path), asset.get("mime_type", "image/png"), len(file_bytes), width, height, sha256, cdn_url, cdn_url, storage_path)
)
if m_key not in asset_urls_by_key:
asset_urls_by_key[m_key] = []
asset_urls_by_key[m_key].append(cdn_url)
conn.commit()
print(f"=== Successfully Indexed {len(asset_urls_by_key)} Media Groups into Database ===")
print("=== Linking Media Assets to Products and Variants ===")
cur.execute("""
SELECT p.product_id, p.name, p.slug, b.slug as brand_slug, c.slug as category_slug
FROM products p
LEFT JOIN brands b ON p.brand_id = b.brand_id
LEFT JOIN categories c ON p.category_id = c.category_id
""")
products = cur.fetchall()
def canonicalize(s):
if not s: return ""
return re.sub(r'-+', '-', re.sub(r'[\s_/\\]+', '-', str(s).strip().lower())).strip('-')
prod_linked = 0
var_linked = 0
for product_id, name, slug, brand_slug, category_slug in products:
cur.execute("SELECT variant_id FROM product_variants WHERE product_id = %s", (product_id,))
variants = [r[0] for r in cur.fetchall()]
prod_urls = []
for v_id in variants:
cur.execute("""
SELECT va.attribute_value
FROM variant_attributes va
JOIN attribute_types at ON va.attribute_id = at.attribute_id
WHERE va.variant_id = %s AND (at.code = 'color' OR at.name = 'Color')
LIMIT 1
""", (v_id,))
color_row = cur.fetchone()
color_val = color_row[0] if color_row else ""
candidates = []
if brand_slug and category_slug and color_val:
candidates.append(f"{brand_slug}-{category_slug}-{canonicalize(color_val)}")
if brand_slug and category_slug:
candidates.append(f"{brand_slug}-{category_slug}")
candidates.append(canonicalize(slug))
candidates.append(canonicalize(name))
matched = None
for k in candidates:
if k and k in asset_urls_by_key:
matched = asset_urls_by_key[k]
break
if not matched and brand_slug and category_slug:
prefix = f"{brand_slug}-{category_slug}"
for k, urls in asset_urls_by_key.items():
if k.startswith(prefix):
matched = urls
break
if matched:
cur.execute("DELETE FROM variant_images WHERE variant_id = %s", (v_id,))
for idx, url in enumerate(matched):
vi_id = str(ulid.ULID())
cur.execute(
"INSERT INTO variant_images (image_id, variant_id, image_url, sort_order, is_primary) VALUES (%s, %s, %s, %s, %s)",
(vi_id, v_id, url, idx, idx == 0)
)
var_linked += 1
if not prod_urls:
prod_urls = matched
if prod_urls:
cur.execute("DELETE FROM product_images WHERE product_id = %s", (product_id,))
for idx, url in enumerate(prod_urls):
pi_id = str(ulid.ULID())
cur.execute(
"INSERT INTO product_images (image_id, product_id, image_url, alt_text, sort_order, is_banner) VALUES (%s, %s, %s, %s, %s, %s)",
(pi_id, product_id, url, f"{name} Image {idx+1}", idx, idx == 0)
)
prod_linked += 1
conn.commit()
print(f"=== Linked images to {prod_linked} products and {var_linked} variants ===")
conn.close()