hyrax 5.1.0.pre.beta1 → 5.2.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.
- checksums.yaml +4 -4
- data/.dassie/.env +4 -0
- data/.dassie/Gemfile +12 -7
- data/.dassie/app/controllers/application_controller.rb +4 -0
- data/.dassie/app/helpers/hyrax_helper.rb +4 -0
- data/.dassie/app/models/ability.rb +4 -0
- data/.dassie/app/models/user.rb +11 -0
- data/.dassie/app/views/shared/_footer.html.erb +17 -0
- data/.dassie/config/application.rb +1 -1
- data/.dassie/config/database.yml +18 -0
- data/.dassie/config/environments/production.rb +1 -1
- data/.dassie/config/fedora.yml +6 -6
- data/.dassie/config/initializers/devise.rb +1 -0
- data/.dassie/config/initializers/profiler.rb +5 -0
- data/.dassie/config/locales/hyrax.en.yml +1 -1
- data/.dassie/config/puma.rb +55 -5
- data/.dassie/config/routes.rb +2 -0
- data/.dassie/db/migrate/20250328100249_user_roles.rb +20 -0
- data/.dassie/db/schema.rb +123 -109
- data/.github/workflows/lint-build-test.yml +34 -5
- data/.koppie/.env +1 -1
- data/.koppie/Gemfile +10 -6
- data/.koppie/app/controllers/application_controller.rb +4 -0
- data/.koppie/app/helpers/hyrax_helper.rb +4 -0
- data/.koppie/app/models/ability.rb +4 -0
- data/.koppie/app/models/user.rb +10 -0
- data/.koppie/app/views/shared/_footer.html.erb +17 -0
- data/.koppie/config/database.yml +2 -9
- data/.koppie/config/environments/development.rb +9 -0
- data/.koppie/config/environments/production.rb +1 -1
- data/.koppie/config/initializers/1_valkyrie.rb +5 -5
- data/.koppie/config/initializers/devise.rb +1 -1
- data/.koppie/config/initializers/profiler.rb +5 -0
- data/.koppie/config/locales/hyrax.en.yml +2 -2
- data/.koppie/config/puma.rb +26 -7
- data/.koppie/config/routes.rb +2 -0
- data/.koppie/db/schema.rb +109 -110
- data/CONTAINERS.md +10 -10
- data/Dockerfile +108 -50
- data/Gemfile +2 -1
- data/app/controllers/concerns/hyrax/valkyrie_downloads_controller_behavior.rb +1 -0
- data/app/controllers/concerns/hyrax/works_controller_behavior.rb +2 -1
- data/app/controllers/hyrax/admin/analytics/work_reports_controller.rb +4 -4
- data/app/controllers/hyrax/file_sets_controller.rb +11 -0
- data/app/helpers/hyrax/hyrax_helper_behavior.rb +2 -2
- data/app/helpers/hyrax/trophy_helper.rb +1 -1
- data/app/jobs/concerns/hyrax/queued_job_behavior.rb +22 -0
- data/app/jobs/hyrax/propagate_change_depositor_job.rb +1 -1
- data/app/jobs/hyrax/queued_delete_job.rb +11 -0
- data/app/jobs/hyrax/queued_indexing_job.rb +11 -0
- data/app/jobs/migrate_files_to_valkyrie_job.rb +33 -21
- data/app/jobs/migrate_sipity_entity_job.rb +21 -0
- data/app/models/concerns/hyrax/ability.rb +4 -2
- data/app/models/concerns/hyrax/solr_document_behavior.rb +5 -2
- data/app/models/hyrax/file_metadata.rb +22 -7
- data/app/services/hyrax/analytics/ga4/base.rb +1 -1
- data/app/services/hyrax/analytics/ga4.rb +5 -1
- data/app/services/hyrax/change_depositor_service.rb +1 -1
- data/app/services/hyrax/characterization/valkyrie_characterization_service.rb +21 -13
- data/app/services/hyrax/custom_queries/find_ids_by_model.rb +31 -6
- data/app/services/hyrax/edit_permissions_service.rb +9 -8
- data/app/services/hyrax/workflow/workflow_factory.rb +3 -3
- data/app/services/migrate_resource_service.rb +1 -1
- data/app/views/_user_util_links.html.erb +2 -1
- data/app/views/hyrax/admin/analytics/collection_reports/_top_collections.html.erb +3 -7
- data/app/views/hyrax/admin/analytics/work_reports/_top_file_set_downloads.html.erb +3 -6
- data/app/views/hyrax/admin/analytics/work_reports/_top_works.html.erb +2 -3
- data/app/views/hyrax/admin/analytics/work_reports/_work_files.html.erb +1 -6
- data/app/views/hyrax/base/_social_media.html.erb +2 -0
- data/app/views/hyrax/base/iiif_viewers/_universal_viewer.html.erb +1 -1
- data/app/views/hyrax/dashboard/collections/_show_document_list_menu.html.erb +13 -12
- data/app/views/hyrax/my/_admin_set_action_menu.html.erb +31 -27
- data/app/views/hyrax/my/_collection_action_menu.html.erb +40 -35
- data/app/views/hyrax/my/_work_action_menu.html.erb +23 -22
- data/bin/db-migrate-seed.sh +1 -1
- data/bin/dev-entrypoint.sh +3 -0
- data/config/features.rb +50 -40
- data/config/initializers/indexing_adapter_initializer.rb +4 -0
- data/config/initializers/new_framework_defaults_7_2.rb +6 -4
- data/config/initializers/reform_rails_6_1_monkey_patch.rb +29 -0
- data/config/metadata/core_metadata.yaml +1 -0
- data/docker-compose-dassie.yml +6 -6
- data/docker-compose-koppie.yml +2 -2
- data/docker-compose-sirenia.yml +2 -2
- data/documentation/developing-your-hyrax-based-app.md +2 -2
- data/hyrax.gemspec +3 -3
- data/lib/freyja/persister.rb +11 -4
- data/lib/generators/hyrax/install_generator.rb +0 -5
- data/lib/generators/hyrax/templates/.env +1 -1
- data/lib/generators/hyrax/templates/config/initializers/1_valkyrie.rb +21 -19
- data/lib/generators/hyrax/templates/db/migrate/20170131142607_add_permission_template_to_sipity_workflow.rb.erb +1 -1
- data/lib/generators/hyrax/templates/db/migrate/20170810190549_update_collection_type_column_options.rb.erb +1 -1
- data/lib/generators/hyrax/templates/db/migrate/20230821153635_add_fields_to_counter_metric.rb.erb +1 -1
- data/lib/hyrax/configuration.rb +22 -7
- data/lib/hyrax/controlled_vocabulary/importer/language.rb +5 -1
- data/lib/hyrax/transactions/steps/add_file_sets.rb +2 -1
- data/lib/hyrax/version.rb +1 -1
- data/lib/hyrax.rb +1 -0
- data/lib/tasks/workflow.rake +1 -2
- data/lib/valkyrie/indexing/redis_queue/indexing_adapter.rb +144 -0
- data/lib/wings/valkyrie/query_service.rb +3 -4
- data/template.rb +1 -1
- metadata +28 -14
- data/.github/workflows/main.yml +0 -17
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
return if Rails::VERSION::MAJOR >= 7
|
4
|
+
|
5
|
+
# Taken from https://github.com/trailblazer/reform-rails/issues/86#issuecomment-763120151
|
6
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
7
|
+
# rubocop:disable Lint/UselessAssignment
|
8
|
+
module Reform
|
9
|
+
class Contract < Disposable::Twin
|
10
|
+
class Result
|
11
|
+
private
|
12
|
+
|
13
|
+
# this doesn't do nested errors (e.g. )
|
14
|
+
def filter_for(method, *args)
|
15
|
+
@results.collect { |r| r.public_send(method, *args).to_h }
|
16
|
+
.inject({}) { |hah, err| hah.merge(err) { |_key, old_v, new_v| (new_v.is_a?(Array) ? (old_v |= new_v) : old_v.merge(new_v)) } }
|
17
|
+
.find_all do |_k, v| # filter :nested=>{:something=>["too nested!"]} #DISCUSS: do we want that here?
|
18
|
+
if v.is_a?(Hash)
|
19
|
+
nested_errors = v.select { |attr_key, val| attr_key.is_a?(Integer) && val.is_a?(Array) && val.any? }
|
20
|
+
v = nested_errors.to_a if nested_errors.any?
|
21
|
+
end
|
22
|
+
v.is_a?(ActiveModel::DeprecationHandlingMessageArray)
|
23
|
+
end.to_h
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
29
|
+
# rubocop:disable Lint/UselessAssignment
|
data/docker-compose-dassie.yml
CHANGED
@@ -6,7 +6,7 @@ services:
|
|
6
6
|
args:
|
7
7
|
- EXTRA_APK_PACKAGES=git less
|
8
8
|
- BUNDLE_GEMFILE=Gemfile.dassie
|
9
|
-
image: samvera/hyrax-dev
|
9
|
+
image: ghcr.io/samvera/hyrax-dev:${GITHUB_SHA:-latest}
|
10
10
|
command: sh -c 'bundle exec puma -v -b tcp://0.0.0.0:3000'
|
11
11
|
stdin_open: true
|
12
12
|
tty: true
|
@@ -40,7 +40,7 @@ services:
|
|
40
40
|
- hyrax
|
41
41
|
|
42
42
|
worker:
|
43
|
-
image: samvera/hyrax-dev
|
43
|
+
image: ghcr.io/samvera/hyrax-dev:${GITHUB_SHA:-latest}
|
44
44
|
entrypoint: worker-entrypoint.sh
|
45
45
|
command: sh -c 'bundle exec sidekiq'
|
46
46
|
user: root
|
@@ -68,14 +68,14 @@ services:
|
|
68
68
|
chrome:
|
69
69
|
image: selenium/standalone-chromium:4
|
70
70
|
environment:
|
71
|
-
# - START_XVFB=false
|
71
|
+
# - START_XVFB=false
|
72
72
|
- SE_NODE_SESSION_TIMEOUT=800
|
73
73
|
- SE_ENABLE_TRACING=false
|
74
74
|
- SE_ENABLE_BROWSER_LEFTOVERS_CLEANUP=true
|
75
75
|
- SE_BROWSER_ARGS_DISABLE_DSHM=--disable-dev-shm-usage
|
76
76
|
- SE_BROWSER_ARGS_HEADLESS=--headless=new
|
77
|
-
# logging:
|
78
|
-
# driver: none
|
77
|
+
# logging:
|
78
|
+
# driver: none
|
79
79
|
volumes:
|
80
80
|
- /dev/shm:/dev/shm
|
81
81
|
shm_size: 2g
|
@@ -118,7 +118,7 @@ services:
|
|
118
118
|
memcached:
|
119
119
|
image: bitnami/memcached
|
120
120
|
ports:
|
121
|
-
-
|
121
|
+
- "11211:11211"
|
122
122
|
networks:
|
123
123
|
- hyrax
|
124
124
|
|
data/docker-compose-koppie.yml
CHANGED
@@ -8,7 +8,7 @@ services:
|
|
8
8
|
args:
|
9
9
|
- EXTRA_APK_PACKAGES=git less
|
10
10
|
- BUNDLE_GEMFILE=Gemfile.koppie
|
11
|
-
image: samvera/hyrax-dev
|
11
|
+
image: ghcr.io/samvera/hyrax-dev:${GITHUB_SHA:-latest}
|
12
12
|
command: sh -c 'bundle exec puma -v -b tcp://0.0.0.0:3000'
|
13
13
|
stdin_open: true
|
14
14
|
tty: true
|
@@ -43,7 +43,7 @@ services:
|
|
43
43
|
- koppie
|
44
44
|
|
45
45
|
worker:
|
46
|
-
image: samvera/hyrax-dev
|
46
|
+
image: ghcr.io/samvera/hyrax-dev:${GITHUB_SHA:-latest}
|
47
47
|
entrypoint: worker-entrypoint.sh
|
48
48
|
command: sh -c 'bundle exec sidekiq'
|
49
49
|
user: root
|
data/docker-compose-sirenia.yml
CHANGED
@@ -8,7 +8,7 @@ services:
|
|
8
8
|
args:
|
9
9
|
- EXTRA_APK_PACKAGES=git less
|
10
10
|
- BUNDLE_GEMFILE=Gemfile.koppie
|
11
|
-
image: samvera/hyrax-dev
|
11
|
+
image: ghcr.io/samvera/hyrax-dev:${GITHUB_SHA:-latest}
|
12
12
|
command: sh -c 'bundle exec puma -v -b tcp://0.0.0.0:3000'
|
13
13
|
stdin_open: true
|
14
14
|
tty: true
|
@@ -46,7 +46,7 @@ services:
|
|
46
46
|
- sirenia
|
47
47
|
|
48
48
|
worker:
|
49
|
-
image: samvera/hyrax-dev
|
49
|
+
image: ghcr.io/samvera/hyrax-dev:${GITHUB_SHA:-latest}
|
50
50
|
entrypoint: worker-entrypoint.sh
|
51
51
|
command: sh -c 'bundle exec sidekiq'
|
52
52
|
user: root
|
@@ -32,7 +32,7 @@ You can also try [Running Hyrax-based application in local VM](https://github.co
|
|
32
32
|
During development, running only the dependent services in a container environment may be beneficial. This avoids potential headaches concerning file permissions and eases the use of debugging tools. The application generation instructions below use [Lando](https://lando.dev) to achieve this setup.
|
33
33
|
|
34
34
|
This document contains instructions specific to setting up an app with __Hyrax
|
35
|
-
v5.
|
35
|
+
v5.2.0__. If you are looking for instructions on installing a different
|
36
36
|
version, be sure to select the appropriate branch or tag from the drop-down
|
37
37
|
menu above.
|
38
38
|
|
@@ -148,7 +148,7 @@ Generate a new Rails application using the template.
|
|
148
148
|
**NOTE:** `HYRAX_SKIP_WINGS` is needed here to avoid loading the Wings compatibility layer during the application generation process.
|
149
149
|
|
150
150
|
```shell
|
151
|
-
HYRAX_SKIP_WINGS=true rails _7.2.2.1_ new my_app --database=postgresql -m https://raw.githubusercontent.com/samvera/hyrax/hyrax-v5.
|
151
|
+
HYRAX_SKIP_WINGS=true rails _7.2.2.1_ new my_app --database=postgresql -m https://raw.githubusercontent.com/samvera/hyrax/hyrax-v5.2.0/template.rb
|
152
152
|
```
|
153
153
|
|
154
154
|
Generating a new Rails application using Hyrax's template above takes cares of a number of steps for you, including:
|
data/hyrax.gemspec
CHANGED
@@ -32,13 +32,13 @@ SUMMARY
|
|
32
32
|
# NOTE: rails does not follow sem-ver conventions, it's
|
33
33
|
# minor version releases can include breaking changes; see
|
34
34
|
# http://guides.rubyonrails.org/maintenance_policy.html
|
35
|
-
spec.add_dependency 'rails', '
|
35
|
+
spec.add_dependency 'rails', '> 6.1', '< 8.0'
|
36
36
|
|
37
37
|
spec.add_dependency 'active-fedora', '~> 15.0'
|
38
38
|
spec.add_dependency 'almond-rails', '~> 0.1'
|
39
39
|
spec.add_dependency 'awesome_nested_set', '~> 3.1'
|
40
40
|
spec.add_dependency 'blacklight', '~> 7.29'
|
41
|
-
spec.add_dependency 'blacklight-gallery', '~> 4.
|
41
|
+
spec.add_dependency 'blacklight-gallery', '~> 4.6.4'
|
42
42
|
spec.add_dependency 'breadcrumbs_on_rails', '~> 3.0'
|
43
43
|
spec.add_dependency 'browse-everything', '>= 0.16', '< 2.0'
|
44
44
|
spec.add_dependency 'carrierwave', '~> 1.0'
|
@@ -100,7 +100,7 @@ SUMMARY
|
|
100
100
|
spec.add_development_dependency 'pg', '~> 1.2'
|
101
101
|
spec.add_development_dependency 'rspec-activemodel-mocks', '~> 1.0'
|
102
102
|
spec.add_development_dependency 'rspec-its', '~> 1.1'
|
103
|
-
spec.add_development_dependency 'rspec-rails', '
|
103
|
+
spec.add_development_dependency 'rspec-rails', '> 6.1'
|
104
104
|
spec.add_development_dependency 'rspec_junit_formatter'
|
105
105
|
spec.add_development_dependency "selenium-webdriver", '~> 4.4'
|
106
106
|
spec.add_development_dependency 'i18n-debug'
|
data/lib/freyja/persister.rb
CHANGED
@@ -13,6 +13,7 @@ module Freyja
|
|
13
13
|
# was modified in the database between been read into memory and persisted
|
14
14
|
# rubocop:disable Lint/UnusedMethodArgument
|
15
15
|
def save(resource:, external_resource: false, perform_af_validation: false)
|
16
|
+
was_wings = resource.respond_to?(:wings?) && resource.wings?
|
16
17
|
orm_object = resource_factory.from_resource(resource: resource)
|
17
18
|
orm_object.transaction do
|
18
19
|
orm_object.save!
|
@@ -23,18 +24,24 @@ module Freyja
|
|
23
24
|
"Called from #{Gem.location_of_caller.join(':')}"
|
24
25
|
end
|
25
26
|
end
|
26
|
-
convert_and_migrate_resource(orm_object)
|
27
|
+
convert_and_migrate_resource(orm_object, was_wings)
|
27
28
|
|
28
29
|
rescue ActiveRecord::StaleObjectError
|
29
30
|
raise Valkyrie::Persistence::StaleObjectError, "The object #{resource.id} has been updated by another process."
|
30
31
|
end
|
31
32
|
# rubocop:enable Lint/UnusedMethodArgument
|
32
33
|
|
33
|
-
def convert_and_migrate_resource(orm_object)
|
34
|
+
def convert_and_migrate_resource(orm_object, was_wings)
|
34
35
|
new_resource = resource_factory.to_resource(object: orm_object)
|
35
|
-
if
|
36
|
+
# if the resource was wings and is now a Valkyrie resource, we need to migrate sipity, files, and members
|
37
|
+
if Hyrax.config.valkyrie_transition? && was_wings && !new_resource.wings?
|
36
38
|
MigrateFilesToValkyrieJob.perform_later(new_resource) if new_resource.is_a?(Hyrax::FileSet) && new_resource.file_ids.size == 1 && new_resource.file_ids.first.id.to_s.match('/files/')
|
37
|
-
|
39
|
+
# migrate any members if the resource is a Hyrax work
|
40
|
+
if new_resource.is_a?(Hyrax::Work)
|
41
|
+
member_ids = new_resource.member_ids.map(&:to_s)
|
42
|
+
MigrateResourcesJob.perform_later(ids: member_ids) unless member_ids.empty?
|
43
|
+
MigrateSipityEntityJob.perform_now(id: new_resource.id.to_s)
|
44
|
+
end
|
38
45
|
end
|
39
46
|
new_resource
|
40
47
|
end
|
@@ -209,10 +209,5 @@ module Hyrax
|
|
209
209
|
gem 'dotenv-rails', '~> 2.8'
|
210
210
|
end
|
211
211
|
end
|
212
|
-
|
213
|
-
def support_analytics
|
214
|
-
gem 'google-protobuf', force_ruby_platform: true # required because google-protobuf is not compatible with Alpine linux
|
215
|
-
gem 'grpc', force_ruby_platform: true # required because grpc is not compatible with Alpine linux
|
216
|
-
end
|
217
212
|
end
|
218
213
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
CH12N_TOOL=fits_servlet
|
2
2
|
DATABASE_URL=postgresql://postgres@localhost:5437/hyrax-dev?pool=5
|
3
|
-
|
3
|
+
FEDORA_URL=http://fedoraAdmin:fedoraAdmin@localhost:8989/fcrepo/rest
|
4
4
|
FITS_SERVLET_URL=http://localhost:8085/fits
|
5
5
|
HYRAX_ACTIVE_JOB_QUEUE=async
|
6
6
|
REDIS_URL=redis://localhost:6384
|
@@ -32,7 +32,7 @@ Valkyrie::MetadataAdapter.register(
|
|
32
32
|
# Valkyrie::MetadataAdapter.register(
|
33
33
|
# Valkyrie::Persistence::Fedora::MetadataAdapter.new(
|
34
34
|
# connection: ::Ldp::Client.new(Hyrax.config.fedora_connection_builder.call(
|
35
|
-
# ENV.fetch('
|
35
|
+
# ENV.fetch('FEDORA_URL') { "http://localhost:8080/fcrepo/rest" }
|
36
36
|
# )),
|
37
37
|
# base_path: Rails.env,
|
38
38
|
# schema: Valkyrie::Persistence::Fedora::PermissiveSchema.new(Hyrax::SimpleSchemaLoader.new.permissive_schema_for_valkrie_adapter),
|
@@ -67,7 +67,7 @@ Valkyrie.config.metadata_adapter = ENV.fetch('VALKYRIE_METADATA_ADAPTER') { :pg_
|
|
67
67
|
# Valkyrie::StorageAdapter.register(
|
68
68
|
# Valkyrie::Storage::Fedora.new(
|
69
69
|
# connection: ::Ldp::Client.new(Hyrax.config.fedora_connection_builder.call(
|
70
|
-
# ENV.fetch('
|
70
|
+
# ENV.fetch('FEDORA_URL') { "http://localhost:8080/fcrepo/rest" }
|
71
71
|
# )),
|
72
72
|
# base_path: Rails.env,
|
73
73
|
# fedora_version: 6.5,
|
@@ -86,21 +86,23 @@ Valkyrie.config.storage_adapter = ENV.fetch('VALKYRIE_STORAGE_ADAPTER') { :vers
|
|
86
86
|
|
87
87
|
Valkyrie.config.indexing_adapter = :solr_index
|
88
88
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
89
|
+
Rails.application.reloader.to_prepare do
|
90
|
+
custom_queries = [Hyrax::CustomQueries::Navigators::CollectionMembers,
|
91
|
+
Hyrax::CustomQueries::Navigators::ChildCollectionsNavigator,
|
92
|
+
Hyrax::CustomQueries::Navigators::ParentCollectionsNavigator,
|
93
|
+
Hyrax::CustomQueries::Navigators::ChildFileSetsNavigator,
|
94
|
+
Hyrax::CustomQueries::Navigators::ChildWorksNavigator,
|
95
|
+
Hyrax::CustomQueries::Navigators::ParentWorkNavigator,
|
96
|
+
Hyrax::CustomQueries::Navigators::FindFiles,
|
97
|
+
Hyrax::CustomQueries::FindAccessControl,
|
98
|
+
Hyrax::CustomQueries::FindCollectionsByType,
|
99
|
+
Hyrax::CustomQueries::FindFileMetadata,
|
100
|
+
Hyrax::CustomQueries::FindIdsByModel,
|
101
|
+
Hyrax::CustomQueries::FindManyByAlternateIds,
|
102
|
+
Hyrax::CustomQueries::FindModelsByAccess,
|
103
|
+
Hyrax::CustomQueries::FindCountBy,
|
104
|
+
Hyrax::CustomQueries::FindByDateRange]
|
105
|
+
custom_queries.each do |handler|
|
106
|
+
Hyrax.query_service.custom_queries.register_query_handler(handler)
|
107
|
+
end
|
106
108
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class AddPermissionTemplateToSipityWorkflow < ActiveRecord::Migration
|
1
|
+
class AddPermissionTemplateToSipityWorkflow < ActiveRecord::Migration[6.1]
|
2
2
|
def change
|
3
3
|
add_column :sipity_workflows, :permission_template_id, :integer, index: true
|
4
4
|
remove_index :sipity_workflows, :name
|
@@ -1,4 +1,4 @@
|
|
1
|
-
class UpdateCollectionTypeColumnOptions < ActiveRecord::Migration
|
1
|
+
class UpdateCollectionTypeColumnOptions < ActiveRecord::Migration[6.1]
|
2
2
|
def up
|
3
3
|
change_column :hyrax_collection_types, :title, :string, unique: true
|
4
4
|
change_column :hyrax_collection_types, :machine_id, :string, unique: true
|
data/lib/generators/hyrax/templates/db/migrate/20230821153635_add_fields_to_counter_metric.rb.erb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
class AddFieldsToCounterMetric < ActiveRecord::Migration
|
1
|
+
class AddFieldsToCounterMetric < ActiveRecord::Migration[6.1]
|
2
2
|
def change
|
3
3
|
add_column :hyrax_counter_metrics, :title, :string
|
4
4
|
add_column :hyrax_counter_metrics, :year_of_publication, :integer, index: true
|
data/lib/hyrax/configuration.rb
CHANGED
@@ -133,8 +133,23 @@ module Hyrax
|
|
133
133
|
attr_writer :analytics_reporting
|
134
134
|
attr_reader :analytics_reporting
|
135
135
|
def analytics_reporting?
|
136
|
-
@analytics_reporting ||=
|
136
|
+
@analytics_reporting ||= begin
|
137
|
+
required_env_vars = %w[
|
138
|
+
HYRAX_ANALYTICS_REPORTING
|
139
|
+
GOOGLE_ANALYTICS_ID
|
140
|
+
GOOGLE_ANALYTICS_PROPERTY_ID
|
141
|
+
]
|
142
|
+
|
143
|
+
required_env_vars << if ENV['GOOGLE_ACCOUNT_JSON'].blank?
|
144
|
+
'GOOGLE_ACCOUNT_JSON_PATH'
|
145
|
+
else
|
146
|
+
'GOOGLE_ACCOUNT_JSON'
|
147
|
+
end
|
148
|
+
|
149
|
+
return false if required_env_vars.any? { |var| ENV.fetch(var, '').blank? }
|
150
|
+
|
137
151
|
ActiveModel::Type::Boolean.new.cast(ENV.fetch('HYRAX_ANALYTICS_REPORTING', false))
|
152
|
+
end
|
138
153
|
end
|
139
154
|
|
140
155
|
# Currently supports 'google' or 'matomo'
|
@@ -142,7 +157,7 @@ module Hyrax
|
|
142
157
|
attr_writer :analytics_provider
|
143
158
|
def analytics_provider
|
144
159
|
@analytics_provider ||=
|
145
|
-
ENV.fetch('HYRAX_ANALYTICS_PROVIDER', '
|
160
|
+
ENV.fetch('HYRAX_ANALYTICS_PROVIDER', 'ga4')
|
146
161
|
end
|
147
162
|
|
148
163
|
##
|
@@ -478,31 +493,31 @@ module Hyrax
|
|
478
493
|
# Path on the local file system where derivatives will be stored
|
479
494
|
attr_writer :derivatives_path
|
480
495
|
def derivatives_path
|
481
|
-
@derivatives_path ||= ENV.fetch('HYRAX_DERIVATIVES_PATH', Rails.root.join('tmp', 'derivatives'))
|
496
|
+
@derivatives_path ||= Pathname.new(ENV.fetch('HYRAX_DERIVATIVES_PATH', Rails.root.join('tmp', 'derivatives')))
|
482
497
|
end
|
483
498
|
|
484
499
|
# Path on the local file system where originals will be staged before being ingested into Fedora.
|
485
500
|
attr_writer :working_path
|
486
501
|
def working_path
|
487
|
-
@working_path ||= ENV.fetch('HYRAX_UPLOAD_PATH', Rails.root.join('tmp', 'uploads'))
|
502
|
+
@working_path ||= Pathname.new(ENV.fetch('HYRAX_UPLOAD_PATH', Rails.root.join('tmp', 'uploads')))
|
488
503
|
end
|
489
504
|
|
490
505
|
# @todo do we use both upload_path and working path?
|
491
506
|
# Path on the local file system where originals will be staged before being ingested into Fedora.
|
492
507
|
attr_writer :upload_path
|
493
508
|
def upload_path
|
494
|
-
@upload_path ||= ->() { ENV.fetch('HYRAX_UPLOAD_PATH') { Rails.root.join('tmp', 'uploads') } }
|
509
|
+
@upload_path ||= ->() { Pathname.new(ENV.fetch('HYRAX_UPLOAD_PATH') { Rails.root.join('tmp', 'uploads') }) }
|
495
510
|
end
|
496
511
|
|
497
512
|
attr_writer :cache_path
|
498
513
|
def cache_path
|
499
|
-
@cache_path ||= ->() { ENV.fetch('HYRAX_CACHE_PATH') { Rails.root.join('tmp', 'cache') } }
|
514
|
+
@cache_path ||= ->() { Pathname.new(ENV.fetch('HYRAX_CACHE_PATH') { Rails.root.join('tmp', 'cache') }) }
|
500
515
|
end
|
501
516
|
|
502
517
|
# Path on the local file system where where log and banners will be stored.
|
503
518
|
attr_writer :branding_path
|
504
519
|
def branding_path
|
505
|
-
@branding_path ||= ENV.fetch('HYRAX_BRANDING_PATH', Rails.root.join('public', 'branding'))
|
520
|
+
@branding_path ||= Pathname.new(ENV.fetch('HYRAX_BRANDING_PATH', Rails.root.join('public', 'branding')))
|
506
521
|
end
|
507
522
|
|
508
523
|
# @!endgroup
|
@@ -13,7 +13,11 @@ module Hyrax
|
|
13
13
|
stdout_logger.formatter = proc do |_severity, _datetime, _progname, msg|
|
14
14
|
"#{msg}\n"
|
15
15
|
end
|
16
|
-
|
16
|
+
if Rails.version >= '7.1'
|
17
|
+
ActiveSupport::BroadcastLogger.new(Hyrax.logger, stdout_logger)
|
18
|
+
else
|
19
|
+
Hyrax.logger.extend(ActiveSupport::Logger.broadcast(stdout_logger))
|
20
|
+
end
|
17
21
|
end
|
18
22
|
|
19
23
|
def import
|
@@ -20,10 +20,11 @@ module Hyrax
|
|
20
20
|
##
|
21
21
|
# @param [Hyrax::Work] obj
|
22
22
|
# @param [Enumerable<UploadedFile>] uploaded_files
|
23
|
-
# @param [Enumerable<Hash>] file_set_params
|
23
|
+
# @param [Enumerable<Hash>] file_set_params or nil
|
24
24
|
#
|
25
25
|
# @return [Dry::Monads::Result]
|
26
26
|
def call(obj, uploaded_files: [], file_set_params: [])
|
27
|
+
return Success(obj) if uploaded_files.empty? && file_set_params.blank? # Skip if no files to attach
|
27
28
|
if @handler.new(work: obj).add(files: uploaded_files, file_set_params: file_set_params).attach
|
28
29
|
file_sets = obj.member_ids.map do |member|
|
29
30
|
Hyrax.query_service.find_by(id: member) if Hyrax.query_service.find_by(id: member).is_a? Hyrax::FileSet
|
data/lib/hyrax/version.rb
CHANGED
data/lib/hyrax.rb
CHANGED
@@ -23,6 +23,7 @@ require 'hyrax/valkyrie_can_can_adapter'
|
|
23
23
|
require 'retriable'
|
24
24
|
require 'valkyrie/indexing_adapter'
|
25
25
|
require 'valkyrie/indexing/solr/indexing_adapter'
|
26
|
+
require 'valkyrie/indexing/redis_queue/indexing_adapter'
|
26
27
|
require 'valkyrie/indexing/null_indexing_adapter'
|
27
28
|
|
28
29
|
##
|
data/lib/tasks/workflow.rake
CHANGED
@@ -3,8 +3,7 @@ namespace :hyrax do
|
|
3
3
|
namespace :workflow do
|
4
4
|
desc "Load workflow configuration into the database"
|
5
5
|
task load: :environment do
|
6
|
-
logger = Logger.new(STDOUT)
|
7
|
-
logger.level = Logger::DEBUG
|
6
|
+
logger = Hyrax.logger || Logger.new(STDOUT, level: Logger::DEBUG)
|
8
7
|
Hyrax::Workflow::WorkflowImporter.load_workflows(logger: logger)
|
9
8
|
errors = Hyrax::Workflow::WorkflowImporter.load_errors
|
10
9
|
abort("Failed to process all workflows:\n #{errors.join('\n ')}") unless errors.empty?
|
@@ -0,0 +1,144 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Valkyrie
|
3
|
+
module Indexing
|
4
|
+
module RedisQueue
|
5
|
+
class IndexingAdapter
|
6
|
+
##
|
7
|
+
# @!attribute [r] connection
|
8
|
+
# @return [RSolr::Client]
|
9
|
+
attr_writer :connection
|
10
|
+
attr_accessor :index_queue_name, :delete_queue_name, :index_error_name, :delete_error_name
|
11
|
+
|
12
|
+
##
|
13
|
+
# @param connection [RSolr::Client] The RSolr connection to index to.
|
14
|
+
def initialize(connection: nil, index_queue_name: 'toindex', delete_queue_name: 'todelete')
|
15
|
+
@connection = connection
|
16
|
+
@index_queue_name = index_queue_name
|
17
|
+
@delete_queue_name = delete_queue_name
|
18
|
+
@index_error_name = index_queue_name + "-error"
|
19
|
+
@delete_error_name = delete_queue_name + "-error"
|
20
|
+
end
|
21
|
+
|
22
|
+
def connection
|
23
|
+
@connection ||= default_connection
|
24
|
+
end
|
25
|
+
|
26
|
+
def save(resource:)
|
27
|
+
persist([resource])
|
28
|
+
end
|
29
|
+
|
30
|
+
def save_all(resources:)
|
31
|
+
persist(resources)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Deletes a Solr Document using the ID
|
35
|
+
# @return [Array<Valkyrie::Resource>] resources which have been deleted from Solr
|
36
|
+
def delete(resource:)
|
37
|
+
connection.zadd(delete_queue_name, Time.current.to_i, resource.id.to_s)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Delete the Solr index of all Documents
|
41
|
+
def wipe!
|
42
|
+
connection.del(index_queue_name)
|
43
|
+
connection.del(index_error_name)
|
44
|
+
connection.del(delete_queue_name)
|
45
|
+
connection.del(delete_error_name)
|
46
|
+
end
|
47
|
+
|
48
|
+
def reset!
|
49
|
+
self.connection = default_connection
|
50
|
+
end
|
51
|
+
|
52
|
+
def index_queue(size: 200)
|
53
|
+
set = connection.zpopmin(index_queue_name, size)
|
54
|
+
return [] if set.blank?
|
55
|
+
# we have to load these one at a time because find_all_by_id gets duplicates during wings transition
|
56
|
+
resources = set.map { |id, _time| Hyrax.query_service.find_by(id: id) }
|
57
|
+
solr_indexer = Valkyrie::IndexingAdapter.find(:solr_index)
|
58
|
+
solr_indexer.save_all(resources: resources)
|
59
|
+
solr_indexer.connection.commit
|
60
|
+
rescue
|
61
|
+
# if anything goes wrong, try to requeue the items
|
62
|
+
set.each { |id, time| connection.zadd(index_error_name, time, id) }
|
63
|
+
raise
|
64
|
+
end
|
65
|
+
|
66
|
+
# If a batch fails, try running them one at a time to get down to just records that really fail
|
67
|
+
def index_error_queue(size: 200)
|
68
|
+
@set = []
|
69
|
+
solr_indexer = Valkyrie::IndexingAdapter.find(:solr_index)
|
70
|
+
|
71
|
+
size.times do
|
72
|
+
@set = queue.connection.zpopmin(index_error_name, 1)
|
73
|
+
return [] if @set.blank?
|
74
|
+
# we have to load these one at a time because find_all_by_id gets duplicates during wings transition
|
75
|
+
resource = Hyrax.query_service.find_by(id: @set[0])
|
76
|
+
solr_indexer.save(resource: resource)
|
77
|
+
rescue
|
78
|
+
# if anything goes wrong, try to requeue the items
|
79
|
+
@set.each { |id, _time| queue.connection.zadd(index_error_name + "-twice", Time.now.to_i, id) }
|
80
|
+
end
|
81
|
+
solr_indexer.connection.commit
|
82
|
+
end
|
83
|
+
|
84
|
+
# We reach in to solr directly here to prevent needing to load the objects unnecessarily
|
85
|
+
def delete_queue(size: 200)
|
86
|
+
set = connection.zpopmin(delete_queue_name, size)
|
87
|
+
return [] if set.blank?
|
88
|
+
solr_indexer = Valkyrie::IndexingAdapter.find(:solr_index)
|
89
|
+
set.each do |id, _time|
|
90
|
+
solr_indexer.connection.delete_by_id id.to_s, { softCommit: true }
|
91
|
+
end
|
92
|
+
solr_indexer.connection.commit
|
93
|
+
rescue
|
94
|
+
# if anything goes wrong, try to requeue the items
|
95
|
+
set.each { |id, time| connection.zadd(delete_error_name, time, id) }
|
96
|
+
raise
|
97
|
+
end
|
98
|
+
|
99
|
+
# If a batch fails, try running them one at a time to get down to just records that really fail
|
100
|
+
def delete_error_queue(size: 200)
|
101
|
+
@set = []
|
102
|
+
size.times do
|
103
|
+
@set = connection.zpopmin(delete_error_name, 1)
|
104
|
+
return [] if @set.blank?
|
105
|
+
solr_indexer = Valkyrie::IndexingAdapter.find(:solr_index)
|
106
|
+
solr_indexer.connection.delete_by_id @set[0].to_s, { softCommit: true }
|
107
|
+
solr_indexer.connection.commit
|
108
|
+
rescue
|
109
|
+
# if anything goes wrong, try to requeue the items
|
110
|
+
@set.each { |id, _time| connection.zadd(delete_error_name, Time.now.to_i, id) }
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def list_index
|
115
|
+
connection.zrange(index_queue_name, 0, -1, with_scores: true)
|
116
|
+
end
|
117
|
+
|
118
|
+
def list_delete
|
119
|
+
connection.zrange(delete_queue_name, 0, -1, with_scores: true)
|
120
|
+
end
|
121
|
+
|
122
|
+
def list_index_errors
|
123
|
+
connection.zrange(index_error_name, 0, -1, with_scores: true)
|
124
|
+
end
|
125
|
+
|
126
|
+
def list_delete_errors
|
127
|
+
connection.zrange(delete_error_name, 0, -1, with_scores: true)
|
128
|
+
end
|
129
|
+
|
130
|
+
private
|
131
|
+
|
132
|
+
def persist(resources)
|
133
|
+
resources.map do |r|
|
134
|
+
connection.zadd(index_queue_name, Time.current.to_i, r.id.to_s)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def default_connection
|
139
|
+
Hyrax.config.redis_connection
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -63,11 +63,10 @@ module Wings
|
|
63
63
|
#
|
64
64
|
# @param model [Class]
|
65
65
|
# @return [Array<Valkyrie::Resource>]
|
66
|
-
#
|
67
|
-
# @note Due to implementation details, .find_all_of_model and .count_all_of_model may not
|
68
|
-
# return the same number of results. Is that a bug? Probably.
|
69
66
|
def find_all_of_model(model:)
|
70
|
-
|
67
|
+
ActiveFedora::Base
|
68
|
+
.where(has_model_ssim: [model_class_for(model).to_rdf_representation,
|
69
|
+
model.to_rdf_representation]).map do |obj|
|
71
70
|
resource_factory.to_resource(object: obj)
|
72
71
|
end
|
73
72
|
end
|
data/template.rb
CHANGED