Class: Downloader

Inherits:
Object
  • Object
show all
Defined in:
lib/get_tapas/downloader.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(html, options) ⇒ Downloader

Returns a new instance of Downloader.



7
8
9
10
# File 'lib/get_tapas/downloader.rb', line 7

def initialize(html, options)
  @html = html
  @options = options
end

Instance Attribute Details

#htmlObject

Returns the value of attribute html.



5
6
7
# File 'lib/get_tapas/downloader.rb', line 5

def html
  @html
end

#optionsObject

Returns the value of attribute options.



5
6
7
# File 'lib/get_tapas/downloader.rb', line 5

def options
  @options
end

Instance Method Details

#callObject



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/get_tapas/downloader.rb', line 93

def call
  data_dir = options.data_dir

  ensure_output_dir_exists(data_dir)
  links = get_link_info(html, data_dir)
  _available, _present, absent = download_file_info(links)

  absent.reverse! if options.reverse

  absent_within_desired_range = absent.select { |a| episode_num_ok(a.episode_num)}

  num_downloads_to_do = absent_within_desired_range.size

  if num_downloads_to_do == 0
    puts "No files within the selection criteria needed to be downloaded."
  elsif options.no_op
    puts "No-op mode requested. The following #{num_downloads_to_do} file(s) would have been downloaded without it:\n\n"
    puts absent_within_desired_range.map(&:filename).join("\n"); puts
    exit(0)
  else
    absent_within_desired_range.each_with_index do |link, index|
      download_file(link, data_dir)
      this_was_the_last_one = (index == num_downloads_to_do - 1)
      if options.sleep_interval && (! this_was_the_last_one)
        puts "Sleeping #{options.sleep_interval} seconds..."
        sleep(options.sleep_interval)
      end
    end
  end
end

#download_file(link, data_dir) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/get_tapas/downloader.rb', line 79

def download_file(link, data_dir)
  puts "Downloading #{link.filespec}..."
  tempfilespec = File.join(data_dir, 'tempfile')
  `curl -o #{tempfilespec} #{Shellwords.shellescape(link.url)}`
  if $?.exitstatus == 0
    validate_downloaded_file(tempfilespec)
    FileUtils.mv(tempfilespec, link.filespec)
    puts "Finished downloading #{link.filename}\n\n"
  else
    raise "Curl Download failed with exit status #{$0.exitstatus}."
  end
end

#download_file_info(links) ⇒ Object



51
52
53
54
55
56
# File 'lib/get_tapas/downloader.rb', line 51

def download_file_info(links)
  present, absent = links.partition do |link|
    File.file?(link.filespec)
  end
  [links, present, absent]
end

#ensure_output_dir_exists(dir) ⇒ Object



23
24
25
26
27
28
29
30
31
32
# File 'lib/get_tapas/downloader.rb', line 23

def ensure_output_dir_exists(dir)
  return if Dir.exist?(dir)
  begin
    FileUtils.mkdir_p(dir)
    puts "Created output data directory #{dir}."
  rescue Errno::EACCES
    puts "Unable to create directory #{dir}. Exiting..."
    exit(-1)
  end
end

#episode_num_ok(episode_num) ⇒ Object



13
14
15
16
17
18
19
20
# File 'lib/get_tapas/downloader.rb', line 13

def episode_num_ok(episode_num)
  min = options.min_episode_num
  max = options.max_episode_num

  return false if min && episode_num < min
  return false if max && episode_num > max
  true
end

#filespecs_available(data_dir, links) ⇒ Object



35
36
37
38
# File 'lib/get_tapas/downloader.rb', line 35

def filespecs_available(data_dir, links)
  filenames = links.map { |link| link.filename}
  filenames.map { |fn| File.join(data_dir, fn) }
end

#filespecs_needing_download(available, present) ⇒ Object



46
47
48
# File 'lib/get_tapas/downloader.rb', line 46

def filespecs_needing_download(available, present)
  available - present
end

#filespecs_present(data_dir) ⇒ Object



41
42
43
# File 'lib/get_tapas/downloader.rb', line 41

def filespecs_present(data_dir)
  Dir["#{data_dir}/*"]
end


59
60
61
62
63
64
65
# File 'lib/get_tapas/downloader.rb', line 59

def get_link_info(html, dir)
  links = PageParser.parse(html)
  links.each do |link|
    link.filespec = File.join(dir, link.filename)
    link.episode_num = link.filename.split('-').first.to_i
  end
end

#validate_downloaded_file(filespec) ⇒ Object



68
69
70
71
72
73
74
75
76
# File 'lib/get_tapas/downloader.rb', line 68

def validate_downloaded_file(filespec)
  if File.size(filespec) < 20000
    text = File.read(filespec)
    if %r{<Error>}.match(text) && %r{</Error>}.match(text)
      puts "\nDownload error, text was:\n#{text}\n\n\n"
      raise "Download error"
    end
  end
end