decidim-cdtb 0.6.0 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 30a633cfd37b8c99f0aa405a37d8140ee9d5d6ae06a393cfe29513fd91d425bd
4
- data.tar.gz: da2c0fb5f6fdb4e8086e6d24910825bf7a331884446e27c5932e50fb777759b6
3
+ metadata.gz: 4adf8e2c9aeb9bfef5d29c8b9beb889da8566d7cd5d49debeded01c0aac28030
4
+ data.tar.gz: ed5adda640ba3bfec70f1b13147f5fd05a2ba51cc818f6b8344bb5791354e820
5
5
  SHA512:
6
- metadata.gz: 16ad1987a516def98adb792653df860c6d6a881b9ae38e3c5578725cc3e9674ddacc96fb1bf1c179e9f2673141f6864f5fd5000759cb6c19890f26f95d7b5b8c
7
- data.tar.gz: 84d66913b5ab49b424d47a29ff46b3897d2acd2b7784c5ed42262578dd55042444f847de0af5931b977bd5574e1c7d47f102b0437077acca50f4a799d7cd0d43
6
+ metadata.gz: 55c8a981705afb0014de3d2e8c90ba6de21aba8e9e7d9746cddfa75311a7b22fe5cfdcd31689e2b7a146a789643f795fb52d6c6acdc42dfbf0415d74602dfacd
7
+ data.tar.gz: 8a10c840a930ce5ba7a349890491725ca1ed19a9035f030aab79955d2651b45b9c7d1e1303b2edced69a712a96548060249ec59ad6ee5e82894c8d80d1f1c0e3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.6.1] - 2026-08-27 (patch)
4
+
5
+ - Fix `ArgumentError` in Users::Remover task: `Decidim::CreateReport.call` only takes `(form, reportable)`, drop the extra `reporter_user` argument.
6
+ - Skip orphaned comments (with no `participatory_space`, e.g. their commentable has been removed) when reporting/hiding them in Users::Remover task, instead of aborting the whole task.
7
+ - Add `cdtb:comments:remove_orphaned` task to remove orphaned comments (and their votes, search index entries and moderations).
8
+
3
9
  ## [0.6.0] - 2026-08-25 (minor)
4
10
 
5
11
  - Adapt `Decidim::DestroyAccount` call in Users::Remover task: pass a single form with `current_user` in context instead of `(user, form)`.
data/Gemfile.lock CHANGED
@@ -1,6 +1,6 @@
1
1
  GIT
2
2
  remote: https://github.com/CodiTramuntana/decidim.git
3
- revision: 6c2e53561a9700ad76d0da64f023e6c0690f41ad
3
+ revision: 67e68f735337b9c7fb98de058362e3b457d24c7a
4
4
  branch: release/0.29-stable
5
5
  specs:
6
6
  decidim (0.29.7)
@@ -141,7 +141,7 @@ GIT
141
141
  PATH
142
142
  remote: .
143
143
  specs:
144
- decidim-cdtb (0.6.0)
144
+ decidim-cdtb (0.6.1)
145
145
  decidim (>= 0.29.0)
146
146
  rails (>= 6)
147
147
  ruby-progressbar
@@ -660,7 +660,7 @@ GEM
660
660
  io-console (~> 0.5)
661
661
  request_store (1.5.1)
662
662
  rack (>= 1.4)
663
- responders (3.2.0)
663
+ responders (3.2.1)
664
664
  actionpack (>= 7.0)
665
665
  railties (>= 7.0)
666
666
  rexml (3.4.4)
data/README.md CHANGED
@@ -164,6 +164,22 @@ To execute the task run:
164
164
  bundle exec rake cdtb:users:remove[spam_users.csv,reporter_user@example.org]
