bento_search 1.3.0 → 1.4.2

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: 07eca03117fe99d9677efc390aaef6c62d3cdef5
4
- data.tar.gz: e7eeaff771953510f2f08828410c2db297f4cb36
3
+ metadata.gz: ee7b23e2add7fc9cadf6223574615febac70af86
4
+ data.tar.gz: ebc2f96b07206c4b7a4e4de5083a8ef0a02576ea
5
5
  SHA512:
6
- metadata.gz: 324fb0e242743f393ca3403e6612e51f92a9f704e01aecdba7d8f2eb4bc68b6df07740dbb33fb2ff9120093d91d99d209b16288a4859827d260be72272bd1c3a
7
- data.tar.gz: 6bbc568ac0485540414a7e9a01ae5ade8f17d20fbbc9fa0199bca3dfac1e5739771c6e9ea980b1c8e3fe8593499cbf57c3dfc3368b88b1c13ec2c7facebed2bf
6
+ metadata.gz: 4e7e9044ff5b1bdc115d828c05ddaa7af4190bed36ec28d3994cd8a4b7092f58d7086b1ed322183c32419d29fc2e311172722495fcde7b1b2afa5b4ec70324cf
7
+ data.tar.gz: 86adb80a03ef49a5a2d55d56447f92decb412084d246b092c54558c3ef215ede30517d73438fe9e2cce1c7e3ce3037b6a2e389707f32ef0f69951b685a044c29
data/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  bento_search provides an abstraction/normalization layer for querying and
7
7
  displaying results from external search engines, in Ruby on Rails. Works with
8
- Rails 3.x or 4.x. Currently tested only under ruby 1.9.3. (todo, change this soon)
8
+ Rails 3.x or 4.x. ruby 1.9.3+
9
9
 
10
10
  ### Goals: To help you
11
11
 
@@ -87,7 +87,7 @@ may be required for certain engines.
87
87
  ~~~~
88
88
 
89
89
  `results` are a [BentoSearch::Results](./app/models/bento_search/results.rb) object, which acts like an array of
90
- [BentoSearch::Item](./app/models/bento_search/results.rb) objects, along with some meta-information about the
90
+ [BentoSearch::ResultItem](./app/models/bento_search/result_item.rb) objects, along with some meta-information about the
91
91
  search itself (pagination keys, etc). BentoSearch::Results and Item fields
92
92
  are standardized accross engines. BentoSearch::Items provide semantic
93
93
  values (title, author, etc.), as available from the particular engine.
@@ -350,6 +350,46 @@ end
350
350
  There are additional details that might matter to you, for more info see the
351
351
  [wiki page](https://github.com/jrochkind/bento_search/wiki/Machine-Readable-Serialization-With-Atom)
352
352
 
353
+ ### Round-Trip Serialization to JSON
354
+
355
+ You can serialize BentoSearch::Results to a simple straightforward JSON structure, and de-serialize
356
+ them back into BentoSearch::Results.
357
+
358
+ ~~~ruby
359
+ json_str = results.dump_to_json
360
+ copy_of_results = BentoSearch::Results.load_json(json_str)
361
+ ~~~
362
+
363
+ Search context (query, start, per_page) are not serialized, and will be lost
364
+ on de-serialization.
365
+
366
+ Unlike the Atom serialization, **the JSON serialization is of internal data
367
+ state, without decoration.** Configuration context is not serialized.
368
+
369
+ However, the engine_id is included in serialization if present,
370
+ and configuration from the specified engine
371
+ will be re-assigned on de-serialization. This means if the configuration
372
+ changed between serialization and de-serialization, you get the new stuff
373
+ assigned on de-serialization.
374
+
375
+ The use case guiding JSON serialization is storage somewhere, and
376
+ round-trip de-serialization in the current app context.
377
+
378
+ If you want to take de-serialized results that did not have an engine_id,
379
+ or set configuration on them to a different engine (registered or not) you can:
380
+
381
+ ~~~ruby
382
+ restored = BentoSearch::Results.load_json(json_str)
383
+ some_engine.fill_in_search_metadata_for(restored)
384
+
385
+ # restored Results will have configuration (engine_id, decorators, etc)
386
+ # set to those configured on some_engine
387
+ ~~~
388
+
389
+ If you want a serialization to be consumed by something other than an
390
+ app using the bento_search gem, as an API, we recommend the [Atom serialization](https://github.com/jrochkind/bento_search/wiki/Machine-Readable-Serialization-With-Atom)
391
+ instead.
392
+
353
393
  ## Planned Features
354
394
 
355
395
  I am trying to keep BentoSearch as simple as it can be to conveniently meet
@@ -32,7 +32,7 @@ module BentoSearch
32
32
  # We may provide fancier/nicer API for this in the future, if there's
33
33
  # demand.
34
34
  class SearchController < BentoSearchController
35
- class AccessDenied < Exception ; end
35
+ class AccessDenied < BentoSearch::Error ; end
36
36
 
37
37
 
38
38
  rescue_from AccessDenied, :with => :deny_access
@@ -1,5 +1,7 @@
1
1
  module BentoSearch
2
2
  class Author
3
+ include ::BentoSearch::Results::Serialization
4
+
3
5
  def initialize(args ={})
4
6
  args.each_pair do |key, value|
5
7
  send("#{key}=", value)
@@ -7,15 +9,15 @@ module BentoSearch
7
9
  end
8
10
 
9
11
  # Can be first name or initial, whatever source provides
10
- attr_accessor :first
12
+ serializable_attr_accessor :first
11
13
  # last name/surname/family name as provided by source
12
- attr_accessor :last
14
+ serializable_attr_accessor :last
13
15
  # middle name or initial, as and if provided by source
14
- attr_accessor :middle
16
+ serializable_attr_accessor :middle
15
17
 
16
18
  # if source doens't provide seperate first/last,
17
19
  # source may only be able to provide one big string, author_display
18
- attr_accessor :display
20
+ serializable_attr_accessor :display
19
21
 
20
22
  def empty?
21
23
  first.blank? && last.blank? && middle.blank? && display.blank?
@@ -3,27 +3,30 @@ module BentoSearch
3
3
  #
4
4
  # label, url, other metadata about the link.
5
5
  class Link
6
+ include BentoSearch::Results::Serialization
7
+
8
+ serializable_attr_accessor :label
6
9
  # url is normally a string, but can also be a Hash passed
7
10
  # to url_for in the local app.
8
- attr_accessor :label, :url
11
+ serializable_attr_accessor :url
9
12
 
10
13
  # Used both for HTML links and possibly later Atom.
11
14
  # Must be a string, EITHER a complete URL (representing
12
15
  # vocab term), OR a legal short name from
13
16
  # http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#linkTypes
14
- attr_accessor :rel
17
+ serializable_attr_accessor :rel
15
18
 
16
19
  # MIME content type may be used for both HMTL links and Atom
17
20
  # link 'type' attribute
18
- attr_accessor :type
21
+ serializable_attr_accessor :type
19
22
 
20
23
  # Array of strings, used for CSS classes on this link, possibly
21
24
  # for custom styles/images etc. May be used in non-html link
22
25
  # contexts too.
23
- attr_accessor :style_classes
26
+ serializable_attr_accessor :style_classes
24
27
 
25
28
  # Suggested `target` attribute to render link with as html <a>
26
- attr_accessor :target
29
+ serializable_attr_accessor :target
27
30
 
28
31
  def initialize(hash = {})
29
32
  self.style_classes = []
@@ -105,7 +105,7 @@ begin
105
105
  def start(*search_args)
106
106
  begin
107
107
  @results = self.engine.search(*search_args)
108
- rescue Exception => e
108
+ rescue StandardError => e
109
109
  Rails.logger.error("\nBentoSearch:MultiSearcher caught exception: #{e}\n#{e.backtrace.join(" \n")}")
110
110
  # Make a fake results with caught exception.
111
111
  @results = BentoSearch::Results.new
@@ -1,9 +1,10 @@
1
+ require 'bento_search'
1
2
 
2
3
  # Holds a list of registered search engines with configuration.
3
4
  # There's one global one referened by BentoSearch module, but one
4
5
  # might want to create multiple.
5
6
  class BentoSearch::Registrar
6
- class ::BentoSearch::NoSuchEngine < Exception ; end
7
+ class ::BentoSearch::NoSuchEngine < ::BentoSearch::Error ; end
7
8
 
8
9
  def initialize
9
10
  @registered_engine_confs = {}
@@ -1,4 +1,7 @@
1
1
  require 'language_list'
2
+ require 'bento_search/author'
3
+ require 'bento_search/link'
4
+
2
5
 
3
6
  module BentoSearch
4
7
  # Data object representing a single hit from a search, normalized
@@ -14,6 +17,8 @@ module BentoSearch
14
17
  include ERB::Util # for html_escape for our presentational stuff
15
18
  include ActionView::Helpers::OutputSafetyHelper # for safe_join
16
19
 
20
+ include ::BentoSearch::Results::Serialization
21
+
17
22
  # Can initialize with a hash of key/values
18
23
  def initialize(args = {})
19
24
  args.each_pair do |key, value|
@@ -30,21 +35,24 @@ module BentoSearch
30
35
  # internal unique id for the document, from the particular
31
36
  # search service it came from. May be alphanumeric. May be nil
32
37
  # for engines that don't support it.
33
- attr_accessor :unique_id
38
+ serializable_attr_accessor :unique_id
39
+
34
40
 
35
41
  # If set to true, item will refuse to generate an openurl,
36
42
  # returning nil from #to_openurl or #openurl_kev
37
- attr_accessor :openurl_disabled
43
+ serializable_attr_accessor :openurl_disabled
44
+
38
45
 
39
46
  # Array (possibly empty) of BentoSearch::Link objects
40
47
  # representing additional links. Often SearchEngine's themselves
41
48
  # won't include any of these, but Decorators will be used
42
49
  # to add them in.
43
50
  attr_accessor :other_links
51
+ serializable_attr :other_links, :collection_of => "BentoSearch::Link"
44
52
 
45
53
  # * dc.title
46
54
  # * schema.org CreativeWork: 'name'
47
- attr_accessor :title
55
+ serializable_attr_accessor :title
48
56
  # backwards compat, we used to have separate titles and subtitles
49
57
  alias_method :complete_title, :title
50
58
 
@@ -52,6 +60,7 @@ module BentoSearch
52
60
  # Can be changed in actual presentation with a Decorator.
53
61
  # * schema.org CreativeWork: 'url'
54
62
  attr_accessor :link
63
+ serializable_attr :link
55
64
 
56
65
  # does the #link correspond to fulltext? true or false -- or nil
57
66
  # for unknown/non-applicable. Not all engines will set.
@@ -61,6 +70,7 @@ module BentoSearch
61
70
  def link_is_fulltext=(v)
62
71
  @link_is_fulltext = v
63
72
  end
73
+ serializable_attr :link_is_fulltext
64
74
 
65
75
  # Our own INTERNAL controlled vocab for 'format'.
66
76
  #
@@ -102,7 +112,7 @@ module BentoSearch
102
112
  #
103
113
  # Note: We're re-thinking this, might allow uncontrolled
104
114
  # in here instead.
105
- attr_accessor :format
115
+ serializable_attr_accessor :format
106
116
 
107
117
  # Translated from internal format vocab at #format. Outputs
108
118
  # eg http://schema.org/Book
@@ -127,7 +137,7 @@ module BentoSearch
127
137
  # uncontrolled presumably english-language format string.
128
138
  # if supplied will be used in display in place of controlled
129
139
  # format.
130
- attr_accessor :format_str
140
+ serializable_attr_accessor :format_str
131
141
 
132
142
  # Language of materials. Producer can set language_code to an ISO 639-1 (two
133
143
  # letter) or 639-3 (three letter) language code. If you do this, you don't
@@ -143,7 +153,7 @@ module BentoSearch
143
153
  # #language_iso_639_2 (either may be null), or #language_str for uncontrolled
144
154
  # string. If engine just sets one of these, internals take care of filling
145
155
  # out the others. r
146
- attr_accessor :language_code
156
+ serializable_attr_accessor :language_code
147
157
  attr_writer :language_str
148
158
  def language_str
149
159
  @language_str || language_code.try do |code|
@@ -152,6 +162,7 @@ module BentoSearch
152
162
  end
153
163
  end
154
164
  end
165
+ serializable_attr :language_str
155
166
  # Returns a LanguageList gem language object-- from #language_code
156
167
  # if available, otherwise from direct language_str if available and
157
168
  # possible.
@@ -176,45 +187,46 @@ module BentoSearch
176
187
  # * prism:coverDate, year portion
177
188
  #
178
189
  # See also publication_date when you have a complete date
179
- attr_accessor :year
190
+ serializable_attr_accessor :year
180
191
  # ruby stdlib Date object.
181
192
  attr_accessor :publication_date
193
+ serializable_attr :publication_date, :serializer => "Date"
182
194
 
183
- attr_accessor :volume
184
- attr_accessor :issue
185
- attr_accessor :start_page
186
- attr_accessor :end_page
195
+ serializable_attr_accessor :volume
196
+ serializable_attr_accessor :issue
197
+ serializable_attr_accessor :start_page
198
+ serializable_attr_accessor :end_page
187
199
 
188
200
  # source_title is often used for journal_title (and aliased
189
201
  # as #journal_title, although that may go away), but can
190
202
  # also be used for other 'container' titles. Book title for
191
203
  # a book chapter. Even web site or URL for a web page.
192
- attr_accessor :source_title
204
+ serializable_attr_accessor :source_title
193
205
  alias_method :journal_title, :source_title
194
206
  alias_method :'journal_title=', :'source_title='
195
207
 
196
208
 
197
- attr_accessor :issn
198
- attr_accessor :isbn
199
- attr_accessor :oclcnum # OCLC accession number, WorldCat.
209
+ serializable_attr_accessor :issn
210
+ serializable_attr_accessor :isbn
211
+ serializable_attr_accessor :oclcnum # OCLC accession number, WorldCat.
200
212
 
201
- attr_accessor :doi
202
- attr_accessor :pmid
213
+ serializable_attr_accessor :doi
214
+ serializable_attr_accessor :pmid
203
215
 
204
216
  # usually used for books rather than articles
205
- attr_accessor :publisher
217
+ serializable_attr_accessor :publisher
206
218
 
207
219
  # an openurl kev-encoded context object. optional,
208
220
  # only if source provides one that may be better
209
221
  # than can be constructed from individual elements above
210
- attr_accessor :openurl_kev_co
222
+ serializable_attr_accessor :openurl_kev_co
211
223
 
212
224
  # Short summary of item.
213
225
  # Mark .html_safe if it includes html -- creator is responsible
214
226
  # for making sure html is safely sanitizied and/or stripped,
215
227
  # rails ActionView::Helpers::Sanistize #sanitize and #strip_tags
216
228
  # may be helpful.
217
- attr_accessor :abstract
229
+ serializable_attr_accessor :abstract
218
230
 
219
231
  # An ARRAY of string query-in-context snippets. Will usually
220
232
  # have highlighting <b> tags in it. Creator is responsible
@@ -225,14 +237,16 @@ module BentoSearch
225
237
  # with same content formatted differently (array of multiple vs
226
238
  # one combined string), some engines they may be different.
227
239
  attr_accessor :snippets
240
+ serializable_attr :snippets
228
241
 
229
242
  # An array (order matters) of BentoSearch::Author objects
230
243
  # add authors to it with results.authors << Author
231
244
  attr_accessor :authors
245
+ serializable_attr :authors, :collection_of => "BentoSearch::Author"
232
246
 
233
247
  # engine-specific data not suitable for abstract API, usually
234
248
  # for internal use.
235
- attr_accessor :custom_data
249
+ serializable_attr_accessor :custom_data
236
250
 
237
251
  # Copied over from engine configuration usually, a string
238
252
  # qualified name of a decorator class. Can be nil for default.
@@ -248,6 +262,8 @@ module BentoSearch
248
262
  # into a backpointing reference instead? And user cover-methods
249
263
  # for it? Nice thing about the configuration has instead is it's
250
264
  # easily serializable, it's just data.
265
+ #
266
+ # Although we intentionally do NOT include these in JSON serialization, ha.
251
267
  attr_accessor :display_configuration
252
268
  attr_accessor :engine_id
253
269
 
@@ -0,0 +1,136 @@
1
+ require 'bento_search/results'
2
+ require 'active_support/concern'
3
+ require 'json'
4
+ require 'date'
5
+
6
+ # Call #dump_to_json on a BentoSearch value object (such as BentoSearch::Result or ::Author)
7
+ # to get it in Json
8
+ #
9
+ # Values marked with serializable_attr in BentoSearch::Result are
10
+ # included in seralization.
11
+ #
12
+ # At present metadata and configuration are NOT serialized: #decorator, #display_configuration,
13
+ # and #engine_id are not included in the serialization, so when loaded from serialization,
14
+ # ResultItems will not have such things set.
15
+ #
16
+ # * Works by getting and setting instance variables directly, ignores getters/setters
17
+ #
18
+ # * This means decorated values are NOT included in serialization, the raw
19
+ # values are what is serialized. This is intended, we serialize internal
20
+ # state, not decoration which can be recreated. You should make sure the decorators you
21
+ # want are applied after de-serialization.
22
+ #
23
+ # * preserves html_safety status in serialization, by adding extra `_attr_htmlsafe: true` key/value
24
+ #
25
+ module BentoSearch::Results::Serialization
26
+ extend ActiveSupport::Concern
27
+
28
+ included do
29
+ class_attribute :_serializable_attrs, :_serializable_attr_options
30
+ self._serializable_attrs = []
31
+ self._serializable_attr_options = {}
32
+ end
33
+
34
+ class_methods do
35
+ # Just a macro to mark a property name serializable -- the name is
36
+ # of an instance method that will be included in our serializations
37
+ # and de-serializations.
38
+ #
39
+ # Options:
40
+ # * collection_of: String fully qualified name of a class that is
41
+ # is also BentoSearch::Results::Serialization, the attribute
42
+ # is an array of these.
43
+ # * serializer: String fully qualified class name of a serializer
44
+ # class that has a `dump` and a `load` for individual values,
45
+ # we just use it for Date now, see BentoSearch::Results::Serialization::Date
46
+ def serializable_attr(symbol, options = nil)
47
+ symbol = symbol.to_s
48
+ self._serializable_attrs << symbol
49
+ if options
50
+ self._serializable_attr_options[symbol] = options
51
+ end
52
+ end
53
+
54
+ # convenience macro to do attr_accessor AND mark it
55
+ # serializable
56
+ def serializable_attr_accessor(symbol)
57
+ self.send(:attr_accessor, symbol)
58
+ self.serializable_attr symbol
59
+ end
60
+
61
+ def from_internal_state_hash(hash)
62
+ o = self.new
63
+ hash.each_pair do |key, value|
64
+ key = key.to_s
65
+
66
+ next if key =~ /\A_.*_htmlsafe\Z/
67
+
68
+
69
+ if _serializable_attr_options[key] && _serializable_attr_options[key][:collection_of]
70
+ klass = qualified_const_get(_serializable_attr_options[key][:collection_of])
71
+ value = value.collect do |item|
72
+ klass.from_internal_state_hash(item)
73
+ end
74
+ end
75
+
76
+ if _serializable_attr_options[key] && _serializable_attr_options[key][:serializer]
77
+ klass = qualified_const_get(_serializable_attr_options[key][:serializer])
78
+ value = klass.load(value)
79
+ end
80
+
81
+ if hash["_#{key}_htmlsafe"] == true && value.respond_to?(:html_safe)
82
+ value = value.html_safe
83
+ end
84
+
85
+ o.instance_variable_set("@#{key}", value)
86
+ end
87
+
88
+ return o
89
+ end
90
+
91
+ def load_json(json_str)
92
+ self.from_internal_state_hash( JSON.parse! json_str )
93
+ end
94
+
95
+ end
96
+
97
+ def internal_state_hash
98
+ hash = {}
99
+ self._serializable_attrs.each do |accessor|
100
+ accessor = accessor.to_s
101
+ value = self.instance_variable_get("@#{accessor}")
102
+
103
+ next if value.blank?
104
+
105
+ if _serializable_attr_options[accessor] && _serializable_attr_options[accessor][:serializer]
106
+ klass = self.class.qualified_const_get(_serializable_attr_options[accessor][:serializer])
107
+ value = klass.dump(value)
108
+ elsif value.respond_to?(:to_ary)
109
+ value = value.to_ary.collect do |item|
110
+ item.respond_to?(:internal_state_hash) ? item.internal_state_hash : item
111
+ end
112
+ end
113
+
114
+ hash[accessor] = value
115
+
116
+ if value.respond_to?(:html_safe?) && value.html_safe?
117
+ hash["_#{accessor}_htmlsafe"] = true
118
+ end
119
+ end
120
+ return hash
121
+ end
122
+
123
+ def dump_to_json
124
+ JSON.dump self.internal_state_hash
125
+ end
126
+
127
+ class Date
128
+ def self.dump(datetime)
129
+ datetime.iso8601
130
+ end
131
+ def self.load(str)
132
+ ::Date.iso8601(str)
133
+ end
134
+ end
135
+
136
+ end
@@ -1,10 +1,20 @@
1
+ require 'json'
2
+
1
3
  module BentoSearch
2
4
  # An array-like object (in fact it-subclasses Array) that holds
3
5
  # a page of search results. But also has some meta-data about the
4
6
  # search itself (query, paging, etc).
5
-
7
+ #
6
8
  # If #error is non-nil, object may not have real results, but
7
9
  # be an error. You can use failed? to see.
10
+ #
11
+ # Serializes as a Hash including ONLY the serialized results themselves,
12
+ # and the engine ID. Search context (total items, start, etc) are not
13
+ # included in serialization. Configuration context is also not serialized,
14
+ # although since the engineID is, it can be reconstructed on de-serialization.
15
+ #
16
+ # Serialization isn't actually implemented with the BentoSearch::Results::Serialization
17
+ # module, cause it didn't work out, just re-implemented here with same methods.
8
18
  class Results < ::Array
9
19
  attr_accessor :total_items
10
20
  # 0-based index into total results, used for pagination
@@ -48,6 +58,7 @@ module BentoSearch
48
58
  # Registered id of engine used to create these results,
49
59
  # may be nil if used with an unregistered engine.
50
60
  attr_accessor :engine_id
61
+
51
62
 
52
63
  # Returns a BentoSearch::Results::Pagination, that should be suitable
53
64
  # for passing right to Kaminari (although Kaminari isn't good about doc/specing
@@ -63,6 +74,40 @@ module BentoSearch
63
74
  def inspect
64
75
  "<BentoSearch::Results #{super} #{'FAILED' if self.failed?}>"
65
76
  end
77
+
78
+ # Serialization
79
+ def internal_state_hash
80
+ {
81
+ "engine_id" => self.engine_id,
82
+ "result_items" => self.collect {|i| i.internal_state_hash}
83
+ }
84
+ end
85
+
86
+ # Creates a Results object from an internal_state_hash, and restores
87
+ # it's configuration from engine_id
88
+ def self.from_internal_state_hash(hash)
89
+ results = BentoSearch::Results.new
90
+ results.engine_id = hash["engine_id"]
91
+ hash["result_items"].each do |item_hash|
92
+ results << BentoSearch::ResultItem.from_internal_state_hash(item_hash)
93
+ end
94
+
95
+ if results.engine_id
96
+ BentoSearch.get_engine(results.engine_id).fill_in_search_metadata_for(results, {})
97
+ end
98
+
99
+ return results
100
+ end
101
+
102
+ def dump_to_json
103
+ JSON.dump self.internal_state_hash
104
+ end
105
+
106
+ def self.load_json(json_str)
107
+ from_internal_state_hash JSON.parse(json_str)
108
+ end
109
+
110
+
66
111
 
67
112
  end
68
113
  end
@@ -10,9 +10,13 @@ require 'nokogiri'
10
10
  module BentoSearch
11
11
  # Usually raised by #get on an engine, when result for specified identifier
12
12
  # can't be found.
13
- class NotFound < Exception ; end
13
+ class ::BentoSearch::NotFound < ::BentoSearch::Error ; end
14
14
  # Usually raised by #get when identifier results in more than one record.
15
- class TooManyFound < Exception ; end
15
+ class ::BentoSearch::TooManyFound < ::BentoSearch::Error ; end
16
+ # Raised for problem contacting or unexpected response from
17
+ # remote service. Not yet universally used.
18
+ class ::BentoSearch::FetchError < ::BentoSearch::Error ; end
19
+
16
20
 
17
21
  # Module mix-in for bento_search search engines.
18
22
  #
@@ -217,16 +221,7 @@ module BentoSearch
217
221
  fill_in_search_metadata_for(results, arguments)
218
222
 
219
223
  results.timing = (Time.now - start_t)
220
-
221
- results.each do |item|
222
- # We copy some configuraton info over to each Item, as a convenience
223
- # to display logic that may have decide what to do given only an item,
224
- # and may want to parameterize based on configuration.
225
- item.engine_id = results.engine_id
226
- item.decorator = configuration.lookup!("for_display.decorator")
227
- item.display_configuration = configuration.for_display
228
- end
229
-
224
+
230
225
  return results
231
226
  rescue *auto_rescue_exceptions => e
232
227
  # Uncaught exception, log and turn into failed Results object. We
@@ -252,16 +247,26 @@ module BentoSearch
252
247
 
253
248
  # SOME of the elements of Results to be returned that SearchEngine implementation
254
249
  # fills in automatically post-search. Extracted into a method for DRY in
255
- # error handling to try to fill these in even in errors. And *possible*
256
- # experimental use in other classes for same thing is why method is
257
- # public, see MultiSearcher.
258
- def fill_in_search_metadata_for(results, normalized_arguments)
250
+ # error handling to try to fill these in even in errors. Also can be used
251
+ # as public method for de-serialized or mock results.
252
+ def fill_in_search_metadata_for(results, normalized_arguments = {})
259
253
  results.search_args = normalized_arguments
260
254
  results.start = normalized_arguments[:start] || 0
261
255
  results.per_page = normalized_arguments[:per_page]
262
256
 
263
257
  results.engine_id = configuration.id
264
- results.display_configuration = configuration.for_display
258
+ results.display_configuration = configuration.for_display
259
+
260
+ # We copy some configuraton info over to each Item, as a convenience
261
+ # to display logic that may have decide what to do given only an item,
262
+ # and may want to parameterize based on configuration.
263
+ results.each do |item|
264
+ item.engine_id = configuration.id
265
+ item.decorator = configuration.lookup!("for_display.decorator")
266
+ item.display_configuration = configuration.for_display
267
+ end
268
+
269
+ results
265
270
  end
266
271
 
267
272
 
@@ -539,7 +539,7 @@ class BentoSearch::EdsEngine
539
539
  # there's a short reason in #message, but also
540
540
  # possibly an http_status and http_body copied
541
541
  # from error EDS response.
542
- class EdsCommException < Exception
542
+ class EdsCommException < ::BentoSearch::FetchError
543
543
  attr_accessor :http_status, :http_body
544
544
  def initialize(message, status = nil, body = nil)
545
545
  super(message)