celsius-primo 0.1.3 → 0.1.4

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.
Files changed (24) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/celsius-primo.gemspec +2 -1
  4. data/lib/celsius/primo/soap_api/searcher/search_brief/search_request_transformation/add_sort_by_list.rb +24 -19
  5. data/lib/celsius/primo/soap_api/searcher/search_brief/search_result_transformation/add_missing_facets.rb +23 -31
  6. data/lib/celsius/primo/soap_api/searcher/search_brief/search_result_transformation/process_records.rb +9 -10
  7. data/lib/celsius/primo/version.rb +1 -1
  8. data/spec/assets/adapter/search/{complex_search_request.yml → scenarios/complex_request/search_request.yml} +0 -0
  9. data/spec/assets/adapter/search/{search_result_for_complex_request.yml → scenarios/complex_request/search_result.yml} +0 -0
  10. data/spec/assets/adapter/search/{search_request_with_empty_result.yml → scenarios/empty_result/search_request.yml} +0 -0
  11. data/spec/assets/adapter/search/{empty_search_result.yml → scenarios/empty_result/search_result.yml} +0 -0
  12. data/spec/assets/adapter/search/scenarios/missing_facets/search_request.yml +66 -0
  13. data/spec/assets/adapter/search/scenarios/missing_facets/search_result.yml +158 -0
  14. data/spec/assets/adapter/search/{search_request_for_multiple_publishers.yml → scenarios/result_with_multiple_publishers/search_request.yml} +0 -0
  15. data/spec/assets/adapter/search/{search_result_with_multiple_publishers.yml → scenarios/result_with_multiple_publishers/search_result.yml} +17 -15
  16. data/spec/assets/adapter/search/{search_request.yml → scenarios/simple_request/search_request.yml} +0 -0
  17. data/spec/assets/adapter/search/{search_result.yml → scenarios/simple_request/search_result.yml} +45 -20
  18. data/spec/cassettes/Celsius_Primo_Adapter/_search/passes_the_scenario_complex_request_.yml +191 -0
  19. data/spec/cassettes/Celsius_Primo_Adapter/_search/passes_the_scenario_empty_result_.yml +88 -0
  20. data/spec/cassettes/Celsius_Primo_Adapter/_search/passes_the_scenario_missing_facets_.yml +162 -0
  21. data/spec/cassettes/Celsius_Primo_Adapter/_search/{returns_a_normalized_search_result.yml → passes_the_scenario_result_with_multiple_publishers_.yml} +46 -1484
  22. data/spec/cassettes/Celsius_Primo_Adapter/_search/passes_the_scenario_simple_request_.yml +1169 -0
  23. data/spec/celsius-primo/adapter_spec.rb +15 -12
  24. metadata +50 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4277500e7234aac3afa225684ede09aaf77e99fc
4
- data.tar.gz: d7d6546d49383c0f645b65e23ffb2d092af3c6c8
3
+ metadata.gz: 4efed52d11b5b38d7bbe6a76fe4196b3cac0e617
4
+ data.tar.gz: 7eef803681d80fb6392a8cc38bc0aa700cf836d9
5
5
  SHA512:
6
- metadata.gz: 5f9eac504685fced5f04eab16a437d283d1931285627a761e4cfeab099c7b95cab6124dbb2c30dc49286af9ad2ce7d565c113e80cbc18af1da0f877905e8ea34
7
- data.tar.gz: 4d795059e87617ccec01c34e4b962e42546c744be9bc9ab4a042f9740d7040535876a58fe710d803ba794f2db589c0167409c691136dad060331b8250c0b7158
6
+ metadata.gz: bfdb2a0f4066ee4744353f9ca2b0465776304ff1014f0a46b8eabf96eec744da9abbdac173114fe310e9d4b51b3f589e2c54abf3d3c0c8e1e32eef21cce78844
7
+ data.tar.gz: 4603cab36760f66831bbd13e5cc2d896cd421bbdde5a0f5da90aacbdfae4dcf22974ac86ced8b61cf31f45173ae98ffc32b60a7c9ea7011117d5f11601089897
data/Gemfile CHANGED
@@ -14,3 +14,4 @@ gem "pry-syntax-hacks", "~> 0.0.6"
14
14
 
15
15
  gem "celsius", path: "~/github/ubpb/celsius"
16
16
  gem "deep_merger", path: "~/github/ubpb/deep_merger"
17
+ gem "hashie", github: "intridea/hashie"
@@ -18,11 +18,12 @@ Gem::Specification.new do |spec|
18
18
 
19
19
  spec.add_dependency "celsius", ">= 0.4.3"
20
20
  spec.add_dependency "httpi", ">= 2.1.0", "< 3.0.0"
21
+ spec.add_dependency "hashie"
21
22
  spec.add_dependency "ox", ">= 2.1.0"
22
23
 
23
24
  spec.add_development_dependency "bundler", "~> 1.7"
24
25
  spec.add_development_dependency "rake"
25
- spec.add_development_dependency "rspec", ">= 3.0.0", "< 4.0.0"
26
+ spec.add_development_dependency "rspec", ">= 3.0.0", "< 3.2.0"
26
27
  spec.add_development_dependency "simplecov", ">= 0.8.0"
27
28
  spec.add_development_dependency "vcr", ">= 2.9.0", "< 3.0.0"
28
29
  spec.add_development_dependency "webmock", ">= 1.19.0", "< 2.0.0"
@@ -9,28 +9,33 @@ class Celsius::Primo::SoapApi::Searcher::SearchBrief::SearchRequestTransformatio
9
9
  #
10
10
  def call
11
11
  if sort_fields = (Celsius::Hash.deep_find_key(source, :sort) || []).first
12
- # map sort field values to primo equivalents
13
- primo_sort_fields = sort_fields.map(&transformation.method(:sort_field_mapping))
14
-
15
- # memoize this node to shorten further lines
16
12
  primo_search_request = transformation.inner_search_request.locate("PrimoSearchRequest").first
13
+ insert_sort_by_node(primo_search_request, sort_fields)
14
+ end
15
+ end
17
16
 
18
- # Order matters, SortField *must* be inserted after <Languages>
19
- index_of_languages = primo_search_request.nodes.index do |node|
20
- node.value == "Languages"
21
- end
22
-
23
- # primo can only handle *one* sort field
24
- sort_by_list = Ox.parse(
25
- <<-xml
26
- <SortByList>
27
- <SortField>#{primo_sort_fields.first}</SortField>
28
- </SortByList>
29
- xml
30
- )
31
17
 
32
- # insert the SortByList at the appropriate position
33
- primo_search_request.nodes.insert(index_of_languages + 1, sort_by_list)
18
+ #
19
+ private
20
+ #
21
+ def insert_sort_by_node(primo_search_request, sort_fields)
22
+ # Order matters, SortField *must* be inserted after <Languages>
23
+ index_of_languages = primo_search_request.nodes.index do |node|
24
+ node.value == "Languages"
34
25
  end
26
+
27
+ # primo can only handle *one* sort field
28
+ sort_field = transformation.sort_field_mapping(sort_fields.first)
29
+
30
+ sort_by_list = Ox.parse(
31
+ <<-xml
32
+ <SortByList>
33
+ <SortField>#{sort_field}</SortField>
34
+ </SortByList>
35
+ xml
36
+ )
37
+
38
+ # insert the SortByList at the appropriate position
39
+ primo_search_request.nodes.insert(index_of_languages + 1, sort_by_list)
35
40
  end
36
41
  end
@@ -1,17 +1,31 @@
1
1
  require "celsius/transformation/step"
2
- require "ox"
2
+ require "hashie/extensions/deep_locate"
3
3
 
4
4
  class Celsius::Primo::SoapApi::Searcher::SearchBrief::SearchResultTransformation::
5
5
  AddMissingFacets < Celsius::Transformation::Step
6
6
 
7
- #
8
- # Sometimes, requested facets do not show up in search result, so we have to (re)add them
9
- #
7
+ # handle primo bug where requested facets don't show up in search response
10
8
  def call
11
9
  (search_request["facets"] || {}).each do |facet_name, requested_facet|
10
+ # case 1 - there is no facet at all
12
11
  unless target["facets"][facet_name]
13
12
  if requested_facet["terms"]
14
- target["facets"][facet_name] = empty_search_result_terms_facet
13
+ target["facets"][facet_name] = search_result_terms_facet
14
+ end
15
+ end
16
+ end
17
+
18
+ # case 2 - there is a facet, but the requested facet is not included
19
+ facet_queries = deep_locate(-> (key, value, object) {
20
+ key == "match" && value.keys.any? { |key_| key_.start_with?("facet") }
21
+ }, search_request)
22
+
23
+ facet_queries.each do |facet_query|
24
+ facet_query["match"].tap do |match|
25
+ target["facets"][match.keys.first]["terms"].tap do |facet_terms|
26
+ if facet_terms.none? { |term| term["term"] == match.values.first }
27
+ facet_terms << { "term" => match.values.first, "count" => 1 }
28
+ end
15
29
  end
