From a874ee1df95d49c88bba0f12a9914f5a21740ce1 Mon Sep 17 00:00:00 2001 From: pleabargain Date: Fri, 15 Nov 2024 10:46:29 +0400 Subject: [PATCH 1/3] improved fork --- README.md | 36 ++++++++++++++++---- main.py | 88 ++++++++++++++++++++++++++++++++++++++++++++++-- ppt_data_gen.py | 21 ++++++------ requirements.txt | 2 ++ 4 files changed, 127 insertions(+), 20 deletions(-) create mode 100644 requirements.txt diff --git a/README.md b/README.md index c4a72cf..3e14bb8 100644 --- a/README.md +++ b/README.md @@ -1,23 +1,46 @@ + +# original idea inspired by +https://github.com/Govind-S-B/ppt_generator + + + # PPT Generator A local LLM assisted ppt generation tool ## Why -Writing presentations for course assignments is just boilerplate work most often, especially when even the lecturers dont even care about it. -Thats why I automated the boilerplate work, just enter a topic and the tool generates a simple presentation , enough to satisfy the base course requirement. +Idea generation with Ollama running locally. This will be useful for generating ideas for presentations. And also for generating ppt content. It will pull the available local models and let you select one. + ## Running Locally install [ollama](https://ollama.ai/download) and have it up and running with command `ollama serve` ( applicable to some systems only ) -download the required model ( this can be changed in this [line](https://github.com/Govind-S-B/ppt_generator/blob/main/ppt_data_gen.py#L24) ) + + ``` -ollama pull dolphin2.1-mistral +ollama pull llama3.2 ``` + +install the required python dependencies +``` +pip install -r requirements.txt +``` + +maybe these too + +``` +pip install -U langchain-community +pip install -U langchain-ollama +``` + + + + clone the repo and move into the directory ``` -git clone https://github.com/Govind-S-B/ppt_generator.git +git clone cd ppt_generator ``` install the required python dependencies @@ -25,6 +48,7 @@ install the required python dependencies pip install -r requirements.txt ``` run the streamlit app + ``` -streamlit run main.py +python -m streamlit run main.py ``` diff --git a/main.py b/main.py index 360a987..5d653d4 100644 --- a/main.py +++ b/main.py @@ -1,16 +1,96 @@ +import subprocess import streamlit as st from ppt_data_gen import slide_data_gen from ppt_gen import ppt_gen +import random +from datetime import datetime +import time + +# Define the function to get installed models first +def get_installed_models(): + try: + # Run ollama list command and capture output + result = subprocess.run(['ollama', 'list'], capture_output=True, text=True) + # Split output into lines and skip the header line + lines = result.stdout.strip().split('\n')[1:] + # Extract model names from each line + models = [line.split()[0] for line in lines if line] + return models + except Exception as e: + # Fallback to default models if command fails + st.warning(f"Could not fetch installed models: {str(e)}") + return [] + +# Function to select Ollama model +def select_ollama_model(): + models = get_installed_models() + selected_model = st.selectbox("Select Ollama model:", models) + return selected_model st.title("PPT Generator") +# Input for topic topic = st.text_input("Enter a topic:") -if st.button("Generate"): - data = slide_data_gen(topic) +# Slider for number of slides +num_slides = st.slider("Select number of slides:", min_value=3, max_value=20, value=7) + +# Get selected model +ollama_model = select_ollama_model() + +if st.button("Generate") and topic: + # Initialize progress bar + progress_bar = st.progress(0) + status_text = st.empty() + + # List of random status messages + messages = [ + "Hold your horses—better yet, knit them a sweater while you wait", + "Time flies when you’re watching cat videos. Try it", + "If waiting were a sport, you’d be a gold medalist. Flex those skills", + "Patience is a virtue, and so is binge-watching your favorite show", + "Why not take a power nap? I’ll wake you up… maybe", + "Hang tight—perfect time for a snack break! Got popcorn?", + "Waiting is just the universe’s way of saying, “Do a little dance!”", + "Hold on—time to practice your air guitar solo", + "Think of this as a short intermission. Grab a soda and some popcorn", + "While you’re waiting, why not perfect your paper airplane technique?" + ] + + # Shuffle messages to ensure randomness + random.shuffle(messages) + + # Function to update status message with a dancing cursor + def update_status_with_cursor(message): + cursor_states = ['|', '/', '-', '\\'] + for cursor in cursor_states: + status_text.text(f"{message} {cursor}") + time.sleep(0.25) # Change cursor every 0.25 seconds + + # Update status with a random message and dancing cursor + for _ in range(4): # Display each message for 4 seconds + if messages: + update_status_with_cursor(messages.pop()) + + data = slide_data_gen(topic, num_slides, ollama_model) + progress_bar.progress(50) + + # Update status with another random message and dancing cursor + for _ in range(4): # Display each message for 4 seconds + if messages: + update_status_with_cursor(messages.pop()) + ppt_file = ppt_gen(data) + progress_bar.progress(100) + + # Reset status + status_text.text("Presentation ready for download!") + progress_bar.empty() - file_name = f"Presentation.pptx" + # Create a file name using the topic, model, and current date + date_stamp = datetime.now().strftime("%Y%m%d") + sanitized_topic = topic.replace(" ", "_") # Replace spaces with underscores + file_name = f"{sanitized_topic}_{ollama_model}_{date_stamp}.pptx" st.download_button( label="Download Presentation", @@ -18,3 +98,5 @@ file_name=file_name, mime="application/vnd.openxmlformats-officedocument.presentationml.presentation", ) +else: + st.warning("Please enter a topic to generate the presentation.") diff --git a/ppt_data_gen.py b/ppt_data_gen.py index 68d676c..bdcc2ee 100644 --- a/ppt_data_gen.py +++ b/ppt_data_gen.py @@ -1,5 +1,5 @@ import re -from langchain.llms import Ollama +from langchain_ollama import OllamaLLM def extract_items(input_string): @@ -20,39 +20,38 @@ def extract_items(input_string): return items -def slide_data_gen(topic): - llm = Ollama(model="dolphin2.1-mistral", - temperature="0.4") +def slide_data_gen(topic, num_slides, model): + llm = OllamaLLM(model=model, temperature="0.4") slide_data = [] point_count = 5 - slide_data.append(extract_items(llm(f""" + slide_data.append(extract_items(llm.invoke(f""" You are a text summarization and formatting specialized model that fetches relevant information For the topic "{topic}" suggest a presentation title and a presentation subtitle it should be returned in the format : - << "title" | "subtitle >> + << "title" | "subtitle" >> example : << "Ethics in Design" | "Integrating Ethics into Design Processes" >> """))) - slide_data.append(extract_items(llm(f""" + slide_data.append(extract_items(llm.invoke(f""" You are a text summarization and formatting specialized model that fetches relevant information For the presentation titled "{slide_data[0][0]}" and with subtitle "{slide_data[0][1]}" for the topic "{topic}" - Write a table of contents containing the title of each slide for a 7 slide presentation + Write a table of contents containing the title of each slide for a {num_slides} slide presentation It should be of the format : << "slide1" | "slide2" | "slide3" | ... | >> example : - << "Introduction to Design Ethics" | "User-Centered Design" | "Transparency and Honesty" | "Data Privacy and Security" | "Accessibility and Inclusion" | "Social Impact and Sustainability" | "Ethical AI and Automation" | "Collaboration and Professional Ethics" >> + << "Introduction to Design Ethics" | "AI and the Travel Industry" | "User-Centered Design" | "Transparency and Honesty" | "Data Privacy and Security" | "Accessibility and Inclusion" | "Social Impact and Sustainability" | "Ethical AI and Automation" | "Collaboration and Professional Ethics" >> """))) for subtopic in slide_data[1]: - data_to_clean = llm(f""" + data_to_clean = llm.invoke(f""" You are a content generation specialized model that fetches relevant information and presents it in clear concise manner For the presentation titled "{slide_data[0][0]}" and with subtitle "{slide_data[0][1]}" for the topic "{topic}" @@ -61,7 +60,7 @@ def slide_data_gen(topic): Make the points short, concise and to the point. """) - cleaned_data = llm(f""" + cleaned_data = llm.invoke(f""" You are a text summarization and formatting specialized model that fetches relevant information and formats it into user specified formats Given below is a text draft for a presentation slide containing {point_count} points , extract the {point_count} sentences and format it as : diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..3e419f2 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +streamlit +python-pptx \ No newline at end of file From 2dd9fb64c5fa6cf14086e9018a2bfa0fc8d60e74 Mon Sep 17 00:00:00 2001 From: pleabargain Date: Fri, 15 Nov 2024 11:26:44 +0400 Subject: [PATCH 2/3] more fixes --- README.md | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 3e14bb8..0f9164d 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,27 @@ # original idea inspired by https://github.com/Govind-S-B/ppt_generator +# better version +https://github.com/pleabargain/ppt_generator-1 # PPT Generator -A local LLM assisted ppt generation tool +A local LLM assisted powerpoint generation tool ## Why -Idea generation with Ollama running locally. This will be useful for generating ideas for presentations. And also for generating ppt content. It will pull the available local models and let you select one. +Idea generation with Ollama running locally. This will be useful for generating ideas for presentations. It will pull the available local models and let you select one. + +# What +Don't expect a lot of features. It's a simple tool to generate (generic) powerpoint content. It doesn't support images and there is no styling to speak of. It's just a simple tool to generate ppt content. There all kinds of things that can be added to it. + +* add image generation +* add styling +* add speaker notes +* add speaker notes to slides +* add slide numbers +* add slide layouts +* reference color palettes + ## Running Locally @@ -22,8 +36,19 @@ ollama pull llama3.2 ``` +clone the repo and move into the directory + +``` +git clone https://github.com/pleabargain/ppt_generator-1 +``` + + +``` +cd ppt_generator +``` install the required python dependencies + ``` pip install -r requirements.txt ``` @@ -36,19 +61,9 @@ pip install -U langchain-ollama ``` - - -clone the repo and move into the directory -``` -git clone -cd ppt_generator -``` -install the required python dependencies -``` -pip install -r requirements.txt -``` run the streamlit app ``` python -m streamlit run main.py ``` + From aa2282b72949e76c7cf12d5b2afd2887999bd5a1 Mon Sep 17 00:00:00 2001 From: pleabargain Date: Fri, 15 Nov 2024 13:31:28 +0400 Subject: [PATCH 3/3] added lang option --- README.md | 8 ++++++-- main.py | 11 ++++++++--- ppt_data_gen.py | 46 +++++++++++++++++++--------------------------- 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 0f9164d..0f9ad9f 100644 --- a/README.md +++ b/README.md @@ -13,12 +13,16 @@ A local LLM assisted powerpoint generation tool Idea generation with Ollama running locally. This will be useful for generating ideas for presentations. It will pull the available local models and let you select one. # What -Don't expect a lot of features. It's a simple tool to generate (generic) powerpoint content. It doesn't support images and there is no styling to speak of. It's just a simple tool to generate ppt content. There all kinds of things that can be added to it. +Don't expect a lot of features. + + +I did add a language option. It's not perfect but it's a start. + +It's a simple tool to generate (generic) powerpoint content. It doesn't support images and there is no styling to speak of. It's just a simple tool to generate ppt content. There all kinds of things that can be added to it. * add image generation * add styling * add speaker notes -* add speaker notes to slides * add slide numbers * add slide layouts * reference color palettes diff --git a/main.py b/main.py index 5d653d4..194a27d 100644 --- a/main.py +++ b/main.py @@ -35,7 +35,11 @@ def select_ollama_model(): # Slider for number of slides num_slides = st.slider("Select number of slides:", min_value=3, max_value=20, value=7) -# Get selected model +# Add language selection dropdown +languages = ["English", "French", "Spanish", "German", "Ukrainian", "Arabic"] # Added Ukrainian and Arabic +language = st.selectbox("Select Language:", languages, index=0) + +# Get selected model and language ollama_model = select_ollama_model() if st.button("Generate") and topic: @@ -72,7 +76,8 @@ def update_status_with_cursor(message): if messages: update_status_with_cursor(messages.pop()) - data = slide_data_gen(topic, num_slides, ollama_model) + # Generate slide data with the selected language + data = slide_data_gen(topic, num_slides, ollama_model, language) progress_bar.progress(50) # Update status with another random message and dancing cursor @@ -89,7 +94,7 @@ def update_status_with_cursor(message): # Create a file name using the topic, model, and current date date_stamp = datetime.now().strftime("%Y%m%d") - sanitized_topic = topic.replace(" ", "_") # Replace spaces with underscores + sanitized_topic = topic.replace(" ", "_")[:10] # Truncate topic to 10 characters file_name = f"{sanitized_topic}_{ollama_model}_{date_stamp}.pptx" st.download_button( diff --git a/ppt_data_gen.py b/ppt_data_gen.py index bdcc2ee..f76cf35 100644 --- a/ppt_data_gen.py +++ b/ppt_data_gen.py @@ -20,60 +20,52 @@ def extract_items(input_string): return items -def slide_data_gen(topic, num_slides, model): +def slide_data_gen(topic, num_slides, model, language="English"): llm = OllamaLLM(model=model, temperature="0.4") slide_data = [] point_count = 5 - slide_data.append(extract_items(llm.invoke(f""" + # Generate title and subtitle + title_subtitle = extract_items(llm.invoke(f""" You are a text summarization and formatting specialized model that fetches relevant information - - For the topic "{topic}" suggest a presentation title and a presentation subtitle it should be returned in the format : + For the topic "{topic}" suggest a presentation title and a presentation subtitle in {language}. It should be returned in the format : << "title" | "subtitle" >> + """)) + + # Check if title and subtitle were extracted correctly + if len(title_subtitle) < 2: + raise ValueError("Failed to extract title and subtitle from the model's response.") - example : - << "Ethics in Design" | "Integrating Ethics into Design Processes" >> - """))) + slide_data.append(title_subtitle) - slide_data.append(extract_items(llm.invoke(f""" + # Generate table of contents + toc = extract_items(llm.invoke(f""" You are a text summarization and formatting specialized model that fetches relevant information - For the presentation titled "{slide_data[0][0]}" and with subtitle "{slide_data[0][1]}" for the topic "{topic}" - Write a table of contents containing the title of each slide for a {num_slides} slide presentation + Write a table of contents containing the title of each slide for a {num_slides} slide presentation in {language}. It should be of the format : << "slide1" | "slide2" | "slide3" | ... | >> - - example : - << "Introduction to Design Ethics" | "AI and the Travel Industry" | "User-Centered Design" | "Transparency and Honesty" | "Data Privacy and Security" | "Accessibility and Inclusion" | "Social Impact and Sustainability" | "Ethical AI and Automation" | "Collaboration and Professional Ethics" >> - """))) + """)) - for subtopic in slide_data[1]: + slide_data.append(toc) + for subtopic in slide_data[1]: data_to_clean = llm.invoke(f""" You are a content generation specialized model that fetches relevant information and presents it in clear concise manner - For the presentation titled "{slide_data[0][0]}" and with subtitle "{slide_data[0][1]}" for the topic "{topic}" - Write the contents for a slide with the subtopic {subtopic} + Write the contents for a slide with the subtopic {subtopic} in {language}. Write {point_count} points. Each point 10 words maximum. Make the points short, concise and to the point. """) cleaned_data = llm.invoke(f""" You are a text summarization and formatting specialized model that fetches relevant information and formats it into user specified formats - Given below is a text draft for a presentation slide containing {point_count} points , extract the {point_count} sentences and format it as : - + Given below is a text draft for a presentation slide containing {point_count} points, extract the {point_count} sentences and format it as: << "point1" | "point2" | "point3" | ... | >> - - example : - << "Foster a collaborative and inclusive work environment." | "Respect intellectual property rights and avoid plagiarism." | "Uphold professional standards and codes of ethics." | "Be open to feedback and continuous learning." >> - - -- Beginning of the text -- - {data_to_clean} - -- End of the text -- """) - + slide_data.append([subtopic] + extract_items(cleaned_data)) return slide_data