download_tv 2.1.1 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 358854a4a50e549541b64dfa8e3279998a3c7a12
4
- data.tar.gz: 643f9a41e0c91866228469a26371c35cfda7be82
3
+ metadata.gz: 01776f973e2d3bab1f88189cbf4315fc0f33923e
4
+ data.tar.gz: bf5057e5fbda8bb6724dd69f9d3633abe2fc2f98
5
5
  SHA512:
6
- metadata.gz: f5ae32db31ab5bd149b5c8d1165142b61a7a2df3b41d91c96e9cbbe31f8846333de4b9a5d01b6b34f7f162c68623d0382b7e94dd55e6e1a20a239fa486bbac4d
7
- data.tar.gz: 8b6423716c1bc322aed18bb778160cc5bd1a618a31cfcd3a984f788959c76009f7db80d78c44bf548a25646149f493476a2f16bdbf5e23410356902812457989
6
+ metadata.gz: d6dc22d8625510cf9f1a6aac9198d6f95d6bb4953fd43e175f6ec09b3a397a3ed28239bcc20ff2dd1025cdbe83e20fbc0930febaf42a190e93758c6e1687910a
7
+ data.tar.gz: b60c1b8b52b9c74a1328afb6da8ee3011eb975d187553c5b4f947fce6c07d3c228aa45e45202be21f38f6a3d491b7e24da88980b8136052388ec78b3ba6b3a66
data/.gitignore CHANGED
@@ -1,5 +1,2 @@
1
- date
2
- config
3
- cookie
4
1
  /Gemfile.lock
5
2
  /pkg/
data/README.md CHANGED
@@ -4,7 +4,7 @@
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
 
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
+ download_tv 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.
8
8
 
9
9
  ### Installation
10
10
 
@@ -33,12 +33,20 @@ Specific options:
33
33
 
