berkeley_library-alma 0.0.2 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.idea/alma.iml +17 -15
- data/CHANGES.md +18 -0
- data/README.md +43 -5
- data/bin/alma-mms-lookup +1 -3
- data/lib/berkeley_library/alma/barcode.rb +33 -0
- data/lib/berkeley_library/alma/bib_number.rb +3 -4
- data/lib/berkeley_library/alma/constants.rb +1 -1
- data/lib/berkeley_library/alma/module_info.rb +1 -1
- data/lib/berkeley_library/alma/record_id.rb +12 -26
- data/lib/berkeley_library/alma/sru.rb +79 -0
- data/spec/data/C084093187-sru.xml +299 -0
- data/spec/data/availability-sru.xml +109 -0
- data/spec/data/{b11082434-sru.xml → b110824349-sru.xml} +0 -0
- data/spec/lib/berkeley_library/alma/barcode_spec.rb +67 -0
- data/spec/lib/berkeley_library/alma/bib_number_spec.rb +10 -1
- data/spec/lib/berkeley_library/alma/mms_id_spec.rb +3 -3
- data/spec/lib/berkeley_library/alma/record_id_spec.rb +20 -0
- data/spec/lib/berkeley_library/alma/sru_spec.rb +29 -0
- data/spec/spec_helper.rb +6 -15
- metadata +14 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0805d8fb305dd644ede89efb0c71845c479df3cc8b69334bbfc4e747312c229d'
|
4
|
+
data.tar.gz: 80b1576c6dc7d5bbfd5bd5a0a53985167c4c3929668d505dae92ffcac196988e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 879cb4ef386caa8543bf883ac3b62888c4ca810ef431562618ad456c9d560ee81f6dada5b9ae850ca15523cd6f58d5487919c3e782c817313deaff346912c257
|
7
|
+
data.tar.gz: b10240d0571733f28f90ab099da879647cdd670da05c5af5aa396f0fcd8c9ae026d2ec9b4c1246764a6b919bc594c665ff0096140b400cb2626af893bdcd3b21
|
data/.idea/alma.iml
CHANGED
@@ -8,12 +8,13 @@
|
|
8
8
|
<sourceFolder url="file://$MODULE_DIR$/features" isTestSource="true" />
|
9
9
|
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
10
10
|
<excludeFolder url="file://$MODULE_DIR$/artifacts" />
|
11
|
+
<excludeFolder url="file://$MODULE_DIR$/doc" />
|
11
12
|
</content>
|
12
13
|
<orderEntry type="jdk" jdkName="RVM: ruby-2.7.5" jdkType="RUBY_SDK" />
|
13
14
|
<orderEntry type="sourceFolder" forTests="false" />
|
14
|
-
<orderEntry type="library" scope="PROVIDED" name="actionpack (v6.1.4.
|
15
|
-
<orderEntry type="library" scope="PROVIDED" name="actionview (v6.1.4.
|
16
|
-
<orderEntry type="library" scope="PROVIDED" name="activesupport (v6.1.4.
|
15
|
+
<orderEntry type="library" scope="PROVIDED" name="actionpack (v6.1.4.6, RVM: ruby-2.7.5) [gem]" level="application" />
|
16
|
+
<orderEntry type="library" scope="PROVIDED" name="actionview (v6.1.4.6, RVM: ruby-2.7.5) [gem]" level="application" />
|
17
|
+
<orderEntry type="library" scope="PROVIDED" name="activesupport (v6.1.4.6, RVM: ruby-2.7.5) [gem]" level="application" />
|
17
18
|
<orderEntry type="library" scope="PROVIDED" name="addressable (v2.8.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
18
19
|
<orderEntry type="library" scope="PROVIDED" name="amazing_print (v1.4.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
19
20
|
<orderEntry type="library" scope="PROVIDED" name="ast (v2.4.2, RVM: ruby-2.7.5) [gem]" level="application" />
|
@@ -22,7 +23,7 @@
|
|
22
23
|
<orderEntry type="library" scope="PROVIDED" name="berkeley_library-util (v0.1.1, RVM: ruby-2.7.5) [gem]" level="application" />
|
23
24
|
<orderEntry type="library" scope="PROVIDED" name="builder (v3.2.4, RVM: ruby-2.7.5) [gem]" level="application" />
|
24
25
|
<orderEntry type="library" scope="PROVIDED" name="bundle-audit (v0.1.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
25
|
-
<orderEntry type="library" scope="PROVIDED" name="bundler (v2.
|
26
|
+
<orderEntry type="library" scope="PROVIDED" name="bundler (v2.1.4, RVM: ruby-2.7.5) [gem]" level="application" />
|
26
27
|
<orderEntry type="library" scope="PROVIDED" name="bundler-audit (v0.9.0.1, RVM: ruby-2.7.5) [gem]" level="application" />
|
27
28
|
<orderEntry type="library" scope="PROVIDED" name="ci_reporter (v2.0.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
28
29
|
<orderEntry type="library" scope="PROVIDED" name="ci_reporter_rspec (v1.0.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
@@ -37,13 +38,14 @@
|
|
37
38
|
<orderEntry type="library" scope="PROVIDED" name="hashdiff (v1.0.1, RVM: ruby-2.7.5) [gem]" level="application" />
|
38
39
|
<orderEntry type="library" scope="PROVIDED" name="http-accept (v1.7.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
39
40
|
<orderEntry type="library" scope="PROVIDED" name="http-cookie (v1.0.4, RVM: ruby-2.7.5) [gem]" level="application" />
|
40
|
-
<orderEntry type="library" scope="PROVIDED" name="i18n (v1.
|
41
|
+
<orderEntry type="library" scope="PROVIDED" name="i18n (v1.10.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
41
42
|
<orderEntry type="library" scope="PROVIDED" name="lograge (v0.11.2, RVM: ruby-2.7.5) [gem]" level="application" />
|
42
|
-
<orderEntry type="library" scope="PROVIDED" name="loofah (v2.
|
43
|
+
<orderEntry type="library" scope="PROVIDED" name="loofah (v2.14.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
43
44
|
<orderEntry type="library" scope="PROVIDED" name="marc (v1.1.1, RVM: ruby-2.7.5) [gem]" level="application" />
|
44
45
|
<orderEntry type="library" scope="PROVIDED" name="method_source (v1.0.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
45
46
|
<orderEntry type="library" scope="PROVIDED" name="mime-types (v3.4.1, RVM: ruby-2.7.5) [gem]" level="application" />
|
46
47
|
<orderEntry type="library" scope="PROVIDED" name="mime-types-data (v3.2022.0105, RVM: ruby-2.7.5) [gem]" level="application" />
|
48
|
+
<orderEntry type="library" scope="PROVIDED" name="mini_portile2 (v2.7.1, RVM: ruby-2.7.5) [gem]" level="application" />
|
47
49
|
<orderEntry type="library" scope="PROVIDED" name="minitest (v5.15.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
48
50
|
<orderEntry type="library" scope="PROVIDED" name="netrc (v0.11.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
49
51
|
<orderEntry type="library" scope="PROVIDED" name="nokogiri (v1.13.1, RVM: ruby-2.7.5) [gem]" level="application" />
|
@@ -58,23 +60,23 @@
|
|
58
60
|
<orderEntry type="library" scope="PROVIDED" name="rack-test (v1.1.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
59
61
|
<orderEntry type="library" scope="PROVIDED" name="rails-dom-testing (v2.0.3, RVM: ruby-2.7.5) [gem]" level="application" />
|
60
62
|
<orderEntry type="library" scope="PROVIDED" name="rails-html-sanitizer (v1.4.2, RVM: ruby-2.7.5) [gem]" level="application" />
|
61
|
-
<orderEntry type="library" scope="PROVIDED" name="railties (v6.1.4.
|
63
|
+
<orderEntry type="library" scope="PROVIDED" name="railties (v6.1.4.6, RVM: ruby-2.7.5) [gem]" level="application" />
|
62
64
|
<orderEntry type="library" scope="PROVIDED" name="rainbow (v3.1.1, RVM: ruby-2.7.5) [gem]" level="application" />
|
63
65
|
<orderEntry type="library" scope="PROVIDED" name="rake (v13.0.6, RVM: ruby-2.7.5) [gem]" level="application" />
|
64
66
|
<orderEntry type="library" scope="PROVIDED" name="regexp_parser (v2.2.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
65
67
|
<orderEntry type="library" scope="PROVIDED" name="request_store (v1.5.1, RVM: ruby-2.7.5) [gem]" level="application" />
|
66
68
|
<orderEntry type="library" scope="PROVIDED" name="rest-client (v2.1.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
67
69
|
<orderEntry type="library" scope="PROVIDED" name="rexml (v3.2.5, RVM: ruby-2.7.5) [gem]" level="application" />
|
68
|
-
<orderEntry type="library" scope="PROVIDED" name="rspec (v3.
|
69
|
-
<orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.
|
70
|
-
<orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.
|
71
|
-
<orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.
|
72
|
-
<orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.
|
70
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec (v3.11.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
71
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec-core (v3.11.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
72
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec-expectations (v3.11.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
73
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec-mocks (v3.11.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
74
|
+
<orderEntry type="library" scope="PROVIDED" name="rspec-support (v3.11.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
73
75
|
<orderEntry type="library" scope="PROVIDED" name="rubocop (v1.11.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
74
76
|
<orderEntry type="library" scope="PROVIDED" name="rubocop-ast (v1.15.1, RVM: ruby-2.7.5) [gem]" level="application" />
|
75
77
|
<orderEntry type="library" scope="PROVIDED" name="rubocop-rake (v0.6.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
76
78
|
<orderEntry type="library" scope="PROVIDED" name="rubocop-rspec (v2.4.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
77
|
-
<orderEntry type="library" scope="PROVIDED" name="ruby-marc-spec (v0.1.
|
79
|
+
<orderEntry type="library" scope="PROVIDED" name="ruby-marc-spec (v0.1.3, RVM: ruby-2.7.5) [gem]" level="application" />
|
78
80
|
<orderEntry type="library" scope="PROVIDED" name="ruby-progressbar (v1.11.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
79
81
|
<orderEntry type="library" scope="PROVIDED" name="scrub_rb (v1.0.1, RVM: ruby-2.7.5) [gem]" level="application" />
|
80
82
|
<orderEntry type="library" scope="PROVIDED" name="simplecov (v0.21.2, RVM: ruby-2.7.5) [gem]" level="application" />
|
@@ -90,7 +92,7 @@
|
|
90
92
|
<orderEntry type="library" scope="PROVIDED" name="webmock (v3.14.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
91
93
|
<orderEntry type="library" scope="PROVIDED" name="webrick (v1.7.0, RVM: ruby-2.7.5) [gem]" level="application" />
|
92
94
|
<orderEntry type="library" scope="PROVIDED" name="yard (v0.9.27, RVM: ruby-2.7.5) [gem]" level="application" />
|
93
|
-
<orderEntry type="library" scope="PROVIDED" name="zeitwerk (v2.5.
|
95
|
+
<orderEntry type="library" scope="PROVIDED" name="zeitwerk (v2.5.4, RVM: ruby-2.7.5) [gem]" level="application" />
|
94
96
|
</component>
|
95
97
|
<component name="RModuleSettingsStorage">
|
96
98
|
<LOAD_PATH number="2" string0="$MODULE_DIR$/lib" string1="$MODULE_DIR$/spec" />
|
@@ -107,7 +109,7 @@
|
|
107
109
|
</RakeTaskImpl>
|
108
110
|
<RakeTaskImpl description="Run all specs in spec directory, with coverage" fullCommand="coverage" id="coverage" />
|
109
111
|
<RakeTaskImpl description="Run tests, check test coverage, check code style, check for vulnerabilities, build gem" fullCommand="default" id="default" />
|
110
|
-
<RakeTaskImpl description="Build berkeley_library-alma.gemspec as berkeley_library-alma-0.0.
|
112
|
+
<RakeTaskImpl description="Build berkeley_library-alma.gemspec as berkeley_library-alma-0.0.3.gem" fullCommand="gem" id="gem" />
|
111
113
|
<RakeTaskImpl description="Run RuboCop with auto-correct, and output results to console" fullCommand="ra" id="ra" />
|
112
114
|
<RakeTaskImpl description="Run rubocop with HTML output" fullCommand="rubocop" id="rubocop" />
|
113
115
|
<RakeTaskImpl id="rubocop">
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
# 0.0.5 (4 May 2022)
|
2
|
+
|
3
|
+
- extracts `SRU` module for performing SRU queries.
|
4
|
+
- MARCXML parsing now uses `MARC::NokogiriReader` rather than the `REXML` default.
|
5
|
+
|
6
|
+
# 0.0.4 (15 February 2022)
|
7
|
+
|
8
|
+
- adds `BarCode` subclass of `RecordId`, to look up bibliographic records by
|
9
|
+
item barcode. Note that since barcodes have no consistent format, `BarCode`
|
10
|
+
objects need to be constructed deliberately with `BarCode#new`, not with
|
11
|
+
`RecordId#parse`.
|
12
|
+
|
13
|
+
# 0.0.3 (3 February 2022)
|
14
|
+
|
15
|
+
- use `local_field_996` instead of `other_system_number` when making SRU queries
|
16
|
+
for Millennium records
|
17
|
+
- accept leading upper-case B in bib numbers
|
18
|
+
|
1
19
|
# 0.0.2 (26 January 2022)
|
2
20
|
|
3
21
|
- update to [berkeley_library-marc](https://github.com/BerkeleyLibrary/marc) 0.3.1
|
data/README.md
CHANGED
@@ -41,10 +41,34 @@ options to either:
|
|
41
41
|
|
42
42
|
## Retrieving Alma records
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
[SRU](
|
47
|
-
|
44
|
+
### Via `SRU`
|
45
|
+
|
46
|
+
The [`SRU`](lib/berkeley_library/alma/sru.rb) module encapsulates Alma
|
47
|
+
[SRU](https://developers.exlibrisgroup.com/alma/integrations/sru/) queries.
|
48
|
+
|
49
|
+
Retrieving MARC records:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
reader = BerkeleyLibrary::Alma::SRU.get_marc_records('991005668209706532', '991005668359706532')
|
53
|
+
# => #<MARC::XMLReader:0x0000000135b940e8 @freeze=false, @handle=#<StringIO:0x0000000135b94160>...
|
54
|
+
```
|
55
|
+
|
56
|
+
Making arbitrary SRU queries:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
BerkeleyLibrary::Alma::SRU.make_sru_query('alma.other_system_number=UCB-b123230470-01ucs_ber')
|
60
|
+
# => "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><searchRetrieveResponse xmlns=...
|
61
|
+
```
|
62
|
+
|
63
|
+
### Via `RecordId`
|
64
|
+
|
65
|
+
In addition, individual records can be retrieved from an instance of the
|
66
|
+
[`RecordId`](lib/berkeley_library/alma/record_id.rb) class, which encapsulates
|
67
|
+
an Alma MMS ID, Millennium bib number, or item barcode.
|
68
|
+
|
69
|
+
#### Initializing `RecordID` objects
|
70
|
+
|
71
|
+
Alma MMS ID:
|
48
72
|
|
49
73
|
```ruby
|
50
74
|
mms_id_str = '991054360089706532'
|
@@ -52,7 +76,7 @@ record_id = BerkeleyLibrary::Alma::RecordId.parse(mms_id_str)
|
|
52
76
|
# => #<BerkeleyLibrary::Alma::MMSID:0x0000000138949830 @institution="6532", @mms_id="991054360089706532", @type_prefix="99", @unique_part="105436008970">
|
53
77
|
```
|
54
78
|
|
55
|
-
|
79
|
+
Millennium bib number:
|
56
80
|
|
57
81
|
```ruby
|
58
82
|
bib_number_str = 'b11082434'
|
@@ -60,6 +84,20 @@ record_id = BerkeleyLibrary::Alma::RecordId.parse(bib_number_str)
|
|
60
84
|
# => #<BerkeleyLibrary::Alma::BibNumber:0x0000000118815038 @check_str="9", @digit_str="11082434">
|
61
85
|
```
|
62
86
|
|
87
|
+
Item barcode:
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
barcode_str = 'C084093187'
|
91
|
+
barcode = BerkeleyLibrary::Alma::BarCode.new(barcode_str)
|
92
|
+
# => #<BerkeleyLibrary::Alma::BarCode:0x000000013fac4c08 @barcode="C084093187">
|
93
|
+
```
|
94
|
+
|
95
|
+
⚠️ Note that because of the free-form nature of barcodes, they cannot be auto-detected,
|
96
|
+
and hence are **not** supported by the `RecordId#parse` method; they must be instantiated
|
97
|
+
directly.
|
98
|
+
|
99
|
+
#### Using `RecordId` objects to make SRU queries
|
100
|
+
|
63
101
|
Given a `RecordId` object, you can get the SRU query URI for the corresponding MARC record:
|
64
102
|
|
65
103
|
```ruby
|
data/bin/alma-mms-lookup
CHANGED
@@ -25,9 +25,7 @@ require 'berkeley_library/alma'
|
|
25
25
|
# Configuration
|
26
26
|
|
27
27
|
# Configure Alma URLs etc.
|
28
|
-
BerkeleyLibrary::Alma.
|
29
|
-
Config.default!
|
30
|
-
end
|
28
|
+
BerkeleyLibrary::Alma::Config.default!
|
31
29
|
|
32
30
|
# Set log level
|
33
31
|
BerkeleyLibrary::Logging.logger.level = Logger::Severity::WARN
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'berkeley_library/alma/record_id'
|
2
|
+
|
3
|
+
module BerkeleyLibrary
|
4
|
+
module Alma
|
5
|
+
# {RecordId} subclass representing an item barcode.
|
6
|
+
class BarCode
|
7
|
+
include RecordId
|
8
|
+
|
9
|
+
attr_reader :barcode
|
10
|
+
|
11
|
+
# Initialize a barcode. Since we purchase barcodes of varied formats and accept vendor
|
12
|
+
# barcodes as well we are only validating whether it's a string or not.
|
13
|
+
def initialize(barcode)
|
14
|
+
string?(barcode)
|
15
|
+
@barcode = barcode
|
16
|
+
end
|
17
|
+
|
18
|
+
# Returns the SRU query value for this Barcode.
|
19
|
+
#
|
20
|
+
# @return [String] the Barcode query value
|
21
|
+
def sru_query_value
|
22
|
+
"alma.barcode=#{@barcode}"
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def string?(barcode)
|
28
|
+
raise ArgumentError, "Barcode must be a string: #{barcode.inspect}" unless barcode.is_a?(String)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -18,7 +18,8 @@ module BerkeleyLibrary
|
|
18
18
|
# ------------------------------------------------------------
|
19
19
|
# Initializer
|
20
20
|
|
21
|
-
# Initializes a new {BibNumber} from the specified string.
|
21
|
+
# Initializes a new {BibNumber} from the specified string. Note that a bib number
|
22
|
+
# may start with an upper-case B, but it will be converted to lower case.
|
22
23
|
#
|
23
24
|
# @param [String] bib_number The bib number, with or without check digit
|
24
25
|
# @raise [ArgumentError] if the specified string is not an 8- or 9-digit bib number,
|
@@ -51,9 +52,7 @@ module BerkeleyLibrary
|
|
51
52
|
#
|
52
53
|
# @return [String] the SRU query value
|
53
54
|
def sru_query_value
|
54
|
-
|
55
|
-
other_system_number = "UCB-#{self}-#{Config.alma_institution_code.downcase}"
|
56
|
-
"alma.other_system_number=#{other_system_number}"
|
55
|
+
"alma.local_field_996=#{full_bib}"
|
57
56
|
end
|
58
57
|
|
59
58
|
# ------------------------------------------------------------
|
@@ -4,7 +4,7 @@ module BerkeleyLibrary
|
|
4
4
|
module Alma
|
5
5
|
module Constants
|
6
6
|
# 'x' represents a calculated check digit of 10; 'a' is a wildcard
|
7
|
-
MILLENNIUM_RECORD_RE = /^
|
7
|
+
MILLENNIUM_RECORD_RE = /^[Bb](?<digits>[0-9]{8})(?<check>[0-9ax])?$/.freeze
|
8
8
|
|
9
9
|
# '99' is the Alma prefix for a Metadata Management System ID
|
10
10
|
# see https://knowledge.exlibrisgroup.com/Alma/Product_Documentation/010Alma_Online_Help_(English)/Metadata_Management/005Introduction_to_Metadata_Management/020Record_Numbers
|
@@ -7,7 +7,7 @@ module BerkeleyLibrary
|
|
7
7
|
SUMMARY = 'Alma/Primo utilities for the UC Berkeley Library'.freeze
|
8
8
|
DESCRIPTION = 'A gem providing Alma/Primo-related utility code for the UC Berkeley Library'.freeze
|
9
9
|
LICENSE = 'MIT'.freeze
|
10
|
-
VERSION = '0.0.
|
10
|
+
VERSION = '0.0.5'.freeze
|
11
11
|
HOMEPAGE = 'https://github.com/BerkeleyLibrary/alma'.freeze
|
12
12
|
end
|
13
13
|
end
|
@@ -2,6 +2,7 @@ require 'berkeley_library/logging'
|
|
2
2
|
require 'berkeley_library/marc'
|
3
3
|
require 'berkeley_library/util/uris'
|
4
4
|
require 'berkeley_library/alma/constants'
|
5
|
+
require 'berkeley_library/alma/sru'
|
5
6
|
|
6
7
|
module BerkeleyLibrary
|
7
8
|
module Alma
|
@@ -22,6 +23,9 @@ module BerkeleyLibrary
|
|
22
23
|
# also accepts a {RecordId} and simply returns it, so it can be used in
|
23
24
|
# situations where it may not be clear whether the ID has already been parsed.
|
24
25
|
#
|
26
|
+
# **Note:** Use the {BarCode} class for barcodes, which don't have a consistent
|
27
|
+
# format and hence can't be auto-detected.
|
28
|
+
#
|
25
29
|
# @param id [String, RecordId] the ID to parse
|
26
30
|
# @return [RecordId, nil] an {MMSID} or {BibNumber}, depending on the type of ID,
|
27
31
|
# or `nil` if the specified `id` is neither an MMS ID nor a bib number
|
@@ -44,13 +48,7 @@ module BerkeleyLibrary
|
|
44
48
|
#
|
45
49
|
# @return [URI] the MARC URI
|
46
50
|
def marc_uri
|
47
|
-
|
48
|
-
'version' => '1.2',
|
49
|
-
'operation' => 'searchRetrieve',
|
50
|
-
'query' => sru_query_value
|
51
|
-
)
|
52
|
-
|
53
|
-
URIs.append(Config.alma_sru_base_uri, '?', query_string)
|
51
|
+
SRU.sru_query_uri(sru_query_value)
|
54
52
|
end
|
55
53
|
|
56
54
|
# Makes an SRU query for this record and returns a MARC record, or nil if the
|
@@ -62,8 +60,12 @@ module BerkeleyLibrary
|
|
62
60
|
# @return [MARC::Record, nil] the MARC record
|
63
61
|
# rubocop:disable Naming/AccessorMethodName
|
64
62
|
def get_marc_record
|
65
|
-
|
66
|
-
|
63
|
+
unless (marc_reader = SRU.marc_records_for(sru_query_value))
|
64
|
+
logger.warn("GET #{marc_uri} did not return a MARC record")
|
65
|
+
return nil
|
66
|
+
end
|
67
|
+
|
68
|
+
logger.warn("GET #{marc_uri} did not return a MARC record") unless (marc_record = marc_reader.first)
|
67
69
|
marc_record
|
68
70
|
end
|
69
71
|
# rubocop:enable Naming/AccessorMethodName
|
@@ -74,10 +76,7 @@ module BerkeleyLibrary
|
|
74
76
|
# @return [String, nil] the SRU query response body, or nil in the event of an error.
|
75
77
|
# rubocop:disable Naming/AccessorMethodName
|
76
78
|
def get_marc_xml
|
77
|
-
|
78
|
-
rescue RestClient::Exception => e
|
79
|
-
logger.warn("GET #{marc_uri} failed", e)
|
80
|
-
nil
|
79
|
+
SRU.make_sru_query(sru_query_value)
|
81
80
|
end
|
82
81
|
# rubocop:enable Naming/AccessorMethodName
|
83
82
|
|
@@ -95,19 +94,6 @@ module BerkeleyLibrary
|
|
95
94
|
|
96
95
|
to_s <=> other.to_s
|
97
96
|
end
|
98
|
-
|
99
|
-
# ------------------------------------------------------------
|
100
|
-
# Private methods
|
101
|
-
|
102
|
-
private
|
103
|
-
|
104
|
-
def parse_marc_xml(xml)
|
105
|
-
return unless xml
|
106
|
-
|
107
|
-
input = StringIO.new(xml.scrub)
|
108
|
-
reader = MARC::XMLReader.new(input)
|
109
|
-
reader.first
|
110
|
-
end
|
111
97
|
end
|
112
98
|
end
|
113
99
|
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'berkeley_library/alma/config'
|
3
|
+
require 'berkeley_library/alma/constants'
|
4
|
+
require 'berkeley_library/alma/record_id'
|
5
|
+
require 'berkeley_library/util/uris'
|
6
|
+
|
7
|
+
module BerkeleyLibrary
|
8
|
+
module Alma
|
9
|
+
module SRU
|
10
|
+
include BerkeleyLibrary::Logging
|
11
|
+
include Constants
|
12
|
+
|
13
|
+
class << self
|
14
|
+
include SRU
|
15
|
+
end
|
16
|
+
|
17
|
+
# Given a list of record IDs, returns the MARC records for each ID (if found).
|
18
|
+
#
|
19
|
+
# @param record_ids [Array<String, RecordId>] the record IDs to look up
|
20
|
+
# @return [MARC::XMLReader, nil] a reader for the MARC records, or nil if
|
21
|
+
# the records could not be read
|
22
|
+
def get_marc_records(*record_ids)
|
23
|
+
# noinspection RubyMismatchedReturnType
|
24
|
+
parsed_ids = record_ids.filter_map { |id| RecordId.parse(id) }
|
25
|
+
raise ArgumentError, "Argument #{record_ids.inspect} contain no valid record IDs" if parsed_ids.empty?
|
26
|
+
|
27
|
+
sru_query_value = parsed_ids.map(&:sru_query_value).join(' or ')
|
28
|
+
SRU.marc_records_for(sru_query_value)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns a URI for retrieving records for the specified query
|
32
|
+
# via SRU. Requires {Config#alma_sru_base_uri} to be set.
|
33
|
+
#
|
34
|
+
# @return [URI] the MARC URI
|
35
|
+
def sru_query_uri(sru_query_value)
|
36
|
+
query_string = URI.encode_www_form(
|
37
|
+
'version' => '1.2',
|
38
|
+
'operation' => 'searchRetrieve',
|
39
|
+
'query' => sru_query_value
|
40
|
+
)
|
41
|
+
|
42
|
+
Util::URIs.append(Config.alma_sru_base_uri, '?', query_string)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Makes an SRU query for the specified query value and returns the query response
|
46
|
+
# as a string.
|
47
|
+
#
|
48
|
+
# @param query_value [String] the value of the SRU query parameter
|
49
|
+
# @return [String, nil] the SRU query response body, or nil in the event of an error.
|
50
|
+
def make_sru_query(query_value)
|
51
|
+
uri = sru_query_uri(query_value)
|
52
|
+
do_get(uri)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Makes an SRU query for the specified query value and returns the query response
|
56
|
+
# as MARC records.
|
57
|
+
#
|
58
|
+
# @param query_value [String] the value of the SRU query parameter
|
59
|
+
# @return [MARC::XMLReader, nil] a reader for the MARC records, or nil if
|
60
|
+
# the records could not be read
|
61
|
+
def marc_records_for(query_value)
|
62
|
+
return unless (xml = make_sru_query(query_value))
|
63
|
+
|
64
|
+
input = StringIO.new(xml.scrub)
|
65
|
+
MARC::XMLReader.new(input, parser: 'nokogiri')
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
def do_get(uri)
|
71
|
+
# TODO: can we get the XML as an IO rather than as a string?
|
72
|
+
Util::URIs.get(uri, headers: { user_agent: DEFAULT_USER_AGENT })
|
73
|
+
rescue RestClient::Exception => e
|
74
|
+
logger.warn("GET #{uri} failed", e)
|
75
|
+
nil
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,299 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?><searchRetrieveResponse xmlns="http://www.loc.gov/zing/srw/">
|
2
|
+
<version>1.2</version>
|
3
|
+
<numberOfRecords>1</numberOfRecords>
|
4
|
+
<records>
|
5
|
+
<record>
|
6
|
+
<recordSchema>marcxml</recordSchema>
|
7
|
+
<recordPacking>xml</recordPacking>
|
8
|
+
<recordData>
|
9
|
+
<record xmlns="http://www.loc.gov/MARC21/slim">
|
10
|
+
<leader>03480cgm a2200781Mi 4500</leader>
|
11
|
+
<controlfield tag="001">991039354509706532</controlfield>
|
12
|
+
<controlfield tag="005">20210615124013.0</controlfield>
|
13
|
+
<controlfield tag="007">vd cvaizs</controlfield>
|
14
|
+
<controlfield tag="008">050601p19971996quc135 vleng d</controlfield>
|
15
|
+
<datafield ind1="1" ind2=" " tag="024">
|
16
|
+
<subfield code="a">774212007033</subfield>
|
17
|
+
</datafield>
|
18
|
+
<datafield ind1="4" ind2="2" tag="028">
|
19
|
+
<subfield code="a">20070</subfield>
|
20
|
+
<subfield code="b">Seville Pictures</subfield>
|
21
|
+
</datafield>
|
22
|
+
<datafield ind1=" " ind2=" " tag="035">
|
23
|
+
<subfield code="a">(OCoLC)613118288</subfield>
|
24
|
+
<subfield code="z">(OCoLC)800045975</subfield>
|
25
|
+
<subfield code="z">(OCoLC)811619021</subfield>
|
26
|
+
</datafield>
|
27
|
+
<datafield ind1=" " ind2=" " tag="035">
|
28
|
+
<subfield code="a">(CLU)8266514-ucladb-Voyager</subfield>
|
29
|
+
</datafield>
|
30
|
+
<datafield ind1=" " ind2=" " tag="035">
|
31
|
+
<subfield code="a">(EXLNZ-01UCS_NETWORK)9912724001006531</subfield>
|
32
|
+
</datafield>
|
33
|
+
<datafield ind1=" " ind2=" " tag="040">
|
34
|
+
<subfield code="a">W2U</subfield>
|
35
|
+
<subfield code="b">eng</subfield>
|
36
|
+
<subfield code="c">W2U</subfield>
|
37
|
+
<subfield code="d">OCLCF</subfield>
|
38
|
+
<subfield code="d">OCLCO</subfield>
|
39
|
+
<subfield code="d">TOH</subfield>
|
40
|
+
<subfield code="d">GK8</subfield>
|
41
|
+
<subfield code="d">OCL</subfield>
|
42
|
+
<subfield code="d">OCLCQ</subfield>
|
43
|
+
<subfield code="d">OCLCO</subfield>
|
44
|
+
<subfield code="e">rda</subfield>
|
45
|
+
<subfield code="d">CDS</subfield>
|
46
|
+
<subfield code="d">OCLCA</subfield>
|
47
|
+
</datafield>
|
48
|
+
<datafield ind1="1" ind2=" " tag="041">
|
49
|
+
<subfield code="a">eng</subfield>
|
50
|
+
<subfield code="a">fre</subfield>
|
51
|
+
</datafield>
|
52
|
+
<datafield ind1=" " ind2=" " tag="043">
|
53
|
+
<subfield code="a">n-us---</subfield>
|
54
|
+
</datafield>
|
55
|
+
<datafield ind1=" " ind2=" " tag="044">
|
56
|
+
<subfield code="a">quc</subfield>
|
57
|
+
<subfield code="a">xxu</subfield>
|
58
|
+
<subfield code="a">fr</subfield>
|
59
|
+
</datafield>
|
60
|
+
<datafield ind1=" " ind2=" " tag="046">
|
61
|
+
<subfield code="k">1996</subfield>
|
62
|
+
</datafield>
|
63
|
+
<datafield ind1="1" ind2="4" tag="050">
|
64
|
+
<subfield code="a">PN1997</subfield>
|
65
|
+
<subfield code="b">.L735 1997</subfield>
|
66
|
+
</datafield>
|
67
|
+
<datafield ind1=" " ind2=" " tag="090">
|
68
|
+
<subfield code="b">DVD 3916</subfield>
|
69
|
+
<subfield code="9">LOCAL</subfield>
|
70
|
+
</datafield>
|
71
|
+
<datafield ind1="0" ind2="0" tag="245">
|
72
|
+
<subfield code="a">Lost highway /</subfield>
|
73
|
+
<subfield code="c">October Films presents a CIBY 2000/Asymmetrical production ; a David Lynch film ; produced by Deepak Nayar, Tom Sternberg, Mahy Sweeney ; written by David Lynch & Barry Gifford ; directed by David Lynch.</subfield>
|
74
|
+
</datafield>
|
75
|
+
<datafield ind1=" " ind2=" " tag="257">
|
76
|
+
<subfield code="a">United States</subfield>
|
77
|
+
<subfield code="a">France</subfield>
|
78
|
+
<subfield code="2">naf</subfield>
|
79
|
+
</datafield>
|
80
|
+
<datafield ind1=" " ind2="1" tag="264">
|
81
|
+
<subfield code="a">[Montreal] :</subfield>
|
82
|
+
<subfield code="b">Seville Pictures,</subfield>
|
83
|
+
<subfield code="c">1997.</subfield>
|
84
|
+
</datafield>
|
85
|
+
<datafield ind1=" " ind2=" " tag="300">
|
86
|
+
<subfield code="a">1 videodisc (135 min.) :</subfield>
|
87
|
+
<subfield code="b">sound, color ;</subfield>
|
88
|
+
<subfield code="c">4 3/4 in.</subfield>
|
89
|
+
</datafield>
|
90
|
+
<datafield ind1=" " ind2=" " tag="336">
|
91
|
+
<subfield code="a">two-dimensional moving image</subfield>
|
92
|
+
<subfield code="b">tdi</subfield>
|
93
|
+
<subfield code="2">rdacontent</subfield>
|
94
|
+
</datafield>
|
95
|
+
<datafield ind1=" " ind2=" " tag="337">
|
96
|
+
<subfield code="a">video</subfield>
|
97
|
+
<subfield code="b">v</subfield>
|
98
|
+
<subfield code="2">rdamedia</subfield>
|
99
|
+
</datafield>
|
100
|
+
<datafield ind1=" " ind2=" " tag="338">
|
101
|
+
<subfield code="a">videodisc</subfield>
|
102
|
+
<subfield code="b">vd</subfield>
|
103
|
+
<subfield code="2">rdacarrier</subfield>
|
104
|
+
</datafield>
|
105
|
+
<datafield ind1=" " ind2=" " tag="344">
|
106
|
+
<subfield code="a">digital</subfield>
|
107
|
+
<subfield code="b">optical</subfield>
|
108
|
+
<subfield code="g">stereo</subfield>
|
109
|
+
</datafield>
|
110
|
+
<datafield ind1=" " ind2=" " tag="346">
|
111
|
+
<subfield code="b">NTSC</subfield>
|
112
|
+
</datafield>
|
113
|
+
<datafield ind1=" " ind2=" " tag="347">
|
114
|
+
<subfield code="a">video file</subfield>
|
115
|
+
<subfield code="b">DVD video</subfield>
|
116
|
+
<subfield code="e">Region 1</subfield>
|
117
|
+
<subfield code="2">rda</subfield>
|
118
|
+
</datafield>
|
119
|
+
<datafield ind1=" " ind2=" " tag="380">
|
120
|
+
<subfield code="a">Motion picture</subfield>
|
121
|
+
</datafield>
|
122
|
+
<datafield ind1=" " ind2=" " tag="500">
|
123
|
+
<subfield code="a">Pan and scan version.</subfield>
|
124
|
+
</datafield>
|
125
|
+
<datafield ind1=" " ind2=" " tag="500">
|
126
|
+
<subfield code="a">Special features include: theatrical trailer; interactive menus; scene selection.</subfield>
|
127
|
+
</datafield>
|
128
|
+
<datafield ind1=" " ind2=" " tag="500">
|
129
|
+
<subfield code="a">Originally released as a motion picture in 1996.</subfield>
|
130
|
+
</datafield>
|
131
|
+
<datafield ind1=" " ind2=" " tag="508">
|
132
|
+
<subfield code="a">Music, Angelo Badalamenti ; editor, Mary Sweeney ; director of photography, Peter Deming.</subfield>
|
133
|
+
</datafield>
|
134
|
+
<datafield ind1="1" ind2=" " tag="511">
|
135
|
+
<subfield code="a">Bill Pullman, Patricia Arquette, Balthazar Getty, Robert Blake, Natasha Gregson Wagner, Gary Busey, Robert Loggia.</subfield>
|
136
|
+
</datafield>
|
137
|
+
<datafield ind1=" " ind2=" " tag="520">
|
138
|
+
<subfield code="a">A successful jazz musician whose marriage is on the rocks, a man in black who threatens to expose him, a young mechanic with links to a mobster, and the mobster's moll are all riders on the lost highway, trapped in their worlds of desire, destiny and unknown destination where the truth is always a short way further down the road.</subfield>
|
139
|
+
</datafield>
|
140
|
+
<datafield ind1="8" ind2=" " tag="521">
|
141
|
+
<subfield code="a">Canadian home video rating: R.</subfield>
|
142
|
+
</datafield>
|
143
|
+
<datafield ind1=" " ind2=" " tag="538">
|
144
|
+
<subfield code="a">DVD, Dolby stereo; Region 1; NTSC.</subfield>
|
145
|
+
</datafield>
|
146
|
+
<datafield ind1=" " ind2=" " tag="546">
|
147
|
+
<subfield code="a">In English or dubbed French.</subfield>
|
148
|
+
</datafield>
|
149
|
+
<datafield ind1=" " ind2="0" tag="650">
|
150
|
+
<subfield code="a">Jazz musicians</subfield>
|
151
|
+
<subfield code="z">United States</subfield>
|
152
|
+
<subfield code="v">Drama.</subfield>
|
153
|
+
</datafield>
|
154
|
+
<datafield ind1=" " ind2="7" tag="650">
|
155
|
+
<subfield code="a">Jazz musicians.</subfield>
|
156
|
+
<subfield code="2">fast</subfield>
|
157
|
+
<subfield code="0">(OCoLC)fst00982205</subfield>
|
158
|
+
</datafield>
|
159
|
+
<datafield ind1=" " ind2="7" tag="651">
|
160
|
+
<subfield code="a">United States.</subfield>
|
161
|
+
<subfield code="2">fast</subfield>
|
162
|
+
<subfield code="0">(OCoLC)fst01204155</subfield>
|
163
|
+
</datafield>
|
164
|
+
<datafield ind1=" " ind2="7" tag="655">
|
165
|
+
<subfield code="a">Drama.</subfield>
|
166
|
+
<subfield code="2">fast</subfield>
|
167
|
+
<subfield code="0">(OCoLC)fst01423879</subfield>
|
168
|
+
</datafield>
|
169
|
+
<datafield ind1=" " ind2="7" tag="655">
|
170
|
+
<subfield code="a">Feature films.</subfield>
|
171
|
+
<subfield code="2">fast</subfield>
|
172
|
+
<subfield code="0">(OCoLC)fst01710384</subfield>
|
173
|
+
</datafield>
|
174
|
+
<datafield ind1=" " ind2="7" tag="655">
|
175
|
+
<subfield code="a">Fiction films.</subfield>
|
176
|
+
<subfield code="2">fast</subfield>
|
177
|
+
<subfield code="0">(OCoLC)fst01710264</subfield>
|
178
|
+
</datafield>
|
179
|
+
<datafield ind1=" " ind2="7" tag="655">
|
180
|
+
<subfield code="a">Feature films.</subfield>
|
181
|
+
<subfield code="2">lcgft</subfield>
|
182
|
+
</datafield>
|
183
|
+
<datafield ind1=" " ind2="7" tag="655">
|
184
|
+
<subfield code="a">Fiction films.</subfield>
|
185
|
+
<subfield code="2">lcgft</subfield>
|
186
|
+
</datafield>
|
187
|
+
<datafield ind1="1" ind2=" " tag="700">
|
188
|
+
<subfield code="a">Pullman, Bill,</subfield>
|
189
|
+
<subfield code="e">actor.</subfield>
|
190
|
+
</datafield>
|
191
|
+
<datafield ind1="1" ind2=" " tag="700">
|
192
|
+
<subfield code="a">Arquette, Patricia,</subfield>
|
193
|
+
<subfield code="d">1968-</subfield>
|
194
|
+
<subfield code="e">actor.</subfield>
|
195
|
+
</datafield>
|
196
|
+
<datafield ind1="1" ind2=" " tag="700">
|
197
|
+
<subfield code="a">Getty, Balthazar,</subfield>
|
198
|
+
<subfield code="e">actor.</subfield>
|
199
|
+
</datafield>
|
200
|
+
<datafield ind1="1" ind2=" " tag="700">
|
201
|
+
<subfield code="a">Blake, Robert,</subfield>
|
202
|
+
<subfield code="d">1933-</subfield>
|
203
|
+
<subfield code="e">actor.</subfield>
|
204
|
+
</datafield>
|
205
|
+
<datafield ind1="1" ind2=" " tag="700">
|
206
|
+
<subfield code="a">Wagner, Natasha Gregson,</subfield>
|
207
|
+
<subfield code="d">1970-</subfield>
|
208
|
+
<subfield code="e">actor.</subfield>
|
209
|
+
</datafield>
|
210
|
+
<datafield ind1="1" ind2=" " tag="700">
|
211
|
+
<subfield code="a">Busey, Gary,</subfield>
|
212
|
+
<subfield code="e">actor.</subfield>
|
213
|
+
</datafield>
|
214
|
+
<datafield ind1="1" ind2=" " tag="700">
|
215
|
+
<subfield code="a">Loggia, Robert,</subfield>
|
216
|
+
<subfield code="e">actor.</subfield>
|
217
|
+
</datafield>
|
218
|
+
<datafield ind1="1" ind2=" " tag="700">
|
219
|
+
<subfield code="a">Nayar, Deepak.</subfield>
|
220
|
+
<subfield code="e">film producer.</subfield>
|
221
|
+
</datafield>
|
222
|
+
<datafield ind1="1" ind2=" " tag="700">
|
223
|
+
<subfield code="a">Sternberg, Tom.</subfield>
|
224
|
+
<subfield code="e">film producer.</subfield>
|
225
|
+
</datafield>
|
226
|
+
<datafield ind1="1" ind2=" " tag="700">
|
227
|
+
<subfield code="a">Sweeney, Mahy.</subfield>
|
228
|
+
<subfield code="e">film produer</subfield>
|
229
|
+
</datafield>
|
230
|
+
<datafield ind1="1" ind2=" " tag="700">
|
231
|
+
<subfield code="a">Lynch, David,</subfield>
|
232
|
+
<subfield code="d">1946-</subfield>
|
233
|
+
<subfield code="e">screenwriter,</subfield>
|
234
|
+
<subfield code="e">director.</subfield>
|
235
|
+
</datafield>
|
236
|
+
<datafield ind1="1" ind2=" " tag="700">
|
237
|
+
<subfield code="a">Gifford, Barry,</subfield>
|
238
|
+
<subfield code="d">1946-</subfield>
|
239
|
+
<subfield code="e">screenwriter.</subfield>
|
240
|
+
</datafield>
|
241
|
+
<datafield ind1="2" ind2=" " tag="710">
|
242
|
+
<subfield code="a">Séville Pictures.</subfield>
|
243
|
+
</datafield>
|
244
|
+
<datafield ind1="2" ind2=" " tag="710">
|
245
|
+
<subfield code="a">Asymmetrical (Firm)</subfield>
|
246
|
+
</datafield>
|
247
|
+
<datafield ind1="2" ind2=" " tag="710">
|
248
|
+
<subfield code="a">CIBY 2000 (Firm)</subfield>
|
249
|
+
</datafield>
|
250
|
+
<datafield ind1="2" ind2=" " tag="710">
|
251
|
+
<subfield code="a">October Films.</subfield>
|
252
|
+
</datafield>
|
253
|
+
<datafield ind1="4" ind2="2" tag="956">
|
254
|
+
<subfield code="z">Credits from Internet Movie Database</subfield>
|
255
|
+
<subfield code="u">http://www.imdb.com/title/tt0116922/</subfield>
|
256
|
+
<subfield code="9">LOCAL</subfield>
|
257
|
+
</datafield>
|
258
|
+
<datafield ind1=" " ind2=" " tag="968">
|
259
|
+
<subfield code="a">Reclvl: f Addate: 050601 Addid: SMI Moddate: 090214 Modid: MRC</subfield>
|
260
|
+
<subfield code="9">LOCAL</subfield>
|
261
|
+
</datafield>
|
262
|
+
<datafield ind1=" " ind2=" " tag="996">
|
263
|
+
<subfield code="e">GLADN151847889</subfield>
|
264
|
+
<subfield code="9">LOCAL</subfield>
|
265
|
+
</datafield>
|
266
|
+
<datafield ind1=" " ind2=" " tag="996">
|
267
|
+
<subfield code="a">b111084751</subfield>
|
268
|
+
<subfield code="b">Updated: 06-14-21</subfield>
|
269
|
+
<subfield code="c">Created: 03-17-09</subfield>
|
270
|
+
<subfield code="d">CatDate: 06-01-05</subfield>
|
271
|
+
<subfield code="9">LOCAL</subfield>
|
272
|
+
</datafield>
|
273
|
+
<datafield ind1=" " ind2=" " tag="AVA">
|
274
|
+
<subfield code="0">991039354509706532</subfield>
|
275
|
+
<subfield code="8">22725145850006532</subfield>
|
276
|
+
<subfield code="a">01UCS_BER</subfield>
|
277
|
+
<subfield code="b">MRC</subfield>
|
278
|
+
<subfield code="c">Media Resources Center</subfield>
|
279
|
+
<subfield code="d">DVD 3916</subfield>
|
280
|
+
<subfield code="e">available</subfield>
|
281
|
+
<subfield code="f">1</subfield>
|
282
|
+
<subfield code="g">0</subfield>
|
283
|
+
<subfield code="i">UCB_Campus</subfield>
|
284
|
+
<subfield code="j">mc</subfield>
|
285
|
+
<subfield code="k">8</subfield>
|
286
|
+
<subfield code="p">1</subfield>
|
287
|
+
<subfield code="q">Media Resources Center</subfield>
|
288
|
+
</datafield>
|
289
|
+
</record>
|
290
|
+
</recordData>
|
291
|
+
<recordIdentifier>991039354509706532</recordIdentifier>
|
292
|
+
<recordPosition>1</recordPosition>
|
293
|
+
</record>
|
294
|
+
</records>
|
295
|
+
<extraResponseData xmlns:xb="http://www.exlibris.com/repository/search/xmlbeans/">
|
296
|
+
<xb:exact>true</xb:exact>
|
297
|
+
<xb:responseDate>2022-02-10T12:40:32-0800</xb:responseDate>
|
298
|
+
</extraResponseData>
|
299
|
+
</searchRetrieveResponse>
|
@@ -0,0 +1,109 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?><searchRetrieveResponse xmlns="http://www.loc.gov/zing/srw/">
|
2
|
+
<version>1.2</version>
|
3
|
+
<numberOfRecords>2</numberOfRecords>
|
4
|
+
<records>
|
5
|
+
<record>
|
6
|
+
<recordSchema>marcxml</recordSchema>
|
7
|
+
<recordPacking>xml</recordPacking>
|
8
|
+
<recordData>
|
9
|
+
<record xmlns="http://www.loc.gov/MARC21/slim">
|
10
|
+
<leader>00307nam a2200085 a 4500</leader>
|
11
|
+
<controlfield tag="001">991005668359706532</controlfield>
|
12
|
+
<controlfield tag="008">^^</controlfield>
|
13
|
+
<datafield ind1=" " ind2=" " tag="035">
|
14
|
+
<subfield code="a">(CUY)UCB-b207766733-01ucs_ber</subfield>
|
15
|
+
</datafield>
|
16
|
+
<datafield ind1="1" ind2=" " tag="100">
|
17
|
+
<subfield code="a">Fukazawa, Yukio,</subfield>
|
18
|
+
<subfield code="d">1924-2017.</subfield>
|
19
|
+
</datafield>
|
20
|
+
<datafield ind1="1" ind2="0" tag="245">
|
21
|
+
<subfield code="a">Blue Doors</subfield>
|
22
|
+
<subfield code="h">[graphic]</subfield>
|
23
|
+
</datafield>
|
24
|
+
<datafield ind1=" " ind2=" " tag="300">
|
25
|
+
<subfield code="a">1 relief etching and aquatint :</subfield>
|
26
|
+
<subfield code="b">col.</subfield>
|
27
|
+
</datafield>
|
28
|
+
<datafield ind1=" " ind2=" " tag="996">
|
29
|
+
<subfield code="a">b207766733</subfield>
|
30
|
+
<subfield code="b">Updated: 01-09-19</subfield>
|
31
|
+
<subfield code="c">Created: 11-01-13</subfield>
|
32
|
+
<subfield code="d">CatDate: - -</subfield>
|
33
|
+
<subfield code="9">LOCAL</subfield>
|
34
|
+
</datafield>
|
35
|
+
<datafield ind1=" " ind2=" " tag="AVA">
|
36
|
+
<subfield code="0">991005668359706532</subfield>
|
37
|
+
<subfield code="8">22928381510006532</subfield>
|
38
|
+
<subfield code="a">01UCS_BER</subfield>
|
39
|
+
<subfield code="b">MORR</subfield>
|
40
|
+
<subfield code="c">Morrison</subfield>
|
41
|
+
<subfield code="e">unavailable</subfield>
|
42
|
+
<subfield code="f">1</subfield>
|
43
|
+
<subfield code="g">1</subfield>
|
44
|
+
<subfield code="i">UCB_Campus</subfield>
|
45
|
+
<subfield code="j">mo</subfield>
|
46
|
+
<subfield code="k">#</subfield>
|
47
|
+
<subfield code="p">1</subfield>
|
48
|
+
<subfield code="q">Morrison Library</subfield>
|
49
|
+
</datafield>
|
50
|
+
</record>
|
51
|
+
</recordData>
|
52
|
+
<recordIdentifier>991005668359706532</recordIdentifier>
|
53
|
+
<recordPosition>1</recordPosition>
|
54
|
+
</record>
|
55
|
+
<record>
|
56
|
+
<recordSchema>marcxml</recordSchema>
|
57
|
+
<recordPacking>xml</recordPacking>
|
58
|
+
<recordData>
|
59
|
+
<record xmlns="http://www.loc.gov/MARC21/slim">
|
60
|
+
<leader>00273nam a2200085 a 4500</leader>
|
61
|
+
<controlfield tag="001">991005668209706532</controlfield>
|
62
|
+
<controlfield tag="008">^^</controlfield>
|
63
|
+
<datafield ind1=" " ind2=" " tag="035">
|
64
|
+
<subfield code="a">(CUY)UCB-b207766708-01ucs_ber</subfield>
|
65
|
+
</datafield>
|
66
|
+
<datafield ind1="1" ind2=" " tag="100">
|
67
|
+
<subfield code="a">Beutlich, Tadek.</subfield>
|
68
|
+
</datafield>
|
69
|
+
<datafield ind1="1" ind2="0" tag="245">
|
70
|
+
<subfield code="a">River</subfield>
|
71
|
+
<subfield code="h">[graphic]</subfield>
|
72
|
+
</datafield>
|
73
|
+
<datafield ind1=" " ind2=" " tag="300">
|
74
|
+
<subfield code="a">1 lithograph :</subfield>
|
75
|
+
<subfield code="b">col.</subfield>
|
76
|
+
</datafield>
|
77
|
+
<datafield ind1=" " ind2=" " tag="996">
|
78
|
+
<subfield code="a">b207766708</subfield>
|
79
|
+
<subfield code="b">Updated: 11-01-13</subfield>
|
80
|
+
<subfield code="c">Created: 11-01-13</subfield>
|
81
|
+
<subfield code="d">CatDate: - -</subfield>
|
82
|
+
<subfield code="9">LOCAL</subfield>
|
83
|
+
</datafield>
|
84
|
+
<datafield ind1=" " ind2=" " tag="AVA">
|
85
|
+
<subfield code="0">991005668209706532</subfield>
|
86
|
+
<subfield code="8">22928389410006532</subfield>
|
87
|
+
<subfield code="a">01UCS_BER</subfield>
|
88
|
+
<subfield code="b">MORR</subfield>
|
89
|
+
<subfield code="c">Morrison</subfield>
|
90
|
+
<subfield code="e">available</subfield>
|
91
|
+
<subfield code="f">1</subfield>
|
92
|
+
<subfield code="g">0</subfield>
|
93
|
+
<subfield code="i">UCB_Campus</subfield>
|
94
|
+
<subfield code="j">mo</subfield>
|
95
|
+
<subfield code="k">#</subfield>
|
96
|
+
<subfield code="p">1</subfield>
|
97
|
+
<subfield code="q">Morrison Library</subfield>
|
98
|
+
</datafield>
|
99
|
+
</record>
|
100
|
+
</recordData>
|
101
|
+
<recordIdentifier>991005668209706532</recordIdentifier>
|
102
|
+
<recordPosition>2</recordPosition>
|
103
|
+
</record>
|
104
|
+
</records>
|
105
|
+
<extraResponseData xmlns:xb="http://www.exlibris.com/repository/search/xmlbeans/">
|
106
|
+
<xb:exact>true</xb:exact>
|
107
|
+
<xb:responseDate>2022-05-04T14:31:01-0700</xb:responseDate>
|
108
|
+
</extraResponseData>
|
109
|
+
</searchRetrieveResponse>
|
File without changes
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module BerkeleyLibrary
|
4
|
+
module Alma
|
5
|
+
describe BarCode do
|
6
|
+
before(:each) do
|
7
|
+
BerkeleyLibrary::Alma.configure do
|
8
|
+
Config.alma_sru_host = 'berkeley.alma.exlibrisgroup.com'
|
9
|
+
Config.alma_institution_code = '01UCS_BER'
|
10
|
+
Config.alma_primo_host = 'search.library.berkeley.edu'
|
11
|
+
Config.alma_permalink_key = 'iqob43'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
after(:each) do
|
16
|
+
BerkeleyLibrary::Alma::Config.send(:clear!)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe :new do
|
20
|
+
bad_barcode = 1234
|
21
|
+
it "raises an error for input that's not an string" do
|
22
|
+
expect { BarCode.new(bad_barcode) }.to raise_error(ArgumentError), "#{bad_barcode}: No error raised for #{bad_barcode}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe :marc_record do
|
27
|
+
it 'returns the MARC record' do
|
28
|
+
barcode_id = 'C084093187'
|
29
|
+
stub_sru_request('alma.barcode', barcode_id)
|
30
|
+
|
31
|
+
barcode = BerkeleyLibrary::Alma::BarCode.new(barcode_id)
|
32
|
+
marc_record = barcode.get_marc_record
|
33
|
+
expect(marc_record).not_to be_nil
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'returns nil for an empty response' do
|
37
|
+
empty_sru_response = <<~XML.strip
|
38
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
39
|
+
<searchRetrieveResponse>
|
40
|
+
<version>1.2</version>
|
41
|
+
<numberOfRecords>0</numberOfRecords>
|
42
|
+
<records/>
|
43
|
+
</searchRetrieveResponse>
|
44
|
+
XML
|
45
|
+
|
46
|
+
barcode_id = '991054360089706532doesntexist'
|
47
|
+
sru_url = sru_url_for('alma.barcode', barcode_id)
|
48
|
+
stub_request(:get, sru_url).to_return(status: 200, body: empty_sru_response)
|
49
|
+
|
50
|
+
barcode = BarCode.new(barcode_id)
|
51
|
+
marc_record = barcode.get_marc_record
|
52
|
+
expect(marc_record).to be_nil
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'returns nil for an HTTP error response' do
|
56
|
+
barcode_id = '991054360089706532934j3h'
|
57
|
+
sru_url = sru_url_for('alma.barcode', barcode_id)
|
58
|
+
stub_request(:get, sru_url).to_return(status: 404)
|
59
|
+
|
60
|
+
barcode = BarCode.new(barcode_id)
|
61
|
+
marc_record = barcode.get_marc_record
|
62
|
+
expect(marc_record).to be_nil
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -40,6 +40,14 @@ module BerkeleyLibrary
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
+
it 'accepts an upper-case B, but treats it as lower case' do
|
44
|
+
raw_bib = 'B11082434'
|
45
|
+
expected_bib = 'b110824349'
|
46
|
+
bib_number = BibNumber.new(raw_bib)
|
47
|
+
expect(bib_number.full_bib).to eq(expected_bib)
|
48
|
+
expect(bib_number.to_s).to eq(expected_bib)
|
49
|
+
end
|
50
|
+
|
43
51
|
it 'produces the expected check digit' do
|
44
52
|
aggregate_failures do
|
45
53
|
expected_check_digits_by_bib.each do |bib_expected, cd_expected|
|
@@ -82,7 +90,8 @@ module BerkeleyLibrary
|
|
82
90
|
describe :marc_record do
|
83
91
|
it 'returns the MARC record' do
|
84
92
|
raw_bib_number = 'b11082434'
|
85
|
-
|
93
|
+
full_bib_number = 'b110824349'
|
94
|
+
stub_sru_request('alma.local_field_996', full_bib_number)
|
86
95
|
|
87
96
|
bib_number = BibNumber.new(raw_bib_number)
|
88
97
|
marc_record = bib_number.get_marc_record
|
@@ -58,7 +58,7 @@ module BerkeleyLibrary
|
|
58
58
|
describe :marc_record do
|
59
59
|
it 'returns the MARC record' do
|
60
60
|
raw_mms_id = '991054360089706532'
|
61
|
-
stub_sru_request(raw_mms_id)
|
61
|
+
stub_sru_request('alma.mms_id', raw_mms_id)
|
62
62
|
|
63
63
|
mms_id = MMSID.new(raw_mms_id)
|
64
64
|
marc_record = mms_id.get_marc_record
|
@@ -77,7 +77,7 @@ module BerkeleyLibrary
|
|
77
77
|
XML
|
78
78
|
|
79
79
|
raw_mms_id = '991054360089706532'
|
80
|
-
sru_url = sru_url_for(raw_mms_id)
|
80
|
+
sru_url = sru_url_for('alma.mms_id', raw_mms_id)
|
81
81
|
stub_request(:get, sru_url).to_return(status: 200, body: empty_sru_response)
|
82
82
|
|
83
83
|
mms_id = MMSID.new(raw_mms_id)
|
@@ -87,7 +87,7 @@ module BerkeleyLibrary
|
|
87
87
|
|
88
88
|
it 'returns nil for an HTTP error response' do
|
89
89
|
raw_mms_id = '991054360089706532'
|
90
|
-
sru_url = sru_url_for(raw_mms_id)
|
90
|
+
sru_url = sru_url_for('alma.mms_id', raw_mms_id)
|
91
91
|
stub_request(:get, sru_url).to_return(status: 404)
|
92
92
|
|
93
93
|
mms_id = MMSID.new(raw_mms_id)
|
@@ -36,6 +36,26 @@ module BerkeleyLibrary
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
39
|
+
|
40
|
+
describe 'SRU methods' do
|
41
|
+
before { Config.default! }
|
42
|
+
after { Config.send(:clear!) }
|
43
|
+
|
44
|
+
describe :get_marc_xml do
|
45
|
+
let(:record_id) { RecordId.parse('991054360089706532') }
|
46
|
+
let(:expected_body) { File.read('spec/data/991054360089706532-sru.xml') }
|
47
|
+
|
48
|
+
before do
|
49
|
+
sru_query_uri = record_id.marc_uri
|
50
|
+
stub_request(:get, sru_query_uri).to_return(body: expected_body)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'returns the MARC XML' do
|
54
|
+
marc_xml = record_id.get_marc_xml
|
55
|
+
expect(marc_xml).to eq(expected_body)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
39
59
|
end
|
40
60
|
end
|
41
61
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module BerkeleyLibrary
|
4
|
+
module Alma
|
5
|
+
describe SRU do
|
6
|
+
before { Config.default! }
|
7
|
+
after { Config.send(:clear!) }
|
8
|
+
|
9
|
+
describe :get_marc_records do
|
10
|
+
let(:mms_ids) { %w[991005668209706532 991005668359706532] }
|
11
|
+
|
12
|
+
before do
|
13
|
+
sru_query_value = mms_ids.map { |id| RecordId.parse(id) }.map(&:sru_query_value).join(' or ')
|
14
|
+
sru_query_uri = SRU.sru_query_uri(sru_query_value)
|
15
|
+
stub_request(:get, sru_query_uri).to_return(body: File.read('spec/data/availability-sru.xml'))
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'returns the MARC records' do
|
19
|
+
reader = SRU.get_marc_records(*mms_ids)
|
20
|
+
expect(reader).to be_a(MARC::XMLReader)
|
21
|
+
|
22
|
+
marc_records = reader.to_a
|
23
|
+
expect(marc_records.size).to eq(mms_ids.size)
|
24
|
+
expect(marc_records.map(&:record_id)).to contain_exactly(*mms_ids)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -31,26 +31,17 @@ require 'berkeley_library/alma'
|
|
31
31
|
# ------------------------------------------------------------
|
32
32
|
# Utility methods
|
33
33
|
|
34
|
-
def sru_url_for(
|
35
|
-
|
36
|
-
|
37
|
-
if BerkeleyLibrary::Alma::Constants::ALMA_RECORD_RE =~ record_id
|
38
|
-
"#{sru_url_base}alma.mms_id%3D#{record_id}"
|
39
|
-
elsif BerkeleyLibrary::Alma::Constants::MILLENNIUM_RECORD_RE =~ record_id
|
40
|
-
full_bib_number = BerkeleyLibrary::Alma::BibNumber.new(record_id).to_s
|
41
|
-
"#{sru_url_base}alma.other_system_number%3DUCB-#{full_bib_number}-01ucs_ber"
|
42
|
-
else
|
43
|
-
raise ArgumentError, "Unknown record ID type: #{record_id}"
|
44
|
-
end
|
34
|
+
def sru_url_for(index, value)
|
35
|
+
"https://berkeley.alma.exlibrisgroup.com/view/sru/01UCS_BER?version=1.2&operation=searchRetrieve&query=#{index}%3D#{value}"
|
45
36
|
end
|
46
37
|
|
47
38
|
def sru_data_path_for(record_id)
|
48
39
|
"spec/data/#{record_id}-sru.xml"
|
49
40
|
end
|
50
41
|
|
51
|
-
def stub_sru_request(
|
52
|
-
|
53
|
-
marc_xml_path = sru_data_path_for(
|
42
|
+
def stub_sru_request(index, value)
|
43
|
+
sru_url_ = sru_url_for(index, value)
|
44
|
+
marc_xml_path = sru_data_path_for(value)
|
54
45
|
|
55
|
-
stub_request(:get,
|
46
|
+
stub_request(:get, sru_url_).to_return(status: 200, body: File.read(marc_xml_path))
|
56
47
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: berkeley_library-alma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Moles
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-05-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: berkeley_library-logging
|
@@ -269,12 +269,14 @@ files:
|
|
269
269
|
- bin/alma-mms-lookup
|
270
270
|
- docker-compose.yml
|
271
271
|
- lib/berkeley_library/alma.rb
|
272
|
+
- lib/berkeley_library/alma/barcode.rb
|
272
273
|
- lib/berkeley_library/alma/bib_number.rb
|
273
274
|
- lib/berkeley_library/alma/config.rb
|
274
275
|
- lib/berkeley_library/alma/constants.rb
|
275
276
|
- lib/berkeley_library/alma/mms_id.rb
|
276
277
|
- lib/berkeley_library/alma/module_info.rb
|
277
278
|
- lib/berkeley_library/alma/record_id.rb
|
279
|
+
- lib/berkeley_library/alma/sru.rb
|
278
280
|
- rakelib/bundle.rake
|
279
281
|
- rakelib/coverage.rake
|
280
282
|
- rakelib/gem.rake
|
@@ -282,12 +284,16 @@ files:
|
|
282
284
|
- rakelib/spec.rake
|
283
285
|
- spec/.rubocop.yml
|
284
286
|
- spec/data/991054360089706532-sru.xml
|
285
|
-
- spec/data/
|
287
|
+
- spec/data/C084093187-sru.xml
|
288
|
+
- spec/data/availability-sru.xml
|
289
|
+
- spec/data/b110824349-sru.xml
|
286
290
|
- spec/data/bibs_with_check_digits.txt
|
291
|
+
- spec/lib/berkeley_library/alma/barcode_spec.rb
|
287
292
|
- spec/lib/berkeley_library/alma/bib_number_spec.rb
|
288
293
|
- spec/lib/berkeley_library/alma/config_spec.rb
|
289
294
|
- spec/lib/berkeley_library/alma/mms_id_spec.rb
|
290
295
|
- spec/lib/berkeley_library/alma/record_id_spec.rb
|
296
|
+
- spec/lib/berkeley_library/alma/sru_spec.rb
|
291
297
|
- spec/spec_helper.rb
|
292
298
|
homepage: https://github.com/BerkeleyLibrary/alma
|
293
299
|
licenses:
|
@@ -315,10 +321,14 @@ summary: Alma/Primo utilities for the UC Berkeley Library
|
|
315
321
|
test_files:
|
316
322
|
- spec/.rubocop.yml
|
317
323
|
- spec/data/991054360089706532-sru.xml
|
318
|
-
- spec/data/
|
324
|
+
- spec/data/C084093187-sru.xml
|
325
|
+
- spec/data/availability-sru.xml
|
326
|
+
- spec/data/b110824349-sru.xml
|
319
327
|
- spec/data/bibs_with_check_digits.txt
|
328
|
+
- spec/lib/berkeley_library/alma/barcode_spec.rb
|
320
329
|
- spec/lib/berkeley_library/alma/bib_number_spec.rb
|
321
330
|
- spec/lib/berkeley_library/alma/config_spec.rb
|
322
331
|
- spec/lib/berkeley_library/alma/mms_id_spec.rb
|
323
332
|
- spec/lib/berkeley_library/alma/record_id_spec.rb
|
333
|
+
- spec/lib/berkeley_library/alma/sru_spec.rb
|
324
334
|
- spec/spec_helper.rb
|