ddr-core 0.2.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.
- checksums.yaml +7 -0
- data/LICENSE.txt +12 -0
- data/README.md +27 -0
- data/Rakefile +30 -0
- data/app/assets/config/ddr_core_manifest.js +0 -0
- data/app/controllers/users/omniauth_callbacks_controller.rb +11 -0
- data/app/controllers/users/sessions_controller.rb +15 -0
- data/app/models/concerns/ddr/captionable.rb +25 -0
- data/app/models/concerns/ddr/describable.rb +108 -0
- data/app/models/concerns/ddr/governable.rb +25 -0
- data/app/models/concerns/ddr/has_admin_metadata.rb +141 -0
- data/app/models/concerns/ddr/has_attachments.rb +10 -0
- data/app/models/concerns/ddr/has_children.rb +10 -0
- data/app/models/concerns/ddr/has_content.rb +132 -0
- data/app/models/concerns/ddr/has_extracted_text.rb +10 -0
- data/app/models/concerns/ddr/has_intermediate_file.rb +25 -0
- data/app/models/concerns/ddr/has_multires_image.rb +14 -0
- data/app/models/concerns/ddr/has_parent.rb +18 -0
- data/app/models/concerns/ddr/has_struct_metadata.rb +21 -0
- data/app/models/concerns/ddr/has_thumbnail.rb +33 -0
- data/app/models/concerns/ddr/solr_document_behavior.rb +429 -0
- data/app/models/concerns/ddr/streamable.rb +25 -0
- data/app/models/ddr/admin_set.rb +28 -0
- data/app/models/ddr/attachment.rb +14 -0
- data/app/models/ddr/collection.rb +28 -0
- data/app/models/ddr/component.rb +31 -0
- data/app/models/ddr/contact.rb +23 -0
- data/app/models/ddr/digest.rb +8 -0
- data/app/models/ddr/file.rb +40 -0
- data/app/models/ddr/item.rb +36 -0
- data/app/models/ddr/language.rb +31 -0
- data/app/models/ddr/media_type.rb +22 -0
- data/app/models/ddr/resource.rb +94 -0
- data/app/models/ddr/rights_statement.rb +25 -0
- data/app/models/ddr/target.rb +17 -0
- data/config/initializers/devise.rb +262 -0
- data/config/locales/ddr-core.en.yml +85 -0
- data/config/routes.rb +3 -0
- data/db/migrate/20141104181418_create_users.rb +34 -0
- data/db/migrate/20141107124012_add_columns_to_user.rb +46 -0
- data/lib/ddr-core.rb +1 -0
- data/lib/ddr/auth.rb +80 -0
- data/lib/ddr/auth/ability.rb +18 -0
- data/lib/ddr/auth/ability_definitions.rb +26 -0
- data/lib/ddr/auth/ability_definitions/admin_set_ability_definitions.rb +9 -0
- data/lib/ddr/auth/ability_definitions/alias_ability_definitions.rb +23 -0
- data/lib/ddr/auth/ability_definitions/attachment_ability_definitions.rb +13 -0
- data/lib/ddr/auth/ability_definitions/collection_ability_definitions.rb +28 -0
- data/lib/ddr/auth/ability_definitions/component_ability_definitions.rb +13 -0
- data/lib/ddr/auth/ability_definitions/item_ability_definitions.rb +13 -0
- data/lib/ddr/auth/ability_definitions/lock_ability_definitions.rb +13 -0
- data/lib/ddr/auth/ability_definitions/publication_ability_definitions.rb +16 -0
- data/lib/ddr/auth/ability_definitions/role_based_ability_definitions.rb +39 -0
- data/lib/ddr/auth/ability_definitions/superuser_ability_definitions.rb +9 -0
- data/lib/ddr/auth/ability_factory.rb +10 -0
- data/lib/ddr/auth/abstract_ability.rb +48 -0
- data/lib/ddr/auth/affiliation.rb +14 -0
- data/lib/ddr/auth/affiliation_groups.rb +20 -0
- data/lib/ddr/auth/anonymous_ability.rb +7 -0
- data/lib/ddr/auth/auth_context.rb +109 -0
- data/lib/ddr/auth/auth_context_factory.rb +13 -0
- data/lib/ddr/auth/detached_auth_context.rb +19 -0
- data/lib/ddr/auth/dynamic_groups.rb +13 -0
- data/lib/ddr/auth/effective_permissions.rb +12 -0
- data/lib/ddr/auth/effective_roles.rb +9 -0
- data/lib/ddr/auth/failure_app.rb +16 -0
- data/lib/ddr/auth/group.rb +40 -0
- data/lib/ddr/auth/grouper_gateway.rb +70 -0
- data/lib/ddr/auth/groups.rb +32 -0
- data/lib/ddr/auth/ldap_gateway.rb +74 -0
- data/lib/ddr/auth/permissions.rb +18 -0
- data/lib/ddr/auth/remote_groups.rb +14 -0
- data/lib/ddr/auth/role_based_access_controls_enforcement.rb +56 -0
- data/lib/ddr/auth/roles.rb +28 -0
- data/lib/ddr/auth/roles/role.rb +121 -0
- data/lib/ddr/auth/roles/role_type.rb +23 -0
- data/lib/ddr/auth/roles/role_types.rb +52 -0
- data/lib/ddr/auth/superuser_ability.rb +7 -0
- data/lib/ddr/auth/test_helpers.rb +22 -0
- data/lib/ddr/auth/user.rb +54 -0
- data/lib/ddr/auth/web_auth_context.rb +29 -0
- data/lib/ddr/core.rb +110 -0
- data/lib/ddr/core/engine.rb +8 -0
- data/lib/ddr/core/version.rb +5 -0
- data/lib/ddr/error.rb +16 -0
- data/lib/ddr/files.rb +13 -0
- data/lib/ddr/fits.rb +189 -0
- data/lib/ddr/index.rb +29 -0
- data/lib/ddr/index/abstract_query_result.rb +22 -0
- data/lib/ddr/index/connection.rb +38 -0
- data/lib/ddr/index/csv_query_result.rb +84 -0
- data/lib/ddr/index/document_builder.rb +9 -0
- data/lib/ddr/index/field.rb +35 -0
- data/lib/ddr/index/field_attribute.rb +22 -0
- data/lib/ddr/index/fields.rb +154 -0
- data/lib/ddr/index/filter.rb +139 -0
- data/lib/ddr/index/query.rb +82 -0
- data/lib/ddr/index/query_builder.rb +185 -0
- data/lib/ddr/index/query_clause.rb +112 -0
- data/lib/ddr/index/query_params.rb +40 -0
- data/lib/ddr/index/query_result.rb +102 -0
- data/lib/ddr/index/response.rb +30 -0
- data/lib/ddr/index/sort_order.rb +28 -0
- data/lib/ddr/index/unique_key_field.rb +12 -0
- data/lib/ddr/managers.rb +9 -0
- data/lib/ddr/managers/manager.rb +13 -0
- data/lib/ddr/managers/technical_metadata_manager.rb +141 -0
- data/lib/ddr/structure.rb +188 -0
- data/lib/ddr/structures/agent.rb +49 -0
- data/lib/ddr/structures/component_type_term.rb +29 -0
- data/lib/ddr/structures/div.rb +64 -0
- data/lib/ddr/structures/f_locat.rb +54 -0
- data/lib/ddr/structures/file.rb +52 -0
- data/lib/ddr/structures/file_grp.rb +35 -0
- data/lib/ddr/structures/file_sec.rb +22 -0
- data/lib/ddr/structures/fptr.rb +31 -0
- data/lib/ddr/structures/mets_hdr.rb +37 -0
- data/lib/ddr/structures/mptr.rb +49 -0
- data/lib/ddr/structures/struct_map.rb +40 -0
- data/lib/ddr/utils.rb +185 -0
- data/lib/ddr/vocab.rb +22 -0
- data/lib/ddr/vocab/asset.rb +51 -0
- data/lib/ddr/vocab/contact.rb +9 -0
- data/lib/ddr/vocab/display.rb +9 -0
- data/lib/ddr/vocab/duke_terms.rb +13 -0
- data/lib/ddr/vocab/rdf_vocabulary_parser.rb +43 -0
- data/lib/ddr/vocab/roles.rb +25 -0
- data/lib/ddr/vocab/sources/duketerms.rdf +870 -0
- data/lib/ddr/vocab/vocabulary.rb +37 -0
- data/lib/ddr/workflow.rb +8 -0
- data/lib/tasks/ddr/core_tasks.rake +4 -0
- metadata +428 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Ddr::Structures
|
|
2
|
+
class ComponentTypeTerm
|
|
3
|
+
|
|
4
|
+
CONFIG_FILE = ::File.join(Rails.root, 'config', 'structure_component_type.yml')
|
|
5
|
+
|
|
6
|
+
@@lookup = {}
|
|
7
|
+
|
|
8
|
+
def self.term(media_type)
|
|
9
|
+
hit = lookup_table.detect { |k,v| media_type =~ k }
|
|
10
|
+
hit.last if hit
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.lookup_table
|
|
14
|
+
load_lookup if @@lookup.empty?
|
|
15
|
+
@@lookup
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.load_lookup
|
|
19
|
+
config = YAML::load(::File.read(CONFIG_FILE))
|
|
20
|
+
config.each do |type_term, media_types|
|
|
21
|
+
media_types.each do |media_type|
|
|
22
|
+
lookup_key = Regexp.new("\\A#{media_type.gsub('*', '.*')}\\Z")
|
|
23
|
+
@@lookup[lookup_key] = type_term
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module Ddr::Structures
|
|
2
|
+
#
|
|
3
|
+
# Wraps a Nokogiri (XML) 'div' node
|
|
4
|
+
#
|
|
5
|
+
class Div < SimpleDelegator
|
|
6
|
+
|
|
7
|
+
def id
|
|
8
|
+
self['ID']
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def label
|
|
12
|
+
self['LABEL']
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def order
|
|
16
|
+
self['ORDER']
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def orderlabel
|
|
20
|
+
self['ORDERLABEL']
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def type
|
|
24
|
+
self['TYPE']
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def divs
|
|
28
|
+
xpath('xmlns:div').map { |node| Div.new(node) }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def fptrs
|
|
32
|
+
xpath('xmlns:fptr').map { |node| Fptr.new(node) }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def mptrs
|
|
36
|
+
xpath('xmlns:mptr').map { |node| Mptr.new(node) }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def <=>(other)
|
|
40
|
+
order.to_i <=> other.order.to_i
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def dereferenced_hash
|
|
44
|
+
contents = []
|
|
45
|
+
contents.concat(divs.map { |div| div.dereferenced_hash }) unless divs.empty?
|
|
46
|
+
contents.concat(fptrs.map { |fptr| fptr.dereferenced_hash }) unless fptrs.empty?
|
|
47
|
+
contents.concat(mptrs.map { |mptr| mptr.dereferenced_hash }) unless mptrs.empty?
|
|
48
|
+
dh = { id: id, label: label, order: order, orderlabel: orderlabel, type: type }.compact
|
|
49
|
+
dh[:contents] = contents unless contents.empty?
|
|
50
|
+
dh
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self.build(args)
|
|
54
|
+
node = Nokogiri::XML::Node.new('div', args[:document])
|
|
55
|
+
node['ID'] = args[:id] if args[:id]
|
|
56
|
+
node['LABEL'] = args[:label] if args[:label]
|
|
57
|
+
node['ORDER'] = args[:order] if args[:order]
|
|
58
|
+
node['ORDERLABEL'] = args[:orderlabel] if args[:orderlabel]
|
|
59
|
+
node['TYPE'] = args[:type] if args[:type]
|
|
60
|
+
node
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module Ddr::Structures
|
|
2
|
+
#
|
|
3
|
+
# Wraps a Nokogiri (XML) 'FLocat' node
|
|
4
|
+
#
|
|
5
|
+
class FLocat < SimpleDelegator
|
|
6
|
+
|
|
7
|
+
def id
|
|
8
|
+
self['ID']
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def loctype
|
|
12
|
+
self['LOCTYPE']
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def otherloctype
|
|
16
|
+
self['OTHERLOCTYPE']
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def use
|
|
20
|
+
self['USE']
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def href
|
|
24
|
+
self['xlink:href']
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def ark?
|
|
28
|
+
loctype == 'ARK'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def ark
|
|
32
|
+
href if ark?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def effective_use
|
|
36
|
+
use ? use : File.new(parent).effective_use
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def repo_id
|
|
40
|
+
SolrDocument.find_by_permanent_id(ark).id if ark?
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.build(args)
|
|
44
|
+
node = Nokogiri::XML::Node.new('FLocat', args[:document])
|
|
45
|
+
node['ID'] = args[:id] if args[:id]
|
|
46
|
+
node['LOCTYPE'] = args[:loctype] if args[:loctype]
|
|
47
|
+
node['OTHERLOCTYPE'] = args[:otherloctype] if args[:otherloctype]
|
|
48
|
+
node['USE'] = args[:use] if args[:use]
|
|
49
|
+
node['xlink:href'] = args[:href] if args[:href]
|
|
50
|
+
node
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module Ddr::Structures
|
|
2
|
+
#
|
|
3
|
+
# Wraps a Nokogiri (XML) 'file' node
|
|
4
|
+
#
|
|
5
|
+
class File < SimpleDelegator
|
|
6
|
+
|
|
7
|
+
def id
|
|
8
|
+
self['ID']
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def use
|
|
12
|
+
self['USE']
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def files
|
|
16
|
+
xpath('xmlns:file').map { |node| File.new(node) }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def flocats
|
|
20
|
+
xpath('xmlns:FLocat').map { |node| FLocat.new(node) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def effective_use
|
|
24
|
+
if use
|
|
25
|
+
use
|
|
26
|
+
else
|
|
27
|
+
case parent.name
|
|
28
|
+
when "file"
|
|
29
|
+
File.new(parent).effective_use
|
|
30
|
+
when "fileGrp"
|
|
31
|
+
FileGrp.new(parent).effective_use
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def repo_ids
|
|
37
|
+
flocats.map(&:repo_id)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def self.build(args)
|
|
41
|
+
node = Nokogiri::XML::Node.new('file', args[:document])
|
|
42
|
+
node['ID'] = args[:id] if args[:id]
|
|
43
|
+
node['USE'] = args[:use] if args[:use]
|
|
44
|
+
node
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def self.find(structure, fileid)
|
|
48
|
+
structure.files[fileid]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Ddr::Structures
|
|
2
|
+
#
|
|
3
|
+
# Wraps a Nokogiri (XML) 'fileGrp' node
|
|
4
|
+
#
|
|
5
|
+
class FileGrp < SimpleDelegator
|
|
6
|
+
|
|
7
|
+
def id
|
|
8
|
+
self['ID']
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def use
|
|
12
|
+
self['USE']
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def filegrps
|
|
16
|
+
xpath('xmlns:filegrp').map { |node| FileGrp.new(node) }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def files
|
|
20
|
+
xpath('xmlns:file').map { |node| File.new(node) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def effective_use
|
|
24
|
+
use
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.build(args)
|
|
28
|
+
node = Nokogiri::XML::Node.new('fileGrp', args[:document])
|
|
29
|
+
node['ID'] = args[:id] if args[:id]
|
|
30
|
+
node['USE'] = args[:use] if args[:use]
|
|
31
|
+
node
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Ddr::Structures
|
|
2
|
+
#
|
|
3
|
+
# Wraps a Nokogiri (XML) 'fileSec' node
|
|
4
|
+
#
|
|
5
|
+
class FileSec < SimpleDelegator
|
|
6
|
+
|
|
7
|
+
def id
|
|
8
|
+
self['ID']
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def filegrps
|
|
12
|
+
xpath('xmlns:fileGrp').map { |node| FileGrp.new(node) }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.build(args)
|
|
16
|
+
node = Nokogiri::XML::Node.new('fileSec', args[:document])
|
|
17
|
+
node['ID'] = args[:id] if args[:id]
|
|
18
|
+
node
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Ddr::Structures
|
|
2
|
+
#
|
|
3
|
+
# Wraps a Nokogiri (XML) 'fptr' node
|
|
4
|
+
#
|
|
5
|
+
class Fptr < SimpleDelegator
|
|
6
|
+
|
|
7
|
+
def id
|
|
8
|
+
self['ID']
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def fileid
|
|
12
|
+
self['FILEID']
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def dereferenced_hash
|
|
16
|
+
structure = Ddr::Structure.new(document)
|
|
17
|
+
file = File.find(structure, fileid)
|
|
18
|
+
repo_id = file.repo_ids.first
|
|
19
|
+
use = file.flocats.first.effective_use
|
|
20
|
+
{ id: id, repo_id: repo_id, use: use }.compact
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.build(args)
|
|
24
|
+
node = Nokogiri::XML::Node.new('fptr', args[:document])
|
|
25
|
+
node['ID'] = args[:id] if args[:id]
|
|
26
|
+
node['FILEID'] = args[:fileid] if args[:fileid]
|
|
27
|
+
node
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Ddr::Structures
|
|
2
|
+
#
|
|
3
|
+
# Wraps a Nokogiri (XML) 'metsHdr' node
|
|
4
|
+
#
|
|
5
|
+
class MetsHdr < SimpleDelegator
|
|
6
|
+
|
|
7
|
+
def id
|
|
8
|
+
self['ID']
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def createdate
|
|
12
|
+
self['CREATEDATE']
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def lastmoddate
|
|
16
|
+
self['LASTMODDATE']
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def recordstatus
|
|
20
|
+
self['RECORDSTATUS']
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def agents
|
|
24
|
+
xpath('xmlns:agent').map { |node| Agent.new(node) }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def self.build(args)
|
|
28
|
+
node = Nokogiri::XML::Node.new('metsHdr', args[:document])
|
|
29
|
+
node['ID'] = args[:id] if args[:id]
|
|
30
|
+
node['CREATEDATE'] = args[:createdate] if args[:createdate]
|
|
31
|
+
node['LASTMODDATE'] = args[:lastmoddate] if args[:lastmoddate]
|
|
32
|
+
node['RECORDSTATUS'] = args[:recordstatus] if args[:recordstatus]
|
|
33
|
+
node
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module Ddr::Structures
|
|
2
|
+
#
|
|
3
|
+
# Wraps a Nokogiri (XML) 'mptr' node
|
|
4
|
+
#
|
|
5
|
+
class Mptr < SimpleDelegator
|
|
6
|
+
|
|
7
|
+
def id
|
|
8
|
+
self['ID']
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def loctype
|
|
12
|
+
self['LOCTYPE']
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def otherloctype
|
|
16
|
+
self['OTHERLOCTYPE']
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def href
|
|
20
|
+
self['xlink:href']
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def ark?
|
|
24
|
+
loctype == 'ARK'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def ark
|
|
28
|
+
href if ark?
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def repo_id
|
|
32
|
+
SolrDocument.find_by_permanent_id(ark).id if ark?
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def dereferenced_hash
|
|
36
|
+
{ id: id, repo_id: repo_id }.compact
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def self.build(args)
|
|
40
|
+
node = Nokogiri::XML::Node.new('mptr', args[:document])
|
|
41
|
+
node['ID'] = args[:id] if args[:id]
|
|
42
|
+
node['LOCTYPE'] = args[:loctype] if args[:loctype]
|
|
43
|
+
node['OTHERLOCTYPE'] = args[:otherloctype] if args[:otherloctype]
|
|
44
|
+
node['xlink:href'] = args[:href] if args[:href]
|
|
45
|
+
node
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Ddr::Structures
|
|
2
|
+
#
|
|
3
|
+
# Wraps a Nokogiri (XML) 'structMap' node
|
|
4
|
+
#
|
|
5
|
+
class StructMap < SimpleDelegator
|
|
6
|
+
|
|
7
|
+
def id
|
|
8
|
+
self['ID']
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def label
|
|
12
|
+
self['LABEL']
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def type
|
|
16
|
+
self['TYPE']
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def divs
|
|
20
|
+
xpath('xmlns:div').map { |node| Div.new(node) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def dereferenced_hash
|
|
24
|
+
contents = []
|
|
25
|
+
contents.concat(divs.map { |div| div.dereferenced_hash }) unless divs.empty?
|
|
26
|
+
dh = { id: id, label: label, type: type }.compact
|
|
27
|
+
dh[:contents] = contents unless contents.empty?
|
|
28
|
+
dh
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def self.build(args)
|
|
32
|
+
node = Nokogiri::XML::Node.new('structMap', args[:document])
|
|
33
|
+
node['ID'] = args[:id] if args[:id]
|
|
34
|
+
node['LABEL'] = args[:label] if args[:label]
|
|
35
|
+
node['TYPE'] = args[:type] if args[:type]
|
|
36
|
+
node
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
end
|
data/lib/ddr/utils.rb
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
require 'openssl'
|
|
2
|
+
|
|
3
|
+
module Ddr::Utils
|
|
4
|
+
extend Deprecation
|
|
5
|
+
|
|
6
|
+
def self.digest content, algorithm
|
|
7
|
+
raise TypeError, "Algorithm must be a string: #{algorithm.inspect}" unless algorithm.is_a?(String)
|
|
8
|
+
digest_class = OpenSSL::Digest.const_get(algorithm.sub("-", "").to_sym)
|
|
9
|
+
digest_class.new(content).to_s
|
|
10
|
+
rescue NameError => e
|
|
11
|
+
raise ArgumentError, "Invalid algorithm: #{algorithm}"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.file_or_path?(file)
|
|
15
|
+
file_path(file)
|
|
16
|
+
rescue ArgumentError
|
|
17
|
+
false
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.file_path?(file)
|
|
21
|
+
# length is a sanity check
|
|
22
|
+
file.is_a?(String) && (file.length < 1024) && File.exist?(file)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.file_path(file)
|
|
26
|
+
if file.respond_to?(:path)
|
|
27
|
+
::File.absolute_path(file.path)
|
|
28
|
+
elsif file_path?(file)
|
|
29
|
+
file
|
|
30
|
+
else
|
|
31
|
+
raise ArgumentError, "Argument is neither a File nor a path to an existing file."
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.file_name_for(file)
|
|
36
|
+
if file.respond_to?(:original_filename) && file.original_filename.present?
|
|
37
|
+
file.original_filename
|
|
38
|
+
else
|
|
39
|
+
File.basename file_path(file)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def self.file_uri?(uri)
|
|
44
|
+
return false unless uri
|
|
45
|
+
URI.parse(uri).scheme == "file"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def self.sanitize_filename(file_name)
|
|
49
|
+
return unless file_name
|
|
50
|
+
raise ArgumentError, "file_name argument must be a string" unless file_name.is_a?(String)
|
|
51
|
+
raise ArgumentError, "file_name argument must not include path" if file_name.include?(File::SEPARATOR)
|
|
52
|
+
file_name.gsub(/[^\w\.\-]/,"_")
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Return file path for URI string
|
|
56
|
+
# Should reverse .path_to_uri
|
|
57
|
+
# "file:/path/to/file" => "/path/to/file"
|
|
58
|
+
# @param uri [String] The URI string to pathify
|
|
59
|
+
# @return [String] the file path
|
|
60
|
+
def self.path_from_uri(uri_string)
|
|
61
|
+
uri = URI.parse(uri_string)
|
|
62
|
+
unless uri.scheme == "file"
|
|
63
|
+
raise ArgumentError, "URI does not have the file: scheme."
|
|
64
|
+
end
|
|
65
|
+
URI.unescape(uri.path)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Return URI string for file path
|
|
69
|
+
# Should reverse .path_from_uri
|
|
70
|
+
# "/path/to/file" => "file:/path/to/file"
|
|
71
|
+
# @param path [String] the file path
|
|
72
|
+
# @return [String] the file: URI string
|
|
73
|
+
def self.path_to_uri(path)
|
|
74
|
+
uri = URI.parse URI.escape(path)
|
|
75
|
+
uri.scheme = "file"
|
|
76
|
+
uri.to_s
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def self.ds_as_of_date_time(ds)
|
|
80
|
+
ds.create_date_string
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
### DDRevo ################################
|
|
84
|
+
# Needs replacements for ActiveFedora::Base.find_each call.
|
|
85
|
+
### DDRevo ################################
|
|
86
|
+
# # # Find an object with a given identifier and return its PID.
|
|
87
|
+
# # Returns the PID if a single object is found.
|
|
88
|
+
# # Returns nil if no object is found.
|
|
89
|
+
# # Raises Ddr::Models::Error if more than one object is found.
|
|
90
|
+
# # Options can be provided to limit the scope of matching objects
|
|
91
|
+
# # model: Will only consider objects of that model
|
|
92
|
+
# # collection: Will only consider objects that either are that collection or which are
|
|
93
|
+
# # direct children of that collection (i.e., effectively searches a collection and its
|
|
94
|
+
# # items for an object with the given identifier)
|
|
95
|
+
# def self.pid_for_identifier(identifier, opts={})
|
|
96
|
+
# model = opts.fetch(:model, nil)
|
|
97
|
+
# collection = opts.fetch(:collection, nil)
|
|
98
|
+
# objs = []
|
|
99
|
+
# ActiveFedora::Base.find_each( { Ddr::Index::Fields::IDENTIFIER_ALL => identifier }, { :cast => true } ) { |o| objs << o }
|
|
100
|
+
# pids = []
|
|
101
|
+
# objs.each { |obj| pids << obj.pid }
|
|
102
|
+
# if model.present?
|
|
103
|
+
# objs.each { |obj| pids.delete(obj.pid) unless obj.is_a?(model.constantize) }
|
|
104
|
+
# end
|
|
105
|
+
# if collection.present?
|
|
106
|
+
# objs.each do |obj|
|
|
107
|
+
# pids.delete(obj.pid) unless obj == collection || obj.parent == collection
|
|
108
|
+
# end
|
|
109
|
+
# end
|
|
110
|
+
# case pids.size
|
|
111
|
+
# when 0
|
|
112
|
+
# nil
|
|
113
|
+
# when 1
|
|
114
|
+
# pids.first
|
|
115
|
+
# else
|
|
116
|
+
# raise Ddr::Models::Error, I18n.t('ddr.errors.multiple_object_matches', :criteria => "identifier #{identifier}")
|
|
117
|
+
# end
|
|
118
|
+
# end
|
|
119
|
+
|
|
120
|
+
### DDRevo ################################
|
|
121
|
+
# This probably isn't relevant in DDRevo context.
|
|
122
|
+
### DDRevo ################################
|
|
123
|
+
# # Returns the reflection object for a given model name and relationship name
|
|
124
|
+
# # E.g., relationship_object_reflection("Item", "parent") returns the reflection object for
|
|
125
|
+
# # an Item's parent relationship. This reflection object can then be used to obtain the
|
|
126
|
+
# # class of the relationship object using the reflection_object_class(reflection) method below.
|
|
127
|
+
# def self.relationship_object_reflection(model, relationship_name)
|
|
128
|
+
# reflection = nil
|
|
129
|
+
# if model
|
|
130
|
+
# begin
|
|
131
|
+
# reflections = model.constantize.reflections
|
|
132
|
+
# rescue NameError
|
|
133
|
+
# # nothing to do here except that we can't return the appropriate reflection
|
|
134
|
+
# else
|
|
135
|
+
# reflections.each do |reflect|
|
|
136
|
+
# if reflect[0].eql?(relationship_name.to_sym)
|
|
137
|
+
# reflection = reflect
|
|
138
|
+
# end
|
|
139
|
+
# end
|
|
140
|
+
# end
|
|
141
|
+
# end
|
|
142
|
+
# return reflection
|
|
143
|
+
# end
|
|
144
|
+
|
|
145
|
+
### DDRevo ################################
|
|
146
|
+
# This probably isn't relevant in DDRevo context.
|
|
147
|
+
### DDRevo ################################
|
|
148
|
+
# # Returns the class associated with the :class_name attribute in the options of a reflection
|
|
149
|
+
# # E.g., reflection_object_class(relationship_object_reflection("Item", "parent")) returns the
|
|
150
|
+
# # Collection class.
|
|
151
|
+
# def self.reflection_object_class(reflection)
|
|
152
|
+
# reflection_object_model = nil
|
|
153
|
+
# klass = nil
|
|
154
|
+
# if reflection[1].options[:class_name]
|
|
155
|
+
# reflection_object_model = reflection[1].options[:class_name]
|
|
156
|
+
# else
|
|
157
|
+
# reflection_object_model = ActiveSupport::Inflector.camelize(reflection[0])
|
|
158
|
+
# end
|
|
159
|
+
# if reflection_object_model
|
|
160
|
+
# begin
|
|
161
|
+
# klass = reflection_object_model.constantize
|
|
162
|
+
# rescue NameError
|
|
163
|
+
# # nothing to do here except that we can't return the reflection object class
|
|
164
|
+
# end
|
|
165
|
+
# end
|
|
166
|
+
# return klass
|
|
167
|
+
# end
|
|
168
|
+
|
|
169
|
+
# Returns a string suitable to index as a Solr date
|
|
170
|
+
# @param dt [Date, DateTime, Time] the date/time
|
|
171
|
+
# @return [String]
|
|
172
|
+
def self.solr_date(dt)
|
|
173
|
+
return if dt.nil?
|
|
174
|
+
dt.to_time.utc.iso8601
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def self.solr_dates(dts)
|
|
178
|
+
dts.map { |dt| solr_date(dt) }
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
class << self
|
|
182
|
+
alias_method :file_name, :file_name_for
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
end
|