Batnini commited on
Commit
d0b3c39
ยท
verified ยท
1 Parent(s): c3539cc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -153
app.py CHANGED
@@ -1,157 +1,38 @@
1
- import requests
2
- import logging
3
- import pandas as pd
4
- import numpy as np
5
- from sentence_transformers import SentenceTransformer
6
- from sklearn.metrics.pairwise import cosine_similarity
7
- from config import QURAN_DATA_SOURCES, MODEL_NAME, CHUNK_SIZE
8
- import time
9
 
10
- class QuranSearchEngine:
11
- def __init__(self):
12
- self.full_quran_url = "https://cdn.jsdelivr.net/npm/quran-json@3.1.2/dist/quran.json"
13
- self.logger = logging.getLogger(__name__)
14
- self.full_quran = None
15
- self.surahs = None
16
- self.all_verses = [] # List of {'surah_id': int, 'verse_num': int, 'text': str}
17
- self.verse_embeddings = None
18
- self.model = None
19
- self._load_full_quran()
20
- print(f"Surahs loaded: {len(self.surahs) if self.surahs else 0}") # Debug
21
- self._load_all_verses_and_embeddings()
22
- print(f"Verses loaded: {len(self.all_verses)}") # Debug
23
-
24
- def _load_full_quran(self):
25
- max_retries = 3
26
- for attempt in range(max_retries):
27
- try:
28
- response = requests.get(self.full_quran_url, timeout=10)
29
- response.raise_for_status()
30
- self.full_quran = response.json() # Array of surah dicts
31
- self.surahs = self.full_quran
32
- break
33
- except Exception as e:
34
- self.logger.error(f"Attempt {attempt + 1}/{max_retries} failed to fetch full Quran: {e}")
35
- if attempt == max_retries - 1:
36
- self.surahs = self._load_fallback_surahs()
37
- time.sleep(2 ** attempt)
38
-
39
- def _load_all_verses_and_embeddings(self):
40
- if not self.full_quran:
41
- self.logger.error("No full Quran loaded, skipping verse loading")
42
- self.all_verses = [
43
- {'surah_id': 1, 'verse_num': 1, 'text': "ุจูุณู’ู…ู ูฑู„ู„ู‘ูŽู‡ู ูฑู„ุฑู‘ูŽุญู’ู…ูŽู€ูฐู†ู ูฑู„ุฑู‘ูŽุญููŠู…ู"},
44
- ]
45
- return
46
-
47
- for surah in self.full_quran:
48
- surah_id = surah['id']
49
- for verse in surah['verses']:
50
- self.all_verses.append({
51
- 'surah_id': surah_id,
52
- 'verse_num': verse['id'],
53
- 'text': verse['text']
54
- })
55
-
56
- try:
57
- self.model = SentenceTransformer(MODEL_NAME)
58
- verse_texts = [v['text'] for v in self.all_verses]
59
- self.verse_embeddings = []
60
- for i in range(0, len(verse_texts), CHUNK_SIZE):
61
- chunk = verse_texts[i:i + CHUNK_SIZE]
62
- embeddings = self.model.encode(chunk, convert_to_tensor=False)
63
- self.verse_embeddings.append(embeddings)
64
- self.verse_embeddings = np.vstack(self.verse_embeddings)
65
- except Exception as e:
66
- self.logger.error(f"Failed to compute embeddings: {e}")
67
- self.verse_embeddings = None
68
-
69
- def get_surahs(self):
70
- if self.surahs:
71
- return [
72
- (s['name'], s['id'])
73
- for s in self.surahs
74
- ]
75
- return self._load_fallback_surahs()
76
-
77
- def get_surah_text(self, surah_id):
78
- if self.full_quran:
79
- try:
80
- surah = self.full_quran[surah_id - 1]
81
- verses = surah['verses']
82
- return "\n\n".join(f"ุขูŠุฉ {v['id']}: {v['text']}" for v in verses)
83
- except IndexError:
84
- self.logger.error(f"Surah {surah_id} not found in cached data")
85
-
86
- # Fallback if cache failed
87
- max_retries = 3
88
- for attempt in range(max_retries):
89
- try:
90
- response = requests.get(f"https://quranapi.pages.dev/api/{surah_id}.json", timeout=10)
91
- response.raise_for_status()
92
- data = response.json()
93
- verses = data['arabic1']
94
- return "\n\n".join(f"ุขูŠุฉ {i + 1}: {v}" for i, v in enumerate(verses))
95
- except Exception as e:
96
- self.logger.error(f"Attempt {attempt + 1}/{max_retries} failed to fetch surah {surah_id}: {e}")
97
- if attempt == max_retries - 1:
98
- return self._load_fallback_verse()
99
- time.sleep(2 ** attempt)
100
-
101
- def search_verses(self, query, top_k=5):
102
- if self.verse_embeddings is None or not self.all_verses:
103
- return self._keyword_fallback_search(query, top_k)
104
-
105
- try:
106
- query_embedding = self.model.encode([query], convert_to_tensor=False)
107
- similarities = cosine_similarity(query_embedding, self.verse_embeddings)[0]
108
- top_indices = np.argsort(similarities)[-top_k:][::-1]
109
-
110
- results = []
111
- for idx in top_indices:
112
- verse = self.all_verses[idx]
113
- surah_name = self.surahs[verse['surah_id'] - 1]['name']
114
- results.append(
115
- f"ุณูˆุฑุฉ {surah_name} - ุขูŠุฉ {verse['verse_num']}:\n{verse['text']}"
116
- )
117
- return "\n\n".join(results)
118
- except Exception as e:
119
- self.logger.error(f"Search failed: {e}")
120
- return "ุญุฏุซ ุฎุทุฃ ุฃุซู†ุงุก ุงู„ุจุญุซ. ุฌุฑุจ ู…ุฑุฉ ุฃุฎุฑู‰."
121
 
