base_indexer 3.0.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +40 -0
  3. data/.travis.yml +17 -0
  4. data/Gemfile +49 -0
  5. data/LICENSE +13 -0
  6. data/README.md +151 -0
  7. data/app/controllers/base_indexer/about_controller.rb +1 -1
  8. data/base_indexer.gemspec +40 -0
  9. data/code_diagram.png +0 -0
  10. data/config/initializers/base_indexer.rb +0 -2
  11. data/config/initializers/config.rb +6 -0
  12. data/lib/base_indexer.rb +0 -3
  13. data/lib/base_indexer/engine.rb +0 -9
  14. data/lib/base_indexer/main_indexer_engine.rb +5 -6
  15. data/lib/base_indexer/solr/client.rb +3 -3
  16. data/lib/base_indexer/version.rb +1 -1
  17. data/lib/generators/base_indexer/install_generator.rb +1 -1
  18. data/lib/generators/base_indexer/templates/settings.yml +5 -0
  19. data/lib/tasks/index.rake +4 -4
  20. data/spec/base_indexer/main_indexer_engine_spec.rb +46 -0
  21. data/spec/base_indexer/solr/client_spec.rb +47 -0
  22. data/spec/base_indexer/solr/writer_spec.rb +72 -0
  23. data/spec/controllers/base_indexer/items_controller_spec.rb +36 -0
  24. data/spec/fixtures/vcr_cassettes/available_mods_xml.yml +105 -0
  25. data/spec/fixtures/vcr_cassettes/available_purl_xml.yml +110 -0
  26. data/spec/fixtures/vcr_cassettes/get_collection_name_for_item.yml +197 -0
  27. data/spec/fixtures/vcr_cassettes/read_mods_in_vaild.yml +154 -0
  28. data/spec/fixtures/vcr_cassettes/read_mods_vaild.yml +199 -0
  29. data/spec/fixtures/vcr_cassettes/read_purl_in_vaild.yml +154 -0
  30. data/spec/fixtures/vcr_cassettes/read_purl_vaild.yml +197 -0
  31. data/spec/fixtures/vcr_cassettes/rsolr_client_delete.yml +174 -0
  32. data/spec/fixtures/vcr_cassettes/rsolr_client_index.yml +115 -0
  33. data/spec/fixtures/vcr_cassettes/rsolr_update.yml +313 -0
  34. data/spec/spec_helper.rb +112 -0
  35. data/spec/test_app_templates/lib/generators/test_app_generator.rb +14 -0
  36. metadata +72 -14
  37. data/lib/base_indexer/config/solr_configuration.rb +0 -17
  38. data/lib/base_indexer/config/solr_configuration_from_file.rb +0 -25
  39. data/lib/generators/base_indexer/templates/solr.yml +0 -4
@@ -1,3 +1,3 @@
1
1
  module BaseIndexer
2
- VERSION = '3.0.0'
2
+ VERSION = '4.0.0'
3
3
  end
@@ -7,7 +7,7 @@ module BaseIndexer
7
7
  desc 'Install Base Indexer'
8
8
 
9
9
  def assets
10
- copy_file 'solr.yml', 'config/solr.yml'
10
+ copy_file 'settings.yml', 'config/settings.yml'
11
11
  end
12
12
 
13
13
  def add_routes
@@ -0,0 +1,5 @@
1
+ SOLR_TARGETS:
2
+ target1:
3
+ url: http://localhost:8983/solr/
4
+ target2:
5
+ url: http://localhost:8983/solr/
data/lib/tasks/index.rake CHANGED
@@ -30,7 +30,7 @@ task :log_indexer => :environment do |t, args|
30
30
  raise 'Log type must be preassembly, remediate or csv.' unless ['preassembly','remediate','csv'].include? log_type
31
31
  raise 'Log file not found.' unless File.readable? log_file_path
32
32
 
33
- target_config=BaseIndexer.solr_configuration_class_name.constantize.instance.get_configuration_hash[target.upcase]
33
+ target_config = Settings.SOLR_TARGETS[target]
34
34
 
35
35
  raise 'Target not found.' if target_config.nil?
36
36
 
@@ -121,7 +121,7 @@ task :index => :environment do |t, args|
121
121
 
