Alide21 commited on
Commit
18efb04
·
verified ·
1 Parent(s): 4033e26

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +37 -27
app.py CHANGED
@@ -34,7 +34,6 @@ body { direction: rtl; background-color: #f4f6f9; }
34
 
35
  .hero-header h1, .hero-header p, .hero-header span { color: white !important; }
36
 
37
- /* الرقم أبيض ناصع */
38
  .real-count {
39
  font-size: 4rem;
40
  color: #FFFFFF !important;
@@ -68,6 +67,9 @@ body { direction: rtl; background-color: #f4f6f9; }
68
  line-height: 1.8 !important;
69
  text-align: center;
70
  }
 
 
 
71
  """
72
 
73
  # --- المنطق الخلفي ---
@@ -91,38 +93,43 @@ with ThreadPoolExecutor(max_workers=10) as executor:
91
  ALL_AYAT = [item for sublist in results for item in sublist]
92
 
93
  def validate_ayah(v):
94
- """التحقق من طول الآية (أقل من 200 رمز/حرف)"""
95
  return len(v['text']) <= 200
96
 
 
 
 
 
 
 
 
97
  def jump_to_ayah(s_name, a_num):
98
  try:
99
  target_num = int(a_num)
100
  for i, v in enumerate(ALL_AYAT):
101
  if v['surah_name'] == s_name and v['ayah'] == target_num:
102
  if not validate_ayah(v):
103
- return "⚠️ الآية المختارة طويلة جداً (تتجاوز 200 رمز). يرجى اختيار آية أقصر.", gr.update(), gr.update(), gr.update()
104
- return "✅ تم العثور على الآية", f"<div class='ayah-text'>{v['text']}</div>", f"### {v['surah_name']} | آية {v['ayah']}", i
105
- return "⚠️ الآية غير موجودة، تأكد من الرقم", gr.update(), gr.update(), gr.update()
 
106
  except:
107
- return "⚠️ خطأ في المدخلات", gr.update(), gr.update(), gr.update()
108
 
109
  def on_submit(audio, current_idx):
110
  if not audio: return "⚠️ سجل صوتك أولاً", gr.update(), gr.update(), current_idx
111
  v = ALL_AYAT[current_idx]
112
  try:
113
  api.upload_file(path_or_fileobj=audio, path_in_repo=f"data/s{v['surah']}_a{v['ayah']}_{uuid.uuid4().hex[:6]}.wav", repo_id=REPO_ID, repo_type="dataset", token=HF_TOKEN)
114
- while True:
115
- next_idx = random.randint(0, len(ALL_AYAT)-1)
116
- if validate_ayah(ALL_AYAT[next_idx]): break
117
  nv = ALL_AYAT[next_idx]
118
- return "✅ تم الحفظ بنجاح", f"<div class='ayah-text'>{nv['text']}</div>", f"### {nv['surah_name']} | آية {nv['ayah']}", next_idx
119
  except Exception as e: return f"❌ فشل الرفع: {str(e)}", gr.update(), gr.update(), current_idx
120
 
121
  # --- بناء الواجهة ---
122
  with gr.Blocks(title="منصة تلاوة") as demo:
123
- idx_state = gr.State(random.randint(0, len(ALL_AYAT)-1))
 
124
 
125
- # الهيدر
126
  gr.HTML(f"""
127
  <div class="hero-header">
128
  <h1>مِنَصَّة التِّلَاوَة</h1>
@@ -135,27 +142,27 @@ with gr.Blocks(title="منصة تلاوة") as demo:
135
  """)
136
 
137
  with gr.Column(elem_classes="gradio-container"):
138
- # إرشادات RTL
139
  gr.HTML("""
140
  <div class="instruction-box">
141
- <strong>💡 تنبيه هام:</strong>
142
- لضمان جودة تدريب الذكاء الاصطناعي، يرجى قراءة الآية بنفس واحد دون توقف وتكرار.
143
- <br>نقبل حالياً الآيات التي لا تتجاوز 200 رمز لضمان دقة التحليل.
144
  </div>
145
  """)
146
 
147
  with gr.Row():
148
  with gr.Column(scale=2):
149
  with gr.Column(elem_classes="custom-card"):
150
- # عرض آية عشوائية أولية صالحة
151
- start_v = ALL_AYAT[idx_state.value]
152
- if not validate_ayah(start_v):
153
- idx_state.value = next(i for i, v in enumerate(ALL_AYAT) if validate_ayah(v))
154
- start_v = ALL_AYAT[idx_state.value]
155
-
156
- info_text = gr.Markdown(f"### {start_v['surah_name']} | آية {start_v['ayah']}")
157
- text_html = gr.HTML(f"<div class='ayah-text'>{start_v['text']}</div>")
158
- status_msg = gr.Markdown("")
 
159
  with gr.Row():
160
  send_btn = gr.Button("🎤 إرسال التسجيل", variant="primary")
161
  rnd_btn = gr.Button("🔄 آية عشوائية", variant="secondary")
@@ -171,10 +178,13 @@ with gr.Blocks(title="منصة تلاوة") as demo:
171
  a_num = gr.Number(label="رقم الآية", value=1, precision=0)
172
  go_btn = gr.Button("انتقال")
173
 
 
 
 
174
  # أحداث الأزرار
175
  rnd_btn.click(
176
- lambda: (v := next(ALL_AYAT[i] for _ in range(100) if validate_ayah(ALL_AYAT[i := random.randint(0, len(ALL_AYAT)-1)]))) and
177
- (f"<div class='ayah-text'>{v['text']}</div>", f"### {v['surah_name']} | آية {v['ayah']}", i, ""),
178
  outputs=[text_html, info_text, idx_state, status_msg],
179
  show_progress="hidden"
180
  )
 
34
 
35
  .hero-header h1, .hero-header p, .hero-header span { color: white !important; }
36
 
 
37
  .real-count {
38
  font-size: 4rem;
39
  color: #FFFFFF !important;
 
67
  line-height: 1.8 !important;
68
  text-align: center;
69
  }
70
+
71
+ /* ضبط اتجاه رسائل الحالة */
72
+ .status-msg { direction: rtl !important; text-align: right !important; }
73
  """
74
 
75
  # --- المنطق الخلفي ---
 
93
  ALL_AYAT = [item for sublist in results for item in sublist]
94
 
95
  def validate_ayah(v):
 
96
  return len(v['text']) <= 200
97
 
98
+ # دالة لاختيار آية عشوائية صالحة
99
+ def get_random_valid_ayah():
100
+ while True:
101
+ idx = random.randint(0, len(ALL_AYAT)-1)
102
+ if validate_ayah(ALL_AYAT[idx]):
103
+ return idx
104
+
105
  def jump_to_ayah(s_name, a_num):
106
  try:
107
  target_num = int(a_num)
108
  for i, v in enumerate(ALL_AYAT):
109
  if v['surah_name'] == s_name and v['ayah'] == target_num:
110
  if not validate_ayah(v):
111
+ return "⚠️ الآية المختارة طويلة جداً (تتجاوز 200 رمز).", gr.update(), gr.update(), gr.update()
112
+ # الرسالة هنا RTL
113
+ return " تم العثور على الآية بنجاح", f"<div class='ayah-text'>{v['text']}</div>", f"### {v['surah_name']} | آية {v['ayah']}", i
114
+ return "⚠️ الآية غير موجودة في هذه السورة.", gr.update(), gr.update(), gr.update()
115
  except:
116
+ return "⚠️ يرجى التأكد من رقم الآية.", gr.update(), gr.update(), gr.update()
117
 
118
  def on_submit(audio, current_idx):
119
  if not audio: return "⚠️ سجل صوتك أولاً", gr.update(), gr.update(), current_idx
120
  v = ALL_AYAT[current_idx]
121
  try:
122
  api.upload_file(path_or_fileobj=audio, path_in_repo=f"data/s{v['surah']}_a{v['ayah']}_{uuid.uuid4().hex[:6]}.wav", repo_id=REPO_ID, repo_type="dataset", token=HF_TOKEN)
123
+ next_idx = get_random_valid_ayah()
 
 
124
  nv = ALL_AYAT[next_idx]
125
+ return "✅ تم الحفظ بنجاح، جزاك الله خيراً", f"<div class='ayah-text'>{nv['text']}</div>", f"### {nv['surah_name']} | آية {nv['ayah']}", next_idx
126
  except Exception as e: return f"❌ فشل الرفع: {str(e)}", gr.update(), gr.update(), current_idx
127
 
128
  # --- بناء الواجهة ---
129
  with gr.Blocks(title="منصة تلاوة") as demo:
130
+ # الآن سيتم اختيار آية جديدة في كل مرة يتم فيها بناء الـ Blocks (أي عند التحديث)
131
+ idx_state = gr.State(get_random_valid_ayah())
132
 
 
133
  gr.HTML(f"""
134
  <div class="hero-header">
135
  <h1>مِنَصَّة التِّلَاوَة</h1>
 
142
  """)
143
 
144
  with gr.Column(elem_classes="gradio-container"):
 
145
  gr.HTML("""
146
  <div class="instruction-box">
147
+ <strong>💡 تنبيه للجودة:</strong>
148
+ يرجى قراءة الآية بنفس واحد.
149
+ <br>نقبل الآيات التي لا تتجاوز 200 رمز لضمان دقة التحليل.
150
  </div>
151
  """)
152
 
153
  with gr.Row():
154
  with gr.Column(scale=2):
155
  with gr.Column(elem_classes="custom-card"):
156
+ # نستخدم دالة لتهيئة العرض الأول بناءً على idx_state
157
+ def load_initial_ayah(idx):
158
+ v = ALL_AYAT[idx]
159
+ return f"<div class='ayah-text'>{v['text']}</div>", f"### {v['surah_name']} | آية {v['ayah']}"
160
+
161
+ # إنشاء المكونات بقيم فارغة ثم تعبئتها
162
+ info_text = gr.Markdown()
163
+ text_html = gr.HTML()
164
+ status_msg = gr.Markdown(elem_classes="status-msg")
165
+
166
  with gr.Row():
167
  send_btn = gr.Button("🎤 إرسال التسجيل", variant="primary")
168
  rnd_btn = gr.Button("🔄 آية عشوائية", variant="secondary")
 
178
  a_num = gr.Number(label="رقم الآية", value=1, precision=0)
179
  go_btn = gr.Button("انتقال")
180
 
181
+ # حدث لتحميل الآية عند فتح الصفحة لأول مرة
182
+ demo.load(load_initial_ayah, inputs=[idx_state], outputs=[text_html, info_text])
183
+
184
  # أحداث الأزرار
185
  rnd_btn.click(
186
+ lambda: (idx := get_random_valid_ayah()) and (v := ALL_AYAT[idx]) and
187
+ (f"<div class='ayah-text'>{v['text']}</div>", f"### {v['surah_name']} | آية {v['ayah']}", idx, ""),
188
  outputs=[text_html, info_text, idx_state, status_msg],
189
  show_progress="hidden"
190
  )