download_tv 2.4.7 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
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