Class: Opac
Overview
FIXME This service is not working For starters it needs the method service_types_generated()
Direct Known Subclasses
Constant Summary
Constant Summary
Constants inherited from Service
Service::LinkOutFilterTask, Service::StandardTask
Instance Attribute Summary (collapse)
-
- (Object) display_name
readonly
Returns the value of attribute display_name.
-
- (Object) record_attributes
readonly
Returns the value of attribute record_attributes.
Attributes inherited from Service
#name, #priority, #request, #service_id, #session_id, #status, #task, #url
Instance Method Summary (collapse)
-
- (Object) check_holdings(holdings, request)
The client should be able to return an array of holdings objects.
-
- (Object) collect_record_attributes(client, request)
The client is expected to respond to results and return an array of MARC records.
-
- (Object) collect_subjects(marc, request)
Gathers the subject headings from the MARC 6xx fields and creates service types.
-
- (Object) enhance_referent(marc, request, accuracy)
When given a MARC record, this method fills in any missing pieces of the Request.referent.
-
- (Object) handle(request)
The Opac class has a few assumptions
-
You have some sort of bib client to get MARC records from your OPAC
-
This operates independently of holdings data
-
If your client can supply holdings information, you have the methods:
-
init_holdings_client
-
get_holdings.
-
-
- (Boolean) is_conference?(marc)
Check the leader to determine if this is defined as a conference or proceeding in the MARC.
-
- (Object) nature_of_contents(marc)
When given a MARC record, determines if the referent should be defined as a dissertation, report or patent.
-
- (Object) parse_for_fulltext_links(marc, request)
Searches the MARC record for 856 tags, checks to see if they seem to be digital representations and, if so, adds them as fulltext service types.
-
- (Object) record_type(marc)
Determines the kind of record referred to in the MARC leader/fixed fields (Book, Serial, Map, etc.).
-
- (Object) response_url(service_type, http_params)
Builds a URL either based on a URL in the value_string or builds a link to the OPAC using the direct_link_arg and the bib ID.
-
- (Object) search_bib_data(request)
Searches the bibliographic database.
-
- (Object) to_fulltext(response)
When given a ServiceResponse object as its argument, returns the anchor text and URL.
-
- (Object) to_holding(response)
When given a ServiceResponse object as its argument, returns the object as a hash with the keys:
-
:display_text
-
:call_number
-
:status
-
:source_name (which equates to self.display_name).
-
Methods inherited from Service
#handle_wrapper, #initialize, #link_out_filter, #preempted_by, required_config_params, #response_to_view_data, #service_types_generated, #session, #update_session, #view_data_from_service_type
Constructor Details
This class inherits a constructor from Service
Instance Attribute Details
- (Object) display_name (readonly)
Returns the value of attribute display_name
5 6 7 |
# File 'lib/service_adaptors/opac.rb', line 5 def display_name @display_name end |
- (Object) record_attributes (readonly)
Returns the value of attribute record_attributes
5 6 7 |
# File 'lib/service_adaptors/opac.rb', line 5 def record_attributes @record_attributes end |
Instance Method Details
- (Object) check_holdings(holdings, request)
The client should be able to return an array of holdings objects
89 90 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 124 125 126 |
# File 'lib/service_adaptors/opac.rb', line 89 def check_holdings(holdings, request) return if holdings.empty? # These need to moved to services.yml electronic_locations = ['INTERNET', 'NETLIBRARY', 'GALILEO'] holdings.each do | holding | @record_attributes[holding.identifier.to_s][:holdings] = holding holding.locations.each do | location | next if electronic_locations.index(location.code) location.items.each do | item | if request.referent.format == 'journal' and request.referent.["volume"] and @record_attributes[holding.identifier.to_s][:conference] == false copy_match = false if item.enumeration if vol_match = item.enumeration.match(/VOL [A-z0-9\-]*/) vol = vol_match[0] vol.sub!(/^VOL\s*/, '') (svol, evol) = vol.split('-') if request.referent.["volume"] == svol copy_match = true elsif evol if request.referent.["volume"] == evol copy_match = true elsif request.referent.["volume"].to_i > svol.to_i and request.referent.["volume"].to_i < evol.to_i copy_match = true end end end end if copy_match == true request.add_service_response({:service=>self,:key=>holding.identifier.to_s,:value_string=>location.name,:value_alt_string=>item.call_number,:value_text=>item.status.to_s},['holding']) break end else request.add_service_response({:service=>self,:key=>holding.identifier.to_s,:value_string=>location.name,:value_alt_string=>item.call_number,:value_text=>item.status.to_s},['holding']) end end end end end |
- (Object) collect_record_attributes(client, request)
The client is expected to respond to results and return an array of MARC records. Override this method (and parse_for_fulltext, collect_subjects, and enhance_referent) if your client does not return MARC.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/service_adaptors/opac.rb', line 47 def collect_record_attributes(client, request) require 'marc' client.results.each do | record | MARC::XMLReader.new(StringIO.new(record.to_s)).each do | rec | id = nil # Assumes your local control number to be defined in 001 rec.find_all { | f| '001' === f.tag}.each do | bibnum | id = bibnum.value @record_attributes[id] = {} end # Conferences have their own crazy logic if self.is_conference?(rec) @record_attributes[id][:conference] = true else @record_attributes[id][:conference] = false end self.parse_for_fulltext_links(rec, request) self.collect_subjects(rec, request) self.enhance_referent(rec, request, client.accuracy) end end end |
- (Object) collect_subjects(marc, request)
Gathers the subject headings from the MARC 6xx fields and creates service types
182 183 184 185 186 187 188 189 190 191 192 193 194 195 |
# File 'lib/service_adaptors/opac.rb', line 182 def collect_subjects(marc, request) marc.find_all {|f| ('600'..'699') === f.tag}.each do | subject | subj = '' subj << subject['a'] unless subject['x'].blank? subj << ' ' unless subj.blank? subj << subject['x'] end # This may need to be modified to handle DDC, MeSH, etc. request.add_service_response({:service=>self,:key=>'LCSH',:value_string=>subj},['subject']) \ unless subj.blank? end end |
- (Object) enhance_referent(marc, request, accuracy)
When given a MARC record, this method fills in any missing pieces of the Request.referent. 'accuracy' is a 3 point scale determined by the client, 1 = 'possibly the correct resource', 2 = same resource, but not necessarily the same edition, 3 = exactly the same resource
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 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
# File 'lib/service_adaptors/opac.rb', line 202 def enhance_referent(marc, request, accuracy) return unless accuracy > 2 title_key = case request.referent.format when "book" then "btitle" when "journal" then "jtitle" when "dissertation" then "title" end = request.referent. unless [title_key] if request.referent.["title"] && title_key != "title" request.referent.enhance_referent(title_key, ["title"]) else request.referent.enhance_referent(title_key, marc['245'].value) end end unless ["au"] if marc['100'] && marc['100']['a'] request.referent.enhance_referent('au', marc['100']['a']) end end unless ["aucorp"] if marc['110'] && marc['110']['a'] request.referent.enhance_referent('aucorp', marc['110']['a']) end end return unless accuracy > 3 unless ["place"] if marc['260'] && marc['260']['a'] request.referent.enhance_referent('place', marc['260']['a']) end end unless ["pub"] if marc['260'] && marc['260']['b'] request.referent.enhance_referent('pub', marc['260']['b']) end end unless ["edition"] if marc['250'] && marc['250']['a'] request.referent.enhance_referent('edition', marc['250']['a']) end end unless ["series"] if marc['490'] && marc['490']['a'] request.referent.enhance_referent('series', marc['490']['a']) elsif marc['730'] && marc['730']['a'] request.referent.enhance_referent('series', marc['730']['a']) end end unless ["date"] or request.referent.format == 'journal' if marc['260'] && marc['260']['c'] request.referent.enhance_referent('date', marc['260']['c']) end end unless request.referent.format type = self.record_type(marc) request.referent.enhance_referent('format', 'book', false) if type == "BKS" request.referent.enhance_referent('format', 'journal', false) if type == "SER" end unless ["genre"] if self.is_conference?(marc) if ["atitle"] request.referent.enhance_referent('genre', 'proceeding') else request.referent.enhance_referent('genre', 'conference') end elsif type = self.nature_of_contents(marc) case type when "dissertation" then request.referent.enhance_referent('format', 'dissertation', false) when "patent" then request.referent.enhance_referent('format', 'patent', false) when "report" then request.referent.enhance_referent('genre', 'report') end else type = self.record_type(marc) if type == "BKS" request.referent.enhance_referent('format', 'book', false) unless request.referent.format == 'book' if ["atitle"] request.referent.enhance_referent('genre', 'bookpart') else request.referent.enhance_referent('genre', 'book') end elsif type == "SER" request.referent.enhance_referent('format', 'journal', false) unless request.referent.format == 'journal' if ["atitle"] request.referent.enhance_referent('genre', 'article') elsif ["issue"] request.referent.enhance_referent('genre', 'issue') else request.referent.enhance_referent('genre', 'journal') end end end end unless ["isbn"] if marc['020'] && marc['020']['a'] request.referent.enhance_referent('isbn', marc['020']['a']) end end unless ["issn"] if marc['022'] && marc['022']['a'] request.referent.enhance_referent('issn', marc['022']['a']) end end unless ["sici"] if marc['024'] && marc['024'].indicator1 == "4" request.referent.enhance_referent('sici', marc['024']['a']) end end unless ["coden"] if marc['030'] && marc['030']['a'] request.referent.enhance_referent('coden', marc['030']['a']) end end end |
- (Object) handle(request)
The Opac class has a few assumptions
-
You have some sort of bib client to get MARC records from your OPAC
-
This operates independently of holdings data
-
If your client can supply holdings information, you have the methods:
-
init_holdings_client
-
get_holdings
The Opac class should be extended with your local connection client and not called directly.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/service_adaptors/opac.rb', line 17 def handle(request) # It's unlikely that consortial catalogs allow borrowing # of journals, but this may need to pushed to a client class if request.referent.format == 'journal' and @consortial return request.dispatched(self, true) end @record_attributes = {} self.search_bib_data(request) if self.respond_to?(:init_holdings_client) opac_client = self.init_holdings_client opac_client.get_holdings(@record_attributes.keys) self.check_holdings(opac_client.results, request) else self.add_link_to_opac(client,request) end return request.dispatched(self, true) end |
- (Boolean) is_conference?(marc)
Check the leader to determine if this is defined as a conference or proceeding in the MARC
130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/service_adaptors/opac.rb', line 130 def is_conference?(marc) # Check the leader/008 for books and serials return true if marc['008'].value[29,1] == '1' && marc.leader[6,1].match(/[at]/) && marc.leader[7,1].match(/[abcdms]/) # Check the leader/008 for scores and recordings return true if marc['008'].value[30,2] == 'c' && marc.leader[6,1].match(/[cdij]/) && marc.leader[7,1].match(/[abcdms]/) # Loop through the 006s marc.find_all {|f| ('006') === f.tag}.each { | fxd_fld | return true if fxd_fld.value[12,1] == '1' && fxd_fld.value[0,1].match(/[ats]{1}/) return true if fxd_fld.value[13,2]== 'c' && fxd_fld.value[0,1].match(/[cdij]{1}/) } return false end |
- (Object) nature_of_contents(marc)
When given a MARC record, determines if the referent should be defined as a dissertation, report or patent.
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 |
# File 'lib/service_adaptors/opac.rb', line 321 def nature_of_contents(marc) types = {'m'=>'dissertation','t'=>'report','j'=>'patent'} idx = nil if self.record_type(marc) == 'BKS' idx = 24 len = 4 elsif self.record_type(marc) == 'SER' idx = 25 len = 3 end if idx marc['008'].value[idx,len].split(//).each do | char | return types[char] if types.keys.index(char) end end marc.find_all {|f| ('006') === f.tag}.each do | fxd_fld | idx = nil if fxd_fld.value[0,1].match(/[at]{1}/) idx = 7 len = 4 elsif fxd_fld.value[0,1].match('s') idx = 8 len = 3 end if idx fxd_fld.value[idx,len].split(//).each do | char | return types[char] if types.keys.index(char) end end end return false end |
- (Object) parse_for_fulltext_links(marc, request)
Searches the MARC record for 856 tags, checks to see if they seem to be digital representations and, if so, adds them as fulltext service types
75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/service_adaptors/opac.rb', line 75 def parse_for_fulltext_links(marc, request) eight_fifty_sixes = [] marc.find_all { | f| '856' === f.tag}.each do | link | eight_fifty_sixes << link end eight_fifty_sixes.each do | link | next if link.indicator2.match(/[28]/) next if link['u'].match(/(sfx\.galib\.uga\.edu)|(findit\.library\.gatech\.edu)/) label = (link['z']||'Electronic Access') request.add_service_response({:service=>self,:key=>label,:value_string=>link['u']},['fulltext']) end end |
- (Object) record_type(marc)
Determines the kind of record referred to in the MARC leader/fixed fields (Book, Serial, Map, etc.)
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/service_adaptors/opac.rb', line 146 def record_type(marc) type = marc.leader[6,1] blvl = marc.leader[7,1] valid_types = ['a','t','g','k','r','o','p','e','f','c','d','i','j','m'] rec_types = { 'BKS' => { :type => /[at]{1}/, :blvl => /[acdm]{1}/ }, 'SER' => { :type => /[a]{1}/, :blvl => /[bs]{1}/ }, 'VIS' => { :type => /[gkro]{1}/, :blvl => /[abcdms]{1}/ }, 'MIX' => { :type => /[p]{1}/, :blvl => /[cd]{1}/ }, 'MAP' => { :type => /[ef]{1}/, :blvl => /[abcdms]{1}/ }, 'SCO' => { :type => /[cd]{1}/, :blvl => /[abcdms]{1}/ }, 'REC' => { :type => /[ij]{1}/, :blvl => /[abcdms]{1}/ }, 'COM' => { :type => /[m]{1}/, :blvl => /[abcdms]{1}/ } } rec_types.each_key do | rec_type | return rec_type if type.match(rec_types[rec_type][:type]) and blvl.match(rec_types[rec_type][:blvl]) end end |
- (Object) response_url(service_type, http_params)
Builds a URL either based on a URL in the value_string or builds a link to the OPAC using the direct_link_arg and the bib ID.
356 357 358 359 360 |
# File 'lib/service_adaptors/opac.rb', line 356 def response_url(service_type, http_params) response service_type.service_response return CGI.unescapeHTML(response.value_string) if response.value_string.match(/^http(s)?:\/\//) return @url+'&'+@direct_link_arg+response.response_key end |
- (Object) search_bib_data(request)
Searches the bibliographic database
37 38 39 40 41 |
# File 'lib/service_adaptors/opac.rb', line 37 def search_bib_data(request) client = self.init_bib_client client.search_by_referent(request.referent) self.collect_record_attributes(client, request) end |
- (Object) to_fulltext(response)
When given a ServiceResponse object as its argument, returns the anchor text and URL
167 168 169 |
# File 'lib/service_adaptors/opac.rb', line 167 def to_fulltext(response) return {:display_text=>response.response_key, :url=>response.value_string} end |
- (Object) to_holding(response)
When given a ServiceResponse object as its argument, returns the object as a hash with the keys:
-
:display_text
-
:call_number
-
:status
-
:source_name (which equates to self.display_name)
177 178 179 |
# File 'lib/service_adaptors/opac.rb', line 177 def to_holding(response) return {:display_text=>response.value_string,:call_number=>response.value_alt_string,:status=>response.value_text,:source_name=>self.display_name} end |