SHIKARICHACHA commited on
Commit
cfdf6fe
·
verified ·
1 Parent(s): 83dd0d8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +21 -111
app.py CHANGED
@@ -21,7 +21,6 @@ Major updates:
21
  import sys
22
  import subprocess
23
  from typing import Dict, Optional, Tuple, List
24
- import os
25
 
26
  def install(packages: List[str]):
27
  for package in packages:
@@ -37,25 +36,6 @@ install([
37
  "uuid", "datetime"
38
  ])
39
 
40
- # Download VexFlow for local use if it doesn't exist
41
- def download_vexflow():
42
- static_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "static")
43
- os.makedirs(static_dir, exist_ok=True)
44
- vexflow_path = os.path.join(static_dir, "vexflow.js")
45
-
46
- if not os.path.exists(vexflow_path):
47
- try:
48
- import requests
49
- print("Downloading VexFlow for local use...")
50
- response = requests.get("https://cdn.jsdelivr.net/npm/[email protected]/build/cjs/vexflow.js")
51
- with open(vexflow_path, "wb") as f:
52
- f.write(response.content)
53
- print("VexFlow downloaded successfully.")
54
- except Exception as e:
55
- print(f"Error downloading VexFlow: {e}")
56
-
57
- download_vexflow()
58
-
59
  # -----------------------------------------------------------------------------
60
  # 2. Static imports
61
  # -----------------------------------------------------------------------------
@@ -811,27 +791,8 @@ def create_vexflow_notation(json_data, time_sig, key_sig):
811
  <html>
812
  <head>
813
  <meta charset="utf-8">
814
- <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net https://unpkg.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self' https://cdn.jsdelivr.net https://unpkg.com">
815
  <title>Music Notation</title>
816
- <script src="https://cdn.jsdelivr.net/npm/[email protected]/build/cjs/vexflow.js" integrity="sha384-Ot+lQJkqRGSzafs+z5wJrJUJmTY1+LZEUmNt5XJ5aPsj+RMc4XHmXqxNAYYoZ+e" crossorigin="anonymous"></script>
817
- <script>
818
- // Fallback if the CDN fails
819
- window.addEventListener('error', function(e) {{
820
- if (e.target.src && e.target.src.includes('vexflow')) {{
821
- console.log('VexFlow CDN failed, loading local fallback');
822
- var fallbackScript = document.createElement('script');
823
- // Try local copy first, then unpkg as second fallback
824
- fallbackScript.src = '/static/vexflow.js';
825
- fallbackScript.onerror = function() {{
826
- console.log('Local VexFlow failed, trying unpkg');
827
- var unpkgScript = document.createElement('script');
828
- unpkgScript.src = 'https://unpkg.com/[email protected]/build/cjs/vexflow.js';
829
- document.head.appendChild(unpkgScript);
830
- }};
831
- document.head.appendChild(fallbackScript);
832
- }}
833
- }}, true);
834
- </script>
835
  <style>
836
  #output {{width: 100%; overflow: auto;}}
837
  body {{font-family: Arial, sans-serif;}}
@@ -839,18 +800,18 @@ def create_vexflow_notation(json_data, time_sig, key_sig):
839
  </style>
840
  </head>
841
  <body>
842
- <h2>Exercise in {{key_sig}}, {{time_sig}}</h2>
843
  <div id="output"></div>
844
  <script>
845
  const {{Factory, EasyScore, System}} = Vex.Flow;
846
 
847
  // Create VexFlow factory and context
848
- const vf = new Factory({renderer: {elementId: 'output', width: 1200, height: 400}});
849
  const score = vf.EasyScore();
850
  const system = vf.System();
851
 
852
  // Parse notes from JSON
853
- const jsonData = {{json.dumps(parsed)}};
854
 
855
  // Convert to VexFlow notation
856
  let vexNotes = [];
@@ -884,7 +845,7 @@ def create_vexflow_notation(json_data, time_sig, key_sig):
884
  let vexNote;
885
 
886
  if (isRest) {{
887
- vexNote = `B4/${durationToVex(duration)}/r`;
888
  }} else {{
889
  // Convert scientific notation to VexFlow format
890
  // VexFlow uses lowercase for note names
@@ -892,10 +853,10 @@ def create_vexflow_notation(json_data, time_sig, key_sig):
892
  const match = noteName.match(noteRegex);
893
  if (match) {{
894
  const [_, pitch, octave] = match;
895
- vexNote = `${pitch.toLowerCase()}${octave}/${durationToVex(duration)}`;
896
  }} else {{
897
  // Default if parsing fails
898
- vexNote = `c4/${durationToVex(duration)}`;
899
  }}
900
  }}
901
 
@@ -919,65 +880,26 @@ def create_vexflow_notation(json_data, time_sig, key_sig):
919
  const staves = [];
920
  const measuresPerLine = 4;
921
 
