lexicalspace commited on
Commit
954df8f
·
verified ·
1 Parent(s): 6f50e90

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +116 -0
app.py CHANGED
@@ -17,6 +17,120 @@ from bs4 import BeautifulSoup
17
 
18
 
19
  # --- BATCH 1: MEDIA & FILE FUNCTIONS ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  import streamlit as st
21
  from huggingface_hub import InferenceClient
22
  import os
@@ -971,6 +1085,7 @@ if __name__ == "__main__":
971
  elif mode == "stopwatch": tool_stopwatch()
972
  elif mode == "python": tool_python_checker()
973
  elif mode == "seo": render_seo_ui()
 
974
 
975
  # 5. HOME DASHBOARD (Button Grid)
976
  else:
@@ -983,6 +1098,7 @@ if __name__ == "__main__":
983
 
984
  with c1:
985
  st.info("**📂 Media & Files**")
 
986
  if st.button("🎥 YouTube Downloader"): set_mode("youtube"); st.rerun()
987
  if st.button("🎥 Seo Generator"): set_mode("seo"); st.rerun()
988
 
 
17
 
18
 
19
  # --- BATCH 1: MEDIA & FILE FUNCTIONS ---
20
+
21
+
22
+
23
+
24
+
25
+ import streamlit as st
26
+ from fpdf import FPDF
27
+ import requests
28
+ import os
29
+ import re
30
+
31
+ def run_pdf_converter_app():
32
+ """
33
+ Main container function.
34
+ Contains all logic for downloading fonts, cleaning text, and generating PDF.
35
+ """
36
+
37
+ # --- Nested Helper 1: Download Font (Crucial for HF Spaces) ---
38
+ def get_unicode_font():
39
+ font_filename = "DejaVuSans.ttf"
40
+ # URL to a stable Unicode font source
41
+ font_url = "https://github.com/dejavu-fonts/dejavu-fonts/raw/master/ttf/DejaVuSans.ttf"
42
+
43
+ if not os.path.exists(font_filename):
44
+ try:
45
+ with st.spinner("Downloading Unicode font support..."):
46
+ response = requests.get(font_url)
47
+ with open(font_filename, "wb") as f:
48
+ f.write(response.content)
49
+ except Exception as e:
50
+ st.error(f"Failed to load font: {e}")
51
+ return None
52
+ return font_filename
53
+
54
+ # --- Nested Helper 2: Clean LMS Garbage ---
55
+ def clean_lms_text(text, active=True):
56
+ if not active:
57
+ return text
58
+
59
+ # 1. Normalize line endings (windows/linux compatibility)
60
+ text = text.replace('\r\n', '\n').replace('\r', '\n')
61
+
62
+ # 2. Remove common LMS description patterns
63
+ # Example: specific text like "Question 1" or text inside brackets [Question ID]
64
+ # This Regex removes text inside square brackets often hidden in LMS
65
+ text = re.sub(r'\[.*?\]', '', text)
66
+
67
+ # 3. Remove text inside parenthesis if it looks like a description (optional)
68
+ # un-comment the line below if your LMS writes "Symbol (Name)"
69
+ # text = re.sub(r'\([A-Za-z\s]+\)', '', text)
70
+
71
+ # 4. Remove zero-width spaces often found in web copying
72
+ text = text.replace(u'\u200b', '')
73
+
74
+ return text.strip()
75
+
76
+ # --- Nested Helper 3: PDF Generator ---
77
+ def create_pdf(text_content):
78
+ pdf = FPDF()
79
+ pdf.add_page()
80
+
81
+ # Load the custom font
82
+ font_path = get_unicode_font()
83
+ if font_path:
84
+ # Add font (requires fpdf2)
85
+ pdf.add_font('DejaVu', fname=font_path)
86
+ pdf.set_font('DejaVu', size=12)
87
+ else:
88
+ # Fallback (Symbols will likely fail here)
89
+ pdf.set_font("Arial", size=12)
90
+ st.warning("Using standard font. Special symbols might not appear.")
91
+
92
+ # Write text
93
+ # multi_cell handles text wrapping automatically
94
+ pdf.multi_cell(0, 10, text=text_content)
95
+
96
+ # Return PDF as byte string
97
+ return pdf.output(dest='S')
98
+
99
+ # --- UI LAYOUT ---
100
+ st.markdown("### 📝 LMS Text to PDF Converter")
101
+ st.info("Paste your text below. This tool supports Math symbols ($ \Sigma, \Delta $) and foreign languages.")
102
+
103
+ # 1. Input
104
+ raw_text = st.text_area("Paste Question/Text Here:", height=250)
105
+
106
+ # 2. Settings
107
+ col1, col2 = st.columns(2)
108
+ with col1:
109
+ auto_clean = st.checkbox("Remove LMS hidden codes like [ID_123]", value=True)
110
+ with col2:
111
+ filename = st.text_input("Filename", value="notes.pdf")
112
+
113
+ # 3. Action
114
+ if st.button("Convert to PDF"):
115
+ if not raw_text:
116
+ st.error("Please paste some text first.")
117
+ else:
118
+ # Process
119
+ clean_text = clean_lms_text(raw_text, active=auto_clean)
120
+ pdf_data = create_pdf(clean_text)
121
+
122
+ if pdf_data:
123
+ st.success("Conversion Successful!")
124
+ # Download Button
125
+ st.download_button(
126
+ label="📥 Download PDF",
127
+ data=pdf_data,
128
+ file_name=filename if filename.endswith('.pdf') else f"{filename}.pdf",
129
+ mime="application/pdf"
130
+ )
131
+
132
+
133
+
134
  import streamlit as st
135
  from huggingface_hub import InferenceClient
136
  import os
 
1085
  elif mode == "stopwatch": tool_stopwatch()
1086
  elif mode == "python": tool_python_checker()
1087
  elif mode == "seo": render_seo_ui()
1088
+ elif mode == "Pdf Converter": run_pdf_converter_app()
1089
 
1090
  # 5. HOME DASHBOARD (Button Grid)
1091
  else:
 
1098
 
1099
  with c1:
1100
  st.info("**📂 Media & Files**")
1101
+ if st.button("🎥 Pdf"): set_mode("Pdf Converter"); st.rerun()
1102
  if st.button("🎥 YouTube Downloader"): set_mode("youtube"); st.rerun()
1103
  if st.button("🎥 Seo Generator"): set_mode("seo"); st.rerun()
1104