suby 0.1.0 → 0.1.1
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.
- data/bin/suby +9 -9
- data/lib/suby.rb +59 -53
- data/lib/suby/downloader.rb +16 -4
- data/lib/suby/downloader/addic7ed.rb +6 -2
- data/lib/suby/filename_parser.rb +1 -1
- data/lib/suby/interface.rb +17 -0
- data/suby.gemspec +3 -2
- metadata +20 -8
data/bin/suby
CHANGED
@@ -5,18 +5,18 @@ require 'optparse'
|
|
5
5
|
|
6
6
|
options = {}
|
7
7
|
option_parser = OptionParser.new do |opts|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
opts.banner = "#{File.basename $0} [options] video"
|
9
|
+
opts.separator ' Find and download subtitles for the given video file'
|
10
|
+
opts.separator "\nOptions:"
|
11
11
|
|
12
|
-
|
12
|
+
opts.on '-l', '--lang LANG = en', 'Lang for subtitles' do |lang|
|
13
13
|
options[:lang] = lang
|
14
|
-
|
14
|
+
end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
opts.on '-h', '--help', 'Show usage' do
|
17
|
+
puts opts
|
18
|
+
exit
|
19
|
+
end
|
20
20
|
end
|
21
21
|
|
22
22
|
option_parser.parse!
|
data/lib/suby.rb
CHANGED
@@ -1,71 +1,77 @@
|
|
1
1
|
require_relative 'suby/downloader_error'
|
2
2
|
require_relative 'suby/not_found_error'
|
3
|
+
require_relative 'suby/filename_parser'
|
3
4
|
require_relative 'suby/downloader'
|
4
|
-
|
5
|
+
require_relative 'suby/interface'
|
5
6
|
|
6
|
-
|
7
|
-
|
7
|
+
gem 'rubyzip2'
|
8
|
+
require 'zip'
|
8
9
|
|
9
|
-
|
10
|
+
module Suby
|
11
|
+
SUB_EXTENSIONS = %w[srt sub].map { |ext| ".#{ext}" }
|
10
12
|
TEMP_ARCHIVE_NAME = '__archive__'
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
-
next puts "Skipping: #{file}" if SUB_EXTENSIONS.any? { |ext|
|
15
|
-
File.exist? File.basename(file, File.extname(file)) + ".#{ext}"
|
16
|
-
}
|
17
|
-
download_subtitles_for_file(file, options)
|
18
|
-
}
|
19
|
-
end
|
14
|
+
class << self
|
15
|
+
include Interface
|
20
16
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
17
|
+
def download_subtitles(files, options = {})
|
18
|
+
files.each { |file|
|
19
|
+
next if Dir.exist?(file) or SUB_EXTENSIONS.include?(File.extname(file))
|
20
|
+
next puts "Skipping: #{file}" if SUB_EXTENSIONS.any? { |ext|
|
21
|
+
File.exist? File.basename(file, File.extname(file)) + ext
|
22
|
+
}
|
23
|
+
download_subtitles_for_file(file, options)
|
25
24
|
}
|
26
|
-
|
27
|
-
|
25
|
+
end
|
26
|
+
|
27
|
+
def download_subtitles_for_file(file, options)
|
28
|
+
begin
|
29
|
+
show, season, episode = FilenameParser.parse(file)
|
30
|
+
puts file
|
31
|
+
success = Downloader::DOWNLOADERS.find { |downloader_class|
|
32
|
+
try_downloader(downloader_class.new(file, show, season, episode, options[:lang]))
|
33
|
+
}
|
34
|
+
error "No downloader could find subtitles for #{file}" unless success
|
35
|
+
rescue
|
36
|
+
error " The download of the subtitles failed for #{file}:"
|
37
|
+
error " #{$!.class}: #{$!.message}"
|
38
|
+
puts $!.backtrace.map { |line| line.prepend ' '*4 }
|
28
39
|
end
|
29
|
-
rescue
|
30
|
-
puts " The download of the subtitles failed for #{file}:"
|
31
|
-
puts " #{$!.class}: #{$!.message}"
|
32
|
-
puts $!.backtrace.map { |line| line.prepend ' '*4 }
|
33
40
|
end
|
34
|
-
end
|
35
41
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
42
|
+
def try_downloader(downloader)
|
43
|
+
begin
|
44
|
+
print " #{downloader.to_s.ljust(20)}"
|
45
|
+
downloader.download
|
46
|
+
rescue Suby::NotFoundError => error
|
47
|
+
failure "Failed: #{error.message}"
|
48
|
+
false
|
49
|
+
rescue Suby::DownloaderError => error
|
50
|
+
error "Error: #{error.message}"
|
51
|
+
false
|
52
|
+
else
|
53
|
+
success "Found"
|
54
|
+
true
|
55
|
+
end
|
50
56
|
end
|
51
|
-
end
|
52
57
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
58
|
+
def extract_sub_from_archive(archive, format, basename)
|
59
|
+
case format
|
60
|
+
when :zip
|
61
|
+
Zip::ZipFile.open(archive) { |zip|
|
62
|
+
sub = zip.entries.find { |entry|
|
63
|
+
entry.to_s =~ /#{Regexp.union SUB_EXTENSIONS}$/
|
64
|
+
}
|
65
|
+
raise "no subtitles in #{archive}" unless sub
|
66
|
+
name = basename + File.extname(sub.to_s)
|
67
|
+
sub.extract(name)
|
59
68
|
}
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
69
|
+
else
|
70
|
+
raise "unknown archive type (#{archive})"
|
71
|
+
end
|
72
|
+
ensure
|
73
|
+
# Cleaning
|
74
|
+
File.unlink archive if File.exist? archive
|
66
75
|
end
|
67
|
-
ensure
|
68
|
-
# Cleaning
|
69
|
-
File.unlink archive if File.exist? archive
|
70
76
|
end
|
71
77
|
end
|
data/lib/suby/downloader.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'net/http'
|
2
2
|
require 'cgi/util'
|
3
3
|
require 'nokogiri'
|
4
|
-
require_relative 'filename_parser'
|
5
4
|
|
6
5
|
module Suby
|
7
6
|
class Downloader
|
@@ -12,9 +11,22 @@ module Suby
|
|
12
11
|
|
13
12
|
attr_reader :show, :season, :episode, :file, :lang
|
14
13
|
|
15
|
-
def initialize(file,
|
16
|
-
@file
|
17
|
-
@
|
14
|
+
def initialize(file, *args)
|
15
|
+
@file = file
|
16
|
+
@lang = (args.last || 'en').to_sym
|
17
|
+
case args.size
|
18
|
+
when 0..1
|
19
|
+
@show, @season, @episode = FilenameParser.parse(file)
|
20
|
+
when 3..4
|
21
|
+
@show, @season, @episode = args
|
22
|
+
else
|
23
|
+
raise ArgumentError, "wrong number of arguments: #{args.size+1} for " +
|
24
|
+
"(file, [show, season, episode], [lang])"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_s
|
29
|
+
self.class.name.sub(/^.+::/, '')
|
18
30
|
end
|
19
31
|
|
20
32
|
def http
|
@@ -26,6 +26,8 @@ module Suby
|
|
26
26
|
|
27
27
|
def subtitles_body
|
28
28
|
body = subtitles_response.body
|
29
|
+
body.strip!
|
30
|
+
raise NotFoundError, "show/season/episode not found" if body.empty?
|
29
31
|
if body.include? FILTER_IGNORED
|
30
32
|
raise NotFoundError, "no subtitle available"
|
31
33
|
end
|
@@ -42,10 +44,12 @@ module Suby
|
|
42
44
|
end
|
43
45
|
|
44
46
|
def download_url
|
45
|
-
|
47
|
+
link = Nokogiri(subtitles_body).css('a').find { |a|
|
46
48
|
a[:href].start_with? '/original/' or
|
47
49
|
a[:href].start_with? '/updated/'
|
48
|
-
}
|
50
|
+
}
|
51
|
+
raise NotFoundError, "show/season/episode not found" unless link
|
52
|
+
download_url = link[:href]
|
49
53
|
|
50
54
|
redirected_url download_url
|
51
55
|
end
|
data/lib/suby/filename_parser.rb
CHANGED
@@ -82,7 +82,7 @@ module Suby
|
|
82
82
|
found = FILENAME_PATTERNS.find { |pattern|
|
83
83
|
pattern =~ filename
|
84
84
|
}
|
85
|
-
raise "
|
85
|
+
raise "Wrong file format (#{file})" unless found
|
86
86
|
[clean_show_name($~[:show]), $~[:season].to_i, $~[:episode].to_i]
|
87
87
|
end
|
88
88
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'term/ansicolor'
|
2
|
+
|
3
|
+
module Suby
|
4
|
+
module Interface
|
5
|
+
def success message
|
6
|
+
puts Term::ANSIColor.green message
|
7
|
+
end
|
8
|
+
|
9
|
+
def failure message
|
10
|
+
puts Term::ANSIColor.blue message
|
11
|
+
end
|
12
|
+
|
13
|
+
def error message
|
14
|
+
puts Term::ANSIColor.red message
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/suby.gemspec
CHANGED
@@ -11,7 +11,8 @@ Gem::Specification.new do |s|
|
|
11
11
|
|
12
12
|
s.required_ruby_version = '>= 1.9.2'
|
13
13
|
s.add_dependency 'nokogiri'
|
14
|
-
s.add_dependency '
|
14
|
+
s.add_dependency 'rubyzip2'
|
15
|
+
s.add_dependency 'term-ansicolor'
|
15
16
|
|
16
|
-
s.version = '0.1.
|
17
|
+
s.version = '0.1.1'
|
17
18
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: suby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-08-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
16
|
-
requirement: &
|
16
|
+
requirement: &2156836860 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2156836860
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
|
-
name:
|
27
|
-
requirement: &
|
26
|
+
name: rubyzip2
|
27
|
+
requirement: &2156836400 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,18 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2156836400
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: term-ansicolor
|
38
|
+
requirement: &2156835980 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *2156835980
|
36
47
|
description: Find and download subtitles
|
37
48
|
email: eregontp@gmail.com
|
38
49
|
executables:
|
@@ -46,6 +57,7 @@ files:
|
|
46
57
|
- lib/suby/downloader.rb
|
47
58
|
- lib/suby/downloader_error.rb
|
48
59
|
- lib/suby/filename_parser.rb
|
60
|
+
- lib/suby/interface.rb
|
49
61
|
- lib/suby/not_found_error.rb
|
50
62
|
- lib/suby.rb
|
51
63
|
- .gitignore
|
@@ -71,7 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
83
|
version: '0'
|
72
84
|
requirements: []
|
73
85
|
rubyforge_project:
|
74
|
-
rubygems_version: 1.8.6
|
86
|
+
rubygems_version: 1.8.6.1
|
75
87
|
signing_key:
|
76
88
|
specification_version: 3
|
77
89
|
summary: Subtitles' downloader
|