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 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" ) import pickle with open('books_list.pkl', 'rb') as file: books_list = pickle.load(file) def e_search(query): url_search = 'http://localhost:9202/books_jsons_01/_search' 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) print(j_query) 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): def e_search_book(query): book_name = book_btn.text print(book_name) url_search = 'http://localhost:9202/books_jsons_01/_search' 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 def printer(e, name): query_feild.value=name page.update() def query_feild_changed(string): 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: printer(e, name) ) for name in query_list } str_lower = normalize_arabic(string.control.value) listview.controls = [ list_items.get(n) for n in query_list if str_lower in normalize_arabic(n) ] if str_lower else [] page.update() 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]))) # Set column width here 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 = 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]))) # Set column width here 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)])) ])) page.update() 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 page.update() def show_book_text(e): pass res_dt=DataTable( border=border.all(2, "blue"), border_radius=10, column_spacing=10, #data_row_min_height = 80 ) datatable_row = Row([res_dt],alignment=MainAxisAlignment.CENTER) 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]) #Initial Invisable datatable_row.visible = False await page.add_async(Query_row,listview,datatable_row) app =flet_fastapi.app(main)