Bl4ckSpaces commited on
Commit
f657a6d
·
verified ·
1 Parent(s): c097f5f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +90 -104
app.py CHANGED
@@ -3,127 +3,81 @@ import json
3
  import time
4
  import threading
5
  import os
6
- import shutil
7
  from datetime import datetime, date
8
- from huggingface_hub import HfApi, login
9
 
10
  # --- KONFIGURASI ---
11
- # Token Write (Kita pecah stringnya agar lolos security check HF)
12
- # Token ini PENTING agar server bisa menyimpan file database.json ke dirinya sendiri
13
  HF_TOKEN = "hf_" + "gcQpArWmJAlvIapWLNsJOWUvmbkkVCktgV"
 
 
14
 
15
- # Nama File Database
16
  DB_FILE = "soda_db.json"
17
  LOG_FILE = "soda_logs.json"
18
 
19
- # --- RAM STORAGE (GLOBAL) ---
20
- # Data akan hidup di sini dan sangat cepat diakses
21
  RAM_DB = {"users": {}}
22
  RAM_LOGS = []
23
 
24
  # --- DATABASE ENGINE ---
25
  def load_from_storage():
26
- """Load data dari disk/repo ke RAM saat server nyala (Startup)"""
27
  global RAM_DB, RAM_LOGS
28
  print("🔄 Booting Database Server...")
29
 
30
- # 1. Load DB Users
31
  if os.path.exists(DB_FILE):
32
  try:
33
  with open(DB_FILE, 'r') as f: RAM_DB = json.load(f)
34
- print("✅ Users Loaded to RAM")
35
- except:
36
- print("⚠️ User DB Corrupt/Empty, starting fresh.")
37
- RAM_DB = {"users": {}}
38
- else:
39
- print("⚠️ No User DB Found, starting fresh.")
40
- RAM_DB = {"users": {}}
41
 
42
- # 2. Load Logs
43
  if os.path.exists(LOG_FILE):
44
  try:
45
  with open(LOG_FILE, 'r') as f: RAM_LOGS = json.load(f)
46
- print("✅ Logs Loaded to RAM")
47
  except: RAM_LOGS = []
48
- else:
49
- RAM_LOGS = []
50
 
51
  def save_to_storage_task():
52
- """Background Task: Save RAM ke Disk & Cloud setiap 1 JAM"""
53
  while True:
54
- time.sleep(3600) # Tunggu 1 Jam (3600 detik) - Ganti angka ini jika ingin lebih cepat/lambat
55
- print("💾 [AUTO-SAVE] Saving RAM to Disk & Cloud...")
56
  try:
57
- # 1. Save ke Disk Lokal (Instant)
58
  with open(DB_FILE, 'w') as f: json.dump(RAM_DB, f, indent=2)
59
  with open(LOG_FILE, 'w') as f: json.dump(RAM_LOGS, f, indent=2)
60
 
61
- # 2. Upload ke Cloud Repo (Backup Persistence)
62
- # Ambil Repo ID otomatis dari Environment Variable Space
63
- repo_id = os.getenv("HF_REPO_ID")
64
-
65
- if repo_id:
66
  api = HfApi(token=HF_TOKEN)
67
-
68
- # Upload Database
69
- api.upload_file(
70
- path_or_fileobj=DB_FILE,
71
- path_in_repo=DB_FILE,
72
- repo_id=repo_id,
73
- repo_type="space"
74
- )
75
-
76
- # Upload Logs
77
- api.upload_file(
78
- path_or_fileobj=LOG_FILE,
79
- path_in_repo=LOG_FILE,
80
- repo_id=repo_id,
81
- repo_type="space"
82
- )
83
- print("✅ [AUTO-SAVE] Cloud Sync Complete!")
84
- else:
85
- print("⚠️ [AUTO-SAVE] Repo ID not found (Local Save Only)")
86
-
87
- except Exception as e:
88
- print(f"❌ [AUTO-SAVE] Failed: {e}")
89
-
90
- # Jalankan Load saat startup
91
  load_from_storage()
92
- # Jalankan Background Saver di thread terpisah
93
  threading.Thread(target=save_to_storage_task, daemon=True).start()
94
 
95
- # --- API ENDPOINTS (Dipanggil oleh Server Utama) ---
96
 
97
  def api_auth(action, username, password, email):
98
- """Handle Login & Signup Request"""
99
  try:
100
  today_str = str(date.today())
101
  is_admin = (username == "C0LA21")
102
 
103
  if action == "signup":
