hybag 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/Gemfile +2 -0
- data/README.md +25 -1
- data/hybag.gemspec +1 -1
- data/lib/hybag/ingester.rb +111 -0
- data/lib/hybag/version.rb +1 -1
- data/lib/hybag.rb +4 -1
- data/spec/fixtures/example_datastream.nt +13 -13
- data/spec/fixtures/hybag.yml +1 -0
- data/spec/fixtures/rels.rdf +6 -0
- data/spec/lib/hybag/baggable_spec.rb +3 -2
- data/spec/lib/hybag/ingester_spec.rb +119 -0
- data/spec/lib/hybag_spec.rb +10 -0
- data/spec/spec_helper.rb +0 -1
- metadata +15 -6
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
OTA5YWU4ZGE4YzliMDdkMmU0NzE1YjdmYTQwMTA5MjhhYTExNGFkMQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YjE1ZjI2NGQ1MmY2ZTdhNDgwMjVhMmUwNGIwNzZkZTM1NWVjNjQzMg==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MjM1NDAxMmQ3MDliZTk4Y2U4ZTBiYmQxMTNmODk2MjdlYzQ2NmQ3ZTk3ZDQ3
|
10
|
+
ZjcyZDc3MzEwOTgxZjkzNGNhYjA3MjFhOWM4ZWNmZjM1OGViOTU4ODBiMTQ4
|
11
|
+
NDA4YmZmYTIxMGQ1MjNmMTQyZTIzYzc3MWEwODU1MzZlOTNkOGQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NTQ5NDVmYzcxYzFmNjgyNzM4YWM5Njk4MmEyZTRhZjg2ZDlhYTRhNzE1Yzhm
|
14
|
+
ZWU3YzZiOGMyMmY1MzBhMmNmNjMwYzAxNGMwYmJmZDNmNmUzM2I1MjBjZmQ3
|
15
|
+
YTcwNWY1ZDhjY2M1ODFjODY2ZDA0MjkwZWQ5NjI4N2FlNWI0ODA=
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -18,7 +18,7 @@ Or install it yourself as:
|
|
18
18
|
|
19
19
|
## Usage
|
20
20
|
|
21
|
-
|
21
|
+
#### Include the module in ActiveFedora models you'd like to be baggable
|
22
22
|
|
23
23
|
```ruby
|
24
24
|
class TestClass < ActiveFedora::Base
|
@@ -26,6 +26,30 @@ Or install it yourself as:
|
|
26
26
|
end
|
27
27
|
```
|
28
28
|
|
29
|
+
#### To convert an exported bag back to a model
|
30
|
+
|
31
|
+
**NOTE:** Right now for this to work there must be datastreams defined on the discovered model which match the
|
32
|
+
metadata datastream IDs as tag files and content datastream IDs as data files. This means for a descMetadata
|
33
|
+
datastream to be populated bag_root/descMetadata.* (where * is the extension) must exist.
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
result = Hybag.ingest(BagIt::Bag.new("/path/to/bag"))
|
37
|
+
result.class # => Model in fedora/rels-ext.rdf (preferred) or hybag.yml in bag root. More info below.
|
38
|
+
result.persisted? # => false
|
39
|
+
```
|
40
|
+
|
41
|
+
## Configuration
|
42
|
+
|
43
|
+
#### Determining the model name.
|
44
|
+
|
45
|
+
Currently the model name is determined from the bag's fedora/rels-ext.rdf file (which Hybag::Baggable exports)
|
46
|
+
or a config file stored in bag_root/hybag.yml. The fedora rels-ext takes precedence. An example Hybag.yml format is
|
47
|
+
below
|
48
|
+
|
49
|
+
```yml
|
50
|
+
model: TestModel
|
51
|
+
```
|
52
|
+
|
29
53
|
### Examples
|
30
54
|
|
31
55
|
#### Write the item to disk in rails_root/tmp/bags/filler/pid
|
data/hybag.gemspec
CHANGED
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'rdf/rdfxml'
|
2
|
+
|
3
|
+
module Hybag
|
4
|
+
class Ingester
|
5
|
+
attr_accessor :bag
|
6
|
+
def initialize(bag)
|
7
|
+
@bag = bag
|
8
|
+
end
|
9
|
+
|
10
|
+
def ingest
|
11
|
+
raise "Unable to determine model from bag" if model_name.blank?
|
12
|
+
new_object = ActiveFedora.class_from_string(model_name.to_s).new
|
13
|
+
# Assign a pid
|
14
|
+
new_object.inner_object.pid = ActiveFedora::Base.assign_pid(new_object)
|
15
|
+
set_metadata_streams(new_object)
|
16
|
+
set_file_streams(new_object)
|
17
|
+
return new_object
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
# TODO: What to do if the bag has files that don't have model definitions?
|
23
|
+
# TODO: Add some sort of configuration to map bag filenames -> dsids.
|
24
|
+
def set_metadata_streams(object)
|
25
|
+
object.metadata_streams.each do |ds|
|
26
|
+
if bag_has_metastream?(ds.dsid)
|
27
|
+
ds.content = bag_metastream(ds.dsid).read.strip
|
28
|
+
# Assume the first subject in the metadata is about this object.
|
29
|
+
# TODO: Move this to configuration?
|
30
|
+
first_subject = ds.graph.first_subject
|
31
|
+
new_repository = RDF::Repository.new
|
32
|
+
ds.graph.each_statement do |statement|
|
33
|
+
subject = statement.subject
|
34
|
+
subject = ds.rdf_subject if subject == first_subject
|
35
|
+
new_repository << [subject, statement.predicate, statement.object]
|
36
|
+
end
|
37
|
+
ds.instance_variable_set(:@graph,new_repository)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def set_file_streams(object)
|
43
|
+
file_streams = object.datastreams.select{|k, ds| !ds.metadata?}.values
|
44
|
+
file_streams.each do |ds|
|
45
|
+
if bag_has_datastream?(ds.dsid)
|
46
|
+
ds.content = bag_datastream(ds.dsid).read
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# TODO: Might consider decoration at some point.
|
52
|
+
def bag_filename_to_label(bag_filename)
|
53
|
+
Pathname.new(bag_filename).basename.sub_ext('').to_s
|
54
|
+
end
|
55
|
+
|
56
|
+
def bag_has_datastream?(label)
|
57
|
+
bag.bag_files.any?{|x| bag_filename_to_label(x) == label}
|
58
|
+
end
|
59
|
+
|
60
|
+
def bag_datastream(label)
|
61
|
+
bag_file = bag.bag_files.select{|x| bag_filename_to_label(x) == label}.first
|
62
|
+
result = File.open(bag_file) unless bag_file.blank?
|
63
|
+
return result
|
64
|
+
end
|
65
|
+
|
66
|
+
def bag_has_metastream?(label)
|
67
|
+
bag.tag_files.any?{|x| bag_filename_to_label(x) == label}
|
68
|
+
end
|
69
|
+
|
70
|
+
def bag_metastream(label)
|
71
|
+
tag_file = bag.tag_files.select{|x| bag_filename_to_label(x) == label}.first
|
72
|
+
result = File.open(tag_file) unless tag_file.blank?
|
73
|
+
return result
|
74
|
+
end
|
75
|
+
|
76
|
+
def model_name
|
77
|
+
# TODO: Add a default model_name configuration option?
|
78
|
+
@model_name ||= extract_model_from_rels || extract_model_from_yaml
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
def extract_model_from_rels
|
83
|
+
if File.exist?(fedora_rels)
|
84
|
+
filler_object = ActiveFedora::Base.new
|
85
|
+
rels_datastream = ActiveFedora::RelsExtDatastream.new
|
86
|
+
rels_datastream.model = filler_object
|
87
|
+
ActiveFedora::RelsExtDatastream.from_xml(File.read(fedora_rels).strip,rels_datastream)
|
88
|
+
model_name = ActiveFedora::ContentModel.known_models_for(filler_object).first
|
89
|
+
return model_name.to_s
|
90
|
+
end
|
91
|
+
return model_name
|
92
|
+
end
|
93
|
+
|
94
|
+
def extract_model_from_yaml
|
95
|
+
model_name = nil
|
96
|
+
if(File.exist?(yaml_config))
|
97
|
+
conf = YAML.load(File.read(yaml_config))
|
98
|
+
model_name = conf['model']
|
99
|
+
end
|
100
|
+
return model_name
|
101
|
+
end
|
102
|
+
|
103
|
+
def yaml_config
|
104
|
+
File.join(bag.bag_dir,"hybag.yml")
|
105
|
+
end
|
106
|
+
|
107
|
+
def fedora_rels
|
108
|
+
File.join(bag.bag_dir,"fedora","RELS-EXT.rdf")
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
data/lib/hybag/version.rb
CHANGED
data/lib/hybag.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
<
|
2
|
-
<
|
3
|
-
<
|
4
|
-
<
|
5
|
-
<
|
6
|
-
<
|
7
|
-
<
|
8
|
-
<
|
9
|
-
<
|
10
|
-
<
|
11
|
-
<
|
12
|
-
<
|
13
|
-
<
|
1
|
+
<info:fedora/filler> <http://purl.org/dc/terms/type> "Image" .
|
2
|
+
<info:fedora/filler> <http://purl.org/dc/terms/spatial> "Benton County (Ore.)" .
|
3
|
+
<info:fedora/filler> <http://purl.org/dc/terms/created> "2004-03-17" .
|
4
|
+
<info:fedora/filler> <http://purl.org/dc/terms/description> "Mexican workers in Benton County" .
|
5
|
+
<info:fedora/filler> <http://purl.org/dc/terms/rights> "Permission to use must be obtained from OSU Archives." .
|
6
|
+
<info:fedora/filler> <http://multimedialab.elis.ugent.be/users/samcoppe/ontologies/Premis/premis.owl#originalName> "P0120_2567" .
|
7
|
+
<info:fedora/filler> <http://purl.org/dc/terms/title> "Mexican workers" .
|
8
|
+
<info:fedora/filler> <http://purl.org/dc/terms/subject> "Agricultural laborers--Mexican--Oregon" .
|
9
|
+
<info:fedora/filler> <http://purl.org/dc/terms/subject> "Agricultural laborers--Housing--Oregon" .
|
10
|
+
<info:fedora/filler> <http://purl.org/dc/terms/identifier> "P120:2567" .
|
11
|
+
<info:fedora/filler> <http://purl.org/dc/terms/modified> "2011-12-19" .
|
12
|
+
<info:fedora/filler> <http://purl.org/dc/terms/hasFormat> "B&W print" .
|
13
|
+
<info:fedora/filler> <http://purl.org/dc/terms/date> "1944" .
|
@@ -0,0 +1 @@
|
|
1
|
+
model: TestModel
|
@@ -0,0 +1,6 @@
|
|
1
|
+
|
2
|
+
<rdf:RDF xmlns:ns0="info:fedora/fedora-system:def/model#" xmlns:ns1="info:fedora/fedora-system:def/relations-external#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
3
|
+
<rdf:Description rdf:about="info:fedora/filler">
|
4
|
+
<ns0:hasModel rdf:resource="info:fedora/afmodel:BaggableDummy"></ns0:hasModel>
|
5
|
+
</rdf:Description>
|
6
|
+
</rdf:RDF>
|
@@ -9,6 +9,8 @@ describe Hybag::Baggable do
|
|
9
9
|
@item.descMetadata.content = File.open(File.join(FIXTURE_PATH,"example_datastream.nt")).read
|
10
10
|
content_file = File.open(File.join(FIXTURE_PATH,"hydra.png"))
|
11
11
|
@item.add_file_datastream(content_file, :dsid => "content", :mimeType => "image/png")
|
12
|
+
@item.rels_ext.content = File.open(File.join(FIXTURE_PATH,"rels.rdf")).read
|
13
|
+
@item.load_relationships
|
12
14
|
@item.stub(:persisted?).and_return(true)
|
13
15
|
# Stub Rails root
|
14
16
|
rails = double("Rails")
|
@@ -45,8 +47,7 @@ describe Hybag::Baggable do
|
|
45
47
|
@bag = @item.write_bag('/tmp/bag')
|
46
48
|
end
|
47
49
|
it "should write tag files to disk" do
|
48
|
-
|
49
|
-
#@bag.tag_files.should include(File.join(@bag.bag_dir, 'fedora', 'RELS-EXT.rdf'))
|
50
|
+
@bag.tag_files.should include(File.join(@bag.bag_dir, 'fedora', 'RELS-EXT.rdf'))
|
50
51
|
@bag.tag_files.should include(File.join(@bag.bag_dir, 'descMetadata.nt'))
|
51
52
|
end
|
52
53
|
it "should write content files to disk" do
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'open-uri'
|
3
|
+
require 'pry'
|
4
|
+
require File.join(DUMMY_PATH, "baggable_dummy")
|
5
|
+
|
6
|
+
# Override Kernel.open
|
7
|
+
module ::Kernel
|
8
|
+
private
|
9
|
+
|
10
|
+
alias :original_open :open
|
11
|
+
def open(name, *rest, &block)
|
12
|
+
if name =~ /\|.*/ then
|
13
|
+
original_open(name, *rest, &block)
|
14
|
+
else
|
15
|
+
FakeFS::File.open(name, *rest, &block)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
module_function :open
|
19
|
+
end
|
20
|
+
|
21
|
+
describe Hybag::Ingester do
|
22
|
+
before(:each) do
|
23
|
+
@item = BaggableDummy.new(:pid => "filler")
|
24
|
+
@item.descMetadata.content = File.open(File.join(FIXTURE_PATH,"example_datastream.nt")).read.strip
|
25
|
+
content_file = File.open(File.join(FIXTURE_PATH,"hydra.png"))
|
26
|
+
@item.add_file_datastream(content_file, :dsid => "content", :mimeType => "image/png")
|
27
|
+
@item.rels_ext.content = File.open(File.join(FIXTURE_PATH,"rels.rdf")).read
|
28
|
+
@item.load_relationships
|
29
|
+
@item.stub(:persisted?).and_return(true)
|
30
|
+
# Stub Rails root
|
31
|
+
rails = double("Rails")
|
32
|
+
Rails = rails unless defined?(Rails)
|
33
|
+
Rails.stub(:root).and_return(Pathname.new('/test'))
|
34
|
+
# Stub ActiveFedora assign_pid
|
35
|
+
ActiveFedora::Base.stub(:assign_pid).and_return("new_filler")
|
36
|
+
end
|
37
|
+
let(:item) {@item}
|
38
|
+
let(:bag) {item.write_bag}
|
39
|
+
subject {Hybag::Ingester.new(bag)}
|
40
|
+
describe "functionality" do
|
41
|
+
include FakeFS::SpecHelpers
|
42
|
+
describe ".model_name" do
|
43
|
+
context "when there is a rels" do
|
44
|
+
it "should return the model name stored by the bag in rels" do
|
45
|
+
subject.send(:model_name).should == "BaggableDummy"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
context "when there is no rels" do
|
49
|
+
context "when there is a hybag.yml" do
|
50
|
+
before(:each) do
|
51
|
+
FileUtils.rm(subject.send(:fedora_rels), :force => true)
|
52
|
+
# Add the hybag.yml from fixture
|
53
|
+
FakeFS.deactivate!
|
54
|
+
hybag_content = File.read(File.join(FIXTURE_PATH,"hybag.yml"))
|
55
|
+
FakeFS.activate!
|
56
|
+
File.open(File.join(bag.bag_dir,"hybag.yml"),'w') {|f| f.puts hybag_content}
|
57
|
+
end
|
58
|
+
it "should pull the data out of hybag.yml" do
|
59
|
+
subject.send(:model_name).should == "TestModel"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
context "when there is a rels and a hybag.yml" do
|
64
|
+
before(:each) do
|
65
|
+
# Add the hybag.yml from fixture
|
66
|
+
FakeFS.deactivate!
|
67
|
+
hybag_content = File.read(File.join(FIXTURE_PATH,"hybag.yml"))
|
68
|
+
FakeFS.activate!
|
69
|
+
File.open(File.join(bag.bag_dir,"hybag.yml"),'w') {|f| f.puts hybag_content}
|
70
|
+
end
|
71
|
+
it "should prioritize the rels" do
|
72
|
+
subject.send(:model_name).should == "BaggableDummy"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
describe ".ingest" do
|
77
|
+
context "when there is no discoverable model" do
|
78
|
+
before(:each) do
|
79
|
+
subject.stub(:model_name).and_return(nil)
|
80
|
+
end
|
81
|
+
it "should raise an error" do
|
82
|
+
expect{subject.ingest}.to raise_error("Unable to determine model from bag")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
context "when there is a model" do
|
86
|
+
it "should return an instance of that model" do
|
87
|
+
expect(subject.ingest).to be_kind_of(BaggableDummy)
|
88
|
+
end
|
89
|
+
it "should assign that model a pid" do
|
90
|
+
puts ActiveFedora::Base.assign_pid
|
91
|
+
expect((subject.ingest).pid).to eq "new_filler"
|
92
|
+
end
|
93
|
+
context "and that model is not defined" do
|
94
|
+
before(:each) do
|
95
|
+
subject.stub(:model_name).and_return("Blabla")
|
96
|
+
end
|
97
|
+
it "should raise an error" do
|
98
|
+
expect{subject.ingest}.to raise_error
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
describe "returned model" do
|
103
|
+
let(:built_model) {subject.ingest}
|
104
|
+
it "should populate datastreams" do
|
105
|
+
Array.wrap(built_model.title).first.should == "Mexican workers"
|
106
|
+
end
|
107
|
+
it "should populate file datastreams" do
|
108
|
+
built_model.content.content.should == File.read(File.join(bag.data_dir,"content.png"))
|
109
|
+
end
|
110
|
+
it "should be new" do
|
111
|
+
expect(built_model).to be_new
|
112
|
+
end
|
113
|
+
it "should not be persisted" do
|
114
|
+
expect(built_model).not_to be_persisted
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hybag
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Trey Terrell
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-08-
|
11
|
+
date: 2013-08-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -132,16 +132,16 @@ dependencies:
|
|
132
132
|
name: bagit
|
133
133
|
requirement: !ruby/object:Gem::Requirement
|
134
134
|
requirements:
|
135
|
-
- - '
|
135
|
+
- - ! '>='
|
136
136
|
- !ruby/object:Gem::Version
|
137
|
-
version: 0
|
137
|
+
version: '0'
|
138
138
|
type: :runtime
|
139
139
|
prerelease: false
|
140
140
|
version_requirements: !ruby/object:Gem::Requirement
|
141
141
|
requirements:
|
142
|
-
- - '
|
142
|
+
- - ! '>='
|
143
143
|
- !ruby/object:Gem::Version
|
144
|
-
version: 0
|
144
|
+
version: '0'
|
145
145
|
- !ruby/object:Gem::Dependency
|
146
146
|
name: mime-types
|
147
147
|
requirement: !ruby/object:Gem::Requirement
|
@@ -173,13 +173,18 @@ files:
|
|
173
173
|
- lib/hybag.rb
|
174
174
|
- lib/hybag/bag_writer.rb
|
175
175
|
- lib/hybag/baggable.rb
|
176
|
+
- lib/hybag/ingester.rb
|
176
177
|
- lib/hybag/validator.rb
|
177
178
|
- lib/hybag/version.rb
|
178
179
|
- spec/dummies/baggable_dummy.rb
|
179
180
|
- spec/fixtures/example_datastream.nt
|
181
|
+
- spec/fixtures/hybag.yml
|
180
182
|
- spec/fixtures/hydra.png
|
183
|
+
- spec/fixtures/rels.rdf
|
181
184
|
- spec/lib/hybag/baggable_spec.rb
|
185
|
+
- spec/lib/hybag/ingester_spec.rb
|
182
186
|
- spec/lib/hybag/validator_spec.rb
|
187
|
+
- spec/lib/hybag_spec.rb
|
183
188
|
- spec/spec_helper.rb
|
184
189
|
- spec/support/fakefs.rb
|
185
190
|
homepage: ''
|
@@ -209,8 +214,12 @@ summary: A Hydra gem for adding BagIt functionality to ActiveFedora models.
|
|
209
214
|
test_files:
|
210
215
|
- spec/dummies/baggable_dummy.rb
|
211
216
|
- spec/fixtures/example_datastream.nt
|
217
|
+
- spec/fixtures/hybag.yml
|
212
218
|
- spec/fixtures/hydra.png
|
219
|
+
- spec/fixtures/rels.rdf
|
213
220
|
- spec/lib/hybag/baggable_spec.rb
|
221
|
+
- spec/lib/hybag/ingester_spec.rb
|
214
222
|
- spec/lib/hybag/validator_spec.rb
|
223
|
+
- spec/lib/hybag_spec.rb
|
215
224
|
- spec/spec_helper.rb
|
216
225
|
- spec/support/fakefs.rb
|