addic7ed 0.6.0 → 0.7.0
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/bin/addic7ed +6 -2
- data/lib/addic7ed/episode.rb +9 -9
- data/lib/addic7ed/parser.rb +7 -0
- data/lib/addic7ed/subtitle.rb +6 -2
- data/lib/addic7ed/version.rb +1 -1
- data/lib/addic7ed/video_file.rb +14 -12
- data/spec/lib/addic7ed/episode_spec.rb +8 -0
- data/spec/lib/addic7ed/subtitle_spec.rb +27 -7
- data/spec/lib/addic7ed/video_file_spec.rb +23 -12
- metadata +20 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 31b2fe4ded0361b2b026b14726c480224ab5244a
|
4
|
+
data.tar.gz: aa80369c98fa0c5d69bf69ce6aa9ea6946f76a49
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a1b988d4a1177cfda71df10c16a0948aab0119f59a68a1033cc4abe1bdb8ad30d21822593a57488546e507e49a07b6fc5f91b116f27424d2a3be70eade8ba8b9
|
7
|
+
data.tar.gz: 17f09e0086fa85b5a7fb7973ecc0d3df0d2af9dc1a11fd1b706d55e51579a84ac08ee6e7dc8c218ed82be02cc1c49cb32698b74dfd128c87997632f1990ed835
|
data/bin/addic7ed
CHANGED
@@ -21,6 +21,10 @@ OptionParser.new do |opts|
|
|
21
21
|
options[:language] = l
|
22
22
|
end
|
23
23
|
|
24
|
+
opts.on("--no-hi", "Only download subtitles without Hearing Impaired lines") do |hi|
|
25
|
+
options[:no_hi] = !hi
|
26
|
+
end
|
27
|
+
|
24
28
|
opts.on("-a", "--all-subtitles", "Display all available subtitles") do |a|
|
25
29
|
options[:all] = a
|
26
30
|
end
|
@@ -96,13 +100,13 @@ options[:filenames].each do |filename|
|
|
96
100
|
end
|
97
101
|
next if options[:all]
|
98
102
|
end
|
99
|
-
ep.best_subtitle(options[:language])
|
103
|
+
ep.best_subtitle(options[:language], options[:no_hi])
|
100
104
|
if options[:verbose]
|
101
105
|
puts ' Best subtitle:'
|
102
106
|
puts " #{ep.best_subtitle(options[:language])}"
|
103
107
|
end
|
104
108
|
unless options[:nodownload]
|
105
|
-
ep.download_best_subtitle!(options[:language])
|
109
|
+
ep.download_best_subtitle!(options[:language], options[:no_hi])
|
106
110
|
puts "New subtitle downloaded for #{filename}.\nEnjoy your show :-)".gsub(/^/, options[:verbose] ? ' ' : '') unless options[:quiet]
|
107
111
|
end
|
108
112
|
rescue Addic7ed::InvalidFilename
|
data/lib/addic7ed/episode.rb
CHANGED
@@ -23,18 +23,18 @@ module Addic7ed
|
|
23
23
|
return @subtitles[lang]
|
24
24
|
end
|
25
25
|
|
26
|
-
def best_subtitle(lang = 'fr')
|
26
|
+
def best_subtitle(lang = 'fr', no_hi = false)
|
27
27
|
check_language_availability(lang)
|
28
|
-
find_best_subtitle(lang) unless @best_subtitle and @best_subtitle[lang]
|
28
|
+
find_best_subtitle(lang, no_hi) unless @best_subtitle and @best_subtitle[lang]
|
29
29
|
return @best_subtitle[lang]
|
30
30
|
end
|
31
31
|
|
32
|
-
def download_best_subtitle!(lang, http_redirect_limit = 8)
|
32
|
+
def download_best_subtitle!(lang, no_hi = false, http_redirect_limit = 8)
|
33
33
|
raise HTTPError.new('Too many HTTP redirects') unless http_redirect_limit > 0
|
34
|
-
uri = URI(best_subtitle(lang).url)
|
34
|
+
uri = URI(best_subtitle(lang, no_hi).url)
|
35
35
|
response = get_http_response(uri, url(lang))
|
36
36
|
if response.kind_of?(Net::HTTPRedirection)
|
37
|
-
follow_redirection(lang, response['location'], http_redirect_limit)
|
37
|
+
follow_redirection(lang, no_hi, response['location'], http_redirect_limit)
|
38
38
|
else
|
39
39
|
save_subtitle(response.body, lang)
|
40
40
|
end
|
@@ -48,10 +48,10 @@ module Addic7ed
|
|
48
48
|
@subtitles[lang] = parser.extract_subtitles
|
49
49
|
end
|
50
50
|
|
51
|
-
def find_best_subtitle(lang)
|
51
|
+
def find_best_subtitle(lang, no_hi = false)
|
52
52
|
@best_subtitle ||= {}
|
53
53
|
subtitles(lang).each do |sub|
|
54
|
-
@best_subtitle[lang] = sub if sub.works_for?
|
54
|
+
@best_subtitle[lang] = sub if sub.works_for?(video_file.group, no_hi) and sub.can_replace? @best_subtitle[lang]
|
55
55
|
end
|
56
56
|
raise NoSubtitleFound unless @best_subtitle[lang]
|
57
57
|
end
|
@@ -77,11 +77,11 @@ module Addic7ed
|
|
77
77
|
raise DownloadError
|
78
78
|
end
|
79
79
|
|
80
|
-
def follow_redirection(lang, new_uri, http_redirect_limit)
|
80
|
+
def follow_redirection(lang, no_hi, new_uri, http_redirect_limit)
|
81
81
|
# Addic7ed is serving redirection URL not-encoded, but Ruby does not support it (see http://bugs.ruby-lang.org/issues/7396)
|
82
82
|
best_subtitle(lang).url = URI.escape(new_uri)
|
83
83
|
raise DownloadLimitReached if /^\/downloadexceeded.php/.match best_subtitle(lang).url
|
84
|
-
download_best_subtitle!(lang, http_redirect_limit - 1)
|
84
|
+
download_best_subtitle!(lang, no_hi, http_redirect_limit - 1)
|
85
85
|
end
|
86
86
|
|
87
87
|
def save_subtitle(content, lang)
|
data/lib/addic7ed/parser.rb
CHANGED
@@ -44,6 +44,7 @@ module Addic7ed
|
|
44
44
|
status: extract_status(sub_node),
|
45
45
|
url: extract_url(sub_node),
|
46
46
|
source: extract_source(sub_node),
|
47
|
+
hi: extract_hi(sub_node),
|
47
48
|
downloads: extract_downloads(sub_node),
|
48
49
|
comment: extract_comment(sub_node)
|
49
50
|
)
|
@@ -78,6 +79,12 @@ module Addic7ed
|
|
78
79
|
source_node['href'] if source_node
|
79
80
|
end
|
80
81
|
|
82
|
+
def extract_hi(sub_node)
|
83
|
+
hi_node = sub_node.css('tr:nth-child(4) td.newsDate').children[1]
|
84
|
+
raise Addic7ed::ParsingError unless hi_node
|
85
|
+
!hi_node.attribute("title").nil?
|
86
|
+
end
|
87
|
+
|
81
88
|
def extract_downloads(sub_node)
|
82
89
|
downloads_node = sub_node.css('tr:nth-child(4) td.newsDate').first
|
83
90
|
raise Addic7ed::ParsingError unless downloads_node
|
data/lib/addic7ed/subtitle.rb
CHANGED
@@ -10,6 +10,7 @@ module Addic7ed
|
|
10
10
|
@status = options[:status]
|
11
11
|
@url = options[:url]
|
12
12
|
@via = options[:via]
|
13
|
+
@hi = options[:hi]
|
13
14
|
@downloads = options[:downloads].to_i || 0
|
14
15
|
@comment = normalize_comment(options[:comment])
|
15
16
|
end
|
@@ -18,8 +19,9 @@ module Addic7ed
|
|
18
19
|
"#{url}\t->\t#{version} (#{language}, #{status}) [#{downloads} downloads]#{" (via #{via})" if via}"
|
19
20
|
end
|
20
21
|
|
21
|
-
def works_for?(version = '')
|
22
|
-
|
22
|
+
def works_for?(version = '', no_hi = false)
|
23
|
+
hi_works = !@hi || !no_hi
|
24
|
+
is_completed? and is_compatible_with? version and hi_works
|
23
25
|
end
|
24
26
|
|
25
27
|
def can_replace?(other_subtitle)
|
@@ -60,6 +62,8 @@ module Addic7ed
|
|
60
62
|
end
|
61
63
|
|
62
64
|
def commented_as_compatible_with?(other_version)
|
65
|
+
return false if /(won't|doesn't|not) +work/i.match comment
|
66
|
+
return false if /resync +(from|of)/i.match comment
|
63
67
|
res = comment.include? other_version.downcase
|
64
68
|
res ||= comment.include? COMPATIBILITY_720P[other_version].downcase if COMPATIBILITY_720P[other_version]
|
65
69
|
res ||= comment.include? COMPATIBILITY_720P[version].downcase if COMPATIBILITY_720P[version]
|
data/lib/addic7ed/version.rb
CHANGED
data/lib/addic7ed/video_file.rb
CHANGED
@@ -1,18 +1,19 @@
|
|
1
1
|
module Addic7ed
|
2
2
|
class VideoFile
|
3
3
|
|
4
|
-
TVSHOW_REGEX = /\A(?<showname>.*\w)[\[\. ]+S?(?<season>\d{1,2})[-\. ]?[EX]?(?<episode>\d{2})([-\. ]?[EX]?\d{2})*[\]\. ]+(?<tags>.*)-(?<group>\w*)(\.\w{3})?\z/i
|
4
|
+
TVSHOW_REGEX = /\A(?<showname>.*\w)[\[\. ]+S?(?<season>\d{1,2})[-\. ]?[EX]?(?<episode>\d{2})([-\. ]?[EX]?\d{2})*[\]\. ]+(?<tags>.*)-(?<group>\w*)\[?(?<distribution>\w*)\]?(\.\w{3})?\z/i
|
5
5
|
|
6
|
-
attr_reader :filename, :showname, :season, :episode, :tags, :group
|
6
|
+
attr_reader :filename, :showname, :season, :episode, :tags, :group, :distribution
|
7
7
|
|
8
8
|
def initialize(filename)
|
9
9
|
@filename = filename
|
10
10
|
if match = TVSHOW_REGEX.match(basename)
|
11
|
-
@showname
|
12
|
-
@season
|
13
|
-
@episode
|
14
|
-
@tags
|
15
|
-
@group
|
11
|
+
@showname = match[:showname].gsub('.', ' ')
|
12
|
+
@season = match[:season].to_i
|
13
|
+
@episode = match[:episode].to_i
|
14
|
+
@tags = match[:tags].upcase.split(/[\. ]/)
|
15
|
+
@group = match[:group].upcase
|
16
|
+
@distribution = match[:distribution].upcase
|
16
17
|
else
|
17
18
|
raise InvalidFilename
|
18
19
|
end
|
@@ -49,11 +50,12 @@ module Addic7ed
|
|
49
50
|
|
50
51
|
def inspect
|
51
52
|
"Guesses for #{@filename}:
|
52
|
-
show:
|
53
|
-
season:
|
54
|
-
episode:
|
55
|
-
tags:
|
56
|
-
group:
|
53
|
+
show: #{@showname}
|
54
|
+
season: #{@season}
|
55
|
+
episode: #{@episode}
|
56
|
+
tags: #{@tags}
|
57
|
+
group: #{@group}
|
58
|
+
distribution: #{@distribution}"
|
57
59
|
end
|
58
60
|
|
59
61
|
end
|
@@ -7,6 +7,7 @@ describe Addic7ed::Episode do
|
|
7
7
|
@filename_show_not_found = 'Show.Not.Found.S03E02.720p.HDTV.x264-EVOLVE.mkv'
|
8
8
|
@filename_episode_not_found = 'The.Walking.Dead.S03E42.720p.HDTV.x264-EVOLVE.mkv'
|
9
9
|
@filename_compatible_group = 'The.Walking.Dead.S03E04.HDTV.XviD-ASAP.mkv'
|
10
|
+
@filename_no_hi = 'The.Walking.Dead.S03E02.720p.HDTV.x264-KILLERS.mkv'
|
10
11
|
@episode = Addic7ed::Episode.new(@filename)
|
11
12
|
end
|
12
13
|
|
@@ -78,6 +79,13 @@ describe Addic7ed::Episode do
|
|
78
79
|
expect(compatible_episode.best_subtitle('fr').url).to eq 'http://www.addic7ed.com/updated/8/68508/3'
|
79
80
|
end
|
80
81
|
|
82
|
+
it 'finds the subtitle with status completed, same group name and not hearing impaired' do
|
83
|
+
stub_request(:get, 'http://www.addic7ed.com/serie/The_Walking_Dead/3/2/1')
|
84
|
+
.to_return File.new('spec/responses/walking-dead-3-2-1.http')
|
85
|
+
episode = Addic7ed::Episode.new(@filename_no_hi)
|
86
|
+
expect(episode.best_subtitle('en', true).url).to eq 'http://www.addic7ed.com/updated/1/68018/0'
|
87
|
+
end
|
88
|
+
|
81
89
|
it 'uses French as default language' do
|
82
90
|
expect(@episode.best_subtitle).to eq @episode.best_subtitle('fr')
|
83
91
|
end
|
@@ -65,7 +65,7 @@ describe Addic7ed::Subtitle, "#to_s" do
|
|
65
65
|
end
|
66
66
|
|
67
67
|
describe Addic7ed::Subtitle, "#works_for?" do
|
68
|
-
let(:subtitle) { Addic7ed::Subtitle.new(version: "DIMENSION"
|
68
|
+
let(:subtitle) { Addic7ed::Subtitle.new(version: "DIMENSION") }
|
69
69
|
|
70
70
|
context "when it is incomplete" do
|
71
71
|
before { allow(subtitle).to receive(:is_completed?).and_return(false) }
|
@@ -90,16 +90,36 @@ describe Addic7ed::Subtitle, "#works_for?" do
|
|
90
90
|
expect(subtitle.works_for? "EVOLVE").to be false
|
91
91
|
end
|
92
92
|
|
93
|
-
|
94
|
-
|
93
|
+
context "when is has a compatibility comment" do
|
94
|
+
let(:subtitle) { Addic7ed::Subtitle.new(version: "DIMENSION", comment: "Works with IMMERSE") }
|
95
|
+
|
96
|
+
it "returns true given the same version as comment" do
|
97
|
+
expect(subtitle.works_for? "IMMERSE").to be true
|
98
|
+
end
|
99
|
+
|
100
|
+
it "returns true given a compatible version as comment" do
|
101
|
+
expect(subtitle.works_for? "ASAP").to be true
|
102
|
+
end
|
103
|
+
|
104
|
+
it "returns false given an incompatible version as comment" do
|
105
|
+
expect(subtitle.works_for? "KILLERS").to be false
|
106
|
+
end
|
95
107
|
end
|
96
108
|
|
97
|
-
|
98
|
-
|
109
|
+
context "when is has an incompatibility comment" do
|
110
|
+
let(:subtitle) { Addic7ed::Subtitle.new(version: "DIMENSION", comment: "Doesn't work with IMMERSE") }
|
111
|
+
|
112
|
+
it "returns false" do
|
113
|
+
expect(subtitle.works_for? "IMMERSE").to be false
|
114
|
+
end
|
99
115
|
end
|
100
116
|
|
101
|
-
|
102
|
-
|
117
|
+
context "when is has an ambiguous comment" do
|
118
|
+
let(:subtitle) { Addic7ed::Subtitle.new(version: "DIMENSION", comment: "Resync from IMMERSE") }
|
119
|
+
|
120
|
+
it "returns false" do
|
121
|
+
expect(subtitle.works_for? "IMMERSE").to be false
|
122
|
+
end
|
103
123
|
end
|
104
124
|
end
|
105
125
|
end
|
@@ -8,11 +8,12 @@ describe Addic7ed::VideoFile do
|
|
8
8
|
let(:filename) { filename }
|
9
9
|
|
10
10
|
it "it detects successfully" do
|
11
|
-
expect(file.showname).to eq (expected_show_name || 'Showname')
|
12
|
-
expect(file.season
|
13
|
-
expect(file.episode
|
14
|
-
expect(file.tags
|
15
|
-
expect(file.group
|
11
|
+
expect(file.showname ).to eq (expected_show_name || 'Showname')
|
12
|
+
expect(file.season ).to eq 2
|
13
|
+
expect(file.episode ).to eq 1
|
14
|
+
expect(file.tags ).to eq ['720P', 'HDTV', 'X264']
|
15
|
+
expect(file.group ).to eq 'GROUP'
|
16
|
+
expect(file.distribution).to satisfy { |d| ['', 'DISTRIBUTION'].include?(d) }
|
16
17
|
end
|
17
18
|
end
|
18
19
|
|
@@ -77,6 +78,10 @@ describe Addic7ed::VideoFile do
|
|
77
78
|
it_behaves_like "a media file", "Showname.2014.S02E01.720p.HDTV.x264-GROUP.mkv", "Showname 2014"
|
78
79
|
end
|
79
80
|
|
81
|
+
context "with an optional distribution group name" do
|
82
|
+
it_behaves_like "a media file", "Showname.2014.S02E01.720p.HDTV.x264-GROUP[DISTRIBUTION].mkv", "Showname 2014"
|
83
|
+
end
|
84
|
+
|
80
85
|
context "with a full path" do
|
81
86
|
it_behaves_like "a media file", "/full/path/to/Showname.S02E01.720p.HDTV.x264-GROUP.mkv"
|
82
87
|
end
|
@@ -120,6 +125,11 @@ describe Addic7ed::VideoFile do
|
|
120
125
|
context "with no group" do
|
121
126
|
it_behaves_like "an unknown file", "Showname.S02E01.720p.HDTV.x264.mkv"
|
122
127
|
end
|
128
|
+
|
129
|
+
context "with no distribution" do
|
130
|
+
it_behaves_like "a media file", "Showname.S02E01.720p.HDTV.x264-GROUP.mkv"
|
131
|
+
end
|
132
|
+
|
123
133
|
end
|
124
134
|
|
125
135
|
describe '#encoded_filename' do
|
@@ -177,13 +187,14 @@ describe Addic7ed::VideoFile do
|
|
177
187
|
|
178
188
|
describe '#inspect' do
|
179
189
|
it 'prints a human-readable detailed version' do
|
180
|
-
expect(Addic7ed::VideoFile.new("Showname.S02E01.720p.HDTV.x264-GROUP.mkv").inspect).to eq(
|
181
|
-
'Guesses for Showname.S02E01.720p.HDTV.x264-GROUP.mkv:
|
182
|
-
show:
|
183
|
-
season:
|
184
|
-
episode:
|
185
|
-
tags:
|
186
|
-
group:
|
190
|
+
expect(Addic7ed::VideoFile.new("Showname.S02E01.720p.HDTV.x264-GROUP[DISTRIBUTION].mkv").inspect).to eq(
|
191
|
+
'Guesses for Showname.S02E01.720p.HDTV.x264-GROUP[DISTRIBUTION].mkv:
|
192
|
+
show: Showname
|
193
|
+
season: 2
|
194
|
+
episode: 1
|
195
|
+
tags: ["720P", "HDTV", "X264"]
|
196
|
+
group: GROUP
|
197
|
+
distribution: DISTRIBUTION')
|
187
198
|
end
|
188
199
|
end
|
189
200
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: addic7ed
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Baudino
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-02-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -70,16 +70,30 @@ dependencies:
|
|
70
70
|
name: nokogiri
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 1.6.7.2
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 1.6.7.2
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: json
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 1.7.7
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.7.7
|
83
97
|
description: Ruby script (cli) to fetch subtitles on Addic7ed
|
84
98
|
email: michael.baudino@alpine-lab.com
|
85
99
|
executables:
|