umlaut 4.1.0.pre.alpha.1 → 4.1.0

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: bbf3ca9cc7766fb7cf897a6da4e127686516c412
4
- data.tar.gz: b33c2a561baabf93c5cf69b6ee6bb10fe870087f
3
+ metadata.gz: 10ee00671d4ada36a612ab886c0dba3169b0c5f5
4
+ data.tar.gz: c13eccc534870dbcd6b35335adb3ab6edd3d8acd
5
5
  SHA512:
6
- metadata.gz: 362c88e0352990f39cfde7a7055880f950b52a65504e4d52a8164641f9ef58c203aa6e7c9c40b720aaa3c496a9750f5e2f38ca589a3196b76fd8f9fb78a8270c
7
- data.tar.gz: b4328ca50474c88d2fb0561ca171b2912d2e29644c3de54e1a68c368dd26ffd53c6cf895fc1755e805bce5fbf3418ded11a110006ac3978230292aba31ce4fac
6
+ metadata.gz: bd230f38e80c13e192e0c91001bc38a3628c9908eef08b9c5d035883c5f911d910f147a679283ed3c6bfac9db5a6bb4fa59e616ff6de7b66189030313d339c18
7
+ data.tar.gz: df56e4a11ea2955b53463d9902c7a889b4a6860c7dd33a49dda259338e87c9d88dd83c328b51ef6ed1cbdbd2c407ce07aebfd6d974db63967361bb7a9a74ebdd
data/README.md CHANGED
@@ -63,6 +63,7 @@ in your application's Gemfile in order to get the described functionality.
63
63
  | Add on | Description |
64
64
  |:---|:---|
