geoblacklight_admin 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/admin/document_distributions_controller.rb +23 -10
- data/app/jobs/destroy_document_distributions_job.rb +80 -0
- data/app/views/admin/document_distributions/destroy_all.html.erb +3 -0
- data/app/views/admin/documents/admin.html.erb +1 -1
- data/app/views/admin/notifications/index.html.erb +2 -2
- data/app/views/admin/shared/_navbar.html.erb +1 -1
- data/lib/geoblacklight_admin/version.rb +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 48c3924abd0db3999ab1c702c483d8ba8e57ecee0ce692a7dda60b0707b19b39
|
4
|
+
data.tar.gz: be7b643b6306ba2cd44b35e7c32e0161ef9b83b543500dde617535af848bbc1a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dedd35ccc8137c52fc6ce2f9d9e99357fb5683689ca3ad484a72bed021b79d09974746fd13ed4eba6594f3b2f655d821f919f29f00e5936e9572363482c63d3a
|
7
|
+
data.tar.gz: 4f0557655660b144112a7d532b9f99507f01327bfbba572112ede542bc20f6c0e94ba23f30f692b8ac362c66c6dda3e1027861b743983218c02dc98d47f0a122
|
@@ -91,24 +91,37 @@ module Admin
|
|
91
91
|
|
92
92
|
# DELETE /admin/document_distributions/destroy_all
|
93
93
|
#
|
94
|
-
#
|
95
|
-
#
|
94
|
+
# Queues a background job to destroy all document distributions provided in the file parameter.
|
95
|
+
# The job will process the CSV file and send a notification when complete.
|
96
96
|
def destroy_all
|
97
97
|
return if request.get?
|
98
98
|
|
99
|
-
logger.debug("Destroy Distributions")
|
99
|
+
logger.debug("Queue Destroy Distributions Job")
|
100
100
|
unless params.dig(:document_distribution, :distributions, :file)
|
101
101
|
raise ArgumentError, "File does not exist or is invalid."
|
102
102
|
end
|
103
103
|
|
104
|
+
# Save the uploaded file to a temporary location
|
105
|
+
uploaded_file = params.dig(:document_distribution, :distributions, :file)
|
106
|
+
temp_file_path = Rails.root.join("tmp", "destroy_distributions_#{Time.current.to_i}_#{SecureRandom.hex(8)}.csv")
|
107
|
+
|
108
|
+
File.binwrite(temp_file_path, uploaded_file.read)
|
109
|
+
|
110
|
+
# Queue the background job
|
111
|
+
DestroyDocumentDistributionsJob.perform_later(temp_file_path.to_s, current_user)
|
112
|
+
|
104
113
|
respond_to do |format|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
114
|
+
format.html {
|
115
|
+
redirect_to admin_document_distributions_path,
|
116
|
+
notice: "Distribution destruction job has been queued. You will receive a notification when it completes."
|
117
|
+
}
|
118
|
+
end
|
119
|
+
rescue => e
|
120
|
+
respond_to do |format|
|
121
|
+
format.html {
|
122
|
+
redirect_to admin_document_distributions_path,
|
123
|
+
notice: "Failed to queue distribution destruction job: #{e.message}"
|
124
|
+
}
|
112
125
|
end
|
113
126
|
end
|
114
127
|
|
@@ -0,0 +1,80 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "csv"
|
4
|
+
|
5
|
+
# DestroyDocumentDistributionsJob
|
6
|
+
#
|
7
|
+
# This job processes a CSV file containing document distribution records to be destroyed.
|
8
|
+
# It handles large CSV files in the background to prevent timeouts and provides
|
9
|
+
# progress updates via notifications.
|
10
|
+
class DestroyDocumentDistributionsJob < ApplicationJob
|
11
|
+
queue_as :priority
|
12
|
+
|
13
|
+
def perform(file_path, current_user)
|
14
|
+
logger.debug("DestroyDocumentDistributionsJob: Starting destruction of distributions from #{file_path}")
|
15
|
+
|
16
|
+
destroyed_count = 0
|
17
|
+
error_count = 0
|
18
|
+
errors = []
|
19
|
+
|
20
|
+
begin
|
21
|
+
unless File.exist?(file_path)
|
22
|
+
raise ArgumentError, "File not found: #{file_path}"
|
23
|
+
end
|
24
|
+
|
25
|
+
CSV.foreach(file_path, headers: true) do |row|
|
26
|
+
logger.debug("Processing CSV Row: #{row.to_hash}")
|
27
|
+
|
28
|
+
begin
|
29
|
+
reference_type = ReferenceType.find_by(name: row.to_hash["reference_type"])
|
30
|
+
|
31
|
+
if reference_type.nil?
|
32
|
+
error_count += 1
|
33
|
+
errors << "Reference type not found: #{row.to_hash["reference_type"]}"
|
34
|
+
next
|
35
|
+
end
|
36
|
+
|
37
|
+
destroyed = DocumentDistribution.destroy_by(
|
38
|
+
friendlier_id: row.to_hash["friendlier_id"],
|
39
|
+
reference_type_id: reference_type.id,
|
40
|
+
url: row.to_hash["distribution_url"]
|
41
|
+
)
|
42
|
+
|
43
|
+
if destroyed.any?
|
44
|
+
destroyed_count += destroyed.count
|
45
|
+
logger.debug("Destroyed: #{row.to_hash}")
|
46
|
+
else
|
47
|
+
logger.debug("Not found to destroy: #{row.to_hash}")
|
48
|
+
end
|
49
|
+
rescue => e
|
50
|
+
error_count += 1
|
51
|
+
errors << "Error processing row #{row.to_hash}: #{e.message}"
|
52
|
+
logger.error("Error destroying distribution: #{e}")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Create success notification
|
57
|
+
message = "DISTRIBUTIONS DESTROYED|#{ActionController::Base.helpers.number_with_delimiter(destroyed_count)} distributions destroyed"
|
58
|
+
if error_count > 0
|
59
|
+
message += " (#{error_count} errors)"
|
60
|
+
end
|
61
|
+
|
62
|
+
notification = ExportNotification.with(message: message)
|
63
|
+
notification.deliver(current_user)
|
64
|
+
|
65
|
+
# Clean up the temporary file
|
66
|
+
File.delete(file_path) if File.exist?(file_path)
|
67
|
+
|
68
|
+
logger.debug("DestroyDocumentDistributionsJob: Completed. Destroyed #{destroyed_count} distributions with #{error_count} errors")
|
69
|
+
rescue => e
|
70
|
+
logger.error("DestroyDocumentDistributionsJob: Fatal error - #{e}")
|
71
|
+
|
72
|
+
# Create error notification
|
73
|
+
notification = ExportNotification.with(message: "DISTRIBUTION DESTROY FAILED|Error: #{e.message}")
|
74
|
+
notification.deliver(current_user)
|
75
|
+
|
76
|
+
# Clean up the temporary file
|
77
|
+
File.delete(file_path) if File.exist?(file_path)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -18,6 +18,9 @@
|
|
18
18
|
<p class="alert alert-danger" role="alert">
|
19
19
|
<strong>Warning:</strong> All matching Distributions will be destroyed. There is <strong>NO UNDO</strong> here.
|
20
20
|
</p>
|
21
|
+
<p class="alert alert-info" role="alert">
|
22
|
+
<strong>Note:</strong> Large CSV files will be processed in the background. You will receive a notification when the process completes.
|
23
|
+
</p>
|
21
24
|
<h3 class='h4'>Upload a CSV File</h3>
|
22
25
|
|
23
26
|
<%= simple_form_for DocumentDistribution.new, url: destroy_all_admin_document_distributions_path, method: :post, multipart: true do |f| %>
|
@@ -193,7 +193,7 @@
|
|
193
193
|
</tr>
|
194
194
|
</thead>
|
195
195
|
<tbody>
|
196
|
-
<% @document.
|
196
|
+
<% @document.document_licensed_accesses.each do |da| %>
|
197
197
|
<tr>
|
198
198
|
<td><%= da.institution_code %></td>
|
199
199
|
<td><a href="<%= da.access_url %>"><%= da.access_url %></a></td>
|
@@ -1,7 +1,7 @@
|
|
1
|
-
<%- @page_title = "GBL♦Admin -
|
1
|
+
<%- @page_title = "GBL♦Admin - Notifications" %>
|
2
2
|
|
3
3
|
<h1 style="width:100%;">
|
4
|
-
<%= t('dictionary.
|
4
|
+
<%= t('dictionary.notifications') %>
|
5
5
|
|
6
6
|
<%= link_to('+ Mark All Read', batch_admin_notifications_path(params: {read: 'all'}), {method: 'put', class: "btn btn-primary float-right mr-2"}) %>
|
7
7
|
</h1>
|
@@ -35,7 +35,7 @@
|
|
35
35
|
<% if user_signed_in? %>
|
36
36
|
<li class="nav-item">
|
37
37
|
<%= link_to admin_notifications_url, { class: 'nav-link' } do %>
|
38
|
-
<%= "
|
38
|
+
<%= "Notifications #{notifications_badge}".html_safe %>
|
39
39
|
<% end %>
|
40
40
|
</li>
|
41
41
|
<% end %>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: geoblacklight_admin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Larson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-08-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_storage_validations
|
@@ -458,6 +458,20 @@ dependencies:
|
|
458
458
|
- - "~>"
|
459
459
|
- !ruby/object:Gem::Version
|
460
460
|
version: '2.6'
|
461
|
+
- !ruby/object:Gem::Dependency
|
462
|
+
name: rubyzip
|
463
|
+
requirement: !ruby/object:Gem::Requirement
|
464
|
+
requirements:
|
465
|
+
- - "~>"
|
466
|
+
- !ruby/object:Gem::Version
|
467
|
+
version: '2.3'
|
468
|
+
type: :runtime
|
469
|
+
prerelease: false
|
470
|
+
version_requirements: !ruby/object:Gem::Requirement
|
471
|
+
requirements:
|
472
|
+
- - "~>"
|
473
|
+
- !ruby/object:Gem::Version
|
474
|
+
version: '2.3'
|
461
475
|
- !ruby/object:Gem::Dependency
|
462
476
|
name: byebug
|
463
477
|
requirement: !ruby/object:Gem::Requirement
|
@@ -855,6 +869,7 @@ files:
|
|
855
869
|
- app/jobs/bulk_action_revert_job.rb
|
856
870
|
- app/jobs/bulk_action_run_document_job.rb
|
857
871
|
- app/jobs/bulk_action_run_job.rb
|
872
|
+
- app/jobs/destroy_document_distributions_job.rb
|
858
873
|
- app/jobs/export_job.rb
|
859
874
|
- app/jobs/export_json_bulk_job.rb
|
860
875
|
- app/jobs/export_json_job.rb
|