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" )