subtitle_it 1.5.0 → 1.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +2 -0
- data/{README.txt → README.rdoc} +29 -9
- data/VERSION +1 -1
- data/lib/subtitle_it/bin.rb +32 -32
- data/lib/subtitle_it/subdown.rb +17 -14
- data/lib/subtitle_it/version.rb +1 -1
- data/spec/spec_helper.rb +16 -15
- data/subtitle_it.gemspec +5 -27
- metadata +8 -27
- data/Manifest.txt +0 -68
- data/setup.rb +0 -1585
data/.rspec
ADDED
data/{README.txt → README.rdoc}
RENAMED
@@ -8,15 +8,24 @@ _(____/___(___(__(___/_(_ __/___(_ __/___(___ _ _/_ __(_ __
|
|
8
8
|
Ruby tool to download, create, convert and fix subtitles.
|
9
9
|
|
10
10
|
|
11
|
-
== FEATURES
|
11
|
+
== FEATURES
|
12
12
|
|
13
|
+
* Automatic Download on the terminal
|
13
14
|
* To and from: SRT, SUB, XML(TT), YML, MPL2, RSB and ASS.
|
14
|
-
* Automatic Download from opensubtitles.org
|
15
15
|
* Fixes delays. (SrtResync)
|
16
16
|
* Compatibility with "sube" (http://github.com/vic/sube)
|
17
17
|
|
18
18
|
|
19
|
-
== SYNOPSIS
|
19
|
+
== SYNOPSIS
|
20
|
+
|
21
|
+
Download subtitle:
|
22
|
+
|
23
|
+
subtitle_it Cool-Video.avi
|
24
|
+
|
25
|
+
This will search all languages for the video. You can filter:
|
26
|
+
|
27
|
+
subtitle_it -l Eng Cool-Video.avi
|
28
|
+
|
20
29
|
|
21
30
|
Bash tool:
|
22
31
|
|
@@ -32,7 +41,7 @@ Create a template
|
|
32
41
|
subtitle_it unexistent.file
|
33
42
|
|
34
43
|
|
35
|
-
== INSTALL
|
44
|
+
== INSTALL
|
36
45
|
|
37
46
|
gem sources add http://gems.github.com
|
38
47
|
sudo gem install nofxx-subtitle_it
|
@@ -40,7 +49,8 @@ Create a template
|
|
40
49
|
|
41
50
|
== THE "Ruby Subtitle" Format - RSB
|
42
51
|
|
43
|
-
It`s just a easy way, proof of concept to edit subtitles.
|
52
|
+
It`s just a easy way, proof of concept to edit subtitles.
|
53
|
+
Here is what it looks like:
|
44
54
|
|
45
55
|
00:32 => 00:33 == Nice police work! | Thank you!
|
46
56
|
00:35 => 3 == Nice job!
|
@@ -50,7 +60,17 @@ MM:SS => MM:SS or N == TEXT | NEWLINE
|
|
50
60
|
Create a template to check it out.
|
51
61
|
|
52
62
|
|
53
|
-
==
|
63
|
+
== Automatic Download
|
64
|
+
|
65
|
+
* OpenSubtitles.org - WORK SubtitleIt Agent
|
66
|
+
* addic7ed.com - EVIL NOAPI
|
67
|
+
* legendas.tv - EVIL NOAPI
|
68
|
+
|
69
|
+
|
70
|
+
*NOAPI = Mechanize playground...
|
71
|
+
|
72
|
+
|
73
|
+
== DEV
|
54
74
|
|
55
75
|
To run tests:
|
56
76
|
|
@@ -60,7 +80,7 @@ Documentation => doc
|
|
60
80
|
Subtitle examples => spec/fixtures
|
61
81
|
|
62
82
|
|
63
|
-
== SUBTITLE EDITORS
|
83
|
+
== SUBTITLE EDITORS
|
64
84
|
|
65
85
|
Try those nice editors too, if SubtitleIt does not fit your need:
|
66
86
|
|
@@ -75,12 +95,12 @@ Aegisub: http://www.malakith.net/aegiwiki/Main_Page
|
|
75
95
|
* Marcin (tiraeth) Chwedziak - Sub format first implementation.
|
76
96
|
|
77
97
|
|
78
|
-
== TODO
|
98
|
+
== TODO
|
79
99
|
|
80
100
|
Please visit:
|
81
101
|
|
82
102
|
* http://github.com/nofxx/subtitle_it
|
83
|
-
|
103
|
+
* Support http://www.podnapisi.net/
|
84
104
|
|
85
105
|
== LICENSE:
|
86
106
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.9.0
|
data/lib/subtitle_it/bin.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# SubtitleIt
|
2
2
|
# Command line tool
|
3
|
-
module SubtitleIt
|
4
|
-
|
5
|
-
class Subwork
|
3
|
+
module SubtitleIt
|
4
|
+
|
5
|
+
class Subwork
|
6
6
|
def run!(file, format)
|
7
7
|
raise unless format
|
8
8
|
content = File.open(file, 'r')
|
@@ -12,42 +12,42 @@ module SubtitleIt
|
|
12
12
|
Bin::write_out(Bin.swap_extension(file, format), dump)
|
13
13
|
end
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
class Subdownloader
|
17
17
|
def run!(movie,lang=nil)
|
18
|
-
@movie = Movie.new(movie)
|
18
|
+
@movie = Movie.new(movie)
|
19
19
|
@down = Subdown.new
|
20
20
|
@down.log_in!
|
21
|
-
res = @down.search_subtitles(@movie, lang)
|
21
|
+
res = @down.search_subtitles(@movie, OPTIONS[:lang])
|
22
22
|
if res.length == 0
|
23
23
|
STDOUT.puts "No results found."
|
24
24
|
return
|
25
25
|
end
|
26
26
|
STDOUT.puts "Found #{res.length} result#{"s" if res.length > 1}. Choose one:\n"
|
27
27
|
res.sort.each_with_index { |r,i| STDOUT.puts print_option(r,i) }
|
28
|
-
STDOUT.puts "You can choose multiple ones, separated with spaces or a range separated with hifen."
|
29
|
-
STDOUT.printf "Choose: "
|
28
|
+
STDOUT.puts "You can choose multiple ones, separated with spaces or a range separated with hifen."
|
29
|
+
STDOUT.printf "Choose: "
|
30
30
|
choose = parse_input(STDIN.gets.chomp)
|
31
|
-
choose = choose.map { |c| res[c.to_i-1] }
|
32
|
-
STDOUT.puts "Downloading #{choose.length}
|
33
|
-
choose.each do |sub|
|
31
|
+
choose = choose.map { |c| res[c.to_i-1] }
|
32
|
+
STDOUT.puts "Downloading #{choose.length} subtitle#{'s' if choose.length > 1}..."
|
33
|
+
choose.each do |sub|
|
34
34
|
down_a_sub(sub, sub.format)
|
35
35
|
end
|
36
36
|
@down.log_out!
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
def down_a_sub(sub, format)
|
40
40
|
dump = @down.download_subtitle(sub)
|
41
41
|
movie_name = @movie.filename[0..-4]
|
42
42
|
Bin::write_out(movie_name + format, dump)
|
43
|
-
end
|
43
|
+
end
|
44
44
|
|
45
45
|
def print_option(r, index)
|
46
46
|
c = "#{index+1}) #{r.info["MovieName"]} / #{r.info["MovieYear"]} | #{r.info["SubFileName"]} | Movie score: #{r.info["MovieImdbRating"]}\n"
|
47
47
|
c << " Lang: #{r.info["SubLanguageID"].capitalize} | Format: #{r.info["SubFormat"].upcase} | Downloads: #{r.info["SubDownloadsCnt"]} | Rating: #{r.info["SubRating"]} | CDs: #{r.info["SubSumCD"]}\n"
|
48
48
|
c << " Comments: #{r.info["SubAuthorComment"]} \n\n"
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
def parse_input(input)
|
52
52
|
choose = input.split(" ").map do |c|
|
53
53
|
if c =~ /-/
|
@@ -58,32 +58,32 @@ module SubtitleIt
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
choose.flatten.uniq
|
61
|
-
end
|
61
|
+
end
|
62
62
|
end
|
63
63
|
|
64
|
-
class Bin
|
65
|
-
|
66
|
-
|
64
|
+
class Bin
|
65
|
+
|
66
|
+
|
67
67
|
def Bin.run! argv, lang=nil, format=nil, force=false, delay=nil
|
68
68
|
raise unless argv
|
69
69
|
@force = force
|
70
70
|
@format = format
|
71
|
-
|
72
|
-
unless File.exists?(argv[0])
|
71
|
+
|
72
|
+
unless File.exists?(argv[0])
|
73
73
|
# TODO generate_rsb
|
74
74
|
return
|
75
75
|
end
|
76
|
-
|
77
|
-
|
76
|
+
|
77
|
+
|
78
78
|
@file_in = argv[0]
|
79
|
-
@file_in_ext = Bin.get_extension(@file_in)
|
79
|
+
@file_in_ext = Bin.get_extension(@file_in)
|
80
80
|
if argv[1]
|
81
|
-
@file_out = argv[1]
|
81
|
+
@file_out = argv[1]
|
82
82
|
@file_out_ext = Bin.get_extension(@file_out)
|
83
83
|
@format = @file_out_ext
|
84
|
-
end
|
84
|
+
end
|
85
85
|
if MOVIE_EXTS.include? @file_in_ext
|
86
|
-
Subdownloader.new.run!(argv[0], lang)
|
86
|
+
Subdownloader.new.run!(argv[0], lang)
|
87
87
|
elsif SUB_EXTS.include? @file_in_ext
|
88
88
|
Subwork.new.run!(@file_in, @format)
|
89
89
|
else
|
@@ -94,15 +94,15 @@ module SubtitleIt
|
|
94
94
|
puts e.message
|
95
95
|
exit 1
|
96
96
|
end
|
97
|
-
|
97
|
+
|
98
98
|
def Bin.get_extension(file)
|
99
99
|
raise unless file =~ /\./
|
100
100
|
file.split(".").last
|
101
101
|
end
|
102
|
-
|
102
|
+
|
103
103
|
def Bin.get_enc_platform(filename)
|
104
104
|
raise unless File.exist?(filename)
|
105
|
-
File.open(filename, 'r') do |fd|
|
105
|
+
File.open(filename, 'r') do |fd|
|
106
106
|
fd.gets =~ /\r\n/ ? "WIN" : "UNIX"
|
107
107
|
end
|
108
108
|
end
|
@@ -112,19 +112,19 @@ module SubtitleIt
|
|
112
112
|
f[-3..-1] = extension
|
113
113
|
f
|
114
114
|
end
|
115
|
-
|
115
|
+
|
116
116
|
def Bin.print_languages
|
117
117
|
STDOUT.puts "CODE | LANGUAGE"
|
118
118
|
LANGS.each do |l|
|
119
119
|
STDOUT.puts " #{l[0]} | #{l[1]}"
|
120
120
|
end
|
121
121
|
end
|
122
|
-
|
122
|
+
|
123
123
|
def Bin.write_out(filename,dump)
|
124
124
|
if File.exists?(filename) && !@force
|
125
125
|
STDOUT.puts "File exists. #{filename}"
|
126
126
|
else
|
127
|
-
File.open(filename, 'w') {|f| f.write(dump) }
|
127
|
+
File.open(filename, 'w') {|f| f.write(dump) }
|
128
128
|
STDOUT.puts "Done. Wrote: #{filename}."
|
129
129
|
end
|
130
130
|
end
|
data/lib/subtitle_it/subdown.rb
CHANGED
@@ -23,7 +23,7 @@ module SubtitleIt
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def log_in!
|
26
|
-
result =
|
26
|
+
result = request('LogIn', '', '', '', USER_AGENT)
|
27
27
|
@token = result['token'].to_s
|
28
28
|
end
|
29
29
|
|
@@ -32,25 +32,25 @@ module SubtitleIt
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def log_out!
|
35
|
-
|
35
|
+
request('LogOut')
|
36
36
|
@token = nil
|
37
37
|
end
|
38
38
|
|
39
39
|
def server_info
|
40
|
-
|
40
|
+
request('ServerInfo')
|
41
41
|
end
|
42
42
|
|
43
|
-
def search_subtitles(movie,
|
44
|
-
lang_name, lang_code = LANGS[lang_id.to_sym] if lang_id
|
45
|
-
print "Searching for "
|
46
|
-
puts lang_id ? lang_name + "..." : "all languages."
|
43
|
+
def search_subtitles(movie, lang_name=nil)
|
44
|
+
# lang_name, lang_code = LANGS[lang_id.to_sym] if lang_id
|
45
|
+
# print "Searching for "
|
46
|
+
# puts lang_id ? lang_name + "..." : "all languages."
|
47
47
|
args = {
|
48
|
-
'sublanguageid' => lang_name,
|
48
|
+
'sublanguageid' => lang_name || "",
|
49
49
|
'moviehash' => movie.haxx,
|
50
50
|
'moviebytesize' => movie.size
|
51
51
|
}
|
52
52
|
|
53
|
-
result =
|
53
|
+
result = request('SearchSubtitles', [args])
|
54
54
|
return [] unless result['data'] # if no results result['data'] == false
|
55
55
|
result['data'].inject([]) do |subs, sub_info|
|
56
56
|
subs << Subtitle.new({:info => sub_info})
|
@@ -59,7 +59,7 @@ module SubtitleIt
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def download_subtitle(sub)
|
62
|
-
result =
|
62
|
+
result = request('DownloadSubtitles', [sub.osdb_id])
|
63
63
|
sub.data = self.class.decode_and_unzip(result['data'][0]['data'])
|
64
64
|
end
|
65
65
|
|
@@ -67,7 +67,7 @@ module SubtitleIt
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def imdb_info(movie)
|
70
|
-
result =
|
70
|
+
result = request('CheckMovieHash', [movie.haxx])
|
71
71
|
movie.info = result['data'][movie.haxx] # TODO: Handle if no result for movie
|
72
72
|
end
|
73
73
|
|
@@ -94,14 +94,17 @@ module SubtitleIt
|
|
94
94
|
|
95
95
|
private
|
96
96
|
|
97
|
-
def
|
97
|
+
def request(method, *args)
|
98
|
+
|
98
99
|
unless NO_TOKEN.include? method
|
99
100
|
raise 'Need to be logged in for this.' unless logged_in?
|
100
101
|
args = [@token, *args]
|
101
102
|
end
|
102
103
|
|
104
|
+
p method, args
|
103
105
|
result = @client.call(method, *args)
|
104
|
-
|
106
|
+
p result
|
107
|
+
# $LOG.debug "Client#call #{method}, #{args.inspect}: #{result.inspect}"
|
105
108
|
|
106
109
|
unless self.class.result_status_ok?(result)
|
107
110
|
raise XMLRPC::FaultException.new(result['status'].to_i, result['status'][4..-1]) # 'status' of the form 'XXX Message'
|
@@ -116,7 +119,7 @@ module SubtitleIt
|
|
116
119
|
end
|
117
120
|
|
118
121
|
def prevent_session_expiration
|
119
|
-
|
122
|
+
request('NoOperation')
|
120
123
|
end
|
121
124
|
|
122
125
|
def self.decode_and_unzip(data)
|
data/lib/subtitle_it/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'rspec'
|
2
|
+
require 'rspec_spinner'
|
2
3
|
|
3
4
|
$:.unshift(File.dirname(__FILE__) + '/../lib')
|
4
5
|
require 'subtitle_it'
|
@@ -6,35 +7,35 @@ include SubtitleIt
|
|
6
7
|
|
7
8
|
module SubFixtures
|
8
9
|
def sub_fixture
|
9
|
-
File.open(File.expand_path(File.dirname(__FILE__) + '/fixtures/pulpfiction.sub'))
|
10
|
+
File.open(File.expand_path(File.dirname(__FILE__) + '/fixtures/pulpfiction.sub'))
|
10
11
|
end
|
11
|
-
|
12
|
+
|
12
13
|
def srt_fixture
|
13
|
-
File.open(File.expand_path(File.dirname(__FILE__) + '/fixtures/godfather.srt'))
|
14
|
+
File.open(File.expand_path(File.dirname(__FILE__) + '/fixtures/godfather.srt'))
|
14
15
|
end
|
15
|
-
|
16
|
+
|
16
17
|
def yml_fixture
|
17
|
-
File.open(File.expand_path(File.dirname(__FILE__) + '/fixtures/sincity.yml'))
|
18
|
+
File.open(File.expand_path(File.dirname(__FILE__) + '/fixtures/sincity.yml'))
|
18
19
|
end
|
19
|
-
|
20
|
+
|
20
21
|
def rsb_fixture
|
21
|
-
File.open(File.expand_path(File.dirname(__FILE__) + '/fixtures/pseudo.rsb'))
|
22
|
-
end
|
23
|
-
|
22
|
+
File.open(File.expand_path(File.dirname(__FILE__) + '/fixtures/pseudo.rsb'))
|
23
|
+
end
|
24
|
+
|
24
25
|
def xml_fixture
|
25
|
-
File.open(File.expand_path(File.dirname(__FILE__) + '/fixtures/movie.xml'))
|
26
|
-
end
|
27
|
-
|
26
|
+
File.open(File.expand_path(File.dirname(__FILE__) + '/fixtures/movie.xml'))
|
27
|
+
end
|
28
|
+
|
28
29
|
def mpl_fixture
|
29
|
-
File.open(File.expand_path(File.dirname(__FILE__) + '/fixtures/puplfiction.mpl'))
|
30
|
-
end
|
30
|
+
File.open(File.expand_path(File.dirname(__FILE__) + '/fixtures/puplfiction.mpl'))
|
31
|
+
end
|
31
32
|
end
|
32
33
|
|
33
34
|
|
34
35
|
# ##
|
35
36
|
# rSpec Hash additions.
|
36
37
|
#
|
37
|
-
# From
|
38
|
+
# From
|
38
39
|
# * http://wincent.com/knowledge-base/Fixtures_considered_harmful%3F
|
39
40
|
# * Neil Rahilly
|
40
41
|
class Hash
|
data/subtitle_it.gemspec
CHANGED
@@ -5,23 +5,23 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{subtitle_it}
|
8
|
-
s.version = "1.
|
8
|
+
s.version = "1.9.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Marcos Piccinini"]
|
12
|
-
s.date = %q{2011-
|
12
|
+
s.date = %q{2011-05-30}
|
13
13
|
s.default_executable = %q{subtitle_it}
|
14
14
|
s.description = %q{Download, edit and create subtitles. Supports various formats.}
|
15
15
|
s.email = %q{x@nofxx.com}
|
16
16
|
s.executables = ["subtitle_it"]
|
17
17
|
s.extra_rdoc_files = [
|
18
|
-
"README.
|
18
|
+
"README.rdoc"
|
19
19
|
]
|
20
20
|
s.files = [
|
21
|
+
".rspec",
|
21
22
|
"History.txt",
|
22
23
|
"License.txt",
|
23
|
-
"
|
24
|
-
"README.txt",
|
24
|
+
"README.rdoc",
|
25
25
|
"Rakefile",
|
26
26
|
"VERSION",
|
27
27
|
"bin/subtitle_it",
|
@@ -52,7 +52,6 @@ Gem::Specification.new do |s|
|
|
52
52
|
"script/destroy",
|
53
53
|
"script/generate",
|
54
54
|
"script/txt2html",
|
55
|
-
"setup.rb",
|
56
55
|
"spec/fixtures/godfather.srt",
|
57
56
|
"spec/fixtures/huge.ass",
|
58
57
|
"spec/fixtures/movie.xml",
|
@@ -89,27 +88,6 @@ Gem::Specification.new do |s|
|
|
89
88
|
s.require_paths = ["lib"]
|
90
89
|
s.rubygems_version = %q{1.3.7}
|
91
90
|
s.summary = %q{Download, edit and create subtitles.}
|
92
|
-
s.test_files = [
|
93
|
-
"spec/spec_helper.rb",
|
94
|
-
"spec/subtitle_it/bin_spec.rb",
|
95
|
-
"spec/subtitle_it/fixes_spec.rb",
|
96
|
-
"spec/subtitle_it/formats/ass_spec.rb",
|
97
|
-
"spec/subtitle_it/formats/mpl_spec.rb",
|
98
|
-
"spec/subtitle_it/formats/rsb_spec.rb",
|
99
|
-
"spec/subtitle_it/formats/srt_spec.rb",
|
100
|
-
"spec/subtitle_it/formats/sub_spec.rb",
|
101
|
-
"spec/subtitle_it/formats/xml_spec.rb",
|
102
|
-
"spec/subtitle_it/formats/yml_spec.rb",
|
103
|
-
"spec/subtitle_it/generator_spec.rb",
|
104
|
-
"spec/subtitle_it/movie_hasher_spec.rb",
|
105
|
-
"spec/subtitle_it/movie_spec.rb",
|
106
|
-
"spec/subtitle_it/subdown_spec.rb",
|
107
|
-
"spec/subtitle_it/subline_spec.rb",
|
108
|
-
"spec/subtitle_it/substyle_spec.rb",
|
109
|
-
"spec/subtitle_it/subtime_spec.rb",
|
110
|
-
"spec/subtitle_it/subtitle_spec.rb",
|
111
|
-
"spec/subtitle_it_spec.rb"
|
112
|
-
]
|
113
91
|
|
114
92
|
if s.respond_to? :specification_version then
|
115
93
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|