curation_concerns-models 0.1.0

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 (84) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.md +177 -0
  5. data/README.md +42 -0
  6. data/Rakefile +1 -0
  7. data/app/actors/concerns/curation_concerns/manages_embargoes_actor.rb +99 -0
  8. data/app/actors/curation_concerns/base_actor.rb +90 -0
  9. data/app/actors/curation_concerns/generic_file_actor.rb +150 -0
  10. data/app/actors/curation_concerns/work_actor_behavior.rb +88 -0
  11. data/app/jobs/active_fedora_id_based_job.rb +22 -0
  12. data/app/jobs/active_fedora_pid_based_job.rb +6 -0
  13. data/app/jobs/audit_job.rb +58 -0
  14. data/app/jobs/characterize_job.rb +11 -0
  15. data/app/jobs/copy_permissions_job.rb +24 -0
  16. data/app/jobs/create_derivatives_job.rb +15 -0
  17. data/app/jobs/import_url_job.rb +56 -0
  18. data/app/jobs/ingest_local_file_job.rb +48 -0
  19. data/app/jobs/resolrize_job.rb +9 -0
  20. data/app/models/checksum_audit_log.rb +21 -0
  21. data/app/models/concerns/curation_concerns/ability.rb +34 -0
  22. data/app/models/concerns/curation_concerns/basic_metadata.rb +87 -0
  23. data/app/models/concerns/curation_concerns/collection_behavior.rb +47 -0
  24. data/app/models/concerns/curation_concerns/generic_file/belongs_to_works.rb +53 -0
  25. data/app/models/concerns/curation_concerns/generic_file/characterization.rb +89 -0
  26. data/app/models/concerns/curation_concerns/generic_file/content.rb +8 -0
  27. data/app/models/concerns/curation_concerns/generic_file/export.rb +343 -0
  28. data/app/models/concerns/curation_concerns/generic_file/full_text_indexing.rb +12 -0
  29. data/app/models/concerns/curation_concerns/generic_file/indexing.rb +14 -0
  30. data/app/models/concerns/curation_concerns/generic_file/versions.rb +16 -0
  31. data/app/models/concerns/curation_concerns/generic_file.rb +5 -0
  32. data/app/models/concerns/curation_concerns/generic_file_behavior.rb +44 -0
  33. data/app/models/concerns/curation_concerns/generic_work_behavior.rb +38 -0
  34. data/app/models/concerns/curation_concerns/has_representative.rb +14 -0
  35. data/app/models/concerns/curation_concerns/human_readable_type.rb +23 -0
  36. data/app/models/concerns/curation_concerns/permissions/readable.rb +19 -0
  37. data/app/models/concerns/curation_concerns/permissions/writable.rb +75 -0
  38. data/app/models/concerns/curation_concerns/permissions.rb +7 -0
  39. data/app/models/concerns/curation_concerns/serializers.rb +15 -0
  40. data/app/models/concerns/curation_concerns/solr_document_behavior.rb +135 -0
  41. data/app/models/concerns/curation_concerns/user.rb +65 -0
  42. data/app/models/concerns/curation_concerns/with_basic_metadata.rb +98 -0
  43. data/app/models/concerns/curation_concerns/with_generic_files.rb +29 -0
  44. data/app/models/curation_concerns/classify_concern.rb +47 -0
  45. data/app/models/curation_concerns/quick_classification_query.rb +31 -0
  46. data/app/models/datastreams/fits_datastream.rb +148 -0
  47. data/app/models/version_committer.rb +2 -0
  48. data/app/services/curation_concerns/characterization_service.rb +71 -0
  49. data/app/services/curation_concerns/full_text_extraction_service.rb +38 -0
  50. data/app/services/curation_concerns/generic_file_audit_service.rb +85 -0
  51. data/app/services/curation_concerns/generic_file_indexing_service.rb +14 -0
  52. data/app/services/curation_concerns/generic_work_indexing_service.rb +16 -0
  53. data/app/services/curation_concerns/noid.rb +23 -0
  54. data/app/services/curation_concerns/repository_audit_service.rb +9 -0
  55. data/app/services/curation_concerns/versioning_service.rb +27 -0
  56. data/config/locales/curation_concerns.en.yml +6 -0
  57. data/curation_concerns-models.gemspec +34 -0
  58. data/lib/curation_concerns/messages.rb +66 -0
  59. data/lib/curation_concerns/models/engine.rb +61 -0
  60. data/lib/curation_concerns/models/resque.rb +36 -0
  61. data/lib/curation_concerns/models/utils.rb +22 -0
  62. data/lib/curation_concerns/models/version.rb +5 -0
  63. data/lib/curation_concerns/models.rb +32 -0
  64. data/lib/generators/curation_concerns/models/abstract_migration_generator.rb +30 -0
  65. data/lib/generators/curation_concerns/models/clamav_generator.rb +19 -0
  66. data/lib/generators/curation_concerns/models/fulltext_generator.rb +28 -0
  67. data/lib/generators/curation_concerns/models/install_generator.rb +70 -0
  68. data/lib/generators/curation_concerns/models/templates/app/models/collection.rb +4 -0
  69. data/lib/generators/curation_concerns/models/templates/app/models/generic_file.rb +4 -0
  70. data/lib/generators/curation_concerns/models/templates/config/clamav.rb +1 -0
  71. data/lib/generators/curation_concerns/models/templates/config/curation_concerns.rb +123 -0
  72. data/lib/generators/curation_concerns/models/templates/config/mime_types.rb +6 -0
  73. data/lib/generators/curation_concerns/models/templates/config/redis.yml +9 -0
  74. data/lib/generators/curation_concerns/models/templates/config/redis_config.rb +32 -0
  75. data/lib/generators/curation_concerns/models/templates/config/resque-pool.yml +1 -0
  76. data/lib/generators/curation_concerns/models/templates/config/resque_admin.rb +10 -0
  77. data/lib/generators/curation_concerns/models/templates/config/resque_config.rb +5 -0
  78. data/lib/generators/curation_concerns/models/templates/migrations/create_checksum_audit_logs.rb +19 -0
  79. data/lib/generators/curation_concerns/models/templates/migrations/create_version_committers.rb +15 -0
  80. data/lib/tasks/curation_concerns-models_tasks.rake +75 -0
  81. data/lib/tasks/migrate.rake +13 -0
  82. data/lib/tasks/resque.rake +13 -0
  83. data/lib/tasks/solr_reindex.rake +8 -0
  84. metadata +282 -0