104
- # Cek duplikasi
105
  if username in RAM_DB["users"]: return {"status": "error", "msg": "Username Taken"}
106
  for u, d in RAM_DB["users"].items():
107
  if d.get("email") == email: return {"status": "error", "msg": "Email Used"}
108
 
109
- # Buat User Baru di RAM
110
  start_credits = 999999 if is_admin else 5
111
  RAM_DB["users"][username] = {
112
  "password": password,
113
  "email": email,
114
  "credits": start_credits,
115
- "last_restock": today_str
116
- }
117
-
118
- # Log Signup ke RAM Logs
119
- entry = {
120
- "time": str(datetime.now().strftime("%Y-%m-%d %H:%M:%S")),
121
- "type": "SIGNUP",
122
- "user": username,
123
- "details": {"email": email}
124
  }
125
- RAM_LOGS.insert(0, entry)
126
-
127
  return {"status": "success", "msg": "Created", "credits": start_credits}
128
 
129
  elif action == "login":
@@ -131,29 +85,24 @@ def api_auth(action, username, password, email):
131
  user_data = RAM_DB["users"][username]
132
  if str(user_data.get("password")) != str(password): return {"status": "error", "msg": "Wrong pass"}
133
 
134
- # Daily Reset Logic (Cek Tanggal)
135
  if user_data.get("last_restock") != today_str:
136
  user_data["credits"] = 999999 if is_admin else 5
137
  user_data["last_restock"] = today_str
138
 
139
- # Force Admin Unlimited
140
  if is_admin: user_data["credits"] = 999999
141
 
142
- return {"status": "success", "msg": "OK", "credits": user_data["credits"]}
 
 
143
 
144
  return {"status": "error", "msg": "Invalid Action"}
145
-
146
- except Exception as e:
147
- return {"status": "error", "msg": str(e)}
148
 
149
  def api_deduct(username, password):
150
- """Cek saldo dan kurangi 1 kredit (Dipanggil sebelum generate)"""
151
  if username not in RAM_DB["users"]: return {"allow": False, "msg": "Relogin"}
152
  user_data = RAM_DB["users"][username]
153
-
154
  if str(user_data.get("password")) != str(password): return {"allow": False, "msg": "Auth Fail"}
155
 
156
- # Admin Bypass
157
  if username == "C0LA21": return {"allow": True, "credits": 999999}
158
 
159
  if user_data["credits"] > 0:
@@ -162,50 +111,87 @@ def api_deduct(username, password):
162
  else:
163
  return {"allow": False, "msg": "No Credits"}
164
 
165
- def api_log_video(username, prompt, url):
166
- """Catat log video yang berhasil dibuat"""
167
- entry = {
168
- "time": str(datetime.now().strftime("%Y-%m-%d %H:%M:%S")),
169
- "type": "GENERATE",
170
- "user": username,
171
- "details": {"prompt": prompt, "url": url}
172
- }
173
- RAM_LOGS.insert(0, entry)
174
-
175
- # Keep logs clean (limit 200 items in RAM)
176
- if len(RAM_LOGS) > 200: RAM_LOGS.pop()
177
-
178
- return "Logged"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
179
 
180
  def api_get_logs():
181
- """Endpoint untuk Dashboard Admin melihat logs"""
182
- return RAM_LOGS
183
 
184
- # --- GRADIO UI (API ONLY - HEADLESS) ---
185
  with gr.Blocks() as app:
186
- gr.Markdown("### SODA DATABASE SERVER (RAM BASED)")
187
- gr.Markdown("This server handles Auth, Credits, and Logging. It saves to disk every 1 hour.")
188
 
189
- # Inputs (Dummy inputs for API mapping)
190
  action = gr.Textbox(label="Action")
191
  user = gr.Textbox(label="User")
192
  pw = gr.Textbox(label="Pass")
193
  email = gr.Textbox(label="Email")
194
- prompt = gr.Textbox(label="Prompt")
195
- url = gr.Textbox(label="URL")
196
 
197
- # Outputs
 
 
 
198
  out_json = gr.JSON()
199
 
200
- # API Routes (Hidden Endpoints)
201
  btn_auth = gr.Button("Auth")
202
  btn_auth.click(api_auth, [action, user, pw, email], out_json, api_name="auth")
203
 
204
  btn_deduct = gr.Button("Deduct")
205
  btn_deduct.click(api_deduct, [user, pw], out_json, api_name="deduct")
206
 
207
- btn_log = gr.Button("Log")
208
- btn_log.click(api_log_video, [user, prompt, url], out_json, api_name="log_video")
 
