geoblacklight_sidecar_images 0.1.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Gemfile +5 -5
- data/README.md +136 -11
- data/db/migrate/20180118203155_create_solr_document_sidecars.rb +4 -2
- data/db/migrate/20180118203519_create_sidecar_image_transitions.rb +29 -0
- data/geoblacklight_sidecar_images.gemspec +5 -3
- data/lib/generators/geoblacklight_sidecar_images/{uploaders_generator.rb → config_generator.rb} +4 -5
- data/lib/generators/geoblacklight_sidecar_images/install_generator.rb +8 -14
- data/lib/generators/geoblacklight_sidecar_images/models_generator.rb +24 -2
- data/lib/generators/geoblacklight_sidecar_images/templates/config/initializers/statesman.rb +5 -0
- data/lib/generators/geoblacklight_sidecar_images/templates/jobs/store_image_job.rb +10 -3
- data/lib/generators/geoblacklight_sidecar_images/templates/models/sidecar_image_state_machine.rb +19 -0
- data/lib/generators/geoblacklight_sidecar_images/templates/models/sidecar_image_transition.rb +7 -0
- data/lib/generators/geoblacklight_sidecar_images/templates/models/solr_document_sidecar.rb +34 -2
- data/lib/generators/geoblacklight_sidecar_images/templates/services/image_service.rb +103 -96
- data/lib/generators/geoblacklight_sidecar_images/templates/views/catalog/_index_split_default.html.erb +11 -1
- data/lib/geoblacklight_sidecar_images/version.rb +1 -1
- data/lib/tasks/geoblacklight_sidecar_images_tasks.rake +165 -39
- data/spec/jobs/store_image_job_spec.rb +16 -0
- data/spec/services/image_service_spec.rb +5 -8
- data/template.rb +3 -2
- metadata +48 -24
- data/lib/generators/geoblacklight_sidecar_images/assets_generator.rb +0 -31
- data/lib/generators/geoblacklight_sidecar_images/templates/assets/images/thumbnail-image.png +0 -0
- data/lib/generators/geoblacklight_sidecar_images/templates/assets/images/thumbnail-line.png +0 -0
- data/lib/generators/geoblacklight_sidecar_images/templates/assets/images/thumbnail-mixed.png +0 -0
- data/lib/generators/geoblacklight_sidecar_images/templates/assets/images/thumbnail-multipoint.png +0 -0
- data/lib/generators/geoblacklight_sidecar_images/templates/assets/images/thumbnail-paper-map.png +0 -0
- data/lib/generators/geoblacklight_sidecar_images/templates/assets/images/thumbnail-point.png +0 -0
- data/lib/generators/geoblacklight_sidecar_images/templates/assets/images/thumbnail-polygon.png +0 -0
- data/lib/generators/geoblacklight_sidecar_images/templates/assets/images/thumbnail-raster.png +0 -0
- data/lib/generators/geoblacklight_sidecar_images/templates/uploaders/image_uploader.rb +0 -55
@@ -3,11 +3,15 @@
|
|
3
3
|
##
|
4
4
|
# Metadata for indexed documents
|
5
5
|
class SolrDocumentSidecar < ApplicationRecord
|
6
|
-
|
6
|
+
include Statesman::Adapters::ActiveRecordQueries
|
7
7
|
|
8
8
|
belongs_to :document, required: true, polymorphic: true
|
9
|
+
has_many :sidecar_image_transitions, autosave: false
|
10
|
+
has_one_attached :image
|
11
|
+
|
12
|
+
# If the sidecar solr document is updated, re-fetch thumbnail image
|
13
|
+
after_update :reimage, if: :saved_change_to_version?
|
9
14
|
|
10
|
-
# Roll our own polymorphism because our documents are not AREL-able
|
11
15
|
def document
|
12
16
|
document_type.new document_type.unique_key => document_id
|
13
17
|
end
|
@@ -15,4 +19,32 @@ class SolrDocumentSidecar < ApplicationRecord
|
|
15
19
|
def document_type
|
16
20
|
(super.constantize if defined?(super)) || default_document_type
|
17
21
|
end
|
22
|
+
|
23
|
+
def image_state
|
24
|
+
@state_machine ||= SidecarImageStateMachine.new(
|
25
|
+
self,
|
26
|
+
transition_class: SidecarImageTransition
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.transition_class
|
31
|
+
SidecarImageTransition
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.initial_state
|
35
|
+
:initialized
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.image_url
|
39
|
+
Rails.application.routes.url_helpers.rails_blob_path(self.image, only_path: true)
|
40
|
+
end
|
41
|
+
|
42
|
+
private_class_method :initial_state
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def reimage
|
47
|
+
self.image.purge if self.image.attached?
|
48
|
+
StoreImageJob.perform_later(self.document.id)
|
49
|
+
end
|
18
50
|
end
|
@@ -1,10 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require
|
2
|
+
require "addressable/uri"
|
3
|
+
require "mimemagic"
|
4
4
|
|
5
5
|
class ImageService
|
6
|
+
attr_reader :document
|
7
|
+
attr_writer :metadata, :logger
|
8
|
+
|
6
9
|
def initialize(document)
|
7
10
|
@document = document
|
11
|
+
|
12
|
+
@metadata = Hash.new
|
13
|
+
@metadata['solr_doc_id'] = document.id
|
14
|
+
@metadata['solr_version'] = @document.sidecar.version
|
15
|
+
@metadata['placeheld'] = false
|
16
|
+
|
17
|
+
@document.sidecar.image_state.transition_to!(:processing, @metadata)
|
18
|
+
|
8
19
|
@logger ||= ActiveSupport::TaggedLogging.new(
|
9
20
|
Logger.new(
|
10
21
|
File.join(
|
@@ -14,46 +25,66 @@ class ImageService
|
|
14
25
|
)
|
15
26
|
end
|
16
27
|
|
17
|
-
# Stores the document's image in
|
18
|
-
# using Carrierwave
|
28
|
+
# Stores the document's image in ActiveStorage
|
19
29
|
# @return [Boolean]
|
20
30
|
#
|
21
|
-
# @TODO: EWL
|
22
31
|
def store
|
23
|
-
|
24
|
-
|
25
|
-
sidecar.save!
|
26
|
-
@logger.tagged(@document.id, 'STATUS') { @logger.info 'SUCCESS' }
|
27
|
-
@logger.tagged(@document.id, 'SIDECAR_IMAGE_URL') { @logger.info @document.sidecar.image_url }
|
28
|
-
rescue ActiveRecord::RecordInvalid, FloatDomainError => invalid
|
29
|
-
@logger.tagged(@document.id, 'STATUS') { @logger.info 'FAILURE' }
|
30
|
-
@logger.tagged(@document.id, 'EXCEPTION') { @logger.info invalid.inspect }
|
31
|
-
end
|
32
|
+
# Gentle hands
|
33
|
+
sleep(1)
|
32
34
|
|
33
|
-
|
34
|
-
# @return [Hash]
|
35
|
-
# * :type [String] image mime type
|
36
|
-
# * :data [String] image file data
|
37
|
-
def placeholder
|
38
|
-
placeholder_data
|
39
|
-
end
|
35
|
+
io_file = image_tempfile(@document.id)
|
40
36
|
|
41
|
-
|
37
|
+
if io_file.nil? || @metadata['placeheld'] == true
|
38
|
+
@document.sidecar.image_state.transition_to!(:placeheld, @metadata)
|
39
|
+
log_output
|
40
|
+
else
|
41
|
+
# Remote content-type headers are untrustworthy
|
42
|
+
# Pull the mimetype and file extension via MimeMagic
|
43
|
+
mm = MimeMagic.by_magic(File.open(io_file))
|
44
|
+
|
45
|
+
@metadata['MimeMagic_type'] = mm.type
|
46
|
+
@metadata['MimeMagic_mediatype'] = mm.mediatype
|
47
|
+
@metadata['MimeMagic_subtype'] = mm.subtype
|
48
|
+
|
49
|
+
if mm.mediatype == "image"
|
50
|
+
@document.sidecar.image.attach(
|
51
|
+
io: io_file,
|
52
|
+
filename: "#{@document.id}.#{mm.subtype}",
|
53
|
+
content_type: mm.type
|
54
|
+
)
|
55
|
+
@document.sidecar.image_state.transition_to!(:succeeded, @metadata)
|
56
|
+
else
|
57
|
+
@document.sidecar.image_state.transition_to!(:placeheld, @metadata)
|
58
|
+
end
|
42
59
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
@
|
47
|
-
@
|
60
|
+
log_output
|
61
|
+
end
|
62
|
+
rescue Exception => invalid
|
63
|
+
@metadata['exception'] = invalid.inspect
|
64
|
+
@document.sidecar.image_state.transition_to!(:failed, @metadata)
|
48
65
|
|
49
|
-
|
50
|
-
|
51
|
-
file.write(image_data[:data])
|
52
|
-
file.close
|
66
|
+
log_output
|
67
|
+
end
|
53
68
|
|
54
|
-
|
69
|
+
private
|
55
70
|
|
56
|
-
|
71
|
+
def image_tempfile(document_id)
|
72
|
+
@metadata['viewer_protocol'] = @document.viewer_protocol
|
73
|
+
@metadata['image_url'] = image_url
|
74
|
+
@metadata['service_url'] = service_url
|
75
|
+
@metadata['gblsi_thumbnail_uri'] = gblsi_thumbnail_uri
|
76
|
+
|
77
|
+
if image_data && @metadata['placeheld'] == false
|
78
|
+
temp_file = Tempfile.new([document_id, ".tmp"])
|
79
|
+
temp_file.binmode
|
80
|
+
temp_file.write(image_data)
|
81
|
+
temp_file.rewind
|
82
|
+
|
83
|
+
@metadata['image_tempfile'] = temp_file.inspect
|
84
|
+
temp_file
|
85
|
+
else
|
86
|
+
return nil
|
87
|
+
end
|
57
88
|
end
|
58
89
|
|
59
90
|
# Returns geoserver auth credentials if the document is a restriced Local WMS layer.
|
@@ -80,71 +111,38 @@ class ImageService
|
|
80
111
|
end
|
81
112
|
end
|
82
113
|
|
83
|
-
def placeholder_base_path
|
84
|
-
Rails.root.join('app', 'assets', 'images')
|
85
|
-
end
|
86
|
-
|
87
|
-
# Generates hash containing placeholder mime_type and image.
|
88
|
-
def placeholder_data
|
89
|
-
{ type: 'image/png', data: placeholder_image }
|
90
|
-
end
|
91
|
-
|
92
|
-
# Gets placeholder image from disk.
|
93
|
-
def placeholder_image
|
94
|
-
File.read(placeholder_image_path)
|
95
|
-
end
|
96
|
-
|
97
|
-
# Path to placeholder image based on the layer geometry.
|
98
|
-
def placeholder_image_path
|
99
|
-
geom_type = @document.fetch('layer_geom_type_s', '').tr(' ', '-').downcase
|
100
|
-
thumb_path = "#{placeholder_base_path}/thumbnail-#{geom_type}.png"
|
101
|
-
return "#{placeholder_base_path}/thumbnail-paper-map.png" unless File.exist?(thumb_path)
|
102
|
-
thumb_path
|
103
|
-
end
|
104
|
-
|
105
114
|
# Generates hash containing thumbnail mime_type and image.
|
106
115
|
def image_data
|
107
|
-
return
|
108
|
-
|
116
|
+
return nil unless image_url
|
117
|
+
remote_image
|
109
118
|
end
|
110
119
|
|
111
|
-
# Gets thumbnail image from URL. On error,
|
112
|
-
def
|
120
|
+
# Gets thumbnail image from URL. On error, placehold image.
|
121
|
+
def remote_image
|
113
122
|
auth = geoserver_credentials
|
114
123
|
|
115
|
-
|
116
|
-
b.use FaradayMiddleware::FollowRedirects
|
117
|
-
b.adapter :net_http
|
118
|
-
end
|
119
|
-
|
120
|
-
conn.options.timeout = timeout
|
121
|
-
conn.options.timeout = timeout
|
122
|
-
conn.authorization :Basic, auth if auth
|
123
|
-
|
124
|
-
conn.head.headers['content-type']
|
125
|
-
rescue Faraday::Error::ConnectionFailed
|
126
|
-
placeholder_data[:type]
|
127
|
-
rescue Faraday::Error::TimeoutError
|
128
|
-
placeholder_data[:type]
|
129
|
-
|
130
|
-
# Rescuing Exception intentionally
|
131
|
-
rescue Exception
|
132
|
-
placeholder_data[:type]
|
133
|
-
end
|
124
|
+
uri = Addressable::URI.parse(image_url)
|
134
125
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
conn.options.timeout = timeout
|
141
|
-
conn.authorization :Basic, auth if auth
|
126
|
+
if uri.scheme.include?("http")
|
127
|
+
conn = Faraday.new(url: uri.normalize.to_s) do |b|
|
128
|
+
b.use FaradayMiddleware::FollowRedirects
|
129
|
+
b.adapter :net_http
|
130
|
+
end
|
142
131
|
|
143
|
-
|
132
|
+
conn.options.timeout = timeout
|
133
|
+
conn.authorization :Basic, auth if auth
|
134
|
+
conn.get.body
|
135
|
+
else
|
136
|
+
return nil
|
137
|
+
end
|
144
138
|
rescue Faraday::Error::ConnectionFailed
|
145
|
-
|
139
|
+
@metadata['error'] = "Faraday::Error::ConnectionFailed"
|
140
|
+
@metadata['placeheld'] = true
|
141
|
+
return nil
|
146
142
|
rescue Faraday::Error::TimeoutError
|
147
|
-
|
143
|
+
@metadata['error'] = "Faraday::Error::TimeoutError"
|
144
|
+
@metadata['placeheld'] = true
|
145
|
+
return nil
|
148
146
|
end
|
149
147
|
|
150
148
|
# Returns the thumbnail url.
|
@@ -165,11 +163,6 @@ class ImageService
|
|
165
163
|
end
|
166
164
|
end
|
167
165
|
|
168
|
-
# Determines the image file extension
|
169
|
-
def image_extension
|
170
|
-
@image_extension ||= Rack::Mime::MIME_TYPES.rassoc(remote_content_type).try(:first) || '.png'
|
171
|
-
end
|
172
|
-
|
173
166
|
# Checks if the document is Local restriced access and is a scanned map.
|
174
167
|
def restricted_scanned_map?
|
175
168
|
@document.local_restricted? && @document['layer_geom_type_s'] == 'Image'
|
@@ -189,9 +182,15 @@ class ImageService
|
|
189
182
|
@service_url ||= begin
|
190
183
|
return unless @document.available?
|
191
184
|
protocol = @document.viewer_protocol
|
192
|
-
|
185
|
+
if protocol == 'map' || protocol.nil?
|
186
|
+
@metadata['error'] = "Unsupported viewer protocol"
|
187
|
+
@metadata['placeheld'] = true
|
188
|
+
return nil
|
189
|
+
end
|
193
190
|
"ImageService::#{protocol.camelcase}".constantize.image_url(@document, image_size)
|
194
191
|
rescue NameError
|
192
|
+
@metadata['error'] = "service_url NameError"
|
193
|
+
@metadata['placeheld'] = true
|
195
194
|
return nil
|
196
195
|
end
|
197
196
|
end
|
@@ -202,13 +201,21 @@ class ImageService
|
|
202
201
|
JSON.parse(@document[@document.references.reference_field])['http://schema.org/thumbnailUrl']
|
203
202
|
end
|
204
203
|
|
205
|
-
# Default
|
204
|
+
# Default image size.
|
206
205
|
def image_size
|
207
|
-
|
206
|
+
1500
|
208
207
|
end
|
209
208
|
|
210
209
|
# Faraday timeout value.
|
211
210
|
def timeout
|
212
211
|
30
|
213
212
|
end
|
213
|
+
|
214
|
+
# Capture metadata within image harvest log
|
215
|
+
def log_output
|
216
|
+
@metadata["state"] = @document.sidecar.image_state.current_state
|
217
|
+
@metadata.each do |key,value|
|
218
|
+
@logger.tagged(@document.id, key.to_s) { @logger.info value }
|
219
|
+
end
|
220
|
+
end
|
214
221
|
end
|
@@ -11,7 +11,17 @@
|
|
11
11
|
<div class='col-xs-12'>
|
12
12
|
<div class='media'>
|
13
13
|
<div class='media-left'>
|
14
|
-
|
14
|
+
<% if document.sidecar.image.attached? %>
|
15
|
+
<% if document.sidecar.image.variable? %>
|
16
|
+
<%= image_tag document.sidecar.image.variant(resize: "100x100"), {class: 'media-object'} %>
|
17
|
+
<% else %>
|
18
|
+
<%= image_tag document.sidecar.image, {class: 'media-object'} %>
|
19
|
+
<% end %>
|
20
|
+
<% else %>
|
21
|
+
<span title="<%=document[Settings.FIELDS.GEOM_TYPE]%>">
|
22
|
+
<%= geoblacklight_icon(document[Settings.FIELDS.GEOM_TYPE]) %>
|
23
|
+
</span>
|
24
|
+
<% end %>
|
15
25
|
</div>
|
16
26
|
<div class='media-body'>
|
17
27
|
<small>
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
require 'csv'
|
2
|
+
|
3
|
+
namespace :gblsci do
|
2
4
|
namespace :sample_data do
|
3
5
|
desc 'Ingests a directory of geoblacklight.json files'
|
4
6
|
task :ingest, [:directory] => :environment do |_t, args|
|
@@ -17,60 +19,184 @@ namespace :geoblacklight_sidecar_images do
|
|
17
19
|
end
|
18
20
|
|
19
21
|
namespace :images do
|
20
|
-
desc '
|
21
|
-
task :
|
22
|
-
|
23
|
-
layers = %w[
|
24
|
-
layer_slug_s
|
25
|
-
layer_id_s
|
26
|
-
dc_rights_s
|
27
|
-
dct_provenance_s
|
28
|
-
layer_geom_type_s
|
29
|
-
dct_references_s
|
30
|
-
]
|
31
|
-
index = Geoblacklight::SolrDocument.index
|
32
|
-
results = index.send_and_receive(index.blacklight_config.solr_path,
|
33
|
-
q: query,
|
34
|
-
fl: layers.join(','),
|
35
|
-
rows: 100_000_000)
|
36
|
-
num_found = results.response[:numFound]
|
37
|
-
doc_counter = 0
|
38
|
-
results.docs.each do |document|
|
39
|
-
begin
|
40
|
-
StoreImageJob.perform_later(document.to_h)
|
41
|
-
rescue Blacklight::Exceptions::RecordNotFound
|
42
|
-
next
|
43
|
-
end
|
44
|
-
end
|
22
|
+
desc 'Harvest image for specific document'
|
23
|
+
task :harvest_doc_id, [:doc_id] => [:environment] do |_t, args|
|
24
|
+
StoreImageJob.perform_later(args[:doc_id])
|
45
25
|
end
|
46
26
|
|
47
|
-
desc '
|
48
|
-
task :
|
27
|
+
desc 'Harvest all images'
|
28
|
+
task harvest_all: :environment do
|
49
29
|
begin
|
50
|
-
query = '
|
51
|
-
layers = %w[
|
52
|
-
layer_slug_s
|
53
|
-
layer_id_s
|
54
|
-
dc_rights_s
|
55
|
-
dct_provenance_s
|
56
|
-
layer_geom_type_s
|
57
|
-
dct_references_s
|
58
|
-
]
|
30
|
+
query = '*:*'
|
59
31
|
index = Geoblacklight::SolrDocument.index
|
60
32
|
results = index.send_and_receive(index.blacklight_config.solr_path,
|
61
33
|
q: query,
|
62
|
-
fl:
|
34
|
+
fl: "*",
|
63
35
|
rows: 100_000_000)
|
64
36
|
num_found = results.response[:numFound]
|
65
37
|
doc_counter = 0
|
66
38
|
results.docs.each do |document|
|
39
|
+
sleep(1)
|
67
40
|
begin
|
68
|
-
StoreImageJob.perform_later(document.
|
41
|
+
StoreImageJob.perform_later(document.id)
|
69
42
|
rescue Blacklight::Exceptions::RecordNotFound
|
70
43
|
next
|
71
44
|
end
|
72
45
|
end
|
73
46
|
end
|
74
47
|
end
|
48
|
+
|
49
|
+
desc 'Hash of SolrDocumentSidecar image state counts'
|
50
|
+
task harvest_states: :environment do
|
51
|
+
states = [
|
52
|
+
:initialized,
|
53
|
+
:queued,
|
54
|
+
:processing,
|
55
|
+
:succeeded,
|
56
|
+
:failed,
|
57
|
+
:placeheld
|
58
|
+
]
|
59
|
+
|
60
|
+
col_state = {}
|
61
|
+
states.each do |state|
|
62
|
+
sidecars = SolrDocumentSidecar.in_state(state)
|
63
|
+
col_state[state] = sidecars.size
|
64
|
+
end
|
65
|
+
|
66
|
+
col_state.each do |col,state|
|
67
|
+
puts "#{col} - #{state}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
desc 'Re-queues incomplete states for harvesting'
|
72
|
+
task harvest_retry: :environment do
|
73
|
+
states = [
|
74
|
+
:initialized,
|
75
|
+
:queued,
|
76
|
+
:processing,
|
77
|
+
:failed,
|
78
|
+
:placeheld
|
79
|
+
]
|
80
|
+
|
81
|
+
states.each do |state|
|
82
|
+
sidecars = SolrDocumentSidecar.in_state(state)
|
83
|
+
|
84
|
+
puts "#{state} - #{sidecars.size}"
|
85
|
+
|
86
|
+
sidecars.each do |sc|
|
87
|
+
cat = CatalogController.new
|
88
|
+
begin
|
89
|
+
resp, doc = cat.fetch(sc.document_id)
|
90
|
+
StoreImageJob.perform_later(doc.id)
|
91
|
+
rescue
|
92
|
+
puts "orphaned / #{sc.document_id}"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
desc 'Write harvest state report (CSV)'
|
99
|
+
task harvest_report: :environment do
|
100
|
+
# Create a CSV Dump of Results
|
101
|
+
file = "#{Rails.root}/public/#{Time.now.strftime('%Y-%m-%d_%H-%M-%S')}.sidecar_report.csv"
|
102
|
+
|
103
|
+
sidecars = SolrDocumentSidecar.all
|
104
|
+
|
105
|
+
CSV.open(file, 'w') do |writer|
|
106
|
+
header = [
|
107
|
+
"Sidecar ID",
|
108
|
+
"Document ID",
|
109
|
+
"Current State",
|
110
|
+
"Doc Data Type",
|
111
|
+
"Doc Title",
|
112
|
+
"Doc Institution",
|
113
|
+
"Error",
|
114
|
+
"Viewer Protocol",
|
115
|
+
"Image URL",
|
116
|
+
"GBLSI Thumbnail URL"
|
117
|
+
]
|
118
|
+
|
119
|
+
writer << header
|
120
|
+
|
121
|
+
sidecars.each do |sc|
|
122
|
+
cat = CatalogController.new
|
123
|
+
begin
|
124
|
+
resp, doc = cat.fetch(sc.document_id)
|
125
|
+
writer << [
|
126
|
+
sc.id,
|
127
|
+
sc.document_id,
|
128
|
+
sc.image_state.current_state,
|
129
|
+
doc._source['layer_geom_type_s'],
|
130
|
+
doc._source['dc_title_s'],
|
131
|
+
doc._source['dct_provenance_s'],
|
132
|
+
sc.image_state.last_transition.metadata['exception'],
|
133
|
+
sc.image_state.last_transition.metadata['viewer_protocol'],
|
134
|
+
sc.image_state.last_transition.metadata['image_url'],
|
135
|
+
sc.image_state.last_transition.metadata['gblsi_thumbnail_uri']
|
136
|
+
]
|
137
|
+
rescue Exception => e
|
138
|
+
puts "Exception: #{e.inspect}"
|
139
|
+
puts "orphaned / #{sc.document_id}"
|
140
|
+
next
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
desc 'Destroy all harvested images and sidecar AR objects'
|
147
|
+
task harvest_purge_all: :environment do
|
148
|
+
# Remove all images
|
149
|
+
sidecars = SolrDocumentSidecar.all
|
150
|
+
sidecars.each do |sc|
|
151
|
+
sc.image.purge
|
152
|
+
end
|
153
|
+
|
154
|
+
# Delete all Transitions and Sidecars
|
155
|
+
SidecarImageTransition.destroy_all
|
156
|
+
SolrDocumentSidecar.destroy_all
|
157
|
+
end
|
158
|
+
|
159
|
+
desc 'Destroy orphaned images and sidecar AR objects'
|
160
|
+
# When a SolrDocumentSidecar AR object exists,
|
161
|
+
# but it's corresponding SolrDocument is no longer in the Solr index.
|
162
|
+
task harvest_purge_orphans: :environment do
|
163
|
+
# Remove all images
|
164
|
+
sidecars = SolrDocumentSidecar.all
|
165
|
+
sidecars.each do |sc|
|
166
|
+
cat = CatalogController.new
|
167
|
+
begin
|
168
|
+
resp, doc = cat.fetch(sc.document_id)
|
169
|
+
rescue
|
170
|
+
sc.destroy
|
171
|
+
puts "orphaned / #{sc.document_id} / destroyed"
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
desc 'Destroy select sidecar AR objects by CSV file'
|
177
|
+
task harvest_destroy_batch: :environment do
|
178
|
+
# Expects a CSV file in Rails.root/tmp/destroy_batch.csv
|
179
|
+
#
|
180
|
+
# From your local machine, copy it up to production server like this:
|
181
|
+
# scp destroy_batch.csv swadm@geoprod:/swadm/var/www/geoblacklight/current/tmp/
|
182
|
+
CSV.foreach("#{Rails.root}/tmp/destroy_batch.csv", headers: true) do |row|
|
183
|
+
sc = SolrDocumentSidecar.find_by(:document_id => row[0])
|
184
|
+
sc.destroy
|
185
|
+
puts "document_id - #{row[0]} - destroyed"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
desc 'Inspect failed state objects'
|
190
|
+
task harvest_failed_state_inspect: :environment do
|
191
|
+
states = [
|
192
|
+
:failed
|
193
|
+
]
|
194
|
+
|
195
|
+
states.each do |state|
|
196
|
+
sidecars = SolrDocumentSidecar.in_state(state).each do |sc|
|
197
|
+
puts "#{state} - #{sc.document_id} - #{sc.image_state.last_transition.metadata.inspect}"
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
75
201
|
end
|
76
202
|
end
|