lib/download_tv/downloader.rb in download_tv-2.4.7 vs lib/download_tv/downloader.rb in download_tv-2.5.0

- old
+ new

@@ -1,5 +1,7 @@ +# frozen_string_literal: true + module DownloadTV ## # Entry point of the application class Downloader attr_reader :config @@ -18,56 +20,66 @@ Thread.abort_on_exception = true end def download_single_show(show) t = Torrent.new(@config.content[:grabber]) + show = fix_names([show]).first download(get_link(t, show)) end ## - # Given a file containing a list of episodes (one per line), it tries to find download links for each + # Given a file containing a list of episodes (one per line) + # it tries to find download links for each def download_from_file(filename) if File.exist? filename filename = File.realpath(filename) t = Torrent.new(@config.content[:grabber]) - File.readlines(filename).each { |show| download(get_link(t, show.chomp)) } + to_download = File.readlines(filename, chomp:true) + fix_names(to_download).each { |show| download(get_link(t, show)) } else puts "Error: #{filename} not found" exit 1 end end ## - # Finds download links for all new episodes aired since the last run of the program - # It connects to MyEpisodes in order to find which shows to track and which new episodes aired. + # Finds download links for all new episodes aired since + # the last run of the program + # It connects to MyEpisodes in order to find which shows + # to track and which new episodes aired. def run(dont_update_last_run, offset = 0) + pending = @config.content[:pending] + @config.content[:pending].clear + pending ||= [] date = check_date(offset) + if pending.empty? and date.nil? + puts 'Everything up to date' + exit + end - myepisodes = MyEpisodes.new(@config.content[:myepisodes_user], @config.content[:cookie]) - # Log in using cookie by default - myepisodes.load_cookie - shows = myepisodes.get_shows(date) - to_download = fix_names(shows) + to_download = shows_to_download(date) + to_download.concat pending if to_download.empty? puts 'Nothing to download' else - t = Torrent.new(@config.content[:grabber]) + t = Torrent.new() queue = Queue.new # Adds a link (or empty string to the queue) link_t = Thread.new do - to_download.each { |show| queue << get_link(t, show) } + to_download.each { |show| queue << get_link(t, show, true) } end # Downloads the links as they are added download_t = Thread.new do to_download.size.times do magnet = queue.pop next if magnet == '' # Doesn't download if no torrents are found + download(magnet) end end # Downloading the subtitles @@ -86,68 +98,94 @@ @config.serialize rescue InvalidLoginError warn 'Wrong username/password combination' end + def shows_to_download(date) + myepisodes = MyEpisodes.new(@config.content[:myepisodes_user], + @config.content[:cookie]) + # Log in using cookie by default + myepisodes.load_cookie + shows = myepisodes.get_shows(date) + shows = reject_ignored(shows) + fix_names(shows) + end + ## # Uses a Torrent object to obtain links to the given tv show - # When :auto is true it will try to find the best match based on a set of filters + # When :auto is true it will try to find the best match + # based on a set of filters. # When it's false it will prompt the user to select the preferred result # Returns either a magnet link or an emptry string - def get_link(t, show) - links = t.get_links(show) + def get_link(torrent, show, save_pending=false) + links = torrent.get_links(show) - return '' if links.empty? + if links.empty? + @config.content[:pending] << show if save_pending + return '' + end if @config.content[:auto] links = filter_shows(links) links.first[1] else - puts "Collecting links for #{show}" - links.each_with_index { |data, i| puts "#{i}\t\t#{data[0]}" } + prompt_links(links) + get_link_from_user(links) + end + end - puts - print 'Select the torrent you want to download [-1 to skip]: ' + def get_link_from_user(links) + i = $stdin.gets.chomp.to_i + until i.between?(-1, links.size - 1) + puts 'Index out of bounds. Try again [-1 to skip]: ' i = $stdin.gets.chomp.to_i + end - while i >= links.size || i < -1 - puts 'Index out of bounds. Try again [-1 to skip]: ' - i = $stdin.gets.chomp.to_i - end + i == -1 ? '' : links[i][1] + end - # Use -1 to skip the download - i == -1 ? '' : links[i][1] - end + def prompt_links(links) + links.each_with_index { |data, i| puts "#{i}\t\t#{data[0]}" } + + puts + print 'Select the torrent you want to download [-1 to skip]: ' end + ## + # Returns the date from which to check for shows + # Or nil if the date is today def check_date(offset) last = @config.content[:date] if last - offset != Date.today last - offset - else - puts 'Everything up to date' - exit end end ## # Given a list of shows and episodes: # # * Removes ignored shows - # * Removes apostrophes, colons and parens - def fix_names(shows) - # Ignored shows - s = shows.reject do |i| + def reject_ignored(shows) + shows.reject do |i| # Remove season+episode - @config.content[:ignored].include?(i.split(' ')[0..-2].join(' ').downcase) + @config.content[:ignored] + .include?(i.split(' ')[0..-2].join(' ').downcase) end + + end - s.map { |i| i.gsub(/ \(.+\)|[':]/, '') } + ## + # Given a list of shows and episodes: + # + # * Removes apostrophes, colons and parens + def fix_names(shows) + shows.map { |i| i.gsub(/ \(.+\)|[':]/, '') } end ## - # Iteratively applies filters until they've all been applied or applying the next filter would result in no results + # Iteratively applies filters until they've all been applied + # or applying the next filter would result in no results # These filters are defined at @filters def filter_shows(links) @filters.each do |f| # Apply each filter new_links = links.reject { |name, _link| f.call(name) } # Stop if the filter removes every release