Alide21 commited on
Commit
f8bdf4c
·
verified ·
1 Parent(s): df96b41

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +138 -0
app.py ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ import re
4
+ import random
5
+ import os
6
+ from huggingface_hub import HfApi
7
+ from datetime import datetime
8
+
9
+ # إعدادات الأمان والاتصال
10
+ HF_TOKEN = os.getenv("HF_TOKEN")
11
+ REPO_ID = "Alide21/speech_quran"
12
+ api = HfApi()
13
+
14
+ # تحسين المظهر باستخدام CSS مخصص
15
+ custom_css = """
16
+ .container { max-width: 800px; margin: auto; }
17
+ .ayah-box {
18
+ background: #fdf6e3;
19
+ border-right: 5px solid #d3af37;
20
+ padding: 30px;
21
+ border-radius: 10px;
22
+ font-size: 28px !important;
23
+ line-height: 2 !important;
24
+ text-align: center;
25
+ box-shadow: 0 4px 6px rgba(0,0,0,0.05);
26
+ }
27
+ footer {display: none !important;}
28
+ """
29
+
30
+ def clean_text(text):
31
+ text = re.sub(r'<[^>]*>', '', text)
32
+ return text.strip()
33
+
34
+ def load_quran_data():
35
+ all_verses = []
36
+ # تحميل عينة من السور للسرعة (يمكنك تعديل المدى لـ 115)
37
+ for s in range(1, 115):
38
+ try:
39
+ url = f"https://raw.githubusercontent.com/CheeseWithSauce/TheHolyQuranJSONFormat/refs/heads/main/tajweedsurahs/{s:03}.json"
40
+ data = requests.get(url, timeout=5).json()
41
+ for v in data["verses"]:
42
+ text = clean_text(v["text_ar"])
43
+ if len(text) < 200:
44
+ all_verses.append({
45
+ "surah": s,
46
+ "ayah": v["id"],
47
+ "text": text,
48
+ "surah_name": data["name"]
49
+ })
50
+ except: continue
51
+ return all_verses
52
+
53
+ ALL_AYAT = load_quran_data()
54
+
55
+ def get_stats():
56
+ try:
57
+ files = api.list_repo_files(repo_id=REPO_ID, repo_type="dataset", token=HF_TOKEN)
58
+ return len([f for f in files if f.startswith("data/")])
59
+ except: return 0
60
+
61
+ # الوظيفة الرئيسية مع ميزة الكوكي (تتبع عدد الرفعات في الجلسة)
62
+ def save_submission(audio_path, s_id, a_id, session_count):
63
+ if audio_path is None:
64
+ return "⚠️ الرجاء التسجيل أولاً", None, None, session_count, None
65
+
66
+ file_name = f"{s_id}|{a_id}_{datetime.now().strftime('%M%S')}.wav"
67
+
68
+ try:
69
+ api.upload_file(
70
+ path_or_fileobj=audio_path,
71
+ path_in_repo=f"data/{file_name}",
72
+ repo_id=REPO_ID,
73
+ repo_type="dataset",
74
+ token=HF_TOKEN
75
+ )
76
+
77
+ # تحديث الكوكي/العداد
78
+ new_count = session_count + 1
79
+
80
+ # جلب الآية التالية
81
+ next_v = random.choice(ALL_AYAT) # يمكن تخصيصها لتكون التسلسلية
82
+ stats = get_stats()
83
+
84
+ msg = f"✅ تم الحفظ! إجمالي مساهماتك الآن: {new_count} آيات."
85
+ return msg, f"<div class='ayah-box'>{next_v['text']}</div>", f"سورة {next_v['surah_name']} - آية {next_v['ayah']}", new_count, stats
86
+ except Exception as e:
87
+ return f"❌ خطأ: {str(e)}", None, None, session_count, None
88
+
89
+ # بناء الواجهة
90
+ with gr.Blocks(css=custom_css, title="جامع تلاوات القرآن") as demo:
91
+ # عداد الجلسة (الكوكي)
92
+ session_counter = gr.State(value=0)
93
+
94
+ gr.Markdown("""
95
+ # 🌙 مشروع خادم القرآن الرقمي
96
+ ساهم بصوتك لتطوير أول نموذج ذكاء اصطناعي مفتوح لتصحيح التلاوة.
97
+ """)
98
+
99
+ total_stats = gr.Number(label="إجمالي التسجيلات في القاعدة", value=get_stats(), interactive=False)
100
+
101
+ with gr.Column(elem_classes="container"):
102
+ first_v = random.choice(ALL_AYAT)
103
+
104
+ ayah_info = gr.Markdown(f"### سورة {first_v['surah_name']} - آية {first_v['ayah']}")
105
+ ayah_display = gr.HTML(f"<div class='ayah-box'>{first_v['text']}</div>")
106
+
107
+ audio_input = gr.Audio(sources=["microphone", "upload"], type="filepath", label="سجل أو ارفع الملف")
108
+
109
+ with gr.Row():
110
+ submit_btn = gr.Button("إرسال التسجيل ✅", variant="primary")
111
+ skip_btn = gr.Button("تخطي لآية أخرى ⏭️")
112
+
113
+ result_msg = gr.Markdown("")
114
+
115
+ # إضافة كود JavaScript للتحذير عند الخروج (رسالة التنبيه)
116
+ demo.load(None, None, None, js="""
117
+ window.onbeforeunload = function() {
118
+ return "هل أنت متأكد؟ قد تفقد التسجيل الحالي إذا لم تقم برفعه.";
119
+ };
120
+ """)
121
+
122
+ # تعريف الحالات المخفية للسورة والآية
123
+ curr_s = gr.State(value=first_v['surah'])
124
+ curr_a = gr.State(value=first_v['ayah'])
125
+
126
+ def skip():
127
+ v = random.choice(ALL_AYAT)
128
+ return f"<div class='ayah-box'>{v['text']}</div>", f"### سورة {v['surah_name']} - آية {v['ayah']}", v['surah'], v['ayah']
129
+
130
+ skip_btn.click(skip, outputs=[ayah_display, ayah_info, curr_s, curr_a])
131
+
132
+ submit_btn.click(
133
+ save_submission,
134
+ inputs=[audio_input, curr_s, curr_a, session_counter],
135
+ outputs=[result_msg, ayah_display, ayah_info, session_counter, total_stats]
136
+ )
137
+
138
+ demo.launch()