Example #1
0
    def testAnnotate(self):
        """
        Annotate file in created RO

        ro annotate file attribute-name [ attribute-value ]
        """
        rodir = self.createTestRo("data/ro-test-1", "RO test annotation", "ro-testRoAnnotate")
        args = [
            "ro", "annotate", rodir+"/"+"subdir1/subdir1-file.txt", "title", "subdir1-file title",
            "-v",
            ]
        with SwitchStdout(self.outstr):
            status = ro.runCommand(ro_test_config.CONFIGDIR, ro_test_config.ROBASEDIR, args)
        outtxt = self.outstr.getvalue()
        assert status == 0, outtxt
        self.assertEqual(outtxt.count("ro annotate"), 1)
        #self.assertRegexpMatches(outtxt, "annotation.*dc:title")
        # Read manifest and check for annotation
        manifestgraph = ro_manifest.readManifestGraph(rodir)
        filesubj  = ro_manifest.getComponentUri(rodir, "subdir1/subdir1-file.txt")
        log.debug("filesubj %s"%filesubj)
        filetitle = manifestgraph.value(filesubj, DCTERMS.title, None),
        self.assertEqual(len(filetitle), 1, "Singleton result expected")
        self.assertEqual(filetitle[0], "subdir1-file title")
        self.deleteTestRo(rodir)
        return
Example #2
0
def createAnnotationBody(ro_config, ro_dir, rofile, attrdict, defaultType="string"):
    """
    Create a new annotation body for a single resource in a research object.

    Existing annotations for the same resource are not touched; if an annotation is being
    added or replaced, it is the calling program'sresponsibility to update the manifest to
    reference the active annotations.  A new name is allocated for the created annotation,
    which is returned as the result of this function.

    ro_config   is the research object manager configuration, supplied as a dictionary
    ro_dir      is the research object root directory
    rofile      is the name of the Research Object component to be annotated, possibly
                relative to the RO root directory.
    attrdict    is a dictionary of attributes to be saved inthe annotation body.
                Dictionary keys are attribute names that can be resolved via getAnnotationByName.

    Returns the name of the annotation body created relative to the RO
    manifest and metadata directory.
    """
    # Assemble data for annotation
    anngraph = rdflib.Graph()
    s = ro_manifest.getComponentUri(ro_dir, rofile)
    for k in attrdict:
        (p,t) = getAnnotationByName(ro_config, k, defaultType)
        anngraph.add((s, p, makeAnnotationValue(ro_config, attrdict[k],t)))
    # Write graph and return filename
    return createAnnotationGraphBody(ro_config, ro_dir, rofile, anngraph)
Example #3
0
def _addAnnotationBodyToRoGraph(ro_graph, ro_dir, rofile, annfile):
    """
    Add a new annotation body to an RO graph

    ro_graph    graph to which annotation is added
    ro_dir      is the research object directory
    rofile      is the research object file being annotated
    annfile     is the base file name of the annotation body to be added
    """
    # <ore:aggregates>
    #   <ro:AggregatedAnnotation>
    #     <ro:annotatesAggregatedResource rdf:resource="data/UserRequirements-astro.ods" />
    #     <ao:body rdf:resource=".ro/(annotation).rdf" />
    #   </ro:AggregatedAnnotation>
    # </ore:aggregates>
    ann = rdflib.BNode()
    ro_graph.add((ann, RDF.type, RO.AggregatedAnnotation))
    ro_graph.add((ann, RO.annotatesAggregatedResource, ro_manifest.getComponentUri(ro_dir, rofile)))
    ro_graph.add((ann, AO.body, ro_manifest.getComponentUri(ro_dir, ro_settings.MANIFEST_DIR+"/"+annfile)))
    ro_graph.add((ro_manifest.getComponentUri(ro_dir, "."), ORE.aggregates, ann))
    return
