ddr-core 0.3.0 → 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 +13 -65
- data/app/models/concerns/ddr/has_children.rb +8 -0
- data/app/models/concerns/ddr/has_content.rb +1 -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/concerns/ddr/solr_document_behavior.rb +11 -90
- data/app/models/ddr/#admin_set.rb# +26 -0
- data/app/models/ddr/#auxiliary_resource_cache.rb# +34 -0
- data/app/models/ddr/admin_set.rb +3 -7
- data/app/models/ddr/alert.rb +16 -0
- data/app/models/ddr/auxiliary_resource.rb +24 -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/contact.rb +1 -5
- data/app/models/ddr/finding_aid.rb +61 -0
- data/app/models/ddr/item.rb +0 -14
- data/app/models/ddr/language.rb +1 -6
- data/app/models/ddr/resource.rb +14 -0
- data/app/models/ddr/rights_statement.rb +2 -6
- data/config/locales/ddr-core.en.yml +4 -1
- data/db/migrate/20200207194453_add_default_to_lock_version.rb +6 -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/role_based_ability_definitions.rb +2 -2
- 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_permissions.rb +2 -1
- data/lib/ddr/auth/effective_roles.rb +6 -2
- data/lib/ddr/auth/failure_app.rb +1 -1
- data/lib/ddr/auth/grouper_gateway.rb +2 -2
- data/lib/ddr/auth/permissions.rb +14 -11
- data/lib/ddr/auth/role_based_access_controls_enforcement.rb +1 -37
- data/lib/ddr/auth/roles.rb +15 -3
- data/lib/ddr/auth/roles/role.rb +27 -69
- data/lib/ddr/auth/roles/role_types.rb +13 -6
- data/lib/ddr/core.rb +9 -0
- data/lib/ddr/core/version.rb +1 -1
- data/lib/ddr/fits.rb +0 -91
- data/lib/ddr/index.rb +2 -2
- data/lib/ddr/index/csv_query_result.rb +27 -20
- data/lib/ddr/index/fields.rb +5 -0
- data/lib/ddr/managers/technical_metadata_manager.rb +9 -4
- data/lib/ddr/structure.rb +2 -1
- data/lib/ddr/vocab/asset.rb +4 -0
- data/lib/ddr/workflow.rb +1 -0
- metadata +35 -9
@@ -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
|
data/app/models/ddr/admin_set.rb
CHANGED
@@ -1,9 +1,5 @@
|
|
1
|
-
require "active_resource"
|
2
|
-
|
3
1
|
module Ddr
|
4
|
-
class AdminSet <
|
5
|
-
|
6
|
-
self.site = ENV["DDR_AUX_API_URL"]
|
2
|
+
class AdminSet < AuxiliaryResource
|
7
3
|
|
8
4
|
def self.call(obj)
|
9
5
|
find_by_code(obj.admin_set)
|
@@ -13,11 +9,11 @@ module Ddr
|
|
13
9
|
|
14
10
|
def self.find_by_code(code)
|
15
11
|
return unless code
|
16
|
-
new get(:find, code: code)
|
12
|
+
fetch(code) { new get(:find, code: code) }
|
17
13
|
end
|
18
14
|
|
19
15
|
def self.keys
|
20
|
-
all.map(&:code)
|
16
|
+
fetch("codes") { all.map(&:code) }
|
21
17
|
end
|
22
18
|
|
23
19
|
def to_s
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Ddr
|
2
|
+
class Alert < AuxiliaryResource
|
3
|
+
|
4
|
+
ADMIN_SITE = 'admin'
|
5
|
+
PUBLIC_SITE = 'public'
|
6
|
+
|
7
|
+
# @param [String] the application ('admin' or 'public') for which to return active alerts
|
8
|
+
# @return [Array] the active alerts for the requested application site
|
9
|
+
def self.call(site)
|
10
|
+
get(:active, site: site).map { |resp| new(resp) }
|
11
|
+
rescue ActiveResource::ServerError => e
|
12
|
+
[]
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,24 @@
|
|
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
|
+
class_attribute :cache_expiry, instance_accessor: false
|
13
|
+
self.cache_expiry = 1.hour
|
14
|
+
|
15
|
+
def self.fetch(value_key, &block)
|
16
|
+
Rails.cache.fetch(cache_key(value_key), expires_in: cache_expiry, &block)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.cache_key(suffix)
|
20
|
+
[ model_name.cache_key, suffix ].join('/')
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
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/contact.rb
CHANGED
@@ -0,0 +1,61 @@
|
|
1
|
+
# TODO: 'https://duldev.atlassian.net/browse/DDR-1755'
|
2
|
+
|
3
|
+
module Ddr
|
4
|
+
class FindingAid
|
5
|
+
attr_reader :ead_id
|
6
|
+
|
7
|
+
EAD_XMLNS = "urn:isbn:1-931666-22-9"
|
8
|
+
|
9
|
+
def initialize(ead_id)
|
10
|
+
@ead_id = ead_id
|
11
|
+
end
|
12
|
+
|
13
|
+
def url
|
14
|
+
doc.css("eadid").attr("url").text
|
15
|
+
end
|
16
|
+
|
17
|
+
# The finding aid title
|
18
|
+
def title
|
19
|
+
doc.css("titleproper").children.first.text.strip
|
20
|
+
end
|
21
|
+
|
22
|
+
def repository
|
23
|
+
collection.xpath('ead:did/ead:repository/ead:corpname', ead: EAD_XMLNS).text
|
24
|
+
end
|
25
|
+
|
26
|
+
def collection_date_span
|
27
|
+
collection.xpath('ead:did/ead:unitdate[@type="inclusive"]', ead: EAD_XMLNS).text
|
28
|
+
end
|
29
|
+
|
30
|
+
def collection_number
|
31
|
+
collection.xpath('ead:did/ead:unitid', ead: EAD_XMLNS).text
|
32
|
+
end
|
33
|
+
|
34
|
+
def collection_title
|
35
|
+
collection.xpath('ead:did/ead:unittitle', ead: EAD_XMLNS).text
|
36
|
+
end
|
37
|
+
|
38
|
+
def extent
|
39
|
+
collection.xpath('ead:did/ead:physdesc/ead:extent', ead: EAD_XMLNS).map(&:text).join("; ")
|
40
|
+
end
|
41
|
+
|
42
|
+
def abstract
|
43
|
+
collection.xpath('ead:did/ead:abstract', ead: EAD_XMLNS).text
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def collection
|
49
|
+
doc.xpath('//ead:archdesc[@level="collection"]', ead: EAD_XMLNS)
|
50
|
+
end
|
51
|
+
|
52
|
+
# @raise [OpenURI::HTTPError] if 404, etc.
|
53
|
+
def doc
|
54
|
+
@doc ||= Nokogiri::XML(open(ead_xml_url))
|
55
|
+
end
|
56
|
+
|
57
|
+
def ead_xml_url
|
58
|
+
Ddr.ead_xml_base_url + ead_id + ".xml"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/app/models/ddr/item.rb
CHANGED
@@ -12,25 +12,11 @@ module Ddr
|
|
12
12
|
|
13
13
|
self.parent_class = Ddr::Collection
|
14
14
|
|
15
|
-
### DDRevo #####################
|
16
|
-
# TODO: We may want to revisit this alternate implementation once ddr-core is more fully baked
|
17
|
-
# or it may be fine just as it is
|
18
|
-
### DDRevo #####################
|
19
15
|
def children_having_extracted_text
|
20
|
-
# Ddr::Index::Query.build(self) do |item|
|
21
|
-
# is_part_of item
|
22
|
-
# where attached_files_having_content: "extractedText"
|
23
|
-
# fields :id, :extracted_text
|
24
|
-
# end
|
25
16
|
children.select { |child| child.attached_files_having_content.include?(:extracted_text) }
|
26
17
|
end
|
27
18
|
|
28
|
-
### DDRevo #####################
|
29
|
-
# TODO: We may want to revisit this alternate implementation once ddr-core is more fully baked
|
30
|
-
# or it may be fine just as it is
|
31
|
-
### DDRevo #####################
|
32
19
|
def all_text
|
33
|
-
# children_having_extracted_text.docs.map(&:extracted_text).flatten
|
34
20
|
children_having_extracted_text.map { |child| child.extracted_text.content }.to_a.flatten
|
35
21
|
end
|
36
22
|
|
data/app/models/ddr/language.rb
CHANGED
@@ -1,9 +1,5 @@
|
|
1
|
-
require "active_resource"
|
2
|
-
|
3
1
|
module Ddr
|
4
|
-
class Language <
|
5
|
-
|
6
|
-
self.site = ENV["DDR_AUX_API_URL"]
|
2
|
+
class Language < AuxiliaryResource
|
7
3
|
|
8
4
|
def self.call(obj)
|
9
5
|
obj.language.map do |lang|
|
@@ -28,4 +24,3 @@ module Ddr
|
|
28
24
|
|
29
25
|
end
|
30
26
|
end
|
31
|
-
|
data/app/models/ddr/resource.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module Ddr
|
2
2
|
class Resource < Valkyrie::Resource
|
3
3
|
|
4
|
+
enable_optimistic_locking
|
5
|
+
|
4
6
|
include Describable
|
5
7
|
include Governable
|
6
8
|
include HasAdminMetadata
|
@@ -47,6 +49,10 @@ module Ddr
|
|
47
49
|
can_have_streamable_media?
|
48
50
|
end
|
49
51
|
|
52
|
+
def self.canonical_model_name(model_name)
|
53
|
+
model_name.starts_with?('Ddr::') ? model_name : "Ddr::#{model_name}"
|
54
|
+
end
|
55
|
+
|
50
56
|
def self.common_model_name
|
51
57
|
name.split('::').last
|
52
58
|
end
|
@@ -65,6 +71,10 @@ module Ddr
|
|
65
71
|
alias_method :new_record?, :new_record
|
66
72
|
alias_method :resource_model, :internal_resource
|
67
73
|
|
74
|
+
def rights_statement
|
75
|
+
RightsStatement.call(self)
|
76
|
+
end
|
77
|
+
|
68
78
|
def title_display
|
69
79
|
return title.first if title.present?
|
70
80
|
return identifier.first if identifier.present?
|
@@ -80,6 +90,10 @@ module Ddr
|
|
80
90
|
send(f)&.file_identifier.present?
|
81
91
|
end
|
82
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.
|
83
97
|
def publishable?
|
84
98
|
false
|
85
99
|
end
|
@@ -1,9 +1,5 @@
|
|
1
|
-
require "active_resource"
|
2
|
-
|
3
1
|
module Ddr
|
4
|
-
class RightsStatement <
|
5
|
-
|
6
|
-
self.site = ENV["DDR_AUX_API_URL"]
|
2
|
+
class RightsStatement < AuxiliaryResource
|
7
3
|
|
8
4
|
def self.call(obj)
|
9
5
|
if obj.rights.present?
|
@@ -22,4 +18,4 @@ module Ddr
|
|
22
18
|
end
|
23
19
|
|
24
20
|
end
|
25
|
-
end
|
21
|
+
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
|