122
122
  raise 'You must specify a target and druid.' if target.blank? || druid.blank?
123
123
 
124
- target_config=BaseIndexer.solr_configuration_class_name.constantize.instance.get_configuration_hash[target.upcase]
124
+ target_config = Settings.SOLR_TARGETS[target]
125
125
 
126
126
  raise 'Target not found.' if target_config.nil?
127
127
 
@@ -144,7 +144,7 @@ task :collection_indexer => :environment do |t, args|
144
144
 
145
145
  raise 'You must specify a target and collection druid.' if target.blank? || collection_druid.blank?
146
146
 
147
- target_config=BaseIndexer.solr_configuration_class_name.constantize.instance.get_configuration_hash[target.upcase]
147
+ target_config = Settings.SOLR_TARGETS[target]
148
148
 
149
149
  raise 'Target not found.' if target_config.nil?
150
150
 
@@ -211,7 +211,7 @@ task :reindexer => :environment do |t, args|
211
211
  raise 'You must specify a target and file.' if target.blank? || file_path.blank?
212
212
  raise 'File not found.' unless File.readable? file_path
213
213
 
214
- target_config=BaseIndexer.solr_configuration_class_name.constantize.instance.get_configuration_hash[target.upcase]
214
+ target_config = Settings.SOLR_TARGETS[target]
215
215
 
216
216
  raise 'Target not found.' if target_config.nil?
