Skydata001 commited on
Commit
8b19f0a
·
verified ·
1 Parent(s): be5ba64

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +185 -157
  2. requirements.txt +1 -0
app.py CHANGED
@@ -7,6 +7,10 @@ import io
7
  import os
8
  import requests
9
  from io import BytesIO
 
 
 
 
10
 
11
  # --- 1. إعدادات الصفحة ---
12
  st.set_page_config(
@@ -14,115 +18,101 @@ st.set_page_config(
14
  layout="wide"
15
  )
16
 
17
- # --- !!! هذا هو الكود الجديد لتغيير التصميم !!! ---
18
  CUSTOM_CSS = """
19
  <style>
 
20
  /* --- 1. الخلفية الرئيسية والخطوط --- */
21
  body, [data-testid="stAppViewContainer"], [data-testid="stHeader"] {
22
- background-color: #121212 !important; /* الخلفية الرئيسية */
23
- color: #e0e0e0 !important;
24
  }
25
  [data-testid="stHeader"] {
26
- background-color: #1e1e1e !important; /* لون شريط الهيدر */
27
- border-bottom: 1px solid #333;
28
- }
29
- h1, h2, h3, h4, h5, h6 {
30
- color: #ffffff !important; /* ألوان العناوين */
31
- }
32
- p, label, [data-testid="stMarkdownContainer"] {
33
- color: #e0e0e0 !important; /* لون النص العادي */
34
  }
 
 
35
 
36
  /* --- 2. الشريط الجانبي (Sidebar) --- */
37
-
38
- /* <<< تم التعديل: استهداف الشريط الجانبي "المفتوح" فقط لحل مشكلة الجلتش */
39
  [data-testid="stSidebar"][aria-expanded="true"] {
40
- background-color: #1e1e1e !important; /* خلفية الشريط الجانبي */
41
- border-right: 1px solid #333 !important; /* <<< تم التعديل: إضافة important */
42
  }
43
-
44
- /* <<< تم التعديل: استهداف الأزرار داخل الشريط الجانبي "المفتوح" فقط */
45
  [data-testid="stSidebar"][aria-expanded="true"] [data-testid="stRadio"] label {
46
- background-color: #2a2a2a;
47
- padding: 10px;
48
- border-radius: 5px;
49
- margin: 5px 0;
50
- transition: all 0.3s ease;
51
  }
52
- /* <<< تم التعديل */
53
  [data-testid="stSidebar"][aria-expanded="true"] [data-testid="stRadio"] label:hover {
54
- background-color: #333;
55
- color: #007bff;
56
  }
57
- /* <<< تم التعديل */
58
  [data-testid="stSidebar"][aria-expanded="true"] [data-testid="stRadio"] input:checked + div {
59
  color: #007bff;
60
  }
61
 
62
  /* --- 3. زر التحميل (Download Button) --- */
63
  [data-testid="stDownloadButton"] > button {
64
- background-color: #007bff !important;
65
- color: #ffffff !important;
66
- border: none !important;
67
- border-radius: 5px !important;
68
- font-weight: bold !important;
69
- padding: 12px 20px !important;
70
- transition: all 0.3s ease !important;
71
- width: 100%;
72
  }
73
  [data-testid="stDownloadButton"] > button:hover {
74
- background-color: #0056b3 !important;
75
- transform: scale(1.03) !important;
76
  }
77
 
78
  /* --- 4. زر رفع الملفات (File Uploader) --- */
79
  [data-testid="stFileUploader"] section {
80
- background-color: #1e1e1e !important; /* خلفية صندوق الرفع */
81
- border: 1px dashed #333 !important;
82
  border-radius: 8px !important;
83
  }
84
- /* زر "Browse files" */
85
  [data-testid="stFileUploader"] section > button {
86
- background-color: #007bff !important;
87
- color: #ffffff !important;
88
- border: none !important;
89
- border-radius: 5px !important;
90
- font-weight: bold !important;
91
- transition: all 0.3s ease !important;
92
  }
93
  [data-testid="stFileUploader"] section > button:hover {
94
- background-color: #0056b3 !important;
95
- transform: scale(1.03) !important;
96
- }
97
- [data-testid="stFileUploader"] label { /* عنوان صندوق الرفع */
98
- color: #ffffff !important;
99
  }
100
- /* نص "Drag and drop" */
101
  [data-testid="stFileUploader"] section [data-testid="stMarkdownContainer"] p {
102
  color: #aaa !important;
103
  }
104
 
105
  /* --- 5. عناصر أخرى --- */
106
- [data-testid="stImage"] figcaption { /* نص "Processed Image" */
107
- color: #aaa !important;
108
- }
109
- [data-testid="stSpinner"] > div { /* نص التحميل "Processing..." */
110
- color: #e0e0e0 !important;
111
- }
112
- /* صندوق إدخال الرابط */
113
  [data-testid="stTextInput"] input {
114
- background-color: #1e1e1e !important;
115
- color: #e0e0e0 !important;
116
- border: 1px solid #333 !important;
117
- border-radius: 5px !important;
118
  }
119
  </style>
120
  """
121
  st.markdown(CUSTOM_CSS, unsafe_allow_html=True)
122
  # --- نهاية كود التصميم ---
123
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
124
 
125
- # --- 2. قاموس الترجمة (عربي / إنجليزي) ---
 
 
126
  localization = {
127
  'en': {
128
  'brand_title': "",
@@ -140,7 +130,13 @@ localization = {
140
  'error_processing': "Error processing image:",
141
  'generic_error': "An error occurred:",
142
  'page_title': "SkyData - Background Removal",
143
- 'spinner_text': "Processing image, please wait..."
 
 
 
 
 
 
144
  },
145
  'ar': {
146
  'brand_title': "",
@@ -158,15 +154,17 @@ localization = {
158
  'error_processing': "خطأ في معالجة الصورة:",
159
  'generic_error': "حدث خطأ:",
160
  'page_title': "SkyData - أداة إزالة الخلفية",
161
- 'spinner_text': "جاري معالجة الصورة، يرجى الانتظار..."
 
 
 
 
 
 
162
  }
163
  }
164
 
165
- # --- 3. تحميل النموذج ---
166
- torch.set_float32_matmul_precision(["high", "highest"][0])
167
- use_cuda = torch.cuda.is_available()
168
- device = "cuda" if use_cuda else "cpu"
169
-
170
  @st.cache_resource
171
  def load_model():
172
  model = AutoModelForImageSegmentation.from_pretrained("ZhengPeng7/BiRefNet", trust_remote_code=True)
@@ -175,39 +173,61 @@ def load_model():
175
  model = model.half()
176
  return model
177
 
178
- birefnet = load_model()
179
-
180
- transform_image = transforms.Compose([
181
- transforms.Resize((1024, 1024)), # الدقة العالية
182
- transforms.ToTensor(),
183
- transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),
184
- ])
185
-
186
- # --- 4. دالة المعالجة الرئيسية ---
187
  @st.cache_data
188
  def process(image):
 
189
  image_size = image.size
190
  input_images = transform_image(image).unsqueeze(0).to(device)
191
- if use_cuda:
192
- input_images = input_images.half()
193
-
194
  with torch.no_grad():
195
  preds = birefnet(input_images)[-1].sigmoid().cpu()
196
-
197
  pred = preds[0].squeeze()
198
  pred_pil = transforms.ToPILImage()(pred)
199
  mask = pred_pil.resize(image_size)
200
  image.putalpha(mask)
201
-
202
  img_bytes = io.BytesIO()
203
  image.save(img_bytes, format="PNG")
204
  img_bytes = img_bytes.getvalue()
205
-
206
  return image, img_bytes
207
 
208
- # --- 5. واجهة التطبيق (Sidebar) ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
 
210
- # اختيار اللغة
211
  lang_choice = st.sidebar.radio(
212
  label="Select Language / اختر اللغة",
213
  options=["English", "العربية"],
@@ -216,10 +236,17 @@ lang_choice = st.sidebar.radio(
216
  lang_code = 'ar' if lang_choice == 'العربية' else 'en'
217
  loc = localization[lang_code]
218
 
 
 
 
 
 
 
 
219
 
220
- # --- 6. واجهة التطبيق الرئيسية (Main App) ---
221
 
222
- # الشعار والعنوان في الصفحة الرئيسية
223
  LOGO_URL = "https://i.ibb.co/v4vwvcGq/skydatafull.webp"
224
  col1, col2 = st.columns([1, 6])
225
  with col1:
@@ -227,76 +254,77 @@ with col1:
227
  with col2:
228
  st.title(loc['page_title'])
229
 
230
- # بقية الشريط الجانبي
231
- st.sidebar.title(loc['brand_title'])
232
- selected_tab = st.sidebar.radio(loc['input_method'], [loc['tab_upload'], loc['tab_url'], loc['tab_file']])
233
-
234
- # --- منطق التبويبات ---
235
 
236
- if selected_tab == loc['tab_upload']:
237
- uploaded_file = st.file_uploader(loc['upload_prompt'], type=["jpg", "jpeg", "png"])
238
- if uploaded_file is not None:
239
- try:
240
- image = Image.open(uploaded_file).convert("RGB")
241
- with st.spinner(loc['spinner_text']):
242
- processed_image, file_bytes = process(image)
243
-
244
- st.image(processed_image, caption=loc['processed_caption'])
245
- st.download_button(
246
- label=loc['download_button'],
247
- data=file_bytes,
248
- file_name=f"{uploaded_file.name.rsplit('.', 1)[0]}.png",
249
- mime="image/png",
250
- )
251
- except Exception as e:
252
- st.error(f"{loc['generic_error']} {e}")
253
 
254
 
255
- elif selected_tab == loc['tab_url']:
256
- image_url = st.text_input(loc['url_prompt'])
257
- if image_url:
258
- try:
259
- response = requests.get(image_url, stream=True)
260
- response.raise_for_status()
261
- image = Image.open(BytesIO(response.content)).convert("RGB")
262
-
263
- with st.spinner(loc['spinner_text']):
264
- processed_image, file_bytes = process(image)
265
-
266
- st.image(processed_image, caption=loc['processed_caption'])
267
-
268
- try:
269
- file_name = image_url.split('/')[-1].rsplit('.', 1)[0] + ".png"
270
- except Exception:
271
- file_name = "processed_image.png"
272
-
273
- st.download_button(
274
- label=loc['download_button'],
275
- data=file_bytes,
276
- file_name=file_name,
277
- mime="image/png",
278
- )
279
- except requests.exceptions.RequestException as e:
280
- st.error(f"{loc['error_fetching']} {e}")
281
- except Exception as e:
282
- st.error(f"{loc['error_processing']} {e}")
283
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
284
 
285
- elif selected_tab == loc['tab_file']:
286
- uploaded_file = st.file_uploader(loc['upload_prompt_file'], type=["jpg", "jpeg", "png"])
287
- if uploaded_file is not None:
288
- try:
289
- image = Image.open(uploaded_file).convert("RGB")
290
-
291
- with st.spinner(loc['spinner_text']):
292
- processed_image, file_bytes = process(image)
293
-
294
- st.image(processed_image, caption=loc['processed_caption'])
295
- st.download_button(
296
- label=loc['download_button'],
297
- data=file_bytes,
298
- file_name=f"{uploaded_file.name.rsplit('.', 1)[0]}.png",
299
- mime="image/png",
300
- )
301
- except Exception as e:
302
- st.error(f"{loc['generic_error']} {e}")
 
7
  import os
8
  import requests
9
  from io import BytesIO
10
+ import firebase_admin
11
+ from firebase_admin import credentials, db
12
+ import datetime
13
+ import json
14
 
15
  # --- 1. إعدادات الصفحة ---
16
  st.set_page_config(
 
18
  layout="wide"
19
  )
20
 
21
+ # --- كود التصميم (كما هو) ---
22
  CUSTOM_CSS = """
23
  <style>
24
+ /* ... (نفس كود CSS الذي أصلحناه سابقاً) ... */
25
  /* --- 1. الخلفية الرئيسية والخطوط --- */
26
  body, [data-testid="stAppViewContainer"], [data-testid="stHeader"] {
27
+ background-color: #121212 !important; color: #e0e0e0 !important;
 
28
  }
29
  [data-testid="stHeader"] {
30
+ background-color: #1e1e1e !important; border-bottom: 1px solid #333;
 
 
 
 
 
 
 
31
  }
32
+ h1, h2, h3, h4, h5, h6 { color: #ffffff !important; }
33
+ p, label, [data-testid="stMarkdownContainer"] { color: #e0e0e0 !important; }
34
 
35
  /* --- 2. الشريط الجانبي (Sidebar) --- */
 
 
36
  [data-testid="stSidebar"][aria-expanded="true"] {
37
+ background-color: #1e1e1e !important; border-right: 1px solid #333 !important;
 
38
  }
 
 
39
  [data-testid="stSidebar"][aria-expanded="true"] [data-testid="stRadio"] label {
40
+ background-color: #2a2a2a; padding: 10px; border-radius: 5px;
41
+ margin: 5px 0; transition: all 0.3s ease;
 
 
 
42
  }
 
43
  [data-testid="stSidebar"][aria-expanded="true"] [data-testid="stRadio"] label:hover {
44
+ background-color: #333; color: #007bff;
 
45
  }
 
46
  [data-testid="stSidebar"][aria-expanded="true"] [data-testid="stRadio"] input:checked + div {
47
  color: #007bff;
48
  }
49
 
50
  /* --- 3. زر التحميل (Download Button) --- */
51
  [data-testid="stDownloadButton"] > button {
52
+ background-color: #007bff !important; color: #ffffff !important;
53
+ border: none !important; border-radius: 5px !important;
54
+ font-weight: bold !important; padding: 12px 20px !important;
55
+ transition: all 0.3s ease !important; width: 100%;
 
 
 
 
56
  }
57
  [data-testid="stDownloadButton"] > button:hover {
58
+ background-color: #0056b3 !important; transform: scale(1.03) !important;
 
59
  }
60
 
61
  /* --- 4. زر رفع الملفات (File Uploader) --- */
62
  [data-testid="stFileUploader"] section {
63
+ background-color: #1e1e1e !important; border: 1px dashed #333 !important;
 
64
  border-radius: 8px !important;
65
  }
 
66
  [data-testid="stFileUploader"] section > button {
67
+ background-color: #007bff !important; color: #ffffff !important;
68
+ border: none !important; border-radius: 5px !important;
69
+ font-weight: bold !important; transition: all 0.3s ease !important;
 
 
 
70
  }
71
  [data-testid="stFileUploader"] section > button:hover {
72
+ background-color: #0056b3 !important; transform: scale(1.03) !important;
 
 
 
 
73
  }
74
+ [data-testid="stFileUploader"] label { color: #ffffff !important; }
75
  [data-testid="stFileUploader"] section [data-testid="stMarkdownContainer"] p {
76
  color: #aaa !important;
77
  }
78
 
79
  /* --- 5. عناصر أخرى --- */
80
+ [data-testid="stImage"] figcaption { color: #aaa !important; }
81
+ [data-testid="stSpinner"] > div { color: #e0e0e0 !important; }
 
 
 
 
 
82
  [data-testid="stTextInput"] input {
83
+ background-color: #1e1e1e !important; color: #e0e0e0 !important;
84
+ border: 1px solid #333 !important; border-radius: 5px !important;
 
 
85
  }
86
  </style>
87
  """
88
  st.markdown(CUSTOM_CSS, unsafe_allow_html=True)
89
  # --- نهاية كود التصميم ---
90
 
91
+ # --- <<< جديد: إعداد Firebase ---
92
+ @st.cache_resource
93
+ def init_firebase():
94
+ try:
95
+ # (انظر خطوة الإعداد) جلب المفتاح السري من Hugging Face Secrets
96
+ creds_json_str = os.environ.get("FIREBASE_CREDS")
97
+ if creds_json_str:
98
+ creds_dict = json.loads(creds_json_str)
99
+ cred = credentials.Certificate(creds_dict)
100
+ # (هام) استبدل هذا برابط قاعدة بياناتك من ملف index.html
101
+ db_url = "https://pixelrpg-5ebc3-default-rtdb.europe-west1.firebasedatabase.app"
102
+
103
+ if not firebase_admin._apps:
104
+ firebase_admin.initialize_app(cred, {'databaseURL': db_url})
105
+ return True
106
+ else:
107
+ st.error("خطأ فادح: لم يتم العثور على مفتاح Firebase. يرجى الاتصال بمسؤول الموقع.")
108
+ return False
109
+ except Exception as e:
110
+ st.error(f"خطأ في الاتصال بـ Firebase: {e}")
111
+ return False
112
 
113
+ firebase_initialized = init_firebase()
114
+
115
+ # --- 2. قاموس الترجمة (معدل) ---
116
  localization = {
117
  'en': {
118
  'brand_title': "",
 
130
  'error_processing': "Error processing image:",
131
  'generic_error': "An error occurred:",
132
  'page_title': "SkyData - Background Removal",
133
+ 'spinner_text': "Processing image, please wait...",
134
+ # <<< جديد: رسائل نظام المفاتيح
135
+ 'api_key_prompt': "Enter your API Key",
136
+ 'api_key_missing': "Please enter your API Key to use the tool.",
137
+ 'api_key_invalid': "Invalid API Key. Please get a key from our website.",
138
+ 'limit_reached': "You have reached your daily limit (30 attempts).",
139
+ 'attempts_left': "Attempts left today:"
140
  },
141
  'ar': {
142
  'brand_title': "",
 
154
  'error_processing': "خطأ في معالجة الصورة:",
155
  'generic_error': "حدث خطأ:",
156
  'page_title': "SkyData - أداة إزالة الخلفية",
157
+ 'spinner_text': "جاري معالجة الصورة، يرجى الانتظار...",
158
+ # <<< جديد: رسائل نظام المفاتيح
159
+ 'api_key_prompt': "أدخل مفتاح الاستخدام (API Key)",
160
+ 'api_key_missing': "الرجاء إدخال مفتاح الاستخدام لتشغيل الأداة.",
161
+ 'api_key_invalid': "مفتاح استخدام غير صالح. الرجاء الحصول على مفتاح من موقعنا.",
162
+ 'limit_reached': "لقد وصلت إلى الحد الأقصى (30 محاولة). يرجى المحاولة غداً.",
163
+ 'attempts_left': "المحاولات المتبقية اليوم:"
164
  }
165
  }
166
 
167
+ # --- 3. تحميل النموذج (كما هو) ---
 
 
 
 
168
  @st.cache_resource
169
  def load_model():
170
  model = AutoModelForImageSegmentation.from_pretrained("ZhengPeng7/BiRefNet", trust_remote_code=True)
 
173
  model = model.half()
174
  return model
175
 
176
+ # --- 4. دالة المعالجة (كما هي) ---
 
 
 
 
 
 
 
 
177
  @st.cache_data
178
  def process(image):
179
+ # (نفس دالة المعالجة السابقة)
180
  image_size = image.size
181
  input_images = transform_image(image).unsqueeze(0).to(device)
182
+ if use_cuda: input_images = input_images.half()
 
 
183
  with torch.no_grad():
184
  preds = birefnet(input_images)[-1].sigmoid().cpu()
 
185
  pred = preds[0].squeeze()
186
  pred_pil = transforms.ToPILImage()(pred)
187
  mask = pred_pil.resize(image_size)
188
  image.putalpha(mask)
 
189
  img_bytes = io.BytesIO()
190
  image.save(img_bytes, format="PNG")
191
  img_bytes = img_bytes.getvalue()
 
192
  return image, img_bytes
193
 
194
+ # --- <<< جديد: دالة التحقق من حد الاستخدام ---
195
+ DAILY_LIMIT = 30
196
+ @st.cache_data(ttl=60) # تخزين نتيجة التحقق لمدة 60 ثانية لتجنب الضغط على Firebase
197
+ def check_and_update_limit(api_key, loc):
198
+ if not firebase_initialized:
199
+ return False, loc['generic_error']
200
+
201
+ try:
202
+ ref = db.reference(f'users/{api_key}')
203
+ data = ref.get()
204
+
205
+ if not data:
206
+ return False, loc['api_key_invalid']
207
+
208
+ today_date = datetime.date.today().isoformat()
209
+ last_reset = data.get('lastResetDate', '1970-01-01')
210
+ count = int(data.get('usageCount', 0))
211
+
212
+ # تصفير العداد إذا كان يوماً جديداً
213
+ if last_reset != today_date:
214
+ count = 0
215
+ ref.update({'lastResetDate': today_date, 'usageCount': 0})
216
+
217
+ # التحقق من الحد
218
+ if count >= DAILY_LIMIT:
219
+ st.session_state.remaining_attempts = 0
220
+ return False, loc['limit_reached']
221
+
222
+ # (مهم) تحديث العداد في قاعدة البيانات
223
+ ref.update({'usageCount': count + 1})
224
+ st.session_state.remaining_attempts = DAILY_LIMIT - (count + 1)
225
+ return True, "" # نجح
226
+
227
+ except Exception as e:
228
+ return False, f"Error checking key: {e}"
229
 
230
+ # --- 5. واجهة التطبيق (Sidebar) (معدلة) ---
231
  lang_choice = st.sidebar.radio(
232
  label="Select Language / اختر اللغة",
233
  options=["English", "العربية"],
 
236
  lang_code = 'ar' if lang_choice == 'العربية' else 'en'
237
  loc = localization[lang_code]
238
 
239
+ # --- <<< جديد: إضافة خانة المفتاح ---
240
+ st.sidebar.title(loc['brand_title'])
241
+ api_key = st.sidebar.text_input(loc['api_key_prompt'], type="password")
242
+
243
+ # --- <<< جديد: إظهار المحاولات المتبقية (إذا تم إدخال المفتاح)
244
+ if 'remaining_attempts' in st.session_state:
245
+ st.sidebar.info(f"{loc['attempts_left']} {st.session_state.remaining_attempts}")
246
 
247
+ selected_tab = st.sidebar.radio(loc['input_method'], [loc['tab_upload'], loc['tab_url'], loc['tab_file']])
248
 
249
+ # --- 6. واجهة التطبيق الرئيسية (Main App) (كما هي) ---
250
  LOGO_URL = "https://i.ibb.co/v4vwvcGq/skydatafull.webp"
251
  col1, col2 = st.columns([1, 6])
252
  with col1:
 
254
  with col2:
255
  st.title(loc['page_title'])
256
 
257
+ # --- منطق التبويبات (معدل بالكامل) ---
 
 
 
 
258
 
259
+ # (ملاحظة: قمت بإنشاء دالة موحدة للمعالجة لتجنب تكرار الكود)
260
+ def handle_processing(image, original_name):
261
+ try:
262
+ with st.spinner(loc['spinner_text']):
263
+ processed_image, file_bytes = process(image)
264
+
265
+ st.image(processed_image, caption=loc['processed_caption'])
266
+ st.download_button(
267
+ label=loc['download_button'],
268
+ data=file_bytes,
269
+ file_name=f"{original_name.rsplit('.', 1)[0]}.png",
270
+ mime="image/png",
271
+ )
272
+ except Exception as e:
273
+ st.error(f"{loc['generic_error']} {e}")
 
 
274
 
275
 
276
+ # --- التحقق من المفتاح قبل أي شيء ---
277
+ if not firebase_initialized:
278
+ st.error("خطأ في الاتصال بقاعدة البيانات. لا يمكن تشغيل الأداة.")
279
+ else:
280
+ if selected_tab == loc['tab_upload']:
281
+ uploaded_file = st.file_uploader(loc['upload_prompt'], type=["jpg", "jpeg", "png"])
282
+ if uploaded_file is not None:
283
+ if not api_key:
284
+ st.info(loc['api_key_missing'])
285
+ else:
286
+ is_ok, message = check_and_update_limit(api_key, loc)
287
+ if is_ok:
288
+ image = Image.open(uploaded_file).convert("RGB")
289
+ handle_processing(image, uploaded_file.name)
290
+ else:
291
+ st.warning(message)
 
 
 
 
 
 
 
 
 
 
 
 
292
 
293
+ elif selected_tab == loc['tab_url']:
294
+ image_url = st.text_input(loc['url_prompt'])
295
+ if image_url:
296
+ if not api_key:
297
+ st.info(loc['api_key_missing'])
298
+ else:
299
+ is_ok, message = check_and_update_limit(api_key, loc)
300
+ if is_ok:
301
+ try:
302
+ response = requests.get(image_url, stream=True)
303
+ response.raise_for_status()
304
+ image = Image.open(BytesIO(response.content)).convert("RGB")
305
+
306
+ try:
307
+ file_name = image_url.split('/')[-1]
308
+ except Exception:
309
+ file_name = "processed_image.png"
310
+
311
+ handle_processing(image, file_name)
312
+ except requests.exceptions.RequestException as e:
313
+ st.error(f"{loc['error_fetching']} {e}")
314
+ except Exception as e:
315
+ st.error(f"{loc['error_processing']} {e}")
316
+ else:
317
+ st.warning(message)
318
 
319
+ elif selected_tab == loc['tab_file']:
320
+ uploaded_file = st.file_uploader(loc['upload_prompt_file'], type=["jpg", "jpeg", "png"])
321
+ if uploaded_file is not None:
322
+ if not api_key:
323
+ st.info(loc['api_key_missing'])
324
+ else:
325
+ is_ok, message = check_and_update_limit(api_key, loc)
326
+ if is_ok:
327
+ image = Image.open(uploaded_file).convert("RGB")
328
+ handle_processing(image, uploaded_file.name)
329
+ else:
330
+ st.warning(message)
 
 
 
 
 
 
requirements.txt CHANGED
@@ -7,3 +7,4 @@ transformers==4.48.3
7
  einops>=0.4.0
8
  kornia>=0.6.0
9
  timm>=0.6.0
 
 
7
  einops>=0.4.0
8
  kornia>=0.6.0
9
  timm>=0.6.0
10
+ firebase-admin==6.5.0