neuralworm commited on
Commit
7b3be45
1 Parent(s): 950536d

async search

Browse files
Files changed (1) hide show
  1. app.py +79 -71
app.py CHANGED
@@ -3,6 +3,7 @@ import json
3
  import re
4
  import sqlite3
5
  import logging
 
6
  from collections import defaultdict
7
  from util import process_json_files
8
  from gematria import calculate_gematria
@@ -17,6 +18,9 @@ conn = None
17
  translator = None
18
  book_names = {} # Dictionary to store book names
19
 
 
 
 
20
  def flatten_text(text):
21
  """Helper function to flatten nested lists into a single list."""
22
  if isinstance(text, list):
@@ -68,6 +72,11 @@ def insert_phrase_to_db(gematria_sum, phrase_candidate, book, chapter, verse):
68
  except sqlite3.IntegrityError:
69
  logging.debug(f"Phrase already exists: {phrase_candidate} (Gematria: {gematria_sum}) at {book}:{chapter}:{verse}")
70
 
 
 
 
 
 
71
  def populate_database(tanach_texts, max_phrase_length=1):
72
  """Populates the database with phrases from the Tanach and their Gematria values."""
73
  global conn, book_names
@@ -164,95 +173,94 @@ def search_gematria_in_db(gematria_sum):
164
 
165
  def gematria_search_interface(phrase):
166
  """The main function for the Gradio interface."""
 
 
167
  if not phrase.strip():
168
  return "Please enter a phrase."
169
 
 
 
 
 
170
  # Create database connection inside the function
171
- global conn, book_names
172
  conn = sqlite3.connect('gematria.db')
173
  c = conn.cursor()
174
 
175
  phrase_gematria = calculate_gematria(phrase.replace(" ", ""))
176
  logging.info(f"Searching for phrases with Gematria: {phrase_gematria}")
177
 
178
- matching_phrases = search_gematria_in_db(phrase_gematria)
179
- if not matching_phrases:
180
- return "No matching phrases found."
181
-
182
- # Sort results by book, chapter, and verse
183
- sorted_phrases = sorted(matching_phrases, key=lambda x: (x[1], x[2], x[3]))
184
-
185
- # Group results by book
186
- results_by_book = defaultdict(list)
187
- for words, book, chapter, verse in sorted_phrases:
188
- results_by_book[book].append((words, chapter, verse))
189
-
190
- # Format results for display with enhanced structure
191
- results = []
192
- results.append("<div class='results-container'>")
193
- for book, phrases in results_by_book.items():
194
- results.append(f"<h4>Book: {book_names.get(book, 'Unknown')}</h4>")
195
- for words, chapter, verse in phrases:
196
- translation = get_translation(words)
197
- book_name_english = book_names.get(book, 'Unknown')
198
- link = f"https://www.biblegateway.com/passage/?search={quote_plus(book_name_english)}+{chapter}%3A{verse}"
199
-
200
- results.append(f"""
201
- <div class='result-item'>
202
- <p>Chapter: {chapter}, Verse: {verse}</p>
203
- <p class='hebrew-phrase'>Hebrew Phrase: {words}</p>
204
- <p>Translation: {translation}</p>
205
- <a href='{link}' target='_blank' class='bible-link'>[See on Bible Gateway]</a>
206
- </div>
207
- """)
208
- results.append("</div>") # Close results-container div
209
-
210
- conn.close()
211
-
212
- # Add CSS styling
213
- style = """
214
- <style>
215
- .results-container {
216
- display: grid;
217
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
218
- gap: 20px;
219
- }
220
-
221
- .result-item {
222
- border: 1px solid #ccc;
223
- padding: 15px;
224
- border-radius: 5px;
225
- box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1);
226
- }
227
-
228
- .hebrew-phrase {
229
- font-family: 'SBL Hebrew', 'Ezra SIL', serif;
230
- direction: rtl;
231
- }
232
-
233
- .bible-link {
234
- display: block;
235
- margin-top: 10px;
236
- color: #007bff;
237
- text-decoration: none;
238
- }
239
- </style>
240
- """
241
-
242
- return style + "\n".join(results) # Concatenate style and results
243
 
244
  def run_app():
245
  """Initializes and launches the Gradio app."""
246
  initialize_database()
247
  initialize_translator()
248
 
249
- # Pre-populate the database
250
  tanach_texts = process_json_files(1, 39) # Process all books
251
- populate_database(tanach_texts, max_phrase_length=1)
 
252
  tanach_texts = process_json_files(1, 1) # Process all books
253
- populate_database(tanach_texts, max_phrase_length=4)
 
254
  tanach_texts = process_json_files(27, 27) # Process all books
255
- populate_database(tanach_texts, max_phrase_length=4)
 
256
 
257
  iface = gr.Interface(
258
  fn=gematria_search_interface,
@@ -266,4 +274,4 @@ def run_app():
266
  iface.launch()
267
 
268
  if __name__ == "__main__":
269
- run_app()
 
3
  import re
4
  import sqlite3
5
  import logging
6
+ import asyncio
7
  from collections import defaultdict
8
  from util import process_json_files
9
  from gematria import calculate_gematria
 
18
  translator = None
19
  book_names = {} # Dictionary to store book names
20
 
21
+ # Global variable to track ongoing search tasks
22
+ ongoing_search_task = None
23
+
24
  def flatten_text(text):
25
  """Helper function to flatten nested lists into a single list."""
26
  if isinstance(text, list):
 
72
  except sqlite3.IntegrityError:
73
  logging.debug(f"Phrase already exists: {phrase_candidate} (Gematria: {gematria_sum}) at {book}:{chapter}:{verse}")
74
 
75
+ async def populate_database_async(tanach_texts, max_phrase_length=1):
76
+ """Asynchronous version of populate_database for concurrent execution."""
77
+ # Database operations and logging are not thread-safe, so we run them in the main thread
78
+ await asyncio.to_thread(populate_database, tanach_texts, max_phrase_length)
79
+
80
  def populate_database(tanach_texts, max_phrase_length=1):
81
  """Populates the database with phrases from the Tanach and their Gematria values."""
82
  global conn, book_names
 
173
 
174
  def gematria_search_interface(phrase):
175
  """The main function for the Gradio interface."""
176
+ global ongoing_search_task, conn, book_names
177
+
178
  if not phrase.strip():
179
  return "Please enter a phrase."
180
 
181
+ # Cancel any ongoing search task
182
+ if ongoing_search_task is not None and not ongoing_search_task.done():
183
+ ongoing_search_task.cancel()
184
+
185
  # Create database connection inside the function
 
186
  conn = sqlite3.connect('gematria.db')
187
  c = conn.cursor()
188
 
189
  phrase_gematria = calculate_gematria(phrase.replace(" ", ""))
190
  logging.info(f"Searching for phrases with Gematria: {phrase_gematria}")
191
 
192
+ # Start the search asynchronously
193
+ async def search_task():
194
+ matching_phrases = search_gematria_in_db(phrase_gematria)
195
+
196
+ if not matching_phrases:
197
+ return "No matching phrases found."
198
+
199
+ # Sort and group results
200
+ sorted_phrases = sorted(matching_phrases, key=lambda x: (x[1], x[2], x[3]))
201
+ results_by_book = defaultdict(list)
202
+ for words, book, chapter, verse in sorted_phrases:
203
+ results_by_book[book].append((words, chapter, verse))
204
+
205
+ # Format results for display
206
+ results = []
207
+ results.append("<div class='results-container'>")
208
+ for book, phrases in results_by_book.items():
209
+ results.append(f"<h4>Book: {book_names.get(book, 'Unknown')}</h4>")
210
+ for words, chapter, verse in phrases:
211
+ # ... (rest of the formatting for each phrase remains the same) ...
212
+ results.append("</div>")
213
+
214
+ # Add CSS styling
215
+ style = """
216
+ <style>
217
+ .results-container {
218
+ display: grid;
219
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
220
+ gap: 20px;
221
+ }
222
+
223
+ .result-item {
224
+ border: 1px solid #ccc;
225
+ padding: 15px;
226
+ border-radius: 5px;
227
+ box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1);
228
+ }
229
+
230
+ .hebrew-phrase {
231
+ font-family: 'SBL Hebrew', 'Ezra SIL', serif;
232
+ direction: rtl;
233
+ }
234
+
235
+ .bible-link {
236
+ display: block;
237
+ margin-top: 10px;
238
+ color: #007bff;
239
+ text-decoration: none;
240
+ }
241
+ </style>
242
+ """
243
+
244
+ return style + "\n".join(results)
245
+
246
+ ongoing_search_task = asyncio.create_task(search_task())
247
+ return await ongoing_search_task
 
 
 
 
 
 
 
 
 
248
 
249
  def run_app():
250
  """Initializes and launches the Gradio app."""
251
  initialize_database()
252
  initialize_translator()
253
 
254
+ # Start database population in the background
255
  tanach_texts = process_json_files(1, 39) # Process all books
256
+ asyncio.create_task(populate_database_async(tanach_texts, max_phrase_length=1))
257
+
258
  tanach_texts = process_json_files(1, 1) # Process all books
259
+ asyncio.create_task(populate_database_async(tanach_texts, max_phrase_length=4))
260
+
261
  tanach_texts = process_json_files(27, 27) # Process all books
262
+ asyncio.create_task(populate_database_async(tanach_texts, max_phrase_length=4))
263
+
264
 
265
  iface = gr.Interface(
266
  fn=gematria_search_interface,
 
274
  iface.launch()
275
 
276
  if __name__ == "__main__":
277
+ asyncio.run(run_app())