def _generateStatement(subjectNode, attributeNode, objectValue): """ Internal function to generate a statement from its own attributes! @param RDFNode subjectNode : The subject node for this statement. @param RDFNode attributeNode : The attribute node for this statement. @param undef object : The object where the type should be determined! @return Statement : @author """ #Object node might be another resource or a literal if(isinstance(objectValue, Resource)): if(objectValue.isBlank): #It is a blank resource objectNode = RDF.Node(blank = objectValue.blankIdentifier) else: #It is a normal resource with uri objectNode = RDF.Uri(objectValue.uri) else: #It is a literal - Get info about it literalValues = Resource.castTypeToLiteral(objectValue) #Check what the datatype is (might be None for plain literals) if(literalValues[1] is not None): dt = RDF.Uri(literalValues[1]) objectNode = RDF.Node(literal = literalValues[0], datatype = dt) else: objectNode = RDF.Node(literal = literalValues[0]) #Now return the newly created statement return RDF.Statement(subjectNode, attributeNode, objectNode)
def URI2node(uri): if isinstance(uri, unicode): uri = uri.encode('utf8') if uri.startswith(BNODE_BASE): label = uri[BNODE_BASE_LEN:] return RDF.Node(blank=label) else: return RDF.Node(uri_string=uri)
def _findBottomConcepts(self, conceptUri): qs = RDF.Statement(subject=None, predicate=RDF.Node(uri_string=self.rdfs_subClassOf), object=RDF.Node(uri_string=str(conceptUri))) for statement in self.model.find_statements(qs): bottomConcept = str(statement.subject.uri) self.bottomConcepts.add(bottomConcept) if (statement): self._findBottomConcepts(bottomConcept)
def rate(resource, rating): '''give a resource a nao:numericRating (float from 1-10)''' resource = RDF.Node(RDF.Uri(resource)) rating = RDF.Node(literal=str(rating), datatype=ns['xs'].float.uri) # delete any existing ratings for this resource TripleStore.forget(resource, ns['nao'].numericRating, None) TripleStore.state(resource, ns['nao'].numericRating, rating)
def r_to_l(element): if isinstance(element, rdflib.URIRef): RDF.Uri(element) elif isinstance(element, rdflib.Literal): if element.datatype: kwargs = dict(datatype=RDF.Uri(element.datatype)) else: kwargs = dict(language=element.language) RDF.Node(literal=str(element), **kwargs) elif isinstance(element, rdflib.BNode): RDF.Node(blank=str(element))
def _t(i): if isinstance(i, rdflib.URIRef): return RDF.Node(RDF.Uri(unicode(i))) if isinstance(i, rdflib.BNode): return RDF.Node(blank=str(i)) if isinstance(i, rdflib.Literal): return RDF.Node(literal=str(i)) if isinstance(i, Graph): return _t(i.identifier) if i is None: return None raise TypeError, 'Cannot convert %s' % ` i `
def voidify(self, void_model, dataset): namespaces = lodstats.util.rdf_namespaces.RDFNamespaces() datatype_uri = namespaces.get_rdf_namespace("xsd").integer.uri for property_uri_k, property_uri_v in self.usage_count.iteritems(): property_partitions_node = RDF.Node() statement_property_uri = RDF.Statement(property_partitions_node, namespaces.get_rdf_namespace("void").property, RDF.Node(uri_string=property_uri_k)) statement_property_triples_value = RDF.Statement(property_partitions_node, namespaces.get_rdf_namespace("void").triples, RDF.Node(literal=str(property_uri_v), datatype=datatype_uri)) statement = RDF.Statement(dataset, namespaces.get_rdf_namespace("void").propertyPartition, property_partitions_node) void_model.append(statement) void_model.append(statement_property_uri) void_model.append(statement_property_triples_value)
def __init__(self, uri=None, **args): nd = args.get('node', None) if nd != None: RDFNode.__init__(self, nd) else: if uri != None: # if isinstance(uri, str): # uri = uri.encode() try: RDFNode.__init__(self, RDF.Node(uri_string=uri)) except: logger.warning('uri="%s"(%s)' % (uri, str(type(uri)))) raise else: RDFNode.__init__(self, RDF.Node()) # blank node
def addStatement(model, s, p, o): # Assume subject is a URI string if it is not an RDF.Node if type(s) is not RDF.Node: s_node = RDF.Uri(s) else: s_node = s # Assume predicate is a URI string if it is not an RDF.Node if type(p) is not RDF.Node: p_node = RDF.Uri(p) else: p_node = p # Assume object is a literal if it is not an RDF.Node if type(o) is not RDF.Node: o_node = RDF.Node(o) else: o_node = o statement = RDF.Statement(s_node, p_node, o_node) if statement is None: raise Exception("new RDF.Statement failed") model.add_statement(statement)
def voidify(self): """present stats in VoID (http://www.w3.org/TR/void/)""" serializer = self.get_serializer() ########################### # VoID dataset definition # ########################### void_model = RDF.Model() void_dataset_uri = self.namespaces.get_namespace( 'ls_void') + "?source=" + self.rdf_stats.uri #TODO: URI encode ? void_dataset_entity = RDF.Uri(void_dataset_uri) void_model.append( RDF.Statement(void_dataset_entity, self.namespaces.get_rdf_namespace("rdf").type, self.namespaces.get_rdf_namespace("void").Dataset)) #self.generate_general_void_metadata(void_model, void_dataset_entity) #Number of triples number_of_triples_node = RDF.Node( literal=str(self.rdf_stats.get_no_of_triples()), datatype=self.namespaces.get_rdf_namespace("xsd").integer.uri) void_model.append( RDF.Statement(void_dataset_entity, self.namespaces.get_rdf_namespace("void").triples, number_of_triples_node)) # voidify results from custom stats for stat in lodstats.stats.stats_to_do: stat.voidify(void_model, void_dataset_entity) return serializer.serialize_model_to_string(void_model)
def voidify(self, void_model, dataset): # no of classes result_node = RDF.Node(literal=str(len(self.histogram)), datatype=ns_xs.integer.uri) void_model.append(RDF.Statement(dataset, ns_void.classes, result_node)) # class partition for class_uri, result in self.subject_distinct.iteritems(): clid = RDF.Node() void_model.append( RDF.Statement(dataset, ns_void.classPartition, clid)) void_model.append( RDF.Statement(clid, ns_void['class'], RDF.Uri(class_uri))) result_node = RDF.Node(literal=str(result), datatype=ns_xs.integer.uri) void_model.append( RDF.Statement(clid, ns_void.entities, result_node))
def artists_albums_tagged(_tag): # get a dict of all albums tagged with a certain label, keyed by artist URI albums = {} artists = [] tag = TripleStore.model.get_source(ns['nao'].prefLabel, RDF.Node(_tag)) if tag is None: return (artists, albums) _tagged = TripleStore.model.get_sources(ns['nao'].hasTag, tag) for tagged in _tagged: if not resource_is_type(tagged, ns['mo'].MusicArtist): continue name = artist_name(tagged) artists.append((name, tagged,)) albums[tagged] = [] for made in TripleStore.model.get_sources(ns['foaf'].maker, tagged): if not resource_is_type(made, ns['mo'].Record): continue title = str(TripleStore.model.get_target(made, ns['dc'].title)) albums[tagged].append((title, made)) artists.sort() return (artists, albums)
def addFiles(model, baseUri, inputPath): for root, subFolders, files in os.walk(inputPath): rootUri = root[len(inputPath) + 1:] sys.stderr.write("rootUri: " + rootUri + "\n") files = [f for f in files if not f[0] == '.'] subFolders[:] = [d for d in subFolders if not d[0] == '.'] for fileName in files: f = open(os.path.join(root, fileName), 'r') if (len(rootUri) > 0): fileUri = RDF.Uri(baseUri + rootUri + "/" + fileName) else: fileUri = RDF.Uri(baseUri + fileName) sys.stderr.write("Add Resource: " + fileUri.__str__() + "\n") markdownString = f.read() model.append( RDF.Statement( fileUri, RDF.Uri("http://ns.ontowiki.net/SysOnt/Site/content"), RDF.Node(markdownString, datatype=RDF.Uri( "http://ns.ontowiki.net/SysOnt/Markdown")))) model.append( RDF.Statement( fileUri, RDF.Uri("http://www.w3.org/1999/02/22-rdf-syntax-ns#type"), RDF.Uri("http://xmlns.com/foaf/0.1/Document"))) model.append( RDF.Statement( fileUri, RDF.Uri("http://www.w3.org/2000/01/rdf-schema#label"), fileName))
def createVoIDModel(to): """Creates an RDF Model according to the VoID Dataset spec for the given arguments. Returns: RDF.Model""" # Validate the to string if not isinstance(to, str): logging.error( "Value of 'to' parameter not a string. Failed to update VoID file. Value=%s.", to) return None if not len(to) > 0: logging.error( "Value of 'to' parameter is zero-length. Failed to update VoID file. Value=%s.", to) return None # Prepare the model m = RDF.Model(RDF.MemoryStorage()) rdf = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#' void = "http://rdfs.org/ns/void#" d1lod = "http://dataone.org/" dcterms = "http://purl.org/dc/terms/" subject_node = RDF.Node(blank="d1lod") # Add in our statements m.append( RDF.Statement(subject_node, RDF.Uri(rdf + 'type'), RDF.Uri(void + 'Dataset'))) m.append( RDF.Statement(subject_node, RDF.Uri(void + 'feature'), RDF.Uri(d1lod + 'fulldump'))) m.append( RDF.Statement(subject_node, RDF.Uri(dcterms + 'modified'), RDF.Node(to))) m.append( RDF.Statement(subject_node, RDF.Uri(void + 'dataDump'), RDF.Uri(d1lod + DUMP_FILENAME))) return m
def _remove(self, file, format, context, base_uri): if isinstance(context, unicode): context = context.encode('utf8') context = RDF.Node(context) stream = self._parse(file, format, base_uri) for statement in stream: self._model.remove_statement(statement, context)
def _serialize(self, context_name, format): # this sucks, we need a temp model because contexts can not # be serialized :( if isinstance(context_name, unicode): context_name = context_name.encode('utf8') stream = self._model.as_stream(RDF.Node(context_name)) return self._serialize_stream(stream, format)
def delete_work(self, user_uri, work_uri, linked_entries=False): work = Work.from_model(self._model, work_uri, user_uri) if not self._can_access('delete', work): raise EntryAccessError("Work {0} can't be modified by {1}".format(work_uri, user_uri)) if linked_entries: for source_uri in work.get('source', []): self.delete_source(user_uri=user_uri, source_uri=source_uri, unlink=True) for post_uri in work.get('post', []): self.delete_post(user_uri=user_uri, post_uri=post_uri, unlink=True) for subgraph_uri in work.get_subgraphs(): subgraph_context = RDF.Node(RDF.Uri(subgraph_uri)) self._model.remove_statements_with_context(subgraph_context) work_context = RDF.Node(RDF.Uri(work_uri)) self._model.remove_statements_with_context(work_context)
def voidify(self, void_model, dataset): # usage as property for property_uri, result in self.results['sum'].iteritems(): if result == 0: continue observation = RDF.Node() void_model.append( RDF.Statement(dataset, ns_void.observation, observation)) void_model.append( RDF.Statement(observation, ns_rdf.type, ns_qb.Observation)) void_model.append( RDF.Statement(observation, ns_stats.schema, self.schema)) o_type = RDF.Uri(property_uri) void_model.append( RDF.Statement(observation, ns_stats.subjectsOfType, o_type)) result_node = RDF.Node(literal=str(result), datatype=ns_xs.integer.uri) void_model.append( RDF.Statement(observation, ns_stats.value, result_node))
def voidify(self, void_model, dataset): namespaces = lodstats.util.rdf_namespaces.RDFNamespaces() datatype_uri = namespaces.get_rdf_namespace("xsd").integer.uri number_of_distinct_entities = str(self.results['count']) number_of_entities_node = RDF.Node(literal=number_of_distinct_entities, datatype=datatype_uri) void_model.append( RDF.Statement(dataset, namespaces.get_rdf_namespace("void").entities, number_of_entities_node))
def state_audio_metadata(ts, file_uri, metadata): # it doesn't matter if we add the same statement multiple times, so don't # bother checking if it exists (this could cause problems if we have eg. # different artist names with the same musicbrainz_artistid # artist artist_uri = 'http://zitgist.com/music/artist/' + metadata[ 'musicbrainz_artistid'][0] artist_uri = RDF.Node(RDF.Uri(artist_uri)) ts.state(artist_uri, ns['rdf'].type, ns['mo'].MusicArtist) ts.state(artist_uri, ns['foaf'].name, RDF.Node(metadata['artist'][0])) # album album_uri = 'http://zitgist.com/music/record/' + metadata[ 'musicbrainz_albumid'][0] album_uri = RDF.Node(RDF.Uri(album_uri)) ts.state(album_uri, ns['rdf'].type, ns['mo'].Record) ts.state(album_uri, ns['dc'].title, RDF.Node(metadata['album'][0])) if 'musicbrainz_albumartistid' in metadata: album_artist_uri = 'http://zitgist.com/music/artist/' + metadata[ 'musicbrainz_albumartistid'][0] album_artist_uri = RDF.Node(RDF.Uri(album_artist_uri)) else: album_artist_uri = artist_uri # XXX does album artist have an MO term? ts.state(album_uri, ns['foaf'].maker, album_artist_uri) # track track_uri = 'http://zitgist.com/music/track/' + metadata[ 'musicbrainz_trackid'][0] track_uri = RDF.Node(RDF.Uri(track_uri)) ts.state(track_uri, ns['rdf'].type, ns['mo'].Track) ts.state(album_uri, ns['mo'].track, track_uri) ts.state(track_uri, ns['foaf'].maker, artist_uri) ts.state(track_uri, ns['dc'].title, RDF.Node(metadata['title'][0])) # some artists get clever and have craaaaazzy track numbers if 'tracknumber' in metadata: tn = metadata['tracknumber'][0] else: tn = '0' tn = RDF.Node(literal=tn, datatype=ns['xs'].int.uri) ts.state(track_uri, ns['mo'].track_number, tn) # the particular file ts.state(file_uri, ns['mo'].encodes, track_uri)
def delete_source(self, user_uri, source_uri, unlink=True): source = Source.from_model(self._model, source_uri, user_uri) if not self._can_access('delete', source): raise EntryAccessError("Source {0} can't be modified by {1}".format(source_uri, user_uri)) # delete the link to work, if exists if unlink: # is it safe to assume that catalog:source will precisely # enumerate works and users linked to this source? query_statement = RDF.Statement(None, RDF.Uri(NS_CATALOG + "source"), RDF.Uri(source_uri)) for statement, context in self._model.find_statements_context(query_statement): self._model.remove_statement(statement, context) # delete source data for subgraph_uri in source.get_subgraphs(): subgraph_context = RDF.Node(uri_string=str(subgraph_uri)) self._model.remove_statements_with_context(subgraph_context) self._model.remove_statements_with_context(RDF.Node(RDF.Uri(source_uri)))
def delete_post(self, user_uri, post_uri, unlink=True): post = Post.from_model(self._model, post_uri, user_uri) if not self._can_access('delete', post): raise EntryAccessError("Post {0} can't be modified by {1}".format(post_uri, user_uri)) # delete the link to work, if exists if unlink: # is it safe to assume that catalog:post will precisely # enumerate works linked to the post? query_statement = RDF.Statement(None, RDF.Uri(NS_CATALOG + "post"), RDF.Uri(post_uri)) for statement, context in self._model.find_statements_context(query_statement): self._model.remove_statement(statement, context) # delete post data for subgraph_uri in post.get_subgraphs(): subgraph_context = RDF.Node(uri_string=str(subgraph_uri)) self._model.remove_statements_with_context(subgraph_context) self._model.remove_statements_with_context(RDF.Node(RDF.Uri(post_uri)))
def tag(resource, tags): '''tag a resource with a space-separated string''' resource = RDF.Node(RDF.Uri(resource)) # space-separated, remove empty tags = [x for x in tags.strip().split(' ') if x != ''] # remove all existing tags on this resource TripleStore.forget(resource, ns['nao'].hasTag, None) for _tag in tags: # XXX check if it's a nao:Tag too tag = TripleStore.model.get_source(ns['nao'].prefLabel, RDF.Node(_tag)) if not tag: # create a new nao:Tag with the appropriate prefLabel tag = RDF.Node(blank=None) TripleStore.state(tag, ns['rdf'].type, ns['nao'].Tag) TripleStore.state(tag, ns['nao'].prefLabel, RDF.Node(_tag)) TripleStore.state(resource, ns['nao'].hasTag, tag)
def test_can_prepare_terms_correctly(interface): # RDF.Nodes assert isinstance(interface.prepareTerm(RDF.Node('asdf')), RDF.Node) # RDF.Uris assert isinstance(interface.prepareTerm(RDF.Uri('http://example.org')), RDF.Uri) # Strings assert isinstance(interface.prepareTerm('d1person:urn:uuid:6b1a2286-5205-47d8-9006-76ecce880c6a'), RDF.Uri) assert isinstance(interface.prepareTerm('test'), RDF.Node) assert isinstance(interface.prepareTerm('d1person:test'), RDF.Uri)
def export_model(self, uri, model): for attr in self.attribute_db.list_keys(): if attr.startswith("__"): continue if attr.startswith(VOLATILE_NS): continue values = self.resolve_list(uri, attr, follow_inheritence=False) for v in values: statement=RDF.Statement(RDF.Uri(uri), RDF.Uri(attr), RDF.Node(v)) model.add_statement(statement)
def voidify(self, void_model, dataset): namespaces = lodstats.util.rdf_namespaces.RDFNamespaces() datatype_uri = namespaces.get_rdf_namespace("xsd").int.uri number_of_distinct_classes = str(len(self.usage_count)) number_of_distinct_classes_node = RDF.Node(literal=number_of_distinct_classes, datatype=datatype_uri) void_model.append(RDF.Statement(dataset, namespaces.get_rdf_namespace("void").classes, number_of_distinct_classes_node)) for class_uri_k, class_uri_v in self.usage_count.iteritems(): class_partitions_node = RDF.Node() statement_class_uri = RDF.Statement(class_partitions_node, namespaces.get_rdf_namespace("void")['class'], RDF.Node(uri_string=class_uri_k)) statement_class_triples_value = RDF.Statement(class_partitions_node, namespaces.get_rdf_namespace("void").entities, RDF.Node(literal=str(class_uri_v), datatype=datatype_uri)) statement = RDF.Statement(dataset, namespaces.get_rdf_namespace("void").classPartition, class_partitions_node) void_model.append(statement) void_model.append(statement_class_uri) void_model.append(statement_class_triples_value)
def addIdentifierTriples(self, node, identifier): """ Add triples for the given identifier to the given node. :param node: :param identifier: :return: None """ if self.model is None: raise Exception("Model not found.") scheme = util.getIdentifierScheme(identifier) resolve_url = util.getIdentifierResolveURL(identifier) # Create a blank node for the identifier identifier_node = RDF.Node(blank=str(uuid.uuid4())) self.add(node, 'geolink:hasIdentifier', identifier_node) self.add(identifier_node, 'rdf:type', 'geolink:Identifier') self.add(identifier_node, 'rdfs:label', RDF.Node(identifier)) self.add(identifier_node, 'geolink:hasIdentifierValue', RDF.Node(identifier)) self.add(identifier_node, 'geolink:hasIdentifierScheme', 'datacite:' + scheme) if resolve_url is not None: self.add(identifier_node, 'geolink:hasIdentifierResolveURL', RDF.Uri(resolve_url)) # Also always add the DataOne resolve URL for non local-resource-identifier-scheme identifiers if scheme != 'local-resource-identifier-scheme': dataone_resolve_url = 'https://cn.dataone.org/cn/v1/resolve/%s' % urllib.unquote( identifier).decode('utf8') self.add(identifier_node, 'geolink:hasIdentifierResolveURL', RDF.Uri(dataone_resolve_url)) return
def prepareTerm(self, term): """Prepare an RDF term to be added to an RDF Model. A term is either: - An RDF.Node - An RDF.Uri - A string, which is either: - A binding string (e.g., '?s') - A URI reference (e.g., 'rdf:type') - A URI (e.g., http://...) - A literal If the term is a str with a namespace prefix that the Interface knows about then that namespace will be interpolated prior to making the term into an RDF.Uri. Arguments: term : str | RDF.Node | RDF.Uri The RDF term (subject, predicate, or object) to be prepared. Returns: str | RDF.Node | RDF.Uri """ if isinstance(term, RDF.Uri) or isinstance(term, RDF.Node): return term elif isinstance(term, str) or isinstance(term, unicode): # Binding?: Do nothing if term.startswith('?'): return term # Conver 'http...' strings to RDF.Uri if term.startswith('http'): return RDF.Uri(term) parts = term.split(':') # URI if len(parts) > 1 and parts[0] in self.graph.ns: prefix = self.graph.ns[parts[0]] other_parts = parts[1:] term = RDF.Uri(prefix + ':'.join(other_parts)) else: # Literal term = RDF.Node(term) else: raise Exception( "Invalid term sent can't be prepared: (type is %s) Term is `%s`." % (type(term), term)) return term
def serialize(self): """ Serializes the given resource to triple statements from the Redland RDF library. This is done by using the model manager and its attribute wrapper. @return : @author """ #First set yourself the class type if it is not Resource or already set if(type(self).__name__ != "Resource"): if(not hasattr(self, "type")): self.type = ListenerList([], self, "type") ownClassUri = self.modelManager.classMapper.getClassResource(type(self).__name__) #Do this typing stuff and check if the type is not a resource found = False for r in self.type: try: if(r.uri == ownClassUri): found = True break except: #Do nothing pass if(not found): #Add your own class type self.type.append(Resource(self.modelManager, uri = ownClassUri)) #Initialize an array to store the results in results = [] #Iterate over all variables and store the values for (key, value) in list(self.__dict__.items()): #Only store the values of "public" variables if(not key.startswith("_")): #Subject and attribute are always the of normal type resource if(not self.isBlank): subjectNode = RDF.Uri(self.uri) else: subjectNode = RDF.Node(blank=self.blankIdentifier) attributeNode = RDF.Uri(self.modelManager.attrMapper.getAttributeUri(key)) #Object node might be a list or a skalar if(value is None): #Do nothing pass elif(isinstance(value, list)): for subValue in value: results.append(self._generateStatement(subjectNode, attributeNode, subValue)) else: results.append(Resource._generateStatement(subjectNode, attributeNode, value)) #Now return the results return results
def rdfsInstanceInfo(term, m): """Generate rdfs-type information for instances""" doc = "" t = m.find_statements( RDF.Statement(RDF.Node(RDF.Uri(term)), rdf.type, None)) if t.current(): doc += "<dt>RDF Type:</dt>" while t.current(): doc += "<dd>%s</dd>" % getTermLink(str(t.current().object.uri)) t.next() return doc