diff --git a/app/jobs/regular/admin_confirmation_email.rb b/app/jobs/regular/admin_confirmation_email.rb new file mode 100644 index 00000000..48746de4 --- /dev/null +++ b/app/jobs/regular/admin_confirmation_email.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Jobs + class AdminConfirmationEmail < ::Jobs::Base + sidekiq_options queue: 'critical' + + def execute(args) + to_address = args[:to_address] + token = args[:token] + target_email = args[:target_email] + target_username = args[:target_username] + + raise Discourse::InvalidParameters.new(:to_address) if to_address.blank? + raise Discourse::InvalidParameters.new(:token) if token.blank? + raise Discourse::InvalidParameters.new(:target_email) if target_email.blank? + raise Discourse::InvalidParameters.new(:target_username) if target_username.blank? + + message = AdminConfirmationMailer.send_email(to_address, target_email, target_username, token) + Email::Sender.new(message, :admin_confirmation_message).send + end + + end +end diff --git a/app/jobs/regular/bump_topic.rb b/app/jobs/regular/bump_topic.rb new file mode 100644 index 00000000..a8cd9fa3 --- /dev/null +++ b/app/jobs/regular/bump_topic.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module Jobs + class BumpTopic < ::Jobs::TopicTimerBase + def execute_timer_action(topic_timer, topic) + if Guardian.new(topic_timer.user).can_create_post_on_topic?(topic) + topic.add_small_action(Discourse.system_user, "autobumped", nil, bump: true) + end + + topic_timer.trash!(Discourse.system_user) + end + end +end diff --git a/app/jobs/regular/clear_slow_mode.rb b/app/jobs/regular/clear_slow_mode.rb new file mode 100644 index 00000000..361cce87 --- /dev/null +++ b/app/jobs/regular/clear_slow_mode.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Jobs + class ClearSlowMode < ::Jobs::TopicTimerBase + def execute_timer_action(topic_timer, topic) + topic.update!(slow_mode_seconds: 0) + topic_timer.trash!(Discourse.system_user) + end + end +end diff --git a/app/jobs/regular/close_topic.rb b/app/jobs/regular/close_topic.rb new file mode 100644 index 00000000..3385d63c --- /dev/null +++ b/app/jobs/regular/close_topic.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module Jobs + class CloseTopic < ::Jobs::TopicTimerBase + def execute_timer_action(topic_timer, topic) + silent = @args[:silent] + user = topic_timer.user + + if topic.closed? + topic_timer.destroy! + return + end + + if !Guardian.new(user).can_close_topic?(topic) + topic_timer.destroy! + topic.reload + + if topic_timer.based_on_last_post + topic.inherit_auto_close_from_category(timer_type: silent ? :silent_close : :close) + end + + return + end + + # this handles deleting the topic timer as well, see TopicStatusUpdater + topic.update_status('autoclosed', true, user, { silent: silent }) + + MessageBus.publish("/topic/#{topic.id}", reload_topic: true) + end + end +end diff --git a/app/jobs/regular/confirm_sns_subscription.rb b/app/jobs/regular/confirm_sns_subscription.rb new file mode 100644 index 00000000..f68588f8 --- /dev/null +++ b/app/jobs/regular/confirm_sns_subscription.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Jobs + + class ConfirmSnsSubscription < ::Jobs::Base + sidekiq_options retry: false + + def execute(args) + return unless raw = args[:raw].presence + return unless json = args[:json].presence + return unless subscribe_url = json["SubscribeURL"].presence + + require "aws-sdk-sns" + return unless Aws::SNS::MessageVerifier.new.authentic?(raw) + + uri = begin + URI.parse(subscribe_url) + rescue URI::Error + return + end + + Net::HTTP.get(uri) + end + + end + +end diff --git a/app/jobs/regular/crawl_topic_link.rb b/app/jobs/regular/crawl_topic_link.rb new file mode 100644 index 00000000..da7659ec --- /dev/null +++ b/app/jobs/regular/crawl_topic_link.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require 'open-uri' +require 'nokogiri' +require 'excon' + +module Jobs + class CrawlTopicLink < ::Jobs::Base + + sidekiq_options queue: 'low' + + def execute(args) + raise Discourse::InvalidParameters.new(:topic_link_id) unless args[:topic_link_id].present? + + topic_link = TopicLink.find_by(id: args[:topic_link_id], internal: false, crawled_at: nil) + return if topic_link.blank? + + # Look for a topic embed for the URL. If it exists, use its title and don't crawl + topic_embed = TopicEmbed.where(embed_url: topic_link.url).includes(:topic).references(:topic).first + # topic could be deleted, so skip + if topic_embed && topic_embed.topic + TopicLink.where(id: topic_link.id).update_all(['title = ?, crawled_at = CURRENT_TIMESTAMP', topic_embed.topic.title[0..255]]) + return + end + + begin + crawled = false + + # Special case: Images + # If the link is to an image, put the filename as the title + if FileHelper.is_supported_image?(topic_link.url) + uri = URI(topic_link.url) + filename = File.basename(uri.path) + crawled = (TopicLink.where(id: topic_link.id).update_all(["title = ?, crawled_at = CURRENT_TIMESTAMP", filename]) == 1) + end + + unless crawled + # Fetch the beginning of the document to find the title + title = RetrieveTitle.crawl(topic_link.url) + if title.present? + crawled = (TopicLink.where(id: topic_link.id).update_all(['title = ?, crawled_at = CURRENT_TIMESTAMP', title[0..254]]) == 1) + end + end + rescue Exception + # If there was a connection error, do nothing + ensure + TopicLink.where(id: topic_link.id).update_all('crawled_at = CURRENT_TIMESTAMP') if !crawled && topic_link.present? + end + end + + end +end diff --git a/app/jobs/regular/create_avatar_thumbnails.rb b/app/jobs/regular/create_avatar_thumbnails.rb new file mode 100644 index 00000000..51988a47 --- /dev/null +++ b/app/jobs/regular/create_avatar_thumbnails.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Jobs + + class CreateAvatarThumbnails < ::Jobs::Base + sidekiq_options queue: 'low' + + def execute(args) + return if Rails.env.test? + upload_id = args[:upload_id] + + raise Discourse::InvalidParameters.new(:upload_id) if upload_id.blank? + + return unless upload = Upload.find_by(id: upload_id) + + Discourse.avatar_sizes.each do |size| + OptimizedImage.create_for(upload, size, size) + end + end + + end + +end