E-slam's picture
Update main.py
41c4e1e verified
raw
history blame
7.61 kB
import flet as ft
import flet_fastapi
from flet import *
import requests
import json
import pandas as pd
import elasticsearch_serverless
import re
import os
import pickle
import asyncio
def remove_arabic_diacritics(text):
diacritics_pattern = re.compile(r'[\u064B-\u065F\u0670\u06D6-\u06ED]')
no_diacritics_text = re.sub(diacritics_pattern, '', text)
return no_diacritics_text
diacritics = re.compile("""
ّ | # Tashdid
َ | # Fatha
ً | # Tanwin Fath
ُ | # Damma
ٌ | # Tanwin Damm
ِ | # Kasra
ٍ | # Tanwin Kasr
ْ | # Sukun
ـ # Tatwil/Kashida
""", re.VERBOSE)
def normalize_arabic(text):
text = diacritics.sub('', text)
text = text.replace('أ', 'ا')
text = text.replace('إ', 'ا')
text = text.replace('آ', 'ا')
text = text.replace('ة', 'ه')
text = text.replace('ى', 'ي')
return text
book_selected = False
first_run = 0
client = elasticsearch_serverless.Elasticsearch(
"https://e790c240926f48a78eec48ccb79ddcd1.us-central1.gcp.cloud.es.io:443",
api_key="MmY2VlpZOEJtVVZGLVJjNHpzRTM6akFlVmM2bHhSVmU1M25qRTIyZy1kUQ"
)
with open('books_list.pkl', 'rb') as file:
books_list = pickle.load(file)
def e_search(query):
query = remove_arabic_diacritics(query)
query = normalize_arabic(query)
j_query = {
"size": 500,
"query": {
"match": {
"Text": query
}
}
}
response_search = client.search(index="books_jsons_01", body=j_query)
unique_books = {}
for hit in response_search['hits']['hits']:
book = hit['_source']['Book']
page = hit['_source']['Page']
score = hit['_score']
if book not in unique_books:
unique_books[book] = {'Pages': {page: score}, 'Count': 1}
else:
if page not in unique_books[book]['Pages']:
unique_books[book]['Pages'][page] = score
unique_books[book]['Count'] += 1
book_data = []
for book, info in unique_books.items():
pages = sorted(info['Pages'].items())
book_data.append({'Book': book, 'Pages': [page for page, _ in pages], 'Scores': [score for _, score in pages], 'Count': info['Count']})
df = pd.DataFrame(book_data)
df = df.head(12)
def get_top_two(row):
sorted_row = sorted(zip(row['Pages'], row['Scores']), key=lambda x: x[1], reverse=True)
return [page for page, score in sorted_row[:2]]
try:
df['Top Two Pages'] = df.apply(get_top_two, axis=1)
except:
pass
return df
async def main(page: ft.Page):
async def e_search_book(query):
book_name = book_btn.text
query = remove_arabic_diacritics(query)
query = normalize_arabic(query)
j_query = {
"size": 10,
"query": {
"bool": {
"must": [
{"match": {"Text": query}},
{"match": {"Book": book_name}}
]
}
}
}
response_search = client.search(index="books_jsons_01", body=j_query)
data = []
for hit in response_search['hits']['hits']:
book = hit['_source']['Book']
page = hit['_source']['Page']
score = hit['_score']
text = hit['_source']['Text']
data.append({
"Book": book,
"Page": page,
"Score": score,
"Text": text
})
df = pd.DataFrame(data)
return df
async def printer(e, name):
query_feild.value = name
await page.update_async()
async def query_feild_changed(e):
datatable_row.visible = False
listview.visible = True
query_list = books_list
list_items = {
name: ListTile(
title=Text(name),
leading=Icon(icons.ARROW_RIGHT_SHARP),
on_click=lambda e, name=name: asyncio.create_task(printer(e, name))
)
for name in query_list
}
str_lower = normalize_arabic(e.control.value)
listview.controls = [
list_items.get(n) for n in query_list if str_lower in normalize_arabic(n)
] if str_lower else []
await page.update_async()
async def send_button(e):
global first_run
datatable_row.visible = True
listview.visible = False
if first_run >= 1:
res_dt.columns.clear()
res_dt.rows.clear()
first_run = 1
if not book_selected:
e_search_df = e_search(query_feild.value)
for i in range(len(e_search_df.columns)):
res_dt.columns.append(DataColumn(Text(e_search_df.columns[i])))
for i in range(e_search_df.shape[0]):
res_dt.rows.append(DataRow(cells=[
DataCell(Text(e_search_df['Book'][i], width=450)),
DataCell(Text(e_search_df['Pages'][i], width=180)),
DataCell(Text(e_search_df['Scores'][i], width=180)),
DataCell(Text(e_search_df['Count'][i], width=120)),
DataCell(Text(e_search_df['Top Two Pages'][i], width=200))
]))
else:
e_search_df = await e_search_book(query_feild.value)
for i in range(len(e_search_df.columns)):
res_dt.columns.append(DataColumn(Text(e_search_df.columns[i])))
for i in range(e_search_df.shape[0]):
txt = e_search_df['Text'][i][:80].replace("\n", " ")
res_dt.rows.append(DataRow(cells=[
DataCell(Text(e_search_df['Book'][i], width=450)),
DataCell(Text(e_search_df['Page'][i], width=180)),
DataCell(Text(e_search_df['Score'][i], width=180)),
DataCell(Row([Text(f"{txt}...", width=400), IconButton(icon=icons.ARROW_RIGHT_OUTLINED, height=50, on_click=show_book_text)]))
]))
await page.update_async()
async def book_btn_filter(e):
global book_selected
book_value = query_feild.value
if book_value in books_list:
book_btn.text = query_feild.value
book_btn.bgcolor = colors.GREEN
book_selected = True
else:
book_btn.text = "No Book Found"
book_btn.bgcolor = colors.CYAN
book_selected = False
await page.update_async()
def show_book_text(e):
pass
res_dt = DataTable(
border=border.all(2, "blue"),
border_radius=10,
column_spacing=10,
)
datatable_row = Row([res_dt], alignment=MainAxisAlignment.CENTER)
datatable_row.visible = False
query_feild = TextField(label="Inquiry", hint_text="Please write your inquiry", expand=True,
on_change=query_feild_changed)
query_send = FloatingActionButton(icon=icons.SEND, on_click=send_button)
book_btn = ElevatedButton(text="Book Filter", height=55, width=180, icon=icons.FILTER,
on_click=book_btn_filter, bgcolor=colors.CYAN, color=colors.WHITE,
style=ButtonStyle(shape=RoundedRectangleBorder(radius=10)))
listview = ListView(expand=1, spacing=10, padding=20)
Query_row = Row(controls=[query_feild, book_btn, query_send])
await page.add_async(Query_row, listview, datatable_row)
app = flet_fastapi.app(main)