download_tv 2.4.7 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3da65f8f28fbd1c2d76d9166e5e5ed8e13ddf77546e63a43955d88ca60b226da
4
- data.tar.gz: 526cc3fffa489f0e4f9b568b196bc0c468958fab56f46e72b0fe1222b515aa62
3
+ metadata.gz: d2db543fb9eaf70753008d797005ac32249c67fde6e0b9b6a41e916c0eb66fcb
4
+ data.tar.gz: 41fe118c7d18adb566dec211873d64a3f6d2fdcfeea0f6e18c173545e6b8368c
5
5
  SHA512:
6
- metadata.gz: 0aa3b30cf80314fe1cc88b83a89b1d548a81fd787b38b3aed26433263de54f09288e05413f0eb64654ad2a4d6acfc4c4ae82e780b37a98a40e59bf33b1857475
7
- data.tar.gz: 738b270056911835ac14e073d8067376f43dc2dce4bdaddc7a8c36c38f3eb90ff5adddcd68f387f81d5f71a88aca831684fc086f82b859b90a089e4c2bd41f08
6
+ metadata.gz: e01b1c252163640d4d9be4cf47c3488019387762924de1d72cf58398be28e82ba5355abdf11fe7b31bfe38db5f13969e19081671f45eb0199cffcb776028d152
7
+ data.tar.gz: 57c2389c98774ba8f31e78d4e0adfd857c044862224d2b39611accfc2cd850403f89e2154f91ab6280fc7b6bab187bf524aec4ac950e5385a3a1271bc81c7b30
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
1
  /Gemfile.lock
2
- /pkg/
2
+ /pkg/
3
+ .rubocop.yml
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
2
4
  require 'rake/testtask'
3
5
 
data/bin/tv CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'optparse'
4
5
  require 'download_tv'
@@ -58,6 +59,14 @@ opt_parser = OptionParser.new do |opts|
58
59
  exit
59
60
  end
60
61
 
62
+ opts.on('-p', '--pending', 'Show list of pending downloads') do
63
+ options[:cmd] = 'showpending'
64
+ end
65
+
66
+ opts.on('--clear-pending', 'Clear list of pending downloads') do
67
+ options[:cmd] = 'clearpending'
68
+ end
69
+
61
70
  opts.on('-v', '--version', 'Print version') do
62
71
  puts DownloadTV::VERSION
63
72
  exit
@@ -86,6 +95,10 @@ begin
86
95
  DownloadTV::Configuration.new(config, true)
87
96
  when 'showconfig'
88
97
  DownloadTV::Configuration.new(config).print_config
98
+ when 'showpending'
99
+ DownloadTV::Configuration.new(config).print_attr(:pending)
100
+ when 'clearpending'
101
+ DownloadTV::Configuration.new(config).clear_pending
89
102
  end
90
103
  rescue Interrupt
91
104
  puts 'Interrupt signal detected. Exiting...'
