Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| from PIL import Image | |
| import os | |
| import numpy as np | |
| import cv2 # فقط لقراءة الصور باستخدام imread لضمان التوافق | |
| # ---------------------------------------------------- | |
| # A. الكتالوج والبيانات التجارية (JPG) | |
| # ---------------------------------------------------- | |
| # 🚨 المسارات تطابق تمامًا ملفات JPG المرفوعة حاليًا في مجلد assets/ | |
| GLASSES_CATALOG = { | |
| # النظارة 1 | |
| "النظارة المستديرة (1)": { | |
| "path": "assets/507b01553ce6931a5d45b5554893a24a.jpg", | |
| "price": 120.00, | |
| "description": "نظارة مستديرة كلاسيكية، مثالية للوجه البيضاوي.", | |
| "shape_fit": "بيضاوي" | |
| }, | |
| # النظارة 2 | |
| "النظارة الطيار (2)": { | |
| "path": "assets/56a9c0a1d10c21d475159d6890f4cf48.jpg", | |
| "price": 85.00, | |
| "description": "تصميم طياري رقيق، يبرز جمال الوجه.", | |
| "shape_fit": "بيضاوي" | |
| }, | |
| # النظارة 3 | |
| "النظارة المربعة (3)": { | |
| "path": "assets/b1c4d0a357457c77974d5ce4580d0e8e.jpg", | |
| "price": 99.00, | |
| "description": "إطار مربع عصري، مناسب لإضافة تحديد للوجه البيضاوي.", | |
| "shape_fit": "بيضاوي" | |
| } | |
| } | |
| LOADED_GLASSES = {} | |
| def load_glasses(): | |
| """تحميل صور النظارات عند بدء التشغيل.""" | |
| all_loaded = True | |
| for name, data in GLASSES_CATALOG.items(): | |
| try: | |
| # استخدام OpenCV للقراءة لضمان التوافق مع بيئة Space | |
| img_bgr = cv2.imread(data['path'], cv2.IMREAD_COLOR) | |
| if img_bgr is not None and img_bgr.size > 0: | |
| # تحويلها إلى RGB لكي تتعامل معها مكتبة Gradio بشكل صحيح | |
| img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB) | |
| LOADED_GLASSES[name] = img_rgb | |
| print(f"✅ تم تحميل النظارة '{name}' بنجاح.") | |
| else: | |
| print(f"❌ فشل تحميل النظارة '{name}' من المسار: {data['path']}. يرجى التحقق من وجود الملف واسم الامتداد.") | |
| all_loaded = False | |
| except Exception as e: | |
| print(f"❌ خطأ حاد أثناء محاولة تحميل '{name}': {e}") | |
| all_loaded = False | |
| if not all_loaded: | |
| print("❌ فشل تشغيل Gradio: يرجى مراجعة سجلات التحذيرات لتأكيد تحميل صور النظارات.") | |
| return all_loaded | |
| GLASSES_LOADED_OK = load_glasses() | |
| # ---------------------------------------------------- | |
| # B. دالة عرض الكتالوج فقط (لا تحتاج مدخلات) | |
| # ---------------------------------------------------- | |
| def display_catalog(): | |
| """عرض بيانات الكتالوج والصور المحملة مسبقًا.""" | |
| # تصفية الكتالوج (هنا الكل سيظهر لأنه لا يوجد شرط على الوجه) | |
| filtered_glasses = { | |
| name: data for name, data in GLASSES_CATALOG.items() | |
| if name in LOADED_GLASSES | |
| } | |
| # إعداد المُخرجات للواجهة (3 نظارات) | |
| output_imgs = [None] * 3 | |
| output_info = [None] * 3 | |
| for i, (name, data) in enumerate(filtered_glasses.items()): | |
| if i < 3: | |
| output_imgs[i] = LOADED_GLASSES[name] | |
| output_info[i] = ( | |
| f"**{name}**\n" | |
| f"🏷️ السعر: **{data['price']:.2f} $**\n" | |
| f"{data['description']}" | |
| ) | |
| # المُخرجات تقتصر على صور النظارات ومعلوماتها | |
| return ( | |
| output_imgs[0], output_info[0], | |
| output_imgs[1], output_info[1], | |
| output_imgs[2], output_info[2] | |
| ) | |
| # ---------------------------------------------------- | |
| # C. تشغيل التطبيق (الواجهة التسويقية باستخدام gr.Blocks) | |
| # ---------------------------------------------------- | |
| custom_css = """ | |
| .gradio-container { max-width: 1600px; margin: 0 auto; font-family: 'Arial', sans-serif !important; } | |
| .product-card { border: 1px solid #e0e0e0; border-radius: 10px; padding: 10px; background-color: #ffffff; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05); transition: box-shadow 0.3s ease; } | |
| .product-card:hover { box-shadow: 0 6px 12px rgba(0, 0, 0, 0.1); } | |
| .info-box { background-color: #f8f9fa; padding: 10px; border-radius: 8px; margin-top: 5px; direction: rtl; } | |
| """ | |
| if GLASSES_LOADED_OK: | |
| with gr.Blocks(title="كتالوج النظارات التسويقي", theme=gr.themes.Soft(), css=custom_css) as demo: | |
| gr.Markdown( | |
| """ | |
| # 🛍️ **كتالوج النظارات التسويقي** | |
| إليك نظاراتنا المتاحة حاليًا (3 نظارات) مع تفاصيلها وأسعارها. | |
| --- | |
| """ | |
| ) | |
| gr.Markdown("## ✨ الكتالوج المقترح لك") | |
| # 1. قسم عرض الكتالوج (3 منتجات) | |
| # تعريف المخرجات (صور النظارات ومعلوماتها) | |
| output_img1 = gr.Image(label="النظارة 1", show_label=False) | |
| output_info1 = gr.Markdown("---", elem_classes=["info-box"]) | |
| output_img2 = gr.Image(label="النظارة 2", show_label=False) | |
| output_info2 = gr.Markdown("---", elem_classes=["info-box"]) | |
| output_img3 = gr.Image(label="النظارة 3", show_label=False) | |
| output_info3 = gr.Markdown("---", elem_classes=["info-box"]) | |
| all_outputs = [output_img1, output_info1, output_img2, output_info2, output_img3, output_info3] | |
| with gr.Row(): | |
| with gr.Column(scale=1, elem_classes=["product-card"]): | |
| # تم حذف: output_img1.render() | |
| # تم حذف: output_info1.render() | |
| pass # العناصر تُعرض تلقائياً بمجرد تعريفها في السياق | |
| with gr.Column(scale=1, elem_classes=["product-card"]): | |
| # تم حذف: output_img2.render() | |
| # تم حذف: output_info2.render() | |
| pass | |
| with gr.Column(scale=1, elem_classes=["product-card"]): | |
| # تم حذف: output_img3.render() | |
| # تم حذف: output_info3.render() | |
| pass | |
| # تشغيل الدالة لعرض الكتالوج بمجرد تحميل الواجهة | |
| demo.load( | |
| fn=display_catalog, | |
| inputs=None, | |
| outputs=all_outputs | |
| ) | |
| demo.launch(server_name="0.0.0.0", server_port=7860) | |
| else: | |
| print("❌ فشل تشغيل Gradio: يرجى مراجعة سجلات التحذيرات لتأكيد تحميل صور النظارات.") |