pptmaker_v2 / app.py
yashm's picture
Update app.py
50543ae verified
Raw History Blame Contribute Delete
10.8 kB
import streamlit as st
from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.dml.color import RGBColor
from collections import OrderedDict
import os
# Define templates for different presentation types
templates = {
'Research Presentation': [
{"title": "Introduction", "content": ["Background", "Problem Statement", "Purpose"]},
{"title": "Literature Review", "content": ["Previous Studies", "Key Theories", "Gaps in Research"]},
{"title": "Methodology", "content": ["Research Design", "Data Collection", "Data Analysis"]},
{"title": "Results", "content": ["Data Presentation", "Statistical Analysis", "Interpretation"]},
{"title": "Discussion and Conclusion", "content": ["Summary of Findings", "Implications", "Recommendations for Future Research"]}
],
'Proposal Defense': [
{"title": "Introduction", "content": ["Background Context", "Problem Statement", "Research Questions", "Purpose and Significance"]},
{"title": "Literature Review", "content": ["Key Theories and Concepts", "Current State of Research", "Gaps in Literature"]},
{"title": "Research Design and Methodology", "content": ["Research Framework", "Data Collection Methods", "Analysis Plan", "Ethical Considerations"]},
{"title": "Expected Results", "content": ["Predicted Outcomes", "Potential Implications", "Limitations"]},
{"title": "Timeline", "content": ["Research Phases", "Key Milestones", "Completion Dates"]},
{"title": "Budget", "content": ["Estimated Costs", "Resource Allocation", "Justification"]},
{"title": "Conclusion", "content": ["Summary of Key Points", "Reiteration of Research Importance", "Next Steps"]},
{"title": "Questions and Discussion", "content": ["Anticipated Questions", "Potential Answers", "Further Clarifications"]}
],
'Project Update': [
{"title": "Overview", "content": ["Project Background", "Current Status", "Objectives"]},
{"title": "Progress", "content": ["Tasks Completed", "Milestones Achieved", "Challenges Faced"]},
{"title": "Next Steps", "content": ["Upcoming Tasks", "Milestones", "Deadlines"]},
{"title": "Risks and Issues", "content": ["Current Risks", "Mitigation Strategies", "Dependencies"]},
{"title": "Summary", "content": ["Key Takeaways", "Action Items", "Follow-up Dates"]}
],
'Thesis Defense': [
{"title": "Introduction", "content": ["Research Topic", "Research Questions", "Hypotheses"]},
{"title": "Methodology", "content": ["Research Design", "Data Collection Methods", "Data Analysis Procedures"]},
{"title": "Results", "content": ["Key Findings", "Data Interpretation", "Implications"]},
{"title": "Conclusion", "content": ["Summary of Findings", "Research Contributions", "Future Research"]},
{"title": "Questions and Discussion", "content": ["Common Questions", "Clarifications", "Further Explanations"]}
],
'Business Pitch': [
{"title": "Company Overview", "content": ["Company Background", "Mission and Vision", "Team"]},
{"title": "Market Analysis", "content": ["Industry Overview", "Target Market", "Competitor Analysis"]},
{"title": "Product/Service", "content": ["Product Description", "Unique Selling Points", "Value Proposition"]},
{"title": "Business Model", "content": ["Revenue Streams", "Pricing Strategy", "Sales Channels"]},
{"title": "Financial Plan", "content": ["Revenue Projections", "Cost Structure", "Funding Requirements"]},
{"title": "Conclusion", "content": ["Summary", "Call to Action", "Contact Information"]}
]
}
# Define themes
themes = {
"Corporate": {"font": "Arial", "font_size": 20, "color": "0000FF"},
"Casual": {"font": "Comic Sans MS", "font_size": 18, "color": "FF5733"},
# Add more themes as needed
}
# Function to create PowerPoint presentation based on user inputs
def create_presentation(title_slide_info, sections, theme_name, image_sections):
prs = Presentation()
# Apply theme
theme = themes[theme_name]
# Add a title slide
title_slide_layout = prs.slide_layouts[0]
title_slide = prs.slides.add_slide(title_slide_layout)
title = title_slide.shapes.title
subtitle = title_slide.placeholders[1]
title.text = title_slide_info['title']
subtitle.text = f"{title_slide_info['subtitle']}\n{title_slide_info['institution']}\n{title_slide_info['date']}"
# Add content slides based on sections and subsections
for section_title, section_info in sections.items():
for subsection_title, bullet_points in section_info.items():
slide = add_slide_with_layout(prs, 1, f"{section_title} - {subsection_title}", bullet_points)
# Check if this is the subsection where the image should be added
if section_title in image_sections and image_sections[section_title] == subsection_title:
image_path = os.path.join(os.getcwd(), uploaded_images[section_title].name)
with open(image_path, "wb") as f:
f.write(uploaded_images[section_title].getbuffer())
add_image_to_slide(slide, image_path)
# Save the presentation
filename = 'custom_presentation.pptx'
prs.save(filename)
return filename
# Function to style text
def style_text(paragraph, font_size, font_color):
run = paragraph.add_run()
font = run.font
font.size = Pt(font_size)
font.color.rgb = RGBColor.from_string(font_color)
# Function to add slide with custom layout
def add_slide_with_layout(prs, layout_index, title_text, content_points):
slide_layout = prs.slide_layouts[layout_index]
slide = prs.slides.add_slide(slide_layout)
title_placeholder = slide.shapes.title
body_placeholder = slide.placeholders[1]
title_placeholder.text = title_text
for point in content_points:
p = body_placeholder.text_frame.add_paragraph()
p.text = point
return slide
# Function to add image to a slide
def add_image_to_slide(slide, image_path):
slide.shapes.add_picture(image_path, Inches(1), Inches(1), width=Inches(5), height=Inches(3))
# Function to handle dynamic section addition
def add_new_section(section_counter):
new_section_title = f"Section {section_counter}"
st.session_state.sections[new_section_title] = OrderedDict({"Subsection": []})
st.session_state.section_counter += 1
# Function to handle dynamic subsection addition
def add_new_subsection(section_title):
new_subsection_title = f"Subsection {len(st.session_state.sections[section_title]) + 1}"
if new_subsection_title not in st.session_state.sections[section_title]:
st.session_state.sections[section_title][new_subsection_title] = []
# Streamlit UI setup
st.sidebar.title('Presentation Settings')
presentation_type = st.sidebar.selectbox('Select Presentation Type', list(templates.keys()))
# Reset sections when a new presentation type is selected
if 'last_presentation_type' not in st.session_state or st.session_state.last_presentation_type != presentation_type:
st.session_state.sections = OrderedDict()
st.session_state.section_counter = 1 # Counter for unique section names
for section in templates[presentation_type]:
st.session_state.sections[section['title']] = OrderedDict((content, []) for content in section['content'])
st.session_state.last_presentation_type = presentation_type # Update the last selected type
# Title slide configuration with expander
with st.sidebar.expander("Title Slide Options", expanded=False):
title_slide_info = {
'title': st.text_input("Title", "Your Presentation Title"),
'subtitle': st.text_input("Subtitle", "Your Name"),
'institution': st.text_input("Institution", "Your Institution"),
'date': st.text_input("Date", "Presentation Date")
}
# Theme selection
theme_name = st.sidebar.selectbox("Select Theme", list(themes.keys()))
# Option to add more sections dynamically
if st.sidebar.button("Add More Section"):
add_new_section(st.session_state.section_counter)
# Main page for sections and subsections configuration
st.title('Customize Your Presentation')
# Dictionary to keep track of which section/subsection should have an image
image_sections = {}
for section_title, subsections in list(st.session_state.sections.items()):
with st.expander(f"Section: {section_title}"):
# Edit section title
new_section_title = st.text_input(f"Edit Section Title:", value=section_title, key=f"section_title_{section_title}")
if new_section_title != section_title:
st.session_state.sections[new_section_title] = st.session_state.sections.pop(section_title)
section_title = new_section_title
for subsection_title, bullet_points in list(subsections.items()):
bullets = st.text_area(f"Subsection: {subsection_title} (Enter bullet points separated by newlines)",
value="\n".join(bullet_points),
height=150,
key=f"{section_title}_{subsection_title}").split('\n')
st.session_state.sections[section_title][subsection_title] = bullets
# Let the user choose if this is the subsection where the image should be added
add_image_here = st.checkbox(f"Add image to {subsection_title}?", key=f"checkbox_{section_title}_{subsection_title}")
if add_image_here:
image_sections[section_title] = subsection_title
# Add new subsection to the current section
if st.button(f"Add Subsection to {section_title}", key=f"add_subsection_{section_title}"):
add_new_subsection(section_title)
# Image upload for each section (images should only be uploaded if selected)
uploaded_images = {}
for section_title in st.session_state.sections:
if section_title in image_sections:
uploaded_image = st.file_uploader(f"Upload image for {section_title} (applied to subsection '{image_sections[section_title]}')", type=["png", "jpg", "jpeg"], key=f"image_{section_title}")
if uploaded_image is not None:
uploaded_images[section_title] = uploaded_image
# Generate and download presentation
if st.button('Generate Presentation'):
file_path = create_presentation(title_slide_info, st.session_state.sections, theme_name, image_sections)
with open(file_path, "rb") as file:
st.download_button(
label="Download Presentation",
data=file,
file_name='custom_presentation.pptx',
mime="application/vnd.openxmlformats-officedocument.presentationml.presentation"
)