Class: BorrowDirect::GenerateQuery

Inherits:
Object
  • Object
show all
Defined in:
lib/borrow_direct/generate_query.rb

Overview

Generate a “deep link” to query results in BD’s native HTML interface.

Constant Summary collapse

PUNCT_STRIP_REGEX =
/[[:space:]\)\(\]\[\;\:\.\,\\\/\"\<\>\!]/
@@fields =

Hash from our own API argument to BD field code

{
  :keyword  => "term",
  :title    => "ti",
  :author   => "au",
  :subject  => "su",
  :isbn     => "isbn",
  :issn     => "issn"
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url_base = nil) ⇒ GenerateQuery

Returns a new instance of GenerateQuery.



21
22
23
# File 'lib/borrow_direct/generate_query.rb', line 21

def initialize(url_base = nil)
  self.url_base = (url_base || BorrowDirect::Defaults.html_base_url)
end

Instance Attribute Details

#url_baseObject

Returns the value of attribute url_base.



9
10
11
# File 'lib/borrow_direct/generate_query.rb', line 9

def url_base
  @url_base
end

Class Method Details

.escape(str) ⇒ Object

Escape a query value. We don’t really know how to escape, for now we just remove double quotes and parens, and replace with spaces. those seem to cause problems, and that seems to work.



162
163
164
# File 'lib/borrow_direct/generate_query.rb', line 162

def self.escape(str)
  str.gsub(/[")()]/, ' ')
end

Instance Method Details

#add_query_param(uri, key, value) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/borrow_direct/generate_query.rb', line 170

def add_query_param(uri, key, value)
  uri = URI.parse(uri) unless uri.kind_of? URI

  query_param = "#{CGI.escape key}=#{CGI.escape value}"

  if uri.query
    uri.query += "&" + query_param
  else
    uri.query = query_param
  end
  
  return uri
end

#build_query_with(options) ⇒ Object

build_query_with(:title => “one two”, :author => “three four”) valid keys are those supported by BD HTML interface:

:title, :author, :isbn, :subject, :keyword, :isbn, :issn

For now, the value is always searched as a phrase, and multiple fields are always ‘and’d. We may enhance/expand later.

Returns an un-escaped query, still needs to be put into a URL



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/borrow_direct/generate_query.rb', line 33

def build_query_with(options)
  clauses = []

  options.each_pair do |field, value|
    next if value.nil?

    code = @@fields[field]

    raise ArgumentError.new("Don't recognize field code `#{field}`") unless code

    clauses << %Q{#{code}="#{escape value}"}
  end

  return clauses.join(" and ")
end

#escape(str) ⇒ Object

Instance method version for convenience.



166
167
168
# File 'lib/borrow_direct/generate_query.rb', line 166

def escape(str)
  self.class.escape(str)
end

#normalized_author(author) ⇒ Object

Lowercase, and try to get just the last name out of something that looks like a cataloging authorized heading.

Try to remove leading ‘by’ stuff when we’re getting a 245c



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/borrow_direct/generate_query.rb', line 129

def normalized_author(author)

  return "" if author.nil? || author.empty?

  author = author.downcase
  # Just take everything before the comma/semicolon if we have one --
  # or before an "and", for stripping individuals out of 245c
  # multiples. 
  if author =~ /\A([^,;]*)(,|\sand\s|;)/
    author = $1
  end


  author.gsub!(/\A.*by\s*/, '')

  # We want to remove some punctuation that is better
  # turned into a space in the query. Along with
  # any kind of unicode space, why not. 
  author.gsub!(PUNCT_STRIP_REGEX, ' ')

  # compress any remaining whitespace
  author.strip!
  author.gsub!(/\s+/, ' ')

  return author
end

#normalized_author_title_params(options) ⇒ Object

Give it a :title and optionally an :author, we’ll normalize them to our suggestion for a good BD author-title keyword search. Returns a hash suitable for passing to #query_url_with

Additional option :max_title_words, default 5.

Raises:

  • (ArgumentError)


62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/borrow_direct/generate_query.rb', line 62

def normalized_author_title_params(options)
  raise ArgumentError.new("Need a Hash argument, got #{options.inspect}") unless options.kind_of?(Hash)

  # Symbolize keys please
  #options = options.inject({}){ |h, (k, v)| hash.merge( (k.respond_to?(:to_sym) ? k.to_sym : k) => v )  }

  title           = options[:title].dup  if options[:title]
  author          = options[:author].dup if options[:author]

  
  title  = normalized_title(title, :max_title_words => options[:max_title_words])
  author = normalized_author(author)

  results = {}
  results[:title] = title if title && ! title.empty?
  results[:author] = author if author && ! author.empty?
  
  return results
end

#normalized_author_title_query(options) ⇒ Object

:title, :author and optionally :max_title_words.

Returns a query with a suggested normalized author and title for best BD search. May return just BD base URL if no author/title given.



87
88
89
# File 'lib/borrow_direct/generate_query.rb', line 87

def normalized_author_title_query(options)
  return self.query_url_with self.normalized_author_title_params(options)
end

#normalized_title(title, args = {}) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/borrow_direct/generate_query.rb', line 91

def normalized_title(title, args = {})
  return "" if title.nil? || title.empty?

  max_title_words = args[:max_title_words] || 5
 
  # Remove all things in parens at the END of the title, they tend
  # to be weird addendums. 
  title.gsub!(/\([^)]*\)\s*$/, '')

  # Strip the subtitle or other weird titles, just keep the text
  # before the first colon OR semi-colon
  title.sub!(/[\:\;](.*)$/, '')


  # We want to remove some punctuation that is better
  # turned into a space in the query. Along with
  # any kind of unicode space, why not. 
  title.gsub!(PUNCT_STRIP_REGEX, ' ')

  # compress any remaining whitespace
  title.strip!
  title.gsub!(/\s+/, ' ')

  # downcase
  title.downcase!

  # Limit to only first N words
  if max_title_words && title.index(/((.+?[ ,.:\;]+){#{max_title_words}})/)
    title = title.slice(0, $1.length).gsub(/[ ,.:\;]+$/, '')
  end

  return title
end

#query_url_with(arg) ⇒ Object



51
52
53
54
55
# File 'lib/borrow_direct/generate_query.rb', line 51

def query_url_with(arg)
  query = arg.kind_of?(Hash) ? build_query_with(arg) : arg.to_s
  
  return add_query_param(self.url_base, "query", query).to_s
end