922
- // Create both treble and bass clef staves
923
  for (let i = 0; i < vexNotes.length; i += measuresPerLine) {{
 
924
  const lineNotes = vexNotes.slice(i, i + measuresPerLine);
925
 
926
- // Create a new system for each line with increased height for two staves
927
- const lineSystem = vf.System({{width: 1100, spaceBetweenStaves: 10}});
928
 
929
- // Create treble clef stave
930
- const trebleStave = lineSystem.addStave({{
931
- voices: []
932
- }}).addClef('treble');
933
-
934
- // Create bass clef stave
935
- const bassStave = lineSystem.addStave({{
936
- voices: []
937
- }}).addClef('bass');
938
-
939
- // Add time signature and key to first system
940
- if (i === 0) {{
941
- trebleStave.addTimeSignature(timeSignature);
942
- trebleStave.addKeySignature("{{key_sig.split()[0]}}");
943
- bassStave.addTimeSignature(timeSignature);
944
- bassStave.addKeySignature("{{key_sig.split()[0]}}");
945
- }}
946
-
947
- // Add notes to treble stave
948
- lineNotes.forEach((measure, index) => {
949
- trebleStave.addVoice(
950
- score.voice(score.notes(measure.join(', ')))
951
- );
952
- });
953
-
954
- // Add same notes to bass stave but an octave lower
955
  lineNotes.forEach((measure, index) => {{
956
- // Convert notes to bass clef (one octave lower)
957
- const bassNotes = measure.map(note => {{
958
- // Skip rests
959
- if (note.includes('/r')) return note;
960
-
961
- // Extract note and duration
962
- const [notePart, durationPart] = note.split('/');
963
-
964
- // Lower the octave for bass clef if possible
965
- if (notePart.match(/[a-g][#b]?\d/)) {{
966
- const noteChar = notePart.charAt(0);
967
- const accidental = notePart.match(/[#b]/) ? notePart.match(/[#b]/)[0] : '';
968
- const octave = parseInt(notePart.match(/\d/)[0]);
969
-
970
- // Lower octave by 2 for bass clef
971
- const newOctave = Math.max(2, octave - 2);
972
- return `${noteChar}${accidental}${newOctave}/${durationPart}`;
973
- }}
974
-
975
- return note;
976
  }});
977
 
978
- bassStave.addVoice(
979
- score.voice(score.notes(bassNotes.join(', ')))
980
- );
 
 
981
  }});
982
 
983
  lineSystem.addConnector("singleRight");
@@ -1374,18 +1296,6 @@ def create_ui() -> gr.Blocks:
1374
  # -----------------------------------------------------------------------------
1375
  # 14. Entry point
1376
  # -----------------------------------------------------------------------------
1377
- def is_running_on_huggingface():
1378
- """Check if the app is running on Hugging Face Spaces"""
1379
- return os.environ.get('SPACE_ID') is not None or os.environ.get('SYSTEM') == 'spaces'
1380
-
1381
  if __name__ == "__main__":
1382
  demo = create_ui()
1383
-
1384
- # Configure based on environment
1385
- if is_running_on_huggingface():
1386
- print("Running on Hugging Face Spaces")
1387
- # Configure for Hugging Face Spaces
1388
- demo.launch(share=False, server_name="0.0.0.0", server_port=7860, allowed_paths=["static", "temp_audio"])
1389
- else:
1390
- # Local development
1391
- demo.launch()
 
21
  import sys
22
  import subprocess
23
  from typing import Dict, Optional, Tuple, List
 
24
 
25
  def install(packages: List[str]):
26
  for package in packages:
 
36
  "uuid", "datetime"
37
  ])
38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  # -----------------------------------------------------------------------------
40
  # 2. Static imports
41
  # -----------------------------------------------------------------------------
 
791
  <html>
792
  <head>
793
  <meta charset="utf-8">
 
794
  <title>Music Notation</title>
795
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/build/cjs/vexflow.js"></script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
796
  <style>
797
  #output {{width: 100%; overflow: auto;}}
798
  body {{font-family: Arial, sans-serif;}}
 
800
  </style>
801
  </head>
802
  <body>
803
+ <h2>Exercise in {key_sig}, {time_sig}</h2>
804
  <div id="output"></div>
805
  <script>
806
  const {{Factory, EasyScore, System}} = Vex.Flow;
807
 
808
  // Create VexFlow factory and context
809
+ const vf = new Factory({{renderer: {{elementId: 'output', width: 1200, height: 200}}}});
810
  const score = vf.EasyScore();
811
  const system = vf.System();
812
 
813
  // Parse notes from JSON
814
+ const jsonData = {json.dumps(parsed)};
815
 
816
  // Convert to VexFlow notation
817
  let vexNotes = [];
 
845
  let vexNote;
846
 
847
  if (isRest) {{
848
+ vexNote = `B4/${{durationToVex(duration)}}/r`;
849
  }} else {{
850
  // Convert scientific notation to VexFlow format
851
  // VexFlow uses lowercase for note names
 
853
  const match = noteName.match(noteRegex);
854
  if (match) {{
855
  const [_, pitch, octave] = match;
856
+ vexNote = `${{pitch.toLowerCase()}}${{octave}}/${{durationToVex(duration)}}`;
857
  }} else {{
858
  // Default if parsing fails
859
+ vexNote = `c4/${{durationToVex(duration)}}`;
860
  }}
861
  }}
862
 
 
880
  const staves = [];
881
  const measuresPerLine = 4;
882
 
 
883
  for (let i = 0; i < vexNotes.length; i += measuresPerLine) {{
884
+ const lineStaves = [];
885
  const lineNotes = vexNotes.slice(i, i + measuresPerLine);
886
 
887
+ // Create a new system for each line
888
+ const lineSystem = vf.System({{width: 1100}});
889
 
890
+ // Add staves for each measure in the line
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
891
  lineNotes.forEach((measure, index) => {{
892
+ const stave = lineSystem.addStave({{
893
+ voices: [
894
+ score.voice(score.notes(measure.join(', ')))
895
+ ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
896
  }});
897
 
898
+ // Add time signature and key to first measure of first line
899
+ if (i === 0 && index === 0) {{
900
+ stave.addTimeSignature(timeSignature);
901
+ stave.addKeySignature("{key_sig.split()[0]}");
902
+ }}
903
  }});
904
 
905
  lineSystem.addConnector("singleRight");
 
1296
  # -----------------------------------------------------------------------------
1297
  # 14. Entry point
1298
  # -----------------------------------------------------------------------------
 
 
 
 
1299
  if __name__ == "__main__":
1300
  demo = create_ui()
1301
+ demo.launch()