subtitle_it 0.7.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. data/.autotest +19 -0
  2. data/History.txt +53 -0
  3. data/License.txt +20 -0
  4. data/Manifest.txt +68 -0
  5. data/README.markdown +41 -0
  6. data/README.txt +102 -0
  7. data/Rakefile +4 -0
  8. data/bin/subtitle_it +66 -0
  9. data/config/hoe.rb +73 -0
  10. data/config/requirements.rb +15 -0
  11. data/lib/subtitle_it/bin.rb +132 -0
  12. data/lib/subtitle_it/fixes.rb +12 -0
  13. data/lib/subtitle_it/formats/ass.rb +13 -0
  14. data/lib/subtitle_it/formats/mpl.rb +29 -0
  15. data/lib/subtitle_it/formats/rsb.rb +37 -0
  16. data/lib/subtitle_it/formats/srt.rb +45 -0
  17. data/lib/subtitle_it/formats/sub.rb +49 -0
  18. data/lib/subtitle_it/formats/xml.rb +65 -0
  19. data/lib/subtitle_it/formats/yml.rb +18 -0
  20. data/lib/subtitle_it/generator.rb +15 -0
  21. data/lib/subtitle_it/languages.rb +60 -0
  22. data/lib/subtitle_it/movie.rb +24 -0
  23. data/lib/subtitle_it/movie_hasher.rb +30 -0
  24. data/lib/subtitle_it/platform_endl.rb +9 -0
  25. data/lib/subtitle_it/subdown.rb +107 -0
  26. data/lib/subtitle_it/subline.rb +25 -0
  27. data/lib/subtitle_it/substyle.rb +11 -0
  28. data/lib/subtitle_it/subtime.rb +41 -0
  29. data/lib/subtitle_it/subtitle.rb +76 -0
  30. data/lib/subtitle_it/version.rb +9 -0
  31. data/lib/subtitle_it.rb +22 -0
  32. data/script/console +10 -0
  33. data/script/destroy +14 -0
  34. data/script/generate +14 -0
  35. data/script/txt2html +82 -0
  36. data/setup.rb +1585 -0
  37. data/spec/fixtures/godfather.srt +2487 -0
  38. data/spec/fixtures/huge.ass +22 -0
  39. data/spec/fixtures/movie.xml +28 -0
  40. data/spec/fixtures/movie.yml +163 -0
  41. data/spec/fixtures/pseudo.rsb +6 -0
  42. data/spec/fixtures/pulpfiction.sub +2025 -0
  43. data/spec/fixtures/puplfiction.mpl +12 -0
  44. data/spec/fixtures/sincity.yml +12 -0
  45. data/spec/spec.opts +1 -0
  46. data/spec/spec_helper.rb +71 -0
  47. data/spec/subtitle_it/bin_spec.rb +142 -0
  48. data/spec/subtitle_it/fixes_spec.rb +0 -0
  49. data/spec/subtitle_it/formats/ass_spec.rb +5 -0
  50. data/spec/subtitle_it/formats/mpl_spec.rb +45 -0
  51. data/spec/subtitle_it/formats/rsb_spec.rb +42 -0
  52. data/spec/subtitle_it/formats/srt_spec.rb +57 -0
  53. data/spec/subtitle_it/formats/sub_spec.rb +49 -0
  54. data/spec/subtitle_it/formats/xml_spec.rb +60 -0
  55. data/spec/subtitle_it/formats/yml_spec.rb +20 -0
  56. data/spec/subtitle_it/generator_spec.rb +0 -0
  57. data/spec/subtitle_it/movie_hasher_spec.rb +13 -0
  58. data/spec/subtitle_it/movie_spec.rb +25 -0
  59. data/spec/subtitle_it/subdown_spec.rb +94 -0
  60. data/spec/subtitle_it/subline_spec.rb +30 -0
  61. data/spec/subtitle_it/substyle_spec.rb +1 -0
  62. data/spec/subtitle_it/subtime_spec.rb +73 -0
  63. data/spec/subtitle_it/subtitle_spec.rb +40 -0
  64. data/spec/subtitle_it_spec.rb +11 -0
  65. data/subtitle_it.gemspec +41 -0
  66. data/tasks/deployment.rake +34 -0
  67. data/tasks/environment.rake +7 -0
  68. data/tasks/rspec.rake +21 -0
  69. metadata +152 -0
