worthwhile-models 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/app/models/concerns/curation_concern/collection_model.rb +62 -0
- data/app/models/concerns/curation_concern/curatable.rb +77 -0
- data/app/models/concerns/curation_concern/has_representative.rb +14 -0
- data/app/models/concerns/curation_concern/human_readable_type.rb +23 -0
- data/app/models/concerns/curation_concern/with_basic_metadata.rb +49 -0
- data/app/models/concerns/curation_concern/with_editors.rb +44 -0
- data/app/models/concerns/curation_concern/with_generic_files.rb +23 -0
- data/app/models/concerns/curation_concern/with_linked_resources.rb +21 -0
- data/app/models/concerns/curation_concern/work.rb +24 -0
- data/app/models/concerns/worthwhile/ability.rb +34 -0
- data/app/models/concerns/worthwhile/generic_file/versioned_content.rb +18 -0
- data/app/models/concerns/worthwhile/generic_file_base.rb +64 -0
- data/app/models/concerns/worthwhile/solr_document_behavior.rb +140 -0
- data/app/models/generic_work.rb +5 -0
- data/app/models/worthwhile/classify_concern.rb +47 -0
- data/app/models/worthwhile/content_version.rb +23 -0
- data/app/models/worthwhile/contributor_agreement.rb +23 -0
- data/app/models/worthwhile/generic_file.rb +5 -0
- data/app/models/worthwhile/linked_resource.rb +41 -0
- data/app/models/worthwhile/quick_classification_query.rb +31 -0
- data/lib/worthwhile/models.rb +7 -0
- data/lib/worthwhile/models/engine.rb +11 -0
- data/lib/worthwhile/models/version.rb +5 -0
- data/worthwhile-models.gemspec +29 -0
- metadata +153 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9e40a4356445e489fdd44804236d674d99cd7f29
|
4
|
+
data.tar.gz: 426954c2064b078d0a811069528a96642cb4fdfb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: dd3b23367115d00157ecd7c21b38c8dc0a279f328f4a7d1fe5bfbca99b08518c8512c43056a689b4f8a4d343d6c0db0b302e505e33298052a3b5bdc63b8f358f
|
7
|
+
data.tar.gz: c36133602cc143df28212470c1c0d43588703c2cc9d3840e4525de1f05170ea9c27dc80597f147038aeef302fd2abb3ad5f1832f0c1a54c20aea7194cb63462f
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module CurationConcern
|
2
|
+
module CollectionModel
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
include Hydra::AccessControls::Permissions
|
6
|
+
include Hydra::AccessControls::WithAccessRight
|
7
|
+
include Sufia::Noid
|
8
|
+
include CurationConcern::HumanReadableType
|
9
|
+
include Hydra::Collection
|
10
|
+
include Hydra::Collections::Collectible
|
11
|
+
include CurationConcern::HasRepresentative
|
12
|
+
|
13
|
+
def add_member(collectible)
|
14
|
+
if can_add_to_members?(collectible)
|
15
|
+
collectible.collections << self
|
16
|
+
collectible.save
|
17
|
+
self.members << collectible
|
18
|
+
self.save
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_s
|
23
|
+
self.title.present? ? title : "No Title"
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_solr(solr_doc={}, opts={})
|
27
|
+
super.tap do |solr_doc|
|
28
|
+
Solrizer.set_field(solr_doc, 'generic_type', human_readable_type, :facetable)
|
29
|
+
solr_doc[Solrizer.solr_name('noid', Sufia::GenericFile.noid_indexer)] = noid
|
30
|
+
index_collection_pids(solr_doc)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def can_be_member_of_collection?(collection)
|
35
|
+
collection == self ? false : true
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
# ------------------------------------------------
|
40
|
+
# overriding method from active-fedora:
|
41
|
+
# lib/active_fedora/semantic_node.rb
|
42
|
+
#
|
43
|
+
# The purpose of this override is to ensure that
|
44
|
+
# a collection cannot contain itself.
|
45
|
+
#
|
46
|
+
# TODO: After active-fedora 7.0 is released, this
|
47
|
+
# logic can be moved into a before_add callback.
|
48
|
+
# ------------------------------------------------
|
49
|
+
def add_relationship(predicate, target, literal=false)
|
50
|
+
return if self == target
|
51
|
+
super
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
def can_add_to_members?(collectible)
|
56
|
+
collectible.can_be_member_of_collection?(self)
|
57
|
+
rescue NoMethodError
|
58
|
+
false
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# Replaces Curate's CurationConcern::Model
|
2
|
+
module CurationConcern::Curatable
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
include ::CurationConcern::HumanReadableType
|
7
|
+
include Sufia::Noid
|
8
|
+
include Sufia::ModelMethods
|
9
|
+
include Hydra::Collections::Collectible
|
10
|
+
include Solrizer::Common
|
11
|
+
include ::CurationConcern::HasRepresentative
|
12
|
+
|
13
|
+
# Modules in Curate's CurationConcern::Model that we _might_ pull in later
|
14
|
+
# include Curate::ActiveModelAdaptor
|
15
|
+
|
16
|
+
has_metadata 'properties', type: Worthwhile::PropertiesDatastream
|
17
|
+
has_attributes :relative_path, :depositor, :owner, datastream: :properties, multiple: false
|
18
|
+
class_attribute :human_readable_short_description
|
19
|
+
attr_accessor :files
|
20
|
+
end
|
21
|
+
|
22
|
+
def as_json(options)
|
23
|
+
{ pid: pid, title: title, model: self.class.to_s, curation_concern_type: human_readable_type }
|
24
|
+
end
|
25
|
+
|
26
|
+
def as_rdf_object
|
27
|
+
RDF::URI.new(internal_uri)
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_solr(solr_doc={}, opts={})
|
31
|
+
super.tap do |solr_doc|
|
32
|
+
index_collection_pids(solr_doc)
|
33
|
+
solr_doc[Solrizer.solr_name('noid', Sufia::GenericFile.noid_indexer)] = noid
|
34
|
+
add_derived_date_created(solr_doc)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_s
|
39
|
+
title.join(', ')
|
40
|
+
end
|
41
|
+
|
42
|
+
# Returns a string identifying the path associated with the object. ActionPack uses this to find a suitable partial to represent the object.
|
43
|
+
def to_partial_path
|
44
|
+
"curation_concern/#{super}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def can_be_member_of_collection?(collection)
|
48
|
+
collection == self ? false : true
|
49
|
+
end
|
50
|
+
|
51
|
+
protected
|
52
|
+
|
53
|
+
# A searchable date field that is derived from the (text) field date_created
|
54
|
+
def add_derived_date_created(solr_doc)
|
55
|
+
if self.respond_to?(:date_created)
|
56
|
+
self.class.create_and_insert_terms('date_created_derived', derived_dates, [:dateable], solr_doc)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def derived_dates
|
61
|
+
dates = Array(date_created)
|
62
|
+
dates.map { |date| Curate::DateFormatter.parse(date.to_s).to_s }
|
63
|
+
end
|
64
|
+
|
65
|
+
def index_collection_pids(solr_doc)
|
66
|
+
solr_doc[Solrizer.solr_name(:collection, :facetable)] ||= []
|
67
|
+
solr_doc[Solrizer.solr_name(:collection)] ||= []
|
68
|
+
self.collection_ids.each do |collection_id|
|
69
|
+
collection_obj = ActiveFedora::Base.load_instance_from_solr(collection_id)
|
70
|
+
if collection_obj.is_a?(Collection)
|
71
|
+
solr_doc[Solrizer.solr_name(:collection, :facetable)] << collection_id
|
72
|
+
solr_doc[Solrizer.solr_name(:collection)] << collection_id
|
73
|
+
end
|
74
|
+
end
|
75
|
+
solr_doc
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module CurationConcern::HasRepresentative
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
has_attributes :representative, datastream: :properties, multiple: false
|
6
|
+
end
|
7
|
+
|
8
|
+
def to_solr(solr_doc={}, opts={})
|
9
|
+
super.tap do |solr_doc|
|
10
|
+
solr_doc[Solrizer.solr_name('representative', :stored_searchable)] = representative
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module CurationConcern
|
2
|
+
module HumanReadableType
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
class_attribute :human_readable_short_description, :human_readable_type
|
7
|
+
self.human_readable_type = name.demodulize.titleize
|
8
|
+
end
|
9
|
+
|
10
|
+
def human_readable_type
|
11
|
+
self.class.human_readable_type
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_solr(solr_doc={}, opts={})
|
15
|
+
super(solr_doc, opts)
|
16
|
+
solr_doc[Solrizer.solr_name('human_readable_type',:facetable)] = human_readable_type
|
17
|
+
solr_doc[Solrizer.solr_name('human_readable_type', :stored_searchable)] = human_readable_type
|
18
|
+
return solr_doc
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# Basic metadata for all Works
|
2
|
+
# Required fields:
|
3
|
+
# dc:title
|
4
|
+
# dc:rights
|
5
|
+
#
|
6
|
+
# Optional fields:
|
7
|
+
# dc:contributor
|
8
|
+
# dc:coverage
|
9
|
+
# dc:creator
|
10
|
+
# dc:date
|
11
|
+
# dc:description
|
12
|
+
# dc:format
|
13
|
+
# dc:identifier
|
14
|
+
# dc:language
|
15
|
+
# dc:publisher
|
16
|
+
# dc:relation
|
17
|
+
# dc:source
|
18
|
+
# dc:subject
|
19
|
+
# dc:type
|
20
|
+
module CurationConcern::WithBasicMetadata
|
21
|
+
extend ActiveSupport::Concern
|
22
|
+
|
23
|
+
included do
|
24
|
+
has_metadata "descMetadata", type: ::GenericWorkMetadata
|
25
|
+
# Validations that apply to all types of Work AND Collections
|
26
|
+
validates_presence_of :title, message: 'Your work must have a title.'
|
27
|
+
|
28
|
+
|
29
|
+
# Single-value fields
|
30
|
+
has_attributes :created, :date_modified, :date_uploaded, datastream: :descMetadata, multiple: false
|
31
|
+
|
32
|
+
# Multi-value fields
|
33
|
+
has_attributes :contributor, :creator, :coverage, :date, :description, :content_format, :identifier,
|
34
|
+
:language, :publisher, :relation, :rights, :source, :subject, :title, :type,
|
35
|
+
datastream: :descMetadata, multiple: true
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
# TODO created and date_uploaded?
|
40
|
+
# TODO created and date_created
|
41
|
+
# has_attributes :date_uploaded, :date_modified, :title, :description,
|
42
|
+
# datastream: :descMetadata, multiple: false
|
43
|
+
#
|
44
|
+
# has_attributes :related_url, :based_near, :part_of, :creator, :contributor,
|
45
|
+
# :tag, :rights, :publisher, :date_created, :subject, :resource_type,
|
46
|
+
# :identifier, :language,
|
47
|
+
# datastream: :descMetadata, multiple: true
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module CurationConcern
|
2
|
+
module WithEditors
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def add_editor_group(group_name)
|
6
|
+
self.edit_groups += [group]
|
7
|
+
end
|
8
|
+
|
9
|
+
# @param groups [Array<String>] a list of group names to add
|
10
|
+
def add_editor_groups(groups)
|
11
|
+
groups.each { |g| add_editor_group(g) }
|
12
|
+
end
|
13
|
+
|
14
|
+
def remove_editor_group(group)
|
15
|
+
self.edit_groups -= [group]
|
16
|
+
end
|
17
|
+
|
18
|
+
# @param groups [Array<String>] a list of users to remove
|
19
|
+
def remove_editor_groups(groups)
|
20
|
+
groups.each { |g| remove_editor_group(g) }
|
21
|
+
end
|
22
|
+
|
23
|
+
# @param user [String] the user account you want to grant edit access to.
|
24
|
+
def add_editor(user)
|
25
|
+
self.edit_users += [user]
|
26
|
+
end
|
27
|
+
|
28
|
+
# @param users [Array<String>] a list of users to add
|
29
|
+
def add_editors(users)
|
30
|
+
users.each { |u| add_editor(u) }
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param user [String] the user account you want to revoke edit access for.
|
34
|
+
def remove_editor(user)
|
35
|
+
self.edit_users -= [user]
|
36
|
+
end
|
37
|
+
|
38
|
+
# @param users [Array<String>] a list of users to remove
|
39
|
+
def remove_editors(users)
|
40
|
+
users.each { |u| remove_editor(u) }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Copied from Curate
|
2
|
+
module CurationConcern
|
3
|
+
module WithGenericFiles
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
has_many :generic_files, property: :is_part_of, class_name: "Worthwhile::GenericFile"
|
8
|
+
before_destroy :before_destroy_cleanup_generic_files
|
9
|
+
end
|
10
|
+
|
11
|
+
def before_destroy_cleanup_generic_files
|
12
|
+
generic_files.each(&:destroy)
|
13
|
+
end
|
14
|
+
|
15
|
+
def copy_visibility_to_files
|
16
|
+
generic_files.each do |gf|
|
17
|
+
gf.visibility = visibility
|
18
|
+
gf.save!
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module CurationConcern
|
2
|
+
module WithLinkedResources
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
|
7
|
+
# attribute :linked_resource_urls, multiple: true
|
8
|
+
attr_accessor :linked_resource_urls
|
9
|
+
|
10
|
+
has_many :linked_resources, property: :is_part_of, class_name:"Worthwhile::LinkedResource"
|
11
|
+
|
12
|
+
after_destroy :after_destroy_cleanup_linked_resources
|
13
|
+
end
|
14
|
+
|
15
|
+
def after_destroy_cleanup_linked_resources
|
16
|
+
linked_resources.each(&:destroy)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module CurationConcern::Work
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
include ::CurationConcern::Curatable
|
4
|
+
include ::CurationConcern::WithGenericFiles
|
5
|
+
include Hydra::AccessControls::Embargoable
|
6
|
+
include ::CurationConcern::WithEditors
|
7
|
+
include CurationConcern::WithLinkedResources
|
8
|
+
|
9
|
+
# Modules in Curate's CurationConcern::Work that we _might_ pull in later
|
10
|
+
# include Curate::ActiveModelAdaptor
|
11
|
+
# include CurationConcern::WithLinkedContributors
|
12
|
+
# include CurationConcern::WithRelatedWorks
|
13
|
+
|
14
|
+
included do
|
15
|
+
has_metadata "properties", type: Worthwhile::PropertiesDatastream
|
16
|
+
has_attributes :depositor, :representative, datastream: :properties, multiple: false
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_solr(solr_doc={}, opts={})
|
20
|
+
super(solr_doc, opts)
|
21
|
+
Solrizer.set_field(solr_doc, 'generic_type', 'Work', :facetable)
|
22
|
+
return solr_doc
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Worthwhile
|
2
|
+
module Ability
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
included do
|
5
|
+
self.ability_logic += [:worthwhile_permissions]
|
6
|
+
end
|
7
|
+
|
8
|
+
def worthwhile_permissions
|
9
|
+
|
10
|
+
unless current_user.new_record?
|
11
|
+
can :create, Worthwhile::ClassifyConcern
|
12
|
+
can :create, [Worthwhile::GenericFile, Worthwhile::LinkedResource]
|
13
|
+
end
|
14
|
+
|
15
|
+
if user_groups.include? 'admin'
|
16
|
+
can [:discover, :show, :read, :edit, :update, :destroy], :all
|
17
|
+
end
|
18
|
+
|
19
|
+
can :collect, :all
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
# Add this to your ability_logic if you want all logged in users to be able to submit content
|
24
|
+
def everyone_can_create_curation_concerns
|
25
|
+
unless current_user.new_record?
|
26
|
+
can :create, [Worthwhile.configuration.curation_concerns]
|
27
|
+
can :create, Collection
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Worthwhile
|
2
|
+
class GenericFile
|
3
|
+
module VersionedContent
|
4
|
+
def versions
|
5
|
+
return [] unless persisted?
|
6
|
+
@versions ||= content.versions.collect {|version| Worthwhile::ContentVersion.new(content, version)}
|
7
|
+
end
|
8
|
+
|
9
|
+
def latest_version
|
10
|
+
versions.first || Worthwhile::ContentVersion::Null.new(content)
|
11
|
+
end
|
12
|
+
|
13
|
+
def current_version_id
|
14
|
+
latest_version.version_id
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Worthwhile
|
2
|
+
module GenericFileBase
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
include Hydra::AccessControls::Embargoable
|
5
|
+
include Sufia::ModelMethods
|
6
|
+
include Sufia::Noid
|
7
|
+
include Sufia::GenericFile::MimeTypes
|
8
|
+
include Sufia::GenericFile::Characterization
|
9
|
+
include Sufia::GenericFile::Audit
|
10
|
+
include Sufia::GenericFile::WebForm
|
11
|
+
include Sufia::GenericFile::Derivatives
|
12
|
+
include Sufia::GenericFile::Metadata
|
13
|
+
include Sufia::GenericFile::Versions
|
14
|
+
include Sufia::Permissions::Readable
|
15
|
+
include Worthwhile::GenericFile::VersionedContent
|
16
|
+
|
17
|
+
included do
|
18
|
+
belongs_to :batch, property: :is_part_of, class_name: 'ActiveFedora::Base'
|
19
|
+
|
20
|
+
before_destroy :remove_representative_relationship
|
21
|
+
|
22
|
+
attr_accessor :file
|
23
|
+
|
24
|
+
# make filename single-value (Sufia::GenericFile::Characterization makes it multivalue)
|
25
|
+
# has_attributes :filename, datastream: :characterization, multiple: false
|
26
|
+
def filename
|
27
|
+
content.label
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def human_readable_type
|
32
|
+
self.class.to_s.demodulize.titleize
|
33
|
+
end
|
34
|
+
|
35
|
+
def representative
|
36
|
+
to_param
|
37
|
+
end
|
38
|
+
|
39
|
+
def copy_permissions_from(obj)
|
40
|
+
self.datastreams['rightsMetadata'].ng_xml = obj.datastreams['rightsMetadata'].ng_xml
|
41
|
+
end
|
42
|
+
|
43
|
+
def update_parent_representative_if_empty(obj)
|
44
|
+
return unless obj.representative.blank?
|
45
|
+
obj.representative = self.pid
|
46
|
+
obj.save
|
47
|
+
end
|
48
|
+
|
49
|
+
def remove_representative_relationship
|
50
|
+
return unless ActiveFedora::Base.exists?(batch)
|
51
|
+
return unless batch.representative == self.pid
|
52
|
+
batch.representative = nil
|
53
|
+
batch.save
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_solr(solr_doc = {})
|
57
|
+
super.tap do |solr_doc|
|
58
|
+
# Enables Riiif to not have to recalculate this each time.
|
59
|
+
solr_doc['height_isi'] = Integer(height.first) if height.present?
|
60
|
+
solr_doc['width_isi'] = Integer(width.first) if width.present?
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# This was moved out of sufia-models and into sufia/app/models.
|
2
|
+
# Copied the file in here to retain the functionality until/unless the file gets moved back into sufia-models.
|
3
|
+
# -*- encoding : utf-8 -*-
|
4
|
+
module Worthwhile
|
5
|
+
module SolrDocumentBehavior
|
6
|
+
def title_or_label
|
7
|
+
title || label
|
8
|
+
end
|
9
|
+
|
10
|
+
##
|
11
|
+
# Give our SolrDocument an ActiveModel::Naming appropriate route_key
|
12
|
+
def route_key
|
13
|
+
get(Solrizer.solr_name('has_model', :symbol)).split(':').last.downcase
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_param
|
17
|
+
noid || id
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
title_or_label
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# Offer the source (ActiveFedora-based) model to Rails for some of the
|
26
|
+
# Rails methods (e.g. link_to).
|
27
|
+
# @example
|
28
|
+
# link_to '...', SolrDocument(:id => 'bXXXXXX5').new => <a href="/dams_object/bXXXXXX5">...</a>
|
29
|
+
def to_model
|
30
|
+
m = ActiveFedora::Base.load_instance_from_solr(id, self)
|
31
|
+
m.class == ActiveFedora::Base ? self : m
|
32
|
+
end
|
33
|
+
|
34
|
+
def collection?
|
35
|
+
hydra_model == 'Collection'
|
36
|
+
end
|
37
|
+
|
38
|
+
# Method to return the ActiveFedora model
|
39
|
+
def hydra_model
|
40
|
+
self[Solrizer.solr_name('active_fedora_model', Solrizer::Descriptor.new(:string, :stored, :indexed))]
|
41
|
+
end
|
42
|
+
|
43
|
+
def noid
|
44
|
+
self[Solrizer.solr_name('noid', Sufia::GenericFile.noid_indexer)]
|
45
|
+
end
|
46
|
+
|
47
|
+
def human_readable_type
|
48
|
+
Array(self[Solrizer.solr_name('human_readable_type', :stored_searchable)]).first
|
49
|
+
end
|
50
|
+
|
51
|
+
def representative
|
52
|
+
Array(self[Solrizer.solr_name('representative', :stored_searchable)]).first
|
53
|
+
end
|
54
|
+
|
55
|
+
def date_uploaded
|
56
|
+
field = self[Solrizer.solr_name("desc_metadata__date_uploaded", :stored_sortable, type: :date)]
|
57
|
+
return unless field.present?
|
58
|
+
begin
|
59
|
+
Date.parse(field).to_formatted_s(:standard)
|
60
|
+
rescue
|
61
|
+
Rails.logger.info "Unable to parse date: #{field.first.inspect} for #{self['id']}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def depositor(default = '')
|
66
|
+
val = Array(self[Solrizer.solr_name("depositor")]).first
|
67
|
+
val.present? ? val : default
|
68
|
+
end
|
69
|
+
|
70
|
+
def title
|
71
|
+
Array(self[Solrizer.solr_name('desc_metadata__title')]).first
|
72
|
+
end
|
73
|
+
|
74
|
+
def description
|
75
|
+
Array(self[Solrizer.solr_name('desc_metadata__description')]).first
|
76
|
+
end
|
77
|
+
|
78
|
+
def label
|
79
|
+
Array(self[Solrizer.solr_name('label')]).first
|
80
|
+
end
|
81
|
+
|
82
|
+
def file_format
|
83
|
+
Array(self[Solrizer.solr_name('file_format')]).first
|
84
|
+
end
|
85
|
+
|
86
|
+
def creator
|
87
|
+
Array(self[Solrizer.solr_name("desc_metadata__creator")]).first
|
88
|
+
end
|
89
|
+
|
90
|
+
def tags
|
91
|
+
Array(self[Solrizer.solr_name("desc_metadata__tag")])
|
92
|
+
end
|
93
|
+
|
94
|
+
def resource_type
|
95
|
+
Array(self[Solrizer.solr_name("desc_metadata__resource_type")])
|
96
|
+
end
|
97
|
+
|
98
|
+
def mime_type
|
99
|
+
Array(self[Solrizer.solr_name("mime_type")]).first
|
100
|
+
end
|
101
|
+
|
102
|
+
def read_groups
|
103
|
+
Array(self[::Ability.read_group_field])
|
104
|
+
end
|
105
|
+
|
106
|
+
def edit_groups
|
107
|
+
Array(self[::Ability.edit_group_field])
|
108
|
+
end
|
109
|
+
|
110
|
+
def edit_people
|
111
|
+
Array(self[::Ability.edit_user_field])
|
112
|
+
end
|
113
|
+
|
114
|
+
def public?
|
115
|
+
read_groups.include?('public')
|
116
|
+
end
|
117
|
+
|
118
|
+
def registered?
|
119
|
+
read_groups.include?('registered')
|
120
|
+
end
|
121
|
+
|
122
|
+
def pdf?
|
123
|
+
['application/pdf'].include? self.mime_type
|
124
|
+
end
|
125
|
+
|
126
|
+
def image?
|
127
|
+
['image/png','image/jpeg', 'image/jpg', 'image/jp2', 'image/bmp', 'image/gif', 'image/tiff'].include? self.mime_type
|
128
|
+
end
|
129
|
+
|
130
|
+
def video?
|
131
|
+
['video/mpeg', 'video/mp4', 'video/webm', 'video/x-msvideo', 'video/avi', 'video/quicktime', 'application/mxf'].include? self.mime_type
|
132
|
+
end
|
133
|
+
|
134
|
+
def audio?
|
135
|
+
# audio/x-wave is the mime type that fits 0.6.0 returns for a wav file.
|
136
|
+
# audio/mpeg is the mime type that fits 0.6.0 returns for an mp3 file.
|
137
|
+
['audio/mp3', 'audio/mpeg', 'audio/x-wave', 'audio/x-wav', 'audio/ogg'].include? self.mime_type
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'active_attr'
|
2
|
+
module Worthwhile
|
3
|
+
class ClassifyConcern
|
4
|
+
include ActiveAttr::Model
|
5
|
+
attribute :curation_concern_type
|
6
|
+
|
7
|
+
validates(
|
8
|
+
:curation_concern_type,
|
9
|
+
presence: true,
|
10
|
+
inclusion: { in: lambda { |record| record.registered_curation_concern_types } }
|
11
|
+
)
|
12
|
+
|
13
|
+
def all_curation_concern_classes
|
14
|
+
registered_curation_concern_types.sort.map { |c| self.class.to_class(c) }
|
15
|
+
end
|
16
|
+
|
17
|
+
def registered_curation_concern_types
|
18
|
+
Worthwhile.configuration.registered_curation_concern_types
|
19
|
+
end
|
20
|
+
|
21
|
+
def possible_curation_concern_types
|
22
|
+
registered_curation_concern_types.collect do |concern|
|
23
|
+
[self.class.to_class(concern).human_readable_type, concern]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def curation_concern_class
|
28
|
+
if possible_curation_concern_types.detect{|name, class_name|
|
29
|
+
class_name == curation_concern_type
|
30
|
+
}
|
31
|
+
self.class.to_class(curation_concern_type)
|
32
|
+
else
|
33
|
+
raise RuntimeError, "Invalid :curation_concern_type"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.to_class(type)
|
38
|
+
# TODO we may want to allow a different (or nil) namespace
|
39
|
+
type.camelize.constantize
|
40
|
+
# begin
|
41
|
+
# "::#{type.camelize}".constantize
|
42
|
+
# rescue NameError
|
43
|
+
# "Worthwhile::#{type}".constantize
|
44
|
+
# end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Worthwhile
|
2
|
+
class ContentVersion
|
3
|
+
class Null
|
4
|
+
def initialize(content)
|
5
|
+
end
|
6
|
+
def created_on; 'unknown'; end
|
7
|
+
def committer_name; 'unknown'; end
|
8
|
+
def formatted_created_on(*args); 'unknown'; end
|
9
|
+
def version_id; 'unknown'; end
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader :version_id, :created_on, :committer_name
|
13
|
+
def initialize(content, version_structure)
|
14
|
+
@created_on = version_structure.dsCreateDate
|
15
|
+
@version_id = version_structure.versionID
|
16
|
+
@committer_name = content.version_committer(version_structure)
|
17
|
+
end
|
18
|
+
|
19
|
+
def formatted_created_on(format = :long_ordinal )
|
20
|
+
created_on.localtime.to_formatted_s(format)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Worthwhile
|
2
|
+
class ContributorAgreement
|
3
|
+
attr_reader :curation_concern, :user
|
4
|
+
def initialize(curation_concern, user, params)
|
5
|
+
@curation_concern = curation_concern
|
6
|
+
@user = user
|
7
|
+
@param_value = params[param_key.to_sym] || params[param_key.to_s]
|
8
|
+
end
|
9
|
+
|
10
|
+
def acceptance_value
|
11
|
+
'accept'
|
12
|
+
end
|
13
|
+
|
14
|
+
def param_key
|
15
|
+
:accept_contributor_agreement
|
16
|
+
end
|
17
|
+
attr_reader :param_value
|
18
|
+
|
19
|
+
def is_being_accepted?
|
20
|
+
param_value == acceptance_value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Worthwhile
|
2
|
+
class LinkedResource < ActiveFedora::Base
|
3
|
+
include ::CurationConcern::Work
|
4
|
+
|
5
|
+
has_file_datastream "content", control_group: 'E'
|
6
|
+
has_metadata "descMetadata", type: GenericFileRdfDatastream
|
7
|
+
|
8
|
+
belongs_to :batch, property: :is_part_of, class_name: 'ActiveFedora::Base'
|
9
|
+
|
10
|
+
validates :url, presence: true
|
11
|
+
|
12
|
+
self.human_readable_short_description = "An arbitrary URL reference."
|
13
|
+
include ActionView::Helpers::SanitizeHelper
|
14
|
+
|
15
|
+
has_attributes :date_uploaded, :date_modified, :title, :description, datastream: :descMetadata, multiple: false
|
16
|
+
|
17
|
+
# Creator is multiple to match Sufia::GenericFile#creator
|
18
|
+
has_attributes :creator, datastream: :descMetadata, multiple: true
|
19
|
+
|
20
|
+
def url=(url)
|
21
|
+
u = URI::Parser.new.parse(url)
|
22
|
+
return unless [URI::HTTP, URI::HTTPS, URI::FTP].include?(u.class)
|
23
|
+
content.dsLocation = u.to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
def url
|
27
|
+
content.dsLocation
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_s
|
31
|
+
url
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_solr(solr_doc={}, opts={})
|
35
|
+
super
|
36
|
+
Solrizer.set_field(solr_doc, 'url', url, :stored_searchable)
|
37
|
+
solr_doc
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Worthwhile
|
2
|
+
class QuickClassificationQuery
|
3
|
+
|
4
|
+
def self.each_for_context(*args, &block)
|
5
|
+
new(*args).all.each(&block)
|
6
|
+
end
|
7
|
+
|
8
|
+
attr_reader :user
|
9
|
+
|
10
|
+
def initialize(user, options = {})
|
11
|
+
@user = user
|
12
|
+
@concern_name_normalizer = options.fetch(:concern_name_normalizer, ClassifyConcern.method(:to_class))
|
13
|
+
@registered_curation_concern_names = options.fetch(:registered_curation_concern_names, Worthwhile.configuration.registered_curation_concern_types)
|
14
|
+
end
|
15
|
+
|
16
|
+
def all
|
17
|
+
ActiveFedora::Base.logger.debug "User is #{user}"
|
18
|
+
ActiveFedora::Base.logger.debug "try is #{normalized_curation_concern_names.first}"
|
19
|
+
ActiveFedora::Base.logger.debug "can is #{user.can?(:create, normalized_curation_concern_names.first)}"
|
20
|
+
normalized_curation_concern_names.select {|klass| user.can?(:create, klass)}
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_reader :concern_name_normalizer, :registered_curation_concern_names
|
26
|
+
|
27
|
+
def normalized_curation_concern_names
|
28
|
+
registered_curation_concern_names.collect{|name| concern_name_normalizer.call(name) }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
version = File.read(File.expand_path("../../WORTHWHILE_VERSION", __FILE__)).strip
|
3
|
+
|
4
|
+
lib = File.expand_path('../lib', __FILE__)
|
5
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = "worthwhile-models"
|
9
|
+
spec.version = version
|
10
|
+
spec.authors = ["Justin Coyne"]
|
11
|
+
spec.email = ["justin@curationexperts.com"]
|
12
|
+
spec.summary = %q{Simple institutional repository models for Hydra}
|
13
|
+
spec.description = %q{An extensible repository data-model with works and and many attached files}
|
14
|
+
spec.homepage = ""
|
15
|
+
spec.license = "APACHE2"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0")
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_dependency 'hydra-head', '~> 7.2.2'
|
23
|
+
spec.add_dependency "active_attr"
|
24
|
+
spec.add_dependency 'sufia-models', '~> 4.0.0'
|
25
|
+
spec.add_dependency 'hydra-collections', '~> 2.0.5'
|
26
|
+
|
27
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
28
|
+
spec.add_development_dependency "rake"
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: worthwhile-models
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Justin Coyne
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-10-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: hydra-head
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 7.2.2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 7.2.2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: active_attr
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sufia-models
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 4.0.0
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 4.0.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: hydra-collections
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.0.5
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 2.0.5
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.6'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.6'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: An extensible repository data-model with works and and many attached
|
98
|
+
files
|
99
|
+
email:
|
100
|
+
- justin@curationexperts.com
|
101
|
+
executables: []
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- app/models/concerns/curation_concern/collection_model.rb
|
106
|
+
- app/models/concerns/curation_concern/curatable.rb
|
107
|
+
- app/models/concerns/curation_concern/has_representative.rb
|
108
|
+
- app/models/concerns/curation_concern/human_readable_type.rb
|
109
|
+
- app/models/concerns/curation_concern/with_basic_metadata.rb
|
110
|
+
- app/models/concerns/curation_concern/with_editors.rb
|
111
|
+
- app/models/concerns/curation_concern/with_generic_files.rb
|
112
|
+
- app/models/concerns/curation_concern/with_linked_resources.rb
|
113
|
+
- app/models/concerns/curation_concern/work.rb
|
114
|
+
- app/models/concerns/worthwhile/ability.rb
|
115
|
+
- app/models/concerns/worthwhile/generic_file/versioned_content.rb
|
116
|
+
- app/models/concerns/worthwhile/generic_file_base.rb
|
117
|
+
- app/models/concerns/worthwhile/solr_document_behavior.rb
|
118
|
+
- app/models/generic_work.rb
|
119
|
+
- app/models/worthwhile/classify_concern.rb
|
120
|
+
- app/models/worthwhile/content_version.rb
|
121
|
+
- app/models/worthwhile/contributor_agreement.rb
|
122
|
+
- app/models/worthwhile/generic_file.rb
|
123
|
+
- app/models/worthwhile/linked_resource.rb
|
124
|
+
- app/models/worthwhile/quick_classification_query.rb
|
125
|
+
- lib/worthwhile/models.rb
|
126
|
+
- lib/worthwhile/models/engine.rb
|
127
|
+
- lib/worthwhile/models/version.rb
|
128
|
+
- worthwhile-models.gemspec
|
129
|
+
homepage: ''
|
130
|
+
licenses:
|
131
|
+
- APACHE2
|
132
|
+
metadata: {}
|
133
|
+
post_install_message:
|
134
|
+
rdoc_options: []
|
135
|
+
require_paths:
|
136
|
+
- lib
|
137
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - ">="
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
requirements: []
|
148
|
+
rubyforge_project:
|
149
|
+
rubygems_version: 2.2.2
|
150
|
+
signing_key:
|
151
|
+
specification_version: 4
|
152
|
+
summary: Simple institutional repository models for Hydra
|
153
|
+
test_files: []
|