bento_search 0.6.0 → 0.7.0
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.
- data/README.md +131 -74
- data/app/assets/javascripts/bento_search/ajax_load.js +12 -4
- data/app/assets/stylesheets/bento_search/suggested_styles.css +4 -4
- data/app/helpers/bento_search_helper.rb +114 -27
- data/app/item_decorators/bento_search/decorator_base.rb +53 -0
- data/app/item_decorators/bento_search/ebscohost/conditional_openurl_main_link.rb +36 -0
- data/app/item_decorators/bento_search/no_links.rb +3 -2
- data/app/item_decorators/bento_search/only_premade_openurl.rb +4 -0
- data/app/item_decorators/bento_search/openurl_add_other_link.rb +4 -0
- data/app/item_decorators/bento_search/openurl_main_link.rb +4 -0
- data/app/item_decorators/bento_search/standard_decorator.rb +122 -0
- data/app/models/bento_search/multi_searcher.rb +13 -6
- data/app/models/bento_search/openurl_creator.rb +25 -5
- data/app/models/bento_search/result_item.rb +25 -83
- data/app/models/bento_search/results/pagination.rb +8 -2
- data/app/models/bento_search/search_engine.rb +29 -23
- data/app/search_engines/bento_search/ebsco_host_engine.rb +161 -25
- data/app/search_engines/bento_search/eds_engine.rb +1 -44
- data/app/search_engines/bento_search/google_books_engine.rb +61 -14
- data/app/search_engines/bento_search/google_site_search_engine.rb +3 -1
- data/app/search_engines/bento_search/mock_engine.rb +4 -0
- data/app/search_engines/bento_search/primo_engine.rb +2 -3
- data/app/search_engines/bento_search/scopus_engine.rb +1 -0
- data/app/search_engines/bento_search/summon_engine.rb +5 -1
- data/app/search_engines/bento_search/worldcat_sru_dc_engine.rb +36 -8
- data/app/views/bento_search/_item_title.html.erb +29 -0
- data/app/views/bento_search/_no_results.html.erb +3 -0
- data/app/views/bento_search/_search_error.html.erb +19 -15
- data/app/views/bento_search/_std_item.html.erb +55 -30
- data/app/views/bento_search/search/search.html.erb +7 -0
- data/config/locales/en.yml +22 -0
- data/lib/bento_search/util.rb +63 -1
- data/lib/bento_search/version.rb +1 -1
- data/test/decorator/decorator_base_test.rb +72 -0
- data/test/decorator/standard_decorator_test.rb +55 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/log/development.log +12 -0
- data/test/dummy/log/test.log +119757 -0
- data/test/functional/bento_search/search_controller_test.rb +28 -0
- data/test/helper/bento_search_helper_test.rb +71 -0
- data/test/helper/bento_truncate_helper_test.rb +71 -0
- data/test/unit/ebsco_host_engine_test.rb +110 -3
- data/test/unit/google_books_engine_test.rb +22 -14
- data/test/unit/google_site_search_test.rb +11 -4
- data/test/unit/item_decorators_test.rb +6 -65
- data/test/unit/openurl_creator_test.rb +87 -8
- data/test/unit/result_item_test.rb +1 -11
- data/test/unit/search_engine_base_test.rb +25 -2
- data/test/unit/search_engine_test.rb +16 -0
- data/test/unit/summon_engine_test.rb +3 -0
- data/test/vcr_cassettes/ebscohost/another_dissertation.yml +148 -0
- data/test/vcr_cassettes/ebscohost/dissertation_example.yml +218 -0
- data/test/vcr_cassettes/ebscohost/fulltext_info.yml +1306 -0
- data/test/vcr_cassettes/ebscohost/live_book_example.yml +130 -0
- data/test/vcr_cassettes/ebscohost/live_dissertation.yml +148 -0
- data/test/vcr_cassettes/ebscohost/live_pathological_book_item_example.yml +215 -0
- data/test/vcr_cassettes/google_site/gets_format_string.yml +232 -0
- data/test/vcr_cassettes/max_out_pagination.yml +155 -0
- data/test/vcr_cassettes/worldcat_sru_dc/max_out_pagination.yml +167 -0
- data/test/view/std_item_test.rb +25 -8
- metadata +45 -12
- data/test/unit/result_item_display_test.rb +0 -39
- data/test/unit/worldcat_sru_dc_engine_test.rb +0 -120
@@ -5,6 +5,9 @@
|
|
5
5
|
#
|
6
6
|
# You don't normally create one of these yourself, you get one returned
|
7
7
|
# from Results#pagination
|
8
|
+
#
|
9
|
+
#
|
10
|
+
# <%= paginate @results.pagination %>
|
8
11
|
class BentoSearch::Results::Pagination
|
9
12
|
|
10
13
|
# first arg is results.total_items, second is result
|
@@ -12,9 +15,11 @@ class BentoSearch::Results::Pagination
|
|
12
15
|
#
|
13
16
|
# We don't do the page/start normalization calc here,
|
14
17
|
# we count on them both being passed in, already calculated
|
15
|
-
# by normalize_arguments in SearchResults.
|
16
|
-
# :start, and :per_page
|
18
|
+
# by normalize_arguments in SearchResults. Expects :page, 0-based
|
19
|
+
# :start, and 1-based :per_page to all be passed in in initializer.
|
17
20
|
def initialize(total, normalized_args)
|
21
|
+
normalized_args ||= {} # in some error cases, we end up with nil
|
22
|
+
|
18
23
|
@total_count = total || 0
|
19
24
|
@per_page = normalized_args[:per_page] || 10
|
20
25
|
@current_page = normalized_args[:page] || 1
|
@@ -42,6 +47,7 @@ class BentoSearch::Results::Pagination
|
|
42
47
|
def count_records
|
43
48
|
@total_count
|
44
49
|
end
|
50
|
+
alias count count_records
|
45
51
|
|
46
52
|
def total_pages
|
47
53
|
(@total_count.to_f / @per_page).ceil
|
@@ -49,13 +49,11 @@ module BentoSearch
|
|
49
49
|
# Additional standard configuration keys that are implemented by the bento_search
|
50
50
|
# framework:
|
51
51
|
#
|
52
|
-
# [
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
# item metadata. (Needs more documentation).
|
58
|
-
#
|
52
|
+
# [for_display.decorator]
|
53
|
+
# String name of decorator class that will be applied by #bento_decorate
|
54
|
+
# helper in standard view. See wiki for more info on decorators. Must be
|
55
|
+
# string name, actual class object not supported (to make it easier
|
56
|
+
# to serialize and transport configuration).
|
59
57
|
#
|
60
58
|
# == Implementing a SearchEngine
|
61
59
|
#
|
@@ -143,8 +141,7 @@ module BentoSearch
|
|
143
141
|
# merge in current instance config
|
144
142
|
self.configuration.configure ( aConfiguration )
|
145
143
|
|
146
|
-
# global defaults?
|
147
|
-
self.configuration[:item_decorators] ||= []
|
144
|
+
# global defaults?
|
148
145
|
self.configuration[:for_display] ||= {}
|
149
146
|
|
150
147
|
# check for required keys -- have to be present, and not nil
|
@@ -185,6 +182,9 @@ module BentoSearch
|
|
185
182
|
#
|
186
183
|
# Ask an engine what semantic field names it supports with `engine.semantic_search_keys`
|
187
184
|
#
|
185
|
+
# Unrecognized search fields will be ignored, unless you pass in
|
186
|
+
# :unrecognized_search_field => :raise (or do same in config).
|
187
|
+
#
|
188
188
|
# Ask an engine what sort fields it supports with `engine.sort_keys`. See
|
189
189
|
# list of standard sort keys in I18n file at ./config/locales/en.yml, in
|
190
190
|
# `en.bento_search.sort_keys`.
|
@@ -207,8 +207,7 @@ module BentoSearch
|
|
207
207
|
arguments = normalized_search_arguments(*arguments)
|
208
208
|
|
209
209
|
results = search_implementation(arguments)
|
210
|
-
|
211
|
-
decorate(results)
|
210
|
+
|
212
211
|
|
213
212
|
# standard result metadata
|
214
213
|
results.start = arguments[:start] || 0
|
@@ -220,6 +219,7 @@ module BentoSearch
|
|
220
219
|
results.timing = (Time.now - start_t)
|
221
220
|
|
222
221
|
results.display_configuration = configuration.for_display
|
222
|
+
results.each {|item| item.decorator = configuration.lookup!("for_display.decorator") }
|
223
223
|
|
224
224
|
return results
|
225
225
|
rescue *auto_rescue_exceptions => e
|
@@ -301,14 +301,17 @@ module BentoSearch
|
|
301
301
|
|
302
302
|
# translate semantic_search_field to search_field, or raise if
|
303
303
|
# can't.
|
304
|
-
if (semantic = arguments.delete(:semantic_search_field)) && ! semantic.blank?
|
305
|
-
|
304
|
+
if (semantic = arguments.delete(:semantic_search_field)) && ! semantic.blank?
|
306
305
|
mapped = self.semantic_search_map[semantic.to_s]
|
307
|
-
|
306
|
+
if config_arg(arguments, :unrecognized_search_field) == "raise" && ! mapped
|
308
307
|
raise ArgumentError.new("#{self.class.name} does not know about :semantic_search_field #{semantic}")
|
309
308
|
end
|
310
309
|
arguments[:search_field] = mapped
|
310
|
+
end
|
311
|
+
if config_arg(arguments, :unrecognized_search_field) == "raise" && ! search_keys.include?(arguments[:search_field])
|
312
|
+
raise ArgumentError.new("#{self.class.name} does not know about :search_field #{arguments[:search_field]}")
|
311
313
|
end
|
314
|
+
|
312
315
|
|
313
316
|
return arguments
|
314
317
|
end
|
@@ -328,16 +331,19 @@ module BentoSearch
|
|
328
331
|
|
329
332
|
protected
|
330
333
|
|
331
|
-
#
|
332
|
-
#
|
333
|
-
#
|
334
|
-
def
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
end
|
334
|
+
# get value of an arg that can be supplied in search args OR config,
|
335
|
+
# with search_args over-ridding config. Also normalizes value to_s
|
336
|
+
# (for symbols/strings).
|
337
|
+
def config_arg(arguments, key, default = nil)
|
338
|
+
value = if arguments[key].present?
|
339
|
+
arguments[key]
|
340
|
+
else
|
341
|
+
configuration[key]
|
340
342
|
end
|
343
|
+
|
344
|
+
value = value.to_s if value.kind_of? Symbol
|
345
|
+
|
346
|
+
return value
|
341
347
|
end
|
342
348
|
|
343
349
|
# What exceptions should our #search wrapper rescue and turn
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
require 'nokogiri'
|
2
4
|
|
3
5
|
require 'http_client_patch/include_client'
|
@@ -10,7 +12,41 @@ require 'httpclient'
|
|
10
12
|
#
|
11
13
|
# * profile_id
|
12
14
|
# * profile_password
|
13
|
-
# * databases: ARRAY of ebsco shortcodes of what databases to include in search. If you specify one you don't have access to, you get an error message from ebsco, alas.
|
15
|
+
# * databases: ARRAY of ebsco shortcodes of what databases to include in search. If you specify one you don't have access to, you get an error message from ebsco, alas.
|
16
|
+
#
|
17
|
+
#
|
18
|
+
# == Limits
|
19
|
+
#
|
20
|
+
# While waiting for a future bento_box generalized limit api, this engine
|
21
|
+
# accepts custom search arguments to apply limits:
|
22
|
+
#
|
23
|
+
# [:peer_reviewed_only] Set to boolean true or string 'true', to restrict
|
24
|
+
# results to peer-reviewed only. (Or ask EBSCOHost
|
25
|
+
# api to do so, what we get is what we get).
|
26
|
+
# [:pubyear_start]
|
27
|
+
# [:pubyear_end] Date range limiting, pass in custom search args,
|
28
|
+
# one or both of pubyear_start and pubyear_end
|
29
|
+
# #to_i will be called on it, so can be string.
|
30
|
+
# .search(:query => "foo", :pubyear_start => 2000)
|
31
|
+
#
|
32
|
+
# == Custom response data
|
33
|
+
#
|
34
|
+
# Iff EBSCO API reports that fulltext is available for the hit, then
|
35
|
+
# result.custom_data["fulltext_formats"] will be non-nil, and will be an array of
|
36
|
+
# one or more of EBSCO's internal codes (P=PDF, T=HTML, C=HTML+Images). If
|
37
|
+
# no fulltext is avail according to EBSCO API, result.custom_data["fulltext_formats"]
|
38
|
+
# will be nil.
|
39
|
+
#
|
40
|
+
# #link_is_fulltext also set to true/false
|
41
|
+
#
|
42
|
+
# You can use this to, for instance, hyperlink the displayed title directly
|
43
|
+
# to record on EBSCO if and only if there's fulltext. By writing a custom
|
44
|
+
# decorator. See wiki on decorators.
|
45
|
+
#
|
46
|
+
# == Limitations
|
47
|
+
# We do set language of ResultItems based on what ebsco tells us, but ebsoc
|
48
|
+
# seems to often leave out language or say 'english' for things that are not
|
49
|
+
# (maybe cause abstract is in English?). Config variable to tell us to ignore language?
|
14
50
|
#
|
15
51
|
# == Note on including databases
|
16
52
|
#
|
@@ -59,12 +95,11 @@ require 'httpclient'
|
|
59
95
|
# * DTD of XML Response, hard to interpret but all we've got: http://support.ebsco.com/eit/docs/DTD_EIT_WS_searchResponse.zip
|
60
96
|
#
|
61
97
|
# Hard to find docs page on embedding EBSCO limiters (like peer reviewed only "RV Y") in search query:
|
62
|
-
# http://
|
98
|
+
# http://support.epnet.com/knowledge_base/detail.php?id=5397
|
63
99
|
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
|
67
|
-
# English?). Config variable to tell us to ignore language?
|
100
|
+
# EBSCO searchable support portal has a section for the EIT api we use here:
|
101
|
+
# http://support.epnet.com/knowledge_base/search.php?keyword=&interface_id=1082&document_type=&page_function=search
|
102
|
+
|
68
103
|
class BentoSearch::EbscoHostEngine
|
69
104
|
include BentoSearch::SearchEngine
|
70
105
|
|
@@ -100,6 +135,7 @@ class BentoSearch::EbscoHostEngine
|
|
100
135
|
(fault = xml.at_xpath("./Fault")))
|
101
136
|
|
102
137
|
results.error ||= {}
|
138
|
+
results.error[:api_url] = url
|
103
139
|
results.error[:exception] = exception if exception
|
104
140
|
results.error[:status] = response.status if response
|
105
141
|
|
@@ -126,6 +162,19 @@ class BentoSearch::EbscoHostEngine
|
|
126
162
|
|
127
163
|
end
|
128
164
|
|
165
|
+
# pass in nokogiri record xml for the records/rec node.
|
166
|
+
# Returns nil if NO fulltext is avail on ebsco platform,
|
167
|
+
# non-nil if fulltext is available. Non-nil value will
|
168
|
+
# actually be a non-empty ARRAY of internal EBSCO codes, P=PDF, T=HTML, C=HTML with images.
|
169
|
+
# http://support.epnet.com/knowledge_base/detail.php?topic=996&id=3778&page=1
|
170
|
+
def fulltext_formats(record_xml)
|
171
|
+
fulltext_formats = record_xml.xpath("./header/controlInfo/artinfo/formats/fmt/@type").collect {|n| n.text }
|
172
|
+
|
173
|
+
return nil if fulltext_formats.empty?
|
174
|
+
|
175
|
+
return fulltext_formats
|
176
|
+
end
|
177
|
+
|
129
178
|
|
130
179
|
# Pass in a nokogiri node, return node.text, or nil if
|
131
180
|
# arg was nil or node.text was blank?
|
@@ -144,13 +193,22 @@ class BentoSearch::EbscoHostEngine
|
|
144
193
|
def sniff_format(xml_node)
|
145
194
|
return nil if xml_node.nil?
|
146
195
|
|
147
|
-
|
148
|
-
|
196
|
+
if xml_node.at_xpath("./dissinfo/*")
|
197
|
+
:dissertation
|
198
|
+
elsif xml_node.at_xpath("./jinfo/*") && xml_node.at_xpath("./artinfo/*")
|
149
199
|
"Article"
|
200
|
+
elsif xml_node.at_xpath("./dissinfo/disstl")
|
201
|
+
:dissertation
|
202
|
+
elsif xml_node.at_xpath("./bkinfo") && xml_node.at_xpath("./chapinfo")
|
203
|
+
:book_item
|
204
|
+
elsif xml_node.at_xpath("./bkinfo/btl") && xml_node.at_xpath("./artinfo/tig/atl") &&
|
205
|
+
(text_if_present(xml_node.at_xpath "./bkinfo/btl") != text_if_present(xml_node.at_xpath "./artinfo/tig/atl"))
|
206
|
+
# pathological case of book_item, if it has a bkinfo and an artinfo
|
207
|
+
# but the titles in both sections MATCH, it's just a book. If they're
|
208
|
+
# differnet, it's a book section, bah@
|
209
|
+
:book_item
|
150
210
|
elsif xml_node.at_xpath("./bkinfo/*")
|
151
211
|
"Book"
|
152
|
-
elsif xml_node.at_xpath("./dissinfo/*")
|
153
|
-
:dissertation
|
154
212
|
elsif xml_node.at_xpath("./jinfo/*")
|
155
213
|
:serial
|
156
214
|
else
|
@@ -174,10 +232,15 @@ class BentoSearch::EbscoHostEngine
|
|
174
232
|
components = components.collect {|a| a.titlecase if a}
|
175
233
|
components.uniq! # no need to have the same thing twice
|
176
234
|
|
235
|
+
|
177
236
|
# some hard-coded cases for better user-displayable string, and other
|
178
237
|
# normalization.
|
179
238
|
if ["Academic Journal", "Journal"].include?(components.first) && ["Article", "Journal Article"].include?(components.last)
|
180
239
|
return "Journal Article"
|
240
|
+
elsif components.last == "Book: Monograph"
|
241
|
+
return "Book" # Book: Monograph what??
|
242
|
+
elsif components.first == "Book Article"
|
243
|
+
return "Book Chapter"
|
181
244
|
elsif components.first == "Periodical" && components.length > 1
|
182
245
|
return components.last
|
183
246
|
elsif components.size == 2 && components.first.include?(components.last)
|
@@ -207,7 +270,19 @@ class BentoSearch::EbscoHostEngine
|
|
207
270
|
|
208
271
|
# undocumented but question mark seems to cause a problem for ebsco,
|
209
272
|
# even inside quoted phrases, not sure why.
|
210
|
-
txt.gsub(/[)(\?]/, ' ')
|
273
|
+
txt = txt.gsub(/[)(\?]/, ' ')
|
274
|
+
|
275
|
+
# 'and' and 'or' need to be in phrase quotes to avoid being
|
276
|
+
# interpreted as boolean. For instance, when people just
|
277
|
+
# paste in a title: << A strategy for decreasing anxiety of ICU transfer patients and their families >>
|
278
|
+
# You'd think 'and' as boolean would still work there, but it resulted
|
279
|
+
# in zero hits unless quoted, I dunno. lowercase and uppercase and/or/not
|
280
|
+
# both cause observed weirdness.
|
281
|
+
if ['and', 'or', 'not'].include?( txt.downcase )
|
282
|
+
txt = %Q{"#{txt}"}
|
283
|
+
end
|
284
|
+
|
285
|
+
return txt
|
211
286
|
end
|
212
287
|
|
213
288
|
# Actually turn the user's query into an EBSCO "AND" boolean query,
|
@@ -223,14 +298,12 @@ class BentoSearch::EbscoHostEngine
|
|
223
298
|
ebsco_query_escape(t)
|
224
299
|
end
|
225
300
|
|
226
|
-
|
227
|
-
# make things weird. In phrase quotes they are okay.
|
301
|
+
|
228
302
|
# Remove empty strings. Remove terms that are solely punctuation
|
229
303
|
# without any letters.
|
230
304
|
terms.delete_if do |term|
|
231
305
|
(
|
232
306
|
term.blank? ||
|
233
|
-
["AND", "OR", "NOT"].include?(term) ||
|
234
307
|
term =~ /\A[^[[:alnum:]]]+\Z/
|
235
308
|
)
|
236
309
|
end
|
@@ -251,6 +324,22 @@ class BentoSearch::EbscoHostEngine
|
|
251
324
|
query = "(#{args[:search_field]} #{query})"
|
252
325
|
end
|
253
326
|
|
327
|
+
# peer-reviewed only?
|
328
|
+
if [true, "true"].include? args[:peer_reviewed_only]
|
329
|
+
query += " AND (RV Y)"
|
330
|
+
end
|
331
|
+
|
332
|
+
if args[:pubyear_start] || args[:pubyear_end]
|
333
|
+
from = args[:pubyear_start].to_i
|
334
|
+
from = nil if from == 0
|
335
|
+
|
336
|
+
to = args[:pubyear_end].to_i
|
337
|
+
to = nil if to == 0
|
338
|
+
|
339
|
+
query += " AND (DT #{from}-#{to})"
|
340
|
+
end
|
341
|
+
|
342
|
+
|
254
343
|
url += "&query=#{CGI.escape query}"
|
255
344
|
|
256
345
|
# startrec is 1-based for ebsco, not 0-based like for us.
|
@@ -280,8 +369,33 @@ class BentoSearch::EbscoHostEngine
|
|
280
369
|
item.link = get_link(xml_rec)
|
281
370
|
|
282
371
|
item.issn = text_if_present info.at_xpath("./jinfo/issn")
|
283
|
-
|
284
|
-
|
372
|
+
|
373
|
+
# Dealing with titles is a bit crazy, while articles usually have atitles and
|
374
|
+
# jtitles, sometimes they have a btitle instead. A book will usually have
|
375
|
+
# both btitle and atitle, but sometimes just atitle. Book chapter, oh boy.
|
376
|
+
|
377
|
+
jtitle = text_if_present(info.at_xpath("./jinfo/jtl"))
|
378
|
+
btitle = text_if_present info.at_xpath("./bkinfo/btl")
|
379
|
+
atitle = text_if_present info.at_xpath("./artinfo/tig/atl")
|
380
|
+
|
381
|
+
if jtitle && atitle
|
382
|
+
item.title = atitle
|
383
|
+
item.source_title = jtitle
|
384
|
+
elsif btitle && atitle && atitle != btitle
|
385
|
+
# for a book, sometimes there's an atitle block and a btitle block
|
386
|
+
# when they're identical, this ain't a book section, it's a book.
|
387
|
+
item.title = atitle
|
388
|
+
item.source_title = btitle
|
389
|
+
else
|
390
|
+
item.title = atitle || btitle
|
391
|
+
end
|
392
|
+
# EBSCO sometimes has crazy long titles, truncate em.
|
393
|
+
if item.title.present?
|
394
|
+
item.title = text_helper.truncate(item.title, :length => 200, :separator => ' ', :omission => '…')
|
395
|
+
end
|
396
|
+
|
397
|
+
|
398
|
+
|
285
399
|
item.publisher = text_if_present info.at_xpath("./pubinfo/pub")
|
286
400
|
# if no publisher, but a dissertation institution, use that
|
287
401
|
# as publisher.
|
@@ -294,11 +408,22 @@ class BentoSearch::EbscoHostEngine
|
|
294
408
|
item.isbn = text_if_present info.at_xpath("./bkinfo/isbn")
|
295
409
|
|
296
410
|
item.year = text_if_present info.at_xpath("./pubinfo/dt/@year")
|
411
|
+
# fill in complete publication_date too only if we've got it.
|
412
|
+
if (item.year &&
|
413
|
+
(month = text_if_present info.at_xpath("./pubinfo/dt/@month")) &&
|
414
|
+
(day = text_if_present info.at_xpath("./pubinfo/dt/@day"))
|
415
|
+
)
|
416
|
+
if (item.year.to_i != 0 && month.to_i != 0 && day.to_i != 0)
|
417
|
+
item.publication_date = Date.new(item.year.to_i, month.to_i, day.to_i)
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
297
421
|
item.volume = text_if_present info.at_xpath("./pubinfo/vid")
|
298
422
|
item.issue = text_if_present info.at_xpath("./pubinfo/iid")
|
299
423
|
|
300
|
-
|
301
|
-
|
424
|
+
|
425
|
+
|
426
|
+
|
302
427
|
item.start_page = text_if_present info.at_xpath("./artinfo/ppf")
|
303
428
|
|
304
429
|
item.doi = text_if_present info.at_xpath("./artinfo/ui[@type='doi']")
|
@@ -315,15 +440,21 @@ class BentoSearch::EbscoHostEngine
|
|
315
440
|
item.authors << a
|
316
441
|
end
|
317
442
|
|
318
|
-
|
319
|
-
item.
|
320
|
-
item.format_str = sniff_format_str info
|
443
|
+
item.format = sniff_format info
|
444
|
+
item.format_str = sniff_format_str info
|
321
445
|
|
322
446
|
# Totally unreliable, seems to report english for everything? Maybe
|
323
|
-
# because abstracts are in english? Nevertheless we include for now.
|
447
|
+
# because abstracts are in english? Nevertheless we include for now.
|
324
448
|
item.language_code = text_if_present info.at_xpath("./language/@code")
|
325
|
-
|
326
|
-
|
449
|
+
# why does EBSCO return 'undetermined' sometimes? That might as well be
|
450
|
+
# not there, bah.
|
451
|
+
item.language_code = nil if item.language_code == "und"
|
452
|
+
|
453
|
+
# array of custom ebsco codes (or nil) for fulltext formats avail.
|
454
|
+
item.custom_data["fulltext_formats"] = fulltext_formats xml_rec
|
455
|
+
# if any fulltext format, mark present
|
456
|
+
item.link_is_fulltext = item.custom_data["fulltext_formats"].present?
|
457
|
+
|
327
458
|
return item
|
328
459
|
end
|
329
460
|
|
@@ -343,6 +474,10 @@ class BentoSearch::EbscoHostEngine
|
|
343
474
|
return noko
|
344
475
|
end
|
345
476
|
|
477
|
+
def public_settable_search_args
|
478
|
+
super + [:peer_reviewed_only, :pubyear_start, :pubyear_end]
|
479
|
+
end
|
480
|
+
|
346
481
|
# David Walker says pretty much only relevance and date are realiable
|
347
482
|
# in EBSCOhost cross-search.
|
348
483
|
def sort_definitions
|
@@ -351,9 +486,10 @@ class BentoSearch::EbscoHostEngine
|
|
351
486
|
"date_desc" => {:implementation => "date"}
|
352
487
|
}
|
353
488
|
end
|
354
|
-
|
489
|
+
|
355
490
|
def search_field_definitions
|
356
491
|
{
|
492
|
+
nil => {:semantic => :general},
|
357
493
|
"AU" => {:semantic => :author},
|
358
494
|
"TI" => {:semantic => :title},
|
359
495
|
"SU" => {:semantic => :subject},
|
@@ -21,11 +21,6 @@ require 'http_client_patch/include_client'
|
|
21
21
|
# If turned on, you may get <b class="bento_search_highlight"> tags
|
22
22
|
# in title and abstract output if it's on, marked html_safe.
|
23
23
|
#
|
24
|
-
# If highlighting is on, since the abstract will be marked html safe, the
|
25
|
-
# view layer won't be able to safely truncate it. In fact, it's very hard
|
26
|
-
# to do here too, but we do it anyway, by default to approx configuration
|
27
|
-
# truncate_highlighted num of chars (default 280). Set to nil if you don't
|
28
|
-
# want this.
|
29
24
|
#
|
30
25
|
# == Linking
|
31
26
|
#
|
@@ -394,45 +389,7 @@ class BentoSearch::EdsEngine
|
|
394
389
|
else substr.html_safe
|
395
390
|
end
|
396
391
|
end
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
# Crazy ass method to truncate without getting in the middle of our
|
403
|
-
# html tags. This is wacky hacky, yeah.
|
404
|
-
if configuration.truncate_highlighted
|
405
|
-
remainingLength = configuration.truncate_highlighted
|
406
|
-
in_tag = false
|
407
|
-
elipses_added = false
|
408
|
-
|
409
|
-
truncated_parts = []
|
410
|
-
parts.each do |substr|
|
411
|
-
if remainingLength <=0 && ! in_tag
|
412
|
-
truncated_parts << "..."
|
413
|
-
break
|
414
|
-
end
|
415
392
|
|
416
|
-
if substr =~ /^<b.*\>$/
|
417
|
-
truncated_parts << substr
|
418
|
-
in_tag = true
|
419
|
-
elsif substr == "</b>"
|
420
|
-
truncated_parts << substr
|
421
|
-
in_tag = false
|
422
|
-
elsif ((remainingLength - substr.length) > 0) || in_tag
|
423
|
-
truncated_parts << substr
|
424
|
-
else
|
425
|
-
truncated_parts << helper.truncate(substr, :length => remainingLength, :separator => ' ')
|
426
|
-
break
|
427
|
-
end
|
428
|
-
|
429
|
-
remainingLength = remainingLength - substr.length
|
430
|
-
end
|
431
|
-
|
432
|
-
parts = truncated_parts
|
433
|
-
end
|
434
|
-
|
435
|
-
|
436
393
|
return helper.safe_join(parts, '')
|
437
394
|
end
|
438
395
|
|
@@ -552,7 +509,7 @@ class BentoSearch::EdsEngine
|
|
552
509
|
|
553
510
|
def search_field_definitions
|
554
511
|
{
|
555
|
-
"TX" => {:semantic => :
|
512
|
+
"TX" => {:semantic => :general},
|
556
513
|
"AU" => {:semantic => :author},
|
557
514
|
"TI" => {:semantic => :title},
|
558
515
|
"SU" => {:semantic => :subject},
|