def test_create_no_language(self): """A musiccomposition can be missing a language value, and this should generate a valid mutation""" musiccomposition.mutation_create_music_composition( title="Das Lied von der Erde", contributor="https://www.cpdl.org", creator="https://www.upf.edu", source="https://www.cpdl.org/Das_Lied_von_der_Erde", format_="text/html", subject="Music Composition", inlanguage="de", name="The Song of the Earth" )
def create_musiccomposition(musiccomposition): musiccomposition["creator"] = CREATOR_URL mutation_create = mutation_musiccomposition.mutation_create_music_composition( **musiccomposition) resp = connection.submit_request(mutation_create) # TODO: If this query fails? return resp['data']['CreateMusicComposition']['identifier']
def test_create(self): expected = self.read_file(os.path.join(self.data_dir, "create_musiccomposition.txt")) created_musiccomposition = musiccomposition.mutation_create_music_composition( title="Das Lied von der Erde", contributor="https://www.cpdl.org", creator="https://www.upf.edu", source="https://www.cpdl.org/Das_Lied_von_der_Erde", format_="text/html", subject="Music Composition", language="en", inlanguage="de", name="The Song of the Earth" ) self.assert_queries_equal(created_musiccomposition, expected)
def test_create_all_arguments(self): created_musiccomposition = musiccomposition.mutation_create_music_composition( title="Das Lied von der Erde: I. Das Trinklied vom Jammer der Erde", contributor="https://musicbrainz.org", creator="https://www.upf.edu", source="https://musicbrainz.org/work/ff15c2ab-0775-3757-975a-331357299635", format_="text/html", subject="Music Composition", language="de", inlanguage="de", name="Das Lied von der Erde: I. Das Trinklied vom Jammer der Erde", description="First composition of a song-cycle by Mahler", position=1 ) expected = self.read_file(os.path.join(self.data_dir, "create_musiccomposition_complete.txt")) self.assert_queries_equal(created_musiccomposition, expected)
async def import_tracks(key: str): """ Imports audio fragments from Muziekweb for the key into the Trompa CE. """ print(f"Retrieving release info with key {key} from Muziekweb") # Get data from Muziekweb tracks, music_works, persons = get_mw_audio_1track(key) # tracks = get_mw_audio(key) if tracks is None or len(tracks) == 0: print(f"No track data received for {key}") return ##################################### # PERSONS # Loop the persons on all external links to add references for each CE_person ##################################### list_person_ids = list() for person in persons: person.identifier = await lookupIdentifier("Person", person.source) if person.identifier is not None: print(f"Updating person {person.identifier} in Trompa CE\n") response = await ce.connection.submit_query_async( mutation_update_person(**person.as_dict())) person.identifier = response["data"]["UpdatePerson"]["identifier"] list_person_ids.append(person.identifier) else: print("Inserting new person {} in Trompa CE\n".format(person.name)) response = await ce.connection.submit_query_async( mutation_create_person(**person.as_dict())) person.identifier = response["data"]["CreatePerson"]["identifier"] list_person_ids.append(person.identifier) print(f"Importing Persons for {key} done.") ##################################### # Linking PERSONS # Loop the person identifiers and link them ##################################### for from_id, to_id in itertools.permutations(list_person_ids, 2): query = mutation_person_add_exact_match_person(from_id, to_id) response = await ce.connection.submit_query_async(query) print(f" - Linking Person {from_id} to Person {to_id} done.") ##################################### # MUSICCOMPOSITION # Loop the music works to create the CE_MusicComposition on the CE ##################################### for work in music_works: work.identifier = await lookupIdentifier("MusicComposition", work.source) if work.identifier is not None: print(f"Updating work {work.identifier} in Trompa CE\n", end="") response = await ce.connection.submit_query_async( mutation_update_music_composition(**work.as_dict())) work.identifier = response["data"]["UpdateMusicComposition"][ "identifier"] else: print("Inserting new work {} in Trompa CE\n".format(work.name)) response = await ce.connection.submit_query_async( mutation_create_music_composition(**work.as_dict())) work.identifier = response["data"]["CreateMusicComposition"][ "identifier"] print(f"Importing music composition {work.identifier} done.\n") ##################################### # Linking PERSONS and MUSICCOMPOSITIONS # Loop the person identifiers and link them to music compositions ##################################### for person_id in list_person_ids: query = mutation_merge_music_composition_composer( work.identifier, person_id) response = await ce.connection.submit_query_async(query) print( f" - Linking Person {person_id} to MusicComposition {work.identifier} done.\n" ) ##################################### # AUDIOOBJECTS # Loop the tracks to create the CE_AudioObject on the CE ##################################### for track in tracks: track.identifier = await lookupIdentifier("AudioObject", track.source) if track.identifier is not None: print(f"Updating record {track.identifier} in Trompa CE\n") response = await ce.connection.submit_query_async( mutation_update_audioobject(**track.as_dict())) track.identifier = response["data"]["UpdateAudioObject"][ "identifier"] else: print("Inserting new track {} in Trompa CE\n".format(track.title)) response = await ce.connection.submit_query_async( mutation_create_audioobject(**track.as_dict())) track.identifier = response["data"]["CreateAudioObject"][ "identifier"] print(f"Importing tracks {track.identifier} done.\n") ##################################### # Linking MUSICCOMPOSITIONS and AUDIOOBJECTS # Loop the musicworks identifiers and link them to audioobjects ##################################### query = mutation_merge_audioobject_exampleofwork(track.identifier, work.identifier) response = await ce.connection.submit_query_async(query) print( f" - Linking MusicComposition {work.identifier} to AudioObject {track.identifier} done." )
async def import_tracks(key: str): """ Imports audio fragments from Muziekweb for the key into the Trompa CE. """ print(f"Retrieving release info with key {key} from Muziekweb") # Get data from Muziekweb audio_objects, music_recordings, music_works, persons, music_groups = get_mw_audio_1track( key) # tracks = get_mw_audio(key) if audio_objects is None or len(audio_objects) == 0: print(f"No track data received for {key}") return ##################################### # MUSICCOMPOSITION # Loop the music works to create the CE_MusicComposition on the CE ##################################### for work in music_works: work.identifier = await lookupIdentifier("MusicComposition", work.source) if work.identifier is not None: print(f"Updating work {work.identifier} in Trompa CE\n", end="") response = await ce.connection.submit_query_async( mutation_update_music_composition(**work.as_dict())) work.identifier = response["data"]["UpdateMusicComposition"][ "identifier"] else: print("Inserting new work {} in Trompa CE\n".format(work.name)) response = await ce.connection.submit_query_async( mutation_create_music_composition(**work.as_dict())) work.identifier = response["data"]["CreateMusicComposition"][ "identifier"] print(f"Importing music composition {work.identifier} done.\n") ##################################### # MUSICRECORDING # Loop the music recordings to create the CE_MusicRecording on the CE ##################################### for recording in music_recordings: recording.identifier = await lookupIdentifier("MusicRecording", recording.source) if recording.identifier is not None: print( f"Updating music recording {recording.identifier} in Trompa CE\n" ) response = await ce.connection.submit_query_async( mutation_update_musicrecording(**recording.as_dict())) recording.identifier = response["data"]["UpdateMusicRecording"][ "identifier"] else: print("Inserting new recording {} in Trompa CE\n".format( recording.title)) response = await ce.connection.submit_query_async( mutation_create_musicrecording(**recording.as_dict())) recording.identifier = response["data"]["CreateMusicRecording"][ "identifier"] print(f"Importing recordings {recording.identifier} done.\n") ##################################### # AUDIOOBJECTS # Loop the audio objects to create the CE_AudioObject on the CE ##################################### for audio in audio_objects: audio.identifier = await lookupIdentifier("AudioObject", audio.source) if audio.identifier is not None: print(f"Updating audio object {audio.identifier} in Trompa CE\n") response = await ce.connection.submit_query_async( mutation_update_audioobject(**audio.as_dict())) audio.identifier = response["data"]["UpdateAudioObject"][ "identifier"] else: print("Inserting new audio {} in Trompa CE\n".format(audio.title)) response = await ce.connection.submit_query_async( mutation_create_audioobject(**audio.as_dict())) audio.identifier = response["data"]["CreateAudioObject"][ "identifier"] print(f"Importing audio {audio.identifier} done.\n") ##################################### # Linking MUSICCOMPOSITIONS and MUSICRECORDING # Loop the musicworks identifiers and link them to audioobjects ##################################### query = mutation_merge_music_composition_recorded_as( work.identifier, recording.identifier) response = await ce.connection.submit_query_async(query) print( f" - Linking MusicComposition {work.identifier} to MusicRecording {recording.identifier} done." ) ##################################### # Linking MUSICRECORDING and AUDIOOBJECTS # Loop the musicworks identifiers and link them to audioobjects ##################################### query = mutation_merge_music_recording_audio(recording.identifier, audio.identifier) response = await ce.connection.submit_query_async(query) print( f" - Linking MusicRecording {recording.identifier} to AudioObject {audio.identifier} done." ) ##################################### # PERSONS # Loop the persons on all external links to add references for each CE_person ##################################### list_person_ids = list() for person in persons: person.identifier = await lookupIdentifier("Person", person.source) if person.identifier is not None: print(f"Updating person {person.identifier} in Trompa CE\n") response = await ce.connection.submit_query_async( mutation_update_person(**person.as_dict())) person.identifier = response["data"]["UpdatePerson"]["identifier"] list_person_ids.append(person.identifier) else: print("Inserting new person {} in Trompa CE\n".format(person.name)) response = await ce.connection.submit_query_async( mutation_create_person(**person.as_dict())) person.identifier = response["data"]["CreatePerson"]["identifier"] list_person_ids.append(person.identifier) if list_person_ids: print(f"Importing Persons for {key} done.") ##################################### # Linking PERSONS # Loop the person identifiers and link them ##################################### if not music_groups: for from_id, to_id in itertools.permutations(list_person_ids, 2): query = mutation_person_add_exact_match_person(from_id, to_id) response = await ce.connection.submit_query_async(query) print(f" - Linking Person {from_id} to Person {to_id} done.") ##################################### # Linking PERSONS and MUSICCOMPOSITIONS # Loop the person identifiers and link them to music compositions ##################################### for person_id in list_person_ids: query = mutation_merge_music_composition_composer( work.identifier, person_id) response = await ce.connection.submit_query_async(query) print( f" - Linking Person {person_id} to MusicComposition {work.identifier} done.\n" ) ##################################### # MUSIC GROUPS # Loop the Music Groups on all external links to add references for each CE_person ##################################### list_music_group_ids = list() for music_group in music_groups: music_group.identifier = await lookupIdentifier( "MusicGroup", music_group.source) if music_group.identifier is not None: print( f"Updating music group {music_group.identifier} in Trompa CE\n" ) response = await ce.connection.submit_query_async( mutation_update_musicgroup(**music_group.as_dict())) music_group.identifier = response["data"]["UpdateMusicGroup"][ "identifier"] list_music_group_ids.append(music_group.identifier) else: print("Inserting new music group {} in Trompa CE\n".format( music_group.name)) response = await ce.connection.submit_query_async( mutation_create_musicgroup(**music_group.as_dict())) music_group.identifier = response["data"]["CreateMusicGroup"][ "identifier"] list_music_group_ids.append(music_group.identifier) if list_music_group_ids: print(f"Importing Music Groups for {key} done.") ##################################### # Linking MUSIC GROUPS # Loop the music groups identifiers and link them ##################################### for from_id, to_id in itertools.permutations(list_music_group_ids, 2): query = mutation_musicgroup_add_exact_match_musicgroup(from_id, to_id) response = await ce.connection.submit_query_async(query) print( f" - Linking Music Group {from_id} to Music Group {to_id} done.") ##################################### # Linking MUSIC GROUPS and MUSICCOMPOSITIONS # Loop the music group identifiers and link them to music compositions ##################################### for music_group_id in list_music_group_ids: query = mutation_merge_music_composition_composer( work.identifier, music_group_id) response = await ce.connection.submit_query_async(query) print( f" - Linking MusicGroup {music_group_id} to MusicComposition {work.identifier} done.\n" ) ##################################### # Linking MUSIC GROUPS and PERSONS # Loop the music group identifiers and link them to person identifiers ##################################### for music_group_id in list_music_group_ids: for person_id in list_person_ids: query = mutation_merge_musicgroup_member(person_id, music_group_id) response = await ce.connection.submit_query_async(query) print( f" - Linking Person {person_id} to MusicGroup {music_group_id} done.\n" )
def main(print_queries: bool, submit_queries: bool): # A symphony mutation_symphony = musiccomposition.mutation_create_music_composition( # These 5 fields are required: # Who created the item in the CE, either a link to the version of the software, # or if not possible, https://trompamusic.eu creator="https://github.com/trompamusic/trompa-ce-client/tree/master/demo", # Who this data came from contributor="https://musicbrainz.org", # The specific page that this data came from source="https://musicbrainz.org/work/5b8cb51a-6b4f-48b7-888d-c7f1e812dfba", # The mimetype of `source` format_="text/html", # the html <title> of `source` title="Symphony no. 1 in D major “Titan” - MusicBrainz", name="Symphony no. 1 in D major “Titan”", language="en" ) # The first movement of the above symphony mutation_part = musiccomposition.mutation_create_music_composition( # These 5 fields are required: # Who created the item in the CE, either a link to the version of the software, # or if not possible, https://trompamusic.eu creator="https://github.com/trompamusic/trompa-ce-client/tree/master/demo", # Who this data came from contributor="https://musicbrainz.org", # The specific page that this data came from source="https://musicbrainz.org/work/f969bc33-3297-335b-9dcb-1840bfea4781", # The mimetype of `source` format_="text/html", # the html <title> of `source` title="Symphony no. 1 in D major “Titan”: I. Langsam. Schleppend - MusicBrainz", name="Symphony no. 1 in D major “Titan”: I. Langsam. Schleppend", language="en", # First movement - position 1 position=1 ) print("\nMusicComposition - symphony\n") if print_queries: print(mutation_symphony) if submit_queries: pass print("\nMusicComposition - movement\n") if print_queries: print(mutation_part) if submit_queries: pass # TODO: These ids are just for demonstration, ideally we would get them from the mutations and link the real items symphony_id = "ca75c580-104f-4701-8101-0a6023c791b9" part_id = "89a0319c-bd4b-4e19-b34e-528d3aba7cca" composer_id = "a6900369-b474-40d2-b8fc-724136b48bc0" # The composer is the composer of both the symphony and the movement mutation_symp_composer = musiccomposition.mutation_merge_music_composition_composer(symphony_id, composer_id) mutation_part_composer = musiccomposition.mutation_merge_music_composition_composer(part_id, composer_id) print("\nMusicComposition symphony - Person composer\n") if print_queries: print(mutation_symp_composer) if submit_queries: pass print("\nMusicComposition part - Person composer\n") if print_queries: print(mutation_part_composer) if submit_queries: pass # Mark that the movement is a part of the symphony # This is a property on CreativeWork, and has an inverse isPartOf mutation_has_part = musiccomposition.mutation_merge_music_composition_has_part(symphony_id, part_id) # This is a property on MusicComposition and is more specific, but has no inverse mutation_composition = musiccomposition.mutation_merge_music_composition_included_composition(symphony_id, part_id) print("\nMusicComposition hasPart\n") if print_queries: print(mutation_has_part) if submit_queries: pass print("\nMusicComposition includedComposition\n") if print_queries: print(mutation_composition) if submit_queries: pass """ query { MusicComposition(identifier:"3611b2c6-ea83-407f-881d-cc429e385b79") { identifier name source hasPart { ... on MusicComposition { identifier name source position } } includedComposition { ... on MusicComposition { identifier name source position } } composer { ... on Person { identifier name source } } } } query { MusicComposition(identifier:"1643bf5e-3040-475d-9f51-3e0c3a64452e") { identifier name source position isPartOf { ... on MusicComposition { identifier name source } } } } """ # Languages # MusicCompositions have 2 language fields, 'language', which is the language that `source` is written in, # and 'inLanguage`, which is the language that any lyrics are written in. In some cases we could have # two nodes referring to the same composition, but with a different name and language mutation_de = musiccomposition.mutation_create_music_composition( # These 5 fields are required: # Who created the item in the CE, either a link to the version of the software, # or if not possible, https://trompamusic.eu creator="https://github.com/trompamusic/trompa-ce-client/tree/master/demo", # Who this data came from contributor="https://musicbrainz.org", # The specific page that this data came from source="https://musicbrainz.org/work/14514e77-f06c-4d24-a4d5-9a5962acae64", # The mimetype of `source` format_="text/html", # the html <title> of `source` title="Das Lied von der Erde - MusicBrainz", name="Das Lied von der Erde", language="de", inlanguage="de" ) mutation_en = musiccomposition.mutation_create_music_composition( # These 5 fields are required: # Who created the item in the CE, either a link to the version of the software, # or if not possible, https://trompamusic.eu creator="https://github.com/trompamusic/trompa-ce-client/tree/master/demo", # Who this data came from contributor="https://musicbrainz.org", # The specific page that this data came from source="https://musicbrainz.org/work/14514e77-f06c-4d24-a4d5-9a5962acae64", # The mimetype of `source` format_="text/html", # the html <title> of `source` title="Das Lied von der Erde - MusicBrainz", name="The Song of the Earth", language="en", inlanguage="de" ) print("\nMusicComposition - de\n") if print_queries: print(mutation_de) if submit_queries: pass print("\nMusicComposition - en\n") if print_queries: print(mutation_en) if submit_queries: pass # These two compositions are the same thing, so we should link them as such # TODO: These ids are just for demonstration, ideally we would get them from the mutations and link the real items work_identifiers = ['c64d93b1-818b-4414-a359-8bf2de08d233', 'e0f2a11d-28c4-41dd-afab-58d490d1b00b'] print("\nMusicComposition - MusicComposition exactMatch\n") for fr, to in itertools.permutations(work_identifiers, 2): mutation_match = musiccomposition.mutation_merge_music_composition_exact_match(fr, to) if print_queries: print(mutation_match) if submit_queries: pass """
def main(print_queries: bool, submit_queries: bool): mutation_work = musiccomposition.mutation_create_music_composition( # These 5 fields are required: # Who created the item in the CE, either a link to the version of the software, # or if not possible, https://trompamusic.eu creator= "https://github.com/trompamusic/trompa-ce-client/tree/master/demo", # Who this data came from contributor="https://www.cpdl.org", # The specific page that this data came from source= "https://www.cpdl.org/wiki/index.php/A_este_sol_peregrino_(Tom%C3%A1s_de_Torrej%C3%B3n_y_Velasco)", # The mimetype of `source` format_="text/html", # the html <title> of `source` title="A este sol peregrino (Tomás de Torrejón y Velasco) - ChoralWiki", name="A este sol peregrino (Tomás de Torrejón y Velasco)", language="en", inlanguage="es") print("\nMusicComposition - work\n") if print_queries: print(mutation_work) if submit_queries: pass # PDF score from CPDL cpdl_pdf = mediaobject.mutation_create_media_object( # These 4 fields are required: # Who created the item in the CE, either a link to the version of the software, # or if not possible, https://trompamusic.eu creator= "https://github.com/trompamusic/trompa-ce-client/tree/master/demo", # Who this data came from contributor="https://www.cpdl.org", # The URL to a webpage that describes this MediaObject. CPDL Mediawiki has html pages for each file # If there is no associated webpage for this object, you can set it to the same value as `url` source= "https://www.cpdl.org/wiki/index.php/File:Torrejon-A_este_sol_peregrino.pdf", # The <title> of `source` title="File:Torrejon-A este sol peregrino.pdf - ChoralWiki", name="Torrejon-A este sol peregrino.pdf", # The mimetype of `source` format_="text/html", # Specifically for CPDL, we set URL to the same as `source` url= "https://www.cpdl.org/wiki/index.php/File:Torrejon-A_este_sol_peregrino.pdf", # A url that gives direct access to the bytes that make up this file. # In the case of CPDL we look this up by the API contenturl= "https://www.cpdl.org/wiki/images/b/b5/Torrejon-A_este_sol_peregrino.pdf", # mimetype of contenturl encodingformat="application/pdf", ) # MusicXML score from CPDL. The structure of the fields is the same as for PDF cpdl_musicxml = mediaobject.mutation_create_media_object( creator= "https://github.com/trompamusic/trompa-ce-client/tree/master/demo", # Who this data came from contributor="https://www.cpdl.org", # The URL to a webpage that describes this MediaObject. CPDL Mediawiki has html pages for each file # If there is no associated webpage for this object, you can set it to the same value as `url` source= "https://www.cpdl.org/wiki/index.php/File:Torrejon-A_este_sol_peregrino.mxl", # The <title> of `source` title="File:Torrejon-A_este_sol_peregrino.mxl - ChoralWiki", name="Torrejon-A_este_sol_peregrino.mxl", # The mimetype of `source` format_="text/html", # Specifically for CPDL, we set URL to the same as `source` url= "https://www.cpdl.org/wiki/index.php/File:Torrejon-A_este_sol_peregrino.mxl", # A url that gives direct access to the bytes that make up this file. # In the case of CPDL we look this up by the API contenturl= "https://www.cpdl.org/wiki/images/a/a3/Torrejon-A_este_sol_peregrino.mxl", # mimetype of contenturl encodingformat="application/vnd.recordare.musicxml+xml", ) print("\nMediaObject - CPDL PDF file\n") if print_queries: print(cpdl_pdf) if submit_queries: pass print("\nMediaObject - CPDL MusicXML file\n") if print_queries: print(cpdl_musicxml) if submit_queries: pass work_id = "64a1383c-a85b-4574-aa9c-eda917e5fd2c" pdf_id = "2799ea6c-161a-4379-883e-24e6cf117c11" xml_id = "5a6e8fb2-c922-49aa-89eb-07506210e697" # Both the PDF and MusicXML are examples of the MusicComposition example_of_work_pdf = mediaobject.mutation_merge_mediaobject_example_of_work( pdf_id, work_identifier=work_id) example_of_work_xml = mediaobject.mutation_merge_mediaobject_example_of_work( xml_id, work_identifier=work_id) print("\nMediaObject - MusicComposition exampleOfWork\n") if print_queries: print(example_of_work_pdf) print(example_of_work_xml) if submit_queries: pass # In the case of CPDL, we know that scores are written in an editor and then rendered to PDF. # Therefore, the PDF wasDerivedFrom the xml (http://www.w3.org/ns/prov#wasDerivedFrom) pdf_derived_from_xml = mediaobject.mutation_merge_media_object_wasderivedfrom( pdf_id, xml_id) print("\nMediaObject - MediaObject wasDerivedFrom\n") if print_queries: print(pdf_derived_from_xml) if submit_queries: pass # Audio rendering of a score cpdl_mp3 = mediaobject.mutation_create_media_object( creator= "https://github.com/trompamusic/trompa-ce-client/tree/master/demo", # Who this data came from contributor="https://www.voctrolabs.com/", name="Torrejon-A_este_sol_peregrino", title="Torrejon-A_este_sol_peregrino", # In the case that we don't have a distinct source or url, we can set # all fields to the same value as contenturl source= "https://my-bucket.s3.us-west-2.amazonaws.com/a_este_sol_peregrino.mp3", # The mimetype of `source` format_="audio/mpeg", url= "https://my-bucket.s3.us-west-2.amazonaws.com/a_este_sol_peregrino.mp3", # A url that gives direct access to the bytes that make up this file. contenturl= "https://my-bucket.s3.us-west-2.amazonaws.com/a_este_sol_peregrino.mp3", # mimetype of contenturl encodingformat="audio/mpeg", ) print("\nMediaObject - MP3 rendering\n") if print_queries: print(cpdl_mp3) if submit_queries: pass mp3_id = "5db9bb3b-2653-427a-968a-d446e657f305" # Like the PDF and XML, the mp3 is an Example of the composition example_of_work_mp3 = mediaobject.mutation_merge_mediaobject_example_of_work( mp3_id, work_identifier=work_id) print("\nMediaObject - MusicComposition exampleOfWork\n") if print_queries: print(example_of_work_mp3) if submit_queries: pass # Additionally, we should link the mp3 to the musicxml score that was used as the input. # For completeness we set two relations, schema:encoding and prov:wasDerivedFrom # TODO: The arguments for these two methods are reversed, I'm not sure if it's a good idea mp3_derived_from_xml = mediaobject.mutation_merge_media_object_wasderivedfrom( mp3_id, xml_id) xml_encoding_mp3 = mediaobject.mutation_merge_media_object_encoding( xml_id, mp3_id) print("\nMediaObject - MediaObject relations\n") if print_queries: print(mp3_derived_from_xml) print(xml_encoding_mp3) if submit_queries: pass ######### # IMSLP # ######### imslp_musiccomposition = musiccomposition.mutation_create_music_composition( creator= "https://github.com/trompamusic/trompa-ce-client/tree/master/demo", contributor="https://imslp.org", # The specific page that this data came from source= "https://imslp.org/wiki/Variations_and_Fugue_in_E-flat_major,_Op.35_(Beethoven,_Ludwig_van)", # The mimetype of `source` format_="text/html", # the html <title> of `source` title= "Variations and Fugue in E-flat major, Op.35 (Beethoven, Ludwig van) - IMSLP: Free Sheet Music PDF Download", name="Variations and Fugue in E-flat major, Op.35", language="en", ) # MusicXML score from IMSLP # TODO: Note that this isn't actually a score of the MusicComposition above, but is included as an example imslp_musicxml = mediaobject.mutation_create_media_object( creator= "https://github.com/trompamusic/trompa-ce-client/tree/master/demo", # Who this data came from contributor="https://imslp.org", # The URL to a webpage that describes this MediaObject. CPDL Mediawiki has html pages for each file # If there is no associated webpage for this object, you can set it to the same value as `url` source="https://imslp.org/wiki/File:PMLP580712-07_affer_opem.zip", # The <title> of `source` title= "File:PMLP580712-07 affer opem.zip - IMSLP: Free Sheet Music PDF Download", # The mimetype of `source` format_="text/html", name="PMLP580712-07_affer_opem.zip", # Specifically for IMSLP, we set URL to the "permalink" of this file, which is # its "reverse lookup" url, redirecting to the page of the composition with an anchor ref # to the file itself. In the case of this example, this is # https://imslp.org/wiki/Affer_opem_(Lange,_Gregor)#IMSLP359599 url="https://imslp.org/wiki/Special:ReverseLookup/359599", # A url that gives direct access to the bytes that make up this file. # In IMSLP, we don't link directly to files, because downloads on IMSLP are behind a disclaimer. # We expect that users would go from `source` and derive this themselves. # XML scores for IMSLP are often provided in ZIP files. We use the arcp hash-based identifier # (https://s11.no/2018/arcp.html#hash-based) to refer to a specific file inside the archive: # The sha256 of PMLP580712-07_affer_opem.zip is f0a962e51b53c9f5de92c13e191dc87cc0f2a435745911b4d58a52446299be16 # base64 is ZjBhOTYyZTUxYjUzYzlmNWRlOTJjMTNlMTkxZGM4N2NjMGYyYTQzNTc0NTkxMWI0ZDU4YTUyNDQ2Mjk5YmUxNg== # and the path to the xml file inside the zip archive is /07_affer_opem.xml contenturl= "arcp://ni,sha-256;ZjBhOTYyZTUxYjUzYzlmNWRlOTJjMTNlMTkxZGM4N2NjMGYyYTQzNTc0NTkxMWI0ZDU4YTUyNDQ2Mjk5YmUxNg==/07_affer_opem.xml", # mimetype of contenturl encodingformat="application/vnd.recordare.musicxml+xml", ) # PDF Score from IMSLP imslp_pdf = mediaobject.mutation_create_media_object( creator= "https://github.com/trompamusic/trompa-ce-client/tree/master/demo", # Who this data came from contributor="https://imslp.org", # The URL to a webpage that describes this MediaObject. CPDL Mediawiki has html pages for each file # If there is no associated webpage for this object, you can set it to the same value as `url` source= "https://imslp.org/wiki/File:PMLP05827-Beethoven_Werke_Breitkopf_Serie_17_No_163_Op_35.pdf", # The <title> of `source` title= "File:PMLP05827-Beethoven Werke Breitkopf Serie 17 No 163 Op 35.pdf - IMSLP: Free Sheet Music PDF Download", # The mimetype of `source` format_="text/html", name="PMLP05827-Beethoven Werke Breitkopf Serie 17 No 163 Op 35.pdf", # Specifically for IMSLP, we set URL to the "permalink" of this file, which is # its "reverse lookup" url, redirecting to the page of the composition with an anchor ref # to the file itself. In the case of this example, this is # https://imslp.org/wiki/Variations_and_Fugue_in_E-flat_major,_Op.35_(Beethoven,_Ludwig_van)#IMSLP52946 url="https://imslp.org/wiki/Special:ReverseLookup/52946", # In IMSLP, we don't link directly to files with contenturl, because downloads on IMSLP are behind a disclaimer. # We expect that users would go from `source` and derive this themselves. # Because of this, we don't include the contenturl field ) # Manually created MEI score imslp_mei = mediaobject.mutation_create_media_object( creator= "https://github.com/trompamusic/trompa-ce-client/tree/master/demo", # Who this data came from contributor="https://iwk.mdw.ac.at", # URL on the web that matches contentUrl source= "https://github.com/trompamusic-encodings/Beethoven_Op35_BreitkopfHaertel/blob/master/Beethoven_Op35.mei", # The <title> of `source` title= "Beethoven_Op35_BreitkopfHaertel/Beethoven_Op35.mei at master · trompamusic-encodings/Beethoven_Op35_BreitkopfHaertel", # The mimetype of `source` format_="text/html", name="Beethoven_Op35.mei", # The page that describes the resource url= "https://github.com/trompamusic-encodings/Beethoven_WoO80_BreitkopfHaertel", contenturl= "https://raw.githubusercontent.com/trompamusic-encodings/Beethoven_Op35_BreitkopfHaertel/master/Beethoven_Op35.mei" ) print("\nIMSLP MusicComposition and MediaObjects\n") if print_queries: print(imslp_musiccomposition) print(imslp_pdf) print(imslp_musicxml) print(imslp_mei) if submit_queries: pass work_id = "ddcaf601-80ea-49a9-ba7e-7f27b37da512" pdf_id = "a0ea5add-e30a-4fcc-ace3-25c6b8d2d307" xml_id = "66e70b8d-9d45-499a-ad91-1967caf66967" mei_id = "6d5491f7-6f74-4e77-814a-9f8ce4555a93" # All of the MediaObjects are examples of the MusicComposition example_of_work_pdf = mediaobject.mutation_merge_mediaobject_example_of_work( pdf_id, work_identifier=work_id) example_of_work_xml = mediaobject.mutation_merge_mediaobject_example_of_work( xml_id, work_identifier=work_id) example_of_work_mei = mediaobject.mutation_merge_mediaobject_example_of_work( mei_id, work_identifier=work_id) print("\nMediaObject - MusicComposition exampleOfWork\n") if print_queries: print(example_of_work_pdf) print(example_of_work_xml) print(example_of_work_mei) if submit_queries: pass # Add a relation between the XML and PDF only if you know that it is valid (see CPDL) # The MEI was created by transcribing the PDF, therefore it is is an encoding of the PDF pdf_encoding_mei = mediaobject.mutation_merge_media_object_encoding( pdf_id, mediaobject_derivative_identifier=mei_id) print("\nMediaObject - MediaObject encoding\n") if print_queries: print(pdf_encoding_mei) if submit_queries: pass