Skip to content

Commit 131f072

Browse files
jason-raitzdanschmidt5189
authored andcommitted
AP-483: Use the TIND API to retrieve records
Switches from the public `/search` endpoint to the actual `/api/v1/search` endpoint to retrieve metadata from TIND. Library consumers must set the environment variable LIT_TIND_API_KEY to a suitable TIND API token to authorize this endpoint. At some point in the past week TIND restricted the ability of non-browser/human clients to search records, necessitating this change.
1 parent df94c22 commit 131f072

File tree

10 files changed

+55
-20
lines changed

10 files changed

+55
-20
lines changed

.github/workflows/build.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111

1212
steps:
1313
- name: Check out repository
14-
uses: actions/checkout@v3
14+
uses: actions/checkout@v4
1515

1616
- name: Set up Ruby
1717
uses: ruby/setup-ruby@v1
@@ -24,7 +24,7 @@ jobs:
2424

2525
- name: Upload artifacts
2626
if: ${{ always() }}
27-
uses: actions/upload-artifact@v3
27+
uses: actions/upload-artifact@v4
2828
with:
29-
name: artifacts
29+
name: artifacts-${{ matrix.os }}-${{ matrix.ruby }}
3030
path: artifacts/**

.github/workflows/gem-push.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
packages: write
1414

1515
steps:
16-
- uses: actions/checkout@v3
16+
- uses: actions/checkout@v4
1717

1818
- name: Set up Ruby
1919
uses: ruby/setup-ruby@v1

CHANGES.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# 0.4.3 (2025-11-04)
2+
3+
- BerkeleyLibrary::AV::Metadata::Readers:TIND now uses the /api/v1/search endpoint to retrieve records. The public /search endpoint stopped working for non-browser/human clients in the past week due to TIND changes.
4+
- BerkeleyLibrary::AV::Util#do_get sources the TIND API key from ENV['LIT_TIND_API_KEY'] if it's set.
5+
16
# 0.4.2 (2024-10-10)
27

38
- Add TRANSCRIPTS to `AV::METADATA::FIELDS`
@@ -18,7 +23,7 @@
1823
- `Metadata#player_link_text`
1924
- `Metadata#player_url`
2025
- Remove the following constants:
21-
- `AV::Constants::RESTRICTIONS_CALNET`
26+
- `AV::Constants::RESTRICTIONS_CALNET`
2227
- `AV::Constants::RESTRICTIONS_UCB_IP`
2328
- `AV::Constants::RESTRICTIONS`
2429
- `AV::Constants::RESTRICTIONS_NONE`

lib/berkeley_library/av/core/module_info.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class ModuleInfo
88
SUMMARY = 'UC Berkeley Library audio/video core code'.freeze
99
DESCRIPTION = 'Gem for UC Berkeley Library shared audio/video code'.freeze
1010
LICENSE = 'MIT'.freeze
11-
VERSION = '0.4.2'.freeze
11+
VERSION = '0.4.3'.freeze
1212
HOMEPAGE = 'https://github.com/BerkeleyLibrary/av-core'.freeze
1313

1414
private_class_method :new

lib/berkeley_library/av/metadata/readers/tind.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ def marc_uri_for(record_id)
2222
id_field = id_field_for(record_id)
2323
query_string = URI.encode_www_form(
2424
'p' => "#{id_field}:\"#{record_id}\"",
25-
'of' => 'xm'
25+
'format' => 'xml'
2626
)
27-
URIs.append(base_uri, 'search', '?', query_string)
27+
URIs.append(base_uri, 'api/v1/search', '?', query_string)
2828
end
2929

3030
protected

lib/berkeley_library/av/util.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ module Util
1212
DEFAULT_USER_AGENT = "#{Core::ModuleInfo::NAME} #{Core::ModuleInfo::VERSION} (#{Core::ModuleInfo::HOMEPAGE})".freeze
1313

1414
def do_get(uri, ignore_errors: false)
15-
body = URIs.get(uri, headers: { user_agent: DEFAULT_USER_AGENT })
15+
headers = { user_agent: DEFAULT_USER_AGENT }
16+
if uri.to_s.start_with?(BerkeleyLibrary::AV::Config.tind_base_uri.to_s) && ENV['LIT_TIND_API_KEY']
17+
headers[:authorization] = "Token #{ENV['LIT_TIND_API_KEY']}"
18+
end
19+
body = URIs.get(uri, headers:)
1620
body && body.scrub
1721
rescue RestClient::Exception
1822
raise unless ignore_errors

spec/lib/berkeley_library/av/metadata/metadata_spec.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ module AV
183183
it 'injects a TIND URL if not present (1/2)' do
184184
tind_035 = '(miscmat)00615'
185185
marc_xml = File.read("spec/data/record-#{tind_035}.xml")
186-
search_url = "https://digicoll.lib.berkeley.edu/search?p=035__a%3A%22#{CGI.escape(tind_035)}%22&of=xm"
186+
search_url = "https://digicoll.lib.berkeley.edu/api/v1/search?p=035__a%3A%22#{CGI.escape(tind_035)}%22&format=xml"
187187
stub_request(:get, search_url).to_return(status: 200, body: marc_xml)
188188
metadata = Metadata.for_record(record_id: tind_035)
189189

@@ -200,7 +200,7 @@ module AV
200200
it 'injects a TIND URL if not present (2/2)' do
201201
tind_035 = 'physcolloquia-bk00169017b'
202202
marc_xml = File.read("spec/data/record-#{tind_035}.xml")
203-
search_url = "https://digicoll.lib.berkeley.edu/search?p=035__a%3A%22#{CGI.escape(tind_035)}%22&of=xm"
203+
search_url = "https://digicoll.lib.berkeley.edu/api/v1/search?p=035__a%3A%22#{CGI.escape(tind_035)}%22&format=xml"
204204
stub_request(:get, search_url).to_return(status: 200, body: marc_xml)
205205
metadata = Metadata.for_record(record_id: tind_035)
206206

@@ -218,7 +218,7 @@ module AV
218218
it 'works for TIND records with OskiCat URLs' do
219219
tind_035 = '(pacradio)00107'
220220
marc_xml = File.read("spec/data/record-#{tind_035}.xml")
221-
search_url = "https://digicoll.lib.berkeley.edu/search?p=035__a%3A%22#{CGI.escape(tind_035)}%22&of=xm"
221+
search_url = "https://digicoll.lib.berkeley.edu/api/v1/search?p=035__a%3A%22#{CGI.escape(tind_035)}%22&format=xml"
222222
stub_request(:get, search_url).to_return(status: 200, body: marc_xml)
223223
metadata = Metadata.for_record(record_id: tind_035)
224224

@@ -239,7 +239,7 @@ module AV
239239
it 'works for TIND-only records' do
240240
tind_035 = 'physcolloquia-bk00169017b'
241241
marc_xml = File.read("spec/data/record-#{tind_035}.xml")
242-
search_url = "https://digicoll.lib.berkeley.edu/search?p=035__a%3A%22#{CGI.escape(tind_035)}%22&of=xm"
242+
search_url = "https://digicoll.lib.berkeley.edu/api/v1/search?p=035__a%3A%22#{CGI.escape(tind_035)}%22&format=xml"
243243
stub_request(:get, search_url).to_return(status: 200, body: marc_xml)
244244
metadata = Metadata.for_record(record_id: tind_035)
245245

@@ -259,7 +259,7 @@ module AV
259259
it 'returns the values' do
260260
tind_035 = 'physcolloquia-bk00169017b'
261261
marc_xml = File.read("spec/data/record-#{tind_035}.xml")
262-
search_url = "https://digicoll.lib.berkeley.edu/search?p=035__a%3A%22#{CGI.escape(tind_035)}%22&of=xm"
262+
search_url = "https://digicoll.lib.berkeley.edu/api/v1/search?p=035__a%3A%22#{CGI.escape(tind_035)}%22&format=xml"
263263
stub_request(:get, search_url).to_return(status: 200, body: marc_xml)
264264
metadata = Metadata.for_record(record_id: tind_035)
265265

spec/lib/berkeley_library/av/metadata/source_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ class Metadata
161161

162162
before do
163163
AV::Config.tind_base_uri = 'https://digicoll.lib.berkeley.edu'
164-
@record_url = 'https://digicoll.lib.berkeley.edu/search?p=035__a%3A%22%28pacradio%2900107%22&of=xm'
164+
@record_url = 'https://digicoll.lib.berkeley.edu/api/v1/search?p=035__a%3A%22%28pacradio%2900107%22&format=xml'
165165
end
166166

167167
after do

spec/lib/berkeley_library/av/record_spec.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ module AV
4646
it 'returns a player URI based on the record ID for TIND records' do
4747
tind_035 = '(pacradio)01469'
4848
marc_xml = File.read("spec/data/record-#{tind_035}.xml")
49-
search_url = "https://digicoll.lib.berkeley.edu/search?p=035__a%3A%22#{CGI.escape(tind_035)}%22&of=xm"
49+
search_url = "https://digicoll.lib.berkeley.edu/api/v1/search?p=035__a%3A%22#{CGI.escape(tind_035)}%22&format=xml"
5050
stub_request(:get, search_url).to_return(status: 200, body: marc_xml)
5151

5252
collection = 'Pacifica'
@@ -145,7 +145,7 @@ module AV
145145

146146
it 'returns the TIND ID for TIND records' do
147147
marc_xml = File.read('spec/data/record-(pacradio)01469.xml')
148-
search_url = 'https://digicoll.lib.berkeley.edu/search?p=035__a%3A%22%28pacradio%2901469%22&of=xm'
148+
search_url = 'https://digicoll.lib.berkeley.edu/api/v1/search?p=035__a%3A%22%28pacradio%2901469%22&format=xml'
149149
stub_request(:get, search_url).to_return(status: 200, body: marc_xml)
150150

151151
record = Record.from_metadata(
@@ -168,7 +168,7 @@ module AV
168168
it 'returns nil for TIND records with no bib number' do
169169
tind_id = '(clir)00020'
170170
marc_xml = File.read('spec/data/record-(clir)00020.xml')
171-
search_url = 'https://digicoll.lib.berkeley.edu/search?p=035__a%3A%22%28clir%2900020%22&of=xm'
171+
search_url = 'https://digicoll.lib.berkeley.edu/api/v1/search?p=035__a%3A%22%28clir%2900020%22&format=xml'
172172
stub_request(:get, search_url).to_return(status: 200, body: marc_xml)
173173

174174
record = Record.from_metadata(collection: 'Video-Public-Bancroft', record_id: tind_id)
@@ -179,7 +179,7 @@ module AV
179179
describe :from_metadata do
180180
it 'loads the metadata' do
181181
marc_xml = File.read('spec/data/record-(pacradio)01469.xml')
182-
search_url = 'https://digicoll.lib.berkeley.edu/search?p=035__a%3A%22%28pacradio%2901469%22&of=xm'
182+
search_url = 'https://digicoll.lib.berkeley.edu/api/v1/search?p=035__a%3A%22%28pacradio%2901469%22&format=xml'
183183
stub_request(:get, search_url).to_return(status: 200, body: marc_xml)
184184

185185
record = Record.from_metadata(collection: 'Pacifica', record_id: '(pacradio)01469')
@@ -223,7 +223,7 @@ module AV
223223
end
224224

225225
it "raises #{AV::RecordNotFound} if the record cannot be found" do
226-
search_url = 'https://digicoll.lib.berkeley.edu/search?p=035__a%3A%22%28pacradio%2901469%22&of=xm'
226+
search_url = 'https://digicoll.lib.berkeley.edu/api/v1/search?p=035__a%3A%22%28pacradio%2901469%22&format=xml'
227227
stub_request(:get, search_url).to_return(status: 404)
228228
expect do
229229
Record.from_metadata(

spec/lib/berkeley_library/av/util_spec.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,32 @@ module AV
2424
result = AV::Util.do_get(url, ignore_errors: true)
2525
expect(result).to be_nil
2626
end
27+
28+
it 'includes authorization header for TIND requests if LIT_TIND_API_KEY is set' do
29+
expected_ua = Util::DEFAULT_USER_AGENT
30+
expected_auth = 'Token some-long-api-token-value'
31+
32+
# expect do_get to call URIs.get with the correct headers
33+
# but we don't need to actually perform the request
34+
allow(BerkeleyLibrary::Util::URIs).to receive(:get).and_return('<response></response>')
35+
allow(AV::Config).to receive(:tind_base_uri).and_return(URI('https://tind.example.edu/'))
36+
url = "#{AV::Config.tind_base_uri}/some/api/endpoint"
37+
ENV['LIT_TIND_API_KEY'] = 'some-long-api-token-value'
38+
AV::Util.do_get(url)
39+
expect(BerkeleyLibrary::Util::URIs).to have_received(:get).with(url, headers: { user_agent: expected_ua, authorization: expected_auth })
40+
end
41+
42+
it 'does not include authorization header for non-TIND requests' do
43+
expected_ua = Util::DEFAULT_USER_AGENT
44+
45+
# expect do_get to call URIs.get with the correct headers
46+
# but we don't need to actually perform the request
47+
allow(BerkeleyLibrary::Util::URIs).to receive(:get).and_return('<response></response>')
48+
url = URI('https://alma.example.edu/some/api/endpoint')
49+
ENV['LIT_TIND_API_KEY'] = nil
50+
AV::Util.do_get(url)
51+
expect(BerkeleyLibrary::Util::URIs).to have_received(:get).with(url, headers: { user_agent: expected_ua })
52+
end
2753
end
2854
end
2955
end

0 commit comments

Comments
 (0)