lollms-webui/utilities/execution_engines/lilypond_execution_engine.py

105 lines
3.3 KiB
Python
Raw Normal View History

2024-10-31 20:57:29 +00:00
"""
project: lollms_webui
file: lilypond_execution_engine.py
author: LilyPond integration
description:
This is a utility for executing LilyPond code in LOLLMS
"""
2024-12-19 12:48:57 +00:00
import shutil
2024-10-31 20:57:29 +00:00
import subprocess
import time
from pathlib import Path
2024-12-19 12:48:57 +00:00
import pipmaster as pm
from ascii_colors import trace_exception
2024-10-31 20:57:29 +00:00
from lollms.client_session import Client
from lollms.utilities import discussion_path_to_url, show_yes_no_dialog
2024-12-19 12:48:57 +00:00
from lollms_webui import LOLLMSWebUI
lollmsElfServer: LOLLMSWebUI = LOLLMSWebUI.get_instance()
2024-10-31 20:57:29 +00:00
def check_and_install_lilypond():
"""Check if LilyPond is installed and install it if needed"""
if not pm.is_installed("lilypond"):
2024-12-19 12:48:57 +00:00
if not show_yes_no_dialog(
"Installation", "LilyPond is not installed. Do you want to install it?"
):
return {"status": False, "error": "User refused LilyPond installation!"}
2024-10-31 20:57:29 +00:00
try:
pm.install("lilypond")
2024-12-19 12:48:57 +00:00
return {"status": True}
2024-10-31 20:57:29 +00:00
except Exception as ex:
2024-12-19 12:48:57 +00:00
return {"status": False, "error": f"Failed to install LilyPond: {str(ex)}"}
return {"status": True}
2024-10-31 20:57:29 +00:00
2024-12-19 12:48:57 +00:00
def execute_lilypond(code, client: Client, message_id):
2024-10-31 20:57:29 +00:00
"""Execute LilyPond code and return the result"""
try:
# Check LilyPond installation
check_result = check_and_install_lilypond()
if not check_result["status"]:
return {"output": check_result["error"], "execution_time": 0}
# Start timer
start_time = time.time()
# Import LilyPond after installation check
import lilypond
# Create work directory in discussion folder
root_folder = client.discussion.discussion_folder
root_folder.mkdir(parents=True, exist_ok=True)
2024-12-19 12:48:57 +00:00
2024-10-31 20:57:29 +00:00
# Create LilyPond file
2024-12-19 12:48:57 +00:00
ly_file = root_folder / f"score_{message_id}.ly"
ly_file.write_text(code, encoding="utf8")
2024-10-31 20:57:29 +00:00
# Get the PDF and MIDI outputs
2024-12-19 12:48:57 +00:00
pdf_file = ly_file.with_suffix(".pdf")
midi_file = ly_file.with_suffix(".mid")
2024-10-31 20:57:29 +00:00
# Compile the file
2024-12-19 12:48:57 +00:00
subprocess.run(
[lilypond.executable(), str(ly_file)], check=True, cwd=root_folder
)
2024-10-31 20:57:29 +00:00
# Create links to files
2024-12-19 12:48:57 +00:00
if (
not "http" in lollmsElfServer.config.host
and not "https" in lollmsElfServer.config.host
):
host = "http://" + lollmsElfServer.config.host
2024-10-31 20:57:29 +00:00
else:
host = lollmsElfServer.config.host
2024-12-19 12:48:57 +00:00
pdf_link = (
f"{host}:{lollmsElfServer.config.port}{discussion_path_to_url(pdf_file)}"
)
midi_link = (
f"{host}:{lollmsElfServer.config.port}{discussion_path_to_url(midi_file)}"
)
2024-10-31 20:57:29 +00:00
# Create output HTML
output = f"""
<div>
<h3>LilyPond Output:</h3>
<p><a href="{pdf_link}" target="_blank">View PDF Score</a></p>
<p><a href="{midi_link}" target="_blank">Download MIDI</a></p>
<embed src="{pdf_link}" type="application/pdf" width="100%" height="600px">
</div>
"""
execution_time = time.time() - start_time
return {"output": output, "execution_time": execution_time}
except Exception as ex:
trace = trace_exception(ex)
2024-12-19 12:48:57 +00:00
return {
"output": f"Error executing LilyPond code:\n{trace}",
"execution_time": 0,
}