mead 0.0.5
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/.document +5 -0
- data/Gemfile +27 -0
- data/Gemfile.lock +56 -0
- data/LICENSE +20 -0
- data/README.rdoc +86 -0
- data/Rakefile +67 -0
- data/VERSION +1 -0
- data/bin/automead +53 -0
- data/bin/ead2meads +90 -0
- data/bin/emv +77 -0
- data/bin/mead2barcode +64 -0
- data/bin/meadbfv +27 -0
- data/lib/mead/barcode.rb +49 -0
- data/lib/mead/container.rb +21 -0
- data/lib/mead/ead.rb +215 -0
- data/lib/mead/ead_validator.rb +46 -0
- data/lib/mead/extractor.rb +198 -0
- data/lib/mead/identifier.rb +112 -0
- data/lib/mead/trollop.rb +38 -0
- data/lib/mead/validations.rb +130 -0
- data/lib/mead.rb +71 -0
- data/mead.gemspec +142 -0
- data/test/ead/mc00145.xml +157 -0
- data/test/ead/mc00240.xml +12523 -0
- data/test/ead/ua015_010.xml +31103 -0
- data/test/ead/ua021_428.xml +146 -0
- data/test/ead/ua023_006.xml +469 -0
- data/test/ead/ua023_031.xml +5202 -0
- data/test/ead/ua110_041.xml +4101 -0
- data/test/fixtures/mc00310.xml +186 -0
- data/test/fixtures/ua023_031.xml +5228 -0
- data/test/helper.rb +38 -0
- data/test/test_barcode.rb +25 -0
- data/test/test_ead.rb +193 -0
- data/test/test_ead_validator.rb +18 -0
- data/test/test_extractor.rb +83 -0
- data/test/test_mc00145.rb +19 -0
- data/test/test_mc00240.rb +140 -0
- data/test/test_mead.rb +5 -0
- data/test/test_ua015_010.rb +111 -0
- data/test/test_ua021_428.rb +26 -0
- data/test/test_ua023_006_buildings.rb +111 -0
- data/test/test_ua023_006_faculty.rb +112 -0
- data/test/test_ua110_041.rb +112 -0
- data/test/test_validations.rb +81 -0
- data/watchr.rb +71 -0
- metadata +338 -0
data/.document
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
gem "rmagick", ">= 0"
|
7
|
+
gem "nokogiri", "= 1.4.3.1"
|
8
|
+
gem "json", ">= 0"
|
9
|
+
gem "trollop", ">= 0"
|
10
|
+
|
11
|
+
gem "fastercsv", ">= 0", :platforms => :ruby_18
|
12
|
+
|
13
|
+
gem "gbarcode", ">= 0.98.20", :platforms => :ruby_18
|
14
|
+
|
15
|
+
|
16
|
+
# Add dependencies to develop your gem here.
|
17
|
+
# Include everything needed to run rake, tests, features, etc.
|
18
|
+
group :development do
|
19
|
+
gem "shoulda", ">= 0"
|
20
|
+
gem "bundler", "~> 1.0.0"
|
21
|
+
gem "jeweler", "~> 1.5.1"
|
22
|
+
gem "rcov", ">= 0"
|
23
|
+
gem "reek", "~> 1.2.8"
|
24
|
+
gem "roodi", "~> 2.1.0"
|
25
|
+
gem "fakeweb", ">= 0"
|
26
|
+
gem "ruby-debug"
|
27
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
columnize (0.3.2)
|
5
|
+
fakeweb (1.3.0)
|
6
|
+
fastercsv (1.5.4)
|
7
|
+
gbarcode (0.98.20)
|
8
|
+
git (1.2.5)
|
9
|
+
jeweler (1.5.2)
|
10
|
+
bundler (~> 1.0.0)
|
11
|
+
git (>= 1.2.5)
|
12
|
+
rake
|
13
|
+
json (1.5.0)
|
14
|
+
linecache (0.43)
|
15
|
+
nokogiri (1.4.3.1)
|
16
|
+
rake (0.8.7)
|
17
|
+
rcov (0.9.9)
|
18
|
+
reek (1.2.8)
|
19
|
+
ruby2ruby (~> 1.2)
|
20
|
+
ruby_parser (~> 2.0)
|
21
|
+
sexp_processor (~> 3.0)
|
22
|
+
rmagick (2.13.1)
|
23
|
+
roodi (2.1.0)
|
24
|
+
ruby_parser
|
25
|
+
ruby-debug (0.10.4)
|
26
|
+
columnize (>= 0.1)
|
27
|
+
ruby-debug-base (~> 0.10.4.0)
|
28
|
+
ruby-debug-base (0.10.4)
|
29
|
+
linecache (>= 0.3)
|
30
|
+
ruby2ruby (1.2.5)
|
31
|
+
ruby_parser (~> 2.0)
|
32
|
+
sexp_processor (~> 3.0)
|
33
|
+
ruby_parser (2.0.5)
|
34
|
+
sexp_processor (~> 3.0)
|
35
|
+
sexp_processor (3.0.5)
|
36
|
+
shoulda (2.11.3)
|
37
|
+
trollop (1.16.2)
|
38
|
+
|
39
|
+
PLATFORMS
|
40
|
+
ruby
|
41
|
+
|
42
|
+
DEPENDENCIES
|
43
|
+
bundler (~> 1.0.0)
|
44
|
+
fakeweb
|
45
|
+
fastercsv
|
46
|
+
gbarcode (>= 0.98.20)
|
47
|
+
jeweler (~> 1.5.1)
|
48
|
+
json
|
49
|
+
nokogiri (= 1.4.3.1)
|
50
|
+
rcov
|
51
|
+
reek (~> 1.2.8)
|
52
|
+
rmagick
|
53
|
+
roodi (~> 2.1.0)
|
54
|
+
ruby-debug
|
55
|
+
shoulda
|
56
|
+
trollop
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 North Carolina State University
|
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,86 @@
|
|
1
|
+
= mead
|
2
|
+
|
3
|
+
Metadata from Encoded Archival Description.
|
4
|
+
|
5
|
+
The core of this code is an identifier which expresses the location of an object
|
6
|
+
in a physical collection. This identifier can be used as a filename for
|
7
|
+
digitized objects during scanning. Later descriptive metadata from EAD XML can
|
8
|
+
be extracted. This descriptive metadata can then be applied to stub records for
|
9
|
+
each digital object, which can quickly make digitized objects as discoverable as
|
10
|
+
the archival description makes the physical collections.
|
11
|
+
|
12
|
+
== Functionality
|
13
|
+
|
14
|
+
- Parse EAD XML and output all identifiers (with other metadata) for all the
|
15
|
+
component parts. This export can be CSV or JSON.
|
16
|
+
- Resolve a filename-identifier to a location in the physical collection and
|
17
|
+
extract related metadata up through the hierarchy
|
18
|
+
- Create barcodes based on an identifiers.
|
19
|
+
- Validate whether an identifier is well-formed and valid by resolving to a
|
20
|
+
component part in the EAD XML.
|
21
|
+
- Commandline tools for each of these functions.
|
22
|
+
|
23
|
+
== Installation
|
24
|
+
|
25
|
+
- clone from github and build the gem from source at this time
|
26
|
+
|
27
|
+
== Identifier specification in brief
|
28
|
+
|
29
|
+
These identifiers encode information about where original objects in the physical
|
30
|
+
collection are located. To make this work for as wide a range of encoded EAD XML
|
31
|
+
and archival arrangement and processing practice as we could, it includes many
|
32
|
+
pieces of information to help insure uniqueness within a collection.
|
33
|
+
|
34
|
+
Indentifiers are made up of 6 possible segments. Segments are separated by a
|
35
|
+
single dash - to aid in readability. Take the sample identifier
|
36
|
+
mc00240-001-ff0001-000-001_0001
|
37
|
+
|
38
|
+
1. mc00240: Collection number.
|
39
|
+
The first section identifies the collection and
|
40
|
+
is usually the eadid of the collection. mc00240 refers to
|
41
|
+
http://www.lib.ncsu.edu/findingaids/mc00240
|
42
|
+
|
43
|
+
2. 001: Series number.
|
44
|
+
This is the number of the series of which the physical
|
45
|
+
item is a part. It is a three digit, left zero padded number.
|
46
|
+
|
47
|
+
3. ff0001: Container code & number.
|
48
|
+
The third segment is made up of a two letter
|
49
|
+
code for different container types. The list of current codes can be seen in
|
50
|
+
lib/mead.rb as Mead::CONTAINER_MAPPING. (These are the codes NCSU uses for
|
51
|
+
encoding containers in EAD XML.) The second part is a three digit, left zero
|
52
|
+
padded number. This example would be flatfolder 1.
|
53
|
+
|
54
|
+
4. 000: Folder number.
|
55
|
+
In this case there is no second container, so the folder
|
56
|
+
number is 000. If there was a container with the "folder" value for the type
|
57
|
+
attribute and text content of "3", then this segment would be 003. In the case
|
58
|
+
where the value is other than "folder" the container code is used in front. So
|
59
|
+
a "mapcase" container could be "mc003" when the map case is the third map case
|
60
|
+
in the parent container.
|
61
|
+
|
62
|
+
5. 001: Item number.
|
63
|
+
This is the number of the item in the container. It is an
|
64
|
+
arbitrary incremented number. Multiple pages of multipage document would
|
65
|
+
be considered as one item and so would get the same item number.
|
66
|
+
|
67
|
+
6. _0001: Sequence number (optional).
|
68
|
+
If there is a multipage document then this
|
69
|
+
section can be used. This is the sequence or page number. It is preceded with
|
70
|
+
an underscore.
|
71
|
+
|
72
|
+
|
73
|
+
== TODO
|
74
|
+
|
75
|
+
- Test for use by other institutions. I'm happy to help make this code work for
|
76
|
+
the needs of other institutions.
|
77
|
+
- Get more examples for more tests.
|
78
|
+
- Better exceptions.
|
79
|
+
|
80
|
+
== Author
|
81
|
+
|
82
|
+
Jason Ronallo
|
83
|
+
|
84
|
+
== Copyright
|
85
|
+
|
86
|
+
Copyright (c) 2010 North Carolina State University. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "mead"
|
16
|
+
gem.homepage = "http://github.com/jronallo/mead"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{Extract identifiers and metadata from EAD XML.}
|
19
|
+
gem.description = %Q{Extract identifiers and metadata from EAD XML.}
|
20
|
+
gem.email = "jronallo@gmail.com"
|
21
|
+
gem.authors = ["Jason Ronallo"]
|
22
|
+
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
23
|
+
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
24
|
+
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
25
|
+
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
26
|
+
end
|
27
|
+
Jeweler::RubygemsDotOrgTasks.new
|
28
|
+
|
29
|
+
require 'rake/testtask'
|
30
|
+
Rake::TestTask.new(:test) do |test|
|
31
|
+
test.libs << 'lib' << 'test'
|
32
|
+
test.pattern = 'test/**/test_*.rb'
|
33
|
+
test.verbose = true
|
34
|
+
end
|
35
|
+
|
36
|
+
require 'rcov/rcovtask'
|
37
|
+
Rcov::RcovTask.new do |test|
|
38
|
+
test.libs << 'test'
|
39
|
+
test.pattern = 'test/**/test_*.rb'
|
40
|
+
test.verbose = true
|
41
|
+
end
|
42
|
+
|
43
|
+
require 'reek/rake/task'
|
44
|
+
Reek::Rake::Task.new do |t|
|
45
|
+
t.fail_on_error = true
|
46
|
+
t.verbose = false
|
47
|
+
t.source_files = 'lib/**/*.rb'
|
48
|
+
end
|
49
|
+
|
50
|
+
require 'roodi'
|
51
|
+
require 'roodi_task'
|
52
|
+
RoodiTask.new do |t|
|
53
|
+
t.verbose = false
|
54
|
+
end
|
55
|
+
|
56
|
+
task :default => :test
|
57
|
+
|
58
|
+
require 'rake/rdoctask'
|
59
|
+
Rake::RDocTask.new do |rdoc|
|
60
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
61
|
+
|
62
|
+
rdoc.rdoc_dir = 'rdoc'
|
63
|
+
rdoc.title = "mead #{version}"
|
64
|
+
rdoc.rdoc_files.include('README*')
|
65
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
66
|
+
end
|
67
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.5
|
data/bin/automead
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
3
|
+
require 'pp'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'mead'
|
6
|
+
require 'mead/trollop'
|
7
|
+
require 'trollop'
|
8
|
+
include Mead::TrollopOptions
|
9
|
+
|
10
|
+
opts = Trollop::options do
|
11
|
+
banner <<-EOS
|
12
|
+
This script takes a mead (an identifier of a particular format) and returns
|
13
|
+
metadata for it.
|
14
|
+
|
15
|
+
Usage Example:
|
16
|
+
automead --mead mc00240-001-ff0052-000-001 --baseurl http://www.lib.ncsu.edu/findingaids --ruby [options]
|
17
|
+
|
18
|
+
Default output is pretty printed Ruby. Multiple outputs can be specified.
|
19
|
+
|
20
|
+
where options are:
|
21
|
+
EOS
|
22
|
+
opt :mead, "A mead-style identifier", :required => true, :type => String
|
23
|
+
opt :baseurl, 'Specify just the base URL for grabbing the EAD XML if it is of the format baseurl/eadid.xml.', :type => String
|
24
|
+
opt :url, 'Specify the whole URL for grabbing the EAD XML.', :type => String
|
25
|
+
opt :file, 'File path to EAD XML.', :type => String
|
26
|
+
opt :ruby, 'Output as pretty printed Ruby. Default.'
|
27
|
+
opt :json, 'Output as JSON'
|
28
|
+
end
|
29
|
+
|
30
|
+
check_options(opts)
|
31
|
+
location = get_location(opts)
|
32
|
+
|
33
|
+
mead = Mead::Identifier.new(opts[:mead], location)
|
34
|
+
|
35
|
+
if mead.valid?
|
36
|
+
pp mead.metadata if opts[:ruby]
|
37
|
+
puts mead.metadata.to_json if opts[:json]
|
38
|
+
if !opts[:ruby] and !opts[:json]
|
39
|
+
pp mead.metadata
|
40
|
+
end
|
41
|
+
else
|
42
|
+
response = {}
|
43
|
+
response[:status] = 'Invalid'
|
44
|
+
response.merge!(mead.errors)
|
45
|
+
pp response if opts[:ruby]
|
46
|
+
if opts[:json]
|
47
|
+
response[:mead] = response[:mead].map{|error| error.message }
|
48
|
+
puts response.to_json
|
49
|
+
end
|
50
|
+
if !opts[:ruby] and !opts[:json]
|
51
|
+
pp response
|
52
|
+
end
|
53
|
+
end
|
data/bin/ead2meads
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
3
|
+
require 'pp'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'mead'
|
6
|
+
require 'json'
|
7
|
+
require 'mead/trollop'
|
8
|
+
require 'trollop'
|
9
|
+
include Mead::TrollopOptions
|
10
|
+
|
11
|
+
#eadid, baseurl
|
12
|
+
opts = Trollop::options do
|
13
|
+
banner <<-EOS
|
14
|
+
This script takes an EAD XML document and returns mead identifiers and metadata
|
15
|
+
for it. It is possible to validate whether the parsed EAD XML provides unique
|
16
|
+
identifiers for all component parts.
|
17
|
+
|
18
|
+
Usage Example:
|
19
|
+
ead2meads --url http://www.lib.ncsu.edu/findingaids/mc00240.xml [options]
|
20
|
+
|
21
|
+
Default output is pretty printed Ruby. Multiple outputs can be specified.
|
22
|
+
|
23
|
+
where options are:
|
24
|
+
EOS
|
25
|
+
opt :eadid, 'Eadid of the EAD.', :type => String
|
26
|
+
opt :url, 'Specify the whole URL for grabbing the EAD XML.', :type => String
|
27
|
+
opt :file, 'File path to EAD XML.', :type => String
|
28
|
+
opt :ruby, 'Output as pretty printed Ruby.'
|
29
|
+
opt :json, 'Output as JSON'
|
30
|
+
opt :csv, 'Output as CSV. Default.'
|
31
|
+
opt :valid, 'Only outputs whether the EAD creates valid identifiers or not.'
|
32
|
+
opt :verbose, 'Outputs the list of invalid containers in cases where invalid.'
|
33
|
+
opt :meadsonly, 'Only output a list of mead identifiers.'
|
34
|
+
end
|
35
|
+
|
36
|
+
check_options(opts)
|
37
|
+
location = get_location_options(opts)
|
38
|
+
|
39
|
+
options = {}
|
40
|
+
options[:eadid] = opts[:eadid] if opts[:eadid]
|
41
|
+
options.merge!(location)
|
42
|
+
|
43
|
+
begin
|
44
|
+
ead = Mead::Ead.new(options)
|
45
|
+
rescue => e
|
46
|
+
puts e
|
47
|
+
puts e.backtrace
|
48
|
+
exit
|
49
|
+
end
|
50
|
+
|
51
|
+
if opts[:valid]
|
52
|
+
if ead.valid?
|
53
|
+
puts 'Valid.'
|
54
|
+
else
|
55
|
+
if opts[:verbose]
|
56
|
+
puts Mead::Ead.to_csv(ead.invalid) if opts[:csv]
|
57
|
+
pp ead.invalid if opts[:ruby]
|
58
|
+
puts ead.invalid.to_json if opts[:json]
|
59
|
+
|
60
|
+
if !opts[:csv] and !opts[:ruby] and !opts[:json]
|
61
|
+
puts Mead::Ead.to_csv(ead.invalid)
|
62
|
+
end
|
63
|
+
else
|
64
|
+
if opts[:json]
|
65
|
+
json_output = {:dups => ead.dups.length, :invalid => ead.invalid.length, :total => ead.containers.length}.to_json
|
66
|
+
puts json_output
|
67
|
+
else
|
68
|
+
puts 'Invalid!'
|
69
|
+
puts 'Number of duplicate meads: ' + ead.dups.length.to_s
|
70
|
+
puts 'Effected Containers: ' + ead.invalid.length.to_s
|
71
|
+
puts 'Short meads:' + ead.short_meads.length.to_s
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
end
|
77
|
+
else
|
78
|
+
if opts[:meadsonly]
|
79
|
+
puts ead.meads.join("\n")
|
80
|
+
else
|
81
|
+
puts ead.to_csv if opts[:csv]
|
82
|
+
pp ead.containers if opts[:ruby]
|
83
|
+
puts ead.containers.to_json if opts[:json]
|
84
|
+
|
85
|
+
if !opts[:csv] and !opts[:ruby] and !opts[:json]
|
86
|
+
puts ead.to_csv
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
data/bin/emv
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'pp'
|
3
|
+
require 'rubygems'
|
4
|
+
require 'json'
|
5
|
+
|
6
|
+
# does an Mead::Ead validity check on a directory of EADs using the ead2meads tool
|
7
|
+
dir = ARGV[0] || (puts 'Give the path to a directory of EADs to validate!'; exit)
|
8
|
+
|
9
|
+
valid = []
|
10
|
+
invalid = []
|
11
|
+
invalid_responses = {}
|
12
|
+
|
13
|
+
files = Dir.glob(File.join(dir, '*.xml'))
|
14
|
+
puts files.length
|
15
|
+
files.each_with_index do |path, i|
|
16
|
+
begin
|
17
|
+
eadid = File.basename(path, '.xml')
|
18
|
+
cmd = File.join(File.dirname(__FILE__), 'ead2meads')
|
19
|
+
response = `#{cmd} --file #{path} --json --valid`.chomp
|
20
|
+
pp response
|
21
|
+
if response == 'Valid.'
|
22
|
+
puts i.to_s + ' ' + eadid + ': valid'
|
23
|
+
valid << eadid
|
24
|
+
elsif response.empty?
|
25
|
+
else
|
26
|
+
puts i.to_s + ' ' + eadid + ': !'
|
27
|
+
invalid << eadid
|
28
|
+
invalid_responses[eadid] = response
|
29
|
+
end
|
30
|
+
rescue => e
|
31
|
+
invalid_responses[eadid] = e.backtrace
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
puts 'Valid: ' + valid.length.to_s
|
36
|
+
puts 'Invalid: ' + invalid.length.to_s
|
37
|
+
|
38
|
+
puts 'Show all Invalid?'
|
39
|
+
answer = STDIN.gets
|
40
|
+
if answer.chomp == 'y'
|
41
|
+
pp invalid.sort
|
42
|
+
end
|
43
|
+
|
44
|
+
puts 'Show invalid responses?'
|
45
|
+
answer = STDIN.gets
|
46
|
+
if answer.chomp == 'y'
|
47
|
+
invalid_responses.each do |k,v|
|
48
|
+
puts k
|
49
|
+
puts v.sub("Invalid!\n", '')
|
50
|
+
puts
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
puts 'Show setdata?'
|
55
|
+
answer = STDIN.gets
|
56
|
+
if answer.chomp == 'y'
|
57
|
+
data = [%Q|google.load("visualization", "1", {packages:["corechart"]});
|
58
|
+
google.setOnLoadCallback(drawChart);
|
59
|
+
function drawChart() {
|
60
|
+
var data = new google.visualization.DataTable();","data.addColumn('string', 'eadid');|,
|
61
|
+
"data.addColumn('number', 'duplicates');",
|
62
|
+
"data.addColumn('number', 'invalid containers');"]
|
63
|
+
data << "data.addRows(#{invalid_responses.length});"
|
64
|
+
invalid_order = invalid_responses.keys.sort_by do |k|
|
65
|
+
invalid_response = JSON.parse(invalid_responses[k])
|
66
|
+
invalid_responses[k]["invalid"]
|
67
|
+
end
|
68
|
+
invalid_order.each_with_index do |key, i|
|
69
|
+
invalid_response = JSON.parse(invalid_responses[key])
|
70
|
+
|
71
|
+
data << "data.setValue(#{i}, 0, '#{key}');"
|
72
|
+
data << "data.setValue(#{i}, 1, #{invalid_response['dups']});"
|
73
|
+
data << "data.setValue(#{i}, 2, #{invalid_response['invalid']});"
|
74
|
+
end
|
75
|
+
puts data.join("\n")
|
76
|
+
end
|
77
|
+
|
data/bin/mead2barcode
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
3
|
+
require 'pp'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'mead'
|
6
|
+
require 'mead/trollop'
|
7
|
+
require 'trollop'
|
8
|
+
include Mead::TrollopOptions
|
9
|
+
|
10
|
+
opts = Trollop::options do
|
11
|
+
banner <<-EOS
|
12
|
+
This script takes a mead (an identifier of a particular format), creates a
|
13
|
+
barcode and returns the path to the barcode. Gbarcode and RMagick gems must be
|
14
|
+
installed for this to work.
|
15
|
+
|
16
|
+
Usage Example:
|
17
|
+
mead2barcode --mead mc00240-001-ff0052-000-001 --baseurl http://www.lib.ncsu.edu/findingaids --ruby [options]
|
18
|
+
|
19
|
+
where options are:
|
20
|
+
EOS
|
21
|
+
opt :mead, "A mead-style identifier", :type => String
|
22
|
+
opt :meadfile, "Path to text file with one mead identifier on each line.", :type => String
|
23
|
+
opt :baseurl, 'Specify just the base URL for grabbing the EAD XML if it is of the format baseurl/eadid.xml.', :type => String
|
24
|
+
opt :url, 'Specify the whole URL for grabbing the EAD XML.', :type => String
|
25
|
+
opt :file, 'File path to EAD XML.', :type => String
|
26
|
+
opt :dir, 'Directory to save the barcodes.', :type => String
|
27
|
+
end
|
28
|
+
|
29
|
+
unless opts[:mead] or opts[:meadfile]
|
30
|
+
Trollop::die 'You must specify either a single mead identifier or a file of identifiers'
|
31
|
+
end
|
32
|
+
|
33
|
+
check_options(opts)
|
34
|
+
location = get_location(opts)
|
35
|
+
|
36
|
+
if opts[:mead]
|
37
|
+
meads = [opts[:mead]]
|
38
|
+
else
|
39
|
+
Trollop::die 'meadfile must be a valid path' unless File.exists?(opts[:meadfile])
|
40
|
+
meads = File.open(opts[:meadfile], 'r').read.split
|
41
|
+
end
|
42
|
+
|
43
|
+
successful_paths = []
|
44
|
+
meads.each do |mead_identifier|
|
45
|
+
begin
|
46
|
+
mead = Mead::Identifier.new(mead_identifier, location).extract
|
47
|
+
|
48
|
+
barcode = Mead::Barcode.new(mead)
|
49
|
+
|
50
|
+
if opts[:dir]
|
51
|
+
Trollop::die 'Directory must exist!' unless File.exists?(opts[:dir])
|
52
|
+
end
|
53
|
+
directory = opts[:dir] || Dir.pwd
|
54
|
+
|
55
|
+
label_path = barcode.output_label(directory)
|
56
|
+
successful_paths << label_path
|
57
|
+
puts label_path
|
58
|
+
rescue => e
|
59
|
+
puts mead_identifier + ' ' + e
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
#`convert #{successful_paths.join(' ')} -append -antialias output.png`
|
64
|
+
|
data/bin/meadbfv
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
3
|
+
require 'pp'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'mead'
|
6
|
+
require 'pp'
|
7
|
+
|
8
|
+
|
9
|
+
file = ARGV[0]
|
10
|
+
|
11
|
+
filenames = File.read(file).split
|
12
|
+
|
13
|
+
valid = []
|
14
|
+
invalid = []
|
15
|
+
filenames.each do |filename|
|
16
|
+
mead = Mead::Identifier.new(filename)
|
17
|
+
if mead.valid_format?
|
18
|
+
valid << filename
|
19
|
+
else
|
20
|
+
invalid << filename
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
puts "Total filenames " + filenames.length.to_s
|
25
|
+
puts "Unique filenames " + filenames.uniq.length.to_s
|
26
|
+
puts "Valid filenames " + valid.length.to_s unless valid.empty?
|
27
|
+
puts "Invalid filenames " + invalid.length.to_s unless invalid.empty?
|
data/lib/mead/barcode.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
module Mead
|
2
|
+
class Barcode
|
3
|
+
attr_accessor :mead
|
4
|
+
|
5
|
+
def initialize(identifier)
|
6
|
+
@mead = identifier
|
7
|
+
end
|
8
|
+
|
9
|
+
def output_barcode(directory)
|
10
|
+
bc = Gbarcode.barcode_create(@mead.mead)
|
11
|
+
bc.scalef = 0.5
|
12
|
+
bc.margin = 25
|
13
|
+
Gbarcode.barcode_encode(bc, Gbarcode::BARCODE_128)
|
14
|
+
#tempfile for eps version of barcode
|
15
|
+
eps_path = File.join(directory, @mead.mead + '.eps')
|
16
|
+
png_path = File.join(directory, @mead.mead + '-barcode.png')
|
17
|
+
eps = File.new(eps_path, 'w')
|
18
|
+
Gbarcode.barcode_print(bc, eps, Gbarcode::BARCODE_OUT_EPS)
|
19
|
+
eps.close
|
20
|
+
`convert +antialias #{eps_path} -background white -flatten #{png_path}`
|
21
|
+
File.delete(eps_path)
|
22
|
+
png_path
|
23
|
+
end
|
24
|
+
|
25
|
+
def output_label(directory)
|
26
|
+
text_path = File.join(directory, @mead.mead + '-text.png')
|
27
|
+
label_path = File.join(directory, @mead.mead + '-label.png')
|
28
|
+
`convert -font fixed -pointsize 14 -background white -fill black label:"#{label_text}" #{text_path}`
|
29
|
+
# convert *.png -resize 75% -append output.png
|
30
|
+
png_path = output_barcode(directory)
|
31
|
+
begin
|
32
|
+
`convert #{png_path} #{text_path} -append #{label_path}`
|
33
|
+
rescue
|
34
|
+
end
|
35
|
+
File.delete(png_path)
|
36
|
+
File.delete(text_path)
|
37
|
+
label_path
|
38
|
+
end
|
39
|
+
|
40
|
+
def label_text
|
41
|
+
text = [@mead.mead]
|
42
|
+
text << @mead.metadata.first[:unittitle][0,55]
|
43
|
+
text.last << '...' if @mead.metadata.first[:unittitle].length > 55
|
44
|
+
text << @mead.metadata.first[:item_location]
|
45
|
+
text.join('\n')
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Mead
|
2
|
+
class Container
|
3
|
+
attr_accessor :identifier, :type, :label, :text
|
4
|
+
|
5
|
+
def initialize(options={})
|
6
|
+
@type = options[:type]
|
7
|
+
@label = options[:label]
|
8
|
+
@identifier = options[:identifier]
|
9
|
+
@text = options[:text]
|
10
|
+
end
|
11
|
+
|
12
|
+
def ==(another_container)
|
13
|
+
self.identifier == another_container.identifier and
|
14
|
+
self.type == another_container.type and
|
15
|
+
self.label == another_container.label and
|
16
|
+
self.text == another_container.text
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|