34
34
  ```
35
35
 
36
- Four actions are recognised:
36
+ ### Examples
37
37
 
38
- * By default, it fetches the list of episodes from MyEpisodes that have aired since the program was run for the last time and tries to download them. The -o flag can be used in order to re-download the episodes from previous days.
38
+ By default, it fetches the list of episodes from MyEpisodes.com that have aired since the program was run for the last time and tries to download them. 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)
39
39
 
40
- * In order to download a single episode, use the -d flag. Example: *tv -d Breaking Bad S04E01*
40
+ In order to download a single episode, use the -d flag: *tv -d Breaking Bad S04E01*
41
41
 
42
- * he -f flag can be used to download a set of episodes. This option takes a text file as an argument. Each line of the file is interpreted as a episode to download. Example: *tv -f /path/to/listofeps*
42
+ 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*
43
43
 
44
- * Finally, with -c you can edit your configuration defaults (your MyEpisodes user, whether to save the auth cookie or the shows you wish to ignore)
44
+ 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.
45
+
46
+ 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 (by default, prioritizes PROPER/REPACK releases at 480p).
47
+
48
+ With -g and --show-grabbers, the user can see what grabbers are available and choose one of these as their preferred option. By default, the application searchs for torrents in TorrentAPI, ThePirateBay, KAT and EZTV, in that order, skipping to the next when one of them is down/doesn't have a torrent for said episode.
49
+
50
+ ### License
51
+
52
+ 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/download_tv.gemspec CHANGED
@@ -30,6 +30,8 @@ Gem::Specification.new do |s|
30
30
  s.add_dependency("mechanize")
31
31
  s.add_dependency("date")
32
32
  s.add_dependency("io-console")
33
+ s.add_dependency("fileutils")
33
34
 
34
35
  s.has_rdoc = false
36
+ s.license = "MIT"
35
37
  end
@@ -3,13 +3,13 @@ module DownloadTV
3
3
  attr_reader :content, :config_path
4
4
 
5
5
  def initialize(content={}, force_change=false)
6
- Dir.chdir(__dir__)
7
-
8
- @config_path = content[:path] || "config"
6
+ FileUtils.mkdir_p(File.join(ENV["HOME"], ".config", "download_tv"))
7
+ @config_path = content[:path] || File.join(ENV["HOME"], ".config", "download_tv", "config")
9
8
 
10
9
  if File.exist? @config_path
11
- @content = File.open(@config_path, "rb") { |f| Marshal.load(f) }
10
+ load_config
12
11
  @content.merge!(content) unless content.empty?
12
+ @content[:ignored]&.map!(&:downcase)
13
13
  change_configuration if force_change
14
14
  else
15
15
  @content = content
@@ -43,14 +43,31 @@ module DownloadTV
43
43
  @content[:auto] ||= true
44
44
  @content[:subs] ||= true
45
45
  @content[:grabber] ||= "TorrentAPI"
46
+ @content[:date] ||= Date.today-1
47
+ @content[:version] = DownloadTV::VERSION
46
48
 
47
- serialize()
49
+ serialize
48
50
  end
49
51
 
50
52
 
51
53
  def serialize
52
54
  File.open(@config_path, "wb") { |f| Marshal.dump(@content, f) }
53
55
  end
56
+
57
+ def load_config
58
+ @content = File.open(@config_path, "rb") { |f| Marshal.load(f) }
59
+ if !@content[:version] || breaking_changes?(@content[:version])
60
+ change_configuration
61
+ end
62
+ end
63
+
64
+ ##
65
+ # Returns true if a major or minor update has been detected
66
+ # Returns false if a patch has been detected
67
+ # Returns nil if it's the same version
68
+ def breaking_changes?(version)
69
+ DownloadTV::VERSION.split(".").zip(version.split(".")).find_index { |x, y| y > x }&.< 2
70
+ end
54
71
 
55
72
 
56
73
  def print_config
@@ -43,7 +43,7 @@ module DownloadTV
43
43
  ##
44
44
  # Finds download links for all new episodes aired since the last run of the program
45
45
  # It connects to MyEpisodes in order to find which shows to track and which new episodes aired.
46
- def run(dont_write_to_date_file)
46
+ def run(dont_update_last_run)
47
47
  date = check_date
48
48
 
49
49
  myepisodes = MyEpisodes.new(@config[:myepisodes_user], @config[:cookie])
@@ -86,7 +86,7 @@ module DownloadTV
86
86
  puts "Completed. Exiting..."
87
87
  end
88
88
 
89
- File.write("date", Date.today) unless dont_write_to_date_file
89
+ @config[:date] = Date.today unless dont_update_last_run
90
90
 
91
91
  rescue InvalidLoginError
92
92
  warn "Wrong username/password combination"
@@ -128,19 +128,13 @@ module DownloadTV
128
128
 
129
129
 
130
130
  def check_date
131
- content = File.read("date")
132
-
133
- last = Date.parse(content)
131
+ last = @config[:date]
134
132
  if last - @offset != Date.today
135
133
  last - @offset
136
134
  else
137
135
  puts "Everything up to date"
138
136
  exit
139
137
  end
140
-
141
- rescue Errno::ENOENT
142
- File.write("date", Date.today-1)
143
- retry
144
138
  end
145
139
 
146
140
 
@@ -6,6 +6,7 @@ module DownloadTV
6
6
  @agent = Mechanize.new
7
7
  @user = user
8
8
  @save_cookie = save_cookie
9
+ @cookie_path = File.join(ENV["HOME"], ".config", "download_tv", "cookie")
9
10
  end
10
11
 
11
12
  def login
@@ -35,8 +36,8 @@ module DownloadTV
35
36
  end
36
37
 
37
38
  def load_cookie
38
- if File.exist? "cookie"
39
- @agent.cookie_jar.load "cookie"
39
+ if File.exist? @cookie_path
40
+ @agent.cookie_jar.load @cookie_path
40
41
  page = @agent.get "https://www.myepisodes.com/login.php"
41
42
  if page.links[1].text == "Register"
42
43
  puts "The cookie is invalid/has expired."
@@ -51,7 +52,7 @@ module DownloadTV
51
52
  end
52
53
 
53
54
  def save_cookie
54
- @agent.cookie_jar.save("cookie", session: true)
55
+ @agent.cookie_jar.save(@cookie_path, session: true)
55
56
  @agent
56
57
 
57
58
  end
@@ -1,3 +1,3 @@
1
1
  module DownloadTV
2
- VERSION = "2.1.1"
2
+ VERSION = "2.2.0"
3
3
  end
data/test/config_test.rb CHANGED
@@ -16,37 +16,157 @@ describe DownloadTV::Configuration do
16
16
  create_dummy_config(config_path)
17
17
 
18
18
  c = DownloadTV::Configuration.new(path: config_path)
19
- c.content.must_equal ({path: config_path})
19
+ c.content.must_equal ({path: config_path, version: DownloadTV::VERSION})
20
20
  end
21
21
 
22
22
  it "will load the existing configuration (existing)" do
23
23
  create_dummy_config(config_path, auto: false, myepisodes_user: "dummy")
24
24
 
25
25
  c = DownloadTV::Configuration.new(path: config_path)
26
- c.content.must_equal ({path: config_path, auto: false, myepisodes_user: "dummy"})
26
+ c.content.must_equal ({path: config_path, auto: false, myepisodes_user: "dummy", version: DownloadTV::VERSION})
27
27
  end
28
28
 
29
29
  it "will get overwritten by the parameters given" do
30
30
  create_dummy_config(config_path, myepisodes_user: "dummy")
31
31
 
32
32
  c = DownloadTV::Configuration.new(path: config_path, myepisodes_user: "fake")
33
- c.content.must_equal ({path: config_path, myepisodes_user: "fake"})
33
+ c.content.must_equal ({path: config_path, myepisodes_user: "fake", version: DownloadTV::VERSION})
34
+ end
35
+
36
+ it "will downcase ignored shows" do
37
+ create_dummy_config(config_path, ignored: ["duMMy", "String"])
38
+
39
+ c = DownloadTV::Configuration.new(path: config_path)
40
+ c.content[:ignored].must_equal ["dummy", "string"]
41
+ end
42
+ end
43
+
44
+ describe "the breaking_changes method" do
45
+ it "returns nil when both versions are equal" do
46
+ create_dummy_config(config_path)
47
+
48
+ c = DownloadTV::Configuration.new(path: config_path)
49
+ c.breaking_changes?(DownloadTV::VERSION).must_be_nil
50
+ end
51
+
52
+ it "returns true when there's been a major update" do
53
+ create_dummy_config(config_path)
54
+
55
+ split = DownloadTV::VERSION.split(".")
56
+ split[0] = (split[0].to_i+1).to_s
57
+ new_version = split.join(".")
58
+ c = DownloadTV::Configuration.new(path: config_path)
59
+ c.breaking_changes?(new_version).must_equal true
60
+ end
61
+
62
+ it "returns true when there's been a minor update" do
63
+ create_dummy_config(config_path)
64
+
65
+ split = DownloadTV::VERSION.split(".")
66
+ split[1] = (split[1].to_i+1).to_s
67
+ new_version = split.join(".")
68
+ c = DownloadTV::Configuration.new(path: config_path)
69
+ c.breaking_changes?(new_version).must_equal true
70
+ end
71
+
72
+ it "returns false when it's a small patch" do
73
+ create_dummy_config(config_path)
74
+
75
+ split = DownloadTV::VERSION.split(".")
76
+ split[2] = (split[2].to_i+1).to_s
77
+ new_version = split.join(".")
78
+ c = DownloadTV::Configuration.new(path: config_path)
79
+ c.breaking_changes?(new_version).must_equal false
80
+ end
81
+ end
82
+
83
+ describe "when the file doesn't exist" do
84
+ it "will create a new one" do
85
+ run_silently do
86
+ STDIN.stub :gets, "myepisodes\ncookie\nignored" do
87
+ DownloadTV::Configuration.new(path: config_path)
88
+ end
89
+ end
90
+
91
+ File.exist?(config_path).must_equal true
92
+ end
93
+
94
+ it "will have the right values" do
95
+ c = nil
96
+ run_silently do
97
+ STDIN.stub :gets, "anything" do
98
+ c = DownloadTV::Configuration.new(path: config_path)
99
+ end
100
+ end
101
+
102
+ c.content[:myepisodes_user].must_equal "anything"
103
+ c.content[:cookie].must_equal true
104
+ c.content[:ignored].must_equal ["anything"]
105
+ c.content[:auto].must_equal true
106
+ c.content[:subs].must_equal true
107
+ c.content[:grabber].must_equal "TorrentAPI"
108
+ c.content[:date].must_equal Date.today-1
109
+ c.content[:version].must_equal DownloadTV::VERSION
110
+
111
+ end
112
+
113
+ it "will set the cookie value to false when explicitly told so" do
114
+ c = nil
115
+ run_silently do
116
+ STDIN.stub :gets, "n" do
117
+ c = DownloadTV::Configuration.new(path: config_path)
118
+ end
119
+ end
120
+
121
+ c.content[:cookie].must_equal false
122
+ end
123
+
124
+ it "will separate the ignored values by commas" do
125
+ c = nil
126
+ run_silently do
127
+ STDIN.stub :gets, "ignored1, itsgone, ignored 2" do
128
+ c = DownloadTV::Configuration.new(path: config_path)
129
+ end
130
+ end
131
+ c.content[:ignored].must_equal ["ignored1", "itsgone", "ignored 2"]
34
132
  end
35
133
  end
36
134
 
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
135
+ describe "the serialize method" do
136
+ it "stores the configuration in a Marshal'd file" do
137
+ # Calls serialize
138
+ run_silently do
139
+ STDIN.stub :gets, "anything" do
140
+ DownloadTV::Configuration.new(path: config_path)
141
+ end
142
+ end
143
+ content = File.open(config_path, "rb") { |f| Marshal.load(f) }
44
144
 
45
- # it "will trigger a configuration change when asked to" do
46
- # DownloadTV::Configuration.new(path: config_path, true)
47
- # end
48
- # end
145
+ content[:cookie].must_equal true
146
+ content[:myepisodes_user].must_equal "anything"
147
+ content[:ignored].must_equal ["anything"]
148
+ content[:auto].must_equal true
149
+ content[:subs].must_equal true
150
+ content[:grabber].must_equal "TorrentAPI"
151
+ content[:date].must_equal Date.today-1
152
+ content[:version].must_equal DownloadTV::VERSION
153
+ end
154
+ end
155
+
156
+ describe "the constructor" do
157
+ it "will trigger a configuration change when asked to" do
158
+ create_dummy_config(config_path, auto: false)
159
+ File.exist?(config_path).must_equal true
160
+ c = nil
161
+
162
+ run_silently do
163
+ STDIN.stub :gets, "anything" do
164
+ c = DownloadTV::Configuration.new(path: config_path)
165
+ end
166
+ end
49
167
 
50
- # test [:ignored] gets turned to lowercase
168
+ c.content[:auto].must_equal false
169
+ end
170
+ end
51
171
 
52
172
  end
@@ -5,7 +5,6 @@ describe DownloadTV::Downloader do
5
5
 
6
6
  before do
7
7
  Dir.chdir(__dir__)
8
- File.delete("date") if File.exist?("date")
9
8
  create_dummy_config(config_path) unless File.exist?(config_path)
10
9
  end
11
10
 
@@ -44,35 +43,17 @@ describe DownloadTV::Downloader do
44
43
  shows = ["Mr. Foo S01E02", "Bar (UK) S00E22", "Ignored S20E22", "Let's S05E03"]
45
44
  result = ["Mr. Foo S01E02", "Bar S00E22", "Lets S05E03"]
46
45
 
47
- dl = DownloadTV::Downloader.new(0, ignored: ["Ignored"], path: config_path)
46
+ dl = DownloadTV::Downloader.new(0, ignored: ["ignored"], path: config_path)
48
47
  dl.fix_names(shows).must_equal result
49
48
  end
50
49
  end
51
50
 
52
51
 
53
- describe "the date file" do
54
-
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
58
- dl.check_date
59
- File.exist?("date").must_equal true
60
- end
61
-
62
- it "contains a date after running the method" do
63
- dl = DownloadTV::Downloader.new(0, path: config_path)
64
- Dir.chdir(__dir__)
65
- date = dl.check_date
66
- date.must_equal (Date.today-1)
67
- Date.parse(File.read("date")).must_equal Date.today-1
68
- end
69
-
52
+ describe "the check_date method" do
70
53
  it "exits the script when up to date" do
71
- File.write("date", Date.today)
72
54
  begin
73
- dl = DownloadTV::Downloader.new(0, path: config_path)
74
- Dir.chdir(__dir__)
75
- dl.check_date
55
+ dl = DownloadTV::Downloader.new(0, date: Date.today, path: config_path)
56
+ run_silently { dl.check_date }
76
57
  flunk
77
58
  rescue SystemExit
78
59
 
@@ -80,16 +61,13 @@ describe DownloadTV::Downloader do
80
61
  end
81
62
 
82
63
  it "uses the offset to adjust the date" do
83
- File.write("date", Date.today)
84
-
85
64
  # Would exit with offset 0
86
- dl = DownloadTV::Downloader.new(1, path: config_path)
65
+ dl = DownloadTV::Downloader.new(1, date: Date.today, path: config_path)
87
66
 
88
- Dir.chdir(__dir__)
89
67
  date = dl.check_date
90
68
 
91
69
  date.must_equal (Date.today-1)
92
- Date.parse(File.read("date")).must_equal Date.today
70
+ dl.config[:date].must_equal Date.today
93
71
  end
94
72
 
95
73
  end
data/test/test_helper.rb CHANGED
@@ -5,5 +5,14 @@ require "minitest/autorun"
5
5
 
6
6
 
7
7
  def create_dummy_config(in_path, config={})
8
+ config[:version] = DownloadTV::VERSION if !config[:version]
8
9
  File.open(in_path, "wb") { |f| Marshal.dump(config, f) }
10
+ end
11
+
12
+ def run_silently
13
+ previous_stdout, $stdout = $stdout, StringIO.new
14
+ yield
15
+ $stdout.string
16
+ ensure
17
+ $stdout = previous_stdout
9
18
  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.1.1
4
+ version: 2.2.0
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-31 00:00:00.000000000 Z
11
+ date: 2017-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: fileutils
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  description:
112
126
  email:
113
127
  - guillerg96@gmail.com
@@ -142,7 +156,8 @@ files:
142
156
  - test/test_helper.rb
143
157
  - test/torrent_test.rb
144
158
  homepage: https://github.com/guille/download_tv
145
- licenses: []
159
+ licenses:
160
+ - MIT
146
161
  metadata: {}
147
162
  post_install_message:
148
163
  rdoc_options: []