geoblacklight_sidecar_images 1.1.2 → 2.0.0.pre.alpha.1
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/.github/workflows/ruby.yml +60 -58
- data/Gemfile +5 -23
- data/README.md +66 -58
- data/Rakefile +13 -1
- data/app/controllers/geoblacklight_sidecar_images/application_controller.rb +0 -1
- data/app/helpers/geoblacklight_sidecar_images/application_helper.rb +15 -0
- data/app/jobs/geoblacklight_sidecar_images/store_image_job.rb +11 -4
- data/app/models/concerns/geoblacklight_sidecar_images/solr_document_behavior.rb +24 -0
- data/app/models/concerns/wms_rewrite_concern.rb +13 -4
- data/app/models/sidecar_image_transition.rb +3 -1
- data/app/models/solr_document_sidecar.rb +8 -3
- data/app/services/geoblacklight_sidecar_images/image_service/dynamic_map_layer.rb +2 -6
- data/app/services/geoblacklight_sidecar_images/image_service/esri_thumbnail.rb +11 -0
- data/app/services/geoblacklight_sidecar_images/image_service/image_map_layer.rb +2 -8
- data/app/services/geoblacklight_sidecar_images/image_service/tiled_map_layer.rb +2 -6
- data/app/services/geoblacklight_sidecar_images/image_service/wms.rb +13 -13
- data/app/services/geoblacklight_sidecar_images/image_service.rb +105 -57
- data/db/migrate/20180118203155_create_solr_document_sidecars.rb +3 -1
- data/db/migrate/20180118203519_create_sidecar_image_transitions.rb +3 -6
- data/geoblacklight_sidecar_images.gemspec +8 -11
- data/lib/generators/geoblacklight_sidecar_images/config_generator.rb +1 -11
- data/lib/generators/geoblacklight_sidecar_images/install_generator.rb +63 -12
- data/lib/generators/geoblacklight_sidecar_images/models_generator.rb +2 -36
- data/lib/generators/geoblacklight_sidecar_images/templates/views/catalog/_index_split_default.html.erb +5 -12
- data/lib/geoblacklight_sidecar_images/engine.rb +21 -0
- data/lib/geoblacklight_sidecar_images/field_map.rb +50 -0
- data/lib/geoblacklight_sidecar_images/ogm_thumbnail.rb +35 -0
- data/lib/geoblacklight_sidecar_images/version.rb +1 -1
- data/lib/geoblacklight_sidecar_images.rb +3 -1
- data/lib/tasks/geoblacklight_sidecar_images_tasks.rake +75 -58
- data/spec/helpers/application_helper_spec.rb +32 -0
- data/spec/jobs/store_image_job_spec.rb +4 -3
- data/spec/lib/geoblacklight_sidecar_images/field_map_spec.rb +25 -0
- data/spec/lib/geoblacklight_sidecar_images/ogm_thumbnail_spec.rb +27 -0
- data/spec/lib/tasks/geoblacklight_sidecar_images_spec.rb +16 -15
- data/spec/models/solr_document_sidecar_spec.rb +16 -0
- data/spec/services/image_service_protocol_spec.rb +30 -0
- data/spec/services/image_service_spec.rb +23 -24
- data/spec/spec_helper.rb +24 -24
- data/spec/test_app_templates/Gemfile.extra +4 -2
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +52 -9
- data/template.rb +7 -5
- metadata +65 -83
- data/app/mailers/geoblacklight_sidecar_images/application_mailer.rb +0 -8
- data/app/views/layouts/geoblacklight_sidecar_images/application.html.erb +0 -14
- data/lib/generators/geoblacklight_sidecar_images/helpers_generator.rb +0 -21
- data/lib/generators/geoblacklight_sidecar_images/templates/helpers/blacklight/layout_helper_behavior.rb +0 -110
- /data/app/models/{application_record.rb → geoblacklight_sidecar_images/application_record.rb} +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ab3fbb4fea06b510373aacfcac11b0a9941c088140939a0f58f5cfbd5e7617a2
|
|
4
|
+
data.tar.gz: 969301942ddb0601b14e2cc05d2d59708a71abda75dd2349f705c918d4007fe2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d2577da5f702ede9ac232880d3f9d3114aea42c57c34a256c345db46bd075dc6c4729fc10a25dc4f37f4618cb262b139c859ef1142f8b3b62caed497a64f652c
|
|
7
|
+
data.tar.gz: ab4297ae1e5c68b9adc5fdb81831f2d415c480b52f67baeb33bd65006fcd38fb34b9ce7e103646361eb504b58e6d6c39801cad67042f9474c04c208d3c554263
|
data/.github/workflows/ruby.yml
CHANGED
|
@@ -4,74 +4,76 @@ on:
|
|
|
4
4
|
push:
|
|
5
5
|
branches:
|
|
6
6
|
- main
|
|
7
|
-
-
|
|
7
|
+
- develop
|
|
8
8
|
pull_request:
|
|
9
9
|
|
|
10
10
|
jobs:
|
|
11
11
|
linter:
|
|
12
12
|
runs-on: ubuntu-latest
|
|
13
|
-
strategy:
|
|
14
|
-
matrix:
|
|
15
|
-
bundler_version: [2.2.8]
|
|
16
|
-
faraday_version: ['~> 2.0']
|
|
17
13
|
steps:
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
run: bundle _${{ matrix.bundler_version }}_ install
|
|
27
|
-
env:
|
|
28
|
-
FARADAY_VERSION: ${{ matrix.faraday_version }}
|
|
29
|
-
- name: Run linter
|
|
30
|
-
run: bundle exec standardrb
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- name: Set up Ruby
|
|
16
|
+
uses: ruby/setup-ruby@v1
|
|
17
|
+
with:
|
|
18
|
+
ruby-version: "3.3"
|
|
19
|
+
bundler-cache: true
|
|
20
|
+
- name: Run linter
|
|
21
|
+
run: bundle exec standardrb
|
|
31
22
|
|
|
32
23
|
test:
|
|
33
24
|
runs-on: ubuntu-latest
|
|
34
25
|
strategy:
|
|
26
|
+
fail-fast: false
|
|
35
27
|
matrix:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
28
|
+
include:
|
|
29
|
+
- ruby_version: "3.3"
|
|
30
|
+
rails_version: "7.2.2"
|
|
31
|
+
geoblacklight_version: "~> 4.4"
|
|
32
|
+
engine_cart_options: "--skip-git --skip-listen --skip-spring --skip-keeps --skip-action-cable --skip-test --skip-docker --skip-rubocop --skip-brakeman --skip-kamal --skip-solid --skip-bundle"
|
|
33
|
+
- ruby_version: "3.4"
|
|
34
|
+
rails_version: "8.1.3"
|
|
35
|
+
geoblacklight_version: "~> 5.3"
|
|
36
|
+
engine_cart_options: "--skip-docker --skip-action-cable --skip-rubocop --skip-brakeman --skip-kamal --skip-solid --skip-thruster --skip-bundle -a propshaft --css bootstrap --js importmap"
|
|
37
|
+
- ruby_version: "4.0"
|
|
38
|
+
rails_version: "8.1.3"
|
|
39
|
+
geoblacklight_version: "6.0.0.pre.alpha.7"
|
|
40
|
+
engine_cart_options: "--skip-docker --skip-action-cable --skip-rubocop --skip-brakeman --skip-kamal --skip-solid --skip-thruster --skip-bundle -a propshaft --css bootstrap --js importmap"
|
|
40
41
|
|
|
41
|
-
name:
|
|
42
|
+
name: ruby ${{ matrix.ruby_version }} / rails ${{ matrix.rails_version }} / gbl ${{ matrix.geoblacklight_version }}
|
|
42
43
|
steps:
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
44
|
+
- uses: actions/checkout@v4
|
|
45
|
+
- name: Set up Ruby
|
|
46
|
+
uses: ruby/setup-ruby@v1
|
|
47
|
+
with:
|
|
48
|
+
ruby-version: ${{ matrix.ruby_version }}
|
|
49
|
+
- name: Install libvips and ImageMagick
|
|
50
|
+
run: sudo apt-get update && sudo apt-get install -y libvips42 imagemagick
|
|
51
|
+
- name: Create Solr container
|
|
52
|
+
run: docker run -d -p 8983:8983 geoblacklight/solr:8.9-v1.0.0 server/scripts/ci-start.sh
|
|
53
|
+
- name: Install dependencies
|
|
54
|
+
run: bundle install
|
|
55
|
+
env:
|
|
56
|
+
RAILS_VERSION: ${{ matrix.rails_version }}
|
|
57
|
+
GEOBLACKLIGHT_VERSION: ${{ matrix.geoblacklight_version }}
|
|
58
|
+
- name: Setup Yarn
|
|
59
|
+
run: exec "yarnpkg"
|
|
60
|
+
- name: Load config into solr
|
|
61
|
+
run: |
|
|
62
|
+
cd solr/conf
|
|
63
|
+
zip -1 -r solr_config.zip ./*
|
|
64
|
+
curl -H "Content-type:application/octet-stream" --data-binary @solr_config.zip "http://solr:SolrRocks@127.0.0.1:8983/solr/admin/configs?action=UPLOAD&name=blacklight"
|
|
65
|
+
curl -H 'Content-type: application/json' http://solr:SolrRocks@127.0.0.1:8983/api/collections/ -d '{create: {name: blacklight-core, config: blacklight, numShards: 1}}'
|
|
66
|
+
- name: Run tests
|
|
67
|
+
run: bundle exec rake ci
|
|
68
|
+
env:
|
|
69
|
+
RAILS_VERSION: ${{ matrix.rails_version }}
|
|
70
|
+
GEOBLACKLIGHT_VERSION: ${{ matrix.geoblacklight_version }}
|
|
71
|
+
ENGINE_CART_RAILS_OPTIONS: ${{ matrix.engine_cart_options }}
|
|
72
|
+
SOLR_URL: http://solr:SolrRocks@localhost:8983/solr/blacklight-core
|
|
73
|
+
BUNDLE_SPECIFIC_PLATFORM: "true"
|
|
74
|
+
- name: Upload coverage artifacts
|
|
75
|
+
uses: actions/upload-artifact@v4
|
|
76
|
+
if: always()
|
|
77
|
+
with:
|
|
78
|
+
name: coverage-ruby${{ matrix.ruby_version }}-rails${{ matrix.rails_version }}
|
|
79
|
+
path: coverage/
|
data/Gemfile
CHANGED
|
@@ -1,27 +1,13 @@
|
|
|
1
1
|
source "https://rubygems.org"
|
|
2
2
|
|
|
3
|
-
# Declare your gem's dependencies in geoblacklight_sidecar_images.gemspec.
|
|
4
|
-
# Bundler will treat runtime dependencies like base dependencies, and
|
|
5
|
-
# development dependencies will be added by default to the :development group.
|
|
6
|
-
|
|
7
|
-
# Please see geoblacklight_sidecar_images.gemspec for dependency information.
|
|
8
3
|
gemspec
|
|
9
4
|
|
|
10
|
-
#
|
|
11
|
-
|
|
12
|
-
# Git. Remember to move these dependencies to your gemspec before releasing
|
|
13
|
-
# your gem to rubygems.org.
|
|
14
|
-
|
|
15
|
-
group :development, :test do
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
# To use a debugger
|
|
19
|
-
# gem 'byebug', group: [:development, :test]
|
|
5
|
+
# Ruby 4 removed cgi from default gems
|
|
6
|
+
gem "cgi" if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("4.0.0")
|
|
20
7
|
|
|
21
8
|
# BEGIN ENGINE_CART BLOCK
|
|
22
9
|
# engine_cart: 1.2.0
|
|
23
10
|
# engine_cart stanza: 0.10.0
|
|
24
|
-
# the below comes from engine_cart, a gem used to test this Rails engine gem in the context of a Rails app.
|
|
25
11
|
file = File.expand_path("Gemfile", ENV["ENGINE_CART_DESTINATION"] || ENV["RAILS_ROOT"] || File.expand_path(".internal_test_app", File.dirname(__FILE__)))
|
|
26
12
|
|
|
27
13
|
if File.exist?(file)
|
|
@@ -33,8 +19,7 @@ if File.exist?(file)
|
|
|
33
19
|
end
|
|
34
20
|
else
|
|
35
21
|
Bundler.ui.warn "[EngineCart] Unable to find test application dependencies in #{file}, using placeholder dependencies"
|
|
36
|
-
gem "geoblacklight", ">=
|
|
37
|
-
gem "mini_magick", "~> 4.9.4"
|
|
22
|
+
gem "geoblacklight", ENV["GEOBLACKLIGHT_VERSION"] || ">= 4.0"
|
|
38
23
|
gem "image_processing", "~> 1.6"
|
|
39
24
|
gem "statesman", ">= 3.4"
|
|
40
25
|
gem "marcel", ">= 1.0"
|
|
@@ -48,9 +33,6 @@ else
|
|
|
48
33
|
end
|
|
49
34
|
end
|
|
50
35
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
eval File.read("spec/test_app_templates/Gemfile.extra"), nil, "spec/test_app_templates/Gemfile.extra"
|
|
54
|
-
# rubocop:enable Security/Eval
|
|
55
|
-
end
|
|
36
|
+
extra = File.expand_path("spec/test_app_templates/Gemfile.extra", File.dirname(__FILE__))
|
|
37
|
+
eval_gemfile extra if File.exist?(extra)
|
|
56
38
|
# END ENGINE_CART BLOCK
|
data/README.md
CHANGED
|
@@ -12,34 +12,34 @@ Store local copies of remote imagery in GeoBlacklight.
|
|
|
12
12
|
* [Development](#development)
|
|
13
13
|
|
|
14
14
|
## Description
|
|
15
|
+
|
|
15
16
|
This GeoBlacklight plugin captures remote images from geographic web services and saves them locally. It borrows the concept of a [SolrDocumentSidecar](https://github.com/projectblacklight/spotlight/blob/master/app/models/spotlight/solr_document_sidecar.rb) from [Spotlight](https://github.com/projectblacklight/spotlight), to have an ActiveRecord-based "sidecar" to match each non-AR SolrDocument. This allows us to use [ActiveStorage](https://github.com/rails/rails/tree/master/activestorage) to attach images to our solr documents.
|
|
16
17
|
|
|
17
18
|
### Example Screenshot
|
|
19
|
+
|
|
18
20
|

|
|
19
21
|
|
|
20
22
|
## Requirements
|
|
21
23
|
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
24
|
+
* Ruby >= 3.3 (CI also runs on 3.4 and 4.0)
|
|
25
|
+
* Rails >= 7.2, < 9 (tested on 7.2 with GeoBlacklight 4 and 8.1 with GeoBlacklight 5/6)
|
|
26
|
+
* GeoBlacklight 4.x, 5.x, or 6.x
|
|
27
|
+
* [libvips](https://www.libvips.org/) (Rails default) or [ImageMagick](https://github.com/ImageMagick/ImageMagick)
|
|
25
28
|
|
|
26
29
|
### Suggested
|
|
27
30
|
|
|
28
|
-
* Background
|
|
29
|
-
|
|
30
|
-
[Sidekiq](https://github.com/mperham/sidekiq) is an excellent choice if you need an opinion.
|
|
31
|
+
* Background job processor — [Solid Queue](https://github.com/rails/solid_queue) (Rails 8) or [Sidekiq](https://github.com/sidekiq/sidekiq)
|
|
31
32
|
|
|
32
33
|
## Installation
|
|
33
34
|
|
|
34
|
-
### Existing GeoBlacklight
|
|
35
|
-
|
|
36
|
-
GeoBlacklight v4 with Aardvark metadata / Add the gem to your Gemfile.
|
|
35
|
+
### Existing GeoBlacklight instance
|
|
37
36
|
|
|
38
37
|
```ruby
|
|
39
|
-
gem "geoblacklight_sidecar_images", "~>
|
|
38
|
+
gem "geoblacklight_sidecar_images", "~> 2.0"
|
|
40
39
|
```
|
|
41
40
|
|
|
42
|
-
GeoBlacklight v3 with GBL
|
|
41
|
+
GeoBlacklight v3 with GBL 1.0 metadata still uses the 0.9.x series:
|
|
42
|
+
|
|
43
43
|
```ruby
|
|
44
44
|
gem "geoblacklight_sidecar_images", "~> 0.9.1", "< 1.0"
|
|
45
45
|
```
|
|
@@ -50,13 +50,15 @@ Run the generator.
|
|
|
50
50
|
$ bin/rails generate geoblacklight_sidecar_images:install
|
|
51
51
|
```
|
|
52
52
|
|
|
53
|
+
Use `--skip-views` on GeoBlacklight 5/6 apps that render results with ViewComponents rather than the GBL 4 split catalog partial. Use `--skip-assets` when the host is not using Sprockets.
|
|
54
|
+
|
|
53
55
|
Run the database migration.
|
|
54
56
|
|
|
55
57
|
```bash
|
|
56
58
|
$ bin/rails db:migrate
|
|
57
59
|
```
|
|
58
60
|
|
|
59
|
-
Complete any necessary [Active Storage setup](https://
|
|
61
|
+
Complete any necessary [Active Storage setup](https://guides.rubyonrails.org/active_storage_overview.html#setup) steps, for example:
|
|
60
62
|
|
|
61
63
|
1. Add a config/storage.yml file
|
|
62
64
|
|
|
@@ -66,23 +68,24 @@ local:
|
|
|
66
68
|
root: <%= Rails.root.join("storage") %>
|
|
67
69
|
```
|
|
68
70
|
|
|
69
|
-
2. Add config/environments declarations, development.rb for example:
|
|
71
|
+
2. Add config/environments declarations, development.rb for example:
|
|
70
72
|
|
|
71
73
|
```
|
|
72
74
|
# Store uploaded files on the local file system (see config/storage.yml for options)
|
|
73
75
|
config.active_storage.service = :local
|
|
74
76
|
```
|
|
75
77
|
|
|
76
|
-
|
|
78
|
+
The install generator appends Sidecar Images settings to `config/settings.yml` (`GBLSI_THUMBNAIL_FIELD`, optional GeoServer proxy keys, and optional `GBLSI_OGM_API_URL`). Leave the GeoServer URLs blank unless you need authenticated local WMS harvesting. Leave `GBLSI_OGM_API_URL` blank unless you want to skip harvest and render OpenGeoMetadata API thumbnails instead.
|
|
77
79
|
|
|
78
|
-
|
|
80
|
+
`SolrDocument#sidecar` is included by the engine. You do not need to copy a method into `app/models/solr_document.rb`. If you are upgrading from 1.x, you can remove the generator-injected `sidecar` method from that file.
|
|
81
|
+
|
|
82
|
+
### New GeoBlacklight instance
|
|
79
83
|
|
|
80
84
|
```bash
|
|
81
85
|
$ rails new app-name -m https://raw.githubusercontent.com/geoblacklight/geoblacklight_sidecar_images/develop/template.rb
|
|
82
|
-
|
|
83
86
|
```
|
|
84
87
|
|
|
85
|
-
### Ingest
|
|
88
|
+
### Ingest test documents
|
|
86
89
|
|
|
87
90
|
```bash
|
|
88
91
|
# Run your GBL instance
|
|
@@ -98,9 +101,11 @@ bundle exec rake gblsci:sample_data:seed
|
|
|
98
101
|
|
|
99
102
|
### Harvest images
|
|
100
103
|
|
|
104
|
+
Harvest is only needed when you store thumbnails in Active Storage. If `GBLSI_OGM_API_URL` is set, skip these tasks and see [OpenGeoMetadata API thumbnails](#opengeometadata-api-thumbnails).
|
|
105
|
+
|
|
101
106
|
#### Harvest all images
|
|
102
107
|
|
|
103
|
-
Spawns background jobs to harvest images for all documents in your Solr index.
|
|
108
|
+
Spawns background jobs to harvest images for all documents in your Solr index (paginated with Solr cursorMarks).
|
|
104
109
|
|
|
105
110
|
```bash
|
|
106
111
|
bundle exec rake gblsci:images:harvest_all
|
|
@@ -141,40 +146,38 @@ We use a state machine library to track success/failure of our harvest tasks. Th
|
|
|
141
146
|
SolrDocumentSidecar.in_state(:succeeded) => [#<SolrDocumentSidecar:0x0000000170697960 ... ]
|
|
142
147
|
SolrDocumentSidecar.image.attached? => false
|
|
143
148
|
SolrDocumentSidecar.image_state.current_state => "placeheld"
|
|
144
|
-
SolrDocumentSidecar.image_state.last_transition => #<SidecarImageTransition id: 207, to_state: "placeheld", metadata: {"solr_doc_id"=>"stanford-cg357zz0321",
|
|
149
|
+
SolrDocumentSidecar.image_state.last_transition => #<SidecarImageTransition id: 207, to_state: "placeheld", metadata: {"solr_doc_id"=>"stanford-cg357zz0321", ...>
|
|
145
150
|
```
|
|
146
151
|
|
|
147
152
|
### Destroy images
|
|
148
153
|
|
|
149
|
-
|
|
154
|
+
Destructive tasks require `CONFIRM=1`.
|
|
150
155
|
|
|
151
|
-
Remove
|
|
156
|
+
#### Remove everything
|
|
152
157
|
|
|
153
158
|
```bash
|
|
154
|
-
bundle exec rake gblsci:images:harvest_purge_all
|
|
159
|
+
CONFIRM=1 bundle exec rake gblsci:images:harvest_purge_all
|
|
155
160
|
```
|
|
156
161
|
|
|
157
162
|
#### Remove orphaned AR objects
|
|
158
163
|
|
|
159
|
-
Remove all sidecar objects and attached images for AR objects without a corresponding Solr document
|
|
160
|
-
|
|
161
164
|
```bash
|
|
162
|
-
bundle exec rake gblsci:images:harvest_purge_orphans
|
|
165
|
+
CONFIRM=1 bundle exec rake gblsci:images:harvest_purge_orphans
|
|
163
166
|
```
|
|
164
167
|
|
|
165
168
|
#### Remove a batch
|
|
166
169
|
|
|
167
|
-
Remove sidecar objects and attached images via a CSV file of document ids
|
|
170
|
+
Remove sidecar objects and attached images via a CSV file of document ids at `tmp/destroy_batch.csv`.
|
|
168
171
|
|
|
169
172
|
```bash
|
|
170
|
-
bundle exec rake gblsci:images:harvest_destroy_batch
|
|
173
|
+
CONFIRM=1 bundle exec rake gblsci:images:harvest_destroy_batch
|
|
171
174
|
```
|
|
172
175
|
|
|
173
176
|
### Troubleshooting
|
|
174
177
|
|
|
175
178
|
#### Harvest report
|
|
176
179
|
|
|
177
|
-
Generate a CSV file of sidecar objects and associated image state
|
|
180
|
+
Generate a CSV file of sidecar objects and associated image state under `tmp/`.
|
|
178
181
|
|
|
179
182
|
```bash
|
|
180
183
|
bundle exec rake gblsci:images:harvest_report
|
|
@@ -197,63 +200,64 @@ If you add a thumbnail uri to your geoblacklight solr documents...
|
|
|
197
200
|
```json
|
|
198
201
|
{
|
|
199
202
|
...
|
|
200
|
-
"
|
|
201
|
-
"
|
|
202
|
-
"thumbnail_path_ss":"https://umedia.lib.umn.edu/sites/default/files/imagecache/square300/reference/562/image/jpeg/1089695.jpg",
|
|
203
|
-
"
|
|
203
|
+
"dct_format_s": "TIFF",
|
|
204
|
+
"dct_creator_sm": ["Minnesota. Department of Highways."],
|
|
205
|
+
"thumbnail_path_ss": "https://umedia.lib.umn.edu/sites/default/files/imagecache/square300/reference/562/image/jpeg/1089695.jpg",
|
|
206
|
+
"gbl_resourceClass_sm": ["Imagery"],
|
|
204
207
|
...
|
|
205
208
|
}
|
|
206
209
|
```
|
|
207
210
|
|
|
208
|
-
Then you can edit your GeoBlacklight settings.yml file to point at that solr field (Settings.GBLSI_THUMBNAIL_FIELD). Any docs in your index that have a value for that field will harvest the image at that URI instead of trying to retrieve an image via IIIF or the other web services.
|
|
211
|
+
Then you can edit your GeoBlacklight settings.yml file to point at that solr field (`Settings.GBLSI_THUMBNAIL_FIELD`). Any docs in your index that have a value for that field will harvest the image at that URI instead of trying to retrieve an image via IIIF or the other web services.
|
|
212
|
+
|
|
213
|
+
## OpenGeoMetadata API thumbnails
|
|
214
|
+
|
|
215
|
+
To skip harvest, Active Storage, and the sidecar state machine entirely, point views at the OpenGeoMetadata API. Thumbnails are loaded in the browser from:
|
|
216
|
+
|
|
217
|
+
`https://ogm.geo4lib.app/api/v1/resources/{id}/thumbnail`
|
|
218
|
+
|
|
219
|
+
Set the API root in `config/settings.yml`:
|
|
220
|
+
|
|
221
|
+
```yaml
|
|
222
|
+
GBLSI_OGM_API_URL: 'https://ogm.geo4lib.app/api/v1'
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
`sidecar_thumbnail_tag document` then renders an `img` for that URL (for example `stanford-mp692kw6192` → `/resources/stanford-mp692kw6192/thumbnail`). No sidecar row is created. Harvest rake tasks are unused in this mode.
|
|
226
|
+
|
|
227
|
+
The harvest/Active Storage path remains the default when `GBLSI_OGM_API_URL` is blank.
|
|
209
228
|
|
|
210
229
|
## View customization
|
|
211
230
|
|
|
212
|
-
Use basic Active Storage patterns to display imagery in your application.
|
|
231
|
+
Use basic Active Storage patterns, or the engine helper, to display imagery in your application.
|
|
213
232
|
|
|
214
|
-
### Example
|
|
233
|
+
### Example methods
|
|
215
234
|
|
|
216
235
|
```ruby
|
|
217
|
-
#
|
|
218
|
-
|
|
236
|
+
# Helper (available in host views). Uses the OGM API when GBLSI_OGM_API_URL is
|
|
237
|
+
# set; otherwise uses a harvested Active Storage attachment.
|
|
238
|
+
<%= sidecar_thumbnail_tag document, size: [200, 200] %>
|
|
219
239
|
|
|
220
|
-
#
|
|
240
|
+
# Harvested Active Storage (only when OGM API thumbnails are not enabled)
|
|
241
|
+
document.sidecar.image.attached?
|
|
221
242
|
document.sidecar.image.variable?
|
|
222
|
-
|
|
223
|
-
# Example image_tag with resize
|
|
224
243
|
<%= image_tag document.sidecar.image.variant(resize_to_fit: [100, 100]), {class: 'media-object'} %>
|
|
225
|
-
|
|
226
244
|
```
|
|
227
245
|
|
|
228
246
|
### Search results
|
|
229
247
|
|
|
230
|
-
|
|
248
|
+
On GeoBlacklight 4, the install generator can copy a catalog `_index_split_default.html.erb` partial. GeoBlacklight 5/6 apps should call `sidecar_thumbnail_tag` (or `document.sidecar.image`) from their result component instead of replacing Blacklight helpers.
|
|
231
249
|
|
|
232
250
|
### Show pages
|
|
233
251
|
|
|
234
252
|
Example for adding a thumbnail to the show page sidebar.
|
|
235
253
|
|
|
236
|
-
*catalog/_show_sidebar.html.erb*
|
|
237
|
-
|
|
238
254
|
```ruby
|
|
239
|
-
|
|
240
|
-
<% if @document.sidecar.image.attached? %>
|
|
241
|
-
<% if @document.sidecar.image.variable? %>
|
|
242
|
-
<div class="card">
|
|
243
|
-
<div class="card-header">Thumbnail</div>
|
|
244
|
-
<div class="card-body">
|
|
245
|
-
<%= image_tag @document.sidecar.image.variant(resize_to_fit: [200, 200]), {class: 'mr-3'} %>
|
|
246
|
-
</div>
|
|
247
|
-
</div>
|
|
248
|
-
<% end %>
|
|
249
|
-
<% end %>
|
|
250
|
-
|
|
255
|
+
<%= sidecar_thumbnail_tag @document, size: [200, 200], class: "mr-3" %>
|
|
251
256
|
```
|
|
252
257
|
|
|
253
258
|
## Development
|
|
254
259
|
|
|
255
260
|
```bash
|
|
256
|
-
|
|
257
261
|
# Run test suite
|
|
258
262
|
bundle exec rake ci
|
|
259
263
|
|
|
@@ -269,8 +273,12 @@ bundle exec rake gblsci:images:harvest_all
|
|
|
269
273
|
|
|
270
274
|
# Tail image service log file
|
|
271
275
|
tail -f log/image_service_development.log
|
|
276
|
+
```
|
|
272
277
|
|
|
278
|
+
Test against a specific stack with environment variables:
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
RAILS_VERSION=8.1.3 GEOBLACKLIGHT_VERSION="~> 5.3" bundle exec rake ci
|
|
273
282
|
```
|
|
274
283
|
|
|
275
284
|
[See Localhost Results](http://localhost:3000/?per_page=50&q=&search_field=all_fields)
|
|
276
|
-
|
data/Rakefile
CHANGED
|
@@ -22,11 +22,23 @@ RuboCop::RakeTask.new(:rubocop)
|
|
|
22
22
|
require "solr_wrapper/rake_task"
|
|
23
23
|
require "engine_cart/rake_task"
|
|
24
24
|
require "geoblacklight_sidecar_images/version"
|
|
25
|
+
require "fileutils"
|
|
26
|
+
|
|
27
|
+
# EngineCart bundles the test app before TestAppGenerator runs. Copy Bundler
|
|
28
|
+
# platform settings so Nokogiri uses the precompiled native gem.
|
|
29
|
+
Rake::Task["engine_cart:inject_gemfile_extras"].enhance do
|
|
30
|
+
dest = File.join(EngineCart.destination, ".bundle")
|
|
31
|
+
FileUtils.mkdir_p(dest)
|
|
32
|
+
File.write(File.join(dest, "config"), <<~YAML)
|
|
33
|
+
---
|
|
34
|
+
BUNDLE_FORCE_RUBY_PLATFORM: "false"
|
|
35
|
+
BUNDLE_SPECIFIC_PLATFORM: "true"
|
|
36
|
+
YAML
|
|
37
|
+
end
|
|
25
38
|
|
|
26
39
|
desc "Run test suite"
|
|
27
40
|
task ci: ["engine_cart:generate"] do
|
|
28
41
|
ENV["environment"] = "test"
|
|
29
|
-
# run the tests
|
|
30
42
|
Rake::Task["spec"].invoke
|
|
31
43
|
end
|
|
32
44
|
|
|
@@ -2,5 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
module GeoblacklightSidecarImages
|
|
4
4
|
module ApplicationHelper
|
|
5
|
+
def sidecar_thumbnail_tag(document, size: [200, 200], **options)
|
|
6
|
+
options = {alt: "", role: "presentation"}.merge(options)
|
|
7
|
+
|
|
8
|
+
ogm_url = document.try(:ogm_thumbnail_url)
|
|
9
|
+
return image_tag(ogm_url, options) if ogm_url.present?
|
|
10
|
+
|
|
11
|
+
sidecar = document.sidecar
|
|
12
|
+
return unless sidecar.image.attached?
|
|
13
|
+
|
|
14
|
+
if sidecar.image.variable?
|
|
15
|
+
image_tag sidecar.image.variant(resize_to_fit: size), options
|
|
16
|
+
else
|
|
17
|
+
image_tag sidecar.image, options
|
|
18
|
+
end
|
|
19
|
+
end
|
|
5
20
|
end
|
|
6
21
|
end
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "faraday"
|
|
4
|
+
|
|
3
5
|
module GeoblacklightSidecarImages
|
|
4
6
|
class StoreImageJob < ApplicationJob
|
|
5
|
-
queue_as :
|
|
7
|
+
queue_as :gblsci
|
|
8
|
+
|
|
9
|
+
retry_on Faraday::TimeoutError, wait: :polynomially_longer, attempts: 5
|
|
10
|
+
retry_on Faraday::ConnectionFailed, wait: :polynomially_longer, attempts: 3
|
|
11
|
+
discard_on Blacklight::Exceptions::RecordNotFound
|
|
6
12
|
|
|
7
13
|
def perform(solr_document_id)
|
|
8
14
|
document = Geoblacklight::SolrDocument.find(solr_document_id)
|
|
9
15
|
|
|
10
|
-
metadata = {
|
|
11
|
-
|
|
12
|
-
|
|
16
|
+
metadata = {
|
|
17
|
+
"solr_doc_id" => document.id,
|
|
18
|
+
"solr_version" => document.sidecar.version
|
|
19
|
+
}
|
|
13
20
|
|
|
14
21
|
document.sidecar.image_state.transition_to!(:queued, metadata)
|
|
15
22
|
GeoblacklightSidecarImages::ImageService.new(document).store
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module GeoblacklightSidecarImages
|
|
4
|
+
module SolrDocumentBehavior
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
def ogm_thumbnail_url
|
|
8
|
+
GeoblacklightSidecarImages::OgmThumbnail.url_for(self)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def sidecar
|
|
12
|
+
record = SolrDocumentSidecar.find_or_initialize_by(
|
|
13
|
+
document_id: id,
|
|
14
|
+
document_type: self.class.to_s
|
|
15
|
+
)
|
|
16
|
+
version = _source["_version_"]
|
|
17
|
+
if record.new_record? || record.version != version
|
|
18
|
+
record.version = version
|
|
19
|
+
record.save!
|
|
20
|
+
end
|
|
21
|
+
record
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module WmsRewriteConcern
|
|
4
|
-
extend
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
5
|
|
|
6
6
|
def viewer_endpoint
|
|
7
|
-
if local_restricted?
|
|
8
|
-
# replace wms prefix with cas authed proxy
|
|
7
|
+
if local_restricted? && geoserver_proxy_configured?
|
|
9
8
|
super.gsub(Settings.INSTITUTION_GEOSERVER_URL, Settings.PROXY_GEOSERVER_URL)
|
|
10
9
|
else
|
|
11
10
|
super
|
|
@@ -17,6 +16,16 @@ module WmsRewriteConcern
|
|
|
17
16
|
end
|
|
18
17
|
|
|
19
18
|
def local?
|
|
20
|
-
|
|
19
|
+
name = Settings.INSTITUTION_LOCAL_NAME.to_s
|
|
20
|
+
return false if name.blank?
|
|
21
|
+
|
|
22
|
+
fetch(GeoblacklightSidecarImages::FieldMap[:provider], "").casecmp(name).zero?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def geoserver_proxy_configured?
|
|
28
|
+
Settings.INSTITUTION_GEOSERVER_URL.to_s.present? &&
|
|
29
|
+
Settings.PROXY_GEOSERVER_URL.to_s.present?
|
|
21
30
|
end
|
|
22
31
|
end
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
class SidecarImageTransition < ApplicationRecord
|
|
3
|
+
class SidecarImageTransition < GeoblacklightSidecarImages::ApplicationRecord
|
|
4
|
+
self.table_name = "sidecar_image_transitions"
|
|
5
|
+
|
|
4
6
|
include Statesman::Adapters::ActiveRecordTransition
|
|
5
7
|
|
|
6
8
|
validates :to_state, inclusion: {in: SidecarImageStateMachine.states}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
##
|
|
4
|
-
#
|
|
5
|
-
class SolrDocumentSidecar < ApplicationRecord
|
|
4
|
+
# ActiveRecord sidecar for a Solr document, with an attached thumbnail image.
|
|
5
|
+
class SolrDocumentSidecar < GeoblacklightSidecarImages::ApplicationRecord
|
|
6
|
+
self.table_name = "solr_document_sidecars"
|
|
7
|
+
|
|
6
8
|
include Statesman::Adapters::ActiveRecordQueries[
|
|
7
9
|
transition_class: SidecarImageTransition,
|
|
8
10
|
initial_state: :initialized
|
|
@@ -12,6 +14,7 @@ class SolrDocumentSidecar < ApplicationRecord
|
|
|
12
14
|
has_many :sidecar_image_transitions, autosave: false, dependent: :destroy
|
|
13
15
|
has_one_attached :image
|
|
14
16
|
|
|
17
|
+
# SolrDocument is not an ActiveRecord model. Reconstruct from the stored id.
|
|
15
18
|
def document
|
|
16
19
|
document_type.new document_type.unique_key => document_id
|
|
17
20
|
end
|
|
@@ -35,7 +38,9 @@ class SolrDocumentSidecar < ApplicationRecord
|
|
|
35
38
|
:initialized
|
|
36
39
|
end
|
|
37
40
|
|
|
38
|
-
def
|
|
41
|
+
def image_url
|
|
42
|
+
return unless image.attached?
|
|
43
|
+
|
|
39
44
|
Rails.application.routes.url_helpers.rails_blob_path(image, only_path: true)
|
|
40
45
|
end
|
|
41
46
|
|