├── .env.example
├── .gitattributes
├── .gitignore
├── LICENSE
├── README.md
├── docs
├── CODE_STRUCTURE.md
└── CONTRIBUTING.md
├── myapp
├── __init__.py
├── database.py
├── flaskapp.py
├── forms.py
├── generated
│ └── .gitkeep
├── instance
│ ├── .gitkeep
│ └── site.db
├── models.py
├── static
│ ├── CSS
│ │ └── style.css
│ ├── JS
│ │ └── main.js
│ ├── Profile
│ │ └── default.jpeg
│ ├── img
│ │ ├── content-creation.png
│ │ ├── docs.png
│ │ ├── logo.png
│ │ ├── rocket.png
│ │ ├── showcase2.png
│ │ ├── step1.png
│ │ ├── step2.png
│ │ ├── step3.png
│ │ ├── step4.png
│ │ ├── step5.png
│ │ ├── step6.png
│ │ └── user.png
│ └── presentations
│ │ ├── bright_modern.pptx
│ │ ├── dark_modern.pptx
│ │ └── simple.pptx
├── templates
│ ├── generator.html
│ ├── home.html
│ ├── layout.html
│ ├── login.html
│ ├── profile.html
│ └── register.html
└── utils
│ ├── gpt_generate.py
│ └── text_pp.py
└── requirements.txt
/.env.example:
--------------------------------------------------------------------------------
1 | # Secret Key for Flask(You can decide on your own)
2 | SECRET_KEY=your_secret_key
3 |
4 | # OpenAI API Key
5 | OPENAI_API_KEY=your_openai_key
6 |
7 | # Pexels API Key
8 | PEXELS_API_KEY=your_pexels_key
9 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.html linguist-vendored
2 | *.css linguist-vendored
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | instance/site.db
3 | .env
4 | *.pyc
5 | .DS_Store
6 | __pycache__/
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Ota Hina
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | [](https://www.python.org/)
4 | 
5 | [](https://github.com/otahina/PowerPoint-Generator-Python-Project.git)
6 | [](https://github.com/otahina)
7 |
8 |
9 |
10 | ## PowerPoint Generator: Your Gateway to Effortless Presentations 🚀
11 |
12 | Dive into the ease of presentation creation with PowerPoint Generator, a smart web application crafted to automate
13 | PowerPoint presentations! 🌟
14 | This project is ripe for growth and eager for your contributions. Let's enhance its capability together! 😊
15 |
16 | ## Demo Highlights 🎬
17 |
18 | https://github.com/otahina/PowerPoint-Generator-Python-Project/assets/108225969/82d98c7a-0244-4fed-8f6b-f6c994fd69e3
19 |
20 | ## Table of Contents 📋
21 |
22 | 1. [Features](#features)
23 | 2. [Inner Structure of the Project](#inner-structure-of-the-project)
24 | 3. [How to Use](#how-to-use)
25 | 4. [How to Contribute](#how-to-contribute)
26 |
27 | ## Features
28 |
29 | * **🤖 AI-Driven Content Creation**: Utilize the power of GPT-3.5 Turbo to generate slide content based on user's input.
30 | * **😎 Intelligent Slide Generation**: The tool intelligently proposes titles and content for each slide.
31 | * **🎨 Customizable Themes**: Choose color themes for your presentation, giving it a personalized touch.
32 | * **🙂 User-Friendly Interface**: Clear instructions and an intuitive design make the PowerPoint generation process seamless and straightforward.
33 |
34 | ## Inner Structure of the project
35 |
36 | If you want to learn how to use the GPT API for creating PowerPoint presentations or understand how the project is
37 | organized, check out [CODE_STRUCTURE.md](docs/CODE_STRUCTURE.md). 🧐
38 | In this document, I explain the code and the relationships between different parts of the code.
39 |
40 | ## How to use
41 |
42 | If you want to try using this project, here is a step-by-step guide.
43 | Those who want to contribute to (which is welcome!), please check [How to Contribute](#how-to-contribute)
44 |
45 |
47 | Step 1: Star The Repo ⭐️
48 |
49 |
50 | Star the repo to start using this project 👍
51 |
52 | 
53 |
54 |
60 | Step 2: Clone It 🐑
61 |
62 |
63 | - **Using Git**
64 |
65 | Open your terminal and run the following command:
66 |
67 | ```bash
68 | git clone https://github.com/otahina/PowerPoint-Generator-Python-Project.git
69 | ```
70 |
71 | - **Using Download ZIP**
72 |
73 | 1. Go to the GitHub page of the repository.
74 | 2. Click on the green **Code** button.
75 | 3. In the dropdown menu, select **Download ZIP**.
76 |
77 |
82 | Step 3: Create a Virtual Environment 📟
83 |
84 |
85 | On Windows 🪟
86 | - Open your **Command Prompt** and navigate to your project's directory.
87 | - Run the command line by line.
88 | ```bash
89 | python -m venv venv
90 | .\venv\Scripts\activate
91 | pip install -r requirements.txt
92 | ```
93 | On macOS and Linux 🐧
94 | - Open your **Terminal** and navigate to your project's directory.
95 | - Run the command line by line.
96 | ```bash
97 | python3 -m venv venv
98 | source venv/bin/activate
99 | pip install -r requirements.txt
100 | ```
101 |
107 | Step 4: Setup API Keys 🔑
108 |
109 |
110 | ⚠️ This step is very important to make the project work!
111 | please make sure if you set up everything correctly.
112 | Instruction ▶️ [Setup the Secret Key and OpenAI Key](set-up-api-keys)
113 |
114 |
121 | Step 5: Run 🏃
122 |
123 |
124 | Navigate to `myapp` directory. Run `flaskapp.py`
125 |
126 | ```bash
127 | python3 myapp/flaskapp.py
128 | ```
129 |
130 |
138 | Step 1: Star The Repo ⭐️
139 |
140 |
141 | Star the repo to start your contribution ⭐️
142 |
143 | 
144 |
145 |
151 | Step 2: Fork it 🍴
152 |
153 |
154 | On the [GitHub page for this repository](https://github.com/otahina/PowerPoint-Generator-Python-Project.git), click on the Button "**Fork**".
155 |
156 | 
157 |
158 |
164 | Step 3: Clone it 🐑
165 |
166 |
167 | - **Method 1:** GitHub Desktop
168 |
169 | > ⚠️ **NOTE:** If you're not familiar with Git, using **GitHub Desktop Application** is a better start. If you choose this method, make sure to download it before continuing reading.
170 | >
171 | > ❗❗ Access link to download [**here**](https://desktop.github.com).
172 |
173 | - **Method 2:** Git
174 |
175 | Clone the **forked repository**. Open terminal (command prompt) and type:
176 |
177 | ```bash
178 | git clone https://github.com/
191 | Step 4: Create your feature branch 🌴
192 |
193 |
194 | Always keep your local copy of the repository updated with the original repository.
195 | Before making any changes and/or in an appropriate interval, follow the following steps:
196 |
197 | - **Method 1:** GitHub Desktop
198 |
199 | Learn more about how to create new branch [here](https://docs.github.com/en/desktop/contributing-and-collaborating-using-github-desktop/making-changes-in-a-branch/managing-branches#creating-a-branch) and how to fetch and pull origin from/to your local machine [here](https://docs.github.com/en/desktop/contributing-and-collaborating-using-github-desktop/keeping-your-local-repository-in-sync-with-github/syncing-your-branch).
200 |
201 | Learn more about how to fetch and pull origin from/to your local machine using **GitHub Desktop** [here](https://docs.github.com/en/desktop/contributing-and-collaborating-using-github-desktop/keeping-your-local-repository-in-sync-with-github/syncing-your-branch).
202 |
203 | - **Method 2:** Git
204 |
205 | Run the following commands **_carefully_** to update your local repository.
206 |
207 | ```bash
208 | # If you cloned a while ago, get the latest changes from upstream
209 | git checkout main
210 | git remote add upstream https://github.com/otahina/PowerPoint-Generator-Python-Project.git
211 | git pull upstream main
212 |
213 | # Make a feature branch (Always check your current branch is up to date before creating a new branch from it to avoid merge conflicts)
214 | git checkout -b
223 | Step 5: Pull Request 🖐️
224 |
225 |
226 | 1. Open the GitHub website and find your forked repository.
227 | 2. On your fork's GitHub page, click 'New Pull Request'.
228 | 3. Ensure the base branch is the original repository's branch you want to merge into(main branch),
229 | and the compare branch is your feature branch.
230 | 4. Click 'Create Pull Request', add a title and a brief description of your changes.
231 |
232 | Thank you for your contribution!
233 | I'll check your pull request. 😀
234 |
235 |
271 | Ota Hina
272 |
273 | Gagandeep Singh
274 |
275 |
276 | ## License 📄
277 |
278 | This project is licensed under the terms of the MIT license.
279 |
280 |
281 |
282 |
283 |
--------------------------------------------------------------------------------
/docs/CODE_STRUCTURE.md:
--------------------------------------------------------------------------------
1 | # Code Structure of the project
2 |
3 | ## Introduction
4 | This document outlines the structure and functionality of the various modules and functions utilized within this project.
5 |
6 | ## Utilizing GPT for Presentation Generation
7 |
8 | The core functionality of this application is in `flaskapp.py`, where various functions are called to handle different
9 | aspects of the application. One crucial part of this script is the endpoint defined for generating presentations based
10 | on user input:
11 |
12 | ```python
13 | @app.route('/generator', methods=['GET', 'POST'])
14 | def generate():
15 | if request.method == 'POST':
16 | number_of_slide = request.form['number_of_slide']
17 | user_text = request.form['user_text']
18 | template_choice = request.form.get('template_choice')
19 | presentation_title = request.form['presentation_title']
20 | presenter_name = request.form['presenter_name']
21 | insert_image = 'insert_image' in request.form
22 | ```
23 | In the snippet above, we define an endpoint at `/generator` which accepts both `GET` and `POST` requests.
24 | When a `POST` request is made to this endpoint, the application collects necessary information from the user through
25 | a form submission. This information includes the number of slides, text content, template choice, presentation title,
26 | presenter name, and an option to insert images.
27 |
28 | The next snippet demonstrates how we prepare the user's input for processing by the GPT model:
29 | ```python
30 | user_message = f"I want you to come up with the idea for the PowerPoint. The number of slides is {number_of_slide}. " \
31 | f"The content is: {user_text}.The title of content for each slide must be unique, " \
32 | f"and extract the most important keyword within two words for each slide. Summarize the content for each slide. "
33 | ```
34 |
35 | Rather than passing the raw user_text directly to GPT, we construct a formatted message, user_message, that encapsulates
36 | the user's request in a structured manner. This approach enables a clearer communication of the user's intent to GPT,
37 | ensuring that the generated presentation aligns with the specified requirements.
38 | This formatting is robust to variations in user input, accommodating a range of phrasing and request complexities.
39 |
40 | For instance, whether a user submits a content request as `Evolution of AI` or phrases it as `Can you make a
41 | presentation for Evolution of AI with clear examples?`, , the application is designed to interpret and process the
42 | request effectively.
43 |
44 | Keyword extraction is later utilized for retrieving relevant images using the Pexels API.
45 |
46 | In the code snippet below, `flaskapp.py` executes three functions:
47 | - `chat_development()` from `gpt_generate.py` located in `myapp/utils`, to retrieve GPT's response.
48 | - `parse_response()` from `text_pp.py` located in `myapp/utils`, to process the assistant's response and obtain the
49 | - content for the slides.
50 | - `create_ppt()` from `text_pp.py` located in `myapp/utils`, to forward the slide content, template choice,
51 | - presenter's name, and image insertion option.
52 |
53 | ```python
54 | assistant_response = chat_development(user_message)
55 | # Check the response (for debug)
56 | print(assistant_response)
57 | slides_content = parse_response(assistant_response)
58 | create_ppt(slides_content, template_choice, presentation_title, presenter_name, insert_image)
59 |
60 |
61 | >print(assistant_response) is used to check if the GPT is correctly responding or not.
62 |
63 | ```python
64 | assistant_response = chat_development(user_message)
65 | # Check the response (for debug)
66 | print(assistant_response)
67 | slides_content = parse_response(assistant_response)
68 | create_ppt(slides_content, template_choice, presentation_title, presenter_name, insert_image)
69 | ```
70 |
71 | ### `gpt_generate.py`
72 |
73 | **build_conversation**
74 |
75 | ```python
76 | def build_conversation(user_message):
77 | return [
78 | {"role": "system",
79 | "content": "You are an assistant that gives the idea for PowerPoint presentations. When answering, give the user the summarized content for each slide based on the number of slide. "
80 | "And the format of the answer must be Slide X(the number of the slide): {title of the content} /n Content: /n content with some bullet points."
81 | "Keyword: /n Give the most important keyword(within two words) that represents the slide for each one"},
82 | {"role": "user", "content": user_message}
83 | ]
84 | ```
85 |
86 | This function is defined to accept one argument: user_message, which is made in `flaskapp.py`.
87 | The content in the "system" role serves as an instruction or a **prompt** for the GPT model, helping to set the context
88 | or the scenario in which the model should operate. This way, when the model receives the user's request in the "user"
89 | role, it has a clear understanding of how to handle and respond to that request in a manner that aligns with the given
90 | instruction.
91 | In the above code, we include how GPT should answer it in the prompt, so that we can get a response in such a way that,
92 | ```
93 | Assistant Response:
94 | Slide 1: Evolution of AI
95 | Content:
96 | - Overview of AI evolution
97 | - Milestones of AI development
98 | - Impact of AI on various industries
99 | - Future prospects of AI
100 | - Ethical considerations in AI development
101 | Keyword: Evolution, AI
102 | ```
103 |
104 | **generate_assistant_message**
105 |
106 | ```python
107 | def generate_assistant_message(conversation):
108 | response = openai.ChatCompletion.create(
109 | model="gpt-3.5-turbo",
110 | messages=conversation
111 | )
112 | return response['choices'][0]['message']['content']
113 | ```
114 | A request is made to OpenAI's ChatCompletion endpoint using the `openai.ChatCompletion.create` method.
115 | The model parameter specifies the model version to use, in this case, **"gpt-3.5-turbo"**.
116 | The messages parameter passes the conversation array (made in the `chat_development`) to the OpenAI API.
117 | Finally, it extracts and returns the content of the message generated by the assistant.
118 |
119 | **chat_development**
120 |
121 | ```python
122 | conversation = build_conversation(user_message)
123 | try:
124 | assistant_message = generate_assistant_message(conversation)
125 | except openai.error.RateLimitError as e:
126 | assistant_message = "Rate limit exceeded. Sleeping for a bit..."
127 |
128 | return assistant_message
129 | ```
130 |
131 | The `try` block attempts to obtain a response from the GPT model by calling the `generate_assistant_message` function
132 | If a `RatelimitError` is encountered (likely due to exceeding the API rate limit), the `except` block is executed.
133 | In this block, a message "Rate limit exceeded. Sleeping for a bit…" is assigned to `assistant_message`.
134 |
135 | If you encounter the "Rate limit exceeded" message, it's advisable to check your OpenAI API usage on
136 | the [OPENAI API Usage](https://platform.openai.com/account/usage) page. This could potentially be a result of exhausting
137 | your API rate limits, and verifying your usage might provide insights into the cause and possible solutions.
--------------------------------------------------------------------------------
/docs/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to Automated PowerPoint Generator Project
2 |
3 | ## ※Under construction
4 |
5 | Hello! Thank you for considering contributing to PowerPoint Generator. Your help is essential for keeping this project great. We welcome contributions from everyone, and there are many ways to contribute, from improving the documentation, submitting bug reports and feature requests, or writing code.
6 |
7 | ## Table of Contents
8 |
9 | - [Getting Started](#getting-started)
10 | - [Communication](#communication)
11 | - [Coding Standards](#coding-standards)
12 | - [Environment Setup](#environment-setup)
13 | - [Testing](#testing)
14 | - [Submission Guidelines](#submission-guidelines)
15 | - [Review Process](#review-process)
16 | - [Recognition](#recognition)
17 | - [Code of Conduct](#code-of-conduct)
18 | - [Additional Resources](#additional-resources)
19 | - [Troubleshooting](#troubleshooting)
20 |
21 | ## Getting Started
22 |
23 | 1. **Star the Repo**: Star the repository to start your contribution ⭐️
24 |
25 | 2. **Fork it**: Click on the Button "**Fork**" to create a copy of the repository in your GitHub account.
26 |
27 | 3. **Clone it**: Clone the forked repository to your local machine.
28 |
29 | ```
30 | git clone https://github.com/otahina/PowerPoint-Generator-Python-Project.git
31 | ```
32 |
33 |
--------------------------------------------------------------------------------
/myapp/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/otahina/PowerPoint-Generator-Python-Project/50a8f194678d07d2e2d057a089f6b746e62c42c8/myapp/__init__.py
--------------------------------------------------------------------------------
/myapp/database.py:
--------------------------------------------------------------------------------
1 | from flask_sqlalchemy import SQLAlchemy
2 |
3 | db = SQLAlchemy()
--------------------------------------------------------------------------------
/myapp/flaskapp.py:
--------------------------------------------------------------------------------
1 | import os
2 | from flask import Flask, render_template, url_for, flash, redirect, request, send_from_directory, abort, jsonify
3 | from flask_login import LoginManager, login_user, login_required, logout_user, current_user
4 |
5 | from forms import RegistrationForm, LoginForm
6 | from flask_bcrypt import Bcrypt
7 | from database import db
8 | from models import User
9 | from utils.gpt_generate import chat_development
10 | from utils.text_pp import parse_response, create_ppt
11 | from dotenv import load_dotenv
12 |
13 | load_dotenv() # This loads the .env file
14 |
15 | app = Flask(__name__)
16 | app.config['SECRET_KEY'] = os.getenv('SECRET_KEY')
17 | app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
18 | bcrypt = Bcrypt(app)
19 | db.init_app(app)
20 |
21 |
22 | # Configure Flask-Login
23 | login_manager = LoginManager()
24 | login_manager.login_view = "login"
25 | login_manager.init_app(app)
26 |
27 |
28 | @login_manager.user_loader
29 | def load_user(user_id):
30 | return User.query.get(int(user_id))
31 |
32 |
33 | @app.route("/")
34 | @app.route("/home")
35 | def home():
36 | return render_template('home.html', user=current_user)
37 |
38 |
39 | @app.route('/profile')
40 | @login_required
41 | def profile():
42 | return render_template('profile.html')
43 |
44 |
45 | @app.route("/register", methods=['GET', 'POST'])
46 | def register():
47 | form = RegistrationForm()
48 | if form.validate_on_submit():
49 | hashed_password = bcrypt.generate_password_hash(form.password.data).decode('utf-8')
50 | user = User(username=form.username.data, email=form.email.data, password=hashed_password)
51 | db.session.add(user)
52 | db.session.commit()
53 | login_user(user, remember=True)
54 | flash('Your account has been created! You are now able to log in', 'success')
55 | return redirect(url_for('login'))
56 | return render_template('register.html', title='Register', form=form, user=current_user)
57 |
58 |
59 | @app.route("/login", methods=['GET', 'POST'])
60 | def login():
61 | # if the user is already authenticated, redirect them to home page
62 | if current_user.is_authenticated:
63 | return redirect(url_for('home'))
64 |
65 | form = LoginForm()
66 | if form.validate_on_submit():
67 | user = User.query.filter_by(email=form.email.data).first()
68 | if user and bcrypt.check_password_hash(user.password, form.password.data):
69 | login_user(user, remember=form.remember.data)
70 | return redirect(url_for('home'))
71 | else:
72 | flash('Login Unsuccessful. Please check email and password', 'danger')
73 | return render_template('login.html', title='Login', form=form, user=current_user)
74 |
75 |
76 |
77 | @app.route('/logout')
78 | @login_required
79 | def logout():
80 | logout_user()
81 | return redirect(url_for('login'))
82 |
83 |
84 | @app.route('/generator', methods=['GET', 'POST'])
85 | def generate():
86 | if request.method == 'POST':
87 | number_of_slide = request.form.get('number_of_slide')
88 | user_text = request.form.get('user_text')
89 | template_choice = request.form.get('template_choice')
90 | presentation_title = request.form.get('presentation_title')
91 | presenter_name = request.form.get('presenter_name')
92 | insert_image = 'insert_image' in request.form
93 |
94 | user_message = f"I want you to come up with the idea for the PowerPoint. The number of slides is {number_of_slide}. " \
95 | f"The content is: {user_text}.The title of content for each slide must be unique, " \
96 | f"and extract the most important keyword within two words for each slide. Summarize the content for each slide. "
97 |
98 | assistant_response = chat_development(user_message)
99 | # Check the response (for debug)
100 | print(f"Assistant Response:\n{assistant_response}")
101 | slides_content = parse_response(assistant_response)
102 | create_ppt(slides_content, template_choice, presentation_title, presenter_name, insert_image)
103 |
104 | return render_template('generator.html', title='Generate')
105 |
106 |
107 | @app.route('/download/
22 |
43 |
With the use of advanced AI, your PowerPoint presentations are generated 55 | with ease. Simply provide your desired content, and our application will handle the structuring 56 | and 57 | summarization for each slide. Say goodbye to the stress of manually creating slide content and 58 | be confident 59 | that your message is being communicated effectively.
60 |Everything you need to generate a PowerPoint presentation is readily available. 69 | With a user-friendly interface, you can input your content, select your template, and generate 70 | your presentation all in one place. The application reduces routine work, allowing you to focus 71 | on the creative aspects of your presentation.
72 |Our PowerPoint generator takes the complexity out of creating a 81 | well-structured presentation. It handles the challenging task of organizing your information 82 | into clear, concise, and engaging slides. It accepts from long content like the docmentation 83 | of your work to short description of your idea. No need to worry about information overload or 84 | slide formatting.
85 |
90 | How To Use
92 |
115 |
4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | {% if title %} 25 |
26 | {% else %} 27 |
28 | {% endif %} 29 | 30 |
69 |