2024-10-21 22:58:53 +00:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
class ExternalAPIImage < ApplicationRecord
|
|
|
|
class Error < StandardError; end
|
|
|
|
CACHE_TIME = 2.days
|
|
|
|
IGNORED_ARTISTS = %w[avoid_posting conditional_dnp sound_warning epilepsy_warning].freeze
|
|
|
|
|
2024-10-22 00:16:52 +00:00
|
|
|
Site = Struct.new(:name, :value, :format)
|
|
|
|
SITES = [
|
|
|
|
Site.new("E621", "e621", "https://e621.net/posts/%s"),
|
|
|
|
Site.new("Femboy Fans", "femboyfans", "https://femboy.fan/posts/%s"),
|
|
|
|
].freeze
|
|
|
|
|
2024-10-21 22:58:53 +00:00
|
|
|
belongs_to :api_image
|
|
|
|
|
2024-10-22 00:16:52 +00:00
|
|
|
validates :site, inclusion: { in: SITES.map(&:value) }
|
2024-10-24 09:36:59 +00:00
|
|
|
validate :not_deleted, on: :create
|
2024-10-21 22:58:53 +00:00
|
|
|
|
2024-10-22 00:16:52 +00:00
|
|
|
enum site: SITES.to_h { |s| [s.value, s.value] }
|
2024-10-21 22:58:53 +00:00
|
|
|
|
|
|
|
module DataMethods
|
|
|
|
def url
|
|
|
|
case site
|
|
|
|
when "e621"
|
|
|
|
"https://e621.net/posts/#{external_id}"
|
|
|
|
when "femboyfans"
|
|
|
|
"https://femboy.fan/posts/#{external_id}"
|
|
|
|
else
|
|
|
|
data_error("format url")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def file_url
|
|
|
|
return nil if is_deleted?
|
|
|
|
case site
|
|
|
|
when "e621", "femboyfans"
|
|
|
|
cache.dig("file", "url")
|
|
|
|
else
|
|
|
|
data_error("format file_url")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def width
|
|
|
|
case site
|
|
|
|
when "e621", "femboyfans"
|
|
|
|
cache.dig("file", "width")
|
|
|
|
else
|
|
|
|
data_error("format width")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def height
|
|
|
|
case site
|
|
|
|
when "e621", "femboyfans"
|
|
|
|
cache.dig("file", "height")
|
|
|
|
else
|
|
|
|
data_error("format height")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def size
|
|
|
|
case site
|
|
|
|
when "e621", "femboyfans"
|
|
|
|
cache.dig("file", "size")
|
|
|
|
else
|
|
|
|
data_error("format size")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def ext
|
|
|
|
case site
|
|
|
|
when "e621", "femboyfans"
|
|
|
|
cache.dig("file", "ext")
|
|
|
|
else
|
|
|
|
data_error("format ext")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def md5
|
|
|
|
case site
|
|
|
|
when "e621", "femboyfans"
|
|
|
|
cache.dig("file", "md5")
|
|
|
|
else
|
|
|
|
data_error("format md5")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def is_deleted?
|
|
|
|
case site
|
|
|
|
when "e621", "femboyfans"
|
|
|
|
cache.dig("flags", "deleted")
|
|
|
|
else
|
|
|
|
false
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def artists
|
|
|
|
case site
|
|
|
|
when "e621", "femboyfans"
|
|
|
|
cache.dig("tags", "artist") - IGNORED_ARTISTS
|
|
|
|
else
|
|
|
|
data_error("format artists")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def sources
|
|
|
|
case site
|
|
|
|
when "e621", "femboyfans"
|
|
|
|
[url] + cache["sources"].select { |s| s.start_with?("http") }
|
|
|
|
else
|
|
|
|
data_error("format sources")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def report_url
|
|
|
|
case site
|
|
|
|
when "e621", "femboyfans"
|
|
|
|
url
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def data_error(text)
|
|
|
|
raise(Error, "Don't know how to #{text} for ExternalApiImage #{id}: #{site}")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
module CacheMethods
|
|
|
|
def cache
|
|
|
|
update_cache! if cached_data.blank?
|
|
|
|
update_cache if cache_expired?
|
|
|
|
cached_data
|
|
|
|
end
|
|
|
|
|
|
|
|
def cache_expired?
|
|
|
|
cache_last_updated_at < CACHE_TIME.ago
|
|
|
|
end
|
|
|
|
|
|
|
|
def update_cache
|
|
|
|
UpdateExternalCacheJob.perform_later(self)
|
|
|
|
end
|
|
|
|
|
|
|
|
def update_cache!
|
|
|
|
case site
|
|
|
|
when "e621"
|
|
|
|
data = Requests::E621.get_post(id: external_id)
|
|
|
|
when "femboyfans"
|
|
|
|
data = Requests::FemboyFans.get_post(id: external_id)
|
|
|
|
else
|
|
|
|
data_error("update cache")
|
|
|
|
end
|
|
|
|
update(cached_data: data, cache_last_updated_at: Time.now)
|
|
|
|
if is_deleted?
|
|
|
|
api_image.remove_iqdb
|
|
|
|
else
|
|
|
|
api_image.update_iqdb
|
|
|
|
end
|
|
|
|
api_image.update(is_viewable: !is_deleted?)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
include CacheMethods
|
|
|
|
include DataMethods
|
2024-10-24 09:36:59 +00:00
|
|
|
|
|
|
|
def not_deleted
|
|
|
|
if is_deleted?
|
|
|
|
errors.add(:external_id, "is deleted")
|
|
|
|
throw(:abort)
|
|
|
|
end
|
|
|
|
end
|
2024-10-21 22:58:53 +00:00
|
|
|
end
|