ans123 commited on
Commit
747aa89
·
verified ·
1 Parent(s): 952e968

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +164 -91
app.py CHANGED
@@ -228,109 +228,182 @@ def create_pdf(proposal, output_path="proposal.pdf"):
228
 
229
  def create_slides(proposal):
230
  """Create PowerPoint slides from the proposal"""
231
- prs = Presentation()
232
-
233
- # Extract title
234
- title = extract_title(proposal)
235
-
236
- # Set up slide layouts
237
- title_slide_layout = prs.slide_layouts[0]
238
- section_title_layout = prs.slide_layouts[2]
239
- content_layout = prs.slide_layouts[1]
240
-
241
- # Add title slide
242
- title_slide = prs.slides.add_slide(title_slide_layout)
243
- title_slide.shapes.title.text = f"Project Proposal: {title}"
244
- subtitle = title_slide.placeholders[1]
245
- subtitle.text = "Professional Project Proposal"
246
-
247
- # List of sections to look for
248
- sections = [
249
- "Executive Summary",
250
- "Project Background",
251
- "Goals and Objectives",
252
- "Methodology and Approach",
253
- "Timeline",
254
- "Budget Considerations",
255
- "Expected Outcomes",
256
- "Team and Resources",
257
- "Risk Assessment",
258
- "Conclusion"
259
- ]
260
-
261
- # Extract sections using regex
262
- section_matches = re.finditer(r'\*\*\d+\.\s+(.*?)\*\*\n\n(.*?)(?=\*\*\d+\.|\Z)',
263
- proposal, re.DOTALL)
264
-
265
- for match in section_matches:
266
- section_title = match.group(1)
267
- section_content = match.group(2).strip()
268
 
269
- # Add section title slide
270
- section_slide = prs.slides.add_slide(section_title_layout)
271
- section_slide.shapes.title.text = section_title
 
272
 
273
- # Split content into paragraphs
274
- paragraphs = section_content.split('\n\n')
 
 
 
275
 
276
- # Process each paragraph
277
- current_slide = None
278
- text_frame = None
279
- paragraphs_on_slide = 0
 
 
 
 
 
 
 
 
 
280
 
281
- for para in paragraphs:
282
- para = para.strip()
283
- if not para:
284
- continue
 
 
 
285
 
286
- # Start a new slide if needed
287
- if current_slide is None or paragraphs_on_slide >= 3:
288
- current_slide = prs.slides.add_slide(content_layout)
289
- current_slide.shapes.title.text = section_title
290
- text_frame = current_slide.placeholders[1].text_frame
291
- paragraphs_on_slide = 0
292
 
293
- # Add the paragraph
294
- p = text_frame.add_paragraph()
295
 
296
- # Check if it's a bullet point list
297
- if re.match(r'^[\*\-]', para):
298
- # Process bullet points
299
- bullet_items = re.split(r'\n[\*\-]\s+', para)
300
- for item in bullet_items:
301
- item = item.strip()
302
- if item:
303
- # Remove leading bullet if present
304
- item = re.sub(r'^[\*\-]\s+', '', item)
305
- bullet_p = text_frame.add_paragraph()
306
- bullet_p.text = item
307
- bullet_p.level = 1
308
- else:
309
- p.text = para
310
 
311
- paragraphs_on_slide += 1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
312
 
313
- # Save the presentation
314
- output_path = "proposal_slides.pptx"
315
- prs.save(output_path)
316
- return output_path
 
 
 
 
 
 
 
 
 
 
 
 
317
 
318
  def process_input(description, project_type):
319
  """Process the input and generate both proposal, PDF and slides"""
320
- # Check if input is too short
321
- if len(description.strip()) < 10:
322
- return "Please provide a more detailed project description (at least 10 characters).", None, None
323
-
324
- # Generate the proposal
325
- proposal = generate_proposal(description, project_type)
326
-
327
- # Create the PDF
328
- pdf_path = create_pdf(proposal)
329
-
330
- # Create the slides
331
- ppt_path = create_slides(proposal)
332
-
333
- return proposal, pdf_path, ppt_path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334
 
335
  # Create Gradio interface
336
  def create_interface():
 
228
 
229
  def create_slides(proposal):
230
  """Create PowerPoint slides from the proposal"""
231
+ try:
232
+ prs = Presentation()
233
+
234
+ # Extract title
235
+ title = extract_title(proposal)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
 
237
+ # Set up slide layouts
238
+ title_slide_layout = prs.slide_layouts[0]
239
+ section_title_layout = prs.slide_layouts[2]
240
+ content_layout = prs.slide_layouts[1]
241
 
242
+ # Add title slide
243
+ title_slide = prs.slides.add_slide(title_slide_layout)
244
+ title_slide.shapes.title.text = f"Project Proposal: {title}"
245
+ subtitle = title_slide.placeholders[1]
246
+ subtitle.text = "Professional Project Proposal"
247
 
248
+ # List of sections to look for
249
+ sections = [
250
+ "Executive Summary",
251
+ "Project Background",
252
+ "Goals and Objectives",
253
+ "Methodology and Approach",
254
+ "Timeline",
255
+ "Budget Considerations",
256
+ "Expected Outcomes",
257
+ "Team and Resources",
258
+ "Risk Assessment",
259
+ "Conclusion"
260
+ ]
261
 
