ddr-core 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|