Skip to content

Commit

Permalink
Progress bar is now present bottom right of the page, this will be wh…
Browse files Browse the repository at this point in the history
…at is used for all background tasks (#310)
  • Loading branch information
brand-it authored Apr 15, 2024
1 parent 950e8b7 commit d316ad5
Show file tree
Hide file tree
Showing 32 changed files with 257 additions and 89 deletions.
5 changes: 4 additions & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
inherit_from: .rubocop_todo.yml

require:
- rubocop-rspec
- rubocop-capybara
- rubocop-factory_bot
- rubocop-rails
- rubocop-rspec
- rubocop-rspec_rails

Style/Documentation:
Enabled: false
Expand Down
22 changes: 18 additions & 4 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,40 @@
# This configuration was generated by
# `rubocop --auto-gen-config --auto-gen-only-exclude --exclude-limit 1000`
# on 2022-07-06 20:07:25 UTC using RuboCop version 1.31.1.
# on 2024-04-12 20:21:30 UTC using RuboCop version 1.63.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
# versions of RuboCop, may require this file to be generated again.

# Offense count: 4
# Configuration parameters: AutoCorrect.
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle.
# SupportedStyles: leading, trailing
Layout/LineContinuationLeadingSpace:
Exclude:
- 'app/clients/the_movie_db/base.rb'
- 'spec/listeners/the_movie_db/tv_listener_spec.rb'

# Offense count: 1
# Configuration parameters: IgnoredMethods, Max.
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes, Max.
Metrics/AbcSize:
Exclude:
- 'app/workers/scan_plex_worker.rb'

# Offense count: 1
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
Metrics/CyclomaticComplexity:
Exclude:
- 'app/controllers/start_controller.rb'

# Offense count: 3
# Configuration parameters: CountComments, Max, CountAsOne, AllowedMethods, AllowedPatterns.
Metrics/MethodLength:
Exclude:
- 'app/workers/scan_plex_worker.rb'

# Offense count: 1
# Configuration parameters: IgnoredMethods, Max.
# Configuration parameters: AllowedMethods, AllowedPatterns, Max.
Metrics/PerceivedComplexity:
Exclude:
- 'app/controllers/start_controller.rb'
Expand Down
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,12 @@ group :development, :test do
gem 'rspec-github', require: false
gem 'rspec-rails'
gem 'rubocop'
gem 'rubocop-capybara'
gem 'rubocop-discourse'
gem 'rubocop-factory_bot'
gem 'rubocop-rails'
gem 'rubocop-rspec'
gem 'rubocop-rspec_rails'
gem 'shoulda-matchers'
gem 'super_diff'
gem 'timecop'
Expand Down
3 changes: 3 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -457,9 +457,12 @@ DEPENDENCIES
rspec-github
rspec-rails
rubocop
rubocop-capybara
rubocop-discourse
rubocop-factory_bot
rubocop-rails
rubocop-rspec
rubocop-rspec_rails
sass-rails
selenium-webdriver
shoulda-matchers
Expand Down
11 changes: 7 additions & 4 deletions app/assets/stylesheets/bg_process.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
.bg-processes {
position: fixed;
right: 0;
top: 0;
z-index: 4;
}

.bg-process {
--bs-toast-bg: rgba(var(--bs-body-bg-rgb), 0.85);
--bs-toast-border-color: var(--bs-border-color-translucent);
Expand All @@ -18,17 +25,13 @@
background-color: $dark-black;
border-radius: var(--bs-toast-border-radius);
border: var(--bs-toast-border-width) solid var(--bs-toast-border-color);
bottom: 0;
box-shadow: var(--bs-toast-box-shadow);
color: var(--bs-toast-color);
font-size: var(--bs-toast-font-size);
margin: 2em;
max-width: 100%;
pointer-events: auto;
position: fixed;
right: 0;
width: var(--bs-toast-max-width);
z-index: 4;

.header {
display: flex;
Expand Down
2 changes: 1 addition & 1 deletion app/components/disk_card_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<% unless @in_progress %>
<button data-disks-target="reload" data-action="click->disks#reload" data-url="<%= reload_disk_path %>" class='btn btn-primary'>Reload Disks</button>
<% if @movie && @movie.selected? %>
<%= link_to 'Rip', rip_movie_path(@movie), method: :post, class: 'btn btn-primary' %>
<%= link_to 'Rip', rip_movie_path(@movie), data: { turbo_method: :post }, class: 'btn btn-primary' %>
<% end %>
<% end %>
<% else %>
Expand Down
34 changes: 34 additions & 0 deletions app/components/movie_title_table_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<table class="table" id="<%= dom_id %>">
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Duration</th>
<th>Size</th>
<th></th>
</tr>
</thead>
<tbody class="disk_titles">
<% disks.each do |disk| %>
<% disk.disk_titles.sort_by { |d| movie.runtime_range.include?(d.duration) ? 0 : 1 }.each do |disk_title| %>
<% text_class = 'text-primary-emphasis' if movie.runtime_range.include?(disk_title.duration) %>

<tr>
<th scope="row" class="<%= text_class %>"><%= disk_title.id %></th>
<td class="<%= text_class %>"><%= disk_title.name %></td>
<td class="<%= text_class %>"><%= distance_of_time_in_words(disk_title.duration.seconds) %></td>
<td class="<%= disk_title.size >= free_disk_space ? 'text-danger' : text_class %>">
<%= number_to_human_size(disk_title.size, precision: 3) %>
<% if disk_title.size >= free_disk_space %>
WARNING: Not enough space available to rip need another <%= number_to_human_size(disk_title.size - free_disk_space, precision: 3) %>
<% end %>
</td>
<td class="<%= text_class %>">
<%= link_to 'Rip', video_disk_title_path(movie, disk_title), data: { turbo_method: :patch } %>
</td>
</tr>
<% end %>

<% end %>
</tbody>
</table>
26 changes: 26 additions & 0 deletions app/components/movie_title_table_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# frozen_string_literal: true

class MovieTitleTableComponent < ViewComponent::Base
extend Dry::Initializer

option :disks, Types::Array.of(Types.Instance(Disk))
option :movie, Types.Instance(Movie)

def dom_id
"#{self.class.name.parameterize}-#{movie.id}"
end

def free_disk_space
@free_disk_space ||= stats.block_size * stats.blocks_available
end

def total_disk_space
@total_disk_space ||= stats.block_size * stats.blocks
end

private

def stats
@stats ||= Sys::Filesystem.stat('/')
end
end
6 changes: 5 additions & 1 deletion app/components/progress_bar_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
</div>
</div>
<div>
<%= message.presence || model.model_name.singular %> ... <%= number_to_percentage completed, precision: 2 %>
<%= message.presence || model.model_name.singular %>
<% if show_percentage %>
...
<%= number_to_percentage completed, precision: 2 %>
<% end %>
</div>
</div>
1 change: 1 addition & 0 deletions app/components/progress_bar_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class ProgressBarComponent < ViewComponent::Base
option :completed, Types::Coercible::Float, default: -> { 0.0 }, null: nil
option :status, default: -> { 'info' }, null: nil
option :message, optional: true
option :show_percentage, default: -> { true }

def dom_id
"#{model.model_name.name}-progress-bar"
Expand Down
5 changes: 5 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class ApplicationController < ActionController::Base
before_action :plex_config
before_action :movie_db_config
before_action :mkv_config
before_action :load_disk_worker
helper_method :free_disk_space, :total_disk_space

def current_user
Expand All @@ -22,6 +23,10 @@ def total_disk_space
@total_disk_space ||= stats.block_size * stats.blocks
end

def load_disk_worker
LoadDiskWorker.perform_async
end

private

def stats
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/movies_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
class MoviesController < ApplicationController
def show
@movie = movie
@disks = CreateDisksService.call
@disks = FindExistingDisksService.call
end

def create
Expand Down
5 changes: 4 additions & 1 deletion app/controllers/the_movie_dbs_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ def next_page
private

def synced_recently?
Video.maximum(:synced_on) < 5.minutes.ago
last_sync = Video.maximum(:synced_on)
return false if last_sync.nil?

last_sync + 5.minutes > Time.zone.now
end

def search_service
Expand Down
5 changes: 3 additions & 2 deletions app/javascript/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@
import 'core-js/stable'
import 'regenerator-runtime/runtime'

require("@rails/ujs").start();
require("@rails/activestorage").start();
require("./channels");
require("@popperjs/core");
require("bootstrap");

import '@fortawesome/fontawesome-free/js/all.js';

// Uncomment to copy all static images under ../images to the output folder and reference
Expand All @@ -23,3 +22,5 @@ import '@fortawesome/fontawesome-free/js/all.js';
import '@hotwired/turbo-rails';

import "./controllers"
import "./channels"
import "./minimal_form"
5 changes: 5 additions & 0 deletions app/javascript/channels/disk_channel.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import CableReady from 'cable_ready'
import consumer from './consumer'


consumer.subscriptions.create('DiskTitleChannel', {
// // print out a connection established
// connected(data) {
// console.log("DiskTitleChannel" + data)
// },
received(data) {
if (data.cableReady) CableReady.perform(data.operations)
}
Expand Down
1 change: 1 addition & 0 deletions app/javascript/channels/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
// Channel files must be named *_channel.js.

const channels = require.context('.', true, /_channel\.js$/)
console.log("channels", channels.keys())
channels.keys().forEach(channels)
1 change: 1 addition & 0 deletions app/javascript/minimal_form.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
document.addEventListener("turbo:load", function () {
console.log('minimal_form.js loaded')
document.querySelectorAll('.minimal-input input').forEach(function (input) {
addHasValue = function (input) {
if (input.value.trim() != '') {
Expand Down
5 changes: 1 addition & 4 deletions app/services/disk_info_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ def size_matcher
27 => :filename
}.freeze

option :config_make_mkv, Types.Instance(Config::MakeMkv), default: proc { Config::MakeMkv.newest }
option :disk_name, Types::String

def results
Expand All @@ -63,9 +62,7 @@ def results
end

def info
@info ||= system!(
"#{config_make_mkv.settings.makemkvcon_path} info dev:#{disk_name} -r"
)
@info ||= makemkvcon("info dev:#{disk_name} -r")
end

def tinfos
Expand Down
23 changes: 23 additions & 0 deletions app/services/find_existing_disks_service.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

class FindExistingDisksService
MOUNT_LINE = %r{\A(?<disk_name>\S+)\son\s(?:/Volumes/|)(?<name>\S+)}
class << self
delegate :call, to: :new
end

# example line:
# /dev/disk4 on /Volumes/PLANET51 (udf, local, nodev, nosuid, read-only, noowners)
def call
mounts = `mount`
disks = []
mounts.each_line do |line|
next unless line.start_with?('/dev/')

match = line.match(MOUNT_LINE)
rdisk_name = match[:disk_name].gsub('/dev/', '/dev/r')
disks << Disk.find_by(name: match[:name], disk_name: [match[:disk_name], rdisk_name])
end
disks.compact
end
end
8 changes: 1 addition & 7 deletions app/services/list_drives_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ class ListDrivesService
include Shell
include MkvParser

option :config_make_mkv, Types.Instance(::Config::MakeMkv), default: -> { ::Config::MakeMkv.newest }
option :noscan, Types::Bool, default: -> { false }

class << self
Expand All @@ -20,14 +19,9 @@ def results

private

def makemkvcon_path
config_make_mkv.settings.makemkvcon_path
end

def info
@info ||= system!(
@info ||= makemkvcon(
[
makemkvcon_path,
'-r',
'--cache=1',
('--noscan' if noscan),
Expand Down
17 changes: 17 additions & 0 deletions app/tool_box/shell.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,23 @@ def capture3(*cmd)
Standard.new(stdout_str:, stderr_str:, status:)
end

def makemkvcon(*cmd)
makemkvcon_path = Config::MakeMkv.newest.settings.makemkvcon_path
sleep 1 while process_running?('makemkvcon')
system!([makemkvcon_path, *cmd].join(' '))
end

def process_running?(process_name)
output = if OS.mac? || OS.linux?
`ps aux | grep #{process_name} | grep -v grep`
elsif OS.windows?
`tasklist | findstr #{process_name}`
else
raise Error, 'Unsupported OS'
end
!output.empty?
end

def system!(*cmd)
response = capture3(*cmd)
raise Error, "#{cmd} - #{response.stderr_str}" unless response.status.success?
Expand Down
2 changes: 1 addition & 1 deletion app/views/disk_titles/_disk_title.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@
<% end %>
</td>
<td class="<%= text_class %>">
<%= link_to 'Rip', video_disk_title_path(video, disk_title), method: :patch %>
<%= link_to 'Rip', video_disk_title_path(video, disk_title), data: { turbo_method: :patch } %>
</td>
</tr>
Loading

0 comments on commit d316ad5

Please sign in to comment.