Spaces:
Runtime error
Runtime error
| import os | |
| import time | |
| import numpy as np | |
| from datetime import datetime, timezone | |
| from supabase import create_client, Client | |
| # ======================================== | |
| # π Supabase Setup | |
| # ======================================== | |
| SUPABASE_URL = os.getenv("SUPABASE_URL") | |
| SUPABASE_KEY = os.getenv("SUPABASE_KEY") | |
| supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY) | |
| # ======================================== | |
| # π Helper Functions | |
| # ======================================== | |
| def fetch_user_activity(user_id): | |
| response = supabase.table("user_activity") \ | |
| .select("*") \ | |
| .eq("actor_user_id", user_id) \ | |
| .execute() | |
| return response.data | |
| def fetch_safe_content(): | |
| # ================= POSTS ================= | |
| posts = supabase.table("posts").select("id, caption").execute().data | |
| moderated_posts = supabase.table("content_moderation") \ | |
| .select("post_id, result") \ | |
| .eq("post_type", "post") \ | |
| .execute().data | |
| safe_posts = {p["post_id"] for p in moderated_posts if p["result"] == "safe"} | |
| safe_post_ids = [ | |
| p["id"] for p in posts | |
| if (p["id"] in safe_posts) or | |
| (p["id"] not in [m["post_id"] for m in moderated_posts]) | |
| ] | |
| # ================= TRENDZ ================= | |
| trendz = supabase.table("trendz").select("id, caption").execute().data | |
| moderated_trendz = supabase.table("content_moderation") \ | |
| .select("post_id, result") \ | |
| .eq("post_type", "trendz") \ | |
| .execute().data | |
| safe_trendz = {t["post_id"] for t in moderated_trendz if t["result"] == "safe"} | |
| safe_trendz_ids = [ | |
| t["id"] for t in trendz | |
| if (t["id"] in safe_trendz) or | |
| (t["id"] not in [m["post_id"] for m in moderated_trendz]) | |
| ] | |
| return safe_post_ids, safe_trendz_ids, posts, trendz | |
| def recommend(user_id, top_n=5): | |
| activities = fetch_user_activity(user_id) | |
| safe_post_ids, safe_trendz_ids, posts, trendz = fetch_safe_content() | |
| summaries = [a["content_summary"] for a in activities if a.get("content_summary")] | |
| # Extract keywords | |
| keywords = [] | |
| for summary in summaries: | |
| keywords.extend(summary.lower().split()) | |
| # ================= POSTS ================= | |
| post_scores = {} | |
| for p in posts: | |
| if p["id"] in safe_post_ids: | |
| caption = (p.get("caption") or "").lower() | |
| score = sum(caption.count(word) for word in keywords) | |
| post_scores[p["id"]] = score | |
| # ================= TRENDZ ================= | |
| trendz_scores = {} | |
| for t in trendz: | |
| if t["id"] in safe_trendz_ids: | |
| caption = (t.get("caption") or "").lower() | |
| score = sum(caption.count(word) for word in keywords) | |
| trendz_scores[t["id"]] = score | |
| # Sort | |
| recommended_posts = [ | |
| pid for pid, _ in sorted(post_scores.items(), key=lambda x: x[1], reverse=True)[:top_n] | |
| ] | |
| recommended_trendz = [ | |
| tid for tid, _ in sorted(trendz_scores.items(), key=lambda x: x[1], reverse=True)[:top_n] | |
| ] | |
| # ================= FALLBACK ================= | |
| if not recommended_posts and safe_post_ids: | |
| recommended_posts = list( | |
| np.random.choice(safe_post_ids, min(top_n, len(safe_post_ids)), replace=False) | |
| ) | |
| if not recommended_trendz and safe_trendz_ids: | |
| recommended_trendz = list( | |
| np.random.choice(safe_trendz_ids, min(top_n, len(safe_trendz_ids)), replace=False) | |
| ) | |
| return recommended_posts, recommended_trendz | |
| def store_recommendations(user_id, posts, trendz): | |
| now = datetime.now(timezone.utc).isoformat() | |
| supabase.table("user_recommendations").upsert({ | |
| "user_id": user_id, | |
| "recommended_post_ids": posts, | |
| "recommended_trendz_ids": trendz, | |
| "generated_at": now | |
| }).execute() | |
| # ======================================== | |
| # π BACKGROUND WORKER (EVERY 10 MIN) | |
| # ======================================== | |
| def recommendation_worker(): | |
| while True: | |
| try: | |
| print("\nπ Running recommendation job...") | |
| users = supabase.table("profiles") \ | |
| .select("id") \ | |
| .limit(20) \ | |
| .execute().data | |
| for u in users: | |
| posts, trendz = recommend(u["id"]) | |
| store_recommendations(u["id"], posts, trendz) | |
| print(f"β Updated user {u['id']}") | |
| except Exception as e: | |
| print("β Worker error:", e) | |
| print("β³ Sleeping for 10 minutes...\n") | |
| time.sleep(600) | |
| # ======================================== | |
| # βΆοΈ AUTO START | |
| # ======================================== | |
| if __name__ == "__main__": | |
| print("π₯ Starting AI Recommendation Worker...") | |
| recommendation_worker() |