ddr-models 3.0.0.alpha.2 → 3.0.0.alpha.3

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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +5 -2
  3. data/lib/ddr/actions/fixity_check.rb +8 -5
  4. data/lib/ddr/auth/ability_definitions/role_based_ability_definitions.rb +1 -1
  5. data/lib/ddr/auth/grouper_gateway.rb +51 -53
  6. data/lib/ddr/datastreams/datastream_behavior.rb +65 -66
  7. data/lib/ddr/events/event.rb +2 -2
  8. data/lib/ddr/events/fixity_check_event.rb +3 -2
  9. data/lib/ddr/index/fields.rb +1 -0
  10. data/lib/ddr/managers/derivatives_manager.rb +3 -3
  11. data/lib/ddr/managers/permanent_id_manager.rb +2 -2
  12. data/lib/ddr/models.rb +5 -2
  13. data/lib/ddr/models/attached_file_profile.rb +12 -0
  14. data/lib/ddr/models/attached_files_profile.rb +21 -0
  15. data/lib/ddr/models/base.rb +77 -74
  16. data/lib/ddr/models/describable.rb +3 -3
  17. data/lib/ddr/models/governable.rb +1 -1
  18. data/lib/ddr/models/indexing.rb +1 -0
  19. data/lib/ddr/models/licenses/license.rb +8 -2
  20. data/lib/ddr/models/metadata/descriptive_metadata.rb +6 -10
  21. data/lib/ddr/models/metadata/metadata_mapping.rb +45 -0
  22. data/lib/ddr/models/object_api.rb +11 -0
  23. data/lib/ddr/models/solr_document.rb +16 -9
  24. data/lib/ddr/models/url_safe_id.rb +9 -0
  25. data/lib/ddr/models/version.rb +1 -1
  26. data/lib/ddr/utils.rb +3 -3
  27. data/spec/auth/ability_spec.rb +9 -9
  28. data/spec/jobs/fits_file_characterization_spec.rb +3 -3
  29. data/spec/models/active_fedora_base_spec.rb +4 -4
  30. data/spec/models/active_fedora_datastream_spec.rb +6 -8
  31. data/spec/models/collection_spec.rb +1 -1
  32. data/spec/models/descriptive_metadata_spec.rb +0 -3
  33. data/spec/models/effective_license_spec.rb +4 -4
  34. data/spec/models/indexing_spec.rb +1 -1
  35. data/spec/models/license_spec.rb +3 -3
  36. data/spec/spec_helper.rb +6 -5
  37. data/spec/support/shared_examples_for_ddr_models.rb +1 -0
  38. data/spec/support/shared_examples_for_describables.rb +2 -2
  39. data/spec/support/shared_examples_for_events.rb +6 -6
  40. data/spec/support/shared_examples_for_fixity_checkable_spec.rb +15 -0
  41. data/spec/support/shared_examples_for_governables.rb +1 -1
  42. metadata +9 -4
  43. data/lib/ddr/models/metadata/metadata_mapper.rb +0 -32
  44. data/lib/ddr/models/metadata/metadata_mappers.rb +0 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b5e64a6ea529a126ced98548f47347d51f25beb2
4
- data.tar.gz: f8e1c3cc8ee4fdc79c1bdb3a3ae936c56074e1be
3
+ metadata.gz: 5ba4e9d42e6784bc59cf386c341006539ff072f1
4
+ data.tar.gz: 88c2d6e6589785a20228e615a287d8f334cc98f3
5
5
  SHA512:
