# typed: strict class Domain::Post::E621Post < Domain::Post aux_table :e621 has_single_file! has_faving_users! Domain::User::E621User, Domain::UserPostFav::E621UserPostFav belongs_to_groups! :pools, Domain::PostGroup::E621Pool, Domain::PostGroupJoin::E621PoolJoin belongs_to :parent_post, class_name: "Domain::Post::E621Post", foreign_key: :parent_post_e621_id, primary_key: :e621_id, optional: true belongs_to :uploader_user, class_name: "::Domain::User::E621User", inverse_of: :uploaded_posts, optional: true belongs_to :last_index_page, class_name: "HttpLogEntry", optional: true belongs_to :scan_log_entry, class_name: "HttpLogEntry", optional: true belongs_to :caused_by_entry, class_name: "HttpLogEntry", optional: true validates :state, inclusion: { in: %w[ok removed scan_error file_error] } validates :rating, inclusion: { in: %w[s q e], }, if: ->(p) { p.rating.present? } validates :e621_id, presence: true after_initialize do self.state ||= "ok" self.flags_array ||= [] self.pools_array ||= [] self.sources_array ||= [] self.artists_array ||= [] end sig { params(log_entry: HttpLogEntry).void } def set_index_page_entry(log_entry) self.last_index_page = log_entry self.index_page_ids ||= [] self.index_page_ids << log_entry.id end sig { override.returns(Integer) } def num_post_files_for_view 1 end sig { override.returns([String, Symbol]) } def self.param_prefix_and_attribute ["e621", :e621_id] end sig { override.returns(Symbol) } def self.post_order_attribute :e621_id end sig { override.returns(String) } def self.view_prefix "e621" end sig { override.returns(Domain::DomainType) } def self.domain_type Domain::DomainType::E621 end sig { override.returns(T.nilable(String)) } def title self .sources_array .lazy .filter_map do |source| model = T.cast( T.unsafe(ApplicationController.helpers).link_for_source(source), T.nilable(Domain::PostsHelper::LinkForSource), )&.model return model.title if model && model.is_a?(Domain::Post) end .first || "E621 Post #{self.e621_id}" end sig { override.returns(T.nilable(String)) } def primary_creator_name_fallback_for_view guess_creator_from_sources&.name_for_view || self.class.first_valid_artist_tag_in(self.tags_array&.dig("artist")) || self.class.first_valid_artist_tag_in(self.artists_array) end sig { override.returns(T.nilable(Domain::User)) } def primary_fallback_creator_for_view guess_creator_from_sources end sig { override.returns(T.nilable(String)) } def description_html_for_view self.description end INVALID_ARTIST_TAGS = %w[unknown unknown_artist sound_warning].freeze sig { params(list: T.nilable(T::Array[String])).returns(T.nilable(String)) } def self.first_valid_artist_tag_in(list) list && list .lazy .filter_map { |tag| INVALID_ARTIST_TAGS.include?(tag) ? nil : tag } .first end sig { override.returns(T.nilable(T.any(String, Integer))) } def domain_id_for_view self.e621_id end sig { override.returns(T.nilable(HttpLogEntry)) } def scanned_post_log_entry_for_view self.scan_log_entry || self.last_index_page || self.caused_by_entry end sig { override.returns(String) } def description_html_base_domain "e621.net" end sig { override.returns(T.nilable(Addressable::URI)) } def external_url_for_view if self.e621_id.present? Addressable::URI.parse("https://e621.net/posts/#{self.e621_id}") end end sig { override.returns(T.nilable(Domain::PostFile)) } def primary_file_for_view self.file end sig { returns(String) } def rating_for_view case self.rating when nil "None" when "s" "Safe" when "q" "Questionable" when "e" "Explicit" else "Unknown (#{self.rating})" end end private sig { returns(T.nilable(Domain::User)) } def guess_creator_from_sources self .sources_array .lazy .filter_map do |source| model = T.cast( T.unsafe(ApplicationController.helpers).link_for_source(source), T.nilable(Domain::PostsHelper::LinkForSource), )&.model if model && model.is_a?(Domain::Post) && model.class.has_creators? T.unsafe(model).creator elsif model && model.is_a?(Domain::User) model else nil end end .first end end