# admin_office_app_patch.py #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Divid Teacher — Bridge لمكتب الإدارة V10. الإصدار: admin_office_app_patch_v5_admin_office_v10_unified_diagnostics المهام: - استخدام admin_access_manager لتسجيل دخول owner / manager_1 / manager_2. - تركيب admin_office_ui.py داخل admin_panel الحالي. - تمرير حقل كلمة مرور المدير نفسه حتى يفحص كل زر الصلاحية على السيرفر. - إبقاء مكونات الفحص القديمة في الخلف للتوافق مع callbacks القديمة، بينما الفحوص المرئية أصبحت مجتمعة داخل تبويب «الفحص» في Admin Office V10. - لا يحتاج تعديل app.py يدويًا طالما أن app.py يستدعي apply_admin_office_patch(). """ from __future__ import annotations import re VERSION = "admin_office_app_patch_v5_admin_office_v10_unified_diagnostics" REQUIRED_ADMIN_OFFICE_VERSION = ( "admin_office_ui_v10_repository_browser_" "flexible_audit_unified_diagnostics" ) def _patch_admin_login(source: str) -> str: new_login = r'''def ui_admin_login(password): password = str(password or "").strip() try: from admin_access_manager import get_manager as get_admin_access_manager access = get_admin_access_manager() result = access.authenticate(password) except Exception as exc: return ( markdown_error(f"تعذر تحميل نظام صلاحيات المدراء: {exc}"), gr.update(visible=False), ) if isinstance(result, dict) and result.get("success"): display_name = str(result.get("display_name") or "المدير").strip() admin_id = str(result.get("admin_id") or "").strip() return ( markdown_success( f"تم فتح لوحة المدير: {display_name}" + (f" — {admin_id}" if admin_id else "") ), gr.update(visible=True), ) message = ( str(result.get("message") or "كلمة مرور المدير غير صحيحة.") if isinstance(result, dict) else "كلمة مرور المدير غير صحيحة." ) return ( markdown_error(message), gr.update(visible=False), )''' pattern = r'''def ui_admin_login\(password\):.*?(?=\n\ndef ui_admin_list_students\()''' patched, count = re.subn( pattern, new_login, source, count=1, flags=re.DOTALL, ) if count != 1: raise RuntimeError( "لم أجد دالة ui_admin_login الحالية بصورة آمنة؛ " "لم يتم تطبيق Patch حتى لا نكسر التطبيق." ) return patched def _hide_legacy_admin_tools(source: str) -> str: """ لا يحذف الوظائف القديمة ولا callbacks الخاصة بها. يخفي واجهتها فقط لأن Admin Office V10 يعرض الفحوص في تبويب واحد. """ replacements = { ' gr.Markdown("## أدوات المدير والفحص")': ' gr.Markdown("## أدوات المدير والفحص القديمة - نُقلت إلى تبويب الفحص", visible=False)', ' check = gr.Button("فحص النظام")': ' check = gr.Button("فحص النظام", visible=False)', ' queue_center_btn = gr.Button("عرض الحصص العلاجية")': ' queue_center_btn = gr.Button("عرض الحصص العلاجية", visible=False)', ' process_task_btn = gr.Button("معالجة مهمة واحدة")': ' process_task_btn = gr.Button("معالجة مهمة واحدة", visible=False)', ' queue_test_btn = gr.Button("اختبار نظام الحصص المؤجلة")': ' queue_test_btn = gr.Button("اختبار نظام الحصص المؤجلة", visible=False)', ' media_test_btn = gr.Button("اختبار فيديو الحصة العلاجية")': ' media_test_btn = gr.Button("اختبار فيديو الحصة العلاجية", visible=False)', ' admin_media_html = gr.HTML("")': ' admin_media_html = gr.HTML("", visible=False)', ' admin_out = gr.Markdown("")': ' admin_out = gr.Markdown("", visible=False)', ' with gr.Accordion("فحص دخول الطالب", open=False):': ' with gr.Accordion("فحص دخول الطالب", open=False, visible=False):', } for old, new in replacements.items(): if old in source: source = source.replace(old, new, 1) return source def apply_admin_office_patch(source: str) -> str: if not isinstance(source, str) or not source.strip(): raise RuntimeError("مصدر app.py فارغ.") source = _patch_admin_login(source) source = _hide_legacy_admin_tools(source) marker = ' with gr.Accordion("إدارة تسجيل الطلاب", open=True):' if marker in source: indent = " " else: marker = 'with gr.Accordion("إدارة تسجيل الطلاب", open=True):' if marker not in source: raise RuntimeError( "لم أجد واجهة إدارة تسجيل الطلاب القديمة داخل المصدر. " "لم يتم تطبيق Patch حتى لا نكسر التطبيق." ) pos = source.find(marker) indent = source[source.rfind("\n", 0, pos) + 1:pos] replacement = ( indent + "# مكتب الإدارة V10 متعدد المديرين والصلاحيات والفحص الموحد\n" + indent + "try:\n" + indent + " from admin_office_ui import build_admin_office\n" + indent + " _ADMIN_OFFICE_COMPONENTS = build_admin_office(\n" + indent + " get_admin_manager=get_admin_manager,\n" + indent + " get_student_manager=get_student_manager,\n" + indent + " admin_key=ADMIN_PANEL_KEY,\n" + indent + " admin_password_component=admin_password,\n" + indent + " )\n" + indent + "except Exception as _admin_office_error:\n" + indent + " gr.Markdown(\n" + indent + ' "### تعذر تحميل Admin Office V10\\n\\n"\n' + indent + " + str(_admin_office_error)\n" + indent + " )\n\n" + indent + "# واجهة التسجيل القديمة مخفية للتوافق فقط\n" + indent + 'with gr.Accordion("إدارة تسجيل الطلاب القديمة - توافق", open=False, visible=False):' ) patched = source.replace(marker, replacement, 1) required = [ "from admin_access_manager import get_manager as get_admin_access_manager", "from admin_office_ui import build_admin_office", "admin_password_component=admin_password", "_ADMIN_OFFICE_COMPONENTS = build_admin_office(", "Admin Office V10", ] missing = [item for item in required if item not in patched] if missing: raise RuntimeError( "فشل التحقق من Patch مكتب الإدارة V10: " + repr(missing) ) # إذا كان مصدر التطبيق كاملاً وصالحًا، نتحقق من الصياغة قبل التنفيذ. compile(patched, "", "exec") return patched def summary(): return { "success": True, "ready": True, "version": VERSION, "admin_office_required_version": REQUIRED_ADMIN_OFFICE_VERSION, "multi_admin": True, "unified_diagnostics": True, "legacy_diagnostics_deleted": False, "legacy_diagnostics_hidden_for_compatibility": True, "app_py_manual_change_required": False, }