Spaces:
Running
Running
Upload 3 files
Browse files- app.py +7 -3
- bot.py +23 -16
- index.html +22 -25
app.py
CHANGED
|
@@ -983,10 +983,14 @@ def api_gemini_voices():
|
|
| 983 |
{"id": "Puck", "name": "Puck (Male, Upbeat)"},
|
| 984 |
{"id": "Aoede", "name": "Aoede (Female, Breezy)"},
|
| 985 |
{"id": "Zephyr", "name": "Zephyr (Female, Bright)"},
|
| 986 |
-
{"id": "Achelois", "name": "Achelois (Female, Soft)"},
|
| 987 |
-
{"id": "Pegasus", "name": "Pegasus (Male, Confident)"},
|
| 988 |
-
{"id": "Perseus", "name": "Perseus (Male, Casual)"},
|
| 989 |
{"id": "Schedar", "name": "Schedar (Male, Even-keeled)"},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 990 |
]
|
| 991 |
return jsonify(ok=True, voices=voices)
|
| 992 |
|
|
|
|
| 983 |
{"id": "Puck", "name": "Puck (Male, Upbeat)"},
|
| 984 |
{"id": "Aoede", "name": "Aoede (Female, Breezy)"},
|
| 985 |
{"id": "Zephyr", "name": "Zephyr (Female, Bright)"},
|
|
|
|
|
|
|
|
|
|
| 986 |
{"id": "Schedar", "name": "Schedar (Male, Even-keeled)"},
|
| 987 |
+
{"id": "Sulafat", "name": "Sulafat (Female, Warm)"},
|
| 988 |
+
{"id": "Iapetus", "name": "Iapetus (Male, Clear)"},
|
| 989 |
+
{"id": "Rasalgethi", "name": "Rasalgethi (Male, Informative)"},
|
| 990 |
+
{"id": "Gacrux", "name": "Gacrux (Female, Mature)"},
|
| 991 |
+
{"id": "Pulcherrima", "name": "Pulcherrima (Female, Upbeat)"},
|
| 992 |
+
{"id": "Achird", "name": "Achird (Female, Friendly)"},
|
| 993 |
+
{"id": "Zubenelgenubi", "name": "Zubenelgenubi (Male, Casual)"},
|
| 994 |
]
|
| 995 |
return jsonify(ok=True, voices=voices)
|
| 996 |
|
bot.py
CHANGED
|
@@ -257,14 +257,14 @@ async def btn_auto_process(update: Update, ctx: ContextTypes.DEFAULT_TYPE):
|
|
| 257 |
await update.message.reply_text("❌ /start နှိပ်ပြီး ဦးစွာ login ဝင်ပါ")
|
| 258 |
return ST_MAIN
|
| 259 |
s = sess(cid)
|
| 260 |
-
if s['coins'] != -1 and s['coins'] <
|
| 261 |
await update.message.reply_text(
|
| 262 |
-
f"❌ Coins မလုံလောက်ဘူး\nသင့်မှာ *{s['coins']}* ရှိတယ် — *
|
| 263 |
parse_mode=ParseMode.MARKDOWN, reply_markup=main_kb(cid))
|
| 264 |
return ST_MAIN
|
| 265 |
cancel_flags[cid] = False
|
| 266 |
await update.message.reply_text(
|
| 267 |
-
"📥 *Auto Process* —
|
| 268 |
"အောက်ပါ link တစ်ခုခု ပို့ပါ သို့မဟုတ် Video File တင်ပါ —\n\n"
|
| 269 |
"• YouTube\n• TikTok\n• Facebook\n• Instagram\n\n"
|
| 270 |
"_(ဖျက်သိမ်းလိုရင် ❌ နှိပ်ပါ)_",
|
|
@@ -377,10 +377,10 @@ async def recv_video_input(update: Update, ctx: ContextTypes.DEFAULT_TYPE):
|
|
| 377 |
fresh_coins = get_coins(s['username'])
|
| 378 |
if fresh_coins is not None:
|
| 379 |
s['coins'] = fresh_coins
|
| 380 |
-
if not s['is_admin'] and s['coins'] != -1 and s['coins'] <
|
| 381 |
await update.message.reply_text(
|
| 382 |
f"❌ *Coins မလုံလောက်ဘူး*\n\n"
|
| 383 |
-
f"သင့်မှာ *{s['coins']}* ရှိတယ် — *
|
| 384 |
f"🛒 Coins ဝယ်ရန် ခလုတ်နှိပ်ပါ",
|
| 385 |
parse_mode=ParseMode.MARKDOWN, reply_markup=main_kb(cid)
|
| 386 |
)
|
|
@@ -428,10 +428,10 @@ async def _do_process(bot, cid, prog_msg_id, pending_url=None, pending_file_id=N
|
|
| 428 |
fresh = get_coins(s['username'])
|
| 429 |
if fresh is not None:
|
| 430 |
s['coins'] = fresh
|
| 431 |
-
if s['coins'] != -1 and s['coins'] <
|
| 432 |
await prog(
|
| 433 |
f"❌ *Coins မလုံလောက်ဘူး*\n\n"
|
| 434 |
-
f"သင့်မှာ *{fmt_coins(s['coins'])}* ရှိတယ် — *
|
| 435 |
f"🛒 Coins ဝယ်ပြီးနောက် ထပ်ကြိုးစားပါ"
|
| 436 |
)
|
| 437 |
return
|
|
@@ -501,7 +501,7 @@ async def _do_process(bot, cid, prog_msg_id, pending_url=None, pending_file_id=N
|
|
| 501 |
_build_video(vpath, cmb, mpath, ad, vd, s['crop'], s['flip'], s['color'], s['watermark'], out_file)
|
| 502 |
|
| 503 |
if not s['is_admin']:
|
| 504 |
-
ok2, rem = deduct(s['username'],
|
| 505 |
if ok2:
|
| 506 |
s['coins'] = rem; upd_stat(s['username'], 'tr'); upd_stat(s['username'], 'vd')
|
| 507 |
|
|
@@ -1048,8 +1048,8 @@ async def recv_text(update: Update, ctx: ContextTypes.DEFAULT_TYPE):
|
|
| 1048 |
|
| 1049 |
if re.match(r'https?://', text):
|
| 1050 |
s['pending_url'] = text; s['pending_file_id'] = None
|
| 1051 |
-
if s['coins'] != -1 and s['coins'] <
|
| 1052 |
-
await update.message.reply_text(f"❌ Coins မလုံလောက်ဘူး ({s['coins']}) —
|
| 1053 |
return ST_MAIN
|
| 1054 |
# Busy check
|
| 1055 |
if is_processing(cid):
|
|
@@ -1065,9 +1065,9 @@ async def recv_text(update: Update, ctx: ContextTypes.DEFAULT_TYPE):
|
|
| 1065 |
fresh_coins2 = get_coins(s['username'])
|
| 1066 |
if fresh_coins2 is not None:
|
| 1067 |
s['coins'] = fresh_coins2
|
| 1068 |
-
if not s['is_admin'] and s['coins'] != -1 and s['coins'] <
|
| 1069 |
await update.message.reply_text(
|
| 1070 |
-
f"❌ Coins မလုံလောက်ဘူး ({s['coins']}) —
|
| 1071 |
)
|
| 1072 |
return ST_MAIN
|
| 1073 |
cancel_flags[cid] = False
|
|
@@ -1126,13 +1126,20 @@ def main():
|
|
| 1126 |
async def _clear_webhook():
|
| 1127 |
try:
|
| 1128 |
await application.bot.delete_webhook(drop_pending_updates=True)
|
| 1129 |
-
logger.info('
|
| 1130 |
except Exception as _e:
|
| 1131 |
logger.warning(f'deleteWebhook: {_e}')
|
| 1132 |
-
await _aio.sleep(
|
| 1133 |
-
|
|
|
|
|
|
|
|
|
|
| 1134 |
logger.info('🤖 Recap Studio Bot အသင့်ဖြစ်ပြီ!')
|
| 1135 |
-
application.run_polling(
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1136 |
|
| 1137 |
if __name__ == '__main__':
|
| 1138 |
main()
|
|
|
|
| 257 |
await update.message.reply_text("❌ /start နှိပ်ပြီး ဦးစွာ login ဝင်ပါ")
|
| 258 |
return ST_MAIN
|
| 259 |
s = sess(cid)
|
| 260 |
+
if s['coins'] != -1 and s['coins'] < 1:
|
| 261 |
await update.message.reply_text(
|
| 262 |
+
f"❌ Coins မလုံလောက်ဘူး\nသင့်မှာ *{s['coins']}* ရှိတယ် — *1* လိုတယ်\n\n🛒 Coins ဝယ်ရန် ခလုတ်နှိပ်ပါ",
|
| 263 |
parse_mode=ParseMode.MARKDOWN, reply_markup=main_kb(cid))
|
| 264 |
return ST_MAIN
|
| 265 |
cancel_flags[cid] = False
|
| 266 |
await update.message.reply_text(
|
| 267 |
+
"📥 *Auto Process* — 1 Coin ကုန်မည်\n\n"
|
| 268 |
"အောက်ပါ link တစ်ခုခု ပို့ပါ သို့မဟုတ် Video File တင်ပါ —\n\n"
|
| 269 |
"• YouTube\n• TikTok\n• Facebook\n• Instagram\n\n"
|
| 270 |
"_(ဖျက်သိမ်းလိုရင် ❌ နှိပ်ပါ)_",
|
|
|
|
| 377 |
fresh_coins = get_coins(s['username'])
|
| 378 |
if fresh_coins is not None:
|
| 379 |
s['coins'] = fresh_coins
|
| 380 |
+
if not s['is_admin'] and s['coins'] != -1 and s['coins'] < 1:
|
| 381 |
await update.message.reply_text(
|
| 382 |
f"❌ *Coins မလုံလောက်ဘူး*\n\n"
|
| 383 |
+
f"သင့်မှာ *{s['coins']}* ရှိတယ် — *1* လိုတယ်\n\n"
|
| 384 |
f"🛒 Coins ဝယ်ရန် ခလုတ်နှိပ်ပါ",
|
| 385 |
parse_mode=ParseMode.MARKDOWN, reply_markup=main_kb(cid)
|
| 386 |
)
|
|
|
|
| 428 |
fresh = get_coins(s['username'])
|
| 429 |
if fresh is not None:
|
| 430 |
s['coins'] = fresh
|
| 431 |
+
if s['coins'] != -1 and s['coins'] < 1:
|
| 432 |
await prog(
|
| 433 |
f"❌ *Coins မလုံလောက်ဘူး*\n\n"
|
| 434 |
+
f"သင့်မှာ *{fmt_coins(s['coins'])}* ရှိတယ် — *1* လိုတယ်\n"
|
| 435 |
f"🛒 Coins ဝယ်ပြီးနောက် ထပ်ကြိုးစားပါ"
|
| 436 |
)
|
| 437 |
return
|
|
|
|
| 501 |
_build_video(vpath, cmb, mpath, ad, vd, s['crop'], s['flip'], s['color'], s['watermark'], out_file)
|
| 502 |
|
| 503 |
if not s['is_admin']:
|
| 504 |
+
ok2, rem = deduct(s['username'], 1)
|
| 505 |
if ok2:
|
| 506 |
s['coins'] = rem; upd_stat(s['username'], 'tr'); upd_stat(s['username'], 'vd')
|
| 507 |
|
|
|
|
| 1048 |
|
| 1049 |
if re.match(r'https?://', text):
|
| 1050 |
s['pending_url'] = text; s['pending_file_id'] = None
|
| 1051 |
+
if s['coins'] != -1 and s['coins'] < 1:
|
| 1052 |
+
await update.message.reply_text(f"❌ Coins မလုံလောက်ဘူး ({s['coins']}) — 1 လိုသည်")
|
| 1053 |
return ST_MAIN
|
| 1054 |
# Busy check
|
| 1055 |
if is_processing(cid):
|
|
|
|
| 1065 |
fresh_coins2 = get_coins(s['username'])
|
| 1066 |
if fresh_coins2 is not None:
|
| 1067 |
s['coins'] = fresh_coins2
|
| 1068 |
+
if not s['is_admin'] and s['coins'] != -1 and s['coins'] < 1:
|
| 1069 |
await update.message.reply_text(
|
| 1070 |
+
f"❌ Coins မလုံလောက်ဘူး ({s['coins']}) — 1 လိုသည်"
|
| 1071 |
)
|
| 1072 |
return ST_MAIN
|
| 1073 |
cancel_flags[cid] = False
|
|
|
|
| 1126 |
async def _clear_webhook():
|
| 1127 |
try:
|
| 1128 |
await application.bot.delete_webhook(drop_pending_updates=True)
|
| 1129 |
+
logger.info('OK: Webhook cleared')
|
| 1130 |
except Exception as _e:
|
| 1131 |
logger.warning(f'deleteWebhook: {_e}')
|
| 1132 |
+
await _aio.sleep(3)
|
| 1133 |
+
try:
|
| 1134 |
+
_aio.run(_clear_webhook())
|
| 1135 |
+
except RuntimeError:
|
| 1136 |
+
pass
|
| 1137 |
logger.info('🤖 Recap Studio Bot အသင့်ဖြစ်ပြီ!')
|
| 1138 |
+
application.run_polling(
|
| 1139 |
+
drop_pending_updates=True,
|
| 1140 |
+
allowed_updates=Update.ALL_TYPES,
|
| 1141 |
+
close_loop=False,
|
| 1142 |
+
)
|
| 1143 |
|
| 1144 |
if __name__ == '__main__':
|
| 1145 |
main()
|
index.html
CHANGED
|
@@ -729,7 +729,7 @@ body{background:var(--bg);color:var(--text);font-family:var(--F);min-height:100v
|
|
| 729 |
<!-- VIDEO OPTIONS -->
|
| 730 |
<div class="card">
|
| 731 |
<div class="ch"><div class="ci ci-g"><i class="fas fa-film"></i></div><div class="ct">Video Options</div></div>
|
| 732 |
-
<div class="egrid">
|
| 733 |
<div class="ei"><div class="eil">Aspect Ratio</div>
|
| 734 |
<select class="esel" id="crop" onchange="syncCanvasInner(document.getElementById('pvid'));">
|
| 735 |
<option value="original" selected>Original</option>
|
|
@@ -738,37 +738,34 @@ body{background:var(--bg);color:var(--text);font-family:var(--F);min-height:100v
|
|
| 738 |
<option value="1:1">1:1 Square</option>
|
| 739 |
</select>
|
| 740 |
</div>
|
| 741 |
-
<div class="ei"><div class="eil"
|
| 742 |
<button class="icon-toggle" id="btn-flip" onclick="toggleOpt('flip')"><i class="fas fa-arrows-alt-h"></i> Off</button>
|
| 743 |
</div>
|
| 744 |
-
<div class="ei"><div class="eil"
|
| 745 |
<button class="icon-toggle" id="btn-col" onclick="toggleOpt('col')"><i class="fas fa-adjust"></i> Off</button>
|
| 746 |
</div>
|
| 747 |
-
|
| 748 |
-
|
| 749 |
-
<!-- Background Music -->
|
| 750 |
-
<div style="margin-top:12px;border-top:1px solid rgba(255,255,255,.08);padding-top:12px">
|
| 751 |
-
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:8px">
|
| 752 |
-
<div class="eil" style="margin:0"><i class="fas fa-music" style="margin-right:6px;color:#a855f7"></i>Background Music</div>
|
| 753 |
<button class="icon-toggle" id="btn-bgm" onclick="toggleBgm()"><i class="fas fa-music"></i> Off</button>
|
| 754 |
</div>
|
| 755 |
-
<div
|
| 756 |
-
<
|
| 757 |
-
<
|
| 758 |
-
|
| 759 |
-
|
| 760 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 761 |
</div>
|
| 762 |
-
</div>
|
| 763 |
-
|
| 764 |
-
<!-- Watermark -->
|
| 765 |
-
<div class="wm-row">
|
| 766 |
-
<div class="wm-lbl"><i class="fas fa-stamp" style="color:#f59e0b"></i> Watermark</div>
|
| 767 |
-
<button class="wm-toggle" id="btn-wm" onclick="toggleWm()">Off</button>
|
| 768 |
-
</div>
|
| 769 |
-
<div class="wm-wrap" id="wm-wrap">
|
| 770 |
-
<input class="winp" id="wm-text" placeholder="ဥပမာ — @YourPage သို့မဟုတ် Recap Studio" maxlength="40" style="margin-top:6px;font-size:.8rem">
|
| 771 |
-
<div style="font-size:.67rem;color:var(--muted2);margin-top:5px;display:flex;align-items:center;gap:5px"><i class="fas fa-arrows-alt-v" style="color:#f59e0b"></i>Video ထဲမှာ ဖြည်းဖြည်းချင်း အပေါ်အောက် ရွေ့နေမည်</div>
|
| 772 |
</div>
|
| 773 |
|
| 774 |
</div>
|
|
|
|
| 729 |
<!-- VIDEO OPTIONS -->
|
| 730 |
<div class="card">
|
| 731 |
<div class="ch"><div class="ci ci-g"><i class="fas fa-film"></i></div><div class="ct">Video Options</div></div>
|
| 732 |
+
<div class="egrid" style="grid-template-columns:1fr 1fr;gap:8px">
|
| 733 |
<div class="ei"><div class="eil">Aspect Ratio</div>
|
| 734 |
<select class="esel" id="crop" onchange="syncCanvasInner(document.getElementById('pvid'));">
|
| 735 |
<option value="original" selected>Original</option>
|
|
|
|
| 738 |
<option value="1:1">1:1 Square</option>
|
| 739 |
</select>
|
| 740 |
</div>
|
| 741 |
+
<div class="ei"><div class="eil">Flip</div>
|
| 742 |
<button class="icon-toggle" id="btn-flip" onclick="toggleOpt('flip')"><i class="fas fa-arrows-alt-h"></i> Off</button>
|
| 743 |
</div>
|
| 744 |
+
<div class="ei"><div class="eil">Color Boost</div>
|
| 745 |
<button class="icon-toggle" id="btn-col" onclick="toggleOpt('col')"><i class="fas fa-adjust"></i> Off</button>
|
| 746 |
</div>
|
| 747 |
+
<div class="ei"><div class="eil">Background Music</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 748 |
<button class="icon-toggle" id="btn-bgm" onclick="toggleBgm()"><i class="fas fa-music"></i> Off</button>
|
| 749 |
</div>
|
| 750 |
+
<div class="ei" style="grid-column:1/-1;padding:0;border:none;background:none">
|
| 751 |
+
<div id="bgm-wrap" style="display:none">
|
| 752 |
+
<label style="display:flex;align-items:center;gap:10px;background:rgba(255,255,255,.05);border:1px dashed rgba(168,85,247,.3);border-radius:9px;padding:10px 12px;cursor:pointer">
|
| 753 |
+
<i class="fas fa-cloud-upload-alt" style="color:#a855f7;font-size:1.1rem"></i>
|
| 754 |
+
<span id="bgm-name" style="color:rgba(255,255,255,.5);font-size:.82rem">Click to upload MP3 / WAV</span>
|
| 755 |
+
<input type="file" id="bgm-file" accept=".mp3,.wav,audio/*" style="display:none" onchange="onBgmFile(this)">
|
| 756 |
+
</label>
|
| 757 |
+
</div>
|
| 758 |
+
</div>
|
| 759 |
+
<div class="ei" style="grid-column:1/-1">
|
| 760 |
+
<div style="display:flex;align-items:center;justify-content:space-between">
|
| 761 |
+
<div class="eil" style="margin:0"><i class="fas fa-stamp" style="margin-right:6px;color:#f59e0b"></i>Watermark</div>
|
| 762 |
+
<button class="wm-toggle" id="btn-wm" onclick="toggleWm()">Off</button>
|
| 763 |
+
</div>
|
| 764 |
+
<div class="wm-wrap" id="wm-wrap" style="margin-top:8px">
|
| 765 |
+
<input class="winp" id="wm-text" placeholder="ဥပမာ — @YourPage သို့မဟုတ် Recap Studio" maxlength="40" style="margin-top:4px;font-size:.8rem;width:100%">
|
| 766 |
+
<div style="font-size:.67rem;color:var(--muted2);margin-top:5px;display:flex;align-items:center;gap:5px"><i class="fas fa-arrows-alt-v" style="color:#f59e0b"></i>Video ထဲမှာ ဖြည်းဖြည်းချင်း အပေါ်အောက် ရွေ့နေမည်</div>
|
| 767 |
+
</div>
|
| 768 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 769 |
</div>
|
| 770 |
|
| 771 |
</div>
|