krikri 0.7.2 → 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d72a1b6b8d6ea4472d527c4ecacac7095211bdfe
4
- data.tar.gz: 521e0ed975aaaf8e9ed132948e8a4ad6e396e21d
3
+ metadata.gz: 96bca4e27356f470641703f33e18cf175ebd69ff
4
+ data.tar.gz: bc9ae30eda3a0afb8bddf6acf303b4613f74a779
5
5
  SHA512:
6
- metadata.gz: 3ba3aacbb12f39c70b9643c2cb1288ae46d80557efacc5c6766f51c0bfd79be67cdd611fb601b54002bddc66278d6083f97e5bc1712ee502f1d948b14dfadb83
7
- data.tar.gz: 5ad8d81909cebfd15f2517267f27028ad0667e2c4712f34fea4e61a90fae727976675df9a89898abc8c2e9ae42c474f93624fdfeb0313f766e85fc17cc4ed094
6
+ metadata.gz: d4d51fb35e997ca7ec9100d2d8ea55fbb54dcda052374794e3c40518f77da172dfa690e2d65f2be238beefca0447d1a08272483b4618d28ded01ee78f9037136
7
+ data.tar.gz: 6df381f8ac7c5defc2ac5a05421b24a80cec0f948c3481b06f4e5b8989a5750b65ed33acd988f933dce334dcb5328017961f4c61cb4e39b5b9d7969a9c14037c
@@ -134,9 +134,9 @@ module Krikri
134
134
  # @param [Hash] user_parameters a hash of user-supplied parameters.
135
135
  def records_by_provider(solr_params, user_params)
136
136
  if @provider_id.present?
137
- provider = Krikri::Provider.find(@provider_id)
137
+ rdf_subject = Krikri::Provider.base_uri + @provider_id
138
138
  solr_params[:fq] ||= []
139
- solr_params[:fq] << "provider_id:\"#{provider.rdf_subject}\""
139
+ solr_params[:fq] << "provider_id:\"#{rdf_subject}\""
140
140
  end
141
141
  end
142
142
 
@@ -15,7 +15,7 @@ module Krikri
15
15
  # @return [String]
16
16
  def provider_name(provider)
17
17
  provider = Krikri::Provider.find(provider) if provider.is_a? String
18
- provider.present? ? provider.provider_name : "All Providers"
18
+ provider.present? ? provider.name : 'All Providers'
19
19
  end
20
20
 
21
21
  ##
@@ -1,80 +1,173 @@
1
1
  module Krikri
2
2
  ##
3
- # This models provider data from the {Krikri::Repository}.
3
+ # Provider is an ActiveModel object. It represents a provider that has been
4
+ # indexed in Solr.
4
5
  #
5
- # @todo create an appropriate `ActiveTriples::PersistenceStrategy' for
6
- # handling providers as data from a repository alongside LDP data.
7
- # @see ActiveTriples::Resource
8
- class Provider < DPLA::MAP::Agent
9
- configure :base_uri => Krikri::Settings.prov.provider_base
6
+ # This is a read-only object. It does not write new providers to Solr, nor
7
+ # does it update or delete providers.
8
+ #
9
+ # A DPLA::MAP::Agent object can be constructed from an instance of this
10
+ # ActiveModel object using the :agent method. The DPLA::MAP::Agent object
11
+ # interacts with Marmotta, rather than Solr.
12
+ #
13
+ # @example Krikri::Provider.find(rdf_subject: 'http://blah.com/123').agent
14
+ # => [DPLA::MAP::Agent]
15
+ #
16
+ class Provider
17
+ include ActiveModel::Validations
18
+ include ActiveModel::Conversion
19
+ extend ActiveModel::Naming
20
+
21
+ ##
22
+ # @!attribute :rdf_subject [String] the URI identifying the provider
23
+ # @example: "http://blah.com/contributor/123"
24
+ #
25
+ # @!attribute :id [String] the stub id
26
+ # @example: "123"
27
+ #
28
+ # @!attribute :name [String] the human-redable name of the provider
29
+ #
30
+ # @!attribute :agent [DPLA::MAP::Agent] an ActiveTriples representation of
31
+ # the provider, read from Marmotta.
32
+ attr_accessor :rdf_subject, :name
33
+ attr_reader :agent, :id
34
+
35
+ ##
36
+ # Initializes a Provider object.
37
+ #
38
+ # @param attributes [Hash]
39
+ # If the params Hash contains a valid value for :rdf_subject, the model can
40
+ # extrapolate all other attributes.
41
+ #
42
+ # @example
43
+ # Krikri::Provider.new({ rdf_subject: 'http:://blah.com/contributor/123',
44
+ # name: 'Moomin Valley Historical Society' })
45
+ #
46
+ # @raise [NoMethodError] if the params Hash includes a key that does not
47
+ # match listed attr_accessors
48
+ #
49
+ # @return [<Krikri::Provider>]
50
+ def initialize(attributes = {})
51
+ attributes.each do |name, value|
52
+ send("#{name}=", value)
53
+ end
54
+ end
10
55
 
11
56
  ##
12
57
  # Gives a list of all providers, ignoring those with no URI (bnodes).
13
58
  #
59
+ # Providers will be initialized with both an :rdf_subject and a :name,
60
+ # if both exist in the Solr index.
61
+ #
14
62
  # @return [Array<Krikri::Provider>]
15
63
  def self.all
16
64
  query_params = { :rows => 0,
17
65
  :id => '*:*',
18
- 'facet.field' => 'provider_id' }
66
+ :facet => true,
67
+ 'facet.pivot' => 'provider_id,provider_name' }
19
68
  response = Krikri::SolrResponseBuilder.new(query_params).response
20
- response.facets.first.items.map do |item|
21
- provider = new(item.value)
22
- provider.node? ? nil : provider
69
+
70
+ response.facet_pivot['provider_id,provider_name'].map do |facet|
71
+ rdf_subject = facet['value']
72
+ name = facet['pivot'].present? ? facet['pivot'].first['value'] : nil
73
+ provider = new({ :rdf_subject => rdf_subject, :name => name })
74
+ provider.valid_rdf_subject? ? provider : nil
23
75
  end.compact
24
76
  end
25
77
 
26
78
  ##
27
- # @param id [#to_s] the identifier (local name or URI) of the provider
28
- # to find
79
+ # Finds a provider in Solr that matches the given ID, ignoring bnodes.
80
+ #
81
+ # @param [String] :id or :rdf_subject
29
82
  #
30
83
  # @return [Krikri::Provider]
31
- # @todo Use {ActiveTriples}/{RDF::Repository} to populate the object
32
84
  def self.find(id)
33
- return nil if id.nil?
34
- provider = new(id)
35
- provider.reload
36
- return nil if provider.empty?
37
- provider
85
+ rdf_subject = id.start_with?(base_uri) ? id : base_uri + id
86
+ query_params = { :rows => 1,
87
+ :q => rdf_subject,
88
+ :qf => 'provider_id',
89
+ :fl => 'provider_id provider_name' }
90
+ response = Krikri::SolrResponseBuilder.new(query_params).response
91
+ return nil unless response.docs.count > 0
92
+ new({ :rdf_subject => rdf_subject,
93
+ :name => response.docs.first['provider_name'].first })
38
94
  end
39
95
 
40
96
  ##
41
- # Loads the provider's data from the repository.
42
- #
43
- # @return [Krikri::Provider] self
44
- def reload
45
- query = Krikri::Repository.query_client.select.distinct.where([self, :p, :o])
46
- query.each_solution do |solution|
47
- set_value(solution.p, solution.o)
48
- end
97
+ # Get the base of the :rdf_subject for any provider
98
+ # @return [String] ending in "/"
99
+ def self.base_uri
100
+ base_uri = Krikri::Settings.prov.provider_base
101
+ base_uri.end_with?('/') ? base_uri : base_uri << '/'
102
+ end
103
+
104
+ def id
105
+ @id ||= local_name
106
+ end
49
107
 
50
- self
108
+ def name
109
+ @name ||= initialize_name
110
+ end
111
+
112
+ def agent
113
+ @agent ||= initialize_agent
51
114
  end
52
115
 
53
116
  ##
54
- # A list of records of type ore:Aggregation associated with this provider
55
- #
56
- # @return [Array<DPLA::MAP::Aggregation>] the Aggregations with this
57
- # provider
58
- def records
59
- query = Krikri::Repository.query_client.select
60
- .where([:record, RDF::EDM.provider, self],
61
- [:record, RDF.type, RDF::ORE.Aggregation])
117
+ # Tests for providers that have valid a :rdf_subject (not a bnode).
118
+ # A valid :rdf_subject does not necessarily match and :rdf_subject in the
119
+ # Solr index, but it has the correct URI format.
120
+ def valid_rdf_subject?
121
+ return false unless rdf_subject.present?
122
+ rdf_subject.start_with?(self.class.base_uri) ? true : false
123
+ end
62
124
 
63
- query.execute.map do |solution|
64
- DPLA::MAP::Aggregation.new(solution.record)
65
- end
125
+ ##
126
+ # Required ActiveModel method.
127
+ def persisted?
128
+ false
66
129
  end
67
130
 
131
+ private
132
+
68
133
  ##
69
- # @return [String] the local name (last uri segment) for the provider
70
- def id
71
- node? ? nil : rdf_subject.to_s.gsub(base_uri.to_s, '')
134
+ # Gives the last path fragment for :rdf_subject in HTML escaped form,
135
+ # ignoring :rdf_subjects, ignoring bnodes.
136
+ #
137
+ # @example
138
+ # Given: rdf_subject == 'http://my_domain/blah/0123'
139
+ # local_name == '0123'
140
+ #
141
+ # @return [String]
142
+ def local_name
143
+ return nil unless valid_rdf_subject?
144
+ rdf_subject.split('/').last.html_safe
145
+ end
146
+
147
+ ##
148
+ # Gives the :provider_name associated with a provider's :rdf_subject
149
+ # (ie. :provider_id) in Solr, ignoring bnodes.
150
+ #
151
+ # @return [String]
152
+ def initialize_name
153
+ return nil unless valid_rdf_subject?
154
+ query_params = { :rows => 1,
155
+ :q => rdf_subject,
156
+ :qf => 'provider_id',
157
+ :fl => 'provider_name' }
158
+ response = Krikri::SolrResponseBuilder.new(query_params).response
159
+ return nil unless response.docs.count > 0
160
+ response.docs.first['provider_name'].first
72
161
  end
73
162
 
74
163
  ##
75
- # @return [String] the name of the provider
76
- def provider_name
77
- label.first || providedLabel.first || id
164
+ # Creates DPLA::MAP::Agent object from the :rdf_subject and :name, ignoring
165
+ # bnodes.
166
+ #
167
+ # @return [DPLA::MAP::Agent]
168
+ def initialize_agent
169
+ return nil unless valid_rdf_subject?
170
+ DPLA::MAP::Agent.new(rdf_subject).tap { |agent| agent.label = name }
78
171
  end
79
172
  end
80
173
  end
@@ -136,7 +136,7 @@ module Krikri
136
136
  # @todo figure out a better relations pattern between {ActiveRecord} objects
137
137
  # and {ActiveTriples}
138
138
  def build_provider
139
- Krikri::Provider.find(provider)
139
+ Krikri::Provider.new(:rdf_subject => provider).agent
140
140
  end
141
141
 
142
142
  private
@@ -63,9 +63,11 @@ module Krikri
63
63
 
64
64
  private
65
65
 
66
+ ##
67
+ # Get the full URI identifier for the provider
66
68
  def provider_uri
67
69
  return unless provider_id.present?
68
- Krikri::Provider.new(provider_id).rdf_subject
70
+ Krikri::Provider.base_uri + provider_id
69
71
  end
70
72
  end
71
73
  end
@@ -9,7 +9,7 @@
9
9
  <ul>
10
10
  <% @providers.each do |provider| %>
11
11
  <li>
