Skip to content
This repository was archived by the owner on Oct 16, 2020. It is now read-only.

Commit a0df214

Browse files
committed
Merge pull request #7 from MITLibraries/3_mets
Initial Mets generation
2 parents 64c216a + b93170c commit a0df214

File tree

9 files changed

+3266
-0
lines changed

9 files changed

+3266
-0
lines changed

Gemfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ gem 'devise'
77
gem 'http_logger'
88
gem 'jquery-rails'
99
gem 'less-rails'
10+
gem 'nokogiri'
1011
gem 'omniauth-mit-oauth2'
1112
gem 'omniauth-oauth2', '~> 1.3.1'
1213
gem 'passenger'
@@ -35,4 +36,6 @@ group :test do
3536
gem 'minitest-reporters'
3637
gem 'minitest-rails'
3738
gem 'minitest-rails-capybara'
39+
gem 'vcr'
40+
gem 'webmock'
3841
end

Gemfile.lock

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ GEM
3636
minitest (~> 5.1)
3737
thread_safe (~> 0.3, >= 0.3.4)
3838
tzinfo (~> 1.1)
39+
addressable (2.3.8)
3940
annotate (2.6.10)
4041
activerecord (>= 3.2, <= 4.3)
4142
rake (~> 10.4)
@@ -64,6 +65,8 @@ GEM
6465
term-ansicolor (~> 1.3)
6566
thor (~> 0.19.1)
6667
tins (~> 1.6.0)
68+
crack (0.4.2)
69+
safe_yaml (~> 1.0.0)
6770
debug_inspector (0.0.2)
6871
devise (3.5.2)
6972
bcrypt (~> 3.0)
@@ -81,6 +84,7 @@ GEM
8184
multipart-post (>= 1.2, < 3)
8285
globalid (0.3.6)
8386
activesupport (>= 4.1.0)
87+
hashdiff (0.2.3)
8488
hashie (3.4.3)
8589
http-cookie (1.0.2)
8690
domain_name (~> 0.5)
@@ -203,6 +207,7 @@ GEM
203207
ruby-progressbar (~> 1.7)
204208
tins (<= 1.6.0)
205209
ruby-progressbar (1.7.5)
210+
safe_yaml (1.0.4)
206211
simplecov (0.10.0)
207212
docile (~> 1.1.0)
208213
json (~> 1.8)
@@ -237,13 +242,18 @@ GEM
237242
unf (0.1.4)
238243
unf_ext
239244
unf_ext (0.0.7.1)
245+
vcr (3.0.0)
240246
warden (1.2.3)
241247
rack (>= 1.0)
242248
web-console (2.2.1)
243249
activemodel (>= 4.0)
244250
binding_of_caller (>= 0.7.2)
245251
railties (>= 4.0)
246252
sprockets-rails (>= 2.0, < 4.0)
253+
webmock (1.22.3)
254+
addressable (>= 2.3.6)
255+
crack (>= 0.3.2)
256+
hashdiff
247257
xpath (2.0.0)
248258
nokogiri (~> 1.3)
249259

@@ -262,6 +272,7 @@ DEPENDENCIES
262272
minitest-rails
263273
minitest-rails-capybara
264274
minitest-reporters
275+
nokogiri
265276
omniauth-mit-oauth2
266277
omniauth-oauth2 (~> 1.3.1)
267278
passenger
@@ -273,7 +284,9 @@ DEPENDENCIES
273284
therubyracer
274285
twitter-bootstrap-rails
275286
uglifier (>= 1.3.0)
287+
vcr
276288
web-console (~> 2.0)
289+
webmock
277290

278291
BUNDLED WITH
279292
1.10.6

