bk939448 commited on
Commit
9478d05
Β·
verified Β·
1 Parent(s): 490ce53

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +79 -26
app.py CHANGED
@@ -3,9 +3,10 @@ import io
3
  import time
4
  import requests
5
  import base64
 
6
  from flask import Flask, request, jsonify, render_template_string
7
  from PIL import Image, ImageOps
8
- from huggingface_hub import HfApi
9
 
10
  app = Flask(__name__)
11
 
@@ -17,18 +18,66 @@ XOR_KEY = os.environ.get("XOR_KEY", "badal_master_key") # Tumhari Secret Chabi
17
 
18
  Image.MAX_IMAGE_PIXELS = None
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  # --- πŸ” XOR ENCRYPTION ENGINE ---
21
  def xor_encrypt_decrypt_bytes(data: bytes, key: str) -> bytes:
22
  """Image ke binary data ko corrupt/decrypt karta hai"""
23
  key_bytes = key.encode()
24
  key_len = len(key_bytes)
25
- # Python me bytes ko XOR karna
26
  return bytes([b ^ key_bytes[i % key_len] for i, b in enumerate(data)])
27
 
28
  def encrypt_filename(filename: str, key: str) -> str:
29
  """Filename ko encrypt karke base64 URL-safe banata hai"""
30
  xored = "".join(chr(ord(c) ^ ord(key[i % len(key)])) for i, c in enumerate(filename))
31
- # Padding hata dete hain taaki URL clean dikhe
32
  return base64.urlsafe_b64encode(xored.encode()).decode().rstrip("=")
33
 
34
  # --- 🧠 SUPER-OPTIMIZER LOGIC ---
@@ -79,12 +128,10 @@ def handle_upload():
79
  return jsonify({"success": False, "error": "HF Secrets missing!"}), 500
80
 
81
  try:
82
- # 1. Check if Direct File Upload
83
  if 'file' in request.files and request.files['file'].filename != '':
84
  file = request.files['file']
85
  image_content = file.read()
86
 
87
- # 2. Check if URL Upload
88
  elif request.args.get('url') or request.form.get('url'):
89
  img_url = request.args.get('url') or request.form.get('url')
90
  resp = requests.get(img_url, timeout=20)
@@ -95,36 +142,28 @@ def handle_upload():
95
  if not image_content:
96
  return jsonify({"success": False, "error": "No file or URL provided"}), 400
97
 
98
- # 3. Optimize Image
99
  optimized_data = dynamic_optimize(image_content, comp_level)
100
-
101
- # 4. πŸ” ENCRYPT THE IMAGE DATA (Magic Happens Here!)
102
  encrypted_image_data = xor_encrypt_decrypt_bytes(optimized_data, XOR_KEY)
103
 
104
- # 5. Generate Real Filename & Encrypt it
105
  real_filename = f"img_{int(time.time())}_{os.urandom(3).hex()}.webp"
106
  encrypted_filename = encrypt_filename(real_filename, XOR_KEY)
107
 
108
- path_in_repo = f"posters/{real_filename}"
 
 
 
109
 
110
- # 6. Upload ENCRYPTED GARBAGE to Hugging Face
111
- api = HfApi()
112
- api.upload_file(
113
- path_or_fileobj=encrypted_image_data, # Uploading corrupted bytes
114
- path_in_repo=path_in_repo,
115
- repo_id=HF_REPO,
116
- repo_type="dataset",
117
- token=HF_TOKEN
118
- )
119
-
120
- # 7. Create Final Worker URL for User
121
  worker_base = WORKER_URL if WORKER_URL.endswith('/') else WORKER_URL + '/'
122
  final_cf_url = f"{worker_base}{encrypted_filename}"
