addic7ed 3.0.0 → 4.0.0.pre.beta.5
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/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
|