def get_or_create_verovio_application(): creator = "https://github.com/trompamusic/ce-data-import/tree/master/algorithms/mxml-to-mei" source = "https://www.verovio.org" run = subprocess.run(['verovio', '-v'], check=True, capture_output=True) version = str(run.stdout, "utf-8").strip() query_application = queries_application.query_softwareapplication( creator=creator, source=source, softwareversion=version) app_response = submit_query(query_application, auth_required=True) app = app_response.get('data', {}).get('SoftwareApplication', []) if app: return app[0]["identifier"] else: mutation_create = mutations_application.mutation_create_application( name="Verovio", contributor=source, creator=creator, source=source, language="en", title="Verovio", softwareversion=version) create_response = submit_query(mutation_create, auth_required=True) app = create_response.get('data', {}).get('CreateSoftwareApplication', {}) return app["identifier"]
def create_listitem_node(name: str, contributor: str = None, creator: str = None, description: str = None, position: Optional[int] = None): """Create a ListItem object and return the corresponding identifier. (https://schema.org/ListItem) Arguments: name: The name of the ListItem object. contributor: A person, an organization, or a service responsible for contributing the ListItem to the web resource. creator: The person, organization or service who created the ListItem. description: The description of the ItemList object position: the position of the ListItem Raises: QueryException if the query fails to execute Returns: The identifier of the ListItem object created """ mutation = mutations_itemlist.mutation_create_listitem( contributor=contributor, name=name, creator=creator, description=description, position=position) resp = submit_query(mutation) result = resp.get("data", {}).get("CreateListItem") if result: element_id = result["identifier"] else: raise QueryException(resp['errors']) return element_id
def create_mei_node(meiurl): filename = os.path.basename(meiurl) imslp_mei = mediaobject.mutation_create_media_object( creator= "https://github.com/trompamusic/ce-data-import/tree/master/algorithms/mxml-to-mei", # Who this data came from contributor="https://trompamusic.eu", # URL on the web that matches contentUrl source=meiurl, # The <title> of `source` title=filename, # The mimetype of `source` format_="application/mei+xml", name=filename, # The page that describes the resource url=meiurl, contenturl=meiurl, encodingformat="application/mei+xml") mei_response = submit_query(imslp_mei, auth_required=True) mei = mei_response.get('data', {}).get('CreateMediaObject', {}) if mei: return mei["identifier"] else: return None
def send_query_and_get_id(query, return_type=None): response = connection.submit_query(query, auth_required=True) data = response.get("data") if data and return_type: item = data.get(return_type) if item: if isinstance(item, list): return [i["identifier"] for i in item] return item["identifier"] return None
def get_ids(): query = """ query { ThingInterface { identifier } } """ response = connection.submit_query(query) data = response["data"]["ThingInterface"] ids = [i["identifier"] for i in data] return ids
def mei_for_xml_exists(mediaobject_id): mo_query = query_mediaobject( filter_={ "wasDerivedFrom": { "identifier": mediaobject_id }, "format": "application/mei+xml" }) mo_response = submit_query(mo_query) mo = mo_response.get('data', {}).get('MediaObject', []) if mo: return True else: return False
def convert_ce_node(mediaobject_id): """Take a MediaObject Ensure that encodingFormat is one of the musicxml ones - if the contenturl is a content url, then find it (special-case imslp), otherwise just download it - do conversion - create mediaobject, link to input file, link to composition, upload to s3""" if mei_for_xml_exists(mediaobject_id): print("An MEI file derived from this MusicXML already exists", file=sys.stderr) return return_items = [ "identifier", "name", "contributor", "url", "contentUrl", { "exampleOfWork": ["identifier"] } ] mo_query = query_mediaobject(identifier=mediaobject_id, return_items=return_items) mo_response = submit_query(mo_query) mo = mo_response.get('data', {}).get('MediaObject', []) if mo: mo = mo[0] mo_id = mo['identifier'] mo_contributor = mo['contributor'] work = mo['exampleOfWork'] if not work: print('Unexpectedly this MediaObject has no exampleOfWork', file=sys.stderr) return work_id = work[0]['identifier'] if mo_contributor == "https://cpdl.org": mei_id, used_musescore = process_cpdl(mo) elif mo_contributor == "https://imslp.org": mei_id, used_musescore = process_imslp(mo) else: print("Contributor isn't one of cpdl or imslp", file=sys.stderr) return if mei_id: join_existing_and_new_mei(musiccomposition_id=work_id, mxml_mo_id=mo_id, mei_mo_id=mei_id, used_musescore=used_musescore) else: print("Failed to convert file", file=sys.stderr) else: print("Cannot find a MediaObject", file=sys.stderr) return
def merge_itemlist_itemlistelement_nodes(itemlist_id: str, element_id: str): """Add a ThingInterface in an ItemList object based on the identifiers. (https://schema.org/itemListElement) Arguments: itemlist_id: The unique identifier of the ItemList object. element_id: The unique identifier of the ThingInterface object. Raises: QueryException if the query fails to execute """ mutation = mutations_itemlist.mutation_add_itemlist_itemlist_element( itemlist_id=itemlist_id, element_id=element_id) resp = submit_query(mutation) result = resp.get("data", {}).get("MergeItemListItemListElement") if not result: raise QueryException(resp['errors'])
def merge_sequence_listitem_nextitem_nodes(listitem_ids: list): """Add a sequence of NextItem to a ListItem objects based on the identifiers. (https://schema.org/nextItem) Arguments: listitem_ids: The list of unique identifiers of the ListItem objects. Raises: QueryException if the query fails to execute """ mutation = mutations_itemlist.mutation_sequence_add_listitem_nextitem( listitem_ids=listitem_ids) resp = submit_query(mutation) result = resp.get("data", {}) if not result: raise QueryException(resp['errors'])
def create_musicplaylist_node(title: str, contributor: str, creator: str, source: str, format_: str, name: str = None, language: str = None, num_tracks: int = None): """Create a MusicPlaylist object and return the corresponding identifier. (https://schema.org/MusicPlaylist) Arguments: name: The name of the MusicPlaylist object. creator: The person, organization or service who created the thing the web resource is about. contributor: A person, an organization, or a service responsible f for contributing the MusicPlaylist to the web resource. This can be either a name or a base URL. format_: A MimeType of the format of the page describing the MusicPlaylist. source: The URL of the web resource about this MusicPlaylist. title: The title of the resource indicated by `source` numTracks: The number of tracks in the MusicPlaylist Raises: QueryException if the query fails to execute Returns: The identifier of the MusicPlaylist object created """ mutation = mutations_playlist.mutation_create_musicplaylist( title=title, contributor=contributor, creator=creator, source=source, format_=format_, name=name, language=language, num_tracks=num_tracks) resp = submit_query(mutation) result = resp.get("data", {}).get("CreateMusicPlaylist") if result: playlist_id = result["identifier"] else: raise QueryException(resp['errors']) return playlist_id
def update_listitem_position(listitem_id: str, position: int): """ Submit a mutation which changes the value of the position field on a given ListItem Arguments: listitem_id: the CE identifier of a ListItem position: The value to set the position field to Raises: QueryException if the query fails to execute """ mutation = mutations_itemlist.mutation_update_listitem( identifier=listitem_id, position=position) resp = submit_query(mutation) result = resp.get("data", {}).get("UpdateListItem") if not result: raise QueryException(resp['errors'])
def merge_listitem_nextitem_nodes(listitem_id: str, nextitem_id: str): """Add a NextItem to a ListItem object based on the identifier. (https://schema.org/nextItem) Arguments: listitem_id: The unique identifier of the ListItem object. nextitem_id: The unique identifier of the NextItem object. Raises: QueryException if the query fails to execute """ mutation = mutations_itemlist.mutation_add_listitem_nextitem( listitem_id=listitem_id, nextitem_id=nextitem_id) resp = submit_query(mutation) result = resp.get("data", {}).get("MergeListItemNextItem") if not result: raise QueryException(resp['errors'])
def merge_musicplaylist_itemlist(playlist_id: str, itemlist_id: str): """Add a ItemList to a MusicPlaylist based on the identifiers. (https://schema.org/MusicPlaylist) Arguments: playlist_id: the MusicPlaylist identifier. itemlist_id: the ItemList identifier. Raises: QueryException if the query fails to execute """ mutation = mutations_playlist.mutation_merge_musicplaylist_itemlist( playlist_identifier=playlist_id, itemlist_identifier=itemlist_id) resp = submit_query(mutation) result = resp.get("data", {}) if not result: raise QueryException(resp['errors'])
def itemlist_node_exists(itemlist_id: str): """ Check if ItemList already exists in the CE Arguments: itemlist_id: The unique identifiers of the ItemList object Raises: QueryException if the query fails to execute Return: True if ListItem object exists """ query = query_itemlist(identifier=itemlist_id) resp = submit_query(query) result = resp.get("data", {}).get("ItemList") if not result: raise QueryException(resp['errors']) else: return result
def create_blank_mei_node(): """Create a MediaObject that we want to use to store an MEI file, but don't add any content to it. This is so that we can get the identifier to name the file in the local filesystem.""" imslp_mei = mediaobject.mutation_create_media_object( creator= "https://github.com/trompamusic/ce-data-import/tree/master/algorithms/mxml-to-mei", # Who this data came from contributor="https://trompamusic.eu", # These values must be set, but we'll update them later in update_mei_node title="", source="", format_="/") mei_response = submit_query(imslp_mei, auth_required=True) mei = mei_response.get('data', {}).get('CreateMediaObject', {}) if mei: return mei["identifier"] else: return None
def merge_sequence_listitem_item_nodes(listitem_ids: list, item_ids: list): """Add a sequence of Items to a ListItems objects based on the identifiers. (https://schema.org/item) Arguments: listitem_ids: The list of unique identifier of the ListItem object. item_ids: The list of unique identifier of the Item object. Raises: QueryException if the query fails to execute ValueError if not all the Items passed as input are found """ mutation = mutations_itemlist.mutation_sequence_add_listitem_item( listitem_ids=listitem_ids, item_ids=item_ids) resp = submit_query(mutation) result = resp.get("data", {}) if not result: raise QueryException(resp['errors']) elif len(result.keys()) != len(listitem_ids): raise ValueError( "Number of Item objects founds does not match with input list")
def merge_sequence_itemlist_itemlistelement_nodes(itemlist_id: str, element_ids: list): """Add a sequence of ListItem objects to a ItemList object. Arguments: itemlist_id: The unique identifier of the ItemList object. element_ids: The list of unique identifier of the ThingInterface object. Raises: QueryException if the query fails to execute ValueError if not all the ListItems passed as input are found """ mutation = mutations_itemlist.mutation_sequence_add_itemlist_itemlist_element( itemlist_id=itemlist_id, element_ids=element_ids) resp = submit_query(mutation) result = resp.get("data", {}) if not result: raise QueryException(resp['errors']) elif len(result.keys()) != len(element_ids): raise ValueError( "Number of ListItem objects founds does not match with input list")
def join_existing_and_new_mei(musiccomposition_id, mxml_mo_id, mei_mo_id, used_musescore: bool): """ Indicate that the MEI is an exampleOfWork of the composition That the MEI wasDerivedFrom the MXML That the MEI used verovio to create it """ application_id = get_or_create_verovio_application() example_mutation = mediaobject.mutation_merge_mediaobject_example_of_work( mei_mo_id, work_identifier=musiccomposition_id) submit_query(example_mutation, auth_required=True) derivedfrom_mutation = mediaobject.mutation_merge_media_object_wasderivedfrom( mei_mo_id, mxml_mo_id) submit_query(derivedfrom_mutation, auth_required=True) used_mutation = mediaobject.mutation_add_media_object_used( mei_mo_id, application_id) submit_query(used_mutation, auth_required=True) if used_musescore: musescore_application_id = get_or_create_musescore_application() used_mutation = mediaobject.mutation_add_media_object_used( mei_mo_id, musescore_application_id) submit_query(used_mutation, auth_required=True)
def get_nonexistent_listitem_nodes(item_ids: list): """ Check if Items already exist in the CE Arguments: item_ids: The list of unique identifiers of the Item objects Raises: QueryException if the query fails to execute Return: Set of identifiers not found """ query = query_listitems(identifiers=item_ids) resp = submit_query(query) result = resp.get("data", {}).get("ThingInterface") not_found = set() if not result: raise QueryException(resp['errors']) elif len(result) != len(item_ids): not_found = set(item_ids) - set( [item['identifier'] for item in result]) return not_found
def update_mei_node(mei_id, meiurl): filename = os.path.basename(meiurl) """Given an MEI MediaObject node id, update it to add the URL """ imslp_mei = mediaobject.mutation_update_media_object( identifier=mei_id, # URL on the web that matches contentUrl source=meiurl, # The <title> of `source` title=filename, # The mimetype of `source` format_="application/mei+xml", name=filename, # The page that describes the resource url=meiurl, contenturl=meiurl, encodingformat="application/mei+xml") mei_response = submit_query(imslp_mei, auth_required=True) mei = mei_response.get('data', {}).get('UpdateMediaObject', {}) if mei: return mei["identifier"] else: return None
def create_itemlist_node(name: str, contributor: str = None, creator: str = None, description: str = None, ordered: bool = False): """Create a ItemList object and return the corresponding identifier. (https://schema.org/ItemList) Arguments: name: The name of the ItemList object. contributor: A person, an organization, or a service responsible for contributing the ItemList to the web resource. creator: The person, organization or service who created the ItemList. description: The description of the ItemList object ordered: The type of ordering for the list (ascending, descending, unordered, ordered) Raises: QueryException if the query fails to execute Returns: The identifier of the ItemList object created """ itemlistorder = ItemListOrderType.ItemListUnordered if ordered: itemlistorder = ItemListOrderType.ItemListOrderAscending mutation = mutations_itemlist.mutation_create_itemlist( contributor=contributor, creator=creator, name=name, itemlistorder=itemlistorder, description=description) resp = submit_query(mutation) result = resp.get("data", {}).get("CreateItemList") if result: itemlist_id = result["identifier"] else: raise QueryException(resp['errors']) return itemlist_id
def create_sequence_listitem_nodes(name: str, listitems: list, ids_mode: bool, contributor: str): """Create a sequence of ListItem object and return the corresponding identifiers. (https://schema.org/ListItem) Arguments: listitems: the ListItems objects to create ids_mode: the type of Items to create (from ID or from string value) contributor: A person, an organization, or a service responsible for contributing the ListItem to the web resource. name: The name of the ListItem object. Raises: QueryException if the query fails to execute Returns: The identifiers of the ListItem objects created. """ if not ids_mode: description = [item for item in listitems] else: description = [None for item in listitems] mutation = mutations_itemlist.mutation_sequence_create_listitem( name=name, listitems=listitems, description=description, contributor=contributor) resp = submit_query(mutation) result = resp.get("data", {}) if len(result.keys()) != len(listitems): raise QueryException(resp['errors']) else: listitems_ids = [ result[listalias]['identifier'] for listalias in result ] return listitems_ids