subtitle_it 1.9.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/Gemfile +3 -0
- data/{README.rdoc → README.md} +22 -18
- data/Rakefile +13 -18
- data/bin/subtitle_it +4 -8
- data/lib/subtitle_it/bin.rb +50 -58
- data/lib/subtitle_it/fixes.rb +3 -4
- data/lib/subtitle_it/formats/ass.rb +5 -6
- data/lib/subtitle_it/formats/mpl.rb +9 -9
- data/lib/subtitle_it/formats/rsb.rb +9 -9
- data/lib/subtitle_it/formats/srt.rb +17 -14
- data/lib/subtitle_it/formats/sub.rb +7 -7
- data/lib/subtitle_it/formats/xml.rb +13 -12
- data/lib/subtitle_it/formats/yml.rb +5 -5
- data/lib/subtitle_it/generator.rb +2 -2
- data/lib/subtitle_it/languages.rb +52 -53
- data/lib/subtitle_it/movie.rb +26 -6
- data/lib/subtitle_it/platform_endl.rb +7 -5
- data/lib/subtitle_it/subdown.rb +30 -33
- data/lib/subtitle_it/subline.rb +5 -5
- data/lib/subtitle_it/substyle.rb +3 -9
- data/lib/subtitle_it/subtime.rb +19 -10
- data/lib/subtitle_it/subtitle.rb +20 -28
- data/lib/subtitle_it/version.rb +1 -7
- data/lib/subtitle_it.rb +7 -7
- data/spec/fixtures/movie.xml +2 -2
- data/spec/spec_helper.rb +6 -6
- data/spec/subtitle_it/bin_spec.rb +110 -98
- data/spec/subtitle_it/formats/ass_spec.rb +2 -3
- data/spec/subtitle_it/formats/mpl_spec.rb +26 -28
- data/spec/subtitle_it/formats/rsb_spec.rb +29 -30
- data/spec/subtitle_it/formats/srt_spec.rb +27 -30
- data/spec/subtitle_it/formats/sub_spec.rb +19 -21
- data/spec/subtitle_it/formats/xml_spec.rb +21 -21
- data/spec/subtitle_it/formats/yml_spec.rb +14 -15
- data/spec/subtitle_it/movie_spec.rb +24 -15
- data/spec/subtitle_it/subdown_spec.rb +58 -65
- data/spec/subtitle_it/subline_spec.rb +17 -18
- data/spec/subtitle_it/subtime_spec.rb +43 -44
- data/spec/subtitle_it/subtitle_spec.rb +28 -29
- data/spec/subtitle_it_spec.rb +4 -5
- data/subtitle_it.gemspec +25 -98
- metadata +121 -67
- data/.rspec +0 -2
- data/config/hoe.rb +0 -73
- data/config/requirements.rb +0 -15
- data/lib/subtitle_it/movie_hasher.rb +0 -30
- data/script/console +0 -10
- data/script/destroy +0 -14
- data/script/generate +0 -14
- data/script/txt2html +0 -82
- data/spec/subtitle_it/movie_hasher_spec.rb +0 -13
- data/tasks/deployment.rake +0 -34
- data/tasks/environment.rake +0 -7
- data/tasks/rspec.rake +0 -21
@@ -1,9 +1,9 @@
|
|
1
1
|
module SubtitleIt
|
2
2
|
# class Generate
|
3
|
-
# def generate_rsb(filename)
|
3
|
+
# def generate_rsb(filename)
|
4
4
|
# dump = <<GEN
|
5
5
|
# - title: #{argv[0]}
|
6
|
-
# - authors: FIXME
|
6
|
+
# - authors: FIXME
|
7
7
|
# - version: FIXME
|
8
8
|
# 00:05:26.500 => 00:05:28.500 == worth killing for...
|
9
9
|
# 00:06:00.400 => 00:06:03.400 == worth dying for...
|
@@ -7,58 +7,57 @@ module SubtitleIt
|
|
7
7
|
#
|
8
8
|
# Need to rewrite "Portuguese" => [:pt, :por, :whatever]
|
9
9
|
LANGS = {
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:
|
16
|
-
:
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:
|
23
|
-
:
|
24
|
-
:
|
25
|
-
:
|
26
|
-
:
|
27
|
-
:
|
28
|
-
:
|
29
|
-
:
|
30
|
-
:
|
31
|
-
:
|
32
|
-
:
|
33
|
-
:
|
34
|
-
:
|
35
|
-
:
|
36
|
-
:
|
37
|
-
:
|
38
|
-
:
|
39
|
-
:
|
40
|
-
:
|
41
|
-
:
|
42
|
-
:
|
43
|
-
:
|
44
|
-
:
|
45
|
-
:
|
46
|
-
:
|
47
|
-
:
|
48
|
-
:
|
49
|
-
:
|
50
|
-
:
|
51
|
-
:
|
52
|
-
:
|
53
|
-
:
|
54
|
-
:
|
55
|
-
:
|
56
|
-
:
|
57
|
-
:
|
58
|
-
:
|
59
|
-
:
|
60
|
-
:
|
61
|
-
:
|
10
|
+
aa: 'Afar',
|
11
|
+
ab: 'Abkhazian',
|
12
|
+
af: 'Afrikaans',
|
13
|
+
ak: 'Akan',
|
14
|
+
ay: 'Assyrian',
|
15
|
+
sq: 'Albanian',
|
16
|
+
am: 'Amharic',
|
17
|
+
ar: 'Arabic',
|
18
|
+
br: %w(Brazilian por),
|
19
|
+
hy: 'Armenian',
|
20
|
+
bs: 'Bosnian',
|
21
|
+
bg: 'Bulgarian',
|
22
|
+
ca: 'Catalan',
|
23
|
+
cs: 'Czech',
|
24
|
+
da: 'Danish',
|
25
|
+
nl: 'Dutch',
|
26
|
+
en: %w(English eng),
|
27
|
+
et: 'Estonian',
|
28
|
+
fr: %w(French fra),
|
29
|
+
de: 'German',
|
30
|
+
gl: 'Galician',
|
31
|
+
el: 'Greek',
|
32
|
+
he: 'Hebrew',
|
33
|
+
hi: 'Hindi',
|
34
|
+
hr: 'Croatian',
|
35
|
+
hu: 'Hungarian',
|
36
|
+
is: 'Icelandic',
|
37
|
+
id: 'Indonesian',
|
38
|
+
it: 'Italian',
|
39
|
+
ja: 'Japanese',
|
40
|
+
kk: 'Kazakh',
|
41
|
+
ko: 'Korean',
|
42
|
+
lv: 'Latvian',
|
43
|
+
lt: 'Lithuanian',
|
44
|
+
lb: 'Luxembourgish',
|
45
|
+
mk: 'Macedonian',
|
46
|
+
ms: 'Malay',
|
47
|
+
no: 'Norwegian',
|
48
|
+
pl: 'Polish',
|
49
|
+
pt: 'Portuguese',
|
50
|
+
ru: 'Russian',
|
51
|
+
sr: 'Serbian',
|
52
|
+
es: 'Spanish',
|
53
|
+
sk: 'Slovak',
|
54
|
+
sl: 'Slovenian',
|
55
|
+
sv: 'Swedish',
|
56
|
+
th: 'Thai',
|
57
|
+
tr: 'Turkish',
|
58
|
+
uk: 'Ukrainian',
|
59
|
+
vi: 'Vietnamese',
|
60
|
+
ro: 'Romanian',
|
61
|
+
zh: 'Chinese'
|
62
62
|
}
|
63
|
-
|
64
63
|
end
|
data/lib/subtitle_it/movie.rb
CHANGED
@@ -1,23 +1,43 @@
|
|
1
|
-
# downsub - github.com/johanlunds/downsub
|
2
|
-
require 'subtitle_it/movie_hasher'
|
3
|
-
|
4
1
|
module SubtitleIt
|
5
2
|
class Movie
|
6
|
-
|
7
3
|
attr_reader :filename
|
8
4
|
attr_accessor :info
|
5
|
+
CHUNK_SIZE = 64 * 1024 # in bytes
|
9
6
|
|
10
7
|
def initialize(filename)
|
11
8
|
@filename = filename
|
12
9
|
@info = {}
|
13
10
|
end
|
14
11
|
|
12
|
+
def compute_haxx
|
13
|
+
filesize = File.size(@filename)
|
14
|
+
out = filesize
|
15
|
+
|
16
|
+
# Read 64 kbytes, divide up into 64 bits and add each
|
17
|
+
# to hash. Do for beginning and end of file.
|
18
|
+
File.open(filename, 'rb') do |f|
|
19
|
+
# Q = unsigned long long = 64 bit
|
20
|
+
f.read(CHUNK_SIZE).unpack('Q*').each do |n|
|
21
|
+
out = out + n & 0xffffffffffffffff # to remain as 64 bit number
|
22
|
+
end
|
23
|
+
|
24
|
+
f.seek([0, filesize - CHUNK_SIZE].max, IO::SEEK_SET)
|
25
|
+
|
26
|
+
# And again for the end of the file
|
27
|
+
f.read(CHUNK_SIZE).unpack('Q*').each do |n|
|
28
|
+
out = out + n & 0xffffffffffffffff
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
sprintf('%016x', out)
|
33
|
+
end
|
34
|
+
|
15
35
|
def haxx
|
16
|
-
@haxx ||=
|
36
|
+
@haxx ||= compute_haxx
|
17
37
|
end
|
18
38
|
|
19
39
|
def size
|
20
40
|
@size ||= File.size(@filename)
|
21
41
|
end
|
22
42
|
end
|
23
|
-
end
|
43
|
+
end
|
@@ -1,9 +1,11 @@
|
|
1
1
|
module PlatformEndLine
|
2
|
-
def platform(
|
3
|
-
raw =~ /\r\n/ ?
|
2
|
+
def platform(raw)
|
3
|
+
raw =~ /\r\n/ ? 'WIN' : 'UNIX'
|
4
|
+
rescue ArgumentError => e
|
5
|
+
'WIN'
|
4
6
|
end
|
5
|
-
|
6
|
-
|
7
|
+
|
8
|
+
def endline(raw)
|
9
|
+
platform(raw) == 'WIN' ? "\r\n" : "\n"
|
7
10
|
end
|
8
11
|
end
|
9
|
-
|
data/lib/subtitle_it/subdown.rb
CHANGED
@@ -8,12 +8,12 @@ require 'subtitle_it/subtitle'
|
|
8
8
|
require 'subtitle_it/languages'
|
9
9
|
|
10
10
|
module SubtitleIt
|
11
|
+
# Download subtitles
|
11
12
|
class Subdown
|
12
|
-
HOST =
|
13
|
-
HOST_DEV =
|
13
|
+
HOST = 'http://api.opensubtitles.org/xml-rpc'
|
14
|
+
HOST_DEV = 'http://dev.opensubtitles.org/xml-rpc'
|
14
15
|
|
15
|
-
|
16
|
-
USER_AGENT = "SubtitleIt #{SubtitleIt::VERSION::STRING}"
|
16
|
+
USER_AGENT = "SubtitleIt #{SubtitleIt::VERSION}"
|
17
17
|
|
18
18
|
NO_TOKEN = %w(ServerInfo LogIn)
|
19
19
|
|
@@ -40,12 +40,9 @@ module SubtitleIt
|
|
40
40
|
request('ServerInfo')
|
41
41
|
end
|
42
42
|
|
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."
|
43
|
+
def search_subtitles(movie, lang_name = nil)
|
47
44
|
args = {
|
48
|
-
'sublanguageid' => lang_name ||
|
45
|
+
'sublanguageid' => lang_name || '',
|
49
46
|
'moviehash' => movie.haxx,
|
50
47
|
'moviebytesize' => movie.size
|
51
48
|
}
|
@@ -53,7 +50,7 @@ module SubtitleIt
|
|
53
50
|
result = request('SearchSubtitles', [args])
|
54
51
|
return [] unless result['data'] # if no results result['data'] == false
|
55
52
|
result['data'].inject([]) do |subs, sub_info|
|
56
|
-
subs << Subtitle.new(
|
53
|
+
subs << Subtitle.new(info: sub_info)
|
57
54
|
subs
|
58
55
|
end
|
59
56
|
end
|
@@ -63,12 +60,12 @@ module SubtitleIt
|
|
63
60
|
sub.data = self.class.decode_and_unzip(result['data'][0]['data'])
|
64
61
|
end
|
65
62
|
|
66
|
-
def upload_subtitle(
|
63
|
+
def upload_subtitle(_movie, _subs)
|
67
64
|
end
|
68
65
|
|
69
66
|
def imdb_info(movie)
|
70
67
|
result = request('CheckMovieHash', [movie.haxx])
|
71
|
-
movie.info = result['data'][movie.haxx] # TODO: Handle if
|
68
|
+
movie.info = result['data'][movie.haxx] # TODO: Handle if movie 404
|
72
69
|
end
|
73
70
|
|
74
71
|
def self.subtitle_languages
|
@@ -76,38 +73,38 @@ module SubtitleIt
|
|
76
73
|
"#{k} -> #{v}"
|
77
74
|
end.join("\n")
|
78
75
|
end
|
79
|
-
#
|
80
|
-
|
81
|
-
#
|
82
|
-
#
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
|
87
|
-
#
|
88
|
-
|
89
|
-
#
|
90
|
-
#
|
91
|
-
#
|
92
|
-
#
|
93
|
-
#
|
76
|
+
#
|
77
|
+
# Get the Opensubtitle.org language id from the language string
|
78
|
+
# (e.g. 'French' returns 'fra' )
|
79
|
+
# def Subdown.opsub_id( language )
|
80
|
+
# ary = LANGS.find do |sym_lang|
|
81
|
+
# sym_lang if sym_lang[1].downcase == language.downcase
|
82
|
+
# end
|
83
|
+
# OPSUB_LANGS[ ary[0] ]
|
84
|
+
# end
|
85
|
+
|
86
|
+
# def Subdown.subtitle_languages
|
87
|
+
# lang_ary = []
|
88
|
+
# OPSUB_LANGS.each_key do |key|
|
89
|
+
# lang_ary.push( LANGS[key] )
|
90
|
+
# end
|
91
|
+
# lang_ary.sort.inject( "" ) { |str, lang| str << lang + " " }
|
92
|
+
# end
|
94
93
|
|
95
94
|
private
|
96
95
|
|
97
96
|
def request(method, *args)
|
98
|
-
|
99
97
|
unless NO_TOKEN.include? method
|
100
|
-
|
98
|
+
fail 'Need to be logged in for this.' unless logged_in?
|
101
99
|
args = [@token, *args]
|
102
100
|
end
|
103
101
|
|
104
|
-
p method, args
|
105
102
|
result = @client.call(method, *args)
|
106
|
-
p result
|
107
|
-
# $LOG.debug "Client#call #{method}, #{args.inspect}: #{result.inspect}"
|
108
103
|
|
109
104
|
unless self.class.result_status_ok?(result)
|
110
|
-
|
105
|
+
# 'status' of the form 'XXX Message'
|
106
|
+
fail XMLRPC::FaultException.new(result['status'].to_i,
|
107
|
+
result['status'][4..-1])
|
111
108
|
end
|
112
109
|
|
113
110
|
result
|
data/lib/subtitle_it/subline.rb
CHANGED
@@ -2,24 +2,24 @@
|
|
2
2
|
# Holds a subtitle`s line.
|
3
3
|
module SubtitleIt
|
4
4
|
class Subline
|
5
|
-
attr_accessor :time_on, :time_off, :text
|
5
|
+
attr_accessor :time_on, :time_off, :text
|
6
6
|
# time_on/off may be:
|
7
7
|
# HH:MM:SS,MMM
|
8
8
|
# MM:SS
|
9
|
-
# S
|
9
|
+
# S
|
10
10
|
# text lines should be separated by |
|
11
|
-
def initialize(time_on, time_off, text)
|
11
|
+
def initialize(time_on, time_off, text)
|
12
12
|
@time_on, @time_off = filter(time_on, time_off)
|
13
13
|
# ugly FIXME: when pseudo uses time => 3 or TT format
|
14
14
|
# need to add seconds on time_off to time_on
|
15
15
|
@time_off += @time_on if @time_off < @time_on
|
16
16
|
@text = text
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
def filter(*args)
|
20
20
|
args.map do |arg|
|
21
21
|
Subtime.new(arg)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
25
|
-
end
|
25
|
+
end
|
data/lib/subtitle_it/substyle.rb
CHANGED
data/lib/subtitle_it/subtime.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
# SubtitleIt
|
2
2
|
# Time class
|
3
3
|
module SubtitleIt
|
4
|
+
# A kinda of Time
|
4
5
|
class Subtime
|
5
6
|
attr_accessor :hrs, :min, :sec, :ms
|
6
7
|
|
7
8
|
def initialize(data)
|
8
|
-
|
9
|
+
fail if data.nil?
|
9
10
|
parse_data(data)
|
10
11
|
end
|
11
12
|
|
@@ -18,28 +19,36 @@ module SubtitleIt
|
|
18
19
|
@hrs, @min = @min.divmod(60)
|
19
20
|
when String
|
20
21
|
time, float = data.split(/\.|\,/)
|
21
|
-
time = time.split(/:/).map
|
22
|
-
@ms = ((
|
22
|
+
time = time.split(/:/).map(&:to_i)
|
23
|
+
@ms = (('0.%d' % float.to_i).to_f * 1000).to_i if float
|
23
24
|
@sec, @min, @hrs = time.reverse
|
24
|
-
else
|
25
|
+
else fail 'Format unknown.'
|
25
26
|
end
|
26
|
-
#FIXME: dunno what to do about this.. nil = problems with to_i
|
27
|
+
# FIXME: dunno what to do about this.. nil = problems with to_i
|
27
28
|
@hrs ||= 0; @min ||= 0; @sec ||= 0; @ms ||= 0
|
28
29
|
end
|
29
30
|
|
30
31
|
# to_s(separator) => to_s(",") => 00:00:00,000
|
31
|
-
def to_s(sep='.')
|
32
|
+
def to_s(sep = '.')
|
32
33
|
"%02d:%02d:%02d#{sep}%03d" % [@hrs, @min, @sec, @ms]
|
33
34
|
end
|
34
35
|
|
35
36
|
# return time as a total in ms
|
36
37
|
def to_i
|
37
|
-
(
|
38
|
+
(@hrs * 3600 + @min * 60 + @sec) * 1000 + @ms
|
38
39
|
end
|
39
40
|
|
40
|
-
def +(other)
|
41
|
-
|
42
|
-
|
41
|
+
def +(other)
|
42
|
+
Subtime.new(to_i + other.to_i)
|
43
|
+
end
|
44
|
+
|
45
|
+
def -(other)
|
46
|
+
Subtime.new(to_i - other.to_i)
|
47
|
+
end
|
48
|
+
|
49
|
+
def <=>(other)
|
50
|
+
to_i <=> other.to_i
|
51
|
+
end
|
43
52
|
include Comparable
|
44
53
|
end
|
45
54
|
end
|
data/lib/subtitle_it/subtitle.rb
CHANGED
@@ -9,21 +9,19 @@ require 'subtitle_it/formats/mpl'
|
|
9
9
|
# http://www.opensubtitles.org/addons/export_languages.php
|
10
10
|
|
11
11
|
module SubtitleIt
|
12
|
-
|
13
12
|
MOVIE_EXTS = %w(3g2 3gp 3gp2 3gpp 60d ajp asf asx avchd avi bik bix box cam dat divx dmf dv dvr-ms evo flc fli flic flv flx gvi gvp h264 m1v m2p m2ts m2v m4e m4v mjp mjpeg mjpg mkv moov mov movhd movie movx mp4 mpe mpeg mpg mpv mpv2 mxf nsv nut ogg ogm omf ps qt ram rm rmvb swf ts vfw vid video viv vivo vob vro wm wmv wmx wrap wvx wx x264 xvid)
|
14
13
|
SUB_EXTS = %w(srt sub smi txt ssa ass mpl xml yml rsb)
|
15
|
-
|
16
|
-
|
17
|
-
class Subtitle
|
14
|
+
|
15
|
+
class Subtitle
|
18
16
|
include Formats
|
19
17
|
attr_reader :id, :raw, :format, :lines, :style, :info, :filename, :rating, :language, :user, :release_name,
|
20
18
|
:osdb_id, :download_count, :download_url, :original_filename
|
21
|
-
|
19
|
+
|
22
20
|
def initialize(args = {})
|
23
21
|
# Looks like opensubtitle is the only provider around..
|
24
22
|
# If a second one comes need big refactor...
|
25
23
|
if @info = args[:info]
|
26
|
-
|
24
|
+
# @osdb_info = info
|
27
25
|
@osdb_id = @info['IDSubtitleFile'].to_s
|
28
26
|
@original_filename = @info['SubFileName'].to_s
|
29
27
|
@format = @info['SubFormat'].to_s
|
@@ -35,42 +33,36 @@ module SubtitleIt
|
|
35
33
|
@uploaded_at = @info['SubAddDate'].to_s # TODO: convert to time object?
|
36
34
|
@download_url = @info['SubDownloadLink'].to_s
|
37
35
|
end
|
38
|
-
@fps = args[:fps] || 23.976
|
36
|
+
@fps = args[:fps] || 23.976
|
39
37
|
parse_dump(args[:dump], args[:format]) if args[:dump]
|
40
38
|
end
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
def fps=(fps)
|
47
|
-
@fps = fps
|
48
|
-
end
|
49
|
-
|
39
|
+
|
40
|
+
attr_writer :style
|
41
|
+
|
42
|
+
attr_writer :fps
|
43
|
+
|
50
44
|
def data=(data)
|
51
45
|
@raw = data
|
52
46
|
end
|
53
|
-
|
47
|
+
|
54
48
|
def <=>(other)
|
55
|
-
|
49
|
+
rating <=> other.rating
|
56
50
|
end
|
57
51
|
include Comparable
|
58
52
|
|
59
53
|
private
|
60
|
-
|
61
|
-
def parse_dump(dump,format)
|
62
|
-
|
63
|
-
@raw = dump.
|
54
|
+
|
55
|
+
def parse_dump(dump, format)
|
56
|
+
fail unless SUB_EXTS.include?(format)
|
57
|
+
@raw = dump.is_a?(String) ? dump : dump.read
|
64
58
|
@format = format
|
65
59
|
parse_lines!
|
66
60
|
end
|
67
|
-
|
61
|
+
|
68
62
|
def parse_lines!
|
69
|
-
self.lines = send :"parse_#{@format}"
|
63
|
+
self.lines = send :"parse_#{@format}"
|
70
64
|
end
|
71
|
-
|
72
|
-
|
73
|
-
@lines = lines
|
74
|
-
end
|
65
|
+
|
66
|
+
attr_writer :lines
|
75
67
|
end
|
76
68
|
end
|
data/lib/subtitle_it/version.rb
CHANGED
data/lib/subtitle_it.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require '
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$LOAD_PATH.include?(File.dirname(__FILE__)) || $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
require 'yaml'
|
4
|
+
|
4
5
|
require 'subtitle_it/version'
|
5
6
|
require 'subtitle_it/languages'
|
6
7
|
require 'subtitle_it/subtime'
|
@@ -17,15 +18,14 @@ end
|
|
17
18
|
|
18
19
|
class Numeric
|
19
20
|
def reduce
|
20
|
-
self /
|
21
|
+
self / 10**Math.log10(self).to_i
|
21
22
|
end
|
22
23
|
end
|
23
24
|
|
24
|
-
if RUBY_PLATFORM >=
|
25
|
+
if RUBY_PLATFORM >= '1.9'
|
25
26
|
class String
|
26
27
|
def to_a
|
27
|
-
|
28
|
+
lines.to_a
|
28
29
|
end
|
29
30
|
end
|
30
31
|
end
|
31
|
-
|
data/spec/fixtures/movie.xml
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
</head>
|
11
11
|
<body>
|
12
12
|
<div xml:lang="en">
|
13
|
-
<p begin="00:00:00.00" dur="00:00:03.07">I had just joined <span tts:fontFamily="monospaceSansSerif,proportionalSerif,TheOther"tts:fontSize="+2">Macromedia</span> in 1996,</p>
|
13
|
+
<p begin="00:00:00.00" dur="00:00:03.07">I had just joined <span tts:fontFamily="monospaceSansSerif,proportionalSerif,TheOther" tts:fontSize="+2">Macromedia</span> in 1996,</p>
|
14
14
|
<p begin="00:00:03.07" dur="00:00:03.35">and we were trying to figure out what to do about the internet.</p>
|
15
15
|
<p begin="00:00:06.42" dur="00:00:03.15">And the company was in dire straights at the time.</p>
|
16
16
|
<p begin="00:00:09.57" dur="00:00:01.45">We were a CD-ROM authoring company,</p>
|
@@ -25,4 +25,4 @@
|
|
25
25
|
<p begin="00:00:29.02" dur="00:00:01.30" style="1">as <span tts:color="#ccc333">easy</span> as drawing on paper.</p>
|
26
26
|
</div>
|
27
27
|
</body>
|
28
|
-
</tt>
|
28
|
+
</tt>
|
data/spec/spec_helper.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
+
require 'colorize'
|
1
2
|
require 'rspec'
|
2
|
-
require '
|
3
|
+
require 'rspec/mocks'
|
3
4
|
|
4
|
-
|
5
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
|
5
6
|
require 'subtitle_it'
|
6
7
|
include SubtitleIt
|
7
8
|
|
@@ -31,7 +32,6 @@ module SubFixtures
|
|
31
32
|
end
|
32
33
|
end
|
33
34
|
|
34
|
-
|
35
35
|
# ##
|
36
36
|
# rSpec Hash additions.
|
37
37
|
#
|
@@ -45,7 +45,7 @@ class Hash
|
|
45
45
|
# { :a => 1, :b => 2, :c => 3 }.except(:a)
|
46
46
|
# => { :b => 2, :c => 3 }
|
47
47
|
def except(*keys)
|
48
|
-
|
48
|
+
reject { |k, _v| keys.include?(k || k.to_sym) }
|
49
49
|
end
|
50
50
|
##
|
51
51
|
# Override some keys.
|
@@ -53,7 +53,7 @@ class Hash
|
|
53
53
|
# { :a => 1, :b => 2, :c => 3 }.with(:a => 4)
|
54
54
|
# => { :a => 4, :b => 2, :c => 3 }
|
55
55
|
def with(overrides = {})
|
56
|
-
|
56
|
+
merge overrides
|
57
57
|
end
|
58
58
|
##
|
59
59
|
# Returns a Hash with only the pairs identified by +keys+.
|
@@ -61,6 +61,6 @@ class Hash
|
|
61
61
|
# { :a => 1, :b => 2, :c => 3 }.only(:a)
|
62
62
|
# => { :a => 1 }
|
63
63
|
def only(*keys)
|
64
|
-
|
64
|
+
reject { |k, _v| !keys.include?(k || k.to_sym) }
|
65
65
|
end
|
66
66
|
end
|