diff --git a/config.example.json b/config.example.json index ac808fc..8722d59 100644 --- a/config.example.json +++ b/config.example.json @@ -11,9 +11,19 @@ "free_monthly": 30, "admin_key": "sk-draco-admin-CHANGE_ME", "plans": { - "satchel": {"usd": 3, "credits": 60}, - "crate": {"usd": 10, "credits": 250}, - "hoard": {"usd": 25, "credits": 750} + "satchel": { + "usd": 3, + "credits": 60 + }, + "crate": { + "usd": 10, + "credits": 250 + }, + "hoard": { + "usd": 50, + "credits": 1000000, + "label": "UNLIMITED 30 DAYS" + } }, "btcpay": { "url": "https://btcpay.thetempleofdoom.com", @@ -21,4 +31,4 @@ "api_key": "SET_ME", "webhook_secret": "SET_ME" } -} +} \ No newline at end of file diff --git a/draco_core.py b/draco_core.py index cb51a8a..451d15e 100644 --- a/draco_core.py +++ b/draco_core.py @@ -21,6 +21,7 @@ CREATE TABLE IF NOT EXISTS users ( credits INTEGER DEFAULT 0, free_used INTEGER DEFAULT 0, total_calls INTEGER DEFAULT 0, + unlimited_until VARCHAR(32), is_admin INTEGER DEFAULT 0, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, last_used_at TIMESTAMP @@ -59,10 +60,16 @@ def db(): def init_db(): c = db() c.executescript(SCHEMA) - try: # in-place migration for DBs created before total_calls existed - c.execute("SELECT total_calls FROM users LIMIT 1") - except sqlite3.OperationalError: - c.execute("ALTER TABLE users ADD COLUMN total_calls INTEGER DEFAULT 0") + for col, decl in (("total_calls", "INTEGER DEFAULT 0"), # idempotent migrations: + ("unlimited_until", "VARCHAR(32)")): # gunicorn workers race at boot + try: + c.execute(f"SELECT {col} FROM users LIMIT 1") + except sqlite3.OperationalError: + try: + c.execute(f"ALTER TABLE users ADD COLUMN {col} {decl}") + except sqlite3.OperationalError as e: # another worker won the race + if "duplicate column" not in str(e).lower(): + raise c.commit() c.execute("INSERT OR IGNORE INTO users (email, api_key, credits, is_admin) VALUES (?,?,?,1)", ("admin@draco.local", CFG["admin_key"], 999999)) @@ -417,7 +424,9 @@ def consume(user, kind, detail="", ip=""): cur = c.execute("SELECT credits, free_used FROM users WHERE id=?", (user["id"],)).fetchone() row = c.execute("SELECT * FROM users WHERE id=?", (user["id"],)).fetchone() month = time.strftime("%Y-%m") - if row["free_used"] < CFG["free_monthly"]: + if row["unlimited_until"] and row["unlimited_until"] > time.strftime("%Y-%m-%d"): + pass # HOARD subscriber: unlimited, no decrement + elif row["free_used"] < CFG["free_monthly"]: c.execute("UPDATE users SET free_used=free_used+1, last_used_at=CURRENT_TIMESTAMP WHERE id=?", (user["id"],)) elif row["credits"] > 0: c.execute("UPDATE users SET credits=credits-1, last_used_at=CURRENT_TIMESTAMP WHERE id=?", (user["id"],)) @@ -580,7 +589,12 @@ def handle_webhook(body, header_sig_ok): return True if etype == "InvoiceSettled": c.execute("UPDATE payments SET status='settled', settled_at=CURRENT_TIMESTAMP WHERE invoice_id=?", (invoice_id,)) - c.execute("UPDATE users SET credits=credits+? WHERE id=?", (p["credits"], p["user_id"])) + if p["amount_usd"] >= 50: # HOARD = $50/mo unlimited: 30 days from settle + import datetime + until = (datetime.date.today() + datetime.timedelta(days=30)).isoformat() + c.execute("UPDATE users SET unlimited_until=? WHERE id=?", (until, p["user_id"])) + else: + c.execute("UPDATE users SET credits=credits+? WHERE id=?", (p["credits"], p["user_id"])) else: c.execute("UPDATE payments SET status='processing' WHERE invoice_id=?", (invoice_id,)) c.commit() diff --git a/pages.py b/pages.py index a7d082e..54b636e 100644 --- a/pages.py +++ b/pages.py @@ -75,16 +75,18 @@ NAV = """DRACObook-forged oracle PAGE_HOME = """
Most AI assistants guess. DRACO retrieves from __STATS__ — - languages, kernels, networks, exploitation, red-team tradecraft — and shows you the exact - books behind every answer. Check the citations. That's the proof.
+ ◈ THE LARGEST PROVABLE BOOK-GROUNDED AI ON THE INTERNET +Generic chatbots hallucinate from compressed training data. DRACO retrieves + live from __STATS__ of actual expert books — languages, kernels, networks, + exploitation, red-team tradecraft — and stamps the exact source on every claim. + No cutoff. No hallucination. Receipts attached.
$50/mo HOARD = unlimited: every ask, every search, the whole +{{ mb }}M-char library, as hard as you want to run it. Or pay-per-use with packs. Bitcoin only, +no subscription trap — HOARD simply expires in 30 days unless you renew.
| Pack | Price | Credits | $/credit | |
|---|---|---|---|---|
| Tier | Price | What you get | ||
| {{ name }} | ${{ '%.2f'|format(p.usd) }} | {{ p.credits }} | ${{ '%.3f'|format(p.usd / p.credits) }} | +|
| {{ name }}{% if p.usd >= 50 %} BEST{% endif %} | +${{ '%.0f'|format(p.usd) }}{% if p.usd >= 50 %}/mo{% endif %} | +{% if p.usd >= 50 %}UNLIMITED asks + searches for 30 days. The whole library, unmetered.{% else %}{{ p.credits }} credits (1 = 1 ask or search), never expire.{% endif %} |