Example #4
0
def _getAnnotationValues(ro_config, ro_dir, rofile, attrname):
    """
    Returns iterator over annotation values for given subject and attribute
    """
    log.debug("getAnnotationValues: ro_dir %s, rofile %s, attrname %s"%(ro_dir, rofile, attrname))
    ro_graph    = ro_manifest.readManifestGraph(ro_dir)
    subject     = ro_manifest.getComponentUri(ro_dir, rofile)
    (predicate,valtype) = getAnnotationByName(ro_config, attrname)
    #@@TODO refactor common code with getRoAnnotations, etc.
    for ann_node in ro_graph.subjects(predicate=RO.annotatesAggregatedResource, object=subject):
        ann_uri   = ro_graph.value(subject=ann_node, predicate=AO.body)
        ann_graph = readAnnotationBody(ro_dir, ro_manifest.getComponentUriRel(ro_dir, ann_uri))
        for v in ann_graph.objects(subject=subject, predicate=predicate):
            #log.debug("Triple: %s %s %s"%(subject,p,v))
            yield v
    return
Example #5
0
def _removeSimpleAnnotation(ro_config, ro_dir, rofile, attrname, attrvalue):
    """
    Remove a simple annotation or multiple matching annotations a research object.

    ro_config   is the research object manager configuration, supplied as a dictionary
    ro_dir      is the research object root directory
    rofile      names the annotated file or resource, possibly relative to the RO.
    attrname    names the attribute in a form recognized by getAnnotationByName
    attrvalue   is the attribute value to be deleted, or Nomne to delete all vaues
    """
    log.debug("removeSimpleAnnotation: ro_dir %s, rofile %s, attrname %s, attrvalue %s"%
              (ro_dir, rofile, attrname, attrvalue))
    # Enumerate annotations
    # For each:
    #     if annotation is only one in graph then:
    #         remove aggregated annotation
    #     else:
    #         create new annotation graph witj annotation removed
    #         update aggregated annotation
    ro_graph    = ro_manifest.readManifestGraph(ro_dir)
    subject     = ro_manifest.getComponentUri(ro_dir, rofile)
    (predicate,valtype) = getAnnotationByName(ro_config, attrname)
    val         = attrvalue and makeAnnotationValue(ro_config, attrvalue, valtype)
    #@@TODO refactor common code with getRoAnnotations, etc.
    add_annotations = []
    remove_annotations = []
    for ann_node in ro_graph.subjects(predicate=RO.annotatesAggregatedResource, object=subject):
        ann_uri   = ro_graph.value(subject=ann_node, predicate=AO.body)
        ann_graph = readAnnotationBody(ro_dir, ro_manifest.getComponentUriRel(ro_dir, ann_uri))
        if (subject, predicate, val) in ann_graph:
            ann_graph.remove((subject, predicate, val))
            if (subject, None, None) in ann_graph:
                # Triples remain in annotation body: write new body and update RO graph
                ann_name = createAnnotationGraphBody(ro_config, ro_dir, rofile, ann_graph)
                remove_annotations.append(ann_node)
                add_annotations.append(ann_name)
            else:
                # Remove annotation from RO graph
                remove_annotations.append(ann_node)
    # Update RO graph if needed
    if add_annotations or remove_annotations:
        for a in remove_annotations:
            _removeAnnotationBodyFromRoGraph(ro_graph, a)
        for a in add_annotations:
            _addAnnotationBodyToRoGraph(ro_graph, ro_dir, rofile, a)
        ro_manifest.writeManifestGraph(ro_dir, ro_graph)
    return
Example #6
0
def _replaceSimpleAnnotation(ro_config, ro_dir, rofile, attrname, attrvalue):
    """
    Replace a simple annotation in a research object.

    ro_config   is the research object manager configuration, supplied as a dictionary
    ro_dir      is the research object root directory
    rofile      names the file or resource to be annotated, possibly relative to the RO.
    attrname    names the attribute in a form recognized by getAnnotationByName
    attrvalue   is a new value to be associated with the attribute
    """
    ro_graph = ro_manifest.readManifestGraph(ro_dir)
    subject  = ro_manifest.getComponentUri(ro_dir, rofile)
    (predicate,valtype) = getAnnotationByName(ro_config, attrname)
    log.debug("Replace annotation: subject %s, predicate %s, value %s"%(repr(subject), repr(predicate), repr(attrvalue)))
    ro_graph.remove((subject, predicate, None))
    ro_graph.add((subject, predicate, makeAnnotationValue(ro_config, attrvalue, valtype)))
    ro_manifest.writeManifestGraph(ro_dir, ro_graph)
    return
