AiOCR / app.py
Asem75's picture
Update app.py
80b78f0 verified
Raw
History Blame Contribute Delete
16.9 kB
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
import time
import hashlib
import gradio as gr
from huggingface_hub import login
# استيراد منطق الإدارة وقنوات الخزنة من الملف المنفصل
import admin_panel
# تسجيل الدخول وتأكيد السيادة
TOKEN = os.getenv("AIOCR_KEY")
if TOKEN:
TOKEN = TOKEN.strip().split()[0]
login(token=TOKEN)
# دالة التحكم في ظهور زر التحقق بمجرد بدء كتابة الاسم
def on_username_change(username):
if username.strip():
return gr.update(visible=True)
return gr.update(visible=False)
# دالة التحقق من الاسم داخل الخزنة السحابية
def check_user_in_vault(username):
if not username.strip():
return (
gr.update(visible=False),
gr.update(visible=False),
gr.update(visible=False),
"⚠️ يرجى إدخال الاسم أولاً لإجراء الفحص السيادي."
)
registry = admin_panel.read_vault_file(admin_panel.USER_REGISTRY_FILE) or {}
if username.strip() in registry:
return (
gr.update(visible=False),
gr.update(visible=False),
gr.update(visible=True),
f"🟢 مرحباً بعودتك يا {username}! تم التحقق من وجودك بالخزنة. يمكنك العبور الآن مباشرة."
)
else:
return (
gr.update(visible=True, value=""),
gr.update(visible=True, value=False),
gr.update(visible=False),
"ℹ️ هذا الاسم غير مسجل سابقاً. يرجى إكمال إدخال الإيميل والموافقة على الشروط لإتمام التسجيل الأول."
)
# دالة التحكم في ظهور زر البصمة بناءً على الموافقة على الشروط
def toggle_gait_button(terms_accepted, email_val):
if terms_accepted and email_val.strip():
return gr.update(visible=True)
return gr.update(visible=False)
# دالة التنقل من واجهة الأزرار الستة إلى واجهة التسجيل
def navigate_to_registration(service_name):
return (
gr.update(visible=False),
gr.update(visible=True),
f"🎯 الخدمة المحددة حالياً: {service_name}",
service_name
)
# 🎯 دالة موحّدة: تأخذ البصمة وتولّد رابط العبور وتعرضه فوراً في ضغطة واحدة
# (دُمجت هنا خطوتا "navigate_to_gait_interface" و"generate_redirect_link"
# القديمتين معاً، فلا حاجة لزر "إتمام عملية البصمة" المنفصل بعد الآن)
def navigate_to_gait_interface(username, email, service):
status_text = f"⚙️ تم ربط الجلسة بنجاح للمشترك: **{username}** | الخدمة المحددة: **{service}**"
# دالة تشفير ثابتة (تأخذ الاسم والإيميل) لإنتاج نفس الرقم دائماً لكل مستخدم
combined_string = f"{username.strip()}-{email.strip()}"
hash_object = hashlib.md5(combined_string.encode('utf-8'))
stable_numeric_id = str(int(hash_object.hexdigest(), 16) % 100000000).zfill(8)
generated_device_token = f"SECURE-FPR-{stable_numeric_id}"
# 🎯 التوجيه بحسب الخدمة المختارة: AI TTS تتجه لمساحة Radar تحديداً.
# تنسيق رابط Hugging Face Space الرسمي: https://<username>-<space-name>.hf.space
# (حروف صغيرة بالكامل + تحويل الشَّرطة السفلية "_" إلى شَرطة عادية "-")
# Asem75/Aiocr_Radar → asem75-aiocr-radar
if service == "AI_TTS":
target_base = "https://asem75-aiocr-radar.hf.space"
else:
target_base = "https://asem75-aiocr-upload.hf.space"
redirect_url = f"{target_base}/?user={username}&email={email}&device_token={generated_device_token}"
html_output = f"""
<div style="text-align:center; padding:20px; border: 2px solid #d4af37; background:#111827; border-radius:10px; margin-top:15px;">
<h4 style="color:#22c55e; margin:0 0 10px 0;">✅ تم إتمام ومطابقة البصمة بنجاح!</h4>
<p style="color:#f3f4f6; font-size:15px; margin-bottom:15px;">اضغط على الرابط أدناه للعبور الآمن إلى بوابة الخدمة:</p>
<a href="{redirect_url}" target="_blank" style="display:inline-block; padding:12px 25px; background:linear-gradient(135deg, #d4af37, #aa841a); color:#0f172a; font-weight:bold; font-size:16px; text-decoration:none; border-radius:8px; box-shadow: 0 0 15px #d4af37;">🔓 فتح بوابة العبور</a>
</div>
"""
return (
gr.update(visible=False), # إخفاء طبقة التسجيل
gr.update(visible=True), # إظهار طبقة العبور النهائية
status_text, # نص معلومات الجلسة
gr.update(visible=True, value=html_output), # إظهار رابط العبور فوراً
)
# 🎯 دالة العودة السيادية إلى الصفحة الرئيسية لمنع أي نقص بالمعلومات
def navigate_back_to_dashboard():
return (
gr.update(visible=True), # إظهار الأزرار الستة لخدمات المنصة
gr.update(visible=False), # إخفاء طبقة البصمة
"⚠️ يرجى الضغط على إحدى الأيقونات النشطة في الأعلى للبدء...", # تصفير مؤشر الخدمة
gr.update(visible=False), # إخفاء زر العبور للتسجيل
gr.update(visible=False) # إخفاء مخرجات رابط الرفع HTML
)
def load_initial_about_data():
about_data = admin_panel.read_vault_file(admin_panel.ABOUT_APP_FILE) or {}
info_val = about_data.get("info", "مرحباً بك في المنظومة الموحدة لخدمات الذكاء الاصطناعي السيادي.")
version_val = about_data.get("version", "v3.0.0")
return info_val, f"الإصدار الحالي المعتمد: {version_val}"
COMBINED_CSS = """
body, .gradio-container { background-color: #0b0f19 !important; color: #f3f4f6 !important; font-family: 'Tajawal', sans-serif !important; }
h1, h2, h3 { color: #d4af37 !important; text-align: center; }
.custom-btn-card { font-size: 16px !important; font-weight: bold !important; height: 110px !important; border: 2px solid #38bdf8 !important; background: #1e293b !important; border-radius: 12px !important; cursor: pointer !important; transition: all 0.3s ease !important; }
.custom-btn-card:hover { transform: translateY(-4px) !important; box-shadow: 0 0 15px #38bdf8 !important; }
.custom-btn-disabled { font-size: 16px !important; font-weight: bold !important; height: 110px !important; border: 2px solid #475569 !important; background: #1e293b !important; opacity: 0.4 !important; border-radius: 12px !important; cursor: not-allowed !important; }
button, .gr-button { background: linear-gradient(135deg, #d4af37, #aa841a) !important; color: #0f172a !important; font-weight: bold !important; border-radius: 8px !important; }
.custom-gait-container { padding: 20px; border: 1px dashed #d4af37; background-color: #111827; border-radius: 10px; margin-bottom: 15px; }
"""
with gr.Blocks(title="بوابة توجيه المنظومة الموحدة") as demo:
selected_service_state = gr.State("")
gr.HTML("""
<div style="text-align:center; padding:20px; border-radius:10px; margin-bottom:15px;">
<h1 style="margin:0; font-size:2.2rem; filter:drop-shadow(0 0 10px #d4af37);">🔮 سديم المنظومة السيادية الموحدة</h1>
<p style="color:#9ca3af; margin:5px 0 0 0; font-size:1.05rem;">بوابة العبور الذكية الموحدة للمساحات السيادية ومراقبة الرام</p>
</div>
""")
with gr.Tabs():
with gr.Tab("📱 خدمات المنصة الرقمية"):
with gr.Column(visible=True) as layer_1_icons:
gr.HTML("<h3 style='text-align:right; margin-bottom:20px; color:#38bdf8;'>👋 خطوتك الأولى: اختر الخدمة الذكية التي تود تفعيلها من القائمة التالية:</h3>")
with gr.Row():
btn_ocr = gr.Button("🔮\nAI OCR", elem_classes="custom-btn-card")
btn_tts = gr.Button("🗣️\nAI TTS", elem_classes="custom-btn-card")
btn_teacher = gr.Button("👨‍🏫\nMy Teacher", elem_classes="custom-btn-card")
with gr.Row():
btn_explore = gr.Button("📚\nMy Courses", elem_classes="custom-btn-card")
btn_editor_dis = gr.Button("📝\nAI Editor (قريباً)", elem_classes="custom-btn-disabled", interactive=False)
btn_vault_dis = gr.Button("🛡️\nخزنة الحماية (قريباً)", elem_classes="custom-btn-disabled", interactive=False)
service_indicator = gr.Markdown("⚠️ يرجى الضغط على إحدى الأيقونات النشطة في الأعلى للبدء...", elem_id="serv-ind")
next_to_reg_btn = gr.Button("🚪 ادخل للتسجيل وتأكيد الهوية", variant="primary", visible=False)
with gr.Column(visible=False) as layer_2_registration:
gr.HTML("<h3 style='text-align:right; color:#d4af37;'>📝 خطوتك الثانية: تسجيل الهوية والعبور الآمن للبصمة</h3>")
with gr.Tabs():
with gr.Tab("🔐 بوابة العبور والتسجيل"):
with gr.Row():
client_name = gr.Textbox(label="👤 الاسم الكامل", placeholder="اكتب اسمك الثلاثي هنا لتأكيد البصمة...")
verify_user_btn = gr.Button("🔍 فحص والتحقق من الاسم في الخزنة السحابية", variant="secondary", visible=False)
status_check_output = gr.Markdown("📌 بانتظار إدخال الاسم وضغط زر التحقق...")
with gr.Row():
client_email = gr.Textbox(label="📧 البريد الإلكتروني المعتمد", placeholder="اكتب بريدك الإلكتروني هنا...", visible=False)
terms_checkbox = gr.Checkbox(label="📜 أوافق بالكامل على شروط وأحكام العبور السيادية واستخدام المنظومة الموحدة", value=False, visible=False)
go_to_static_btn = gr.Button("🔗 الانتقال إلى فحص البصمة والتوجيه النهائي", variant="primary", visible=False)
with gr.Tab("ℹ️ حول التطبيق والوثيقة الاستراتيجية"):
about_text_box = gr.Markdown("جاري جلب وثيقة التعريف السحابية...")
version_box = gr.Markdown("الإصدار: جاري الفحص...")
# ──────────────────────────────────────────────────────────
# طبقة العبور النهائية: أصبحت الآن تعرض رابط العبور مباشرة
# بمجرد الوصول إليها (تم حذف شاشة "الوقوف أمام الكاميرا"
# وزر "إتمام عملية البصمة" المنفصل بناءً على طلبك)
# ──────────────────────────────────────────────────────────
with gr.Column(visible=False) as layer_4_gait:
gr.HTML("<h3 style='text-align:center; color:#38bdf8;'>👣 بوابة العبور النهائية</h3>")
gait_session_info = gr.Markdown("⚙️ جاري تحميل بيانات الجلسة المشفرة...")
redirect_link_output = gr.HTML(visible=False)
back_to_services_btn = gr.Button("🔄 العودة إلى القائمة الرئيسية للخدمات", variant="secondary")
with gr.Tab("👑 قمرة القيادة (خاص بالأدمن)"):
with gr.Row():
admin_pwd_input = gr.Textbox(label="🔑 أدخل رمز العبور السيادي للأدمن", type="password", placeholder="اكتب كلمة مرور الإدارة لوصول كامل...")
verify_pwd_btn = gr.Button("🔓 فحص وتفعيل الصلاحيات")
admin_auth_status = gr.Markdown("🔒 بانتظار إدخال رمز العبور السيادي...")
with gr.Column(visible=False) as layer_3_admin_panel:
about_info_input = gr.Textbox(label="📝 نص وثيقة التعريف الاستراتيجية بالمنظومة", lines=5, visible=False)
about_version_input = gr.Textbox(label="🔢 رقم الإصدار المعتمد سيادياً", visible=False)
adm_refresh_msg, adm_msg_tbl, adm_refresh_usr, adm_usr_tbl = admin_panel.build_admin_ui(about_info_input, about_version_input)
# ================= خريطة تفاعلات الأحداث =================
btn_ocr.click(fn=lambda: ("AI_OCR", "🟢 تم اختيار خدمة: **AI OCR** بنجاح. يمكنك الآن الدخول للتسجيل.", gr.update(visible=True)), outputs=[selected_service_state, service_indicator, next_to_reg_btn])
btn_tts.click(fn=lambda: ("AI_TTS", "🟢 تم اختيار خدمة: **AI TTS** بنجاح. يمكنك الآن الدخول للتسجيل.", gr.update(visible=True)), outputs=[selected_service_state, service_indicator, next_to_reg_btn])
btn_teacher.click(fn=lambda: ("My_Teacher", "🟢 تم اختيار خدمة: **My Teacher** بنجاح. يمكنك الآن الدخول للتسجيل.", gr.update(visible=True)), outputs=[selected_service_state, service_indicator, next_to_reg_btn])
btn_explore.click(fn=lambda: ("My_Courses", "🟢 تم اختيار خدمة: **My Courses** بنجاح. يمكنك الآن الدخول للتسجيل.", gr.update(visible=True)), outputs=[selected_service_state, service_indicator, next_to_reg_btn])
next_to_reg_btn.click(
fn=navigate_to_registration,
inputs=[selected_service_state],
outputs=[layer_1_icons, layer_2_registration, service_indicator, selected_service_state]
)
client_name.change(fn=on_username_change, inputs=[client_name], outputs=[verify_user_btn])
verify_user_btn.click(
fn=check_user_in_vault,
inputs=[client_name],
outputs=[client_email, terms_checkbox, go_to_static_btn, status_check_output]
)
terms_checkbox.change(fn=toggle_gait_button, inputs=[terms_checkbox, client_email], outputs=[go_to_static_btn])
client_email.change(fn=toggle_gait_button, inputs=[terms_checkbox, client_email], outputs=[go_to_static_btn])
# ضغطة واحدة فقط: تنتقل لطبقة العبور وتولّد رابط التحويل وتعرضه مباشرة
go_to_static_btn.click(
fn=navigate_to_gait_interface,
inputs=[client_name, client_email, selected_service_state],
outputs=[layer_2_registration, layer_4_gait, gait_session_info, redirect_link_output]
)
back_to_services_btn.click(
fn=navigate_back_to_dashboard,
outputs=[layer_1_icons, layer_4_gait, service_indicator, next_to_reg_btn, redirect_link_output]
)
def unlock_admin_panel(password):
if password == "asem2026":
return gr.update(visible=True), gr.update(value="🔓 تم التحقق بنجاح! قمرة القيادة نشطة الآن.")
return gr.update(visible=False), gr.update(value="❌ كلمة المرور غير صحيحة. الوصول مرفوض.")
verify_pwd_btn.click(fn=unlock_admin_panel, inputs=[admin_pwd_input], outputs=[layer_3_admin_panel, admin_auth_status])
demo.load(fn=load_initial_about_data, outputs=[about_text_box, version_box])
demo.load(admin_panel.load_messages_grid, outputs=[adm_msg_tbl])
demo.load(admin_panel.get_users_table, outputs=[adm_usr_tbl])
if __name__ == "__main__":
demo.launch(server_name="0.0.0.0", theme=gr.themes.Soft(), css=COMBINED_CSS)