app/models/epdcx.rb

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
class Epdcx
2+
def initialize(xml, submission)
3+
@xml = xml
4+
@xml['mets'].xmlData do
5+
@xml['epdcx'].descriptionSet(
6+
'xmlns:epdcx' => 'http://purl.org/eprint/epdcx/2006-11-16/',
7+
'xsi:schemaLocation' =>
8+
'http://purl.org/eprint/epdcx/xsd/2006-11-16/epdcx.xsd') do
9+
work(submission)
10+
entity(submission)
11+
end
12+
end
13+
end
14+
15+
private
16+
17+
def entity(submission)
18+
@xml['epdcx'].description('epdcx:resourceId' => 'sword-mets-expr-1') do
19+
expression
20+
lang
21+
journal_article
22+
statement('http://purl.org/eprint/terms/bibliographicCitation',
23+
submission.journal)
24+
doi(submission)
25+
end
26+
end
27+
28+
def work(submission)
29+
@xml['epdcx'].description('epdcx:resourceId' => 'sword-mets-epdcx-1') do
30+
scholarly_work
31+
statement('http://purl.org/dc/elements/1.1/title', submission.title)
32+
statement('http://purl.org/dc/elements/1.1/creator', submission.author)
33+
34+
@xml['epdcx'].statement('epdcx:propertyURI' =>
35+
'http://purl.org/eprint/terms/isExpressedAs') do
36+
@xml['epdcx'].valueRef('sword-mets-expr-1')
37+
end
38+
end
39+
end
40+
41+
def doi(submission)
42+
@xml['epdcx'].statement('epdcx:propertyURI' =>
43+
'http://purl.org/dc/elements/1.1/identifier') do
44+
@xml['epdcx'].valueString('epdcx:sesURI' =>
45+
'http://purl.org/dc/terms/URI') do
46+
@xml.text(submission.doi)
47+
end
48+
end
49+
end
50+
51+
def expression
52+
@xml['epdcx'].statement('epdcx:propertyURI' =>
53+
'http://purl.org/dc/elements/1.1/type',
54+
'epdcx:valueURI' =>
55+
'http://purl.org/eprint/entityType/Expression')
56+
end
57+
58+
def journal_article
59+
@xml['epdcx'].statement('epdcx:propertyURI' =>
60+
'http://purl.org/dc/elements/1.1/type',
61+
'epdcx:vesURI' =>
62+
'http://purl.org/eprint/terms/Type',
63+
'epdcx:valueURI' =>
64+
'http://purl.org/eprint/type/JournalArticle')
65+
end
66+
67+
def lang
68+
@xml['epdcx'].statement('epdcx:propertyURI' =>
69+
'http://purl.org/dc/elements/1.1/language',
70+
'epdcx:vesURI' =>
71+
'http://purl.org/dc/terms/RFC3066') do
72+
@xml['epdcx'].valueString('en')
73+
end
74+
end
75+
76+
def scholarly_work
77+
@xml['epdcx'].statement('epdcx:propertyURI' =>
78+
'http://purl.org/dc/elements/1.1/type',
79+
'epdcx:valueURI' =>
80+
'http://purl.org/eprint/entityType/ScholarlyWork')
81+
end
82+
83+
def statement(prop_uri, value)
84+
@xml['epdcx'].statement('epdcx:propertyURI' => prop_uri) do
85+
@xml['epdcx'].valueString(value)
86+
end
87+
end
88+
end

