Skip to content

Commit

Permalink
Make tv shows show all episodes (#491)
Browse files Browse the repository at this point in the history
  • Loading branch information
brand-it authored Oct 31, 2024
1 parent a2546b1 commit bcc6324
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 122 deletions.
2 changes: 1 addition & 1 deletion app/controllers/seasons_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def rip_disk_titles
end

def episode_params
params[:episodes].reject { _1[:episode_id].blank? }.sort_by do |episode_param|
params[:episodes].reject { _1[:episode_id].blank? || _1[:disk_title_id].blank? }.sort_by do |episode_param|
season.episodes.find { _1.id == episode_param[:episode_id].to_i }.episode_number
end
end
Expand Down
2 changes: 1 addition & 1 deletion app/models/disk_title.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def duration
end

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

private
Expand Down
37 changes: 21 additions & 16 deletions app/services/episode_disk_title_selector_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,44 +8,49 @@ class EpisodeDiskTitleSelectorService < ApplicationService
:uploaded?
)

option :disk, Types.Instance(Disk)
option :disk, Types.Instance(Disk).optional
option :episodes, Types::Coercible::Array.of(Types.Instance(Episode))

def call
disk.disk_titles.map do |disk_title|
sort_episodes.map do |episode|
Info.new(
disk_title,
select_episode(disk_title),
ripped?(disk_title),
uploaded?(disk_title)
episode_disk_title(episode),
episode,
episode.ripped_disk_titles.any?,
uploaded?(episode)
)
end
end

private

def episode_disk_title(episode)
return if disk.nil?
return if selected_episodes.include?(episode)

disk.disk_titles.find { within_range?(episode, _1) && selected_disk_titles.exclude?(_1) }.tap do |disk_title|
selected_disk_titles.append(disk_title) if disk_title
end
end

def select_episode(disk_title)
episode = sort_episodes.find { selected_episodes.exclude?(_1) && within_range?(_1, disk_title) }
selected_episodes.append(episode)
episode
end

def ripped?(disk_title)
ripped_disk_titles.any? { _1.filename == disk_title.filename }
end

def uploaded?(disk_title)
ripped_disk_titles.find { _1.filename == disk_title.filename }&.video_blob&.uploaded? || false
end

def ripped_disk_titles
@ripped_disk_titles ||= episodes.flat_map(&:ripped_disk_titles)
def uploaded?(episode)
episode.ripped_disk_titles.any? { _1&.video_blob&.uploaded? }
end

def within_range?(episode, disk_title)
episode.runtime_range.include?(disk_title.duration)
end

def selected_disk_titles
@selected_disk_titles ||= []
end

def selected_episodes
@selected_episodes ||= episodes.select do |episode|
episode.ripped_disk_titles.any? || episode.uploaded_video_blobs.any?
Expand Down
162 changes: 59 additions & 103 deletions app/views/seasons/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -10,69 +10,8 @@
</ol>
</nav>
<hr/>
<% if @disks.any? %>
<%= simple_form_for :episodes, url: rip_tv_season_path(@tv, @season), class: 'pb-4', data: { controller: 'manage-selections' } do |f| %>
<%= hidden_field_tag :disk_id, @disks.first&.id %>
<table class="table">
<thead>
<tr>
<th>Ripped</th>
<th>Uploaded</th>
<th>#</th>
<th>Name</th>
<th>Filename</th>
<th>Angle</th>
<th>Duration</th>
<th>
<a class='btn btn-info' data-action="click->manage-selections#clearInputs">Clear Selected Episodes</a>
</th>
<th>Part</th>
</tr>
</thead>
<tbody>
<% EpisodeDiskTitleSelectorService.call(disk: @disks.first, episodes: @season.episodes).each do |title| %>
<%= hidden_field_tag "episodes[][disk_title_id]", title.disk_title.id %>
<tr>
<td>
<h1>
<% if title.ripped? %>
<%= icon('square-check') %>
<% else %>
<%= icon('square') %>
<% end %>
</h1>
</td>
<td>
<h1>
<% if title.uploaded? %>
<%= icon('square-check') %>
<% else %>
<%= icon('square') %>
<% end %>
</h1>
</td>
<td>#<%= title.disk_title.title_id %></td>
<td><%= title.disk_title.name %></td>
<td><%= title.disk_title.filename %></td>
<td><%= title.disk_title.angle %></td>
<td><%= distance_of_time_in_words(title.disk_title.duration) %></td>
<td>
<%= select_tag 'episodes[][episode_id]',
options_from_collection_for_select(@season.episodes, :id, :to_label, title.episode&.id), prompt: "Select Episode", data: { manage_selections_target: :input } %>
</td>
<td>
<%= number_field_tag "episodes[][part]" %>
</td>
</tr>
<% end %>
</tbody>
<div class='bg-dark w-100 fixed-bottom mt-1 text-right p-3 border-top'>
<%= f.button :submit, 'Rip Disk' %>
</div>
</table>
<% end %>
<% else %>

