Spaces:
Running
Running
The default selection has been changed from URL Mode to HTML Text Mode.
Browse files- app.py +36 -36
- requirements.txt +1 -1
- webui.bat +132 -18
app.py
CHANGED
|
@@ -156,7 +156,7 @@ def process_conversion_request(
|
|
| 156 |
if not check_pandoc_available():
|
| 157 |
error_msg = "Error: Pandoc executable not found. Please ensure Pandoc is installed or run `pip install pypandoc_binary`."
|
| 158 |
# Yield a final state for all outputs
|
| 159 |
-
yield error_msg, None, gr.Markdown(visible=False)
|
| 160 |
return
|
| 161 |
|
| 162 |
# --- Determine Pandoc Settings based on Checkbox ---
|
|
@@ -179,7 +179,7 @@ def process_conversion_request(
|
|
| 179 |
# --- 1. Validate URL and Determine Restriction Path ---
|
| 180 |
start_url_str = start_url_str.strip()
|
| 181 |
if not start_url_str:
|
| 182 |
-
yield "Error: Starting URL cannot be empty.", None, gr.Markdown(visible=False)
|
| 183 |
return
|
| 184 |
|
| 185 |
try:
|
|
@@ -205,7 +205,7 @@ def process_conversion_request(
|
|
| 205 |
start_path_dir_for_restriction = None # Treat like root, don't restrict path based on this
|
| 206 |
|
| 207 |
except ValueError as e:
|
| 208 |
-
yield f"Error: Invalid starting URL '{start_url_str}': {e}", None, gr.Markdown(visible=False)
|
| 209 |
return
|
| 210 |
|
| 211 |
# Log restriction status
|
|
@@ -225,7 +225,7 @@ def process_conversion_request(
|
|
| 225 |
dequeued_count = 0
|
| 226 |
|
| 227 |
log_messages = ["Process started...", restriction_msg, conversion_mode_msg]
|
| 228 |
-
yield "\n".join(log_messages), None, gr.Markdown(visible=False)
|
| 229 |
|
| 230 |
# --- 3. Crawl and Convert Loop ---
|
| 231 |
while not urls_to_process.empty():
|
|
@@ -322,7 +322,7 @@ def process_conversion_request(
|
|
| 322 |
# --- 4. Create ZIP Archive ---
|
| 323 |
progress(1.0, desc="Zipping files...")
|
| 324 |
log_messages.append("\nCrawling complete. Creating ZIP file...")
|
| 325 |
-
yield "\n".join(log_messages), None, gr.Markdown(visible=False)
|
| 326 |
|
| 327 |
with tempfile.NamedTemporaryFile(suffix=".zip", delete=False) as temp_zip:
|
| 328 |
output_zip_path = temp_zip.name
|
|
@@ -332,15 +332,15 @@ def process_conversion_request(
|
|
| 332 |
log_messages.append(f"Converted {converted_count} pages using {'aggressive' if use_aggressive_conversion else 'standard'} mode.")
|
| 333 |
if failed_urls:
|
| 334 |
log_messages.append(f"Failed to process {len(failed_urls)} URLs.")
|
| 335 |
-
yield "\n".join(log_messages), output_zip_path, gr.Markdown(visible=False)
|
| 336 |
else:
|
| 337 |
log_messages.append("\nError: Failed to create the final ZIP archive.")
|
| 338 |
-
yield "\n".join(log_messages), None, gr.Markdown(visible=False)
|
| 339 |
|
| 340 |
except Exception as e:
|
| 341 |
error_log = f"\nAn unexpected error occurred: {e}\n{traceback.format_exc()}"
|
| 342 |
logging.error(error_log)
|
| 343 |
-
yield error_log, None, gr.Markdown(visible=False)
|
| 344 |
finally:
|
| 345 |
# --- Cleanup ---
|
| 346 |
if staging_dir and os.path.exists(staging_dir):
|
|
@@ -353,7 +353,7 @@ def process_conversion_request(
|
|
| 353 |
|
| 354 |
if not html_text_input or not html_text_input.strip():
|
| 355 |
log_messages.append("Error: HTML content cannot be empty.")
|
| 356 |
-
yield "\n".join(log_messages), None, gr.Markdown(visible=False)
|
| 357 |
return
|
| 358 |
|
| 359 |
progress(0.5, desc="Converting HTML text...")
|
|
@@ -377,14 +377,14 @@ def process_conversion_request(
|
|
| 377 |
# Yield the final state: update logs, clear zip, show markdown preview, provide md file
|
| 378 |
yield ("\n".join(log_messages),
|
| 379 |
None,
|
| 380 |
-
|
| 381 |
-
|
| 382 |
else:
|
| 383 |
# Conversion failed, show logs and hide/clear other outputs
|
| 384 |
yield ("\n".join(log_messages),
|
| 385 |
None,
|
| 386 |
-
|
| 387 |
-
|
| 388 |
|
| 389 |
css = """
|
| 390 |
textarea[rows]:not([rows="1"]) {
|
|
@@ -408,8 +408,8 @@ with gr.Blocks(title="HTML to Markdown Converter", css=css) as demo:
|
|
| 408 |
"""
|
| 409 |
# HTML to Markdown Converter (via pypandoc)
|
| 410 |
Choose an input method:
|
| 411 |
-
1. **Convert from
|
| 412 |
-
2. **Convert from
|
| 413 |
|
| 414 |
**This tool requires `pip install pypandoc_binary` to function correctly.**
|
| 415 |
"""
|
|
@@ -417,13 +417,21 @@ with gr.Blocks(title="HTML to Markdown Converter", css=css) as demo:
|
|
| 417 |
|
| 418 |
# --- Input type selector ---
|
| 419 |
input_type_radio = gr.Radio(
|
| 420 |
-
["Convert from
|
| 421 |
label="Input Type",
|
| 422 |
-
value="Convert from
|
| 423 |
)
|
| 424 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 425 |
# --- URL Mode UI ---
|
| 426 |
-
with gr.Column(visible=
|
| 427 |
url_input = gr.Textbox(
|
| 428 |
label="Starting Index HTML URL",
|
| 429 |
placeholder="e.g., https://dghs-imgutils.deepghs.org/main/index.html"
|
|
@@ -433,14 +441,6 @@ with gr.Blocks(title="HTML to Markdown Converter", css=css) as demo:
|
|
| 433 |
value=True # Default to restricting path
|
| 434 |
)
|
| 435 |
|
| 436 |
-
# --- HTML Text Mode UI ---
|
| 437 |
-
with gr.Column(visible=False) as text_mode_ui:
|
| 438 |
-
html_text_input = gr.Textbox(
|
| 439 |
-
label="Paste HTML Source Code Here",
|
| 440 |
-
lines=10, # Give it a decent initial size
|
| 441 |
-
placeholder="<html><body><h1>Title</h1><p>This is a paragraph.</p></body></html>"
|
| 442 |
-
)
|
| 443 |
-
|
| 444 |
# --- Common Options ---
|
| 445 |
with gr.Row():
|
| 446 |
aggressive_md_checkbox = gr.Checkbox(
|
|
@@ -451,26 +451,26 @@ with gr.Blocks(title="HTML to Markdown Converter", css=css) as demo:
|
|
| 451 |
with gr.Row():
|
| 452 |
start_button = gr.Button("Start Conversion", variant="primary")
|
| 453 |
|
| 454 |
-
# --- URL Mode Outputs ---
|
| 455 |
-
with gr.Column(visible=True) as url_mode_outputs:
|
| 456 |
-
log_output = gr.Textbox(label="Progress Logs", lines=15, interactive=False, show_copy_button=True)
|
| 457 |
-
zip_output = gr.File(label="Download Markdown Archive (ZIP)")
|
| 458 |
-
|
| 459 |
# --- HTML Text Mode Outputs ---
|
| 460 |
-
with gr.Column(visible=
|
| 461 |
gr.Markdown("---")
|
| 462 |
gr.Markdown("### Markdown Conversion Result")
|
| 463 |
-
md_output_display = gr.Markdown(label="Preview") # Preview the result
|
| 464 |
md_output_file = gr.File(label="Download Markdown File (.md)") # Download the single file
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 465 |
|
| 466 |
# --- UI Logic to switch between modes ---
|
| 467 |
def update_ui_visibility(input_type):
|
| 468 |
is_url_mode = (input_type == "Convert from URL")
|
| 469 |
return {
|
| 470 |
-
url_mode_ui: gr.update(visible=is_url_mode),
|
| 471 |
text_mode_ui: gr.update(visible=not is_url_mode),
|
| 472 |
-
url_mode_outputs: gr.update(visible=is_url_mode),
|
| 473 |
text_mode_outputs: gr.update(visible=not is_url_mode),
|
|
|
|
|
|
|
| 474 |
}
|
| 475 |
|
| 476 |
input_type_radio.change(
|
|
@@ -493,8 +493,8 @@ with gr.Blocks(title="HTML to Markdown Converter", css=css) as demo:
|
|
| 493 |
outputs=[
|
| 494 |
log_output,
|
| 495 |
zip_output,
|
|
|
|
| 496 |
md_output_display,
|
| 497 |
-
md_output_file
|
| 498 |
],
|
| 499 |
show_progress="full"
|
| 500 |
)
|
|
|
|
| 156 |
if not check_pandoc_available():
|
| 157 |
error_msg = "Error: Pandoc executable not found. Please ensure Pandoc is installed or run `pip install pypandoc_binary`."
|
| 158 |
# Yield a final state for all outputs
|
| 159 |
+
yield error_msg, None, None, gr.Markdown(visible=False)
|
| 160 |
return
|
| 161 |
|
| 162 |
# --- Determine Pandoc Settings based on Checkbox ---
|
|
|
|
| 179 |
# --- 1. Validate URL and Determine Restriction Path ---
|
| 180 |
start_url_str = start_url_str.strip()
|
| 181 |
if not start_url_str:
|
| 182 |
+
yield "Error: Starting URL cannot be empty.", None, None, gr.Markdown(visible=False)
|
| 183 |
return
|
| 184 |
|
| 185 |
try:
|
|
|
|
| 205 |
start_path_dir_for_restriction = None # Treat like root, don't restrict path based on this
|
| 206 |
|
| 207 |
except ValueError as e:
|
| 208 |
+
yield f"Error: Invalid starting URL '{start_url_str}': {e}", None, None, gr.Markdown(visible=False)
|
| 209 |
return
|
| 210 |
|
| 211 |
# Log restriction status
|
|
|
|
| 225 |
dequeued_count = 0
|
| 226 |
|
| 227 |
log_messages = ["Process started...", restriction_msg, conversion_mode_msg]
|
| 228 |
+
yield "\n".join(log_messages), None, None, gr.Markdown(visible=False)
|
| 229 |
|
| 230 |
# --- 3. Crawl and Convert Loop ---
|
| 231 |
while not urls_to_process.empty():
|
|
|
|
| 322 |
# --- 4. Create ZIP Archive ---
|
| 323 |
progress(1.0, desc="Zipping files...")
|
| 324 |
log_messages.append("\nCrawling complete. Creating ZIP file...")
|
| 325 |
+
yield "\n".join(log_messages), None, None, gr.Markdown(visible=False)
|
| 326 |
|
| 327 |
with tempfile.NamedTemporaryFile(suffix=".zip", delete=False) as temp_zip:
|
| 328 |
output_zip_path = temp_zip.name
|
|
|
|
| 332 |
log_messages.append(f"Converted {converted_count} pages using {'aggressive' if use_aggressive_conversion else 'standard'} mode.")
|
| 333 |
if failed_urls:
|
| 334 |
log_messages.append(f"Failed to process {len(failed_urls)} URLs.")
|
| 335 |
+
yield "\n".join(log_messages), output_zip_path, None, gr.Markdown(visible=False)
|
| 336 |
else:
|
| 337 |
log_messages.append("\nError: Failed to create the final ZIP archive.")
|
| 338 |
+
yield "\n".join(log_messages), None, None, gr.Markdown(visible=False)
|
| 339 |
|
| 340 |
except Exception as e:
|
| 341 |
error_log = f"\nAn unexpected error occurred: {e}\n{traceback.format_exc()}"
|
| 342 |
logging.error(error_log)
|
| 343 |
+
yield error_log, None, None, gr.Markdown(visible=False)
|
| 344 |
finally:
|
| 345 |
# --- Cleanup ---
|
| 346 |
if staging_dir and os.path.exists(staging_dir):
|
|
|
|
| 353 |
|
| 354 |
if not html_text_input or not html_text_input.strip():
|
| 355 |
log_messages.append("Error: HTML content cannot be empty.")
|
| 356 |
+
yield "\n".join(log_messages), None, None, gr.Markdown(visible=False)
|
| 357 |
return
|
| 358 |
|
| 359 |
progress(0.5, desc="Converting HTML text...")
|
|
|
|
| 377 |
# Yield the final state: update logs, clear zip, show markdown preview, provide md file
|
| 378 |
yield ("\n".join(log_messages),
|
| 379 |
None,
|
| 380 |
+
temp_md_path,
|
| 381 |
+
gr.Markdown(value=markdown_output, visible=True), )
|
| 382 |
else:
|
| 383 |
# Conversion failed, show logs and hide/clear other outputs
|
| 384 |
yield ("\n".join(log_messages),
|
| 385 |
None,
|
| 386 |
+
None,
|
| 387 |
+
gr.Markdown(visible=False), )
|
| 388 |
|
| 389 |
css = """
|
| 390 |
textarea[rows]:not([rows="1"]) {
|
|
|
|
| 408 |
"""
|
| 409 |
# HTML to Markdown Converter (via pypandoc)
|
| 410 |
Choose an input method:
|
| 411 |
+
1. **Convert from HTML Text**: Paste raw HTML source code directly to convert it into a single Markdown output.
|
| 412 |
+
2. **Convert from URL**: Enter the starting `index.html` URL of an online documentation site. The script will crawl internal links, convert pages to Markdown, and package the results into a ZIP file.
|
| 413 |
|
| 414 |
**This tool requires `pip install pypandoc_binary` to function correctly.**
|
| 415 |
"""
|
|
|
|
| 417 |
|
| 418 |
# --- Input type selector ---
|
| 419 |
input_type_radio = gr.Radio(
|
| 420 |
+
["Convert from HTML Text", "Convert from URL", ],
|
| 421 |
label="Input Type",
|
| 422 |
+
value="Convert from HTML Text"
|
| 423 |
)
|
| 424 |
|
| 425 |
+
# --- HTML Text Mode UI ---
|
| 426 |
+
with gr.Column(visible=True) as text_mode_ui:
|
| 427 |
+
html_text_input = gr.Textbox(
|
| 428 |
+
label="Paste HTML Source Code Here",
|
| 429 |
+
lines=10, # Give it a decent initial size
|
| 430 |
+
placeholder="<html><body><h1>Title</h1><p>This is a paragraph.</p></body></html>"
|
| 431 |
+
)
|
| 432 |
+
|
| 433 |
# --- URL Mode UI ---
|
| 434 |
+
with gr.Column(visible=False) as url_mode_ui:
|
| 435 |
url_input = gr.Textbox(
|
| 436 |
label="Starting Index HTML URL",
|
| 437 |
placeholder="e.g., https://dghs-imgutils.deepghs.org/main/index.html"
|
|
|
|
| 441 |
value=True # Default to restricting path
|
| 442 |
)
|
| 443 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 444 |
# --- Common Options ---
|
| 445 |
with gr.Row():
|
| 446 |
aggressive_md_checkbox = gr.Checkbox(
|
|
|
|
| 451 |
with gr.Row():
|
| 452 |
start_button = gr.Button("Start Conversion", variant="primary")
|
| 453 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 454 |
# --- HTML Text Mode Outputs ---
|
| 455 |
+
with gr.Column(visible=True) as text_mode_outputs:
|
| 456 |
gr.Markdown("---")
|
| 457 |
gr.Markdown("### Markdown Conversion Result")
|
|
|
|
| 458 |
md_output_file = gr.File(label="Download Markdown File (.md)") # Download the single file
|
| 459 |
+
md_output_display = gr.Markdown(label="Preview") # Preview the result
|
| 460 |
+
|
| 461 |
+
# --- URL Mode Outputs ---
|
| 462 |
+
with gr.Column(visible=False) as url_mode_outputs:
|
| 463 |
+
log_output = gr.Textbox(label="Progress Logs", lines=15, interactive=False, show_copy_button=True)
|
| 464 |
+
zip_output = gr.File(label="Download Markdown Archive (ZIP)")
|
| 465 |
|
| 466 |
# --- UI Logic to switch between modes ---
|
| 467 |
def update_ui_visibility(input_type):
|
| 468 |
is_url_mode = (input_type == "Convert from URL")
|
| 469 |
return {
|
|
|
|
| 470 |
text_mode_ui: gr.update(visible=not is_url_mode),
|
|
|
|
| 471 |
text_mode_outputs: gr.update(visible=not is_url_mode),
|
| 472 |
+
url_mode_ui: gr.update(visible=is_url_mode),
|
| 473 |
+
url_mode_outputs: gr.update(visible=is_url_mode),
|
| 474 |
}
|
| 475 |
|
| 476 |
input_type_radio.change(
|
|
|
|
| 493 |
outputs=[
|
| 494 |
log_output,
|
| 495 |
zip_output,
|
| 496 |
+
md_output_file,
|
| 497 |
md_output_display,
|
|
|
|
| 498 |
],
|
| 499 |
show_progress="full"
|
| 500 |
)
|
requirements.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
gradio==5.
|
| 2 |
requests
|
| 3 |
beautifulsoup4
|
| 4 |
lxml
|
|
|
|
| 1 |
+
gradio==5.50.0
|
| 2 |
requests
|
| 3 |
beautifulsoup4
|
| 4 |
lxml
|
webui.bat
CHANGED
|
@@ -1,21 +1,61 @@
|
|
| 1 |
@echo off
|
| 2 |
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
if not defined PYTHON (set PYTHON=python)
|
| 7 |
-
if not defined
|
|
|
|
| 8 |
|
| 9 |
mkdir tmp 2>NUL
|
| 10 |
|
|
|
|
| 11 |
%PYTHON% -c "" >tmp/stdout.txt 2>tmp/stderr.txt
|
| 12 |
if %ERRORLEVEL% == 0 goto :check_pip
|
| 13 |
echo Couldn't launch python
|
| 14 |
goto :show_stdout_stderr
|
| 15 |
|
| 16 |
:check_pip
|
|
|
|
| 17 |
%PYTHON% -mpip --help >tmp/stdout.txt 2>tmp/stderr.txt
|
| 18 |
if %ERRORLEVEL% == 0 goto :start_venv
|
|
|
|
| 19 |
if "%PIP_INSTALLER_LOCATION%" == "" goto :show_stdout_stderr
|
| 20 |
%PYTHON% "%PIP_INSTALLER_LOCATION%" >tmp/stdout.txt 2>tmp/stderr.txt
|
| 21 |
if %ERRORLEVEL% == 0 goto :start_venv
|
|
@@ -23,33 +63,107 @@ echo Couldn't install pip
|
|
| 23 |
goto :show_stdout_stderr
|
| 24 |
|
| 25 |
:start_venv
|
| 26 |
-
if
|
| 27 |
-
if ["%
|
|
|
|
|
|
|
| 28 |
|
|
|
|
| 29 |
dir "%VENV_DIR%\Scripts\Python.exe" >tmp/stdout.txt 2>tmp/stderr.txt
|
| 30 |
-
if %ERRORLEVEL% == 0 goto :
|
| 31 |
|
|
|
|
|
|
|
| 32 |
for /f "delims=" %%i in ('CALL %PYTHON% -c "import sys; print(sys.executable)"') do set PYTHON_FULLNAME="%%i"
|
| 33 |
echo Creating venv in directory %VENV_DIR% using python %PYTHON_FULLNAME%
|
| 34 |
%PYTHON_FULLNAME% -m venv "%VENV_DIR%" >tmp/stdout.txt 2>tmp/stderr.txt
|
| 35 |
-
if %ERRORLEVEL%
|
| 36 |
-
echo Unable to create venv in directory "%VENV_DIR%"
|
| 37 |
-
goto :show_stdout_stderr
|
| 38 |
-
|
| 39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
set PYTHON="%VENV_DIR%\Scripts\Python.exe"
|
| 41 |
-
echo venv %PYTHON%
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
|
| 43 |
-
:
|
|
|
|
|
|
|
| 44 |
goto :launch
|
| 45 |
|
| 46 |
:launch
|
| 47 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 48 |
pause
|
| 49 |
exit /b
|
| 50 |
|
| 51 |
-
:show_stdout_stderr
|
| 52 |
|
|
|
|
|
|
|
| 53 |
echo.
|
| 54 |
echo exit code: %errorlevel%
|
| 55 |
|
|
@@ -61,13 +175,13 @@ type tmp\stdout.txt
|
|
| 61 |
|
| 62 |
:show_stderr
|
| 63 |
for /f %%i in ("tmp\stderr.txt") do set size=%%~zi
|
| 64 |
-
if %size% equ 0 goto :
|
| 65 |
echo.
|
| 66 |
echo stderr:
|
| 67 |
type tmp\stderr.txt
|
| 68 |
|
| 69 |
:endofscript
|
| 70 |
-
|
| 71 |
echo.
|
| 72 |
echo Launch unsuccessful. Exiting.
|
| 73 |
pause
|
|
|
|
|
|
| 1 |
@echo off
|
| 2 |
|
| 3 |
+
chcp 65001
|
| 4 |
+
set PYTHONUTF8=1
|
| 5 |
+
:: The original source of the webui.bat file is stable-diffusion-webui
|
| 6 |
+
:: Modified and enhanced by Gemini with features for venv management and requirements handling.
|
| 7 |
+
|
| 8 |
+
:: --------- Configuration ---------
|
| 9 |
+
set COMMANDLINE_ARGS=
|
| 10 |
+
|
| 11 |
+
:: Define the application directory (folder name)
|
| 12 |
+
:: Leave empty if the app is in the root directory.
|
| 13 |
+
set APP_DIR=
|
| 14 |
+
|
| 15 |
+
:: Define the name of the Launch application
|
| 16 |
+
set APPLICATION_NAME=app.py
|
| 17 |
+
|
| 18 |
+
:: Define the requirements filename, default is requirements.txt
|
| 19 |
+
set REQUIREMENTS_FILE=requirements.txt
|
| 20 |
+
|
| 21 |
+
:: Define the name of the virtual environment directory
|
| 22 |
+
set VENV_NAME=venv
|
| 23 |
+
|
| 24 |
+
:: Set to 1 to always attempt to update packages from requirements.txt on every launch
|
| 25 |
+
set ALWAYS_UPDATE_REQS=1
|
| 26 |
+
:: ---------------------------------
|
| 27 |
+
|
| 28 |
+
:: --------- Path Setup Logic ---------
|
| 29 |
+
:: Logic to handle paths based on whether APP_DIR is set
|
| 30 |
+
if defined APP_DIR (
|
| 31 |
+
set "TARGET_REQ=%~dp0%APP_DIR%\%REQUIREMENTS_FILE%"
|
| 32 |
+
set "TARGET_SCRIPT=%~dp0%APP_DIR%\%APPLICATION_NAME%"
|
| 33 |
+
echo Working in subdirectory: %APP_DIR%
|
| 34 |
+
) else (
|
| 35 |
+
set "TARGET_REQ=%~dp0%REQUIREMENTS_FILE%"
|
| 36 |
+
set "TARGET_SCRIPT=%~dp0%APPLICATION_NAME%"
|
| 37 |
+
echo Working in root directory.
|
| 38 |
+
)
|
| 39 |
+
:: ------------------------------------
|
| 40 |
+
|
| 41 |
+
:: Set PYTHON executable if not already defined
|
| 42 |
if not defined PYTHON (set PYTHON=python)
|
| 43 |
+
:: Set VENV_DIR using VENV_NAME if not already defined
|
| 44 |
+
if not defined VENV_DIR (set "VENV_DIR=%~dp0%VENV_NAME%")
|
| 45 |
|
| 46 |
mkdir tmp 2>NUL
|
| 47 |
|
| 48 |
+
:: Check if Python is callable
|
| 49 |
%PYTHON% -c "" >tmp/stdout.txt 2>tmp/stderr.txt
|
| 50 |
if %ERRORLEVEL% == 0 goto :check_pip
|
| 51 |
echo Couldn't launch python
|
| 52 |
goto :show_stdout_stderr
|
| 53 |
|
| 54 |
:check_pip
|
| 55 |
+
:: Check if pip is available
|
| 56 |
%PYTHON% -mpip --help >tmp/stdout.txt 2>tmp/stderr.txt
|
| 57 |
if %ERRORLEVEL% == 0 goto :start_venv
|
| 58 |
+
:: If pip is not available and PIP_INSTALLER_LOCATION is set, try to install pip
|
| 59 |
if "%PIP_INSTALLER_LOCATION%" == "" goto :show_stdout_stderr
|
| 60 |
%PYTHON% "%PIP_INSTALLER_LOCATION%" >tmp/stdout.txt 2>tmp/stderr.txt
|
| 61 |
if %ERRORLEVEL% == 0 goto :start_venv
|
|
|
|
| 63 |
goto :show_stdout_stderr
|
| 64 |
|
| 65 |
:start_venv
|
| 66 |
+
:: Skip venv creation/activation if VENV_DIR is explicitly set to "-"
|
| 67 |
+
if ["%VENV_DIR%"] == ["-"] goto :skip_venv_entirely
|
| 68 |
+
:: Skip venv creation/activation if SKIP_VENV is set to "1"
|
| 69 |
+
if ["%SKIP_VENV%"] == ["1"] goto :skip_venv_entirely
|
| 70 |
|
| 71 |
+
:: Check if the venv already exists by looking for Python.exe in its Scripts directory
|
| 72 |
dir "%VENV_DIR%\Scripts\Python.exe" >tmp/stdout.txt 2>tmp/stderr.txt
|
| 73 |
+
if %ERRORLEVEL% == 0 goto :activate_venv_and_maybe_update
|
| 74 |
|
| 75 |
+
:: Venv does not exist, create it
|
| 76 |
+
echo Virtual environment not found in "%VENV_DIR%". Creating a new one.
|
| 77 |
for /f "delims=" %%i in ('CALL %PYTHON% -c "import sys; print(sys.executable)"') do set PYTHON_FULLNAME="%%i"
|
| 78 |
echo Creating venv in directory %VENV_DIR% using python %PYTHON_FULLNAME%
|
| 79 |
%PYTHON_FULLNAME% -m venv "%VENV_DIR%" >tmp/stdout.txt 2>tmp/stderr.txt
|
| 80 |
+
if %ERRORLEVEL% NEQ 0 (
|
| 81 |
+
echo Unable to create venv in directory "%VENV_DIR%"
|
| 82 |
+
goto :show_stdout_stderr
|
| 83 |
+
)
|
| 84 |
+
echo Venv created.
|
| 85 |
+
|
| 86 |
+
:: Install requirements for the first time if venv was just created
|
| 87 |
+
:: This section handles the initial installation of packages from requirements.txt
|
| 88 |
+
:: immediately after a new virtual environment is created.
|
| 89 |
+
echo Checking for %REQUIREMENTS_FILE% for initial setup...
|
| 90 |
+
if exist "%TARGET_REQ%" (
|
| 91 |
+
echo Found %REQUIREMENTS_FILE% at "%TARGET_REQ%", attempting to install for initial setup...
|
| 92 |
+
call "%VENV_DIR%\Scripts\activate.bat"
|
| 93 |
+
echo Installing packages from %REQUIREMENTS_FILE% ^(initial setup^)...
|
| 94 |
+
"%VENV_DIR%\Scripts\python.exe" -m pip install -r "%TARGET_REQ%"
|
| 95 |
+
if %ERRORLEVEL% NEQ 0 (
|
| 96 |
+
echo Failed to install requirements during initial setup. Please check the output above.
|
| 97 |
+
pause
|
| 98 |
+
goto :show_stdout_stderr_custom_pip_initial
|
| 99 |
+
)
|
| 100 |
+
echo Initial requirements installed successfully.
|
| 101 |
+
call "%VENV_DIR%\Scripts\deactivate.bat"
|
| 102 |
+
) else (
|
| 103 |
+
echo No %REQUIREMENTS_FILE% found at "%TARGET_REQ%", skipping package installation.
|
| 104 |
+
)
|
| 105 |
+
goto :activate_venv_and_maybe_update
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
:activate_venv_and_maybe_update
|
| 109 |
+
:: This label is reached if the venv exists or was just created.
|
| 110 |
+
:: Set PYTHON to point to the venv's Python interpreter.
|
| 111 |
set PYTHON="%VENV_DIR%\Scripts\Python.exe"
|
| 112 |
+
echo Activating venv: %PYTHON%
|
| 113 |
+
|
| 114 |
+
:: Always update requirements if ALWAYS_UPDATE_REQS is 1
|
| 115 |
+
:: This section allows for updating packages from requirements.txt on every launch
|
| 116 |
+
:: if the ALWAYS_UPDATE_REQS variable is set to 1.
|
| 117 |
+
if defined ALWAYS_UPDATE_REQS (
|
| 118 |
+
if "%ALWAYS_UPDATE_REQS%"=="1" (
|
| 119 |
+
echo ALWAYS_UPDATE_REQS is enabled.
|
| 120 |
+
if exist "%TARGET_REQ%" (
|
| 121 |
+
echo Attempting to update packages from "%TARGET_REQ%"...
|
| 122 |
+
REM No need to call activate.bat here again, PYTHON is already set to the venv's python
|
| 123 |
+
%PYTHON% -m pip install -r "%TARGET_REQ%"
|
| 124 |
+
if %ERRORLEVEL% NEQ 0 (
|
| 125 |
+
echo Failed to update requirements. Please check the output above.
|
| 126 |
+
pause
|
| 127 |
+
goto :endofscript
|
| 128 |
+
)
|
| 129 |
+
echo Requirements updated successfully.
|
| 130 |
+
) else (
|
| 131 |
+
echo ALWAYS_UPDATE_REQS is enabled, but no %REQUIREMENTS_FILE% found. Skipping update.
|
| 132 |
+
)
|
| 133 |
+
) else (
|
| 134 |
+
echo ALWAYS_UPDATE_REQS is not enabled or not set to 1. Skipping routine update.
|
| 135 |
+
)
|
| 136 |
+
)
|
| 137 |
+
|
| 138 |
+
goto :launch
|
| 139 |
|
| 140 |
+
:skip_venv_entirely
|
| 141 |
+
:: This label is reached if venv usage is explicitly skipped.
|
| 142 |
+
echo Skipping venv.
|
| 143 |
goto :launch
|
| 144 |
|
| 145 |
:launch
|
| 146 |
+
:: Launch the main application
|
| 147 |
+
echo Launching Web UI with arguments: %COMMANDLINE_ARGS% %*
|
| 148 |
+
echo Script path: %TARGET_SCRIPT%
|
| 149 |
+
%PYTHON% "%TARGET_SCRIPT%" %COMMANDLINE_ARGS% %*
|
| 150 |
+
echo Launch finished.
|
| 151 |
+
pause
|
| 152 |
+
exit /b
|
| 153 |
+
|
| 154 |
+
:show_stdout_stderr_custom_pip_initial
|
| 155 |
+
:: Custom error handler for failures during the initial pip install process.
|
| 156 |
+
echo.
|
| 157 |
+
echo exit code ^(pip initial install^): %errorlevel%
|
| 158 |
+
echo Errors during initial pip install. See output above.
|
| 159 |
+
echo.
|
| 160 |
+
echo Launch unsuccessful. Exiting.
|
| 161 |
pause
|
| 162 |
exit /b
|
| 163 |
|
|
|
|
| 164 |
|
| 165 |
+
:show_stdout_stderr
|
| 166 |
+
:: General error handler: displays stdout and stderr from the tmp directory.
|
| 167 |
echo.
|
| 168 |
echo exit code: %errorlevel%
|
| 169 |
|
|
|
|
| 175 |
|
| 176 |
:show_stderr
|
| 177 |
for /f %%i in ("tmp\stderr.txt") do set size=%%~zi
|
| 178 |
+
if %size% equ 0 goto :endofscript
|
| 179 |
echo.
|
| 180 |
echo stderr:
|
| 181 |
type tmp\stderr.txt
|
| 182 |
|
| 183 |
:endofscript
|
|
|
|
| 184 |
echo.
|
| 185 |
echo Launch unsuccessful. Exiting.
|
| 186 |
pause
|
| 187 |
+
exit /b
|