2024-05-03 03:04:43 +00:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
class ShortUrl < ApplicationRecord
|
|
|
|
belongs_to_creator
|
|
|
|
belongs_to :api_key, optional: true
|
|
|
|
|
|
|
|
validates :code, format: { with: /\A[A-Za-z_\-\d]+\z/ }, length: { maximum: 50 }, presence: true, uniqueness: true
|
|
|
|
validates :creator_name, length: { maximum: 50 }
|
|
|
|
validates :url, format: { with: /\A#{URI::DEFAULT_PARSER.make_regexp(%w[http https])}\z/ }, length: { maximum: 2048 }, presence: true
|
|
|
|
before_validation :set_creator_name_if_blank
|
|
|
|
|
|
|
|
before_create do
|
|
|
|
self.code ||= SecureRandom.alphanumeric(8)
|
|
|
|
self.url = url.strip
|
|
|
|
end
|
|
|
|
|
|
|
|
attr_accessor :no_webhook_messages, :skip_validations
|
|
|
|
|
|
|
|
after_create :send_created, unless: :no_webhook_messages
|
|
|
|
after_update :send_updated, unless: :no_webhook_messages
|
|
|
|
after_destroy :send_deleted, unless: :no_webhook_messages
|
|
|
|
|
|
|
|
def self.override(code, url)
|
|
|
|
prev = find_by(code: code)
|
|
|
|
return prev if prev&.url == url && prev&.management_code.nil?
|
|
|
|
CurrentUser.as_system do
|
2024-05-09 02:33:45 +00:00
|
|
|
prev&.update!(code: "#{code}_#{prev.id}")
|
2024-05-03 03:04:43 +00:00
|
|
|
create!(
|
2024-05-09 02:29:00 +00:00
|
|
|
code: code,
|
|
|
|
creator_name: "YiffyAPI",
|
|
|
|
creator_ua: "YiffyAPI",
|
|
|
|
url: url,
|
|
|
|
no_webhook_messages: true,
|
2024-05-03 03:04:43 +00:00
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def shorturl
|
|
|
|
"https://yiff.rocks/#{code}"
|
|
|
|
end
|
|
|
|
|
|
|
|
def credit=(value)
|
|
|
|
self.creator_name = value
|
|
|
|
end
|
|
|
|
|
|
|
|
def set_creator_name_if_blank
|
|
|
|
self.creator_name = creator.name if creator_name.blank?
|
|
|
|
end
|
|
|
|
|
|
|
|
def serializable_hash(*)
|
|
|
|
{
|
|
|
|
code: code,
|
|
|
|
createdAt: created_at,
|
|
|
|
modifiedAt: updated_at,
|
|
|
|
url: url,
|
|
|
|
pos: id,
|
|
|
|
credit: creator_name || creator&.name,
|
|
|
|
fullURL: shorturl,
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
module WebhookMethods
|
|
|
|
GREEN = 0x008000
|
|
|
|
YELLOW = 0xFFA500
|
|
|
|
RED = 0xFF0000
|
|
|
|
|
|
|
|
def execute(content)
|
|
|
|
Websites.config.yiffyapi_apikey_shortener_webhook.execute({
|
|
|
|
embeds: [content],
|
|
|
|
})
|
|
|
|
end
|
|
|
|
|
|
|
|
def send_created
|
|
|
|
execute({
|
|
|
|
title: "Short URL Created",
|
|
|
|
description: <<~DESC,
|
|
|
|
ID: **#{id}**
|
|
|
|
Code: **#{code}**
|
|
|
|
URL: #{url}
|
|
|
|
IP: **#{creator_ip_addr}**
|
|
|
|
User-Agent: **#{creator_ua}**
|
|
|
|
Blame: #{blame}
|
|
|
|
DESC
|
|
|
|
color: GREEN,
|
|
|
|
timestamp: Time.now.iso8601,
|
|
|
|
})
|
|
|
|
end
|
|
|
|
|
|
|
|
def send_deleted
|
|
|
|
execute({
|
|
|
|
title: "Short URL Deleted",
|
|
|
|
description: <<~DESC,
|
|
|
|
ID: **#{id}**
|
|
|
|
Code: **#{code}**
|
|
|
|
URL: #{url}
|
|
|
|
Blame: #{blame}
|
|
|
|
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(:url, changes)
|
|
|
|
check_change(:creator_name, changes)
|
|
|
|
|
|
|
|
return if changes.empty?
|
|
|
|
|
|
|
|
changes << "Blame: #{blame}"
|
|
|
|
execute({
|
|
|
|
title: "Short URL Updated",
|
|
|
|
description: changes.join("\n"),
|
|
|
|
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
|