<%= simple_form_for :episodes, url: rip_tv_season_path(@tv, @season), class: 'pb-4', data: { controller: 'manage-selections' } do |f| %>
<%= hidden_field_tag :disk_id, @disks.first&.id %>
<table class="table">
<thead>
<tr>
Expand All @@ -88,48 +27,65 @@
</tr>
</thead>
<tbody>
<% @season.episodes.each do |episode| %>
<tr>
<td>
<%= imdb_image_tag episode.still_path, width: 100, height: 100 %>
</td>
<td class="text-center">
<h1>
<% if episode.ripped_disk_titles.any? %>
<%= icon('square-check') %>
<% else %>
<%= icon('square') %>
<% EpisodeDiskTitleSelectorService.call(disk: @disks.first, episodes: @season.episodes).each do |title| %>
<%= hidden_field_tag "episodes[][episode_id]", title.episode.id %>
<tr>
<td>
<%= imdb_image_tag title.episode.still_path, width: 100, height: 100 %>
</td>
<td class="text-center">
<h1>
<% if title.ripped? %>
<%= icon('square-check') %>
<% else %>
<%= icon('square') %>
<% end %>
</h1>
</td>
<td class="text-center">
<h1>
<% if title.uploaded? %>
<%= icon('square-check') %>
<% else %>
<%= icon('square') %>
<% end %>
</h1>
</td>
<td>
<%= title.episode.episode_number %>
</td>
<td><%= title.episode.name %></td>
<td><%= title.episode.air_date %></td>
<td><%= distance_of_time_in_words(title.episode.runtime) if title.episode.runtime %>
<td>
<%= link_to_movie_db_episode(@season.tv.the_movie_db_id, @season.season_number, title.episode.episode_number) %>
</td>
<td>
<% if @disks.any? %>
<%= select_tag 'episodes[][disk_title_id]',
options_from_collection_for_select(@disks.first.disk_titles, :id, :to_label, title.disk_title&.id), prompt: "Select Disk Title", data: { manage_selections_target: :input } %>
<% end %>
</h1>
</td>
<td class="text-center">
<h1>
<% if episode.ripped_disk_titles.any? { _1.video_blob.uploaded? } %>
<%= icon('square-check') %>
<% else %>
<%= icon('square') %>
</td>
<td>
<% if @disks.any? %>
<%= number_field_tag "episodes[][part]" %>
<% end %>
</h1>
</td>
<td>
<%= episode.episode_number %>
</td>
<td><%= episode.name %></td>
<td><%= episode.air_date %></td>
<td><%= distance_of_time_in_words(episode.runtime) if episode.runtime %>
<td>
<%= link_to_movie_db_episode(@season.tv.the_movie_db_id, @season.season_number, episode.episode_number) %>
</td>
</tr>
<tr>
<td colspan="1"></td>
<td colspan="8">
<% episode.video_blobs.each do |video_blob| %>
<p><%= video_blob.key %></p>
<% end %>
</td>
</tr>
<% end %>
</td>
</tr>
<tr>
<td colspan="1"></td>
<td colspan="8">
<% title.episode.video_blobs.each do |video_blob| %>
<p><%= video_blob.key %></p>
<% end %>
</td>
</tr>
<% end %>
</tbody>
</table>
<% if @disks.any? %>
<div class='bg-dark w-100 fixed-bottom mt-1 text-right p-3 border-top'>
<%= f.button :submit, 'Rip Disk' %>
</div>
<% end %>
<% end %>
2 changes: 1 addition & 1 deletion current_version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v5.8.0
v5.9.0
1 change: 1 addition & 0 deletions spec/services/episode_disk_title_selector_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
it { expect(call.first.disk_title.id).to eq(disk_title_a.id) }
it { expect(call.second.episode.id).to eq(episodes.second.id) }
it { expect(call.second.disk_title.id).to eq(disk_title_b.id) }
it('does not assocate a disk_title') { expect(call.third.disk_title).to be_nil }
end
end
end

0 comments on commit bcc6324

Please sign in to comment.