217
217
 
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe BaseIndexer::MainIndexerEngine do
4
+ before :all do
5
+ DiscoveryIndexer::PURL_DEFAULT = 'https://purl.stanford.edu'
6
+ end
7
+
8
+ describe '.delete' do
9
+ it 'should call solr_delete_from_all for delete call' do
10
+ expect_any_instance_of(BaseIndexer::Solr::Writer).to receive(:solr_delete_from_all)
11
+ .with('aa111aa1111', 'target1' => { 'url' => 'http://localhost:8983/solr/' }, 'target2' => { 'url' => 'http://localhost:8983/solr/' })
12
+
13
+ BaseIndexer::MainIndexerEngine.new.delete 'aa111aa1111'
14
+ end
15
+ end
16
+
17
+ describe '.read_purl' do
18
+ it 'should read purl xml for a valid druid' do
19
+ VCR.use_cassette('read_purl_vaild') do
20
+ purl_model = DiscoveryIndexer::InputXml::Purlxml.new('dk605tp1619').load
21
+ expect(purl_model.label).to eq('Walters MS 690')
22
+ end
23
+ end
24
+
25
+ it 'should raise an error for not found druid' do
26
+ VCR.use_cassette('read_purl_in_vaild') do
27
+ expect { DiscoveryIndexer::InputXml::Purlxml.new('aa111aa1111').load }.to raise_error(DiscoveryIndexer::Errors::MissingPurlPage)
28
+ end
29
+ end
30
+ end
31
+
32
+ describe '.read_mods' do
33
+ it 'should read mods xml for a valid druid' do
34
+ VCR.use_cassette('read_mods_vaild') do
35
+ mods_model = DiscoveryIndexer::InputXml::Modsxml.new('dk605tp1619').load
36
+ expect(mods_model.sw_full_title).to eq('Walters Ms. W.690, Single leaf of a couple embracing.')
37
+ end
38
+ end
39
+
40
+ it 'should raise an error for not found druid' do
41
+ VCR.use_cassette('read_mods_in_vaild') do
42
+ expect { DiscoveryIndexer::InputXml::Modsxml.new('aa111aa1111').load }.to raise_error(DiscoveryIndexer::Errors::MissingModsPage)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe BaseIndexer::Solr::Client do
4
+ let(:druid) { 'cb077vs7846' }
5
+ let (:solr_doc) { double('solr_doc', {}) }
6
+ let(:max_retries) { 10 }
7
+ describe '.solr_url' do
8
+ it 'should correctly handle urls with both trailing and leading slashes' do
9
+ connectors=[RSolr.connect(url: 'http://localhost:8983/solr/'),RSolr.connect(url: 'http://localhost:8983/solr')]
10
+ connectors.each do |connector|
11
+ expect(described_class.solr_url(connector)).to eq 'http://localhost:8983/solr/update?commit=true'
12
+ end
13
+ end
14
+ end
15
+
16
+ describe '.process' do
17
+ describe 'delete' do
18
+ let (:solr_connector) { double('connector', { options: { url: 'http://localhost:8983/solr/' } } ) }
19
+ let(:is_delete) { true }
20
+ it 'should send a delete_by_id command' do
21
+ expect(solr_connector).to receive(:delete_by_id).with(druid, {:add_attributes=>{:commitWithin=>10000}})
22
+ BaseIndexer::Solr::Client.process(druid, {}, solr_connector, max_retries, is_delete)
23
+ end
24
+ end
25
+ describe 'update' do
26
+ let(:is_delete) { false }
27
+ let(:response) { double({}) }
28
+ let (:solr_connector) { double('connector', { options: { url: 'http://localhost:8983/solr/', allow_update: true } } ) }
29
+ it 'should send update_solr_doc' do
30
+ allow(solr_connector).to receive(:get).with("select", {:params=>{:q=>"id:\"cb077vs7846\""}}).and_return(:response)
31
+ allow(BaseIndexer::Solr::Client).to receive(:update_solr_doc).with(druid, solr_doc, solr_connector)
32
+ expect(solr_connector).to receive(:add).with(solr_doc, :add_attributes => {:commitWithin => 10000})
33
+ BaseIndexer::Solr::Client.process(druid, solr_doc, solr_connector, max_retries, is_delete)
34
+ end
35
+ end
36
+ describe 'add' do
37
+ let(:is_delete) { false }
38
+ let(:response) { double({}) }
39
+ let (:solr_connector) { double('connector', { options: { url: 'http://localhost:8983/solr/', allow_update: true, commitWithin: '10000'} } ) }
40
+ it 'should send an add command' do
41
+ allow(solr_connector).to receive(:get).with("select", {:params=>{:q=>"id:\"cb077vs7846\""}}).and_return(:response)
42
+ expect(solr_connector).to receive(:add).with(solr_doc, :add_attributes => {:commitWithin => 10000})
43
+ BaseIndexer::Solr::Client.process(druid, solr_doc, solr_connector, max_retries, is_delete)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ describe BaseIndexer::Solr::Writer do
4
+ let(:sw_connection) { { url: 'http://solr-core:8983/sw-prod/' } }
5
+ let(:preview_connection) { { url: 'http://solr-core:8983/sw-preview/' } }
6
+ let(:mix_targets) { { 'searchworks' => true, 'searchworks:preview' => false } }
7
+ let(:index_targets) { { 'searchworks' => true } }
8
+ let(:delete_targets) { { 'searchworks:preview' => false } }
9
+ let(:solr_doc) { { id: '123' } }
10
+ let(:id) { '123' }
11
+
12
+ before do
13
+ allow(subject).to receive(:solr_targets_configs).and_return(
14
+ 'searchworks' => sw_connection,
15
+ 'searchworks:preview' => preview_connection
16
+ )
17
+ end
18
+
19
+ describe '.process' do
20
+ it 'should create two arrays index_targets and delete_targets' do
21
+ expect(subject).to receive(:solr_index_client).with(id, solr_doc, ['searchworks'])
22
+ expect(subject).to receive(:solr_delete_client).with(id, ['searchworks:preview'])
23
+ subject.process(id, solr_doc, mix_targets, {})
24
+ end
25
+ it 'should not send delete messages when there are no delete targets' do
26
+ expect(subject).to receive(:solr_index_client).with(id, solr_doc, ['searchworks'])
27
+ expect(subject).not_to receive(:solr_delete_client)
28
+ subject.process(id, solr_doc, index_targets, {})
29
+ end
30
+ it 'should not send index messages when there are no index targets' do
31
+ expect(subject).not_to receive(:solr_index_client)
32
+ expect(subject).to receive(:solr_delete_client).with(id, ['searchworks:preview'])
33
+ subject.process(id, solr_doc, delete_targets, {})
34
+ end
35
+ end
36
+
37
+ describe '.solr_delete_client' do
38
+ it 'should call solr client delete method for each target' do
39
+ expect(BaseIndexer::Solr::Client).to receive(:delete).with('aa111bb222', an_instance_of(RSolr::Client))
40
+ expect(BaseIndexer::Solr::Client).to receive(:delete).with('aa111bb222', an_instance_of(RSolr::Client))
41
+ subject.solr_delete_client('aa111bb222', ['searchworks', 'searchworks:preview'])
42
+ end
43
+
44
+ it 'should not call solr client delete method when there is no client for the given target' do
45
+ expect(BaseIndexer::Solr::Client).not_to receive(:delete)
46
+ subject.solr_delete_client('aa111bb222', ['blah'])
47
+ end
48
+ end
49
+
50
+ describe '.get_connector_for_target' do
51
+ it 'should return a connector for a target that is avaliable in config list' do
52
+ solr_connector = subject.get_connector_for_target('searchworks')
53
+ expect(solr_connector).to be_a(RSolr::Client)
54
+ expect(solr_connector.uri.to_s).to eq('http://solr-core:8983/sw-prod/')
55
+
56
+ solr_connector = subject.get_connector_for_target('searchworks:preview')
57
+ expect(solr_connector).to be_a(RSolr::Client)
58
+ expect(solr_connector.uri.to_s).to eq('http://solr-core:8983/sw-preview/')
59
+ end
60
+
61
+ it 'should return nil for a target that is not avaliable in config list' do
62
+ solr_connector = subject.get_connector_for_target('nothing')
63
+ expect(solr_connector).to be_nil
64
+ end
65
+
66
+ it 'should return nil for a nil solr targets list' do
67
+ allow(subject).to receive(:solr_targets_configs).and_return(nil)
68
+ solr_connector = subject.get_connector_for_target('searchworks')
69
+ expect(solr_connector).to be_nil
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe BaseIndexer::ItemsController, type: :controller do
4
+ let(:my_instance) { instance_double(BaseIndexer::MainIndexerEngine) }
5
+ before do
6
+ allow(BaseIndexer::MainIndexerEngine).to receive(:new).and_return(my_instance)
7
+ end
8
+ describe 'PATCH/PUT update' do
9
+ it 'creates an indexing job' do
10
+ expect(my_instance).to receive(:index).with('bb1111cc2222', 'SEARCHWORKS' => true)
11
+ patch :update, druid: 'druid:bb1111cc2222', subtarget: 'SEARCHWORKS', use_route: :base_indexer
12
+ expect(response.status).to eq 200
13
+ end
14
+ it 'when something bad happens return a 500' do
15
+ expect(my_instance).to receive(:index).with('bb1111cc2222', 'SEARCHWORKS' => true).and_raise(StandardError)
16
+ patch :update, druid: 'druid:bb1111cc2222', subtarget: 'SEARCHWORKS', use_route: :base_indexer
17
+ expect(response.status).to eq 500
18
+ end
19
+ end
20
+ describe 'DELETE destroy' do
21
+ context 'with a subtarget' do
22
+ it 'sends an "#index" with a false to the IndexerEngine' do
23
+ expect(my_instance).to receive(:index).with('bb1111cc2222', 'SEARCHWORKS' => false)
24
+ delete :destroy, druid: 'druid:bb1111cc2222', subtarget: 'SEARCHWORKS', use_route: :base_indexer
25
+ expect(response.status).to eq 200
26
+ end
27
+ end
28
+ context 'without a subtarget' do
29
+ it 'sends a "#delete" to the IndexerEngine' do
30
+ expect(my_instance).to receive(:delete).with('bb1111cc2222')
31
+ delete :destroy, druid: 'druid:bb1111cc2222', use_route: :base_indexer
32
+ expect(response.status).to eq 200
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,105 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://purl.stanford.edu/tn629pk3948.mods
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - Ruby
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Date:
22
+ - Mon, 07 Dec 2015 18:52:07 GMT
23
+ Server:
24
+ - Apache/2.2.15 (CentOS)
25
+ Cache-Control:
26
+ - max-age=0, private, must-revalidate
27
+ Etag:
28
+ - '"900541a398ecb6cfcf6094ac2c30d50c"'
29
+ X-Frame-Options:
30
+ - SAMEORIGIN
31
+ X-Xss-Protection:
32
+ - 1; mode=block
33
+ X-Content-Type-Options:
34
+ - nosniff
35
+ X-Runtime:
36
+ - '0.017935'
37
+ X-Request-Id:
38
+ - 31e4c8b2-07a3-449a-bca3-ff74047daae3
39
+ X-Powered-By:
40
+ - Phusion Passenger 5.0.16
41
+ Strict-Transport-Security:
42
+ - max-age=31536000; includeSubDomains
43
+ Last-Modified:
44
+ - Thu, 05 Nov 2015 23:18:09 GMT
45
+ Status:
46
+ - 200 OK
47
+ Transfer-Encoding:
48
+ - chunked
49
+ Content-Type:
50
+ - application/xml; charset=utf-8
51
+ body:
52
+ encoding: UTF-8
53
+ string: |
54
+ <?xml version="1.0" encoding="UTF-8"?>
55
+ <mods:mods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mods="http://www.loc.gov/mods/v3" version="3.4" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-4.xsd">
56
+ <mods:identifier type="local" displayLabel="Source ID">V0401_b1_1.01</mods:identifier>
57
+ <mods:identifier type="local" displayLabel="Call number">V0401</mods:identifier>
58
+ <mods:titleInfo>
59
+ <mods:title>Lecture 1</mods:title>
60
+ </mods:titleInfo>
61
+ <mods:originInfo>
62
+ <mods:dateCreated encoding="w3cdtf" keyDate="yes">2003-01-27</mods:dateCreated>
63
+ <mods:placeTerm type="text">Stanford (Calif.)</mods:placeTerm>
64
+ </mods:originInfo>
65
+ <mods:physicalDescription>
66
+ <mods:form authority="PBCore instantiationPhysical">VHS</mods:form>
67
+ <mods:extent>1 tape</mods:extent>
68
+ <mods:reformattingQuality>access</mods:reformattingQuality>
69
+ <mods:internetMediaType>video/mpeg</mods:internetMediaType>
70
+ <mods:digitalOrigin>reformatted digital</mods:digitalOrigin>
71
+ </mods:physicalDescription>
72
+ <mods:typeOfResource>moving image</mods:typeOfResource>
73
+ <mods:name authority="naf" valueURI="http://id.loc.gov/authorities/names/no2005099404" type="personal">
74
+ <mods:namePart>Frantz, Marge</mods:namePart>
75
+ <mods:role>
76
+ <mods:roleTerm authority="marcrelator" valueURI="http://id.loc.gov/vocabulary/relators/spk" type="text">Speaker</mods:roleTerm>
77
+ </mods:role>
78
+ </mods:name>
79
+ <mods:subject authority="lcsh" valueURI="http://id.loc.gov/authorities/subjects/sh2008117594">
80
+ <mods:topic>Anti-Communist Movements--United States</mods:topic>
81
+ </mods:subject>
82
+ <mods:subject>
83
+ <mods:name type="personal" authority="lcsh" valueURI="http://id.loc.gov/authorities/names/n79043290">
84
+ <mods:namePart>McCarthy, Joseph, 1908-1957</mods:namePart>
85
+ </mods:name>
86
+ </mods:subject>
87
+ <mods:location>
88
+ <mods:physicalLocation authority="naf" valueURI="http://id.loc.gov/authorities/names/no2014019980" displayLabel="Repository" type="repository">Stanford University. Libraries. Department of Special Collections and University Archives</mods:physicalLocation>
89
+ <mods:url>http://purl.stanford.edu/tn629pk3948</mods:url>
90
+ </mods:location>
91
+ <mods:language>
92
+ <mods:languageTerm type="code" authority="iso639-2">eng</mods:languageTerm>
93
+ </mods:language>
94
+ <mods:relatedItem type="host">
95
+ <mods:titleInfo>
96
+ <mods:title>Marge Frantz lectures on McCarthyism, 2003</mods:title>
97
+ </mods:titleInfo>
98
+ <mods:identifier type="uri">http://purl.stanford.edu/yk804rq1656</mods:identifier>
99
+ <mods:typeOfResource collection="yes"/>
100
+ </mods:relatedItem>
101
+ <mods:accessCondition type="useAndReproduction">Digital recordings from this collection may be accessed freely. These files may not be reproduced or used for any purpose without permission. For permission requests, please contact Stanford University Department of Special Collections University Archives (speccollref@stanford.edu).</mods:accessCondition>
102
+ </mods:mods>
103
+ http_version:
104
+ recorded_at: Mon, 07 Dec 2015 18:52:07 GMT
105
+ recorded_with: VCR 2.9.3
@@ -0,0 +1,110 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://purl.stanford.edu/tn629pk3948.xml
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept-Encoding:
11
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
12
+ Accept:
13
+ - "*/*"
14
+ User-Agent:
15
+ - Ruby
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ Date:
22
+ - Mon, 07 Dec 2015 18:52:07 GMT
23
+ Server:
24
+ - Apache/2.2.15 (CentOS)
25
+ Cache-Control:
26
+ - max-age=0, private, must-revalidate
27
+ Etag:
28
+ - '"900541a398ecb6cfcf6094ac2c30d50c"'
29
+ X-Frame-Options:
30
+ - SAMEORIGIN
31
+ X-Xss-Protection:
32
+ - 1; mode=block
33
+ X-Content-Type-Options:
34
+ - nosniff
35
+ X-Runtime:
36
+ - '0.022400'
37
+ X-Request-Id:
38
+ - 09e13cdf-25f1-4aca-96e2-dbaa5a2d3f1d
39
+ X-Powered-By:
40
+ - Phusion Passenger 5.0.16
41
+ Strict-Transport-Security:
42
+ - max-age=31536000; includeSubDomains
43
+ Last-Modified:
44
+ - Thu, 05 Nov 2015 23:18:09 GMT
45
+ Status:
46
+ - 200 OK
47
+ Transfer-Encoding:
48
+ - chunked
49
+ Content-Type:
50
+ - application/xml; charset=utf-8
51
+ body:
52
+ encoding: UTF-8
53
+ string: "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<publicObject id=\"druid:tn629pk3948\"
54
+ published=\"2015-11-05T15:18:04-08:00\" publishVersion=\"dor-services/4.22.3\">\n
55
+ \ <identityMetadata>\n <sourceId source=\"sul\">V0401_b1_1.01</sourceId>\n
56
+ \ <objectId>druid:tn629pk3948</objectId>\n <objectCreator>DOR</objectCreator>\n
57
+ \ <objectLabel>Lecture 1</objectLabel>\n <objectType>item</objectType>\n
58
+ \ <adminPolicy>druid:ww057vk7675</adminPolicy>\n <otherId name=\"label\"/>\n
59
+ \ <otherId name=\"uuid\">08d544da-d459-11e2-8afb-0050569b3c3c</otherId>\n
60
+ \ <tag>Project:V0401 mccarthyism:vhs</tag>\n <tag> Process:Content Type:Media</tag>\n
61
+ \ <tag> JIRA:DIGREQ-592</tag>\n <tag> SMPL:video:ua</tag>\n <tag>
62
+ Registered By:gwillard</tag>\n <tag>Remediated By : 4.6.6.2</tag>\n </identityMetadata>\n
63
+ \ <contentMetadata objectId=\"tn629pk3948\" type=\"media\">\n <resource
64
+ sequence=\"1\" id=\"tn629pk3948_1\" type=\"video\">\n <label>Tape 1</label>\n
65
+ \ <file id=\"tn629pk3948_sl.mp4\" mimetype=\"video/mp4\" size=\"3615267858\">\n
66
+ \ \n \n </file>\n </resource>\n <resource sequence=\"2\"
67
+ id=\"tn629pk3948_2\" type=\"image\">\n <label>Image of media (1 of 3)</label>\n
68
+ \ <file id=\"tn629pk3948_img_1.jp2\" mimetype=\"image/jp2\" size=\"919945\">\n
69
+ \ <imageData width=\"1777\" height=\"2723\"/>\n </file>\n </resource>\n
70
+ \ <resource sequence=\"3\" id=\"tn629pk3948_3\" type=\"image\">\n <label>Image
71
+ of media (2 of 3)</label>\n <file id=\"tn629pk3948_img_2.jp2\" mimetype=\"image/jp2\"
72
+ size=\"719940\">\n <imageData width=\"2560\" height=\"1475\"/>\n </file>\n
73
+ \ </resource>\n <resource sequence=\"4\" id=\"tn629pk3948_4\" type=\"image\">\n
74
+ \ <label>Image of media (3 of 3)</label>\n <file id=\"tn629pk3948_img_3.jp2\"
75
+ mimetype=\"image/jp2\" size=\"411054\">\n <imageData width=\"1547\"
76
+ height=\"1379\"/>\n </file>\n </resource>\n </contentMetadata>\n
77
+ \ <rightsMetadata>\n <access type=\"discover\">\n <machine>\n <world/>\n
78
+ \ </machine>\n </access>\n <access type=\"read\">\n <machine>\n
79
+ \ <world/>\n </machine>\n </access>\n <use>\n <human
80
+ type=\"useAndReproduction\">Digital recordings from this collection may be
81
+ accessed freely. These files may not be reproduced or used for any purpose
82
+ without permission. For permission requests, please contact Stanford University
83
+ Department of Special Collections University Archives (speccollref@stanford.edu).</human>\n
84
+ \ </use>\n <use>\n <human type=\"creativeCommons\"/>\n <machine
85
+ type=\"creativeCommons\"/>\n </use>\n </rightsMetadata>\n <rdf:RDF xmlns:fedora=\"info:fedora/fedora-system:def/relations-external#\"
86
+ xmlns:fedora-model=\"info:fedora/fedora-system:def/model#\" xmlns:hydra=\"http://projecthydra.org/ns/relations#\"
87
+ xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n <rdf:Description
88
+ rdf:about=\"info:fedora/druid:tn629pk3948\">\n <fedora:isMemberOf rdf:resource=\"info:fedora/druid:yk804rq1656\"/>\n
89
+ \ <fedora:isMemberOfCollection rdf:resource=\"info:fedora/druid:yk804rq1656\"/>\n
90
+ \ </rdf:Description>\n </rdf:RDF>\n <oai_dc:dc xmlns:dc=\"http://purl.org/dc/elements/1.1/\"
91
+ xmlns:srw_dc=\"info:srw/schema/1/dc-schema\" xmlns:oai_dc=\"http://www.openarchives.org/OAI/2.0/oai_dc/\"
92
+ xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.openarchives.org/OAI/2.0/oai_dc/
93
+ http://www.openarchives.org/OAI/2.0/oai_dc.xsd\">\n <dc:identifier>V0401_b1_1.01</dc:identifier>\n
94
+ \ <dc:identifier>V0401</dc:identifier>\n <dc:title>Lecture 1</dc:title>\n
95
+ \ <dc:date>2003-01-27</dc:date>\n <dc:format>1 tape</dc:format>\n <dc:format>VHS</dc:format>\n
96
+ \ <dc:format>video/mpeg</dc:format>\n <dc:type>MovingImage</dc:type>\n
97
+ \ <dc:contributor>Frantz, Marge (Speaker)</dc:contributor>\n <dc:subject>Anti-Communist
98
+ Movements--United States</dc:subject>\n <dc:subject>McCarthy, Joseph, 1908-1957</dc:subject>\n
99
+ \ <dc:relation type=\"repository\">Stanford University. Libraries. Department
100
+ of Special Collections and University Archives http://purl.stanford.edu/tn629pk3948</dc:relation>\n
101
+ \ <dc:rights>Digital recordings from this collection may be accessed freely.
102
+ These files may not be reproduced or used for any purpose without permission.
103
+ For permission requests, please contact Stanford University Department of
104
+ Special Collections University Archives (speccollref@stanford.edu). \n </dc:rights>\n
105
+ \ <dc:language>eng</dc:language>\n <dc:relation type=\"collection\">Marge
106
+ Frantz lectures on McCarthyism, 2003</dc:relation>\n </oai_dc:dc>\n <releaseData>\n
107
+ \ <release to=\"Searchworks\">true</release>\n </releaseData>\n</publicObject>\n"
108
+ http_version:
109
+ recorded_at: Mon, 07 Dec 2015 18:52:07 GMT
110
+ recorded_with: VCR 2.9.3