camdog920's picture
Upload app.py
c1e7261 verified
"""
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
)