From 9e16e12fc8dd02abe5b023cc4d9e97223ea7630b Mon Sep 17 00:00:00 2001 From: Shreya H S Date: Sun, 6 Oct 2024 15:40:43 +0530 Subject: [PATCH 1/4] Addition of recipe_finder through API using streamlit --- .../ApiPrograms/recipe_finder/.gitignore | 14 ++ .../recipe_finder/recipe_finder.py | 137 ++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 src/apps/pages/programs/ApiPrograms/recipe_finder/.gitignore create mode 100644 src/apps/pages/programs/ApiPrograms/recipe_finder/recipe_finder.py diff --git a/src/apps/pages/programs/ApiPrograms/recipe_finder/.gitignore b/src/apps/pages/programs/ApiPrograms/recipe_finder/.gitignore new file mode 100644 index 00000000..34785bfa --- /dev/null +++ b/src/apps/pages/programs/ApiPrograms/recipe_finder/.gitignore @@ -0,0 +1,14 @@ +# Ignore Python cache files +__pycache__/ + +# Ignore .env file for API keys +.env + +# Ignore virtual environment +venv/ + +# Ignore log files +*.log + +# Ignore compiled files +*.pyc \ No newline at end of file diff --git a/src/apps/pages/programs/ApiPrograms/recipe_finder/recipe_finder.py b/src/apps/pages/programs/ApiPrograms/recipe_finder/recipe_finder.py new file mode 100644 index 00000000..1994e179 --- /dev/null +++ b/src/apps/pages/programs/ApiPrograms/recipe_finder/recipe_finder.py @@ -0,0 +1,137 @@ +import streamlit as st +import requests +import os +from dotenv import load_dotenv + +# Load environment variables from .env file +load_dotenv() + +# Function to fetch recipes +def fetch_recipes(query): + api_key = os.getenv('SPOONACULAR_API_KEY') # Retrieve API key from environment variable + api_url = f"https://api.spoonacular.com/recipes/complexSearch?query={query}&apiKey={api_key}" + response = requests.get(api_url) + return response.json() +# Streamlit UI + +# Add custom CSS +st.write( + """ + + """, + unsafe_allow_html=True, +) + +# Display the title with the custom class +st.markdown('

Recipe Finder

