Esempio n. 1
0
def insertedmaterial(mydb, cursor, cursorupdate):

    graph = Graph() # graph for the dataset
    docgraph1 = Graph() # graph for the documentation drawing
    docgraph2 = Graph()  # graph for the documentation drawing
    docgraph3 = Graph()  # graph for the documentation drawing
    # add namespaces
    graph = apply_namespaces(graph)
    docgraph1 = apply_namespaces(docgraph1)
    docgraph2 = apply_namespaces(docgraph2)
    # get the ones we need here
    STCATH = get_namespace(graph, 'stcath')
    CRM = get_namespace(graph, 'crm')

    doci1 = 2 # msid with no inserted material
    doci2 = 21 # msid with inserted material

    # deal with thesaurus concepts

    # 1_5_InsertedMaterial
    cursor.execute("SELECT mss.msuuid, mss.cataloguename, im.msid, im.yesno, im.insertedmaterial FROM MSs mss INNER JOIN `1_5_InsertedMaterial` im on mss.id=im.msid")
    rows = cursor.fetchall()

    for row in rows:
        shelfmark = row["cataloguename"]
        msuuid = URIRef(row["msuuid"], str(STCATH))
        if row["yesno"] == "no":
            graph.add((msuuid, CRM["NTPXX_does_not_hold_or_support_physical_thing_of_type"], CRM["E18_Physical_Thing"]))
        elif row["yesno"] == "yes":
            graph.add((msuuid, CRM["TPXX_holds_or_supports_physical_thing_of_type"], CRM["E18_Physical_Thing"]))
            graph.add((msuuid, CRM["P3_has_note"], Literal("Inserted material of " + shelfmark + ": " + str(row["insertedmaterial"]), lang="en")))

        if row["msid"] == doci1:
            docgraph1.add((msuuid, CRM["NTPXX_does_not_hold_or_support_physical_thing_of_type"], CRM["E18_Physical_Thing"]))
            docgraph1.add((msuuid, RDF.type, CRM["E22_Man-Made_Object"]))
            docgraph1.add((CRM["E18_Physical_Thing"], RDF.type, CRM["E55_Type"]))
            docgraph1.add((msuuid, RDFS.label, Literal(row["cataloguename"], lang="en")))
        if row["msid"] == doci2:
            docgraph2.add((msuuid, CRM["TPXX_holds_or_supports_physical_thing_of_type"], CRM["E18_Physical_Thing"]))
            docgraph2.add((msuuid, RDF.type, CRM["E22_Man-Made_Object"]))
            docgraph2.add((CRM["E18_Physical_Thing"], RDF.type, CRM["E55_Type"]))
            docgraph2.add((msuuid, RDFS.label, Literal(row["cataloguename"], lang="en")))
            docgraph2.add((msuuid, CRM["P3_has_note"], Literal("Inserted material of " + shelfmark + ": " + row["insertedmaterial"], lang="en")))

    # documentation drawing
    dot1 = visualise_graph(docgraph1, 'MS without inserted material', "forth")
    dot2 = visualise_graph(docgraph2, 'MS with inserted material', "forth")
    dot1.render('insertedmaterial/insertedmaterial-1.gv', format='svg')
    dot2.render('insertedmaterial/insertedmaterial-2.gv', format='svg')

    # serialise the graph
    graph.serialize(destination='insertedmaterial/insertedmaterial.ttl', format='turtle', encoding="utf-8")
    docgraph1.serialize(destination='insertedmaterial/insertedmaterial-doc-1.n3', format='n3', encoding="utf-8")
    docgraph2.serialize(destination='insertedmaterial/insertedmaterial-doc-2.n3', format='n3', encoding="utf-8")
Esempio n. 2
0
def get_qname(tag_uri, tag_name):
    """Returns the fully qualified name.
    """
    if tag_uri is None:
        return tag_name
    prefix = get_namespace(tag_uri).prefix
    if prefix is None:
        return tag_name
    return '%s:%s' % (prefix, tag_name)
Esempio n. 3
0
def get_end_tag(value):
    # NOTE This method must be fast, that's why we copy here some code from
    # other methods (like get_qname), to reduce calls.

    tag_uri, tag_name = value
    namespace = get_namespace(tag_uri)
    # Case 1: empty
    schema = namespace.get_element_schema(tag_name)
    if getattr(schema, 'is_empty', False):
        return ''
    # Case 2: no prefix
    if tag_uri is None or namespace.prefix is None:
        return '</%s>' % tag_name
    # Case 3: prefix
    return '</%s:%s>' % (namespace.prefix, tag_name)
Esempio n. 4
0
def get_attribute_qname(namespace, local_name):
    """Returns the fully qualified name"""
    if namespace is None:
        return local_name

    prefix = get_namespace(namespace).prefix
    if prefix is None:
        return local_name

    # Namespace declarations for the default namespace lack the local
    # name (e.g. xmlns="http://www.example.org"). Here 'xmlns' is always
    # the prefix, and there is not a local name. This an special case.
    if local_name is None:
        return prefix

    return '%s:%s' % (prefix, local_name)
