Spaces:
Sleeping
Sleeping
import flet as ft | |
import json | |
import pandas as pd | |
import Bot_Page | |
import Bot_Page_ٍSummary | |
import time | |
import utils | |
df_laws = pd.read_excel("Data/UAE_Laws_LC_April_3.xlsx") | |
def unique_ordered_list(law_ids): | |
seen = set() | |
unique_list = [] | |
for item in law_ids: | |
if item not in seen: | |
seen.add(item) | |
unique_list.append(item) | |
return unique_list | |
def mawad_func(law_id): | |
return [json.loads(item) for item in json_nodes if json.loads(item).get("File_ID") == str(law_id)] | |
def main(page: ft.Page): | |
page.theme = ft.Theme( | |
color_scheme=ft.ColorScheme( | |
primary=ft.colors.BLUE, | |
secondary=ft.colors.CYAN, | |
), | |
font_family="Arial" | |
) | |
page.bgcolor = ft.colors.WHITE | |
page.window_maximized = True | |
page.horizontal_alignment = ft.CrossAxisAlignment.STRETCH | |
page.vertical_alignment = ft.MainAxisAlignment.START | |
relevant_matches_active = False | |
current_file_id = None | |
current_hits = None | |
def create_table(books, pages, hits): | |
def create_cell(content, h, wid, is_header=False): | |
return ft.Container( | |
content=ft.Text(content, weight="bold" if is_header else None), | |
border=ft.border.all(1, "cyan"), | |
padding=ft.padding.all(8), | |
border_radius=2, | |
alignment=ft.alignment.center, | |
width=wid, | |
height=h | |
) | |
headers_height = 40 | |
headers_width = 250 | |
header = ft.Row( | |
controls=[ | |
create_cell("الموضوع", headers_height, 500, is_header=True), | |
create_cell("تاريخ الاصدار", headers_height, headers_width, is_header=True), | |
create_cell("التشريع", headers_height, headers_width, is_header=True) | |
], | |
alignment="center", | |
spacing=0 | |
) | |
values_height = 90 | |
values = ft.Row( | |
controls=[ | |
create_cell(hits, values_height, 500), | |
create_cell(pages, values_height, headers_width), | |
create_cell(books, values_height, headers_width) | |
], | |
alignment="center", | |
spacing=0 | |
) | |
table = ft.Column( | |
controls=[ | |
header, | |
values | |
], | |
alignment="center", | |
spacing=0 | |
) | |
return table | |
def on_search(e): | |
loading_indicator.visible = True | |
law_info_table.visible = False | |
page.update() | |
query = search_field.value | |
if current_search_mode.value == "Mode 1 is selected": | |
res = utils.Get_Azure_AI_RAG_Json(query,20) | |
law_ids = [int(id.get("File_ID")) for id in res] | |
unique_law_ids = unique_ordered_list(law_ids) | |
results = df_laws[df_laws['Id'].isin(unique_law_ids)].reset_index() | |
results['Id'] = pd.Categorical(results['Id'], categories=unique_law_ids, ordered=True) | |
results = results.sort_values('Id').reset_index(drop=True) | |
results = results.head(10) | |
elif current_search_mode.value == "Mode 2 is selected": | |
res = utils.by_law_title(query,20) | |
law_ids = [int(id.get("File_ID")) for id in res] | |
unique_law_ids = unique_ordered_list(law_ids) | |
results = df_laws[df_laws['Id'].isin(unique_law_ids)].reset_index() | |
results['Id'] = pd.Categorical(results['Id'], categories=unique_law_ids, ordered=True) | |
results = results.sort_values('Id').reset_index(drop=True) | |
results = results.head(10) | |
table.rows.clear() | |
for i in range(results.shape[0]): | |
curr_id = int(results['Id'][i]) | |
count_df = (df_laws[df_laws['Id']== curr_id]).reset_index()['Subjects Count'][0] | |
articles_count = int(count_df) | |
table.rows.append( | |
ft.DataRow(cells=[ | |
ft.DataCell(ft.IconButton(ft.icons.LINK, on_click=lambda e, link=results['short_url'][i]: page.launch_url(link))), | |
ft.DataCell(ft.Text(articles_count, text_align=ft.TextAlign.RIGHT)), | |
ft.DataCell(ft.Container( | |
ft.Text(results['Description'][i], text_align=ft.TextAlign.RIGHT, rtl=True), | |
alignment=ft.alignment.center_right | |
)), | |
ft.DataCell(ft.Container( | |
ft.Text(results['Issue Date'][i], text_align=ft.TextAlign.RIGHT, rtl=True), | |
alignment=ft.alignment.center_right | |
)), | |
ft.DataCell(ft.Container( | |
ft.TextButton(results['Topic'][i], on_click=lambda e, file_id=results['Id'][i]: show_topic_details(file_id, res)), | |
alignment=ft.alignment.center_right | |
)), | |
]) | |
) | |
loading_indicator.visible = False | |
table.visible = True | |
page.update() | |
loading_indicator = ft.ProgressRing(visible=False) | |
def show_topic_details(file_id, res): | |
dialog_button.on_click = lambda e, fid=file_id :open_chat_dlg(e, fid) | |
summary_button.on_click = lambda e, fid=file_id :open_summary_dlg(e, fid) | |
nonlocal current_file_id, current_hits | |
current_file_id = file_id | |
current_hits = res | |
table.visible = False | |
law_info_table.visible = True | |
info_df = df_laws[df_laws['Id'] == file_id].reset_index() | |
description = info_df['Description'][0] | |
issue_date = info_df['Issue Date'][0] | |
link = info_df['short_url'][0] | |
topic = info_df['Topic'][0] | |
law_info_table.controls = [create_table(topic, issue_date, description)] | |
mada_df = pd.read_csv(f"Data/Topics_CSV/{file_id}.csv") | |
mada_df = mada_df[mada_df['Header'] != "Desc"] | |
mawad_details = mada_df['Header'].to_list() | |
if len(res) == 0: | |
ordered_details = mawad_details | |
hits = [] | |
else: | |
hits = [item for item in res if item['File_ID'] == str(file_id)] | |
hits = [item['Row_Header'] for item in hits] | |
if relevant_matches_active: | |
ordered_details = {header: index for index, header in enumerate(hits)} | |
ordered_details = sorted(mawad_details, key=lambda x: ordered_details.get(x, float('inf'))) | |
else: | |
ordered_details = mawad_details | |
details_list.controls.clear() | |
for item in ordered_details: | |
if not relevant_matches_active or item in hits: | |
bc = ft.colors.YELLOW if item in hits else ft.colors.WHITE | |
curr_mada_text =(mada_df[mada_df['Header'] == item]).reset_index()['Header'][0] + " * " + (mada_df[mada_df['Header'] == item]).reset_index()['Text'][0] | |
details_list.controls.append( | |
ft.Container( | |
content=ft.ElevatedButton( | |
text=item, | |
on_click=lambda e, text=curr_mada_text: show_mada_text(text), | |
bgcolor=ft.colors.CYAN, | |
color=bc | |
), | |
alignment=ft.alignment.center_right, | |
padding=ft.padding.all(10), | |
border_radius=ft.border_radius.all(5), | |
shadow=ft.BoxShadow( | |
blur_radius=5, | |
spread_radius=1, | |
color=ft.colors.GREY_100, | |
offset=ft.Offset(2, 2) | |
) | |
) | |
) | |
details_view.visible = True | |
search_view.visible = False | |
page.update() | |
def show_mada_text(text): | |
try: | |
header, article = text.split('*', 1) | |
header_text = ft.Text(header, weight=ft.FontWeight.BOLD, rtl=True, text_align=ft.TextAlign.CENTER) | |
article_text = ft.Text(article.strip(), rtl=True, text_align=ft.TextAlign.RIGHT) | |
column_controls = [header_text, article_text] | |
except: | |
column_controls = [ft.Text(text,rtl=True)] | |
mada_column.content.controls = column_controls | |
page.update() | |
def go_back_to_search(e): | |
details_view.visible = False | |
search_view.visible = True | |
table.visible = True | |
page.update() | |
def toggle_relevant_matches(e): | |
nonlocal relevant_matches_active | |
relevant_matches_active = not relevant_matches_active | |
relevant_matches_button.bgcolor = ft.colors.YELLOW if relevant_matches_active else ft.colors.CYAN | |
page.update() | |
if current_file_id is not None: | |
show_topic_details(current_file_id, current_hits) | |
search_field = ft.TextField(label="أدخل أستفسارك", text_align=ft.TextAlign.RIGHT, expand=True) | |
search_button = ft.ElevatedButton("بحث", icon=ft.icons.SEND, on_click=on_search, bgcolor=ft.colors.BLUE, color=ft.colors.WHITE) | |
table = ft.DataTable( | |
border=ft.border.all(2, "cyan"), | |
border_radius=10, | |
vertical_lines=ft.BorderSide(1, color="F6F5F5"), | |
horizontal_lines=ft.BorderSide(1, "F6F5F5"), | |
columns=[ | |
ft.DataColumn(label=ft.Text("رابط القانون", text_align=ft.TextAlign.RIGHT)), | |
ft.DataColumn(label=ft.Text("المواد", text_align=ft.TextAlign.RIGHT)), | |
ft.DataColumn(label=ft.Text("الموضوع", text_align=ft.TextAlign.RIGHT, rtl=True)), | |
ft.DataColumn(label=ft.Text("تاريخ الإصدار", text_align=ft.TextAlign.RIGHT, rtl=True)), | |
ft.DataColumn(label=ft.Text("التشريع", text_align=ft.TextAlign.RIGHT, rtl=True, width = 350)), | |
], | |
rows=[] | |
) | |
details_list = ft.Column(scroll=ft.ScrollMode.AUTO) | |
container_style = { | |
"width": page.window_width / 2 - 20, | |
"height": page.window_height - 250, | |
"padding": 20, | |
"bgcolor": ft.colors.WHITE, | |
"border": ft.border.all(1, color=ft.colors.GREY_200), | |
"border_radius": ft.border_radius.all(15), | |
"shadow": ft.BoxShadow( | |
blur_radius=20, | |
spread_radius=2, | |
color=ft.colors.BLACK12, | |
offset=ft.Offset(4, 4) | |
) | |
} | |
details_column = ft.Container( | |
content=details_list, | |
**container_style | |
) | |
mada_column = ft.Container( | |
content=ft.Column(controls=[], scroll=ft.ScrollMode.AUTO, alignment=ft.MainAxisAlignment.CENTER, | |
horizontal_alignment=ft.CrossAxisAlignment.CENTER), | |
**container_style | |
) | |
def radio_mode(radio_group): | |
if radio_group.value == "في محتوى التشريعات": | |
current_search_mode.value = ("Mode 1 is selected") | |
elif radio_group.value == "في عناوين التشريعات": | |
current_search_mode.value = ("Mode 2 is selected") | |
def on_radio_change(e): | |
radio_mode(e.control) | |
search_mode_radios = ft.RadioGroup( | |
on_change=on_radio_change, | |
value="في محتوى التشريعات", | |
content=ft.Row( | |
[ | |
ft.Row([ft.Text("في عناوين التشريعات", weight=ft.FontWeight.BOLD), ft.Radio(value="في عناوين التشريعات")]), | |
ft.Row([ft.Text("في محتوى التشريعات", weight=ft.FontWeight.BOLD), ft.Radio(value="في محتوى التشريعات")]), | |
], | |
alignment=ft.MainAxisAlignment.CENTER, | |
spacing=80 | |
) | |
) | |
current_search_mode = ft.Text("", visible = False) | |
back_button = ft.ElevatedButton( | |
text="عودة", | |
on_click=go_back_to_search, | |
icon=ft.icons.ARROW_BACK_IOS_NEW_SHARP, | |
bgcolor=ft.colors.CYAN, | |
color=ft.colors.WHITE | |
) | |
relevant_matches_button = ft.ElevatedButton( | |
text="نتائج البحث", | |
on_click=toggle_relevant_matches, | |
bgcolor=ft.colors.CYAN, | |
color=ft.colors.WHITE, | |
style=ft.ButtonStyle( | |
shape=ft.RoundedRectangleBorder(radius=8), | |
elevation=2, | |
) | |
) | |
table_container = ft.Container( | |
content=table, | |
width=page.width, | |
) | |
search_view = ft.Column([ | |
ft.Row([search_field, search_button, loading_indicator], alignment=ft.MainAxisAlignment.END, spacing=10), | |
search_mode_radios, | |
current_search_mode, | |
], alignment=ft.MainAxisAlignment.START, spacing=20) | |
dlg = ft.AlertDialog( | |
modal=True, | |
content = ft.Text(), | |
) | |
def open_summary_dlg(e, fid): | |
bot_page = Bot_Page_ٍSummary.main(ft.Page, fid, df_laws) | |
bot_page.controls[0].content.controls[0].content.controls[2].controls[0].on_click = lambda e: page.close(dlg) | |
dlg.content = bot_page | |
dlg.open = True | |
dlg.update() | |
time.sleep(1) | |
bot_page.controls[1].on_click(None) | |
time.sleep(1) | |
bot_page.controls[2].on_click(None) | |
page.update() | |
def open_chat_dlg(e, fid): | |
bot_page = Bot_Page.main(ft, ft.Page, utils.by_law_id, fid, df_laws) | |
bot_page.controls[0].content.controls[0].content.controls[2].controls[0].on_click = lambda e: page.close(dlg) | |
dlg.content = bot_page | |
dlg.open = True | |
dlg.update() | |
dialog_button = ft.ElevatedButton( | |
text="س , ج حول التشريع", | |
icon=ft.icons.CHAT, | |
tooltip="Required", | |
on_click=open_chat_dlg, | |
style=ft.ButtonStyle( | |
bgcolor=ft.colors.WHITE, | |
color=ft.colors.BLACK, | |
shape=ft.RoundedRectangleBorder(radius=15), | |
elevation=5, | |
side=ft.BorderSide( | |
color=ft.colors.GREY, | |
width=1 | |
) | |
) | |
) | |
summary_button = ft.ElevatedButton( | |
text="ملخص التشريع", | |
icon=ft.icons.MENU_BOOK, | |
tooltip="ملخص", | |
on_click=open_summary_dlg, | |
style=ft.ButtonStyle( | |
bgcolor=ft.colors.WHITE, | |
color=ft.colors.BLACK, | |
shape=ft.RoundedRectangleBorder(radius=15), | |
elevation=5, | |
side=ft.BorderSide( | |
color=ft.colors.GREY, | |
width=1 | |
) | |
) | |
) | |
page.add(dlg) | |
left_buttons_row = ft.Row( | |
controls=[back_button, relevant_matches_button], | |
alignment=ft.MainAxisAlignment.CENTER, | |
spacing=20 | |
) | |
right_buttons_row = ft.Row( | |
controls=[dialog_button, summary_button], | |
alignment=ft.MainAxisAlignment.CENTER, | |
spacing=20 | |
) | |
detailed_buttons_row = ft.Row( | |
controls=[left_buttons_row, right_buttons_row], | |
alignment=ft.MainAxisAlignment.SPACE_AROUND, | |
spacing=20 | |
) | |
law_info_table = ft.Row([ft.Text("")], alignment=ft.MainAxisAlignment.CENTER) | |
details_view = ft.Column( | |
[ | |
ft.Row( | |
[ | |
law_info_table | |
], | |
alignment=ft.MainAxisAlignment.CENTER | |
), | |
detailed_buttons_row, | |
ft.Row( | |
[ | |
#ft.Text(" "), | |
mada_column, | |
details_column | |
], | |
alignment=ft.MainAxisAlignment.CENTER, | |
spacing=20 | |
) | |
], | |
alignment=ft.MainAxisAlignment.CENTER, | |
spacing=20, | |
visible=False | |
) | |
law_info_table.visible = False | |
page.add(ft.Column([search_view, table_container, details_view])) | |
table.visible = False | |
current_search_mode.value = "Mode 1 is selected" | |
page.update() | |
ft.app(target=main, assets_dir='assets') |