data/download_tv.gemspec CHANGED
@@ -1,6 +1,6 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
- lib = File.expand_path('../lib', __FILE__)
3
+ lib = File.expand_path('lib', __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
  require 'download_tv/version'
6
6
 
@@ -23,11 +23,11 @@ Gem::Specification.new do |s|
23
23
  s.executables = ['tv']
24
24
 
25
25
  s.add_development_dependency 'bundler', '~> 1.15'
26
- s.add_development_dependency 'rake', '~> 10.0'
27
26
  s.add_development_dependency 'minitest', '~> 5.0'
27
+ s.add_development_dependency 'rake', '~> 10.0'
28
28
 
29
29
  s.add_dependency('json')
30
30
  s.add_dependency('mechanize')
31
31
 
32
- s.license = 'MIT'
32
+ s.license = 'MIT'
33
33
  end
data/lib/download_tv.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
  require 'mechanize'
3
5
  require 'date'
@@ -13,7 +15,7 @@ require 'download_tv/linkgrabber'
13
15
  require 'download_tv/subtitles'
14
16
 
15
17
  module DownloadTV
16
- USER_AGENT = "DownloadTV #{DownloadTV::VERSION}".freeze
18
+ USER_AGENT = "DownloadTV #{DownloadTV::VERSION}"
17
19
 
18
20
  class NoTorrentsError < StandardError; end
19
21
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DownloadTV
2
4
  ##
3
5
  # Class used for managing the configuration of the application
@@ -6,7 +8,7 @@ module DownloadTV
6
8
 
7
9
  def initialize(content = {}, force_change = false)
8
10
  FileUtils.mkdir_p(File.join(ENV['HOME'], '.config', 'download_tv'))
9
- @config_path = content[:path] || File.join(ENV['HOME'], '.config', 'download_tv', 'config')
11
+ @config_path = content[:path] || default_config_path
10
12
 
11
13
  if File.exist? @config_path
12
14
  load_config
@@ -20,34 +22,52 @@ module DownloadTV
20
22
  end
21
23
 
22
24
  def change_configuration
25
+ prompt_for_myep_user
26
+ prompt_for_cookie
27
+ prompt_for_ignored
28
+ STDOUT.flush
29
+
30
+ set_default_values
31
+ serialize
32
+ end
33
+
34
+ def prompt_for_myep_user
23
35
  if @content[:myepisodes_user]
24
36
  print "Enter your MyEpisodes username (#{@content[:myepisodes_user]}) : "
25
37
  else
26
38
  print 'Enter your MyEpisodes username: '
27
39
  end
28
40
  @content[:myepisodes_user] = STDIN.gets.chomp
41
+ end
29
42
 
43
+ def prompt_for_cookie
30
44
  print 'Save cookie? (y)/n: '
31
45
  @content[:cookie] = !(STDIN.gets.chomp.casecmp? 'n')
46
+ end
32
47
 
48
+ def prompt_for_ignored
33
49
  if @content[:ignored]
34
50
  puts "Enter a comma-separated list of shows to ignore: (#{@content[:ignored]})"
35
51
  else
36
52
  puts 'Enter a comma-separated list of shows to ignore: '
37
53
  end
38
54
 
39
- @content[:ignored] = STDIN.gets.chomp.split(',').map(&:strip).map(&:downcase)
40
- STDOUT.flush
55
+ @content[:ignored] = STDIN.gets
56
+ .chomp
57
+ .split(',')
58
+ .map(&:strip)
59
+ .map(&:downcase)
60
+ end
41
61
 
62
+ def set_default_values
42
63
  # When modifying existing config, keeps previous values
43
64
  # When creating new one, sets defaults
44
65
  @content[:auto] ||= true
45
66
  @content[:subs] ||= true
46
67
  @content[:grabber] ||= 'TorrentAPI'
47
68
  @content[:date] ||= Date.today - 1
69
+ @content[:pending] = []
48
70
  @content[:version] = DownloadTV::VERSION
49
-
50
- serialize
51
71
  end
52
72
 
53
73
  def serialize
@@ -67,16 +87,32 @@ module DownloadTV
67
87
  retry
68
88
  end
69
89
 
90
+ def default_config_path
91
+ File.join(ENV['HOME'], '.config', 'download_tv', 'config')
92
+ end
93
+
70
94
  ##
71
95
  # Returns true if a major or minor update has been detected
72
96
  # Returns false if a patch has been detected
73
97
  # Returns nil if it's the same version
74
98
  def breaking_changes?(version)
75
- DownloadTV::VERSION.split('.').zip(version.split('.')).find_index { |x, y| y > x }&.< 2
99
+ DownloadTV::VERSION.split('.')
100
+ .zip(version.split('.'))
101
+ .find_index { |x, y| y < x }
102
+ &.< 2
76
103
  end
77
104
 
78
105
  def print_config
79
106
  @content.each { |k, v| puts "#{k}: #{v}" }
80
107
  end
108
+
109
+ def print_attr(arg)
110
+ puts @content[arg]
111
+ end
112
+
113
+ def clear_pending
114
+ @content[:pending].clear
115
+ @content.serialize
116
+ end
81
117
  end
82
118
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DownloadTV
2
4
  ##
3
5
  # Entry point of the application
@@ -20,16 +22,19 @@ module DownloadTV
20
22
 
21
23
  def download_single_show(show)
22
24
  t = Torrent.new(@config.content[:grabber])
25
+ show = fix_names([show]).first
23
26
  download(get_link(t, show))
24
27
  end
25
28
 
26
29
  ##
27
- # Given a file containing a list of episodes (one per line), it tries to find download links for each
30
+ # Given a file containing a list of episodes (one per line)
31
+ # it tries to find download links for each
28
32
  def download_from_file(filename)
29
33
  if File.exist? filename
30
34
  filename = File.realpath(filename)
31
35
  t = Torrent.new(@config.content[:grabber])
32
- File.readlines(filename).each { |show| download(get_link(t, show.chomp)) }
36
+ to_download = File.readlines(filename, chomp:true)
37
+ fix_names(to_download).each { |show| download(get_link(t, show)) }
33
38
  else
34
39
  puts "Error: #{filename} not found"
35
40
  exit 1
@@ -37,28 +42,34 @@ module DownloadTV
37
42
  end
38
43
 
39
44
  ##
40
- # Finds download links for all new episodes aired since the last run of the program
41
- # It connects to MyEpisodes in order to find which shows to track and which new episodes aired.
45
+ # Finds download links for all new episodes aired since
46
+ # the last run of the program
47
+ # It connects to MyEpisodes in order to find which shows
48
+ # to track and which new episodes aired.
42
49
  def run(dont_update_last_run, offset = 0)
50
+ pending = @config.content[:pending]
51
+ @config.content[:pending].clear
52
+ pending ||= []
43
53
  date = check_date(offset)
54
+ if pending.empty? and date.nil?
55
+ puts 'Everything up to date'
56
+ exit
57
+ end
44
58
 
45
- myepisodes = MyEpisodes.new(@config.content[:myepisodes_user], @config.content[:cookie])
46
- # Log in using cookie by default
47
- myepisodes.load_cookie
48
- shows = myepisodes.get_shows(date)
49
- to_download = fix_names(shows)
59
+ to_download = shows_to_download(date)
60
+ to_download.concat pending
50
61
 
51
62
  if to_download.empty?
52
63
  puts 'Nothing to download'
53
64
 
54
65
  else
55
- t = Torrent.new(@config.content[:grabber])
66
+ t = Torrent.new()
56
67
 
57
68
  queue = Queue.new
58
69
 
59
70
  # Adds a link (or empty string to the queue)
60
71
  link_t = Thread.new do
61
- to_download.each { |show| queue << get_link(t, show) }
72
+ to_download.each { |show| queue << get_link(t, show, true) }
62
73
  end
63
74
 
64
75
  # Downloads the links as they are added
@@ -66,6 +77,7 @@ module DownloadTV
66
77
  to_download.size.times do
67
78
  magnet = queue.pop
68
79
  next if magnet == '' # Doesn't download if no torrents are found
80
+
69
81
  download(magnet)
70
82
  end
71
83
  end
@@ -88,45 +100,64 @@ module DownloadTV
88
100
  warn 'Wrong username/password combination'
89
101
  end
90
102
 
103
+ def shows_to_download(date)
104
+ myepisodes = MyEpisodes.new(@config.content[:myepisodes_user],
105
+ @config.content[:cookie])
106
+ # Log in using cookie by default
107
+ myepisodes.load_cookie
108
+ shows = myepisodes.get_shows(date)
109
+ shows = reject_ignored(shows)
110
+ fix_names(shows)
111
+ end
112
+
91
113
  ##
92
114
  # Uses a Torrent object to obtain links to the given tv show
93
- # When :auto is true it will try to find the best match based on a set of filters
115
+ # When :auto is true it will try to find the best match
116
+ # based on a set of filters.
94
117
  # When it's false it will prompt the user to select the preferred result
95
118
  # Returns either a magnet link or an emptry string
96
- def get_link(t, show)
97
- links = t.get_links(show)
119
+ def get_link(torrent, show, save_pending=false)
120
+ links = torrent.get_links(show)
98
121
 
99
- return '' if links.empty?
122
+ if links.empty?
123
+ @config.content[:pending] << show if save_pending
124
+ return ''
125
+ end
100
126
 
101
127
  if @config.content[:auto]
102
128
  links = filter_shows(links)
103
129
  links.first[1]
104
130
  else
105
- puts "Collecting links for #{show}"
106
- links.each_with_index { |data, i| puts "#{i}\t\t#{data[0]}" }
131
+ prompt_links(links)
132
+ get_link_from_user(links)
133
+ end
134
+ end
107
135
 
108
- puts
109
- print 'Select the torrent you want to download [-1 to skip]: '
136
+ def get_link_from_user(links)
137
+ i = $stdin.gets.chomp.to_i
110
138
 
139
+ until i.between?(-1, links.size - 1)
140
+ puts 'Index out of bounds. Try again [-1 to skip]: '
111
141
  i = $stdin.gets.chomp.to_i
142
+ end
112
143
 
113
- while i >= links.size || i < -1
114
- puts 'Index out of bounds. Try again [-1 to skip]: '
115
- i = $stdin.gets.chomp.to_i
116
- end
144
+ i == -1 ? '' : links[i][1]
145
+ end
117
146
 
118
- # Use -1 to skip the download
119
- i == -1 ? '' : links[i][1]
120
- end
147
+ def prompt_links(links)
148
+ links.each_with_index { |data, i| puts "#{i}\t\t#{data[0]}" }
149
+
150
+ puts
151
+ print 'Select the torrent you want to download [-1 to skip]: '
121
152
  end
122
153
 
154
+ ##
155
+ # Returns the date from which to check for shows
156
+ # Or nil if the date is today
123
157
  def check_date(offset)
124
158
  last = @config.content[:date]
125
159
  if last - offset != Date.today
126
160
  last - offset
127
- else
128
- puts 'Everything up to date'
129
- exit
130
161
  end
131
162
  end
132
163
 
@@ -134,19 +165,26 @@ module DownloadTV
134
165
  # Given a list of shows and episodes:
135
166
  #
136
167
  # * Removes ignored shows
137
- # * Removes apostrophes, colons and parens
138
- def fix_names(shows)
139
- # Ignored shows
140
- s = shows.reject do |i|
168
+ def reject_ignored(shows)
169
+ shows.reject do |i|
141
170
  # Remove season+episode
142
- @config.content[:ignored].include?(i.split(' ')[0..-2].join(' ').downcase)
171
+ @config.content[:ignored]
172
+ .include?(i.split(' ')[0..-2].join(' ').downcase)
143
173
  end
174
+
175
+ end
144
176
 
145
- s.map { |i| i.gsub(/ \(.+\)|[':]/, '') }
177
+ ##
178
+ # Given a list of shows and episodes:
179
+ #
180
+ # * Removes apostrophes, colons and parens
181
+ def fix_names(shows)
182
+ shows.map { |i| i.gsub(/ \(.+\)|[':]/, '') }
146
183
  end
147
184
 
148
185
  ##
149
- # Iteratively applies filters until they've all been applied or applying the next filter would result in no results
186
+ # Iteratively applies filters until they've all been applied
187
+ # or applying the next filter would result in no results
150
188
  # These filters are defined at @filters
151
189
  def filter_shows(links)
152
190
  @filters.each do |f| # Apply each filter
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DownloadTV
2
4
  ##
3
5
  # Addic7ed prototype (WIP)
4
6
  class Addic7ed < LinkGrabber
5
7
  def initialize
6
- super('http://www.addic7ed.com/search.php?search=%s&Submit=Search')
8
+ super('http://www.addic7ed.com/search.php?search=%s'\
9
+ '&Submit=Search')
7
10
  end
8
11
 
9
12
  def get_subs(show)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DownloadTV
2
4
  ##
3
5
  # EZTV.ag grabber
@@ -6,9 +8,9 @@ module DownloadTV
6
8
  super('https://eztv.ag/search/%s')
7
9
  end
8
10
 
9
- def get_links(s)
11
+ def get_links(show)
10
12
  # Format the url
11
- search = format(@url, s)
13
+ search = format(@url, show)
12
14
 
13
15
  data = @agent.get(search).search('a.magnet')
14
16
 
@@ -18,8 +20,15 @@ module DownloadTV
18
20
  # EZTV shows 50 latest releases if it can't find the torrent
19
21
  raise NoTorrentsError if data.size == 50
20
22
 
21
- names = data.collect { |i| i.attribute('title').text.chomp(' Magnet Link') }
22
- links = data.collect { |i| i.attribute('href').text }
23
+ names = data.collect do |i|
24
+ i.attribute('title')
25
+ .text
26
+ .chomp(' Magnet Link')
27
+ end
28
+ links = data.collect do |i|
29
+ i.attribute('href')
30
+ .text
31
+ end
23
32
 
24
33
  names.zip(links)
25
34
  end
@@ -1,32 +1,47 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DownloadTV
2
4
  ##
3
5
  # KATcr.co grabber
4
6
  class KAT < LinkGrabber
7
+ attr_reader :max_tries
8
+
5
9
  def initialize
6
10
  super('https://katcr.co/advanced-usearch/')
11
+ @max_tries = 5
7
12
  end
8
13
 
9
- def get_links(s)
14
+ def get_links(show)
10
15
  tries = 0
11
- max_tries = 5
12
16
 
13
17
  params = {
14
18
  'category': 'TV',
15
19
  'orderby': 'seeds-desc',
16
- 'search': s
20
+ 'search': show
17
21
  }
18
22
 
19
- data = @agent.post(@url, params).search('tbody tr td[1]')
23
+ data = @agent.post(@url, params)
24
+ .search('tbody tr td[1]')
20
25
 
21
- names = data.map { |i| i.search('a.torrents_table__torrent_title b').text }
22
- links = data.map { |i| i.search('div.torrents_table__actions a[3]').first.attribute('href').text }
26
+ names = data.map do |i|
27
+ i.search('a.torrents_table__torrent_title b')
28
+ .text
29
+ end
30
+
31
+ links = data.map do |i|
32
+ i.search('div.torrents_table__actions a[3]')
33
+ .first
34
+ .attribute('href')
35
+ .text
36
+ end
23
37
 
24
38
  raise NoTorrentsError if data.empty?
25
39
 
26
40
  names.zip(links)
27
41
  rescue Net::HTTP::Persistent::Error => e
28
42
  raise unless e.message =~ /too many connection resets/
29
- raise if tries >= max_tries
43
+ raise if tries >= @max_tries
44
+
30
45
  tries += 1
31
46
  retry
32
47
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DownloadTV
2
4
  ##
3
5
  # TorrentAPI.org grabber
@@ -7,7 +9,9 @@ module DownloadTV
7
9
  attr_reader :wait
8
10
 
9
11
  def initialize
10
- super('https://torrentapi.org/pubapi_v2.php?mode=search&search_string=%s&token=%s&app_id=DownloadTV&sort=seeders')
12
+ super('https://torrentapi.org/pubapi_v2.php?'\
13
+ 'mode=search&search_string=%s&token=%s&'\
14
+ 'app_id=DownloadTV&sort=seeders')
11
15
  @wait = 0.1
12
16
  end
13
17
 
@@ -26,37 +30,41 @@ module DownloadTV
26
30
  end
27
31
  end
28
32
 
33
+ ##
34
+ # Makes a get request tp the given url.
35
+ # Returns the JSON response parsed into a hash
36
+ def request_and_parse(url)
37
+ page = @agent.get(url).content
38
+ JSON.parse(page)
39
+ end
40
+
29
41
  ##
30
42
  # Connects to Torrentapi.org and requests a token, returning it
31
43
  # Tokens automatically expire every 15 minutes
32
44
  def renew_token
33
- page = @agent.get('https://torrentapi.org/pubapi_v2.php?get_token=get_token&app_id=DownloadTV').content
34
-
35
- obj = JSON.parse(page)
45
+ obj = request_and_parse('https://torrentapi.org/pubapi_v2'\
46
+ '.php?get_token=get_token&app_id='\
47
+ 'DownloadTV')
36
48
 
37
49
  @token = obj['token']
38
50
  end
39
51
 
40
- def get_links(s)
52
+ def get_links(show)
41
53
  @token ||= renew_token
42
54
 
43
- # Format the url
44
- search = format(@url, s, @token)
55
+ search = format(@url, show, @token)
45
56
 
46
- page = @agent.get(search).content
47
- obj = JSON.parse(page)
57
+ obj = request_and_parse(search)
48
58
 
49
59
  if obj['error_code'] == 4 # Token expired
50
60
  renew_token
51
- search = format(@url, s, @token)
52
- page = @agent.get(search).content
53
- obj = JSON.parse(page)
61
+ search = format(@url, show, @token)
62
+ obj = request_and_parse(search)
54
63
  end
55
64
 
56
65
  while obj['error_code'] == 5 # Violate 1req/2s limit
57
66
  sleep(@wait)
58
- page = @agent.get(search).content
59
- obj = JSON.parse(page)
67
+ obj = request_and_parse(search)
60
68
  end
61
69
 
62
70
  raise NoTorrentsError if obj['error']
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DownloadTV
2
4
  ##
3
5
  # ThePirateBay grabber
@@ -8,13 +10,11 @@ module DownloadTV
8
10
  super("#{proxy}/search/%s/0/7/0")
9
11
  end
10
12
 
11
- def get_links(s)
12
- # Format the url
13
- search = format(@url, s)
13
+ def get_links(show)
14
+ search = format(@url, show)
14
15
 
15
- data = @agent.get(search).search('#searchResult tr')
16
16
  # Skip the header
17
- data = data.drop 1
17
+ data = @agent.get(search).search('#searchResult tr').drop 1
18
18
 
19
19
  raise NoTorrentsError if data.empty?
20
20
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DownloadTV
2
4
  ##
3
5
  # Interface for the grabbers
@@ -12,13 +14,18 @@ module DownloadTV
12
14
 
13
15
  def online?
14
16
  @agent.read_timeout = 2
15
- @agent.head(format(@url, 'test'))
17
+ url = if @url.include? '%s'
18
+ format(@url, 'test')
19
+ else
20
+ @url
21
+ end
22
+ @agent.head(url)
16
23
  true
17
24
  rescue Mechanize::ResponseCodeError, Net::HTTP::Persistent::Error
18
25
  false
19
26
  end
20
27
 
21
- def get_links(_s)
28
+ def get_links(_show)
22
29
  raise NotImplementedError
23
30
  end
24
31
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DownloadTV
2
4
  ##
3
5
  # API wrapper for MyEpisodes
@@ -11,15 +13,7 @@ module DownloadTV
11
13
  end
12
14
 
13
15
  def login
14
- if !@user || @user == ''
15
- print 'Enter your MyEpisodes username: '
16
- @user = STDIN.gets.chomp
17
- end
18
-
19
- print 'Enter your MyEpisodes password: '
20
- pass = STDIN.noecho(&:gets).chomp
21
- puts
22
-
16
+ pass = prompt_user_data
23
17
  page = @agent.get 'https://www.myepisodes.com/login.php'
24
18
 
25
19
  login_form = page.forms[1]
@@ -35,19 +29,34 @@ module DownloadTV
35
29
  @agent
36
30
  end
37
31
 
32
+ def prompt_user_data
33
+ if !@user || @user == ''
34
+ print 'Enter your MyEpisodes username: '
35
+ @user = STDIN.gets.chomp
36
+ end
37
+
38
+ print 'Enter your MyEpisodes password: '
39
+ pass = STDIN.noecho(&:gets).chomp
40
+ puts
41
+ pass
42
+ end
43
+
38
44
  def load_cookie
39
45
  if File.exist? @cookie_path
40
46
  @agent.cookie_jar.load @cookie_path
41
- page = @agent.get 'https://www.myepisodes.com/login.php'
42
- if page.links[1].text == 'Register'
43
- puts 'The cookie is invalid/has expired.'
44
- login
45
- end
46
- @agent
47
+ return @agent if logged_in?
48
+
49
+ puts 'The cookie is invalid/has expired.'
47
50
  else
48
51
  puts 'Cookie file not found'
49
- login
50
52
  end
53
+
54
+ login
55
+ end
56
+
57
+ def logged_in?
58
+ page = @agent.get 'https://www.myepisodes.com/login.php'
59
+ page.links[1].text != 'Register'
51
60
  end
52
61
 
53
62
  def save_cookie
@@ -56,22 +65,31 @@ module DownloadTV
56
65
  end
57
66
 
58
67
  def get_shows(last)
68
+ return [] if last.nil?
59
69
  page = @agent.get 'https://www.myepisodes.com/ajax/service.php?mode=view_privatelist'
60
70
  shows = page.parser.css('tr.past')
61
71
 
62
- s = shows.select do |i|
72
+ shows = filter_newer_shows(shows, last)
73
+
74
+ build_show_strings(shows)
75
+ end
76
+
77
+ def filter_newer_shows(shows, date)
78
+ shows.select do |i|
63
79
  airdate = i.css('td.date')[0].text
64
- Date.parse(airdate) >= last
80
+ Date.parse(airdate) >= date
65
81
  end
82
+ end
66
83
 
67
- s.map do |i|
68
- name = i.css('td.showname').text
84
+ def build_show_strings(shows)
85
+ shows.map do |i|
86
+ sname = i.css('td.showname').text
69
87
  ep = i.css('td.longnumber').text
70
88
 
71
89
  ep.insert(0, 'S')
72
90
  ep.sub!('x', 'E')
73
91
 
74
- "#{name} #{ep}"
92
+ "#{sname} #{ep}"
75
93
  end
76
94
  end
77
95
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DownloadTV
2
4
  ##
3
5
  # Manages the subtitles (WIP)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DownloadTV
2
4
  ##
3
5
  # Class in charge of managing the link grabbers
@@ -5,7 +7,8 @@ module DownloadTV
5
7
  attr_reader :g_instances, :tries
6
8
 
7
9
  def grabbers
8
- %w[TorrentAPI ThePirateBay Eztv KAT]
10
+ # %w[TorrentAPI ThePirateBay Eztv KAT]
11
+ %w[TorrentAPI ThePirateBay Eztv]
9
12
  end
10
13
 
11
14
  def initialize(default_grabber = nil)
@@ -27,6 +30,7 @@ module DownloadTV
27
30
  exit 1
28
31
  end
29
32
  return if @g_instances.first.online?
33
+
30
34
  # We won't be using this grabber
31
35
  warn "Problem accessing #{@g_instances.first.class.name}"
32
36
  @tries -= 1
@@ -48,7 +52,6 @@ module DownloadTV
48
52
 
49
53
  links
50
54
  rescue NoTorrentsError
51
- puts "No torrents found for #{show} using #{@g_instances.first.class.name}"
52
55
 
53
56
  # Use next grabber
54
57
  if @tries.positive?
@@ -59,7 +62,7 @@ module DownloadTV
59
62
  else
60
63
  reset_grabbers_order
61
64
  reset_tries
62
- # Handle show not found here!!
65
+ puts "No torrents found for #{show}"
63
66
  return []
64
67
  end
65
68
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module DownloadTV
2
- VERSION = '2.4.7'.freeze
4
+ VERSION = '2.5.0'
3
5
  end
data/test/config_test.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  describe DownloadTV::Configuration do
@@ -104,6 +106,7 @@ describe DownloadTV::Configuration do
104
106
  c.content[:ignored].must_equal ['anything']
105
107
  c.content[:auto].must_equal true
106
108
  c.content[:subs].must_equal true
109
+ c.content[:pending].must_equal []
107
110
  c.content[:grabber].must_equal 'TorrentAPI'
108
111
  c.content[:date].must_equal(Date.today - 1)
109
112
  c.content[:version].must_equal DownloadTV::VERSION
@@ -149,6 +152,7 @@ describe DownloadTV::Configuration do
149
152
  content[:ignored].must_equal ['anything']
150
153
  content[:auto].must_equal true
151
154
  content[:subs].must_equal true
155
+ content[:pending].must_equal []
152
156
  content[:grabber].must_equal 'TorrentAPI'
153
157
  content[:date].must_equal Date.today - 1
154
158
  content[:version].must_equal DownloadTV::VERSION
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  describe DownloadTV::Downloader do
@@ -22,27 +24,32 @@ describe DownloadTV::Downloader do
22
24
 
23
25
  describe 'the fix_names method' do
24
26
  it 'should remove apostrophes, colons and parens' do
25
- shows = ['Mr. Foo S01E02', 'Bar (UK) S00E22', "Let's S05E03", 'Baz: The Story S05E22']
26
- result = ['Mr. Foo S01E02', 'Bar S00E22', 'Lets S05E03', 'Baz The Story S05E22']
27
+ shows = ['Mr. Foo S01E02', 'Bar (UK) S00E22', "Let's S05E03",
28
+ 'Baz: The Story S05E22']
29
+ result = ['Mr. Foo S01E02', 'Bar S00E22', 'Lets S05E03',
30
+ 'Baz The Story S05E22']
27
31
 
28
32
  dl = DownloadTV::Downloader.new(ignored: [], path: config_path)
29
33
  dl.fix_names(shows).must_equal result
30
34
  end
31
35
 
36
+ end
37
+
38
+ describe 'the reject_ignored method' do
32
39
  it 'should remove ignored shows' do
33
- shows = ['Mr. Foo S01E02', 'Bar (UK) S00E22', 'Ignored S20E22', "Let's S05E03"]
34
- result = ['Mr. Foo S01E02', 'Bar S00E22', 'Lets S05E03']
40
+ shows = ['Bar S00E22', 'Ignored S20E22']
41
+ result = ['Bar S00E22']
35
42
 
36
43
  dl = DownloadTV::Downloader.new(ignored: ['ignored'], path: config_path)
37
- dl.fix_names(shows).must_equal result
44
+ dl.reject_ignored(shows).must_equal result
38
45
  end
46
+
39
47
  end
40
48
 
41
49
  describe 'the check_date method' do
42
50
  it 'exits the script when up to date' do
43
51
  dl = DownloadTV::Downloader.new(date: Date.today, path: config_path)
44
- to_run = -> { run_silently { dl.check_date(0) } }
45
- to_run.must_raise SystemExit
52
+ dl.check_date(0).must_be_nil
46
53
  end
47
54
 
48
55
  it 'uses the offset to adjust the date' do
@@ -80,7 +87,8 @@ describe DownloadTV::Downloader do
80
87
 
81
88
  it 'removes names without PROPER or REPACK in them' do
82
89
  dl = DownloadTV::Downloader.new(path: config_path)
83
- links = [['Link 1', ''], ['Link 2 2160p', ''], ['Link 3', ''], ['Link 4 PROPER', ''], ['Link REPACK 5', '']]
90
+ links = [['Link 1', ''], ['Link 2 2160p', ''], ['Link 3', ''],
91
+ ['Link 4 PROPER', ''], ['Link REPACK 5', '']]
84
92
  res = [['Link 4 PROPER', ''], ['Link REPACK 5', '']]
85
93
  dl.filter_shows(links).must_equal res
86
94
  end
@@ -99,11 +107,15 @@ describe DownloadTV::Downloader do
99
107
  show = 'Example Show S01E01'
100
108
 
101
109
  t.expect(:get_links, [], [show])
102
- dl = DownloadTV::Downloader.new(auto: true, path: config_path)
103
- dl.get_link(t, show).must_equal ''
110
+ dl = DownloadTV::Downloader.new(auto: true, path: config_path, pending: ['show 11'])
111
+ dl.get_link(t, show, true).must_equal ''
112
+ dl.config.content[:pending].must_equal ['show 11', show]
113
+
104
114
  t.expect(:get_links, [], [show])
105
- dl = DownloadTV::Downloader.new(auto: false, path: config_path)
106
- dl.get_link(t, show).must_equal ''
115
+ dl = DownloadTV::Downloader.new(auto: false, path: config_path, pending: [])
116
+ dl.get_link(t, show, true).must_equal ''
117
+ dl.config.content[:pending].must_include show
118
+
107
119
  t.verify
108
120
  end
109
121
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  describe DownloadTV::LinkGrabber do
data/test/test_helper.rb CHANGED
@@ -1,4 +1,6 @@
1
- $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
2
4
  require 'download_tv'
3
5
  require 'minitest/autorun'
4
6
 
data/test/torrent_test.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  describe DownloadTV::Torrent do
@@ -25,8 +27,8 @@ describe DownloadTV::Torrent do
25
27
  describe 'when giving it a default grabber' do
26
28
  it 'has a default order' do
27
29
  t = DownloadTV::Torrent.new(nil)
28
- expected = grabber_names.map { |i| "DownloadTV::#{i}"}
29
- t.g_instances.map { |i| i.class.name}.must_equal expected
30
+ expected = grabber_names.map { |i| "DownloadTV::#{i}" }
31
+ t.g_instances.map { |i| i.class.name }.must_equal expected
30
32
  end
31
33
 
32
34
  grabber_names.each do |g|
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: download_tv
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.7
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - guille
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-05 00:00:00.000000000 Z
11
+ date: 2018-12-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -25,33 +25,33 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.15'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: minitest
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '5.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '5.0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: minitest
42
+ name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '5.0'
47
+ version: '10.0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '5.0'
54
+ version: '10.0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: json
57
57
  requirement: !ruby/object:Gem::Requirement