addic7ed 3.0.0 → 4.0.0.pre.beta.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/addic7ed.rb +5 -10
- data/lib/addic7ed/common.rb +13 -1285
- data/lib/addic7ed/config.json +1417 -0
- data/lib/addic7ed/errors.rb +8 -7
- data/lib/addic7ed/models/episode.rb +112 -0
- data/lib/addic7ed/models/search.rb +90 -0
- data/lib/addic7ed/models/subtitle.rb +109 -0
- data/lib/addic7ed/models/subtitles_collection.rb +63 -0
- data/lib/addic7ed/models/video_file.rb +147 -0
- data/lib/addic7ed/service.rb +13 -0
- data/lib/addic7ed/services/check_compatibility.rb +44 -0
- data/lib/addic7ed/services/download_subtitle.rb +53 -0
- data/lib/addic7ed/services/get_shows_list.rb +29 -0
- data/lib/addic7ed/services/{addic7ed_comment_normalizer.rb → normalize_comment.rb} +4 -8
- data/lib/addic7ed/services/normalize_version.rb +22 -0
- data/lib/addic7ed/services/parse_page.rb +43 -0
- data/lib/addic7ed/services/parse_subtitle.rb +79 -0
- data/lib/addic7ed/services/url_encode_show_name.rb +46 -0
- data/lib/addic7ed/version.rb +1 -1
- metadata +63 -50
- data/bin/addic7ed +0 -144
- data/lib/addic7ed/episode.rb +0 -95
- data/lib/addic7ed/parser.rb +0 -105
- data/lib/addic7ed/services/addic7ed_version_normalizer.rb +0 -24
- data/lib/addic7ed/show_list.rb +0 -61
- data/lib/addic7ed/subtitle.rb +0 -72
- data/lib/addic7ed/video_file.rb +0 -41
- data/spec/lib/addic7ed/common_spec.rb +0 -21
- data/spec/lib/addic7ed/episode_spec.rb +0 -165
- data/spec/lib/addic7ed/services/addic7ed_comment_normalizer_spec.rb +0 -12
- data/spec/lib/addic7ed/services/addic7ed_version_normalizer_spec.rb +0 -73
- data/spec/lib/addic7ed/show_list_spec.rb +0 -42
- data/spec/lib/addic7ed/subtitle_spec.rb +0 -182
- data/spec/lib/addic7ed/video_file_spec.rb +0 -159
- data/spec/responses/basic_redirection.http +0 -13
- data/spec/responses/homepage.http +0 -921
- data/spec/responses/redirection_loop.http +0 -12
- data/spec/responses/walking-dead-3-2-1.http +0 -770
- data/spec/responses/walking-dead-3-2-48.http +0 -2117
- data/spec/responses/walking-dead-3-2-7.http +0 -659
- data/spec/responses/walking-dead-3-2-8.http +0 -815
- data/spec/responses/walking-dead-3-2-8_best_subtitle.http +0 -1928
- data/spec/responses/walking-dead-3-4-8.http +0 -732
- data/spec/responses/walking-dead-3-42-8.http +0 -13
- data/spec/spec_helper.rb +0 -26
data/bin/addic7ed
DELETED
@@ -1,144 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
def require_dependencies
|
4
|
-
require 'optparse'
|
5
|
-
require 'oga'
|
6
|
-
require 'addic7ed'
|
7
|
-
end
|
8
|
-
|
9
|
-
begin
|
10
|
-
require_dependencies # People don't all use rubygems, you know...
|
11
|
-
rescue LoadError
|
12
|
-
require 'rubygems' # But most do :-)
|
13
|
-
require_dependencies
|
14
|
-
end
|
15
|
-
|
16
|
-
options = {}
|
17
|
-
OptionParser.new do |opts|
|
18
|
-
opts.banner = "Usage: addic7ed [options] <file1> [<file2>, <file3>, ...]"
|
19
|
-
|
20
|
-
opts.on("-l [LANGUAGE]", "--language [LANGUAGE]", "Language code to look subtitles for (default: French)") do |l|
|
21
|
-
options[:language] = l
|
22
|
-
end
|
23
|
-
|
24
|
-
opts.on("--no-hi", "Only download subtitles without Hearing Impaired lines") do |hi|
|
25
|
-
options[:no_hi] = !hi
|
26
|
-
end
|
27
|
-
|
28
|
-
opts.on("-a", "--all-subtitles", "Display all available subtitles") do |a|
|
29
|
-
options[:all] = a
|
30
|
-
end
|
31
|
-
|
32
|
-
opts.on("-n", "--do-not-download", "Do not download the subtitle") do |n|
|
33
|
-
options[:nodownload] = n
|
34
|
-
end
|
35
|
-
|
36
|
-
opts.on("-f", "--force", "Overwrite existing subtitle") do |f|
|
37
|
-
options[:force] = f
|
38
|
-
end
|
39
|
-
|
40
|
-
opts.on("-u", "--untagged", "Do not include language code in subtitle filename") do |u|
|
41
|
-
options[:untagged] = u
|
42
|
-
end
|
43
|
-
|
44
|
-
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
|
45
|
-
options[:verbose] = v
|
46
|
-
end
|
47
|
-
|
48
|
-
opts.on("-q", "--quiet", "Run without output (cron-mode)") do |q|
|
49
|
-
options[:quiet] = q
|
50
|
-
end
|
51
|
-
|
52
|
-
opts.on("-d", "--debug", "Debug mode [do not use]") do |d|
|
53
|
-
options[:debug] = d
|
54
|
-
end
|
55
|
-
|
56
|
-
opts.on_tail("-h", "--help", "Show this message") do
|
57
|
-
puts opts
|
58
|
-
exit
|
59
|
-
end
|
60
|
-
|
61
|
-
opts.on_tail("-L", "--list-languages", "List all available languages") do
|
62
|
-
puts "All available languages (with their corresponding ISO code):"
|
63
|
-
Addic7ed::LANGUAGES.each do |lang, infos|
|
64
|
-
puts "#{lang}:\t#{infos[:name]}"
|
65
|
-
end
|
66
|
-
exit
|
67
|
-
end
|
68
|
-
|
69
|
-
opts.on_tail("-V", "--version", "Show version number") do
|
70
|
-
puts "This is addic7ed-ruby version #{Addic7ed::VERSION} by Michael Baudino (https://github.com/michaelbaudino)"
|
71
|
-
puts "Licensed under the terms of the MIT License"
|
72
|
-
exit
|
73
|
-
end
|
74
|
-
end.parse!
|
75
|
-
|
76
|
-
options[:filenames] = ARGV
|
77
|
-
options[:language] ||= 'fr'
|
78
|
-
|
79
|
-
# Main loop over mandatory arguments (e.g. filenames)
|
80
|
-
|
81
|
-
options[:filenames].each do |filename|
|
82
|
-
unless File.file? filename or options[:debug]
|
83
|
-
puts "Warning: #{filename} does not exist or is not a regular file. Skipping.".gsub(/^/, options[:verbose] ? ' ' : '') unless options[:quiet]
|
84
|
-
next
|
85
|
-
end
|
86
|
-
|
87
|
-
begin
|
88
|
-
ep = Addic7ed::Episode.new(filename, options[:untagged])
|
89
|
-
puts "Searching subtitles for #{ep.video_file.basename}" if options[:verbose]
|
90
|
-
if File.file?(filename.gsub(/\.\w{3}$/, '.srt')) and not options[:force]
|
91
|
-
puts "A subtitle already exists (#{filename.gsub(/\.\w{3}$/, '.srt')}). Skipping.".gsub(/^/, options[:verbose] ? ' ' : '') unless options[:quiet]
|
92
|
-
next
|
93
|
-
end
|
94
|
-
puts ep.video_file.inspect.gsub(/^/, ' ') if options[:verbose]
|
95
|
-
ep.subtitles(options[:language])
|
96
|
-
if options[:all] or options[:verbose]
|
97
|
-
puts 'Available subtitles:'.gsub(/^/, options[:verbose] ? ' ' : '')
|
98
|
-
ep.subtitles(options[:language]).each do |sub|
|
99
|
-
puts "#{sub}".gsub(/^/, options[:verbose] ? ' ' : ' ')
|
100
|
-
end
|
101
|
-
next if options[:all]
|
102
|
-
end
|
103
|
-
ep.best_subtitle(options[:language], options[:no_hi])
|
104
|
-
if options[:verbose]
|
105
|
-
puts ' Best subtitle:'
|
106
|
-
puts " #{ep.best_subtitle(options[:language])}"
|
107
|
-
end
|
108
|
-
unless options[:nodownload]
|
109
|
-
ep.download_best_subtitle!(options[:language], options[:no_hi])
|
110
|
-
puts "New subtitle downloaded for #{filename}.\nEnjoy your show :-)".gsub(/^/, options[:verbose] ? ' ' : '') unless options[:quiet]
|
111
|
-
end
|
112
|
-
rescue Addic7ed::InvalidFilename
|
113
|
-
puts "#{filename} does not seem to be a valid TV show filename. Skipping.".gsub(/^/, options[:verbose] ? ' ' : '') unless options[:quiet]
|
114
|
-
next
|
115
|
-
rescue Addic7ed::ShowNotFound
|
116
|
-
puts "Show not found on Addic7ed : #{ep.video_file.filename}. Skipping.".gsub(/^/, options[:verbose] ? ' ' : '') unless options[:quiet]
|
117
|
-
next
|
118
|
-
rescue Addic7ed::EpisodeNotFound
|
119
|
-
puts "Episode not found on Addic7ed : #{ep.video_file.filename}. Skipping.".gsub(/^/, options[:verbose] ? ' ' : '') unless options[:quiet]
|
120
|
-
next
|
121
|
-
rescue Addic7ed::LanguageNotSupported
|
122
|
-
puts "Addic7ed does not support language '#{options[:language]}'. Exiting.".gsub(/^/, options[:verbose] ? ' ' : '') unless options[:quiet]
|
123
|
-
break
|
124
|
-
rescue Addic7ed::ParsingError
|
125
|
-
puts "HTML parsing failed. Either you've found a bug (please submit an issue) or Addic7ed website has been updated and cannot be crawled anymore (in this case, please wait for an update or submit a pull request). Skipping.".gsub(/^/, options[:verbose] ? ' ' : '') unless options[:quiet]
|
126
|
-
next
|
127
|
-
rescue Addic7ed::NoSubtitleFound
|
128
|
-
puts "No (acceptable) subtitle has been found on Addic7ed for #{filename}. Maybe try again later.".gsub(/^/, options[:verbose] ? ' ' : '') unless options[:quiet]
|
129
|
-
next
|
130
|
-
rescue Addic7ed::DownloadError
|
131
|
-
puts "The subtitle could not be downloaded. Skipping.".gsub(/^/, options[:verbose] ? ' ' : '') unless options[:quiet]
|
132
|
-
next
|
133
|
-
rescue Addic7ed::DownloadLimitReached
|
134
|
-
puts "You exceeded your daily download count. Exiting.".gsub(/^/, options[:verbose] ? ' ' : '') unless options[:quiet]
|
135
|
-
break
|
136
|
-
rescue Addic7ed::SubtitleCannotBeSaved
|
137
|
-
puts "The downloaded subtitle could not be saved as #{filename.gsub(/\.\w{3}$/, '.srt')}. Skipping.".gsub(/^/, options[:verbose] ? ' ' : '') unless options[:quiet]
|
138
|
-
next
|
139
|
-
rescue Addic7ed::HTTPError => e
|
140
|
-
puts "Network error: #{e.message}".gsub(/^/, options[:verbose] ? ' ' : '') unless options[:quiet]
|
141
|
-
next
|
142
|
-
end
|
143
|
-
|
144
|
-
end
|
data/lib/addic7ed/episode.rb
DELETED
@@ -1,95 +0,0 @@
|
|
1
|
-
require 'net/http'
|
2
|
-
require 'open-uri'
|
3
|
-
|
4
|
-
module Addic7ed
|
5
|
-
class Episode
|
6
|
-
|
7
|
-
attr_reader :video_file, :untagged
|
8
|
-
|
9
|
-
def initialize(filename, untagged = false)
|
10
|
-
@video_file = Addic7ed::VideoFile.new(filename)
|
11
|
-
@untagged = untagged
|
12
|
-
end
|
13
|
-
|
14
|
-
def url(lang = 'fr')
|
15
|
-
check_language_availability(lang)
|
16
|
-
@localized_urls ||= {}
|
17
|
-
@localized_urls[lang] ||= "http://www.addic7ed.com/serie/#{ShowList.url_segment_for(video_file.showname)}/#{video_file.season}/#{video_file.episode}/#{LANGUAGES[lang][:id]}"
|
18
|
-
end
|
19
|
-
|
20
|
-
def subtitles(lang = 'fr')
|
21
|
-
check_language_availability(lang)
|
22
|
-
find_subtitles(lang) unless @subtitles and @subtitles[lang]
|
23
|
-
return @subtitles[lang]
|
24
|
-
end
|
25
|
-
|
26
|
-
def best_subtitle(lang = 'fr', no_hi = false)
|
27
|
-
check_language_availability(lang)
|
28
|
-
find_best_subtitle(lang, no_hi) unless @best_subtitle and @best_subtitle[lang]
|
29
|
-
return @best_subtitle[lang]
|
30
|
-
end
|
31
|
-
|
32
|
-
def download_best_subtitle!(lang, no_hi = false, http_redirect_limit = 8)
|
33
|
-
raise HTTPError.new('Too many HTTP redirects') unless http_redirect_limit > 0
|
34
|
-
uri = URI(best_subtitle(lang, no_hi).url)
|
35
|
-
response = get_http_response(uri, url(lang))
|
36
|
-
if response.kind_of?(Net::HTTPRedirection)
|
37
|
-
follow_redirection(lang, no_hi, response['location'], http_redirect_limit)
|
38
|
-
else
|
39
|
-
save_subtitle(response.body, lang)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
protected
|
44
|
-
|
45
|
-
def find_subtitles(lang)
|
46
|
-
initialize_language(lang)
|
47
|
-
parser = Addic7ed::Parser.new(self, lang)
|
48
|
-
@subtitles[lang] = parser.extract_subtitles
|
49
|
-
end
|
50
|
-
|
51
|
-
def find_best_subtitle(lang, no_hi = false)
|
52
|
-
@best_subtitle ||= {}
|
53
|
-
subtitles(lang).each do |sub|
|
54
|
-
@best_subtitle[lang] = sub if sub.works_for?(video_file.group, no_hi) and sub.can_replace? @best_subtitle[lang]
|
55
|
-
end
|
56
|
-
raise NoSubtitleFound unless @best_subtitle[lang]
|
57
|
-
end
|
58
|
-
|
59
|
-
def check_language_availability(lang)
|
60
|
-
raise LanguageNotSupported unless LANGUAGES[lang]
|
61
|
-
end
|
62
|
-
|
63
|
-
def initialize_language(lang)
|
64
|
-
@subtitles ||= {}
|
65
|
-
@subtitles[lang] ||= []
|
66
|
-
end
|
67
|
-
|
68
|
-
def get_http_response(uri, referer)
|
69
|
-
Net::HTTP.start(uri.hostname, uri.port) do |http|
|
70
|
-
request = Net::HTTP::Get.new(uri.request_uri)
|
71
|
-
# Addic7ed needs the Referer to be correct. User-agent is just here to fake a real browser request.
|
72
|
-
request['Referer'] = referer
|
73
|
-
request['User-Agent'] = USER_AGENTS.sample
|
74
|
-
http.request(request)
|
75
|
-
end
|
76
|
-
rescue
|
77
|
-
raise DownloadError
|
78
|
-
end
|
79
|
-
|
80
|
-
def follow_redirection(lang, no_hi, new_uri, http_redirect_limit)
|
81
|
-
# Addic7ed is serving redirection URL not-encoded, but Ruby does not support it (see http://bugs.ruby-lang.org/issues/7396)
|
82
|
-
best_subtitle(lang).url = URI.escape(new_uri)
|
83
|
-
raise DownloadLimitReached if /^\/downloadexceeded.php/.match best_subtitle(lang).url
|
84
|
-
download_best_subtitle!(lang, no_hi, http_redirect_limit - 1)
|
85
|
-
end
|
86
|
-
|
87
|
-
def save_subtitle(content, lang)
|
88
|
-
Kernel.open "#{video_file}".gsub(/\.\w{3}$/, untagged ? ".srt" : ".#{lang}.srt"), 'w' do |f|
|
89
|
-
f << content
|
90
|
-
end
|
91
|
-
rescue
|
92
|
-
raise SubtitleCannotBeSaved
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
data/lib/addic7ed/parser.rb
DELETED
@@ -1,105 +0,0 @@
|
|
1
|
-
require 'oga'
|
2
|
-
require 'net/http'
|
3
|
-
require 'open-uri'
|
4
|
-
|
5
|
-
module Addic7ed
|
6
|
-
class Parser
|
7
|
-
|
8
|
-
def initialize(episode, lang)
|
9
|
-
@episode, @lang = episode, lang
|
10
|
-
@subtitles = []
|
11
|
-
end
|
12
|
-
|
13
|
-
def extract_subtitles
|
14
|
-
@dom = subtitles_page_dom
|
15
|
-
check_subtitles_presence
|
16
|
-
parse_subtitle_nodes_list
|
17
|
-
@subtitles
|
18
|
-
end
|
19
|
-
|
20
|
-
protected
|
21
|
-
|
22
|
-
def subtitles_page_dom
|
23
|
-
uri = URI(@episode.url(@lang))
|
24
|
-
response = Net::HTTP.start(uri.hostname, uri.port) do |http|
|
25
|
-
request = Net::HTTP::Get.new(uri.request_uri)
|
26
|
-
request["User-Agent"] = USER_AGENTS.sample
|
27
|
-
http.request(request)
|
28
|
-
end
|
29
|
-
raise EpisodeNotFound unless response.body
|
30
|
-
Oga.parse_html(response.body)
|
31
|
-
end
|
32
|
-
|
33
|
-
def check_subtitles_presence
|
34
|
-
raise NoSubtitleFound unless @dom.css('select#filterlang ~ font[color="yellow"]').empty?
|
35
|
-
end
|
36
|
-
|
37
|
-
def parse_subtitle_nodes_list
|
38
|
-
sublist_node = @dom.css('#container95m table.tabel95 table.tabel95')
|
39
|
-
raise NoSubtitleFound if sublist_node.size == 0
|
40
|
-
sublist_node.each do |sub_node|
|
41
|
-
@subtitles << parse_subtitle_node(sub_node)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def parse_subtitle_node(sub_node)
|
46
|
-
Addic7ed::Subtitle.new(
|
47
|
-
version: extract_version(sub_node),
|
48
|
-
language: extract_language(sub_node),
|
49
|
-
status: extract_status(sub_node),
|
50
|
-
url: extract_url(sub_node),
|
51
|
-
source: extract_source(sub_node),
|
52
|
-
hi: extract_hi(sub_node),
|
53
|
-
downloads: extract_downloads(sub_node),
|
54
|
-
comment: extract_comment(sub_node)
|
55
|
-
)
|
56
|
-
end
|
57
|
-
|
58
|
-
def extract_version(sub_node)
|
59
|
-
version_node = sub_node.css('.NewsTitle').first
|
60
|
-
raise Addic7ed::ParsingError unless version_node
|
61
|
-
version_node.text
|
62
|
-
end
|
63
|
-
|
64
|
-
def extract_language(sub_node)
|
65
|
-
language_node = sub_node.css('.language').first
|
66
|
-
raise Addic7ed::ParsingError unless language_node
|
67
|
-
language_node.text.gsub(/\A\W*/, '').gsub(/[^\w\)]*\z/, '')
|
68
|
-
end
|
69
|
-
|
70
|
-
def extract_status(sub_node)
|
71
|
-
status_node = sub_node.css('tr:nth-child(3) td:nth-child(4) b').first
|
72
|
-
raise Addic7ed::ParsingError unless status_node
|
73
|
-
status_node.text.strip
|
74
|
-
end
|
75
|
-
|
76
|
-
def extract_url(sub_node)
|
77
|
-
url_node = sub_node.css('a.buttonDownload').last
|
78
|
-
raise Addic7ed::ParsingError unless url_node
|
79
|
-
'http://www.addic7ed.com' + url_node['href']
|
80
|
-
end
|
81
|
-
|
82
|
-
def extract_source(sub_node)
|
83
|
-
source_node = sub_node.css('tr:nth-child(3) td:first-child a').first
|
84
|
-
source_node['href'] if source_node
|
85
|
-
end
|
86
|
-
|
87
|
-
def extract_hi(sub_node)
|
88
|
-
hi_node = sub_node.css('tr:nth-child(4) td.newsDate img').last
|
89
|
-
raise Addic7ed::ParsingError unless hi_node
|
90
|
-
!hi_node.attribute("title").nil?
|
91
|
-
end
|
92
|
-
|
93
|
-
def extract_downloads(sub_node)
|
94
|
-
downloads_node = sub_node.css('tr:nth-child(4) td.newsDate').first
|
95
|
-
raise Addic7ed::ParsingError unless downloads_node
|
96
|
-
/(?<downloads>\d*) Downloads/.match(downloads_node.text)[:downloads]
|
97
|
-
end
|
98
|
-
|
99
|
-
def extract_comment(sub_node)
|
100
|
-
comment_node = sub_node.css('tr:nth-child(2) td.newsDate').first
|
101
|
-
raise Addic7ed::ParsingError unless comment_node
|
102
|
-
comment_node.text.gsub(/<img[^>]+\>/i, "")
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
module Addic7ed
|
2
|
-
class Addic7edVersionNormalizer
|
3
|
-
attr_reader :version
|
4
|
-
|
5
|
-
def initialize(version)
|
6
|
-
@version = version || ""
|
7
|
-
end
|
8
|
-
|
9
|
-
def self.call(version)
|
10
|
-
new(version).call
|
11
|
-
end
|
12
|
-
|
13
|
-
def call
|
14
|
-
version.
|
15
|
-
gsub(/[[:space:]]/, "").
|
16
|
-
upcase.
|
17
|
-
gsub(/,[\d\. ]+MBS$/, '').
|
18
|
-
gsub(/(^VERSION *|720P|1080P|HDTV|PROPER|RERIP|INTERNAL|X\.?264)/, '').
|
19
|
-
gsub(/[- \.]/, '')
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
end
|
data/lib/addic7ed/show_list.rb
DELETED
@@ -1,61 +0,0 @@
|
|
1
|
-
module Addic7ed
|
2
|
-
class ShowList
|
3
|
-
attr_reader :raw_name
|
4
|
-
|
5
|
-
def initialize(raw_name)
|
6
|
-
@raw_name = raw_name
|
7
|
-
end
|
8
|
-
|
9
|
-
def self.url_segment_for(raw_name)
|
10
|
-
new(raw_name).url_segment_for
|
11
|
-
end
|
12
|
-
|
13
|
-
def url_segment_for
|
14
|
-
shows_matching = shows_matching_exactly
|
15
|
-
shows_matching = shows_matching_without_year if shows_matching.empty?
|
16
|
-
raise ShowNotFound if shows_matching.empty?
|
17
|
-
shows_matching.last.gsub(' ', '_')
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def shows_matching_exactly
|
23
|
-
@shows_matching_exactly ||= addic7ed_shows.select{ |addic7ed_show| is_matching? addic7ed_show }
|
24
|
-
end
|
25
|
-
|
26
|
-
def shows_matching_without_year
|
27
|
-
@shows_matching_without_year ||= addic7ed_shows.select{ |addic7ed_show| is_matching? addic7ed_show, :comparer_without_year }
|
28
|
-
end
|
29
|
-
|
30
|
-
def default_comparer(showname)
|
31
|
-
showname.downcase.gsub("'", "").gsub(".", " ").strip
|
32
|
-
end
|
33
|
-
|
34
|
-
def comparer_without_year(showname)
|
35
|
-
default_comparer(showname).gsub(/ \(\d{4}\)( |$)/, '\1')
|
36
|
-
end
|
37
|
-
|
38
|
-
def is_matching?(addic7ed_show, comparer = :default_comparer)
|
39
|
-
[humanized_name, addic7ed_show].map(&method(comparer)).reduce(:==)
|
40
|
-
end
|
41
|
-
|
42
|
-
def humanized_name
|
43
|
-
@humanized_name ||= raw_name.
|
44
|
-
gsub(/[_\.]+/, ' ').
|
45
|
-
gsub(/ (US|UK)( |$)/i, ' (\1)\2').
|
46
|
-
gsub(/ (\d{4})( |$)/i, ' (\1)\2')
|
47
|
-
end
|
48
|
-
|
49
|
-
def addic7ed_shows
|
50
|
-
@@addic7ed_shows ||= Oga.parse_html(addic7ed_homepage.body).css("select#qsShow option:not(:first-child)").map(&:text)
|
51
|
-
end
|
52
|
-
|
53
|
-
def addic7ed_homepage
|
54
|
-
Net::HTTP.start("www.addic7ed.com") do |http|
|
55
|
-
request = Net::HTTP::Get.new("/")
|
56
|
-
request["User-Agent"] = USER_AGENTS.sample
|
57
|
-
http.request(request)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
data/lib/addic7ed/subtitle.rb
DELETED
@@ -1,72 +0,0 @@
|
|
1
|
-
module Addic7ed
|
2
|
-
class Subtitle
|
3
|
-
|
4
|
-
attr_reader :version, :language, :status, :via, :downloads, :comment
|
5
|
-
attr_accessor :url
|
6
|
-
|
7
|
-
def initialize(options = {})
|
8
|
-
@version = Addic7edVersionNormalizer.call(options[:version])
|
9
|
-
@language = options[:language]
|
10
|
-
@status = options[:status]
|
11
|
-
@url = options[:url]
|
12
|
-
@via = options[:via]
|
13
|
-
@hi = options[:hi]
|
14
|
-
@downloads = options[:downloads].to_i || 0
|
15
|
-
@comment = Addic7edCommentNormalizer.call(options[:comment])
|
16
|
-
end
|
17
|
-
|
18
|
-
def to_s
|
19
|
-
"#{url}\t->\t#{version} (#{language}, #{status}) [#{downloads} downloads]#{" (via #{via})" if via}"
|
20
|
-
end
|
21
|
-
|
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
|
25
|
-
end
|
26
|
-
|
27
|
-
def can_replace?(other_subtitle)
|
28
|
-
return false unless is_completed?
|
29
|
-
return true if other_subtitle.nil?
|
30
|
-
language == other_subtitle.language &&
|
31
|
-
is_compatible_with?(other_subtitle.version) &&
|
32
|
-
is_more_popular_than?(other_subtitle)
|
33
|
-
end
|
34
|
-
|
35
|
-
def is_featured?
|
36
|
-
via == "http://addic7ed.com"
|
37
|
-
end
|
38
|
-
|
39
|
-
def is_completed?
|
40
|
-
status == 'Completed'
|
41
|
-
end
|
42
|
-
|
43
|
-
protected
|
44
|
-
|
45
|
-
def is_compatible_with?(other_version)
|
46
|
-
defined_as_compatible_with(other_version) || generally_compatible_with?(other_version) || commented_as_compatible_with?(other_version)
|
47
|
-
end
|
48
|
-
|
49
|
-
def defined_as_compatible_with(other_version)
|
50
|
-
version.split(",").include? other_version
|
51
|
-
end
|
52
|
-
|
53
|
-
def generally_compatible_with?(other_version)
|
54
|
-
COMPATIBILITY_720P[version] == other_version || COMPATIBILITY_720P[other_version] == version
|
55
|
-
end
|
56
|
-
|
57
|
-
def commented_as_compatible_with?(other_version)
|
58
|
-
return false if /(won't|doesn't|not) +work/i.match comment
|
59
|
-
return false if /resync +(from|of)/i.match comment
|
60
|
-
res = comment.include? other_version.downcase
|
61
|
-
res ||= comment.include? COMPATIBILITY_720P[other_version].downcase if COMPATIBILITY_720P[other_version]
|
62
|
-
res ||= comment.include? COMPATIBILITY_720P[version].downcase if COMPATIBILITY_720P[version]
|
63
|
-
!!res
|
64
|
-
end
|
65
|
-
|
66
|
-
def is_more_popular_than?(other_subtitle)
|
67
|
-
return true if other_subtitle.nil?
|
68
|
-
return false if other_subtitle.is_featured?
|
69
|
-
return downloads > other_subtitle.downloads
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|