FEATURE: set a timer to delete a topic
This commit is contained in:
parent
21238692d9
commit
1019bbda46
|
@ -6,6 +6,7 @@ import { popupAjaxError } from 'discourse/lib/ajax-error';
|
|||
export const CLOSE_STATUS_TYPE = 'close';
|
||||
const OPEN_STATUS_TYPE = 'open';
|
||||
const PUBLISH_TO_CATEGORY_STATUS_TYPE = 'publish_to_category';
|
||||
const DELETE_STATUS_TYPE = 'delete';
|
||||
|
||||
export default Ember.Controller.extend(ModalFunctionality, {
|
||||
loading: false,
|
||||
|
@ -14,14 +15,18 @@ export default Ember.Controller.extend(ModalFunctionality, {
|
|||
selection: Ember.computed.alias('model.topic_status_update.status_type'),
|
||||
autoOpen: Ember.computed.equal('selection', OPEN_STATUS_TYPE),
|
||||
autoClose: Ember.computed.equal('selection', CLOSE_STATUS_TYPE),
|
||||
autoDelete: Ember.computed.equal('selection', DELETE_STATUS_TYPE),
|
||||
publishToCategory: Ember.computed.equal('selection', PUBLISH_TO_CATEGORY_STATUS_TYPE),
|
||||
|
||||
showTimeOnly: Ember.computed.or('autoOpen', 'autoDelete'),
|
||||
|
||||
@computed("model.closed")
|
||||
statusUpdates(closed) {
|
||||
return [
|
||||
{ id: CLOSE_STATUS_TYPE, name: I18n.t(closed ? 'topic.temp_open.title' : 'topic.auto_close.title'), },
|
||||
{ id: OPEN_STATUS_TYPE, name: I18n.t(closed ? 'topic.auto_reopen.title' : 'topic.temp_close.title') },
|
||||
{ id: PUBLISH_TO_CATEGORY_STATUS_TYPE, name: I18n.t('topic.publish_to_category.title') }
|
||||
{ id: PUBLISH_TO_CATEGORY_STATUS_TYPE, name: I18n.t('topic.publish_to_category.title') },
|
||||
{ id: DELETE_STATUS_TYPE, name: I18n.t('topic.auto_delete.title') }
|
||||
];
|
||||
},
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
</div>
|
||||
|
||||
<div>
|
||||
{{#if autoOpen}}
|
||||
{{#if showTimeOnly}}
|
||||
{{auto-update-input
|
||||
input=updateTime
|
||||
statusType=selection
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
module Jobs
|
||||
class DeleteTopic < Jobs::Base
|
||||
|
||||
def execute(args)
|
||||
topic_status_update = TopicStatusUpdate.find_by(id: args[:topic_status_update_id])
|
||||
|
||||
topic = topic_status_update&.topic
|
||||
|
||||
if topic_status_update.blank? || topic.blank? ||
|
||||
topic_status_update.execute_at > Time.zone.now
|
||||
return
|
||||
end
|
||||
|
||||
if Guardian.new(topic_status_update.user).can_delete?(topic)
|
||||
first_post = topic.ordered_posts.first
|
||||
PostDestroyer.new(topic_status_update.user, first_post, { context: I18n.t("topic_statuses.auto_deleted_by_timer") }).destroy
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -35,7 +35,8 @@ class TopicStatusUpdate < ActiveRecord::Base
|
|||
@types ||= Enum.new(
|
||||
close: 1,
|
||||
open: 2,
|
||||
publish_to_category: 3
|
||||
publish_to_category: 3,
|
||||
delete: 4
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -77,6 +78,10 @@ class TopicStatusUpdate < ActiveRecord::Base
|
|||
Jobs.cancel_scheduled_job(:publish_topic_to_category, topic_status_update_id: id)
|
||||
end
|
||||
|
||||
def cancel_auto_delete_job
|
||||
Jobs.cancel_scheduled_job(:delete_topic, topic_status_update_id: id)
|
||||
end
|
||||
|
||||
def schedule_auto_open_job(time)
|
||||
return unless topic
|
||||
topic.update_status('closed', true, user) if !topic.closed
|
||||
|
@ -104,6 +109,10 @@ class TopicStatusUpdate < ActiveRecord::Base
|
|||
def publishing_to_category?
|
||||
self.status_type.to_i == TopicStatusUpdate.types[:publish_to_category]
|
||||
end
|
||||
|
||||
def schedule_auto_delete_job(time)
|
||||
Jobs.enqueue_at(time, :delete_topic, topic_status_update_id: id)
|
||||
end
|
||||
end
|
||||
|
||||
# == Schema Information
|
||||
|
|
|
@ -1524,12 +1524,15 @@ en:
|
|||
label: "Auto-close topic hours:"
|
||||
error: "Please enter a valid value."
|
||||
based_on_last_post: "Don't close until the last post in the topic is at least this old."
|
||||
auto_delete:
|
||||
title: "Auto-Delete Topic"
|
||||
|
||||
status_update_notice:
|
||||
auto_open: "This topic will automatically open %{timeLeft}."
|
||||
auto_close: "This topic will automatically close %{timeLeft}."
|
||||
auto_publish_to_category: "This topic will be published to <a href=%{categoryUrl}>#%{categoryName}</a> %{timeLeft}."
|
||||
auto_close_based_on_last_post: "This topic will close %{duration} after the last reply."
|
||||
auto_delete: "This topic will be automatically deleted %{timeLeft}."
|
||||
auto_close_title: 'Auto-Close Settings'
|
||||
auto_close_immediate:
|
||||
one: "The last post in the topic is already 1 hour old, so the topic will be closed immediately."
|
||||
|
|
|
@ -1656,6 +1656,7 @@ en:
|
|||
pinned_globally_disabled: "This topic is now unpinned. It will no longer appear at the top of its category."
|
||||
visible_enabled: "This topic is now listed. It will be displayed in topic lists."
|
||||
visible_disabled: "This topic is now unlisted. It will no longer be displayed in any topic lists. The only way to access this topic is via direct link."
|
||||
auto_deleted_by_timer: "Automatically deleted by timer."
|
||||
|
||||
login:
|
||||
not_approved: "Your account hasn't been approved yet. You will be notified by email when you are ready to log in."
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
require 'rails_helper'
|
||||
|
||||
describe Jobs::DeleteTopic do
|
||||
let(:admin) { Fabricate(:admin) }
|
||||
|
||||
let(:topic) do
|
||||
Fabricate(:topic,
|
||||
topic_status_updates: [Fabricate(:topic_status_update, user: admin)]
|
||||
)
|
||||
end
|
||||
|
||||
let(:first_post) { create_post(topic: topic) }
|
||||
|
||||
before do
|
||||
SiteSetting.queue_jobs = true
|
||||
end
|
||||
|
||||
it "can close a topic" do
|
||||
first_post
|
||||
Timecop.freeze(2.hours.from_now) do
|
||||
described_class.new.execute(topic_status_update_id: topic.topic_status_update.id)
|
||||
expect(topic.reload).to be_trashed
|
||||
expect(first_post.reload).to be_trashed
|
||||
end
|
||||
end
|
||||
|
||||
it "should do nothing if topic is already deleted" do
|
||||
first_post
|
||||
topic.trash!
|
||||
Timecop.freeze(2.hours.from_now) do
|
||||
Topic.any_instance.expects(:trash!).never
|
||||
described_class.new.execute(topic_status_update_id: topic.topic_status_update.id)
|
||||
end
|
||||
end
|
||||
|
||||
it "should do nothing if it's too early" do
|
||||
t = Fabricate(:topic,
|
||||
topic_status_updates: [Fabricate(:topic_status_update, user: admin, execute_at: 5.hours.from_now)]
|
||||
)
|
||||
create_post(topic: t)
|
||||
Timecop.freeze(4.hours.from_now) do
|
||||
described_class.new.execute(topic_status_update_id: t.topic_status_update.id)
|
||||
expect(t.reload).to_not be_trashed
|
||||
end
|
||||
end
|
||||
|
||||
describe "user isn't authorized to delete topics" do
|
||||
let(:topic) {
|
||||
Fabricate(:topic,
|
||||
topic_status_updates: [Fabricate(:topic_status_update, user: Fabricate(:user))]
|
||||
)
|
||||
}
|
||||
|
||||
it "shouldn't delete the topic" do
|
||||
create_post(topic: topic)
|
||||
Timecop.freeze(2.hours.from_now) do
|
||||
described_class.new.execute(topic_status_update_id: topic.topic_status_update.id)
|
||||
expect(topic.reload).to_not be_trashed
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue