Class: Hip3::BibSearcher

Inherits:
Object
  • Object
show all
Defined in:
app/models/hip3/bib_searcher.rb

Overview

Searches using the HIP3 xml 'interface', which means it may be sensitive to HIP display changes that change XML. It finds BibNums, and creates Hip3Bib objects based on that bibNum. Doesn't take any other info but Bib num from the actual search response, but it could, and pre-load the bib object.

Constant Summary collapse

ISSN_KW_INDEX =
'.IS'
ISBN_KW_INDEX =
'.IB'
GEN_KW_INDEX =
'.GW'
TITLE_KW_INDEX =
'.TW'
SERIAL_TITLE_KW_INDEX =
'.ST'
AUTHOR_KW_INDEX =
'.AW'
BIBNUM_INDEX =
'BIB'
SUDOC_KW_INDEX =
'.SD'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(arg_base_path, arg_http_session = nil) ⇒ BibSearcher

open a persistent connection. You are advised to use our special Hip3::HTTPSession, for it's error handling. Or better yet, just leave second argument empty, and we'll create one for you.


44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'app/models/hip3/bib_searcher.rb', line 44

def initialize(arg_base_path, arg_http_session=nil)      
    self.hip_base_url_str = arg_base_path
    self.hip_base_url = URI::parse(self.hip_base_url_str);
    
    
	self.httpSession = arg_http_session
    if self.httpSession.nil?
      self.httpSession = Hip3::HTTPSession.create(self.hip_base_url.host() )
    end
    
    self.keywords = []
	
end

Instance Attribute Details

#bibnumObject

Returns the value of attribute bibnum


37
38
39
# File 'app/models/hip3/bib_searcher.rb', line 37

def bibnum
  @bibnum
end

#hip_base_urlObject

Returns the value of attribute hip_base_url


35
36
37
# File 'app/models/hip3/bib_searcher.rb', line 35

def hip_base_url
  @hip_base_url
end

#hip_base_url_strObject

Returns the value of attribute hip_base_url_str


35
36
37
# File 'app/models/hip3/bib_searcher.rb', line 35

def hip_base_url_str
  @hip_base_url_str
end

#httpSessionObject

Returns the value of attribute httpSession


34
35
36
# File 'app/models/hip3/bib_searcher.rb', line 34

def httpSession
  @httpSession
end

#isbnObject

writers provided concretely


36
37
38
# File 'app/models/hip3/bib_searcher.rb', line 36

def isbn
  @isbn
end

#issnObject

writers provided concretely


36
37
38
# File 'app/models/hip3/bib_searcher.rb', line 36

def issn
  @issn
end

#keywordsObject

Returns the value of attribute keywords


38
39
40
# File 'app/models/hip3/bib_searcher.rb', line 38

def keywords
  @keywords
end

#sudocObject

Returns the value of attribute sudoc


37
38
39
# File 'app/models/hip3/bib_searcher.rb', line 37

def sudoc
  @sudoc
end

Instance Method Details

#countObject

returns the numbef of hits–does not cache anything, calling this method will cause a trip to the db, and calling search will cause another one.


170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'app/models/hip3/bib_searcher.rb', line 170

def count
  return [] if insufficient_query

  httpResp = httpSession.get( searchPath, nil )
  reDoc = Nokogiri::XML( httpResp.body )

  # Confusingly, sometimes
			# this gives us a search results page, and sometimes it gives us
			# a single bib

  # single bib?
  if reDoc.at('searchresponse/fullnonmarc/searchresults/results/row/key')
    return 1
  end

  # Multiple, get the count
  hits = reDoc.at('searchresponse/yoursearch/hits')
  return hits ? hits.inner_text.to_s.to_i : 0       
end

#insufficient_queryObject


230
231
232
233
# File 'app/models/hip3/bib_searcher.rb', line 230

def insufficient_query
  # Have to have some search criteria to search
  return (self.issn.nil? && self.isbn.nil? && self.sudoc.blank? && self.bibnum.blank? && self.keywords.blank? && @search_hash.blank?)
end

#keyword_url_argsObject


160
161
162
163
164
165
# File 'app/models/hip3/bib_searcher.rb', line 160

def keyword_url_args
  args =
  self.keywords.collect { |k| "&index=#{@keyword_index}&term=#{CGI.escape('"' + k + '"')}" }

  return args.join("&oper=and") || ""            
end

#searchObject

Returns an array of bib objects.


191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'app/models/hip3/bib_searcher.rb', line 191

