60 lines
1.7 KiB
Ruby
60 lines
1.7 KiB
Ruby
# typed: strict
|
|
|
|
module FaUriHelper
|
|
extend T::Sig
|
|
|
|
FA_CDN_HOSTS = %w[d.facdn.net d.furaffinity.net].freeze
|
|
|
|
class FaMediaUrlInfo < T::ImmutableStruct
|
|
extend T::Sig
|
|
include T::Struct::ActsAsComparable
|
|
|
|
const :url_name, String
|
|
const :original_file_posted, Integer
|
|
const :latest_file_posted, Integer
|
|
const :filename, String
|
|
const :filename_with_ts, String
|
|
|
|
sig { returns(Time) }
|
|
def original_file_posted_at
|
|
Time.at(original_file_posted)
|
|
end
|
|
|
|
sig { returns(Time) }
|
|
def latest_file_posted_at
|
|
Time.at(latest_file_posted)
|
|
end
|
|
end
|
|
|
|
sig { params(url_str: String).returns(T.nilable(FaMediaUrlInfo)) }
|
|
def self.parse_fa_media_url(url_str)
|
|
uri = Addressable::URI.parse(url_str)
|
|
return nil unless is_fa_cdn_host?(uri.host)
|
|
# paths are in the form of `art/<user.url_name>/<latest_file_ts>/<og_file_ts>.<rest_of_filename>`
|
|
# latest_file_ts is the timestamp of the most up to date file that has been uploaded for the post
|
|
# og_file_ts is the timestamp of when the post was originally made
|
|
path = uri.path
|
|
match =
|
|
path.match(
|
|
%r{/art/(?<url_name>[^/]+)/(stories/)?(?<latest_ts>\d+)/(?<original_ts>\d+)\.(?<filename>.*)},
|
|
)
|
|
return nil unless match
|
|
url_name = match[:url_name]
|
|
latest_ts = match[:latest_ts].to_i
|
|
original_ts = match[:original_ts].to_i
|
|
filename = match[:filename]
|
|
FaMediaUrlInfo.new(
|
|
url_name:,
|
|
original_file_posted: original_ts,
|
|
latest_file_posted: latest_ts,
|
|
filename:,
|
|
filename_with_ts: path.split("/").last,
|
|
)
|
|
end
|
|
|
|
sig { params(host: String).returns(T::Boolean) }
|
|
def self.is_fa_cdn_host?(host)
|
|
FA_CDN_HOSTS.include?(host)
|
|
end
|
|
end
|