Websites/app/models/external_api_image.rb

171 lines
3.5 KiB
Ruby

# 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
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
belongs_to :api_image
validates :site, inclusion: { in: SITES.map(&:value) }
validate :not_deleted, on: :create
enum site: SITES.to_h { |s| [s.value, s.value] }
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
def not_deleted
if is_deleted?
errors.add(:external_id, "is deleted")
throw(:abort)
end
end
end