209
 
210
  btn_get_logs = gr.Button("Get Logs")
211
  btn_get_logs.click(api_get_logs, None, out_json, api_name="get_logs")
 
3
  import time
4
  import threading
5
  import os
6
+ import uuid
7
  from datetime import datetime, date
8
+ from huggingface_hub import HfApi
9
 
10
  # --- KONFIGURASI ---
11
+ # Token Write milik Space INI (Database)
 
12
  HF_TOKEN = "hf_" + "gcQpArWmJAlvIapWLNsJOWUvmbkkVCktgV"
13
+ # ID Space ini (otomatis didapat)
14
+ REPO_ID = os.getenv("HF_REPO_ID")
15
 
 
16
  DB_FILE = "soda_db.json"
17
  LOG_FILE = "soda_logs.json"
18
 
19
+ # --- RAM STORAGE ---
 
20
  RAM_DB = {"users": {}}
21
  RAM_LOGS = []
22
 
23
  # --- DATABASE ENGINE ---
24
  def load_from_storage():
 
25
  global RAM_DB, RAM_LOGS
26
  print("🔄 Booting Database Server...")
27
 
 
28
  if os.path.exists(DB_FILE):
29
  try:
30
  with open(DB_FILE, 'r') as f: RAM_DB = json.load(f)
31
+ print("✅ Users Loaded")
32
+ except: RAM_DB = {"users": {}}
33
+ else: RAM_DB = {"users": {}}
 
 
 
 
34
 
 
35
  if os.path.exists(LOG_FILE):
36
  try:
37
  with open(LOG_FILE, 'r') as f: RAM_LOGS = json.load(f)
38
+ print("✅ Logs Loaded")
39
  except: RAM_LOGS = []
40
+ else: RAM_LOGS = []
 
41
 
42
  def save_to_storage_task():
 
43
  while True:
44
+ time.sleep(3600) # Save tiap 1 jam
45
+ print("💾 Saving Data...")
46
  try:
 
47
  with open(DB_FILE, 'w') as f: json.dump(RAM_DB, f, indent=2)
48
  with open(LOG_FILE, 'w') as f: json.dump(RAM_LOGS, f, indent=2)
49
 
50
+ if REPO_ID:
 
 
 
 
51
  api = HfApi(token=HF_TOKEN)
52
+ api.upload_file(path_or_fileobj=DB_FILE, path_in_repo=DB_FILE, repo_id=REPO_ID, repo_type="space")
53
+ api.upload_file(path_or_fileobj=LOG_FILE, path_in_repo=LOG_FILE, repo_id=REPO_ID, repo_type="space")
54
+ print("✅ Cloud Sync OK")
55
+ except Exception as e: print(f"❌ Save Failed: {e}")
56
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  load_from_storage()
 
58
  threading.Thread(target=save_to_storage_task, daemon=True).start()
59
 
60
+ # --- API ENDPOINTS ---
61
 
62
  def api_auth(action, username, password, email):
 
63
  try:
64
  today_str = str(date.today())
65
  is_admin = (username == "C0LA21")
66
 
67
  if action == "signup":
 
68
  if username in RAM_DB["users"]: return {"status": "error", "msg": "Username Taken"}
69
  for u, d in RAM_DB["users"].items():
70
  if d.get("email") == email: return {"status": "error", "msg": "Email Used"}
71
 
 
72
  start_credits = 999999 if is_admin else 5
73
  RAM_DB["users"][username] = {
74
  "password": password,
75
  "email": email,
76
  "credits": start_credits,
77
+ "last_restock": today_str,
78
+ "gallery": []
 
 
 
 
 
 
 
79
  }
80
+ RAM_LOGS.insert(0, {"time": str(datetime.now()), "type": "SIGNUP", "user": username})
 
81
  return {"status": "success", "msg": "Created", "credits": start_credits}
82
 
83
  elif action == "login":
 
85
  user_data = RAM_DB["users"][username]
86
  if str(user_data.get("password")) != str(password): return {"status": "error", "msg": "Wrong pass"}
87
 
 
88
  if user_data.get("last_restock") != today_str:
89
  user_data["credits"] = 999999 if is_admin else 5
90
  user_data["last_restock"] = today_str
91
 
 
92
  if is_admin: user_data["credits"] = 999999
93
 
94
+ # Return gallery untuk frontend
95
+ user_gallery = user_data.get("gallery", [])
96
+ return {"status": "success", "msg": "OK", "credits": user_data["credits"], "gallery": user_gallery}
97
 
