cul-fedora-arm 0.5.1

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.
data/.buildpath ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <buildpath>
3
+ <buildpathentry kind="src" path="lib"/>
4
+ <buildpathentry kind="src" path="test"/>
5
+ <buildpathentry exported="true" kind="con" path="org.eclipse.dltk.launching.INTERPRETER_CONTAINER"/>
6
+ </buildpath>
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.sw?
2
+ private
3
+ .DS_Store
4
+ coverage
5
+ rdoc
6
+ pkg
data/.loadpath ADDED
@@ -0,0 +1,5 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <loadpath>
3
+ <pathentry path="" type="src"/>
4
+ <pathentry exported="true" path="org.rubypeople.rdt.launching.RUBY_CONTAINER" type="con"/>
5
+ </loadpath>
data/.project ADDED
@@ -0,0 +1,17 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <projectDescription>
3
+ <name>cul-fedora-arm</name>
4
+ <comment></comment>
5
+ <projects>
6
+ </projects>
7
+ <buildSpec>
8
+ <buildCommand>
9
+ <name>org.eclipse.dltk.core.scriptbuilder</name>
10
+ <arguments>
11
+ </arguments>
12
+ </buildCommand>
13
+ </buildSpec>
14
+ <natures>
15
+ <nature>org.eclipse.dltk.ruby.core.nature</nature>
16
+ </natures>
17
+ </projectDescription>
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 James Stuart
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,29 @@
1
+ = cul-fedora-arm
2
+
3
+ This is designed, given an input specification referring to several metadata and resource files, create and ingest objects into a Fedora reposito
4
+
5
+ == Input
6
+
7
+ The input consists of a specification of relationships and metadata that can be given in one of three ways:
8
+ * A file name
9
+ * An enumerable array of strings
10
+ * A series of FILL IN objects
11
+
12
+ === Input Specification
13
+
14
+ Description goes here.
15
+
16
+ == Note on Patches/Pull Requests
17
+
18
+ * Fork the project.
19
+ * Make your feature addition or bug fix.
20
+ * Add tests for it. This is important so I don't break it in a
21
+ future version unintentionally.
22
+ * Commit, do not mess with rakefile, version, or history.
23
+ (if you want to have your own version, that is fine but
24
+ bump version in a commit by itself I can ignore when I pull)
25
+ * Send me a pull request. Bonus points for topic branches.
26
+
27
+ == Copyright
28
+
29
+ Copyright (c) 2009 James Stuart. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,60 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "cul-fedora-arm"
8
+ gem.summary = %Q{Tools for dealing with Cul ARM specification}
9
+ gem.description = %Q{Tools for dealing with Cul ARM specification}
10
+ gem.email = "tastyhat@jamesstuart.org"
11
+ gem.homepage = "http://github.com/tastyhat/cul-fedora-arm"
12
+ gem.authors = ["James Stuart"]
13
+ gem.add_development_dependency "thoughtbot-shoulda"
14
+ gem.add_development_dependency "thoughtbot-factory_girl"
15
+ gem.add_dependency "activesupport"
16
+ gem.add_dependency "ruby-fedora"
17
+
18
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
19
+ end
20
+ rescue LoadError
21
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
22
+ end
23
+
24
+ require 'rake/testtask'
25
+ Rake::TestTask.new(:test) do |test|
26
+ test.libs << 'lib' << 'test'
27
+ test.pattern = 'test/**/*_test.rb'
28
+ test.verbose = true
29
+ end
30
+
31
+ begin
32
+ require 'rcov/rcovtask'
33
+ Rcov::RcovTask.new do |test|
34
+ test.libs << 'test'
35
+ test.pattern = 'test/**/*_test.rb'
36
+ test.verbose = true
37
+ end
38
+ rescue LoadError
39
+ task :rcov do
40
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
41
+ end
42
+ end
43
+
44
+ task :test => :check_dependencies
45
+
46
+ task :default => :test
47
+
48
+ require 'rake/rdoctask'
49
+ Rake::RDocTask.new do |rdoc|
50
+ if File.exist?('VERSION')
51
+ version = File.read('VERSION')
52
+ else
53
+ version = ""
54
+ end
55
+
56
+ rdoc.rdoc_dir = 'rdoc'
57
+ rdoc.title = "cul-fedora-arm #{version}"
58
+ rdoc.rdoc_files.include('README*')
59
+ rdoc.rdoc_files.include('lib/**/*.rb')
60
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.5.1
@@ -0,0 +1,92 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{cul-fedora-arm}
8
+ s.version = "0.5.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["James Stuart"]
12
+ s.date = %q{2009-10-21}
13
+ s.description = %q{Tools for dealing with Cul ARM specification}
14
+ s.email = %q{tastyhat@jamesstuart.org}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".buildpath",
21
+ ".document",
22
+ ".gitignore",
23
+ ".loadpath",
24
+ ".project",
25
+ "LICENSE",
26
+ "README.rdoc",
27
+ "Rakefile",
28
+ "VERSION",
29
+ "cul-fedora-arm.gemspec",
30
+ "lib/cul-fedora-arm.rb",
31
+ "lib/cul/fedora/.rb",
32
+ "lib/cul/fedora/arm/builder.rb",
33
+ "lib/cul/fedora/arm/foxml_builder.rb",
34
+ "lib/cul/fedora/arm/tasks.rb",
35
+ "lib/cul/fedora/connector.rb",
36
+ "lib/cul/fedora/image/image.rb",
37
+ "test/cul_fedora_arm_builder_test.rb",
38
+ "test/cul_fedora_arm_tasks_test.rb",
39
+ "test/cul_fedora_image_test.rb",
40
+ "test/factories.rb",
41
+ "test/fixtures/case1/builder-template-noheader.txt",
42
+ "test/fixtures/case1/builder-template.txt",
43
+ "test/fixtures/case2/builder-template.txt",
44
+ "test/fixtures/case3/builder-template.txt",
45
+ "test/fixtures/case3/test001.bmp",
46
+ "test/fixtures/case3/test001.gif",
47
+ "test/fixtures/case3/test001.jpg",
48
+ "test/fixtures/case3/test001.png",
49
+ "test/fixtures/case3/test001.tiff",
50
+ "test/fixtures/case4/builder-template.txt",
51
+ "test/fixtures/case4/test-mods.xml",
52
+ "test/helpers/soap_inputs.rb",
53
+ "test/helpers/template_builder.rb",
54
+ "test/test_helper.rb"
55
+ ]
56
+ s.homepage = %q{http://github.com/tastyhat/cul-fedora-arm}
57
+ s.rdoc_options = ["--charset=UTF-8"]
58
+ s.require_paths = ["lib"]
59
+ s.rubygems_version = %q{1.3.5}
60
+ s.summary = %q{Tools for dealing with Cul ARM specification}
61
+ s.test_files = [
62
+ "test/cul_fedora_arm_builder_test.rb",
63
+ "test/cul_fedora_arm_tasks_test.rb",
64
+ "test/cul_fedora_image_test.rb",
65
+ "test/factories.rb",
66
+ "test/helpers/soap_inputs.rb",
67
+ "test/helpers/template_builder.rb",
68
+ "test/test_helper.rb"
69
+ ]
70
+
71
+ if s.respond_to? :specification_version then
72
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
73
+ s.specification_version = 3
74
+
75
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
76
+ s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
77
+ s.add_development_dependency(%q<thoughtbot-factory_girl>, [">= 0"])
78
+ s.add_runtime_dependency(%q<activesupport>, [">= 0"])
79
+ s.add_runtime_dependency(%q<ruby-fedora>, [">= 0"])
80
+ else
81
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
82
+ s.add_dependency(%q<thoughtbot-factory_girl>, [">= 0"])
83
+ s.add_dependency(%q<activesupport>, [">= 0"])
84
+ s.add_dependency(%q<ruby-fedora>, [">= 0"])
85
+ end
86
+ else
87
+ s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
88
+ s.add_dependency(%q<thoughtbot-factory_girl>, [">= 0"])
89
+ s.add_dependency(%q<activesupport>, [">= 0"])
90
+ s.add_dependency(%q<ruby-fedora>, [">= 0"])
91
+ end
92
+ end
@@ -0,0 +1,6 @@
1
+ require "cul/fedora/arm/foxml_builder"
2
+ require "cul/fedora/arm/builder"
3
+ require "cul/fedora/arm/tasks"
4
+ require "cul/fedora/connector"
5
+ require "activesupport"
6
+ require "ruby-fedora"
File without changes
@@ -0,0 +1,230 @@
1
+
2
+ module Cul
3
+ module Fedora
4
+ module Arm
5
+
6
+ # This class is for building ARM resource models in Fedora
7
+ #
8
+ # Authors:: James Stuart (mailto:james.stuart at columbia.edu), Benjamin Armintor (mailto: ba2213 at columbia.edu)
9
+ # License::
10
+ # Dependencies:: activesupport
11
+
12
+ class Builder
13
+
14
+ # TODO: abstract this to allow for multiple patterns
15
+
16
+ # list of columns for a template with no header row
17
+ DEFAULT_TEMPLATE_HEADER = [:sequence, :target, :model_type, :source, :template_type, :dc_format, :id, :pid, :action, :license]
18
+
19
+ # columns that must have values
20
+ REQUIRED_COLUMNS = [:sequence]
21
+
22
+ # columns that must be included in a template
23
+ MANDATORY_COLUMNS = [:sequence, :target, :model_type]
24
+
25
+ # list of columns which may have values
26
+ VALID_COLUMNS = [:sequence, :target, :model_type, :source, :template_type, :dc_format, :id, :pid, :action, :license]
27
+
28
+ FOXML_BUILDER = FoxmlBuilder.new()
29
+ # array of individual hash: each hash corresponds to a metadata or resource.
30
+
31
+ attr_reader :parts, :connector
32
+
33
+
34
+ # creates a Builder object. Can be used with no arguments, or with ONE of the following options
35
+ # [:template]:: builds parts based on an enumerable list of strings (for example, the result of File.open)
36
+ # [:header]:: designates for a template whether a header is specified
37
+ # and one or more of the following:
38
+ # [:host]:: designates a fedora host server name
39
+ # [:admin_port]:: designates a fedora host port for admin
40
+ # [:admin_ssl]:: designates whether ssl should be used
41
+
42
+ # [:user]:: designates a fedora user
43
+ # [:pwd]:: designates a fedora user credential
44
+ def initialize(*args)
45
+ options = args.extract_options!
46
+
47
+ @parts = []
48
+ @connector = options.delete(:connector)
49
+ @namespace = options.delete(:ns)
50
+
51
+ if (template = options.delete(:template)) || (file = options.delete(:file))
52
+ template ||= File.open(file,"r")
53
+
54
+ header = options.delete(:header)
55
+ header = true if header.nil?
56
+
57
+ raise ArgumentError, "arguments should only include one of the following: :template, :file" unless options.empty?
58
+
59
+ parse_template(template, header)
60
+ else
61
+
62
+ raise ArgumentError, "arguments should only include one of the following: :template, :file" unless options.empty?
63
+ end
64
+
65
+ end
66
+
67
+ # adds one part to the parts array
68
+ # arguments are a hash array of column name (underscored symbols) to values
69
+ def add_part(*args)
70
+ value_hash = args.extract_options!
71
+
72
+ test_for_invalid_columns(value_hash.keys)
73
+ test_for_required_columns(value_hash)
74
+
75
+ raise "Sequence ID already taken" if part_by_sequence(value_hash[:sequence])
76
+
77
+ @parts << value_hash
78
+ end
79
+
80
+ # looks for a part by :sequence key
81
+ # note: if loading from a template, sequence will not be an integer, but rather a string
82
+ def part_by_sequence(sequence_id)
83
+ @parts.detect { |p| p[:sequence] == sequence_id}
84
+ end
85
+ # looks for a part by :pid key
86
+ def part_by_pid(pid)
87
+ @parts.detect { |p| p[:pid] == pid}
88
+ end
89
+
90
+ def purge(pid)
91
+ if(@apim)
92
+ purge = Tasks::PurgeTask.new(pid)
93
+ purge.post(@connector)
94
+ end
95
+ end
96
+
97
+ def process_parts()
98
+ reserve_pids(parts)
99
+ parts.each { |part_hash|
100
+ process(part_hash)
101
+ }
102
+ end
103
+
104
+ def process(value_hash)
105
+ # part is a hash
106
+ op = value_hash[:action] + "_" + value_hash[:model_type]
107
+ op.downcase!
108
+ op = op.intern
109
+ raise "Unknown operation #{op}" unless method(op)
110
+ return method(op).call(value_hash)
111
+ end
112
+
113
+ def insert_aggregator(value_hash)
114
+ data = FOXML_BUILDER.build(value_hash)
115
+ task = Tasks::InsertFoxmlTask.new(data)
116
+ task.post(@connector)
117
+ task.response
118
+ end
119
+ def insert_metadata(value_hash)
120
+ data = FOXML_BUILDER.build(value_hash)
121
+ task = Tasks::InsertFoxmlTask.new(data)
122
+ task.post(@connector)
123
+ task.response
124
+ end
125
+ def insert_resource(value_hash)
126
+ data = FOXML_BUILDER.build(value_hash)
127
+ task = Tasks::InsertFoxmlTask.new(data)
128
+ task.post(@connector)
129
+ task.response
130
+ end
131
+
132
+ def reserve_pids(parts=@parts)
133
+ assigned = []
134
+ if (parts.nil?)
135
+ return assigned
136
+ end
137
+ missing = 0
138
+ # count missing pids
139
+ parts.each { |part|
140
+ test_for_required_columns(part)
141
+ if ( part[:action].strip().eql?('insert'))
142
+ if ( !part.has_key?(:pid) or part[:pid].strip().empty?)
143
+ missing += 1
144
+ end
145
+ end
146
+ }
147
+ task = Tasks::ReservePidsTask.new(missing,@namespace)
148
+ task.post(@connector)
149
+ pids = (missing == 1)? [task.response.pid]:task.response.pid
150
+ # assign new pids
151
+ parts.each { |part|
152
+ if ( part[:action].strip().eql?('insert'))
153
+ if ( !part.has_key?(:pid) or part[:pid].strip().empty?)
154
+ part[:pid] = pids.delete_at(0)
155
+ assigned.push(part[:pid])
156
+ end
157
+ end
158
+ }
159
+ # make substitutions in target values
160
+ parts.each { |part|
161
+ if(part.has_key?(:target))
162
+ target = part[:target]
163
+ targets = target.split(';')
164
+ targets.collect! { |t|
165
+ if (t =~ /^\d+$/)
166
+ t = part_by_sequence(t)[:pid]
167
+ end
168
+ t
169
+ }
170
+ part[:target] = targets.join(';')
171
+ end
172
+ }
173
+ assigned
174
+ end
175
+
176
+
177
+
178
+ protected
179
+
180
+
181
+ # checks keys of a hash to make sure all elements of REQUIRED_COLUMNS are contained.
182
+ def test_for_required_columns(value_hash)
183
+ missing_values = REQUIRED_COLUMNS.select { |col| !value_hash.has_key?(col) || value_hash[col].nil? }
184
+ if (value_hash.has_key?(:action) and value_hash[:action].eql?('update'))
185
+ raise "Update operations require a PID" unless (value_hash.has_key(:pid) and !value_hash[:pid].strip().eql?(''))
186
+ end
187
+ raise "Missing required values #{missing_values.join(",")}" unless missing_values.empty?
188
+ end
189
+
190
+ # checks list of column names to make sure every one is in VALID_COLUMNS
191
+ def test_for_invalid_columns(columns)
192
+ invalid_columns = columns.select { |c| !VALID_COLUMNS.include?(c) }
193
+ raise "Invalid column(s) found: #{invalid_columns.join(",")}" unless invalid_columns.empty?
194
+ end
195
+
196
+ # parses an enumerable of strings to build parts
197
+ # an optional header row specifies the columns, however sequence must be included and must be first
198
+ # TODO: fix this to include a header option
199
+ def parse_template(template, has_header_row)
200
+ header_columns = DEFAULT_TEMPLATE_HEADER # list of columns
201
+
202
+
203
+ template.each_with_index do |line, i|
204
+
205
+ # if first row, check for header
206
+ if i == 0
207
+ header_columns = line.split("\t").collect { |cn| cn.strip.underscore.to_sym } if has_header_row
208
+
209
+ # check to make sure all mandatory columns are in the template
210
+ missing_mandatory_columns = MANDATORY_COLUMNS.select { |c| !header_columns.include?(c) }
211
+ raise "Missing mandatory column(s) found: #{missing_mandatory_columns.join(",")}" unless missing_mandatory_columns.empty?
212
+
213
+ test_for_invalid_columns(header_columns)
214
+
215
+ # skip header_row
216
+ next if has_header_row
217
+
218
+ end
219
+
220
+ # create hash out of columns and whitespace-stripped values
221
+ value_hash = Hash[*header_columns.zip(line.split("\t").collect(&:strip)).flatten]
222
+ add_part(value_hash)
223
+ end
224
+ parts
225
+ end
226
+ end
227
+ end
228
+ end
229
+
230
+ end