diff --git a/app/assets/stylesheets/bg_process.scss b/app/assets/stylesheets/bg_process.scss index 20f25e8e..761f9609 100644 --- a/app/assets/stylesheets/bg_process.scss +++ b/app/assets/stylesheets/bg_process.scss @@ -1,10 +1,3 @@ -.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); @@ -31,7 +24,6 @@ margin: 2em; max-width: 100%; pointer-events: auto; - width: var(--bs-toast-max-width); .header { display: flex; diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index becae409..d17949db 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -3,10 +3,11 @@ class ApplicationController < ActionController::Base include Rescuer - before_action :plex_config - before_action :movie_db_config - before_action :mkv_config + before_action :continue_upload before_action :load_disk_worker + before_action :mkv_config + before_action :movie_db_config + before_action :plex_config helper_method :free_disk_space, :total_disk_space def current_user @@ -27,6 +28,16 @@ def load_disk_worker LoadDiskWorker.perform_async end + def continue_upload + return if UploadWorker.job.pending? + + Video.find_each do |video| + next unless video.tmp_plex_path_exists? + + UploadWorker.perform_async(disk_title: video.disk_title) + end + end + private def stats diff --git a/app/listeners/upload_progress_listener.rb b/app/listeners/upload_progress_listener.rb index 65341564..b912cb76 100644 --- a/app/listeners/upload_progress_listener.rb +++ b/app/listeners/upload_progress_listener.rb @@ -26,12 +26,18 @@ def update_component cable_ready.broadcast end - def component - ProgressBarComponent.new \ - model: DiskTitle, - completed: percentage, - status: :info, - message: title + def component # rubocop:disable Metrics/MethodLength + progress_bar = render( + ProgressBarComponent.new( + model: Video, + completed: percentage, + status: :info, + message: title + ), layout: false + ) + component = ProcessComponent.new(worker: UploadWorker) + component.with_body { progress_bar } + component end def percentage diff --git a/app/services/find_existing_disks_service.rb b/app/services/find_existing_disks_service.rb index 38f4f4e8..7fc1408d 100644 --- a/app/services/find_existing_disks_service.rb +++ b/app/services/find_existing_disks_service.rb @@ -1,23 +1,46 @@ # frozen_string_literal: true class FindExistingDisksService - MOUNT_LINE = %r{\A(?\S+)\son\s(?:/Volumes/|)(?\S+)} + MOUNT_LINE = %r{\A(?\S+)\son\s(?:/Volumes/|)(?.*)\s[(]} + Device = Struct.new(:name, :disk_name) do + def rdisk_name + disk_name.gsub('/dev/', '/dev/r') + end + end + 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| + def call # rubocop:disable Metrics/MethodLength + index = 0 + devices.reduce(Disk.all) do |disks, device| + if index.zero? + disks.where( + name: device.name, + disk_name: [device.disk_name, device.rdisk_name] + ) + else + disks.or( + Disk.where( + name: device.name, + disk_name: [device.disk_name, device.rdisk_name] + ) + ) + end.tap { index += 1 } + end + end + + private + + def devices + @devices ||= `mount`.each_line.filter_map 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]) + Device.new(match[:name], match[:disk_name]) end - disks.compact end end diff --git a/app/tool_box/shell.rb b/app/tool_box/shell.rb index 3b8d49c2..f9a1fa8d 100755 --- a/app/tool_box/shell.rb +++ b/app/tool_box/shell.rb @@ -3,7 +3,15 @@ module Shell class Error < StandardError; end - Standard = Struct.new(:stdout_str, :stderr_str, :status, keyword_init: true) + Standard = Struct.new(:stdout_str, :stderr_str, :status, keyword_init: true) do + include MkvParser + + delegate :success?, to: :status + + def parsed_mkv + @parsed_mkv ||= parse_mkv_string(stdout_str) + end + end def capture3(*cmd) Rails.logger.debug { "command: #{cmd.join(', ')}" } diff --git a/app/views/layouts/_bg_progress.erb b/app/views/layouts/_bg_progress.erb new file mode 100644 index 00000000..fa790479 --- /dev/null +++ b/app/views/layouts/_bg_progress.erb @@ -0,0 +1,52 @@ +
+ <%= render ProcessComponent.new worker: ScanPlexWorker do |c| %> + <%= c.with_body do %> + <% if ScanPlexWorker.job.pending? %> + <%= + render( + ProgressBarComponent.new( + model: Movie, + completed: (ScanPlexWorker.job.worker.completed.zero? ? 20 : ScanPlexWorker.job.worker.completed), + status: :success, + message: 'scanning plex for movies', + show_percentage: false + ) + ) + %> + <% else %> + Done! you have a total of <%= pluralize(Video.count, 'video') %> on plex. + <% end %> + <% end %> + <% end %> + + <%= render ProcessComponent.new worker: LoadDiskWorker do |c| %> + <%= c.with_body do %> + <% if LoadDiskWorker.job.pending? %> + Loading the disk info + <% elsif (disks = FindExistingDisksService.call).any? %> + <%= disks.map(&:name).join(', ') %> is ready to be ripped. + <% else %> + No disks found + <% end %> + <% end %> + <% end %> + <%= render ProcessComponent.new worker: UploadWorker do |c| %> + <%= c.with_body do %> + <% if UploadWorker.job.pending? %> + + <%= + render( + ProgressBarComponent.new( + model: DiskTitle, + show_percentage: false, + status: :info, + message: 'upload in progress' + ) + ) + %> + <% else %> + Nothing is being uploaded to <%= Config::Plex.newest.settings_ftp_host %> + <% end %> + <% end %> + <% end %> +
diff --git a/app/views/layouts/application.erb b/app/views/layouts/application.erb index 6e4511e8..46bd4d49 100644 --- a/app/views/layouts/application.erb +++ b/app/views/layouts/application.erb @@ -6,49 +6,21 @@ <%= render 'layouts/head' %> -
- <%= render ProcessComponent.new worker: ScanPlexWorker do |c| %> - <%= c.with_body do %> - <% if ScanPlexWorker.job.pending? %> - <%= - render( - ProgressBarComponent.new( - model: Movie, - completed: (ScanPlexWorker.job.worker.completed.zero? ? 20 : ScanPlexWorker.job.worker.completed), - status: :success, - message: 'scanning plex for movies', - show_percentage: false - ) - ) - %> - <% else %> - Done! you have a total of <%= pluralize(Video.count, 'video') %> on plex. - <% end %> - <% end %> - <% end %> - <%= render ProcessComponent.new worker: LoadDiskWorker do |c| %> - <%= c.with_body do %> - <% if LoadDiskWorker.job.pending? %> - Loading the disk info - <% elsif (disks = FindExistingDisksService.call).any? %> - <%= disks.map(&:name).join(', ') %> is ready to be ripped. - <% else %> - No disks found - <% end %> - <% end %> - <% end %> -
- <%= render ToastComponent.new do |c| %> - <%= c.body do %> - testing - <% end %> - <% end %> <%= render 'layouts/header' %> -
<%= yield %>
+
+
+
+ <%= render 'layouts/bg_progress' %> +
+
+ <%= yield %> +
+
+
diff --git a/app/workers/load_disk_worker.rb b/app/workers/load_disk_worker.rb index 4cdc301c..3f91b0f1 100644 --- a/app/workers/load_disk_worker.rb +++ b/app/workers/load_disk_worker.rb @@ -2,19 +2,10 @@ class LoadDiskWorker < ApplicationWorker def perform - cable_ready[DiskTitleChannel.channel_name].morph \ - selector: "##{component.dom_id}", - html: render(component, layout: false) - cable_ready[DiskTitleChannel.channel_name].reload if existing_disks.nil? + cable_ready[DiskTitleChannel.channel_name].reload if existing_disks.nil? && disks.present? cable_ready.broadcast end - def component - component = ProcessComponent.new(worker: ScanPlexWorker) - component.with_body { disks.map(&:name).join(', ') } - component - end - def disks @disks ||= existing_disks || CreateDisksService.call end diff --git a/app/workers/rip_worker.rb b/app/workers/rip_worker.rb index f446ea34..d05fdf7c 100644 --- a/app/workers/rip_worker.rb +++ b/app/workers/rip_worker.rb @@ -22,9 +22,8 @@ def create_mkv(disk_title) end def upload_mkv(disk_title) - @progress_listener = UploadProgressListener.new(file_size: disk_title.size) - Ftp::UploadMkvService.call disk_title:, - progress_listener: + sleep 1 while UploadWorker.job.pending? + UploadWorker.perform_async(disk_title) end def disk_titles diff --git a/app/workers/upload_worker.rb b/app/workers/upload_worker.rb new file mode 100644 index 00000000..fd6eb33b --- /dev/null +++ b/app/workers/upload_worker.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class UploadWorker < ApplicationWorker + option :disk_title, Types.Instance(DiskTitle) + + def perform + progress_listener = UploadProgressListener.new( + title: "Uploading #{disk_title.video.title}", + file_size: disk_title.size + ) + Ftp::UploadMkvService.call disk_title:, + progress_listener: + end +end