button fix
Browse files
app.py
CHANGED
|
@@ -23,10 +23,10 @@ import io
|
|
| 23 |
if not os.getcwd() in sys.path:
|
| 24 |
sys.path.append(os.getcwd())
|
| 25 |
|
| 26 |
-
# Check if
|
| 27 |
if importlib.util.find_spec("detectron") is None:
|
| 28 |
-
print("🔄
|
| 29 |
-
print("Installing PyTorch and
|
| 30 |
os.system("pip install torch torchvision --extra-index-url https://download.pytorch.org/whl/cpu")
|
| 31 |
os.system("pip install git+https://github.com/facebookresearch/detectron2.git")
|
| 32 |
print("Installation complete!")
|
|
@@ -77,72 +77,122 @@ MAILJET_CONFIG = {
|
|
| 77 |
'URL': 'https://api.mailjet.com/v3.1/send'
|
| 78 |
}
|
| 79 |
|
| 80 |
-
# JavaScript pour la gestion des cookies
|
| 81 |
COOKIE_JAVASCRIPT = """
|
| 82 |
<script>
|
| 83 |
-
// Fonctions de gestion des cookies HEDI
|
| 84 |
function setCookie(name, value, days = 1) {
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
}
|
| 89 |
|
| 90 |
function getCookie(name) {
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
let
|
| 95 |
-
|
| 96 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
}
|
| 98 |
-
return null;
|
| 99 |
}
|
| 100 |
|
| 101 |
function getHediUsage() {
|
| 102 |
try {
|
|
|
|
| 103 |
const today = new Date().toISOString().split('T')[0]; // YYYY-MM-DD
|
| 104 |
const lastDate = getCookie('hedi_last_date');
|
| 105 |
|
| 106 |
// Reset quotidien automatique
|
| 107 |
if (lastDate !== today) {
|
| 108 |
-
console.log('🔄 Daily reset: ' + lastDate + ' → ' + today);
|
| 109 |
setCookie('hedi_usage_count', '0', 1);
|
| 110 |
setCookie('hedi_last_date', today, 1);
|
|
|
|
| 111 |
return 0;
|
| 112 |
}
|
| 113 |
|
| 114 |
const usage = parseInt(getCookie('hedi_usage_count') || '0');
|
| 115 |
-
console.log('🍪
|
| 116 |
return usage;
|
| 117 |
} catch (e) {
|
| 118 |
-
console.error('Error
|
| 119 |
return 0;
|
| 120 |
}
|
| 121 |
}
|
| 122 |
|
| 123 |
function saveHediUsage(count) {
|
| 124 |
try {
|
|
|
|
| 125 |
const today = new Date().toISOString().split('T')[0];
|
| 126 |
-
setCookie('hedi_usage_count', count.toString(), 1);
|
| 127 |
-
setCookie('hedi_last_date', today, 1);
|
| 128 |
-
|
| 129 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 130 |
} catch (e) {
|
| 131 |
-
console.error('Error saving usage to cookies:', e);
|
| 132 |
return false;
|
| 133 |
}
|
| 134 |
}
|
| 135 |
|
| 136 |
-
// Exposer les fonctions globalement
|
| 137 |
window.hediCookies = {
|
| 138 |
-
getUsage:
|
| 139 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 140 |
};
|
| 141 |
|
| 142 |
-
// Initialiser au chargement
|
| 143 |
-
|
| 144 |
-
|
| 145 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 146 |
</script>
|
| 147 |
"""
|
| 148 |
|
|
@@ -788,7 +838,7 @@ def create_gradio_interface():
|
|
| 788 |
</div>
|
| 789 |
""")
|
| 790 |
|
| 791 |
-
# === SECTION 2: Boutons ===
|
| 792 |
gr.HTML("")
|
| 793 |
with gr.Row():
|
| 794 |
analyze_btn = gr.Button(
|
|
@@ -796,13 +846,22 @@ def create_gradio_interface():
|
|
| 796 |
variant="primary",
|
| 797 |
size="lg",
|
| 798 |
elem_classes="hedi-btn-primary",
|
| 799 |
-
scale=
|
| 800 |
)
|
| 801 |
clear_btn = gr.Button(
|
| 802 |
"🗑️ Clear",
|
| 803 |
variant="secondary",
|
| 804 |
scale=1
|
| 805 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 806 |
|
| 807 |
# === SECTION 3: Usage Counter et Real-time Monitoring ===
|
| 808 |
with gr.Row(equal_height=True):
|
|
@@ -950,14 +1009,37 @@ def create_gradio_interface():
|
|
| 950 |
<p>• <strong>No registration:</strong> No account needed, just cookies</p>
|
| 951 |
</div>
|
| 952 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 953 |
</div>
|
| 954 |
""")
|
| 955 |
|
| 956 |
# === FONCTIONS EVENT HANDLERS ===
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 957 |
def update_interface(*args):
|
| 958 |
try:
|
| 959 |
image, damage_thresh, deepfake_thresh, device_val, current_usage, email = args
|
| 960 |
|
|
|
|
|
|
|
| 961 |
if image is None:
|
| 962 |
return [
|
| 963 |
"""<div style="background: #fef2f2; padding: 20px; border-radius: 8px; border: 1px solid #fecaca; margin-top: 10px; color: #000000 !important;">
|
|
@@ -974,7 +1056,8 @@ def create_gradio_interface():
|
|
| 974 |
gr.update(visible=False),
|
| 975 |
"",
|
| 976 |
"",
|
| 977 |
-
get_usage_display_html(current_usage)
|
|
|
|
| 978 |
]
|
| 979 |
|
| 980 |
if not email:
|
|
@@ -993,9 +1076,13 @@ def create_gradio_interface():
|
|
| 993 |
gr.update(visible=False),
|
| 994 |
"",
|
| 995 |
"",
|
| 996 |
-
get_usage_display_html(current_usage)
|
|
|
|
| 997 |
]
|
| 998 |
|
|
|
|
|
|
|
|
|
|
| 999 |
# Check usage limit
|
| 1000 |
if current_usage >= MAX_TRIES:
|
| 1001 |
return [
|
|
@@ -1014,27 +1101,19 @@ def create_gradio_interface():
|
|
| 1014 |
gr.update(visible=False),
|
| 1015 |
"",
|
| 1016 |
"",
|
| 1017 |
-
get_usage_display_html(current_usage)
|
|
|
|
| 1018 |
]
|
| 1019 |
|
| 1020 |
-
|
| 1021 |
-
processing_status = """<div style="background: #fef3c7; padding: 20px; border-radius: 8px; border: 1px solid #fcd34d; margin-top: 10px; color: #000000 !important;">
|
| 1022 |
-
<div style="display: flex; align-items: center; margin-bottom: 12px;">
|
| 1023 |
-
<span style="font-size: 18px; margin-right: 8px;">🔄</span>
|
| 1024 |
-
<strong style="color: #000000 !important;">Analysis Status</strong>
|
| 1025 |
-
</div>
|
| 1026 |
-
<div style="color: #92400e; text-align: center;">
|
| 1027 |
-
<div><strong>Processing in progress...</strong></div>
|
| 1028 |
-
<div style="font-size: 14px; margin-top: 8px;">AI analysis and email delivery</div>
|
| 1029 |
-
<div style="font-size: 12px; margin-top: 4px; opacity: 0.8;">Please wait 30-60 seconds</div>
|
| 1030 |
-
</div>
|
| 1031 |
-
</div>"""
|
| 1032 |
|
| 1033 |
# Call the REAL processing function
|
| 1034 |
analysis_text, new_usage_count, status_message, download_path = process_image_sequential(
|
| 1035 |
image, damage_thresh, deepfake_thresh, device_val, current_usage, email
|
| 1036 |
)
|
| 1037 |
|
|
|
|
|
|
|
| 1038 |
# Check if analysis was successful
|
| 1039 |
if "✅" in status_message or "sent via Mailjet" in status_message:
|
| 1040 |
success_status = """<div style="background: #f0fdf4; padding: 20px; border-radius: 8px; border: 1px solid #bbf7d0; margin-top: 10px; color: #000000 !important;">
|
|
@@ -1058,7 +1137,8 @@ def create_gradio_interface():
|
|
| 1058 |
gr.update(value=download_path, visible=bool(download_path)),
|
| 1059 |
"",
|
| 1060 |
analysis_text,
|
| 1061 |
-
get_usage_display_html(new_usage_count)
|
|
|
|
| 1062 |
]
|
| 1063 |
else:
|
| 1064 |
# Analysis failed
|
|
@@ -1079,10 +1159,15 @@ def create_gradio_interface():
|
|
| 1079 |
gr.update(visible=False),
|
| 1080 |
"",
|
| 1081 |
analysis_text,
|
| 1082 |
-
get_usage_display_html(new_usage_count)
|
|
|
|
| 1083 |
]
|
| 1084 |
|
| 1085 |
except Exception as e:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1086 |
error_status = f"""<div style="background: #fef2f2; padding: 20px; border-radius: 8px; border: 1px solid #fecaca; margin-top: 10px; color: #000000 !important;">
|
| 1087 |
<div style="display: flex; align-items: center; margin-bottom: 12px;">
|
| 1088 |
<span style="font-size: 18px; margin-right: 8px;">❌</span>
|
|
@@ -1094,7 +1179,15 @@ def create_gradio_interface():
|
|
| 1094 |
</div>
|
| 1095 |
</div>"""
|
| 1096 |
|
| 1097 |
-
return [
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1098 |
|
| 1099 |
def clear_interface():
|
| 1100 |
return [
|
|
@@ -1108,46 +1201,59 @@ def create_gradio_interface():
|
|
| 1108 |
<div style="color: #6b7280; font-size: 14px; margin-top: 8px;">Upload an image and click Analyze</div>
|
| 1109 |
</div>
|
| 1110 |
</div>""",
|
| 1111 |
-
0, # Reset usage counter display
|
| 1112 |
gr.update(visible=False),
|
| 1113 |
"",
|
| 1114 |
"",
|
| 1115 |
get_usage_display_html(0),
|
|
|
|
| 1116 |
""
|
| 1117 |
]
|
| 1118 |
|
| 1119 |
-
# Event handlers
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1120 |
analyze_btn.click(
|
| 1121 |
-
fn=
|
| 1122 |
inputs=[input_image, damage_threshold, deepfake_threshold, device, usage_counter, recipient_email],
|
| 1123 |
-
outputs=[status_display, usage_counter, download_file, download_info, output_text, usage_display
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1124 |
js="""
|
| 1125 |
-
(
|
| 1126 |
-
|
| 1127 |
-
|
| 1128 |
-
|
| 1129 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1130 |
}
|
| 1131 |
"""
|
| 1132 |
)
|
| 1133 |
|
| 1134 |
clear_btn.click(
|
| 1135 |
fn=clear_interface,
|
| 1136 |
-
outputs=[status_display, usage_counter, download_file, download_info, output_text, usage_display, recipient_email]
|
| 1137 |
)
|
| 1138 |
|
| 1139 |
-
#
|
| 1140 |
app.load(
|
| 1141 |
-
fn=lambda: [0, get_usage_display_html(0)],
|
| 1142 |
-
outputs=[usage_counter, usage_display
|
| 1143 |
-
js="""
|
| 1144 |
-
() => {
|
| 1145 |
-
// Initialiser l'usage depuis les cookies au chargement
|
| 1146 |
-
const usage = window.hediCookies.getUsage();
|
| 1147 |
-
console.log('🍪 Page loaded, usage from cookies:', usage);
|
| 1148 |
-
return [usage, null]; // Le HTML sera mis à jour côté Python
|
| 1149 |
-
}
|
| 1150 |
-
"""
|
| 1151 |
)
|
| 1152 |
|
| 1153 |
return app
|
|
@@ -1350,16 +1456,23 @@ def validate_email(email):
|
|
| 1350 |
def process_image_sequential(input_image, damage_threshold, deepfake_threshold, device_str, usage_count, recipient_email):
|
| 1351 |
"""Main processing function with sequential pipeline: Damage Detection → Deepfake Detection"""
|
| 1352 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1353 |
# Handle usage count
|
| 1354 |
if usage_count is None:
|
| 1355 |
usage_count = 0
|
|
|
|
| 1356 |
|
| 1357 |
try:
|
| 1358 |
usage_count = int(usage_count)
|
| 1359 |
except (TypeError, ValueError):
|
|
|
|
| 1360 |
usage_count = 0
|
| 1361 |
|
| 1362 |
usage_count = usage_count + 1
|
|
|
|
| 1363 |
|
| 1364 |
progress_info = []
|
| 1365 |
progress_info.append(f"📊 Individual Usage: {usage_count}/{MAX_TRIES}")
|
|
@@ -1732,6 +1845,7 @@ if __name__ == "__main__":
|
|
| 1732 |
# Test Mailjet configuration
|
| 1733 |
if MAILJET_CONFIG['API_KEY'] and MAILJET_CONFIG['SECRET_KEY']:
|
| 1734 |
print("📧 Mailjet API: ✅ Configured")
|
|
|
|
| 1735 |
# Test connection at startup
|
| 1736 |
if test_mailjet_connection():
|
| 1737 |
print("📧 Mailjet: ✅ Connection test successful")
|
|
|
|
| 23 |
if not os.getcwd() in sys.path:
|
| 24 |
sys.path.append(os.getcwd())
|
| 25 |
|
| 26 |
+
# Check if detectron2 is installed and attempt installation if needed
|
| 27 |
if importlib.util.find_spec("detectron") is None:
|
| 28 |
+
print("🔄 Detectron2 not found. Attempting installation...")
|
| 29 |
+
print("Installing PyTorch and Detectron2...")
|
| 30 |
os.system("pip install torch torchvision --extra-index-url https://download.pytorch.org/whl/cpu")
|
| 31 |
os.system("pip install git+https://github.com/facebookresearch/detectron2.git")
|
| 32 |
print("Installation complete!")
|
|
|
|
| 77 |
'URL': 'https://api.mailjet.com/v3.1/send'
|
| 78 |
}
|
| 79 |
|
| 80 |
+
# JavaScript pour la gestion des cookies - Version corrigée
|
| 81 |
COOKIE_JAVASCRIPT = """
|
| 82 |
<script>
|
| 83 |
+
// Fonctions de gestion des cookies HEDI - Version Debug
|
| 84 |
function setCookie(name, value, days = 1) {
|
| 85 |
+
try {
|
| 86 |
+
const expires = new Date();
|
| 87 |
+
expires.setTime(expires.getTime() + (days * 24 * 60 * 60 * 1000));
|
| 88 |
+
document.cookie = name + '=' + value + ';expires=' + expires.toUTCString() + ';path=/;SameSite=Lax';
|
| 89 |
+
console.log('✅ Cookie set:', name, '=', value);
|
| 90 |
+
return true;
|
| 91 |
+
} catch (e) {
|
| 92 |
+
console.error('❌ Error setting cookie:', e);
|
| 93 |
+
return false;
|
| 94 |
+
}
|
| 95 |
}
|
| 96 |
|
| 97 |
function getCookie(name) {
|
| 98 |
+
try {
|
| 99 |
+
const nameEQ = name + '=';
|
| 100 |
+
const ca = document.cookie.split(';');
|
| 101 |
+
for(let i = 0; i < ca.length; i++) {
|
| 102 |
+
let c = ca[i];
|
| 103 |
+
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
|
| 104 |
+
if (c.indexOf(nameEQ) == 0) {
|
| 105 |
+
const value = c.substring(nameEQ.length, c.length);
|
| 106 |
+
console.log('📖 Cookie read:', name, '=', value);
|
| 107 |
+
return value;
|
| 108 |
+
}
|
| 109 |
+
}
|
| 110 |
+
console.log('📖 Cookie not found:', name);
|
| 111 |
+
return null;
|
| 112 |
+
} catch (e) {
|
| 113 |
+
console.error('❌ Error reading cookie:', e);
|
| 114 |
+
return null;
|
| 115 |
}
|
|
|
|
| 116 |
}
|
| 117 |
|
| 118 |
function getHediUsage() {
|
| 119 |
try {
|
| 120 |
+
console.log('🔍 Getting HEDI usage...');
|
| 121 |
const today = new Date().toISOString().split('T')[0]; // YYYY-MM-DD
|
| 122 |
const lastDate = getCookie('hedi_last_date');
|
| 123 |
|
| 124 |
// Reset quotidien automatique
|
| 125 |
if (lastDate !== today) {
|
| 126 |
+
console.log('🔄 Daily reset detected: ' + lastDate + ' → ' + today);
|
| 127 |
setCookie('hedi_usage_count', '0', 1);
|
| 128 |
setCookie('hedi_last_date', today, 1);
|
| 129 |
+
console.log('✅ Usage reset to 0');
|
| 130 |
return 0;
|
| 131 |
}
|
| 132 |
|
| 133 |
const usage = parseInt(getCookie('hedi_usage_count') || '0');
|
| 134 |
+
console.log('🍪 Current usage from cookies: ' + usage + '/10');
|
| 135 |
return usage;
|
| 136 |
} catch (e) {
|
| 137 |
+
console.error('❌ Error getting usage from cookies:', e);
|
| 138 |
return 0;
|
| 139 |
}
|
| 140 |
}
|
| 141 |
|
| 142 |
function saveHediUsage(count) {
|
| 143 |
try {
|
| 144 |
+
console.log('💾 Saving usage to cookies:', count);
|
| 145 |
const today = new Date().toISOString().split('T')[0];
|
| 146 |
+
const success1 = setCookie('hedi_usage_count', count.toString(), 1);
|
| 147 |
+
const success2 = setCookie('hedi_last_date', today, 1);
|
| 148 |
+
|
| 149 |
+
if (success1 && success2) {
|
| 150 |
+
console.log('✅ Usage saved successfully: ' + count + '/10');
|
| 151 |
+
return true;
|
| 152 |
+
} else {
|
| 153 |
+
console.error('❌ Failed to save usage');
|
| 154 |
+
return false;
|
| 155 |
+
}
|
| 156 |
} catch (e) {
|
| 157 |
+
console.error('❌ Error saving usage to cookies:', e);
|
| 158 |
return false;
|
| 159 |
}
|
| 160 |
}
|
| 161 |
|
| 162 |
+
// Exposer les fonctions globalement avec fallback
|
| 163 |
window.hediCookies = {
|
| 164 |
+
getUsage: function() {
|
| 165 |
+
try {
|
| 166 |
+
return getHediUsage();
|
| 167 |
+
} catch (e) {
|
| 168 |
+
console.error('Fallback: Error in getUsage', e);
|
| 169 |
+
return 0;
|
| 170 |
+
}
|
| 171 |
+
},
|
| 172 |
+
saveUsage: function(count) {
|
| 173 |
+
try {
|
| 174 |
+
return saveHediUsage(count);
|
| 175 |
+
} catch (e) {
|
| 176 |
+
console.error('Fallback: Error in saveUsage', e);
|
| 177 |
+
return false;
|
| 178 |
+
}
|
| 179 |
+
}
|
| 180 |
};
|
| 181 |
|
| 182 |
+
// Initialiser immédiatement ET au chargement
|
| 183 |
+
console.log('🍪 HEDI Cookies loading...');
|
| 184 |
+
try {
|
| 185 |
+
const initialUsage = getHediUsage();
|
| 186 |
+
console.log('🍪 HEDI Cookies initialized with usage:', initialUsage);
|
| 187 |
+
} catch (e) {
|
| 188 |
+
console.error('❌ Error during initialization:', e);
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
// Double initialisation pour être sûr
|
| 192 |
+
setTimeout(function() {
|
| 193 |
+
console.log('🍪 HEDI Cookies late initialization...');
|
| 194 |
+
window.hediCookies.getUsage();
|
| 195 |
+
}, 1000);
|
| 196 |
</script>
|
| 197 |
"""
|
| 198 |
|
|
|
|
| 838 |
</div>
|
| 839 |
""")
|
| 840 |
|
| 841 |
+
# === SECTION 2: Boutons et Debug ===
|
| 842 |
gr.HTML("")
|
| 843 |
with gr.Row():
|
| 844 |
analyze_btn = gr.Button(
|
|
|
|
| 846 |
variant="primary",
|
| 847 |
size="lg",
|
| 848 |
elem_classes="hedi-btn-primary",
|
| 849 |
+
scale=2
|
| 850 |
)
|
| 851 |
clear_btn = gr.Button(
|
| 852 |
"🗑️ Clear",
|
| 853 |
variant="secondary",
|
| 854 |
scale=1
|
| 855 |
)
|
| 856 |
+
# Bouton de test JavaScript (temporaire pour debug)
|
| 857 |
+
test_js_btn = gr.Button(
|
| 858 |
+
"🍪 Test Cookies",
|
| 859 |
+
variant="secondary",
|
| 860 |
+
scale=1
|
| 861 |
+
)
|
| 862 |
+
|
| 863 |
+
# Debug info (temporaire)
|
| 864 |
+
debug_info = gr.HTML("")
|
| 865 |
|
| 866 |
# === SECTION 3: Usage Counter et Real-time Monitoring ===
|
| 867 |
with gr.Row(equal_height=True):
|
|
|
|
| 1009 |
<p>• <strong>No registration:</strong> No account needed, just cookies</p>
|
| 1010 |
</div>
|
| 1011 |
</div>
|
| 1012 |
+
|
| 1013 |
+
<div style="background: #fff7ed; border: 1px solid #fed7aa; padding: 16px; border-radius: 12px; margin-top: 20px; color: #000000 !important;">
|
| 1014 |
+
<h3 style="color: #ea580c; display: flex; align-items: center; margin-bottom: 12px;"><span style="margin-right: 12px;">🔧</span>Troubleshooting & Debug</h3>
|
| 1015 |
+
<div style="color: #c2410c;">
|
| 1016 |
+
<p>• <strong>Test Cookies button:</strong> Click to verify JavaScript functions are working</p>
|
| 1017 |
+
<p>• <strong>Browser Console:</strong> Press F12 and check Console tab for cookie debugging info</p>
|
| 1018 |
+
<p>• <strong>Debug info:</strong> Green area below buttons shows function call status</p>
|
| 1019 |
+
<p>• <strong>If nothing happens:</strong> Check console for errors, try refreshing page</p>
|
| 1020 |
+
<p>• <strong>Cookie issues:</strong> Clear browser cookies for this site and try again</p>
|
| 1021 |
+
</div>
|
| 1022 |
+
</div>
|
| 1023 |
</div>
|
| 1024 |
""")
|
| 1025 |
|
| 1026 |
# === FONCTIONS EVENT HANDLERS ===
|
| 1027 |
+
def test_javascript_cookies():
|
| 1028 |
+
"""Fonction pour tester les cookies JavaScript"""
|
| 1029 |
+
return """
|
| 1030 |
+
<div style="background: #f0f9ff; padding: 15px; border-radius: 8px; border: 1px solid #bfdbfe; color: #000000 !important;">
|
| 1031 |
+
<h4 style="color: #000000 !important;">🍪 JavaScript Cookie Test</h4>
|
| 1032 |
+
<p>Check browser console (F12) for cookie debugging info.</p>
|
| 1033 |
+
<p>This test verifies that JavaScript functions are working.</p>
|
| 1034 |
+
</div>
|
| 1035 |
+
"""
|
| 1036 |
+
|
| 1037 |
def update_interface(*args):
|
| 1038 |
try:
|
| 1039 |
image, damage_thresh, deepfake_thresh, device_val, current_usage, email = args
|
| 1040 |
|
| 1041 |
+
print(f"🎯 update_interface called with args: image={image is not None}, usage={current_usage}, email={bool(email)}")
|
| 1042 |
+
|
| 1043 |
if image is None:
|
| 1044 |
return [
|
| 1045 |
"""<div style="background: #fef2f2; padding: 20px; border-radius: 8px; border: 1px solid #fecaca; margin-top: 10px; color: #000000 !important;">
|
|
|
|
| 1056 |
gr.update(visible=False),
|
| 1057 |
"",
|
| 1058 |
"",
|
| 1059 |
+
get_usage_display_html(current_usage),
|
| 1060 |
+
f"<div style='color: green;'>✅ Function called successfully with usage: {current_usage}</div>"
|
| 1061 |
]
|
| 1062 |
|
| 1063 |
if not email:
|
|
|
|
| 1076 |
gr.update(visible=False),
|
| 1077 |
"",
|
| 1078 |
"",
|
| 1079 |
+
get_usage_display_html(current_usage),
|
| 1080 |
+
f"<div style='color: orange;'>⚠️ Email missing. Usage: {current_usage}</div>"
|
| 1081 |
]
|
| 1082 |
|
| 1083 |
+
# Pour l'instant, on utilise l'usage passé en paramètre
|
| 1084 |
+
# Plus tard, on pourra intégrer la récupération depuis les cookies
|
| 1085 |
+
|
| 1086 |
# Check usage limit
|
| 1087 |
if current_usage >= MAX_TRIES:
|
| 1088 |
return [
|
|
|
|
| 1101 |
gr.update(visible=False),
|
| 1102 |
"",
|
| 1103 |
"",
|
| 1104 |
+
get_usage_display_html(current_usage),
|
| 1105 |
+
f"<div style='color: red;'>❌ Usage limit reached: {current_usage}/{MAX_TRIES}</div>"
|
| 1106 |
]
|
| 1107 |
|
| 1108 |
+
print(f"🚀 Starting analysis process...")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1109 |
|
| 1110 |
# Call the REAL processing function
|
| 1111 |
analysis_text, new_usage_count, status_message, download_path = process_image_sequential(
|
| 1112 |
image, damage_thresh, deepfake_thresh, device_val, current_usage, email
|
| 1113 |
)
|
| 1114 |
|
| 1115 |
+
print(f"✅ Analysis completed. New usage: {new_usage_count}")
|
| 1116 |
+
|
| 1117 |
# Check if analysis was successful
|
| 1118 |
if "✅" in status_message or "sent via Mailjet" in status_message:
|
| 1119 |
success_status = """<div style="background: #f0fdf4; padding: 20px; border-radius: 8px; border: 1px solid #bbf7d0; margin-top: 10px; color: #000000 !important;">
|
|
|
|
| 1137 |
gr.update(value=download_path, visible=bool(download_path)),
|
| 1138 |
"",
|
| 1139 |
analysis_text,
|
| 1140 |
+
get_usage_display_html(new_usage_count),
|
| 1141 |
+
f"<div style='color: green;'>✅ Analysis successful! Usage: {new_usage_count}/{MAX_TRIES}</div>"
|
| 1142 |
]
|
| 1143 |
else:
|
| 1144 |
# Analysis failed
|
|
|
|
| 1159 |
gr.update(visible=False),
|
| 1160 |
"",
|
| 1161 |
analysis_text,
|
| 1162 |
+
get_usage_display_html(new_usage_count),
|
| 1163 |
+
f"<div style='color: red;'>❌ Analysis failed: {status_message}</div>"
|
| 1164 |
]
|
| 1165 |
|
| 1166 |
except Exception as e:
|
| 1167 |
+
print(f"❌ Error in update_interface: {e}")
|
| 1168 |
+
import traceback
|
| 1169 |
+
traceback.print_exc()
|
| 1170 |
+
|
| 1171 |
error_status = f"""<div style="background: #fef2f2; padding: 20px; border-radius: 8px; border: 1px solid #fecaca; margin-top: 10px; color: #000000 !important;">
|
| 1172 |
<div style="display: flex; align-items: center; margin-bottom: 12px;">
|
| 1173 |
<span style="font-size: 18px; margin-right: 8px;">❌</span>
|
|
|
|
| 1179 |
</div>
|
| 1180 |
</div>"""
|
| 1181 |
|
| 1182 |
+
return [
|
| 1183 |
+
error_status,
|
| 1184 |
+
current_usage,
|
| 1185 |
+
gr.update(visible=False),
|
| 1186 |
+
"",
|
| 1187 |
+
f"Error: {str(e)}",
|
| 1188 |
+
get_usage_display_html(current_usage),
|
| 1189 |
+
f"<div style='color: red;'>❌ Exception: {str(e)}</div>"
|
| 1190 |
+
]
|
| 1191 |
|
| 1192 |
def clear_interface():
|
| 1193 |
return [
|
|
|
|
| 1201 |
<div style="color: #6b7280; font-size: 14px; margin-top: 8px;">Upload an image and click Analyze</div>
|
| 1202 |
</div>
|
| 1203 |
</div>""",
|
| 1204 |
+
0, # Reset usage counter display
|
| 1205 |
gr.update(visible=False),
|
| 1206 |
"",
|
| 1207 |
"",
|
| 1208 |
get_usage_display_html(0),
|
| 1209 |
+
"<div style='color: blue;'>🔄 Interface cleared</div>",
|
| 1210 |
""
|
| 1211 |
]
|
| 1212 |
|
| 1213 |
+
# Event handlers - Version simplifiée avec debug
|
| 1214 |
+
def handle_analyze_click(image, damage_thresh, deepfake_thresh, device_val, current_usage, email):
|
| 1215 |
+
# Cette fonction sera appelée côté Python
|
| 1216 |
+
print(f"🎯 Analyze button clicked!")
|
| 1217 |
+
print(f"📊 Current inputs: image={image is not None}, usage={current_usage}, email={bool(email)}")
|
| 1218 |
+
return update_interface(image, damage_thresh, deepfake_thresh, device_val, current_usage, email)
|
| 1219 |
+
|
| 1220 |
analyze_btn.click(
|
| 1221 |
+
fn=handle_analyze_click,
|
| 1222 |
inputs=[input_image, damage_threshold, deepfake_threshold, device, usage_counter, recipient_email],
|
| 1223 |
+
outputs=[status_display, usage_counter, download_file, download_info, output_text, usage_display, debug_info]
|
| 1224 |
+
)
|
| 1225 |
+
|
| 1226 |
+
test_js_btn.click(
|
| 1227 |
+
fn=test_javascript_cookies,
|
| 1228 |
+
outputs=[debug_info],
|
| 1229 |
js="""
|
| 1230 |
+
() => {
|
| 1231 |
+
console.log('🍪 Testing JavaScript cookies...');
|
| 1232 |
+
try {
|
| 1233 |
+
const currentUsage = window.hediCookies.getUsage();
|
| 1234 |
+
console.log('✅ Current usage:', currentUsage);
|
| 1235 |
+
window.hediCookies.saveUsage(currentUsage + 1);
|
| 1236 |
+
console.log('✅ Test save completed');
|
| 1237 |
+
alert('✅ Cookie test completed! Check console (F12) for details. Current usage: ' + currentUsage);
|
| 1238 |
+
return null;
|
| 1239 |
+
} catch (e) {
|
| 1240 |
+
console.error('❌ Cookie test failed:', e);
|
| 1241 |
+
alert('❌ Cookie test failed: ' + e.message);
|
| 1242 |
+
return null;
|
| 1243 |
+
}
|
| 1244 |
}
|
| 1245 |
"""
|
| 1246 |
)
|
| 1247 |
|
| 1248 |
clear_btn.click(
|
| 1249 |
fn=clear_interface,
|
| 1250 |
+
outputs=[status_display, usage_counter, download_file, download_info, output_text, usage_display, debug_info, recipient_email]
|
| 1251 |
)
|
| 1252 |
|
| 1253 |
+
# Initialisation au chargement de la page
|
| 1254 |
app.load(
|
| 1255 |
+
fn=lambda: [0, get_usage_display_html(0), "<div style='color: blue;'>🔄 Page loaded, cookies will be initialized</div>"],
|
| 1256 |
+
outputs=[usage_counter, usage_display, debug_info]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1257 |
)
|
| 1258 |
|
| 1259 |
return app
|
|
|
|
| 1456 |
def process_image_sequential(input_image, damage_threshold, deepfake_threshold, device_str, usage_count, recipient_email):
|
| 1457 |
"""Main processing function with sequential pipeline: Damage Detection → Deepfake Detection"""
|
| 1458 |
|
| 1459 |
+
print(f"🚀 process_image_sequential called!")
|
| 1460 |
+
print(f"📊 Parameters: image={input_image is not None}, threshold_damage={damage_threshold}, threshold_deepfake={deepfake_threshold}")
|
| 1461 |
+
print(f"📧 Email: {recipient_email}, Usage: {usage_count}")
|
| 1462 |
+
|
| 1463 |
# Handle usage count
|
| 1464 |
if usage_count is None:
|
| 1465 |
usage_count = 0
|
| 1466 |
+
print(f"⚠️ Usage count was None, set to 0")
|
| 1467 |
|
| 1468 |
try:
|
| 1469 |
usage_count = int(usage_count)
|
| 1470 |
except (TypeError, ValueError):
|
| 1471 |
+
print(f"⚠️ Could not convert usage_count to int: {usage_count}, defaulting to 0")
|
| 1472 |
usage_count = 0
|
| 1473 |
|
| 1474 |
usage_count = usage_count + 1
|
| 1475 |
+
print(f"📈 Incremented usage count to: {usage_count}")
|
| 1476 |
|
| 1477 |
progress_info = []
|
| 1478 |
progress_info.append(f"📊 Individual Usage: {usage_count}/{MAX_TRIES}")
|
|
|
|
| 1845 |
# Test Mailjet configuration
|
| 1846 |
if MAILJET_CONFIG['API_KEY'] and MAILJET_CONFIG['SECRET_KEY']:
|
| 1847 |
print("📧 Mailjet API: ✅ Configured")
|
| 1848 |
+
print(f"📧 From: {MAILJET_CONFIG['FROM_NAME']} <{MAILJET_CONFIG['FROM_EMAIL']}>")
|
| 1849 |
# Test connection at startup
|
| 1850 |
if test_mailjet_connection():
|
| 1851 |
print("📧 Mailjet: ✅ Connection test successful")
|