triannon 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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