Spaces:
Sleeping
Sleeping
File size: 10,893 Bytes
5ea3020 f71cd62 d864c28 f71cd62 d864c28 f71cd62 f31c502 5ea3020 f71cd62 d885d7d 5ea3020 f31c502 f71cd62 5ea3020 d864c28 f71cd62 d864c28 f71cd62 5ea3020 f71cd62 5ea3020 f71cd62 d864c28 5ea3020 f71cd62 d885d7d 5ea3020 f71cd62 5ea3020 f31c502 f71cd62 d864c28 5ea3020 f71cd62 5ea3020 f71cd62 d864c28 f71cd62 d864c28 f71cd62 d864c28 f71cd62 d864c28 f71cd62 d864c28 f71cd62 d864c28 f71cd62 d864c28 f71cd62 d864c28 f71cd62 d864c28 5ea3020 f71cd62 f31c502 f71cd62 5ea3020 f71cd62 5ea3020 f71cd62 d864c28 5ea3020 f71cd62 5ea3020 f71cd62 d864c28 f71cd62 d864c28 f71cd62 d864c28 5ea3020 f71cd62 5ea3020 f71cd62 5ea3020 d864c28 5ea3020 f71cd62 d885d7d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
import gradio as gr
import json
import matplotlib.pyplot as plt # استيراد مكتبة Matplotlib لرسم المخططات
import numpy as np # قد نحتاجه لبعض العمليات الحسابية البسيطة
import matplotlib.font_manager as fm # استيراد font_manager للتحكم في الخطوط
import arabic_reshaper # لاستعادة شكل الحروف العربية
from bidi.algorithm import get_display # لضبط اتجاه النص RTL
# استيراد الدالة الرئيسية لتقييم قائمة تشغيل YouTube من ملف main.py
# تأكد أن ملف main.py موجود في نفس المجلد وأن النماذج (.pkl) متاحة له
from main import evaluate_youtube_playlist_individually_same_method2
# =======================================================
# إعداد الخطوط لـ Matplotlib لدعم اللغة العربية
# =======================================================
# يجب التأكد من تثبيت خط عربي في بيئة Docker الخاصة بـ Hugging Face Space.
# مثال على التثبيت في Dockerfile: RUN apt-get update && apt-get install -y fonts-noto-arabic
# سنبحث عن خط Noto Sans Arabic، وإذا لم نجده، سيظل Matplotlib يستخدم الخط الافتراضي
font_path = None
# البحث عن خط Noto Sans Arabic أو Tajawal (يمكنك تغيير هذا بناءً على الخط الذي تفضله وتثبته)
for font in fm.findSystemFonts(fontpaths=None):
if 'NotoSansArabic' in font or 'Tajawal' in font or 'Amiri' in font:
font_path = font
break
if font_path:
# إضافة الخط العربي إلى قائمة الخطوط الافتراضية لـ Matplotlib
plt.rcParams['font.sans-serif'] = [fm.FontProperties(fname=font_path).get_name()] + plt.rcParams['font.sans-serif']
# تعطيل عرض علامة السالب كـ "صندوق" في بعض الخطوط
plt.rcParams['axes.unicode_minus'] = False
# تعيين عائلة الخط الافتراضية
plt.rcParams['font.family'] = 'sans-serif'
print(f"تم تعيين الخط العربي لـ Matplotlib: {font_path}") # لغرض التصحيح في السجلات
else:
print("تحذير: لم يتم العثور على خط عربي مناسب. قد لا يظهر النص العربي بشكل صحيح في المخطط.")
gr.Warning("تحذير: لم يتم العثور على خط عربي مناسب. قد لا يظهر النص العربي بشكل صحيح في المخطط.")
async def evaluate_playlist_local(youtube_url: str, max_comments_per_video: int = 50, max_workers: int = 3):
"""
تستدعي دالة تقييم قائمة تشغيل YouTube مباشرة من ملف main.py.
وتعيد النتائج النصية مجمعة في صندوق واحد، بالإضافة إلى مخطط Matplotlib يوضح نسب التعليقات.
"""
error_message = ""
# تهيئة المخرجات الافتراضية في حالة وجود خطأ أو عدم وجود رابط
default_text_output = "الرجاء إدخال رابط صحيح وتشغيل التقييم."
# إنشاء شكل Matplotlib فارغ لتجنب الأخطاء في حالة عدم وجود بيانات للمخطط
default_plot = plt.figure()
plt.close(default_plot) # إغلاق الشكل الافتراضي لمنع عرضه غير الضروري
# التحقق من أن الرابط ليس فارغًا قبل المتابعة
if not youtube_url:
error_message = "الرجاء إدخال رابط قائمة تشغيل أو فيديو يوتيوب."
gr.Warning(error_message) # عرض تحذير للمستخدم في واجهة Gradio
return error_message, default_plot # إرجاع رسالة خطأ ومخطط فارغ
try:
# استدعاء الدالة الرئيسية لمعالجة قائمة التشغيل/الفيديو
result = await evaluate_youtube_playlist_individually_same_method2(
youtube_url=youtube_url,
max_comments_per_video=max_comments_per_video,
max_workers=max_workers
)
# التحقق مما إذا كانت الدالة قد أعادت خطأ
if "error" in result:
error_message = f"خطأ في المعالجة: {result['error']}"
gr.Error(error_message) # عرض الخطأ كرسالة خطأ حمراء في Gradio
return error_message, default_plot # إرجاع رسالة الخطأ ومخطط فارغ
# استخراج النتائج المطلوبة من كائن JSON المُعاد
overall_quality = result.get("overall_quality", "غير متوفر")
composite_quality = result.get("composite_quality", "غير متوفر")
composite_score = result.get("composite_score", "غير متوفر")
percent_good_videos = result.get("percent_good_videos", "غير متوفر")
# التأكد من أن النسب عددية، وإلا سيتم تعيينها إلى 0.0
positive_ratio = result.get("positive_ratio", 0.0)
negative_ratio = result.get("negative_ratio", 0.0)
# =======================================================
# 1. إعداد النص الموحد ليتم عرضه في صندوق واحد (باستخدام Markdown للتنسيق)
# =======================================================
formatted_output_text = f"""
## 📊 نتائج تقييم قائمة التشغيل:
- **الجودة العامة:** **{overall_quality}**
- **الجودة المركبة:** **{composite_quality}**
- **النقاط المركبة:** **{composite_score} / 100**
- **نسبة الفيديوهات الجيدة:** **{percent_good_videos}%**
- **نسبة التعليقات الإيجابية:** **{positive_ratio}%**
- **نسبة التعليقات السلبية:** **{negative_ratio}%**
"""
# =======================================================
# 2. رسم المخطط باستخدام Matplotlib (مخطط دائري)
# =======================================================
# إنشاء شكل ومحاور للمخطط بحجم مناسب
fig, ax = plt.subplots(figsize=(6, 4))
# النصوص العربية التي ستظهر على المخطط
labels_arabic = ['إيجابية', 'سلبية']
# تطبيق arabic_reshaper و get_display على التسميات العربية
# هذا هو الجزء الذي يحل مشكلة قلب النص وتقطيعه
reshaped_labels = [get_display(arabic_reshaper.reshape(label)) for label in labels_arabic]
sizes = [positive_ratio, negative_ratio] # قيم النسب المئوية
colors = ['#4CAF50', '#F44336'] # ألوان الشرائح (أخضر للإيجابي، أحمر للسلبي)
explode = (0.1, 0) # "تفجير" الشريحة الإيجابية قليلاً لإبرازها (اختياري)
# رسم المخطط الدائري باستخدام التسميات المصححة
ax.pie(sizes, explode=explode, labels=reshaped_labels, colors=colors,
autopct='%1.1f%%', shadow=True, startangle=90, textprops={'fontsize': 12})
ax.axis('equal') # يضمن أن يكون المخطط دائريًا متناسبًا.
# تطبيق arabic_reshaper و get_display على عنوان المخطط
reshaped_title = get_display(arabic_reshaper.reshape('توزيع التعليقات'))
ax.set_title(reshaped_title, fontsize=14, pad=20)
# إغلاق الشكل لمنع Matplotlib من عرضه تلقائيًا في الخلفية، Gradio سيتولى العرض.
plt.close(fig)
# إرجاع النص المنسق والمخطط كناتجين للدالة
return formatted_output_text, fig
except Exception as e:
# التقاط أي أخطاء غير متوقعة أثناء المعالجة
error_message = f"حدث خطأ غير متوقع أثناء المعالجة: {e}"
gr.Error(error_message) # عرض رسالة الخطأ للمستخدم
return error_message, default_plot # إرجاع رسالة الخطأ ومخطط فارغ في حالة الفشل
# بناء واجهة Gradio باستخدام gr.Blocks للتحكم في التخطيط
with gr.Blocks(title="تقييم قائمة تشغيل يوتيوب") as demo:
# عنوان ووصف الواجهة
gr.Markdown("# 📊 تقييم جودة قائمة تشغيل يوتيوب")
gr.Markdown("أدخل رابط قائمة تشغيل أو فيديو يوتيوب لتقييم جودتها بناءً على التحليلات والمشاعر.")
# تقسيم الواجهة إلى صفين (Row) لأعمدة المدخلات والمخرجات
with gr.Row():
# العمود الأول للمدخلات
with gr.Column(scale=1):
youtube_url_input = gr.Textbox(label="رابط قائمة تشغيل/فيديو يوتيوب", placeholder="الصق رابط يوتيوب هنا...", interactive=True)
max_comments_input = gr.Slider(minimum=10, maximum=200, value=50, step=10, label="الحد الأقصى للتعليقات لكل فيديو", interactive=True)
max_workers_input = gr.Slider(minimum=1, maximum=10, value=3, step=1, label="الحد الأقصى للعمال المتوازيين", interactive=True)
submit_button = gr.Button("🚀 تقييم قائمة التشغيل", variant="primary") # زر الإرسال الرئيسي
# العمود الثاني للمخرجات (بجعل scale=2 ليكون أكبر)
with gr.Column(scale=2):
# صندوق نصي واحد لعرض جميع النتائج النصية المنسقة
output_text_box = gr.Markdown(label="النتائج النهائية للتقييم")
# عنصر Gradio لعرض مخطط Matplotlib
output_plot = gr.Plot(label="توزيع التعليقات (إيجابية مقابل سلبية)")
# ربط زر الإرسال بالدالة evaluate_playlist_local
# المدخلات هي عناصر واجهة المستخدم التي توفر البيانات للدالة
# المخرجات هي عناصر واجهة المستخدم التي ستعرض النتائج من الدالة
submit_button.click(
evaluate_playlist_local,
inputs=[youtube_url_input, max_comments_input, max_workers_input],
outputs=[output_text_box, output_plot]
)
# تشغيل واجهة Gradio
demo.launch(debug=True) |