download_tv 2.1.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +6 -2
- data/bin/tv +9 -9
- data/download_tv.gemspec +2 -3
- data/lib/download_tv/configuration.rb +16 -7
- data/lib/download_tv/downloader.rb +89 -28
- data/lib/download_tv/grabbers/addic7ed.rb +1 -1
- data/lib/download_tv/grabbers/kat.rb +1 -1
- data/lib/download_tv/linkgrabber.rb +1 -1
- data/lib/download_tv/myepisodes.rb +1 -1
- data/lib/download_tv/torrent.rb +10 -56
- data/lib/download_tv/version.rb +1 -1
- data/test/config_test.rb +52 -0
- data/test/downloader_test.rb +111 -33
- data/test/grabbers_test.rb +1 -8
- data/test/test_helper.rb +4 -0
- data/test/torrent_test.rb +0 -2
- metadata +7 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 358854a4a50e549541b64dfa8e3279998a3c7a12
|
|
4
|
+
data.tar.gz: 643f9a41e0c91866228469a26371c35cfda7be82
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f5ae32db31ab5bd149b5c8d1165142b61a7a2df3b41d91c96e9cbbe31f8846333de4b9a5d01b6b34f7f162c68623d0382b7e94dd55e6e1a20a239fa486bbac4d
|
|
7
|
+
data.tar.gz: 8b6423716c1bc322aed18bb778160cc5bd1a618a31cfcd3a984f788959c76009f7db80d78c44bf548a25646149f493476a2f16bdbf5e23410356902812457989
|
data/README.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://travis-ci.org/guille/download_tv)
|
|
4
4
|
[](https://badge.fury.io/rb/download_tv)
|
|
5
|
+
[](https://codeclimate.com/github/guille/download_tv)
|
|
5
6
|
|
|
6
7
|
download_tv is a Ruby command line application that automatically downloads the new episodes from the shows you follow. It grabs the list of shows from your MyEpisodes account.
|
|
7
8
|
|
|
@@ -21,10 +22,13 @@ Specific options:
|
|
|
21
22
|
-f, --file PATH Download shows from a file
|
|
22
23
|
-d, --download SHOW Downloads given show
|
|
23
24
|
-c, --configure Configures defaults
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
--show-config Show current configuration values
|
|
26
|
+
--dry-run Don't write to the date file
|
|
26
27
|
-a, --[no-]auto Automatically find links
|
|
27
28
|
-s, --[no-]subtitles Download subtitles
|
|
29
|
+
-g, --grabber GRABBER Use given grabber as first option
|
|
30
|
+
--show-grabbers List available grabbers
|
|
31
|
+
-v Print version
|
|
28
32
|
-h, --help Show this message
|
|
29
33
|
|
|
30
34
|
```
|
data/bin/tv
CHANGED
|
@@ -5,10 +5,9 @@ require 'download_tv'
|
|
|
5
5
|
|
|
6
6
|
options = {}
|
|
7
7
|
options[:offset] = 0
|
|
8
|
-
options[:auto] = true
|
|
9
|
-
options[:subs] = true
|
|
10
8
|
options[:dry] = false
|
|
11
9
|
options[:cmd] = "run"
|
|
10
|
+
config = {}
|
|
12
11
|
|
|
13
12
|
opt_parser = OptionParser.new do |opts|
|
|
14
13
|
opts.banner = "Usage: tv [options]"
|
|
@@ -43,15 +42,15 @@ opt_parser = OptionParser.new do |opts|
|
|
|
43
42
|
end
|
|
44
43
|
|
|
45
44
|
opts.on("-a", "--[no-]auto", "Automatically find links") do |n|
|
|
46
|
-
|
|
45
|
+
config[:auto] = n
|
|
47
46
|
end
|
|
48
47
|
|
|
49
48
|
opts.on("-s", "--[no-]subtitles", "Download subtitles") do |n|
|
|
50
|
-
|
|
49
|
+
config[:subs] = n
|
|
51
50
|
end
|
|
52
51
|
|
|
53
52
|
opts.on("-g", "--grabber GRABBER", "Use given grabber as first option") do |g|
|
|
54
|
-
|
|
53
|
+
config[:grabber] = g
|
|
55
54
|
end
|
|
56
55
|
|
|
57
56
|
opts.on("--show-grabbers", "List available grabbers") do
|
|
@@ -73,19 +72,20 @@ end
|
|
|
73
72
|
opt_parser.parse!(ARGV)
|
|
74
73
|
|
|
75
74
|
begin
|
|
76
|
-
dl = DownloadTV::Downloader.new(options[:offset], options[:auto], options[:subs], options[:grabber])
|
|
77
75
|
case options[:cmd]
|
|
78
76
|
when "run"
|
|
77
|
+
dl = DownloadTV::Downloader.new(options[:offset], config)
|
|
79
78
|
dl.run(options[:dry])
|
|
80
79
|
when "dl"
|
|
80
|
+
dl = DownloadTV::Downloader.new(options[:offset], config)
|
|
81
81
|
dl.download_single_show(options[:arg])
|
|
82
82
|
when "file"
|
|
83
|
+
dl = DownloadTV::Downloader.new(options[:offset], config)
|
|
83
84
|
dl.download_from_file(options[:arg])
|
|
84
85
|
when "config"
|
|
85
|
-
DownloadTV::Configuration.new true
|
|
86
|
+
DownloadTV::Configuration.new(config, true)
|
|
86
87
|
when "showconfig"
|
|
87
|
-
DownloadTV::Configuration.new.print_config
|
|
88
|
-
|
|
88
|
+
DownloadTV::Configuration.new(config).print_config
|
|
89
89
|
end
|
|
90
90
|
rescue Interrupt
|
|
91
91
|
puts "Interrupt signal detected. Exiting..."
|
data/download_tv.gemspec
CHANGED
|
@@ -9,17 +9,16 @@ Gem::Specification.new do |s|
|
|
|
9
9
|
s.authors = ["guille"]
|
|
10
10
|
s.email = ["guillerg96@gmail.com"]
|
|
11
11
|
|
|
12
|
-
s.summary = %q{DownloadTV
|
|
12
|
+
s.summary = %q{DownloadTV is a tool that allows the user to find magnet links for tv show episodes. It accepts shows as arguments, from a file or it can integrate with your MyEpisodes account.}
|
|
13
13
|
s.homepage = "https://github.com/guille/download_tv"
|
|
14
14
|
|
|
15
15
|
s.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
16
16
|
f.match(%r{^(test)/})
|
|
17
17
|
end
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
s.test_files = `git ls-files -- test/*`.split($/)
|
|
20
20
|
s.require_paths = ["lib"]
|
|
21
21
|
|
|
22
|
-
# s.bindir = "exe"
|
|
23
22
|
s.executables = ["tv"]
|
|
24
23
|
s.default_executable = 'tv'
|
|
25
24
|
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
module DownloadTV
|
|
2
2
|
class Configuration
|
|
3
|
-
attr_reader :content
|
|
3
|
+
attr_reader :content, :config_path
|
|
4
4
|
|
|
5
|
-
def initialize(force_change=false)
|
|
5
|
+
def initialize(content={}, force_change=false)
|
|
6
6
|
Dir.chdir(__dir__)
|
|
7
|
+
|
|
8
|
+
@config_path = content[:path] || "config"
|
|
7
9
|
|
|
8
|
-
if File.
|
|
9
|
-
@content = File.open(
|
|
10
|
+
if File.exist? @config_path
|
|
11
|
+
@content = File.open(@config_path, "rb") { |f| Marshal.load(f) }
|
|
12
|
+
@content.merge!(content) unless content.empty?
|
|
10
13
|
change_configuration if force_change
|
|
11
14
|
else
|
|
12
|
-
@content =
|
|
15
|
+
@content = content
|
|
13
16
|
change_configuration
|
|
14
17
|
end
|
|
15
18
|
end
|
|
@@ -32,15 +35,21 @@ module DownloadTV
|
|
|
32
35
|
puts "Enter a comma-separated list of shows to ignore: "
|
|
33
36
|
end
|
|
34
37
|
|
|
35
|
-
@content[:ignored] = STDIN.gets.chomp.split(",").map(&:strip)
|
|
38
|
+
@content[:ignored] = STDIN.gets.chomp.split(",").map(&:strip).map(&:downcase)
|
|
36
39
|
STDOUT.flush
|
|
37
40
|
|
|
41
|
+
# When modifying existing config, keeps previous values
|
|
42
|
+
# When creating new one, sets defaults
|
|
43
|
+
@content[:auto] ||= true
|
|
44
|
+
@content[:subs] ||= true
|
|
45
|
+
@content[:grabber] ||= "TorrentAPI"
|
|
46
|
+
|
|
38
47
|
serialize()
|
|
39
48
|
end
|
|
40
49
|
|
|
41
50
|
|
|
42
51
|
def serialize
|
|
43
|
-
File.open(
|
|
52
|
+
File.open(@config_path, "wb") { |f| Marshal.dump(@content, f) }
|
|
44
53
|
end
|
|
45
54
|
|
|
46
55
|
|
|
@@ -2,43 +2,48 @@ module DownloadTV
|
|
|
2
2
|
|
|
3
3
|
class Downloader
|
|
4
4
|
|
|
5
|
-
attr_reader :offset, :
|
|
6
|
-
|
|
5
|
+
attr_reader :offset, :config
|
|
6
|
+
|
|
7
|
+
def initialize(offset=0, config={})
|
|
8
|
+
# Change to installation directory
|
|
9
|
+
Dir.chdir(__dir__)
|
|
7
10
|
|
|
8
|
-
def initialize(offset, auto, subs, grabber, config={})
|
|
9
11
|
@offset = offset.abs
|
|
10
|
-
@
|
|
11
|
-
|
|
12
|
-
@
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
@config = Configuration.new(config).content # Load configuration
|
|
13
|
+
|
|
14
|
+
@filters = [
|
|
15
|
+
->(n){ n.include?("2160p") },
|
|
16
|
+
->(n){ n.include?("1080p") },
|
|
17
|
+
->(n){ n.include?("720p") },
|
|
18
|
+
->(n){ n.include?("WEB") },
|
|
19
|
+
->(n){ !n.include?("PROPER") && !n.include?("REPACK") },
|
|
20
|
+
]
|
|
18
21
|
|
|
19
22
|
Thread.abort_on_exception = true
|
|
20
23
|
end
|
|
21
24
|
|
|
22
25
|
def download_single_show(show)
|
|
23
|
-
t = Torrent.new(@grabber)
|
|
24
|
-
download(
|
|
26
|
+
t = Torrent.new(@config[:grabber])
|
|
27
|
+
download(get_link(t, show))
|
|
25
28
|
end
|
|
26
29
|
|
|
27
30
|
|
|
31
|
+
##
|
|
32
|
+
# Given a file containing a list of episodes (one per line), it tries to find download links for each
|
|
28
33
|
def download_from_file(filename)
|
|
34
|
+
if !File.exist? filename
|
|
35
|
+
puts "Error: #{filename} not found"
|
|
36
|
+
exit 1
|
|
37
|
+
end
|
|
29
38
|
filename = File.realpath(filename)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
File.readlines(filename).each { |show| download(t.get_link(show, @auto)) }
|
|
33
|
-
|
|
39
|
+
t = Torrent.new(@config[:grabber])
|
|
40
|
+
File.readlines(filename).each { |show| download(get_link(t, show)) }
|
|
34
41
|
end
|
|
35
42
|
|
|
36
43
|
##
|
|
37
|
-
#
|
|
44
|
+
# Finds download links for all new episodes aired since the last run of the program
|
|
45
|
+
# It connects to MyEpisodes in order to find which shows to track and which new episodes aired.
|
|
38
46
|
def run(dont_write_to_date_file)
|
|
39
|
-
# Change to installation directory
|
|
40
|
-
Dir.chdir(__dir__)
|
|
41
|
-
|
|
42
47
|
date = check_date
|
|
43
48
|
|
|
44
49
|
myepisodes = MyEpisodes.new(@config[:myepisodes_user], @config[:cookie])
|
|
@@ -50,14 +55,14 @@ module DownloadTV
|
|
|
50
55
|
puts "Nothing to download"
|
|
51
56
|
|
|
52
57
|
else
|
|
53
|
-
t = Torrent.new(@grabber)
|
|
58
|
+
t = Torrent.new(@config[:grabber])
|
|
54
59
|
to_download = fix_names(shows)
|
|
55
60
|
|
|
56
61
|
queue = Queue.new
|
|
57
62
|
|
|
58
63
|
# Adds a link (or empty string to the queue)
|
|
59
64
|
link_t = Thread.new do
|
|
60
|
-
to_download.each { |show| queue <<
|
|
65
|
+
to_download.each { |show| queue << get_link(t, show) }
|
|
61
66
|
end
|
|
62
67
|
|
|
63
68
|
# Downloads the links as they are added
|
|
@@ -70,7 +75,7 @@ module DownloadTV
|
|
|
70
75
|
end
|
|
71
76
|
|
|
72
77
|
# Downloading the subtitles
|
|
73
|
-
# subs_t = @subs and Thread.new do
|
|
78
|
+
# subs_t = @config[:subs] and Thread.new do
|
|
74
79
|
# to_download.each { |show| @s.get_subs(show) }
|
|
75
80
|
# end
|
|
76
81
|
|
|
@@ -84,7 +89,41 @@ module DownloadTV
|
|
|
84
89
|
File.write("date", Date.today) unless dont_write_to_date_file
|
|
85
90
|
|
|
86
91
|
rescue InvalidLoginError
|
|
87
|
-
|
|
92
|
+
warn "Wrong username/password combination"
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
##
|
|
96
|
+
# Uses a Torrent object to obtain links to the given tv show
|
|
97
|
+
# When :auto is true it will try to find the best match based on a set of filters
|
|
98
|
+
# When it's false it will prompt the user to select the preferred result
|
|
99
|
+
# Returns either a magnet link or an emptry string
|
|
100
|
+
def get_link(t, show)
|
|
101
|
+
links = t.get_links(show)
|
|
102
|
+
|
|
103
|
+
return "" if links.empty?
|
|
104
|
+
|
|
105
|
+
if @config[:auto]
|
|
106
|
+
links = filter_shows(links)
|
|
107
|
+
links.first[1]
|
|
108
|
+
|
|
109
|
+
else
|
|
110
|
+
puts "Collecting links for #{show}"
|
|
111
|
+
links.each_with_index { |data, i| puts "#{i}\t\t#{data[0]}" }
|
|
112
|
+
|
|
113
|
+
puts
|
|
114
|
+
print "Select the torrent you want to download [-1 to skip]: "
|
|
115
|
+
|
|
116
|
+
i = $stdin.gets.chomp.to_i
|
|
117
|
+
|
|
118
|
+
while i >= links.size || i < -1
|
|
119
|
+
puts "Index out of bounds. Try again [-1 to skip]: "
|
|
120
|
+
i = $stdin.gets.chomp.to_i
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Use -1 to skip the download
|
|
124
|
+
i == -1 ? "" : links[i][1]
|
|
125
|
+
end
|
|
126
|
+
|
|
88
127
|
end
|
|
89
128
|
|
|
90
129
|
|
|
@@ -105,18 +144,40 @@ module DownloadTV
|
|
|
105
144
|
end
|
|
106
145
|
|
|
107
146
|
|
|
147
|
+
##
|
|
148
|
+
# Given a list of shows and episodes:
|
|
149
|
+
#
|
|
150
|
+
# * Removes ignored shows
|
|
151
|
+
# * Removes apostrophes, colons and parens
|
|
108
152
|
def fix_names(shows)
|
|
109
153
|
# Ignored shows
|
|
110
154
|
s = shows.reject do |i|
|
|
111
155
|
# Remove season+episode
|
|
112
|
-
@config[:ignored].include?(i.split(" ")[0..-2].join(" "))
|
|
156
|
+
@config[:ignored].include?(i.split(" ")[0..-2].join(" ").downcase)
|
|
113
157
|
end
|
|
114
158
|
|
|
115
|
-
|
|
116
|
-
s.map { |t| t.gsub(/ \(.+\)|[':]/, "") }
|
|
159
|
+
s.map { |i| i.gsub(/ \(.+\)|[':]/, "") }
|
|
117
160
|
end
|
|
118
161
|
|
|
162
|
+
##
|
|
163
|
+
# Iteratively applies filters until they've all been applied or applying the next filter would result in no results
|
|
164
|
+
# These filters are defined at @filters
|
|
165
|
+
def filter_shows(links)
|
|
166
|
+
@filters.each do |f| # Apply each filter
|
|
167
|
+
new_links = links.reject { |name, _link| f.(name) }
|
|
168
|
+
# Stop if the filter removes every release
|
|
169
|
+
break if new_links.size == 0
|
|
170
|
+
|
|
171
|
+
links = new_links
|
|
172
|
+
end
|
|
119
173
|
|
|
174
|
+
links
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
##
|
|
179
|
+
# Spawns a silent process to download a given magnet link
|
|
180
|
+
# Uses xdg-open (not portable)
|
|
120
181
|
def download(link)
|
|
121
182
|
exec = "xdg-open \"#{link}\""
|
|
122
183
|
|
data/lib/download_tv/torrent.rb
CHANGED
|
@@ -17,14 +17,6 @@ module DownloadTV
|
|
|
17
17
|
# Silently ignores bad names
|
|
18
18
|
@g_names.rotate! @g_names.find_index(default_grabber).to_i
|
|
19
19
|
|
|
20
|
-
@filters = [
|
|
21
|
-
->(n){n.include?("2160")},
|
|
22
|
-
->(n){n.include?("1080")},
|
|
23
|
-
->(n){n.include?("720")},
|
|
24
|
-
->(n){n.include?("WEB")},
|
|
25
|
-
->(n){!n.include?("PROPER") || !n.include?("REPACK")},
|
|
26
|
-
]
|
|
27
|
-
|
|
28
20
|
change_grabbers
|
|
29
21
|
|
|
30
22
|
end
|
|
@@ -46,7 +38,7 @@ module DownloadTV
|
|
|
46
38
|
|
|
47
39
|
rescue Mechanize::ResponseCodeError, Net::HTTP::Persistent::Error
|
|
48
40
|
|
|
49
|
-
|
|
41
|
+
warn "Problem accessing #{newt.class.name}"
|
|
50
42
|
# We won't be using this grabber
|
|
51
43
|
@n_grabbers = @n_grabbers-1
|
|
52
44
|
@tries = @tries - 1
|
|
@@ -54,48 +46,19 @@ module DownloadTV
|
|
|
54
46
|
change_grabbers
|
|
55
47
|
|
|
56
48
|
rescue SocketError, Errno::ECONNRESET, Net::OpenTimeout
|
|
57
|
-
|
|
58
|
-
exit
|
|
49
|
+
warn "Connection error."
|
|
50
|
+
exit 1
|
|
59
51
|
|
|
60
52
|
end
|
|
61
53
|
|
|
62
54
|
|
|
63
|
-
def
|
|
55
|
+
def get_links(show)
|
|
64
56
|
links = @g_instances.first.get_links(show)
|
|
65
57
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
puts "#{i}\t\t#{data[0]}"
|
|
69
|
-
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
puts
|
|
73
|
-
print "Select the torrent you want to download [-1 to skip]: "
|
|
74
|
-
|
|
75
|
-
i = $stdin.gets.chomp.to_i
|
|
76
|
-
|
|
77
|
-
while i >= links.size || i < -1
|
|
78
|
-
puts "Index out of bounds. Try again: "
|
|
79
|
-
i = $stdin.gets.chomp.to_i
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
# Reset the counter
|
|
83
|
-
@tries = @n_grabbers - 1
|
|
84
|
-
|
|
85
|
-
# Use -1 to skip the download
|
|
86
|
-
i == -1 ? "" : links[i][1]
|
|
58
|
+
# Reset the counter
|
|
59
|
+
@tries = @n_grabbers - 1
|
|
87
60
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
links = filter_shows(links)
|
|
91
|
-
|
|
92
|
-
# Reset the counter
|
|
93
|
-
@tries = @n_grabbers - 1
|
|
94
|
-
|
|
95
|
-
# Get the first result left
|
|
96
|
-
links[0][1]
|
|
97
|
-
|
|
98
|
-
end
|
|
61
|
+
links
|
|
99
62
|
|
|
100
63
|
rescue NoTorrentsError
|
|
101
64
|
puts "No torrents found for #{show} using #{@g_instances.first.class.name}"
|
|
@@ -108,23 +71,14 @@ module DownloadTV
|
|
|
108
71
|
|
|
109
72
|
else # Reset the counter
|
|
110
73
|
@tries = @n_grabbers - 1
|
|
111
|
-
#
|
|
112
|
-
return
|
|
74
|
+
# Handle show not found here!!
|
|
75
|
+
return []
|
|
113
76
|
|
|
114
77
|
end
|
|
115
78
|
|
|
116
79
|
end
|
|
117
80
|
|
|
118
|
-
|
|
119
|
-
@filters.each do |f| # Apply each filter
|
|
120
|
-
new_links = links.reject {|name, link| f.(name)}
|
|
121
|
-
# Stop if the filter removes every release
|
|
122
|
-
break if new_links.size == 0
|
|
123
|
-
|
|
124
|
-
links = new_links
|
|
125
|
-
end
|
|
126
|
-
links
|
|
127
|
-
end
|
|
81
|
+
|
|
128
82
|
end
|
|
129
83
|
|
|
130
84
|
end
|
data/lib/download_tv/version.rb
CHANGED
data/test/config_test.rb
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
|
|
3
|
+
describe DownloadTV::Configuration do
|
|
4
|
+
config_path = File.realdirpath("#{__dir__}/test_config")
|
|
5
|
+
|
|
6
|
+
before do
|
|
7
|
+
Dir.chdir(__dir__)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
after do
|
|
11
|
+
File.delete(config_path) if File.exist?(config_path)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
describe "when the file already exists" do
|
|
15
|
+
it "will load the existing configuration (blank)" do
|
|
16
|
+
create_dummy_config(config_path)
|
|
17
|
+
|
|
18
|
+
c = DownloadTV::Configuration.new(path: config_path)
|
|
19
|
+
c.content.must_equal ({path: config_path})
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it "will load the existing configuration (existing)" do
|
|
23
|
+
create_dummy_config(config_path, auto: false, myepisodes_user: "dummy")
|
|
24
|
+
|
|
25
|
+
c = DownloadTV::Configuration.new(path: config_path)
|
|
26
|
+
c.content.must_equal ({path: config_path, auto: false, myepisodes_user: "dummy"})
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "will get overwritten by the parameters given" do
|
|
30
|
+
create_dummy_config(config_path, myepisodes_user: "dummy")
|
|
31
|
+
|
|
32
|
+
c = DownloadTV::Configuration.new(path: config_path, myepisodes_user: "fake")
|
|
33
|
+
c.content.must_equal ({path: config_path, myepisodes_user: "fake"})
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# describe "when the file doesn't exist" do
|
|
38
|
+
# it "will create a new one" do
|
|
39
|
+
# # Send stuff to stdin
|
|
40
|
+
# flunk
|
|
41
|
+
# DownloadTV::Configuration.new(path: config_path)
|
|
42
|
+
# File.exist?(config_path).must_equal true
|
|
43
|
+
# end
|
|
44
|
+
|
|
45
|
+
# it "will trigger a configuration change when asked to" do
|
|
46
|
+
# DownloadTV::Configuration.new(path: config_path, true)
|
|
47
|
+
# end
|
|
48
|
+
# end
|
|
49
|
+
|
|
50
|
+
# test [:ignored] gets turned to lowercase
|
|
51
|
+
|
|
52
|
+
end
|
data/test/downloader_test.rb
CHANGED
|
@@ -1,75 +1,67 @@
|
|
|
1
1
|
require "test_helper"
|
|
2
2
|
|
|
3
3
|
describe DownloadTV::Downloader do
|
|
4
|
+
config_path = File.realdirpath("#{__dir__}/test_config")
|
|
5
|
+
|
|
4
6
|
before do
|
|
5
|
-
Dir.chdir(
|
|
7
|
+
Dir.chdir(__dir__)
|
|
6
8
|
File.delete("date") if File.exist?("date")
|
|
9
|
+
create_dummy_config(config_path) unless File.exist?(config_path)
|
|
7
10
|
end
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
->{ DownloadTV::Downloader.new(0, true) }.must_raise ArgumentError
|
|
13
|
-
->{ DownloadTV::Downloader.new(0, true, true) }.must_raise ArgumentError
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it "can receive an optional configuration hash" do
|
|
17
|
-
DownloadTV::Downloader.new(0, true, true, nil, {:hi => 1}).config.must_equal ({:hi => 1})
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it "should receive an integer for the offset" do
|
|
21
|
-
->{ DownloadTV::Downloader.new("foo", true, true, nil, {1=>1}) }.must_raise NoMethodError
|
|
22
|
-
end
|
|
12
|
+
after do
|
|
13
|
+
File.delete(config_path) if File.exist?(config_path)
|
|
14
|
+
end
|
|
23
15
|
|
|
16
|
+
describe "when creating the object" do
|
|
24
17
|
it "should store the first argument as @offset" do
|
|
25
|
-
DownloadTV::Downloader.new(3,
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
it "should store the second argument as @auto" do
|
|
29
|
-
DownloadTV::Downloader.new(3, true, true, nil, {1=>1}).auto.must_equal true
|
|
30
|
-
DownloadTV::Downloader.new(3, false, true, nil, {1=>1}).auto.must_equal false
|
|
18
|
+
DownloadTV::Downloader.new(3, path: config_path).offset.must_equal 3
|
|
19
|
+
DownloadTV::Downloader.new(-3, path: config_path).offset.must_equal 3
|
|
31
20
|
end
|
|
32
21
|
|
|
33
|
-
it "should
|
|
34
|
-
DownloadTV::Downloader.new(
|
|
35
|
-
DownloadTV::Downloader.new(3, true, false, nil, {1=>1}).subs.must_equal false
|
|
22
|
+
it "should receive an integer for the offset" do
|
|
23
|
+
->{ DownloadTV::Downloader.new("foo") }.must_raise NoMethodError
|
|
36
24
|
end
|
|
37
25
|
|
|
38
|
-
it "
|
|
39
|
-
DownloadTV::Downloader.new(
|
|
40
|
-
|
|
26
|
+
it "can receive an optional configuration hash" do
|
|
27
|
+
dl = DownloadTV::Downloader.new(0, auto: true, grabber: "KAT", path: config_path)
|
|
28
|
+
dl.config[:auto].must_equal true
|
|
29
|
+
dl.config[:grabber].must_equal "KAT"
|
|
41
30
|
end
|
|
42
31
|
|
|
43
32
|
end
|
|
44
33
|
|
|
45
|
-
describe "the fix_names
|
|
46
|
-
config = {:ignored => ["Ignored"]}
|
|
47
|
-
dl = DownloadTV::Downloader.new(0, true, true, nil, config)
|
|
48
|
-
|
|
34
|
+
describe "the fix_names method" do
|
|
49
35
|
it "should remove apostrophes, colons and parens" do
|
|
50
36
|
shows = ["Mr. Foo S01E02", "Bar (UK) S00E22", "Let's S05E03", "Baz: The Story S05E22"]
|
|
51
37
|
result = ["Mr. Foo S01E02", "Bar S00E22", "Lets S05E03", "Baz The Story S05E22"]
|
|
38
|
+
|
|
39
|
+
dl = DownloadTV::Downloader.new(0, ignored: [], path: config_path)
|
|
52
40
|
dl.fix_names(shows).must_equal result
|
|
53
41
|
end
|
|
54
42
|
|
|
55
43
|
it "should remove ignored shows" do
|
|
56
|
-
|
|
57
44
|
shows = ["Mr. Foo S01E02", "Bar (UK) S00E22", "Ignored S20E22", "Let's S05E03"]
|
|
58
45
|
result = ["Mr. Foo S01E02", "Bar S00E22", "Lets S05E03"]
|
|
46
|
+
|
|
47
|
+
dl = DownloadTV::Downloader.new(0, ignored: ["Ignored"], path: config_path)
|
|
59
48
|
dl.fix_names(shows).must_equal result
|
|
60
49
|
end
|
|
61
50
|
end
|
|
62
51
|
|
|
63
52
|
|
|
64
53
|
describe "the date file" do
|
|
65
|
-
dl = DownloadTV::Downloader.new(0, true, true, nil, {1=>1})
|
|
66
54
|
|
|
67
55
|
it "should be created if it doesn't exist" do
|
|
56
|
+
dl = DownloadTV::Downloader.new(0, path: config_path)
|
|
57
|
+
Dir.chdir(__dir__) # Use date file in test directory
|
|
68
58
|
dl.check_date
|
|
69
59
|
File.exist?("date").must_equal true
|
|
70
60
|
end
|
|
71
61
|
|
|
72
62
|
it "contains a date after running the method" do
|
|
63
|
+
dl = DownloadTV::Downloader.new(0, path: config_path)
|
|
64
|
+
Dir.chdir(__dir__)
|
|
73
65
|
date = dl.check_date
|
|
74
66
|
date.must_equal (Date.today-1)
|
|
75
67
|
Date.parse(File.read("date")).must_equal Date.today-1
|
|
@@ -78,13 +70,99 @@ describe DownloadTV::Downloader do
|
|
|
78
70
|
it "exits the script when up to date" do
|
|
79
71
|
File.write("date", Date.today)
|
|
80
72
|
begin
|
|
73
|
+
dl = DownloadTV::Downloader.new(0, path: config_path)
|
|
74
|
+
Dir.chdir(__dir__)
|
|
81
75
|
dl.check_date
|
|
82
76
|
flunk
|
|
83
77
|
rescue SystemExit
|
|
84
78
|
|
|
85
79
|
end
|
|
86
80
|
end
|
|
81
|
+
|
|
82
|
+
it "uses the offset to adjust the date" do
|
|
83
|
+
File.write("date", Date.today)
|
|
84
|
+
|
|
85
|
+
# Would exit with offset 0
|
|
86
|
+
dl = DownloadTV::Downloader.new(1, path: config_path)
|
|
87
|
+
|
|
88
|
+
Dir.chdir(__dir__)
|
|
89
|
+
date = dl.check_date
|
|
90
|
+
|
|
91
|
+
date.must_equal (Date.today-1)
|
|
92
|
+
Date.parse(File.read("date")).must_equal Date.today
|
|
93
|
+
end
|
|
87
94
|
|
|
88
95
|
end
|
|
89
96
|
|
|
97
|
+
describe "the filter_shows method" do
|
|
98
|
+
it "removes names with 2160p in them" do
|
|
99
|
+
dl = DownloadTV::Downloader.new(0, path: config_path)
|
|
100
|
+
links = [["Link 1", ""], ["Link 2 2160p", ""], ["Link 3", ""]]
|
|
101
|
+
res = [["Link 1", ""], ["Link 3", ""]]
|
|
102
|
+
dl.filter_shows(links).must_equal res
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "removes names with 1080p in them" do
|
|
106
|
+
dl = DownloadTV::Downloader.new(0, path: config_path)
|
|
107
|
+
links = [["Link.1080p", ""], ["Link 2 2160p", ""], ["Link 3", ""]]
|
|
108
|
+
res = [["Link 3", ""]]
|
|
109
|
+
dl.filter_shows(links).must_equal res
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it "removes names with 720p in them" do
|
|
113
|
+
dl = DownloadTV::Downloader.new(0, path: config_path)
|
|
114
|
+
links = [["Link 1", ""], ["Link 2 720p", ""], ["Link.720p.rip", ""]]
|
|
115
|
+
res = [["Link 1", ""]]
|
|
116
|
+
dl.filter_shows(links).must_equal res
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "removes names with WEB in them" do
|
|
120
|
+
dl = DownloadTV::Downloader.new(0, path: config_path)
|
|
121
|
+
links = [["Link 1 WEBRIP", ""], ["Link 2 rip", ""], ["Link.720p.rip", ""]]
|
|
122
|
+
res = [["Link 2 rip", ""]]
|
|
123
|
+
dl.filter_shows(links).must_equal res
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it "removes names without PROPER or REPACK in them" do
|
|
127
|
+
dl = DownloadTV::Downloader.new(0, path: config_path)
|
|
128
|
+
links = [["Link 1", ""], ["Link 2 2160p", ""], ["Link 3", ""], ["Link 4 PROPER", ""], ["Link REPACK 5", ""]]
|
|
129
|
+
res = [["Link 4 PROPER", ""], ["Link REPACK 5", ""]]
|
|
130
|
+
dl.filter_shows(links).must_equal res
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "doesn't apply a filter if it would reject every option" do
|
|
134
|
+
dl = DownloadTV::Downloader.new(0, path: config_path)
|
|
135
|
+
links = [["Link 1 720p", ""], ["Link 2 2160p", ""], ["Link 720p 3", ""]]
|
|
136
|
+
res = [["Link 1 720p", ""], ["Link 720p 3", ""]]
|
|
137
|
+
dl.filter_shows(links).must_equal res
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
describe "the get_link method" do
|
|
142
|
+
it "returns an empty string when it can't find links" do
|
|
143
|
+
t = Minitest::Mock.new
|
|
144
|
+
show = "Example Show S01E01"
|
|
145
|
+
|
|
146
|
+
t.expect(:get_links, [], [show])
|
|
147
|
+
dl = DownloadTV::Downloader.new(0, auto: true, path: config_path)
|
|
148
|
+
dl.get_link(t, show).must_equal ""
|
|
149
|
+
t.expect(:get_links, [], [show])
|
|
150
|
+
dl = DownloadTV::Downloader.new(0, auto: false, path: config_path)
|
|
151
|
+
dl.get_link(t, show).must_equal ""
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
it "returns the first link when auto is set to true" do
|
|
157
|
+
t = Minitest::Mock.new
|
|
158
|
+
show = "Example Show S01E01"
|
|
159
|
+
|
|
160
|
+
t.expect(:get_links, [["Name 1", "Link 1"], ["Name 2", "Link 2"]], [show])
|
|
161
|
+
dl = DownloadTV::Downloader.new(0, auto: true, path: config_path)
|
|
162
|
+
dl.get_link(t, show).must_equal "Link 1"
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
90
168
|
end
|
data/test/grabbers_test.rb
CHANGED
|
@@ -7,28 +7,20 @@ describe DownloadTV::LinkGrabber do
|
|
|
7
7
|
|
|
8
8
|
instances.each do |grabber|
|
|
9
9
|
describe grabber do
|
|
10
|
-
# grabber = g#(Object.const_get "DownloadTV::#{g}").new
|
|
11
|
-
|
|
12
10
|
it "will have a url attribute on creation" do
|
|
13
|
-
# instance_eval("#{g}.new")
|
|
14
|
-
|
|
15
11
|
grabber.url.wont_be_nil
|
|
16
12
|
end
|
|
17
13
|
|
|
18
14
|
it "should get a 200 code response" do
|
|
19
|
-
# grabber = (Object.const_get g).new
|
|
20
15
|
grabber.test_connection.code.must_equal "200"
|
|
21
16
|
end
|
|
22
17
|
|
|
23
18
|
it "will raise NoTorrentsError when torrent can't be found" do
|
|
24
|
-
# grabber = (Object.const_get g).new
|
|
25
19
|
notfound = ->{ grabber.get_links("Totally Fake Show askjdgsaudas") }
|
|
26
20
|
notfound.must_raise DownloadTV::NoTorrentsError
|
|
27
|
-
|
|
28
21
|
end
|
|
29
22
|
|
|
30
23
|
it "will return an array with names and links of results when a torrent can be found" do
|
|
31
|
-
# grabber = (Object.const_get g).new
|
|
32
24
|
result = grabber.get_links("Game Of Thrones S04E01")
|
|
33
25
|
result.must_be_instance_of Array
|
|
34
26
|
result.wont_be :empty?
|
|
@@ -37,6 +29,7 @@ describe DownloadTV::LinkGrabber do
|
|
|
37
29
|
r[0].must_be_instance_of String
|
|
38
30
|
r[0].upcase.must_include "THRONES"
|
|
39
31
|
r[1].must_be_instance_of String
|
|
32
|
+
r[1].must_include "magnet:"
|
|
40
33
|
end
|
|
41
34
|
|
|
42
35
|
end
|
data/test/test_helper.rb
CHANGED
data/test/torrent_test.rb
CHANGED
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.1.
|
|
4
|
+
version: 2.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- guille
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-07-
|
|
11
|
+
date: 2017-07-31 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -136,6 +136,7 @@ files:
|
|
|
136
136
|
- lib/download_tv/subtitles.rb
|
|
137
137
|
- lib/download_tv/torrent.rb
|
|
138
138
|
- lib/download_tv/version.rb
|
|
139
|
+
- test/config_test.rb
|
|
139
140
|
- test/downloader_test.rb
|
|
140
141
|
- test/grabbers_test.rb
|
|
141
142
|
- test/test_helper.rb
|
|
@@ -162,9 +163,11 @@ rubyforge_project:
|
|
|
162
163
|
rubygems_version: 2.6.12
|
|
163
164
|
signing_key:
|
|
164
165
|
specification_version: 4
|
|
165
|
-
summary: DownloadTV
|
|
166
|
-
|
|
166
|
+
summary: DownloadTV is a tool that allows the user to find magnet links for tv show
|
|
167
|
+
episodes. It accepts shows as arguments, from a file or it can integrate with your
|
|
168
|
+
MyEpisodes account.
|
|
167
169
|
test_files:
|
|
170
|
+
- test/config_test.rb
|
|
168
171
|
- test/downloader_test.rb
|
|
169
172
|
- test/grabbers_test.rb
|
|
170
173
|
- test/test_helper.rb
|