download_tv 2.5.4 → 2.6.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +35 -0
- data/.gitignore +2 -1
- data/README.md +17 -5
- data/bin/tv +16 -7
- data/download_tv.gemspec +4 -2
- data/lib/download_tv.rb +2 -1
- data/lib/download_tv/configuration.rb +45 -8
- data/lib/download_tv/downloader.rb +46 -81
- data/lib/download_tv/filterer.rb +45 -0
- data/lib/download_tv/grabbers/eztv.rb +8 -5
- data/lib/download_tv/grabbers/torrentapi.rb +3 -1
- data/lib/download_tv/linkgrabber.rb +1 -1
- data/lib/download_tv/myepisodes.rb +2 -2
- data/lib/download_tv/torrent.rb +1 -1
- data/lib/download_tv/version.rb +1 -1
- data/test/config_test.rb +31 -31
- data/test/downloader_test.rb +32 -43
- data/test/grabbers_test.rb +11 -11
- data/test/torrent_test.rb +5 -5
- metadata +41 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ae40682e4e3243ca753612350278b095a1274aed5fe1a9c40d89667ffe8c87be
|
4
|
+
data.tar.gz: 23c9b0a31757f175cdf2c2dd6da373c129f23bf1abcec7b48c1592639b72fda6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 877d89743ee680c99cef11514a295a6a4e59e02b8fbdbb394a5889f9ab9f34237c3ddc4c11a085c26c7b442fa2b05b401bf6f61a1154fac93efe9d9dd6b81d30
|
7
|
+
data.tar.gz: 4a1ba85e231db16d52ea57d068a79271b15095ac82f49b906af65ff77a5edc6449bb0541fa7c284616025fe2284dacefbcff17258a40480e9492c3c0ebe0c140
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
2
|
+
# They are provided by a third-party and are governed by
|
3
|
+
# separate terms of service, privacy policy, and support
|
4
|
+
# documentation.
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
7
|
+
|
8
|
+
name: Ruby
|
9
|
+
|
10
|
+
on:
|
11
|
+
push:
|
12
|
+
branches: [ master ]
|
13
|
+
pull_request:
|
14
|
+
branches: [ master ]
|
15
|
+
|
16
|
+
jobs:
|
17
|
+
test:
|
18
|
+
|
19
|
+
runs-on: ubuntu-latest
|
20
|
+
strategy:
|
21
|
+
matrix:
|
22
|
+
ruby-version: ['2.6', '2.7', '3.0']
|
23
|
+
|
24
|
+
steps:
|
25
|
+
- uses: actions/checkout@v2
|
26
|
+
- name: Set up Ruby
|
27
|
+
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
28
|
+
# change this to (see https://github.com/ruby/setup-ruby#versioning):
|
29
|
+
# uses: ruby/setup-ruby@v1
|
30
|
+
uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
|
31
|
+
with:
|
32
|
+
ruby-version: ${{ matrix.ruby-version }}
|
33
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
34
|
+
- name: Run tests
|
35
|
+
run: bundle exec rake
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# download_tv
|
2
2
|
|
3
|
-
|
3
|
+
![Build Status](https://github.com/guille/download_tv/actions/workflows/ruby.yml/badge.svg)
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/download_tv.svg)](https://badge.fury.io/rb/download_tv)
|
5
5
|
[![Code Climate](https://codeclimate.com/github/guille/download_tv.svg)](https://codeclimate.com/github/guille/download_tv)
|
6
6
|
|
@@ -21,17 +21,17 @@ Specific options:
|
|
21
21
|
-o, --offset OFFSET Move back the last run offset
|
22
22
|
-f, --file PATH Download shows from a file
|
23
23
|
-d, --download SHOW Downloads given show
|
24
|
-
|
24
|
+
-s, --season SEASON Limit the show download to a specific season
|
25
25
|
-t, --tomorrow Download shows airing today
|
26
26
|
-c, --configure Configures defaults
|
27
27
|
--show-config Show current configuration values
|
28
28
|
--dry-run Don't write to the date file
|
29
29
|
-a, --[no-]auto Automatically find links
|
30
|
-
-s, --[no-]subtitles Download subtitles
|
31
30
|
-g, --grabber GRABBER Use given grabber as first option
|
32
31
|
--show-grabbers List available grabbers
|
33
32
|
-p, --pending Show list of pending downloads
|
34
33
|
--clear-pending Clear list of pending downloads
|
34
|
+
-q, --queue SHOW Add show episode to pending downloads list
|
35
35
|
-v, --version Print version
|
36
36
|
-h, --help Show this message
|
37
37
|
```
|
@@ -42,11 +42,13 @@ By default, download_tv connects to your MyEpisodes.com account and fetches the
|
|
42
42
|
|
43
43
|
The -o flag can be used in order to re-download the episodes from previous days. The --dry-run option is useful to prevent download_tv from updating the date (for example, when running the application shortly after an episode airs).
|
44
44
|
|
45
|
+
Starting in version 2.5.4, download_tv includes the --tomorrow flag. By default, an execution of download_tv will download shows airing from the last execution of the program up to a day prior to the current day. Use this flag to include shows airing today in this search. This can be useful depending on your timezone or on the airtime of the shows you follow.
|
46
|
+
|
45
47
|
**Note**: Due to API limitations, the gem won't find shows aired more than 14 days prior to the execution of the script.
|
46
48
|
|
47
49
|
The options -c and --show-config allow the user to change or view the current configuration values, respectively. These options include your myepisodes username, whether to save cookies or ask for password on each run and the list of ignored shows among other things. The configuration files are (mostly) backwards compatible. The gem will force you to change your configuration after an update if there are breaking changes in it.
|
48
50
|
|
49
|
-
The `auto` flag toggles whether all the results for each show are prompted to the user for him to choose or if the application should try to choose the download link automatically (
|
51
|
+
The `auto` flag toggles whether all the results for each show are prompted to the user for him to choose or if the application should try to choose the download link automatically (see Section Filters).
|
50
52
|
|
51
53
|
### Single torrent download
|
52
54
|
|
@@ -70,6 +72,16 @@ I usually publish a patch update to the gem when I detect one of them isn't work
|
|
70
72
|
|
71
73
|
download_tv version 2.5.0 persists the list of shows it can't find on a given execution (when connecting to MyEpisodes, not for single show or file downloads) and it will try to find them again on following executions. This list can be viewed by passing the -p flag to the tv binary. The list can be cleared with the --clear-pending option.
|
72
74
|
|
75
|
+
Version 2.6.0 adds functionality to queue an episode by running `tv --queue "show name"`. The --queue parameter cannot be used in conjunction with any other parameters. On the plus side, it doesn't need the show name to be quoted or the spaces escaped.
|
76
|
+
|
77
|
+
### Filters
|
78
|
+
|
79
|
+
download_tv version 2.5.5 adds the possibility of setting include/exclude filters for the automatic download of shows.
|
80
|
+
|
81
|
+
Up until that version, the filters by default were excluding 1080p or 720p, as well as including PROPER or REPACK releases when available. From that version onwards, the user can specify in their configuration (`tv -c`) a list of words to include or exclude from their results.
|
82
|
+
|
83
|
+
Please keep in mind that this is not a hard filter. The application will apply as many user-defined filters as possible **while still returning at least one result**.
|
84
|
+
|
73
85
|
### License
|
74
86
|
|
75
|
-
This project is released under the terms of the MIT license. See [LICENSE.md](https://github.com/guille/download_tv/blob/master/LICENSE.md) file for details.
|
87
|
+
This project is released under the terms of the MIT license. See [LICENSE.md](https://github.com/guille/download_tv/blob/master/LICENSE.md) file for details.
|
data/bin/tv
CHANGED
@@ -30,7 +30,7 @@ opt_parser = OptionParser.new do |opts|
|
|
30
30
|
options[:arg] = s
|
31
31
|
end
|
32
32
|
|
33
|
-
opts.on('--season SEASON', 'Limit the show download to a specific season') do |s|
|
33
|
+
opts.on('-s', '--season SEASON', 'Limit the show download to a specific season') do |s|
|
34
34
|
options[:cmd] = 'dl'
|
35
35
|
options[:season] = s
|
36
36
|
end
|
@@ -55,10 +55,6 @@ opt_parser = OptionParser.new do |opts|
|
|
55
55
|
config[:auto] = n
|
56
56
|
end
|
57
57
|
|
58
|
-
opts.on('-s', '--[no-]subtitles', 'Download subtitles') do |n|
|
59
|
-
config[:subs] = n
|
60
|
-
end
|
61
|
-
|
62
58
|
opts.on('-g', '--grabber GRABBER', 'Use given grabber as first option') do |g|
|
63
59
|
config[:grabber] = g
|
64
60
|
end
|
@@ -76,6 +72,11 @@ opt_parser = OptionParser.new do |opts|
|
|
76
72
|
options[:cmd] = 'clearpending'
|
77
73
|
end
|
78
74
|
|
75
|
+
opts.on('-q', '--queue SHOW', 'Add show episode to pending downloads list') do |s|
|
76
|
+
options[:cmd] = 'queue'
|
77
|
+
options[:arg] = s
|
78
|
+
end
|
79
|
+
|
79
80
|
opts.on('-v', '--version', 'Print version') do
|
80
81
|
puts DownloadTV::VERSION
|
81
82
|
exit
|
@@ -87,7 +88,13 @@ opt_parser = OptionParser.new do |opts|
|
|
87
88
|
end
|
88
89
|
end
|
89
90
|
|
90
|
-
|
91
|
+
begin
|
92
|
+
opt_parser.parse!(ARGV)
|
93
|
+
rescue OptionParser::InvalidOption => e
|
94
|
+
warn e.message
|
95
|
+
puts opt_parser.help
|
96
|
+
exit 1
|
97
|
+
end
|
91
98
|
|
92
99
|
begin
|
93
100
|
case options[:cmd]
|
@@ -106,7 +113,7 @@ begin
|
|
106
113
|
dl.download_from_file(options[:arg])
|
107
114
|
when 'tomorrow'
|
108
115
|
dl = DownloadTV::Downloader.new(config)
|
109
|
-
dl.
|
116
|
+
dl.run(options[:dry], options[:offset].abs, include_tomorrow: true)
|
110
117
|
when 'config'
|
111
118
|
DownloadTV::Configuration.new(config, true)
|
112
119
|
when 'showconfig'
|
@@ -115,6 +122,8 @@ begin
|
|
115
122
|
DownloadTV::Configuration.new(config).print_attr(:pending)
|
116
123
|
when 'clearpending'
|
117
124
|
DownloadTV::Configuration.new(config).clear_pending
|
125
|
+
when 'queue'
|
126
|
+
DownloadTV::Configuration.new(config).queue_pending(options[:arg])
|
118
127
|
end
|
119
128
|
rescue Interrupt
|
120
129
|
puts 'Interrupt signal detected. Exiting...'
|
data/download_tv.gemspec
CHANGED
@@ -22,9 +22,11 @@ Gem::Specification.new do |s|
|
|
22
22
|
|
23
23
|
s.executables = ['tv']
|
24
24
|
|
25
|
-
s.add_development_dependency 'bundler', '~>
|
25
|
+
s.add_development_dependency 'bundler', '~> 2.0'
|
26
26
|
s.add_development_dependency 'minitest', '~> 5.0'
|
27
|
-
s.add_development_dependency
|
27
|
+
s.add_development_dependency "rake", ">= 12.3.3"
|
28
|
+
s.add_development_dependency 'pry', '~> 0.13'
|
29
|
+
s.add_development_dependency 'byebug', '~> 11.1'
|
28
30
|
|
29
31
|
s.add_dependency('json')
|
30
32
|
s.add_dependency('mechanize')
|
data/lib/download_tv.rb
CHANGED
@@ -11,6 +11,7 @@ require 'download_tv/version'
|
|
11
11
|
require 'download_tv/configuration'
|
12
12
|
require 'download_tv/downloader'
|
13
13
|
require 'download_tv/torrent'
|
14
|
+
require 'download_tv/filterer'
|
14
15
|
require 'download_tv/myepisodes'
|
15
16
|
require 'download_tv/linkgrabber'
|
16
17
|
require 'download_tv/subtitles'
|
@@ -23,4 +24,4 @@ module DownloadTV
|
|
23
24
|
class NoSubtitlesError < StandardError; end
|
24
25
|
end
|
25
26
|
|
26
|
-
Dir[File.join(__dir__, 'download_tv', 'grabbers', '*.rb')].each { |file| require file }
|
27
|
+
Dir[File.join(__dir__, 'download_tv', 'grabbers', '*.rb')].sort.each { |file| require file }
|
@@ -25,7 +25,8 @@ module DownloadTV
|
|
25
25
|
prompt_for_myep_user
|
26
26
|
prompt_for_cookie
|
27
27
|
prompt_for_ignored
|
28
|
-
|
28
|
+
prompt_for_filters
|
29
|
+
$stdout.flush
|
29
30
|
|
30
31
|
set_default_values
|
31
32
|
serialize
|
@@ -37,12 +38,13 @@ module DownloadTV
|
|
37
38
|
else
|
38
39
|
print 'Enter your MyEpisodes username: '
|
39
40
|
end
|
40
|
-
|
41
|
+
input = $stdin.gets.chomp
|
42
|
+
@content[:myepisodes_user] = input if input
|
41
43
|
end
|
42
44
|
|
43
45
|
def prompt_for_cookie
|
44
46
|
print 'Save cookie? (y)/n: '
|
45
|
-
@content[:cookie] = !(
|
47
|
+
@content[:cookie] = !($stdin.gets.chomp.casecmp? 'n')
|
46
48
|
end
|
47
49
|
|
48
50
|
def prompt_for_ignored
|
@@ -52,11 +54,40 @@ module DownloadTV
|
|
52
54
|
puts 'Enter a comma-separated list of shows to ignore: '
|
53
55
|
end
|
54
56
|
|
55
|
-
@content[:ignored] =
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
57
|
+
@content[:ignored] = $stdin.gets
|
58
|
+
.chomp
|
59
|
+
.split(',')
|
60
|
+
.map(&:strip)
|
61
|
+
.map(&:downcase)
|
62
|
+
end
|
63
|
+
|
64
|
+
def prompt_for_filters
|
65
|
+
puts "Current filters: (#{@content[:filters]})" if @content[:filters]
|
66
|
+
|
67
|
+
@content[:filters] = {}
|
68
|
+
|
69
|
+
puts 'Enter a comma-separated list of terms to include: '
|
70
|
+
|
71
|
+
@content[:filters][:includes] = $stdin.gets
|
72
|
+
.chomp
|
73
|
+
.split(',')
|
74
|
+
.map(&:strip)
|
75
|
+
.map(&:upcase)
|
76
|
+
|
77
|
+
puts 'Enter a comma-separated list of terms to exclude: '
|
78
|
+
|
79
|
+
@content[:filters][:excludes] = $stdin.gets
|
80
|
+
.chomp
|
81
|
+
.split(',')
|
82
|
+
.map(&:strip)
|
83
|
+
.map(&:upcase)
|
84
|
+
end
|
85
|
+
|
86
|
+
def default_filters
|
87
|
+
{
|
88
|
+
'includes' => %w[PROPER REPACK],
|
89
|
+
'excludes' => %w[2160P 1080P 720P]
|
90
|
+
}
|
60
91
|
end
|
61
92
|
|
62
93
|
def set_default_values
|
@@ -66,6 +97,7 @@ module DownloadTV
|
|
66
97
|
@content[:subs] ||= true
|
67
98
|
@content[:grabber] ||= 'TorrentAPI'
|
68
99
|
@content[:date] ||= Date.today - 1
|
100
|
+
@content[:filters] ||= default_filters
|
69
101
|
@content[:pending] ||= []
|
70
102
|
@content[:version] = DownloadTV::VERSION
|
71
103
|
end
|
@@ -115,5 +147,10 @@ module DownloadTV
|
|
115
147
|
@content[:pending].clear
|
116
148
|
serialize
|
117
149
|
end
|
150
|
+
|
151
|
+
def queue_pending(show)
|
152
|
+
@content[:pending] << show
|
153
|
+
serialize
|
154
|
+
end
|
118
155
|
end
|
119
156
|
end
|
@@ -9,29 +9,30 @@ module DownloadTV
|
|
9
9
|
def initialize(config = {})
|
10
10
|
@config = Configuration.new(config) # Load configuration
|
11
11
|
|
12
|
-
@filters = [
|
13
|
-
->(n) { n.include?('2160p') },
|
14
|
-
->(n) { n.include?('1080p') },
|
15
|
-
->(n) { n.include?('720p') },
|
16
|
-
# ->(n) { n.include?('WEB') },
|
17
|
-
->(n) { !n.include?('PROPER') && !n.include?('REPACK') }
|
18
|
-
]
|
19
|
-
|
20
12
|
Thread.abort_on_exception = true
|
21
13
|
end
|
22
14
|
|
15
|
+
##
|
16
|
+
# Tries to download episodes in order for a given season,
|
17
|
+
# until it can't find any
|
18
|
+
def download_entire_season(show, season)
|
19
|
+
t = Torrent.new(@config.content[:grabber])
|
20
|
+
season.insert(0, '0') if season.size == 1
|
21
|
+
episode = "#{show} s#{season}e01"
|
22
|
+
loop do
|
23
|
+
link = get_link(t, episode)
|
24
|
+
break if link.empty?
|
25
|
+
|
26
|
+
download(link)
|
27
|
+
episode = episode.next
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
23
31
|
def download_single_show(show, season = nil)
|
24
32
|
t = Torrent.new(@config.content[:grabber])
|
25
33
|
show = fix_names([show]).first
|
26
34
|
if season
|
27
|
-
|
28
|
-
episode = "#{show} s#{season}e01"
|
29
|
-
loop do
|
30
|
-
link = get_link(t, episode)
|
31
|
-
break if link.empty?
|
32
|
-
download(link)
|
33
|
-
episode = episode.next
|
34
|
-
end
|
35
|
+
download_entire_season(show, season)
|
35
36
|
else
|
36
37
|
download(get_link(t, show))
|
37
38
|
end
|
@@ -52,53 +53,45 @@ module DownloadTV
|
|
52
53
|
end
|
53
54
|
end
|
54
55
|
|
56
|
+
##
|
57
|
+
# Returns the date from which to check shows
|
58
|
+
def date_to_check_from(offset)
|
59
|
+
return @config.content[:date] if offset.zero?
|
60
|
+
|
61
|
+
Date.today - offset
|
62
|
+
end
|
63
|
+
|
55
64
|
##
|
56
65
|
# Finds download links for all new episodes aired since
|
57
66
|
# the last run of the program
|
58
67
|
# It connects to MyEpisodes in order to find which shows
|
59
68
|
# to track and which new episodes aired.
|
60
|
-
|
69
|
+
# The param +dont_update_last_run+ prevents changing the configuration's date value
|
70
|
+
# The param +offset+ can be used to move the date back that many days in the check
|
71
|
+
# The param +include_tomorrow+ will add the current day to the list of dates to search
|
72
|
+
def run(dont_update_last_run, offset = 0, include_tomorrow: false)
|
61
73
|
pending = @config.content[:pending].clone
|
62
74
|
@config.content[:pending].clear
|
63
75
|
pending ||= []
|
64
|
-
date =
|
76
|
+
date = date_to_check_from(offset)
|
65
77
|
|
66
|
-
pending.concat shows_to_download(date) if date
|
78
|
+
pending.concat shows_to_download(date) if date < Date.today
|
79
|
+
pending.concat today_shows_to_download if include_tomorrow && date < Date.today.next
|
67
80
|
|
68
81
|
if pending.empty?
|
69
82
|
puts 'Nothing to download'
|
70
83
|
else
|
71
|
-
find_and_download(pending)
|
84
|
+
find_and_download(pending.uniq)
|
72
85
|
puts 'Completed. Exiting...'
|
73
86
|
end
|
74
87
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
##
|
82
|
-
# Finds download links for all the episodes set to air today.
|
83
|
-
# TODO: Refactor with #run()
|
84
|
-
def run_ahead(dont_update_last_run)
|
85
|
-
pending = @config.content[:pending].clone
|
86
|
-
@config.content[:pending].clear
|
87
|
-
pending ||= []
|
88
|
-
|
89
|
-
# Has the program already been run with --tomorrow
|
90
|
-
if @config.content[:date] < Date.today.next
|
91
|
-
pending.concat today_shows_to_download
|
92
|
-
end
|
93
|
-
|
94
|
-
if pending.empty?
|
95
|
-
puts 'Nothing to download'
|
96
|
-
else
|
97
|
-
find_and_download(pending)
|
98
|
-
puts 'Completed. Exiting...'
|
88
|
+
unless dont_update_last_run
|
89
|
+
@config.content[:date] = if include_tomorrow
|
90
|
+
Date.today.next
|
91
|
+
else
|
92
|
+
[Date.today, @config.content[:date]].max
|
93
|
+
end
|
99
94
|
end
|
100
|
-
|
101
|
-
@config.content[:date] = Date.today.next unless dont_update_last_run
|
102
95
|
@config.serialize
|
103
96
|
rescue InvalidLoginError
|
104
97
|
warn 'Wrong username/password combination'
|
@@ -110,7 +103,7 @@ module DownloadTV
|
|
110
103
|
|
111
104
|
# Adds a link (or empty string to the queue)
|
112
105
|
link_t = Thread.new do
|
113
|
-
shows.each { |show| queue << get_link(t, show, true) }
|
106
|
+
shows.each { |show| queue << get_link(t, show, save_pending: true) }
|
114
107
|
end
|
115
108
|
|
116
109
|
# Downloads the links as they are added
|
@@ -123,20 +116,13 @@ module DownloadTV
|
|
123
116
|
end
|
124
117
|
end
|
125
118
|
|
126
|
-
# Downloading the subtitles
|
127
|
-
# subs_t = @config.content[:subs] and Thread.new do
|
128
|
-
# shows.each { |show| @s.get_subs(show) }
|
129
|
-
# end
|
130
|
-
|
131
119
|
link_t.join
|
132
120
|
download_t.join
|
133
|
-
# subs_t.join
|
134
121
|
end
|
135
122
|
|
136
123
|
def shows_to_download(date)
|
137
124
|
myepisodes = MyEpisodes.new(@config.content[:myepisodes_user],
|
138
125
|
@config.content[:cookie])
|
139
|
-
# Log in using cookie by default
|
140
126
|
myepisodes.load_cookie
|
141
127
|
shows = myepisodes.get_shows_since(date)
|
142
128
|
shows = reject_ignored(shows)
|
@@ -158,7 +144,7 @@ module DownloadTV
|
|
158
144
|
# based on a set of filters.
|
159
145
|
# When it's false it will prompt the user to select the preferred result
|
160
146
|
# Returns either a magnet link or an emptry string
|
161
|
-
def get_link(torrent, show, save_pending
|
147
|
+
def get_link(torrent, show, save_pending: false)
|
162
148
|
links = torrent.get_links(show)
|
163
149
|
|
164
150
|
if links.empty?
|
@@ -193,19 +179,6 @@ module DownloadTV
|
|
193
179
|
print 'Select the torrent you want to download [-1 to skip]: '
|
194
180
|
end
|
195
181
|
|
196
|
-
##
|
197
|
-
# Returns the date from which to check shows
|
198
|
-
# or nil if the program was already ran today
|
199
|
-
# Passing an offset skips this check
|
200
|
-
def check_date(offset)
|
201
|
-
if offset.zero?
|
202
|
-
last = @config.content[:date]
|
203
|
-
last if last < Date.today
|
204
|
-
else
|
205
|
-
Date.today - offset
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
182
|
##
|
210
183
|
# Given a list of shows and episodes:
|
211
184
|
#
|
@@ -227,24 +200,16 @@ module DownloadTV
|
|
227
200
|
end
|
228
201
|
|
229
202
|
##
|
230
|
-
#
|
231
|
-
#
|
232
|
-
#
|
203
|
+
# Removes links whose names don't match the user filters
|
204
|
+
# Runs until no filters are left to be applied or applying
|
205
|
+
# a filter would leave no results
|
233
206
|
def filter_shows(links)
|
234
|
-
|
235
|
-
|
236
|
-
# Stop if the filter removes every release
|
237
|
-
break if new_links.empty?
|
238
|
-
|
239
|
-
links = new_links
|
240
|
-
end
|
241
|
-
|
242
|
-
links
|
207
|
+
f = Filterer.new(@config.content[:filters])
|
208
|
+
f.filter(links)
|
243
209
|
end
|
244
210
|
|
245
211
|
##
|
246
212
|
# Spawns a silent process to download a given magnet link
|
247
|
-
# Uses xdg-open (not portable)
|
248
213
|
def download(link)
|
249
214
|
@cmd ||= detect_os
|
250
215
|
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DownloadTV
|
4
|
+
##
|
5
|
+
# Builds and applies filters to the results
|
6
|
+
class Filterer
|
7
|
+
attr_reader :filters
|
8
|
+
|
9
|
+
def initialize(filters_config)
|
10
|
+
@filters = []
|
11
|
+
build_filters(filters_config)
|
12
|
+
end
|
13
|
+
|
14
|
+
def build_include_filter(str)
|
15
|
+
@filters << ->(n) { !n.upcase.include?(str) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def build_exclude_filter(str)
|
19
|
+
@filters << ->(n) { n.upcase.include?(str) }
|
20
|
+
end
|
21
|
+
|
22
|
+
def build_filters(filters_config)
|
23
|
+
return unless filters_config
|
24
|
+
|
25
|
+
filters_config[:includes].map { |i| build_include_filter(i) }
|
26
|
+
filters_config[:excludes].map { |i| build_exclude_filter(i) }
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Iteratively applies filters until they've all been applied
|
31
|
+
# or applying the next filter would result in no results
|
32
|
+
def filter(shows)
|
33
|
+
# shows is tuple (show name, link)
|
34
|
+
@filters.each do |f|
|
35
|
+
new_shows = shows.reject { |name, _link| f.call(name) }
|
36
|
+
# Go to next filter if the filter removes every release
|
37
|
+
next if new_shows.empty?
|
38
|
+
|
39
|
+
shows = new_shows
|
40
|
+
end
|
41
|
+
|
42
|
+
shows
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -12,20 +12,23 @@ module DownloadTV
|
|
12
12
|
# Format the url
|
13
13
|
search = format(@url, show)
|
14
14
|
|
15
|
-
|
15
|
+
raw_data = @agent.get(search)
|
16
|
+
raw_links = raw_data.search('a.magnet')
|
17
|
+
raw_seeders = raw_data.search('td.forum_thread_post_end').map { |e| e.children[0].text.to_i }
|
18
|
+
raw_links = raw_links.sort_by.with_index { |_, index| raw_seeders[index] }.reverse
|
16
19
|
|
17
|
-
# Torrent name in
|
20
|
+
# Torrent name in raw_links[i].attribute 'title'
|
18
21
|
# 'Suits S04E01 HDTV x264-LOL Torrent: Magnet Link'
|
19
22
|
|
20
23
|
# EZTV shows 50 latest releases if it can't find the torrent
|
21
|
-
raise NoTorrentsError if
|
24
|
+
raise NoTorrentsError if raw_links.size == 50
|
22
25
|
|
23
|
-
names =
|
26
|
+
names = raw_links.collect do |i|
|
24
27
|
i.attribute('title')
|
25
28
|
.text
|
26
29
|
.chomp(' Magnet Link')
|
27
30
|
end
|
28
|
-
links =
|
31
|
+
links = raw_links.collect do |i|
|
29
32
|
i.attribute('href')
|
30
33
|
.text
|
31
34
|
end
|
@@ -21,13 +21,15 @@ module DownloadTV
|
|
21
21
|
@agent.read_timeout = 2
|
22
22
|
renew_token
|
23
23
|
true
|
24
|
-
rescue Mechanize::ResponseCodeError
|
24
|
+
rescue Mechanize::ResponseCodeError => e
|
25
25
|
if e.response_code == '429'
|
26
26
|
sleep(@wait)
|
27
27
|
retry
|
28
28
|
else
|
29
29
|
false
|
30
30
|
end
|
31
|
+
rescue Net::HTTP::Persistent::Error => e
|
32
|
+
false
|
31
33
|
end
|
32
34
|
|
33
35
|
##
|
@@ -32,11 +32,11 @@ module DownloadTV
|
|
32
32
|
def prompt_user_data
|
33
33
|
if !@user || @user == ''
|
34
34
|
print 'Enter your MyEpisodes username: '
|
35
|
-
@user =
|
35
|
+
@user = $stdin.gets.chomp
|
36
36
|
end
|
37
37
|
|
38
38
|
print 'Enter your MyEpisodes password: '
|
39
|
-
pass =
|
39
|
+
pass = $stdin.noecho(&:gets).chomp
|
40
40
|
puts
|
41
41
|
pass
|
42
42
|
end
|
data/lib/download_tv/torrent.rb
CHANGED
data/lib/download_tv/version.rb
CHANGED
data/test/config_test.rb
CHANGED
@@ -18,28 +18,28 @@ describe DownloadTV::Configuration do
|
|
18
18
|
create_dummy_config(config_path)
|
19
19
|
|
20
20
|
c = DownloadTV::Configuration.new(path: config_path)
|
21
|
-
c.content.must_equal(path: config_path, version: DownloadTV::VERSION)
|
21
|
+
_(c.content).must_equal(path: config_path, version: DownloadTV::VERSION)
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'will load the existing configuration (existing)' do
|
25
25
|
create_dummy_config(config_path, auto: false, myepisodes_user: 'dummy')
|
26
26
|
|
27
27
|
c = DownloadTV::Configuration.new(path: config_path)
|
28
|
-
c.content.must_equal(path: config_path, auto: false, myepisodes_user: 'dummy', version: DownloadTV::VERSION)
|
28
|
+
_(c.content).must_equal(path: config_path, auto: false, myepisodes_user: 'dummy', version: DownloadTV::VERSION)
|
29
29
|
end
|
30
30
|
|
31
31
|
it 'will get overwritten by the parameters given' do
|
32
32
|
create_dummy_config(config_path, myepisodes_user: 'dummy')
|
33
33
|
|
34
34
|
c = DownloadTV::Configuration.new(path: config_path, myepisodes_user: 'fake')
|
35
|
-
c.content.must_equal(path: config_path, myepisodes_user: 'fake', version: DownloadTV::VERSION)
|
35
|
+
_(c.content).must_equal(path: config_path, myepisodes_user: 'fake', version: DownloadTV::VERSION)
|
36
36
|
end
|
37
37
|
|
38
38
|
it 'will downcase ignored shows' do
|
39
39
|
create_dummy_config(config_path, ignored: %w[duMMy String])
|
40
40
|
|
41
41
|
c = DownloadTV::Configuration.new(path: config_path)
|
42
|
-
c.content[:ignored].must_equal %w[dummy string]
|
42
|
+
_(c.content[:ignored]).must_equal %w[dummy string]
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
@@ -48,7 +48,7 @@ describe DownloadTV::Configuration do
|
|
48
48
|
create_dummy_config(config_path)
|
49
49
|
|
50
50
|
c = DownloadTV::Configuration.new(path: config_path)
|
51
|
-
c.breaking_changes?(DownloadTV::VERSION).must_be_nil
|
51
|
+
_(c.breaking_changes?(DownloadTV::VERSION)).must_be_nil
|
52
52
|
end
|
53
53
|
|
54
54
|
it "returns true when there's been a major update" do
|
@@ -58,7 +58,7 @@ describe DownloadTV::Configuration do
|
|
58
58
|
split[0] = (split[0].to_i - 1).to_s
|
59
59
|
new_version = split.join('.')
|
60
60
|
c = DownloadTV::Configuration.new(path: config_path)
|
61
|
-
c.breaking_changes?(new_version).must_equal true
|
61
|
+
_(c.breaking_changes?(new_version)).must_equal true
|
62
62
|
end
|
63
63
|
|
64
64
|
it "returns true when there's been a minor update" do
|
@@ -68,7 +68,7 @@ describe DownloadTV::Configuration do
|
|
68
68
|
split[1] = (split[1].to_i - 1).to_s
|
69
69
|
new_version = split.join('.')
|
70
70
|
c = DownloadTV::Configuration.new(path: config_path)
|
71
|
-
c.breaking_changes?(new_version).must_equal true
|
71
|
+
_(c.breaking_changes?(new_version)).must_equal true
|
72
72
|
end
|
73
73
|
|
74
74
|
it "returns false when it's a small patch" do
|
@@ -78,7 +78,7 @@ describe DownloadTV::Configuration do
|
|
78
78
|
split[2] = (split[2].to_i - 1).to_s
|
79
79
|
new_version = split.join('.')
|
80
80
|
c = DownloadTV::Configuration.new(path: config_path)
|
81
|
-
c.breaking_changes?(new_version).must_equal false
|
81
|
+
_(c.breaking_changes?(new_version)).must_equal false
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
@@ -90,7 +90,7 @@ describe DownloadTV::Configuration do
|
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
|
-
File.exist?(config_path).must_equal true
|
93
|
+
_(File.exist?(config_path)).must_equal true
|
94
94
|
end
|
95
95
|
|
96
96
|
it 'will have the right values' do
|
@@ -101,15 +101,15 @@ describe DownloadTV::Configuration do
|
|
101
101
|
end
|
102
102
|
end
|
103
103
|
|
104
|
-
c.content[:myepisodes_user].must_equal 'anything'
|
105
|
-
c.content[:cookie].must_equal true
|
106
|
-
c.content[:ignored].must_equal ['anything']
|
107
|
-
c.content[:auto].must_equal true
|
108
|
-
c.content[:subs].must_equal true
|
109
|
-
c.content[:pending].must_equal []
|
110
|
-
c.content[:grabber].must_equal 'TorrentAPI'
|
111
|
-
c.content[:date].must_equal(Date.today - 1)
|
112
|
-
c.content[:version].must_equal DownloadTV::VERSION
|
104
|
+
_(c.content[:myepisodes_user]).must_equal 'anything'
|
105
|
+
_(c.content[:cookie]).must_equal true
|
106
|
+
_(c.content[:ignored]).must_equal ['anything']
|
107
|
+
_(c.content[:auto]).must_equal true
|
108
|
+
_(c.content[:subs]).must_equal true
|
109
|
+
_(c.content[:pending]).must_equal []
|
110
|
+
_(c.content[:grabber]).must_equal 'TorrentAPI'
|
111
|
+
_(c.content[:date]).must_equal(Date.today - 1)
|
112
|
+
_(c.content[:version]).must_equal DownloadTV::VERSION
|
113
113
|
end
|
114
114
|
|
115
115
|
it 'will set the cookie value to false when explicitly told so' do
|
@@ -120,7 +120,7 @@ describe DownloadTV::Configuration do
|
|
120
120
|
end
|
121
121
|
end
|
122
122
|
|
123
|
-
c.content[:cookie].must_equal false
|
123
|
+
_(c.content[:cookie]).must_equal false
|
124
124
|
end
|
125
125
|
|
126
126
|
it 'will separate the ignored values by commas' do
|
@@ -130,7 +130,7 @@ describe DownloadTV::Configuration do
|
|
130
130
|
c = DownloadTV::Configuration.new(path: config_path)
|
131
131
|
end
|
132
132
|
end
|
133
|
-
c.content[:ignored].must_equal ['ignored1', 'itsgone', 'ignored 2']
|
133
|
+
_(c.content[:ignored]).must_equal ['ignored1', 'itsgone', 'ignored 2']
|
134
134
|
end
|
135
135
|
end
|
136
136
|
|
@@ -147,22 +147,22 @@ describe DownloadTV::Configuration do
|
|
147
147
|
content = JSON.parse(source, symbolize_names: true)
|
148
148
|
content[:date] = Date.parse(content[:date])
|
149
149
|
|
150
|
-
content[:cookie].must_equal true
|
151
|
-
content[:myepisodes_user].must_equal 'anything'
|
152
|
-
content[:ignored].must_equal ['anything']
|
153
|
-
content[:auto].must_equal true
|
154
|
-
content[:subs].must_equal true
|
155
|
-
content[:pending].must_equal []
|
156
|
-
content[:grabber].must_equal 'TorrentAPI'
|
157
|
-
content[:date].must_equal Date.today - 1
|
158
|
-
content[:version].must_equal DownloadTV::VERSION
|
150
|
+
_(content[:cookie]).must_equal true
|
151
|
+
_(content[:myepisodes_user]).must_equal 'anything'
|
152
|
+
_(content[:ignored]).must_equal ['anything']
|
153
|
+
_(content[:auto]).must_equal true
|
154
|
+
_(content[:subs]).must_equal true
|
155
|
+
_(content[:pending]).must_equal []
|
156
|
+
_(content[:grabber]).must_equal 'TorrentAPI'
|
157
|
+
_(content[:date]).must_equal Date.today - 1
|
158
|
+
_(content[:version]).must_equal DownloadTV::VERSION
|
159
159
|
end
|
160
160
|
end
|
161
161
|
|
162
162
|
describe 'the constructor' do
|
163
163
|
it 'will trigger a configuration change when asked to' do
|
164
164
|
create_dummy_config(config_path, auto: false)
|
165
|
-
File.exist?(config_path).must_equal true
|
165
|
+
_(File.exist?(config_path)).must_equal true
|
166
166
|
c = nil
|
167
167
|
|
168
168
|
run_silently do
|
@@ -171,7 +171,7 @@ describe DownloadTV::Configuration do
|
|
171
171
|
end
|
172
172
|
end
|
173
173
|
|
174
|
-
c.content[:auto].must_equal false
|
174
|
+
_(c.content[:auto]).must_equal false
|
175
175
|
end
|
176
176
|
end
|
177
177
|
end
|
data/test/downloader_test.rb
CHANGED
@@ -17,8 +17,8 @@ describe DownloadTV::Downloader do
|
|
17
17
|
describe 'when creating the object' do
|
18
18
|
it 'can receive an optional configuration hash' do
|
19
19
|
dl = DownloadTV::Downloader.new(auto: true, grabber: 'KAT', path: config_path)
|
20
|
-
dl.config.content[:auto].must_equal true
|
21
|
-
dl.config.content[:grabber].must_equal 'KAT'
|
20
|
+
_(dl.config.content[:auto]).must_equal true
|
21
|
+
_(dl.config.content[:grabber]).must_equal 'KAT'
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
@@ -30,7 +30,7 @@ describe DownloadTV::Downloader do
|
|
30
30
|
'Baz The Story S05E22']
|
31
31
|
|
32
32
|
dl = DownloadTV::Downloader.new(ignored: [], path: config_path)
|
33
|
-
dl.fix_names(shows).must_equal result
|
33
|
+
_(dl.fix_names(shows)).must_equal result
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -40,62 +40,51 @@ describe DownloadTV::Downloader do
|
|
40
40
|
result = ['Bar S00E22']
|
41
41
|
|
42
42
|
dl = DownloadTV::Downloader.new(ignored: ['ignored'], path: config_path)
|
43
|
-
dl.reject_ignored(shows).must_equal result
|
43
|
+
_(dl.reject_ignored(shows)).must_equal result
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
describe 'the
|
48
|
-
it '
|
47
|
+
describe 'the date_to_check_from method' do
|
48
|
+
it 'returns the config date when offset is not given' do
|
49
49
|
dl = DownloadTV::Downloader.new(date: Date.today, path: config_path)
|
50
|
-
dl.
|
50
|
+
_(dl.date_to_check_from(0)).must_equal Date.today
|
51
51
|
end
|
52
52
|
|
53
53
|
it 'uses the offset to adjust the date' do
|
54
54
|
# Would exit with offset 0
|
55
55
|
dl = DownloadTV::Downloader.new(date: Date.today, path: config_path)
|
56
56
|
|
57
|
-
date = dl.
|
57
|
+
date = dl.date_to_check_from(1)
|
58
58
|
|
59
|
-
date.must_equal(Date.today - 1)
|
60
|
-
dl.config.content[:date].must_equal Date.today
|
59
|
+
_(date).must_equal(Date.today - 1)
|
60
|
+
_(dl.config.content[:date]).must_equal Date.today
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
64
|
describe 'the filter_shows method' do
|
65
|
-
it 'removes names with
|
66
|
-
|
65
|
+
it 'removes names with exclude words in them' do
|
66
|
+
f = {:excludes => ["2160P"], :includes => []}
|
67
|
+
dl = DownloadTV::Downloader.new(path: config_path, filters: f)
|
67
68
|
links = [['Link 1', ''], ['Link 2 2160p', ''], ['Link 3', '']]
|
68
69
|
res = [['Link 1', ''], ['Link 3', '']]
|
69
|
-
dl.filter_shows(links).must_equal res
|
70
|
+
_(dl.filter_shows(links)).must_equal res
|
70
71
|
end
|
71
72
|
|
72
|
-
it 'removes names
|
73
|
-
|
74
|
-
|
75
|
-
res = [['Link 3', '']]
|
76
|
-
dl.filter_shows(links).must_equal res
|
77
|
-
end
|
78
|
-
|
79
|
-
it 'removes names with 720p in them' do
|
80
|
-
dl = DownloadTV::Downloader.new(path: config_path)
|
81
|
-
links = [['Link 1', ''], ['Link 2 720p', ''], ['Link.720p.rip', '']]
|
82
|
-
res = [['Link 1', '']]
|
83
|
-
dl.filter_shows(links).must_equal res
|
84
|
-
end
|
85
|
-
|
86
|
-
it 'removes names without PROPER or REPACK in them' do
|
87
|
-
dl = DownloadTV::Downloader.new(path: config_path)
|
73
|
+
it 'removes names without include words in them' do
|
74
|
+
f = {:excludes => [], :includes => %w[REPACK]}
|
75
|
+
dl = DownloadTV::Downloader.new(path: config_path, filters: f)
|
88
76
|
links = [['Link 1', ''], ['Link 2 2160p', ''], ['Link 3', ''],
|
89
|
-
['Link
|
90
|
-
res = [['Link
|
91
|
-
dl.filter_shows(links).must_equal res
|
77
|
+
['Link REPACK 5', '']]
|
78
|
+
res = [['Link REPACK 5', '']]
|
79
|
+
_(dl.filter_shows(links)).must_equal res
|
92
80
|
end
|
93
81
|
|
94
82
|
it "doesn't apply a filter if it would reject every option" do
|
95
|
-
|
83
|
+
f = {:excludes => %w[2160P 720P], :includes => []}
|
84
|
+
dl = DownloadTV::Downloader.new(path: config_path, filters: f)
|
96
85
|
links = [['Link 1 720p', ''], ['Link 2 2160p', ''], ['Link 720p 3', '']]
|
97
86
|
res = [['Link 1 720p', ''], ['Link 720p 3', '']]
|
98
|
-
dl.filter_shows(links).must_equal res
|
87
|
+
_(dl.filter_shows(links)).must_equal res
|
99
88
|
end
|
100
89
|
end
|
101
90
|
|
@@ -106,13 +95,13 @@ describe DownloadTV::Downloader do
|
|
106
95
|
|
107
96
|
t.expect(:get_links, [], [show])
|
108
97
|
dl = DownloadTV::Downloader.new(auto: true, path: config_path, pending: ['show 11'])
|
109
|
-
dl.get_link(t, show, true).must_equal ''
|
110
|
-
dl.config.content[:pending].must_equal ['show 11', show]
|
98
|
+
_(dl.get_link(t, show, save_pending: true)).must_equal ''
|
99
|
+
_(dl.config.content[:pending]).must_equal ['show 11', show]
|
111
100
|
|
112
101
|
t.expect(:get_links, [], [show])
|
113
102
|
dl = DownloadTV::Downloader.new(auto: false, path: config_path, pending: [])
|
114
|
-
dl.get_link(t, show, true).must_equal ''
|
115
|
-
dl.config.content[:pending].must_include show
|
103
|
+
_(dl.get_link(t, show, save_pending: true)).must_equal ''
|
104
|
+
_(dl.config.content[:pending]).must_include show
|
116
105
|
|
117
106
|
t.verify
|
118
107
|
end
|
@@ -123,7 +112,7 @@ describe DownloadTV::Downloader do
|
|
123
112
|
|
124
113
|
t.expect(:get_links, [['Name 1', 'Link 1'], ['Name 2', 'Link 2']], [show])
|
125
114
|
dl = DownloadTV::Downloader.new(auto: true, path: config_path)
|
126
|
-
dl.get_link(t, show).must_equal 'Link 1'
|
115
|
+
_(dl.get_link(t, show)).must_equal 'Link 1'
|
127
116
|
t.verify
|
128
117
|
end
|
129
118
|
end
|
@@ -134,7 +123,7 @@ describe DownloadTV::Downloader do
|
|
134
123
|
RbConfig::CONFIG['host_os'] = 'linux-gnu'
|
135
124
|
|
136
125
|
dl = DownloadTV::Downloader.new(path: config_path)
|
137
|
-
dl.detect_os.must_equal 'xdg-open'
|
126
|
+
_(dl.detect_os).must_equal 'xdg-open'
|
138
127
|
|
139
128
|
RbConfig::CONFIG['host_os'] = prev
|
140
129
|
end
|
@@ -144,7 +133,7 @@ describe DownloadTV::Downloader do
|
|
144
133
|
RbConfig::CONFIG['host_os'] = 'darwin15.6.0'
|
145
134
|
|
146
135
|
dl = DownloadTV::Downloader.new(path: config_path)
|
147
|
-
dl.detect_os.must_equal 'open'
|
136
|
+
_(dl.detect_os).must_equal 'open'
|
148
137
|
|
149
138
|
RbConfig::CONFIG['host_os'] = prev
|
150
139
|
end
|
@@ -155,8 +144,8 @@ describe DownloadTV::Downloader do
|
|
155
144
|
|
156
145
|
dl = DownloadTV::Downloader.new(path: config_path)
|
157
146
|
|
158
|
-
to_run = -> { run_silently { dl.detect_os.must_equal 'xdg-open' } }
|
159
|
-
to_run.must_raise SystemExit
|
147
|
+
to_run = -> { run_silently { _(dl.detect_os).must_equal 'xdg-open' } }
|
148
|
+
_(to_run).must_raise SystemExit
|
160
149
|
|
161
150
|
RbConfig::CONFIG['host_os'] = prev
|
162
151
|
end
|
data/test/grabbers_test.rb
CHANGED
@@ -11,30 +11,30 @@ describe DownloadTV::LinkGrabber do
|
|
11
11
|
next unless grabber.online?
|
12
12
|
|
13
13
|
it 'will have a url attribute on creation' do
|
14
|
-
grabber.url.wont_be_nil
|
14
|
+
_(grabber.url).wont_be_nil
|
15
15
|
end
|
16
16
|
|
17
17
|
it "will raise NoTorrentsError when torrent can't be found" do
|
18
18
|
notfound = -> { grabber.get_links('Totally Fake Show askjdgsaudas') }
|
19
|
-
notfound.must_raise DownloadTV::NoTorrentsError
|
19
|
+
_(notfound).must_raise DownloadTV::NoTorrentsError
|
20
20
|
end
|
21
21
|
|
22
22
|
it 'will return an array with names and links of results when a torrent can be found' do
|
23
|
-
result = grabber.get_links('
|
24
|
-
result.must_be_instance_of Array
|
25
|
-
result.wont_be :empty?
|
23
|
+
result = grabber.get_links('The Boys S01E01')
|
24
|
+
_(result).must_be_instance_of Array
|
25
|
+
_(result).wont_be :empty?
|
26
26
|
result.each do |r|
|
27
|
-
r.size.must_equal 2
|
28
|
-
r[0].must_be_instance_of String
|
29
|
-
r[0].upcase.must_include '
|
30
|
-
r[1].must_be_instance_of String
|
31
|
-
r[1].must_include 'magnet:'
|
27
|
+
_(r.size).must_equal 2
|
28
|
+
_(r[0]).must_be_instance_of String
|
29
|
+
_(r[0].upcase).must_include 'BOYS'
|
30
|
+
_(r[1]).must_be_instance_of String
|
31
|
+
_(r[1]).must_include 'magnet:'
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
37
|
it "raises an error if the instance doesn't implement get_links" do
|
38
|
-
-> { DownloadTV::LinkGrabber.new('').get_links('test') }.must_raise NotImplementedError
|
38
|
+
_(-> { DownloadTV::LinkGrabber.new('').get_links('test') }).must_raise NotImplementedError
|
39
39
|
end
|
40
40
|
end
|
data/test/torrent_test.rb
CHANGED
@@ -10,16 +10,16 @@ describe DownloadTV::Torrent do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
it 'will populate the instances' do
|
13
|
-
@t.g_instances.size.must_equal grabber_names.size
|
13
|
+
_(@t.g_instances.size).must_equal grabber_names.size
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'will start with all tries available' do
|
17
|
-
@t.tries.must_equal grabber_names.size - 1
|
17
|
+
_(@t.tries).must_equal grabber_names.size - 1
|
18
18
|
end
|
19
19
|
|
20
20
|
it 'will call get_links on its grabber' do
|
21
21
|
@t.g_instances.first.stub :get_links, %w[test result] do
|
22
|
-
@t.get_links('test show').must_equal %w[test result]
|
22
|
+
_(@t.get_links('test show')).must_equal %w[test result]
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -28,13 +28,13 @@ describe DownloadTV::Torrent do
|
|
28
28
|
it 'has a default order' do
|
29
29
|
t = DownloadTV::Torrent.new(nil)
|
30
30
|
expected = grabber_names.map { |i| "DownloadTV::#{i}" }
|
31
|
-
t.g_instances.map { |i| i.class.name }.must_equal expected
|
31
|
+
_(t.g_instances.map { |i| i.class.name }).must_equal expected
|
32
32
|
end
|
33
33
|
|
34
34
|
grabber_names.each do |g|
|
35
35
|
it 'correctly uses the given grabber first' do
|
36
36
|
t = DownloadTV::Torrent.new(g)
|
37
|
-
t.g_instances.first.class.name.must_equal "DownloadTV::#{g}"
|
37
|
+
_(t.g_instances.first.class.name).must_equal "DownloadTV::#{g}"
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|
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
|
+
version: 2.6.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- guille
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-05-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '2.0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '2.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: minitest
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -40,18 +40,46 @@ dependencies:
|
|
40
40
|
version: '5.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 12.3.3
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 12.3.3
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.13'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.13'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: byebug
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
44
72
|
requirements:
|
45
73
|
- - "~>"
|
46
74
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
75
|
+
version: '11.1'
|
48
76
|
type: :development
|
49
77
|
prerelease: false
|
50
78
|
version_requirements: !ruby/object:Gem::Requirement
|
51
79
|
requirements:
|
52
80
|
- - "~>"
|
53
81
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
82
|
+
version: '11.1'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: json
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,7 +108,7 @@ dependencies:
|
|
80
108
|
- - ">="
|
81
109
|
- !ruby/object:Gem::Version
|
82
110
|
version: '0'
|
83
|
-
description:
|
111
|
+
description:
|
84
112
|
email:
|
85
113
|
- guillerg96@gmail.com
|
86
114
|
executables:
|
@@ -88,6 +116,7 @@ executables:
|
|
88
116
|
extensions: []
|
89
117
|
extra_rdoc_files: []
|
90
118
|
files:
|
119
|
+
- ".github/workflows/ruby.yml"
|
91
120
|
- ".gitignore"
|
92
121
|
- ".travis.yml"
|
93
122
|
- Gemfile
|
@@ -99,6 +128,7 @@ files:
|
|
99
128
|
- lib/download_tv.rb
|
100
129
|
- lib/download_tv/configuration.rb
|
101
130
|
- lib/download_tv/downloader.rb
|
131
|
+
- lib/download_tv/filterer.rb
|
102
132
|
- lib/download_tv/grabbers/addic7ed.rb
|
103
133
|
- lib/download_tv/grabbers/eztv.rb
|
104
134
|
- lib/download_tv/grabbers/kat.rb
|
@@ -118,7 +148,7 @@ homepage: https://github.com/guille/download_tv
|
|
118
148
|
licenses:
|
119
149
|
- MIT
|
120
150
|
metadata: {}
|
121
|
-
post_install_message:
|
151
|
+
post_install_message:
|
122
152
|
rdoc_options: []
|
123
153
|
require_paths:
|
124
154
|
- lib
|
@@ -133,9 +163,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
133
163
|
- !ruby/object:Gem::Version
|
134
164
|
version: '0'
|
135
165
|
requirements: []
|
136
|
-
|
137
|
-
|
138
|
-
signing_key:
|
166
|
+
rubygems_version: 3.2.17
|
167
|
+
signing_key:
|
139
168
|
specification_version: 4
|
140
169
|
summary: DownloadTV is a tool that allows the user to find magnet links for tv show
|
141
170
|
episodes. It accepts shows as arguments, from a file or it can integrate with your
|