123
 
 
124
  return jsonify({
125
  "success": True,
126
- "url": final_cf_url, # Cloudflare Worker URL with Encrypted Name
127
- "real_hf_filename": real_filename, # (Just for debugging, DB me mat dalna)
128
  "level_used": comp_level,
129
  "original_size_kb": round(len(image_content)/1024, 2),
130
  "encrypted_size_kb": round(len(encrypted_image_data)/1024, 2)
@@ -158,6 +197,7 @@ HTML_UI = """
158
  .url-box { background: #0f172a; padding: 12px; border: 1px solid #059669; border-radius: 6px; margin: 10px 0; font-family: monospace; font-size: 13px; color: #34d399; overflow-x: auto; white-space: nowrap; }
159
  .stats { display: flex; justify-content: space-between; font-size: 13px; margin-top: 15px; background: rgba(0,0,0,0.2); padding: 8px 12px; border-radius: 6px; }
160
  .preview-img { max-width: 100%; border-radius: 8px; margin-top: 15px; border: 1px solid #334155; display: block; }
 
161
  @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
162
  .copy-btn { background: #334155; color: #fff; padding: 5px 10px; font-size: 11px; border-radius: 4px; border: none; cursor: pointer; float: right; margin-top: -35px; margin-right: 5px; }
163
  </style>
@@ -198,7 +238,12 @@ HTML_UI = """
198
  <span>Original: <span id="oldSize">--</span> KB</span>
199
  <span style="color: #34d399;">Optimized: <span id="newSize">--</span> KB</span>
200
  </div>
201
- <img id="resImg" class="preview-img" src="" alt="Preview">
 
 
 
 
 
202
  </div>
203
  </div>
204
 
@@ -229,7 +274,15 @@ HTML_UI = """
229
  document.getElementById('resLink').innerText = data.url;
230
  document.getElementById('oldSize').innerText = data.original_size_kb;
231
  document.getElementById('newSize').innerText = data.encrypted_size_kb;
232
- document.getElementById('resImg').src = data.url;
 
 
 
 
 
 
 
 
233
  resDiv.style.display = "block";
234
  } else {
235
  alert("Processing Error: " + data.error);
@@ -256,4 +309,4 @@ def index():
256
  return render_template_string(HTML_UI)
257
 
258
  if __name__ == '__main__':
259
- app.run(host='0.0.0.0', port=7860)
 
3
  import time
4
  import requests
5
  import base64
6
+ import threading
7
  from flask import Flask, request, jsonify, render_template_string
8
  from PIL import Image, ImageOps
9
+ from huggingface_hub import HfApi, CommitOperationAdd
10
 
11
  app = Flask(__name__)
12
 
 
18
 
19
  Image.MAX_IMAGE_PIXELS = None
20
 
21
+ # --- πŸ“ LOCAL STORAGE SETUP (Queue ke liye) ---
22
+ PENDING_DIR = "pending_uploads"
23
+ os.makedirs(PENDING_DIR, exist_ok=True)
24
+
25
+ # --- πŸ”„ BACKGROUND BATCH UPLOADER (Har 45 seconds) ---
26
+ def background_uploader():
27
+ api = HfApi()
28
+ while True:
29
+ time.sleep(45) # ⏱️ 45 Second Timer
30
+ try:
31
+ files_to_upload = os.listdir(PENDING_DIR)
32
+ if not files_to_upload:
33
+ continue
34
+
35
+ print(f"πŸš€ [BATCH UPLOAD] {len(files_to_upload)} files ko ek saath upload kar rahe hain...")
36
+
37
+ operations = []
38
+ uploaded_files = []
39
+
40
+ for filename in files_to_upload:
41
+ file_path = os.path.join(PENDING_DIR, filename)
42
+ operations.append(
43
+ CommitOperationAdd(
44
+ path_in_repo=f"posters/{filename}",
45
+ path_or_fileobj=file_path
46
+ )
47
+ )
48
+ uploaded_files.append(file_path)
49
+
50
+ # Single Commit on Hugging Face
51
+ api.create_commit(
52
+ repo_id=HF_REPO,
53
+ repo_type="dataset",
54
+ token=HF_TOKEN,
55
+ operations=operations,
56
+ commit_message=f"Batch upload of {len(operations)} images by OptiPix"
57
+ )
58
+ print("βœ… [BATCH UPLOAD] Success! Local files delete kar rahe hain...")
59
+
60
+ for f in uploaded_files:
61
+ try:
62
+ os.remove(f)
63
+ except:
64
+ pass
65
+ except Exception as e:
66
+ print(f"❌ [BATCH UPLOAD] Error: {e}")
67
+
68
+ # App start hote hi background thread on
69
+ threading.Thread(target=background_uploader, daemon=True).start()
70
+
71
  # --- πŸ” XOR ENCRYPTION ENGINE ---
72
  def xor_encrypt_decrypt_bytes(data: bytes, key: str) -> bytes:
73
  """Image ke binary data ko corrupt/decrypt karta hai"""
74
  key_bytes = key.encode()
75
  key_len = len(key_bytes)
 
76
  return bytes([b ^ key_bytes[i % key_len] for i, b in enumerate(data)])
77
 
78
  def encrypt_filename(filename: str, key: str) -> str:
79
  """Filename ko encrypt karke base64 URL-safe banata hai"""
80
  xored = "".join(chr(ord(c) ^ ord(key[i % len(key)])) for i, c in enumerate(filename))
 
81
  return base64.urlsafe_b64encode(xored.encode()).decode().rstrip("=")
82
 
83
  # --- 🧠 SUPER-OPTIMIZER LOGIC ---
 
128
  return jsonify({"success": False, "error": "HF Secrets missing!"}), 500
129
 
130
  try:
 
131
  if 'file' in request.files and request.files['file'].filename != '':
132
  file = request.files['file']
133
  image_content = file.read()
134
 
 
135
  elif request.args.get('url') or request.form.get('url'):
136
  img_url = request.args.get('url') or request.form.get('url')
137
  resp = requests.get(img_url, timeout=20)
 
142
  if not image_content:
143
  return jsonify({"success": False, "error": "No file or URL provided"}), 400
144
 
145
+ # Optimize & Encrypt
146
  optimized_data = dynamic_optimize(image_content, comp_level)
 
 
147
  encrypted_image_data = xor_encrypt_decrypt_bytes(optimized_data, XOR_KEY)
148
 
149
+ # Generate Filenames
150
  real_filename = f"img_{int(time.time())}_{os.urandom(3).hex()}.webp"
151
  encrypted_filename = encrypt_filename(real_filename, XOR_KEY)
152
 
153
+ # Save to Local Queue instead of Direct Upload
154
+ local_filepath = os.path.join(PENDING_DIR, real_filename)
155
+ with open(local_filepath, "wb") as f:
156
+ f.write(encrypted_image_data)
157
 
158
+ # Create Final Worker URL
 
 
 
 
 
 
 
 
 
 
159
  worker_base = WORKER_URL if WORKER_URL.endswith('/') else WORKER_URL + '/'
160
  final_cf_url = f"{worker_base}{encrypted_filename}"
161
 
162
+ # Exact Same JSON Response!
163
  return jsonify({
164
  "success": True,
165
+ "url": final_cf_url,
166
+ "real_hf_filename": real_filename,
167
  "level_used": comp_level,
168
  "original_size_kb": round(len(image_content)/1024, 2),
169
  "encrypted_size_kb": round(len(encrypted_image_data)/1024, 2)
 
197
  .url-box { background: #0f172a; padding: 12px; border: 1px solid #059669; border-radius: 6px; margin: 10px 0; font-family: monospace; font-size: 13px; color: #34d399; overflow-x: auto; white-space: nowrap; }
198
  .stats { display: flex; justify-content: space-between; font-size: 13px; margin-top: 15px; background: rgba(0,0,0,0.2); padding: 8px 12px; border-radius: 6px; }
199
  .preview-img { max-width: 100%; border-radius: 8px; margin-top: 15px; border: 1px solid #334155; display: block; }
200
+ .notice-text { color: #fbbf24; font-size: 13.5px; margin-top: 15px; font-weight: 600; text-align: center; background: rgba(251, 191, 36, 0.1); padding: 10px; border-radius: 6px; border: 1px solid rgba(251, 191, 36, 0.3); }
201
  @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
202
  .copy-btn { background: #334155; color: #fff; padding: 5px 10px; font-size: 11px; border-radius: 4px; border: none; cursor: pointer; float: right; margin-top: -35px; margin-right: 5px; }
203
  </style>
 
238
  <span>Original: <span id="oldSize">--</span> KB</span>
239
  <span style="color: #34d399;">Optimized: <span id="newSize">--</span> KB</span>
240
  </div>
241
+
242
+ <div class="notice-text">
243
+ ⏳ Note: The image URL will be live in max 45 seconds.
244
+ </div>
245
+
246
+ <img id="resImg" class="preview-img" src="" alt="Preview will load soon...">
247
  </div>
248
  </div>
249
 
 
274
  document.getElementById('resLink').innerText = data.url;
275
  document.getElementById('oldSize').innerText = data.original_size_kb;
276
  document.getElementById('newSize').innerText = data.encrypted_size_kb;
277
+
278
+ // Pehle image src hatayenge taaki broken image na dikhe timer ke dauran
279
+ document.getElementById('resImg').src = "";
280
+
281
+ // 45 seconds baad automatically image reload karwane ka try karenge preview ke liye
282
+ setTimeout(() => {
283
+ document.getElementById('resImg').src = data.url;
284
+ }, 46000);
285
+
286
  resDiv.style.display = "block";
287
  } else {
288
  alert("Processing Error: " + data.error);
 
309
  return render_template_string(HTML_UI)
310
 
311
  if __name__ == '__main__':
312
+ app.run(host='0.0.0.0', port=7860)