ABDALLALSWAITI commited on
Commit
807e481
Β·
verified Β·
1 Parent(s): 39b1a26

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +202 -32
src/streamlit_app.py CHANGED
@@ -1,40 +1,210 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
  import streamlit as st
 
 
 
 
 
5
 
6
- """
7
- # Welcome to Streamlit!
 
 
 
8
 
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
 
 
 
 
15
 
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
 
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
 
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
1
  import streamlit as st
2
+ import subprocess
3
+ import os
4
+ import tempfile
5
+ import shutil
6
+ from pathlib import Path
7
 
8
+ st.set_page_config(
9
+ page_title="HTML to PDF Converter",
10
+ page_icon="πŸ“„",
11
+ layout="wide"
12
+ )
13
 
14
+ def convert_html_to_pdf(html_content, aspect_ratio):
15
+ """
16
+ Convert HTML content to PDF using Puppeteer
17
+
18
+ Args:
19
+ html_content: String containing HTML content
20
+ aspect_ratio: One of "16:9", "1:1", or "9:16"
21
+
22
+ Returns:
23
+ Path to generated PDF file or error message
24
+ """
25
+ try:
26
+ # Create temporary directory for processing
27
+ temp_dir = tempfile.mkdtemp()
28
+
29
+ # Save HTML content to temporary file
30
+ html_file = os.path.join(temp_dir, "input.html")
31
+ with open(html_file, 'w', encoding='utf-8') as f:
32
+ f.write(html_content)
33
+
34
+ # Run Node.js script to convert HTML to PDF
35
+ result = subprocess.run(
36
+ ['node', 'puppeteer_pdf.js', html_file, aspect_ratio],
37
+ capture_output=True,
38
+ text=True,
39
+ timeout=60
40
+ )
41
+
42
+ if result.returncode != 0:
43
+ return None, f"PDF conversion failed: {result.stderr}"
44
+
45
+ # Get the generated PDF path
46
+ pdf_file = html_file.replace('.html', '.pdf')
47
+
48
+ if not os.path.exists(pdf_file):
49
+ return None, "PDF file was not generated"
50
+
51
+ # Copy PDF to a permanent location
52
+ output_pdf = os.path.join(tempfile.gettempdir(), f"output_{os.getpid()}.pdf")
53
+ shutil.copy(pdf_file, output_pdf)
54
+
55
+ # Clean up temporary directory
56
+ shutil.rmtree(temp_dir, ignore_errors=True)
57
+
58
+ return output_pdf, None
59
+
60
+ except subprocess.TimeoutExpired:
61
+ return None, "Error: PDF conversion timed out (60 seconds)"
62
+ except Exception as e:
63
+ return None, f"Error: {str(e)}"
64
 
65
+ # Page header
66
+ st.title("πŸ“„ HTML to PDF Converter")
67
+ st.markdown("""
68
+ Convert HTML files or HTML code to PDF using Puppeteer.
69
+ Supports multiple aspect ratios: **16:9** (landscape), **1:1** (square), and **9:16** (portrait).
70
+ """)
71
 
72
+ # Create tabs
73
+ tab1, tab2 = st.tabs(["πŸ“€ Upload HTML File", "πŸ“ Paste HTML Code"])
74
 
75
+ # Tab 1: Upload HTML File
76
+ with tab1:
77
+ col1, col2 = st.columns([1, 1])
78
+
79
+ with col1:
80
+ uploaded_file = st.file_uploader(
81
+ "Choose an HTML file",
82
+ type=['html', 'htm'],
83
+ key="file_uploader"
84
+ )
85
+
86
+ aspect_ratio_file = st.radio(
87
+ "Aspect Ratio",
88
+ options=["16:9", "1:1", "9:16"],
89
+ index=0,
90
+ key="aspect_file",
91
+ help="Select the page orientation and dimensions"
92
+ )
93
+
94
+ convert_file_btn = st.button("πŸ”„ Convert to PDF", key="convert_file", type="primary", use_container_width=True)
95
+
96
+ with col2:
97
+ if convert_file_btn:
98
+ if uploaded_file is not None:
99
+ with st.spinner("Converting HTML to PDF..."):
100
+ # Read uploaded file
101
+ html_content = uploaded_file.read().decode('utf-8')
102
+
103
+ # Convert to PDF
104
+ pdf_path, error = convert_html_to_pdf(html_content, aspect_ratio_file)
105
+
106
+ if error:
107
+ st.error(error)
108
+ else:
109
+ st.success("βœ… PDF generated successfully!")
110
+
111
+ # Read PDF file
112
+ with open(pdf_path, 'rb') as f:
113
+ pdf_data = f.read()
114
+
115
+ # Download button
116
+ st.download_button(
117
+ label="⬇️ Download PDF",
118
+ data=pdf_data,
119
+ file_name="converted.pdf",
120
+ mime="application/pdf",
121
+ use_container_width=True
122
+ )
123
+ else:
124
+ st.warning("Please upload an HTML file first.")
125
 
126
+ # Tab 2: Paste HTML Code
127
+ with tab2:
128
+ col1, col2 = st.columns([1, 1])
129
+
130
+ with col1:
131
+ html_code = st.text_area(
132
+ "HTML Content",
133
+ value="""<!DOCTYPE html>
134
+ <html>
135
+ <head>
136
+ <title>Sample Document</title>
137
+ <style>
138
+ body {
139
+ font-family: Arial, sans-serif;
140
+ margin: 40px;
141
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
142
+ color: white;
143
+ }
144
+ h1 {
145
+ font-size: 48px;
146
+ margin-bottom: 20px;
147
+ }
148
+ p {
149
+ font-size: 18px;
150
+ line-height: 1.6;
151
+ }
152
+ </style>
153
+ </head>
154
+ <body>
155
+ <h1>Hello, PDF World! 🌍</h1>
156
+ <p>This is a sample HTML document converted to PDF.</p>
157
+ <p>You can customize this HTML with your own content!</p>
158
+ </body>
159
+ </html>""",
160
+ height=400,
161
+ key="html_code"
162
+ )
163
+
164
+ aspect_ratio_text = st.radio(
165
+ "Aspect Ratio",
166
+ options=["16:9", "1:1", "9:16"],
167
+ index=0,
168
+ key="aspect_text",
169
+ help="Select the page orientation and dimensions"
170
+ )
171
+
172
+ convert_text_btn = st.button("πŸ”„ Convert to PDF", key="convert_text", type="primary", use_container_width=True)
173
+
174
+ with col2:
175
+ if convert_text_btn:
176
+ if html_code and html_code.strip():
177
+ with st.spinner("Converting HTML to PDF..."):
178
+ # Convert to PDF
179
+ pdf_path, error = convert_html_to_pdf(html_code, aspect_ratio_text)
180
+
181
+ if error:
182
+ st.error(error)
183
+ else:
184
+ st.success("βœ… PDF generated successfully!")
185
+
186
+ # Read PDF file
187
+ with open(pdf_path, 'rb') as f:
188
+ pdf_data = f.read()
189
+
190
+ # Download button
191
+ st.download_button(
192
+ label="⬇️ Download PDF",
193
+ data=pdf_data,
194
+ file_name="converted.pdf",
195
+ mime="application/pdf",
196
+ use_container_width=True
197
+ )
198
+ else:
199
+ st.warning("Please enter HTML content first.")
200
 
201
+ # Footer with tips
202
+ st.markdown("---")
203
+ st.markdown("""
204
+ ### πŸ’‘ Tips:
205
+ - **16:9** - Best for presentations and landscape documents (297mm Γ— 210mm)
206
+ - **1:1** - Square format (210mm Γ— 210mm)
207
+ - **9:16** - Portrait format, standard A4 (210mm Γ— 297mm)
208
+ - Include inline CSS for styling
209
+ - External resources should use absolute URLs
210
+ """)