a11yist/app/models/link.rb

66 lines
1.3 KiB
Ruby
Raw Normal View History

2024-09-05 22:54:38 +02:00
# frozen_string_literal: true
require "net/http"
2024-07-26 03:26:57 +02:00
2024-07-26 00:59:00 +02:00
class Link < ApplicationRecord
belongs_to :link_category
2024-09-05 22:54:38 +02:00
has_and_belongs_to_many :checks
2024-09-11 20:44:33 +02:00
has_rich_text :description
2024-07-26 00:59:00 +02:00
validates :url, :text, presence: true
validate :check_url
validate :valid_url
2024-07-26 03:26:57 +02:00
2024-07-26 00:59:00 +02:00
before_validation :ensure_absolute_url
2024-09-05 22:54:38 +02:00
def t_text
text
end
2024-07-26 00:59:00 +02:00
def ok?
2024-09-05 22:54:38 +02:00
fail_count.zero?
end
def to_s
"#{text} (#{url})"
2024-07-26 00:59:00 +02:00
end
private
2024-09-05 22:54:38 +02:00
USER_AGENT = "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0"
2024-07-26 00:59:00 +02:00
def check_url(input = url, add_error = true)
response = begin
2024-07-26 03:26:57 +02:00
Net::HTTP.get_response(URI.parse(input), 'User-Agent': USER_AGENT)
2024-07-26 00:59:00 +02:00
rescue Socket::ResolutionError
errors.add(:url, :invalid) if add_error
return false
end
2024-07-26 03:26:57 +02:00
2024-07-26 00:59:00 +02:00
case response
when Net::HTTPSuccess
self.last_check_at = Time.zone.now
self.fail_count = 0
2024-07-26 03:26:57 +02:00
2024-07-26 00:59:00 +02:00
true
when Net::HTTPRedirection
check_url(response[:location])
else
self.last_check_at = Time.zone.now
self.fail_count += 1
errors.add(:url, :invalid) if add_error
false
end
end
def ensure_absolute_url
2024-07-26 03:26:57 +02:00
self.url = "https://#{url}" unless url.match?(%r{https{0,1}://.*})
2024-07-26 00:59:00 +02:00
end
def valid_url
2024-07-26 03:26:57 +02:00
errors.add(:url, :invalid) unless url.match(/\A#{URI::DEFAULT_PARSER.make_regexp(%w[http https])}\z/)
2024-07-26 00:59:00 +02:00
end
end