hyrax 4.0.0.rc2 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.dassie/Gemfile +0 -2
  3. data/.dassie/config/analytics.yml +2 -2
  4. data/.dassie/config/initializers/redis_config.rb +7 -1
  5. data/.github/ISSUE_TEMPLATE.md +14 -9
  6. data/.github/PULL_REQUEST_TEMPLATE.md +22 -6
  7. data/.koppie/Gemfile +0 -2
  8. data/.koppie/README.md +11 -11
  9. data/.koppie/config/analytics.yml +1 -0
  10. data/.koppie/config/initializers/redis_config.rb +7 -1
  11. data/.regen +1 -1
  12. data/CONTAINERS.md +15 -15
  13. data/README.md +2 -2
  14. data/app/builders/hyrax/bootstrap_breadcrumbs_builder.rb +1 -1
  15. data/app/services/hyrax/analytics/google.rb +23 -15
  16. data/app/services/hyrax/analytics/matomo.rb +4 -3
  17. data/app/services/hyrax/custom_queries/navigators/find_files.rb +1 -4
  18. data/app/services/hyrax/lock_manager.rb +36 -6
  19. data/app/views/hyrax/base/_form_files.html.erb +7 -2
  20. data/app/views/hyrax/file_sets/_versioning.html.erb +1 -1
  21. data/app/views/layouts/hyrax/dashboard.html.erb +1 -1
  22. data/app/views/layouts/hyrax.html.erb +1 -1
  23. data/config/locales/hyrax.de.yml +11 -3
  24. data/config/locales/hyrax.en.yml +5 -2
  25. data/config/locales/hyrax.es.yml +4 -1
  26. data/config/locales/hyrax.fr.yml +4 -1
  27. data/config/locales/hyrax.it.yml +5 -2
  28. data/config/locales/hyrax.pt-BR.yml +9 -2
  29. data/config/locales/hyrax.zh.yml +4 -1
  30. data/docker-compose-koppie.yml +0 -1
  31. data/docker-compose.yml +0 -1
  32. data/documentation/legacyREADME.md +4 -4
  33. data/hyrax.gemspec +1 -0
  34. data/lib/generators/hyrax/templates/config/analytics.yml +1 -0
  35. data/lib/generators/hyrax/templates/config/initializers/redis_config.rb +7 -1
  36. data/lib/hyrax/configuration.rb +7 -1
  37. data/lib/hyrax/redis_event_store.rb +21 -13
  38. data/lib/hyrax/version.rb +1 -1
  39. data/template.rb +1 -1
  40. metadata +18 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 24e7e9d00de4eebd2f2dfaf96bcd1a09ac9589b17e94ddcc0bf5681d3c93b0c4
4
- data.tar.gz: 92753b2fbb1271cfec93e2eddd07d11da1091eaf8b36494e754ac3400a83a6a1
3
+ metadata.gz: c53f04239ef92492dd8a98a52c8f13cb446c18ba4ad04d22e5b78673e688aa8c
4
+ data.tar.gz: a804bc525628fbe33352617f8f8c0074d454def18a5e90c4d82e6c6a46aa25c2
5
5
  SHA512:
6
- metadata.gz: 16a328b5b11d826f8149f0b260675ffe913d7e41a4b5c37035696cb32741b650a9f4bf9fa0d70ed08a1be712ddc8b452824bfb5be60a99b1a9d52ead57d8b7f3
7
- data.tar.gz: bff8a0b37d073e1014f9566472030bb2b22e16a19fc1413dec6405cf21d6c3f178b0644ecbb48ee8ed0d259fe4f1b0422e747a5f3192c63753dc76d89ba8cb33
6
+ metadata.gz: 968a88b13e65cc3f88d30c142d4a69d39e5e21930c04a03f86af4ec2625443741da5e73662db261dc5758e770e669b521b866a1274d5d0bdfba8fcd2ef1b05c0
7
+ data.tar.gz: aa1568f4a0b53f442682f87721dc4c7d458716af085df77ef3523eedae5e0e663bf708f04ef6a02f06ddf3aa143d4fd73fe513f6bbe23b1e43402438abc10ff1
data/.dassie/Gemfile CHANGED
@@ -8,8 +8,6 @@ else
8
8
  end
9
9
  git_source(:github) { |repo| "https://github.com/#{repo}.git" }
10
10
 
11
- ruby '3.2.1'
12
-
13
11
  # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
14
12
  gem 'rails', '~> 6.0'
15
13
  # Use postgresql as the database for Active Record
@@ -3,11 +3,11 @@ analytics:
3
3
  analytics_id: <%= ENV['GOOGLE_ANALYTICS_ID'] %>
4
4
  app_name: <%= ENV['GOOGLE_OAUTH_APP_NAME'] %>
5
5
  app_version: <%= ENV['GOOGLE_OAUTH_APP_VERSION'] %>
6
+ privkey_value: <%= ENV['GOOGLE_OAUTH_PRIVATE_KEY_VALUE'] %>
6
7
  privkey_path: <%= ENV['GOOGLE_OAUTH_PRIVATE_KEY_PATH'] %>
7
8
  privkey_secret: <%= ENV['GOOGLE_OAUTH_PRIVATE_KEY_SECRET'] %>
8
9
  client_email: <%= ENV['GOOGLE_OAUTH_CLIENT_EMAIL'] %>
9
- matomo:
10
+ matomo:
10
11
  base_url: <%= ENV['MATOMO_BASE_URL'] %>
11
12
  site_id: <%= ENV['MATOMO_SITE_ID'] %>
12
13
  auth_token: <%= ENV['MATOMO_AUTH_TOKEN'] %>
13
-
@@ -1,4 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
  require 'redis'
3
+ require 'connection_pool'
3
4
  config = YAML.safe_load(ERB.new(IO.read(Rails.root.join('config', 'redis.yml'))).result)[Rails.env].with_indifferent_access
4
- Redis.current = Redis.new(config.merge(thread_safe: true))
5
+
6
+ size = ENV.fetch("HYRAX_REDIS_POOL_SIZE", 5)
7
+ timeout = ENV.fetch("HYRAX_REDIS_TIMEOUT", 5)
8
+
9
+ Hyrax.config.redis_connection =
10
+ ConnectionPool::Wrapper.new(size: size, timeout: timeout) { Redis.new(config) }
@@ -1,20 +1,25 @@
1
1
  ### Descriptive summary
2
2
 
3
- Include what version of Hyrax relates to this issue (7.x, 6.x, HEAD, etc.) if appropriate, and any relevant tracebacks if you're reporting a bug.
3
+ Present tense short summary (30 words or less)
4
4
 
5
- ### Rationale
5
+ ### Steps to reproduce the behavior in User Interface (UI)
6
6
 
7
- Provide the rationale or user story that describes "why" this issue should be addressed. Especially if this is a new feature or significant change to the existing implementation.
7
+ 1. Do this
8
+ 2. Then do this...
9
+ 3. Include note here if not testable in UI
8
10
 
9
- ### Expected behavior
11
+ ### Actual behavior (include screenshots if available)
10
12
 