16
30
  end
17
31
  end
@@ -20,36 +34,14 @@ class Celsius::Primo::SoapApi::Searcher::SearchBrief::SearchResultTransformation
20
34
  #
21
35
  private
22
36
  #
23
- def empty_search_result_terms_facet
37
+ def search_result_terms_facet(terms = [])
24
38
  {
25
39
  "_type" => "terms",
26
- "terms" => []
40
+ "terms" => terms
27
41
  }
28
42
  end
29
43
 
30
- =begin
31
- # handle primo bug where requested facets don't show up in search response
32
- process "//match", source: -> { @search_request} do |match, target|
33
- if (target_facet_name = match.nodes.first.value).start_with?("facet_")
34
- target_facet_value = match.nodes.first.text
35
- target_facet_count = find_all(@search_brief_return, "SEGMENTS/JAGROOT/RESULT/DOCSET/DOC").length
36
-
37
- # case 1 - there is no facet at all
38
- unless find(target, "facets/#{target_facet_name}")
39
- find(target, "facets") << element(target_facet_name) do |target_facet|
40
- target_facet << element("_type", text: "terms")
41
- target_facet << array("terms")
42
- end
43
- end
44
-
45
- # case 2 - there is a facet, but the requested facet is not included
46
- unless find_all(target, "facets/#{target_facet_name}/terms/terms/term").map(&:text).include?(target_facet_value)
47
- array(find(target, "facets/#{target_facet_name}/terms")) do |term|
48
- term << element("term", text: target_facet_value)
49
- term << element("count", text: target_facet_count.to_s, type: "integer")
50
- end
51
- end
52
- end
44
+ def deep_locate(*args)
45
+ Hashie::Extensions::DeepLocate.deep_locate(*args)
53
46
  end
54
- =end
55
47
  end
@@ -38,20 +38,19 @@ class Celsius::Primo::SoapApi::Searcher::SearchBrief::SearchResultTransformation
38
38
  #
39
39
  def add_place_of_publication!(record)
40
40
  if record["publisher"] && !record["placeOfPublication"]
41
- record["placeOfPublication"] = []
42
- record["publisher"] = ensure_array(record["publisher"])
41
+ places_seperated_from_publishers = ensure_array(record["publisher"]).map do |publisher|
42
+ publisher.match(/(\A[^:]*):(.*)/).captures.map(&:strip)
43
+ end
43
44
 
44
- record["publisher"].each.with_index do |publisher, index|
45
- publisher.match(/(\A[^:]*):(.*)/) do |match|
46
- _place_of_publication, _publisher = match.captures.map(&:strip)
45
+ places_of_publication, publishers = [], []
47
46
 
48
- record["placeOfPublication"][index] = _place_of_publication
49
- record["publisher"][index] = _publisher
50
- end
47
+ places_seperated_from_publishers.each.with_index do |place_and_publisher, index|
48
+ places_of_publication[index] = place_and_publisher.first
49
+ publishers[index] = place_and_publisher.last
51
50
  end
52
51
 
53
- record["placeOfPublication"] = collapse_array(record["placeOfPublication"])
54
- record["publisher"] = collapse_array(record["publisher"])
52
+ record["placeOfPublication"] = collapse_array(places_of_publication)
53
+ record["publisher"] = collapse_array(publishers)
55
54
  end
56
55
  end
57
56
 
@@ -1,5 +1,5 @@
1
1
  module Celsius
2
2
  module Primo
3
- VERSION = "0.1.3"
3
+ VERSION = "0.1.4"
4
4
  end
5
5
  end
