triannon 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,36 +0,0 @@
1
- module Triannon
2
-
3
- class RootAnnotationCreator
4
-
5
- # Creates an LDP Container to hold all the annotations
6
- # Called from config/initializers/root_annotation_container.rb during app bootup
7
- # @return [Boolean] true if the root container was created, false if the container already exists or if there were issues
8
- def self.create
9
- conn = Faraday.new :url => Triannon.config[:ldp_url]
10
- resp = conn.head
11
- unless resp.status == 404 || resp.status == 410
12
- puts "Root annotation resource already exists."
13
- return false
14
- end
15
-
16
- uri = RDF::URI.new Triannon.config[:ldp_url]
17
- conn = Faraday.new :url => uri.parent.to_s
18
- slug = uri.to_s.split('/').last
19
-
20
- resp = conn.post do |req|
21
- req.headers['Content-Type'] = 'text/turtle'
22
- req.headers['Slug'] = slug
23
- end
24
-
25
- if resp.status == 201
26
- puts "Created root annotation container #{Triannon.config[:ldp_url]}"
27
- return true
28
- else
29
- puts "Unable to create root annotation container #{Triannon.config[:ldp_url]}"
30
- return false
31
- # TODO raise an exception if we get here?
32
- end
33
- end
34
-
35
- end
36
- end
@@ -1,173 +0,0 @@
1
- module Triannon
2
- # a wrapper class for RDF::Graph that adds methods specific to Triannon
3
- # this is intended to be used for an RDF::Graph of a single annotation
4
- class Graph
5
-
6
- # Class Methods ----------------------------------------------------------------
7
-
8
- # given an RDF::Resource (an RDF::Node or RDF::URI), look for all the statements with that object
9
- # as the subject, and recurse through the graph to find all descendant statements pertaining to the subject
10
- # @param subject the RDF object to be used as the subject in the graph query. Should be an RDF::Node or RDF::URI
11
- # @param [RDF::Graph] graph
12
- # @return [Array[RDF::Statement]] all the triples with the given subject
13
- def self.subject_statements(subject, graph)
14
- result = []
15
- graph.query([subject, nil, nil]).each { |stmt|
16
- result << stmt
17
- subject_statements(stmt.object, graph).each { |s| result << s }
18
- }
19
- result.uniq
20
- end
21
-
22
- # @return [RDF::Query] query for a subject :s with type of RDF::OpenAnnotation.Annotation
23
- def self.anno_query
24
- q = RDF::Query.new
25
- q << [:s, RDF.type, RDF::OpenAnnotation.Annotation]
26
- end
27
-
28
-
29
- # Instance Methods ----------------------------------------------------------------
30
-
31
- # instantiate this class for an RDF::Graph of a single annotation
32
- def initialize(rdf_graph)
33
- @graph = rdf_graph
34
- end
35
-
36
- # @return json-ld representation of graph with OpenAnnotation context as a url
37
- def jsonld_oa
38
- inline_context = @graph.dump(:jsonld, :context => Triannon::JsonldContext::OA_DATED_CONTEXT_URL)
39
- hash_from_json = JSON.parse(inline_context)
40
- hash_from_json["@context"] = Triannon::JsonldContext::OA_DATED_CONTEXT_URL
41
- hash_from_json.to_json
42
- end
43
-
44
- # @return json-ld representation of graph with IIIF context as a url
45
- def jsonld_iiif
46
- inline_context = @graph.dump(:jsonld, :context => Triannon::JsonldContext::IIIF_CONTEXT_URL)
47
- hash_from_json = JSON.parse(inline_context)
48
- hash_from_json["@context"] = Triannon::JsonldContext::IIIF_CONTEXT_URL
49
- hash_from_json.to_json
50
- end
51
-
52
- # Canned Query methods ----------------------------------------------------------------
53
-
54
- # @return [String] the id of this annotation as a url string, or nil if it is a Node
55
- def id_as_url
56
- solution = @graph.query self.class.anno_query
57
- if solution && solution.size == 1
58
- rdf_resource = solution.first.s
59
- rdf_resource.to_s if rdf_resource.is_a?(RDF::URI)
60
- # TODO: raise exception if not a URI?
61
- end
62
- end
63
-
64
- # @return [Array<String>] Array of urls expressing the OA motivated_by values
65
- def motivated_by
66
- motivations = []
67
- q = self.class.anno_query.dup
68
- q << [:s, RDF::OpenAnnotation.motivatedBy, :motivated_by]
69
- solution = @graph.query q
70
- if solution && solution.size > 0
71
- solution.each {|res|
72
- motivations << res.motivated_by.to_s
73
- }
74
- end
75
- # TODO: raise exception if none? (validation)
76
- motivations
77
- end
78
-
79
- # @param [RDF::URI] predicate either RDF::OpenAnnotation.hasTarget or RDF::OpenAnnotation.hasBody
80
- # @return [Array<String>] urls for the predicate, as an Array of Strings
81
- def predicate_urls(predicate)
82
- urls = []
83
- predicate_solns = @graph.query [nil, predicate, nil]
84
- predicate_solns.each { |predicate_stmt |
85
- predicate_obj = predicate_stmt.object
86
- urls << predicate_obj.to_str.strip if predicate_obj.is_a?(RDF::URI)
87
- }
88
- urls
89
- end
90
-
91
- # For all bodies that are of type ContentAsText, get the characters as a single String in the returned Array.
92
- # @return [Array<String>] body chars as Strings, in an Array (one element for each contentAsText body)
93
- def body_chars
94
- result = []
95
- q = RDF::Query.new
96
- q << [nil, RDF::OpenAnnotation.hasBody, :body]
97
- q << [:body, RDF.type, RDF::Content.ContentAsText]
98
- q << [:body, RDF::Content.chars, :body_chars]
99
- solns = @graph.query q
100
- solns.each { |soln|
101
- result << soln.body_chars.value
102
- }
103
- result
104
- end
105
-
106
- # @return [String] The datetime from the annotatedAt property, or nil
107
- def annotated_at
108
- solution = @graph.query [nil, RDF::OpenAnnotation.annotatedAt, nil]
109
- if solution && solution.size == 1
110
- solution.first.object.to_s
111
- end
112
- end
113
-
114
-
115
- # Changing the Graph ----------------------------------------------------------------
116
-
117
- # remove all RDF::OpenAnnotation.hasBody and .hasTarget statements
118
- # and any other statements associated with body and target objects,
119
- # leaving all statements to be stored as part of base object in LDP store
120
- def remove_non_base_statements
121
- remove_has_target_statements
122
- remove_has_body_statements
123
- end
124
-
125
- # remove all RDF::OpenAnnotation.hasBody statements and any other statements associated with body objects
126
- def remove_has_body_statements
127
- remove_predicate_and_its_object_statements RDF::OpenAnnotation.hasBody
128
- end
129
-
130
- # remove all RDF::OpenAnnotation.hasTarget statements and any other statements associated with body objects
131
- def remove_has_target_statements
132
- remove_predicate_and_its_object_statements RDF::OpenAnnotation.hasTarget
133
- end
134
-
135
- # remove all such predicate statements and any other statements associated with predicates' objects
136
- def remove_predicate_and_its_object_statements(predicate)
137
- predicate_stmts = @graph.query([nil, predicate, nil])
138
- predicate_stmts.each { |pstmt|
139
- pred_obj = pstmt.object
140
- Triannon::Graph.subject_statements(pred_obj, @graph).each { |s|
141
- @graph.delete s
142
- } unless !Triannon::Graph.subject_statements(pred_obj, @graph)
143
- @graph.delete pstmt
144
- }
145
- end
146
-
147
- # transform an outer blank node into a null relative URI
148
- def make_null_relative_uri_out_of_blank_node
149
- anno_stmts = @graph.query([nil, RDF.type, RDF::OpenAnnotation.Annotation])
150
- anno_rdf_obj = anno_stmts.first.subject
151
- if anno_rdf_obj.is_a?(RDF::Node)
152
- # use null relative URI representation of blank node
153
- anno_subject = RDF::URI.new
154
- else # it's already a URI
155
- anno_subject = anno_rdf_obj
156
- end
157
- Triannon::Graph.subject_statements(anno_rdf_obj, @graph).each { |s|
158
- if s.subject == anno_rdf_obj && anno_subject != anno_rdf_obj
159
- @graph << RDF::Statement({:subject => anno_subject,
160
- :predicate => s.predicate,
161
- :object => s.object})
162
- @graph.delete s
163
- end
164
- }
165
- end
166
-
167
- # send unknown methods to RDF::Graph
168
- def method_missing(sym, *args, &block)
169
- @graph.send sym, *args, &block
170
- end
171
-
172
- end
173
- end
@@ -1,13 +0,0 @@
1
- module Triannon
2
- class JsonldContext
3
-
4
- # TODO: perhaps this should no longer be a class -- these could be Triannon constants ...
5
-
6
- OA_CONTEXT_URL = "http://www.w3.org/ns/oa.jsonld"
7
-
8
- OA_DATED_CONTEXT_URL = "http://www.w3.org/ns/oa-context-20130208.json"
9
-
10
- IIIF_CONTEXT_URL = "http://iiif.io/api/presentation/2/context.json"
11
-
12
- end
13
- end