download_tv 2.5.3 → 2.6.2
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 +22 -7
- data/bin/tv +32 -7
- data/download_tv.gemspec +4 -2
- data/lib/download_tv.rb +3 -1
- data/lib/download_tv/configuration.rb +46 -8
- data/lib/download_tv/downloader.rb +83 -73
- 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 +9 -6
- 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 +29 -40
- 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: 29c9837fef84c38a41063a8526525e12ce56c82bd8c8467289401dd8ae5453ba
|
4
|
+
data.tar.gz: c448ce24115b3cb19dcc128c56a47cdee61d072994dafcfe5ab3d53b5d799109
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a00092c93cc8076bf41d2a43a198f16be217ef251f74586387f92303e2db9baf0db8008f09271a7f086788578368dec2a881429136caf0d9c71d4fc2ff00be22
|
7
|
+
data.tar.gz: b79f9e1625c27bd2c3f2c6c33b8092dcd0c1fb8c29a4e0f950619d0484d20d7fa175398e5d9e67cc6e8e7c268f137715e3c7e04e1c5c1e323c45d436a084eb4c
|
@@ -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,18 +21,19 @@ 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
|
+
-s, --season SEASON Limit the show download to a specific season
|
25
|
+
-t, --tomorrow Download shows airing today
|
24
26
|
-c, --configure Configures defaults
|
25
27
|
--show-config Show current configuration values
|
26
28
|
--dry-run Don't write to the date file
|
27
29
|
-a, --[no-]auto Automatically find links
|
28
|
-
-s, --[no-]subtitles Download subtitles
|
29
30
|
-g, --grabber GRABBER Use given grabber as first option
|
30
31
|
--show-grabbers List available grabbers
|
31
32
|
-p, --pending Show list of pending downloads
|
32
33
|
--clear-pending Clear list of pending downloads
|
33
|
-
-
|
34
|
+
-q, --queue SHOW Add show episode to pending downloads list
|
35
|
+
-v, --version Print version
|
34
36
|
-h, --help Show this message
|
35
|
-
|
36
37
|
```
|
37
38
|
|
38
39
|
### MyEpisodes integration
|
@@ -41,11 +42,13 @@ By default, download_tv connects to your MyEpisodes.com account and fetches the
|
|
41
42
|
|
42
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).
|
43
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
|
+
|
44
47
|
**Note**: Due to API limitations, the gem won't find shows aired more than 14 days prior to the execution of the script.
|
45
48
|
|
46
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.
|
47
50
|
|
48
|
-
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).
|
49
52
|
|
50
53
|
### Single torrent download
|
51
54
|
|
@@ -53,6 +56,8 @@ In order to download a single episode, use the -d flag, quoting the string when
|
|
53
56
|
|
54
57
|
Although it uses some settings and grabbers specific for TV shows, this option can also be used as a quick way to find and download any torrent.
|
55
58
|
|
59
|
+
It can be used with the --season flag to try to find and download a whole season of the given show: *tv -d "Breaking Bad" --season 4*. It will start searching from episode 1 and continue until it can't find any torrent for the episode.
|
60
|
+
|
56
61
|
### Multi torrent download
|
57
62
|
|
58
63
|
The -f flag can be used to read the list of episodes to download from a file. Each line of the file is interpreted as a episode to download: *tv -f /path/to/listofeps*
|
@@ -65,8 +70,18 @@ I usually publish a patch update to the gem when I detect one of them isn't work
|
|
65
70
|
|
66
71
|
### Pending shows
|
67
72
|
|
68
|
-
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). This list can be viewed by passing the -p flag to the tv binary. The list can be cleared with the --clear-pending option.
|
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.
|
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**.
|
69
84
|
|
70
85
|
### License
|
71
86
|
|
72
|
-
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,6 +30,15 @@ opt_parser = OptionParser.new do |opts|
|
|
30
30
|
options[:arg] = s
|
31
31
|
end
|
32
32
|
|
33
|
+
opts.on('-s', '--season SEASON', 'Limit the show download to a specific season') do |s|
|
34
|
+
options[:cmd] = 'dl'
|
35
|
+
options[:season] = s
|
36
|
+
end
|
37
|
+
|
38
|
+
opts.on('-t', '--tomorrow', 'Download shows airing today') do |s|
|
39
|
+
options[:cmd] = 'tomorrow'
|
40
|
+
end
|
41
|
+
|
33
42
|
opts.on('-c', '--configure', 'Configures defaults') do
|
34
43
|
options[:cmd] = 'config'
|
35
44
|
end
|
@@ -46,10 +55,6 @@ opt_parser = OptionParser.new do |opts|
|
|
46
55
|
config[:auto] = n
|
47
56
|
end
|
48
57
|
|
49
|
-
opts.on('-s', '--[no-]subtitles', 'Download subtitles') do |n|
|
50
|
-
config[:subs] = n
|
51
|
-
end
|
52
|
-
|
53
58
|
opts.on('-g', '--grabber GRABBER', 'Use given grabber as first option') do |g|
|
54
59
|
config[:grabber] = g
|
55
60
|
end
|
@@ -67,6 +72,11 @@ opt_parser = OptionParser.new do |opts|
|
|
67
72
|
options[:cmd] = 'clearpending'
|
68
73
|
end
|
69
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
|
+
|
70
80
|
opts.on('-v', '--version', 'Print version') do
|
71
81
|
puts DownloadTV::VERSION
|
72
82
|
exit
|
@@ -78,7 +88,13 @@ opt_parser = OptionParser.new do |opts|
|
|
78
88
|
end
|
79
89
|
end
|
80
90
|
|
81
|
-
|
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
|
82
98
|
|
83
99
|
begin
|
84
100
|
case options[:cmd]
|
@@ -86,11 +102,18 @@ begin
|
|
86
102
|
dl = DownloadTV::Downloader.new(config)
|
87
103
|
dl.run(options[:dry], options[:offset].abs)
|
88
104
|
when 'dl'
|
89
|
-
|
90
|
-
|
105
|
+
if options[:arg]
|
106
|
+
dl = DownloadTV::Downloader.new(config)
|
107
|
+
dl.download_single_show(options[:arg], options[:season])
|
108
|
+
else
|
109
|
+
warn 'You must use the season option with the -d option'
|
110
|
+
end
|
91
111
|
when 'file'
|
92
112
|
dl = DownloadTV::Downloader.new(config)
|
93
113
|
dl.download_from_file(options[:arg])
|
114
|
+
when 'tomorrow'
|
115
|
+
dl = DownloadTV::Downloader.new(config)
|
116
|
+
dl.run(options[:dry], options[:offset].abs, include_tomorrow: true)
|
94
117
|
when 'config'
|
95
118
|
DownloadTV::Configuration.new(config, true)
|
96
119
|
when 'showconfig'
|
@@ -99,6 +122,8 @@ begin
|
|
99
122
|
DownloadTV::Configuration.new(config).print_attr(:pending)
|
100
123
|
when 'clearpending'
|
101
124
|
DownloadTV::Configuration.new(config).clear_pending
|
125
|
+
when 'queue'
|
126
|
+
DownloadTV::Configuration.new(config).queue_pending(options[:arg])
|
102
127
|
end
|
103
128
|
rescue Interrupt
|
104
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
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'set'
|
3
4
|
require 'json'
|
4
5
|
require 'mechanize'
|
5
6
|
require 'date'
|
@@ -10,6 +11,7 @@ require 'download_tv/version'
|
|
10
11
|
require 'download_tv/configuration'
|
11
12
|
require 'download_tv/downloader'
|
12
13
|
require 'download_tv/torrent'
|
14
|
+
require 'download_tv/filterer'
|
13
15
|
require 'download_tv/myepisodes'
|
14
16
|
require 'download_tv/linkgrabber'
|
15
17
|
require 'download_tv/subtitles'
|
@@ -22,4 +24,4 @@ module DownloadTV
|
|
22
24
|
class NoSubtitlesError < StandardError; end
|
23
25
|
end
|
24
26
|
|
25
|
-
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,11 +97,13 @@ 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
|
72
104
|
|
73
105
|
def serialize
|
106
|
+
@content[:pending] = @content[:pending].uniq
|
74
107
|
File.write(@config_path, JSON.generate(@content))
|
75
108
|
end
|
76
109
|
|
@@ -114,5 +147,10 @@ module DownloadTV
|
|
114
147
|
@content[:pending].clear
|
115
148
|
serialize
|
116
149
|
end
|
150
|
+
|
151
|
+
def queue_pending(show)
|
152
|
+
@content[:pending] << show
|
153
|
+
serialize
|
154
|
+
end
|
117
155
|
end
|
118
156
|
end
|
@@ -9,21 +9,32 @@ 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
|
|
23
|
-
|
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
|
+
season.insert(0, '0') if season.size == 1
|
20
|
+
episode = "#{show} s#{season}e01"
|
21
|
+
loop do
|
22
|
+
link = get_link(t, episode)
|
23
|
+
break if link.empty?
|
24
|
+
|
25
|
+
download(link)
|
26
|
+
episode = episode.next
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def download_single_show(show, season = nil)
|
24
31
|
t = Torrent.new(@config.content[:grabber])
|
25
32
|
show = fix_names([show]).first
|
26
|
-
|
33
|
+
if season
|
34
|
+
download_entire_season(show, season)
|
35
|
+
else
|
36
|
+
download(get_link(t, show))
|
37
|
+
end
|
27
38
|
end
|
28
39
|
|
29
40
|
##
|
@@ -41,71 +52,87 @@ module DownloadTV
|
|
41
52
|
end
|
42
53
|
end
|
43
54
|
|
55
|
+
##
|
56
|
+
# Returns the date from which to check shows
|
57
|
+
def date_to_check_from(offset)
|
58
|
+
return @config.content[:date] if offset.zero?
|
59
|
+
|
60
|
+
Date.today - offset
|
61
|
+
end
|
62
|
+
|
44
63
|
##
|
45
64
|
# Finds download links for all new episodes aired since
|
46
65
|
# the last run of the program
|
47
66
|
# It connects to MyEpisodes in order to find which shows
|
48
67
|
# to track and which new episodes aired.
|
49
|
-
|
68
|
+
# The param +dont_update_last_run+ prevents changing the configuration's date value
|
69
|
+
# The param +offset+ can be used to move the date back that many days in the check
|
70
|
+
# The param +include_tomorrow+ will add the current day to the list of dates to search
|
71
|
+
def run(dont_update_last_run, offset = 0, include_tomorrow: false)
|
50
72
|
pending = @config.content[:pending].clone
|
51
73
|
@config.content[:pending].clear
|
52
74
|
pending ||= []
|
53
|
-
date =
|
54
|
-
if pending.empty? && date.nil?
|
55
|
-
puts 'Everything up to date'
|
56
|
-
exit
|
57
|
-
end
|
75
|
+
date = date_to_check_from(offset)
|
58
76
|
|
59
|
-
|
60
|
-
|
77
|
+
pending.concat shows_to_download(date) if date < Date.today
|
78
|
+
pending.concat today_shows_to_download if include_tomorrow && date < Date.today.next
|
61
79
|
|
62
|
-
if
|
80
|
+
if pending.empty?
|
63
81
|
puts 'Nothing to download'
|
64
|
-
|
65
82
|
else
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
# Adds a link (or empty string to the queue)
|
71
|
-
link_t = Thread.new do
|
72
|
-
to_download.each { |show| queue << get_link(t, show, true) }
|
73
|
-
end
|
83
|
+
find_and_download(pending.uniq)
|
84
|
+
puts 'Completed. Exiting...'
|
85
|
+
end
|
74
86
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
87
|
+
unless dont_update_last_run
|
88
|
+
@config.content[:date] = if include_tomorrow
|
89
|
+
Date.today.next
|
90
|
+
else
|
91
|
+
[Date.today, @config.content[:date]].max
|
92
|
+
end
|
93
|
+
end
|
94
|
+
@config.serialize
|
95
|
+
rescue InvalidLoginError
|
96
|
+
warn 'Wrong username/password combination'
|
97
|
+
end
|
80
98
|
|
81
|
-
|
82
|
-
|
83
|
-
|
99
|
+
def find_and_download(shows)
|
100
|
+
t = Torrent.new
|
101
|
+
queue = Queue.new
|
84
102
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
103
|
+
# Adds a link (or empty string to the queue)
|
104
|
+
link_t = Thread.new do
|
105
|
+
shows.each { |show| queue << get_link(t, show, save_pending: true) }
|
106
|
+
end
|
89
107
|
|
90
|
-
|
91
|
-
|
92
|
-
|
108
|
+
# Downloads the links as they are added
|
109
|
+
download_t = Thread.new do
|
110
|
+
shows.size.times do
|
111
|
+
magnet = queue.pop
|
112
|
+
next if magnet == '' # Doesn't download if no torrents are found
|
93
113
|
|
94
|
-
|
114
|
+
download(magnet)
|
115
|
+
end
|
95
116
|
end
|
96
117
|
|
97
|
-
|
98
|
-
|
99
|
-
rescue InvalidLoginError
|
100
|
-
warn 'Wrong username/password combination'
|
118
|
+
link_t.join
|
119
|
+
download_t.join
|
101
120
|
end
|
102
121
|
|
103
122
|
def shows_to_download(date)
|
104
123
|
myepisodes = MyEpisodes.new(@config.content[:myepisodes_user],
|
105
124
|
@config.content[:cookie])
|
106
|
-
# Log in using cookie by default
|
107
125
|
myepisodes.load_cookie
|
108
|
-
shows = myepisodes.
|
126
|
+
shows = myepisodes.get_shows_since(date)
|
127
|
+
shows = reject_ignored(shows)
|
128
|
+
fix_names(shows)
|
129
|
+
end
|
130
|
+
|
131
|
+
def today_shows_to_download
|
132
|
+
myepisodes = MyEpisodes.new(@config.content[:myepisodes_user],
|
133
|
+
@config.content[:cookie])
|
134
|
+
myepisodes.load_cookie
|
135
|
+
shows = myepisodes.today_shows
|
109
136
|
shows = reject_ignored(shows)
|
110
137
|
fix_names(shows)
|
111
138
|
end
|
@@ -116,7 +143,7 @@ module DownloadTV
|
|
116
143
|
# based on a set of filters.
|
117
144
|
# When it's false it will prompt the user to select the preferred result
|
118
145
|
# Returns either a magnet link or an emptry string
|
119
|
-
def get_link(torrent, show, save_pending
|
146
|
+
def get_link(torrent, show, save_pending: false)
|
120
147
|
links = torrent.get_links(show)
|
121
148
|
|
122
149
|
if links.empty?
|
@@ -151,15 +178,6 @@ module DownloadTV
|
|
151
178
|
print 'Select the torrent you want to download [-1 to skip]: '
|
152
179
|
end
|
153
180
|
|
154
|
-
##
|
155
|
-
# Returns the date from which to check for shows
|
156
|
-
# Or nil if the date is today
|
157
|
-
def check_date(offset)
|
158
|
-
last = @config.content[:date]
|
159
|
-
last -= offset
|
160
|
-
last if last != Date.today
|
161
|
-
end
|
162
|
-
|
163
181
|
##
|
164
182
|
# Given a list of shows and episodes:
|
165
183
|
#
|
@@ -181,24 +199,16 @@ module DownloadTV
|
|
181
199
|
end
|
182
200
|
|
183
201
|
##
|
184
|
-
#
|
185
|
-
#
|
186
|
-
#
|
202
|
+
# Removes links whose names don't match the user filters
|
203
|
+
# Runs until no filters are left to be applied or applying
|
204
|
+
# a filter would leave no results
|
187
205
|
def filter_shows(links)
|
188
|
-
|
189
|
-
|
190
|
-
# Stop if the filter removes every release
|
191
|
-
break if new_links.empty?
|
192
|
-
|
193
|
-
links = new_links
|
194
|
-
end
|
195
|
-
|
196
|
-
links
|
206
|
+
f = Filterer.new(@config.content[:filters])
|
207
|
+
f.filter(links)
|
197
208
|
end
|
198
209
|
|
199
210
|
##
|
200
211
|
# Spawns a silent process to download a given magnet link
|
201
|
-
# Uses xdg-open (not portable)
|
202
212
|
def download(link)
|
203
213
|
@cmd ||= detect_os
|
204
214
|
|
@@ -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
|
@@ -64,17 +64,20 @@ module DownloadTV
|
|
64
64
|
@agent
|
65
65
|
end
|
66
66
|
|
67
|
-
def
|
68
|
-
return [] if last.nil?
|
69
|
-
|
67
|
+
def get_shows_since(last)
|
70
68
|
page = @agent.get 'https://www.myepisodes.com/ajax/service.php?mode=view_privatelist'
|
71
69
|
shows = page.parser.css('tr.past')
|
72
|
-
|
73
70
|
shows = filter_newer_shows(shows, last)
|
71
|
+
build_show_strings(shows)
|
72
|
+
end
|
74
73
|
|
74
|
+
def today_shows
|
75
|
+
page = @agent.get 'https://www.myepisodes.com/ajax/service.php?mode=view_privatelist'
|
76
|
+
shows = page.parser.css('tr.today')
|
75
77
|
build_show_strings(shows)
|
76
78
|
end
|
77
79
|
|
80
|
+
# Only keep the shows that have aired since the given date
|
78
81
|
def filter_newer_shows(shows, date)
|
79
82
|
shows.select do |i|
|
80
83
|
airdate = i.css('td.date')[0].text
|
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,14 +40,14 @@ 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
47
|
describe 'the check_date method' do
|
48
48
|
it 'exits the script when up to date' do
|
49
49
|
dl = DownloadTV::Downloader.new(date: Date.today, path: config_path)
|
50
|
-
dl.check_date(0).must_be_nil
|
50
|
+
_(dl.check_date(0)).must_be_nil
|
51
51
|
end
|
52
52
|
|
53
53
|
it 'uses the offset to adjust the date' do
|
@@ -56,46 +56,35 @@ describe DownloadTV::Downloader do
|
|
56
56
|
|
57
57
|
date = dl.check_date(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, 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, 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.2
|
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-20 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
|