burtenshaw commited on
Commit
21c1f59
·
1 Parent(s): a947fe6

match chromium headleass install

Browse files
Files changed (2) hide show
  1. app/app.py +93 -32
  2. packages.txt +1 -0
app/app.py CHANGED
@@ -136,63 +136,124 @@ def reconstruct_presentation_markdown(slides_data):
136
 
137
 
138
  def generate_pdf_from_markdown(markdown_file_path, output_pdf_path):
139
- """Generates a PDF from a Markdown file using bs pdf."""
140
- logger.info(
141
- f"Attempting PDF gen using bs pdf: {markdown_file_path} -> {output_pdf_path}"
142
- )
143
  working_dir = os.path.dirname(markdown_file_path)
144
  markdown_filename = os.path.basename(markdown_file_path)
145
- # Ensure output directory exists (bs pdf might not create it)
146
- Path(output_pdf_path).parent.mkdir(parents=True, exist_ok=True)
147
-
 
148
  pdf_gen_success = False
149
 
150
- # ---- Run bs pdf ----
151
  try:
152
- # Use the absolute path for the output file
153
- pdf_command = ["bs", "pdf", markdown_filename, "-o", str(output_pdf_path)]
154
- logger.info(f"Running: {' '.join(pdf_command)} in CWD: {working_dir}")
155
- pdf_result = subprocess.run(
156
- pdf_command,
157
  cwd=working_dir,
158
  capture_output=True,
159
  text=True,
160
  check=True,
161
- timeout=180, # Combined timeout (adjust as needed)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
  )
163
- logger.info("bs pdf command executed successfully.")
164
- logger.debug(f"bs pdf stdout:\n{pdf_result.stdout}")
165
- logger.debug(f"bs pdf stderr:\n{pdf_result.stderr}")
166
 
167
  if os.path.exists(output_pdf_path):
168
  logger.info(f"PDF generated successfully: {output_pdf_path}")
169
  pdf_gen_success = True
170
  return output_pdf_path
171
  else:
172
- logger.error("bs pdf command finished but output PDF not found.")
173
- raise gr.Error("bs pdf finished but failed to create the PDF file.")
174
 
175
  except FileNotFoundError:
176
  logger.error(
177
- "`bs` command not found. Install backslide (`npm install -g backslide`) "
178
- "and ensure its dependencies (like decktape) are met."
179
- )
180
- raise gr.Error(
181
- "PDF generation tool (backslide/bs) not found or not configured correctly."
182
  )
 
183
  except subprocess.CalledProcessError as e:
184
- logger.error(f"Backslide (bs pdf) failed (code {e.returncode}).")
185
- # stderr from bs pdf might include decktape errors if it failed
186
- logger.error(f"bs pdf stderr:\n{e.stderr}")
187
- raise gr.Error(f"Backslide PDF generation failed: {e.stderr[:500]}...")
188
  except subprocess.TimeoutExpired:
189
- logger.error("Backslide (bs pdf) timed out.")
190
- raise gr.Error("PDF generation timed out (backslide/bs pdf).")
191
  except Exception as e:
192
- logger.error(f"Unexpected error during bs pdf: {e}", exc_info=True)
 
 
193
  raise gr.Error(f"Unexpected error during PDF generation: {e}")
194
  finally:
195
- # No intermediate HTML cleanup needed anymore
 
 
 
 
 
 
 
 
 
196
  if pdf_gen_success:
197
  logger.info(f"PDF generation process completed for {output_pdf_path}.")
198
  else:
 
136
 
137
 
138
  def generate_pdf_from_markdown(markdown_file_path, output_pdf_path):
139
+ """Generates a PDF from a Markdown file using bs export + decktape."""
140
+ logger.info(f"Attempting PDF gen: {markdown_file_path} -> {output_pdf_path}")
 
 
141
  working_dir = os.path.dirname(markdown_file_path)
142
  markdown_filename = os.path.basename(markdown_file_path)
143
+ html_output_dir_name = "bs_html_output"
144
+ html_output_dir_abs = os.path.join(working_dir, html_output_dir_name)
145
+ expected_html_filename = os.path.splitext(markdown_filename)[0] + ".html"
146
+ generated_html_path_abs = os.path.join(html_output_dir_abs, expected_html_filename)
147
  pdf_gen_success = False
148
 
149
+ # ---- Step 1: Generate HTML using bs export ----
150
  try:
151
+ Path(html_output_dir_abs).mkdir(parents=True, exist_ok=True)
152
+ export_command = ["bs", "export", markdown_filename, "-o", html_output_dir_name]
153
+ logger.info(f"Running: {' '.join(export_command)} in CWD: {working_dir}")
154
+ export_result = subprocess.run(
155
+ export_command,
156
  cwd=working_dir,
157
  capture_output=True,
158
  text=True,
159
  check=True,
160
+ timeout=60,
161
+ )
162
+ logger.info("Backslide (bs export) OK.")
163
+ logger.debug(f"bs export stdout:\n{export_result.stdout}")
164
+ logger.debug(f"bs export stderr:\n{export_result.stderr}")
165
+
166
+ if not os.path.exists(generated_html_path_abs):
167
+ logger.error(f"Expected HTML not found: {generated_html_path_abs}")
168
+ try:
169
+ files_in_dir = os.listdir(html_output_dir_abs)
170
+ logger.error(f"Files in {html_output_dir_abs}: {files_in_dir}")
171
+ except FileNotFoundError:
172
+ logger.error(
173
+ f"HTML output directory {html_output_dir_abs} not found after bs run."
174
+ )
175
+ raise FileNotFoundError(
176
+ f"Generated HTML not found: {generated_html_path_abs}"
177
+ )
178
+
179
+ except FileNotFoundError:
180
+ logger.error(
181
+ "`bs` command not found. Install backslide (`npm install -g backslide`)."
182
+ )
183
+ raise gr.Error("HTML generation tool (backslide/bs) not found.")
184
+ except subprocess.CalledProcessError as e:
185
+ logger.error(f"Backslide (bs export) failed (code {e.returncode}).")
186
+ logger.error(f"bs stderr:\n{e.stderr}")
187
+ raise gr.Error(f"Backslide HTML failed: {e.stderr[:500]}...")
188
+ except subprocess.TimeoutExpired:
189
+ logger.error("Backslide (bs export) timed out.")
190
+ raise gr.Error("HTML generation timed out (backslide).")
191
+ except Exception as e:
192
+ logger.error(f"Unexpected error during bs export: {e}", exc_info=True)
193
+ raise gr.Error(f"Unexpected error during HTML generation: {e}")
194
+
195
+ # ---- Step 2: Generate PDF from HTML using decktape ----
196
+ try:
197
+ Path(output_pdf_path).parent.mkdir(parents=True, exist_ok=True)
198
+ html_file_url = Path(generated_html_path_abs).as_uri()
199
+ decktape_command = [
200
+ "decktape",
201
+ "-p",
202
+ "1000",
203
+ "--chrome-arg=--allow-running-insecure-content",
204
+ "--chrome-arg=--disable-web-security",
205
+ "--chrome-arg=--no-sandbox",
206
+ html_file_url,
207
+ str(output_pdf_path),
208
+ ]
209
+ logger.info(f"Running PDF conversion: {' '.join(decktape_command)}")
210
+ decktape_result = subprocess.run(
211
+ decktape_command,
212
+ capture_output=True,
213
+ text=True,
214
+ check=True,
215
+ timeout=120,
216
  )
217
+ logger.info("Decktape command executed successfully.")
218
+ logger.debug(f"decktape stdout:\n{decktape_result.stdout}")
219
+ logger.debug(f"decktape stderr:\n{decktape_result.stderr}")
220
 
221
  if os.path.exists(output_pdf_path):
222
  logger.info(f"PDF generated successfully: {output_pdf_path}")
223
  pdf_gen_success = True
224
  return output_pdf_path
225
  else:
226
+ logger.error("Decktape command finished but output PDF not found.")
227
+ raise gr.Error("Decktape finished, but the PDF file was not created.")
228
 
229
  except FileNotFoundError:
230
  logger.error(
231
+ "`decktape` command not found. Install decktape (`npm install -g decktape`)."
 
 
 
 
232
  )
233
+ raise gr.Error("PDF generation tool (decktape) not found.")
234
  except subprocess.CalledProcessError as e:
235
+ logger.error(f"Decktape command failed (code {e.returncode}).")
236
+ logger.error(f"decktape stderr:\n{e.stderr}")
237
+ raise gr.Error(f"Decktape PDF failed: {e.stderr[:500]}...")
 
238
  except subprocess.TimeoutExpired:
239
+ logger.error("Decktape command timed out.")
240
+ raise gr.Error("PDF generation timed out (decktape).")
241
  except Exception as e:
242
+ logger.error(
243
+ f"Unexpected error during decktape PDF generation: {e}", exc_info=True
244
+ )
245
  raise gr.Error(f"Unexpected error during PDF generation: {e}")
246
  finally:
247
+ # --- Cleanup HTML output directory ---
248
+ if os.path.exists(html_output_dir_abs):
249
+ try:
250
+ shutil.rmtree(html_output_dir_abs)
251
+ logger.info(f"Cleaned up HTML temp dir: {html_output_dir_abs}")
252
+ except Exception as cleanup_e:
253
+ logger.warning(
254
+ f"Could not cleanup HTML dir {html_output_dir_abs}: {cleanup_e}"
255
+ )
256
+ # Log final status
257
  if pdf_gen_success:
258
  logger.info(f"PDF generation process completed for {output_pdf_path}.")
259
  else:
packages.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ chromium-browser