Class: DownloadTV::Downloader
- Inherits:
-
Object
- Object
- DownloadTV::Downloader
- Defined in:
- lib/download_tv/downloader.rb
Overview
Entry point of the application
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
Returns the value of attribute config.
Instance Method Summary collapse
-
#check_date(offset) ⇒ Object
Returns the date from which to check shows or nil if the program was already ran today Passing an offset skips this check.
- #detect_os ⇒ Object
-
#download(link) ⇒ Object
Spawns a silent process to download a given magnet link Uses xdg-open (not portable).
-
#download_from_file(filename) ⇒ Object
Given a file containing a list of episodes (one per line) it tries to find download links for each.
- #download_single_show(show, season = nil) ⇒ Object
-
#filter_shows(links) ⇒ Object
Removes links whose names don’t match the user filters Runs until no filters are left to be applied or applying a filter would leave no results.
- #find_and_download(shows) ⇒ Object
-
#fix_names(shows) ⇒ Object
Given a list of shows and episodes:.
-
#get_link(torrent, show, save_pending = false) ⇒ Object
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.
- #get_link_from_user(links) ⇒ Object
-
#initialize(config = {}) ⇒ Downloader
constructor
A new instance of Downloader.
- #prompt_links(links) ⇒ Object
-
#reject_ignored(shows) ⇒ Object
Given a list of shows and episodes:.
-
#run(dont_update_last_run, offset = 0) ⇒ Object
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.
-
#run_ahead(dont_update_last_run) ⇒ Object
Finds download links for all the episodes set to air today.
- #shows_to_download(date) ⇒ Object
- #today_shows_to_download ⇒ Object
Constructor Details
#initialize(config = {}) ⇒ Downloader
Returns a new instance of Downloader.
9 10 11 12 13 |
# File 'lib/download_tv/downloader.rb', line 9 def initialize(config = {}) @config = Configuration.new(config) # Load configuration Thread.abort_on_exception = true end |
Instance Attribute Details
#config ⇒ Object (readonly)
Returns the value of attribute config.
7 8 9 |
# File 'lib/download_tv/downloader.rb', line 7 def config @config end |
Instance Method Details
#check_date(offset) ⇒ Object
Returns the date from which to check shows or nil if the program was already ran today Passing an offset skips this check
198 199 200 201 202 203 204 205 |
# File 'lib/download_tv/downloader.rb', line 198 def check_date(offset) if offset.zero? last = @config.content[:date] last if last < Date.today else Date.today - offset end end |
#detect_os ⇒ Object
247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/download_tv/downloader.rb', line 247 def detect_os case RbConfig::CONFIG['host_os'] when /linux/ 'xdg-open' when /darwin/ 'open' else warn "You're using an unsupported platform." exit 1 end end |
#download(link) ⇒ Object
Spawns a silent process to download a given magnet link Uses xdg-open (not portable)
239 240 241 242 243 244 245 |
# File 'lib/download_tv/downloader.rb', line 239 def download(link) @cmd ||= detect_os exec = "#{@cmd} \"#{link}\"" Process.detach(Process.spawn(exec, i[out err] => '/dev/null')) end |
#download_from_file(filename) ⇒ Object
Given a file containing a list of episodes (one per line) it tries to find download links for each
36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/download_tv/downloader.rb', line 36 def download_from_file(filename) if File.exist? filename filename = File.realpath(filename) t = Torrent.new(@config.content[:grabber]) 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 |
#download_single_show(show, season = nil) ⇒ Object
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/download_tv/downloader.rb', line 15 def download_single_show(show, season = nil) t = Torrent.new(@config.content[:grabber]) show = fix_names([show]).first if season season.insert(0, '0') if season.size == 1 episode = "#{show} s#{season}e01" loop do link = get_link(t, episode) break if link.empty? download(link) episode = episode.next end else download(get_link(t, show)) end end |
#filter_shows(links) ⇒ Object
Removes links whose names don’t match the user filters Runs until no filters are left to be applied or applying a filter would leave no results
231 232 233 234 |
# File 'lib/download_tv/downloader.rb', line 231 def filter_shows(links) f = Filterer.new(@config.content[:filters]) f.filter(links) end |
#find_and_download(shows) ⇒ Object
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/download_tv/downloader.rb', line 105 def find_and_download(shows) t = Torrent.new queue = Queue.new # Adds a link (or empty string to the queue) link_t = Thread.new do shows.each { |show| queue << get_link(t, show, true) } end # Downloads the links as they are added download_t = Thread.new do shows.size.times do magnet = queue.pop next if magnet == '' # Doesn't download if no torrents are found download(magnet) end end # Downloading the subtitles # subs_t = @config.content[:subs] and Thread.new do # shows.each { |show| @s.get_subs(show) } # end link_t.join download_t.join # subs_t.join end |
#fix_names(shows) ⇒ Object
Given a list of shows and episodes:
-
Removes apostrophes, colons and parens
223 224 225 |
# File 'lib/download_tv/downloader.rb', line 223 def fix_names(shows) shows.map { |i| i.gsub(/ \(.+\)|[':]/, '') } end |
#get_link(torrent, show, save_pending = false) ⇒ Object
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 it’s false it will prompt the user to select the preferred result Returns either a magnet link or an emptry string
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/download_tv/downloader.rb', line 159 def get_link(torrent, show, save_pending = false) links = torrent.get_links(show) if links.empty? @config.content[:pending] << show if save_pending return '' end if @config.content[:auto] links = filter_shows(links) links.first[1] else prompt_links(links) get_link_from_user(links) end end |
#get_link_from_user(links) ⇒ Object
176 177 178 179 180 181 182 183 184 185 |
# File 'lib/download_tv/downloader.rb', line 176 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 i == -1 ? '' : links[i][1] end |
#prompt_links(links) ⇒ Object
187 188 189 190 191 192 |
# File 'lib/download_tv/downloader.rb', line 187 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 |
#reject_ignored(shows) ⇒ Object
Given a list of shows and episodes:
-
Removes ignored shows
211 212 213 214 215 216 217 |
# File 'lib/download_tv/downloader.rb', line 211 def reject_ignored(shows) shows.reject do |i| # Remove season+episode @config.content[:ignored] .include?(i.split(' ')[0..-2].join(' ').downcase) end end |
#run(dont_update_last_run, offset = 0) ⇒ Object
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.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/download_tv/downloader.rb', line 53 def run(dont_update_last_run, offset = 0) pending = @config.content[:pending].clone @config.content[:pending].clear pending ||= [] date = check_date(offset) pending.concat shows_to_download(date) if date if pending.empty? puts 'Nothing to download' else find_and_download(pending) puts 'Completed. Exiting...' end @config.content[:date] = [Date.today, @config.content[:date]].max unless dont_update_last_run @config.serialize rescue InvalidLoginError warn 'Wrong username/password combination' end |
#run_ahead(dont_update_last_run) ⇒ Object
Finds download links for all the episodes set to air today. TODO: Refactor with #run()
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/download_tv/downloader.rb', line 77 def run_ahead(dont_update_last_run) pending = @config.content[:pending].clone @config.content[:pending].clear pending ||= [] # Make normal run first if necessary if @config.content[:date] < Date.today pending.concat shows_to_download(@config.content[:date]) end # Only do --tomorrow run if it hasn't happened already if @config.content[:date] < Date.today.next pending.concat today_shows_to_download end if pending.empty? puts 'Nothing to download' else find_and_download(pending) puts 'Completed. Exiting...' end @config.content[:date] = Date.today.next unless dont_update_last_run @config.serialize rescue InvalidLoginError warn 'Wrong username/password combination' end |
#shows_to_download(date) ⇒ Object
134 135 136 137 138 139 140 141 142 |
# File 'lib/download_tv/downloader.rb', line 134 def shows_to_download(date) myepisodes = MyEpisodes.new(@config.content[:myepisodes_user], @config.content[:cookie]) # Log in using cookie by default myepisodes. shows = myepisodes.get_shows_since(date) shows = reject_ignored(shows) fix_names(shows) end |
#today_shows_to_download ⇒ Object
144 145 146 147 148 149 150 151 |
# File 'lib/download_tv/downloader.rb', line 144 def today_shows_to_download myepisodes = MyEpisodes.new(@config.content[:myepisodes_user], @config.content[:cookie]) myepisodes. shows = myepisodes.today_shows shows = reject_ignored(shows) fix_names(shows) end |