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
Example #4
0
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
Example #5
0
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'])
Example #10
0
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'])
Example #13
0
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
Example #15
0
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")
Example #18
0
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
Example #20
0
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