curation_concerns-models 0.1.0

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