# frozen_string_literal: true module DupeTools FORMATS_ORDER = %w[video/webm image/svg+xml image/png image/gif image/jpeg other].freeze def forward_merge? duplicate_of_post.id > post.id end def both_are_images? post.media_type == 'image' && duplicate_of_post.media_type == 'image' end def target_longer? return false unless both_are_images? duplicate_of_post.image.duration > post.image.duration end def source_longer? return false unless both_are_images? post.image.duration > duplicate_of_post.image.duration end def higher_res? return false unless both_are_images? duplicate_of_post.image.width > post.image.width || duplicate_of_post.image.height > post.image.height end def same_res? return true unless both_are_images? duplicate_of_post.image.width == post.image.width && duplicate_of_post.image.height == post.image.height end def same_format? return false unless both_are_images? duplicate_of_post.image.mime_type == post.image.mime_type end def better_format? return false unless both_are_images? source_index = FORMATS_ORDER.index(post.image.mime_type) || FORMATS_ORDER.length - 1 target_index = FORMATS_ORDER.index(duplicate_of_post.image.mime_type) || FORMATS_ORDER.length - 1 target_index < source_index end def same_aspect_ratio? return true unless both_are_images? (duplicate_of_post.image.aspect_ratio - post.image.aspect_ratio).abs <= 0.009 end def neither_have_source? duplicate_of_post.source_url.blank? && post.source_url.blank? end def same_source? duplicate_of_post.source_url.to_s == post.source_url.to_s end def similar_source? host1 = Addressable::URI.parse(post.source_url).host.to_s host2 = Addressable::URI.parse(duplicate_of_post.source_url).host.to_s host1 == host2 || host1.end_with?('deviantart.com') && host2.end_with?('deviantart.com') rescue StandardError false # can't parse the URI end def source_on_target? duplicate_of_post.source_url.present? && post.source_url.blank? end def source_on_source? duplicate_of_post.source_url.blank? && post.source_url.present? end def same_artist_tags? source_artist_tags == target_artist_tags end def more_artist_tags_on_target? target_artist_tags.superset? source_artist_tags end def more_artist_tags_on_source? source_artist_tags.superset? target_artist_tags end def target_artist_tags @_target_artist_tags ||= duplicate_of_post.tags.where(namespace: :artist).to_set end def source_artist_tags @_source_artist_tags ||= post.tags.where(namespace: :artist).to_set end def same_rating_tags? target_rating_tags == source_rating_tags end def target_rating_tags @_target_rating_tags ||= duplicate_of_post.tags.rating_tags.to_set end def source_rating_tags @_source_rating_tags ||= post.tags.rating_tags.to_set end def target_is_edit? @_target_is_edit ||= duplicate_of_post.tags.where(name: 'edit').present? end def source_is_edit? @_source_is_edit ||= post.tags.where(name: 'edit').present? end def both_are_edits? source_is_edit? && target_is_edit? end def target_is_alternate_version? @_target_is_alternate_version ||= duplicate_of_post.tags.where(name: 'alternate version').present? end def source_is_alternate_version? @_source_is_alternate_version ||= post.tags.where(name: 'alternate version').present? end def both_are_alternate_versions? source_is_alternate_version? && target_is_alternate_version? end def neither_have_locations? source.locations.blank? && target.locations.blank? end end