subfinder 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.circleci/config.yml +55 -0
- data/.gitignore +9 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +62 -0
- data/LICENSE.txt +21 -0
- data/README.md +104 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/bin/subfinder +5 -0
- data/fixtures/vcr_cassettes/download_subtitle.yml +5071 -0
- data/fixtures/vcr_cassettes/integration_test.yml +1537 -0
- data/fixtures/vcr_cassettes/wrong_download_url.yml +112 -0
- data/lib/subfinder.rb +19 -0
- data/lib/subfinder/config.rb +8 -0
- data/lib/subfinder/logger.rb +22 -0
- data/lib/subfinder/main.rb +20 -0
- data/lib/subfinder/parser/args.rb +41 -0
- data/lib/subfinder/parser/download.rb +35 -0
- data/lib/subfinder/parser/files.rb +40 -0
- data/lib/subfinder/parser/subscene.rb +93 -0
- data/lib/subfinder/subtitle.rb +59 -0
- data/lib/subfinder/version.rb +3 -0
- data/movies_list_creator.rb +23 -0
- data/subfinder.gemspec +35 -0
- metadata +215 -0
@@ -0,0 +1,112 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: https://subscene.com/subtitles/english-text/MGNU9jG42CkOL8vcxVwLzwaKhIvuPAE0Bb7OqO62gY8-mFppv1EKkdjJVrTFiRBfXA2sxFE5E8je3FtYz11K6jGRckMYNf6S5LznnuUB5aV_PjsPghQ
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
Accept:
|
11
|
+
- "*/*"
|
12
|
+
Accept-Encoding:
|
13
|
+
- gzip, deflate
|
14
|
+
User-Agent:
|
15
|
+
- rest-client/2.0.2 (darwin18 x86_64) ruby/2.3.7p456
|
16
|
+
Host:
|
17
|
+
- subscene.com
|
18
|
+
response:
|
19
|
+
status:
|
20
|
+
code: 200
|
21
|
+
message: OK
|
22
|
+
headers:
|
23
|
+
Date:
|
24
|
+
- Fri, 25 Jan 2019 13:12:49 GMT
|
25
|
+
Content-Type:
|
26
|
+
- text/html; charset=utf-8
|
27
|
+
Transfer-Encoding:
|
28
|
+
- chunked
|
29
|
+
Connection:
|
30
|
+
- keep-alive
|
31
|
+
Set-Cookie:
|
32
|
+
- __cfduid=d54bf78588c18d70a094eac3fc7e5ce8a1548421969; expires=Sat, 25-Jan-20
|
33
|
+
13:12:49 GMT; path=/; domain=.subscene.com; HttpOnly; Secure
|
34
|
+
Cache-Control:
|
35
|
+
- private
|
36
|
+
Vary:
|
37
|
+
- Accept-Encoding
|
38
|
+
Expect-Ct:
|
39
|
+
- max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
|
40
|
+
Server:
|
41
|
+
- cloudflare
|
42
|
+
Cf-Ray:
|
43
|
+
- 49eafe5f2f01730d-AMS
|
44
|
+
Content-Encoding:
|
45
|
+
- gzip
|
46
|
+
body:
|
47
|
+
encoding: ASCII-8BIT
|
48
|
+
string: !binary |-
|
49
|
+
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
|
109
|
+
HAAA
|
110
|
+
http_version:
|
111
|
+
recorded_at: Fri, 25 Jan 2019 13:12:50 GMT
|
112
|
+
recorded_with: VCR 4.0.0
|
data/lib/subfinder.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'colorize'
|
3
|
+
require 'logger'
|
4
|
+
require 'optparse'
|
5
|
+
require 'zip'
|
6
|
+
|
7
|
+
require_relative 'subfinder/version'
|
8
|
+
require_relative 'subfinder/subtitle'
|
9
|
+
require_relative 'subfinder/config'
|
10
|
+
require_relative 'subfinder/main'
|
11
|
+
require_relative 'subfinder/logger'
|
12
|
+
|
13
|
+
require_relative 'subfinder/parser/args'
|
14
|
+
require_relative 'subfinder/parser/files'
|
15
|
+
require_relative 'subfinder/parser/subscene'
|
16
|
+
require_relative 'subfinder/parser/download'
|
17
|
+
|
18
|
+
module Subfinder
|
19
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Subfinder
|
2
|
+
class Logger < ::Logger
|
3
|
+
class << self
|
4
|
+
def setting
|
5
|
+
logger = Logger.new STDOUT
|
6
|
+
logger.level = Logger::INFO
|
7
|
+
logger.formatter = proc do |_severity, _datetime, _progname, msg|
|
8
|
+
"#{msg}\n"
|
9
|
+
end
|
10
|
+
@logger = logger
|
11
|
+
end
|
12
|
+
|
13
|
+
def info(str)
|
14
|
+
@logger.info(str)
|
15
|
+
end
|
16
|
+
|
17
|
+
def debug(str)
|
18
|
+
@logger.info(str) if Config.debug
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Subfinder
|
2
|
+
class Main
|
3
|
+
class << self
|
4
|
+
def run(args)
|
5
|
+
Subfinder::Logger.setting
|
6
|
+
Logger.info welcome_message
|
7
|
+
Subfinder::Parser::Args.new args
|
8
|
+
Subfinder::Subtitle.new.match
|
9
|
+
end
|
10
|
+
|
11
|
+
def welcome_message
|
12
|
+
'''
|
13
|
+
|
14
|
+
welcome to subfinder Gem!
|
15
|
+
|
16
|
+
'''.green
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Subfinder
|
2
|
+
module Parser
|
3
|
+
class Args
|
4
|
+
def initialize(args)
|
5
|
+
@args = args
|
6
|
+
parse_args
|
7
|
+
validate_required_args
|
8
|
+
end
|
9
|
+
|
10
|
+
def parse_args
|
11
|
+
opts = OptionParser.new
|
12
|
+
opts.banner = usage_msg
|
13
|
+
opts.separator ''
|
14
|
+
opts.separator 'options:'
|
15
|
+
opts.on('-u', '--url url', 'Set subscene url page') { |url| Config.url = url }
|
16
|
+
opts.on('-l', '--language language', 'Set subtitle language') { |language| Config.language = language }
|
17
|
+
opts.on('-v', '--version', 'Show the Compare Crypto version') { puts("compare-crypto #{CompareCrypto::VERSION}"); exit }
|
18
|
+
opts.on('-h', '--help', 'Show this message') { puts(opts); exit }
|
19
|
+
opts.on('-d', '--debug', 'debug') { Config.debug = true }
|
20
|
+
|
21
|
+
opts.parse!(@args)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def validate_required_args
|
27
|
+
Config.language ||= 'en'
|
28
|
+
Config.working_dir = Dir.pwd
|
29
|
+
end
|
30
|
+
|
31
|
+
def usage_msg
|
32
|
+
usage = '
|
33
|
+
Usage:
|
34
|
+
subfinder [options]
|
35
|
+
See https://github.com/sizief/subfinder for more information. Emm, nothing there really, just source code, if you want to improve the code or report a bug visit the page.
|
36
|
+
'
|
37
|
+
usage
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'rest-client'
|
2
|
+
module Subfinder
|
3
|
+
module Parser
|
4
|
+
class Download
|
5
|
+
def initialize(url)
|
6
|
+
@url = url
|
7
|
+
end
|
8
|
+
|
9
|
+
def save
|
10
|
+
res = RestClient.get @url
|
11
|
+
return false unless response_is_healthy? res
|
12
|
+
|
13
|
+
file_name = res.headers[:content_disposition].split('=')[1]
|
14
|
+
File.write("#{Config.working_dir}/#{file_name}", res.body)
|
15
|
+
Logger.info "Downloaded to #{Config.working_dir}/#{file_name}"
|
16
|
+
true
|
17
|
+
rescue StandardError => e
|
18
|
+
Logger.info "Error when downloading '#{@url}'\n Error message: #{e}\n".red
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
def response_is_healthy?(res)
|
23
|
+
if res.code != 200
|
24
|
+
Logger.info "Error when downloading '#{@url}'\n Error message: resposnse code is #{res.code}\n".red
|
25
|
+
false
|
26
|
+
elsif res.body.include? 'An error occurred while processing your request.'
|
27
|
+
Logger.info "Error when downloading '#{@url}'\n Error message: 'An error occurred while processing your request.'\n".red
|
28
|
+
false
|
29
|
+
else
|
30
|
+
true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Subfinder
|
2
|
+
module Parser
|
3
|
+
class Files
|
4
|
+
class << self
|
5
|
+
def list
|
6
|
+
prepare_file_list
|
7
|
+
Dir["#{Config.working_dir}/*"]
|
8
|
+
end
|
9
|
+
|
10
|
+
def prepare_file_list
|
11
|
+
files = Dir["#{Config.working_dir}/*"]
|
12
|
+
compressed_files = files.select { |file| ['.zip', '.rar'].include? File.extname(file) }
|
13
|
+
extract_all compressed_files
|
14
|
+
move_compressed_files compressed_files
|
15
|
+
end
|
16
|
+
|
17
|
+
def extract_all(array_list)
|
18
|
+
array_list.each do |file|
|
19
|
+
Zip::File.open(file) do |zip_file|
|
20
|
+
zip_file.each do |entry|
|
21
|
+
file_path = Config.working_dir + '/' + entry.name
|
22
|
+
unless File.exist? file_path
|
23
|
+
Logger.info "Extracting #{entry.name}"
|
24
|
+
entry.extract(file_path)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def move_compressed_files(compressed_files)
|
32
|
+
unless compressed_files.empty?
|
33
|
+
Dir.mkdir(Config.working_dir + '/compressed') unless File.exist?(Config.working_dir + '/compressed')
|
34
|
+
compressed_files.each { |f| File.rename(f, File.dirname(f) + '/compressed/' + File.basename(f)) }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'open-uri'
|
3
|
+
|
4
|
+
module Subfinder
|
5
|
+
module Parser
|
6
|
+
class Subscene
|
7
|
+
attr_reader :link
|
8
|
+
DOMAIN = 'https://subscene.com'.freeze
|
9
|
+
|
10
|
+
def initialize(file_name)
|
11
|
+
@file_name = file_name
|
12
|
+
end
|
13
|
+
|
14
|
+
def get
|
15
|
+
target_uri = find_link(create_links_list(open_online_document(Config.url)))
|
16
|
+
Subfinder::Parser::Download.new(find_download_link(open_online_document(DOMAIN + target_uri))).save
|
17
|
+
end
|
18
|
+
|
19
|
+
def open_online_document(url)
|
20
|
+
open url
|
21
|
+
rescue StandardError => e
|
22
|
+
Logger.info "Error when connecting to '#{url}'\n Error message: #{e}\n".red
|
23
|
+
abort('Check your internet connection or VPN and try again')
|
24
|
+
end
|
25
|
+
|
26
|
+
def find_download_link(page)
|
27
|
+
doc = Nokogiri::HTML(page)
|
28
|
+
download_link = nil
|
29
|
+
doc.css('.download').each do |link|
|
30
|
+
download_link = link.xpath('./a/@href').to_s.strip # link
|
31
|
+
end
|
32
|
+
Logger.debug "download_link: #{download_link}"
|
33
|
+
DOMAIN + download_link
|
34
|
+
end
|
35
|
+
|
36
|
+
def find_link(links)
|
37
|
+
max_match_point = 0
|
38
|
+
winner = ''
|
39
|
+
|
40
|
+
links.each do |link|
|
41
|
+
next if link[0] != Config.language
|
42
|
+
|
43
|
+
match_point = match_point_for link[1]
|
44
|
+
if match_point > max_match_point
|
45
|
+
max_match_point = match_point
|
46
|
+
winner = link[2]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
Logger.debug "winner is #{winner}"
|
50
|
+
winner
|
51
|
+
end
|
52
|
+
|
53
|
+
def match_point_for(target)
|
54
|
+
point = 0
|
55
|
+
file_name_array = @file_name.split('.')
|
56
|
+
# next we want to know if name of the sub is seprataed by . or space
|
57
|
+
target_array = target.split('.').size > target.split(' ').size ? target.split('.') : target.split(' ')
|
58
|
+
target_array = target_array.map(&:downcase)
|
59
|
+
|
60
|
+
file_name_array.each do |word|
|
61
|
+
point += 1 if target_array.include? word.downcase
|
62
|
+
end
|
63
|
+
(point * 100) / file_name_array.size
|
64
|
+
end
|
65
|
+
|
66
|
+
def create_links_list(page)
|
67
|
+
array = []
|
68
|
+
doc = Nokogiri::HTML(page)
|
69
|
+
doc.xpath('//table//tr').each do |link|
|
70
|
+
next if link.xpath('./td/a/span/text()')[0].nil? # language
|
71
|
+
|
72
|
+
array << [convert_to_code(link.xpath('./td/a/span/text()')[0].to_s.strip), # language
|
73
|
+
link.xpath('./td/a/span/text()')[1].to_s.strip, # name
|
74
|
+
link.xpath('./td/a/@href')[0].to_s.strip] # link
|
75
|
+
end
|
76
|
+
Logger.debug "array_list: #{array}"
|
77
|
+
array
|
78
|
+
end
|
79
|
+
|
80
|
+
def convert_to_code(language)
|
81
|
+
case language
|
82
|
+
when 'Farsi/Persian'
|
83
|
+
'fa'
|
84
|
+
when 'English'
|
85
|
+
'en'
|
86
|
+
else
|
87
|
+
language
|
88
|
+
end
|
89
|
+
# TODO: add other languages codes
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Subfinder
|
2
|
+
class Subtitle
|
3
|
+
def initialize
|
4
|
+
@success = 0
|
5
|
+
@failure = 0
|
6
|
+
end
|
7
|
+
|
8
|
+
def match
|
9
|
+
Subfinder::Parser::Files.list.each do |video_file|
|
10
|
+
next unless Subfinder::Config.video_formats.include? File.extname(video_file)
|
11
|
+
next if subtitle_exists? video_file
|
12
|
+
|
13
|
+
if episode_number(video_file).nil?
|
14
|
+
Logger.info "Can not find the episode and season number for: #{File.basename(video_file)}".red
|
15
|
+
@failure += 1
|
16
|
+
next
|
17
|
+
else
|
18
|
+
find_subtitle_for video_file
|
19
|
+
end
|
20
|
+
end
|
21
|
+
Logger.info "Sub added: #{@success}, Sub not found: #{@failure}, Total file proccessed: #{@failure + @success}".green
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def episode_number(video_file)
|
27
|
+
video_file.scan(/[a-zA-Z]+\d+\d+[a-zA-Z]+\d+\d/).first.downcase
|
28
|
+
end
|
29
|
+
|
30
|
+
def subtitle_exists?(video_file)
|
31
|
+
return true if Subfinder::Parser::Files.list.include? video_file.split('.')[0..-2].join('.') + '.srt'
|
32
|
+
end
|
33
|
+
|
34
|
+
def find_subtitle_for(video_file)
|
35
|
+
subtitles = Subfinder::Parser::Files.list.select { |item| item[/#{episode_number(video_file)}/i] && item[/.srt/] }
|
36
|
+
if subtitles.empty?
|
37
|
+
Logger.info "Subtitle for #{File.basename(video_file)} is not exists on disk "
|
38
|
+
subscene = Subfinder::Parser::Subscene.new(video_file)
|
39
|
+
if !Config.url.nil? && subscene.get
|
40
|
+
Subfinder::Parser::Files.prepare_file_list
|
41
|
+
Logger.info "Subtitle downloaded for #{File.basename(video_file)}"
|
42
|
+
else
|
43
|
+
Logger.info "Subtitle can not found on Subscene for #{File.basename(video_file)}".red
|
44
|
+
Logger.info 'Please provide a url with "-u" siwtch'.red if Config.url.nil?
|
45
|
+
@failure += 1
|
46
|
+
return
|
47
|
+
end
|
48
|
+
end
|
49
|
+
rename_subtitle video_file
|
50
|
+
end
|
51
|
+
|
52
|
+
def rename_subtitle(video_file)
|
53
|
+
subtitles = Subfinder::Parser::Files.list.select { |item| item[/#{episode_number(video_file)}/i] && item[/.srt/] }
|
54
|
+
File.rename(subtitles.first, File.dirname(subtitles.first) + '/' + File.basename(video_file).split('.')[0..-2].join('.') + '.srt')
|
55
|
+
Logger.info "Subtitle renamed for: #{File.basename(video_file)}"
|
56
|
+
@success += 1
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|