Websites/app/models/short_url.rb

138 lines
3.4 KiB
Ruby

# 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
prev&.update!(code: "#{code}_#{prev.id}")
create!(
code: code,
creator_name: "YiffyAPI",
creator_ua: "YiffyAPI",
url: url,
no_webhook_messages: true,
)
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