bartzon-osdb 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ Manifest
2
+ README.md
3
+ Rakefile
4
+ bin/getsub
5
+ lib/osdb.rb
6
+ lib/osdb/language.rb
7
+ lib/osdb/movie.rb
8
+ lib/osdb/options.rb
9
+ lib/osdb/server.rb
10
+ lib/osdb/sub.rb
11
+ osdb.gemspec
12
+ spec/fixtures/somemovie.avi
13
+ spec/osdb/language_spec.rb
14
+ spec/osdb/movie_spec.rb
15
+ spec/osdb/server_spec.rb
16
+ spec/osdb/sub_spec.rb
17
+ spec/spec_helper.rb
@@ -0,0 +1,31 @@
1
+ # OSDb
2
+
3
+ Client library for the [OSDb protocol](http://trac.opensubtitles.org/projects/opensubtitles/wiki/XMLRPC).
4
+ Currently the implentation is limited to movie identification and subtitles search
5
+
6
+ ## Examples
7
+
8
+ Just read the source of `bin/getsub` it is a typical example of OSDb's capacities.
9
+
10
+ ## getsub
11
+
12
+ The osdb gem provide a simple script to find and download the best subtitle on
13
+ [opensubtitles.org](http://www.opensubtitles.org/) for your video file.
14
+
15
+ ### Installation
16
+
17
+ $ gem install bartzon-osdb
18
+
19
+ ### Usage
20
+
21
+ You just have to execute `getsub` with some video files in arguments:
22
+
23
+ $ getsub somemovie.avi othermovie.mkv
24
+
25
+ Or specify a directory to search recursively:
26
+
27
+ $ getsub -d ~/Movies
28
+
29
+ For options details just run:
30
+
31
+ $ getsub --help
@@ -0,0 +1,25 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'spec/rake/spectask'
4
+
5
+ Spec::Rake::SpecTask.new(:spec) do |spec|
6
+ spec.libs << 'lib' << 'spec'
7
+ spec.spec_files = FileList['spec/**/*_spec.rb']
8
+ end
9
+
10
+ begin
11
+ require 'echoe'
12
+
13
+ Echoe.new('bartzon-osdb', '0.0.6') do |p|
14
+ p.description = "Ruby library to access OSDb services like OpenSubtitles.org"
15
+ p.url = "http://github.com/bartzon/ruby-osdb"
16
+ p.author = "Jean Boussier, Bart Zonneveld"
17
+ p.email = "jean.boussier @nospam@ gmail.com, loop@superinfinite.com"
18
+ end
19
+
20
+ rescue LoadError => e
21
+ puts "Failed to load Echoe"
22
+ puts e.message
23
+ end
24
+
25
+ task :default => :spec
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{bartzon-osdb}
5
+ s.version = "0.0.6"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Jean Boussier, Bart Zonneveld"]
9
+ s.date = %q{2010-12-09}
10
+ s.default_executable = %q{getsub}
11
+ s.description = %q{Ruby library to access OSDb services like OpenSubtitles.org}
12
+ s.email = %q{jean.boussier @nospam@ gmail.com, loop@superinfinite.com}
13
+ s.executables = ["getsub"]
14
+ s.extra_rdoc_files = ["README.md", "bin/getsub", "lib/osdb.rb", "lib/osdb/language.rb", "lib/osdb/movie.rb", "lib/osdb/options.rb", "lib/osdb/server.rb", "lib/osdb/sub.rb"]
15
+ s.files = ["Manifest", "README.md", "Rakefile", "bin/getsub", "lib/osdb.rb", "lib/osdb/language.rb", "lib/osdb/movie.rb", "lib/osdb/options.rb", "lib/osdb/server.rb", "lib/osdb/sub.rb", "osdb.gemspec", "spec/fixtures/somemovie.avi", "spec/osdb/language_spec.rb", "spec/osdb/movie_spec.rb", "spec/osdb/server_spec.rb", "spec/osdb/sub_spec.rb", "spec/spec_helper.rb", "bartzon-osdb.gemspec"]
16
+ s.homepage = %q{http://github.com/bartzon/ruby-osdb}
17
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Bartzon-osdb", "--main", "README.md"]
18
+ s.require_paths = ["lib"]
19
+ s.rubyforge_project = %q{bartzon-osdb}
20
+ s.rubygems_version = %q{1.3.7}
21
+ s.summary = %q{Ruby library to access OSDb services like OpenSubtitles.org}
22
+
23
+ if s.respond_to? :specification_version then
24
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
+ s.specification_version = 3
26
+
27
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
28
+ else
29
+ end
30
+ else
31
+ end
32
+ end
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ STDOUT.sync = true
4
+
5
+ require 'optparse'
6
+ require 'uri'
7
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'osdb')
8
+
9
+ OSDb::Sub.fetch_all
@@ -0,0 +1,37 @@
1
+ require 'xmlrpc/client'
2
+
3
+ module OSDb
4
+ base_path = File.expand_path(File.dirname(__FILE__) + '/osdb')
5
+ autoload :Language, "#{base_path}/language"
6
+ autoload :Movie, "#{base_path}/movie"
7
+ autoload :Server, "#{base_path}/server"
8
+ autoload :Sub, "#{base_path}/sub"
9
+ autoload :Options, "#{base_path}/options"
10
+
11
+ def self.log(str='')
12
+ puts str unless options[:silent]
13
+ end
14
+
15
+ def self.options
16
+ @@options ||= OSDb::Options.parse_options
17
+ end
18
+
19
+ def self.curl_available?
20
+ %x{ curl --version 2> /dev/null > /dev/null }
21
+ $?.success?
22
+ end
23
+
24
+ def self.wget_available?
25
+ %x{ wget --version 2> /dev/null > /dev/null }
26
+ $?.success?
27
+ end
28
+
29
+ def self.server
30
+ @@server ||= OSDb::Server.new(
31
+ :host => 'api.opensubtitles.org',
32
+ :path => '/xml-rpc',
33
+ :timeout => 90,
34
+ :useragent => "SubDownloader 2.0.10" # register useragent ? WTF ? too boring.
35
+ )
36
+ end
37
+ end
@@ -0,0 +1,84 @@
1
+ module OSDb
2
+
3
+ LANGUAGES = [
4
+ {:iso639_1 => 'sq', :iso639_2b => 'alb', :locale => 'sq', :name => 'Albanian'},
5
+ {:iso639_1 => 'ar', :iso639_2b => 'ara', :locale => 'ar', :name => 'Arabic'},
6
+ {:iso639_1 => 'hy', :iso639_2b => 'arm', :locale => 'hy', :name => 'Armenian'},
7
+ {:iso639_1 => 'ms', :iso639_2b => 'may', :locale => 'ms', :name => 'Malay'},
8
+ {:iso639_1 => 'bs', :iso639_2b => 'bos', :locale => 'bs', :name => 'Bosnian'},
9
+ {:iso639_1 => 'bg', :iso639_2b => 'bul', :locale => 'bg', :name => 'Bulgarian'},
10
+ {:iso639_1 => 'ca', :iso639_2b => 'cat', :locale => 'ca', :name => 'Catalan'},
11
+ {:iso639_1 => 'eu', :iso639_2b => 'eus', :locale => 'eu', :name => 'Basque'},
12
+ {:iso639_1 => 'zh', :iso639_2b => 'chi', :locale => 'zh_CN', :name => 'Chinese (China)'},
13
+ {:iso639_1 => 'hr', :iso639_2b => 'hrv', :locale => 'hr', :name => 'Croatian'},
14
+ {:iso639_1 => 'cs', :iso639_2b => 'cze', :locale => 'cs', :name => 'Czech'},
15
+ {:iso639_1 => 'da', :iso639_2b => 'dan', :locale => 'da', :name => 'Danish'},
16
+ {:iso639_1 => 'nl', :iso639_2b => 'dut', :locale => 'nl', :name => 'Dutch'},
17
+ {:iso639_1 => 'en', :iso639_2b => 'eng', :locale => 'en', :name => 'English (US)'},
18
+ {:iso639_1 => 'en', :iso639_2b => 'bre', :locale => 'en_GB', :name => 'English (UK)'},
19
+ {:iso639_1 => 'eo', :iso639_2b => 'epo', :locale => 'eo', :name => 'Esperanto'},
20
+ {:iso639_1 => 'et', :iso639_2b => 'est', :locale => 'et', :name => 'Estonian'},
21
+ {:iso639_1 => 'fi', :iso639_2b => 'fin', :locale => 'fi', :name => 'Finnish'},
22
+ {:iso639_1 => 'fr', :iso639_2b => 'fre', :locale => 'fr', :name => 'French'},
23
+ {:iso639_1 => 'gl', :iso639_2b => 'glg', :locale => 'gl', :name => 'Galician'},
24
+ {:iso639_1 => 'ka', :iso639_2b => 'geo', :locale => 'ka', :name => 'Georgian'},
25
+ {:iso639_1 => 'de', :iso639_2b => 'ger', :locale => 'de', :name => 'German'},
26
+ {:iso639_1 => 'el', :iso639_2b => 'ell', :locale => 'el', :name => 'Greek'},
27
+ {:iso639_1 => 'he', :iso639_2b => 'heb', :locale => 'he', :name => 'Hebrew'},
28
+ {:iso639_1 => 'hu', :iso639_2b => 'hun', :locale => 'hu', :name => 'Hungarian'},
29
+ {:iso639_1 => 'id', :iso639_2b => 'ind', :locale => 'id', :name => 'Indonesian'},
30
+ {:iso639_1 => 'it', :iso639_2b => 'ita', :locale => 'it', :name => 'Italian'},
31
+ {:iso639_1 => 'ja', :iso639_2b => 'jpn', :locale => 'ja', :name => 'Japanese'},
32
+ {:iso639_1 => 'kk', :iso639_2b => 'kaz', :locale => 'kk', :name => 'Kazakh'},
33
+ {:iso639_1 => 'ko', :iso639_2b => 'kor', :locale => 'ko', :name => 'Korean'},
34
+ {:iso639_1 => 'lv', :iso639_2b => 'lav', :locale => 'lv', :name => 'Latvian'},
35
+ {:iso639_1 => 'lt', :iso639_2b => 'lit', :locale => 'lt', :name => 'Lithuanian'},
36
+ {:iso639_1 => 'lb', :iso639_2b => 'ltz', :locale => 'lb', :name => 'Luxembourgish'},
37
+ {:iso639_1 => 'mk', :iso639_2b => 'mac', :locale => 'mk', :name => 'Macedonian'},
38
+ {:iso639_1 => 'no', :iso639_2b => 'nor', :locale => 'no', :name => 'Norwegian'},
39
+ {:iso639_1 => 'fa', :iso639_2b => 'per', :locale => 'fa', :name => 'Persian'},
40
+ {:iso639_1 => 'pl', :iso639_2b => 'pol', :locale => 'pl', :name => 'Polish'},
41
+ {:iso639_1 => 'pt', :iso639_2b => 'por', :locale => 'pt_PT', :name => 'Portuguese (Portugal)'},
42
+ {:iso639_1 => 'pb', :iso639_2b => 'pob', :locale => 'pt_BR', :name => 'Portuguese (Brazil)'},
43
+ {:iso639_1 => 'ro', :iso639_2b => 'rum', :locale => 'ro', :name => 'Romanian'},
44
+ {:iso639_1 => 'ru', :iso639_2b => 'rus', :locale => 'ru', :name => 'Russian'},
45
+ {:iso639_1 => 'sr', :iso639_2b => 'scc', :locale => 'sr', :name => 'Serbian'},
46
+ {:iso639_1 => 'sk', :iso639_2b => 'slo', :locale => 'sk', :name => 'Slovak'},
47
+ {:iso639_1 => 'sl', :iso639_2b => 'slv', :locale => 'sl', :name => 'Slovenian'},
48
+ {:iso639_1 => 'es', :iso639_2b => 'spa', :locale => 'es_ES', :name => 'Spanish (Spain)'},
49
+ {:iso639_1 => 'sv', :iso639_2b => 'swe', :locale => 'sv', :name => 'Swedish'},
50
+ {:iso639_1 => 'th', :iso639_2b => 'tha', :locale => 'th', :name => 'Thai'},
51
+ {:iso639_1 => 'tr', :iso639_2b => 'tur', :locale => 'tr', :name => 'Turkish'},
52
+ {:iso639_1 => 'uk', :iso639_2b => 'ukr', :locale => 'uk', :name => 'Ukrainian'},
53
+ {:iso639_1 => 'vi', :iso639_2b => 'vie', :locale => 'vi', :name => 'Vietnamese'}
54
+ ]
55
+
56
+ class Language
57
+
58
+ class << self
59
+
60
+ def from_locale(locale)
61
+ locale = locale.split('.').first
62
+ lang = LANGUAGES.find{ |lang| lang[:locale] == locale }
63
+ return from_locale(locale.split('_').first) if !lang && locale.include?('_')
64
+ new(lang)
65
+ end
66
+
67
+ def from_iso639_2b(code)
68
+ new(LANGUAGES.find{ |lang| lang[:iso639_2b] == code })
69
+ end
70
+
71
+ end
72
+
73
+ attr_reader :name, :to_iso639_1, :to_iso639_2b, :to_locale
74
+
75
+ def initialize(hash)
76
+ @name = hash[:name]
77
+ @to_iso639_1 = hash[:iso639_1]
78
+ @to_iso639_2b = hash[:iso639_2b]
79
+ @to_locale = hash[:locale]
80
+ end
81
+
82
+ end
83
+
84
+ end
@@ -0,0 +1,81 @@
1
+ module OSDb
2
+ class Movie
3
+
4
+ attr_reader :path
5
+
6
+ class << self
7
+ def get_movie_list
8
+
9
+ if dir = OSDb.options[:dir]
10
+ path = Dir.glob(File.join(dir, '**', "*.{#{OSDb.options[:movie_exts]}}"))
11
+ movies = path.map { |path| new(path) }
12
+ else
13
+ movies = ARGV.map{ |path| OSDb::Movie.new(path) }
14
+ end
15
+ movies.reject!(&:has_sub?) unless OSDb.options[:force]
16
+
17
+ if movies.empty?
18
+ OSDb.log "All movies in #{dir} already have subtitles."
19
+ exit 1
20
+ end
21
+
22
+ movies
23
+ end
24
+ end
25
+
26
+ def initialize(path)
27
+ @path = path
28
+ end
29
+
30
+ def has_sub?
31
+ exist = false
32
+ %w(.srt .sub .smi).each{ |ext| exist ||= File.exist?(path.gsub(File.extname(path), ext)) }
33
+ exist
34
+ end
35
+
36
+ def sub_path(format)
37
+ path.gsub(File.extname(path), ".#{format}")
38
+ end
39
+
40
+ def hash
41
+ @hash ||= self.class.compute_hash(path)
42
+ end
43
+
44
+ def size
45
+ @size ||= File.size(path)
46
+ end
47
+
48
+ CHUNK_SIZE = 64 * 1024 # in bytes
49
+
50
+ # from http://trac.opensubtitles.org/projects/opensubtitles/wiki/HashSourceCodes
51
+ def self.compute_hash(path)
52
+ begin
53
+ filesize = File.size(path)
54
+ hash = filesize
55
+
56
+ # Read 64 kbytes, divide up into 64 bits and add each
57
+ # to hash. Do for beginning and end of file.
58
+ File.open(path, 'rb') do |f|
59
+ # Q = unsigned long long = 64 bit
60
+ f.read(CHUNK_SIZE).unpack("Q*").each do |n|
61
+ hash = hash + n & 0xffffffffffffffff # to remain as 64 bit number
62
+ end
63
+
64
+ f.seek([0, filesize - CHUNK_SIZE].max, IO::SEEK_SET)
65
+
66
+ # And again for the end of the file
67
+ f.read(CHUNK_SIZE).unpack("Q*").each do |n|
68
+ hash = hash + n & 0xffffffffffffffff
69
+ end
70
+ end
71
+
72
+ sprintf("%016x", hash)
73
+ rescue Errno::EPERM
74
+ OSDb.log("* could not read #{path}")
75
+ rescue RuntimeError
76
+ OSDb.log("* could not read #{path}")
77
+ end
78
+ end
79
+
80
+ end
81
+ end
@@ -0,0 +1,51 @@
1
+ module OSDb
2
+ class Options
3
+
4
+ class << self
5
+ def env_lang
6
+ OSDb::Language.from_locale(ENV['LANG'])
7
+ end
8
+
9
+ def parse_options
10
+ @@options = {:languages => [env_lang.to_iso639_2b], :force => false, :dir => nil, :silent => false, :movie_exts => %w{avi,mpg,m4v,mkv,mov,ogv,divx} }
11
+
12
+ @@parser ||= OptionParser.new do |opts|
13
+ opts.banner = "Automatically download subs for your video files using opensubtitles.org"
14
+ opts.separator ""
15
+ opts.separator "Usage: getsub [options] DIRECTORY | VIDEO_FILE [VIDEO_FILE ...]"
16
+ opts.separator ""
17
+ opts.separator "Main options:"
18
+
19
+ opts.on("-e", "--extensions EXTENSIONS", "Movie extensions to search for when using --directory. Default: #{@@options[:movie_exts].join(',')}") do |exts|
20
+ @@options[:movie_exts] = exts.split(',')
21
+ end
22
+
23
+ opts.on("-l", "--languages LANGUAGES", "Sub language ISO 963 code separated by comma's like fre or eng. Default: env $LANG (#{env_lang.to_iso639_2b})") do |languages|
24
+ @@options[:languages] = languages.split(',')
25
+ end
26
+
27
+ opts.on("-d", "--directory DIRECTORY", "Specify a directory to search recursively for movies") do |dir|
28
+ @@options[:dir] = dir
29
+ end
30
+
31
+ opts.on("-f", "--force", "Download sub even if video already has one") { @@options[:force] = true }
32
+
33
+ opts.on("-s", "--silent", "Don't output anything") { options[:silent] = true }
34
+ end
35
+ @@parser.parse!
36
+
37
+ if !@@options[:dir] && ARGV.empty?
38
+ help
39
+ exit 1
40
+ end
41
+
42
+ @@options
43
+ end
44
+
45
+ def help
46
+ puts @@parser.help
47
+ end
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,53 @@
1
+ module OSDb
2
+
3
+ class LoginFailed < ::Exception
4
+ end
5
+
6
+ class Server
7
+
8
+ attr_reader :username, :password, :language, :useragent, :client
9
+
10
+ def initialize(options={})
11
+ @username = options[:username] || ''
12
+ @password = options[:password] || ''
13
+ @language = options[:language] || 'eng'
14
+ @useragent = options[:useragent] || 'ruby-osdb v0.1'
15
+ @client = ::XMLRPC::Client.new(*options.values_at(:host, :path, :port, :proxy_host, :proxy_port, :http_user, :http_password, :use_ssl, :timeout))
16
+ end
17
+
18
+ def token
19
+ @token ||= login
20
+ end
21
+
22
+ def login
23
+ response = client.call('LogIn', username, password, language, useragent)
24
+ if response['status'] != '200 OK'
25
+ raise LoginFailed.new("Failed to login with #{username} : #{password}. Server return code: #{response['status']}")
26
+ end
27
+ response['token']
28
+ end
29
+
30
+ def logout
31
+ client.call('LogOut', token)
32
+ @token = nil
33
+ end
34
+
35
+ def check_movie_hash(*hashes)
36
+ client.call('CheckMovieHash', token, hashes)
37
+ end
38
+
39
+ def search_subtitles(*queries)
40
+ subs = client.call('SearchSubtitles', token, queries)['data']
41
+ subs ? subs.map{ |s| Sub.new(s) } : []
42
+ rescue EOFError
43
+ []
44
+ rescue RuntimeError
45
+ []
46
+ end
47
+
48
+ def info
49
+ client.call('ServerInfo')
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,91 @@
1
+ require 'uri'
2
+
3
+ module OSDb
4
+
5
+ class Sub
6
+
7
+ attr_reader :url, :format, :language, :rating, :movie_name, :raw_data
8
+
9
+ class << self
10
+ def fetch_all
11
+ movies = Movie.get_movie_list
12
+
13
+ movies.each do |movie|
14
+ begin
15
+ OSDb.log "* search subs for: #{movie.path}"
16
+ subs = OSDb.server.search_subtitles(:moviehash => movie.hash, :moviebytesize => movie.size, :sublanguageid => OSDb.options[:languages].join(','))
17
+ if subs.any?
18
+ if sub = select_sub(subs)
19
+ sub_path = movie.sub_path(sub.format)
20
+ Sub.download!(sub.url, sub_path)
21
+ end
22
+ else
23
+ OSDb.log "* no sub found"
24
+ end
25
+ OSDb.log
26
+ end
27
+ end
28
+ end
29
+
30
+ def download!(url, local_path)
31
+ OSDb.log "* download #{url} to #{local_path}"
32
+ if OSDb.curl_available?
33
+ %x{ curl -s '#{url}' | gunzip > "#{local_path}" }
34
+ elsif OSDb.wget_available?
35
+ %x{ wget -O -quiet - '#{url}' | gunzip > "#{local_path}"}
36
+ else
37
+ OSDb.log "Can't found any curl or wget please install one of them or manualy download your sub"
38
+ OSDb.log url
39
+ end
40
+ end
41
+
42
+ private
43
+ def select_sub(subs)
44
+ return subs.first if subs.length == 1
45
+ movies = group_by_movie_name(subs)
46
+ return movies.values.first.max if movies.length == 1
47
+ if selected_movie_subs = ask_user_to_identify_movie(movies)
48
+ selected_movie_subs.max
49
+ else
50
+ nil
51
+ end
52
+ end
53
+
54
+ def group_by_movie_name(subs)
55
+ subs.inject({}) do |hash, sub|
56
+ hash[sub.movie_name] ||= []
57
+ hash[sub.movie_name] << sub
58
+ hash
59
+ end
60
+ end
61
+
62
+ def ask_user_to_identify_movie(movies)
63
+ puts "D'oh! You stumbled upon a hash conflict, please resolve it:"
64
+ puts
65
+ puts " 0 - none of the below"
66
+ movies.keys.each_with_index do |name, index|
67
+ puts " #{index+1} - #{name}"
68
+ end
69
+ puts
70
+ print 'id: '
71
+ str = STDIN.gets.to_i
72
+ str == 0 ? false : movies[movies.keys[str.to_i]]
73
+ end
74
+ end
75
+
76
+ def initialize(data)
77
+ @url = URI.parse(data['SubDownloadLink'])
78
+ @format = data['SubFormat']
79
+ @language = Language.from_iso639_2b(data['SubLanguageID'])
80
+ @rating = data['SubRating'].to_f
81
+ @movie_name = data['MovieName']
82
+ @raw_data = data
83
+ end
84
+
85
+ def <=>(other)
86
+ rating <=> other.rating
87
+ end
88
+
89
+ end
90
+
91
+ end
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{osdb}
5
+ s.version = "0.0.5"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Jean Boussier, Bart Zonneveld"]
9
+ s.date = %q{2010-12-09}
10
+ s.default_executable = %q{getsub}
11
+ s.description = %q{Ruby library to access OSDb services like OpenSubtitles.org}
12
+ s.email = %q{jean.boussier @nospam@ gmail.com, loop@superinfinite.com}
13
+ s.executables = ["getsub"]
14
+ s.extra_rdoc_files = ["README.md", "bin/getsub", "lib/osdb.rb", "lib/osdb/language.rb", "lib/osdb/movie.rb", "lib/osdb/server.rb", "lib/osdb/sub.rb", "lib/osdb/options.rb"]
15
+ s.files = FileList['lib/**/*.rb', 'bin/*', '[A-Z]*', 'spec/**/*'].to_a
16
+ s.homepage = %q{http://github.com/bartzon/ruby-osdb}
17
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Osdb", "--main", "README.md"]
18
+ s.require_paths = ["lib"]
19
+ s.rubyforge_project = %q{osdb}
20
+ s.rubygems_version = %q{1.3.7}
21
+ s.summary = %q{Ruby library to access OSDb services like OpenSubtitles.org}
22
+
23
+ if s.respond_to? :specification_version then
24
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
25
+ s.specification_version = 3
26
+
27
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
28
+ else
29
+ end
30
+ else
31
+ end
32
+ end
@@ -0,0 +1,57 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe OSDb::Language do
4
+
5
+ describe '.from_locale' do
6
+
7
+ describe "simple locale" do
8
+
9
+ subject{ OSDb::Language.from_locale('fr') }
10
+
11
+ its(:name) { should == 'French' }
12
+
13
+ its(:to_iso639_1) { should == 'fr' }
14
+
15
+ its(:to_iso639_2b) { should == 'fre' }
16
+
17
+ end
18
+
19
+ describe "locale with territory" do
20
+
21
+ subject{ OSDb::Language.from_locale('en_US') }
22
+
23
+ its(:name) { should == 'English (US)' }
24
+
25
+ its(:to_iso639_1) { should == 'en' }
26
+
27
+ its(:to_iso639_2b) { should == 'eng' }
28
+
29
+ end
30
+
31
+ describe "locale with territory and encoding" do
32
+
33
+ subject{ OSDb::Language.from_locale('es_ES.UTF8') }
34
+
35
+ its(:name) { should == 'Spanish (Spain)' }
36
+
37
+ its(:to_iso639_1) { should == 'es' }
38
+
39
+ its(:to_iso639_2b) { should == 'spa' }
40
+
41
+ end
42
+
43
+ end
44
+
45
+ describe ".from_iso_639_2b" do
46
+
47
+ subject{ OSDb::Language.from_iso639_2b('bre') }
48
+
49
+ its(:name) { should == 'English (UK)' }
50
+
51
+ its(:to_iso639_1) { should == 'en' }
52
+
53
+ its(:to_locale) { should == 'en_GB' }
54
+
55
+ end
56
+
57
+ end
@@ -0,0 +1,11 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe OSDb::Movie do
4
+
5
+ subject do
6
+ OSDb::Movie.new(File.dirname(__FILE__) + '/../fixtures/somemovie.avi')
7
+ end
8
+
9
+ its(:hash) { should == '243339b48f4e8741' }
10
+
11
+ end
@@ -0,0 +1,79 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe OSDb::Server do
4
+
5
+ before :all do
6
+ @server = OSDb::Server.new(
7
+ :host => 'api.opensubtitles.org',
8
+ :path => '/xml-rpc',
9
+ :timeout => 60, # OS.org is very very slow ....
10
+ :useragent => 'OS Test User Agent'
11
+ )
12
+ end
13
+
14
+ subject { @server }
15
+
16
+ it 'should respond to #info' do
17
+ hash_including(
18
+ "seconds" => instance_of(Float),
19
+ "last_update_strings" => instance_of(Hash),
20
+ "website_url"=>"http://www.opensubtitles.org",
21
+ "contact"=>"admin@opensubtitles.org",
22
+ "application"=>"OpenSuber v0.2",
23
+ "xmlrpc_version"=>"0.1",
24
+ "xmlrpc_url"=>"http://api.opensubtitles.net/xml-rpc"
25
+ ).should == subject.info
26
+ end
27
+
28
+ it 'should automatically call #login when token is needed' do
29
+ subject.instance_variable_get('@token').should be_nil
30
+ subject.token.should match(/[a-z0-9]{26}/)
31
+ subject.instance_variable_get('@token').should == subject.token
32
+ end
33
+
34
+ it 'should clear @login after #logout' do
35
+ expect{
36
+ subject.logout
37
+ }.to change{ subject.instance_variable_get('@token') }.from(instance_of(String)).to(nil)
38
+ end
39
+
40
+ describe "#check_movie_hash" do
41
+
42
+ it 'should identify movie' do
43
+ subject.check_movie_hash('37d0c7d0cfcbe280')['data'].should == {
44
+ "37d0c7d0cfcbe280" => {
45
+ "MovieYear" => "1996",
46
+ "MovieImdbID" => "0117500",
47
+ "MovieName" => "The Rock",
48
+ "MovieHash" => "37d0c7d0cfcbe280"
49
+ }
50
+ }
51
+ end
52
+
53
+ end
54
+
55
+ describe '#search_subtitles' do
56
+
57
+ it 'can search by hash and size' do
58
+ subs = subject.search_subtitles(:moviehash => 'bd71526264fd8bd9', :moviebytesize => '183406990', :sublanguageid => 'fre')
59
+ subs.should be_a(Array)
60
+ subs.length.should >= 2
61
+ subs.each do |sub|
62
+ sub.language.name.should == 'French'
63
+ sub.raw_data['MovieName'].should == '"How I Met Your Mother"'
64
+ end
65
+ end
66
+
67
+ it 'can search by imdbid' do
68
+ subs = subject.search_subtitles(:imdbid => "0117500", :sublanguageid => 'fre')
69
+ subs.should be_a(Array)
70
+ subs.length.should >= 1
71
+ subs.each do |sub|
72
+ sub.language.name.should == 'French'
73
+ sub.raw_data['MovieName'].should == 'The Rock'
74
+ end
75
+ end
76
+
77
+ end
78
+
79
+ end
@@ -0,0 +1,33 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+
3
+ describe OSDb::Sub do
4
+
5
+ before :each do
6
+ @response = {
7
+ 'SubFormat' => 'srt',
8
+ 'SubDownloadLink' => 'http://example.com/foo.srt.gz',
9
+ 'SubRating' => '7.89',
10
+ 'SubLanguageID' => 'dut',
11
+ 'MovieName' => 'Lock, Stock and Two Smoking Barrels'
12
+ }
13
+ end
14
+
15
+ subject do
16
+ OSDb::Sub.new @response
17
+ end
18
+
19
+ its(:format) { should == 'srt' }
20
+
21
+ its(:url) { should be_an(URI::HTTP) }
22
+
23
+ its(:language) { should be_a(OSDb::Language) }
24
+
25
+ its(:rating) { should == 7.89 }
26
+
27
+ its(:movie_name) { should == 'Lock, Stock and Two Smoking Barrels' }
28
+
29
+ it 'should be comparable' do
30
+ [subject, OSDb::Sub.new(@response.merge('SubRating' => '2.45'))].max.should == subject
31
+ end
32
+
33
+ end
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + '/../lib/osdb'
2
+ require 'spec/autorun'
3
+
4
+ # Spec Helpers
5
+ Dir[File.dirname(__FILE__) + '/*_spec_helper.rb'].each do |f|
6
+ require File.expand_path(f)
7
+ end
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bartzon-osdb
3
+ version: !ruby/object:Gem::Version
4
+ hash: 19
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 6
10
+ version: 0.0.6
11
+ platform: ruby
12
+ authors:
13
+ - Jean Boussier, Bart Zonneveld
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-12-09 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: Ruby library to access OSDb services like OpenSubtitles.org
23
+ email: jean.boussier @nospam@ gmail.com, loop@superinfinite.com
24
+ executables:
25
+ - getsub
26
+ extensions: []
27
+
28
+ extra_rdoc_files:
29
+ - README.md
30
+ - bin/getsub
31
+ - lib/osdb.rb
32
+ - lib/osdb/language.rb
33
+ - lib/osdb/movie.rb
34
+ - lib/osdb/options.rb
35
+ - lib/osdb/server.rb
36
+ - lib/osdb/sub.rb
37
+ files:
38
+ - Manifest
39
+ - README.md
40
+ - Rakefile
41
+ - bin/getsub
42
+ - lib/osdb.rb
43
+ - lib/osdb/language.rb
44
+ - lib/osdb/movie.rb
45
+ - lib/osdb/options.rb
46
+ - lib/osdb/server.rb
47
+ - lib/osdb/sub.rb
48
+ - osdb.gemspec
49
+ - spec/fixtures/somemovie.avi
50
+ - spec/osdb/language_spec.rb
51
+ - spec/osdb/movie_spec.rb
52
+ - spec/osdb/server_spec.rb
53
+ - spec/osdb/sub_spec.rb
54
+ - spec/spec_helper.rb
55
+ - bartzon-osdb.gemspec
56
+ has_rdoc: true
57
+ homepage: http://github.com/bartzon/ruby-osdb
58
+ licenses: []
59
+
60
+ post_install_message:
61
+ rdoc_options:
62
+ - --line-numbers
63
+ - --inline-source
64
+ - --title
65
+ - Bartzon-osdb
66
+ - --main
67
+ - README.md
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ none: false
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ hash: 3
76
+ segments:
77
+ - 0
78
+ version: "0"
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ hash: 11
85
+ segments:
86
+ - 1
87
+ - 2
88
+ version: "1.2"
89
+ requirements: []
90
+
91
+ rubyforge_project: bartzon-osdb
92
+ rubygems_version: 1.3.7
93
+ signing_key:
94
+ specification_version: 3
95
+ summary: Ruby library to access OSDb services like OpenSubtitles.org
96
+ test_files: []
97
+