From d86253a7fba6cb9cdd1bd0811e9ec05c2308c969 Mon Sep 17 00:00:00 2001 From: Shudarsan Regmi Date: Fri, 26 Apr 2024 14:59:08 +0530 Subject: [PATCH 1/7] Download results as pdf feature was added --- app.py | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/app.py b/app.py index bf44307..f49e0e6 100644 --- a/app.py +++ b/app.py @@ -5,6 +5,7 @@ import pandas as pd import streamlit as st from streamlit_folium import st_folium +import pdfkit #Page Setup st.set_page_config( @@ -83,6 +84,76 @@ def run_center_randomizer(schools_tsv, centers_tsv, prefs_tsv): cmd = f"python school_center.py {schools_tsv} {centers_tsv} {prefs_tsv}" subprocess.run(cmd, shell=True) + +def generate_pdf(results_data,filename,title): + st.toast("Generating Pdf..") + st.write("Generating pdf...") + + # Convert DataFrame to HTML with modern table styling + html_content = results_data.to_html(index=False, classes=['modern-table']) + + # HTML template for the PDF content + html_template = f""" + + + + School Center + + + +
+
+

नेपाल सरकार

+

शिक्षा, विज्ञान तथा प्रविधि मन्त्रालय

+

सिंहदरबार, काठमाडौं

+

{title}

+

Randomly generated using center-randomize project by MOEST, Government of Nepal

