c3po 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 af83
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
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.
data/README.md ADDED
@@ -0,0 +1,67 @@
1
+ C3PO
2
+ ====
3
+
4
+ Ruby translator client. Actual provider :
5
+
6
+ * Google Translate
7
+ * Bing Translate
8
+
9
+ Ruby 1.9.2 is strongly recommanded.
10
+
11
+
12
+ Dependency
13
+ ----------
14
+
15
+ `libcurl4-gnutls-dev`
16
+
17
+
18
+ Installation
19
+ ------------
20
+
21
+ Install it with rubygems:
22
+
23
+ ``` ruby
24
+ gem install c3po
25
+ ```
26
+
27
+ With bundler, add it to your `Gemfile`:
28
+
29
+ ``` ruby
30
+ gem "c3po", "~>0.1"
31
+ ```
32
+
33
+
34
+ Usage
35
+ -----
36
+
37
+ ``` ruby
38
+ # Define a provider
39
+ C3po.configure do |config|
40
+ config.provider = :google
41
+ config.google_api_key = "MYAPIKEY"
42
+ end
43
+
44
+ # Define several provider
45
+ C3po.configure do |config|
46
+ config.provider = [:google, :bing]
47
+ config.google_api_key = "MYAPIKEY"
48
+ config.bing_api_key = "MYAPIKEY"
49
+ end
50
+
51
+ # Let's translate
52
+ translator = C3po.new('I want this droid to be translated')
53
+ translator.translate(:en, :fr) # =>
54
+ translator.is # => :en
55
+ translator.is?(:de) # => false
56
+ ```
57
+
58
+ Todo
59
+ ----
60
+
61
+ * More specs
62
+ * Use it
63
+
64
+ Copyright
65
+ ---------
66
+
67
+ See LICENSE for further details.
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ # encoding: utf-8
2
+ require "c3po"
data/lib/c3po.rb ADDED
@@ -0,0 +1,97 @@
1
+ # encoding: utf-8
2
+ class C3po
3
+
4
+ class NoGivenString < Exception; end
5
+ class NoGivenProvider < Exception; end
6
+
7
+ autoload :Translator, 'c3po/translator'
8
+ autoload :Client, 'c3po/client'
9
+
10
+ module Translator
11
+ autoload :Configuration, 'c3po/translator/configuration'
12
+ autoload :Result, 'c3po/translator/result'
13
+ autoload :Google, 'c3po/translator/google'
14
+ autoload :Bing, 'c3po/translator/bing'
15
+ end
16
+
17
+ include Client
18
+ include C3po::Translator
19
+
20
+ attr_reader :base_url, :to_be_translated, :errors, :result, :adaptor
21
+
22
+ # Define a translator object.
23
+ #
24
+ # @example
25
+ # translator = C3po.new('to be translated')
26
+ # translator.translate(:fr, :en)
27
+ #
28
+ # @param [ String ] string String on witch we will work
29
+ #
30
+ # @since 0.0.1
31
+ #
32
+ def initialize(to_be_translated = nil)
33
+ raise NoGivenString if to_be_translated.nil?
34
+ @to_be_translated = to_be_translated
35
+ select_provider
36
+ @base_url = self.class.base_url
37
+ @result = C3po::Translator::Result.new
38
+ @errors = []
39
+ end
40
+
41
+ class << self
42
+
43
+ attr_accessor :base_url
44
+
45
+ # Define a configure block.
46
+ #
47
+ # Delegates to C3po::Translator::Configuration
48
+ #
49
+ # config.provider can be an Array. In this case,
50
+ # provider will be randomly choosen from it.
51
+ #
52
+ # @example Define the option.
53
+ # C3po.configure do |config|
54
+ # config.provider = :google
55
+ # config.google_api_key = "MYAPIKEY"
56
+ # end
57
+ #
58
+ # @param [ Proc ] block The block getting called.
59
+ #
60
+ # @since 0.0.1
61
+ #
62
+ def configure(&block)
63
+ C3po::Translator::Configuration.configure(&block)
64
+ end
65
+
66
+ end # self
67
+
68
+ private
69
+
70
+ # Include provider based on configuration
71
+ #
72
+ # @since 0.0.1
73
+ #
74
+ def select_provider
75
+ case provider
76
+ when :google
77
+ @adaptor = Google.new @to_be_translated
78
+ when :bing
79
+ @adaptor = Bing.new @to_be_translated
80
+ else
81
+ raise NoGivenProvider
82
+ end
83
+ end
84
+
85
+ # Choose provider based on configuration
86
+ #
87
+ # If Configuration.provider is an Array,
88
+ # take a random value from as provider
89
+ #
90
+ # @since 0.0.1
91
+ #
92
+ def provider
93
+ provider = Configuration.provider
94
+ @provider ||= provider.is_a?(Array) ? provider.sample : provider
95
+ end
96
+
97
+ end # C3po
@@ -0,0 +1,78 @@
1
+ # encoding: utf-8
2
+ require 'typhoeus'
3
+
4
+ class C3po
5
+ module Client
6
+
7
+ # Query a web service.
8
+ #
9
+ # Returns a translated string or an array of errors.
10
+ #
11
+ # @example
12
+ # fetch {:key => 'MYAPIKEY',
13
+ # :q => 'Something to translate'
14
+ # }
15
+ #
16
+ # @param [Hash] Query containing all the params.
17
+ #
18
+ # @return [String] Translated string.
19
+ #
20
+ # @since 0.0.1
21
+ #
22
+ def fetch(query)
23
+ request = set_request query
24
+ request.on_complete {|response| process_reponse response}
25
+
26
+ hydra = Typhoeus::Hydra.hydra
27
+ hydra.queue request
28
+ hydra.run
29
+
30
+ @response if @errors.empty?
31
+ end
32
+
33
+ private
34
+
35
+ # Create a Typhoeus request object.
36
+ #
37
+ # @example
38
+ # set_request {:key => 'MYAPIKEY',
39
+ # :q => 'Something to translate'
40
+ # }
41
+ #
42
+ # @param [Hash] Query containing all the params.
43
+ #
44
+ # @return [Typhoeus::Request] Translated string.
45
+ #
46
+ # @since 0.0.1
47
+ #
48
+ def set_request(query)
49
+ Typhoeus::Request.new @adaptor.base_url, :params => query
50
+ end
51
+
52
+ # Process response.
53
+ #
54
+ # @example
55
+ # process_reponse response
56
+ #
57
+ # @param [Typhoeus::Response] Typhoeus response object.
58
+ #
59
+ # @return [Typhoeus::Request] Translated string.
60
+ #
61
+ # @since 0.0.1
62
+ #
63
+ def process_reponse(response)
64
+ if response.success?
65
+ begin
66
+ @response = @adaptor.parse response.body
67
+ rescue
68
+ @errors << 'Invalid response'
69
+ end
70
+ elsif response.timed_out?
71
+ @errors << 'timeout'
72
+ else
73
+ @errors << "HTTP request failed: #{response.code}"
74
+ end
75
+ end
76
+
77
+ end # Client
78
+ end # C3po
@@ -0,0 +1,67 @@
1
+ # encoding: utf-8
2
+ class C3po
3
+ module Translator
4
+
5
+ # Translate a string.
6
+ #
7
+ # @example
8
+ # translator = C3po.new('translate')
9
+ # translator.translate(:en, :fr)
10
+ #
11
+ # @param [ Symbol ] language to translate from
12
+ # @param [ Symbol ] language to translate to
13
+ #
14
+ # @return [String] the translated string
15
+ #
16
+ # @since 0.0.1
17
+ #
18
+ def translate(from, to)
19
+ @result.translation ||= fetch @adaptor.build_query(from, to)
20
+ end
21
+
22
+ # Grab languages list from provider.
23
+ #
24
+ # @example
25
+ # translator = C3po.new('translate')
26
+ # translator.languages
27
+ #
28
+ # @return [Array] the languages list
29
+ #
30
+ # @since 0.0.1
31
+ #
32
+ def languages
33
+ @result.languages ||= fetch @adaptor.build_languages_query
34
+ end
35
+
36
+ # Identify language.
37
+ #
38
+ # @example
39
+ # translator = C3po.new('translate')
40
+ # translator.is
41
+ #
42
+ # @return [String] the identified language
43
+ #
44
+ # @since 0.0.1
45
+ #
46
+ def is
47
+ @result.language ||= fetch @adaptor.build_detect_query
48
+ end
49
+
50
+ # Check language.
51
+ #
52
+ # @example
53
+ # translator = C3po.new('translate')
54
+ # translator.is? :fr
55
+ #
56
+ # @param [ Symbol ] language to check
57
+ #
58
+ # @return [Boolean]
59
+ #
60
+ # @since 0.0.1
61
+ #
62
+ def is?(language)
63
+ language.to_s == is
64
+ end
65
+
66
+ end #Translator
67
+ end #C3po
@@ -0,0 +1,75 @@
1
+ # encoding: utf-8
2
+ require 'nokogiri'
3
+
4
+ class C3po
5
+ module Translator
6
+ class Bing
7
+ attr_reader :base_url
8
+
9
+ def initialize(to_be_translated)
10
+ @to_be_translated = to_be_translated
11
+ @default = {
12
+ :appId => C3po::Translator::Configuration.bing_api_key,
13
+ }
14
+ end
15
+
16
+ # Build a query for the Bing Translate api.
17
+ #
18
+ # @example
19
+ # build_query :fr, :en
20
+ #
21
+ # @param [Symbol] Language to be translated from.
22
+ # [Symbol] Language to be translated to.
23
+ #
24
+ # @return [Hash] Hash of param.
25
+ #
26
+ # @since 0.0.1
27
+ #
28
+ def build_query(from, to)
29
+ @base_url = 'http://api.microsofttranslator.com/V2/Http.svc/Translate'
30
+ @default.merge({:text => @to_be_translated,
31
+ :from => from.to_s,
32
+ :to => to.to_s
33
+ })
34
+ end
35
+
36
+ def build_languages_query
37
+ @base_url = 'http://api.microsofttranslator.com/V1/Http.svc/GetLanguages'
38
+ @default
39
+ end
40
+
41
+ # Build a query for detect method of Bing Translate api.
42
+ #
43
+ # @example
44
+ # build_detect_query
45
+ #
46
+ # @return [Hash] Hash of param.
47
+ #
48
+ # @since 0.0.1
49
+ #
50
+ def build_detect_query
51
+ @base_url = 'http://api.microsofttranslator.com/V2/Http.svc/Detect'
52
+ @default.merge({:text => @to_be_translated})
53
+ end
54
+
55
+ # Parse xml response from Bing webservice.
56
+ #
57
+ # XML is serious business.
58
+ #
59
+ # @example
60
+ # parse my_xml
61
+ #
62
+ # @param [String] response Json representation
63
+ #
64
+ # @return [String] Translated string.
65
+ #
66
+ # @since 0.0.1
67
+ #
68
+ def parse(response)
69
+ xpath = Nokogiri::XML(response).xpath('/')
70
+ return xpath.text unless xpath.children.empty?
71
+ response.to_s.split("\r\n")
72
+ end
73
+ end #Bing
74
+ end # Translator
75
+ end #C3po
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+ class C3po
3
+ module Translator
4
+
5
+ class Configuration
6
+
7
+ class << self
8
+
9
+ attr_accessor :provider, :google_api_key, :bing_api_key
10
+
11
+ # Define a configure block.
12
+ #
13
+ # config.provider can be an Array. In this case,
14
+ # provider will be randomly choosen from it.
15
+ #
16
+ # @example Define the option.
17
+ # C3po.configure do |config|
18
+ # config.provider = :google
19
+ # config.google_api_key = "MYAPIKEY"
20
+ # end
21
+ #
22
+ # @param [ Proc ] block The block getting called.
23
+ #
24
+ # @since 0.0.1
25
+ #
26
+ def configure(&block)
27
+ yield self
28
+ end
29
+
30
+ end # self
31
+ end # Configuration
32
+ end # Translator
33
+ end #C3po
@@ -0,0 +1,90 @@
1
+ # encoding: utf-8
2
+ require 'yajl'
3
+
4
+ class C3po
5
+ module Translator
6
+ class Google
7
+ attr_reader :base_url
8
+
9
+ def initialize(to_be_translated = nil)
10
+ @to_be_translated = to_be_translated
11
+ @default = {
12
+ :key => C3po::Translator::Configuration.google_api_key
13
+ }
14
+ end
15
+
16
+ # Build a query for Google Translate api.
17
+ #
18
+ # @example
19
+ # build_query :fr, :en
20
+ #
21
+ # @param [Symbol] Language to be translated from.
22
+ # [Symbol] Language to be translated to.
23
+ #
24
+ # @return [Hash] Hash of param.
25
+ #
26
+ # @since 0.0.1
27
+ #
28
+ def build_query(from, to)
29
+ @base_url = 'https://www.googleapis.com/language/translate/v2'
30
+ @default.merge({:q => @to_be_translated,
31
+ :source => from.to_s,
32
+ :target => to.to_s
33
+ })
34
+ end
35
+
36
+ # Build a query for languages method of Google Translate api.
37
+ #
38
+ # @example
39
+ # build_languages_query
40
+ #
41
+ # @return [Hash] Hash of param.
42
+ #
43
+ # @since 0.0.1
44
+ #
45
+ def build_languages_query
46
+ @base_url = 'https://www.googleapis.com/language/translate/v2/languages'
47
+ @default
48
+ end
49
+
50
+ # Build a query for detect method of Google Translate api.
51
+ #
52
+ # @example
53
+ # build_detect_query
54
+ #
55
+ # @return [Hash] Hash of param.
56
+ #
57
+ # @since 0.0.1
58
+ #
59
+ def build_detect_query
60
+ @base_url = 'https://www.googleapis.com/language/translate/v2/detect'
61
+ @default.merge({:q => @to_be_translated})
62
+ end
63
+
64
+ # Parse json response from Google webservice.
65
+ #
66
+ # @example
67
+ # parse my_json
68
+ #
69
+ # @param [String] response Json representation
70
+ #
71
+ # @return [String] Translated string.
72
+ # @return [String] Detected language.
73
+ # @return [Array] Languages list.
74
+ #
75
+ # @since 0.0.1
76
+ #
77
+ def parse(response)
78
+ data = Yajl::Parser.parse(response)['data']
79
+ if data['translations']
80
+ data['translations'][0]['translatedText']
81
+ elsif data['detections']
82
+ data['detections'][0][0]["language"]
83
+ else
84
+ data['languages'].inject([]) {|languages, value| languages << value['language']}
85
+ end
86
+ end
87
+
88
+ end #Google
89
+ end # Translator
90
+ end #C3po
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+ class C3po
3
+ module Translator
4
+ class Result < Struct.new(:translation, :language, :languages)
5
+ end # Result
6
+ end # Translator
7
+ end # C3po
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: c3po
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - af83
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-10-27 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &20830440 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.6'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *20830440
25
+ - !ruby/object:Gem::Dependency
26
+ name: typhoeus
27
+ requirement: &20829960 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 0.2.4
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *20829960
36
+ - !ruby/object:Gem::Dependency
37
+ name: nokogiri
38
+ requirement: &20829500 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 1.5.0
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *20829500
47
+ - !ruby/object:Gem::Dependency
48
+ name: yajl-ruby
49
+ requirement: &20829040 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.8.2
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *20829040
58
+ description: Ruby translation client
59
+ email: jboyer@af83.com
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files:
63
+ - README.md
64
+ files:
65
+ - LICENSE
66
+ - README.md
67
+ - Gemfile
68
+ - lib/c3po.rb
69
+ - lib/c3po/translator/configuration.rb
70
+ - lib/c3po/translator/bing.rb
71
+ - lib/c3po/translator/google.rb
72
+ - lib/c3po/translator/result.rb
73
+ - lib/c3po/client.rb
74
+ - lib/c3po/translator.rb
75
+ - init.rb
76
+ homepage:
77
+ licenses: []
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubyforge_project:
96
+ rubygems_version: 1.8.6
97
+ signing_key:
98
+ specification_version: 3
99
+ summary: Ruby translation client
100
+ test_files: []