Spaces:
Runtime error
Runtime error
Delete app/DocumentGeneration/document_helpers.py
Browse files
app/DocumentGeneration/document_helpers.py
DELETED
|
@@ -1,159 +0,0 @@
|
|
| 1 |
-
# Document Helper Functions
|
| 2 |
-
# Contains helper functions like filter_empty_sections(), extract_business_name_from_content(), etc.
|
| 3 |
-
|
| 4 |
-
import re
|
| 5 |
-
import os
|
| 6 |
-
import sys
|
| 7 |
-
from typing import List, Dict, Any
|
| 8 |
-
|
| 9 |
-
# Add the parent directory to sys.path to import from models.py
|
| 10 |
-
sys.path.append(os.path.dirname(os.path.dirname(__file__)))
|
| 11 |
-
from models import ExportSection
|
| 12 |
-
|
| 13 |
-
def extract_business_name_from_content(sections: List[ExportSection]) -> str:
|
| 14 |
-
"""Extract business name from markdown content"""
|
| 15 |
-
for section in sections:
|
| 16 |
-
if section.content:
|
| 17 |
-
lines = section.content.split('\n')
|
| 18 |
-
for i, line in enumerate(lines):
|
| 19 |
-
line = line.strip()
|
| 20 |
-
# Look for "Business Name:" pattern
|
| 21 |
-
if '**Business Name:**' in line or 'Business Name:' in line:
|
| 22 |
-
# Extract the business name from the line
|
| 23 |
-
if '**Business Name:**' in line:
|
| 24 |
-
business_name = line.split('**Business Name:**')[1].strip()
|
| 25 |
-
else:
|
| 26 |
-
business_name = line.split('Business Name:')[1].strip()
|
| 27 |
-
|
| 28 |
-
# Keep markdown formatting - don't strip ** symbols
|
| 29 |
-
# business_name = re.sub(r'[*_`~]', '', business_name)
|
| 30 |
-
business_name = business_name.strip()
|
| 31 |
-
|
| 32 |
-
if business_name:
|
| 33 |
-
return business_name
|
| 34 |
-
|
| 35 |
-
# If not found on same line, check next line
|
| 36 |
-
if i + 1 < len(lines):
|
| 37 |
-
next_line = lines[i + 1].strip()
|
| 38 |
-
business_name = next_line # Keep ** symbols
|
| 39 |
-
business_name = business_name.strip()
|
| 40 |
-
if business_name:
|
| 41 |
-
return business_name
|
| 42 |
-
|
| 43 |
-
return None
|
| 44 |
-
|
| 45 |
-
def extract_subheadings(content: str) -> List[str]:
|
| 46 |
-
"""Extract subheadings from markdown content"""
|
| 47 |
-
subheadings = []
|
| 48 |
-
lines = content.split('\n')
|
| 49 |
-
|
| 50 |
-
for line in lines:
|
| 51 |
-
line = line.strip()
|
| 52 |
-
# Look for various markdown header patterns
|
| 53 |
-
if (line.startswith('##') and not line.startswith('###')) or \
|
| 54 |
-
line.startswith('**') and line.endswith('**') and len(line) > 4:
|
| 55 |
-
# Remove markdown formatting and clean up
|
| 56 |
-
if line.startswith('##'):
|
| 57 |
-
subheading = re.sub(r'^##+\s*', '', line)
|
| 58 |
-
else:
|
| 59 |
-
# Handle bold text that might be headings - keep ** symbols
|
| 60 |
-
subheading = line # Keep ** symbols instead of stripping them
|
| 61 |
-
|
| 62 |
-
# subheading = re.sub(r'[*_`~]', '', subheading) # Commented out to preserve ** symbols
|
| 63 |
-
if subheading.strip() and len(subheading.strip()) > 3: # Avoid very short headings
|
| 64 |
-
subheadings.append(subheading.strip())
|
| 65 |
-
|
| 66 |
-
return subheadings
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
def filter_empty_sections(sections: List[ExportSection]) -> List[ExportSection]:
|
| 79 |
-
"""Filter out sections with no content to prevent empty pages"""
|
| 80 |
-
filtered_sections = []
|
| 81 |
-
|
| 82 |
-
for section in sections:
|
| 83 |
-
if section.content and section.content.strip():
|
| 84 |
-
# Clean the content to check if it's actually meaningful
|
| 85 |
-
cleaned_content = section.content # No clean_text_for_pdf import, so use raw content
|
| 86 |
-
if cleaned_content and len(cleaned_content.strip()) > 10: # At least 10 characters
|
| 87 |
-
filtered_sections.append(section)
|
| 88 |
-
# logging.info(f"Section '{section.title}' passed filtering with {len(cleaned_content)} characters")
|
| 89 |
-
else:
|
| 90 |
-
# logging.info(f"Section '{section.title}' filtered out - content too short: {len(cleaned_content) if cleaned_content else 0} chars")
|
| 91 |
-
pass
|
| 92 |
-
else:
|
| 93 |
-
# logging.info(f"Section '{section.title}' filtered out - no content")
|
| 94 |
-
pass
|
| 95 |
-
|
| 96 |
-
# logging.info(f"Filtered sections: {len(filtered_sections)} out of {len(sections)} total")
|
| 97 |
-
return filtered_sections
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
def remove_duplicate_headings(content: str) -> str:
|
| 101 |
-
"""Remove duplicate headings from content"""
|
| 102 |
-
if not content:
|
| 103 |
-
return content
|
| 104 |
-
|
| 105 |
-
lines = content.split('\n')
|
| 106 |
-
cleaned_lines = []
|
| 107 |
-
seen_headings = set()
|
| 108 |
-
|
| 109 |
-
for line in lines:
|
| 110 |
-
line = line.strip()
|
| 111 |
-
if not line:
|
| 112 |
-
cleaned_lines.append('')
|
| 113 |
-
continue
|
| 114 |
-
|
| 115 |
-
# Check if this is any type of heading
|
| 116 |
-
is_heading = False
|
| 117 |
-
heading_text = ""
|
| 118 |
-
|
| 119 |
-
# Markdown headings (# ## ### etc.)
|
| 120 |
-
if line.startswith('#'):
|
| 121 |
-
heading_text = re.sub(r'^#+\s*', '', line).strip()
|
| 122 |
-
is_heading = True
|
| 123 |
-
|
| 124 |
-
# Bold headings (**text**)
|
| 125 |
-
elif line.startswith('**') and line.endswith('**') and len(line) > 4:
|
| 126 |
-
heading_text = line[2:-2].strip() # Remove ** symbols
|
| 127 |
-
is_heading = True
|
| 128 |
-
|
| 129 |
-
# Check for numbered headings (e.g., "8.1 Management Team")
|
| 130 |
-
elif re.match(r'^\d+\.?\d*\s+', line):
|
| 131 |
-
heading_text = re.sub(r'^\d+\.?\d*\s+', '', line).strip()
|
| 132 |
-
is_heading = True
|
| 133 |
-
|
| 134 |
-
if is_heading and heading_text:
|
| 135 |
-
# Normalize the heading text for comparison
|
| 136 |
-
normalized_text = heading_text.lower().strip()
|
| 137 |
-
|
| 138 |
-
# Also check for variations with "and" vs "&"
|
| 139 |
-
variations = [
|
| 140 |
-
normalized_text,
|
| 141 |
-
normalized_text.replace(' & ', ' and '),
|
| 142 |
-
normalized_text.replace(' and ', ' & '),
|
| 143 |
-
normalized_text.replace('&', 'and'),
|
| 144 |
-
normalized_text.replace('and', '&')
|
| 145 |
-
]
|
| 146 |
-
|
| 147 |
-
# Check if any variation has been seen before
|
| 148 |
-
is_duplicate = any(var in seen_headings for var in variations)
|
| 149 |
-
|
| 150 |
-
if not is_duplicate:
|
| 151 |
-
# Add all variations to seen set
|
| 152 |
-
for var in variations:
|
| 153 |
-
seen_headings.add(var)
|
| 154 |
-
cleaned_lines.append(line)
|
| 155 |
-
# Skip duplicate headings
|
| 156 |
-
else:
|
| 157 |
-
cleaned_lines.append(line)
|
| 158 |
-
|
| 159 |
-
return '\n'.join(cleaned_lines)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|