+
+
+ {html_content} + + + """ + + # Generate the PDF from the HTML content + pdfkit.from_string(html_template, f"{filename}.pdf", options={'encoding': 'utf-8'}) + st.success(f"Successfully Downloaded {filename}.pdf!") + #Function to filter the data def filter_data(df, filter_type, filter_value): if filter_type in df.columns: @@ -169,13 +240,23 @@ def save_file_to_temp(file_obj): tab1.divider() tab1.subheader('All Data') tab1.dataframe(df_school_center) + + + else: tab1.info("No calculated data available.", icon="ℹ️") if 'school_center_distance' in st.session_state.calculated_data: - df = pd.read_csv(st.session_state.calculated_data['school_center_distance'], sep="\t") - tab2.dataframe(df) + df_school_center_distance = pd.read_csv(st.session_state.calculated_data['school_center_distance'], sep="\t") + tab2.dataframe(df_school_center_distance) else: tab2.error("School Center Distance file not found.") + # Download Button + + def download_handler(): + generate_pdf(df_school_center, "school_center", "School Center") + generate_pdf(df_school_center_distance,"school_center_distance","School Center Distance") + st.button("Download Results as PDF!", on_click=download_handler) + elif st.session_state.calculate_clicked and not st.session_state.calculated_data: tab1.error("School Center data not found in session state.") From 1a8922ed75ed0e5ef5343188e38971e5a6af11f2 Mon Sep 17 00:00:00 2001 From: Shudarsan Regmi <65646203+ShudarsanRegmi@users.noreply.github.com> Date: Fri, 26 Apr 2024 17:48:56 +0530 Subject: [PATCH 2/7] Added logo to the downloaded pdfs Co-authored-by: Dhiraj Raut <63958838+dhirajraut1@users.noreply.github.com> --- app.py | 1 + 1 file changed, 1 insertion(+) diff --git a/app.py b/app.py index f49e0e6..a808b8d 100644 --- a/app.py +++ b/app.py @@ -138,6 +138,7 @@ def generate_pdf(results_data,filename,title):
+

नेपाल सरकार

शिक्षा, विज्ञान तथा प्रविधि मन्त्रालय

सिंहदरबार, काठमाडौं

From 961f4850ac038f6a8431c7052a18973f68a23ac6 Mon Sep 17 00:00:00 2001 From: Shudarsan Regmi Date: Fri, 26 Apr 2024 17:58:50 +0530 Subject: [PATCH 3/7] Updated requirements.txt --- requirements.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/requirements.txt b/requirements.txt index e006666..f02cf50 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,3 +7,5 @@ pytest-cov==5.0.0 streamlit==1.33.0 streamlit_folium==0.19.1 folium==0.16.0 +wkhtmltopdf==0.2 +pdfkit==1.0.0 \ No newline at end of file From 59cc772a3df6c1078a7b740c2f0819c490fd7d0f Mon Sep 17 00:00:00 2001 From: Shudarsan Regmi Date: Fri, 26 Apr 2024 18:46:50 +0530 Subject: [PATCH 4/7] Irrelevant columns were removed from the pdf --- app.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app.py b/app.py index a808b8d..dff84ee 100644 --- a/app.py +++ b/app.py @@ -126,7 +126,7 @@ def generate_pdf(results_data,filename,title): }} #main-header {{ display: flex; - align-items: center; /* Added align-items to center vertically */ + align-items: center; justify-content: center; }} @@ -255,8 +255,10 @@ def save_file_to_temp(file_obj): # Download Button def download_handler(): - generate_pdf(df_school_center, "school_center", "School Center") - generate_pdf(df_school_center_distance,"school_center_distance","School Center Distance") + print(df_school_center.columns) + print(df_school_center_distance.columns) + generate_pdf(df_school_center.drop(['center_lat','center_long'],axis=1), "school_center", "School Center") + generate_pdf(df_school_center_distance.drop(['school_lat','school_long'],axis=1),"school_center_distance","School Center Distance") st.button("Download Results as PDF!", on_click=download_handler) elif st.session_state.calculate_clicked and not st.session_state.calculated_data: From 77263cbd775a22b4932e3816885b5aab6e9372f6 Mon Sep 17 00:00:00 2001 From: Shudarsan Regmi Date: Fri, 26 Apr 2024 19:06:09 +0530 Subject: [PATCH 5/7] Generated pdfs were stored in separate directory --- app.py | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/app.py b/app.py index dff84ee..a5d56c6 100644 --- a/app.py +++ b/app.py @@ -7,6 +7,9 @@ from streamlit_folium import st_folium import pdfkit +#Constants +DOWNLOAD_DIR="generated-pdfs" + #Page Setup st.set_page_config( page_title="MOEST Exam Center Calculator", @@ -99,6 +102,11 @@ def generate_pdf(results_data,filename,title): School Center @@ -142,6 +151,7 @@ def generate_pdf(results_data,filename,title):

नेपाल सरकार

शिक्षा, विज्ञान तथा प्रविधि मन्त्रालय

सिंहदरबार, काठमाडौं

+

{title}

Randomly generated using center-randomize project by MOEST, Government of Nepal

@@ -152,7 +162,9 @@ def generate_pdf(results_data,filename,title): """ # Generate the PDF from the HTML content - pdfkit.from_string(html_template, f"{filename}.pdf", options={'encoding': 'utf-8'}) + if not os.path.exists(DOWNLOAD_DIR): + os.mkdir(DOWNLOAD_DIR) + pdfkit.from_string(html_template, f"{DOWNLOAD_DIR}/{filename}.pdf", options={'encoding': 'utf-8'}) st.success(f"Successfully Downloaded {filename}.pdf!") #Function to filter the data @@ -255,8 +267,6 @@ def save_file_to_temp(file_obj): # Download Button def download_handler(): - print(df_school_center.columns) - print(df_school_center_distance.columns) generate_pdf(df_school_center.drop(['center_lat','center_long'],axis=1), "school_center", "School Center") generate_pdf(df_school_center_distance.drop(['school_lat','school_long'],axis=1),"school_center_distance","School Center Distance") st.button("Download Results as PDF!", on_click=download_handler) From 66526c2170942de7454dafc2e411cd170b5a94bc Mon Sep 17 00:00:00 2001 From: Shudarsan Regmi Date: Fri, 26 Apr 2024 22:29:06 +0530 Subject: [PATCH 6/7] View pdf feature was added --- app.py | 48 ++++++++++++++++++++++++++++++++++++++---------- file-server.py | 22 ++++++++++++++++++++++ 2 files changed, 60 insertions(+), 10 deletions(-) create mode 100644 file-server.py diff --git a/app.py b/app.py index a5d56c6..fff0ef7 100644 --- a/app.py +++ b/app.py @@ -7,8 +7,14 @@ from streamlit_folium import st_folium import pdfkit + #Constants DOWNLOAD_DIR="generated-pdfs" +STATIC_FILE_SERVER_HOST="http://localhost" +STATIC_FILE_SERVER_PORT=int(os.getenv('PORT',8005)) + + +subprocess.Popen(['python3','file-server.py']) #Page Setup st.set_page_config( @@ -96,10 +102,12 @@ def generate_pdf(results_data,filename,title): html_content = results_data.to_html(index=False, classes=['modern-table']) # HTML template for the PDF content + + # Generate the PDF from the HTML content html_template = f""" - + School Center @@ -160,12 +168,12 @@ def generate_pdf(results_data,filename,title): """ - - # Generate the PDF from the HTML content if not os.path.exists(DOWNLOAD_DIR): os.mkdir(DOWNLOAD_DIR) pdfkit.from_string(html_template, f"{DOWNLOAD_DIR}/{filename}.pdf", options={'encoding': 'utf-8'}) st.success(f"Successfully Downloaded {filename}.pdf!") + st.session_state.downloaded = True + st.session_state.school_center_pdf_link = f"{STATIC_FILE_SERVER_HOST}:{STATIC_FILE_SERVER_PORT}/{DOWNLOAD_DIR}/{filename}.pdf" #Function to filter the data def filter_data(df, filter_type, filter_value): @@ -249,7 +257,7 @@ def save_file_to_temp(file_obj): m.add_child(fg) with tab1: st_folium( m, width=1200, height=400 ) - + tab1.divider() tab1.subheader('All Data') tab1.dataframe(df_school_center) @@ -258,7 +266,7 @@ def save_file_to_temp(file_obj): else: tab1.info("No calculated data available.", icon="ℹ️") - + if 'school_center_distance' in st.session_state.calculated_data: df_school_center_distance = pd.read_csv(st.session_state.calculated_data['school_center_distance'], sep="\t") tab2.dataframe(df_school_center_distance) @@ -270,6 +278,26 @@ def download_handler(): generate_pdf(df_school_center.drop(['center_lat','center_long'],axis=1), "school_center", "School Center") generate_pdf(df_school_center_distance.drop(['school_lat','school_long'],axis=1),"school_center_distance","School Center Distance") st.button("Download Results as PDF!", on_click=download_handler) + try: + if st.session_state.downloaded: + school_center_download_button_html = f""" + + + """ + school_center_distance_download_button_html = f""" + + + """ + st.markdown(school_center_download_button_html, unsafe_allow_html=True) + st.markdown(school_center_distance_download_button_html, unsafe_allow_html=True) + except AttributeError: + print("Has not been downloaded yet..") elif st.session_state.calculate_clicked and not st.session_state.calculated_data: tab1.error("School Center data not found in session state.") diff --git a/file-server.py b/file-server.py new file mode 100644 index 0000000..d2da23a --- /dev/null +++ b/file-server.py @@ -0,0 +1,22 @@ +from flask import Flask, send_from_directory +import os + +app = Flask(__name__) + +PORT = int(os.getenv('PORT',8005)) + +# Route to serve the index.html file from the 'static' directory +@app.route('/') +def index(): + return send_from_directory('static', 'index.html') + +# Route to serve static files (e.g., CSS, JavaScript, images) +@app.route('/generated-pdfs/') +def static_files(filename): + return send_from_directory('generated-pdfs', filename) + + +if __name__ == "__main__": + app.run(port=PORT,debug=True) + +#Todo: Gracefully shutdown the server when the tab is closed \ No newline at end of file From 791cd7532b50ff92b2a066e9041e17b492615830 Mon Sep 17 00:00:00 2001 From: Shudarsan Regmi Date: Fri, 26 Apr 2024 22:33:54 +0530 Subject: [PATCH 7/7] Updated requirements.txt --- requirements.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f02cf50..ba57400 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,4 +8,5 @@ streamlit==1.33.0 streamlit_folium==0.19.1 folium==0.16.0 wkhtmltopdf==0.2 -pdfkit==1.0.0 \ No newline at end of file +pdfkit==1.0.0 +Flask==3.0.2