Skip to content

Commit

Permalink
Enhance Episode and Disk Management with Additional Features and Opti…
Browse files Browse the repository at this point in the history
…mizations (#489)
  • Loading branch information
brand-it authored Oct 31, 2024
1 parent a863f1f commit a2546b1
Show file tree
Hide file tree
Showing 38 changed files with 45,336 additions and 40,692 deletions.
38 changes: 15 additions & 23 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This configuration was generated by
# `rubocop --auto-gen-config --exclude-limit 1000`
# on 2024-10-04 16:12:21 UTC using RuboCop version 1.66.1.
# on 2024-10-31 17:43:13 UTC using RuboCop version 1.67.0.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
Expand All @@ -18,25 +18,25 @@ Lint/UnreachableCode:
Exclude:
- 'lib/tasks/upload.rake'

# Offense count: 18
# Offense count: 23
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
Metrics/AbcSize:
Max: 55
Max: 69

# Offense count: 3
# Offense count: 5
# Configuration parameters: CountComments, CountAsOne.
Metrics/ClassLength:
Max: 207
Max: 214

# Offense count: 4
# Offense count: 5
# Configuration parameters: AllowedMethods, AllowedPatterns.
Metrics/CyclomaticComplexity:
Max: 20

# Offense count: 17
# Offense count: 21
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
Metrics/MethodLength:
Max: 25
Max: 37

# Offense count: 1
# Configuration parameters: CountComments, CountAsOne.
Expand All @@ -46,7 +46,7 @@ Metrics/ModuleLength:
# Offense count: 1
# Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
Metrics/ParameterLists:
Max: 12
Max: 13

# Offense count: 4
# Configuration parameters: AllowedMethods, AllowedPatterns.
Expand All @@ -58,24 +58,23 @@ Naming/ConstantName:
Exclude:
- 'app/models/config/serializer.rb'

# Offense count: 2
# Offense count: 1
# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
# AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to
Naming/MethodParameterName:
Exclude:
- 'app/controllers/seasons_controller.rb'
- 'app/listeners/the_movie_db/video_listener.rb'

# Offense count: 2
# Offense count: 8
# Configuration parameters: CountAsOne.
RSpec/ExampleLength:
Max: 13

# Offense count: 6
# Offense count: 11
RSpec/MultipleExpectations:
Max: 3

# Offense count: 1
# Offense count: 6
# Configuration parameters: AllowSubject, Max.
RSpec/MultipleMemoizedHelpers:
Exclude:
Expand All @@ -93,23 +92,16 @@ RSpec/SubjectStub:
Exclude:
- 'spec/listeners/disk_listener_spec.rb'

# Offense count: 12
# Offense count: 8
Rails/I18nLocaleTexts:
Exclude:
- 'app/controllers/config/make_mkvs_controller.rb'
- 'app/controllers/config/plexes_controller.rb'
- 'app/controllers/config/slacks_controller.rb'
- 'app/controllers/config/the_movie_dbs_controller.rb'
- 'app/controllers/users_controller.rb'
- 'app/models/config/slack.rb'

# Offense count: 1
# This cop supports safe autocorrection (--autocorrect).
Style/IfUnlessModifier:
Exclude:
- 'app/controllers/config/the_movie_dbs_controller.rb'

# Offense count: 9
# Offense count: 20
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns.
# URISchemes: http, https
Expand Down
4 changes: 3 additions & 1 deletion app/components/movie_title_table_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
<th>Duration (<%= distance_of_time_in_words @movie.movie_runtime.seconds %>)</th>
<th>Size</th>
<th>Edition</th>
<th><a class='btn btn-info' data-action="click->manage-selections#clearInputs">Select None</a></th>
<th>
<a class='btn btn-info' data-action="click->manage-selections#clearInputs">Select None</a>
</th>
</tr>
</thead>
<tbody class="disk_titles">
Expand Down
4 changes: 2 additions & 2 deletions app/components/search_component.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<%= simple_form_for search_service, as: :search, url: the_movie_dbs_path, method: :get, html: { class: 'row pb-4', style: "margin: auto; width: 50%;" }, data: { turbo_frame: 'videos', turbo_action: 'replace', controller: 'submit-on-keyup' } do |f| %>
<%= simple_form_for search_service, as: :search, url: the_movie_dbs_path, method: :get, html: { class: 'row pb-4', style: "margin: auto; width: 50%;" }, data: form_data do |f| %>
<div class='col-8 col-md-10 col-lg-10 p-0'>
<%= f.input :query, label: 'Search for TV or Movie', autofocus: true, required: false, input_html: { data: { action: "keyup->submit-on-keyup#submitWithDebounce", submit_on_keyup_target: :input } } %>
<%= f.input :query, label: 'Search for TV or Movie', autofocus: true, required: false, input_html: input_html %>
</div>
<div class='col align-self-center p-0 text-center mt-2'>
<%= f.button :submit, 'Search', data: { disable_with: 'Searching' } %>
Expand Down
27 changes: 27 additions & 0 deletions app/components/search_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,31 @@ class SearchComponent < ViewComponent::Base
extend Dry::Initializer

option :search_service, Types.Instance(::VideoSearchQuery), default: -> { VideoSearchQuery.new }
option :submit_on_key_up, Types::Coercible::Bool, default: -> { true }

def form_data
if submit_on_key_up
{
turbo_frame: 'videos',
turbo_action: 'replace',
controller: 'submit-on-keyup'
}
else
{
turbo_frame: 'videos',
turbo_action: 'replace'
}
end
end

def input_html
return {} unless submit_on_key_up

{
data: {
action: 'keyup->submit-on-keyup#submitWithDebounce',
submit_on_keyup_target: :input
}
}
end
end
39 changes: 28 additions & 11 deletions app/controllers/seasons_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,43 @@ def show
end

def rip
tv = Tv.find(params[:tv_id])
season = tv.seasons.find(params[:id])
disk = Disk.find(params[:disk_id])
disk_titles = rip_disk_titles(tv, disk, season)
job = RipWorker.perform_async(disk_id: disk.id, disk_titles:)
job = RipWorker.perform_async(disk_id: disk.id, disk_titles: rip_disk_titles)
redirect_to job_path(job)
end

private

def rip_disk_titles(tv, disk, season)
episode_params.map do |episode_param|
episode = season.episodes.find { _1.id == episode_param[:id].to_i }
def season
@season ||= tv.seasons.find(params[:id])
end

def disk
@disk ||= Disk.find(params[:disk_id])
end

def tv
@tv ||= Tv.find(params[:tv_id])
end

def rip_disk_titles
@rip_disk_titles ||= episode_params.map do |episode_param|
episode = season.episodes.find { _1.id == episode_param[:episode_id].to_i }
disk_title = disk.disk_titles.find { _1.id == episode_param[:disk_title_id].to_i }
disk_title.update!(video: tv, episode:)
{ id: disk_title.id }
if disk_title.episode
disk_title.update!(video: tv, episode_last: episode)
else
disk_title.update!(video: tv, episode:)
end
RipWorker::DiskTitleHash[{
id: disk_title.id,
part: episode_param[:part].presence&.to_i
}]
end
end

def episode_params
params[:episodes].reject { _1[:disk_title_id].blank? }
params[:episodes].reject { _1[:episode_id].blank? }.sort_by do |episode_param|
season.episodes.find { _1.id == episode_param[:episode_id].to_i }.episode_number
end
end
end
12 changes: 12 additions & 0 deletions app/models/disk_title.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
# updated_at :datetime not null
# disk_id :bigint
# episode_id :integer
# episode_last_id :integer
# mkv_progress_id :bigint
# title_id :integer not null
# video_blob_id :integer
Expand All @@ -25,6 +26,7 @@
#
# index_disk_titles_on_disk_id (disk_id)
# index_disk_titles_on_episode_id (episode_id)
# index_disk_titles_on_episode_last_id (episode_last_id)
# index_disk_titles_on_mkv_progress_id (mkv_progress_id)
# index_disk_titles_on_video (video_id)
# index_disk_titles_on_video_blob_id (video_blob_id)
Expand All @@ -34,6 +36,7 @@ class DiskTitle < ApplicationRecord

belongs_to :video, optional: true
belongs_to :episode, optional: true
belongs_to :episode_last, optional: true, class_name: 'Episode'
belongs_to :disk, optional: true

belongs_to :video_blob, optional: true
Expand All @@ -43,11 +46,20 @@ class DiskTitle < ApplicationRecord

validates :filename, presence: true

before_save :set_episode_last

def duration
super&.seconds
end

def to_label
"##{title_id} #{name} #{distance_of_time_in_words(duration)}"
end

private

def set_episode_last
self.episode_last = nil if episode.nil?
self.episode_last ||= episode
end
end
21 changes: 16 additions & 5 deletions app/models/episode.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,30 +21,41 @@
# index_episodes_on_season_id (season_id)
#
class Episode < ApplicationRecord
include ActionView::Helpers::DateHelper

belongs_to :season
has_many :disk_titles, dependent: :nullify
has_many :ripped_disk_titles, -> { ripped }, class_name: 'DiskTitle', dependent: false, inverse_of: :episode
has_many :video_blobs, dependent: :nullify
has_many :uploaded_video_blobs, -> { uploaded }, class_name: 'VideoBlob', dependent: false, inverse_of: :episode

validates :episode_number, presence: true

scope :order_by_episode_number, -> { order(:episode_number) }

delegate :tv, to: :season
delegate :title, :plex_name, to: :tv, prefix: true
EPISODE_RUNNTIME_MARGIN = 3.minutes.to_i

def runtime
@runtime ||= super&.minutes
def to_label
"s#{season.format_season_number}e#{format_episode_number} - #{runtime ? distance_of_time_in_words(runtime) : 'runtime unknown'} - #{name}"
end

def runtime_range
return if runtime.nil?

@runtime_range ||= (runtime - 3.minutes)...(runtime + 3.minutes)
@runtime_range ||= (runtime - EPISODE_RUNNTIME_MARGIN)...(runtime + EPISODE_RUNNTIME_MARGIN)
end

def plex_name
[tv.plex_name, "s#{season.format_season_number}e#{format_episode_number}", name].compact_blank.join(' - ')
def plex_name(part: nil, episode_last: nil)
[
tv.plex_name,
[
"s#{season.format_season_number}e#{format_episode_number}",
("e#{episode_last.format_episode_number}" if episode_last && episode_last.id != id)
].compact_blank.join('-'),
part ? "pt#{part}" : name
].compact_blank.join(' - ')
end

def format_episode_number
Expand Down
21 changes: 18 additions & 3 deletions app/models/video_blob.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,19 @@
# key :string not null
# metadata :text
# optimized :boolean default(FALSE), not null
# part :integer
# uploadable :boolean default(FALSE), not null
# uploaded_on :datetime
# created_at :datetime not null
# updated_at :datetime not null
# episode_id :bigint
# episode_last_id :integer
# video_id :integer
#
# Indexes
#
# idx_on_extra_type_number_video_id_extra_type_1978193db6 (extra_type_number,video_id,extra_type) UNIQUE
# index_video_blobs_on_episode_last_id (episode_last_id)
# index_video_blobs_on_key (key) UNIQUE
# index_video_blobs_on_key_and_service_name (key) UNIQUE
# index_video_blobs_on_video (video_id)
Expand All @@ -47,6 +50,7 @@ class VideoBlob < ApplicationRecord

belongs_to :video
belongs_to :episode, optional: true
belongs_to :episode_last, optional: true, class_name: 'Episode'
has_many :disk_titles, dependent: :nullify

scope :checksum, -> { where.not(checksum: nil) }
Expand All @@ -66,6 +70,7 @@ class VideoBlob < ApplicationRecord
:extra,
:filename,
:optimized,
:part,
:plex_version,
:season,
:title,
Expand All @@ -78,6 +83,8 @@ class VideoBlob < ApplicationRecord

before_validation :set_defaults
before_validation :set_edition
before_validation :set_part
before_validation :set_episode_last

validates :key, presence: true, uniqueness: { message: ->(blob, _) { "#{blob.key} has already been taken" } }
validates :extra_type, presence: true
Expand All @@ -86,8 +93,7 @@ class VideoBlob < ApplicationRecord

def title
if video.tv?
season = episode.season
"#{video.title} - S#{season.season_number}E#{episode.episode_number} #{episode.name}"
episode_plex_name(part:, episode_last:)
elsif feature_films?
video.title
else
Expand Down Expand Up @@ -141,7 +147,7 @@ def plex_name
video_plex_name, ("{edition-#{edition}}" if edition.present?)
].compact_blank.join(' ')
elsif video&.tv?
episode_plex_name
episode_plex_name(part:, episode_last:)
end
end

Expand Down Expand Up @@ -193,4 +199,13 @@ def set_defaults
def set_edition
self.edition = parsed_edition
end

def set_part
self.part ||= parsed_part
end

def set_episode_last
self.episode_last = nil if episode.nil?
self.episode_last ||= episode
end
end
Loading

0 comments on commit a2546b1

Please sign in to comment.