Esempio n. 5
0
def boxingleavesdate(mydb, cursor, cursorupdate):
    graph = Graph()  # graph for the dataset
    docgraph = Graph()  # graph for the documentation drawing
    # add namespaces
    graph = apply_namespaces(graph)
    docgraph = apply_namespaces(docgraph)
    # get the ones we need here
    STCATH = get_namespace(graph, 'stcath')
    CRM = get_namespace(graph, 'crm')

    # deal with thesaurus concepts
    graph.add(
        (URIRef("http://stcath.measuringbox"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://stcath.measuringbox"), RDF.type, SKOS.Concept))
    graph.add((URIRef("http://stcath.measuringbox"), SKOS.prefLabel,
               Literal("measuring boxes", lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300055644"), RDF.type,
               CRM["E55_Type"]))  # height
    graph.add((URIRef("http://vocab.getty.edu/aat/300055644"), SKOS.prefLabel,
               Literal('height', lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300055647"), RDF.type,
               CRM["E55_Type"]))  # width
    graph.add((URIRef("http://vocab.getty.edu/aat/300055647"), SKOS.prefLabel,
               Literal('width', lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300055646"), RDF.type,
               CRM["E55_Type"]))  # thickness
    graph.add((URIRef("http://vocab.getty.edu/aat/300055646"), SKOS.prefLabel,
               Literal('thickness', lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300379097"), RDF.type,
               CRM["E58_Measurement_Unit"]))  # mm
    graph.add((URIRef("http://vocab.getty.edu/aat/300379097"), SKOS.prefLabel,
               Literal('millimeters', lang="en")))

    doci = 1  # set the desirable db row for the documentation example

    # 1_0_BoxingLeavesDate
    cursor.execute(
        "SELECT mss.cataloguename, mss.msuuid, bld.* FROM 1_0_BoxingLeavesDate bld INNER JOIN MSs mss ON mss.id = bld.msid"
    )
    rows = cursor.fetchall()

    for i, row in enumerate(rows):
        shelfmark = row["cataloguename"]

        msuuid = URIRef(row["msuuid"], str(STCATH))
        if row["measurementuuid"] is None:  # if there is no measurementuuid, make one
            newuuid = str(uuid.uuid4())
            measurementuuid = URIRef(newuuid, str(STCATH))
            # update the database
            sql = "UPDATE 1_0_BoxingLeavesDate SET measurementuuid=%s WHERE msid=%s"
            val = (newuuid, row["msid"])
            cursorupdate.execute(sql, val)
            mydb.commit()
        else:  # else just fetch it
            measurementuuid = URIRef(row["measurementuuid"], str(STCATH))

        # height
        if row["heightuuid"] is None:
            newuuid = str(uuid.uuid4())
            dimensionhuuid = URIRef(newuuid, str(STCATH))
            # update the database
            sql = "UPDATE 1_0_BoxingLeavesDate SET heightuuid=%s WHERE msid=%s"
            val = (newuuid, row["msid"])
            cursorupdate.execute(sql, val)
            mydb.commit()
        else:
            dimensionhuuid = URIRef(row["heightuuid"], str(STCATH))

        # width
        if row["widthuuid"] is None:
            newuuid = str(uuid.uuid4())
            dimensionwuuid = URIRef(newuuid, str(STCATH))
            # update the database
            sql = "UPDATE 1_0_BoxingLeavesDate SET widthuuid=%s WHERE msid=%s"
            val = (newuuid, row["msid"])
            cursorupdate.execute(sql, val)
            mydb.commit()
        else:
            dimensionwuuid = URIRef(row["widthuuid"], str(STCATH))

        # thickness
        if row["thicknessuuid"] is None:
            newuuid = str(uuid.uuid4())
            dimensiontuuid = URIRef(newuuid, str(STCATH))
            # update the database
            sql = "UPDATE 1_0_BoxingLeavesDate SET thicknessuuid=%s WHERE msid=%s"
            val = (newuuid, row["msid"])
            cursorupdate.execute(sql, val)
            mydb.commit()
        else:
            dimensiontuuid = URIRef(row["thicknessuuid"], str(STCATH))

        # boxing status
        if row["boxingstatus"] is not None:
            boxingnote = row["boxingstatus"]
            if row["boxingnotes"] is not None:
                boxingnote = row["boxingstatus"] + " - " + row["boxingnotes"]

        # survey date
        if row["surveyeventuuid"] is None:
            newuuid = str(uuid.uuid4())
            surveyeventuuid = URIRef(newuuid, str(STCATH))
            # update the database
            sql = "UPDATE 1_0_BoxingLeavesDate SET surveyeventuuid=%s WHERE msid=%s"
            val = (newuuid, row["msid"])
            cursorupdate.execute(sql, val)
            mydb.commit()
        else:
            surveyeventuuid = URIRef(row["surveyeventuuid"], str(STCATH))

        if row["surveytimespanuuid"] is None:
            newuuid = str(uuid.uuid4())
            surveytimespanuuid = URIRef(newuuid, str(STCATH))
            # update the database
            sql = "UPDATE 1_0_BoxingLeavesDate SET surveytimespanuuid=%s WHERE msid=%s"
            val = (newuuid, row["msid"])
            cursorupdate.execute(sql, val)
            mydb.commit()
        else:
            surveytimespanuuid = URIRef(row["surveytimespanuuid"], str(STCATH))

        graph.add((measurementuuid, RDF.type,
                   CRM["E16_Measurement"]))  # rdf type the measurement
        graph.add((measurementuuid, RDFS.label,
                   Literal('Measurement of overall dimensions of ' + shelfmark,
                           lang="en")))
        graph.add((measurementuuid, CRM["P39_measured"],
                   msuuid))  # measurement event measured the manuscript
        graph.add((measurementuuid, CRM["P125_used_object_of_type"],
                   URIRef("http://stcath.measuringbox")
                   ))  # measurement used measuring box
        graph.add((dimensionhuuid, RDF.type,
                   CRM["E54_Dimension"]))  # rdf type the dimension
        graph.add((dimensionhuuid, RDFS.label,
                   Literal('Height of ' + shelfmark, lang="en")))
        graph.add((measurementuuid, CRM["P40_observed_dimension"],
                   dimensionhuuid))  # measurement observes the dimension
        graph.add((dimensionhuuid, CRM["P2_has_type"],
                   URIRef("http://vocab.getty.edu/aat/300055644")
                   ))  # dimension has type height
        graph.add(
            (dimensionhuuid, CRM["P90_has_value"],
             Literal(str(row["height"]))))  # dimension has value from the db
        graph.add((dimensionhuuid, CRM["P91_has_unit"],
                   URIRef("http://vocab.getty.edu/aat/300379097")
                   ))  # dimension has unit mm
        graph.add((dimensionwuuid, RDF.type,
                   CRM["E54_Dimension"]))  # rdf type the dimension
        graph.add((dimensionwuuid, RDFS.label,
                   Literal('Width of ' + shelfmark, lang="en")))
        graph.add((measurementuuid, CRM["P40_observed_dimension"],
                   dimensionwuuid))  # measurement observes the dimension
        graph.add((dimensionwuuid, CRM["P2_has_type"],
                   URIRef("http://vocab.getty.edu/aat/300055647")
                   ))  # dimension has type width
        graph.add(
            (dimensionwuuid, CRM["P90_has_value"],
             Literal(str(row["width"]))))  # dimension has value from the db
        graph.add((dimensionwuuid, CRM["P91_has_unit"],
                   URIRef("http://vocab.getty.edu/aat/300379097")
                   ))  # dimension has unit mm
        graph.add((dimensiontuuid, RDF.type,
                   CRM["E54_Dimension"]))  # rdf type the dimension
        graph.add((dimensiontuuid, RDFS.label,
                   Literal('Thickness of ' + shelfmark, lang="en")))
        graph.add((measurementuuid, CRM["P40_observed_dimension"],
                   dimensiontuuid))  # measurement observes the dimension
        graph.add((dimensiontuuid, CRM["P2_has_type"],
                   URIRef("http://vocab.getty.edu/aat/300055646")
                   ))  # dimension has type thickness
        graph.add((dimensiontuuid, CRM["P90_has_value"],
                   Literal(str(
                       row["thickness"]))))  # dimension has value from the db
        graph.add((dimensiontuuid, CRM["P91_has_unit"],
                   URIRef("http://vocab.getty.edu/aat/300379097")
                   ))  # dimension has unit mm
        graph.add((msuuid, CRM["P3_has_note"], Literal(boxingnote)
                   ))  # add boxing notes as a note to the manuscript node
        graph.add(
            (surveyeventuuid, RDF.type,
             CRM["E13_Attribute_Assignment"]))  # rdf type the survey event
        graph.add((surveyeventuuid, RDFS.label,
                   Literal('Survey event for ' + shelfmark, lang="en")))
        graph.add(
            (surveytimespanuuid, RDF.type,
             CRM["E52_Time-Span"]))  # rdf type the survey event time-span
        graph.add((surveytimespanuuid, RDFS.label,
                   Literal('Time-span of survey event for ' + shelfmark,
                           lang="en")))
        graph.add((surveyeventuuid, CRM["P4_has_time-span"],
                   surveytimespanuuid))  # survey event has time-span
        graph.add(
            (surveyeventuuid, CRM["P9_consists_of"],
             measurementuuid))  # measurement event is part of survey event

        if row["surveydate"] is not None:
            graph.add((surveytimespanuuid, CRM["P82a_begin_of_the_begin"],
                       Literal(
                           str(row["surveydate"]).replace(
                               "00:00:00", "08:00:00").replace(" ", "T"))))
            graph.add((surveytimespanuuid, CRM["P82b_end_of_the_end"],
                       Literal(
                           str(row["surveydate"]).replace(
                               "00:00:00", "20:00:00").replace(" ", "T"))))

        if i == doci:
            docgraph.add((URIRef("http://stcath.measuringbox"), RDF.type,
                          CRM["E55_Type"]))
            docgraph.add((URIRef("http://stcath.measuringbox"), SKOS.prefLabel,
                          Literal("measuring boxes", lang="en")))
            docgraph.add((URIRef("http://vocab.getty.edu/aat/300055644"),
                          RDF.type, CRM["E55_Type"]))  # height
            docgraph.add((URIRef("http://vocab.getty.edu/aat/300055644"),
                          SKOS.prefLabel, Literal('height', lang="en")))
            docgraph.add((URIRef("http://vocab.getty.edu/aat/300055647"),
                          RDF.type, CRM["E55_Type"]))  # width
            docgraph.add((URIRef("http://vocab.getty.edu/aat/300055647"),
                          SKOS.prefLabel, Literal('width', lang="en")))
            docgraph.add((URIRef("http://vocab.getty.edu/aat/300055646"),
                          RDF.type, CRM["E55_Type"]))  # thickness
            docgraph.add((URIRef("http://vocab.getty.edu/aat/300055646"),
                          SKOS.prefLabel, Literal('thickness', lang="en")))
            docgraph.add((URIRef("http://vocab.getty.edu/aat/300379097"),
                          RDF.type, CRM["E58_Measurement_Unit"]))  # mm
            docgraph.add((URIRef("http://vocab.getty.edu/aat/300379097"),
                          SKOS.prefLabel, Literal('millimeters', lang="en")))
            docgraph.add((msuuid, RDF.type, CRM["E22_Man-Made_Object"]))
            docgraph.add((msuuid, RDFS.label,
                          Literal(str(row["cataloguename"]), lang="en")))
            docgraph.add((measurementuuid, RDF.type,
                          CRM["E16_Measurement"]))  # rdf type the measurement
            docgraph.add(
                (measurementuuid, RDFS.label,
                 Literal('Measurement of overall dimensions of ' + shelfmark,
                         lang="en")))
            docgraph.add((measurementuuid, CRM["P39_measured"],
                          msuuid))  # measurement event measured the manuscript
            docgraph.add((measurementuuid, CRM["P125_used_object_of_type"],
                          URIRef("http://stcath.measuringbox")
                          ))  # measurement used measuring box
            docgraph.add((dimensionhuuid, RDF.type,
                          CRM["E54_Dimension"]))  # rdf type the dimension
            docgraph.add((dimensionhuuid, RDFS.label,
                          Literal('Height of ' + shelfmark, lang="en")))
            docgraph.add(
                (measurementuuid, CRM["P40_observed_dimension"],
                 dimensionhuuid))  # measurement observes the dimension
            docgraph.add((dimensionhuuid, CRM["P2_has_type"],
                          URIRef("http://vocab.getty.edu/aat/300055644")
                          ))  # dimension has type height
            docgraph.add(
                (dimensionhuuid, CRM["P90_has_value"],
                 Literal(str(
                     row["height"]))))  # dimension has value from the db
            docgraph.add((dimensionhuuid, CRM["P91_has_unit"],
                          URIRef("http://vocab.getty.edu/aat/300379097")
                          ))  # dimension has unit mm
            docgraph.add((dimensionwuuid, RDF.type,
                          CRM["E54_Dimension"]))  # rdf type the dimension
            docgraph.add((dimensionwuuid, RDFS.label,
                          Literal('Width of ' + shelfmark, lang="en")))
            docgraph.add(
                (measurementuuid, CRM["P40_observed_dimension"],
                 dimensionwuuid))  # measurement observes the dimension
            docgraph.add((dimensionwuuid, CRM["P2_has_type"],
                          URIRef("http://vocab.getty.edu/aat/300055647")
                          ))  # dimension has type width
            docgraph.add(
                (dimensionwuuid, CRM["P90_has_value"],
                 Literal(str(
                     row["width"]))))  # dimension has value from the db
            docgraph.add((dimensionwuuid, CRM["P91_has_unit"],
                          URIRef("http://vocab.getty.edu/aat/300379097")
                          ))  # dimension has unit mm
            docgraph.add((dimensiontuuid, RDF.type,
                          CRM["E54_Dimension"]))  # rdf type the dimension
            docgraph.add((dimensiontuuid, RDFS.label,
                          Literal('Thickness of ' + shelfmark, lang="en")))
            docgraph.add(
                (measurementuuid, CRM["P40_observed_dimension"],
                 dimensiontuuid))  # measurement observes the dimension
            docgraph.add((dimensiontuuid, CRM["P2_has_type"],
                          URIRef("http://vocab.getty.edu/aat/300055646")
                          ))  # dimension has type thickness
            docgraph.add(
                (dimensiontuuid, CRM["P90_has_value"],
                 Literal(str(
                     row["thickness"]))))  # dimension has value from the db
            docgraph.add((dimensiontuuid, CRM["P91_has_unit"],
                          URIRef("http://vocab.getty.edu/aat/300379097")
                          ))  # dimension has unit mm
            docgraph.add(
                (msuuid, CRM["P3_has_note"], Literal(boxingnote)
                 ))  # add boxing notes as a note to the manuscript node
            docgraph.add(
                (surveyeventuuid, RDF.type,
                 CRM["E13_Attribute_Assignment"]))  # rdf type the survey event
            docgraph.add((surveyeventuuid, RDFS.label,
                          Literal('Survey event for ' + shelfmark, lang="en")))
            docgraph.add(
                (surveytimespanuuid, RDF.type,
                 CRM["E52_Time-Span"]))  # rdf type the survey event time-span
            docgraph.add((surveytimespanuuid, RDFS.label,
                          Literal('Time-span of survey event for ' + shelfmark,
                                  lang="en")))
            docgraph.add((surveyeventuuid, CRM["P4_has_time-span"],
                          surveytimespanuuid))  # survey event has time-span
            docgraph.add((surveytimespanuuid, CRM["P82a_begin_of_the_begin"],
                          Literal(
                              str(row["surveydate"]).replace(
                                  "00:00:00", "08:00:00").replace(" ", "T"))))
            docgraph.add((surveytimespanuuid, CRM["P82b_end_of_the_end"],
                          Literal(
                              str(row["surveydate"]).replace(
                                  "00:00:00", "20:00:00").replace(" ", "T"))))
            docgraph.add(
                (surveyeventuuid, CRM["P9_consists_of"],
                 measurementuuid))  # measurement event is part of survey event

    # documentation drawing
    dot = visualise_graph(docgraph, 'Boxing, leaves, survey date')
    dot.render('boxingleavesdate/1-0-boxingleavesdate.gv', format='svg')

    # serialise the graph
    graph.serialize(destination='boxingleavesdate/1-0-boxingleavesdate.ttl',
                    format='turtle',
                    encoding="utf-8")
    docgraph.serialize(destination='boxingleavesdate/1-0-boxingleavesdate.n3',
                       format='n3',
                       encoding="utf-8")
Esempio n. 6
0
def pagemarkers(mydb, cursor, cursorupdate):

    graph = Graph() # graph for the dataset
    docgraph1 = Graph() # graph for the documentation drawing
    docgraph2 = Graph()  # graph for the documentation drawing
    docgraph3 = Graph()  # graph for the documentation drawing
    # add namespaces
    graph = apply_namespaces(graph)
    docgraph1 = apply_namespaces(docgraph1)
    docgraph2 = apply_namespaces(docgraph2)
    docgraph3 = apply_namespaces(docgraph3)
    # get the ones we need here
    STCATH = get_namespace(graph, 'stcath')
    CRM = get_namespace(graph, 'crm')

    doci1 = 2 # msid with no pagemarkers
    doci2 = 395 # msid with pagemarkers, pagemarker id: 217
    doci3 = 555 # msid with natural colour, pagemarker id: 241

    # deal with thesaurus concepts
    graph.add((URIRef("http://w3id.org/lob/concept/5423"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://w3id.org/lob/concept/5423"), SKOS.prefLabel, Literal("leaf markers", lang="en")))
    graph.add((URIRef("http://w3id.org/lob/concept/2945"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://w3id.org/lob/concept/2945"), SKOS.prefLabel, Literal("leaf tab markers", lang="en")))
    graph.add((URIRef("http://w3id.org/lob/concept/2944"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://w3id.org/lob/concept/2944"), SKOS.prefLabel, Literal("leaf string markers", lang="en")))
    graph.add((URIRef("http://w3id.org/lob/concept/1658"), RDF.type, CRM["E57_Material"]))
    graph.add((URIRef("http://w3id.org/lob/concept/1658"), RDFS.label, Literal("tanned skin", lang="en")))
    graph.add((URIRef("http://w3id.org/lob/concept/2468"), RDF.type, CRM["E57_Material"]))
    graph.add((URIRef("http://w3id.org/lob/concept/2468"), RDFS.label, Literal("silk", lang="en")))
    graph.add((URIRef("http://w3id.org/lob/concept/2470"), RDF.type, CRM["E57_Material"]))
    graph.add((URIRef("http://w3id.org/lob/concept/2470"), RDFS.label, Literal("textile", lang="en")))
    graph.add((URIRef("http://w3id.org/lob/concept/1481"), RDF.type, CRM["E57_Material"]))
    graph.add((URIRef("http://w3id.org/lob/concept/1481"), RDFS.label, Literal("paper", lang="en")))
    graph.add((URIRef("http://w3id.org/lob/concept/1197"), RDF.type, CRM["E57_Material"]))
    graph.add((URIRef("http://w3id.org/lob/concept/1197"), RDFS.label, Literal("alum-tawed skin", lang="en")))
    graph.add((URIRef("http://w3id.org/lob/concept/1485"), RDF.type, CRM["E57_Material"]))
    graph.add((URIRef("http://w3id.org/lob/concept/1485"), RDFS.label, Literal("parchment", lang="en")))
    graph.add((URIRef("http://w3id.org/lob/concept/2474"), RDF.type, CRM["E57_Material"]))
    graph.add((URIRef("http://w3id.org/lob/concept/2474"), RDFS.label, Literal("thread", lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300014585"), RDF.type, CRM["E57_Material"]))
    graph.add((URIRef("http://vocab.getty.edu/aat/300014585"), RDFS.label, Literal("wax", lang="en")))
    graph.add((URIRef("http://w3id.org/lob/concept/3855"), RDF.type, CRM["E57_Material"]))
    graph.add((URIRef("http://w3id.org/lob/concept/3855"), RDFS.label, Literal("solid-coloured paper", lang="en")))
    graph.add((URIRef("http://w3id.org/lob/concept/3165"), RDF.type, CRM["E57_Material"]))
    graph.add((URIRef("http://w3id.org/lob/concept/3165"), RDFS.label, Literal("paint (coating)", lang="en")))
    graph.add((URIRef("http://w3id.org/lob/concept/5429"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://w3id.org/lob/concept/5429"), RDFS.label, Literal("adhering", lang="en")))
    graph.add((URIRef("http://w3id.org/lob/concept/2362"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://w3id.org/lob/concept/2362"), RDFS.label, Literal("sewing (techniques)", lang="en")))
    graph.add((URIRef("http://stcath.looped"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://stcath.looped"), RDFS.label, Literal("looped", lang="en")))
    graph.add((URIRef("http://w3id.org/lob/concept/1476"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://w3id.org/lob/concept/1476"), RDFS.label, Literal("painting (techniques)", lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300129361"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://vocab.getty.edu/aat/300129361"), RDFS.label, Literal("blue (color)", lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300127490"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://vocab.getty.edu/aat/300127490"), RDFS.label, Literal("brown (color)", lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300311191"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://vocab.getty.edu/aat/300311191"), RDFS.label, Literal("gold (color)", lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300127526"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://vocab.getty.edu/aat/300127526"), RDFS.label, Literal("dark brown", lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300126272"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://vocab.getty.edu/aat/300126272"), RDFS.label, Literal("deep red", lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300126225"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://vocab.getty.edu/aat/300126225"), RDFS.label, Literal("red (color)", lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300127503"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://vocab.getty.edu/aat/300127503"), RDFS.label, Literal("light brown", lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300311191"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://vocab.getty.edu/aat/300311191"), RDFS.label, Literal("gold (color)", lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300127794"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://vocab.getty.edu/aat/300127794"), RDFS.label, Literal("yellow (color)", lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300128438"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://vocab.getty.edu/aat/300128438"), RDFS.label, Literal("green (color)", lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300129394"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://vocab.getty.edu/aat/300129394"), RDFS.label, Literal("deep blue", lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300311191"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://vocab.getty.edu/aat/300311191"), RDFS.label, Literal("gold (color)", lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300056130"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://vocab.getty.edu/aat/300056130"), RDFS.label, Literal("color (perceived attribute)", lang="en")))
    graph.add((URIRef("http://stcath.sound"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://stcath.sound"), RDFS.label, Literal("sound", lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300131111"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://vocab.getty.edu/aat/300131111"), RDFS.label, Literal("detached (positional attribute) ", lang="en")))
    graph.add((URIRef("http://stcath.brokenoff"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://stcath.brokenoff"), RDFS.label, Literal("broken off", lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300219449"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://vocab.getty.edu/aat/300219449"), RDFS.label, Literal("wear", lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300379497"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://vocab.getty.edu/aat/300379497"), RDFS.label, Literal("stains (damage)", lang="en")))
    graph.add((URIRef("http://stcath.missing"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://stcath.missing"), RDFS.label, Literal("missing", lang="en")))
    graph.add((URIRef("http://stcath.trimmedforedge"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://stcath.trimmedforedge"), RDFS.label, Literal("trimmed foredge", lang="en")))
    graph.add((URIRef("http://stcath.dangling"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://stcath.dangling"), RDFS.label, Literal("dangling", lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300380188"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://vocab.getty.edu/aat/300380188"), RDFS.label, Literal("rodent (damage)", lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300230031"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://vocab.getty.edu/aat/300230031"), RDFS.label, Literal("insect damage", lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300053077"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://vocab.getty.edu/aat/300053077"), RDFS.label, Literal("abrasion (condition or effect)", lang="en")))
    graph.add((URIRef("http://vocab.getty.edu/aat/300219449"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://vocab.getty.edu/aat/300219449"), RDFS.label, Literal("wear", lang="en")))
    graph.add((URIRef("http://stcath.dirty"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://stcath.dirty"), RDFS.label, Literal("dirty", lang="en")))

    # 1_1_PageMarkers
    cursor.execute("SELECT mss.msuuid, mss.cataloguename, pms.msid, pms.yesnonk FROM MSs mss INNER JOIN `1_2_PageMarkers` pms on mss.id=pms.msid")
    rows = cursor.fetchall()

    for row in rows:
        msuuid = URIRef(row["msuuid"], str(STCATH))
        if row["yesnonk"] == "no":
            graph.add((msuuid, CRM["NTP46_is_not_composed_of_physical_thing_of_type"], URIRef("http://w3id.org/lob/concept/5423")))

        if row["msid"] == doci1:
            docgraph1.add((URIRef("http://w3id.org/lob/concept/5423"), RDF.type, CRM["E55_Type"]))
            docgraph1.add((URIRef("http://w3id.org/lob/concept/5423"), SKOS.prefLabel, Literal("leaf markers", lang="en")))
            docgraph1.add((msuuid, CRM["NTP46_is_not_composed_of_physical_thing_of_type"], URIRef("http://w3id.org/lob/concept/5423")))
            docgraph1.add((msuuid, RDF.type, CRM["E22_Man-Made_Object"]))
            docgraph1.add((msuuid, RDFS.label, Literal(row["cataloguename"], lang="en")))
        if row["msid"] == doci2:
            docgraph2.add((msuuid, RDF.type, CRM["E22_Man-Made_Object"]))
            docgraph2.add((msuuid, RDFS.label, Literal(row["cataloguename"], lang="en")))
        if row["msid"] == doci3:
            docgraph3.add((msuuid, RDF.type, CRM["E22_Man-Made_Object"]))
            docgraph3.add((msuuid, RDFS.label, Literal(row["cataloguename"], lang="en")))

    # Pagemarkers
    cursor.execute("SELECT mss.msuuid, mss.cataloguename, pm.msid, pm.id, pm.uuid, pm.type, pm.attachment, pm.partadditionuuid, pm.material FROM PageMarkers pm INNER JOIN MSs mss ON pm.msid=mss.id")
    rows = cursor.fetchall()

    for row in rows:
        shelfmark = row["cataloguename"]
        msuuid = URIRef(row["msuuid"], str(STCATH))
        # pagemarker series attachment, type, material
        if row["uuid"] is None:
            newuuid = str(uuid.uuid4())
            pagemarkeruuid = URIRef(newuuid, str(STCATH))
            # update the database
            sql = "UPDATE PageMarkers SET uuid=%s WHERE id=%s"
            val = (newuuid, row["id"])
            cursorupdate.execute(sql, val)
            mydb.commit()
        else:
            pagemarkeruuid = URIRef(row["uuid"], str(STCATH))

        if row["type"] is not None:
            if bool(row["type"] == "Folded") | bool(row["type"] == "Folded and knotted") | bool(row["type"] == "Straight") | bool(row["type"] == "Platted") | bool(row["type"] == "Tied") | bool(row["type"] == "Twisted thread") | bool(row["type"] == "Thread"):
                graph.add((pagemarkeruuid, RDF.type, CRM["E22_Man-Made_Object"])) # page markers of these types are separate things.
                graph.add((msuuid, CRM["P46_is_composed_of"], pagemarkeruuid))  # book is composed of page markers
            elif bool(row["type"] == "Wax") | bool(row["type"] == "Painted"):
                graph.add((pagemarkeruuid, RDF.type, CRM["E25_Man-Made_Feature"]))  # page markers of these types are features, i.e. cannot be removed.
                graph.add((msuuid, CRM["P56_bears_feature"], pagemarkeruuid))  # book bears feature page markers
            else:
                graph.add((pagemarkeruuid, RDF.type, CRM["E24_Physical_Man-Made_Thing"])) # page markers of these types are separate things.
                graph.add((msuuid, CRM["P46_is_composed_of"], pagemarkeruuid))  # book is composed of page markers

            if row["type"] != "-":
                if bool(row["type"] == "Folded") | bool(row["type"] == "Folded and knotted"):
                    pagemarkertypeuuid = URIRef("http://w3id.org/lob/concept/2945")
                elif row["type"] == "Straight":
                    pagemarkertypeuuid = URIRef("http://w3id.org/lob/concept/5423")
                elif bool(row["type"] == "Platted") | bool(row["type"] == "Tied") | bool(row["type"] == "Twisted thread") | bool(row["type"] == "Thread"):
                    pagemarkertypeuuid = URIRef("http://w3id.org/lob/concept/2944")
                elif bool(row["type"] == "Wax") | bool(row["type"] == "Painted"):
                    # TODO: consider a new type of page marker which is a feature
                    pass
                graph.add((pagemarkeruuid, CRM["P2_has_type"], pagemarkertypeuuid))
                graph.add((msuuid, CRM["TP46_is_composed_of_physical_thing_of_type"], pagemarkertypeuuid))
        else:
            graph.add((pagemarkeruuid, RDF.type, CRM["E24_Physical_Man-Made_Thing"]))  # not sure what these page markers are
            graph.add((msuuid, CRM["P46_is_composed_of"], pagemarkeruuid))  # book is composed of page markers
        graph.add((pagemarkeruuid, RDFS.label, Literal("Page-markers of " + shelfmark, lang="en")))

        if row["attachment"] is not None:
            if row["partadditionuuid"] is None:
                newuuid = str(uuid.uuid4())
                partadditionuuid = URIRef(newuuid, str(STCATH))
                # update the database
                sql = "UPDATE PageMarkers SET partadditionuuid=%s WHERE id=%s"
                val = (newuuid, row["id"])
                cursorupdate.execute(sql, val)
                mydb.commit()
            else:
                partadditionuuid = URIRef(row["partadditionuuid"], str(STCATH))
            graph.add((partadditionuuid, RDF.type, CRM["E79_Part_Addition"])) # type the part addition event
            graph.add((partadditionuuid, RDFS.label, Literal("Addition of pagemarkers to " + shelfmark, lang="en"))) # label
            graph.add((partadditionuuid, CRM["P110_augmented"], msuuid)) # augmented book
            graph.add((partadditionuuid, CRM["P111_added"], pagemarkeruuid)) # added pagemarker

            if row["attachment"] != "-":
                if row["attachment"] == "Adhesive":
                    partadditiontechniqueuuid = URIRef("http://w3id.org/lob/concept/5429")
                elif row["attachment"] == "Sewn":
                    partadditiontechniqueuuid = URIRef("http://w3id.org/lob/concept/2362")
                elif row["attachment"] == "Looped":
                    partadditiontechniqueuuid = URIRef("http://stcath.looped")
                elif row["attachment"] == "Paint":
                    partadditiontechniqueuuid = URIRef("http://w3id.org/lob/concept/1476")
                graph.add((partadditionuuid, CRM["P32_used_general_technique"], partadditiontechniqueuuid))

        if row["material"] is not None and row["material"] != "-":
            if bool(row["material"] == "Candle wax"):
                materialuuid = URIRef("http://vocab.getty.edu/aat/300014585")
            elif row["material"] == "Tanned leather":
                materialuuid = URIRef("http://w3id.org/lob/concept/1658")
            elif row["material"] == "Silk":
                materialuuid = URIRef("http://w3id.org/lob/concept/2468")
            elif row["material"] == "Textile":
                materialuuid = URIRef("http://w3id.org/lob/concept/2470")
            elif row["material"] == "Paper":
                materialuuid = URIRef("http://w3id.org/lob/concept/1481")
            elif row["material"] == "Tawed leather":
                materialuuid = URIRef("http://w3id.org/lob/concept/1197")
            elif row["material"] == "Parchment":
                materialuuid = URIRef("http://w3id.org/lob/concept/1485")
            elif row["material"] == "Natural thread":
                materialuuid = URIRef("http://w3id.org/lob/concept/2474")
            elif row["material"] == "Wax":
                materialuuid = URIRef("http://vocab.getty.edu/aat/300014585")
            elif row["material"] == "Tinted paper":
                materialuuid = URIRef("http://w3id.org/lob/concept/3855")
            elif row["material"] == "Paint":
                materialuuid = URIRef("http://w3id.org/lob/concept/3165")
            graph.add((pagemarkeruuid, CRM["P45_consists_of"], materialuuid))

        if row["msid"] == doci2:
            docgraph2.add((pagemarkeruuid, RDF.type, CRM["E22_Man-Made_Object"]))
            docgraph2.add((pagemarkeruuid, RDFS.label, Literal("Page-markers of " + shelfmark, lang="en")))
            docgraph2.add((msuuid, CRM["TP46_is_composed_of_physical_thing_of_type"], pagemarkertypeuuid))
            docgraph2.add((msuuid, CRM["P46_is_composed_of"], pagemarkeruuid))  # book is composed of page markers
            docgraph2.add((pagemarkeruuid, CRM["P2_has_type"], pagemarkertypeuuid))
            docgraph2.add((partadditionuuid, RDF.type, CRM["E79_Part_Addition"]))  # type the part addition event
            docgraph2.add((partadditionuuid, RDFS.label, Literal("Addition of pagemarkers to " + shelfmark, lang="en")))  # label
            docgraph2.add((partadditionuuid, CRM["P110_augmented"], msuuid))  # augmented book
            docgraph2.add((partadditionuuid, CRM["P111_added"], pagemarkeruuid))  # added pagemarker
            docgraph2.add((partadditionuuid, CRM["P32_used_general_technique"], partadditiontechniqueuuid))
            docgraph2.add((pagemarkeruuid, CRM["P45_consists_of"], materialuuid))
            docgraph2.add((URIRef("http://w3id.org/lob/concept/2470"), RDF.type, CRM["E57_Material"]))
            docgraph2.add((URIRef("http://w3id.org/lob/concept/2470"), RDFS.label, Literal("textile", lang="en")))
            docgraph2.add((URIRef("http://w3id.org/lob/concept/2945"), RDF.type, CRM["E55_Type"]))
            docgraph2.add((URIRef("http://w3id.org/lob/concept/2945"), SKOS.prefLabel, Literal("leaf tab markers", lang="en")))
            docgraph2.add((URIRef("http://w3id.org/lob/concept/5429"), RDF.type, CRM["E55_Type"]))
            docgraph2.add((URIRef("http://w3id.org/lob/concept/5429"), RDFS.label, Literal("adhering", lang="en")))
            docgraph2.add((URIRef("http://vocab.getty.edu/aat/300129361"), RDF.type, CRM["E55_Type"]))
            docgraph2.add((URIRef("http://vocab.getty.edu/aat/300129361"), RDFS.label, Literal("blue (color)", lang="en")))
        if row["msid"] == doci3:
            docgraph3.add((pagemarkeruuid, RDF.type, CRM["E22_Man-Made_Object"]))
            docgraph3.add((pagemarkeruuid, RDFS.label, Literal("Page-markers of " + shelfmark, lang="en")))
            docgraph3.add((msuuid, CRM["TP46_is_composed_of_physical_thing_of_type"], pagemarkertypeuuid))
            docgraph3.add((msuuid, CRM["P46_is_composed_of"], pagemarkeruuid))  # book is composed of page markers
            docgraph3.add((pagemarkeruuid, CRM["P2_has_type"], pagemarkertypeuuid))
            docgraph3.add((partadditionuuid, RDF.type, CRM["E79_Part_Addition"]))  # type the part addition event
            docgraph3.add((partadditionuuid, RDFS.label, Literal("Addition of pagemarkers to " + shelfmark, lang="en")))  # label
            docgraph3.add((partadditionuuid, CRM["P110_augmented"], msuuid))  # augmented book
            docgraph3.add((partadditionuuid, CRM["P111_added"], pagemarkeruuid))  # added pagemarker
            docgraph3.add((partadditionuuid, CRM["P32_used_general_technique"], partadditiontechniqueuuid))
            docgraph3.add((pagemarkeruuid, CRM["P45_consists_of"], materialuuid))
            docgraph3.add((URIRef("http://w3id.org/lob/concept/2474"), RDF.type, CRM["E57_Material"]))
            docgraph3.add((URIRef("http://w3id.org/lob/concept/2474"), RDFS.label, Literal("thread", lang="en")))
            docgraph3.add((URIRef("http://w3id.org/lob/concept/2944"), RDF.type, CRM["E55_Type"]))
            docgraph3.add((URIRef("http://w3id.org/lob/concept/2944"), SKOS.prefLabel, Literal("leaf string markers", lang="en")))
            docgraph3.add((URIRef("http://stcath.looped"), RDF.type, CRM["E55_Type"]))
            docgraph3.add((URIRef("http://stcath.looped"), RDFS.label, Literal("looped", lang="en")))
            docgraph3.add((URIRef("http://vocab.getty.edu/aat/300056130"), RDF.type, CRM["E55_Type"]))
            docgraph3.add((URIRef("http://vocab.getty.edu/aat/300056130"), RDFS.label, Literal("color (perceived attribute)", lang="en")))

    # PageMarkers colour
    cursor.execute("SELECT mss.id AS msid, pm.uuid, pmc.pagemarker, pmc.pagemarkercolour FROM PageMarkersColour pmc LEFT JOIN PageMarkers pm on pm.id=pmc.pagemarker INNER JOIN MSs mss ON pm.msid=mss.id")
    rows = cursor.fetchall()
    for row in rows:
        pagemarkeruuid = URIRef(row["uuid"], str(STCATH))
        if row["pagemarkercolour"] is not None and row["pagemarkercolour"] != "-" and row["pagemarkercolour"] != "NK":
            if row["pagemarkercolour"] == "Natural":
                graph.add((pagemarkeruuid, CRM["NTP56_does_not_bear_feature_of_type"], URIRef("http://vocab.getty.edu/aat/300056130"))) # pagemarker does not have colour
            else:
                if row["pagemarkercolour"] == "Blue":
                    colouruuid = URIRef("http://vocab.getty.edu/aat/300129361")
                elif row["pagemarkercolour"] == "Brown":
                    colouruuid = URIRef("http://vocab.getty.edu/aat/300127490")
                elif row["pagemarkercolour"] == "Gold" or row["pagemarkercolour"] == "Gilded" or row["pagemarkercolour"] == "Gilt":
                    colouruuid = URIRef("http://vocab.getty.edu/aat/300311191")
                elif row["pagemarkercolour"] == "Dark brown":
                    colouruuid = URIRef("http://vocab.getty.edu/aat/300127526")
                elif row["pagemarkercolour"] == "Deep red":
                    colouruuid = URIRef("http://vocab.getty.edu/aat/300126272")
                elif row["pagemarkercolour"] == "Red":
                    colouruuid = URIRef("http://vocab.getty.edu/aat/300126225")
                elif row["pagemarkercolour"] == "Light brown":
                    colouruuid = URIRef("http://vocab.getty.edu/aat/300127503")
                elif row["pagemarkercolour"] == "Yellow":
                    colouruuid = URIRef("http://vocab.getty.edu/aat/300127794")
                elif row["pagemarkercolour"] == "Green":
                    colouruuid = URIRef("http://vocab.getty.edu/aat/300128438")
                elif row["pagemarkercolour"] == "Deep blue":
                    colouruuid = URIRef("http://vocab.getty.edu/aat/300129394")
                graph.add((pagemarkeruuid, CRM["P56_bears_feature"], colouruuid))

        if row["msid"] == doci2:
            docgraph2.add((pagemarkeruuid, CRM["P56_bears_feature"], colouruuid))
        if row["msid"] == doci3:
            docgraph3.add((pagemarkeruuid, CRM["NTP56_does_not_bear_feature_of_type"], URIRef("http://vocab.getty.edu/aat/300056130")))  # pagemarker does not have colour

    # Pagemarker locations
    cursor.execute("SELECT mss.id AS msid, pm.uuid AS pagemarkersetuuid, pml.id, pml.uuid AS pagemarkersubsetuuid, pml.pagemarker, pml.pagemarkerlocation, pml.locationno FROM PageMarkersLocation pml LEFT JOIN PageMarkers pm ON pm.id=pml.pagemarker INNER JOIN MSs mss ON mss.id=pm.msid")
    rows = cursor.fetchall()

    for row in rows:
        pagemarkersetuuid = URIRef(row["pagemarkersetuuid"], str(STCATH)) # we should have a uuid for every set of pagemerkers by now
        pagemarkersetlabel = graph.preferredLabel(pagemarkersetuuid, lang="en") # get the pagemarkers set label
        # find the total number of pagemarkers in this set
        cursor.execute("SELECT SUM(locationno) FROM `PageMarkersLocation` WHERE pagemarker=" + str(row["pagemarker"]))
        pagemarkersettotal = cursor.fetchall()
        # add the number of parts for it
        graph.add((pagemarkersetuuid, CRM["P57_has_number_of_parts"], Literal(pagemarkersettotal[0]["SUM(locationno)"])))
        # pagemarker subsets
        if row["pagemarkersubsetuuid"] is None:
            newuuid = str(uuid.uuid4())
            pagemarkersubsetuuid = URIRef(newuuid, str(STCATH))
            # update the database
            sql = "UPDATE PageMarkersLocation SET uuid=%s WHERE id=%s"
            val = (newuuid, row["id"])
            cursorupdate.execute(sql, val)
            mydb.commit()
        else:
            pagemarkersubsetuuid = URIRef(row["pagemarkersubsetuuid"], str(STCATH))
        pmstype = graph.value(pagemarkersetuuid, RDF.type) # find the rdf type of the pagemarker set, we assume that the subset is of the same type
        graph.add((pagemarkersubsetuuid, RDF.type, pmstype))
        graph.add((pagemarkersubsetuuid, RDFS.label, Literal("Subset of '" + str(pagemarkersetlabel[0][1]) + "' on " + row["pagemarkerlocation"], lang="en")))
        graph.add((pagemarkersetuuid, CRM["P46_is_composed_of"], pagemarkersubsetuuid))
        graph.add((pagemarkersubsetuuid, CRM["P57_has_number_of_parts"], Literal(row["locationno"]))) # specify the pagemarker subset in the specific location
        if row["pagemarkerlocation"] is not None:
            if row["pagemarkerlocation"] == "Foredge":
                # TODO: query the graph to get the URI of the textblock foredge place
                pass
            elif row["pagemarkerlocation"] == "Head":
                # TODO: query the graph to get the URI of the textblock foredge place
                pass
            elif row["pagemarkerlocation"] == "Tail":
                # TODO: query the graph to get the URI of the textblock foredge place
                pass
            # graph.add((pagemarkersubsetuuid, CRM["P53_has_former_or_current_location"], *place*))

        if row["msid"] == doci2:
            docgraph2.add((pagemarkersubsetuuid, RDF.type, pmstype))
            docgraph2.add((pagemarkersubsetuuid, RDFS.label, Literal("Subset of '" + str(pagemarkersetlabel[0][1]) + "' on " + row["pagemarkerlocation"], lang="en")))
            docgraph2.add((pagemarkersetuuid, CRM["P46_is_composed_of"], pagemarkersubsetuuid))
            docgraph2.add((pagemarkersubsetuuid, CRM["P57_has_number_of_parts"], Literal(row["locationno"])))
        if row["msid"] == doci3:
            docgraph3.add((pagemarkersubsetuuid, RDF.type, pmstype))
            docgraph3.add((pagemarkersubsetuuid, RDFS.label, Literal("Subset of '" + str(pagemarkersetlabel[0][1]) + "' on " + row["pagemarkerlocation"], lang="en")))
            docgraph3.add((pagemarkersetuuid, CRM["P46_is_composed_of"], pagemarkersubsetuuid))
            docgraph3.add((pagemarkersubsetuuid, CRM["P57_has_number_of_parts"], Literal(row["locationno"])))

    # Pagemarker conditions
    cursor.execute("SELECT mss.id AS msid, pm.uuid AS pagemarkersetuuid, pmc.id, pmc.uuid AS pagemarkersubsetuuid, pmc.pagemarker, pmc.condition, pmc.conditionuuid, pmc.conditionno FROM PageMarkersCondition pmc INNER JOIN PageMarkers pm ON pm.id=pmc.pagemarker INNER JOIN MSs mss ON mss.id=pm.msid")
    rows = cursor.fetchall()

    for row in rows:
        pagemarkersetuuid = URIRef(row["pagemarkersetuuid"], str(STCATH)) # we should have a uuid for every set of pagemerkers by now
        pagemarkersetlabel = graph.preferredLabel(pagemarkersetuuid, lang="en") # get the pagemarkers set label
        # pagemarker subsets
        if row["pagemarkersubsetuuid"] is None:
            newuuid = str(uuid.uuid4())
            pagemarkersubsetuuid = URIRef(newuuid, str(STCATH))
            # update the database
            sql = "UPDATE PageMarkersCondition SET uuid=%s WHERE id=%s"
            val = (newuuid, row["id"])
            cursorupdate.execute(sql, val)
            mydb.commit()
        else:
            pagemarkersubsetuuid = URIRef(row["pagemarkersubsetuuid"], str(STCATH))
        pmstype = graph.value(pagemarkersetuuid, RDF.type) # find the rdf type of the pagemarker set, we assume that the subset is of the same type
        graph.add((pagemarkersubsetuuid, RDF.type, pmstype))
        graph.add((pagemarkersubsetuuid, RDFS.label, Literal("Subset of '" + str(pagemarkersetlabel[0][1]) + "' with condition " + row["condition"], lang="en")))
        graph.add((pagemarkersetuuid, CRM["P46_is_composed_of"], pagemarkersubsetuuid))
        graph.add((pagemarkersubsetuuid, CRM["P57_has_number_of_parts"], Literal(row["conditionno"])))  # specify the pagemarker subset in the specific location
        # subset condition
        if row["conditionuuid"] is None:
            newuuid = str(uuid.uuid4())
            conditionuuid = URIRef(newuuid, str(STCATH))
            # update the database
            sql = "UPDATE PageMarkersCondition SET conditionuuid=%s WHERE id=%s"
            val = (newuuid, row["id"])
            cursorupdate.execute(sql, val)
            mydb.commit()
        else:
            conditionuuid = URIRef(row["conditionuuid"], str(STCATH))
        graph.add((conditionuuid, RDF.type, CRM["E3_Condition_State"]))
        graph.add((conditionuuid, RDFS.label, Literal("Condition of subset of " + str(pagemarkersetlabel[0][1]), lang="en")))
        graph.add((pagemarkersubsetuuid, CRM["P44_has_condition"], conditionuuid)) # subset of pagemarkers have a condition
        if row["condition"] is not None:
            if row["condition"] == "Sound":
                conditiontypeuuid = URIRef("http://stcath.sound")
            elif row["condition"] == "Detached":
                conditiontypeuuid = URIRef("http://vocab.getty.edu/aat/300131111")
            elif row["condition"] == "Broken off":
                conditiontypeuuid = URIRef("http://stcath.brokenoff")
            elif row["condition"] == "Worn":
                conditiontypeuuid = URIRef("http://vocab.getty.edu/aat/300219449")
            elif row["condition"] == "Stained":
                conditiontypeuuid = URIRef("http://vocab.getty.edu/aat/300379497")
            elif row["condition"] == "Missing":
                conditiontypeuuid = URIRef("http://stcath.missing")
            elif row["condition"] == "Trimmed foredge":
                conditiontypeuuid = URIRef("http://stcath.trimmedforedge")
            elif row["condition"] == "Dangling":
                conditiontypeuuid = URIRef("http://stcath.dangling")
            elif row["condition"] == "Adhesive remains only":
                conditiontypeuuid = URIRef("http://stcath.missing")
                graph.add((conditionuuid, CRM["P3_has_note"], Literal(row["condition"], lang="en")))
            elif row["condition"] == "Rodent":
                conditiontypeuuid = URIRef("http://vocab.getty.edu/aat/300380188")
            elif row["condition"] == "Insect damage":
                conditiontypeuuid = URIRef("http://vocab.getty.edu/aat/300230031")
            elif row["condition"] == "Abraded in the fold":
                conditiontypeuuid = URIRef("http://vocab.getty.edu/aat/300053077")
                graph.add((conditionuuid, CRM["P3_has_note"], Literal(row["condition"], lang="en")))
            elif row["condition"] == "Worn at foredge":
                conditiontypeuuid = URIRef("http://vocab.getty.edu/aat/300219449")
                graph.add((conditionuuid, CRM["P3_has_note"], Literal(row["condition"], lang="en")))
            elif row["condition"] == "Dirty":
                conditiontypeuuid = URIRef("http://stcath.dirty")
            graph.add((conditionuuid, CRM["P2_has_type"], conditiontypeuuid))

        if row["msid"] == doci2:
            docgraph2.add((pagemarkersubsetuuid, RDF.type, pmstype))
            docgraph2.add((pagemarkersubsetuuid, RDFS.label, Literal("Subset of '" + str(pagemarkersetlabel[0][1]) + "' with condition " + row["condition"], lang="en")))
            docgraph2.add((pagemarkersetuuid, CRM["P46_is_composed_of"], pagemarkersubsetuuid))
            docgraph2.add((pagemarkersubsetuuid, CRM["P57_has_number_of_parts"], Literal(row["conditionno"])))  # specify the pagemarker subset in the specific location
            docgraph2.add((conditionuuid, RDF.type, CRM["E3_Condition_State"]))
            docgraph2.add((conditionuuid, RDFS.label, Literal("Condition of subset of " + str(pagemarkersetlabel[0][1]), lang="en")))
            docgraph2.add((pagemarkersubsetuuid, CRM["P44_has_condition"], conditionuuid))  # subset of pagemarkers have a condition
            docgraph2.add((conditionuuid, CRM["P2_has_type"], conditiontypeuuid))
            docgraph2.add((URIRef("http://stcath.sound"), RDF.type, CRM["E55_Type"]))
            docgraph2.add((URIRef("http://stcath.sound"), RDFS.label, Literal("sound", lang="en")))
        if row["msid"] == doci3:
            docgraph3.add((pagemarkersubsetuuid, RDF.type, pmstype))
            docgraph3.add((pagemarkersubsetuuid, RDFS.label, Literal("Subset of '" + str(pagemarkersetlabel[0][1]) + "' with condition " + row["condition"], lang="en")))
            docgraph3.add((pagemarkersetuuid, CRM["P46_is_composed_of"], pagemarkersubsetuuid))
            docgraph3.add((pagemarkersubsetuuid, CRM["P57_has_number_of_parts"], Literal(row["conditionno"])))  # specify the pagemarker subset in the specific location
            docgraph3.add((conditionuuid, RDF.type, CRM["E3_Condition_State"]))
            docgraph3.add((conditionuuid, RDFS.label, Literal("Condition of subset of " + str(pagemarkersetlabel[0][1]), lang="en")))
            docgraph3.add((pagemarkersubsetuuid, CRM["P44_has_condition"], conditionuuid))  # subset of pagemarkers have a condition
            docgraph3.add((conditionuuid, CRM["P2_has_type"], conditiontypeuuid))
            docgraph3.add((URIRef("http://stcath.dangling"), RDF.type, CRM["E55_Type"]))
            docgraph3.add((URIRef("http://stcath.dangling"), RDFS.label, Literal("dangling", lang="en")))

    # documentation drawing
    dot1 = visualise_graph(docgraph1, 'MS without page-markers')
    dot2 = visualise_graph(docgraph2, 'MS with page-markers')
    dot3 = visualise_graph(docgraph3, 'MS with page-markers')
    dot1.render('pagemarkers/pagemarkers-1.gv',format='svg')
    dot2.render('pagemarkers/pagemarkers-2.gv',format='svg')
    dot3.render('pagemarkers/pagemarkers-3.gv', format='svg')

    # serialise the graph
    graph.serialize(destination='pagemarkers/pagemarkers.ttl', format='turtle', encoding="utf-8")
    docgraph1.serialize(destination='pagemarkers/pagemarkers-doc-1.n3', format='n3', encoding="utf-8")
    docgraph2.serialize(destination='pagemarkers/pagemarkers-doc-2.n3', format='n3', encoding="utf-8")
    docgraph3.serialize(destination='pagemarkers/pagemarkers-doc-3.n3', format='n3', encoding="utf-8")
Esempio n. 7
0
def liftingtabs(mydb, cursor, cursorupdate):

    graph = Graph()  # graph for the dataset
    docgraph1 = Graph()  # graph for the documentation drawing
    docgraph2 = Graph()  # graph for the documentation drawing
    # add namespaces
    graph = apply_namespaces(graph)
    docgraph1 = apply_namespaces(docgraph1)
    docgraph2 = apply_namespaces(docgraph2)
    # get the ones we need here
    STCATH = get_namespace(graph, 'stcath')
    CRM = get_namespace(graph, 'crm')

    doci1 = 2  # msid with no liftingtabs
    doci2 = 1307  # msid with liftingtabs, pagemarker id: 23

    # deal with thesaurus concepts
    graph.add((URIRef("http://w3id.org/lob/concept/2833"), RDF.type,
               CRM["E55_Type"]))
    graph.add((URIRef("http://w3id.org/lob/concept/2833"), RDFS.label,
               Literal("board strap markers", lang="en")))
    graph.add((URIRef("http://w3id.org/lob/concept/1658"), RDF.type,
               CRM["E57_Material"]))
    graph.add((URIRef("http://w3id.org/lob/concept/1658"), RDFS.label,
               Literal("tanned skin", lang="en")))
    graph.add((URIRef("http://w3id.org/lob/concept/1197"), RDF.type,
               CRM["E57_Material"]))
    graph.add((URIRef("http://w3id.org/lob/concept/1197"), RDFS.label,
               Literal("tawed skin", lang="en")))
    graph.add((URIRef("http://w3id.org/lob/concept/5429"), RDF.type,
               CRM["E55_Type"]))
    graph.add((URIRef("http://w3id.org/lob/concept/5429"), RDFS.label,
               Literal("adhering", lang="en")))
    graph.add((URIRef("http://w3id.org/lob/concept/4045"), RDF.type,
               CRM["E55_Type"]))
    graph.add((URIRef("http://w3id.org/lob/concept/4045"), RDFS.label,
               Literal("nailing", lang="en")))
    graph.add((URIRef("http://stcath.overturnin"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://stcath.overturnin"), RDFS.label,
               Literal("over turn-in attaching", lang="en")))
    graph.add((URIRef("http://stcath.underturnin"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://stcath.underturnin"), RDFS.label,
               Literal("under turn-in attaching", lang="en")))
    graph.add((URIRef("http://stcath.brokenoff"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://stcath.brokenoff"), RDFS.label,
               Literal("broken off", lang="en")))
    graph.add(
        (URIRef("http://stcath.brokenandsewn"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://stcath.brokenandsewn"), RDFS.label,
               Literal("broken and sewn", lang="en")))
    graph.add((URIRef("http://stcath.missing"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://stcath.missing"), RDFS.label,
               Literal("missing", lang="en")))
    graph.add((URIRef("http://stcath.sound"), RDF.type, CRM["E55_Type"]))
    graph.add(
        (URIRef("http://stcath.sound"), RDFS.label, Literal("sound",
                                                            lang="en")))
    graph.add((URIRef("http://stcath.worn"), RDF.type, CRM["E55_Type"]))
    graph.add(
        (URIRef("http://stcath.worn"), RDFS.label, Literal("worn", lang="en")))
    graph.add((URIRef("http://stcath.detached"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://stcath.detached"), RDFS.label,
               Literal("detached", lang="en")))
    graph.add((URIRef("http://stcath.dangling"), RDF.type, CRM["E55_Type"]))
    graph.add((URIRef("http://stcath.dangling"), RDFS.label,
               Literal("dangling", lang="en")))

    docgraph1.add((URIRef("http://w3id.org/lob/concept/2833"), RDF.type,
                   CRM["E55_Type"]))
    docgraph1.add((URIRef("http://w3id.org/lob/concept/2833"), RDFS.label,
                   Literal("board strap markers", lang="en")))

    docgraph2.add((URIRef("http://w3id.org/lob/concept/2833"), RDF.type,
                   CRM["E55_Type"]))
    docgraph2.add((URIRef("http://w3id.org/lob/concept/2833"), RDFS.label,
                   Literal("board strap markers", lang="en")))
    docgraph2.add((URIRef("http://w3id.org/lob/concept/1658"), RDF.type,
                   CRM["E55_Type"]))
    docgraph2.add((URIRef("http://w3id.org/lob/concept/1658"), RDFS.label,
                   Literal("tanned skin", lang="en")))
    docgraph2.add((URIRef("http://w3id.org/lob/concept/5429"), RDF.type,
                   CRM["E55_Type"]))
    docgraph2.add((URIRef("http://w3id.org/lob/concept/5429"), RDFS.label,
                   Literal("adhering", lang="en")))
    docgraph2.add(
        (URIRef("http://stcath.underturnin"), RDF.type, CRM["E55_Type"]))
    docgraph2.add((URIRef("http://stcath.underturnin"), RDFS.label,
                   Literal("under turn-in attaching", lang="en")))
    docgraph2.add(
        (URIRef("http://stcath.brokenoff"), RDF.type, CRM["E55_Type"]))
    docgraph2.add((URIRef("http://stcath.brokenoff"), RDFS.label,
                   Literal("broken off", lang="en")))

    # 1_3_LiftingTabs
    cursor.execute(
        "SELECT mss.msuuid, mss.cataloguename, lt.msid, lt.yesnonk FROM MSs mss INNER JOIN `1_3_LiftingTabs` lt on mss.id=lt.msid"
    )
    rows = cursor.fetchall()

    for row in rows:
        msuuid = URIRef(row["msuuid"], str(STCATH))
        if row["yesnonk"] == "no":
            graph.add((msuuid,
                       CRM["NTP46_is_not_composed_of_physical_thing_of_type"],
                       URIRef("http://w3id.org/lob/concept/2833")))

        if row["msid"] == doci1:
            docgraph1.add(
                (msuuid,
                 CRM["NTP46_is_not_composed_of_physical_thing_of_type"],
                 URIRef("http://w3id.org/lob/concept/2833")))
            docgraph1.add((msuuid, RDF.type, CRM["E22_Man-Made_Object"]))
            docgraph1.add(
                (msuuid, RDFS.label, Literal(row["cataloguename"], lang="en")))
        if row["msid"] == doci2:
            docgraph2.add((msuuid, RDF.type, CRM["E22_Man-Made_Object"]))
            docgraph2.add(
                (msuuid, RDFS.label, Literal(row["cataloguename"], lang="en")))

    # LiftingTabs
    cursor.execute(
        "SELECT lt.id, mss.msuuid, mss.cataloguename, lt.msid, lt.partadditionuuid, lt.leftliftingtabuuid, lt.rightliftingtabuuid, lt.location, lt.material, lt.attachment, lt.turnin FROM MSs mss INNER JOIN `LiftingTabs` lt on mss.id=lt.msid"
    )
    rows = cursor.fetchall()

    for row in rows:
        shelfmark = row["cataloguename"]
        msuuid = URIRef(row["msuuid"], str(STCATH))
        # lifting tabs
        locations = row["location"].split(",")
        # TODO: deal with option "Centre, board"
        for location in locations:
            location = location.strip()
            if location == "Left board" or location == "Both boards" or location == "Right board":
                if location == "Left board" or location == "Both boards":
                    if row["leftliftingtabuuid"] is None:
                        newuuid = str(uuid.uuid4())
                        leftliftingtabuuid = URIRef(newuuid, str(STCATH))
                        # update the database
                        sql = "UPDATE LiftingTabs SET leftliftingtabuuid=%s WHERE id=%s"
                        val = (newuuid, row["id"])
                        cursorupdate.execute(sql, val)
                        mydb.commit()
                    else:
                        leftliftingtabuuid = URIRef(row["leftliftingtabuuid"],
                                                    str(STCATH))

                    graph.add((leftliftingtabuuid, RDF.type,
                               CRM["E22_Man-Made_Object"]))
                    graph.add((leftliftingtabuuid, CRM["P2_has_type"],
                               URIRef("http://w3id.org/lob/concept/2833")))
                    graph.add((leftliftingtabuuid, RDFS.label,
                               Literal("Left board marker of " + shelfmark,
                                       lang="en")))

                    if row["material"] == "Tanned leather":
                        graph.add((leftliftingtabuuid, CRM["P45_consists_of"],
                                   URIRef("http://w3id.org/lob/concept/1658")))
                    elif row["material"] == "Tawed leather":
                        graph.add((leftliftingtabuuid, CRM["P45_consists_of"],
                                   URIRef("http://w3id.org/lob/concept/1197")))

                if location == "Right board" or location == "Both boards":
                    if row["rightliftingtabuuid"] is None:
                        newuuid = str(uuid.uuid4())
                        rightliftingtabuuid = URIRef(newuuid, str(STCATH))
                        # update the database
                        sql = "UPDATE LiftingTabs SET rightliftingtabuuid=%s WHERE id=%s"
                        val = (newuuid, row["id"])
                        cursorupdate.execute(sql, val)
                        mydb.commit()
                    else:
                        rightliftingtabuuid = URIRef(
                            row["rightliftingtabuuid"], str(STCATH))

                    graph.add((rightliftingtabuuid, RDF.type,
                               CRM["E22_Man-Made_Object"]))
                    graph.add((rightliftingtabuuid, CRM["P2_has_type"],
                               URIRef("http://w3id.org/lob/concept/2833")))
                    graph.add((rightliftingtabuuid, RDFS.label,
                               Literal("Right board marker of " + shelfmark,
                                       lang="en")))

                    if row["material"] == "Tanned leather":
                        graph.add((rightliftingtabuuid, CRM["P45_consists_of"],
                                   URIRef("http://w3id.org/lob/concept/1658")))
                    elif row["material"] == "Tawed leather":
                        graph.add((rightliftingtabuuid, CRM["P45_consists_of"],
                                   URIRef("http://w3id.org/lob/concept/1197")))

                if row["partadditionuuid"] is None:
                    newuuid = str(uuid.uuid4())
                    partadditionuuid = URIRef(newuuid, str(STCATH))
                    # update the database
                    sql = "UPDATE LiftingTabs SET partadditionuuid=%s WHERE id=%s"
                    val = (newuuid, row["id"])
                    cursorupdate.execute(sql, val)
                    mydb.commit()
                else:
                    partadditionuuid = URIRef(row["partadditionuuid"],
                                              str(STCATH))

                graph.add(
                    (partadditionuuid, RDF.type, CRM["E79_Part_Addition"]))
                graph.add((partadditionuuid, RDFS.label,
                           Literal("Addition of board markers to " + shelfmark,
                                   lang="en")))
                graph.add((partadditionuuid, CRM["P110_augmented"], msuuid))

                if location == "Both boards" or location == "Left board":
                    graph.add((partadditionuuid, CRM["P111_added"],
                               leftliftingtabuuid))
                if location == "Both boards" or location == "Right board":
                    graph.add((partadditionuuid, CRM["P111_added"],
                               rightliftingtabuuid))
                if row['attachment'] == "Glued":
                    graph.add(
                        (partadditionuuid, CRM["P32_used_general_technique"],
                         URIRef("http://w3id.org/lob/concept/5429")))
                elif row['attachment'] == "Nailed":
                    graph.add(
                        (partadditionuuid, CRM["P32_used_general_technique"],
                         URIRef("http://w3id.org/lob/concept/4045")))
                if row['turnin'] == "Under turn-in":
                    graph.add(
                        (partadditionuuid, CRM["P32_used_general_technique"],
                         URIRef("http://stcath.underturnin")))
                elif row['turnin'] == "Over turn-in":
                    graph.add(
                        (partadditionuuid, CRM["P32_used_general_technique"],
                         URIRef("http://stcath.overturnin")))

        if location == "Both boards":
            # TODO: Mark the location of the lifting tabs when the board foredge place is available
            #graph.add((leftliftingtabuuid, CRM["P55_has_current_location"], ...))
            #graph.add((rightliftingtabuuid, CRM["P55_has_current_location"], ...))
            pass
        elif location == "Right board":
            # TODO: Mark the location of the lifting tabs when the board foredge place is available
            #graph.add((rightliftingtabuuid, CRM["P55_has_current_location"], ...))
            pass
        elif location == "Left board":
            # TODO: Mark the location of the lifting tabs when the board foredge place is available
            #graph.add((leftliftingtabuuid, CRM["P55_has_current_location"], ...))
            pass

        if row["msid"] == doci2:
            docgraph2.add(
                (leftliftingtabuuid, RDF.type, CRM["E22_Man-Made_Object"]))
            docgraph2.add((leftliftingtabuuid, RDFS.label,
                           Literal("Left board marker of " + shelfmark,
                                   lang="en")))
            docgraph2.add((leftliftingtabuuid, CRM["P2_has_type"],
                           URIRef("http://w3id.org/lob/concept/2833")))
            docgraph2.add(
                (rightliftingtabuuid, RDF.type, CRM["E22_Man-Made_Object"]))
            docgraph2.add((rightliftingtabuuid, RDFS.label,
                           Literal("Right board marker of " + shelfmark,
                                   lang="en")))
            docgraph2.add((rightliftingtabuuid, CRM["P2_has_type"],
                           URIRef("http://w3id.org/lob/concept/2833")))
            docgraph2.add(
                (partadditionuuid, RDF.type, CRM["E79_Part_Addition"]))
            docgraph2.add((partadditionuuid, RDFS.label,
                           Literal("Addition of board markers to " + shelfmark,
                                   lang="en")))
            docgraph2.add(
                (partadditionuuid, CRM["P111_added"], leftliftingtabuuid))
            docgraph2.add(
                (partadditionuuid, CRM["P111_added"], rightliftingtabuuid))
            docgraph2.add((partadditionuuid, CRM["P110_augmented"], msuuid))
            docgraph2.add(
                (leftliftingtabuuid, RDF.type, CRM["E22_Man-Made_Object"]))
            docgraph2.add((leftliftingtabuuid, RDFS.label,
                           Literal("Left board marker of " + shelfmark,
                                   lang="en")))
            docgraph2.add(
                (rightliftingtabuuid, RDF.type, CRM["E22_Man-Made_Object"]))
            docgraph2.add((rightliftingtabuuid, RDFS.label,
                           Literal("Right board marker of " + shelfmark,
                                   lang="en")))
            docgraph2.add(
                (partadditionuuid, RDF.type, CRM["E79_Part_Addition"]))
            docgraph2.add((partadditionuuid, RDFS.label,
                           Literal("Addition of board markers to " + shelfmark,
                                   lang="en")))
            docgraph2.add(
                (partadditionuuid, CRM["P111_added"], leftliftingtabuuid))
            docgraph2.add(
                (partadditionuuid, CRM["P111_added"], rightliftingtabuuid))
            docgraph2.add((partadditionuuid, CRM["P110_augmented"], msuuid))
            docgraph2.add((leftliftingtabuuid, CRM["P45_consists_of"],
                           URIRef("http://w3id.org/lob/concept/1658")))
            docgraph2.add((rightliftingtabuuid, CRM["P45_consists_of"],
                           URIRef("http://w3id.org/lob/concept/1658")))
            docgraph2.add((partadditionuuid, CRM["P32_used_general_technique"],
                           URIRef("http://w3id.org/lob/concept/5429")))
            docgraph2.add((partadditionuuid, CRM["P32_used_general_technique"],
                           URIRef("http://stcath.underturnin")))

    # LiftingTabsCondition
    cursor.execute(
        "SELECT ltc.id, lt.msid, mss.msuuid, mss.cataloguename, lt.leftliftingtabuuid, lt.rightliftingtabuuid, ltc.condition, ltc.conditionuuid, ltc.leftboard FROM `LiftingTabsCondition` ltc LEFT JOIN `LiftingTabs` lt ON ltc.liftingtabid=lt.id INNER JOIN MSs mss ON mss.id=lt.msid"
    )
    rows = cursor.fetchall()

    for row in rows:
        shelfmark = row["cataloguename"]
        msuuid = URIRef(row["msuuid"], str(STCATH))
        if row['leftliftingtabuuid'] is not None:
            leftliftingtabuuid = URIRef(row["leftliftingtabuuid"], str(STCATH))
        # elif row['leftliftingtabuuid'] is None:
        #     if row["leftboard"] == 1: # we have a left lifting tab condition but no left lifting tab
        #         print(str(row["msid"]) + ", ")
        if row['rightliftingtabuuid'] is not None:
            rightliftingtabuuid = URIRef(row["rightliftingtabuuid"],
                                         str(STCATH))
        # elif row['rightliftingtabuuid'] is None:
        #     if row["leftboard"] == 0: # we have a right lifting tab condition but no right lifting tab
        #         print(str(row["msid"]) + ", ")
        if row["leftboard"] == 1:  # this is the left board
            if row["conditionuuid"] is None:
                newuuid = str(uuid.uuid4())
                conditionuuid = URIRef(newuuid, str(STCATH))
                # update the database
                sql = "UPDATE LiftingTabsCondition SET conditionuuid=%s WHERE id=%s"
                val = (newuuid, row["id"])
                cursorupdate.execute(sql, val)
                mydb.commit()
            else:
                conditionuuid = URIRef(row["conditionuuid"], str(STCATH))

            graph.add((conditionuuid, RDF.type, CRM["E3_Condition_State"]))
            graph.add(
                (conditionuuid, RDFS.label,
                 Literal("Condition of left board marker of " + shelfmark,
                         lang="en")))
            graph.add(
                (leftliftingtabuuid, CRM["P44_has_condition"], conditionuuid))

            if row["msid"] == doci2:
                docgraph2.add(
                    (conditionuuid, RDF.type, CRM["E3_Condition_State"]))
                docgraph2.add(
                    (conditionuuid, RDFS.label,
                     Literal("Condition of left board marker of " + shelfmark,
                             lang="en")))
                docgraph2.add((leftliftingtabuuid, CRM["P44_has_condition"],
                               conditionuuid))
                docgraph2.add((conditionuuid, CRM["P2_has_type"],
                               URIRef("http://stcath.brokenoff")))

        elif row["leftboard"] == 0:  # this is the right board
            if row["conditionuuid"] is None:
                newuuid = str(uuid.uuid4())
                conditionuuid = URIRef(newuuid, str(STCATH))
                # update the database
                sql = "UPDATE LiftingTabsCondition SET conditionuuid=%s WHERE id=%s"
                val = (newuuid, row["id"])
                cursorupdate.execute(sql, val)
                mydb.commit()
            else:
                conditionuuid = URIRef(row["conditionuuid"], str(STCATH))

            graph.add((conditionuuid, RDF.type, CRM["E3_Condition_State"]))
            graph.add(
                (conditionuuid, RDFS.label,
                 Literal("Condition of right board marker of " + shelfmark,
                         lang="en")))
            graph.add(
                (rightliftingtabuuid, CRM["P44_has_condition"], conditionuuid))

            if row["msid"] == doci2:
                docgraph2.add(
                    (conditionuuid, RDF.type, CRM["E3_Condition_State"]))
                docgraph2.add(
                    (conditionuuid, RDFS.label,
                     Literal("Condition of right board marker of " + shelfmark,
                             lang="en")))
                docgraph2.add((rightliftingtabuuid, CRM["P44_has_condition"],
                               conditionuuid))
                docgraph2.add((conditionuuid, CRM["P2_has_type"],
                               URIRef("http://stcath.brokenoff")))

        if row["condition"] == "Broken off":
            graph.add((conditionuuid, CRM["P2_has_type"],
                       URIRef("http://stcath.brokenoff")))
        elif row["condition"] == "Broken and Sewn":
            graph.add((conditionuuid, CRM["P2_has_type"],
                       URIRef("http://stcath.brokenandsewn")))
        elif row["condition"] == "Missing":
            graph.add((conditionuuid, CRM["P2_has_type"],
                       URIRef("http://stcath.missing")))
        elif row["condition"] == "Sound":
            graph.add((conditionuuid, CRM["P2_has_type"],
                       URIRef("http://stcath.sound")))
        elif row["condition"] == "Worn":
            graph.add((conditionuuid, CRM["P2_has_type"],
                       URIRef("http://stcath.worn")))
        elif row["condition"] == "Detached":
            graph.add((conditionuuid, CRM["P2_has_type"],
                       URIRef("http://stcath.detached")))
        elif row["condition"] == "Dangling":
            graph.add((conditionuuid, CRM["P2_has_type"],
                       URIRef("http://stcath.dangling")))

    # documentation drawing
    dot1 = visualise_graph(docgraph1, 'MS without board strap markers',
                           "forth")
    dot2 = visualise_graph(docgraph2, 'MS with board strap markers', "forth")
    dot1.render('liftingtabs/liftingtabs-1.gv', format='svg')
    dot2.render('liftingtabs/liftingtabs-2.gv', format='svg')

    # serialise the graph
    graph.serialize(destination='liftingtabs/liftingtabs.ttl',
                    format='turtle',
                    encoding="utf-8")
    docgraph1.serialize(destination='liftingtabs/liftingtabs-doc-1.n3',
                        format='n3',
                        encoding="utf-8")
    docgraph2.serialize(destination='liftingtabs/liftingtabs-doc-2.n3',
                        format='n3',
                        encoding="utf-8")