import asyncio import asyncpg import urllib.request import json DB_URL = "postgresql://teeoff_admin:teeoff_secret_password@db:5432/teeoff" async def fetch_json(url): """Hjelpefunksjon for å hente JSON fra en URL""" try: req = urllib.request.Request(url, headers={'User-Agent': 'TeeOff-Migrator/2.0'}) with urllib.request.urlopen(req) as response: return json.loads(response.read().decode()) except Exception as e: # print(f"⚠️ Kunne ikke hente {url}: {e}") return None async def fetch_media_urls_by_ids(media_ids): """Henter URLer for en liste med media-IDer (ACF Slides)""" if not media_ids or not isinstance(media_ids, list) or len(media_ids) == 0: return [] valid_ids = [str(mid) for mid in media_ids if isinstance(mid, (int, str)) and str(mid).isdigit()] if not valid_ids: return [] ids_str = ",".join(valid_ids) url = f"https://teeoff.no/wp-json/wp/v2/media?include={ids_str}" data = await fetch_json(url) urls = [] if data: for m in data: if 'source_url' in m: urls.append(m['source_url']) return urls async def run_robust_import(): print("🕵️‍♂️ Starter den store bildejakten (sjekker både Utvalgt bilde og Slides)...") conn = await asyncpg.connect(DB_URL) # VIKTIG: Vi tømmer tabellen for å starte med blanke ark og unngå duplikater await conn.execute("TRUNCATE facility_images CASCADE;") print("🗑️ Tømte gammel bilde-tabell. Starter import...") # Hent alle anleggene fra vår egen database facilities = await conn.fetch("SELECT id, slug, name FROM facilities ORDER BY name") total_images_saved = 0 for i, fac in enumerate(facilities): fac_id = fac['id'] slug = fac['slug'] name = fac['name'] print(f"[{i+1}/{len(facilities)}] Sjekker: {name} ({slug})...") # Hent data fra WP med ?_embed for å få tak i Utvalgt bilde lett wp_url = f"https://teeoff.no/wp-json/wp/v2/golfbaner?slug={slug}&_embed" wp_data_list = await fetch_json(wp_url) if not wp_data_list: print(" ❌ Fant ikke anlegget i WordPress API.") continue post = wp_data_list[0] final_image_urls = [] # 1. SJEKK: "Utvalgt bilde" (Standard WordPress) try: embedded = post.get('_embedded', {}) if 'wp:featuredmedia' in embedded and len(embedded['wp:featuredmedia']) > 0: feat_media = embedded['wp:featuredmedia'][0] feat_url = feat_media.get('source_url') if feat_url: final_image_urls.append(feat_url) # print(f" -> Fant utvalgt bilde.") except Exception as e: print(f" ⚠️ Feil ved sjekk av utvalgt bilde: {e}") # 2. SJEKK: ACF Slides (Bildekarusell) try: acf = post.get('acf') or {} slides_ids = acf.get('slides') slide_urls = await fetch_media_urls_by_ids(slides_ids) if slide_urls: final_image_urls.extend(slide_urls) # print(f" -> Fant {len(slide_urls)} bilder i slider.") except Exception as e: print(f" ⚠️ Feil ved sjekk av slides: {e}") # Fjern duplikater (hvis samme bilde er brukt begge steder) og bevar rekkefølgen unique_urls = list(dict.fromkeys(final_image_urls)) # LAGRE I DATABASEN if unique_urls: sort_order = 0 for url in unique_urls: await conn.execute( "INSERT INTO facility_images (facility_id, image_url, sort_order) VALUES ($1, $2, $3)", fac_id, url, sort_order ) sort_order += 1 print(f" ✅ Lagret {len(unique_urls)} unike bilder.") total_images_saved += len(unique_urls) else: print(" ⚠️ Fant INGEN bilder for dette anlegget.") print(f"\n🎉 FERDIG! Totalt {total_images_saved} bilder er nå trygt lagret i galleriet.") await conn.close() if __name__ == "__main__": asyncio.run(run_robust_import())