krikri 0.7.2 → 0.7.3

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.
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