subtitle_it 0.7.7 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/License.txt +2 -2
- data/README.txt +31 -24
- data/Rakefile +21 -4
- data/VERSION +1 -0
- data/bin/subtitle_it +25 -20
- data/lib/subtitle_it/formats/ass.rb +1 -1
- data/lib/subtitle_it/formats/mpl.rb +4 -4
- data/lib/subtitle_it/formats/rsb.rb +9 -9
- data/lib/subtitle_it/formats/sub.rb +16 -15
- data/lib/subtitle_it/formats/xml.rb +5 -5
- data/lib/subtitle_it/languages.rb +14 -10
- data/lib/subtitle_it/movie.rb +1 -2
- data/lib/subtitle_it/subdown.rb +52 -33
- data/lib/subtitle_it/subtime.rb +19 -15
- data/lib/subtitle_it/version.rb +3 -3
- data/lib/subtitle_it.rb +9 -0
- data/spec/fixtures/pseudo.rsb +2 -2
- data/spec/spec_helper.rb +2 -8
- data/spec/subtitle_it/formats/sub_spec.rb +15 -15
- data/spec/subtitle_it/formats/xml_spec.rb +24 -24
- data/spec/subtitle_it/subdown_spec.rb +76 -36
- data/subtitle_it.gemspec +110 -24
- metadata +53 -44
- data/.autotest +0 -19
- data/README.markdown +0 -41
- data/spec/spec.opts +0 -1
data/License.txt
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c) 2008 Marcos Piccinini,
|
1
|
+
Copyright (c) 2008 Marcos Piccinini, Giovanni Rapagnani, Warlley Rezende
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
a copy of this software and associated documentation files (the
|
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
17
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
18
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
19
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.txt
CHANGED
@@ -1,4 +1,9 @@
|
|
1
|
-
|
1
|
+
__ __
|
2
|
+
/ ) / , / /
|
3
|
+
----\--------------/__--_/_------_/_---/----__-----/---_/_-
|
4
|
+
\ / / / ) / / / / /___) / /
|
5
|
+
_(____/___(___(__(___/_(_ __/___(_ __/___(___ _ _/_ __(_ __
|
6
|
+
|
2
7
|
|
3
8
|
Ruby tool to download, create, convert and fix subtitles.
|
4
9
|
|
@@ -6,22 +11,9 @@ Ruby tool to download, create, convert and fix subtitles.
|
|
6
11
|
== FEATURES:
|
7
12
|
|
8
13
|
* To and from: SRT, SUB, XML(TT), YML, MPL2, RSB and ASS.
|
9
|
-
* Download from opensubtitles.org
|
14
|
+
* Automatic Download from opensubtitles.org
|
10
15
|
* Fixes delays. (SrtResync)
|
11
|
-
|
12
|
-
|
13
|
-
== TODO:
|
14
|
-
|
15
|
-
* Support styles
|
16
16
|
* Compatibility with "sube" (http://github.com/vic/sube)
|
17
|
-
* Fix delays
|
18
|
-
* Convert 1 to 2 CD`s and versa-vice
|
19
|
-
* ASS Format (Yes, for the funny of it...)
|
20
|
-
|
21
|
-
|
22
|
-
== REQUIREMENTS:
|
23
|
-
|
24
|
-
* hpricot
|
25
17
|
|
26
18
|
|
27
19
|
== SYNOPSIS:
|
@@ -35,10 +27,10 @@ Convert a srt to sub:
|
|
35
27
|
|
36
28
|
Add a delay of 1 minute:
|
37
29
|
subtitle_it -d 60 in.srt
|
38
|
-
|
30
|
+
|
39
31
|
Create a template
|
40
|
-
subtitle_it unexistent.file
|
41
|
-
|
32
|
+
subtitle_it unexistent.file
|
33
|
+
|
42
34
|
|
43
35
|
== INSTALL:
|
44
36
|
|
@@ -51,9 +43,11 @@ Create a template
|
|
51
43
|
It`s just a easy way, proof of concept to edit subtitles. Here is what it looks like:
|
52
44
|
|
53
45
|
00:32 => 00:33 == Nice police work! | Thank you!
|
54
|
-
|
46
|
+
00:35 => 3 == Nice job!
|
47
|
+
|
48
|
+
MM:SS => MM:SS or N == TEXT | NEWLINE
|
55
49
|
|
56
|
-
Create a template to check it out.
|
50
|
+
Create a template to check it out.
|
57
51
|
|
58
52
|
|
59
53
|
== DEV:
|
@@ -61,10 +55,10 @@ Create a template to check it out.
|
|
61
55
|
To run tests:
|
62
56
|
|
63
57
|
rake spec or autotest
|
64
|
-
|
58
|
+
|
65
59
|
Documentation => doc
|
66
60
|
Subtitle examples => spec/fixtures
|
67
|
-
|
61
|
+
|
68
62
|
|
69
63
|
== SUBTITLE EDITORS:
|
70
64
|
|
@@ -75,11 +69,24 @@ Jubler: http://www.jubler.org/
|
|
75
69
|
Aegisub: http://www.malakith.net/aegiwiki/Main_Page
|
76
70
|
|
77
71
|
|
72
|
+
== THANKS
|
73
|
+
|
74
|
+
* Johanlunds - Opensubtitle.org code (to be used as a gem soon).
|
75
|
+
* Marcin (tiraeth) Chwedziak - Sub format first implementation.
|
76
|
+
|
77
|
+
|
78
|
+
== TODO:
|
79
|
+
|
80
|
+
Please visit:
|
81
|
+
|
82
|
+
* http://github.com/nofxx/subtitle_it
|
83
|
+
|
84
|
+
|
78
85
|
== LICENSE:
|
79
86
|
|
80
87
|
(The MIT License)
|
81
88
|
|
82
|
-
Copyright (c) 2008 Marcos Piccinini,
|
89
|
+
Copyright (c) 2008 Marcos Piccinini, Giovanni Rapagnani, Warlley Rezende
|
83
90
|
|
84
91
|
|
85
92
|
Permission is hereby granted, free of charge, to any person obtaining
|
@@ -99,4 +106,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
99
106
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
100
107
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
101
108
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
102
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
109
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
CHANGED
@@ -1,4 +1,21 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
|
4
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "subtitle_it"
|
8
|
+
gem.summary = "Download, edit and create subtitles."
|
9
|
+
gem.description = "Download, edit and create subtitles. Supports various formats."
|
10
|
+
gem.email = "x@nofxx.com"
|
11
|
+
gem.homepage = "http://github.com/nofxx/subtitle_it"
|
12
|
+
gem.authors = ["Marcos Piccinini"]
|
13
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
14
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
|
+
end
|
16
|
+
Jeweler::GemcutterTasks.new
|
17
|
+
rescue LoadError
|
18
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
19
|
+
end
|
20
|
+
|
21
|
+
task :default => :build
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.5.0
|
data/bin/subtitle_it
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# SubtitleIt
|
3
3
|
#
|
4
|
-
# Created on 2008-
|
5
|
-
#
|
4
|
+
# Created on 2008-09-04.
|
5
|
+
# Copyleft (c) 2008. MIT License.
|
6
6
|
#
|
7
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
8
|
begin
|
8
9
|
require 'rubygems'
|
9
10
|
rescue LoadError
|
@@ -28,28 +29,33 @@ SubtitleIt - Download, convert and create subtitles.
|
|
28
29
|
|
29
30
|
Usage: #{File.basename($0)} [options] movie or file_in [file_out]
|
30
31
|
|
31
|
-
Options are:
|
32
|
-
|
33
32
|
BANNER
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
33
|
+
|
34
|
+
opts.separator " Options are:"
|
35
|
+
|
36
|
+
opts.on("-l", "--language [LANGUAGE]", String,
|
37
|
+
"Language to search subtitles for, try it empty to see the supported ones.") do |ol|
|
38
|
+
if ol.nil?
|
39
|
+
puts Subdown.subtitle_languages
|
40
|
+
exit
|
41
|
+
end
|
42
|
+
OPTIONS[:lang] = ol
|
43
|
+
end
|
38
44
|
|
39
45
|
opts.on("-c", "--convert=FORMAT", String,
|
40
|
-
"Format to convert to") { |OPTIONS[:format]
|
41
|
-
|
46
|
+
"Format to convert to") { |of| OPTIONS[:format] = of }
|
47
|
+
|
42
48
|
opts.on("-d", "--delay=DELAY", Float,
|
43
|
-
"Delay to add/remove") { |OPTIONS[:delay]
|
44
|
-
|
45
|
-
opts.on("-f", "--force", "Force overwrite") { OPTIONS[:force] = true }
|
46
|
-
|
49
|
+
"Delay to add/remove") { |od| OPTIONS[:delay] = od }
|
50
|
+
|
51
|
+
opts.on("-f", "--force", "Force overwrite") { OPTIONS[:force] = true }
|
52
|
+
|
47
53
|
opts.on("-h", "--help",
|
48
|
-
"Show this help message.") { puts opts; exit }
|
49
|
-
|
54
|
+
"Show this help message.") { puts opts; exit }
|
55
|
+
|
50
56
|
opts.on("-v", "--version",
|
51
|
-
"Show program version") { puts "SubtitleIt v#{SubtitleIt::VERSION::STRING}"; exit }
|
52
|
-
|
57
|
+
"Show program version") { puts "SubtitleIt v#{SubtitleIt::VERSION::STRING}"; exit }
|
58
|
+
|
53
59
|
opts.parse!(ARGV)
|
54
60
|
|
55
61
|
if MANDATORY_OPTIONS && MANDATORY_OPTIONS.find { |option| OPTIONS[option.to_sym].nil? }
|
@@ -58,9 +64,8 @@ BANNER
|
|
58
64
|
end
|
59
65
|
|
60
66
|
if ARGV.empty?
|
61
|
-
puts parser
|
67
|
+
puts parser
|
62
68
|
exit
|
63
69
|
else
|
64
70
|
SubtitleIt::Bin.run! ARGV, OPTIONS[:lang], OPTIONS[:format], OPTIONS[:force], OPTIONS[:delay]
|
65
71
|
end
|
66
|
-
|
@@ -9,10 +9,10 @@ module Formats
|
|
9
9
|
include PlatformEndLine
|
10
10
|
def parse_mpl
|
11
11
|
@raw.to_a.inject([]) do |i,l|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
line_data = l.scan(/^\[([0-9]{1,})\]\[([0-9]{1,})\](.+)$/)
|
13
|
+
line_data = line_data.at 0
|
14
|
+
time_on, time_off, text = line_data
|
15
|
+
time_on, time_off = [time_on.to_i, time_off.to_i].map { |t| t.to_i * 1000 }
|
16
16
|
i << Subline.new(time_on, time_off, text.chomp)
|
17
17
|
end
|
18
18
|
end
|
@@ -12,26 +12,26 @@ module Formats
|
|
12
12
|
include PlatformEndLine
|
13
13
|
def parse_rsb
|
14
14
|
inn = @raw.to_a
|
15
|
-
@title = inn.delete_at(0).split(':')[1]
|
16
|
-
@authors = inn.delete_at(0).split(':')[1]
|
17
|
-
@version = inn.delete_at(0).split(':')[1]
|
15
|
+
@title = inn.delete_at(0).split(':')[1]
|
16
|
+
@authors = inn.delete_at(0).split(':')[1]
|
17
|
+
@version = inn.delete_at(0).split(':')[1]
|
18
18
|
inn.inject([]) do |final,line|
|
19
19
|
time_on,time_off = line.split('=>').map { |t| t.strip }
|
20
|
-
text = line.split('==')[1]
|
21
|
-
final << Subline.new(time_on, time_off, text)
|
20
|
+
text = line.split('==')[1] #.strip
|
21
|
+
final << Subline.new(time_on, time_off, text ? text.strip : nil)
|
22
22
|
end
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
def to_rsb
|
26
26
|
endl = endline( @raw )
|
27
27
|
out = ["- title: #{@title}", "- authors: #{@authors}", "- version: #{@version}"]
|
28
28
|
@lines.each do |l|
|
29
29
|
out << "%s => %s == %s" % [l.time_on.to_s, l.time_off.to_s, l.text]
|
30
|
-
end
|
30
|
+
end
|
31
31
|
return out.join( endl ) + endl
|
32
32
|
#out = "- title: #{@title}\n- authors: #{@authors}\n- version: #{@version}\n"
|
33
33
|
#out << @lines.inject([]) do |i,l|
|
34
34
|
# i << "%s => %s == %s" % [l.time_on.to_s, l.time_off.to_s, l.text]
|
35
|
-
#end.join("\n")
|
36
|
-
end
|
35
|
+
#end.join("\n")
|
36
|
+
end
|
37
37
|
end
|
@@ -13,37 +13,38 @@
|
|
13
13
|
#
|
14
14
|
# Where N is ms / framerate / 1000 (ms -> s)
|
15
15
|
#
|
16
|
-
# parts of the code from 'simplesubtitler' from Marcin (tiraeth) Chwedziak
|
16
|
+
# parts of the code from 'simplesubtitler' from Marcin (tiraeth) Chwedziak
|
17
17
|
#
|
18
18
|
module Formats
|
19
19
|
include PlatformEndLine
|
20
20
|
#between our formats, what changes can be reduced to a value
|
21
21
|
def ratio
|
22
|
-
1
|
22
|
+
1
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
def parse_sub
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
26
|
+
# FIXME: 1.8 and 1.9 way of working
|
27
|
+
@raw.send(@raw.respond_to?(:lines) ? :lines : :to_a).reduce([]) do |i,l|
|
28
|
+
line_data = l.scan(/^\{([0-9]{1,})\}\{([0-9]{1,})\}(.+)$/)
|
29
|
+
line_data = line_data.at 0
|
30
|
+
time_on, time_off, text = line_data
|
31
|
+
time_on, time_off = [time_on.to_i, time_off.to_i].map do |t|
|
32
|
+
(t.to_i / @fps * 1000 / ratio).to_i
|
33
|
+
end
|
34
|
+
i << Subline.new(time_on, time_off, text ? text.chomp : nil)
|
34
35
|
end
|
35
36
|
end
|
36
|
-
|
37
|
+
|
37
38
|
def to_sub
|
38
39
|
endl = endline( @raw )
|
39
40
|
line_ary = []
|
40
|
-
@lines.each do |l|
|
41
|
+
@lines.each do |l|
|
41
42
|
line_ary << "{%d}{%d}%s" % [parse_time(l.time_on), parse_time(l.time_off), l.text]
|
42
43
|
end
|
43
44
|
return line_ary.join( endl ) + endl
|
44
45
|
end
|
45
|
-
|
46
|
+
|
46
47
|
def parse_time(n)
|
47
48
|
n.to_i / 1000 * @fps * ratio
|
48
49
|
end
|
49
|
-
end
|
50
|
+
end
|
@@ -20,9 +20,9 @@
|
|
20
20
|
# </body>
|
21
21
|
#</tt>
|
22
22
|
require 'hpricot'
|
23
|
-
module Formats
|
23
|
+
module Formats
|
24
24
|
include PlatformEndLine
|
25
|
-
|
25
|
+
|
26
26
|
def parse_xml
|
27
27
|
final = []
|
28
28
|
doc = Hpricot.XML(@raw)
|
@@ -33,7 +33,7 @@ module Formats
|
|
33
33
|
end
|
34
34
|
return final
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
def xml_lines
|
38
38
|
endl = endline( @raw )
|
39
39
|
line_ary = []
|
@@ -43,12 +43,12 @@ module Formats
|
|
43
43
|
end
|
44
44
|
return line_ary.join( endl )
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
def to_xml
|
48
48
|
endl = endline( @raw )
|
49
49
|
out = <<XML
|
50
50
|
<?xml version="1.0" encoding="UTF-8"?>
|
51
|
-
<tt xml:lang="en" xmlns="http://www.w3.org/2006/
|
51
|
+
<tt xml:lang="en" xmlns="http://www.w3.org/2006/10/ttaf1" xmlns:tts="http://www.w3.org/2006/10/ttaf1#styling">
|
52
52
|
<head>
|
53
53
|
<styling>#{@style + endl if @style}
|
54
54
|
</styling>
|
@@ -1,36 +1,40 @@
|
|
1
1
|
module SubtitleIt
|
2
|
-
#
|
3
|
-
# now I`m more lost.... opensubtitle uses a 3 chars like
|
2
|
+
# opensubtitle uses a 3 chars like
|
4
3
|
# Por => Portuguese
|
5
4
|
# Cze => Czech ....
|
5
|
+
#
|
6
|
+
# LANGUAGE / HUMAN NAME / OPENSUBTITLE CODE
|
7
|
+
#
|
8
|
+
# Need to rewrite "Portuguese" => [:pt, :por, :whatever]
|
6
9
|
LANGS = {
|
7
10
|
:aa => 'Afar',
|
8
11
|
:ab => 'Abkhazian',
|
9
12
|
:af => 'Afrikaans',
|
10
13
|
:ak => 'Akan',
|
14
|
+
:ay => 'Assyrian',
|
11
15
|
:sq => 'Albanian',
|
12
16
|
:am => 'Amharic',
|
13
17
|
:ar => 'Arabic',
|
14
|
-
:
|
18
|
+
:br => ['Brazilian', 'por'],
|
15
19
|
:hy => 'Armenian',
|
16
20
|
:bs => 'Bosnian',
|
17
21
|
:bg => 'Bulgarian',
|
18
22
|
:ca => 'Catalan',
|
19
|
-
:zh => 'Chinese',
|
20
23
|
:cs => 'Czech',
|
21
24
|
:da => 'Danish',
|
22
25
|
:nl => 'Dutch',
|
26
|
+
:en => ['English','eng'],
|
23
27
|
:et => 'Estonian',
|
24
|
-
:fr => 'French',
|
28
|
+
:fr => ['French', 'fra'],
|
25
29
|
:de => 'German',
|
26
|
-
:gl => 'Galician',
|
30
|
+
:gl => 'Galician',
|
27
31
|
:el => 'Greek',
|
28
32
|
:he => 'Hebrew',
|
29
33
|
:hi => 'Hindi',
|
30
34
|
:hr => 'Croatian',
|
31
35
|
:hu => 'Hungarian',
|
32
36
|
:is => 'Icelandic',
|
33
|
-
:id => 'Indonesian',
|
37
|
+
:id => 'Indonesian',
|
34
38
|
:it => 'Italian',
|
35
39
|
:ja => 'Japanese',
|
36
40
|
:kk => 'Kazakh',
|
@@ -54,7 +58,7 @@ module SubtitleIt
|
|
54
58
|
:uk => 'Ukrainian',
|
55
59
|
:vi => 'Vietnamese',
|
56
60
|
:ro => 'Romanian',
|
57
|
-
:
|
58
|
-
:ay => 'Assyrian'
|
61
|
+
:zh => 'Chinese'
|
59
62
|
}
|
60
|
-
|
63
|
+
|
64
|
+
end
|
data/lib/subtitle_it/movie.rb
CHANGED
@@ -9,7 +9,6 @@ module SubtitleIt
|
|
9
9
|
|
10
10
|
def initialize(filename)
|
11
11
|
@filename = filename
|
12
|
-
@haxx = nil
|
13
12
|
@info = {}
|
14
13
|
end
|
15
14
|
|
@@ -18,7 +17,7 @@ module SubtitleIt
|
|
18
17
|
end
|
19
18
|
|
20
19
|
def size
|
21
|
-
File.size(@filename)
|
20
|
+
@size ||= File.size(@filename)
|
22
21
|
end
|
23
22
|
end
|
24
23
|
end
|
data/lib/subtitle_it/subdown.rb
CHANGED
@@ -5,12 +5,14 @@ require 'stringio'
|
|
5
5
|
|
6
6
|
require 'subtitle_it/version'
|
7
7
|
require 'subtitle_it/subtitle'
|
8
|
+
require 'subtitle_it/languages'
|
8
9
|
|
9
10
|
module SubtitleIt
|
10
11
|
class Subdown
|
11
|
-
HOST = "http://
|
12
|
+
HOST = "http://api.opensubtitles.org/xml-rpc"
|
12
13
|
HOST_DEV = "http://dev.opensubtitles.org/xml-rpc"
|
13
14
|
|
15
|
+
# USER_AGENT = "SubDownloader #{SubtitleIt::VERSION::STRING}"
|
14
16
|
USER_AGENT = "SubtitleIt #{SubtitleIt::VERSION::STRING}"
|
15
17
|
|
16
18
|
NO_TOKEN = %w(ServerInfo LogIn)
|
@@ -38,11 +40,12 @@ module SubtitleIt
|
|
38
40
|
call('ServerInfo')
|
39
41
|
end
|
40
42
|
|
41
|
-
def search_subtitles(movie,
|
42
|
-
|
43
|
-
|
43
|
+
def search_subtitles(movie, lang_id=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."
|
44
47
|
args = {
|
45
|
-
'sublanguageid' =>
|
48
|
+
'sublanguageid' => lang_name,
|
46
49
|
'moviehash' => movie.haxx,
|
47
50
|
'moviebytesize' => movie.size
|
48
51
|
}
|
@@ -57,7 +60,7 @@ module SubtitleIt
|
|
57
60
|
|
58
61
|
def download_subtitle(sub)
|
59
62
|
result = call('DownloadSubtitles', [sub.osdb_id])
|
60
|
-
sub.data = self.class.decode_and_unzip(result['data'][0]['data'])
|
63
|
+
sub.data = self.class.decode_and_unzip(result['data'][0]['data'])
|
61
64
|
end
|
62
65
|
|
63
66
|
def upload_subtitle(movie, subs)
|
@@ -68,40 +71,56 @@ module SubtitleIt
|
|
68
71
|
movie.info = result['data'][movie.haxx] # TODO: Handle if no result for movie
|
69
72
|
end
|
70
73
|
|
71
|
-
def subtitle_languages
|
72
|
-
LANGS.map
|
73
|
-
|
74
|
+
def self.subtitle_languages
|
75
|
+
LANGS.map do |k, v|
|
76
|
+
"#{k} -> #{v}"
|
77
|
+
end.join("\n")
|
74
78
|
end
|
79
|
+
#
|
80
|
+
# def Subdown.opsub_id( language ) # Get the Opensubtitle.org language id from the language string (e.g. 'French' returns 'fra' )
|
81
|
+
# ary = LANGS.find do |sym_lang|
|
82
|
+
# sym_lang if sym_lang[1].downcase == language.downcase
|
83
|
+
# end
|
84
|
+
# OPSUB_LANGS[ ary[0] ]
|
85
|
+
# end
|
86
|
+
|
87
|
+
# def Subdown.subtitle_languages
|
88
|
+
# lang_ary = []
|
89
|
+
# OPSUB_LANGS.each_key do |key|
|
90
|
+
# lang_ary.push( LANGS[key] )
|
91
|
+
# end
|
92
|
+
# lang_ary.sort.inject( "" ) { |str, lang| str << lang + " " }
|
93
|
+
# end
|
75
94
|
|
76
95
|
private
|
77
96
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
97
|
+
def call(method, *args)
|
98
|
+
unless NO_TOKEN.include? method
|
99
|
+
raise 'Need to be logged in for this.' unless logged_in?
|
100
|
+
args = [@token, *args]
|
101
|
+
end
|
83
102
|
|
84
|
-
|
103
|
+
result = @client.call(method, *args)
|
85
104
|
# $LOG.debug "Client#call #{method}, #{args.inspect}: #{result.inspect}"
|
86
|
-
|
87
|
-
if !self.class.result_status_ok?(result)
|
88
|
-
raise XMLRPC::FaultException.new(result['status'].to_i, result['status'][4..-1]) # 'status' of the form 'XXX Message'
|
89
|
-
end
|
90
|
-
|
91
|
-
result
|
92
|
-
end
|
93
|
-
|
94
|
-
# Returns true if status is OK (ie. in range 200-299) or don't exists.
|
95
|
-
def self.result_status_ok?(result)
|
96
|
-
!result.key?('status') || (200...300) === result['status'].to_i
|
97
|
-
end
|
98
105
|
|
99
|
-
|
100
|
-
|
106
|
+
unless self.class.result_status_ok?(result)
|
107
|
+
raise XMLRPC::FaultException.new(result['status'].to_i, result['status'][4..-1]) # 'status' of the form 'XXX Message'
|
101
108
|
end
|
102
109
|
|
103
|
-
|
104
|
-
|
105
|
-
|
110
|
+
result
|
111
|
+
end
|
112
|
+
|
113
|
+
# Returns true if status is OK (ie. in range 200-299) or don't exists.
|
114
|
+
def self.result_status_ok?(result)
|
115
|
+
!result.key?('status') || (200...300) === result['status'].to_i
|
116
|
+
end
|
117
|
+
|
118
|
+
def prevent_session_expiration
|
119
|
+
call('NoOperation')
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.decode_and_unzip(data)
|
123
|
+
Zlib::GzipReader.new(StringIO.new(XMLRPC::Base64.decode(data))).read
|
124
|
+
end
|
106
125
|
end
|
107
|
-
end
|
126
|
+
end
|
data/lib/subtitle_it/subtime.rb
CHANGED
@@ -3,39 +3,43 @@
|
|
3
3
|
module SubtitleIt
|
4
4
|
class Subtime
|
5
5
|
attr_accessor :hrs, :min, :sec, :ms
|
6
|
-
|
7
|
-
def initialize(data)
|
8
|
-
raise if data == nil
|
6
|
+
|
7
|
+
def initialize(data)
|
8
|
+
raise if data == nil
|
9
9
|
parse_data(data)
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
# parses string like '00:00:00,000' or single number as ms.
|
13
13
|
def parse_data(data)
|
14
14
|
case data
|
15
|
-
when Numeric
|
16
|
-
@sec, @ms
|
15
|
+
when Numeric
|
16
|
+
@sec, @ms = data.divmod(1000)
|
17
17
|
@min, @sec = @sec.divmod(60)
|
18
18
|
@hrs, @min = @min.divmod(60)
|
19
|
-
when String
|
19
|
+
when String
|
20
20
|
time, float = data.split(/\.|\,/)
|
21
21
|
time = time.split(/:/).map { |s| s.to_i }
|
22
22
|
@ms = (("0.%d" % float.to_i).to_f * 1000).to_i if float
|
23
23
|
@sec, @min, @hrs = time.reverse
|
24
24
|
else raise "Format unknown."
|
25
|
-
end
|
25
|
+
end
|
26
26
|
#FIXME: dunno what to do about this.. nil = problems with to_i
|
27
27
|
@hrs ||= 0; @min ||= 0; @sec ||= 0; @ms ||= 0
|
28
28
|
end
|
29
29
|
|
30
30
|
# to_s(separator) => to_s(",") => 00:00:00,000
|
31
|
-
def to_s(sep='.')
|
32
|
-
|
31
|
+
def to_s(sep='.')
|
32
|
+
"%02d:%02d:%02d#{sep}%03d" % [@hrs, @min, @sec, @ms]
|
33
|
+
end
|
34
|
+
|
33
35
|
# return time as a total in ms
|
34
|
-
def to_i
|
35
|
-
|
36
|
-
|
37
|
-
|
36
|
+
def to_i
|
37
|
+
( @hrs * 3600 + @min * 60 + @sec ) * 1000 + @ms
|
38
|
+
end
|
39
|
+
|
40
|
+
def +(other); Subtime.new(self.to_i + other.to_i); end
|
41
|
+
def -(other); Subtime.new(self.to_i - other.to_i); end
|
38
42
|
def <=>(other); self.to_i <=> other.to_i; end
|
39
43
|
include Comparable
|
40
44
|
end
|
41
|
-
end
|
45
|
+
end
|
data/lib/subtitle_it/version.rb
CHANGED
data/lib/subtitle_it.rb
CHANGED
data/spec/fixtures/pseudo.rsb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
- title: sincity
|
2
|
-
- authors:
|
2
|
+
- authors:
|
3
3
|
- version: 1.1
|
4
4
|
00:05:26.500 => 00:05:28.500 == worth killing for...
|
5
5
|
00:06:00.400 => 00:06:03.400 == worth dying for...
|
6
|
-
00:07:00.300 => 00:07:03.300 == worth going to the hell for...
|
6
|
+
00:07:00.300 => 00:07:03.300 == worth going to the hell for...
|