def search
    return [] if insufficient_query
	httpResp = httpSession.get(searchPath(), nil )

    
	bib_xml = Nokogiri::XML( httpResp.body )
	# Confusingly, sometimes
	# this gives us a search results page, and sometimes it gives us
	# a single bib

	# single bib?
	if ( bibNum = bib_xml.at('searchresponse/fullnonmarc/searchresults/results/row/key'))
		# Single bib
		#return [Hip3::Bib.new( httpSession, bibNum.text, reDoc)]
      return [Hip3::Bib.new( bibNum.inner_text, self.hip_base_url,
                             :http_session => httpSession,
                             :bib_xml_doc => bib_xml
                             )]
	end

	
	# Multi-response
	# Get Bib #s and titles for each result.
    
	bib_summaries =  bib_xml.search('searchresponse/summary/searchresults/results/row');

    return bib_summaries.collect do |bib_xml|
      next unless bib_xml.at('key')

      # Find a title from the summary xml
      title_el = bib_xml.at('TITLE/data/text')
      title = title_el ? title_el.inner_text : nil
      # remove possible author on there, after a '/' char. That's how HIP rolls.
      title.sub!(/\/.*$/, '')
      
      Hip3::Bib.new(bib_xml.at('key').inner_text, self.hip_base_url, :http_session => httpSession, :title => title )
    end
end

#search_hash=(hash) ⇒ Object

Yet another way to specify search criteria. Hash, where the key is the name of a HIP keyword Index (use constants in this class if possible), and the value is an array of keywords. Everything is “anded” together.


91
92
93
# File 'app/models/hip3/bib_searcher.rb', line 91

def search_hash=(hash)
  @search_hash = hash
end

#search_urlObject


235
236
237
# File 'app/models/hip3/bib_searcher.rb', line 235

def search_url
  return self.hip_base_url_str + '?' + self.searchPath(:xml => false )
end

#searchPath(args = {}) ⇒ Object

Returns the URL starting from / that specifies the search criteria to HIP.


119
120
121
122
123
124
125
126
127
128
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
155
156
157
158
# File 'app/models/hip3/bib_searcher.rb', line 119

def searchPath(args = {})
    args[:xml] = true if args[:xml].nil?
    
	path = self.hip_base_url.path() + '?' 			"menu=search&aspect=power&npp=30&ipp=20&spp=20&profile=general&ri=2"

    criteria = Array.new

    # Need to do search_hash first, to make sure bibnum and isbn search
    # come LAST, for HIP. 
    unless ( @search_hash.blank?)
      manual_criteria = []
      @search_hash.each_pair do |index, kws|
       manual_criteria << kws.collect do |kw|
           kw = '"' + kw + '"' unless [BIBNUM_INDEX, ISSN_KW_INDEX, ISBN_KW_INDEX, AUTHOR_KW_INDEX].include?(index)
          "&index=#{index}&term=#{URI.escape(kw)}"
        end
      end
      path << manual_criteria.join("&oper=and") << "&oper=or"
    end

    
    criteria<< "&index=#{SUDOC_KW_INDEX}&term=#{URI.escape('"' + self.sudoc + '"' )}" unless sudoc.nil?
    criteria << "&index=#{ISSN_KW_INDEX}&term=#{URI.escape(self.issn)}" unless issn.nil?
    # For some reason ISBN must be LAST in order, and bibnum must be right before, or HIP doesn't like it.
    criteria << "&index=#{BIBNUM_INDEX}&term=#{URI.escape(self.bibnum)}" unless bibnum.blank?
    # Go figure. I hate you, HIP. 
    criteria << "&index=#{ISBN_KW_INDEX}&term=#{URI.escape(self.isbn)}" unless isbn.nil?
    
    criteria << keyword_url_args
    path << criteria.join("&oper=or")



    
    path << "&x=0&y=0&aspect=power"
    path << "&GetXML=1" if args[:xml]

    return path

end

#set_keywords(arg_kw, args = {}) ⇒ Object


99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'app/models/hip3/bib_searcher.rb', line 99

def set_keywords(arg_kw, args={})

  arg_kw = [] if arg_kw.nil?
  args[:index] = :general unless args[:index]

  @keywords = arg_kw


  
  if (args[:index] == :title)
    @keyword_index = TITLE_KW_INDEX
  elsif (args[:index] == :serial_title)
    @keyword_index = SERIAL_TITLE_KW_INDEX
  else
    @keyword_index = GEN_KW_INDEX
  end
end