diff --git a/app/controllers/yiff_rest/api_v2/images_controller.rb b/app/controllers/yiff_rest/api_v2/images_controller.rb index 737618f..bba8717 100644 --- a/app/controllers/yiff_rest/api_v2/images_controller.rb +++ b/app/controllers/yiff_rest/api_v2/images_controller.rb @@ -9,6 +9,7 @@ module YiffRest def index @sp = search_images_params + @sp[:id] ||= @sp[:md5] @pagy, @images = pagy(APIImage.search(@sp).order(created_at: :desc), size: [1, 2, 2, 1]) end @@ -46,10 +47,16 @@ module YiffRest def destroy @image = APIImage.find(params[:id]) + @image.deletion_reason = params.dig(:api_image, :deletion_reason) @image.destroy redirect_to(yiff_rest_api_v2_manage_images_path(search: { category: @image.category }), notice: "Image deleted") end + def delete_with_reason + # deletion_reason + @image = APIImage.find(params[:id]) + end + private def load_category diff --git a/app/models/api_image.rb b/app/models/api_image.rb index ebd884c..50bb535 100644 --- a/app/models/api_image.rb +++ b/app/models/api_image.rb @@ -3,7 +3,7 @@ class APIImage < ApplicationRecord belongs_to_creator - attr_accessor :file, :exception + attr_accessor :file, :exception, :deletion_reason, :no_webhook_messages validates :category, presence: true, inclusion: { in: -> { APIImage.categories.map(&:db) } } validates :id, uniqueness: true, on: :file @@ -16,8 +16,12 @@ class APIImage < ApplicationRecord end after_create :invalidate_cache + after_create :send_created, unless: :no_webhook_messages after_update :update_files, if: :saved_change_to_category? + after_update :send_updated, unless: :no_webhook_messages after_destroy :delete_files + after_destroy :send_deleted, unless: :no_webhook_messages + def delete_files Websites.config.yiffy2_storage.delete(path) @@ -70,7 +74,6 @@ class APIImage < ApplicationRecord def search(params) q = super - params[:id] ||= params[:md5] q = q.attribute_matches(:category, params[:category]) q = q.attribute_matches(:original_url, params[:original_url]) q.order(created_at: :desc) @@ -205,4 +208,105 @@ class APIImage < ApplicationRecord def sync APIImageSyncJob.perform_later(self) end + + module WebhookMethods + GREEN = 0x008000 + YELLOW = 0xFFA500 + RED = 0xFF0000 + GREEN_TICK = "<:GreenTick:1235058920762904576>" + RED_TICK = "<:RedTick:1235058898549870724>" + + def execute(content) + Websites.config.yiffyapi_image_logs_webhook.execute({ + embeds: [content], + }) + end + + def send_created + execute({ + title: "Image Uploaded", + description: <<~DESC, + ID: `#{md5}` + Artists: `#{artists.join(', ')}` + Sources: + #{sources.map { |s| "* #{s}" }.join("\n")} + Upload Type: #{original_url.present? ? "[url](#{original_url})" : 'file'} + Uploaded By: <@#{creator.id}> (`#{creator.name}`) + Created At: + Updated At: + DESC + color: GREEN, + timestamp: Time.now.iso8601, + }) + end + + def send_deleted + execute({ + title: "Image Deleted", + description: <<~DESC, + ID: `#{md5}` + Artists: `#{artists.join(', ')}` + Sources: + #{sources.map { |s| "* #{s}" }.join("\n")} + Upload Type: #{original_url.present? ? "[url](#{original_url})" : 'file'} + Uploaded By: <@#{creator.id}> (`#{creator.name}`) + Reason: #{deletion_reason || 'None Provided'} + Created At: + Updated At: + DESC + color: RED, + timestamp: Time.now.iso8601, + }) + end + + def check_change(attr, changes) + changes << "#{attr.to_s.titleize}: **#{send("#{attr}_before_last_save")}** -> **#{send(attr)}**" if send("saved_change_to_#{attr}?") + end + + def send_updated + changes = [] + check_change(:artists, changes) + check_change(:category, changes) + + if sources != sources_before_last_save + diff = [] + sources_before_last_save.each do |source| + diff << "- #{source}" unless sources.include?(source) + end + + sources.each do |source| + diff << "+ #{source}" unless sources_before_last_save.include?(source) + end + + changes << "Sources:\n```diff\n#{diff.join("\n")}\n```" + end + + return if changes.empty? + + changes << "Blame: #{blame}" + execute({ + title: "Image Updated", + description: <<~DESC, + ID: `#{md5}` + #{changes.join("\n")} + DESC + color: YELLOW, + timestamp: Time.now.iso8601, + }) + end + + def blame + if CurrentUser.user.present? + "<@#{CurrentUser.id}> (`#{CurrentUser.name}`)" + elsif Rails.const_defined?("Console") + "**Console**" + elsif CurrentUser.ip_addr + "**#{CurrentUser.ip_addr}**" + else + "**Unknown**" + end + end + end + + include WebhookMethods end diff --git a/app/views/yiff_rest/api_v2/images/delete_with_reason.html.erb b/app/views/yiff_rest/api_v2/images/delete_with_reason.html.erb new file mode 100644 index 0000000..4a0e693 --- /dev/null +++ b/app/views/yiff_rest/api_v2/images/delete_with_reason.html.erb @@ -0,0 +1,14 @@ +<% content_for(:page_title) do %> + YiffyAPI - Delete Image +<% end %> + +<%= render "yiff_rest/api_v2/manage/nav" %> + +
+
+ <%= simple_form_for(@image, url: yiff_rest_api_v2_manage_image_path(manage_id: params[:manage_id], id: params[:id]), method: :delete) do |f| %> + <%= f.input(:deletion_reason) %> + <%= f.button(:submit, "Delete Image", name: nil) %> + <% end %> +
+
diff --git a/app/views/yiff_rest/api_v2/images/index.html.erb b/app/views/yiff_rest/api_v2/images/index.html.erb index a338c35..a5c40a4 100644 --- a/app/views/yiff_rest/api_v2/images/index.html.erb +++ b/app/views/yiff_rest/api_v2/images/index.html.erb @@ -49,7 +49,8 @@ <%= link_to "Edit", edit_yiff_rest_api_v2_manage_image_path(manage_id: params[:id], id: img.id) %> | - <%= link_to "Delete", yiff_rest_api_v2_manage_image_path(manage_id: params[:id], id: img.id), method: :delete %> + <%= link_to "Delete", yiff_rest_api_v2_manage_image_path(manage_id: params[:id], id: img.id), method: :delete %>
+ <%= link_to "Delete W/R", delete_with_reason_yiff_rest_api_v2_manage_image_path(manage_id: params[:id], id: img.id) %> <% end %> diff --git a/config/default_config.rb b/config/default_config.rb index 6498c18..2324f37 100644 --- a/config/default_config.rb +++ b/config/default_config.rb @@ -81,6 +81,10 @@ module Websites # Requests::DiscordWebhook.new(id: "", token: "") end + def yiffyapi_image_logs_webhook + # Requests::DiscordWebhook.new(id: "", token: "") + end + def yiffyapi_apikey_shortener_webhook # Requests::DiscordWebhook.new(id: "", token: "") end @@ -219,7 +223,7 @@ module Websites end def yiffy2_cdn_url - # return "http://yiffy2.local" if Rails.env.development? + return "http://yiffy2.local" if Rails.env.development? "https://v2.yiff.media" end diff --git a/config/routes/yiff_rest_routes.rb b/config/routes/yiff_rest_routes.rb index 71545c3..c873280 100644 --- a/config/routes/yiff_rest_routes.rb +++ b/config/routes/yiff_rest_routes.rb @@ -51,7 +51,9 @@ module YiffRestRoutes collection do get(:logout) put(:sync) - resources(:images, as: "manage_images") + resources(:images, as: "manage_images") do + get(:delete_with_reason, on: :member) + end end end get("/", to: redirect("https://yiff.rest"))