Zhu-FaceOnLive commited on
Commit
e500d0d
Β·
verified Β·
1 Parent(s): 8921763

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +77 -147
app.py CHANGED
@@ -1,142 +1,47 @@
1
  import os
2
  import gradio as gr
3
- import requests
4
- import base64
5
  from io import BytesIO
6
- from PIL import Image
7
- import hashlib
8
- import concurrent.futures
9
  import zipfile
10
  import tempfile
 
 
 
 
 
11
 
12
- # Constants
13
- FREE_URL = os.environ.get("SERVER_URL_FREE")
14
- PREMIUM_URL = os.environ.get("SERVER_URL_PREMIUM")
15
- PREMIUM_URL2 = os.environ.get("SERVER_URL_PREMIUM2")
16
- TOKEN_SERVER_URL = os.environ.get("TOKEN_URL")
17
- API_KEY = os.environ.get("API_KEY")
18
 
19
  STATUS_MESSAGES = {
20
- 301: "Too many faces in the photo.",
21
- 302: "Face is not clear enough.",
22
- 303: "No matches found. Try Deep Search with premium token.",
23
- 304: "No face in the photo.",
24
- 305: "Search blocked for privacy issue.",
25
- 401: "Invalid image format.",
26
- 402: "Wrong request.",
27
- 403: "Please try again later.",
28
- 404: "Timeout, try again."
29
  }
30
- FREE_SUFFIX = "*********"
31
 
32
- def image_to_base64(image):
33
- buffered = BytesIO()
34
- image.save(buffered, format="JPEG", quality=90)
35
- return base64.b64encode(buffered.getvalue()).decode('utf-8')
36
 
37
  def base64_to_image(base64_str):
38
  return base64.b64decode(base64_str + '=' * (-len(base64_str) % 4))
39
 
40
- def check_db(img_array, suffix):
41
- hashes = []
42
- out_array = []
43
- for item in img_array:
44
- try:
45
- image_data = base64_to_image(item["image"])
46
- image_hash = hashlib.sha256(image_data).hexdigest()
47
- hashes.append(image_hash)
48
- out_array.append((Image.open(BytesIO(image_data)), item["url"] + suffix))
49
- except base64.binascii.Error as e:
50
- raise ValueError(f"Invalid base64 string: {str(e)}")
51
- except Exception as e:
52
- raise ValueError(f"Error processing image: {str(e)}")
53
-
54
- try:
55
- response = requests.post(url=TOKEN_SERVER_URL + '/lookup-hashes', json={"hashes": hashes})
56
- out_array = [value for i, value in enumerate(out_array) if i not in response.json().get('res')]
57
- except:
58
- raise gr.Error("Token Server Error!")
59
-
60
- return out_array
61
-
62
- def verify_token(token):
63
- try:
64
- response = requests.post(url=TOKEN_SERVER_URL + '/verify-token', json={"token": token})
65
- if response.json().get('status') == 'success':
66
- return PREMIUM_URL
67
- else:
68
- raise gr.Error("Invalid token! For free search, use empty string for token")
69
- except:
70
- raise gr.Error("Invalid token!")
71
-
72
- def activate_token(token):
73
- try:
74
- requests.post(url=TOKEN_SERVER_URL + '/activate-token', json={"token": token})
75
- except:
76
- raise gr.Error("Invalid token!")
77
-
78
- def get_image_base64(file):
79
- try:
80
- image = Image.open(file)
81
- return image_to_base64(image)
82
- except Exception as e:
83
- raise gr.Error("Please select image file!")
84
-
85
- def send_requests(url, file):
86
- with concurrent.futures.ThreadPoolExecutor() as executor:
87
- future1 = executor.submit(requests.post, url, headers={"X-RapidAPI-Key": API_KEY}, json={"image": get_image_base64(file)})
88
- if url == PREMIUM_URL:
89
- future2 = executor.submit(requests.post, PREMIUM_URL2, files={"image": open(file, 'rb')})
90
- response1 = future1.result()
91
- response2 = future2.result()
92
- return response1, response2
93
- else:
94
- response1 = future1.result()
95
- return response1, None
96
-
97
- def process_response(response, soc_res, url, token):
98
- status_code = response.status_code
99
-
100
- if not soc_res:
101
- if status_code in STATUS_MESSAGES:
102
- gr.Info(STATUS_MESSAGES[status_code])
103
-
104
- if status_code > 300:
105
- return []
106
-
107
- try:
108
- res = response.json().get('img_array', []) if status_code in [201, 202] else []
109
- if soc_res:
110
- res = soc_res[0] + res + soc_res[1]
111
-
112
- suffix = "" if url == PREMIUM_URL else FREE_SUFFIX
113
- out_array = check_db(res, suffix)
114
-
115
- if url == PREMIUM_URL:
116
- activate_token(token)
117
-
118
- return out_array
119
- except:
120
- raise gr.Error("Try again.")
121
-
122
- def process_response2(response):
123
- if response.status_code == 200:
124
- part1 = response.json().get('part1')
125
- part2 = response.json().get('part2')
126
-
127
- if not part1 and not part2:
128
- return None
129
- return (part1, part2)
130
- return None
131
-
132
  def search_face(file, token=None):
133
- url = FREE_URL
134
- if token:
135
- url = verify_token(token)
136
-
137
- response1, response2 = send_requests(url, file)
138
- soc_res = process_response2(response2) if response2 else None
139
- return process_response(response1, soc_res, url, token)
 
 
 
 
 
 
 
 
 
 
 
140
 
141
  def export_images(items):
142
  if not items:
@@ -145,10 +50,14 @@ def export_images(items):
145
  zip_buffer = BytesIO()
146
  with zipfile.ZipFile(zip_buffer, 'w') as zip_file:
147
  url_text = ""
148
- for i, item in enumerate(items):
 
 
 
149
  with open(item[0], 'rb') as img_file:
150
  zip_file.writestr(f'image_{i}.jpg', img_file.read())
151
  url_text += f"image_{i}.jpg: {item[1]}\n"
 
152
  zip_file.writestr("urls.txt", url_text)
153
  zip_buffer.seek(0)
154
 
@@ -164,10 +73,14 @@ caption.caption {
164
  cursor: text;
165
  }
166
 
167
- div#component-16 {
168
  max-height: 63.39px;
169
  }
170
 
 
 
 
 
171
  .svelte-snayfm {
172
  height: auto;
173
  }
@@ -197,7 +110,6 @@ links.forEach(link => {
197
  }
198
  });
199
  link.setAttribute('href', targetUrl.toString());
200
- console.log(`Updated Link: ${targetUrl.toString()}`);
201
  }
202
  });
203
 
@@ -217,7 +129,7 @@ head = """
217
  </script>
218
  """
219
 
220
- output = gr.Gallery(label="Found Images", columns=[4], object_fit="contain", height="auto", interactive=False)
221
  col2 = gr.Column(scale=2, visible=False)
222
 
223
  def init_ui():
@@ -229,23 +141,39 @@ def search_ui():
229
  def search_face_examples(image):
230
  return search_face(image), gr.update(visible=False), gr.update(visible=True)
231
 
