malikrf22 commited on
Commit
07e9acf
·
verified ·
1 Parent(s): 6912e02

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -556
app.py DELETED
@@ -1,556 +0,0 @@
1
- """
2
- app.py - Grok Video Studio
3
- Frontend UI + Login System + Task Manager
4
- Otak mesin diambil dari dataset privat malikrf22/seedance-core
5
- """
6
-
7
- import gradio as gr
8
- import os
9
- import sys
10
- import json
11
- import threading
12
- import importlib
13
- import tempfile
14
- import shutil
15
- from pathlib import Path
16
- from huggingface_hub import hf_hub_download, HfApi
17
-
18
- # =========================================================================
19
- # 1. KONFIGURASI
20
- # =========================================================================
21
- HF_TOKEN = os.environ.get("HF_TOKEN")
22
- REPO_ID = "malikrf22/seedance-core"
23
-
24
- if not HF_TOKEN:
25
- raise ValueError(
26
- "HF_TOKEN tidak ditemukan! "
27
- "Tambahkan di Settings > Secrets di Space HF Anda."
28
- )
29
-
30
- hf_api = HfApi(token=HF_TOKEN)
31
-
32
-
33
- # =========================================================================
34
- # 2. DOWNLOAD & IMPORT CORE ENGINE DARI DATASET PRIVAT
35
- # =========================================================================
36
- def load_core_engine():
37
- """Download core_engine.py dari dataset privat dan import sebagai modul"""
38
- print("[SYSTEM] Mengunduh core_engine.py dari dataset privat...")
39
-
40
- core_path = hf_hub_download(
41
- repo_id=REPO_ID,
42
- filename="core_engine3.py",
43
- repo_type="dataset",
44
- token=HF_TOKEN,
45
- force_download=True
46
- )
47
-
48
- core_dir = os.path.dirname(core_path)
49
- if core_dir not in sys.path:
50
- sys.path.insert(0, core_dir)
51
-
52
- # Jika sudah pernah diimport, reload
53
- if "core_engine" in sys.modules:
54
- importlib.reload(sys.modules["core_engine"])
55
- print("[SYSTEM] core_engine.py di-RELOAD.")
56
- else:
57
- print("[SYSTEM] core_engine.py di-IMPORT pertama kali.")
58
-
59
- import core_engine
60
- return core_engine
61
-
62
-
63
- # Load saat startup
64
- engine = load_core_engine()
65
-
66
-
67
- # =========================================================================
68
- # 3. DATABASE USER (REALTIME DARI DATASET PRIVAT)
69
- # =========================================================================
70
- def load_users_db():
71
- """Download users.json terbaru dari dataset privat (realtime, no cache)"""
72
- try:
73
- db_path = hf_hub_download(
74
- repo_id=REPO_ID,
75
- filename="users3.json",
76
- repo_type="dataset",
77
- token=HF_TOKEN,
78
- force_download=True
79
- )
80
- with open(db_path, "r") as f:
81
- return json.load(f)
82
- except Exception as e:
83
- print(f"[ERROR] Gagal load users.json: {e}")
84
- return {}
85
-
86
-
87
- def save_users_db(db):
88
- """Upload users.json yang diperbarui ke dataset privat"""
89
- try:
90
- temp_path = os.path.join(tempfile.gettempdir(), "users_upload.json")
91
- with open(temp_path, "w") as f:
92
- json.dump(db, f, indent=2)
93
- hf_api.upload_file(
94
- path_or_fileobj=temp_path,
95
- path_in_repo="users.json",
96
- repo_id=REPO_ID,
97
- repo_type="dataset"
98
- )
99
- return True
100
- except Exception as e:
101
- print(f"[ERROR] Gagal save users.json: {e}")
102
- return False
103
-
104
-
105
- # =========================================================================
106
- # 4. TASK LIMITER (MAKS 5 PROSES BERSAMAAN PER USER)
107
- # =========================================================================
108
- _task_counts = {} # {"mmm123": 2, "userpremium1": 0}
109
- _task_lock = threading.Lock()
110
-
111
-
112
- def acquire_task_slot(pwd):
113
- """Coba ambil 1 slot task. Return True jika berhasil."""
114
- with _task_lock:
115
- current = _task_counts.get(pwd, 0)
116
- if current >= 5:
117
- return False
118
- _task_counts[pwd] = current + 1
119
- return True
120
-
121
-
122
- def release_task_slot(pwd):
123
- """Lepaskan 1 slot task."""
124
- with _task_lock:
125
- if pwd in _task_counts:
126
- _task_counts[pwd] = max(0, _task_counts[pwd] - 1)
127
-
128
-
129
- def get_active_count(pwd):
130
- """Cek berapa task aktif untuk user ini."""
131
- with _task_lock:
132
- return _task_counts.get(pwd, 0)
133
-
134
-
135
- # =========================================================================
136
- # 5. FUNGSI-FUNGSI UI
137
- # =========================================================================
138
-
139
- def do_login(password):
140
- """
141
- Validasi sandi terhadap users.json (realtime download).
142
- Jika cocok: sembunyikan login, tampilkan main, isi settings.
143
- """
144
- if not password or not password.strip():
145
- return (
146
- gr.update(visible=True), # login_screen tetap tampil
147
- gr.update(visible=False), # main_screen tetap sembunyi
148
- "", # session_pwd
149
- "❌ Masukkan sandi!", # login_msg
150
- "", "", "" # cookie, statsig, userid
151
- )
152
-
153
- password = password.strip()
154
- db = load_users_db()
155
-
156
- if password not in db:
157
- return (
158
- gr.update(visible=True),
159
- gr.update(visible=False),
160
- "",
161
- "❌ Sandi tidak ditemukan. Hubungi admin.",
162
- "", "", ""
163
- )
164
-
165
- user = db[password]
166
- return (
167
- gr.update(visible=False), # sembunyikan login
168
- gr.update(visible=True), # tampilkan main
169
- password, # simpan di session
170
- "", # kosongkan login_msg
171
- user.get("cookie", ""),
172
- user.get("x_statsig", ""),
173
- user.get("x_userid", "")
174
- )
175
-
176
-
177
- def do_save_settings(pwd, cookie, statsig, userid):
178
- """Simpan settings user ke dataset privat."""
179
- if not pwd:
180
- return "❌ Session tidak valid. Login ulang."
181
-
182
- db = load_users_db()
183
- if pwd not in db:
184
- return "❌ User tidak ditemukan di database."
185
-
186
- db[pwd]["cookie"] = cookie.strip()
187
- db[pwd]["x_statsig"] = statsig.strip()
188
- db[pwd]["x_userid"] = userid.strip()
189
-
190
- if save_users_db(db):
191
- return "✅ Settings berhasil disimpan!"
192
- else:
193
- return "❌ Gagal menyimpan ke server. Coba lagi."
194
-
195
-
196
- def do_logout():
197
- """Kembali ke layar login."""
198
- return (
199
- gr.update(visible=True), # tampilkan login
200
- gr.update(visible=False), # sembunyikan main
201
- "", # reset session
202
- "", "", "" # kosongkan settings
203
- )
204
-
205
-
206
- # =========================================================================
207
- # 6. WRAPPER GENERATE / EXTEND / UPSCALE DENGAN TASK LIMITER
208
- # =========================================================================
209
-
210
- def get_user_data(pwd):
211
- """Ambil data user terbaru dari database."""
212
- db = load_users_db()
213
- return db.get(pwd, {})
214
-
215
-
216
- def wrapped_generate(prompt, duration, ratio, images, pwd):
217
- """Generate video dengan batasan maks 5 task bersamaan."""
218
- if not pwd:
219
- yield None, "[ERROR] Anda belum login!", None, None, 0, None
220
- return
221
-
222
- active = get_active_count(pwd)
223
- if not acquire_task_slot(pwd):
224
- yield (
225
- None,
226
- f"[LIMIT] Anda sedang menjalankan {active}/5 proses.\n"
227
- f"Tunggu salah satu selesai sebelum memulai yang baru.",
228
- None, None, 0, None
229
- )
230
- return
231
-
232
- try:
233
- user_data = get_user_data(pwd)
234
-
235
- # Reload engine untuk pastikan versi terbaru
236
- global engine
237
- engine = load_core_engine()
238
-
239
- for output in engine.generate_initial(
240
- prompt, duration, ratio, images, user_data
241
- ):
242
- yield output
243
- except Exception as e:
244
- yield None, f"[EXCEPTION] {str(e)}", None, None, 0, None
245
- finally:
246
- release_task_slot(pwd)
247
-
248
-
249
- def wrapped_extend(current_id, original_id, current_dur, ratio, ext_dur, pwd):
250
- """Extend video dengan batasan maks 5 task bersamaan."""
251
- if not pwd:
252
- yield None, "[ERROR] Anda belum login!", current_id, current_dur
253
- return
254
-
255
- if not acquire_task_slot(pwd):
256
- active = get_active_count(pwd)
257
- yield (
258
- None,
259
- f"[LIMIT] Anda sedang menjalankan {active}/5 proses.\n"
260
- f"Tunggu salah satu selesai.",
261
- current_id, current_dur
262
- )
263
- return
264
-
265
- try:
266
- user_data = get_user_data(pwd)
267
-
268
- global engine
269
- engine = load_core_engine()
270
-
271
- for output in engine.extend_video(
272
- current_id, original_id, current_dur, ratio, ext_dur, user_data
273
- ):
274
- yield output
275
- except Exception as e:
276
- yield None, f"[EXCEPTION] {str(e)}", current_id, current_dur
277
- finally:
278
- release_task_slot(pwd)
279
-
280
-
281
- def wrapped_upscale(current_id, pwd):
282
- """Upscale video dengan batasan maks 5 task bersamaan."""
283
- if not pwd:
284
- yield None, "[ERROR] Anda belum login!"
285
- return
286
-
287
- if not acquire_task_slot(pwd):
288
- active = get_active_count(pwd)
289
- yield (
290
- None,
291
- f"[LIMIT] Anda sedang menjalankan {active}/5 proses.\n"
292
- f"Tunggu salah satu selesai."
293
- )
294
- return
295
-
296
- try:
297
- user_data = get_user_data(pwd)
298
-
299
- global engine
300
- engine = load_core_engine()
301
-
302
- for output in engine.upscale_video(current_id, user_data):
303
- yield output
304
- except Exception as e:
305
- yield None, f"[EXCEPTION] {str(e)}"
306
- finally:
307
- release_task_slot(pwd)
308
-
309
-
310
- # =========================================================================
311
- # 7. MEMBANGUN UI GRADIO
312
- # =========================================================================
313
-
314
- css = """
315
- .login-container {
316
- max-width: 400px;
317
- margin: 100px auto;
318
- padding: 30px;
319
- border-radius: 12px;
320
- background: #1a1a2e;
321
- box-shadow: 0 8px 32px rgba(0,0,0,0.3);
322
- }
323
- .login-container h2 {
324
- text-align: center;
325
- color: #e0e0e0;
326
- }
327
- .studio-header {
328
- text-align: center;
329
- padding: 10px;
330
- margin-bottom: 10px;
331
- }
332
- .status-bar {
333
- font-size: 0.85em;
334
- padding: 8px 12px;
335
- border-radius: 6px;
336
- background: #0d1117;
337
- color: #58a6ff;
338
- border: 1px solid #21262d;
339
- }
340
- footer {visibility: hidden}
341
- """
342
-
343
- with gr.Blocks(
344
- title="Grok Video Studio",
345
- theme=gr.themes.Base(
346
- primary_hue="blue",
347
- neutral_hue="slate",
348
- ),
349
- css=css
350
- ) as demo:
351
-
352
- # ── STATE ──
353
- session_pwd = gr.State("")
354
- state_current_id = gr.State(None)
355
- state_original_id = gr.State(None)
356
- state_duration = gr.State(0.0)
357
- state_ratio = gr.State(None)
358
-
359
- # =================================================================
360
- # LAYAR LOGIN
361
- # =================================================================
362
- with gr.Column(visible=True, elem_classes="login-container") as login_screen:
363
- gr.Markdown("## 🔐 Grok Video Studio")
364
- gr.Markdown(
365
- "Masukkan sandi akses Anda untuk melanjutkan.",
366
- elem_classes="studio-header"
367
- )
368
- in_password = gr.Textbox(
369
- label="Sandi Akses",
370
- type="password",
371
- placeholder="Masukkan sandi...",
372
- max_lines=1
373
- )
374
- btn_login = gr.Button("🔓 Masuk", variant="primary", size="lg")
375
- login_msg = gr.Markdown("")
376
-
377
- # =================================================================
378
- # LAYAR UTAMA
379
- # =================================================================
380
- with gr.Column(visible=False) as main_screen:
381
- # Header
382
- with gr.Row():
383
- gr.Markdown("# 🎬 Grok Video Studio", elem_classes="studio-header")
384
- btn_logout = gr.Button("🚪 Logout", size="sm", scale=0)
385
-
386
- with gr.Tabs():
387
- # ─────────────────────────────────────────────────────────
388
- # TAB 1: STUDIO
389
- # ─────────────────────────────────────────────────────────
390
- with gr.Tab("🎬 Studio"):
391
- with gr.Row():
392
- # Kolom Kiri: Input
393
- with gr.Column(scale=1):
394
- gr.Markdown("### Generate Video")
395
- in_prompt = gr.Textbox(
396
- label="Prompt",
397
- placeholder="Deskripsikan video yang ingin dibuat...",
398
- lines=3
399
- )
400
- in_images = gr.File(
401
- label="Referensi Gambar (Opsional)",
402
- file_count="multiple",
403
- file_types=["image"]
404
- )
405
- with gr.Row():
406
- in_duration = gr.Slider(
407
- 1, 15, value=5, step=1,
408
- label="Durasi (detik)"
409
- )
410
- in_ratio = gr.Dropdown(
411
- ["16:9", "9:16", "1:1", "2:3", "3:2"],
412
- value="16:9", label="Rasio"
413
- )
414
- btn_generate = gr.Button(
415
- "🚀 Generate Video", variant="primary"
416
- )
417
-
418
- gr.Markdown("---")
419
- gr.Markdown("### Extend Video")
420
- in_ext_dur = gr.Slider(
421
- 1, 15, value=5, step=1,
422
- label="Tambah Durasi (detik)"
423
- )
424
- btn_extend = gr.Button("➕ Extend Video")
425
-
426
- gr.Markdown("---")
427
- gr.Markdown("### Upscale HD")
428
- btn_upscale = gr.Button(
429
- "✨ Upscale ke HD", variant="secondary"
430
- )
431
-
432
- # Kolom Kanan: Output
433
- with gr.Column(scale=2):
434
- out_video = gr.Video(label="Hasil Video")
435
- out_log = gr.Textbox(
436
- label="Server Log (Raw)",
437
- lines=18,
438
- max_lines=25,
439
- autoscroll=True,
440
- show_copy_button=True
441
- )
442
-
443
- # ─────────────────────────────────────────────────────────
444
- # TAB 2: SETTINGS
445
- # ─────────────────────────────────────────────────────────
446
- with gr.Tab("⚙️ Settings"):
447
- gr.Markdown("### Kredensial Akun Grok")
448
- gr.Markdown(
449
- "Data ini bersifat **pribadi** dan tersimpan terenkripsi "
450
- "di server. User lain tidak bisa melihat data Anda."
451
- )
452
- set_cookie = gr.Textbox(
453
- label="Cookie (Raw String)",
454
- placeholder="Paste seluruh cookie string dari browser...",
455
- lines=4
456
- )
457
- set_statsig = gr.Textbox(
458
- label="x_statsig",
459
- placeholder="Paste x_statsig header..."
460
- )
461
- set_userid = gr.Textbox(
462
- label="x_userid",
463
- placeholder="Paste x_userid..."
464
- )
465
- btn_save = gr.Button("💾 Simpan Settings", variant="primary")
466
- save_status = gr.Markdown("")
467
-
468
- # =================================================================
469
- # WIRING (LOGIC CONNECTIONS)
470
- # =================================================================
471
-
472
- # ── LOGIN ──
473
- btn_login.click(
474
- fn=do_login,
475
- inputs=[in_password],
476
- outputs=[
477
- login_screen, main_screen, session_pwd, login_msg,
478
- set_cookie, set_statsig, set_userid
479
- ]
480
- )
481
-
482
- # Enter key juga bisa login
483
- in_password.submit(
484
- fn=do_login,
485
- inputs=[in_password],
486
- outputs=[
487
- login_screen, main_screen, session_pwd, login_msg,
488
- set_cookie, set_statsig, set_userid
489
- ]
490
- )
491
-
492
- # ── LOGOUT ──
493
- btn_logout.click(
494
- fn=do_logout,
495
- inputs=[],
496
- outputs=[login_screen, main_screen, session_pwd,
497
- set_cookie, set_statsig, set_userid]
498
- )
499
-
500
- # ── SAVE SETTINGS ──
501
- btn_save.click(
502
- fn=do_save_settings,
503
- inputs=[session_pwd, set_cookie, set_statsig, set_userid],
504
- outputs=[save_status]
505
- )
506
-
507
- # ── GENERATE ──
508
- btn_generate.click(
509
- fn=wrapped_generate,
510
- inputs=[in_prompt, in_duration, in_ratio, in_images, session_pwd],
511
- outputs=[
512
- out_video, out_log,
513
- state_current_id, state_original_id,
514
- state_duration, state_ratio
515
- ]
516
- )
517
-
518
- # ── EXTEND ──
519
- btn_extend.click(
520
- fn=wrapped_extend,
521
- inputs=[
522
- state_current_id, state_original_id,
523
- state_duration, state_ratio,
524
- in_ext_dur, session_pwd
525
- ],
526
- outputs=[out_video, out_log, state_current_id, state_duration]
527
- )
528
-
529
- # ── UPSCALE ──
530
- btn_upscale.click(
531
- fn=wrapped_upscale,
532
- inputs=[state_current_id, session_pwd],
533
- outputs=[out_video, out_log]
534
- )
535
-
536
-
537
- # =========================================================================
538
- # 8. LAUNCH
539
- # =========================================================================
540
- if __name__ == "__main__":
541
- print("=" * 60)
542
- print("🚀 Grok Video Studio")
543
- print(" Core Engine: dataset privat malikrf22/seedance-core")
544
- print(" Task Limit: 5 concurrent per user")
545
- print(" Login: password-only (no username)")
546
- print("=" * 60)
547
-
548
- demo.queue(
549
- max_size=200,
550
- default_concurrency_limit=50
551
- )
552
- demo.launch(
553
- server_name="0.0.0.0",
554
- server_port=7860,
555
- show_error=True
556
- )