Spaces:
Running on Zero
Running on Zero
File size: 2,954 Bytes
aa151d2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | """ABC notation utilities: MusicXML conversion and HTML visualization."""
import html as html_module
import json
import os
import subprocess
import tempfile
from config import ABC2XML_PATH, APP_DIR
def abc_to_musicxml_file(abc: str):
"""Convert ABC to MusicXML using abc2xml.py; return file path for download or None."""
if not (abc or "").strip():
return None
try:
result = subprocess.run(
[os.environ.get("PYTHON", "python"), ABC2XML_PATH, "-"],
input=(abc or "").strip().encode("utf-8"),
capture_output=True,
cwd=APP_DIR,
timeout=30,
)
if result.returncode != 0 or not result.stdout:
return None
xml_bytes = result.stdout
if isinstance(xml_bytes, bytes):
xml_str = xml_bytes.decode("utf-8", errors="replace")
else:
xml_str = xml_bytes
tmpdir = tempfile.mkdtemp(prefix="musicxml_")
score_path = os.path.join(tmpdir, "score.musicxml")
try:
with open(score_path, "w", encoding="utf-8") as f:
f.write(xml_str)
return score_path
except Exception:
try:
os.unlink(score_path)
except Exception:
pass
try:
os.rmdir(tmpdir)
except Exception:
pass
return None
except Exception:
return None
def abc_viz_html(abc: str) -> str:
"""Generate HTML with ABCJS for rendering ABC notation in Gradio."""
viz_abc = abc or ""
data_attr = html_module.escape(json.dumps(viz_abc), quote=True)
# Gradio strips <script> in gr.HTML; use iframe srcdoc so ABCJS runs inside the frame.
inner = (
'<!DOCTYPE html><html><head><meta charset="utf-8">'
'<style>body{overflow:auto;margin:0;} #abc-viz{width:100%;}</style></head><body>'
'<div id="abc-viz" data-abc="' + data_attr + '"></div>'
'<script src="https://cdnjs.cloudflare.com/ajax/libs/abcjs/6.4.0/abcjs-basic-min.js"><\x2fscript>'
'<script>'
'(function(){ var el=document.getElementById("abc-viz"); if(!el) return; '
'var run=function(){ try { var abc=JSON.parse(el.getAttribute("data-abc")); '
'if(typeof ABCJS!=="undefined"&&abc) ABCJS.renderAbc("abc-viz",abc,{responsive:"resize"}); } catch(e){ el.innerHTML="<span>Invalid ABC</span>"; } }; '
'if(typeof ABCJS!=="undefined") run(); else { var s=document.createElement("script"); '
's.src="https://cdnjs.cloudflare.com/ajax/libs/abcjs/6.4.0/abcjs-basic-min.js"; s.onload=run; document.head.appendChild(s); } })();'
'<\x2fscript></body></html>'
)
srcdoc_escaped = inner.replace("&", "&").replace('"', """)
return '<iframe sandbox="allow-scripts" title="ABC notation" style="width:100%;height:60vh;max-height:400px;display:block;" srcdoc="' + srcdoc_escaped + '"></iframe>'
|