11
- ### Actual behavior
13
+ Include what version of Hyrax relates to this issue (3.x, 4.x, main branch, etc.) if appropriate, and any relevant error messages/tracebacks if you're reporting a bug.
12
14
 
13
- ### Steps to reproduce the behavior
15
+ ### Acceptance Criteria/Expected Behavior
14
16
 
15
- 1. Do this
16
- 2. Then do this...
17
+ - [ ] Create checkbox list of what done looks like...
18
+
19
+ ### Rationale (for feature request only)
20
+
21
+ Provide the rationale or user story that describes "why" this issue should be addressed. Especially if this is a new feature or significant change to the existing implementation.
17
22
 
18
23
  ### Related work
19
24
 
20
- Link to related tickets or prior related work here.
25
+ Link to related issues or prior related work here.
@@ -1,7 +1,28 @@
1
+ ### Fixes
2
+
1
3
  Fixes #issuenumber ; refs #issuenumber
2
4
 
5
+ ### Summary
6
+
3
7
  Present tense short summary (50 characters or less)
4
8
 
9
+ ### Guidance for testing, such as acceptance criteria or new user interface behaviors:
10
+ *
11
+ *
12
+ *
13
+
14
+ ### Type of change (for release notes)
15
+
16
+ - [ ] Major Changes (Potentially breaking changes)
17
+ - [ ] New Features
18
+ - [ ] Deprecations
19
+ - [ ] Bug Fixes
20
+ - [ ] Valkyrie Progress
21
+ - [ ] Documentation
22
+ - [ ] Containerization
23
+
24
+ ### Detailed Description
25
+
5
26
  More detailed description, if necessary. Try to be as descriptive as you can: even if you think that the PR content is obvious, it may not be obvious to others. Include tracebacks if helpful, and be sure to call out any bits of the PR that may be work-in-progress.
6
27
 
7
28
  Description can have multiple paragraphs and you can use code examples inside:
@@ -14,12 +35,7 @@ class PostsController
14
35
  end
15
36
  ```
16
37
 
17
- Changes proposed in this pull request:
18
- *
19
- *
20
- *
21
-
22
- Guidance for testing, such as acceptance criteria or new user interface behaviors:
38
+ ### Changes proposed in this pull request:
23
39
  *
24
40
  *
25
41
  *
data/.koppie/Gemfile CHANGED
@@ -6,8 +6,6 @@ else
6
6
  end
7
7
  git_source(:github) { |repo| "https://github.com/#{repo}.git" }
8
8
 
9
- ruby '2.7.7'
10
-
11
9
  gem 'bootsnap', '>= 1.1.0', require: false
12
10
  gem 'bootstrap', '~> 4.0'
13
11
  gem 'coffee-rails', '~> 4.2'
data/.koppie/README.md CHANGED
@@ -1,18 +1,18 @@
1
1
  # Koppie
2
2
 
3
- > Isolated granite outcrops in Southern Africa that are a favored habitat for hyraxes.
3
+ > Isolated granite outcrops in Southern Africa that are a favored habitat for hyraxes.
4
4
 
5
5
  Koppie is an application used for testing the state of [Hyrax](https://github.com/samvera/hyrax)
6
- using Postgres as the metadata store for objects. This is similar to the Dassie test application
6
+ using Postgres as the metadata store for objects. This is similar to the Dassie test application
7
7
  that lives in `.dassie`, however in this application Fedora is
8
- not used for storing object metadata or files. The Hyrax gem is sourced from the local hyrax
8
+ not used for storing object metadata or files. The Hyrax gem is sourced from the local hyrax
9
9
  directory one level up from `.koppie` for development purposes.
10
10
 
11
11
  ## Known Issues
12
12
 
13
13
  Collection model
14
14
  * `/app/models/collection.rb` - is_a `ActiveFedora::Base`
15
- * if `Collection` is changed to `Valkyrie::Resource`, there is an infinite loop while loading
15
+ * if `Collection` is changed to `Valkyrie::Resource`, there is an infinite loop while loading
16
16
  due to reference to ::Collection in `lib/hyrax/collection_name.rb` in the hyrax engine
17
17
 
18
18
  Default Admin Set
@@ -21,14 +21,14 @@ Default Admin Set
21
21
 
22
22
  ## Questions
23
23
 
24
- Please direct questions about this code or the servers where it runs to the `#hyrax-valkyrie`
24
+ Please direct questions about this code or the servers where it runs to the `#hyrax-valkyrie`
25
25
  channel on Samvera slack.
26
26
 
27
27
  ## Contributing
28
28
 
29
29
  If you're working on a PR for this project, create a feature branch off of `main`.
30
30
 