165
165
  ```
166
166
 
167
+ ### Comments
168
+
169
+ Tasks related with comments.
170
+
171
+ #### Remove orphaned comments
172
+
173
+ Removes `Decidim::Comments::Comment`'s whose participatory space can no longer be resolved: this happens when their root commentable (e.g. a proposal or a meeting) and/or its participatory space has been removed without cascading its comments. Trying to report or hide these comments raises `ActiveRecord::RecordInvalid` (a `Decidim::Moderation` requires a `participatory_space`), which is the same condition `cdtb:users:remove` skips.
174
+
175
+ The task also removes the comment's votes, search index entries and any moderation/report referencing it.
176
+
177
+ To execute the task run:
178
+
179
+ ```
180
+ bin/rake cdtb:comments:remove_orphaned
181
+ ```
182
+
167
183
  ### Participatory Spaces
168
184
 
169
185
  #### Add content blocks
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Cdtb
5
+ module Comments
6
+ # Removes Decidim::Comments::Comment's that are orphaned: their
7
+ # participatory space can no longer be resolved, be it because their
8
+ # root commentable (e.g. a proposal or a meeting) was removed without
9
+ # cascading its comments, or because the participatory space itself
10
+ # was removed.
11
+ #
12
+ # This is the same condition Decidim::Cdtb::Users::Remover skips when
13
+ # reporting/hiding comments, since Decidim::CreateReport requires a
14
+ # participatory_space to create the Moderation.
15
+ #
16
+ # Rows are deleted with `delete_all` (no callbacks, no validations) on
17
+ # purpose: Decidim::Searchable#remove_from_index blows up for these
18
+ # comments, since it ends up calling `comment.organization.id` and
19
+ # `organization` is nil for an orphaned comment.
20
+ class OrphanedRemover < ::Decidim::Cdtb::Task
21
+ def initialize
22
+ @root_commentable_orphaned = {}
23
+ progress_bar = { title: "Decidim::Comments::Comment" }
24
+ super("REMOVE ORPHANED COMMENTS", progress_bar:)
25
+ end
26
+
27
+ def prepare_execution(_ctx)
28
+ @num_comments = query.count
29
+ log_task_info("Checking #{@num_comments} comments...")
30
+ end
31
+
32
+ def total_items
33
+ @num_comments
34
+ end
35
+
36
+ def do_execution(context)
37
+ progress_bar = context[:progress_bar]
38
+
39
+ query.find_each do |comment|
40
+ remove_comment(comment) if orphaned?(comment)
41
+ progress_bar.increment
42
+ end
43
+ end
44
+
45
+ def end_execution(_ctx)
46
+ log_task_step("#{@num_applied} orphaned comments removed")
47
+ end
48
+
49
+ private
50
+
51
+ # Comments that share the same root_commentable share the same fate,
52
+ # so the check is cached by that key to avoid resolving it once per
53
+ # comment in a heavily-commented orphaned thread. `find_each` always
54
+ # batches by primary key, so no explicit ordering helps that cache hit.
55
+ def query
56
+ Decidim::Comments::Comment.all
57
+ end
58
+
59
+ def orphaned?(comment)
60
+ key = [comment.decidim_root_commentable_type, comment.decidim_root_commentable_id]
61
+ @root_commentable_orphaned.fetch(key) { @root_commentable_orphaned[key] = comment.participatory_space.blank? }
62
+ end
63
+
64
+ def remove_comment(comment)
65
+ remove_moderations(comment)
66
+ Decidim::Comments::CommentVote.where(decidim_comment_id: comment.id).delete_all
67
+ Decidim::SearchableResource.where(resource_type: "Decidim::Comments::Comment", resource_id: comment.id).delete_all
68
+ Decidim::Comments::Comment.where(id: comment.id).delete_all
69
+
70
+ @num_applied += 1
71
+ puts "OK: Comment #{comment.id} removed (orphaned)"
72
+ end
73
+
74
+ def remove_moderations(comment)
75
+ moderation_ids = Decidim::Moderation.where(
76
+ decidim_reportable_type: "Decidim::Comments::Comment",
77
+ decidim_reportable_id: comment.id
78
+ ).pluck(:id)
79
+ return if moderation_ids.empty?
80
+
81
+ Decidim::Report.where(decidim_moderation_id: moderation_ids).delete_all
82
+ Decidim::Moderation.where(id: moderation_ids).delete_all
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "decidim/cdtb/tasks_utils"
4
4
  require "decidim/cdtb/task"
5
+ require "decidim/cdtb/comments/orphaned_remover"
5
6
  require "decidim/cdtb/fixes/nickname_fixer"
6
7
  require "decidim/cdtb/fixes/you_tube_embeds_fixer"
7
8
  require "decidim/cdtb/users/remover"
@@ -67,11 +67,23 @@ module Decidim
67
67
 
68
68
  def manage_comments(comments, user, reporter_user)
69
69
  comments.find_each do |comment|
70
+ next unless orphaned_comment_skip_check(comment)
71
+
70
72
  report_comment(comment, user, reporter_user) unless comment.reported?
71
73
  hide_comment(comment, user, reporter_user) unless comment.hidden?
72
74
  end
73
75
  end
74
76
 
77
+ # Comments whose commentable (or its participatory space) has been removed
78
+ # have no `participatory_space`, which makes `Decidim::CreateReport` blow up
79
+ # (Moderation requires a participatory_space) and would abort the whole batch.
80
+ def orphaned_comment_skip_check(comment)
81
+ return true if comment.participatory_space.present?
82
+
83
+ puts "SKIP: Comment #{comment.id} of User #{comment.decidim_author_id} has no participatory space (orphaned)"
84
+ false
85
+ end
86
+
75
87
  def block_user(user, reporter_user)
76
88
  params = {
77
89
  user_id: user.id,
@@ -117,15 +129,14 @@ module Decidim
117
129
  end
118
130
 
119
131
  def report_comment(comment, user, reporter_user)
120
- params = {
121
- reason: "spam",
122
- details: "Spam message"
123
- }
124
-
125
- form = Decidim::ReportForm.from_params(params).with_context(context_for_report(user, comment, reporter_user))
132
+ form = report_form_for(comment, user, reporter_user)
126
133
  reportable = GlobalID::Locator.locate_signed(comment.to_sgid.to_s)
127
134
 
128
- Decidim::CreateReport.call(form, reportable, reporter_user) do
135
+ create_report(form, reportable, comment, user)
136
+ end
137
+
138
+ def create_report(form, reportable, comment, user)
139
+ Decidim::CreateReport.call(form, reportable) do
129
140
  on(:ok) do
130
141
  puts "OK: Comment #{comment.id} of User #{user.id} reported"
131
142
  end
@@ -134,6 +145,17 @@ module Decidim
134
145
  puts "ERROR: Comment #{comment.id} of User #{user.id} not reported"
135
146
  end
136
147
  end
148
+ rescue ActiveRecord::RecordInvalid => e
149
+ puts "ERROR: Comment #{comment.id} of User #{user.id} not reported (#{e.message})"
150
+ end
151
+
152
+ def report_form_for(comment, user, reporter_user)
153
+ params = {
154
+ reason: "spam",
155
+ details: "Spam message"
156
+ }
157
+
158
+ Decidim::ReportForm.from_params(params).with_context(context_for_report(user, comment, reporter_user))
137
159
  end
138
160
 
139
161
  def hide_comment(comment, user, reporter_user)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Decidim
4
4
  module Cdtb
5
- VERSION = "0.6.0"
5
+ VERSION = "0.6.1"
6
6
  DECIDIM_MIN_VERSION = ">= 0.29.0"
7
7
  end
8
8
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "decidim/cdtb/tasks"
4
+
5
+ namespace :cdtb do
6
+ namespace :comments do
7
+ desc <<~EODESC
8
+ Remove orphaned Decidim::Comments::Comment's: comments whose participatory
9
+ space can no longer be resolved (their root commentable and/or their
10
+ participatory space has been removed).
11
+ EODESC
12
+ task remove_orphaned: [:environment] do
13
+ task = Decidim::Cdtb::Comments::OrphanedRemover.new
14
+ task.execute!
15
+ end
16
+ end
17
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: decidim-cdtb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oliver Valls
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-08-26 00:00:00.000000000 Z
11
+ date: 2026-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: decidim
@@ -91,6 +91,7 @@ files:
91
91
  - decidim-cdtb.gemspec
92
92
  - lib/cdtb/ip_parser.rb
93
93
  - lib/decidim/cdtb.rb
94
+ - lib/decidim/cdtb/comments/orphaned_remover.rb
94
95
  - lib/decidim/cdtb/engine.rb
95
96
  - lib/decidim/cdtb/fixes/nickname_fixer.rb
96
97
  - lib/decidim/cdtb/fixes/you_tube_embeds_fixer.rb
@@ -117,6 +118,7 @@ files:
117
118
  - lib/generators/cdtb/github_actions/templates/zeitwerk.yml
118
119
  - lib/tasks/anonymize.rake
119
120
  - lib/tasks/census.rake
121
+ - lib/tasks/comments.rake
120
122
  - lib/tasks/fix_youtube_embeds.rake
121
123
  - lib/tasks/logs.rake
122
124
  - lib/tasks/multitenants.rake