# frozen_string_literal: true # == Schema Information # # Table name: instance_infos # # id :bigint(8) not null, primary key # domain :string default(""), not null # software :string default(""), not null # version :string default(""), not null # data :jsonb not null # created_at :datetime not null # updated_at :datetime not null # class InstanceInfo < ApplicationRecord after_commit :reset_cache EMOJI_REACTION_AVAILABLE_SOFTWARES = %w( akkoma calckey catodon cherrypick fedibird firefish iceshrimp meisskey misskey pleroma sharkey tanukey ).freeze QUOTE_AVAILABLE_SOFTWARES = EMOJI_REACTION_AVAILABLE_SOFTWARES + %w(bridgy-fed).freeze STATUS_REFERENCE_AVAILABLE_SOFTWARES = %w(fedibird).freeze CIRCLE_AVAILABLE_SOFTWARES = %w(fedibird).freeze MISSKEY_FORKS = %w( calckey cherrypick firefish iceshrimp meisskey misskey rosekey sharkey tanukey ).freeze INVALID_SUBSCRIPTION_SOFTWARES = MISSKEY_FORKS - %w(firefish) PROXY_ACCOUNT_SOFTWARES = MISSKEY_FORKS NO_LANGUAGE_FLAG_SOFTWARES = MISSKEY_FORKS - %w(firefish) class << self def available_features(domain) return local_features if domain.nil? Rails.cache.fetch("domain_available_features:#{domain}") { load_available_features(domain) } end def invalid_subscription_software?(domain) INVALID_SUBSCRIPTION_SOFTWARES.include?(software_name(domain)) end def proxy_account_software?(domain) PROXY_ACCOUNT_SOFTWARES.include?(software_name(domain)) end def no_language_flag_software?(domain) NO_LANGUAGE_FLAG_SOFTWARES.include?(software_name(domain)) end private def load_available_features(domain) return local_features if domain.nil? info = InstanceInfo.find_by(domain: domain) { emoji_reaction: feature_available?(info, EMOJI_REACTION_AVAILABLE_SOFTWARES, 'emoji_reaction'), quote: feature_available?(info, QUOTE_AVAILABLE_SOFTWARES, 'quote'), status_reference: feature_available?(info, STATUS_REFERENCE_AVAILABLE_SOFTWARES, 'status_reference'), circle: feature_available?(info, CIRCLE_AVAILABLE_SOFTWARES, 'circle'), } end def local_features { emoji_reaction: Setting.enable_emoji_reaction, quote: true, status_reference: true, circle: true, } end def feature_available?(info, softwares, feature_name) return false if info.nil? softwares.include?(info.software) || metadata_features(info)&.include?(feature_name) || false end def metadata_features(info) return nil unless info.data.is_a?(Hash) && info.data['metadata'].is_a?(Hash) && info.data['metadata']['features'].is_a?(Array) info.data['metadata']['features'] end def software_name(domain) Rails.cache.fetch("software_name:#{domain}") { load_software_name(domain) } end def load_software_name(domain) return 'threads' if domain == 'threads.net' info = InstanceInfo.find_by(domain: domain) return nil if info.nil? info.software end end private def reset_cache Rails.cache.delete("domain_available_features:#{domain}") Rails.cache.delete("software_name:#{domain}") end end