Skip to content

Commit

Permalink
Merge pull request #404 from CPJKU/url_loading
Browse files Browse the repository at this point in the history
Utilities to load Scores from URL
  • Loading branch information
manoskary authored Jan 10, 2025
2 parents 9c31c5b + 108a4a6 commit 31faf74
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 10 deletions.
44 changes: 36 additions & 8 deletions partitura/io/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
"""
from typing import Union
import os

import urllib.request
from urllib.parse import urlparse
import tempfile
from .importmusicxml import load_musicxml
from .importmidi import load_score_midi, load_performance_midi
from .musescore import load_via_musescore
Expand All @@ -32,6 +34,14 @@ class NotSupportedFormatError(Exception):
pass


def is_url(input):
try:
result = urlparse(input)
return all([result.scheme, result.netloc])
except ValueError:
return False


@deprecated_alias(score_fn="filename")
@deprecated_parameter("ensure_list")
def load_score(filename: PathLike, force_note_ids="keep") -> Score:
Expand All @@ -57,11 +67,29 @@ def load_score(filename: PathLike, force_note_ids="keep") -> Score:
scr: :class:`partitura.score.Score`
A score instance.
"""
if is_url(filename):
url = filename
# Send a GET request to the URL
with urllib.request.urlopen(url) as response:
data = response.read()

# Extract the file extension from the URL
extension = os.path.splitext(url)[-1]

# Create a temporary file
temp_file = tempfile.NamedTemporaryFile(suffix=extension, delete=True)

# Write the content to the temporary file
with open(temp_file.name, 'wb') as f:
f.write(data)

filename = temp_file.name
else:
extension = os.path.splitext(filename)[-1].lower()

extension = os.path.splitext(filename)[-1].lower()
if extension in (".mxl", ".xml", ".musicxml"):
# Load MusicXML
return load_musicxml(
score = load_musicxml(
filename=filename,
force_note_ids=force_note_ids,
)
Expand All @@ -71,15 +99,15 @@ def load_score(filename: PathLike, force_note_ids="keep") -> Score:
assign_note_ids = False
else:
assign_note_ids = True
return load_score_midi(
score = load_score_midi(
filename=filename,
assign_note_ids=assign_note_ids,
)
elif extension in [".mei"]:
# Load MEI
return load_mei(filename=filename)
score = load_mei(filename=filename)
elif extension in [".kern", ".krn"]:
return load_kern(
score = load_kern(
filename=filename,
force_note_ids=force_note_ids,
)
Expand Down Expand Up @@ -107,7 +135,7 @@ def load_score(filename: PathLike, force_note_ids="keep") -> Score:
".gp",
]:
# Load MuseScore
return load_via_musescore(
score = load_via_musescore(
filename=filename,
force_note_ids=force_note_ids,
)
Expand All @@ -117,11 +145,11 @@ def load_score(filename: PathLike, force_note_ids="keep") -> Score:
filename=filename,
create_score=True,
)
return score
else:
raise NotSupportedFormatError(
f"{extension} file extension is not supported. If this should be supported, consider editing partitura/io/__init__.py file"
)
return score


def load_score_as_part(filename: PathLike) -> Part:
Expand Down
4 changes: 2 additions & 2 deletions partitura/score.py
Original file line number Diff line number Diff line change
Expand Up @@ -6062,8 +6062,8 @@ def process_local_key(loc_k_text, glob_k_text, return_step_alter=False):
"iii": Interval(3, "m"),
"iv": Interval(4, "P"),
"v": Interval(5, "P"),
"vi": Interval(6, "m"),
"vii": Interval(7, "m"),
"vi": Interval(6, "M"),
"vii": Interval(7, "M"),
"viio": Interval(7, "M"),
"N": Interval(2, "m"),
"iio": Interval(2, "M"),
Expand Down
26 changes: 26 additions & 0 deletions tests/test_urlload.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import unittest
from partitura import load_score
import numpy as np


class TestImport(unittest.TestCase):
def test_load_kern(self):
score = load_score("https://raw.githubusercontent.com/CPJKU/partitura/refs/heads/main/partitura/assets/score_example.krn")
note_array = score.note_array()
self.assertTrue(np.all(note_array["pitch"] == [69, 72, 76]))

def test_load_mei(self):
score = load_score("https://raw.githubusercontent.com/CPJKU/partitura/refs/heads/main/partitura/assets/score_example.mei")
note_array = score.note_array()
self.assertTrue(np.all(note_array["pitch"] == [69, 72, 76]))

def test_load_midi(self):
score = load_score("https://raw.githubusercontent.com/CPJKU/partitura/refs/heads/main/partitura/assets/score_example.mid")
note_array = score.note_array()
self.assertTrue(np.all(note_array["pitch"] == [69, 72, 76]))

def test_load_musicxml(self):
score = load_score("https://raw.githubusercontent.com/CPJKU/partitura/refs/heads/main/partitura/assets/score_example.musicxml")
note_array = score.note_array()
self.assertTrue(np.all(note_array["pitch"] == [69, 72, 76]))

0 comments on commit 31faf74

Please sign in to comment.