Class: Opac
Overview
FIXME This service is not working For starters it needs the method service_types_generated()
Constant Summary
Constants inherited from Service
Service::LinkOutFilterTask, Service::StandardTask
Instance Attribute Summary collapse
-
#display_name ⇒ Object
readonly
Returns the value of attribute display_name.
-
#record_attributes ⇒ Object
readonly
Returns the value of attribute record_attributes.
Attributes inherited from Service
#group, #name, #priority, #request, #service_id, #status, #task, #url
Instance Method Summary collapse
-
#check_holdings(holdings, request) ⇒ Object
The client should be able to return an array of holdings objects.
-
#collect_record_attributes(client, request) ⇒ Object
The client is expected to respond to results and return an array of MARC records.
-
#enhance_referent(marc, request, accuracy) ⇒ Object
When given a MARC record, this method fills in any missing pieces of the Request.referent.
-
#handle(request) ⇒ Object
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.
-
#is_conference?(marc) ⇒ Boolean
Check the leader to determine if this is defined as a conference or proceeding in the MARC.
-
#nature_of_contents(marc) ⇒ Object
When given a MARC record, determines if the referent should be defined as a dissertation, report or patent.
-
#parse_for_fulltext_links(marc, request) ⇒ Object
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.
-
#record_type(marc) ⇒ Object
Determines the kind of record referred to in the MARC leader/fixed fields (Book, Serial, Map, etc.).
-
#response_url(service_type, http_params) ⇒ Object
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.
-
#search_bib_data(request) ⇒ Object
Searches the bibliographic database.
-
#to_fulltext(response) ⇒ Object
When given a ServiceResponse object as its argument, returns the anchor text and URL.
-
#to_holding(response) ⇒ Object
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
#credits, #handle_wrapper, #initialize, #link_out_filter, #preempted_by, required_config_params, #service_types_generated, #translate
Constructor Details
This class inherits a constructor from Service
Instance Attribute Details
#display_name ⇒ Object (readonly)
Returns the value of attribute display_name.
5 6 7 |
# File 'app/service_adaptors/opac.rb', line 5 def display_name @display_name end |
#record_attributes ⇒ Object (readonly)
Returns the value of attribute record_attributes.
5 6 7 |
# File 'app/service_adaptors/opac.rb', line 5 def record_attributes @record_attributes end |
Instance Method Details
#check_holdings(holdings, request) ⇒ Object
The client should be able to return an array of holdings objects
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 127 128 129 130 |
# File 'app/service_adaptors/opac.rb', line 93 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, :service_type_value => '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,:service_type_value=>'holding') end end end end end |
#collect_record_attributes(client, request) ⇒ Object
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 |
# File 'app/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.enhance_referent(rec, request, client.accuracy) end end end |
#enhance_referent(marc, request, accuracy) ⇒ Object
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
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 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 |
# File 'app/service_adaptors/opac.rb', line 192 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 |
#handle(request) ⇒ Object
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 'app/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 |
#is_conference?(marc) ⇒ Boolean
Check the leader to determine if this is defined as a conference or proceeding in the MARC
134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'app/service_adaptors/opac.rb', line 134 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 |
#nature_of_contents(marc) ⇒ Object
When given a MARC record, determines if the referent should be defined as a dissertation, report or patent.
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 |
# File 'app/service_adaptors/opac.rb', line 311 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 |
#parse_for_fulltext_links(marc, request) ⇒ Object
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
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'app/service_adaptors/opac.rb', line 74 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'], :service_type_value => 'fulltext' ) end end |
#record_type(marc) ⇒ Object
Determines the kind of record referred to in the MARC leader/fixed fields (Book, Serial, Map, etc.)
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'app/service_adaptors/opac.rb', line 150 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 |
#response_url(service_type, http_params) ⇒ Object
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.
346 347 348 349 350 |
# File 'app/service_adaptors/opac.rb', line 346 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 |
#search_bib_data(request) ⇒ Object
Searches the bibliographic database
37 38 39 40 41 |
# File 'app/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 |
#to_fulltext(response) ⇒ Object
When given a ServiceResponse object as its argument, returns the anchor text and URL
171 172 173 |
# File 'app/service_adaptors/opac.rb', line 171 def to_fulltext(response) return {:display_text=>response.response_key, :url=>response.value_string} end |
#to_holding(response) ⇒ Object
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)
181 182 183 |
# File 'app/service_adaptors/opac.rb', line 181 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 |