app/models/mets.rb

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
class Mets
2+
def initialize(submission)
3+
@submission = submission
4+
@builder = Nokogiri::XML::Builder.new do |xml|
5+
xml['mets'].mets(
6+
'xmlns:mets' => 'http://www.loc.gov/METS/',
7+
'xmlns:xlink' => 'http://www.w3.org/1999/xlink',
8+
'xmlns:epdcx' => 'http://purl.org/eprint/epdcx/2006-11-16/') do
9+
overall_structure(xml)
10+
end
11+
end
12+
end
13+
14+
def to_xml
15+
@builder.to_xml
16+
end
17+
18+
private
19+
20+
def overall_structure(xml)
21+
header(xml)
22+
dmd(xml)
23+
filesec(xml)
24+
structmap(xml)
25+
end
26+
27+
def header(xml)
28+
xml['mets'].metsHdr('CREATEDATE' => '2009-02-12T08:35:13.561-05:00') do
29+
xml['mets'].agent('ROLE' => 'DISSEMINATOR',
30+
'TYPE' => 'ORGANIZATION') do
31+
xml['mets'].name('MIT Libraries: QuickSubmit')
32+
end
33+
end
34+
end
35+
36+
def dmd(xml)
37+
xml['mets'].dmdSec('ID' => 'VAA4025-102-1-a01-dmd') do
38+
xml['mets'].mdWrap('MDTYPE' => 'OTHER', 'OTHERMDTYPE' => 'EPDCX',
39+
'MIMETYPE' => 'text/xml') do
40+
xml_data(xml)
41+
end
42+
end
43+
end
44+
45+
def filesec(xml)
46+
xml['mets'].fileSec('ID' => 'VAA4025-102-1-a02-dmd') do
47+
xml['mets'].fileGrp('USE' => 'CONTENT') do
48+
xml['mets'].file('ID' => 'JHEP09',
49+
'MIMETYPE' => 'application/pdf') do
50+
xml['mets'].FLocat('LOCTYPE' => 'URL',
51+
'xlink:href' => 'JHEP09(2015)175_pdfa.pdf')
52+
end
53+
end
54+
end
55+
end
56+
57+
def structmap(xml)
58+
xml['mets'].structMap('ID' => 'VAA4025-102-1-a03-dmd') do
59+
xml['mets'].div('DMDID' => 'sword-mets-dmd-1') do
60+
xml['mets'].div('TYPE' => 'File') do
61+
xml['mets'].fptr('FILEID' => 'JHEP09')
62+
end
63+
end
64+
end
65+
end
66+
67+
def xml_data(xml)
68+
Epdcx.new(xml, @submission)
69+
end
70+
end

app/models/submission.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,8 @@ class Submission < ActiveRecord::Base
2020
validates :user, presence: true
2121
validates :title, presence: true
2222
validates :agreed_to_license, inclusion: { in: [true] }
23+
24+
def to_mets
25+
Mets.new(self).to_xml
26+
end
2327
end

test/models/mets_test.rb

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
require 'test_helper'
2+
3+
class MetsTest < ActiveSupport::TestCase
4+
test 'initializing with a full submission creates valid mets xml' do
5+
VCR.use_cassette('mets_dtd') do
6+
dtd = Net::HTTP.get(URI('http://www.loc.gov/standards/mets/version111/mets.xsd'))
7+
sub = submissions(:sub_two)
8+
xsd = Nokogiri::XML::Schema(dtd)
9+
xml = Mets.new(sub).to_xml
10+
doc = Nokogiri::XML(xml)
11+
assert_equal(true, xsd.valid?(doc))
12+
end
13+
end
14+
15+
test 'initializing with a sparse submission creates valid mets xml' do
16+
VCR.use_cassette('mets_dtd') do
17+
dtd = Net::HTTP.get(URI('http://www.loc.gov/standards/mets/version111/mets.xsd'))
18+
sub = submissions(:sub_one)
19+
xsd = Nokogiri::XML::Schema(dtd)
20+
xml = Mets.new(sub).to_xml
21+
doc = Nokogiri::XML(xml)
22+
assert_equal(true, xsd.valid?(doc))
23+
end
24+
end
25+
end

test/models/submission_test.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,15 @@ class SubmissionTest < ActiveSupport::TestCase
4040
sub.agreed_to_license = false
4141
assert_not sub.valid?
4242
end
43+
44+
test '#mets' do
45+
VCR.use_cassette('mets_dtd') do
46+
dtd = Net::HTTP.get(
47+
URI('http://www.loc.gov/standards/mets/version111/mets.xsd'))
48+
sub = submissions(:sub_two)
49+
xsd = Nokogiri::XML::Schema(dtd)
50+
doc = Nokogiri::XML(sub.to_mets)
51+
assert_equal(true, xsd.valid?(doc))
52+
end
53+
end
4354
end

test/test_helper.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
require 'minitest/reporters'
1313
Minitest::Reporters.use!
1414

15+
VCR.configure do |config|
16+
config.cassette_library_dir = 'test/vcr_cassettes'
17+
config.hook_into :webmock
18+
end
19+
1520
module ActiveSupport
1621
class TestCase
1722
# Setup all fixtures in test/fixtures/*.yml for all tests in alpha order.

0 commit comments

Comments
 (0)