232
- with gr.Blocks(css=custom_css, head=head, delete_cache=(3600, 3600)) as demo:
233
- gr.Markdown(
234
- """
235
- # Free Face Search Online - If this space was helpful, please like ❀️ above!
236
- #### [Discover more about our Face Search on our website.](https://faceonlive.com/face-search-online)
237
  #### [Check out our Face Search API integration and affiliate program here.](https://portfolio.faceonlive.com/#face_search)
238
- <br>
239
- """
240
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
241
  with gr.Row():
242
  with gr.Column(scale=1) as col1:
243
- image = gr.Image(type='filepath', height=480)
244
- token = gr.Textbox(placeholder="(Optional) Get Premium Token Below.", label="Premium Token")
245
- gr.HTML("<a href='https://faceonlive.pocketsflow.com/checkout?productId=676c15b1971244a587ca07cb' target='_blank' style='font-size: 16px;'>Get Premium Token: Deep Search Including Social Media & Full URL Reveal</a>")
246
- gr.HTML("<a href='https://faceonlive.pocketsflow.com/checkout?productId=676d7e7597f8b3b699f84820' target='_blank' style='font-size: 16px;'>Protect Your Privacy – Start Your Takedown Now</a>")
247
- search_face_button = gr.Button("Search Face")
248
- gr.Examples(['examples/1.jpg', 'examples/2.jpg'], inputs=image, cache_examples=True, cache_mode='eager', fn=search_face_examples, outputs=[output, col1, col2])
 
 
 
 
 
249
 
250
  with col2.render():
251
  gr.Markdown("> ### **⚠️ Reminder:** Export images before refreshing the page by clicking the 'Export Images' button.")
@@ -253,19 +181,21 @@ with gr.Blocks(css=custom_css, head=head, delete_cache=(3600, 3600)) as demo:
253
  with gr.Row():
254
  export_button = gr.Button("Export Images")
255
  export_file = gr.File(label="Download")
256
- gr.HTML("<a href='https://faceonlive.pocketsflow.com/checkout?productId=676c15b1971244a587ca07cb' target='_blank' style='font-size: 16px;'>Get Premium Token: Deep Search Including Social Media & Full URL Reveal</a>")
257
- gr.HTML("<a href='https://faceonlive.pocketsflow.com/checkout?productId=676d7e7597f8b3b699f84820' target='_blank' style='font-size: 16px;'>Protect Your Privacy – Start Your Takedown Now</a>")
 
 
 
258
  new_search_button = gr.Button("πŸš€ Try New Search")
259
-
260
 
261
  search_face_button.click(search_ui, inputs=[], outputs=[col1, col2], api_name=False)
262
  search_face_button.click(search_face, inputs=[image, token], outputs=[output], api_name=False)
263
  export_button.click(export_images, inputs=[output], outputs=export_file, api_name=False)
264
-
265
  new_search_button.click(init_ui, inputs=[], outputs=[col1, col2], api_name=False)
266
 
267
  gr.HTML('<a href="https://visitorbadge.io/status?path=https%3A%2F%2Fhuggingface.co%2Fspaces%2FFaceOnLive%2FFace-Search-Online"><img src="https://api.visitorbadge.io/api/visitors?path=https%3A%2F%2Fhuggingface.co%2Fspaces%2FFaceOnLive%2FFace-Search-Online&labelColor=%23ff8a65&countColor=%2337d67a&style=flat&labelStyle=upper" /></a>')
268
  html = gr.HTML()
269
  demo.load(None, inputs=None, outputs=html, js=js)
270
 
271
- demo.queue(api_open=False, default_concurrency_limit=8).launch(server_name="0.0.0.0", server_port=7860, show_api=False)
 
1
  import os
2
  import gradio as gr
 
 
3
  from io import BytesIO
 
 
 
4
  import zipfile
5
  import tempfile
6
+ import random
7
+ import json
8
+ from gradio_client import Client, handle_file
9
+ import base64
10
+ from PIL import Image
11
 
12
+ BACKEND = os.getenv("BACKEND")
13
+ TOKEN = os.getenv("TOKEN")
14
+ BUY_PREMIUM = "πŸ₯‡ Get Premium Token to Unlock"
 
 
 
15
 
16
  STATUS_MESSAGES = {
17
+ 201: "Not satisfied with the results? Get a Premium Token for instant, deeper results including social profiles.",
18
+ 301: "Invalid token! Get Premium Token using link in page"
 
 
 
 
 
 
 
19
  }
 
20
 
21
+ backend = Client(BACKEND, hf_token=TOKEN)
 
 
 
22
 
23
  def base64_to_image(base64_str):
24
  return base64.b64decode(base64_str + '=' * (-len(base64_str) % 4))
25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  def search_face(file, token=None):
27
+ result_text = backend.predict(
28
+ file=handle_file(file),
29
+ token=token,
30
+ api_name="/search_face"
31
+ )
32
+
33
+ result = json.loads(result_text)
34
+ outarray = []
35
+ if result['status'] > 300:
36
+ raise gr.Error(STATUS_MESSAGES[result['status']])
37
+
38
+ for item in result['result']:
39
+ image = Image.open(BytesIO(base64_to_image(item['image'])))
40
+ outarray.append((image, item['url']))
41
+
42
+ if result['status'] == 201:
43
+ gr.Info(STATUS_MESSAGES[result['status']], duration=8)
44
+ return outarray
45
 
46
  def export_images(items):
47
  if not items:
 
50
  zip_buffer = BytesIO()
51
  with zipfile.ZipFile(zip_buffer, 'w') as zip_file:
52
  url_text = ""
53
+ i = 1
54
+ for item in items:
55
+ if item[1] == BUY_PREMIUM:
56
+ continue
57
  with open(item[0], 'rb') as img_file:
58
  zip_file.writestr(f'image_{i}.jpg', img_file.read())
59
  url_text += f"image_{i}.jpg: {item[1]}\n"
60
+ i += 1
61
  zip_file.writestr("urls.txt", url_text)
62
  zip_buffer.seek(0)
63
 
 
73
  cursor: text;
74
  }
75
 
76
+ div#component-21 {
77
  max-height: 63.39px;
78
  }
79
 
80
+ div#component-9 {
81
+ background-color: tomato;
82
+ }
83
+
84
  .svelte-snayfm {
85
  height: auto;
86
  }
 
