Spaces:
Sleeping
Sleeping
| import os | |
| import gradio as gr | |
| from groq import Groq | |
| import reportlab.lib.pagesizes as pagesizes | |
| from reportlab.pdfgen import canvas | |
| from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle | |
| from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer | |
| from reportlab.lib.units import inch | |
| from io import BytesIO | |
| import docx | |
| from docx.shared import Pt, Inches | |
| from docx.enum.text import WD_ALIGN_PARAGRAPH | |
| import time | |
| import tempfile | |
| # Initialize the Groq client | |
| GROQ_API_KEY = os.getenv('GROQ_API_KEY') | |
| GROQ_MODEL = "llama-3.3-70b-versatile" | |
| client = Groq(api_key=GROQ_API_KEY) | |
| # Custom CSS for styling | |
| custom_css = """ | |
| .generate-btn { | |
| margin: 0 auto !important; | |
| display: block !important; | |
| } | |
| .output-box { | |
| background-color: black !important; | |
| border-radius: 8px !important; | |
| padding: 20px !important; | |
| box-shadow: 0 2px 5px rgba(0,0,0,0.1) !important; | |
| margin-top: 20px !important; | |
| color: white !important; | |
| } | |
| .app-header { | |
| text-align: center !important; | |
| margin-bottom: 20px !important; | |
| } | |
| /* Fix text visibility */ | |
| .gradio-container input[type=text], | |
| .gradio-container textarea { | |
| color: #000000 !important; | |
| background-color: #ffffff !important; | |
| border: 1px solid #cccccc !important; | |
| } | |
| /* Make sure placeholder text is visible but distinct */ | |
| .gradio-container input::placeholder, | |
| .gradio-container textarea::placeholder { | |
| color: #888888 !important; | |
| opacity: 1; | |
| } | |
| /* Ensure the output text is clearly visible */ | |
| .output-box, .markdown-text { | |
| color: #000000 !important; | |
| } | |
| /* Loading indicator styling */ | |
| .loading-indicator { | |
| text-align: center; | |
| padding: 20px; | |
| font-style: italic; | |
| color: #555; | |
| } | |
| """ | |
| def generate_opt_framework(topic): | |
| """Generate an OPT framework for the given topic using Groq API""" | |
| if not topic: | |
| return "Please enter a topic to generate an OPT framework." | |
| prompt = f""" | |
| Generate an OPT (Objectives, Products, Tasks) framework for: {topic} | |
| Format your response as follows: | |
| # OPT Framework for: {topic} | |
| ## Objectives | |
| Clear, high-level goals that define what success looks like for this topic/project. | |
| ## Products | |
| Specific, tangible deliverables that will help achieve the objectives. | |
| ## Tasks | |
| Detailed, actionable steps required to create each product. | |
| Make your response comprehensive but practical, with clear language and realistic items. | |
| """ | |
| try: | |
| chat_completion = client.chat.completions.create( | |
| model=GROQ_MODEL, | |
| messages=[ | |
| {"role": "system", "content": "You are an expert at creating OPT frameworks to help with project planning and goal setting."}, | |
| {"role": "user", "content": prompt} | |
| ], | |
| temperature=0.7, | |
| max_tokens=1500 | |
| ) | |
| framework = chat_completion.choices[0].message.content | |
| return framework | |
| except Exception as e: | |
| return f"Error generating OPT framework: {str(e)}" | |
| def generate_automation_analysis(opt_content): | |
| """Generate automation analysis for the OPT framework tasks""" | |
| if not opt_content or "Tasks" not in opt_content: | |
| return "No tasks found to analyze for automation." | |
| prompt = f""" | |
| Analyze the following OPT framework and identify tasks that can be automated: | |
| {opt_content} | |
| For each task that can be automated: | |
| 1. Identify the task | |
| 2. Explain why it can be automated | |
| 3. Provide a step-by-step beginner's guide to automating this task | |
| 4. Suggest tools or software that could help with the automation | |
| Format your response as a comprehensive automation analysis with clear sections and explanations. | |
| """ | |
| try: | |
| chat_completion = client.chat.completions.create( | |
| model=GROQ_MODEL, | |
| messages=[ | |
| {"role": "system", "content": "You are an expert at identifying tasks that can be automated and providing guidance on automation techniques."}, | |
| {"role": "user", "content": prompt} | |
| ], | |
| temperature=0.7, | |
| max_tokens=2000 | |
| ) | |
| analysis = chat_completion.choices[0].message.content | |
| return analysis | |
| except Exception as e: | |
| return f"Error generating automation analysis: {str(e)}" | |
| def handle_topic_submission(topic): | |
| """Handle topic submission from text input""" | |
| opt_framework = generate_opt_framework(topic) | |
| return opt_framework, gr.update(visible=True), gr.update(visible=True) | |
| def handle_example_topic(example_topic): | |
| """Handle clicking on example topic buttons""" | |
| opt_framework = generate_opt_framework(example_topic) | |
| return example_topic, opt_framework, gr.update(visible=True), gr.update(visible=True) | |
| def handle_regenerate(topic): | |
| """Handle regeneration request""" | |
| if not topic: | |
| return "Please enter a topic first." | |
| opt_framework = generate_opt_framework(topic) | |
| return opt_framework | |
| def analyze_with_progress(opt_content, progress=gr.Progress()): | |
| """Handle request for automation analysis with progress indication""" | |
| # Initial loading state | |
| progress(0, desc="Preparing analysis...") | |
| yield "Analyzing tasks for automation potential. Please wait...", gr.update(visible=True) | |
| # Simulate progress steps to provide visual feedback | |
| progress(0.3, desc="Identifying tasks...") | |
| time.sleep(0.5) # Just to show progress visually | |
| progress(0.6, desc="Evaluating automation potential...") | |
| time.sleep(0.5) | |
| progress(0.8, desc="Generating step-by-step guides...") | |
| time.sleep(0.5) | |
| # Generate the actual analysis | |
| analysis = generate_automation_analysis(opt_content) | |
| # Complete the progress and return results | |
| progress(1.0, desc="Complete!") | |
| yield analysis, gr.update(visible=True) | |
| def create_pdf_file(content, title): | |
| """Create a PDF document from the content and save to temp file""" | |
| # Create a temporary file | |
| temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.pdf') | |
| temp_filename = temp_file.name | |
| temp_file.close() | |
| doc = SimpleDocTemplate(temp_filename, pagesize=pagesizes.letter) | |
| styles = getSampleStyleSheet() | |
| story = [] | |
| # Add custom title style | |
| title_style = ParagraphStyle( | |
| 'TitleStyle', | |
| parent=styles['Heading1'], | |
| fontSize=16, | |
| alignment=1, | |
| spaceAfter=0.5*inch | |
| ) | |
| # Add title | |
| story.append(Paragraph(f"OPT Framework and Automation Analysis: {title}", title_style)) | |
| story.append(Spacer(1, 0.25*inch)) | |
| # Process content | |
| paragraphs = content.split('\n') | |
| for para in paragraphs: | |
| if para.startswith('# '): | |
| story.append(Paragraph(para[2:], styles['Heading1'])) | |
| elif para.startswith('## '): | |
| story.append(Paragraph(para[3:], styles['Heading2'])) | |
| elif para.startswith('### '): | |
| story.append(Paragraph(para[4:], styles['Heading3'])) | |
| elif para.strip(): | |
| story.append(Paragraph(para, styles['Normal'])) | |
| else: | |
| story.append(Spacer(1, 0.1*inch)) | |
| doc.build(story) | |
| return temp_filename | |
| def create_docx_file(content, title): | |
| """Create a DOCX document from the content and save to temp file""" | |
| # Create a temporary file | |
| temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.docx') | |
| temp_filename = temp_file.name | |
| temp_file.close() | |
| doc = docx.Document() | |
| # Add title | |
| title_para = doc.add_paragraph() | |
| title_run = title_para.add_run(f"OPT Framework and Automation Analysis: {title}") | |
| title_run.font.size = Pt(18) | |
| title_run.font.bold = True | |
| title_para.alignment = WD_ALIGN_PARAGRAPH.CENTER | |
| # Process content | |
| paragraphs = content.split('\n') | |
| for para in paragraphs: | |
| if para.startswith('# '): | |
| p = doc.add_paragraph() | |
| run = p.add_run(para[2:]) | |
| run.font.size = Pt(16) | |
| run.font.bold = True | |
| elif para.startswith('## '): | |
| p = doc.add_paragraph() | |
| run = p.add_run(para[3:]) | |
| run.font.size = Pt(14) | |
| run.font.bold = True | |
| elif para.startswith('### '): | |
| p = doc.add_paragraph() | |
| run = p.add_run(para[4:]) | |
| run.font.size = Pt(12) | |
| run.font.bold = True | |
| elif para.strip(): | |
| doc.add_paragraph(para) | |
| doc.save(temp_filename) | |
| return temp_filename | |
| def download_pdf(opt_content, analysis_content, topic): | |
| """Create PDF for download""" | |
| combined_content = f"{opt_content}\n\n# Automation Analysis\n\n{analysis_content}" | |
| pdf_path = create_pdf_file(combined_content, topic) | |
| return pdf_path | |
| def download_docx(opt_content, analysis_content, topic): | |
| """Create DOCX for download""" | |
| combined_content = f"{opt_content}\n\n# Automation Analysis\n\n{analysis_content}" | |
| docx_path = create_docx_file(combined_content, topic) | |
| return docx_path | |
| # Create the Gradio interface | |
| with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue"), css=custom_css) as app: | |
| # App header | |
| gr.Markdown("# OPT Framework Generator", elem_classes=["app-header"]) | |
| # What is OPT Framework (unhidden) | |
| gr.Markdown(""" | |
| ## What is the OPT Framework? | |
| The OPT Framework is a structured approach to planning that breaks down goals into three key components: | |
| - **Objectives**: High-level goals that define what success looks like | |
| - **Products**: Tangible deliverables that help achieve the objectives | |
| - **Tasks**: Specific, actionable steps required to create each product | |
| This framework brings clarity, focus, and momentum to any project, making execution more purposeful and efficient. | |
| """) | |
| # How to use section (collapsible) | |
| with gr.Accordion("How to Use This App", open=False): | |
| gr.Markdown(""" | |
| 1. Enter your topic or project in the text box, or click one of the example buttons | |
| 2. Click "Generate OPT Framework" to create your custom framework | |
| 3. Click "Generate Another Version" if you want alternative options | |
| 4. Analyze tasks for automation potential | |
| 5. Download your complete analysis as PDF or DOCX for future reference | |
| This tool helps you organize any project or goal into a clear, actionable plan with insights on which tasks can be automated. | |
| (PS: Please wait for a few seconds before downloading the report) | |
| """) | |
| # Input section with text box and examples side by side | |
| with gr.Row(): | |
| with gr.Column(scale=7): # 70% width for text input | |
| topic_input = gr.Textbox( | |
| label="Enter your project/goal", | |
| placeholder="Enter anything you can think of... a project, goal, business idea, personal challenge, etc.", | |
| lines=3 | |
| ) | |
| submit_btn = gr.Button("Generate OPT Framework", variant="primary", elem_classes=["generate-btn"]) | |
| with gr.Column(scale=3): # 30% width for examples | |
| gr.Markdown("### Quick Examples:") | |
| example_btns = [ | |
| gr.Button("Mobile App Development"), | |
| gr.Button("Content Marketing Strategy"), | |
| gr.Button("Home Renovation Project"), | |
| gr.Button("Personal Fitness Goal"), | |
| gr.Button("Writing a Novel") | |
| ] | |
| # Output section with custom styling | |
| opt_output = gr.Markdown(elem_classes=["output-box"], label="Generated OPT Framework") | |
| with gr.Row(visible=False) as action_row: | |
| regenerate_btn = gr.Button("Generate Another Version") | |
| analyze_btn = gr.Button("Analyze Tasks for Automation") | |
| # Loading indicator and analysis output | |
| analysis_output = gr.Markdown(elem_classes=["output-box"], label="Automation Analysis", visible=False) | |
| with gr.Row(visible=False) as download_container: | |
| download_btn = gr.Button("Download Report (Please wait for a few seconds before downloading)") | |
| with gr.Row(visible=False) as download_format_row: | |
| time.sleep(1) | |
| pdf_btn = gr.Button("PDF") | |
| docx_btn = gr.Button("DOCX") | |
| # Set up event handlers | |
| submit_btn.click( | |
| handle_topic_submission, | |
| inputs=[topic_input], | |
| outputs=[opt_output, action_row, analyze_btn] | |
| ) | |
| for btn in example_btns: | |
| btn.click( | |
| handle_example_topic, | |
| inputs=[btn], | |
| outputs=[topic_input, opt_output, action_row, analyze_btn] | |
| ) | |
| regenerate_btn.click( | |
| handle_regenerate, | |
| inputs=[topic_input], | |
| outputs=[opt_output] | |
| ) | |
| # Modified to use streaming output for better loading feedback | |
| analyze_btn.click( | |
| analyze_with_progress, | |
| inputs=[opt_output], | |
| outputs=[analysis_output, download_container], | |
| show_progress=True | |
| ) | |
| download_btn.click( | |
| lambda: gr.update(visible=True), | |
| outputs=[download_format_row] | |
| ) | |
| pdf_btn.click( | |
| download_pdf, | |
| inputs=[opt_output, analysis_output, topic_input], | |
| outputs=[gr.File(label="Download PDF")] | |
| ) | |
| docx_btn.click( | |
| download_docx, | |
| inputs=[opt_output, analysis_output, topic_input], | |
| outputs=[gr.File(label="Download DOCX")] | |
| ) | |
| if __name__ == "__main__": | |
| app.launch() |