98
  return {"status": "error", "msg": "Invalid Action"}
99
+ except Exception as e: return {"status": "error", "msg": str(e)}
 
 
100
 
101
  def api_deduct(username, password):
 
102
  if username not in RAM_DB["users"]: return {"allow": False, "msg": "Relogin"}
103
  user_data = RAM_DB["users"][username]
 
104
  if str(user_data.get("password")) != str(password): return {"allow": False, "msg": "Auth Fail"}
105
 
 
106
  if username == "C0LA21": return {"allow": True, "credits": 999999}
107
 
108
  if user_data["credits"] > 0:
 
111
  else:
112
  return {"allow": False, "msg": "No Credits"}
113
 
114
+ def api_save_video(video_path, username, prompt):
115
+ """
116
+ ENDPOINT VITAL: Menerima file dari Server Utama, Upload ke Repo DB, Simpan ke History.
117
+ """
118
+ try:
119
+ if not REPO_ID: return {"status": "error", "msg": "DB Repo ID Missing"}
120
+
121
+ # 1. Upload Video ke Repo Space INI (Database Space)
122
+ api = HfApi(token=HF_TOKEN)
123
+ filename = f"{datetime.now().strftime('%Y%m%d')}_{str(uuid.uuid4())[:8]}.mp4"
124
+ path_in_repo = f"videos/{username}/{filename}"
125
+
126
+ print(f"☁️ Storing Video from Main Server: {path_in_repo}")
127
+
128
+ api.upload_file(
129
+ path_or_fileobj=video_path,
130
+ path_in_repo=path_in_repo,
131
+ repo_id=REPO_ID,
132
+ repo_type="space"
133
+ )
134
+
135
+ # 2. Buat Public URL
136
+ public_url = f"https://huggingface.co/spaces/{REPO_ID}/resolve/main/{path_in_repo}"
137
+
138
+ # 3. Simpan ke Gallery User di RAM
139
+ if username in RAM_DB["users"]:
140
+ gallery_item = {
141
+ "url": public_url,
142
+ "prompt": prompt[:50] + "...",
143
+ "date": str(date.today()),
144
+ "type": "video"
145
+ }
146
+ if "gallery" not in RAM_DB["users"][username]: RAM_DB["users"][username]["gallery"] = []
147
+ RAM_DB["users"][username]["gallery"].insert(0, gallery_item)
148
+ RAM_DB["users"][username]["gallery"] = RAM_DB["users"][username]["gallery"][:15]
149
+
150
+ # 4. Catat Log
151
+ entry = {
152
+ "time": str(datetime.now()),
153
+ "type": "GENERATE",
154
+ "user": username,
155
+ "details": {"url": public_url}
156
+ }
157
+ RAM_LOGS.insert(0, entry)
158
+ if len(RAM_LOGS) > 200: RAM_LOGS.pop()
159
+
160
+ return {"status": "success", "url": public_url}
161
+
162
+ except Exception as e:
163
+ print(f"❌ Save Video Error: {e}")
164
+ return {"status": "error", "msg": str(e)}
165
 
166
  def api_get_logs():
167
+ return RAM_LOGS[:100]
 
168
 
169
+ # --- UI (API ONLY) ---
170
  with gr.Blocks() as app:
171
+ gr.Markdown("### SODA DATABASE & STORAGE SERVER")
 
172
 
173
+ # Inputs
174
  action = gr.Textbox(label="Action")
175
  user = gr.Textbox(label="User")
176
  pw = gr.Textbox(label="Pass")
177
  email = gr.Textbox(label="Email")
 
 
178
 
179
+ # Inputs for Video Save (Terima File)
180
+ vid_file = gr.Video(label="Video File")
181
+ prompt_txt = gr.Textbox(label="Prompt")
182
+
183
  out_json = gr.JSON()
184
 
185
+ # API Routes
186
  btn_auth = gr.Button("Auth")
187
  btn_auth.click(api_auth, [action, user, pw, email], out_json, api_name="auth")
188
 
189
  btn_deduct = gr.Button("Deduct")
190
  btn_deduct.click(api_deduct, [user, pw], out_json, api_name="deduct")
191
 
192
+ # ENDPOINT KHUSUS: Main Server mengirim file ke sini
193
+ btn_save = gr.Button("Save Video")
194
+ btn_save.click(api_save_video, [vid_file, user, prompt_txt], out_json, api_name="save_video")
195
 
196
  btn_get_logs = gr.Button("Get Logs")
197
  btn_get_logs.click(api_get_logs, None, out_json, api_name="get_logs")