ddr-core 1.1.2 → 1.2.0.rc1
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 +4 -4
- data/README.md +1 -1
- data/app/models/concerns/ddr/#search_builder_behavior.rb# +10 -0
- data/app/models/concerns/ddr/describable.rb +8 -12
- data/app/models/concerns/ddr/has_admin_metadata.rb +6 -0
- data/app/models/concerns/ddr/has_parent.rb +14 -2
- data/app/models/concerns/ddr/search_builder_behavior.rb~ +9 -0
- data/app/models/ddr/#admin_set.rb# +26 -0
- data/app/models/ddr/#auxiliary_resource_cache.rb# +34 -0
- data/app/models/ddr/auxiliary_resource.rb~ +13 -0
- data/app/models/ddr/cacheable_auxiliary_resource.rb~ +20 -0
- data/app/models/ddr/collection.rb +5 -4
- data/app/models/ddr/component.rb +8 -0
- data/app/models/ddr/resource.rb +4 -0
- data/config/locales/ddr-core.en.yml +2 -0
- data/lib/ddr/auth/#duke_person.rb# +9 -0
- data/lib/ddr/auth/ability_definitions/publication_ability_definitions.rb +7 -0
- data/lib/ddr/auth/ability_definitions/superuser_ability_definitions.rb +3 -0
- data/lib/ddr/auth/duke_directory.rb~ +7 -0
- data/lib/ddr/auth/effective_roles.rb +1 -1
- data/lib/ddr/auth/permissions.rb +14 -11
- data/lib/ddr/auth/role_based_access_controls_enforcement.rb +1 -1
- data/lib/ddr/auth/roles.rb +15 -3
- data/lib/ddr/auth/roles/role.rb +27 -24
- data/lib/ddr/auth/roles/role_types.rb +13 -6
- data/lib/ddr/core/version.rb +1 -1
- data/lib/ddr/index/csv_query_result.rb +27 -20
- data/lib/ddr/index/fields.rb +1 -0
- data/lib/ddr/vocab/asset.rb +4 -0
- data/lib/ddr/workflow.rb +1 -0
- metadata +15 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c58f60f94bc6a54ea670eb5a7a096e69221e5b8e6fce28191b939f283d4c3528
|
4
|
+
data.tar.gz: 170f607020dfabfa89c77c4a31b3daa10bc7d40bd06c251ff3e3d0a0372159e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ff5d87897742e3f736e3313a06145a6d378e168e72d6872effc563906370fe66865bf663027defe32041a45ab92910dab97e9d9a1ebd6d21bdf1d9b0b381b84
|
7
|
+
data.tar.gz: 48869cd2b81bd88378779ab319fb4a13407bc9060aa099b6b45d33469e8d6605af177aecff033b921f5588bca616f94e077ce75455d45ddba2a619fc7d0119a7
|
data/README.md
CHANGED
@@ -0,0 +1,10 @@
|
|
1
|
+
module Ddr
|
2
|
+
module SearchBuilderBehavior
|
3
|
+
|
4
|
+
def effective_role_filter(agents)
|
5
|
+
# https://lucene.apache.org/solr/guide/7_7/other-parsers.html#term-query-parser
|
6
|
+
"{!terms f=#{Ddr::Index::Fields::EFFECTIVE_ROLE} method=booleanQuery}#{agents.join(',')}"
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
end
|
@@ -15,6 +15,8 @@ module Ddr
|
|
15
15
|
term_names
|
16
16
|
end
|
17
17
|
|
18
|
+
# Dublin Core vocabulary comes from the rdf-vocab gem (https://github.com/ruby-rdf/rdf-vocab)
|
19
|
+
# DDR vocabulary is defined locally
|
18
20
|
def self.vocabularies
|
19
21
|
[RDF::Vocab::DC, Ddr::Vocab::DukeTerms].freeze
|
20
22
|
end
|
@@ -34,7 +36,11 @@ module Ddr
|
|
34
36
|
|
35
37
|
included do
|
36
38
|
Ddr::Describable.term_names.each do |term_name|
|
37
|
-
|
39
|
+
if term_name == :available # Intercept dcterms:available and set it to a single date so it can be used for embargoes
|
40
|
+
attribute term_name, Valkyrie::Types::DateTime.optional
|
41
|
+
else
|
42
|
+
attribute term_name, Valkyrie::Types::Set
|
43
|
+
end
|
38
44
|
end
|
39
45
|
end
|
40
46
|
|
@@ -53,7 +59,7 @@ module Ddr
|
|
53
59
|
arg = args.pop
|
54
60
|
terms = case arg.to_sym
|
55
61
|
when :empty
|
56
|
-
desc_metadata_terms.select { |t| values(t).empty? }
|
62
|
+
desc_metadata_terms.select { |t| values(t).nil? || values(t).empty? }
|
57
63
|
when :present
|
58
64
|
desc_metadata_terms.select { |t| values(t).present? }
|
59
65
|
when :defined_attributes
|
@@ -94,15 +100,5 @@ module Ddr
|
|
94
100
|
desc_metadata_terms.each { |t| set_desc_metadata_values(t, term_values_hash[t]) }
|
95
101
|
end
|
96
102
|
|
97
|
-
################
|
98
|
-
# I do not believe this method is needed any longer since I can't find any usage of it in ddr-models, ddr-batch,
|
99
|
-
# dul-hydra, ddr-public, or ddr-portals
|
100
|
-
################
|
101
|
-
# module ClassMethods
|
102
|
-
# def find_by_identifier(identifier)
|
103
|
-
# find(Ddr::Index::Fields::IDENTIFIER_ALL => identifier)
|
104
|
-
# end
|
105
|
-
# end
|
106
|
-
|
107
103
|
end
|
108
104
|
end
|
@@ -7,6 +7,7 @@ module Ddr
|
|
7
7
|
affiliation: Valkyrie::Types::Set,
|
8
8
|
aleph_id: Valkyrie::Types::Strict::String.optional,
|
9
9
|
aspace_id: Valkyrie::Types::Strict::String.optional,
|
10
|
+
contentdm_id: Valkyrie::Types::Strict::String.optional,
|
10
11
|
depositor: Valkyrie::Types::Strict::String.optional,
|
11
12
|
display_format: Valkyrie::Types::Strict::String.optional,
|
12
13
|
doi: Valkyrie::Types::Strict::String.optional,
|
@@ -54,6 +55,11 @@ module Ddr
|
|
54
55
|
workflow_state == Ddr::Workflow::UNPUBLISHED
|
55
56
|
end
|
56
57
|
|
58
|
+
# Usually won't be called directly. See `publishable?` on Resource and its derivatives
|
59
|
+
def nonpublishable?
|
60
|
+
workflow_state == Ddr::Workflow::NONPUBLISHABLE
|
61
|
+
end
|
62
|
+
|
57
63
|
def resource_roles
|
58
64
|
roles.select(&:in_resource_scope?)
|
59
65
|
end
|
@@ -7,12 +7,24 @@ module Ddr
|
|
7
7
|
attribute :parent_id, Valkyrie::Types::ID.optional
|
8
8
|
end
|
9
9
|
|
10
|
+
def has_parent?
|
11
|
+
parent_id.present?
|
12
|
+
end
|
13
|
+
|
10
14
|
def parent
|
11
|
-
Ddr.query_service.find_by(id: parent_id) if
|
15
|
+
Ddr.query_service.find_by(id: parent_id) if has_parent?
|
12
16
|
end
|
13
17
|
|
18
|
+
# Resources with parents (currently, Items and Components) are publishable only if they have not been marked
|
19
|
+
# nonpublishable and their parent is published
|
14
20
|
def publishable?
|
15
|
-
|
21
|
+
!nonpublishable? && parental_publication_guard
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def parental_publication_guard
|
27
|
+
parent.present? && parent.published?
|
16
28
|
end
|
17
29
|
|
18
30
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Ddr
|
2
|
+
class AdminSet < AuxiliaryResource
|
3
|
+
|
4
|
+
def self.call(obj)
|
5
|
+
find_by_code(obj.admin_set)
|
6
|
+
rescue ActiveResource::ResourceNotFound => e
|
7
|
+
raise Ddr::NotFoundError, e
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.find_by_code(code)
|
11
|
+
return unless code
|
12
|
+
new get(:find, code: code)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.keys
|
16
|
+
with_cache("keys") do
|
17
|
+
all.map(&:code)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
title
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'active_resource'
|
2
|
+
|
3
|
+
module Ddr
|
4
|
+
class AuxiliaryResourceCache < ActiveSupport::Cache::MemoryStore
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@_cache =
|
8
|
+
end
|
9
|
+
|
10
|
+
def with(key, &block)
|
11
|
+
begin
|
12
|
+
cache.set(key, block.call)
|
13
|
+
rescue ActiveResource::ServerError => e
|
14
|
+
if cache.key?(key)
|
15
|
+
Rails.logger.error(e)
|
16
|
+
cache.get(key)
|
17
|
+
else
|
18
|
+
raise
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def get(key)
|
26
|
+
@_cache[key]
|
27
|
+
end
|
28
|
+
|
29
|
+
def set(key, value)
|
30
|
+
@_cache[key] = value
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'active_resource'
|
2
|
+
|
3
|
+
module Ddr
|
4
|
+
#
|
5
|
+
# Abstract superclass for resources bound to ddr-aux API data
|
6
|
+
#
|
7
|
+
class AuxiliaryResource < ActiveResource::Base
|
8
|
+
|
9
|
+
# ActiveResource freezes `site` in subclasses
|
10
|
+
self.site = Ddr.ddr_aux_api_url
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Ddr
|
2
|
+
module CacheableAuxiliaryResource
|
3
|
+
|
4
|
+
def with_cache(key, &block)
|
5
|
+
block.call.tap { |value| cache.write(key, value) }
|
6
|
+
rescue ActiveResource::ServerError => e
|
7
|
+
if value = cache.fetch(key)
|
8
|
+
logger.error(e) if logger
|
9
|
+
value
|
10
|
+
else
|
11
|
+
raise
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def cache
|
16
|
+
@cache ||= ActiveSupport::Cache::MemoryStore.new
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -16,12 +16,13 @@ module Ddr
|
|
16
16
|
query.docs
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
|
19
|
+
# Collection resources are publishable unless they have been marked nonpublishable
|
20
|
+
def publishable?
|
21
|
+
!nonpublishable?
|
21
22
|
end
|
22
23
|
|
23
|
-
def
|
24
|
-
|
24
|
+
def targets
|
25
|
+
Ddr.query_service.find_inverse_references_by(resource: self, property: 'for_collection_id')
|
25
26
|
end
|
26
27
|
|
27
28
|
end
|
data/app/models/ddr/component.rb
CHANGED
data/app/models/ddr/resource.rb
CHANGED
@@ -90,6 +90,10 @@ module Ddr
|
|
90
90
|
send(f)&.file_identifier.present?
|
91
91
|
end
|
92
92
|
|
93
|
+
# By default, no resources are publishable. To enable publication of a particular class of resource, (1) include
|
94
|
+
# the `HasAdminMetadata` concern in the model class, which defines a `nonpublishable?` method which returns true
|
95
|
+
# if the workflow_state is "nonpublishable" and (2) override the `publishable?` method to provide the logic
|
96
|
+
# for determining if a particular resource is publishable.
|
93
97
|
def publishable?
|
94
98
|
false
|
95
99
|
end
|
@@ -2,6 +2,10 @@ module Ddr
|
|
2
2
|
module Auth
|
3
3
|
class PublicationAbilityDefinitions < AbilityDefinitions
|
4
4
|
|
5
|
+
# An object can't be published if it's already published or not publishable
|
6
|
+
# It can't be unpublished if it's already unpublished
|
7
|
+
# It can't be made nonpublishable if it's already published (must be unpublished
|
8
|
+
# first) or already nonpublishable
|
5
9
|
def call
|
6
10
|
cannot :publish, Ddr::Resource do |obj|
|
7
11
|
obj.published? || !obj.publishable?
|
@@ -9,6 +13,9 @@ module Ddr
|
|
9
13
|
cannot :unpublish, Ddr::Resource do |obj|
|
10
14
|
!obj.published?
|
11
15
|
end
|
16
|
+
cannot :make_nonpublishable, Ddr::Resource do |obj|
|
17
|
+
obj.published? || !obj.publishable?
|
18
|
+
end
|
12
19
|
end
|
13
20
|
|
14
21
|
end
|
@@ -1,6 +1,9 @@
|
|
1
1
|
module Ddr::Auth
|
2
2
|
class SuperuserAbilityDefinitions < AbilityDefinitions
|
3
3
|
|
4
|
+
# This bypasses all checks, including ones that look at whether an
|
5
|
+
# action is possible, not just allowed. So superusers may initiate
|
6
|
+
# actions which will fail.
|
4
7
|
def call
|
5
8
|
can :manage, :all
|
6
9
|
end
|
data/lib/ddr/auth/permissions.rb
CHANGED
@@ -1,18 +1,21 @@
|
|
1
1
|
module Ddr::Auth
|
2
2
|
class Permissions
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
4
|
+
DISCOVER = :discover
|
5
|
+
READ = :read
|
6
|
+
DOWNLOAD = :download
|
7
|
+
ADD_CHILDREN = :add_children
|
8
|
+
UPDATE = :update
|
9
|
+
REPLACE = :replace
|
10
|
+
ARRANGE = :arrange
|
11
|
+
PUBLISH = :publish
|
12
|
+
UNPUBLISH = :unpublish
|
13
|
+
MAKE_NONPUBLISHABLE = :make_nonpublishable
|
14
|
+
AUDIT = :audit
|
15
|
+
GRANT = :grant
|
14
16
|
|
15
|
-
ALL = [ READ, DOWNLOAD, ADD_CHILDREN, UPDATE,
|
17
|
+
ALL = [ DISCOVER, READ, DOWNLOAD, ADD_CHILDREN, UPDATE,
|
18
|
+
REPLACE, ARRANGE, PUBLISH, UNPUBLISH, MAKE_NONPUBLISHABLE, AUDIT, GRANT ]
|
16
19
|
|
17
20
|
end
|
18
21
|
end
|
data/lib/ddr/auth/roles.rb
CHANGED
@@ -10,18 +10,30 @@ module Ddr::Auth
|
|
10
10
|
|
11
11
|
RESOURCE_SCOPE = "resource".freeze
|
12
12
|
POLICY_SCOPE = "policy".freeze
|
13
|
-
SCOPES = [RESOURCE_SCOPE, POLICY_SCOPE].freeze
|
13
|
+
SCOPES = [ RESOURCE_SCOPE, POLICY_SCOPE ].freeze
|
14
|
+
|
15
|
+
ORDERED_ROLE_TYPES = [
|
16
|
+
CURATOR,
|
17
|
+
EDITOR,
|
18
|
+
METADATA_EDITOR,
|
19
|
+
CONTRIBUTOR,
|
20
|
+
DOWNLOADER,
|
21
|
+
VIEWER,
|
22
|
+
METADATA_VIEWER
|
23
|
+
]
|
14
24
|
|
15
25
|
class << self
|
16
|
-
|
17
26
|
def type_map
|
18
27
|
@type_map ||= role_types.map { |role_type| [role_type.to_s, role_type] }.to_h
|
19
28
|
end
|
20
29
|
|
21
30
|
def role_types
|
22
|
-
|
31
|
+
ORDERED_ROLE_TYPES
|
23
32
|
end
|
24
33
|
|
34
|
+
def titles
|
35
|
+
@titles ||= role_types.map(&:title)
|
36
|
+
end
|
25
37
|
end
|
26
38
|
|
27
39
|
end
|
data/lib/ddr/auth/roles/role.rb
CHANGED
@@ -8,35 +8,38 @@ module Ddr
|
|
8
8
|
|
9
9
|
DEFAULT_SCOPE = Roles::RESOURCE_SCOPE
|
10
10
|
|
11
|
-
ValidScope = Valkyrie::Types::
|
12
|
-
ValidRoleType = Valkyrie::Types::Strict::String.enum(*(Roles
|
11
|
+
ValidScope = Valkyrie::Types::Coercible::String.default(DEFAULT_SCOPE).enum(*(Roles::SCOPES))
|
12
|
+
ValidRoleType = Valkyrie::Types::Strict::String.enum(*(Roles.titles))
|
13
|
+
ValidAgent = Valkyrie::Types::Coercible::String.constrained(min_size: 1)
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
# @param args [Hash] the attributes
|
22
|
-
# @return [Role] the role
|
23
|
-
# @example
|
24
|
-
# Role.build type: "Curator", agent: "bob", scope: "resource"
|
25
|
-
def build(args={})
|
26
|
-
new.tap do |role|
|
27
|
-
args[:role_type] ||= args.delete(:type)
|
28
|
-
args[:agent] ||= nil # Triggers a constraint error
|
29
|
-
args[:agent] = args[:agent].to_s # Coerce Ddr::Auth:Group to string
|
30
|
-
|
31
|
-
args.each do |attr, val|
|
32
|
-
role.set_value(attr, val)
|
33
|
-
end
|
15
|
+
# Symbolize input keys
|
16
|
+
# https://dry-rb.org/gems/dry-struct/1.0/recipes/#symbolize-input-keys
|
17
|
+
transform_keys do |key|
|
18
|
+
_k = key.to_sym
|
19
|
+
# For backwards compat allow :type as an alias for :role_type
|
20
|
+
_k == :type ? :role_type : _k
|
21
|
+
end
|
34
22
|
|
35
|
-
|
23
|
+
# Make nils use default values
|
24
|
+
# https://dry-rb.org/gems/dry-struct/1.0/recipes/#resolving-default-values-on-code-nil-code
|
25
|
+
transform_types do |type|
|
26
|
+
if type.default?
|
27
|
+
type.constructor do |value|
|
28
|
+
value.nil? ? Dry::Types::Undefined : value
|
36
29
|
end
|
30
|
+
else
|
31
|
+
type
|
37
32
|
end
|
33
|
+
end
|
38
34
|
|
39
|
-
|
35
|
+
attribute :agent, ValidAgent
|
36
|
+
attribute :role_type, ValidRoleType
|
37
|
+
attribute :scope, ValidScope
|
38
|
+
|
39
|
+
# DEPRECATED: Use constructor
|
40
|
+
def self.build(args={})
|
41
|
+
new(args)
|
42
|
+
end
|
40
43
|
|
41
44
|
# Roles are considered equal (==) if they
|
42
45
|
# are of the same type and have the same agent and scope.
|
@@ -14,36 +14,43 @@ module Ddr
|
|
14
14
|
"Editor",
|
15
15
|
"The Editor role conveys reponsibility for managing the content, " \
|
16
16
|
"description and structural arrangement of a resource.",
|
17
|
-
[ Permissions::
|
18
|
-
Permissions::
|
17
|
+
[ Permissions::DISCOVER, Permissions::READ, Permissions::DOWNLOAD,
|
18
|
+
Permissions::ADD_CHILDREN, Permissions::UPDATE,
|
19
|
+
Permissions::REPLACE, Permissions::ARRANGE ]
|
19
20
|
)
|
20
21
|
|
21
22
|
METADATA_EDITOR = RoleType.new(
|
22
23
|
"MetadataEditor",
|
23
24
|
"The Metadata Editor role conveys responsibility for " \
|
24
25
|
"managing the description of a resource.",
|
25
|
-
[ Permissions::READ, Permissions::DOWNLOAD, Permissions::UPDATE ]
|
26
|
+
[ Permissions::DISCOVER, Permissions::READ, Permissions::DOWNLOAD, Permissions::UPDATE ]
|
26
27
|
)
|
27
28
|
|
28
29
|
CONTRIBUTOR = RoleType.new(
|
29
30
|
"Contributor",
|
30
31
|
"The Contributor role conveys responsibility for adding related " \
|
31
32
|
"resources to a resource, such as works to a collection.",
|
32
|
-
[ Permissions::READ, Permissions::ADD_CHILDREN ]
|
33
|
+
[ Permissions::DISCOVER, Permissions::READ, Permissions::ADD_CHILDREN ]
|
33
34
|
)
|
34
35
|
|
35
36
|
DOWNLOADER = RoleType.new(
|
36
37
|
"Downloader",
|
37
38
|
"The Downloader role conveys access to the \"master\" file " \
|
38
39
|
"(original content bitstream) of a resource.",
|
39
|
-
[ Permissions::READ, Permissions::DOWNLOAD ]
|
40
|
+
[ Permissions::DISCOVER, Permissions::READ, Permissions::DOWNLOAD ]
|
40
41
|
)
|
41
42
|
|
42
43
|
VIEWER = RoleType.new(
|
43
44
|
"Viewer",
|
44
45
|
"The Viewer role conveys access to the description and \"access\" " \
|
45
46
|
"files (e.g., derivative bitstreams) of a resource.",
|
46
|
-
[ Permissions::READ ]
|
47
|
+
[ Permissions::DISCOVER, Permissions::READ ]
|
48
|
+
)
|
49
|
+
|
50
|
+
METADATA_VIEWER = RoleType.new(
|
51
|
+
"MetadataViewer",
|
52
|
+
"The MetadataViewer role coveys access to the description of a resource.",
|
53
|
+
[ Permissions::DISCOVER ]
|
47
54
|
)
|
48
55
|
|
49
56
|
end
|
data/lib/ddr/core/version.rb
CHANGED
@@ -6,8 +6,35 @@ module Ddr::Index
|
|
6
6
|
MAX_ROWS = 10**8 # Just set to a really high number :)
|
7
7
|
CSV_MV_SEPARATOR = ";"
|
8
8
|
|
9
|
+
DEFAULT_CSV_OPTIONS = {
|
10
|
+
headers: :first_row,
|
11
|
+
return_headers: false,
|
12
|
+
write_headers: true,
|
13
|
+
converters: [
|
14
|
+
# convert semicolons
|
15
|
+
lambda { |f| f.gsub(/\\#{CSV_MV_SEPARATOR}/, CSV_MV_SEPARATOR) rescue f },
|
16
|
+
# convert escaped newlines
|
17
|
+
lambda { |f| f.gsub(/\\r/, "\r").gsub(/\\n/, "\n") rescue f }
|
18
|
+
],
|
19
|
+
}.freeze
|
20
|
+
|
9
21
|
delegate :headers, :to_s, :to_csv, to: :table
|
10
22
|
|
23
|
+
attr_reader :csv_opts
|
24
|
+
|
25
|
+
#
|
26
|
+
# See Ruby docs on CSV::new for details on available keys
|
27
|
+
# and values for the optional `csv_options' Hash parameter.
|
28
|
+
#
|
29
|
+
# N.B. If you want to *add* a converter and retain the
|
30
|
+
# default converters, append DEFAULT_CSV_OPTIONS[:converters]
|
31
|
+
# to your Array of converters.
|
32
|
+
#
|
33
|
+
def initialize(query, csv_opts: {})
|
34
|
+
super(query)
|
35
|
+
@csv_opts = DEFAULT_CSV_OPTIONS.merge(csv_opts)
|
36
|
+
end
|
37
|
+
|
11
38
|
def delete_empty_columns!
|
12
39
|
table.by_col!.delete_if { |c, vals| vals.all?(&:nil?) }
|
13
40
|
end
|
@@ -24,14 +51,6 @@ module Ddr::Index
|
|
24
51
|
@table ||= CSV.parse(data, csv_opts)
|
25
52
|
end
|
26
53
|
|
27
|
-
def csv_opts
|
28
|
-
{ headers: csv_headers,
|
29
|
-
converters: [convert_semicolons, convert_escaped_newlines],
|
30
|
-
return_headers: false,
|
31
|
-
write_headers: true,
|
32
|
-
}
|
33
|
-
end
|
34
|
-
|
35
54
|
def solr_csv_opts
|
36
55
|
{ "csv.mv.separator" => CSV_MV_SEPARATOR,
|
37
56
|
"csv.header" => solr_csv_header?,
|
@@ -44,10 +63,6 @@ module Ddr::Index
|
|
44
63
|
query.fields.map { |f| f.respond_to?(:heading) ? f.heading : f.to_s }
|
45
64
|
end
|
46
65
|
|
47
|
-
def csv_headers
|
48
|
-
:first_row
|
49
|
-
end
|
50
|
-
|
51
66
|
def solr_csv_header?
|
52
67
|
query.fields.empty?
|
53
68
|
end
|
@@ -72,13 +87,5 @@ module Ddr::Index
|
|
72
87
|
Connection.get("select", params: solr_csv_params)
|
73
88
|
end
|
74
89
|
|
75
|
-
def convert_semicolons
|
76
|
-
lambda { |f| f.gsub(/\\#{CSV_MV_SEPARATOR}/, CSV_MV_SEPARATOR) rescue f }
|
77
|
-
end
|
78
|
-
|
79
|
-
def convert_escaped_newlines
|
80
|
-
lambda { |f| f.gsub(/\\r/, "\r").gsub(/\\n/, "\n") rescue f }
|
81
|
-
end
|
82
|
-
|
83
90
|
end
|
84
91
|
end
|
data/lib/ddr/index/fields.rb
CHANGED
@@ -29,6 +29,7 @@ module Ddr::Index
|
|
29
29
|
CONTENT_CREATE_DATE = Field.new :content_create_date, :stored_sortable, type: :date
|
30
30
|
CONTENT_SIZE = Field.new :content_size, solr_name: "content_size_lsi"
|
31
31
|
CONTENT_SIZE_HUMAN = Field.new :content_size_human, :symbol
|
32
|
+
CONTENTDM_ID = Field.new :contentdm_id, :stored_sortable
|
32
33
|
CONTRIBUTOR_FACET = Field.new :contributor_facet, :facetable
|
33
34
|
CREATOR_FACET = Field.new :creator_facet, :facetable
|
34
35
|
DATE_FACET = Field.new :date_facet, :facetable
|
data/lib/ddr/vocab/asset.rb
CHANGED
@@ -47,5 +47,9 @@ module Ddr::Vocab
|
|
47
47
|
label: "Nested Path",
|
48
48
|
comment: "The nested/tree path to the object to be reflected in structural metadata."
|
49
49
|
|
50
|
+
property "contentdmId",
|
51
|
+
label: "CONTENTdm ID"
|
52
|
+
comment: "The CONTENTdm reference corresponding to the object."
|
53
|
+
|
50
54
|
end
|
51
55
|
end
|
data/lib/ddr/workflow.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ddr-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jim Coble
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2020-
|
14
|
+
date: 2020-06-10 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: activeresource
|
@@ -89,14 +89,14 @@ dependencies:
|
|
89
89
|
requirements:
|
90
90
|
- - "~>"
|
91
91
|
- !ruby/object:Gem::Version
|
92
|
-
version: 2.
|
92
|
+
version: 2.1.0
|
93
93
|
type: :runtime
|
94
94
|
prerelease: false
|
95
95
|
version_requirements: !ruby/object:Gem::Requirement
|
96
96
|
requirements:
|
97
97
|
- - "~>"
|
98
98
|
- !ruby/object:Gem::Version
|
99
|
-
version: 2.
|
99
|
+
version: 2.1.0
|
100
100
|
- !ruby/object:Gem::Dependency
|
101
101
|
name: grouper-rest-client
|
102
102
|
requirement: !ruby/object:Gem::Requirement
|
@@ -306,6 +306,7 @@ files:
|
|
306
306
|
- app/assets/config/ddr_core_manifest.js
|
307
307
|
- app/controllers/users/omniauth_callbacks_controller.rb
|
308
308
|
- app/controllers/users/sessions_controller.rb
|
309
|
+
- app/models/concerns/ddr/#search_builder_behavior.rb#
|
309
310
|
- app/models/concerns/ddr/captionable.rb
|
310
311
|
- app/models/concerns/ddr/describable.rb
|
311
312
|
- app/models/concerns/ddr/governable.rb
|
@@ -319,12 +320,17 @@ files:
|
|
319
320
|
- app/models/concerns/ddr/has_parent.rb
|
320
321
|
- app/models/concerns/ddr/has_struct_metadata.rb
|
321
322
|
- app/models/concerns/ddr/has_thumbnail.rb
|
323
|
+
- app/models/concerns/ddr/search_builder_behavior.rb~
|
322
324
|
- app/models/concerns/ddr/solr_document_behavior.rb
|
323
325
|
- app/models/concerns/ddr/streamable.rb
|
326
|
+
- app/models/ddr/#admin_set.rb#
|
327
|
+
- app/models/ddr/#auxiliary_resource_cache.rb#
|
324
328
|
- app/models/ddr/admin_set.rb
|
325
329
|
- app/models/ddr/alert.rb
|
326
330
|
- app/models/ddr/attachment.rb
|
327
331
|
- app/models/ddr/auxiliary_resource.rb
|
332
|
+
- app/models/ddr/auxiliary_resource.rb~
|
333
|
+
- app/models/ddr/cacheable_auxiliary_resource.rb~
|
328
334
|
- app/models/ddr/collection.rb
|
329
335
|
- app/models/ddr/component.rb
|
330
336
|
- app/models/ddr/contact.rb
|
@@ -345,6 +351,7 @@ files:
|
|
345
351
|
- db/migrate/20200207194453_add_default_to_lock_version.rb
|
346
352
|
- lib/ddr-core.rb
|
347
353
|
- lib/ddr/auth.rb
|
354
|
+
- lib/ddr/auth/#duke_person.rb#
|
348
355
|
- lib/ddr/auth/ability.rb
|
349
356
|
- lib/ddr/auth/ability_definitions.rb
|
350
357
|
- lib/ddr/auth/ability_definitions/admin_set_ability_definitions.rb
|
@@ -365,6 +372,7 @@ files:
|
|
365
372
|
- lib/ddr/auth/auth_context.rb
|
366
373
|
- lib/ddr/auth/auth_context_factory.rb
|
367
374
|
- lib/ddr/auth/detached_auth_context.rb
|
375
|
+
- lib/ddr/auth/duke_directory.rb~
|
368
376
|
- lib/ddr/auth/dynamic_groups.rb
|
369
377
|
- lib/ddr/auth/effective_permissions.rb
|
370
378
|
- lib/ddr/auth/effective_roles.rb
|
@@ -450,11 +458,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
450
458
|
version: '0'
|
451
459
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
452
460
|
requirements:
|
453
|
-
- - "
|
461
|
+
- - ">"
|
454
462
|
- !ruby/object:Gem::Version
|
455
|
-
version:
|
463
|
+
version: 1.3.1
|
456
464
|
requirements: []
|
457
|
-
rubygems_version: 3.0.
|
465
|
+
rubygems_version: 3.0.8
|
458
466
|
signing_key:
|
459
467
|
specification_version: 4
|
460
468
|
summary: Models used in the Duke Digital Repository
|