@@ -0,0 +1,85 @@
1
+ module CurationConcerns
2
+ class GenericFileAuditService
3
+ attr_reader :generic_file
4
+ def initialize(file)
5
+ @generic_file = file
6
+ end
7
+
8
+ NO_RUNS = 999
9
+
10
+ # provides a human readable version of the audit status
11
+ def human_readable_audit_status(stat)
12
+ case stat
13
+ when 0
14
+ 'failing'
15
+ when 1
16
+ 'passing'
17
+ else
18
+ stat
19
+ end
20
+ end
21
+
22
+ # Audits each version of each file if it hasn't been audited recently
23
+ # Returns the set of most recent audit status for each version of the content file
24
+ # @param [Hash] log container for messages, mapping file ids to status
25
+ def audit(log={})
26
+ generic_file.files.each { |f| log[f.id] = audit_file(f) }
27
+ log
28
+ end
29
+
30
+ private
31
+
32
+ # Retrieve or generate the audit check for a file (all versions are checked for versioned files)
33
+ # @param [ActiveFedora::File] file to audit
34
+ # @param [Array] log container for messages
35
+ def audit_file(file, log=[])
36
+ versions = file.has_versions? ? file.versions.all : file
37
+ versions.each { |v| log << audit_file_version(file.id, v.uri) }
38
+ log
39
+ end
40
+
41
+ # Retrieve or generate the audit check for a file and provide a human-readable status message.
42
+ # @param [ActiveFedora::File] file to audit
43
+ def audit_stat(file)
44
+ audit_results = audit_file(file).collect { |result| result["pass"] }
45
+ # check how many non runs we had
46
+ non_runs = audit_results.reduce(0) { |sum, value| value == NO_RUNS ? sum += 1 : sum }
47
+ if non_runs == 0
48
+ audit_results.reduce(true) { |sum, value| sum && value }
49
+ elsif non_runs < audit_results.length
50
+ result = audit_results.reduce(true) { |sum, value| value == NO_RUNS ? sum : sum && value }
51
+ "Some audits have not been run, but the ones run were #{human_readable_audit_status(result)}."
52
+ else
53
+ 'Audits have not yet been run on this file.'
54
+ end
55
+ end
56
+
57
+ # Retrieve or generate the audit check for a specific version of a file
58
+ # @param [String] file_id used to find the file within its parent object (usually "original_file")
59
+ # @param [String] version_uri the version to be audited (or the file uri for non-versioned files)
60
+ def audit_file_version(file_id, version_uri)
61
+ latest_audit = ChecksumAuditLog.logs_for(generic_file.id, file_id).first
62
+ return latest_audit unless needs_audit?(latest_audit)
63
+ CurationConcerns.queue.push(AuditJob.new(generic_file.id, file_id, version_uri))
64
+ latest_audit || ChecksumAuditLog.new(pass: NO_RUNS, generic_file_id: generic_file.id, file_id: file_id, version: version_uri)
65
+ end
66
+
67
+ # Check if time since the last audit is greater than the maximum days allowed between audits
68
+ # @param [ChecksumAuditLog] latest_audit the most recent audit event
69
+ def needs_audit?(latest_audit)
70
+ return true unless latest_audit
71
+ unless latest_audit.updated_at
72
+ logger.warn "***AUDIT*** problem with audit log! Latest Audit is not nil, but updated_at is not set #{latest_audit}"
73
+ return true
74
+ end
75
+ days_since_last_audit(latest_audit) >= CurationConcerns.config.max_days_between_audits
76
+ end
77
+
78
+ # Return the number of days since the latest audit event
79
+ # @param [ChecksumAuditLog] latest_audit the most recent audit event
80
+ def days_since_last_audit(latest_audit)
81
+ (DateTime.now - latest_audit.updated_at.to_date).to_i
82
+ end
83
+
84
+ end
85
+ end
@@ -0,0 +1,14 @@
1
+ module CurationConcerns
2
+ class GenericFileIndexingService < ActiveFedora::IndexingService
3
+ def generate_solr_document
4
+ super.tap do |solr_doc|
5
+ solr_doc[Solrizer.solr_name('label')] = object.label
6
+ solr_doc[Solrizer.solr_name('file_format')] = object.file_format
7
+ solr_doc[Solrizer.solr_name('file_format', :facetable)] = object.file_format
8
+ solr_doc[Solrizer.solr_name(:file_size, :symbol)] = object.file_size[0]
9
+ solr_doc['all_text_timv'] = object.full_text.content
10
+ solr_doc[Solrizer.solr_name('generic_work_ids', :symbol)] = object.generic_work_ids unless object.generic_work_ids.empty?
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ module CurationConcerns
2
+ class GenericWorkIndexingService < ActiveFedora::IndexingService
3
+
4
+ def generate_solr_document
5
+ super.tap do |solr_doc|
6
+ # We know that all the members of GenericWorks are GenericFiles so we can use
7
+ # member_ids which requires fewer Fedora API calls than generic_file_ids.
8
+ # generic_file_ids requires loading all the members from Fedora but member_ids
9
+ # looks just at solr
10
+ solr_doc[Solrizer.solr_name('generic_file_ids', :symbol)] = object.member_ids
11
+ Solrizer.set_field(solr_doc, 'generic_type', 'Work', :facetable)
12
+ end
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,23 @@
1
+ require 'active_fedora/noid'
2
+
3
+ module CurationConcerns
4
+ module Noid
5
+ extend ActiveSupport::Concern
6
+
7
+ ## This overrides the default behavior, which is to ask Fedora for an id
8
+ # @see ActiveFedora::Persistence.assign_id
9
+ def assign_id
10
+ service.mint if CurationConcerns.config.enable_noids
11
+ end
12
+
13
+ def to_param
14
+ id
15
+ end
16
+
17
+ private
18
+
19
+ def service
20
+ @service ||= ActiveFedora::Noid::Service.new
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,9 @@
1
+ module CurationConcerns
2
+ class RepositoryAuditService
3
+ def self.audit_everything
4
+ ::GenericFile.find_each do |gf|
5
+ gf.audit
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ module CurationConcerns
2
+ class VersioningService
3
+ # Make a version and record the version committer
4
+ # @param [ActiveFedora::File] content
5
+ # @param [User] user
6
+ def self.create(content, user=nil)
7
+ content.create_version
8
+ record_committer(content, user) if user
9
+ end
10
+
11
+ # @param [ActiveFedora::File] file
12
+ def self.latest_version_of(file)
13
+ file.versions.last
14
+ end
15
+
16
+ protected
17
+
18
+ # Record the version committer of the last version
19
+ # @param [ActiveFedora::File] content
20
+ # @param [User] user
21
+ def self.record_committer(content, user)
22
+ version = latest_version_of(content)
23
+ return if version.nil?
24
+ VersionCommitter.create(version_id: version.uri, committer_login: user.user_key)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,6 @@
1
+ en:
2
+ curation_concerns:
3
+ product_name: "CurationConcerns"
4
+ product_twitter_handle: "@HydraSphere"
5
+ institution_name: "Institution Name"
6
+ institution_name_full: "The Institution Name"
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ version = File.read(File.expand_path("../../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 = "curation_concerns-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 'active_attr'
23
+ spec.add_dependency 'nest', '~> 1.1'
24
+ spec.add_dependency 'hydra-collections', '~> 6.0.0.alpha'
25
+ spec.add_dependency 'hydra-head', '~> 9.2.2'
26
+ spec.add_dependency 'hydra-works', '~> 0.1'
27
+ spec.add_dependency 'active-fedora', '~> 9.3.0'
28
+ spec.add_dependency 'active_fedora-noid', '~> 1.0.2'
29
+ spec.add_dependency 'resque', '~> 1.23'
30
+ spec.add_dependency 'resque-pool', '~> 0.3'
31
+
32
+ spec.add_development_dependency 'bundler', '~> 1.6'
33
+ spec.add_development_dependency 'rake'
34
+ end
@@ -0,0 +1,66 @@
1
+ module CurationConcerns
2
+ module Messages
3
+ extend ActiveSupport::Concern
4
+
5
+ # Borrowed from AbstractController so we can render html content tags
6
+ attr_accessor :output_buffer
7
+ include ActionView::Helpers::TagHelper
8
+ include ActionView::Helpers::UrlHelper
9
+
10
+ def success_subject
11
+ I18n.t("curation_concerns.messages.success.subject")
12
+ end
13
+
14
+ def failure_subject
15
+ I18n.t("curation_concerns.messages.failure.subject")
16
+ end
17
+
18
+ def single_success id, file
19
+ content_tag :span, id: "ss-"+id do
20
+ [link_to_file(file), I18n.t("curation_concerns.messages.success.single")].join(" ").html_safe
21
+ end
22
+ end
23
+
24
+ def multiple_success id, files
25
+ content_tag :span, id: "ss-"+id do
26
+ [success_link(files), I18n.t("curation_concerns.messages.success.multiple.tag")].join(" ").html_safe
27
+ end
28
+ end
29
+
30
+ def single_failure id, file
31
+ content_tag :span, id: "ss-"+id do
32
+ [link_to_file(file), I18n.t("curation_concerns.messages.failure.single")].join(" ").html_safe
33
+ end
34
+ end
35
+
36
+ def multiple_failure id, files
37
+ content_tag :span, id: "ss-"+id do
38
+ [failure_link(files), I18n.t("curation_concerns.messages.failure.multiple.tag")].join(" ").html_safe
39
+ end
40
+ end
41
+
42
+ # Double-quotes are replaced with single ones so this list can be included in a data block. Ex:
43
+ # <a href="#" data-content="<a href='#'>embedded link</a>" rel="popover">Click me</a>
44
+ def file_list files
45
+ files.map { |gf| link_to_file(gf) }.join(', ').gsub(/"/, "'")
46
+ end
47
+
48
+ def link_to_file file
49
+ link_to(file.to_s, Rails.application.class.routes.url_helpers.curation_concerns_generic_file_path(file))
50
+ end
51
+
52
+ private
53
+
54
+ def success_link files
55
+ link_to I18n.t("curation_concerns.messages.success.multiple.link"), "#",
56
+ rel: "popover",
57
+ data: { content: file_list(files).html_safe, title: I18n.t("curation_concerns.messages.success.title") }
58
+ end
59
+
60
+ def failure_link files
61
+ link_to I18n.t("curation_concerns.messages.failure.multiple.link"), "#",
62
+ rel: "popover",
63
+ data: { content: file_list(files).html_safe, title: I18n.t("curation_concerns.messages.failure.title") }
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,61 @@
1
+ module CurationConcerns
2
+ module Models
3
+
4
+ def self.config(&block)
5
+ @@config ||= Engine::Configuration.new
6
+ yield @@config if block
7
+ return @@config
8
+ end
9
+
10
+
11
+ class Engine < ::Rails::Engine
12
+
13
+ require 'curation_concerns/models/resque'
14
+
15
+ # Set some configuration defaults
16
+ config.persistent_hostpath = "http://localhost/files/"
17
+ config.enable_ffmpeg = false
18
+ config.ffmpeg_path = 'ffmpeg'
19
+ config.fits_message_length = 5
20
+ config.temp_file_base = nil
21
+ config.enable_noids = true
22
+ config.noid_template = '.reeddeeddk'
23
+ config.minter_statefile = '/tmp/minter-state'
24
+ config.redis_namespace = "curation_concerns"
25
+ config.fits_path = "fits.sh"
26
+ config.enable_local_ingest = nil
27
+ config.queue = CurationConcerns::Resque::Queue
28
+
29
+ # Defaulting analytic start date to whenever the file was uploaded by leaving it blank
30
+ config.analytic_start_date = nil
31
+
32
+ config.autoload_paths += %W(
33
+ #{config.root}/app/actors/concerns
34
+ #{config.root}/lib/curation_concerns
35
+ #{config.root}/app/models/datastreams
36
+ )
37
+
38
+ initializer 'requires' do
39
+ require 'active_fedora/noid'
40
+ require 'curation_concerns/noid'
41
+ require 'curation_concerns/permissions'
42
+ end
43
+
44
+ initializer 'configure' do
45
+ CurationConcerns.config.tap do |c|
46
+ Hydra::Derivatives.ffmpeg_path = c.ffmpeg_path
47
+ Hydra::Derivatives.temp_file_base = c.temp_file_base
48
+ Hydra::Derivatives.fits_path = c.fits_path
49
+ Hydra::Derivatives.enable_ffmpeg = c.enable_ffmpeg
50
+
51
+ ActiveFedora::Base.translate_uri_to_id = ActiveFedora::Noid.config.translate_uri_to_id
52
+ ActiveFedora::Base.translate_id_to_uri = ActiveFedora::Noid.config.translate_id_to_uri
53
+ ActiveFedora::Noid.config.template = c.noid_template
54
+ ActiveFedora::Noid.config.statefile = c.minter_statefile
55
+ end
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,36 @@
1
+ # Borrowed from:
2
+ # https://github.com/jeremy/resque-rails/blob/master/lib/resque/rails/queue.rb
3
+ module CurationConcerns
4
+ module Resque
5
+ class Queue
6
+ attr_reader :default_queue_name
7
+
8
+ def initialize(default_queue_name)
9
+ @default_queue_name = default_queue_name
10
+ end
11
+
12
+ def push(job)
13
+ push_tries = 0
14
+ queue = job.respond_to?(:queue_name) ? job.queue_name : default_queue_name
15
+ begin
16
+ ::Resque.enqueue_to queue, MarshaledJob, Base64.encode64(Marshal.dump(job))
17
+ rescue Redis::CannotConnectError
18
+ ActiveFedora::Base.logger.error "Redis is down!"
19
+ rescue Redis::TimeoutError => error
20
+ ActiveFedora::Base.logger.warn "Redis Timed out. Trying again! #{job.inspect}"
21
+ push_tries+=1
22
+ # fail for good if the tries is greater than 3
23
+ raise error if push_tries >=3
24
+ sleep 0.01
25
+ retry
26
+ end
27
+ end
28
+ end
29
+
30
+ class MarshaledJob
31
+ def self.perform(marshaled_job)
32
+ Marshal.load(Base64.decode64(marshaled_job)).run
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,22 @@
1
+ module CurationConcerns
2
+ module Utils
3
+ extend ActiveSupport::Concern
4
+
5
+ def retry_unless(number_of_tries, condition, &block)
6
+ self.class.retry_unless(number_of_tries, condition, &block)
7
+ end
8
+
9
+ module ClassMethods
10
+ def retry_unless(number_of_tries, condition, &block)
11
+ raise ArgumentError, "First argument must be an enumerator" unless number_of_tries.is_a? Enumerator
12
+ raise ArgumentError, "Second argument must be a lambda" unless condition.respond_to? :call
13
+ raise ArgumentError, "Must pass a block of code to retry" unless block_given?
14
+ number_of_tries.each do
15
+ result = block.call
16
+ return result unless condition.call
17
+ end
18
+ raise RuntimeError, "retry_unless could not complete successfully. Try upping the # of tries?"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,5 @@
1
+ module CurationConcerns
2
+ module Models
3
+ VERSION = "0.1.2"
4
+ end
5
+ end
@@ -0,0 +1,32 @@
1
+ require "curation_concerns/models/version"
2
+ require "curation_concerns/models/engine"
3
+
4
+ require 'hydra/head'
5
+ require 'nest'
6
+ # require "active_resource" # used by GenericFile to catch errors & by GeoNamesResource
7
+ require 'resque/server'
8
+
9
+ module CurationConcerns
10
+ extend ActiveSupport::Autoload
11
+
12
+ module Models
13
+ end
14
+
15
+ autoload :Utils, 'curation_concerns/models/utils'
16
+ autoload :Permissions
17
+ autoload :Messages
18
+
19
+ attr_writer :queue
20
+
21
+ def self.queue
22
+ @queue ||= config.queue.new('curation_concerns')
23
+ end
24
+
25
+ def self.config(&block)
26
+ @@config ||= CurationConcerns::Models::Engine::Configuration.new
27
+
28
+ yield @@config if block
29
+
30
+ return @@config
31
+ end
32
+ end
@@ -0,0 +1,30 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'rails/generators'
3
+ require 'rails/generators/migration'
4
+
5
+ class CurationConcerns::Models::AbstractMigrationGenerator < Rails::Generators::Base
6
+ include Rails::Generators::Migration
7
+
8
+ # Implement the required interface for Rails::Generators::Migration.
9
+ # taken from http://github.com/rails/rails/blob/master/activerecord/lib/generators/active_record.rb
10
+ def self.next_migration_number(path)
11
+ if @prev_migration_nr
12
+ @prev_migration_nr += 1
13
+ else
14
+ if last_migration = Dir[File.join(path, '*.rb')].sort.last
15
+ @prev_migration_nr = last_migration.sub(File.join(path, '/'), '').to_i + 1
16
+ else
17
+ @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
18
+ end
19
+ end
20
+ @prev_migration_nr.to_s
21
+ end
22
+
23
+ protected
24
+
25
+ def better_migration_template(file)
26
+ migration_template "migrations/#{file}", "db/migrate/#{file}"
27
+ rescue Rails::Generators::Error => e
28
+ say_status("warning", e.message, :yellow)
29
+ end
30
+ end
@@ -0,0 +1,19 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'rails/generators'
3
+
4
+ class CurationConcerns::Models::ClamavGenerator < Rails::Generators::Base
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ desc """
8
+ This generator makes the following changes to your application:
9
+ 1. Generates clamav initializer
10
+ """
11
+
12
+ def banner
13
+ say_status("info", "Generating clamav initializers", :blue)
14
+ end
15
+
16
+ def create_initializer_file
17
+ copy_file 'config/clamav.rb', 'config/initializers/clamav.rb'
18
+ end
19
+ end
@@ -0,0 +1,28 @@
1
+ # -*- encoding : utf-8 -*-
2
+ require 'rails/generators'
3
+
4
+ class CurationConcerns::Models::FulltextGenerator < Rails::Generators::Base
5
+ source_root File.expand_path('../templates', __FILE__)
6
+
7
+ desc """
8
+ This generator makes the following changes to your application:
9
+ 1. Copies solrconfig.xml into solr_conf/conf/
10
+ 2. Reconfigures jetty
11
+ """
12
+
13
+ def banner
14
+ say_status("warning", "GENERATING CURATION_CONCERNS FULL-TEXT", :yellow)
15
+ end
16
+
17
+ # Copy CurationConcerns's solrconfig into the dir from which the jetty:config task pulls
18
+ # CurationConcerns's solrconfig includes full-text extraction
19
+ def copy_solr_config
20
+ src = File.join(__FILE__, '..', '..', '..', '..', '..', '..', 'solr_conf', 'conf', 'solrconfig.xml')
21
+ copy_file File.expand_path(src), 'solr_conf/conf/solrconfig.xml', force: true
22
+ end
23
+
24
+ # Copy config, schema, and jars into jetty dir if it exists
25
+ def reconfigure_jetty
26
+ rake "curation_concerns:jetty:config" if File.directory?('jetty')
27
+ end
28
+ end
@@ -0,0 +1,70 @@
1
+ require_relative 'abstract_migration_generator'
2
+
3
+ class CurationConcerns::Models::InstallGenerator < CurationConcerns::Models::AbstractMigrationGenerator
4
+ source_root File.expand_path('../templates', __FILE__)
5
+ argument :model_name, type: :string , default: "user"
6
+ desc """
7
+ This generator makes the following changes to your application:
8
+ 1. Creates several database migrations if they do not exist in /db/migrate
9
+ 2. Creates the curation_concerns.rb configuration file and several others
10
+ 3. Creates the generic_file.rb, generic_work.rb and collection.rb models
11
+ 4. Runs full-text generator
12
+ """
13
+ def banner
14
+ say_status("warning", "GENERATING CURATION_CONCERNS MODELS", :yellow)
15
+ end
16
+
17
+ # Setup the database migrations
18
+ def copy_migrations
19
+ [
20
+ "create_version_committers.rb",
21
+ "create_checksum_audit_logs.rb"#,
22
+ ].each do |file|
23
+ better_migration_template file
24
+ end
25
+ end
26
+
27
+ # Add behaviors to the user model
28
+ def inject_curation_concerns_user_behavior
29
+ file_path = "app/models/#{model_name.underscore}.rb"
30
+ if File.exists?(file_path)
31
+ inject_into_file file_path, after: /include Hydra\:\:User.*$/ do
32
+ "\n # Connects this user object to Curation Concerns behaviors." +
33
+ "\n include CurationConcerns::User\n"
34
+ end
35
+ else
36
+ puts " \e[31mFailure\e[0m CurationConcerns requires a user object. This generators assumes that the model is defined in the file #{file_path}, which does not exist. If you used a different name, please re-run the generator and provide that name as an argument. Such as \b rails -g curation_concerns client"
37
+ end
38
+ end
39
+
40
+ def create_configuration_files
41
+ append_file 'config/initializers/mime_types.rb',
42
+ "\nMime::Type.register 'application/x-endnote-refer', :endnote", {verbose: false }
43
+ copy_file 'config/curation_concerns.rb', 'config/initializers/curation_concerns.rb'
44
+ copy_file 'config/redis.yml', 'config/redis.yml'
45
+ copy_file 'config/resque-pool.yml', 'config/resque-pool.yml'
46
+ copy_file 'config/redis_config.rb', 'config/initializers/redis_config.rb'
47
+ copy_file 'config/resque_admin.rb', 'config/initializers/resque_admin.rb'
48
+ copy_file 'config/resque_config.rb', 'config/initializers/resque_config.rb'
49
+ end
50
+
51
+ def create_collection
52
+ copy_file 'app/models/collection.rb', 'app/models/collection.rb'
53
+ end
54
+
55
+ def create_generic_file
56
+ copy_file 'app/models/generic_file.rb', 'app/models/generic_file.rb'
57
+ end
58
+
59
+ # Sets up full-text indexing (Solr config + jars)
60
+ def full_text_indexing
61
+ generate "curation_concerns:models:fulltext"
62
+ end
63
+
64
+ # Adds clamav initializtion
65
+ def clamav
66
+ generate 'curation_concerns:models:clamav'
67
+ end
68
+
69
+
70
+ end
@@ -0,0 +1,4 @@
1
+ # Generated by curation_concerns:models:install
2
+ class Collection < ActiveFedora::Base
3
+ include ::CurationConcerns::CollectionBehavior
4
+ end
@@ -0,0 +1,4 @@
1
+ # Generated by curation_concerns:models:install
2
+ class GenericFile < ActiveFedora::Base
3
+ include ::CurationConcerns::GenericFileBehavior
4
+ end
@@ -0,0 +1 @@
1
+ ClamAV.instance.loaddb() if defined? ClamAV