12
- <%= link_to provider_name(provider), { controller: 'providers',
12
+ <%= link_to provider.name, { controller: 'providers',
13
13
  action: 'show', id: provider.id } %>
14
14
  </li>
15
15
  <% end %>
@@ -184,26 +184,16 @@ module Krikri::Harvesters
184
184
 
185
185
  ##
186
186
  # Transforms an OAI::Record to xml suitable for saving with the
187
- # OriginalRecord
187
+ # OriginalRecord. It's necessary to build a new document and add the
188
+ # namespace manually to normalize record output between `ListRecords` and
189
+ # `GetRecord` requests.
188
190
  #
189
191
  # @param rec [OAI::Record]
190
192
  # @return [String] an xml string
191
193
  def record_xml(rec)
192
- doc = Nokogiri::XML::Builder.new do |xml|
193
- xml.record('xmlns' => 'http://www.openarchives.org/OAI/2.0/') {
194
- xml.header {
195
- xml.identifier rec.header.identifier
196
- xml.datestamp rec.header.datestamp
197
- rec.header.set_spec.each do |set|
198
- xml.set_spec set.text
199
- end
200
- }
201
- xml << rec.metadata.to_s unless rec.metadata.nil?
202
- xml << rec.about.to_s unless rec.about.nil?
203
- }
204
- end
205
- doc.doc.at_css('header')['status'] = rec.header.status if
206
- rec.header.status
194
+ doc = Nokogiri.XML(rec._source.to_s)
195
+ doc.root
196
+ .add_namespace_definition(nil, 'http://www.openarchives.org/OAI/2.0/')
207
197
  doc.to_xml
208
198
  end
209
199
  end
data/lib/krikri/parser.rb CHANGED
@@ -273,17 +273,54 @@ module Krikri
273
273
  end
274
274
 
275
275
  ##
276
+ # @example selecting by presence of an attribute; returns all nodes where
277
+ # `#attribute?(:type)` is true
278
+ #
279
+ # match_attribute(:type)
280
+ #
281
+ # @example selecting by the value of an attribute; returns all nodes with
282
+ # `#attribute(:type) == other`
283
+ #
284
+ # match_attribute(:type, other)
285
+ #
286
+ # @example selecting by block against an attribute; returns all nodes with
287
+ # `block.call(attribute(:type))` is true
288
+ #
289
+ # match_attribute(:type) { |value| value.starts_with? 'blah' }
290
+ #
291
+ # @example selecting by block against an attribute; returns all nodes with
292
+ # `block.call(attribute(:type)) == other` is true
293
+ #
294
+ # match_attribute(:type, 'moomin') { |value| value.downcase }
295
+ #
276
296
  # @param name [#to_sym] an attribute name
277
- # @param other [Object] an object to for equality with the
297
+ # @param other [Object] an object to check for equality with the
278
298
  # values from the given attribute.
279
299
  #
300
+ # @yield [value] yields each value with the attribute in name to the block
301
+ #
280
302
  # @return [ValueArray] an array containing nodes for which the specified
281
- # attribute has a value matching the given object.
282
- def match_attribute(name, other)
283
- select do |v|
284
- next unless v.attribute?(name.to_sym)
285
- v.send(name).downcase == other.downcase
286
- end
303
+ # attribute has a value matching the given attribute name, object, and
304
+ # block.
305
+ def match_attribute(name, other = nil, &block)
306
+ select(&compare_to_attribute(name, other, &block))
307
+ end
308
+
309
+ ##
310
+ # @param name [#to_sym] an attribute name
311
+ # @param other [Object] an object to check for equality with the
312
+ # values from the given attribute.
313
+ #
314
+ # @yield [value] yields each value with the attribute in name to the block
315
+ #
316
+ # @return [ValueArray] an array containing nodes for which the specified
317
+ # attribute does not have a value matching the given attribute name,
318
+ # object, and block.
319
+ #
320
+ # @see #match_attribute for examples; this calls #reject, where it calls
321
+ # #select.
322
+ def reject_attribute(name, other = nil, &block)
323
+ reject(&compare_to_attribute(name, other, &block))
287
324
  end
288
325
 
289
326
  ##
@@ -301,6 +338,20 @@ module Krikri
301
338
  self.class.new(flat_map { |val| val[name] })
302
339
  end
303
340
 
341
+ private
342
+
343
+ ##
344
+ # @see #match_attribute, #reject_attribute
345
+ def compare_to_attribute(name, other, &block)
346
+ lambda do |v|
347
+ next unless v.attribute?(name.to_sym)
348
+ result = v.send(name)
349
+ result = yield(result) if block_given?
350
+ return result == other if other
351
+ result
352
+ end
353
+ end
354
+
304
355
  public
305
356
 
306
357
  class InvalidParserValueError < TypeError; end
@@ -1,3 +1,3 @@
1
1
  module Krikri
2
- VERSION = '0.7.2'.freeze
2
+ VERSION = '0.7.3'.freeze
3
3
  end
@@ -27,12 +27,13 @@ namespace :krikri do
27
27
  original_record = build(:oai_dc_record)
28
28
  original_record.save unless original_record.exists?
29
29
 
30
- provider = Krikri::Provider.new('123')
31
- provider.label = 'Moomin valley Historical Society'
30
+ provider_uri = Krikri::Provider.base_uri + '123'
31
+ provider = Krikri::Provider.new(:rdf_subject => provider_uri).agent
32
+ provider.label = 'Moomin Valley Historical Society'
32
33
 
33
- agg = build(:aggregation)
34
- agg.originalRecord = original_record.rdf_source
35
- agg.provider = provider
34
+ agg = build(:aggregation,
35
+ :originalRecord => original_record.rdf_source,
36
+ :provider => provider)
36
37
 
37
38
  agg.mint_id!('krikri_sample')
38
39
 
@@ -47,11 +48,15 @@ namespace :krikri do
47
48
  original_record = build(:json_record)
48
49
  original_record.save unless original_record.exists?
49
50
 
51
+ provider_uri = Krikri::Provider.base_uri + '456'
52
+ provider = Krikri::Provider.new(:rdf_subject => provider_uri).agent
53
+ provider.label = 'Snork Maiden Archives'
54
+
50
55
  agg = build(:aggregation,
51
56
  :originalRecord => ActiveTriples::Resource
52
57
  .new(original_record.rdf_subject),
53
- :sourceResource => build(:source_resource, title: nil)
54
- )
58
+ :sourceResource => build(:source_resource, title: nil),
59
+ :provider => provider)
55
60
 
56
61
  agg.mint_id!('krikri_sample_invalid')
57
62