subtitle_it 0.7.7 → 1.5.0
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/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...
|