Example #7
0
def _getFileAnnotations(ro_dir, rofile):
    """
    Returns iterator over annotations applied to a specified component in the RO

    Each value returned by the iterator is a (subject,predicate,object) triple.
    """
    log.debug("getFileAnnotations: ro_dir %s, rofile %s"%(ro_dir, rofile))
    ro_graph    = ro_manifest.readManifestGraph(ro_dir)
    subject     = ro_manifest.getComponentUri(ro_dir, rofile)
    log.debug("getFileAnnotations: %s"%str(subject))
    #@@TODO refactor common code with getRoAnnotations, etc.
    for ann_node in ro_graph.subjects(predicate=RO.annotatesAggregatedResource, object=subject):
        ann_uri   = ro_graph.value(subject=ann_node, predicate=AO.body)
        ann_graph = readAnnotationBody(ro_dir, ro_manifest.getComponentUriRel(ro_dir, ann_uri))
        if ann_graph:
            for (p, v) in ann_graph.predicate_objects(subject=subject):
                #log.debug("Triple: %s %s %s"%(subject,p,v))
                yield (subject, p, v)
    return
Example #8
0
 def annotationTest(self, anntype, annvalue, anntypeuri, annexpect):
     rodir = self.createTestRo("data/ro-test-1", "RO test annotation", "ro-testRoAnnotate")
     args = [
         "ro", "annotate", rodir+"/"+"subdir1/subdir1-file.txt", anntype, annvalue,
         "-v",
         ]
     with SwitchStdout(self.outstr):
         status = ro.runCommand(ro_test_config.CONFIGDIR, ro_test_config.ROBASEDIR, args)
     outtxt = self.outstr.getvalue()
     assert status == 0, outtxt
     self.assertEqual(outtxt.count("ro annotate"), 1)
     # Read manifest and check for annotation
     manifestgraph = ro_manifest.readManifestGraph(rodir)
     filesubj  = ro_manifest.getComponentUri(rodir, "subdir1/subdir1-file.txt")
     fileann   = manifestgraph.value(filesubj, anntypeuri, None),
     #@@TODO: deal with case that expected result is a list
     self.assertEqual(len(fileann), 1, "Singleton result expected")
     self.assertEqual(fileann[0], annexpect)
     self.deleteTestRo(rodir)
     return
Example #9
0
def annotations(progname, configbase, options, args):
    """
    Dusplay annotations
    
    ro annotations [ file | -d dir ]
    """
    # Check command arguments
    if len(args) not in [2,3]:
        print ("%s annotations: wrong number of arguments provided"%
               (progname))
        print ("Usage: %s annotations [ file | -d dir ]"%
               (progname))
        return 1
    ro_config  = ro_utils.readconfig(configbase)
    ro_file    = (args[2] if len(args) >= 3 else "")
    ro_options = {
        "rofile":       ro_file,
        "rodir":        options.rodir or os.path.dirname(ro_file)
        }
    log.debug("ro_options: "+repr(ro_options))
    if options.verbose:
        print "ro annotations -d \"%(rodir)s\" %(rofile)s "%ro_options
    ro_dir= ro_root_directory(progname+" annotations", ro_config, ro_options['rodir'])
    if not ro_dir: return 1
    ro_graph = ro_manifest.readManifestGraph(ro_dir)
    if ro_options['rofile']:
        ro_file     = ro_manifest.getComponentUri(ro_dir, os.path.abspath(ro_options['rofile']))
        annotations = ro_graph.predicate_objects(subject=ro_file)
        print str(ro_file)  # @@TODO figure relativization
        log.debug("annotations for %s"%str(ro_file))
        for (atyp,aval) in annotations:
            aname = getAnnotationNameByUri(ro_config, atyp)
            log.debug("Annotations atyp %s, aname %s, aval %s"%(repr(atyp), aname, repr(aval)))
            print "  %s: %s"%(aname,str(aval))
    else:
        # list all annotations
        assert False, "@@TODO - show annotations for all RO components"
    return 0
