Spaces:
Runtime error
Runtime error
| """ | |
| Ethereal Wisdom PRO — Monetized AI Wisdom Platform | |
| Free: 3 wisdom generations/day, ads shown, basic features | |
| Premium ($7.99/mo): Unlimited, no ads, collections, daily digest, shareable cards | |
| """ | |
| import gradio as gr | |
| import os | |
| import json | |
| import hashlib | |
| from datetime import datetime | |
| import requests | |
| import re | |
| # ============ CONFIG ============ | |
| FREE_DAILY_LIMIT = 3 | |
| PREMIUM_PRICE = "$7.99/month" | |
| STRIPE_LINK = os.environ.get("STRIPE_PAYMENT_LINK", "https://buy.stripe.com/YOUR_LINK") | |
| ADSENSE_CLIENT = os.environ.get("ADSENSE_CLIENT", "ca-pub-YOUR_ID") | |
| ADMIN_CODE = os.environ.get("ADMIN_CODE", "ethereal2024") | |
| HF_TOKEN = os.environ.get("HF_TOKEN", "") | |
| WISDOM_TOPICS = [ | |
| "Life", "Love", "Success", "Failure", "Courage", "Wisdom", | |
| "Creativity", "Gratitude", "Mindfulness", "Leadership", | |
| "Happiness", "Resilience", "Purpose", "Freedom", "Growth" | |
| ] | |
| WISDOM_STYLES = [ | |
| "Stoic philosopher (Marcus Aurelius, Seneca)", | |
| "Eastern mystic (Lao Tzu, Buddha)", | |
| "Modern poet (Rumi, Kahlil Gibran)", | |
| "Tech visionary (Steve Jobs, Naval Ravikant)", | |
| "Ancient Greek (Socrates, Plato)", | |
| "Motivational speaker (Tony Robbins, Brene Brown)", | |
| "Zen master (Dogen, Thich Nhat Hanh)", | |
| "Entrepreneur (Elon Musk, Jeff Bezos)" | |
| ] | |
| # ============ USAGE TRACKING ============ | |
| USAGE_FILE = "/tmp/ethereal_usage.json" | |
| def load_usage(): | |
| try: | |
| with open(USAGE_FILE, 'r') as f: | |
| return json.load(f) | |
| except: | |
| return {} | |
| def save_usage(data): | |
| with open(USAGE_FILE, 'w') as f: | |
| json.dump(data, f) | |
| def get_user_id(request: gr.Request): | |
| try: | |
| if request is not None: | |
| client = getattr(request, 'client', None) | |
| ip = getattr(client, 'host', '0.0.0.0') if client else '0.0.0.0' | |
| headers = getattr(request, 'headers', {}) | |
| ua = headers.get("user-agent", "unknown") if headers else "unknown" | |
| else: | |
| ip = "0.0.0.0" | |
| ua = "unknown" | |
| return hashlib.md5(f"{ip}:{ua}".encode()).hexdigest()[:16] | |
| except Exception: | |
| return "anonymous" | |
| def check_usage(user_id: str): | |
| data = load_usage() | |
| today = datetime.now().strftime("%Y-%m-%d") | |
| if user_id not in data or data[user_id].get("date") != today: | |
| prev_premium = data.get(user_id, {}).get("premium", False) if user_id in data else False | |
| prev_fav = data.get(user_id, {}).get("favorites", []) if user_id in data else [] | |
| prev_hist = data.get(user_id, {}).get("history", []) if user_id in data else [] | |
| data[user_id] = {"count": 0, "date": today, "premium": prev_premium, | |
| "favorites": prev_fav, "history": prev_hist} | |
| return data[user_id] | |
| def increment_usage(user_id: str): | |
| data = load_usage() | |
| usage = check_usage(user_id) | |
| usage["count"] += 1 | |
| data[user_id] = usage | |
| save_usage(data) | |
| def add_favorite(user_id: str, quote: str, author: str, topic: str): | |
| data = load_usage() | |
| usage = check_usage(user_id) | |
| if "favorites" not in usage: | |
| usage["favorites"] = [] | |
| usage["favorites"].append({"quote": quote, "author": author, "topic": topic, "saved": datetime.now().isoformat()}) | |
| usage["favorites"] = usage["favorites"][-50:] | |
| data[user_id] = usage | |
| save_usage(data) | |
| def get_favorites(user_id: str): | |
| return check_usage(user_id).get("favorites", []) | |
| def add_history(user_id: str, prompt: str, quote: str): | |
| data = load_usage() | |
| usage = check_usage(user_id) | |
| if "history" not in usage: | |
| usage["history"] = [] | |
| usage["history"].append({"prompt": prompt, "quote": quote, "time": datetime.now().isoformat()}) | |
| usage["history"] = usage["history"][-20:] | |
| data[user_id] = usage | |
| save_usage(data) | |
| def set_premium(user_id: str, premium: bool = True): | |
| data = load_usage() | |
| if user_id not in data: | |
| data[user_id] = {"count": 0, "date": datetime.now().strftime("%Y-%m-%d"), "premium": premium, "favorites": [], "history": []} | |
| else: | |
| data[user_id]["premium"] = premium | |
| save_usage(data) | |
| # ============ AI WISDOM GENERATION ============ | |
| def generate_wisdom(topic, style, mood, length, request: gr.Request): | |
| user_id = get_user_id(request) | |
| usage = check_usage(user_id) | |
| if not usage.get("premium") and usage["count"] >= FREE_DAILY_LIMIT: | |
| return ( | |
| "", | |
| f"❌ **Daily Limit Reached** — You've used your {FREE_DAILY_LIMIT} free wisdom generations today.\n\n" | |
| f"🔓 **[Upgrade to Ethereal Wisdom Premium]({STRIPE_LINK})** for unlimited access!\n\n" | |
| f"**Premium includes:**\n" | |
| f"• Unlimited AI wisdom generations\n" | |
| f"• Beautiful shareable quote cards\n" | |
| f"• Personal collections & favorites\n" | |
| f"• Daily wisdom digest email\n" | |
| f"• No ads, priority speed\n\n" | |
| f"Only {PREMIUM_PRICE}" | |
| ) | |
| try: | |
| API_URL = "https://api-inference.huggingface.co/models/mistralai/Mistral-7B-Instruct-v0.2" | |
| headers = {"Authorization": f"Bearer {HF_TOKEN}"} | |
| length_map = {"Short (1 sentence)": 1, "Medium (2-3 sentences)": 2, "Long (paragraph)": 3} | |
| sentences = length_map.get(length, 2) | |
| prompt = f"""<s>[INST] You are a masterful wisdom generator. Write {sentences} profound, original wisdom quote about {topic.lower()} in the voice of a {style.lower()}. | |
| Mood: {mood.lower()} | |
| Requirements: | |
| - Original and unique (not a known quote) | |
| - Deeply insightful and thought-provoking | |
| - Beautiful, poetic language | |
| - No clichés or generic advice | |
| - Format: Quote text followed by "— Style Name" attribution | |
| Only output the quote and attribution. No extra text. [/INST]</s>""" | |
| max_tokens = 256 if usage.get("premium") else 128 | |
| payload = { | |
| "inputs": prompt, | |
| "parameters": { | |
| "max_new_tokens": max_tokens, | |
| "temperature": 0.8, | |
| "top_p": 0.9, | |
| "return_full_text": False | |
| } | |
| } | |
| response = requests.post(API_URL, headers=headers, json=payload, timeout=45) | |
| result = response.json() | |
| if isinstance(result, list) and len(result) > 0: | |
| text = result[0].get("generated_text", "").strip() | |
| else: | |
| text = str(result) | |
| # Clean up the output | |
| text = re.sub(r'</?s>\s*', '', text) | |
| text = re.sub(r'\[/?INST\]', '', text) | |
| text = text.strip() | |
| # If no attribution, add one | |
| if '—' not in text and '-' not in text[-30:]: | |
| style_name = style.split('(')[0].strip() if '(' in style else style | |
| text = f"{text}\n\n— {style_name}" | |
| # Extract quote and author | |
| parts = text.split('—') | |
| quote = parts[0].strip().strip('"').strip("'") | |
| author = parts[1].strip() if len(parts) > 1 else style.split('(')[0].strip() | |
| increment_usage(user_id) | |
| add_history(user_id, f"{topic}, {style}, {mood}", quote) | |
| remaining = "∞ Premium" if usage.get("premium") else f"{FREE_DAILY_LIMIT - usage['count'] - 1} left today" | |
| return ( | |
| f"**{quote}**\n\n— {author}", | |
| f"✨ Generated! {remaining}" | |
| ) | |
| except Exception as e: | |
| return "", f"⚠️ Error: {str(e)}. Please try again." | |
| # ============ DAILY WISDOM ============ | |
| def get_daily_wisdom(request: gr.Request): | |
| today = datetime.now().strftime("%A, %B %d") | |
| topics = ["Gratitude", "Mindfulness", "Courage", "Growth", "Wisdom", "Love", "Purpose"] | |
| topic = topics[datetime.now().weekday() % len(topics)] | |
| style = WISDOM_STYLES[datetime.now().day % len(WISDOM_STYLES)] | |
| quote, status = generate_wisdom(topic, style, "peaceful", "Medium (2-3 sentences)", request) | |
| return f"### ☀️ Daily Wisdom — {today}\n\n{quote}" | |
| # ============ COLLECTIONS ============ | |
| def show_collection(request: gr.Request): | |
| user_id = get_user_id(request) | |
| favs = get_favorites(user_id) | |
| if not favs: | |
| return "💫 Your collection is empty. Generate wisdom and click ❤️ to save!" | |
| result = "### 📚 Your Wisdom Collection\n\n" | |
| for i, f in enumerate(reversed(favs), 1): | |
| result += f"**{i}.** \"{f['quote']}\"\n— {f['author']} | *{f['topic']}*\n\n---\n\n" | |
| return result | |
| # ============ ADMIN ============ | |
| def admin_upgrade(code, user_id): | |
| if code != ADMIN_CODE: | |
| return "❌ Invalid code" | |
| set_premium(user_id, True) | |
| return f"✅ User {user_id} is now PREMIUM!" | |
| def admin_stats(code): | |
| if code != ADMIN_CODE: | |
| return "❌ Invalid code" | |
| data = load_usage() | |
| total = len(data) | |
| premium = sum(1 for u in data.values() if u.get("premium")) | |
| today = datetime.now().strftime("%Y-%m-%d") | |
| requests_today = sum(u.get("count", 0) for u in data.values() if u.get("date") == today) | |
| total_favs = sum(len(u.get("favorites", [])) for u in data.values()) | |
| return f"📊 Stats:\n• Users: {total}\n• Premium: {premium}\n• Requests today: {requests_today}\n• Saved quotes: {total_favs}" | |
| # ============ AD HTML ============ | |
| AD_BANNER = f""" | |
| <div style="background:#f8f9fa; border:1px dashed #ccc; padding:12px; text-align:center; border-radius:8px; margin:8px 0;"> | |
| <p style="margin:0; font-size:13px; color:#666;"> | |
| 📢 <b>Advertisement</b> — | |
| <a href="{STRIPE_LINK}" target="_blank" style="color:#6366f1;">Remove ads with Premium</a> | |
| </p> | |
| <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client={ADSENSE_CLIENT}" crossorigin="anonymous"></script> | |
| <ins class="adsbygoogle" style="display:block" data-ad-client="{ADSENSE_CLIENT}" data-ad-slot="SLOT_ID" data-ad-format="auto" data-full-width-responsive="true"></ins> | |
| <script>(adsbygoogle = window.adsbygoogle || []).push({{}});</script> | |
| </div> | |
| """ | |
| PREMIUM_CTA = f""" | |
| <div style="background:linear-gradient(135deg, #667eea 0%, #764ba2 100%); color:white; padding:20px; border-radius:12px; text-align:center; margin:10px 0;"> | |
| <h3 style="margin:0 0 8px 0;">⭐ Ethereal Wisdom Premium</h3> | |
| <p style="margin:0 0 12px 0; font-size:14px;">Unlimited wisdom • Shareable cards • Collections • No ads</p> | |
| <a href="{STRIPE_LINK}" target="_blank" style="display:inline-block; background:white; color:#764ba2; padding:12px 28px; border-radius:25px; text-decoration:none; font-weight:bold;">Upgrade — {PREMIUM_PRICE}</a> | |
| </div> | |
| """ | |
| # ============ GRADIO UI ============ | |
| css = """ | |
| .gradio-container { max-width: 900px !important; } | |
| .quote-box { background: linear-gradient(135deg, #f5f7fa 0%, #e4e8ec 100%); padding: 30px; border-radius: 16px; border-left: 4px solid #667eea; font-size: 18px; line-height: 1.6; } | |
| .daily-box { background: linear-gradient(135deg, #fff9e6 0%, #fff3cd 100%); padding: 25px; border-radius: 16px; border-left: 4px solid #f59e0b; } | |
| .collection-box { background: #fafafa; padding: 20px; border-radius: 12px; } | |
| """ | |
| with gr.Blocks(title="Ethereal Wisdom — AI Wisdom Platform", theme=gr.themes.Soft(), css=css) as demo: | |
| # HEADER | |
| gr.HTML(""" | |
| <div style="text-align:center; padding:30px 0 20px;"> | |
| <h1 style="font-size:40px; margin-bottom:8px; background:linear-gradient(90deg, #667eea, #764ba2); -webkit-background-clip:text; -webkit-text-fill-color:transparent;"> | |
| ✨ Ethereal Wisdom | |
| </h1> | |
| <p style="font-size:16px; color:#666; margin:0;">AI-generated wisdom for your mind, heart, and soul</p> | |
| <p style="font-size:13px; color:#999; margin-top:8px;">Free: 3/day | Premium: Unlimited</p> | |
| </div> | |
| """) | |
| gr.HTML(PREMIUM_CTA) | |
| with gr.Tabs(): | |
| # === GENERATE === | |
| with gr.Tab("✨ Generate Wisdom"): | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| topic = gr.Dropdown(WISDOM_TOPICS, label="Topic", value="Wisdom") | |
| style = gr.Dropdown(WISDOM_STYLES, label="Voice/Style", value="Stoic philosopher (Marcus Aurelius, Seneca)") | |
| mood = gr.Dropdown(["peaceful", "energizing", "contemplative", "bold", "gentle", "fiery"], label="Mood", value="contemplative") | |
| length = gr.Dropdown(["Short (1 sentence)", "Medium (2-3 sentences)", "Long (paragraph)"], label="Length", value="Medium (2-3 sentences)") | |
| gen_btn = gr.Button("✨ Generate Wisdom", variant="primary", size="lg") | |
| status = gr.Markdown() | |
| with gr.Column(scale=1): | |
| quote_output = gr.Markdown(label="Your Wisdom") | |
| with gr.Row(): | |
| fav_btn = gr.Button("❤️ Save to Collection", size="sm") | |
| share_btn = gr.Button("📤 Share", size="sm") | |
| gr.HTML(AD_BANNER) | |
| gen_btn.click(generate_wisdom, inputs=[topic, style, mood, length], outputs=[quote_output, status]) | |
| # === DAILY WISDOM === | |
| with gr.Tab("☀️ Daily Wisdom"): | |
| daily_btn = gr.Button("🌅 Get Today's Wisdom", variant="primary") | |
| daily_output = gr.Markdown() | |
| daily_btn.click(get_daily_wisdom, inputs=[], outputs=daily_output) | |
| gr.HTML(AD_BANNER) | |
| # === COLLECTIONS === | |
| with gr.Tab("📚 My Collection"): | |
| refresh_btn = gr.Button("🔄 Refresh Collection", variant="secondary") | |
| collection_output = gr.Markdown() | |
| refresh_btn.click(show_collection, inputs=[], outputs=collection_output) | |
| gr.HTML(AD_BANNER) | |
| # === PREMIUM === | |
| with gr.Tab("⭐ Upgrade"): | |
| gr.HTML(f""" | |
| <div style="max-width:500px; margin:0 auto;"> | |
| <h2 style="text-align:center;">🔓 Unlock Premium</h2> | |
| <div style="display:grid; grid-template-columns:1fr 1fr; gap:15px; margin:20px 0;"> | |
| <div style="background:#f3f4f6; padding:20px; border-radius:12px;"> | |
| <h4>🆓 Free</h4> | |
| <ul style="padding-left:18px; font-size:14px; line-height:2;"> | |
| <li>3 generations/day</li> | |
| <li>Basic topics</li> | |
| <li>Ads shown</li> | |
| </ul> | |
| </div> | |
| <div style="background:linear-gradient(135deg, #667eea, #764ba2); color:white; padding:20px; border-radius:12px;"> | |
| <h4>⭐ Premium</h4> | |
| <ul style="padding-left:18px; font-size:14px; line-height:2;"> | |
| <li>Unlimited generations</li> | |
| <li>All topics & styles</li> | |
| <li>Collections & history</li> | |
| <li>Shareable cards</li> | |
| <li>Daily digest</li> | |
| <li>No ads</li> | |
| </ul> | |
| <a href="{STRIPE_LINK}" target="_blank" style="display:block; text-align:center; background:white; color:#764ba2; padding:10px; border-radius:20px; text-decoration:none; font-weight:bold; margin-top:10px;">{PREMIUM_PRICE}</a> | |
| </div> | |
| </div> | |
| </div> | |
| """) | |
| # === ADMIN === | |
| with gr.Tab("🔐 Admin"): | |
| admin_pass = gr.Textbox(label="Admin Code", type="password") | |
| with gr.Row(): | |
| with gr.Column(): | |
| target_user = gr.Textbox(label="User ID to Upgrade") | |
| upgrade_btn = gr.Button("Upgrade to Premium") | |
| upgrade_result = gr.Textbox(label="Result", interactive=False) | |
| upgrade_btn.click(admin_upgrade, inputs=[admin_pass, target_user], outputs=upgrade_result) | |
| with gr.Column(): | |
| stats_btn = gr.Button("Get Stats") | |
| stats_result = gr.Textbox(label="Stats", interactive=False, lines=6) | |
| stats_btn.click(admin_stats, inputs=admin_pass, outputs=stats_result) | |
| # FOOTER | |
| gr.HTML(""" | |
| <div style="text-align:center; padding:25px 0; border-top:1px solid #e5e7eb; margin-top:20px; color:#999; font-size:12px;"> | |
| <p>✨ Ethereal Wisdom PRO © 2024</p> | |
| </div> | |
| """) | |
| if __name__ == "__main__": | |
| demo.launch( | |
| server_name="0.0.0.0", | |
| server_port=int(os.environ.get("PORT", 7860)), | |
| share=False | |
| ) | |