6
- metadata.gz: ae6350545f2458891a4bae2baa5ead197a42cec54c3b2c7d5fbd4159a54e4a472e76bda1d667f4c86d8cb6a5a5c06bd36809dacf602310dab7d3143075d1f1b9
7
- data.tar.gz: 139e3ea27a1b2e105054d3ce7cc9fb26599004eddeafa7ca591fd3382d336e584e4ebbd1a2bc4463a936a8444bfe65d3203257ad9dcc88dd4ec9959b2eecf696
6
+ metadata.gz: 41e9ebf75006154ba347dd5fdbc91c44b835990eb46f920c004ce16aed1e9d8637c935d94a4bc1afb4f9924b6ada95da5da6be8e77606fb5bd0251caa69f08a5
7
+ data.tar.gz: 3959dc747ad83c854ef084b25843177e43601273fd6954aea81a7974730802662230f362e000ddfcc27ab80f75965fa238b932b444f377ca2f8d820d05944fb4
@@ -1,12 +1,15 @@
1
1
  language: ruby
2
2
  before_install:
3
3
  - sudo apt-get install libvips-dev
4
+ - gem install bundler --version "~> 1.10"
4
5
  rvm:
5
- - 2.1
6
+ - 2.1.5
6
7
  script: "bundle exec rake ci"
7
8
  cache:
8
- - bundler
9
9
  - apt
10
10
  notifications:
11
11
  email:
12
12
  - lib-drs@duke.edu
13
+ bundler_args: --without production
14
+ jdk:
15
+ - oraclejdk8
@@ -11,19 +11,22 @@ module Ddr
11
11
 
12
12
  # Return result of fixity check
13
13
  def self._execute(object)
14
- Result.new(pid: object.pid).tap do |r|
14
+ Result.new(id: object.id).tap do |r|
15
15
  object.datastreams_to_validate.each do |dsid, ds|
16
- r.success &&= ds.dsChecksumValid
17
- r.results[dsid] = ds.profile
16
+ # r.success &&= ds.dsChecksumValid
17
+ # r.results[dsid] = ds.profile
18
+ checksum_valid = ds.check_fixity
19
+ r.success &&= checksum_valid
20
+ r.results[dsid] = { 'checksum_valid' => checksum_valid }
18
21
  end
19
22
  end
20
23
  end
21
24
 
22
25
  class Result
23
- attr_accessor :pid, :success, :results, :checked_at
26
+ attr_accessor :id, :success, :results, :checked_at
24
27
 
25
28
  def initialize(args={})
26
- @pid = args[:pid]
29
+ @id = args[:id]
27
30
  @success = args[:success] || true
28
31
  @results = args[:results] || {}
29
32
  @checked_at = args[:checked_at] || Time.now.utc
@@ -19,7 +19,7 @@ module Ddr
19
19
  def permissions(obj)
20
20
  case obj
21
21
  when Ddr::Models::Base, SolrDocument
22
- cached_permissions obj.pid do
22
+ cached_permissions obj.id do
23
23
  obj.effective_permissions(agents)
24
24
  end
25
25
  when String
@@ -1,70 +1,68 @@
1
1
  require 'grouper-rest-client'
2
2
  require "delegate"
3
3
 
4
- module Ddr
5
- module Auth
6
- class GrouperGateway < SimpleDelegator
4
+ module Ddr::Auth
5
+ class GrouperGateway < SimpleDelegator
7
6
 
8
- SUBJECT_ID_RE = Regexp.new('[^@]+(?=@duke\.edu)')
9
- DEFAULT_TIMEOUT = 5
7
+ SUBJECT_ID_RE = Regexp.new('[^@]+(?=@duke\.edu)')
8
+ DEFAULT_TIMEOUT = 5
10
9
 
11
- def self.repository_groups(*args)
12
- new.repository_groups(*args)
13
- end
10
+ def self.repository_groups(*args)
11
+ new.repository_groups(*args)
12
+ end
14
13
 
15
- def self.user_groups(*args)
16
- new.user_groups(*args)
17
- end
18
-
19
- def initialize
20
- super Grouper::Rest::Client::Resource.new(ENV["GROUPER_URL"],
21
- user: ENV["GROUPER_USER"],
22
- password: ENV["GROUPER_PASSWORD"],
23
- timeout: ENV.fetch("GROUPER_TIMEOUT", DEFAULT_TIMEOUT).to_i)
24
- end
14
+ def self.user_groups(*args)
15
+ new.user_groups(*args)
16
+ end
25
17
 
