about summary refs log tree commit diff
path: root/app/models/preview_card_provider.rb
blob: 1dd95fc91cbe3fb4928336cb855a23a31a0226b3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# frozen_string_literal: true

# == Schema Information
#
# Table name: preview_card_providers
#
#  id                  :bigint(8)        not null, primary key
#  domain              :string           default(""), not null
#  icon_file_name      :string
#  icon_content_type   :string
#  icon_file_size      :bigint(8)
#  icon_updated_at     :datetime
#  trendable           :boolean
#  reviewed_at         :datetime
#  requested_review_at :datetime
#  created_at          :datetime         not null
#  updated_at          :datetime         not null
#

class PreviewCardProvider < ApplicationRecord
  include DomainNormalizable
  include Attachmentable

  ICON_MIME_TYPES = %w(image/x-icon image/vnd.microsoft.icon image/png).freeze
  LIMIT = 1.megabyte

  validates :domain, presence: true, uniqueness: true, domain: true

  has_attached_file :icon, styles: { static: { format: 'png', convert_options: '-coalesce +profile "!icc,*" +set modify-date +set create-date' } }, validate_media_type: false
  validates_attachment :icon, content_type: { content_type: ICON_MIME_TYPES }, size: { less_than: LIMIT }
  remotable_attachment :icon, LIMIT

  scope :trendable, -> { where(trendable: true) }
  scope :not_trendable, -> { where(trendable: false) }
  scope :reviewed, -> { where.not(reviewed_at: nil) }
  scope :pending_review, -> { where(reviewed_at: nil) }

  def requires_review?
    reviewed_at.nil?
  end

  def reviewed?
    reviewed_at.present?
  end

  def requested_review?
    requested_review_at.present?
  end

  def requires_review_notification?
    requires_review? && !requested_review?
  end

  def self.matching_domain(domain)
    segments = domain.split('.')
    where(domain: segments.map.with_index { |_, i| segments[i..-1].join('.') }).order(Arel.sql('char_length(domain) desc')).first
  end
end