262
+ # Extract sections using regex
263
+ section_matches = re.finditer(r'\*\*\d+\.\s+(.*?)\*\*\n\n(.*?)(?=\*\*\d+\.|\Z)',
264
+ proposal, re.DOTALL)
265
+
266
+ for match in section_matches:
267
+ section_title = match.group(1)
268
+ section_content = match.group(2).strip()
269
 
270
+ # Add section title slide
271
+ section_slide = prs.slides.add_slide(section_title_layout)
272
+ section_slide.shapes.title.text = section_title
 
 
 
273
 
274
+ # Split content into paragraphs
275
+ paragraphs = section_content.split('\n\n')
276
 
277
+ # Process each paragraph
278
+ current_slide = None
279
+ text_frame = None
280
+ paragraphs_on_slide = 0
 
 
 
 
 
 
 
 
 
 
281
 
282
+ for para in paragraphs:
283
+ para = para.strip()
284
+ if not para:
285
+ continue
286
+
287
+ # Start a new slide if needed
288
+ if current_slide is None or paragraphs_on_slide >= 3:
289
+ current_slide = prs.slides.add_slide(content_layout)
290
+ current_slide.shapes.title.text = section_title
291
+ text_frame = current_slide.placeholders[1].text_frame
292
+ paragraphs_on_slide = 0
293
+
294
+ # Add the paragraph
295
+ p = text_frame.add_paragraph()
296
+
297
+ # Check if it's a bullet point list
298
+ if re.match(r'^[\*\-]', para):
299
+ # Process bullet points
300
+ bullet_items = re.split(r'\n[\*\-]\s+', para)
301
+ for item in bullet_items:
302
+ item = item.strip()
303
+ if item:
304
+ # Remove leading bullet if present
305
+ item = re.sub(r'^[\*\-]\s+', '', item)
306
+ bullet_p = text_frame.add_paragraph()
307
+ bullet_p.text = item
308
+ bullet_p.level = 1
309
+ else:
310
+ p.text = para
311
+
312
+ paragraphs_on_slide += 1
313
+
314
+ # Save the presentation
315
+ output_path = "proposal_slides.pptx"
316
+ prs.save(output_path)
317
+ return output_path
318
 
319
+ except Exception as e:
320
+ print(f"Error creating PowerPoint: {e}")
321
+ # Create a simple error presentation
322
+ try:
323
+ prs = Presentation()
324
+ slide = prs.slides.add_slide(prs.slide_layouts[0])
325
+ slide.shapes.title.text = "Error Creating Presentation"
326
+ subtitle = slide.placeholders[1]
327
+ subtitle.text = f"An error occurred: {str(e)}\nPlease try again with a different project description."
328
+
329
+ output_path = "proposal_slides.pptx"
330
+ prs.save(output_path)
331
+ except:
332
+ # If even the error presentation fails, return a default path
333
+ pass
334
+ return output_path
335
 
336
  def process_input(description, project_type):
337
  """Process the input and generate both proposal, PDF and slides"""
338
+ try:
339
+ # Check if input is too short
340
+ if len(description.strip()) < 10:
341
+ return "Please provide a more detailed project description (at least 10 characters).", None, None
342
+
343
+ # Map project type to specific type value
344
+ type_value = None
345
+ if project_type == "SaaS Performance Platform":
346
+ type_value = "saas_performance"
347
+
348
+ # Generate the proposal
349
+ proposal = generate_proposal(description, type_value)
350
+
351
+ # Create a basic PDF without any custom styles - fallback approach
352
+ try:
353
+ from reportlab.lib.pagesizes import letter
354
+ from reportlab.pdfgen import canvas
355
+
356
+ # Basic PDF generation using canvas directly
357
+ c = canvas.Canvas("proposal.pdf", pagesize=letter)
358
+ width, height = letter
359
+
360
+ # Title
361
+ c.setFont("Helvetica-Bold", 16)
362
+ c.drawCentredString(width/2, height-50, "Project Proposal")
363
+
364
+ # Simple text rendering
365
+ c.setFont("Helvetica", 10)
366
+ y = height - 80
367
+ line_height = 14
368
+
369
+ lines = proposal.split('\n')
370
+ for line in lines:
371
+ # Check for page break
372
+ if y < 50:
373
+ c.showPage()
374
+ y = height - 50
375
+
376
+ # Check if it's a header (starts with **)
377
+ if line.startswith('**'):
378
+ c.setFont("Helvetica-Bold", 12)
379
+ # Remove ** markers
380
+ line = line.replace('**', '')
381
+ else:
382
+ c.setFont("Helvetica", 10)
383
+
384
+ # Draw the line
385
+ if line.strip():
386
+ c.drawString(50, y, line)
387
+ y -= line_height
388
+
389
+ c.save()
390
+ pdf_path = "proposal.pdf"
391
+ except Exception as pdf_error:
392
+ print(f"Error creating PDF: {pdf_error}")
393
+ pdf_path = None
394
+
395
+ # Create the slides
396
+ try:
397
+ ppt_path = create_slides(proposal)
398
+ except Exception as ppt_error:
399
+ print(f"Error creating slides: {ppt_error}")
400
+ ppt_path = None
401
+
402
+ return proposal, pdf_path, ppt_path
403
+ except Exception as e:
404
+ error_message = f"An error occurred: {str(e)}\nPlease try again with a different project description."
405
+ print(f"Error in process_input: {e}")
406
+ return error_message, None, None
407
 
408
  # Create Gradio interface
409
  def create_interface():