26
- # List of all grouper groups for the repository
27
- def repository_groups(raw = false)
28
- repo_groups = groups(REPOSITORY_GROUP_FILTER)
29
- if ok?
30
- return repo_groups if raw
31
- repo_groups.map do |g|
32
- Group.new(g["name"], label: g["displayExtension"])
33
- end
34
- else
35
- []
18
+ def initialize
19
+ super Grouper::Rest::Client::Resource.new(ENV["GROUPER_URL"],
20
+ user: ENV["GROUPER_USER"],
21
+ password: ENV["GROUPER_PASSWORD"],
22
+ timeout: ENV.fetch("GROUPER_TIMEOUT", DEFAULT_TIMEOUT).to_i)
23
+ end
24
+
25
+ # List of all grouper groups for the repository
26
+ def repository_groups(raw = false)
27
+ repo_groups = groups(Ddr::Auth.repository_group_filter)
28
+ if ok?
29
+ return repo_groups if raw
30
+ repo_groups.map do |g|
31
+ Group.new(g["name"], label: g["displayExtension"])
36
32
  end
33
+ else
34
+ []
37
35
  end
36
+ end
38
37
 
39
- def user_groups(user, raw = false)
40
- groups = []
41
- subject_id = user.principal_name.scan(SUBJECT_ID_RE).first
42
- return groups unless subject_id
43
- begin
44
- request_body = {
45
- "WsRestGetGroupsRequest" => {
46
- "subjectLookups" => [{"subjectIdentifier" => subject_id}]
47
- }
38
+ def user_groups(user, raw = false)
39
+ groups = []
40
+ subject_id = user.principal_name.scan(SUBJECT_ID_RE).first
41
+ return groups unless subject_id
42
+ begin
43
+ request_body = {
44
+ "WsRestGetGroupsRequest" => {
45
+ "subjectLookups" => [{"subjectIdentifier" => subject_id}]
48
46
  }
49
- # Have to use :call b/c grouper-rest-client :subjects method doesn't support POST
50
- response = call("subjects", :post, request_body)
51
- if ok?
52
- result = response["WsGetGroupsResults"]["results"].first
53
- # Have to manually filter results b/c Grouper WS version 1.5 does not support filter parameter
54
- if result && result["wsGroups"]
55
- groups = result["wsGroups"].select { |g| g["name"] =~ /^#{REPOSITORY_GROUP_FILTER}/ }
56
- end
47
+ }
48
+ # Have to use :call b/c grouper-rest-client :subjects method doesn't support POST
49
+ response = call("subjects", :post, request_body)
50
+ if ok?
51
+ result = response["WsGetGroupsResults"]["results"].first
52
+ # Have to manually filter results b/c Grouper WS version 1.5 does not support filter parameter
53
+ if result && result["wsGroups"]
54
+ groups = result["wsGroups"].select { |g| g["name"] =~ /^#{REPOSITORY_GROUP_FILTER}/ }
57
55
  end
58
- rescue StandardError => e
59
- # XXX Should we raise a custom exception?
60
- Rails.logger.error e
61
- end
62
- return groups if raw
63
- groups.map do |g|
64
- Group.new(g["name"], label: g["displayExtension"])
65
56
  end
57
+ rescue StandardError => e
58
+ # XXX Should we raise a custom exception?
59
+ Rails.logger.error e
60
+ end
61
+ return groups if raw
62
+ groups.map do |g|
63
+ Group.new(g["name"], label: g["displayExtension"])
66
64
  end
67
-
68
65
  end
66
+
69
67
  end
70
68
  end
@@ -1,83 +1,82 @@
1
- module Ddr
2
- module Datastreams
3
- module DatastreamBehavior
1
+ module Ddr::Datastreams
2
+ module DatastreamBehavior
3
+ extend Deprecation
4
4
 
5
- DEFAULT_FILE_EXTENSION = "bin"
6
- STRFTIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%LZ"
5
+ DEFAULT_FILE_EXTENSION = "bin"
6
+ STRFTIME_FORMAT = "%Y-%m-%dT%H:%M:%S.%LZ"
7
7
 
8
- def dsid
9
- warn "[DEPRECATION] `dsid` is no longer a datastream/file method." \
10
- " Use `File.basename(id)`."
11
- if id
12
- ::File.basename(id)
13
- end
8
+ def dsid
9
+ Deprecation.warn(DatastreamBehavior,
10
+ "`dsid` is no longer a datastream/file method. Use `File.basename(id)`.")
11
+ if id
12
+ ::File.basename(id)
14
13
  end
14
+ end
15
15
 
16
- def dsCreateDate
17
- warn "[DEPRECATION] `dsCreateDate` is no longer a datastream/file method." \
18
- " Use `create_date` instead."
19
- create_date
20
- end
16
+ def dsCreateDate
17
+ Deprecation.warn(DatastreamBehavior,
18
+ "`dsCreateDate` is no longer a datastream/file method. Use `create_date` instead.")
19
+ create_date
20
+ end
21
21
 
22
- def validate_checksum!(checksum_value, checksum_type=nil)
23
- raise Ddr::Models::Error, "Checksum cannot be validated on new datastream." if new_record?
24
- raise Ddr::Models::Error, "Checksum cannot be validated on unpersisted content." if content_changed?
25
- raise Ddr::Models::ChecksumInvalid, "The repository internal checksum validation failed." unless check_fixity
26
- algorithm = checksum_type || checksum.algorithm
27
- calculated_checksum = if algorithm == checksum.algorithm
28
- checksum.value
29
- else
30
- content_digest(algorithm)
31
- end
32
- if checksum_value == calculated_checksum
33
- "The checksum #{algorithm}:#{checksum_value} is valid for datastream #{dsid}."
34
- else
35
- raise Ddr::Models::ChecksumInvalid, "The checksum #{algorithm}:#{checksum_value} is not valid for datastream #{dsid}."
36
- end
22
+ def validate_checksum!(checksum_value, checksum_type=nil)
23
+ raise Ddr::Models::Error, "Checksum cannot be validated on new datastream." if new_record?
24
+ raise Ddr::Models::Error, "Checksum cannot be validated on unpersisted content." if content_changed?
25
+ raise Ddr::Models::ChecksumInvalid, "The repository internal checksum validation failed." unless check_fixity
26
+ algorithm = checksum_type || checksum.algorithm
27
+ calculated_checksum = if algorithm == checksum.algorithm
28
+ checksum.value
29
+ else
30
+ content_digest(algorithm)
31
+ end
32
+ if checksum_value == calculated_checksum
33
+ "The checksum #{algorithm}:#{checksum_value} is valid for datastream #{dsid}."
34
+ else
35
+ raise Ddr::Models::ChecksumInvalid, "The checksum #{algorithm}:#{checksum_value} is not valid for datastream #{dsid}."
37
36
  end
37
+ end
38
38
 
39
- def create_date_string
40
- dsCreateDate.strftime(STRFTIME_FORMAT) if dsCreateDate
41
- end
39
+ def create_date_string
40
+ dsCreateDate.strftime(STRFTIME_FORMAT) if dsCreateDate
41
+ end
42
42
 
43
- def content_digest(algorithm)
44
- Ddr::Utils.digest(content, algorithm)
45
- end
43
+ def content_digest(algorithm)
44
+ Ddr::Utils.digest(content, algorithm)
45
+ end
46
46
 
47
- # Return default file extension for datastream based on MIME type
48
- def default_file_extension
49
- mimetypes = MIME::Types[mime_type]
50
- return mimetypes.first.extensions.first unless mimetypes.empty?
51
- case mime_type
52
- when 'application/n-triples'
53
- 'txt'
54
- else
55
- DEFAULT_FILE_EXTENSION
56
- end
47
+ # Return default file extension for datastream based on MIME type
48
+ def default_file_extension
49
+ mimetypes = MIME::Types[mime_type]
50
+ return mimetypes.first.extensions.first unless mimetypes.empty?
51
+ case mime_type
52
+ when 'application/n-triples'
53
+ 'txt'
54
+ else
55
+ DEFAULT_FILE_EXTENSION
57
56
  end
57
+ end
58
58
 
59
- def default_file_prefix
60
- (id && id.gsub(/\//, "_")) || "NEW"
61
- end
59
+ def default_file_prefix
60
+ (id && id.gsub(/\//, "_")) || "NEW"
61
+ end
62
62
 
63
- # Return default file name
64
- def default_file_name
65
- [ default_file_prefix, default_file_extension ].join(".")
66
- end
63
+ # Return default file name
64
+ def default_file_name
65
+ [ default_file_prefix, default_file_extension ].join(".")
66
+ end
67
67
 
68
- def tempfile(prefix: nil, suffix: nil)
69
- if empty?
70
- raise Ddr::Models::Error, "Refusing to create tempfile for empty datastream!"
71
- end
72
- prefix ||= default_file_prefix + "--"
73
- suffix ||= "." + default_file_extension
74
- Tempfile.open [prefix, suffix], encoding: Encoding::ASCII_8BIT do |f|
75
- f.write(content)
76
- f.close
77
- yield f
78
- end
68
+ def tempfile(prefix: nil, suffix: nil)
69
+ if empty?
70
+ raise Ddr::Models::Error, "Refusing to create tempfile for empty datastream!"
71
+ end
72
+ prefix ||= default_file_prefix + "--"
73
+ suffix ||= "." + default_file_extension
74
+ Tempfile.open [prefix, suffix], encoding: Encoding::ASCII_8BIT do |f|
75
+ f.write(content)
76
+ f.close
77
+ yield f
79
78
  end
80
-
81
79
  end
80
+
82
81
  end
83
82
  end
@@ -45,7 +45,7 @@ module Ddr
45
45
  # Scopes
46
46
 
47
47
  def self.for_object(obj)
48
- for_pid(obj.pid)
48
+ for_pid(obj.id)
49
49
  end
50
50
 
51
51
  def self.for_pid(pid)
@@ -92,7 +92,7 @@ module Ddr
92
92
 
93
93
  def object=(obj)
94
94
  raise ArgumentError, "Can't set to new object" if obj.new_record?
95
- self.pid = obj.pid
95
+ self.pid = obj.id
96
96
  @object = obj
97
97
  end
98
98
 
@@ -17,10 +17,11 @@ module Ddr
17
17
  result = notification.payload[:result] # FixityCheck::Result instance
18
18
  detail = [DETAIL_PREAMBLE]
19
19
  result.results.each do |dsid, dsProfile|
20
- validation = dsProfile["dsChecksumValid"] ? VALID : INVALID
20
+ # validation = dsProfile["dsChecksumValid"] ? VALID : INVALID
21
+ validation = dsProfile["checksum_valid"] ? VALID : INVALID
21
22
  detail << DETAIL_TEMPLATE % {dsid: dsid, validation: validation}
22
23
  end
23
- create(pid: result.pid,
24
+ create(pid: result.id,
24
25
  event_date_time: notification.time,
25
26
  outcome: result.success ? SUCCESS : FAILURE,
26
27
  detail: detail.join("\n")
@@ -18,6 +18,7 @@ module Ddr::Index
18
18
  ACTIVE_FEDORA_MODEL = Field.new :active_fedora_model, :stored_sortable
19
19
  ADMIN_SET = Field.new :admin_set, :stored_sortable
20
20
  ADMIN_SET_FACET = Field.new :admin_set_facet, :facetable
21
+ ATTACHED_FILES = Field.new :attached_files, solr_name: "attached_files_ss"
21
22
  BOX_NUMBER_FACET = Field.new :box_number_facet, :facetable
22
23
  COLLECTION_FACET = Field.new :collection_facet, :facetable
23
24
  COLLECTION_URI = Field.new :collection_uri, :symbol
@@ -19,7 +19,7 @@ module Ddr
19
19
  # - object already has this derivative (need to delete or replace it)
20
20
  # - the derivative can be generated for this object
21
21
  if derivative.class.has_derivative?(object) || derivative.class.generatable?(object)
22
- schedule == SCHEDULE_NOW ? update_derivative(derivative) : Resque.enqueue(DerivativeJob, object.pid, derivative_to_update)
22
+ schedule == SCHEDULE_NOW ? update_derivative(derivative) : Resque.enqueue(DerivativeJob, object.id, derivative_to_update)
23
23
  end
24
24
  end
25
25
  end
@@ -38,7 +38,7 @@ module Ddr
38
38
 
39
39
  def generate_derivative(derivative)
40
40
  ActiveSupport::Notifications.instrument(Ddr::Notifications::UPDATE,
41
- pid: object.pid,
41
+ pid: object.id,
42
42
  summary: "Generate #{derivative.class.name} derivative"
43
43
  ) do |payload|
44
44
  derivative.generate!(object)
@@ -47,7 +47,7 @@ module Ddr
47
47
 
48
48
  def delete_derivative(derivative)
49
49
  ActiveSupport::Notifications.instrument(Ddr::Notifications::UPDATE,
50
- pid: object.pid,
50
+ pid: object.id,
51
51
  summary: "Delete derivative #{derivative.class.name}"
52
52
  ) do |payload|
53
53
  derivative.delete!(object)
@@ -21,13 +21,13 @@ module Ddr
21
21
  end
22
22
 
23
23
  def assign_later
24
- Resque.enqueue(AssignmentJob, object.pid)
24
+ Resque.enqueue(AssignmentJob, object.id)
25
25
  end
26
26
 
27
27
  def assign
28
28
  raise Ddr::Models::Error, "Permanent ID already assigned." if object.permanent_id
29
29
  ActiveSupport::Notifications.instrument(Ddr::Notifications::UPDATE,
30
- pid: object.pid,
30
+ pid: object.id,
31
31
  software: SOFTWARE,
32
32
  summary: ASSIGN_EVENT_SUMMARY
33
33
  ) do |payload|
@@ -32,6 +32,8 @@ module Ddr
32
32
 
33
33
  autoload :AccessControllable
34
34
  autoload :AdminSet
35
+ autoload :AttachedFileProfile
36
+ autoload :AttachedFilesProfile
35
37
  autoload :Base
36
38
  autoload :ChecksumInvalid, 'ddr/models/error'
37
39
  autoload :ContentModelError, 'ddr/models/error'
@@ -51,9 +53,11 @@ module Ddr
51
53
  autoload :HasStructMetadata
52
54
  autoload :HasThumbnail
53
55
  autoload :Indexing
56
+ autoload :ObjectApi
54
57
  autoload :SolrDocument
55
58
  autoload :StructDiv
56
59
  autoload :Structure
60
+ autoload :UrlSafeId
57
61
  autoload :YearFacet
58
62
 
59
63
  autoload_under "licenses" do
@@ -67,8 +71,7 @@ module Ddr
67
71
  autoload_under "metadata" do
68
72
  autoload :DescriptiveMetadata
69
73
  autoload :Metadata
70
- autoload :MetadataMapper
71
- autoload :MetadataMappers
74
+ autoload :MetadataMapping
72
75
  autoload :MetadataTerm
73
76
  autoload :MetadataVocabulary
74
77
  autoload :MetadataVocabularies