', unsafe_allow_html=True) + +# Centered input box with placeholder text +st.markdown('
', unsafe_allow_html=True) +query = st.text_input("Ingredients or a dish name, you name it!", placeholder="Enter") +st.markdown('
', unsafe_allow_html=True) + +# Add custom CSS for styling +st.markdown( + """ + + """, + unsafe_allow_html=True, +) + +if query: + # Fetch recipes + recipes_data = fetch_recipes(query) + + # Extract the results list from the response + recipes = recipes_data.get('results', []) + + # Create a flex container for the recipes + st.markdown('
', unsafe_allow_html=True) + + # Display each recipe with the updated styles + for recipe in recipes: + recipe_url = f"https://spoonacular.com/recipes/{recipe['title'].replace(' ', '-').lower()}-{recipe['id']}" + st.markdown( + f""" + +
+ +
{recipe["title"]}
+
+
+ """, + unsafe_allow_html=True, + ) + + st.markdown('
', unsafe_allow_html=True) \ No newline at end of file From b7dd04d1489e466b2f2506a0d0c421677a62cb00 Mon Sep 17 00:00:00 2001 From: Shreya H S Date: Sun, 6 Oct 2024 15:43:35 +0530 Subject: [PATCH 2/4] ignoring vitual env --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 5d8b4bee..d7e9bb87 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ __pycache__/ # Virtual environment myenv /myenv + +/venv \ No newline at end of file From 95d12e23600ec2fe9ca063ef92b44c6ffbe15ec6 Mon Sep 17 00:00:00 2001 From: Shreya H S <135348911+shrehs@users.noreply.github.com> Date: Thu, 31 Oct 2024 22:18:23 +0530 Subject: [PATCH 3/4] PDFToolbox.py --- .../programs/StudyPrograms/PDFToolbox.py | 145 ++++++++++++++++-- 1 file changed, 128 insertions(+), 17 deletions(-) diff --git a/src/apps/pages/programs/StudyPrograms/PDFToolbox.py b/src/apps/pages/programs/StudyPrograms/PDFToolbox.py index 79ffb3f2..a2d4175d 100644 --- a/src/apps/pages/programs/StudyPrograms/PDFToolbox.py +++ b/src/apps/pages/programs/StudyPrograms/PDFToolbox.py @@ -15,21 +15,132 @@ def readPDF(): else: st.warning("No text found in this page", icon="⚠️") -# TODO: Implement mergePDF, splitPDF, rotatePDF, encryptPDF, decryptPDF functions +def readPDF(): + st.markdown("#### PDF Reader App") + file = st.file_uploader("Upload a PDF file", type=["pdf"]) + if not file: + st.stop() + reader = PyPDF2.PdfReader(file) + numPage = st.number_input("From which page to start reading?", format="%d", min_value=1, max_value=len(reader.pages)) + page = reader.pages[numPage-1] + text = page.extract_text() + if text: + st.write(text) + else: + st.warning("No text found on this page", icon="⚠️") + +def mergePDF(): + st.markdown("#### PDF Merger") + uploaded_files = st.file_uploader("Upload PDF files to merge", type=["pdf"], accept_multiple_files=True) + if uploaded_files: + pdf_writer = PyPDF2.PdfWriter() + for file in uploaded_files: + pdf_reader = PyPDF2.PdfReader(file) + for page_num in range(len(pdf_reader.pages)): + page = pdf_reader.pages[page_num] + pdf_writer.add_page(page) + output_pdf = "merged_output.pdf" + with open(output_pdf, "wb") as f: + pdf_writer.write(f) + with open(output_pdf, "rb") as f: + st.download_button("Download Merged PDF", f, file_name="merged_output.pdf") + +def splitPDF(): + st.markdown("#### PDF Splitter") + file = st.file_uploader("Upload a PDF file to split", type=["pdf"]) + if file: + pdf_reader = PyPDF2.PdfReader(file) + start_page = st.number_input("Start page", min_value=1, max_value=len(pdf_reader.pages), value=1) + end_page = st.number_input("End page", min_value=start_page, max_value=len(pdf_reader.pages), value=len(pdf_reader.pages)) + pdf_writer = PyPDF2.PdfWriter() + for i in range(start_page - 1, end_page): + pdf_writer.add_page(pdf_reader.pages[i]) + output_pdf = "split_output.pdf" + with open(output_pdf, "wb") as f: + pdf_writer.write(f) + with open(output_pdf, "rb") as f: + st.download_button("Download Split PDF", f, file_name="split_output.pdf") + +def rotatePDF(): + st.markdown("#### PDF Rotate Tool") + file = st.file_uploader("Upload a PDF file to rotate", type=["pdf"]) + + if not file: + st.warning("Please upload a PDF file", icon="⚠️") + return + + reader = PyPDF2.PdfReader(file) + writer = PyPDF2.PdfWriter() + + # Select rotation angle + angle = st.selectbox("Select rotation angle (clockwise)", [90, 180, 270]) + + # Rotate each page + for page_num in range(len(reader.pages)): + page = reader.pages[page_num] + page.rotate(angle) # Use positive angles for clockwise rotation + writer.add_page(page) + + # Save rotated PDF + output_file = "rotated_output.pdf" + with open(output_file, "wb") as f: + writer.write(f) + + # Provide download link + with open(output_file, "rb") as f: + st.download_button("Download Rotated PDF", f, file_name=output_file) + +def encryptPDF(): + st.markdown("#### PDF Encryptor") + file = st.file_uploader("Upload a PDF file to encrypt", type=["pdf"]) + if file: + password = st.text_input("Enter password", type="password") + if password: + pdf_reader = PyPDF2.PdfReader(file) + pdf_writer = PyPDF2.PdfWriter() + for page in pdf_reader.pages: + pdf_writer.add_page(page) + pdf_writer.encrypt(password) + output_pdf = "encrypted_output.pdf" + with open(output_pdf, "wb") as f: + pdf_writer.write(f) + with open(output_pdf, "rb") as f: + st.download_button("Download Encrypted PDF", f, file_name="encrypted_output.pdf") + +def decryptPDF(): + st.markdown("#### PDF Decryptor") + file = st.file_uploader("Upload an encrypted PDF file to decrypt", type=["pdf"]) + if file: + password = st.text_input("Enter password to decrypt", type="password") + if password: + pdf_reader = PyPDF2.PdfReader(file) + if pdf_reader.decrypt(password): + pdf_writer = PyPDF2.PdfWriter() + for page in pdf_reader.pages: + pdf_writer.add_page(page) + output_pdf = "decrypted_output.pdf" + with open(output_pdf, "wb") as f: + pdf_writer.write(f) + with open(output_pdf, "rb") as f: + st.download_button("Download Decrypted PDF", f, file_name="decrypted_output.pdf") + else: + st.error("Incorrect password", icon="🚫") + def PDFToolbox(): - st.title("PDF Reader & Editor App") - choice = st.selectbox("Choose an operation", [None, "Read PDF", "Merge PDF", "Split PDF", "Rotate PDF", "Encrypt PDF", "Decrypt PDF"]) - if choice == "Read PDF": - readPDF() - elif choice == "Merge PDF": - st.info("Coming soon!", icon="🚧") - elif choice == "Split PDF": - st.info("Coming soon!", icon="🚧") - elif choice == "Rotate PDF": - st.info("Coming soon!", icon="🚧") - elif choice == "Encrypt PDF": - st.info("Coming soon!", icon="🚧") - elif choice == "Decrypt PDF": - st.info("Coming soon!", icon="🚧") - else: - st.warning("Invalid choice!", icon="⚠️") + st.title("PDF Reader & Editor App") + choice = st.selectbox("Choose an operation", [None, "Read PDF", "Merge PDF", "Split PDF", "Rotate PDF", "Encrypt PDF", "Decrypt PDF"]) + + if choice == "Read PDF": + readPDF() + elif choice == "Merge PDF": + mergePDF() + elif choice == "Split PDF": + splitPDF() + elif choice == "Rotate PDF": + rotatePDF() + elif choice == "Encrypt PDF": + encryptPDF() + elif choice == "Decrypt PDF": + decryptPDF() + else: + st.warning("Invalid choice!", icon="⚠️") From 19f627a259ff5a2c99bda4d78826cdbedba0d8b4 Mon Sep 17 00:00:00 2001 From: Shreya H S <135348911+shrehs@users.noreply.github.com> Date: Fri, 1 Nov 2024 12:43:42 +0530 Subject: [PATCH 4/4] Delete src/apps/pages/programs/ApiPrograms/recipe_finder directory --- .../ApiPrograms/recipe_finder/.gitignore | 14 -- .../recipe_finder/recipe_finder.py | 137 ------------------ 2 files changed, 151 deletions(-) delete mode 100644 src/apps/pages/programs/ApiPrograms/recipe_finder/.gitignore delete mode 100644 src/apps/pages/programs/ApiPrograms/recipe_finder/recipe_finder.py diff --git a/src/apps/pages/programs/ApiPrograms/recipe_finder/.gitignore b/src/apps/pages/programs/ApiPrograms/recipe_finder/.gitignore deleted file mode 100644 index 34785bfa..00000000 --- a/src/apps/pages/programs/ApiPrograms/recipe_finder/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -# Ignore Python cache files -__pycache__/ - -# Ignore .env file for API keys -.env - -# Ignore virtual environment -venv/ - -# Ignore log files -*.log - -# Ignore compiled files -*.pyc \ No newline at end of file diff --git a/src/apps/pages/programs/ApiPrograms/recipe_finder/recipe_finder.py b/src/apps/pages/programs/ApiPrograms/recipe_finder/recipe_finder.py deleted file mode 100644 index 1994e179..00000000 --- a/src/apps/pages/programs/ApiPrograms/recipe_finder/recipe_finder.py +++ /dev/null @@ -1,137 +0,0 @@ -import streamlit as st -import requests -import os -from dotenv import load_dotenv - -# Load environment variables from .env file -load_dotenv() - -# Function to fetch recipes -def fetch_recipes(query): - api_key = os.getenv('SPOONACULAR_API_KEY') # Retrieve API key from environment variable - api_url = f"https://api.spoonacular.com/recipes/complexSearch?query={query}&apiKey={api_key}" - response = requests.get(api_url) - return response.json() -# Streamlit UI - -# Add custom CSS -st.write( - """ - - """, - unsafe_allow_html=True, -) - -# Display the title with the custom class -st.markdown('

Recipe Finder

', unsafe_allow_html=True) - -# Centered input box with placeholder text -st.markdown('
', unsafe_allow_html=True) -query = st.text_input("Ingredients or a dish name, you name it!", placeholder="Enter") -st.markdown('
', unsafe_allow_html=True) - -# Add custom CSS for styling -st.markdown( - """ - - """, - unsafe_allow_html=True, -) - -if query: - # Fetch recipes - recipes_data = fetch_recipes(query) - - # Extract the results list from the response - recipes = recipes_data.get('results', []) - - # Create a flex container for the recipes - st.markdown('
', unsafe_allow_html=True) - - # Display each recipe with the updated styles - for recipe in recipes: - recipe_url = f"https://spoonacular.com/recipes/{recipe['title'].replace(' ', '-').lower()}-{recipe['id']}" - st.markdown( - f""" - -
- -
{recipe["title"]}
-
-
- """, - unsafe_allow_html=True, - ) - - st.markdown('
', unsafe_allow_html=True) \ No newline at end of file