Example #10
0
 def testAnnotateMultiple(self):
     rodir  = self.createTestRo("data/ro-test-1", "RO test annotation", "ro-testRoAnnotate")
     rofile = rodir+"/"+"subdir1/subdir1-file.txt"
     annotations = (
         [ {"atypename": "type",        "avalue":"atype",    "atypeuri":DCTERMS.type,        "aexpect":"atype" }
         , {"atypename": "keywords",    "avalue":"asubj",    "atypeuri":DCTERMS.subject,     "aexpect":"asubj" }
         , {"atypename": "description", "avalue":"adesc",    "atypeuri":DCTERMS.description, "aexpect":"adesc" }
         , {"atypename": "format",      "avalue":"aformat",  "atypeuri":DCTERMS.format,      "aexpect":"aformat" }
         , {"atypename": "title",       "avalue":"atitle",   "atypeuri":DCTERMS.title,       "aexpect":"atitle" }
         , {"atypename": "created",     "avalue":"acreated", "atypeuri":DCTERMS.created,     "aexpect":"acreated" }
         #, {"atypename": ..., "avalue":..., "atypeuri":..., "aexpect":... }
         #, {"atypename": ..., "avalue":..., "atypeuri":..., "aexpect":... }
         ])
     self.annotateMultiple(rodir, rofile, annotations)
     # Read manifest and check for annotation
     manifestgraph = ro_manifest.readManifestGraph(rodir)
     filesubj  = ro_manifest.getComponentUri(rodir, "subdir1/subdir1-file.txt")
     for a in annotations:
         fileann   = manifestgraph.value(filesubj, a["atypeuri"], None),
         self.assertEqual(len(fileann), 1, "Singleton result expected")
         self.assertEqual(fileann[0], a["aexpect"])
     self.deleteTestRo(rodir)
     return
Example #11
0
def annotate(progname, configbase, options, args):
    """
    Annotate a specified research object component
    
    ro annotate file attribute-name [ attribute-value ]
    """
    # Check command arguments
    if len(args) not in [4,5]:
        print ("%s annotate: wrong number of arguments provided"%
               (progname))
        print ("Usage: %s annotate file attribute-name [ attribute-value ]"%
               (progname))
        return 1
    ro_config = ro_utils.readconfig(configbase)
    ro_options = {
        "rofile":       args[2],
        "rodir":        os.path.dirname(args[2]),
        "roattribute":  args[3],
        "rovalue":      args[4] or None
        }
    log.debug("ro_options: "+repr(ro_options))
    # Find RO root directory
    ro_dir = ro_root_directory(progname+" attribute", ro_config, ro_options['rodir'])
    if not ro_dir: return 1
    # Read and update manifest
    if options.verbose:
        print "ro annotate %(rofile)s %(roattribute)s \"%(rovalue)s\""%ro_options
    ro_graph = ro_manifest.readManifestGraph(ro_dir)
    (predicate,valtype) = getAnnotationByName(ro_config, ro_options['roattribute'])
    log.debug("Adding annotation predicate: %s, value %s"%(repr(predicate),repr(ro_options['rovalue'])))
    ro_graph.add(
        ( ro_manifest.getComponentUri(ro_dir, os.path.abspath(ro_options['rofile'])),
          predicate,
          rdflib.Literal(ro_options['rovalue']) 
        ) )
    ro_manifest.writeManifestGraph(ro_dir, ro_graph)
    return 0