110
  }
111
  });
112
  link.setAttribute('href', targetUrl.toString());
 
113
  }
114
  });
115
 
 
129
  </script>
130
  """
131
 
132
+ output = gr.Gallery(label="Found Images (The search may take a couple of minutes.)", columns=[3], object_fit="contain", height="480px", interactive=False)
133
  col2 = gr.Column(scale=2, visible=False)
134
 
135
  def init_ui():
 
141
  def search_face_examples(image):
142
  return search_face(image), gr.update(visible=False), gr.update(visible=True)
143
 
144
+ MARKDOWN0 = """
145
+ # Free Face Search Online
 
 
 
146
  #### [Check out our Face Search API integration and affiliate program here.](https://portfolio.faceonlive.com/#face_search)
147
+ """
148
+ MARKDOWN1 = """
149
+ ### [Get Premium Token - Deep Search & Social Media Access](https://faceonlive.pocketsflow.com/checkout?productId=676c15b1971244a587ca07cb)
150
+ ### [Protect Your Privacy – Start Your Takedown Now](https://faceonlive.pocketsflow.com/checkout?productId=676d7e7597f8b3b699f84820)
151
+ """
152
+ MARKDOWN2 = """
153
+ ### [Why Get the Premium Token?](https://faceonlive.pocketsflow.com/checkout?productId=676c15b1971244a587ca07cb)
154
+ βœ… **Deep Search**
155
+ βœ… **Social Media and Deep Web Scan**
156
+ βœ… **Exclusive Access to Hidden Profiles**
157
+ βœ… **No Subscription Needed**
158
+ """
159
+ MARKDOWN3 = """
160
+ <div align="right"><a href="https://faceonlive.com/reverse-image-search" target='_blank' style='font-size: 16px;'>Looking For Reverse Image Search</div>
161
+ """
162
+ with gr.Blocks(css=custom_css, head=head, delete_cache=(3600, 3600)) as demo:
163
+ gr.Markdown(MARKDOWN0)
164
  with gr.Row():
165
  with gr.Column(scale=1) as col1:
166
+ image = gr.Image(type='filepath', height=360)
167
+ with gr.Row():
168
+ with gr.Column():
169
+ token = gr.Textbox(placeholder="(Optional) Get Premium Token Below.", label="Premium Token")
170
+ gr.Markdown(MARKDOWN1)
171
+ with gr.Column():
172
+ md_premium1 = gr.Markdown(MARKDOWN2)
173
+ with gr.Row():
174
+ search_face_button = gr.Button("Reverse Face Search")
175
+ gr.HTML(MARKDOWN3)
176
+ gr.Examples(['examples/1.jpg', 'examples/2.jpg'], inputs=image, cache_examples=True, fn=search_face_examples, outputs=[output, col1, col2])
177
 
178
  with col2.render():
179
  gr.Markdown("> ### **⚠️ Reminder:** Export images before refreshing the page by clicking the 'Export Images' button.")
 
181
  with gr.Row():
182
  export_button = gr.Button("Export Images")
183
  export_file = gr.File(label="Download")
184
+ with gr.Row():
185
+ with gr.Column():
186
+ gr.Markdown(MARKDOWN1)
187
+ with gr.Column():
188
+ md_premium2 = gr.Markdown(MARKDOWN2)
189
  new_search_button = gr.Button("πŸš€ Try New Search")
190
+ gr.HTML(MARKDOWN3)
191
 
192
  search_face_button.click(search_ui, inputs=[], outputs=[col1, col2], api_name=False)
193
  search_face_button.click(search_face, inputs=[image, token], outputs=[output], api_name=False)
194
  export_button.click(export_images, inputs=[output], outputs=export_file, api_name=False)
 
195
  new_search_button.click(init_ui, inputs=[], outputs=[col1, col2], api_name=False)
196
 
197
  gr.HTML('<a href="https://visitorbadge.io/status?path=https%3A%2F%2Fhuggingface.co%2Fspaces%2FFaceOnLive%2FFace-Search-Online"><img src="https://api.visitorbadge.io/api/visitors?path=https%3A%2F%2Fhuggingface.co%2Fspaces%2FFaceOnLive%2FFace-Search-Online&labelColor=%23ff8a65&countColor=%2337d67a&style=flat&labelStyle=upper" /></a>')
198
  html = gr.HTML()
199
  demo.load(None, inputs=None, outputs=html, js=js)
200
 
201
+ demo.queue(api_open=False, default_concurrency_limit=8).launch(show_api=False)