65
65
  | [`umlaut-primo`](https://github.com/team-umlaut/umlaut-primo) | Umlaut services to provide full text service responses, holdings, etc. from the Primo discovery solution. |
66
+ | [`umlaut_borrow_direct`](https://github.com/team-umlaut/umlaut_borrow_direct/tree/master) | Links and embedded availability from BorrowDirect consortial borrowing service |
66
67
 
67
68
 
68
69
  ## Developing
data/Rakefile CHANGED
@@ -20,7 +20,8 @@ RDoc::Task.new(:rdoc) do |rdoc|
20
20
  rdoc.rdoc_files.include('lib/**/*.rb')
21
21
  end
22
22
 
23
-
23
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
24
25
 
25
26
  Bundler::GemHelper.install_tasks
26
27
 
@@ -33,7 +34,4 @@ Rake::TestTask.new(:test) do |t|
33
34
  t.verbose = false
34
35
  end
35
36
 
36
- require 'single_test'
37
- SingleTest.load_tasks
38
-
39
37
  task :default => :test
@@ -1,4 +1,12 @@
1
- /* update_html.js: Provide functions to update content on page with background responses from Umlaut. Used by Umlaut itself, as well as by third party callers.*/
1
+ /* update_html.js:
2
+ * Provide functions to update content on page with background responses from Umlaut.
3
+ * Used by Umlaut itself, as well as by third party callers.
4
+ *
5
+ * This is compiled into a standalone top-level JS file, for src'ing by third
6
+ * party callers.
7
+ *
8
+ * More information on use at https://github.com/team-umlaut/umlaut/wiki/JQuery-Content-Utility
9
+ */
2
10
  (function($) {
3
11
 
4
12
  function SectionTarget(config) {
@@ -6,11 +14,14 @@
6
14
  $.extend(this, config);
7
15
 
8
16
  //Defaults
9
- if (this.selector == undefined)
17
+ if (typeof(this.selector) == 'undefined')
10
18
  this.selector = "#" + this.umlaut_section_id;
11
- if (this.position == undefined)
19
+ if (typeof(this.position) == 'undefined')
12
20
  this.position = "html";
13
-
21
+ // Container must be a JQuery object, if it's not
22
+ // passed in, use $(document)
23
+ if (typeof(this.container) == 'undefined')
24
+ this.container = $(document); // default container is document
14
25
  }
15
26
  //Callback default to no-op function please.
16
27
  var noop = function() {};
@@ -19,53 +30,100 @@
19
30
  SectionTarget.prototype.complete = noop;
20
31
 
21
32
  SectionTarget.prototype.ensure_placement_destination = function() {
22
- if ( this.selector == undefined) {
33
+ if ( typeof(this.selector) == 'undefined') {
23
34
  return null;
24
35
  }
25
36
 
26
37
  //Already have it cached?
27
38
  if ( this.host_div_element ) {
28
39
  return this.host_div_element;
29
- }
40
+ }
30
41
 
31
- var new_div = $('<div class="umlaut" style="display:none"></div>');
42
+ // Create an empty div to hold our content
43
+ var new_div = $('<div class="umlaut" style="display:none"></div>');
44
+
32
45
  // Find the first thing matched by selector, and call the
33
- // method specified in "action" string on it, giving it our
46
+ // method specified in "position" string on it, giving it our
34
47
  // HTML to replace. This works because our actions are
35
48
  // all arguments that will take one method: html, before, after, append,
36
49
  // prepend.
37
- $(this.selector).eq(0)[ this.position ]( new_div );
50
+ this.container.find(this.selector).eq(0)[ this.position ]( new_div );
38
51
 
39
52
  //Cache for later
40
53
  this.host_div_element = new_div;
41
54
  return this.host_div_element;
42
55
  };
43
-
44
56
 
45
57
  // Define an object constructor on the global window object
46
58
  // For our UmlautHtmlUpdater object.
47
59
  //
48
- // Third 'locale' arg is optional locale string eg 'en', 'de'
60
+ // You need to pass the Umlaut Base URL, as well as an OpenURL kev context
61
+ // object. There are additional optional parameters.
62
+ //
63
+ // There are two argument formats you can call `new HTMLUpdater` with.
64
+ // Positional allows you to pass umlaut base and OpenURL:
65
+ // var updater = new Umlaut.HtmlUpdater("http://umlaut.example.edu", "au=Smith&ti=Book")
66
+ //
67
+ // Or named argument style allows you to pass additional parameters,
68
+ // including locale and container.
69
+ //
70
+ // var updater = new Umlaut.HtmlUpdater({
71
+ // umlaut_base: "http://umlaut.example.edu",
72
+ // context_object: "au=Smith&ti=Book",
73
+ // locale: "de",
74
+ // container: "#selector"
75
+ // });
76
+ //
77
+ //
78
+ //
79
+ // The optional 'locale' arg is a locale string eg 'en', 'de'
80
+ //
81
+ // The optional 'container' argument is a selector, DOM element, OR
82
+ // jQuery object. The container limits the updater's content
83
+ // replacements (controlled by selectors on individual sections) to within
84
+ // the container given.
49
85
  //
50
86
  // Note this object is used by external sites as part of the JQuery updater
51
87
  // javascript API. This is API, which has to be callable by non-Umlaut sites.
52
88
  // Try not to change the method signature in incompatible ways.
53
- function HtmlUpdater(umlaut_base, context_object, locale) {
54
- if (context_object == undefined)
55
- context_object = "";
89
+ function HtmlUpdater(first_arg, second_arg, third_arg) {
90
+ if (typeof(first_arg) == "object") {
91
+ // Simply merge arguments object as properties on ourselves.
92
+ $.extend(this, first_arg);
93
+ } else {
94
+ // positional args
95
+ this.umlaut_base = first_arg;
96
+ this.context_object = second_arg;
97
+ this.locale = third_arg;
98
+ }
99
+
100
+ // Argument checking
101
+ if (typeof(this.umlaut_base) == "undefined") {
102
+ throw new Error("new Umlaut.HtmlUpdater: missing umlaut_base (String) argument");
103
+ }
104
+ if (typeof(this.context_object) == "undefined") {
105
+ throw new Error("new Umlaut.HtmlUpdater: missing context_object (String) argument");
106
+ }
107
+
108
+
56
109
 
57
110
  // Remove query string (if present)
58
- umlaut_base = umlaut_base.replace(/\?.*$/, '')
111
+ this.umlaut_base = this.umlaut_base.replace(/\?.*$/, '')
59
112
  // Remove trailing slash
60
- umlaut_base = umlaut_base.replace(/\/$/,'');
61
- this.umlaut_uri = umlaut_base + '/resolve/partial_html_sections?umlaut.response_format=json&' + context_object;
62
- if (locale)
63
- this.umlaut_uri += "&umlaut.locale=" + locale;
113
+ this.umlaut_base = this.umlaut_base.replace(/\/$/,'');
114
+ this.umlaut_uri = this.umlaut_base + '/resolve/partial_html_sections?umlaut.response_format=json&' + this.context_object;
115
+ if (this.locale)
116
+ this.umlaut_uri += "&umlaut.locale=" + this.locale;
64
117
 
65
118
  this.section_targets = [];
66
119
 
67
120
  this.add_section_target = function(config) {
68
- this.section_targets.push( new SectionTarget(config) );
121
+ var target = new SectionTarget(config);
122
+ if (typeof(this.container) !== "undefined") {
123
+ // Turn it into a JQuery object if it wasn't already.
124
+ target.container = $(this.container);
125
+ }
126
+ this.section_targets.push( target );
69
127
  };
70
128
 
71
129
  //default no-op call-backs
@@ -99,11 +157,11 @@
99
157
 
100
158
  var umlaut_html_section = myself.find_umlaut_response_section(umlaut_response, section_target.umlaut_section_id);
101
159
 
102
- if (umlaut_html_section == undefined) {
160
+ if (typeof(umlaut_html_section) == 'undefined') {
103
161
  continue;
104
162
  }
105
163
  var count = null;
106
- if (typeof umlaut_html_section.response_count != "undefined") {
164
+ if (typeof(umlaut_html_section.response_count) != "undefined") {
107
165
  count = parseInt(umlaut_html_section.response_count.value);
108
166
  }
109
167
  var existing_element = section_target.ensure_placement_destination();
@@ -162,7 +220,7 @@
162
220
  };
163
221
 
164
222
  //Put it in a global object, leave space for other things in "Umlaut" later.
165
- if (window.Umlaut == undefined)
223
+ if (typeof(window.Umlaut) == 'undefined')
166
224
  window.Umlaut = new Object();
167
225
  window.Umlaut.HtmlUpdater = HtmlUpdater;
168
226
 
@@ -98,11 +98,13 @@ class SearchController < UmlautController
98
98
  # If we narrowed down to one result redirect
99
99
  # to resolve action.
100
100
  redirect_to( url_for_with_co({:controller => 'resolve'}, @display_results[0]) )
101
- elsif (@display_results.length == 0)
102
- # 0 hits, do it too.
101
+ elsif (@display_results.length == 0) && (umlaut_config.lookup!("search.display_zero_hit_results") != true)
102
+ # If we have 0 hits, also redirect to resolve, unless config tells
103
+ # us not to.
103
104
  redirect_to( url_for_with_co({:controller => 'resolve'}, @search_context_object) )
104
105
  end
105
- @page_title = 'Journal titles that '
106
+
107
+ @page_title = @display_results.length > 0 ? 'Journal titles that ' : 'No journal titles found that '
106
108
  @page_title +=
107
109
  (params["umlaut.title_search_type"] == "begins") ?
108
110
  'begin with ' : 'contain '
@@ -15,7 +15,68 @@ module UmlautConfigurable
15
15
  helper_method :umlaut_config
16
16
  self.umlaut_config = Confstruct::Configuration.new
17
17
  end
18
-
18
+
19
+ # Used for `resolve_sections` config, like an Array but
20
+ # we add a some custom methods into the resolve_sections array,
21
+ # insert_section, remove_section. With a sub-class.
22
+ class ResolveSectionsArray < Array
23
+ # Deprecated. This was a silly confusing way to do this.
24
+ # See #remove and #insert below instead.
25
+ def ensure_order!(first, second)
26
+ $stderr.puts "resolve_sections.ensure_order! is deprecated, please see resolve_sections.remove and resolve_sections.insert"
27
+
28
+ list = self
29
+
30
+ index1 = list.index {|s| s[:div_id].to_s == first.to_s}
31
+ index2 = list.index {|s| s[:div_id].to_s == second.to_s}
32
+
33
+ (list[index1], list[index2] = list[index2], list[index1]) if index1 && index2 && (index1 > index2)
34
+
35
+ list
36
+ end
37
+
38
+ # Insert a section_config hash before or after an existing
39
+ # section, by the existing section's div_id
40
+ #
41
+ # resolve_sections.insert_section({:div_id => "new"}, :after => "fulltext")
42
+ # resolve_sections.insert_section( resolve_sections.remove_section("document_deliver"), :before => "fulltext")
43
+ def insert_section(section_config, options = {})
44
+ list = self
45
+
46
+ if options[:before]
47
+ i = (list.find_index {|s| s[:div_id].to_s == options[:before].to_s}) || 0
48
+ list.insert(i, section_config)
49
+ elsif options[:after]
50
+ i = (list.find_index {|s| s[:div_id].to_s == options[:after].to_s}) || (list.length - 1)
51
+ list.insert(i + 1, section_config)
52
+ else
53
+ # just add at end of list
54
+ list << section_config
55
+ end
56
+ end
57
+
58
+ # Remove a configuration block with a certain div_id from the configuration entirely,
59
+ # returning the removed configuration block (or nil if none exists).
60
+ # You can re-insert it with #insert if you like.
61
+ def remove_section(div_id)
62
+ list = self
63
+ i = list.find_index {|s| s[:div_id].to_s == div_id.to_s}
64
+ return list.delete_at(i) if i
65
+ end
66
+
67
+ # Make deep_dup work
68
+ def deep_dup
69
+ self.class.new.concat super
70
+ end
71
+
72
+ # Make map work returning same class, to avoid breaking Hashie::Mash.
73
+ # Bah, this is a mess, yep.
74
+ def map(*args, &block)
75
+ self.class.new.concat super
76
+ end
77
+ alias_method :collect, :map
78
+
79
+ end
19
80
 
20
81
 
21
82
 
@@ -111,12 +172,12 @@ module UmlautConfigurable
111
172
 
112
173
  # How many seconds between updates of the background updater for background
113
174
  # services?
114
- poll_wait_seconds 2.2
175
+ poll_wait_seconds 2.0
115
176
  # The FIRST AJAX callback for bg tasks should be much quicker. So we
116
177
  # get any bg tasks that executed nearly instantaneously, and on page
117
178
  # refresh when bg is really all loaded on back-end, but still needs JS to
118
179
  # fetch it.
119
- initial_poll_wait_seconds 0.300
180
+ initial_poll_wait_seconds 0.250
120
181
 
121
182
  # if a background service hasn't returned in this many seconds, consider
122
183
  # it failed. (May actually be slow, more likely raised an exception and
@@ -229,59 +290,11 @@ module UmlautConfigurable
229
290
  #
230
291
  # Look in comments at top of SectionRenderer class for what the keys
231
292
  # in each entry mean.
232
-
233
-
234
- # We add a custom method into the resolve_sections array,
235
- # ensure_order!.
236
- resolve_sections [].extend Module.new do
237
-
238
- # Deprecated. This was a silly confusing way to do this.
239
- # See #remove and #insert below instead.
240
- def self.ensure_order!(first, second)
241
- $stderr.puts "resolve_sections.ensure_order! is deprecated, please see resolve_sections.remove and resolve_sections.insert"
242
-
243
- list = self
244
-
245
- index1 = list.index {|s| s[:div_id].to_s == first.to_s}
246
- index2 = list.index {|s| s[:div_id].to_s == second.to_s}
247
-
248
- (list[index1], list[index2] = list[index2], list[index1]) if index1 && index2 && (index1 > index2)
249
-
250
- list
251
- end
252
-
253
- # Insert a section_config hash before or after an existing
254
- # section, by the existing section's div_id
255
- #
256
- # resolve_sections.insert_section({:div_id => "new"}, :after => "fulltext")
257
- # resolve_sections.insert_section( resolve_sections.remove_section("document_deliver"), :before => "fulltext")
258
- def self.insert_section(section_config, options = {})
259
- list = self
260
-
261
- if options[:before]
262
- i = (list.find_index {|s| s[:div_id].to_s == options[:before].to_s}) || 0
263
- list.insert(i, section_config)
264
- elsif options[:after]
265
- i = (list.find_index {|s| s[:div_id].to_s == options[:after].to_s}) || (list.length - 1)
266
- list.insert(i + 1, section_config)
267
- else
268
- # just add at end of list
269
- list << section_config
270
- end
271
- end
272
-
273
- # Remove a configuration block with a certain div_id from the configuration entirely,
274
- # returning the removed configuration block (or nil if none exists).
275
- # You can re-insert it with #insert if you like.
276
- def self.remove_section(div_id)
277
- list = self
278
- i = list.find_index {|s| s[:div_id].to_s == div_id.to_s}
279
- return list.delete_at(i) if i
280
- end
281
-
282
- end
283
-
284
-
293
+
294
+ # ResolveSectionsArray is like an Array, but with
295
+ # some additional methods making it easier to do common
296
+ # configuration tasks.
297
+ resolve_sections ResolveSectionsArray.new
285
298
 
286
299
  ##########
287
300
  #
@@ -412,6 +425,7 @@ module UmlautConfigurable
412
425
  end
413
426
 
414
427
  end
428
+
415
429
  end
416
430
 
417
431
 
@@ -90,6 +90,12 @@ class UmlautController < ApplicationController
90
90
 
91
91
  # can set to "_blank" etc.
92
92
  # result_link_target nil
93
+
94
+ # On 0 hits from search screen, ordinarily we redirect to resolve
95
+ # screen becuase Resolve might be able to provide other useful
96
+ # services such as ILL or backed by other KB's. But to instead
97
+ # display a "no results" page, set:
98
+ # display_zero_hit_results true
93
99
  end
94
100
 
95
101
  # config only relevant to SFX use
@@ -229,11 +229,11 @@ module ResolveHelper
229
229
  # action.
230
230
  def config_resolve_sections
231
231
  unless defined? @_config_resolve_sections
232
- @_config_resolve_sections = umlaut_config.lookup!("resolve_sections", [])
232
+ @_config_resolve_sections = umlaut_config.lookup!("resolve_sections", UmlautConfigurable::ResolveSectionsArray.new)
233
233
 
234
234
  umlaut_config.lookup!("resolve_sections_filter", []).each do |reorder_proc|
235
- # clone it, so we aren't reordering the original
236
- @_config_resolve_sections = @_config_resolve_sections.clone
235
+ # deep dup it, so we aren't reordering the original
236
+ @_config_resolve_sections = @_config_resolve_sections.deep_dup
237
237
  reorder_proc.call(@user_request, @_config_resolve_sections)
238
238
  end
239
239
  end
@@ -251,7 +251,7 @@ module MetadataHelper
251
251
  # and such.
252
252
  def get_isbn(rft)
253
253
  isbn = get_identifier(:urn, "isbn", rft)
254
- isbn = isbn.gsub(/[^\dX-]/, '') if isbn
254
+ isbn = isbn.gsub(/[^\dX]/, '') if isbn
255
255
  return nil if isbn.blank?
256
256
  return isbn
257
257
  end
@@ -151,7 +151,11 @@ class Referent < ActiveRecord::Base
151
151
 
152
152
  rft.metadata.each { | key, value |
153
153
  next unless value.present?
154
- build_referent_value( key, value)
154
+ # Sometimes value is an array, for DC for instance. Do the best we
155
+ # can.
156
+ Array(value).each do |v|
157
+ build_referent_value( key, v)
158
+ end
155
159
  }
156
160
  end
157
161
 
@@ -202,9 +202,12 @@ class Blacklight < Service
202
202
 
203
203
  # Also need to use appropriate 'container' title if avail, not
204
204
  # article title.
205
- title = request.referent['jtitle']
206
- title = request.referent['btitle'] if title.blank?
207
- title = request.referent['title'] if title.blank?
205
+ metadata = request.referent.metadata
206
+ title = metadata['jtitle']
207
+ title = metadata['btitle'] if title.blank?
208
+ title = metadata['title'] if title.blank?
209
+ # remove sub-title for better search
210
+ title.gsub!(/\:.*\Z/, '') if title
208
211
 
209
212
  author = get_top_level_creator(request.referent)
210
213
  return nil unless title && (author || (@bl_fields["serials_limit_clause"] && title_is_serial?(request.referent)))
@@ -36,12 +36,21 @@
36
36
  # relationships, set to empty array [] to eliminate defaults.
37
37
  # sfx_timeout: in seconds, for both open/read timeout value for SFX connection.
38
38
  # Defaults to 8.
39
+ # boost_targets: ARRAY of STRINGS containing SFX target names in the form of
40
+ # "HIGHWIRE_PRESS_JOURNALS". Any target names listed here will be floated to
41
+ # the top of the full-text results list. You can end your boosted target
42
+ # in a "*" to wildcard: "EBSCOHOST_*".
43
+ # sink_targets: ARRAY of STRINGS containing SFX target names in the form of
44
+ # "HIGHWIRE_PRESS_JOURNALS". Any target names listed here will be floated to
45
+ # the bottom of the full-text results list. You an end your sunk target
46
+ # in a "*" to wildcard: "EBSCOHOST_*".
39
47
  # roll_up_prefixes: ARRAY of STRINGs, prefixes like "EBSCOHOST_". If multiple
40
48
  # targets sharing one of the specified prefixes are supplied from SFX,
41
49
  # they will be "rolled up" and collapsed, just the first one included
42
50
  # in response. For TITLE-LEVEL (rather than article-level) requests,
43
51
  # the roll-up algorithm is sensitive to COVERAGES, and will only suppress
44
52
  # targets that have coverages included in remaining non-suppressed targets.
53
+ #
45
54
  class Sfx < Service
46
55
  require 'uri'
47
56
  require 'htmlentities'
@@ -232,6 +241,7 @@ class Sfx < Service
232
241
 
233
242
  # For each target delivered by SFX
234
243
  sfx_obj.search("./ctx_obj_targets/target").each_with_index do|target, target_index|
244
+
235
245
  response_data = {}
236
246
 
237
247
  # First check @extra_targets_of_interest
@@ -311,7 +321,7 @@ class Sfx < Service
311
321
  next
312
322
  end
313
323
 
314
- related_note = "This version provided from related title: <em>" + CGI.unescapeHTML( title ) + "</em>.\n"
324
+ related_note = "May be available under related title: <em>" + CGI.unescapeHTML( title ) + "</em>.\n"
315
325
  end
316
326
 
317
327
  if ( sfx_service_type == 'getDocumentDelivery' )
@@ -377,6 +387,8 @@ class Sfx < Service
377
387
  end
378
388
 
379
389
  if response_queue["fulltext"].present?
390
+ response_queue["fulltext"] = sort_sunk_responses(response_queue["fulltext"])
391
+ response_queue["fulltext"] = sort_boosted_responses(response_queue["fulltext"])
380
392
  response_queue["fulltext"] = roll_up_responses(response_queue["fulltext"], :coverage_sensitive => request.title_level_citation? )
381
393
  end
382
394
 
@@ -517,6 +529,45 @@ class Sfx < Service
517
529
  return list
518
530
  end
519
531
 
532
+ def sort_boosted_responses(list)
533
+ return list unless @boost_targets.present?
534
+
535
+ preferred = []
536
+ other_targets = list
537
+
538
+ @boost_targets.each do |spec|
539
+ (picked, other_targets) = other_targets.partition do |a|
540
+ if spec.end_with?("*")
541
+ a[:sfx_target_name] && a[:sfx_target_name].start_with?(spec[0..-2])
542
+ else
543
+ spec == a[:sfx_target_name]
544
+ end
545
+ end
546
+
547
+ preferred.concat picked
548
+ end
549
+
550
+ return preferred + other_targets
551
+ end
552
+
553
+ def sort_sunk_responses(list)
554
+ return list unless @sink_targets.present?
555
+
556
+ sunk = []
557
+ other_targets = list
558
+ @sink_targets.each do |spec|
559
+ (picked, other_targets) = other_targets.partition do |a|
560
+ if spec.end_with?("*")
561
+ a[:sfx_target_name] && a[:sfx_target_name].start_with?(spec[0..-2])
562
+ else
563
+ spec == a[:sfx_target_name]
564
+ end
565
+ end
566
+ sunk.concat picked
567
+ end
568
+
569
+ return other_targets + sunk
570
+ end
520
571
 
521
572
  def sfx_click_passthrough
522
573
  # From config, or default to false.
@@ -699,12 +750,27 @@ class Sfx < Service
699
750
  end
700
751
 
701
752
 
753
+
754
+ # Don't overwrite a title with a btitle
755
+ unless (metadata['btitle'].present? || metadata['title'].present?)
756
+ request.referent.enhance_referent("title", sfx_metadata["title"]) if sfx_metadata["title"].present?
757
+ request.referent.enhance_referent("btitle", sfx_metadata["btitle"]) if sfx_metadata["btitle"].present?
758
+ end
759
+
760
+
761
+
702
762
  # The rest, we write only if blank, we don't over-write
703
763
  sfx_metadata.each do |key, value|
704
- if (metadata[key].blank?)
764
+ next if value.blank?
705
765
 
706
- # watch out for SFX's weird array values.
707
- request.referent.enhance_referent(key, value)
766
+ # Skip certain internal SFX stuff we don't want to add
767
+ if %w{title btitle isbn_10 isbn_13 eisbn_10 eisbn_13 object_type}.include? key
768
+ next
769
+ end
770
+
771
+ # Don't overwrite a currently existing one
772
+ if (metadata[key].blank?)
773
+ request.referent.enhance_referent(key, value)
708
774
  end
709
775
  end
710
776
  end
@@ -726,5 +792,4 @@ class Sfx < Service
726
792
  return display
727
793
  end
728
794
 
729
- end
730
-
795
+ end
@@ -34,7 +34,7 @@
34
34
  <% unless @hits == 0%>
35
35
  <h3><%= t( 'umlaut.search.showing_results', start: @start_result_num, until: @end_result_num, total: @hits) %></h3>
36
36
  <% end %>
37
- <% if params["rft.jtitle"] %>
37
+ <% if params["rft.jtitle"] && (@display_results.size > 0) %>
38
38
  <div class="note"><em><strong><%= t 'umlaut.search.note' %>:</strong> <%= t 'umlaut.search.other_titles_might' %> </em></div>
39
39
  <% end %>
40
40
  <div class='umlaut-pagination pagination'>
@@ -1,5 +1,5 @@
1
1
  module Umlaut
2
- VERSION = "4.1.0-alpha.1"
2
+ VERSION = "4.1.0"
3
3
 
4
4
  # This is used in Umlaut's .gemspec for generating the gem,
5
5
  # and is also used in the umlaut app generator to make sure
metadata CHANGED
@@ -1,286 +1,278 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: umlaut
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.0.pre.alpha.1
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Rochkind, et al
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-26 00:00:00.000000000 Z
11
+ date: 2015-04-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
15
- version_requirements: !ruby/object:Gem::Requirement
15
+ requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 3.2.12
20
- - - <
20
+ - - "<"
21
21
  - !ruby/object:Gem::Version
22
22
  version: 4.3.0
23
- requirement: !ruby/object:Gem::Requirement
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
24
26
  requirements:
25
- - - '>='
27
+ - - ">="
26
28
  - !ruby/object:Gem::Version
27
29
  version: 3.2.12
28
- - - <
30
+ - - "<"
29
31
  - !ruby/object:Gem::Version
30
32
  version: 4.3.0
31
- prerelease: false
32
- type: :runtime
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: jquery-rails
35
- version_requirements: !ruby/object:Gem::Requirement
35
+ requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - '>='
37
+ - - ">="
38
38
  - !ruby/object:Gem::Version
39
39
  version: '0'
40
- requirement: !ruby/object:Gem::Requirement
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
41
43
  requirements:
42
- - - '>='
44
+ - - ">="
43
45
  - !ruby/object:Gem::Version
44
46
  version: '0'
45
- prerelease: false
46
- type: :runtime
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: nokogiri
49
- version_requirements: !ruby/object:Gem::Requirement
49
+ requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - '>='
51
+ - - ">="
52
52
  - !ruby/object:Gem::Version
53
53
  version: 1.5.3
54
- requirement: !ruby/object:Gem::Requirement
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
55
57
  requirements:
56
- - - '>='
58
+ - - ">="
57
59
  - !ruby/object:Gem::Version
58
60
  version: 1.5.3
59
- prerelease: false
60
- type: :runtime
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: openurl
63
- version_requirements: !ruby/object:Gem::Requirement
63
+ requirement: !ruby/object:Gem::Requirement
64
64
  requirements:
65
- - - ~>
65
+ - - "~>"
66
66
  - !ruby/object:Gem::Version
67
67
  version: '1.0'
68
- requirement: !ruby/object:Gem::Requirement
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
69
71
  requirements:
70
- - - ~>
72
+ - - "~>"
71
73
  - !ruby/object:Gem::Version
72
74
  version: '1.0'
73
- prerelease: false
74
- type: :runtime
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: httpclient
77
- version_requirements: !ruby/object:Gem::Requirement
77
+ requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
- - - ~>
79
+ - - "~>"
80
80
  - !ruby/object:Gem::Version
81
81
  version: '2.4'
82
- requirement: !ruby/object:Gem::Requirement
82
+ type: :runtime
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
83
85
  requirements:
84
- - - ~>
86
+ - - "~>"
85
87
  - !ruby/object:Gem::Version
86
88
  version: '2.4'
87
- prerelease: false
88
- type: :runtime
89
89
  - !ruby/object:Gem::Dependency
90
90
  name: marc
91
- version_requirements: !ruby/object:Gem::Requirement
91
+ requirement: !ruby/object:Gem::Requirement
92
92
  requirements:
93
- - - '>='
93
+ - - ">="
94
94
  - !ruby/object:Gem::Version
95
95
  version: 0.5.0
96
- - - <
96
+ - - "<"
97
97
  - !ruby/object:Gem::Version
98
98
  version: '1.1'
99
- requirement: !ruby/object:Gem::Requirement
99
+ type: :runtime
100
+ prerelease: false
101
+ version_requirements: !ruby/object:Gem::Requirement
100
102
  requirements:
101
- - - '>='
103
+ - - ">="
102
104
  - !ruby/object:Gem::Version
103
105
  version: 0.5.0
104
- - - <
106
+ - - "<"
105
107
  - !ruby/object:Gem::Version
106
108
  version: '1.1'
107
- prerelease: false
108
- type: :runtime
109
109
  - !ruby/object:Gem::Dependency
110
110
  name: isbn
111
- version_requirements: !ruby/object:Gem::Requirement
112
- requirements:
113
- - - ~>
114
- - !ruby/object:Gem::Version
115
- version: 2.0.9
116
111
  requirement: !ruby/object:Gem::Requirement
117
112
  requirements:
118
- - - ~>
113
+ - - "~>"
119
114
  - !ruby/object:Gem::Version
120
115
  version: 2.0.9
121
- prerelease: false
122
116
  type: :runtime
123
- - !ruby/object:Gem::Dependency
124
- name: htmlentities
117
+ prerelease: false
125
118
  version_requirements: !ruby/object:Gem::Requirement
126
119
  requirements:
127
- - - '>='
120
+ - - "~>"
128
121
  - !ruby/object:Gem::Version
129
- version: '0'
122
+ version: 2.0.9
123
+ - !ruby/object:Gem::Dependency
124
+ name: htmlentities
130
125
  requirement: !ruby/object:Gem::Requirement
131
126
  requirements:
132
- - - '>='
127
+ - - ">="
133
128
  - !ruby/object:Gem::Version
134
129
  version: '0'
135
- prerelease: false
136
130
  type: :runtime
137
- - !ruby/object:Gem::Dependency
138
- name: multi_json
131
+ prerelease: false
139
132
  version_requirements: !ruby/object:Gem::Requirement
140
133
  requirements:
141
- - - '>='
134
+ - - ">="
142
135
  - !ruby/object:Gem::Version
143
136
  version: '0'
137
+ - !ruby/object:Gem::Dependency
138
+ name: multi_json
144
139
  requirement: !ruby/object:Gem::Requirement
145
140
  requirements:
146
- - - '>='
141
+ - - ">="
147
142
  - !ruby/object:Gem::Version
148
143
  version: '0'
149
- prerelease: false
150
144
  type: :runtime
151
- - !ruby/object:Gem::Dependency
152
- name: confstruct
145
+ prerelease: false
153
146
  version_requirements: !ruby/object:Gem::Requirement
154
147
  requirements:
155
- - - ~>
148
+ - - ">="
156
149
  - !ruby/object:Gem::Version
157
- version: '0.2'
150
+ version: '0'
151
+ - !ruby/object:Gem::Dependency
152
+ name: confstruct
158
153
  requirement: !ruby/object:Gem::Requirement
159
154
  requirements:
160
- - - ~>
155
+ - - "~>"
161
156
  - !ruby/object:Gem::Version
162
- version: '0.2'
163
- prerelease: false
157
+ version: '1.0'
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: 1.0.1
164
161
  type: :runtime
165
- - !ruby/object:Gem::Dependency
166
- name: scrub_rb
162
+ prerelease: false
167
163
  version_requirements: !ruby/object:Gem::Requirement
168
164
  requirements:
169
- - - '>='
165
+ - - "~>"
170
166
  - !ruby/object:Gem::Version
171
- version: 1.0.1
172
- - - <
167
+ version: '1.0'
168
+ - - ">="
173
169
  - !ruby/object:Gem::Version
174
- version: '2'
170
+ version: 1.0.1
171
+ - !ruby/object:Gem::Dependency
172
+ name: scrub_rb
175
173
  requirement: !ruby/object:Gem::Requirement
176
174
  requirements:
177
- - - '>='
175
+ - - ">="
178
176
  - !ruby/object:Gem::Version
179
177
  version: 1.0.1
180
- - - <
178
+ - - "<"
181
179
  - !ruby/object:Gem::Version
182
180
  version: '2'
183
- prerelease: false
184
181
  type: :runtime
185
- - !ruby/object:Gem::Dependency
186
- name: bootstrap-sass
182
+ prerelease: false
187
183
  version_requirements: !ruby/object:Gem::Requirement
188
184
  requirements:
189
- - - ~>
185
+ - - ">="
190
186
  - !ruby/object:Gem::Version
191
- version: '3.2'
187
+ version: 1.0.1
188
+ - - "<"
189
+ - !ruby/object:Gem::Version
190
+ version: '2'
191
+ - !ruby/object:Gem::Dependency
192
+ name: bootstrap-sass
192
193
  requirement: !ruby/object:Gem::Requirement
193
194
  requirements:
194
- - - ~>
195
+ - - "~>"
195
196
  - !ruby/object:Gem::Version
196
197
  version: '3.2'
197
- prerelease: false
198
198
  type: :runtime
199
- - !ruby/object:Gem::Dependency
200
- name: sass-rails
199
+ prerelease: false
201
200
  version_requirements: !ruby/object:Gem::Requirement
202
201
  requirements:
203
- - - '>='
202
+ - - "~>"
204
203
  - !ruby/object:Gem::Version
205
- version: 3.2.5
204
+ version: '3.2'
205
+ - !ruby/object:Gem::Dependency
206
+ name: sass-rails
206
207
  requirement: !ruby/object:Gem::Requirement
207
208
  requirements:
208
- - - '>='
209
+ - - ">="
209
210
  - !ruby/object:Gem::Version
210
211
  version: 3.2.5
211
- prerelease: false
212
212
  type: :runtime
213
- - !ruby/object:Gem::Dependency
214
- name: single_test
213
+ prerelease: false
215
214
  version_requirements: !ruby/object:Gem::Requirement
216
215
  requirements:
217
- - - ~>
218
- - !ruby/object:Gem::Version
219
- version: 0.5.1
220
- requirement: !ruby/object:Gem::Requirement
221
- requirements:
222
- - - ~>
216
+ - - ">="
223
217
  - !ruby/object:Gem::Version
224
- version: 0.5.1
225
- prerelease: false
226
- type: :development
218
+ version: 3.2.5
227
219
  - !ruby/object:Gem::Dependency
228
220
  name: uglifier
229
- version_requirements: !ruby/object:Gem::Requirement
221
+ requirement: !ruby/object:Gem::Requirement
230
222
  requirements:
231
- - - ~>
223
+ - - "~>"
232
224
  - !ruby/object:Gem::Version
233
225
  version: '1.3'
234
- requirement: !ruby/object:Gem::Requirement
226
+ type: :development
227
+ prerelease: false
228
+ version_requirements: !ruby/object:Gem::Requirement
235
229
  requirements:
236
- - - ~>
230
+ - - "~>"
237
231
  - !ruby/object:Gem::Version
238
232
  version: '1.3'
239
- prerelease: false
240
- type: :development
241
233
  - !ruby/object:Gem::Dependency
242
234
  name: vcr
243
- version_requirements: !ruby/object:Gem::Requirement
235
+ requirement: !ruby/object:Gem::Requirement
244
236
  requirements:
245
- - - ~>
237
+ - - "~>"
246
238
  - !ruby/object:Gem::Version
247
239
  version: '2.9'
248
- requirement: !ruby/object:Gem::Requirement
240
+ type: :development
241
+ prerelease: false
242
+ version_requirements: !ruby/object:Gem::Requirement
249
243
  requirements:
250
- - - ~>
244
+ - - "~>"
251
245
  - !ruby/object:Gem::Version
252
246
  version: '2.9'
253
- prerelease: false
254
- type: :development
255
247
  - !ruby/object:Gem::Dependency
256
248
  name: webmock
257
- version_requirements: !ruby/object:Gem::Requirement
249
+ requirement: !ruby/object:Gem::Requirement
258
250
  requirements:
259
- - - ~>
251
+ - - "~>"
260
252
  - !ruby/object:Gem::Version
261
253
  version: '1.18'
262
- requirement: !ruby/object:Gem::Requirement
254
+ type: :development
255
+ prerelease: false
256
+ version_requirements: !ruby/object:Gem::Requirement
263
257
  requirements:
264
- - - ~>
258
+ - - "~>"
265
259
  - !ruby/object:Gem::Version
266
260
  version: '1.18'
267
- prerelease: false
268
- type: :development
269
261
  - !ruby/object:Gem::Dependency
270
262
  name: minitest
271
- version_requirements: !ruby/object:Gem::Requirement
263
+ requirement: !ruby/object:Gem::Requirement
272
264
  requirements:
273
- - - '>='
265
+ - - ">="
274
266
  - !ruby/object:Gem::Version
275
267
  version: '0'
276
- requirement: !ruby/object:Gem::Requirement
268
+ type: :development
269
+ prerelease: false
270
+ version_requirements: !ruby/object:Gem::Requirement
277
271
  requirements:
278
- - - '>='
272
+ - - ">="
279
273
  - !ruby/object:Gem::Version
280
274
  version: '0'
281
- prerelease: false
282
- type: :development
283
- description:
275
+ description:
284
276
  email:
285
277
  - umlaut-general@rubyforge.org
286
278
  executables:
@@ -288,6 +280,10 @@ executables:
288
280
  extensions: []
289
281
  extra_rdoc_files: []
290
282
  files:
283
+ - LICENSE
284
+ - README.md
285
+ - Rakefile
286
+ - active_record_patch/connection_pool.rb
291
287
  - app/assets/images/error.gif
292
288
  - app/assets/images/frame_remove.gif
293
289
  - app/assets/images/spinner.gif
@@ -310,13 +306,13 @@ files:
310
306
  - app/assets/images/umlaut_icons/list-open.png
311
307
  - app/assets/javascripts/bootstrap3-typeahead.js
312
308
  - app/assets/javascripts/umlaut.js
313
- - app/assets/javascripts/umlaut_ui.js
314
309
  - app/assets/javascripts/umlaut/ajax_windows.js
315
310
  - app/assets/javascripts/umlaut/ensure_window_size.js.erb
316
311
  - app/assets/javascripts/umlaut/expand_contract_toggle.js
317
312
  - app/assets/javascripts/umlaut/load_permalink.js
318
313
  - app/assets/javascripts/umlaut/search_autocomplete.js
319
314
  - app/assets/javascripts/umlaut/update_html.js
315
+ - app/assets/javascripts/umlaut_ui.js
320
316
  - app/assets/stylesheets/umlaut.css.scss
321
317
  - app/assets/stylesheets/umlaut/_admin.scss
322
318
  - app/assets/stylesheets/umlaut/_az.scss
@@ -331,6 +327,7 @@ files:
331
327
  - app/assets/stylesheets/umlaut/_search.scss
332
328
  - app/assets/stylesheets/umlaut/_spinner.scss
333
329
  - app/assets/stylesheets/umlaut/_variables.scss
330
+ - app/controllers/admin/service_errors_controller.rb
334
331
  - app/controllers/export_email_controller.rb
335
332
  - app/controllers/feedback_controller.rb
336
333
  - app/controllers/js_helper_controller.rb
@@ -339,16 +336,15 @@ files:
339
336
  - app/controllers/resolve_controller.rb
340
337
  - app/controllers/resource_controller.rb
341
338
  - app/controllers/search_controller.rb
342
- - app/controllers/store_controller.rb
343
- - app/controllers/umlaut_configurable.rb
344
- - app/controllers/umlaut_controller.rb
345
- - app/controllers/admin/service_errors_controller.rb
346
339
  - app/controllers/search_methods/README.md
347
340
  - app/controllers/search_methods/sfx4.rb
348
341
  - app/controllers/search_methods/sfx_api.rb
342
+ - app/controllers/store_controller.rb
349
343
  - app/controllers/umlaut/controller_behavior.rb
350
344
  - app/controllers/umlaut/controller_logic.rb
351
345
  - app/controllers/umlaut/error_handling.rb
346
+ - app/controllers/umlaut_configurable.rb
347
+ - app/controllers/umlaut_controller.rb
352
348
  - app/helpers/emailer_helper.rb
353
349
  - app/helpers/export_email_helper.rb
354
350
  - app/helpers/open_search_helper.rb
@@ -369,14 +365,6 @@ files:
369
365
  - app/models/collection.rb
370
366
  - app/models/crossref_lookup.rb
371
367
  - app/models/dispatched_service.rb
372
- - app/models/permalink.rb
373
- - app/models/referent.rb
374
- - app/models/referent_value.rb
375
- - app/models/request.rb
376
- - app/models/service_response.rb
377
- - app/models/service_store.rb
378
- - app/models/service_wave.rb
379
- - app/models/sfx_url.rb
380
368
  - app/models/hip3/bib.rb
381
369
  - app/models/hip3/bib_searcher.rb
382
370
  - app/models/hip3/custom_field_lookup.rb
@@ -384,17 +372,25 @@ files:
384
372
  - app/models/hip3/item.rb
385
373
  - app/models/hip3/receipt.rb
386
374
  - app/models/hip3/serial_copy.rb
375
+ - app/models/permalink.rb
376
+ - app/models/referent.rb
377
+ - app/models/referent_value.rb
378
+ - app/models/request.rb
379
+ - app/models/service_response.rb
380
+ - app/models/service_store.rb
381
+ - app/models/service_wave.rb
382
+ - app/models/sfx4/abstract/README.md
387
383
  - app/models/sfx4/abstract/az_extra_info.rb
388
384
  - app/models/sfx4/abstract/az_letter_group.rb
389
385
  - app/models/sfx4/abstract/az_title.rb
390
386
  - app/models/sfx4/abstract/az_title_search.rb
391
387
  - app/models/sfx4/abstract/base.rb
392
- - app/models/sfx4/abstract/README.md
393
388
  - app/models/sfx4/local/az_extra_info.rb
394
389
  - app/models/sfx4/local/az_letter_group.rb
395
390
  - app/models/sfx4/local/az_title.rb
396
391
  - app/models/sfx4/local/az_title_search.rb
397
392
  - app/models/sfx4/local/base.rb
393
+ - app/models/sfx_url.rb
398
394
  - app/presentation/section_renderer.rb
399
395
  - app/referent_filters/dissertation_catch.rb
400
396
  - app/referent_filters/referent_filter.rb
@@ -480,60 +476,57 @@ files:
480
476
  - app/views/search/journal_search.html.erb
481
477
  - app/views/search/journals.html.erb
482
478
  - app/views/testing/index.html.erb
479
+ - app/views/umlaut/README
483
480
  - app/views/umlaut/_alerts.html.erb
484
481
  - app/views/umlaut/_footer.html.erb
485
482
  - app/views/umlaut/_header.html.erb
486
483
  - app/views/umlaut/error.html.erb
487
- - app/views/umlaut/README
484
+ - bin/umlaut
488
485
  - config/locales/en.yml
489
- - db/seeds.rb
490
486
  - db/migrate/01_umlaut_init.rb
491
487
  - db/migrate/02_umlaut_add_service_response_index.rb
492
488
  - db/orig_fixed_data/service_type_values.yml
489
+ - db/seeds.rb
493
490
  - lib/aws_product_sign.rb
494
491
  - lib/cron_tab.rb
495
- - lib/service_type_value.rb
496
- - lib/term_color.rb
497
- - lib/truncate_to_db_limit.rb
498
- - lib/umlaut.rb
499
- - lib/generators/umlaut_app_template.rb
500
492
  - lib/generators/templates/umlaut_services.yml
501
493
  - lib/generators/umlaut/asset_hooks_generator.rb
502
494
  - lib/generators/umlaut/install_generator.rb
503
495
  - lib/generators/umlaut/remove_turbolinks_generator.rb
496
+ - lib/generators/umlaut_app_template.rb
497
+ - lib/service_type_value.rb
504
498
  - lib/tasks/umlaut.rake
505
499
  - lib/tasks/umlaut_asset_compile.rake
506
500
  - lib/tasks/umlaut_migrate_permalinks.rake
501
+ - lib/term_color.rb
502
+ - lib/truncate_to_db_limit.rb
503
+ - lib/umlaut.rb
507
504
  - lib/umlaut/routes.rb
508
505
  - lib/umlaut/test_help.rb
509
506
  - lib/umlaut/util.rb
510
507
  - lib/umlaut/version.rb
511
- - active_record_patch/connection_pool.rb
512
- - LICENSE
513
- - Rakefile
514
- - README.md
515
- - bin/umlaut
516
508
  homepage: https://github.com/team-umlaut/umlaut
517
509
  licenses: []
518
510
  metadata: {}
519
- post_install_message:
511
+ post_install_message:
520
512
  rdoc_options: []
521
513
  require_paths:
522
514
  - lib
523
515
  required_ruby_version: !ruby/object:Gem::Requirement
524
516
  requirements:
525
- - - '>='
517
+ - - ">="
526
518
  - !ruby/object:Gem::Version
527
519
  version: '0'
528
520
  required_rubygems_version: !ruby/object:Gem::Requirement
529
521
  requirements:
530
- - - '>'
522
+ - - ">="
531
523
  - !ruby/object:Gem::Version
532
- version: 1.3.1
524
+ version: '0'
533
525
  requirements: []
534
- rubyforge_project:
535
- rubygems_version: 2.1.9
536
- signing_key:
526
+ rubyforge_project:
527
+ rubygems_version: 2.4.5
528
+ signing_key:
537
529
  specification_version: 4
538
- summary: For Libraries, a just-in-time last-mile service aggregator, taking OpenURL input
530
+ summary: For Libraries, a just-in-time last-mile service aggregator, taking OpenURL
531
+ input
539
532
  test_files: []