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

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