@@ -0,0 +1,66 @@
1
+ ---
2
+ facets:
3
+ facet_tlevel:
4
+ terms:
5
+ field: facet_tlevel
6
+ shard_size: 75
7
+ facet_creator:
8
+ terms:
9
+ field: facet_creator
10
+ shard_size: 75
11
+ facet_local31:
12
+ terms:
13
+ field: facet_local31
14
+ shard_size: 75
15
+ facet_topic:
16
+ terms:
17
+ field: facet_topic
18
+ shard_size: 75
19
+ facet_creationdate:
20
+ terms:
21
+ field: facet_creationdate
22
+ shard_size: 75
23
+ facet_domain:
24
+ terms:
25
+ field: facet_domain
26
+ shard_size: 75
27
+ facet_lang:
28
+ terms:
29
+ field: facet_lang
30
+ shard_size: 75
31
+ facet_local15:
32
+ terms:
33
+ field: facet_local15
34
+ shard_size: 75
35
+ facet_local32:
36
+ terms:
37
+ field: facet_local32
38
+ shard_size: 75
39
+ facet_local33:
40
+ terms:
41
+ field: facet_local33
42
+ shard_size: 75
43
+ from: 0
44
+ size: 20
45
+ sort:
46
+ - _score
47
+ query:
48
+ bool:
49
+ must:
50
+ - query_string:
51
+ default_operator: AND
52
+ fields:
53
+ - _all
54
+ query: linux
55
+ - query_string:
56
+ default_operator: AND
57
+ fields:
58
+ - creator
59
+ query: kofler
60
+ - query_string:
61
+ default_operator: AND
62
+ fields:
63
+ - _all
64
+ query: mysql
65
+ - match:
66
+ facet_topic: MySQL
@@ -0,0 +1,158 @@
1
+ ---
2
+ took:
3
+ hits:
4
+ hits:
5
+ - _type: record
6
+ _source:
7
+ control:
8
+ sourcerecordid: 000831395
9
+ sourceid: PAD_ALEPH
10
+ recordid: PAD_ALEPH000831395
11
+ originalsourceid: PAD01
12
+ ilsapiid: PAD01000831395
13
+ sourcesystem: Aleph
14
+ display:
15
+ type: print
16
+ title: 'MySQL : Einführung, Programmierung, Referenz'
17
+ creator: Kofler, Michael
18
+ publisher: 'München [u.a.] : Addison-Wesley'
19
+ creationdate: '2001'
20
+ format: '624 S. : Ill., graph. Darst.'
21
+ subject: MySQL
22
+ language: ger
23
+ lds01: '{"ht_number":null,"label":"Linux Specials","volume_count":null,"label_additions":null}'
24
+ lds02: 'MySQL : Einführung, Programmierung, Referenz'
25
+ lds10: TWY9467
26
+ search:
27
+ creatorcontrib:
28
+ - Kofler, Michael
29
+ - Kofler, M.
30
+ - Kofler, Michaėlʹ
31
+ title:
32
+ - 'MySQL : Einführung, Programmierung, Referenz'
33
+ - Linux Specials
34
+ subject: MySQL
35
+ general: TWY
36
+ sourceid: PAD_ALEPH
37
+ recordid: PAD_ALEPH000831395
38
+ isbn:
39
+ - 3-8273-1762-2
40
+ - '9783827317629'
41
+ - '3827317622'
42
+ rsrctype: print
43
+ format: '624 S. : Ill., graph. Darst.'
44
+ creationdate: '2001'
45
+ searchscope: PAD_ALEPH
46
+ scope: PAD_ALEPH
47
+ lsr02: 'false'
48
+ lsr03: 'false'
49
+ lsr04: 'true'
50
+ lsr05: HT012953391
51
+ lsr09: '20010522'
52
+ lsr10:
53
+ - TWY9467
54
+ - TWY9467+1
55
+ - TWY9467+2
56
+ - TWY9467+3
57
+ lsr15: TWY
58
+ lsr31: monograph
59
+ lsr32: other
60
+ lsr33: print
61
+ lsr34: 'München [u.a.] : Addison-Wesley'
62
+ sort:
63
+ title: 'MySQL : Einführung, Programmierung, Referenz'
64
+ creationdate: '2001'
65
+ author: Kofler, Michael
66
+ lso01: '20010522'
67
+ lso03: TWY
68
+ lso48: PAD01000831395
69
+ facets:
70
+ language: ger
71
+ creationdate: '2001'
72
+ topic: MySQL
73
+ toplevel: printmedia
74
+ rsrctype:
75
+ - other
76
+ - books
77
+ creatorcontrib: Kofler, Michael
78
+ format: '624 S. : Ill., graph. Darst.'
79
+ lfc15: TWY
80
+ lfc31: monograph
81
+ lfc32: other
82
+ lfc33: print
83
+ frbrgroupid: '282131342'
84
+ frbrtype: '6'
85
+ delivery:
86
+ delcategory: physical_item
87
+ addata:
88
+ lad01: '{"author_statement":["Michael Kofler"],"person_creator_display":["Kofler,
89
+ Michael"]}'
90
+ _id: PAD_ALEPH000831395
91
+ creator: Kofler, Michael
92
+ created: '2001'
93
+ description:
94
+ edition:
95
+ format: '624 S. : Ill., graph. Darst.'
96
+ identifier:
97
+ - PAD01000831395
98
+ - PAD_ALEPH000831395
99
+ isbn:
100
+ - 3-8273-1762-2
101
+ - '9783827317629'
102
+ - '3827317622'
103
+ issn:
104
+ language: ger
105
+ title: 'MySQL : Einführung, Programmierung, Referenz'
106
+ publisher: Addison-Wesley
107
+ subject: MySQL
108
+ placeOfPublication: München [u.a.]
109
+ total: 1
110
+ facets:
111
+ facet_tlevel:
112
+ _type: terms
113
+ terms:
114
+ - term: printmedia
115
+ count: 1
116
+ facet_creator:
117
+ _type: terms
118
+ terms:
119
+ - term: Kofler, Michael
120
+ count: 1
121
+ facet_local31:
122
+ _type: terms
123
+ terms:
124
+ - term: monograph
125
+ count: 1
126
+ facet_topic:
127
+ _type: terms
128
+ terms:
129
+ - term: MySQL
130
+ count: 1
131
+ facet_creationdate:
132
+ _type: terms
133
+ terms:
134
+ - term: '2001'
135
+ count: 1
136
+ facet_domain:
137
+ _type: terms
138
+ terms: []
139
+ facet_lang:
140
+ _type: terms
141
+ terms:
142
+ - term: ger
143
+ count: 1
144
+ facet_local15:
145
+ _type: terms
146
+ terms:
147
+ - term: TWY
148
+ count: 1
149
+ facet_local32:
150
+ _type: terms
151
+ terms:
152
+ - term: other
153
+ count: 1
154
+ facet_local33:
155
+ _type: terms
156
+ terms:
157
+ - term: print
158
+ count: 1
@@ -3127,12 +3127,26 @@ facets:
3127
3127
  facet_topic:
3128
3128
  _type: terms
3129
3129
  terms:
3130
- - term: SHELL
3131
- count: 5
3132
3130
  - term: Rechnernetz
3133
3131
  count: 10
3134
3132
  - term: Personalcomputer
3135
3133
  count: 5
3134
+ - term: Computer science
3135
+ count: 9
3136
+ - term: Unternehmen
3137
+ count: 4
3138
+ - term: Eingebettetes System
3139
+ count: 5
3140
+ - term: Kernel
3141
+ count: 5
3142
+ - term: Programmierung
3143
+ count: 6
3144
+ - term: Python
3145
+ count: 4
3146
+ - term: Software Engineering
3147
+ count: 12
3148
+ - term: SHELL
3149
+ count: 5
3136
3150
  - term: Web-Seite
3137
3151
  count: 7
3138
3152
  - term: c
@@ -3143,34 +3157,22 @@ facets:
3143
3157
  count: 8
3144
3158
  - term: Operating systems (Computers)
3145
3159
  count: 14
3146
- - term: Computer science
3147
- count: 9
3148
3160
  - term: Treiber
3149
3161
  count: 5
3150
- - term: Unternehmen
3162
+ - term: Server
3151
3163
  count: 4
3152
3164
  - term: UNIX
3153
3165
  count: 23
3154
- - term: Eingebettetes System
3155
- count: 5
3156
3166
  - term: Open Source
3157
3167
  count: 6
3158
3168
  - term: Computersicherheit
3159
3169
  count: 6
3160
3170
  - term: Systemverwaltung
3161
3171
  count: 6
3162
- - term: Kernel
3163
- count: 5
3164
- - term: Programmierung
3165
- count: 6
3166
3172
  - term: Softwareentwicklung
3167
3173
  count: 7
3168
3174
  - term: Betriebssystem
3169
3175
  count: 9
3170
- - term: Python
3171
- count: 4
3172
- - term: Software engineering
3173
- count: 12
3174
3176
  - term: Gestaltung
3175
3177
  count: 5
3176
3178
  - term: Computer network architectures