aee0f09db8
- Datafabrik: Dockerfile fix, agentorkestrering fungerar - Vision: Identify-modell, FAISS, OCR alla testade - API: Alla 7 integrationstester passerade - Upplösare: Entitetsupplösning verifierad
199 lines
7.6 KiB
Python
199 lines
7.6 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
quiXzoom Academy — Bildgenerator via AAMOS
|
|
Använder AAMOS video-pipeline DALL-E integration
|
|
"""
|
|
|
|
import requests
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
|
|
# AAMOS API-konfiguration
|
|
AAMOS_BASE = "http://localhost:3100"
|
|
SVEN_KEY = "sven-aamos-integration-2026-wavult"
|
|
|
|
# Bilder att generera
|
|
IMAGES = {
|
|
"m1l1": {
|
|
"title": "Välkommen till quiXzoom",
|
|
"prompt": "A friendly illustration of a person with a smartphone photographing a bridge at sunset. Modern, clean style with blue (#0066FF) and green (#00C853) colors. Pedagogical feel, not photorealistic. 16:9 format. The person looks happy and professional. Warm lighting."
|
|
},
|
|
"m2l1": {
|
|
"title": "AI-granskning av bilder",
|
|
"prompt": "A technical illustration showing AI analysis of a photograph. Split image: left side shows original photo of a bridge, right side shows AI analysis overlay with color-coded indicators marking sharpness, lighting, and composition. Futuristic but pedagogical style."
|
|
},
|
|
"m2l2": {
|
|
"title": "Ljus och exponering",
|
|
"prompt": "Three photos in a row showing the same bridge from the same angle: 1. Left: Underexposed (too dark, details lost), 2. Middle: Perfectly exposed (golden hour, warm light, all details visible), 3. Right: Overexposed (too bright, washed out). Photorealistic style. Educational comparison."
|
|
},
|
|
"m2l3": {
|
|
"title": "Fokus och skärpa",
|
|
"prompt": "Two photos showing a road sign: left image is blurry and out of focus, right image is razor sharp with a magnifying glass effect showing crisp details. Photorealistic with graphic overlay elements. Educational comparison style."
|
|
},
|
|
"m2l4": {
|
|
"title": "Framing och komposition",
|
|
"prompt": "A bridge photographed with correct composition. Overlay showing rule of thirds grid lines, arrow pointing to main subject, green markings indicating good composition. Educational diagram style with photo-realistic base. Clean and modern."
|
|
},
|
|
"m3l1": {
|
|
"title": "GPS-accuracy",
|
|
"prompt": "A technical illustration of a city map from above with a smartphone in the center. 4 GPS satellites above sending signals to the phone. Color-coded accuracy circles around the phone: green (accurate, small circle), yellow (medium), red (low accuracy, large circle). Modern, clean style."
|
|
},
|
|
"m4l1": {
|
|
"title": "Personlig säkerhet",
|
|
"prompt": "A person wearing a reflective safety vest and holding a smartphone, photographing a bridge from a safe distance. Traffic cone, safety distance marked with dashed lines, passing car in background. Modern, friendly illustration style. Blue and orange accents."
|
|
},
|
|
"m5l1": {
|
|
"title": "Batch-fotografering",
|
|
"prompt": "A stylized map illustration with multiple photo points (A, B, C, D, E) connected by an optimized green route. A person with smartphone efficiently following the route. Modern map style with blue and green colors. Clean and pedagogical."
|
|
},
|
|
"m6l1": {
|
|
"title": "Utbetalningsflöde",
|
|
"prompt": "A horizontal flow diagram showing: 1. Approved photo (green checkmark) → 2. AI review (robot icon) → 3. Approval (stamp) → 4. Payment (money/bank icon) → 5. Money in account (happy person). Modern, clean illustration with icons and arrows. Green and blue colors."
|
|
}
|
|
}
|
|
|
|
def generate_via_aamos(image_id: str, prompt: str) -> str:
|
|
"""Generera bild via AAMOS video-pipeline"""
|
|
|
|
url = f"{AAMOS_BASE}/api/aamos/video-pipeline/thumbnail/generate"
|
|
|
|
headers = {
|
|
"Content-Type": "application/json",
|
|
"x-sven-key": SVEN_KEY
|
|
}
|
|
|
|
payload = {
|
|
"videoId": f"academy-{image_id}",
|
|
"imagePrompt": prompt,
|
|
"size": "1792x1024"
|
|
}
|
|
|
|
try:
|
|
response = requests.post(url, headers=headers, json=payload, timeout=60)
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
if data.get('imageUrl'):
|
|
return data['imageUrl']
|
|
else:
|
|
print(f" ⚠️ Ingen bild-URL i svaret: {data.get('error', 'Okänt fel')}")
|
|
return None
|
|
else:
|
|
print(f" ⚠️ AAMOS fel: {response.status_code}")
|
|
print(f" {response.text[:200]}")
|
|
return None
|
|
|
|
except Exception as e:
|
|
print(f" ⚠️ Fel: {e}")
|
|
return None
|
|
|
|
def download_image(url: str, filename: str) -> bool:
|
|
"""Ladda ner bild från URL"""
|
|
|
|
try:
|
|
response = requests.get(url, timeout=30)
|
|
|
|
if response.status_code == 200:
|
|
with open(filename, 'wb') as f:
|
|
f.write(response.content)
|
|
return True
|
|
else:
|
|
print(f" ❌ Kunde inte ladda ner: {response.status_code}")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f" ❌ Fel: {e}")
|
|
return False
|
|
|
|
def upload_to_s3(local_path: str, s3_key: str) -> str:
|
|
"""Ladda upp till S3"""
|
|
|
|
import subprocess
|
|
|
|
cmd = [
|
|
"aws", "s3", "cp", local_path,
|
|
f"s3://quixzoom-landing-prod/{s3_key}",
|
|
"--acl", "public-read",
|
|
"--content-type", "image/png"
|
|
]
|
|
|
|
result = subprocess.run(cmd, capture_output=True, text=True)
|
|
|
|
if result.returncode == 0:
|
|
url = f"https://quixzoom-landing-prod.s3.eu-north-1.amazonaws.com/{s3_key}"
|
|
print(f" ✅ Uppladdad: {url}")
|
|
return url
|
|
else:
|
|
print(f" ❌ S3-fel: {result.stderr}")
|
|
return None
|
|
|
|
def generate_all_images():
|
|
"""Generera alla bilder"""
|
|
|
|
print("🎨 quiXzoom Academy — Bildgenerator via AAMOS")
|
|
print("=" * 60)
|
|
|
|
output_dir = Path("academy-images-final")
|
|
output_dir.mkdir(exist_ok=True)
|
|
|
|
results = []
|
|
|
|
for image_id, image_data in IMAGES.items():
|
|
print(f"\n📚 {image_data['title']}")
|
|
|
|
# Generera via AAMOS
|
|
image_url = generate_via_aamos(image_id, image_data['prompt'])
|
|
|
|
if image_url:
|
|
print(f" ✅ Bild genererad")
|
|
print(f" 📥 Laddar ner...")
|
|
|
|
local_path = output_dir / f"{image_id}.png"
|
|
|
|
if download_image(image_url, str(local_path)):
|
|
print(f" ✅ Sparad")
|
|
|
|
# Ladda upp till S3
|
|
s3_key = f"academy/images/{image_id}.png"
|
|
s3_url = upload_to_s3(str(local_path), s3_key)
|
|
|
|
if s3_url:
|
|
results.append({
|
|
"id": image_id,
|
|
"title": image_data['title'],
|
|
"url": s3_url
|
|
})
|
|
else:
|
|
print(f" ❌ Kunde inte generera")
|
|
|
|
print(f"\n{'=' * 60}")
|
|
print(f"✅ {len(results)}/{len(IMAGES)} bilder genererade")
|
|
|
|
return results
|
|
|
|
if __name__ == "__main__":
|
|
import sys
|
|
|
|
if len(sys.argv) > 1 and sys.argv[1] == "--generate":
|
|
generate_all_images()
|
|
else:
|
|
print("Användning:")
|
|
print(" python generate-academy-images-aamos.py --generate")
|
|
print("")
|
|
print("Detta kommer att:")
|
|
print(" 1. Ansluta till AAMOS video-pipeline API")
|
|
print(" 2. Generera 9 pedagogiska bilder med DALL-E")
|
|
print(" 3. Ladda upp till S3")
|
|
print("")
|
|
print("Testar anslutning...")
|
|
|
|
try:
|
|
r = requests.get(f"{AAMOS_BASE}/health", timeout=5)
|
|
if r.status_code == 200:
|
|
print("✅ AAMOS är tillgänglig!")
|
|
else:
|
|
print(f"⚠️ AAMOS svarade: {r.status_code}")
|
|
except:
|
|
print("❌ Kunde inte ansluta till AAMOS")
|