31
- This repository follows the [Samvera Community Code of Conduct](https://samvera.atlassian.net/wiki/spaces/samvera/pages/405212316/Code+of+Conduct)
31
+ This repository follows the [Samvera Community Code of Conduct](https://samvera.atlassian.net/wiki/spaces/samvera/pages/405212316/Code+of+Conduct)
32
32
  and [language recommendations](https://github.com/samvera/maintenance/blob/master/templates/CONTRIBUTING.md#language).
33
33
  Please ***do not*** create a branch called `master` for this repository or as part of your pull request; the branch will
34
34
  either need to be removed or renamed before it can be considered for inclusion in the code base and history of this repository.
@@ -46,10 +46,10 @@ git clone https://github.com/samvera/hyrax.git
46
46
  Execute the following commands from the hyrax root to start the app using Docker.
47
47
 
48
48
  ```
49
- docker-compose -f docker-compose-koppie.yml build
50
- docker-compose -f docker-compose-koppie.yml up
49
+ docker compose -f docker-compose-koppie.yml build
50
+ docker compose -f docker-compose-koppie.yml up
51
51
  ```
52
52
 
53
- You can find help with additional commands in Hyrax' [FAQ-for-Dassie-Docker-Test-App](https://github.com/samvera/hyrax/wiki/FAQ-for-Dassie-Docker-Test-App).
54
- Most commands can be used directly as described in the FAQ. A few might require
55
- a slight adjustment to work with koppie as a Docker app.
53
+ You can find help with additional commands in Hyrax' [FAQ-for-Dassie-Docker-Test-App](https://github.com/samvera/hyrax/wiki/FAQ-for-Dassie-Docker-Test-App).
54
+ Most commands can be used directly as described in the FAQ. A few might require
55
+ a slight adjustment to work with koppie as a Docker app.
@@ -3,6 +3,7 @@ analytics:
3
3
  analytics_id: <%= ENV['GOOGLE_ANALYTICS_ID'] %>
4
4
  app_name: <%= ENV.fetch('GOOGLE_OAUTH_APP_NAME', 'nurax-pg') %>
5
5
  app_version: <%= ENV.fetch['GOOGLE_OAUTH_APP_VERSION'] %>
6
+ privkey_value: <%= ENV['GOOGLE_OAUTH_PRIVATE_KEY_VALUE'] %>
6
7
  privkey_path: <%= ENV.fetch['GOOGLE_OAUTH_PRIVATE_KEY_PATH'] %>
7
8
  privkey_secret: <%= ENV.fetch['GOOGLE_OAUTH_PRIVATE_KEY_SECRET'] %>
8
9
  client_email: <%= ENV.fetch['GOOGLE_OAUTH_CLIENT_EMAIL'] %>
@@ -1,4 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
  require 'redis'
3
+ require 'connection_pool'
3
4
  config = YAML.safe_load(ERB.new(IO.read(Rails.root.join('config', 'redis.yml'))).result)[Rails.env].with_indifferent_access
4
- Redis.current = Redis.new(config.merge(thread_safe: true))
5
+
6
+ size = ENV.fetch("HYRAX_REDIS_POOL_SIZE", 5)
7
+ timeout = ENV.fetch("HYRAX_REDIS_TIMEOUT", 5)
8
+
9
+ Hyrax.config.redis_connection =
10
+ ConnectionPool::Wrapper.new(size: size, timeout: timeout) { Redis.new(config) }
data/.regen CHANGED
@@ -1,2 +1,2 @@
1
1
  # When updating CI regen seed, set to current date.
2
- 2023-04-11T16:25:55
2
+ 2023-05-24T10:43:07
data/CONTAINERS.md CHANGED
@@ -13,7 +13,7 @@ There are two options for development environments to run:
13
13
  <!-- NOTE: This title is referenced in the top-level README.md. Keep that in mind if you change it. -->
14
14
  ## Hyrax Engine Development
15
15
 
16
- We support a `docker-compose`-based development environment for folks working on
16
+ We support a `docker compose`-based development environment for folks working on
17
17
  the Hyrax engine. This environment is substantially more like a Hyrax production
18
18
  setup than the older `fedora_wrapper`/`solr_wrapper` approach.
19
19
 
@@ -24,8 +24,8 @@ First, make sure you have installed [Docker](https://www.docker.com/). Then clo
24
24
  Within your cloned repository, tell Docker to get started installing your development environment:
25
25
 
26
26
  ```sh
27
- docker-compose build
28
- docker-compose up
27
+ docker compose build
28
+ docker compose up
29
29
  ```
30
30
 
31
31
  This starts containers for:
@@ -40,24 +40,24 @@ This starts containers for:
40
40
 
41
41
  It also runs database migrations. This will also bring up a development application on `http://localhost:3000`.
42
42
 
43
- To stop the containers for the Hyrax-based application, type <kbd>Ctrl</kbd>+<kbd>c</kbd>. To restart the containers you need only run `docker-compose up`.
43
+ To stop the containers for the Hyrax-based application, type <kbd>Ctrl</kbd>+<kbd>c</kbd>. To restart the containers you need only run `docker compose up`.
44
44
 
45
45
  _**Note:** Starting and stopping Docker in this way will preserve your data between restarts._
46
46
 
47
47
  #### Code Changes and Testing
48
48
 
49
- With `docker-compose up` running, any changes you make to your cloned Hyrax code-base should show up in `http://localhost:3000`; There may be cases where you need to restart your test application (e.g. stop the containers and start them up again).
49
+ With `docker compose up` running, any changes you make to your cloned Hyrax code-base should show up in `http://localhost:3000`; There may be cases where you need to restart your test application (e.g. stop the containers and start them up again).
50
50
 
51
51
  Any changes you make to Hyrax should be tested. You can run the full test suite using the following command:
52
52
 
53
53
  ```sh
54
- docker-compose exec -w /app/samvera/hyrax-engine app sh -c "bundle exec rspec"
54
+ docker compose exec -w /app/samvera/hyrax-engine app sh -c "bundle exec rspec"
55
55
  ```
56
56
 
57
57
  Let's break down the above command:
58
58
 
59
59
  <dl>
60
- <dt><code>docker-compose exec</code></dt>
60
+ <dt><code>docker compose exec</code></dt>
61
61
  <dd>Tell docker to run the following:</dd>
62
62
  <dt><code>-w /app/samvera/hyrax-engine</code></dt>
63
63
  <dd>In the working directory "/app/samvera/hyrax-engine" (e.g. your cloned Hyrax repository)</dd>
@@ -86,13 +86,13 @@ bind mount to `/app/samvera/hyrax-webapp`, and your local development copy of Hy
86
86
  What does this structure mean? Let's look at an example. The following command will list the rake tasks for the Hyrax-based application running in Docker:
87
87
 
88
88
  ```sh
89
- docker-compose exec -w /app/samvera/hyrax-webapp app sh -c "bundle exec rake -T"
89
+ docker compose exec -w /app/samvera/hyrax-webapp app sh -c "bundle exec rake -T"
90
90
  ```
91
91
 
92
92
  And this command lists the rake tasks for the Hyrax engine that is in Docker:
93
93
 
94
94
  ```sh
95
- docker-compose exec -w /app/samvera/hyrax-engine app sh -c "bundle exec rake -T"
95
+ docker compose exec -w /app/samvera/hyrax-engine app sh -c "bundle exec rake -T"
96
96
  ```
97
97
 
98
98
  In the two examples, note the difference in the `-w` switch. In the first case, it's referencing the Hyrax-based application. In the latter case, it's referencing the Hyrax engine.
@@ -101,7 +101,7 @@ In the two examples, note the difference in the `-w` switch. In the first case,
101
101
 
102
102
  If you are interested in running Hyrax in debug mode, this requires a somewhat different approach than running Hyrax bare-metal. You need to use `docker attach` to debug the running docker instance.
103
103
 
104
- 1. With `docker-compose up` running open a new Terminal session.
104
+ 1. With `docker compose up` running open a new Terminal session.
105
105
  2. In that new Terminal session, using `docker container ls` find the "CONTAINER ID" for the `hyrax-engine-dev`.
106
106
  3. With the "CONTAINER ID", run `docker attach <CONTAINER ID>`.
107
107
 
@@ -111,7 +111,7 @@ This advice comes from [Debugging Rails App With Docker Compose: How to use Byeb
111
111
 
112
112
  ##### Bad Address SOLR
113
113
 
114
- With `docker-compose up` running, if you see the following, then there may be issues with file permissions:
114
+ With `docker compose up` running, if you see the following, then there may be issues with file permissions:
115
115
 
116
116
  ```
117
117
  db_migrate_1 | waiting for solr:8983
@@ -125,15 +125,15 @@ Executing /opt/docker-solr/scripts/precreate-core hyrax_test /opt/solr/server/co
125
125
  cp: cannot create directory '/var/solr/data/hyrax_test': Permission denied
126
126
  ```
127
127
 
128
- The solution that appears to work is to `docker-compose down --volumes`; This will tear down the docker instance, and remove the volumes. You can then run `docker-compose up` to get back to work. _**Note:** the `--volumes` switch will remove all custom data._
128
+ The solution that appears to work is to `docker compose down --volumes`; This will tear down the docker instance, and remove the volumes. You can then run `docker compose up` to get back to work. _**Note:** the `--volumes` switch will remove all custom data._
129
129
 
130
130
  ##### Errors building the Docker image
131
131
 
132
- If you encounter errors running `docker-compose build`, try running `bundle update` in `./hyrax` as well as within `./hyrax/.dassie`. That can help clear up the problem of a failure to build a particular gem.
132
+ If you encounter errors running `docker compose build`, try running `bundle update` in `./hyrax` as well as within `./hyrax/.dassie`. That can help clear up the problem of a failure to build a particular gem.
133
133
 
134
134
  ##### Containers do not all start
135
135
 
136
- If any of the services fail to start on `docker-compose up`, try clearing out any `Gemfile.lock` files that might exist in `./hyrax` or `./hyrax/.dassie` and run `docker-compose build` again, then `docker-compose up` again.
136
+ If any of the services fail to start on `docker compose up`, try clearing out any `Gemfile.lock` files that might exist in `./hyrax` or `./hyrax/.dassie` and run `docker compose build` again, then `docker compose up` again.
137
137
 
138
138
  ### Koppie Internal Test App with Valkyrie Connector to Postgres
139
139
 
@@ -191,7 +191,7 @@ We publish several Hyrax images to the [GitHub container registry][ghcr] under
191
191
  the [Samvera organization][samvera-packages]. To build them:
192
192
 
193
193
  ```sh
194
- export HYRAX_VERSION=v4.0.0.rc2 # or desired version
194
+ export HYRAX_VERSION=v4.0.0 # or desired version
195
195
  git checkout hyrax-$HYRAX_VERSION
196
196
 
197
197
  docker build --target hyrax-base --tag ghcr.io/samvera/hyrax/hyrax-base:$(git rev-parse HEAD) .
data/README.md CHANGED
@@ -42,7 +42,7 @@ Hyrax offers the ability to:
42
42
 
43
43
  More detailed documentation about Hyrax is available on the [Hyrax Github Wiki](https://github.com/samvera/hyrax/wiki) but if you have questions or need help, please email the [Samvera community tech list](https://samvera.atlassian.net/wiki/spaces/samvera/pages/1171226735/Samvera+Community+Email+Lists#Samvera-Tech-(15-20-messages-per-week-on-average)) or stop by the #dev channel in the [Samvera community Slack team](https://samvera.atlassian.net/wiki/spaces/samvera/pages/405211682/Getting+Started+in+the+Samvera+Community#Join-the-Samvera-Slack-workspace). You can also get in touch with the [Hyrax Maintenance Working Group](https://samvera.atlassian.net/wiki/spaces/samvera/pages/496632295/Hyrax+Maintenance+Working+Group), including the Hyrax Product Owner and Hyrax Tech Lead.
44
44
 
45
- [Reporting Issues](./.github/SUPPORT.md)
45
+ [Reporting Issues](./.github/SUPPORT.md)
46
46
 
47
47
  ## How to Run the Code
48
48
 
@@ -79,4 +79,4 @@ This software has been developed by and is brought to you by the Samvera communi
79
79
 
80
80
  ## License
81
81
 
82
- Hyrax is available under [the Apache 2.0 license](LICENSE).
82
+ Hyrax is available under [the Apache 2.0 license](LICENSE).
@@ -12,7 +12,7 @@ class Hyrax::BootstrapBreadcrumbsBuilder < BreadcrumbsOnRails::Breadcrumbs::Buil
12
12
  def render
13
13
  return "" if @elements.blank?
14
14
 
15
- @context.tag.nav(breadcrumbs_options) do
15
+ @context.tag.nav(**breadcrumbs_options) do
16
16
  @context.tag.ol do
17
17
  safe_join(@elements.uniq.collect { |e| render_element(e) })
18
18
  end
@@ -1,20 +1,24 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'oauth2'
3
4
  require 'signet/oauth_2/client'
4
5
 
5
- # rubocop:disable Metrics/ModuleLength
6
6
  module Hyrax
7
7
  module Analytics
8
+ # rubocop:disable Metrics/ModuleLength
8
9
  module Google
9
10
  extend ActiveSupport::Concern
10
11
  # rubocop:disable Metrics/BlockLength
11
12
  class_methods do
12
- # Loads configuration options from config/analytics.yml. Expected structure:
13
+ # Loads configuration options from config/analytics.yml. You only need PRIVATE_KEY_PATH or
14
+ # PRIVATE_KEY_VALUE. VALUE takes precedence.
15
+ # Expected structure:
13
16
  # `analytics:`
14
17
  # ` google:`
15
18
  # ` app_name: <%= ENV['GOOGLE_OAUTH_APP_NAME']`
16
19
  # ` app_version: <%= ENV['GOOGLE_OAUTH_APP_VERSION']`
17
20
  # ` privkey_path: <%= ENV['GOOGLE_OAUTH_PRIVATE_KEY_PATH']`
21
+ # ` privkey_value: <%= ENV['GOOGLE_OAUTH_PRIVATE_KEY_VALUE']`
18
22
  # ` privkey_secret: <%= ENV['GOOGLE_OAUTH_PRIVATE_KEY_SECRET']`
19
23
  # ` client_email: <%= ENV['GOOGLE_OAUTH_CLIENT_EMAIL']`
20
24
  # @return [Config]
@@ -41,7 +45,8 @@ module Hyrax
41
45
  new config
42
46
  end
43
47
 
44
- REQUIRED_KEYS = %w[analytics_id app_name app_version privkey_path privkey_secret client_email].freeze
48
+ KEYS = %w[analytics_id app_name app_version privkey_path privkey_value privkey_secret client_email].freeze
49
+ REQUIRED_KEYS = %w[analytics_id app_name app_version privkey_secret client_email].freeze
45
50
 
46
51
  def initialize(config)
47
52
  @config = config
@@ -49,18 +54,16 @@ module Hyrax
49
54
 
50
55
  # @return [Boolean] are all the required values present?
51
56
  def valid?
52
- config_keys = @config.keys
53
- REQUIRED_KEYS.all? { |required| config_keys.include?(required) }
54
- end
57
+ return false unless @config['privkey_value'].present? || @config['privkey_path'].present?
55
58
 
56
- REQUIRED_KEYS.each do |key|
57
- class_eval %{ def #{key}; @config.fetch('#{key}'); end }
59
+ REQUIRED_KEYS.all? { |required| @config[required].present? }
58
60
  end
59
61
 
60
- # This method allows setting the analytics id in the initializer
61
- # @deprecated set the analytics id in either ENV['GOOGLE_ANALYTICS_ID'] or config/analytics.yaml
62
- def analytics_id=(value)
63
- @config['analytics_id'] = value
62
+ KEYS.each do |key|
63
+ # rubocop:disable Style/EvalWithLocation
64
+ class_eval %{ def #{key}; @config.fetch('#{key}'); end }
65
+ class_eval %{ def #{key}=(value); @config['#{key}'] = value; end }
66
+ # rubocop:enable Style/EvalWithLocation
64
67
  end
65
68
  end
66
69
 
@@ -77,8 +80,12 @@ module Hyrax
77
80
  end
78
81
 
79
82
  def auth_client(scope)
80
- raise "Private key file for Google analytics was expected at '#{config.privkey_path}', but no file was found." unless File.exist?(config.privkey_path)
81
- private_key = File.read(config.privkey_path)
83
+ private_key = Base64.decode64(config.privkey_value) if config.privkey_value.present?
84
+ if private_key.blank?
85
+ raise "Private key file for Google analytics was expected at '#{config.privkey_path}', but no file was found." unless File.exist?(config.privkey_path)
86
+
87
+ private_key = File.read(config.privkey_path)
88
+ end
82
89
  Signet::OAuth2::Client.new token_credential_uri: 'https://accounts.google.com/o/oauth2/token',
83
90
  audience: 'https://accounts.google.com/o/oauth2/token',
84
91
  scope: scope,
@@ -123,7 +130,7 @@ module Hyrax
123
130
 
124
131
  [start_date, end_date]
125
132
  end
126
- # rubocop:enabl e Metrics/MethodLength
133
+ # rubocop:enable Metrics/MethodLength
127
134
 
128
135
  def keyword_conversion(date)
129
136
  case date
@@ -199,6 +206,7 @@ module Hyrax
199
206
  end
200
207
  # rubocop:enable Metrics/BlockLength
201
208
  end
209
+ # rubocop:enable Metrics/ModuleLength
202
210
  end
203
211
  end
204
212
  # rubocop:enable Metrics/ModuleLength
@@ -11,15 +11,16 @@ module Hyrax
11
11
  # Loads configuration options from config/analytics.yml. Expected structure:
12
12
  # `analytics:`
13
13
  # ` matomo:`
14
- # ` base_url: <%= ENV['MATOMOT_BASE_URL']`
15
- # ` site_id: <%= ENV['MATOMOT_SITE_ID']`
16
- # ` auth_token: <%= ENV['MATOMOT_AUTH_TOKEN']`
14
+ # ` base_url: <%= ENV['MATOMO_BASE_URL']`
15
+ # ` site_id: <%= ENV['MATOMO_SITE_ID']`
16
+ # ` auth_token: <%= ENV['MATOMO_AUTH_TOKEN']`
17
17
  # @return [Config]
18
18
  def config
19
19
  @config ||= Config.load_from_yaml
20
20
  end
21
21
 
22
22
  class Config
23
+ # TODO: test matomo and see if it needs any of the updates from https://github.com/samvera/hyrax/pull/6063
23
24
  def self.load_from_yaml
24
25
  filename = Rails.root.join('config', 'analytics.yml')
25
26
  yaml = YAML.safe_load(ERB.new(File.read(filename)).result)
@@ -80,10 +80,7 @@ module Hyrax
80
80
  files =
81
81
  query_service.custom_queries.find_many_file_metadata_by_use(resource: file_set, use: use)
82
82
 
83
- raise Valkyrie::Persistence::ObjectNotFoundError, "FileSet #{file_set.id}'s #{use.fragment} is missing." if
84
- files.empty?
85
-
86
- files.first
83
+ files.first || raise(Valkyrie::Persistence::ObjectNotFoundError, "FileSet #{file_set.id}'s #{use.fragment} is missing.")
87
84
  end
88
85
  end
89
86
  end
@@ -4,24 +4,54 @@ module Hyrax
4
4
  class LockManager
5
5
  class UnableToAcquireLockError < StandardError; end
6
6
 
7
- attr_reader :client
8
-
7
+ ##
9
8
  # @param [Fixnum] time_to_live How long to hold the lock in milliseconds
10
9
  # @param [Fixnum] retry_count How many times to retry to acquire the lock before raising UnableToAcquireLockError
11
10
  # @param [Fixnum] retry_delay Maximum wait time in milliseconds before retrying. Wait time is a random value between 0 and retry_delay.
12
11
  def initialize(time_to_live, retry_count, retry_delay)
13
12
  @ttl = time_to_live
14
- @client = Redlock::Client.new([Redis.current], retry_count: retry_count, retry_delay: retry_delay)
13
+ @retry_count = retry_count
14
+ @retry_delay = retry_delay
15
15
  end
16
16
 
17
+ ##
17
18
  # Blocks until lock is acquired or timeout.
18
19
  def lock(key)
19
20
  returned_from_block = nil
20
- client.lock(key, @ttl) do |locked|
21
- raise UnableToAcquireLockError unless locked
22
- returned_from_block = yield
21
+
22
+ pool.then do |conn|
23
+ client(conn).lock(key, @ttl) do |locked|
24
+ raise UnableToAcquireLockError unless locked
25
+ returned_from_block = yield
26
+ end
23
27
  end
28
+
24
29
  returned_from_block
30
+ rescue ConnectionPool::TimeoutError => err
31
+ Hyrax.logger.error(err.message)
32
+ raise(ConnectionPool::TimeoutError,
33
+ "Failed to aquire a lock from Redlock due to a Redis connection " /
34
+ "timeout: #{err}. If you are using Redis via `ConnectionPool` " /
35
+ "you may wish to increase the pool size.")
36
+ end
37
+
38
+ private
39
+
40
+ ##
41
+ # @api_private
42
+ def client(conn)
43
+ Redlock::Client.new([conn], retry_count: @retry_count, retry_delay: @retry_delay)
44
+ end
45
+
46
+ ##
47
+ # @api private
48
+ #
49
+ # @note support both a ConnectionPool and a raw Redis client for now.
50
+ # we should drop support for `Redis.current` in 5.0.0.
51
+ # `#then` supports both options. for a ConnectionPool it will block
52
+ # until a connection is available.
53
+ def pool
54
+ Hyrax.config.redis_connection || Redis.current
25
55
  end
26
56
  end
27
57
  end
@@ -4,9 +4,14 @@
4
4
  <!-- The table listing the files available for upload/download -->
5
5
  <table role="presentation" class="table table-striped"><tbody class="files"></tbody></table>
6
6
  <% if Hyrax.config.browse_everything? %>
7
- <%= t('hyrax.base.form_files.local_upload_browse_everything_html', contact_href: link_to(t("hyrax.upload.alert.contact_href_text"), hyrax.contact_form_index_path)) %>
7
+ <%= t('hyrax.base.form_files.local_upload_browse_everything_html',
8
+ contact_href: link_to(t("hyrax.upload.alert.contact_href_text"), hyrax.contact_form_index_path),
9
+ upload_file_limit: Hyrax.config.uploader[:maxNumberOfFiles],
10
+ upload_size_limit: Hyrax.config.uploader[:maxFileSize] / 1.megabytes) %>
8
11
  <% else %>
9
- <%= t('hyrax.base.form_files.local_upload_html') %>
12
+ <%= t('hyrax.base.form_files.local_upload_html',
13
+ upload_file_limit: Hyrax.config.uploader[:maxNumberOfFiles],
14
+ upload_size_limit: Hyrax.config.uploader[:maxFileSize] / 1.megabytes) %>
10
15
  <% end %>
11
16
  <!-- The fileupload-buttonbar contains buttons to add/delete files and start/cancel the upload -->
12
17
  <div class="fileupload-buttonbar">
@@ -41,7 +41,7 @@
41
41
  name: "update_versioning",
42
42
  id: "upload_submit",
43
43
  onclick: "confirmation_needed = false;",
44
- class: "btn btn-primary" do %>
44
+ class: "btn btn-primary text-white" do %>
45
45
  <%= t('.upload') %>
46
46
  <% end %>
47
47
 
@@ -16,7 +16,7 @@
16
16
  <%= render 'hyrax/dashboard/sidebar' %>
17
17
  </div>
18
18
  <div class="main-content maximized<%= " admin-stats" if request.fullpath.include? '/admin/stats' %>">
19
- <%= render_breadcrumbs builder: Hyrax::BootstrapBreadcrumbsBuilder %>
19
+ <%= render_breadcrumbs builder: Hyrax.config.breadcrumb_builder %>
20
20
  <%= render '/flash_msg' %>
21
21
  <% if content_for?(:page_header) %>
22
22
  <div class="row">
@@ -15,7 +15,7 @@
15
15
  <div id="content-wrapper" class="container" role="main">
16
16
  <%= content_for(:container_header) %>
17
17
  <%= render '/flash_msg' %>
18
- <%= render_breadcrumbs builder: Hyrax::BootstrapBreadcrumbsBuilder %>
18
+ <%= render_breadcrumbs builder: Hyrax.config.breadcrumb_builder %>
19
19
  <% if content_for?(:page_header) %>
20
20
  <div class="row">
21
21
  <div class="col-12 main-header">
@@ -542,8 +542,16 @@ de:
542
542
  add_folder: Ordner hinzufügen
543
543
  cancel_upload: Upload abbrechen
544
544
  dropzone: Dateien hier hinziehen.
545
- local_upload_browse_everything_html: "<p>Sie können eine oder mehre Dateien von Ihrem lokalen System oder einem Cloudanbieter hinzufügen, welche mit dieser Arbeit\nverknüpft werden sollen.</p>\n<p>Bitte beachten Sie, dass der Cloud-Anbieter möglicherweise nicht in der Lage ist Ihrer Anfrage nachzukommen, wenn Sie eine große Anzahl von Dateien\ninnerhalb einer kurzen Zeitspanne hochladen. \nWenn Sie\nirgendwelche Fehler beim Hochladen aus der Cloud erhalten, teilen Sie uns dies \nbitte über %{contact_href} mit.</p>\n"
546
- local_upload_html: "<p> Sie können eine oder mehrere Dateien hinzufügen, die dieser Arbeit zugeordnet werden sollen. </p>"
545
+ local_upload_browse_everything_html: |
546
+ <p>Sie können eine oder mehre Dateien von Ihrem lokalen System oder einem Cloudanbieter hinzufügen, welche mit
547
+ dieser Arbeit verknüpft werden sollen.</p>
548
+ <p>Bitte beachten Sie, dass der Cloud-Anbieter möglicherweise nicht in der Lage ist Ihrer Anfrage
549
+ nachzukommen, wenn Sie eine große Anzahl von Dateien innerhalb einer kurzen Zeitspanne hochladen.
550
+ Wenn Sie irgendwelche Fehler beim Hochladen aus der Cloud erhalten, teilen Sie uns dies bitte über %{contact_href} mit.</p>
551
+ <p>Das Hochladen ist auf %{upload_file_limit} Dateien mit jeweils %{upload_size_limit} MB begrenzt.</p>
552
+ local_upload_html: |
553
+ <p>Sie können eine oder mehrere Dateien hinzufügen, die dieser Arbeit zugeordnet werden sollen.</p>
554
+ <p>Das Hochladen ist auf %{upload_file_limit} Dateien mit jeweils %{upload_size_limit} MB begrenzt.</p>
547
555
  form_member_of_collections:
548
556
  actions:
549
557
  remove: Aus der Sammlung entfernen
@@ -1301,7 +1309,7 @@ de:
1301
1309
  restore: Vorherige Version wiederherstellen
1302
1310
  restore_from: Wiederherstellen von
1303
1311
  save: Überarbeitete Version speichern
1304
- save_your_note: Sie müssen auf & quot; Revision speichern & quot; klicken. um eine frühere Version dieser Datei wiederherzustellen
1312
+ save_your_note: Sie müssen auf "Revision speichern" klicken. um eine frühere Version dieser Datei wiederherzustellen
1305
1313
  upload: Neue Version hochladen
1306
1314
  help:
1307
1315
  header: Benutzer-Support
@@ -535,7 +535,10 @@ en:
535
535
  files within a short period of time, the provider may not be able to
536
536
  accommodate your request. If you experience errors uploading from the
537
537
  cloud, let us know via the %{contact_href}.</p>
538
- local_upload_html: "<p>You can add one or more files to associate with this work.</p>"
538
+ <p>Uploads are limited to %{upload_file_limit} files, %{upload_size_limit} MB each.</p>
539
+ local_upload_html: |
540
+ <p>You can add one or more files to associate with this work.</p>
541
+ <p>Uploads are limited to %{upload_file_limit} files, %{upload_size_limit} MB each.</p>
539
542
  form_member_of_collections:
540
543
  actions:
541
544
  remove: Remove from collection
@@ -1290,7 +1293,7 @@ en:
1290
1293
  restore: Restore Previous Version
1291
1294
  restore_from: Restore From
1292
1295
  save: Save Revision
1293
- save_your_note: You must click &quot;Save Revision&quot; to revert a previous version of this file
1296
+ save_your_note: You must click "Save Revision" to revert a previous version of this file
1294
1297
  upload: Upload New Version
1295
1298
  help:
1296
1299
  header: User Support
@@ -548,7 +548,10 @@ es:
548
548
  de tiempo, el proveedor en la nube podría no ser capaz de resolver la
549
549
  petición. Si se experimentan errores durante la carga, por favor,
550
550
  comuníquese con nosotros a través de %{contact_href}.</p>
551
- local_upload_html: "<p>Puede agregar uno o más archivos para asociar con esta obra.</p>"
551
+ <p>Las cargas están limitadas a %{upload_file_limit} archivos, %{upload_size_limit} MB cada uno.</p>
552
+ local_upload_html: |
553
+ <p>Puede agregar uno o más archivos para asociar con esta obra.</p>
554
+ <p>Las cargas están limitadas a %{upload_file_limit} archivos, %{upload_size_limit} MB cada uno.</p>
552
555
  form_member_of_collections:
553
556
  actions:
554
557
  remove: Eliminar de la colección
@@ -549,7 +549,10 @@ fr:
549
549
  répondre à votre demande. Si vous rencontrez des erreurs de
550
550
  téléchargement depuis le nuage, faites-nous savoir via le
551
551
  %{contact_href}.</p>
552
- local_upload_html: "<p>Vous pouvez ajouter un ou plusieurs fichiers à associer à ce travail.</p>"
552
+ <p>Les téléchargements sont limités à %{upload_file_limit} fichiers de %{upload_size_limit} Mo chacun.</p>
553
+ local_upload_html: |
554
+ <p>Vous pouvez ajouter un ou plusieurs fichiers à associer à ce travail.</p>
555
+ <p>Les téléchargements sont limités à %{upload_file_limit} fichiers de %{upload_size_limit} Mo chacun.</p>
553
556
  form_member_of_collections:
554
557
  actions:
555
558
  remove: Supprimer de la collection
@@ -548,7 +548,10 @@ it:
548
548
  periodo di tempo, il provider di cloud potrebbe non essere in grado di
549
549
  accogliere la tua richiesta. Se si verificano errori di caricamento
550
550
  dalla nube, fateci sapere tramite %{contact_href}.</p>
551
- local_upload_html: "<p possibile aggiungere uno o più file da associare a questo lavoro.</p>"
551
+ <p>I caricamenti sono limitati a %{upload_file_limit} file, %{upload_size_limit} MB ciascuno.</p>
552
+ local_upload_html: |
553
+ <p>È possibile aggiungere uno o più file da associare a questo lavoro.</p>
554
+ <p>I caricamenti sono limitati a %{upload_file_limit} file, %{upload_size_limit} MB ciascuno.</p>
552
555
  form_member_of_collections:
553
556
  actions:
554
557
  remove: Rimuovi dalla raccolta
@@ -1306,7 +1309,7 @@ it:
1306
1309
  restore: Ripristina la versione precedente
1307
1310
  restore_from: Ripristina da
1308
1311
  save: Salva revisione
1309
- save_your_note: Devi fare clic su & quot; Salva revisione & quot; per ripristinare una versione precedente di questo file
1312
+ save_your_note: Devi fare clic su "Salva revisione" per ripristinare una versione precedente di questo file
1310
1313
  upload: Carica nuova versione
1311
1314
  help:
1312
1315
  header: Supporto utente
@@ -542,8 +542,15 @@ pt-BR:
542
542
  add_folder: Adicionar pasta
543
543
  cancel_upload: Cancelar upload
544
544
  dropzone: Largue os arquivos aqui.
545
- local_upload_browse_everything_html: "<p>Você pode associar um ou mais arquivos a esta obra. Associe arquivos de seu sistema local ou um provedor de nuvem.</p> <p>Note que se você carregar uma grande quantidade de arquivos dentro de um curto período de tempo, o fornecedor de nuvem pode não ser capaz de acomodar a sua solicitação. Se você tiver algum erro ao carregar da nuvem, avise-nos através do %{contact_href}.<p>"
546
- local_upload_html: "<p>Você pode acrescentar um ou mais arquivos para associar a esta obra.</p>"
545
+ local_upload_browse_everything_html: |
546
+ <p>Você pode associar um ou mais arquivos a esta obra. Associe arquivos de seu sistema local ou um provedor de nuvem.</p>
547
+ <p>Note que se você carregar uma grande quantidade de arquivos dentro de um curto período de tempo,
548
+ o fornecedor de nuvem pode não ser capaz de acomodar a sua solicitação. Se você tiver algum erro ao carregar
549
+ da nuvem, avise-nos através do %{contact_href}.<p>
550
+ <p>Os uploads são limitados a %{upload_file_limit} arquivos, %{upload_size_limit} MB cada.</p>
551
+ local_upload_html: |
552
+ <p>Você pode acrescentar um ou mais arquivos para associar a esta obra.</p>
553
+ <p>Os uploads são limitados a %{upload_file_limit} arquivos, %{upload_size_limit} MB cada.</p>
547
554
  form_member_of_collections:
548
555
  actions:
549
556
  remove: Remover da coleção
@@ -546,7 +546,10 @@ zh:
546
546
  <p>您可以添加一个或多个文件与该工作相关联。</p>
547
547
  <p>请注意如果您在短时间内上传了大量文件, 云提供商可能不能满足您的请求。
548
548
  如果您上传中遇到问题,请用%{contact_href}报告。</p>
549
- local_upload_html: "<p>您可以添加一个或多个文件与该工作相关联。</p>"
549
+ <p>上传限制为 %{upload_file_limit} 个文件,每个文件 %{upload_size_limit} MB。</p>
550
+ local_upload_html: |
551
+ <p>您可以添加一个或多个文件与该工作相关联。</p>
552
+ <p>上传限制为 %{upload_file_limit} 个文件,每个文件 %{upload_size_limit} MB。</p>
550
553
  form_member_of_collections:
551
554
  actions:
552
555
  remove: 从收藏中删除
@@ -104,7 +104,6 @@ services:
104
104
 
105
105
  postgres:
106
106
  image: postgres:latest
107
- restart: always
108
107
  env_file:
109
108
  - .koppie/.env
110
109
  ports:
data/docker-compose.yml CHANGED
@@ -99,7 +99,6 @@ services:
99
99
 
100
100
  postgres:
101
101
  image: postgres:latest
102
- restart: always
103
102
  environment:
104
103
  - POSTGRES_USER=hyrax_user
105
104
  - POSTGRES_PASSWORD=hyrax_password
@@ -50,7 +50,7 @@ The Samvera community is here to help. Please see our [support guide](../.github
50
50
  # Getting started
51
51
 
52
52
  This document contains instructions specific to setting up an app with __Hyrax
53
- v4.0.0.rc2__. If you are looking for instructions on installing a different
53
+ v4.0.0__. If you are looking for instructions on installing a different
54
54
  version, be sure to select the appropriate branch or tag from the drop-down
55
55
  menu above.
56
56
 
@@ -139,11 +139,11 @@ Starting up Redis will depend on your operating system, and may in fact already
139
139
 
140
140
  ## Rails
141
141
 
142
- Hyrax requires Rails 5. We recommend the latest Rails 5.2 release.
142
+ Hyrax requires Rails 6. We recommend the latest Rails 6.1 release.
143
143
 
144
144
  ```
145
145
  # If you don't already have Rails at your disposal...
146
- gem install rails -v 5.2.6
146
+ gem install rails -v 6.1.7.3
147
147
  ```
148
148
 
149
149
  ### JavaScript runtime
@@ -159,7 +159,7 @@ NOTE: The steps need to be done in order to create a new Hyrax based app.
159
159
  Generate a new Rails application using the template.
160
160
 
161
161
  ```
162
- rails _6.1.7.3_ new my_app -m https://raw.githubusercontent.com/samvera/hyrax/hyrax-v4.0.0.rc2/template.rb
162
+ rails _6.1.7.3_ new my_app -m https://raw.githubusercontent.com/samvera/hyrax/hyrax-v4.0.0/template.rb
163
163
  ```
164
164
 
165
165
  Generating a new Rails application using Hyrax's template above takes cares of a number of steps for you, including:
data/hyrax.gemspec CHANGED
@@ -41,6 +41,7 @@ SUMMARY
41
41
  spec.add_dependency 'browse-everything', '>= 0.16', '< 2.0'
42
42
  spec.add_dependency 'carrierwave', '~> 1.0'
43
43
  spec.add_dependency 'clipboard-rails', '~> 1.5'
44
+ spec.add_dependency 'connection_pool', '~> 2.4'
44
45
  spec.add_dependency 'draper', '~> 4.0'
45
46
  spec.add_dependency 'dry-events', '~> 0.2.0'
46
47
  spec.add_dependency 'dry-equalizer', '~> 0.2'
@@ -6,6 +6,7 @@ analytics:
6
6
  analytics_id: <%= ENV['GOOGLE_ANALYTICS_ID'] %>
7
7
  app_name: <%= ENV['GOOGLE_OAUTH_APP_NAME'] %>
8
8
  app_version: <%= ENV['GOOGLE_OAUTH_APP_VERSION'] %>
9
+ privkey_value: <%= ENV['GOOGLE_OAUTH_PRIVATE_KEY_VALUE'] %>
9
10
  privkey_path: <%= ENV['GOOGLE_OAUTH_PRIVATE_KEY_PATH'] %>
10
11
  privkey_secret: <%= ENV['GOOGLE_OAUTH_PRIVATE_KEY_SECRET'] %>
11
12
  client_email: <%= ENV['GOOGLE_OAUTH_CLIENT_EMAIL'] %>
@@ -1,4 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
  require 'redis'
3
+ require 'connection_pool'
3
4
  config = YAML.safe_load(ERB.new(IO.read(Rails.root.join('config', 'redis.yml'))).result)[Rails.env].with_indifferent_access
4
- Redis.current = Redis.new(config.merge(thread_safe: true))
5
+
6
+ size = ENV.fetch("HYRAX_REDIS_POOL_SIZE", 5)
7
+ timeout = ENV.fetch("HYRAX_REDIS_TIMEOUT", 5)
8
+
9
+ Hyrax.config.redis_connection =
10
+ ConnectionPool::Wrapper.new(size: size, timeout: timeout) { Redis.new(config) }
@@ -393,6 +393,11 @@ module Hyrax
393
393
  @banner_image ||= 'https://user-images.githubusercontent.com/101482/29949206-ffa60d2c-8e67-11e7-988d-4910b8787d56.jpg'
394
394
  end
395
395
 
396
+ attr_writer :breadcrumb_builder
397
+ def breadcrumb_builder
398
+ @breadcrumb_builder ||= Hyrax::BootstrapBreadcrumbsBuilder
399
+ end
400
+
396
401
  ##
397
402
  # @return [Boolean]
398
403
  def disable_wings
@@ -611,9 +616,10 @@ module Hyrax
611
616
  @persistent_hostpath ||= "http://localhost/files/"
612
617
  end
613
618
 
619
+ attr_accessor :redis_connection
614
620
  attr_writer :redis_namespace
615
621
  def redis_namespace
616
- @redis_namespace ||= "hyrax"
622
+ @redis_namespace ||= ENV.fetch("HYRAX_REDIS_NAMESPACE", "hyrax")
617
623
  end
618
624
 
619
625
  attr_writer :libreoffice_path
@@ -7,9 +7,11 @@ module Hyrax
7
7
  class << self
8
8
  # @return [Fixnum, nil] the id of the event, or `nil` on failure(?!)
9
9
  def create(action, timestamp)
10
- event_id = instance.incr("events:latest_id")
11
- instance.hmset("events:#{event_id}", "action", action, "timestamp", timestamp)
12
- event_id
10
+ instance.then do |redis|
11
+ event_id = redis.incr("events:latest_id")
12
+ redis.hmset("events:#{event_id}", "action", action, "timestamp", timestamp)
13
+ event_id
14
+ end
13
15
  rescue Redis::CommandError => e
14
16
  logger.error("unable to create event: #{e}")
15
17
  nil
@@ -23,12 +25,16 @@ module Hyrax
23
25
  #
24
26
  # @return [Redis]
25
27
  def instance
26
- if Redis.current.is_a? Redis::Namespace
27
- Redis.current.namespace = namespace
28
+ connection = Hyrax.config.redis_connection || Redis.current
29
+
30
+ if connection.is_a? Redis::Namespace
31
+ connection.namespace = namespace
32
+ connection
33
+ elsif connection == Redis.current
34
+ Redis.current = Redis::Namespace.new(namespace, redis: connection)
28
35
  else
29
- Redis.current = Redis::Namespace.new(namespace, redis: Redis.current)
36
+ connection
30
37
  end
31
- Redis.current
32
38
  end
33
39
 
34
40
  ##
@@ -44,11 +50,13 @@ module Hyrax
44
50
  #
45
51
  # @return [Enumerable<Hash<Symbol, String>>]
46
52
  def fetch(size)
47
- RedisEventStore.instance.lrange(@key, 0, size).map do |event_id|
48
- {
49
- action: RedisEventStore.instance.hget("events:#{event_id}", "action"),
50
- timestamp: RedisEventStore.instance.hget("events:#{event_id}", "timestamp")
51
- }
53
+ Hyrax::RedisEventStore.instance.then do |redis|
54
+ redis.lrange(@key, 0, size).map do |event_id|
55
+ {
56
+ action: redis.hget("events:#{event_id}", "action"),
57
+ timestamp: redis.hget("events:#{event_id}", "timestamp")
58
+ }
59
+ end
52
60
  end
53
61
  rescue Redis::CommandError, Redis::CannotConnectError
54
62
  RedisEventStore.logger.error("unable to fetch event: #{@key}")
@@ -62,7 +70,7 @@ module Hyrax
62
70
  #
63
71
  # @return [Integer, nil] the value successfully pushed; or `nil` on failure(!?)
64
72
  def push(value)
65
- RedisEventStore.instance.lpush(@key, value)
73
+ Hyrax::RedisEventStore.instance.then { |r| r.lpush(@key, value) }
66
74
  rescue Redis::CommandError, Redis::CannotConnectError
67
75
  RedisEventStore.logger.error("unable to push event: #{@key}")
68
76
  nil
data/lib/hyrax/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Hyrax
3
- VERSION = '4.0.0.rc2'
3
+ VERSION = '4.0.0'
4
4
  end
data/template.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  # Hack for https://github.com/rails/rails/issues/35153
3
3
  gsub_file 'Gemfile', /^gem ["']sqlite3["']$/, 'gem "sqlite3", "~> 1.3.0"'
4
- gem 'hyrax', '4.0.0.rc2'
4
+ gem 'hyrax', '4.0.0'
5
5
  run 'bundle install'
6
6
  generate 'hyrax:install', '-f'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hyrax
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0.rc2
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Coyne
@@ -14,7 +14,7 @@ authors:
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
- date: 2023-05-01 00:00:00.000000000 Z
17
+ date: 2023-05-30 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: rails
@@ -162,6 +162,20 @@ dependencies:
162
162
  - - "~>"
163
163
  - !ruby/object:Gem::Version
164
164
  version: '1.5'
165
+ - !ruby/object:Gem::Dependency
166
+ name: connection_pool
167
+ requirement: !ruby/object:Gem::Requirement
168
+ requirements:
169
+ - - "~>"
170
+ - !ruby/object:Gem::Version
171
+ version: '2.4'
172
+ type: :runtime
173
+ prerelease: false
174
+ version_requirements: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - "~>"
177
+ - !ruby/object:Gem::Version
178
+ version: '2.4'
165
179
  - !ruby/object:Gem::Dependency
166
180
  name: draper
167
181
  requirement: !ruby/object:Gem::Requirement
@@ -3292,9 +3306,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
3292
3306
  version: '2.7'
3293
3307
  required_rubygems_version: !ruby/object:Gem::Requirement
3294
3308
  requirements:
3295
- - - ">"
3309
+ - - ">="
3296
3310
  - !ruby/object:Gem::Version
3297
- version: 1.3.1
3311
+ version: '0'
3298
3312
  requirements: []
3299
3313
  rubygems_version: 3.4.12
3300
3314
  signing_key: