app/business_logic/services/btn/release.rb
module Services
module Btn
class Release < Dry::Struct
transform_keys do |key|
key.to_s.underscore.downcase.to_sym
end
REGEX = /(?<name>.*) - S(?<season>\d+)E(?<episode>\d+)\s\[\s(?<year>\d+)\s\]\s\[\s(?<file_type>\w+)\s\|\s(?<file_encoding>[^\s]+)\s\|\s(?<source>[^\s]+)\s\|\s(?<resolution>[^\s]+)/.freeze
attribute :title, Types::String
attribute :url, Types::String
attribute :published_at, Types::JSON::Time
# Data attributes
attribute :name, Types::String
attribute :season, Types::IntegerWithLeadingZero
attribute :episode, Types::IntegerWithLeadingZero
attribute? :year, Types::Coercible::Integer
attribute? :file_type, Types::DowncasedString
attribute :file_encoding, Types::DowncasedString
attribute :source, Types::DowncasedString
attribute :resolution, Types::String
attribute? :hdr, Types::Bool
attribute? :dolby_vision, Types::Bool
def self.from_feed_entry(entry)
matchdata = REGEX.match(entry.title)
if matchdata.present?
new matchdata.names.zip(matchdata.captures).to_h.merge(title: entry.title, url: entry.url, published_at: entry.published, dolby_vision: entry.title.include?(".DV."), hdr: entry.title.include?(".HDR."))
else
NullRelease.new
end
end
def self.from_api_entry(entry)
season_episode = SeasonEpisode.build(entry["GroupName"])
attributes = {
name: entry["Series"],
season: season_episode.season,
episode: season_episode.episode,
file_type: entry["Container"],
file_encoding: entry["Codec"],
source: entry["Source"],
resolution: entry["Resolution"],
title: entry["ReleaseName"],
url: entry["DownloadURL"],
published_at: Time.zone.at(entry["Time"].to_i),
hdr: entry["ReleaseName"].include?(".HDR."),
dolby_vision: entry["ReleaseName"].include?(".DV.")
}
new attributes
end
class SeasonEpisode < Dry::Struct
transform_keys do |key|
key.to_s.underscore.downcase.to_sym
end
attribute :season, Types::Coercible::Integer
attribute :episode, Types::IntegerWithLeadingZero
def self.build(string)
matches = string.match(/S(?<season>\d+)E(?<episode>\d+)/)
if matches
new(season: matches[1], episode: matches[2])
else
new(season: 0, episode: 0)
end
end
end
NullRelease = Naught.build do |config|
config.mimic Release
end
end
end
end