122
- def _keyword_fallback_search(self, query, top_k=5):
123
- query_lower = query.lower()
124
- matches = []
125
- for verse in self.all_verses:
126
- if query_lower in verse['text'].lower():
127
- surah_name = self.surahs[verse['surah_id'] - 1]['name'] if self.surahs else f"ุณูˆุฑุฉ {verse['surah_id']}"
128
- matches.append(f"ุณูˆุฑุฉ {surah_name} - ุขูŠุฉ {verse['verse_num']}:\n{verse['text']}")
129
- return "\n\n".join(matches[:top_k]) or "ู„ุง ุชูˆุฌุฏ ู†ุชุงุฆุฌ ู…ุทุงุจู‚ุฉ."
 
 
 
 
 
130
 
131
- # Fallback methods (unchanged)
132
- def _load_fallback_surahs(self):
133
- try:
134
- for source in QURAN_DATA_SOURCES:
135
- try:
136
- df = pd.read_csv(source)
137
- return [
138
- (row['name_arabic'], row['surah_id'])
139
- for _, row in df.drop_duplicates(subset=['surah_id']).iterrows()
140
- ]
141
- except:
142
- continue
143
- return [
144
- ("ุงู„ูุงุชุญุฉ", 1),
145
- ("ุงู„ุจู‚ุฑุฉ", 2),
146
- ("ุขู„ ุนู…ุฑุงู†", 3)
147
- ]
148
- except Exception as e:
149
- self.logger.error(f"Failed to load fallback surahs: {e}")
150
- return [
151
- ("ุงู„ูุงุชุญุฉ", 1),
152
- ("ุงู„ุจู‚ุฑุฉ", 2),
153
- ("ุขู„ ุนู…ุฑุงู†", 3)
154
- ]
155
 
156
- def _load_fallback_verse(self):
157
- return "ุจุณู… ุงู„ู„ู‡ ุงู„ุฑุญู…ู† ุงู„ุฑุญูŠู…\nุงู„ู„ู‡ ู„ุง ุฅู„ู‡ ุฅู„ุง ู‡ูˆ ุงู„ุญูŠ ุงู„ู‚ูŠูˆู…"
 
1
+ import gradio as gr
2
+ from tools.arabic_generator import ArabicTextGenerator
3
+ from tools.quran_search import QuranSearchEngine
 
 
 
 
 
4
 
5
+ text_gen = ArabicTextGenerator()
6
+ quran = QuranSearchEngine()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
 
8
+ with gr.Blocks(title="ุงู„ุฃุฏูˆุงุช ุงู„ุนุฑุจูŠุฉ") as app:
9
+ # Tab 1: Your Working Arabic Generator (UNTOUCHED)
10
+ with gr.Tab("๐Ÿ–Š๏ธ ู…ูˆู„ุฏ ุงู„ู†ุตูˆุต"):
11
+ text_input = gr.Textbox(label="ุงู„ู†ุต ุงู„ุฃูˆู„ูŠ")
12
+ length_slider = gr.Slider(50, 300, value=100, label="ุทูˆู„ ุงู„ู†ุต")
13
+ gen_btn = gr.Button("ุชูˆู„ูŠุฏ")
14
+ text_output = gr.Textbox(label="ุงู„ู†ุต ุงู„ู…ูˆู„ุฏ", lines=6)
15
+
16
+ gen_btn.click(
17
+ text_gen.generate,
18
+ inputs=[text_input, length_slider],
19
+ outputs=text_output
20
+ )
21
 
22
+ # Tab 2: Quran Surah Viewer (GUARANTEED TO WORK)
23
+ with gr.Tab("๐Ÿ“– ุงู„ู‚ุฑุขู† ุงู„ูƒุฑูŠู…"):
24
+ surah_dropdown = gr.Dropdown(
25
+ label="ุงุฎุชุฑ ุณูˆุฑุฉ",
26
+ choices=quran.get_surahs(),
27
+ value=1 # Default to Al-Fatiha
28
+ )
29
+ show_btn = gr.Button("ุนุฑุถ ุงู„ุณูˆุฑุฉ")
30
+ quran_output = gr.Textbox(label="ุงู„ู†ุต ุงู„ู‚ุฑุขู†ูŠ", lines=15)
31
+
32
+ show_btn.click(
33
+ quran.get_surah_text,
34
+ inputs=surah_dropdown,
35
+ outputs=quran_output
36
+ )
 
 
 
 
 
 
 
 
 
37
 
38
+ app.launch()