diff --git a/app/main.py b/app/main.py
index 9e00344..d9e378d 100644
--- a/app/main.py
+++ b/app/main.py
@@ -343,6 +343,40 @@ def _db_ensure_auth_table():
PRIMARY KEY (day, event)
)
""")
+ # Показы пейвола: по каждому придержанному файлу — кто (account/user) и какой файл.
+ con.execute("""
+ CREATE TABLE IF NOT EXISTS WEB_PAYWALL_EVENTS (
+ job_id TEXT PRIMARY KEY,
+ ts REAL,
+ account TEXT,
+ user_id TEXT,
+ source TEXT,
+ file_name TEXT,
+ size_mb REAL,
+ pages INTEGER,
+ status TEXT DEFAULT 'shown'
+ )
+ """)
+ # Разовый бэкфилл: текущие awaiting_payment (веб+бот) → в журнал показов.
+ try:
+ for _r in con.execute(
+ "SELECT name_or_f, date, time, "
+ "COALESCE(NULLIF(original_name,''), name_or_f) AS nm, source_size_mb, "
+ "COALESCE(NULLIF(pages_total,0), num_pages, 0) AS pg, user_id "
+ "FROM FILES WHERE url_res_f='awaiting_payment'").fetchall():
+ _src = "сайт" if str(_r[6]) == str(WEB_USER_ID) else "бот"
+ _acc = "" if _src == "сайт" else f"tg:{_r[6]}"
+ try:
+ _ts = datetime.datetime.strptime(f"{_r[1]} {_r[2]}", "%Y.%m.%d %H:%M:%S").timestamp()
+ except Exception:
+ _ts = time.time()
+ con.execute(
+ "INSERT OR IGNORE INTO WEB_PAYWALL_EVENTS "
+ "(job_id, ts, account, user_id, source, file_name, size_mb, pages, status) "
+ "VALUES (?,?,?,?,?,?,?,?, 'shown')",
+ (_r[0], _ts, _acc, str(_r[6]), _src, _r[3], _r[4], _r[5]))
+ except Exception as _pmig:
+ print(f"WEB_PAYWALL_EVENTS backfill error: {_pmig}")
# Платежи ЮKassa. status: pending/succeeded/canceled. purpose: donate/api_pro/file/sub.
con.execute("""
CREATE TABLE IF NOT EXISTS WEB_PAYMENTS (
@@ -1074,6 +1108,7 @@ def _finalize_submit(job_id, file_path, original_name, stitching, title,
if held:
# Задание не идёт в очередь бота, пока не оплатят (файл 99₽ или подписка)
_db_set_url_res_f(job_id, "awaiting_payment")
+ _log_paywall_shown(job_id, acc, user_id, "сайт", original_name, size_mb, pages)
return {"job_id": job_id, "requires_payment": True,
"file_price": FILE_PRICE_RUB, "sub_price": SUB_PRICE_RUB}
return {"job_id": job_id}
@@ -1996,6 +2031,7 @@ def _db_mark_payment_paid(payment_id, purpose, api_key, extra=None, payment_meth
job_id = extra.get("job_id")
if job_id and _db_get_url_res_f(job_id) == "awaiting_payment":
_db_set_url_res_f(job_id, "-")
+ _mark_paywall_resolved(job_id, "оплачен")
# Воронка: успешная оплата пейвольных покупок (файл/подписка)
if purpose in ("file", "sub"):
_bump_funnel("pay_success")
@@ -2495,6 +2531,8 @@ async def held_release(payload: dict, request: Request):
return True
ok = await asyncio.to_thread(_release)
+ if ok:
+ await asyncio.to_thread(_mark_paywall_resolved, job_id, "по подписке")
return {"released": bool(ok)}
@@ -3140,6 +3178,12 @@ _ADMIN_HTML = """
+
+