@@ -0,0 +1,45 @@
1
+ # SubtitleIt
2
+ # SRT - Subrip format
3
+ #
4
+ # N
5
+ # 00:55:21,600 --> 00:55:27,197
6
+ # lt's not even 20 years. You've sold the
7
+ # casinos and made fortunes for all of us.
8
+ #
9
+ # Where N is the sub index number
10
+ #
11
+ module Formats
12
+ include PlatformEndLine
13
+ def parse_srt
14
+ endl = endline( @raw )
15
+ @raw.split( endl*2 ).inject([]) do |final,line|
16
+ line = line.split(endl)
17
+ line.delete_at(0)
18
+ time_on,time_off = line[0].split('-->').map { |t| t.strip }
19
+ line.delete_at(0)
20
+ text = line.join("|")
21
+ final << Subline.new(time_on, time_off, text)
22
+ end
23
+ end
24
+
25
+ def to_srt
26
+ endl = endline( @raw )
27
+ out = []
28
+ @lines.each_with_index do |l,i|
29
+ out << "#{i+1}"
30
+ out << "%s --> %s" % [l.time_on.to_s(','), l.time_off.to_s(',')]
31
+ out << l.text.gsub("|", endl) + endl
32
+ end
33
+ out.join( endl )
34
+ end
35
+ end
36
+
37
+ #looks like subrip accepts some styling:
38
+ # sdict.add(new StyledFormat(ITALIC, "i", true));
39
+ # sdict.add(new StyledFormat(ITALIC, "/i", false));
40
+ # sdict.add(new StyledFormat(BOLD, "b", true));
41
+ # sdict.add(new StyledFormat(BOLD, "/b", false));
42
+ # sdict.add(new StyledFormat(UNDERLINE, "u", true));
43
+ # sdict.add(new StyledFormat(UNDERLINE, "/u", false));
44
+ # sdict.add(new StyledFormat(STRIKETHROUGH, "s", true));
45
+ # sdict.add(new StyledFormat(STRIKETHROUGH, "/s", false));
@@ -0,0 +1,49 @@
1
+ # SubtitleIt
2
+ # MPSub, MicroDVD or VOBSub format
3
+ #TODO: tricky.. detect which format we got.
4
+ #
5
+ # {1025}{1115}You always say that.|The same thing every time.
6
+ # {1118}{1177}"l'm throug h, never again,|too dangerous."
7
+ #
8
+ # MicroDVD:
9
+ # {1}{1}25.000
10
+ # {2447}{2513}You should come to the Drama Club, too.
11
+ # {2513}{2594}Yeah. The Drama Club is worried|that you haven't been coming.
12
+ # {2603}{2675}I see. Sorry, I'll drop by next time.
13
+ #
14
+ # Where N is ms / framerate / 1000 (ms -> s)
15
+ #
16
+ # parts of the code from 'simplesubtitler' from Marcin (tiraeth) Chwedziak
17
+ #
18
+ module Formats
19
+ include PlatformEndLine
20
+ #between our formats, what changes can be reduced to a value
21
+ def ratio
22
+ 1
23
+ end
24
+
25
+ def parse_sub
26
+ @raw.to_a.inject([]) do |i,l|
27
+ line_data = l.scan(/^\{([0-9]{1,})\}\{([0-9]{1,})\}(.+)$/)
28
+ line_data = line_data.at 0
29
+ time_on, time_off, text = line_data
30
+ time_on, time_off = [time_on.to_i, time_off.to_i].map do |t|
31
+ (t.to_i / @fps * 1000 / ratio).to_i
32
+ end
33
+ i << Subline.new(time_on, time_off, text.chomp)
34
+ end
35
+ end
36
+
37
+ def to_sub
38
+ endl = endline( @raw )
39
+ line_ary = []
40
+ @lines.each do |l|
41
+ line_ary << "{%d}{%d}%s" % [parse_time(l.time_on), parse_time(l.time_off), l.text]
42
+ end
43
+ return line_ary.join( endl ) + endl
44
+ end
45
+
46
+ def parse_time(n)
47
+ n.to_i / 1000 * @fps * ratio
48
+ end
49
+ end
@@ -0,0 +1,65 @@
1
+ # SubtitleIt
2
+ # XML TT Timed Text
3
+ # http://www.w3.org/TR/2006/CR-ttaf1-dfxp-20061116/
4
+ # http://livedocs.adobe.com/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&file=00000604.html
5
+ #
6
+ # <?xml version="1.0" encoding="UTF-8"?>
7
+ # <tt xml:lang="en" xmlns="http://www.w3.org/2006/04/ttaf1" xmlns:tts="http://www.w3.org/2006/04/ttaf1#styling">
8
+ # <head>
9
+ # <styling>
10
+ # <style id="1" tts:textAlign="right"/>
11
+ # <style id="2" tts:color="transparent"/>
12
+ # </styling>
13
+ # </head>
14
+ # <body>
15
+ # <div xml:lang="en">
16
+ # <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>
17
+ # <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>
18
+ # <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>
19
+ # </div>
20
+ # </body>
21
+ #</tt>
22
+ require 'hpricot'
23
+ module Formats
24
+ include PlatformEndLine
25
+
26
+ def parse_xml
27
+ final = []
28
+ doc = Hpricot.XML(@raw)
29
+ (doc/'tt'/'p').each do |line|
30
+ time_on, time_off = ['begin', 'dur'].map { |str| line[str.to_sym] }
31
+ text = line.innerHTML
32
+ final << Subline.new(time_on,time_off,text)
33
+ end
34
+ return final
35
+ end
36
+
37
+ def xml_lines
38
+ endl = endline( @raw )
39
+ line_ary = []
40
+ @lines.each do |l|
41
+ toff = l.time_off - l.time_on
42
+ line_ary << " <p begin=\"#{l.time_on}\" dur=\"#{toff}\">#{l.text}</p>"
43
+ end
44
+ return line_ary.join( endl )
45
+ end
46
+
47
+ def to_xml
48
+ endl = endline( @raw )
49
+ out = <<XML
50
+ <?xml version="1.0" encoding="UTF-8"?>
51
+ <tt xml:lang="en" xmlns="http://www.w3.org/2006/04/ttaf1" xmlns:tts="http://www.w3.org/2006/04/ttaf1#styling">
52
+ <head>
53
+ <styling>#{@style + endl if @style}
54
+ </styling>
55
+ </head>
56
+ <body>
57
+ <div xml:lang="en">
58
+ #{xml_lines}
59
+ </div>
60
+ </body>
61
+ </tt>
62
+ XML
63
+ out.chomp
64
+ end
65
+ end
@@ -0,0 +1,18 @@
1
+ # SubtitleIt
2
+ # YML Dump
3
+ #
4
+ require 'yaml'
5
+ module Formats
6
+ def parse_yml
7
+ @yaml = YAML::load(@raw)
8
+ header = @yaml.delete('header')
9
+ @title = header['title']
10
+ @author = header['authors']
11
+ @version = header['version']
12
+ @yaml['lines'].map { |l| Subline.new(l[0], l[1], l[2]) }
13
+ end
14
+
15
+ def to_yml
16
+ YAML.dump(self)
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ module SubtitleIt
2
+ # class Generate
3
+ # def generate_rsb(filename)
4
+ # dump = <<GEN
5
+ # - title: #{argv[0]}
6
+ # - authors: FIXME
7
+ # - version: FIXME
8
+ # 00:05:26.500 => 00:05:28.500 == worth killing for...
9
+ # 00:06:00.400 => 00:06:03.400 == worth dying for...
10
+ # 00:07:00.300 => 00:07:03.300 == worth going to the hell for...
11
+ # GEN
12
+ # write_out(filename, dump)
13
+ # end
14
+ # end
15
+ end
@@ -0,0 +1,60 @@
1
+ module SubtitleIt
2
+ #TODO: create a lang class?
3
+ # now I`m more lost.... opensubtitle uses a 3 chars like
4
+ # Por => Portuguese
5
+ # Cze => Czech ....
6
+ LANGS = {
7
+ :aa => 'Afar',
8
+ :ab => 'Abkhazian',
9
+ :af => 'Afrikaans',
10
+ :ak => 'Akan',
11
+ :sq => 'Albanian',
12
+ :am => 'Amharic',
13
+ :ar => 'Arabic',
14
+ :pb => 'Brazilian Portuguese',
15
+ :hy => 'Armenian',
16
+ :bs => 'Bosnian',
17
+ :bg => 'Bulgarian',
18
+ :ca => 'Catalan',
19
+ :zh => 'Chinese',
20
+ :cs => 'Czech',
21
+ :da => 'Danish',
22
+ :nl => 'Dutch',
23
+ :et => 'Estonian',
24
+ :fr => 'French',
25
+ :de => 'German',
26
+ :gl => 'Galician',
27
+ :el => 'Greek',
28
+ :he => 'Hebrew',
29
+ :hi => 'Hindi',
30
+ :hr => 'Croatian',
31
+ :hu => 'Hungarian',
32
+ :is => 'Icelandic',
33
+ :id => 'Indonesian',
34
+ :it => 'Italian',
35
+ :ja => 'Japanese',
36
+ :kk => 'Kazakh',
37
+ :ko => 'Korean',
38
+ :lv => 'Latvian',
39
+ :lt => 'Lithuanian',
40
+ :lb => 'Luxembourgish',
41
+ :mk => 'Macedonian',
42
+ :ms => 'Malay',
43
+ :no => 'Norwegian',
44
+ :pl => 'Polish',
45
+ :pt => 'Portuguese',
46
+ :ru => 'Russian',
47
+ :sr => 'Serbian',
48
+ :es => 'Spanish',
49
+ :sk => 'Slovak',
50
+ :sl => 'Slovenian',
51
+ :sv => 'Swedish',
52
+ :th => 'Thai',
53
+ :tr => 'Turkish',
54
+ :uk => 'Ukrainian',
55
+ :vi => 'Vietnamese',
56
+ :ro => 'Romanian',
57
+ :pb => 'Brazilian',
58
+ :ay => 'Assyrian'
59
+ }
60
+ end
@@ -0,0 +1,24 @@
1
+ # downsub - github.com/johanlunds/downsub
2
+ require 'subtitle_it/movie_hasher'
3
+
4
+ module SubtitleIt
5
+ class Movie
6
+
7
+ attr_reader :filename
8
+ attr_accessor :info
9
+
10
+ def initialize(filename)
11
+ @filename = filename
12
+ @haxx = nil
13
+ @info = {}
14
+ end
15
+
16
+ def haxx
17
+ @haxx ||= MovieHasher::compute_haxx(@filename)
18
+ end
19
+
20
+ def size
21
+ File.size(@filename)
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,30 @@
1
+ # downsub - github.com/johanlunds/downsub
2
+ module SubtitleIt
3
+ module MovieHasher
4
+
5
+ CHUNK_SIZE = 64 * 1024 # in bytes
6
+
7
+ def self.compute_haxx(filename)
8
+ filesize = File.size(filename)
9
+ haxx = filesize
10
+
11
+ # Read 64 kbytes, divide up into 64 bits and add each
12
+ # to hash. Do for beginning and end of file.
13
+ File.open(filename, 'rb') do |f|
14
+ # Q = unsigned long long = 64 bit
15
+ f.read(CHUNK_SIZE).unpack("Q*").each do |n|
16
+ haxx = haxx + n & 0xffffffffffffffff # to remain as 64 bit number
17
+ end
18
+
19
+ f.seek([0, filesize - CHUNK_SIZE].max, IO::SEEK_SET)
20
+
21
+ # And again for the end of the file
22
+ f.read(CHUNK_SIZE).unpack("Q*").each do |n|
23
+ haxx = haxx + n & 0xffffffffffffffff
24
+ end
25
+ end
26
+
27
+ sprintf("%016x", haxx)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,9 @@
1
+ module PlatformEndLine
2
+ def platform( raw )
3
+ raw =~ /\r\n/ ? "WIN" : "UNIX"
4
+ end
5
+ def endline( raw )
6
+ platform( raw ) == "WIN" ? "\r\n" : "\n"
7
+ end
8
+ end
9
+
@@ -0,0 +1,107 @@
1
+ ## downsub - github.com/johanlunds/downsub
2
+ require 'xmlrpc/client'
3
+ require 'zlib'
4
+ require 'stringio'
5
+
6
+ require 'subtitle_it/version'
7
+ require 'subtitle_it/subtitle'
8
+
9
+ module SubtitleIt
10
+ class Subdown
11
+ HOST = "http://www.opensubtitles.org/xml-rpc"
12
+ HOST_DEV = "http://dev.opensubtitles.org/xml-rpc"
13
+
14
+ USER_AGENT = "SubtitleIt #{SubtitleIt::VERSION::STRING}"
15
+
16
+ NO_TOKEN = %w(ServerInfo LogIn)
17
+
18
+ def initialize(host = HOST)
19
+ @client = XMLRPC::Client.new2(host)
20
+ @token = nil
21
+ end
22
+
23
+ def log_in!
24
+ result = call('LogIn', '', '', '', USER_AGENT)
25
+ @token = result['token'].to_s
26
+ end
27
+
28
+ def logged_in?
29
+ !@token.nil? && !@token.empty?
30
+ end
31
+
32
+ def log_out!
33
+ call('LogOut')
34
+ @token = nil
35
+ end
36
+
37
+ def server_info
38
+ call('ServerInfo')
39
+ end
40
+
41
+ def search_subtitles(movie, lang='')
42
+ lang ||= ""
43
+ puts la
44
+ args = {
45
+ 'sublanguageid' => lang,
46
+ 'moviehash' => movie.haxx,
47
+ 'moviebytesize' => movie.size
48
+ }
49
+
50
+ result = call('SearchSubtitles', [args])
51
+ return [] unless result['data'] # if no results result['data'] == false
52
+ result['data'].inject([]) do |subs, sub_info|
53
+ subs << Subtitle.new({:info => sub_info})
54
+ subs
55
+ end
56
+ end
57
+
58
+ def download_subtitle(sub)
59
+ result = call('DownloadSubtitles', [sub.osdb_id])
60
+ sub.data = self.class.decode_and_unzip(result['data'][0]['data'])
61
+ end
62
+
63
+ def upload_subtitle(movie, subs)
64
+ end
65
+
66
+ def imdb_info(movie)
67
+ result = call('CheckMovieHash', [movie.haxx])
68
+ movie.info = result['data'][movie.haxx] # TODO: Handle if no result for movie
69
+ end
70
+
71
+ def subtitle_languages
72
+ LANGS.map { |l| l[0].to_s }
73
+ # TODO.. get the correct codes
74
+ end
75
+
76
+ private
77
+
78
+ def call(method, *args)
79
+ unless NO_TOKEN.include? method
80
+ raise 'Need to be logged in for this.' unless logged_in?
81
+ args = [@token, *args]
82
+ end
83
+
84
+ result = @client.call(method, *args)
85
+ # $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
+
99
+ def prevent_session_expiration
100
+ call('NoOperation')
101
+ end
102
+
103
+ def self.decode_and_unzip(data)
104
+ Zlib::GzipReader.new(StringIO.new(XMLRPC::Base64.decode(data))).read
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,25 @@
1
+ # SubtitleIt
2
+ # Holds a subtitle`s line.
3
+ module SubtitleIt
4
+ class Subline
5
+ attr_accessor :time_on, :time_off, :text
6
+ # time_on/off may be:
7
+ # HH:MM:SS,MMM
8
+ # MM:SS
9
+ # S
10
+ # text lines should be separated by |
11
+ def initialize(time_on, time_off, text)
12
+ @time_on, @time_off = filter(time_on, time_off)
13
+ # ugly FIXME: when pseudo uses time => 3 or TT format
14
+ # need to add seconds on time_off to time_on
15
+ @time_off += @time_on if @time_off < @time_on
16
+ @text = text
17
+ end
18
+
19
+ def filter(*args)
20
+ args.map do |arg|
21
+ Subtime.new(arg)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,11 @@
1
+ module SubtitleIt
2
+ class Substyle
3
+ #TODO
4
+
5
+
6
+
7
+
8
+
9
+
10
+ end
11
+ end
@@ -0,0 +1,41 @@
1
+ # SubtitleIt
2
+ # Time class
3
+ module SubtitleIt
4
+ class Subtime
5
+ attr_accessor :hrs, :min, :sec, :ms
6
+
7
+ def initialize(data)
8
+ raise if data == nil
9
+ parse_data(data)
10
+ end
11
+
12
+ # parses string like '00:00:00,000' or single number as ms.
13
+ def parse_data(data)
14
+ case data
15
+ when Numeric
16
+ @sec, @ms = data.divmod(1000)
17
+ @min, @sec = @sec.divmod(60)
18
+ @hrs, @min = @min.divmod(60)
19
+ when String
20
+ time, float = data.split(/\.|\,/)
21
+ time = time.split(/:/).map { |s| s.to_i }
22
+ @ms = (("0.%d" % float.to_i).to_f * 1000).to_i if float
23
+ @sec, @min, @hrs = time.reverse
24
+ else raise "Format unknown."
25
+ end
26
+ #FIXME: dunno what to do about this.. nil = problems with to_i
27
+ @hrs ||= 0; @min ||= 0; @sec ||= 0; @ms ||= 0
28
+ end
29
+
30
+ # to_s(separator) => to_s(",") => 00:00:00,000
31
+ def to_s(sep='.'); "%02d:%02d:%02d#{sep}%03d" % [@hrs, @min, @sec, @ms]; end
32
+
33
+ # return time as a total in ms
34
+ def to_i; ( @hrs * 3600 + @min * 60 + @sec ) * 1000 + @ms; end
35
+
36
+ def +(other); Subtime.new(self.to_i + other.to_i); end
37
+ def -(other); Subtime.new(self.to_i - other.to_i); end
38
+ def <=>(other); self.to_i <=> other.to_i; end
39
+ include Comparable
40
+ end
41
+ end
@@ -0,0 +1,76 @@
1
+ require 'subtitle_it/formats/srt'
2
+ require 'subtitle_it/formats/sub'
3
+ require 'subtitle_it/formats/yml'
4
+ require 'subtitle_it/formats/rsb'
5
+ require 'subtitle_it/formats/xml'
6
+ require 'subtitle_it/formats/mpl'
7
+
8
+ # http://en.wikipedia.org/wiki/List_of_ISO_639-2_codes
9
+ # http://www.opensubtitles.org/addons/export_languages.php
10
+
11
+ module SubtitleIt
12
+
13
+ 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
+ SUB_EXTS = %w(srt sub smi txt ssa ass mpl xml yml rsb)
15
+
16
+
17
+ class Subtitle
18
+ include Formats
19
+ attr_reader :id, :raw, :format, :lines, :style, :info, :filename, :rating, :language, :user, :release_name,
20
+ :osdb_id, :download_count, :download_url, :original_filename
21
+
22
+ def initialize(args = {})
23
+ # Looks like opensubtitle is the only provider around..
24
+ # If a second one comes need big refactor...
25
+ if @info = args[:info]
26
+ #@osdb_info = info
27
+ @osdb_id = @info['IDSubtitleFile'].to_s
28
+ @original_filename = @info['SubFileName'].to_s
29
+ @format = @info['SubFormat'].to_s
30
+ @user = @info['UserNickName'].to_s
31
+ @language = @info['LanguageName'].to_s
32
+ @release_name = @info['MovieReleaseName'].to_s
33
+ @download_count = @info['SubDownloadsCnt'].to_i
34
+ @rating = @info['SubRating'].to_f
35
+ @uploaded_at = @info['SubAddDate'].to_s # TODO: convert to time object?
36
+ @download_url = @info['SubDownloadLink'].to_s
37
+ end
38
+ @fps = args[:fps] || 23.976
39
+ parse_dump(args[:dump], args[:format]) if args[:dump]
40
+ end
41
+
42
+ def style=(s)
43
+ @style = s
44
+ end
45
+
46
+ def fps=(fps)
47
+ @fps = fps
48
+ end
49
+
50
+ def data=(data)
51
+ @raw = data
52
+ end
53
+
54
+ def <=>(other)
55
+ self.rating <=> other.rating
56
+ end
57
+ include Comparable
58
+
59
+ private
60
+
61
+ def parse_dump(dump,format)
62
+ raise unless SUB_EXTS.include?(format)
63
+ @raw = dump.kind_of?(String) ? dump : dump.read
64
+ @format = format
65
+ parse_lines!
66
+ end
67
+
68
+ def parse_lines!
69
+ self.lines = send :"parse_#{@format}"
70
+ end
71
+
72
+ def lines=(lines)
73
+ @lines = lines
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,9 @@
1
+ module SubtitleIt
2
+ module VERSION #:nodoc:
3
+ MAJOR = 0
4
+ MINOR = 7
5
+ TINY = 7
6
+
7
+ STRING = [MAJOR, MINOR, TINY].join('.')
8
+ end
9
+ end
@@ -0,0 +1,22 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+ require 'rubygems'
4
+ require 'subtitle_it/version'
5
+ require 'subtitle_it/languages'
6
+ require 'subtitle_it/subtime'
7
+ require 'subtitle_it/subline'
8
+ require 'subtitle_it/platform_endl'
9
+ require 'subtitle_it/subtitle'
10
+ require 'subtitle_it/subdown'
11
+ require 'subtitle_it/substyle'
12
+ require 'subtitle_it/movie'
13
+ require 'subtitle_it/bin'
14
+
15
+ module SubtitleIt
16
+ end
17
+
18
+ class Numeric
19
+ def reduce
20
+ self / ( 10 ** Math::log10(self).to_i)
21
+ end
22
+ end
data/script/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/subtitle_it.rb'}"
9
+ puts "Loading subtitle_it gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
data/script/destroy ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
data/script/generate ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)