crowdin-api 0.4.0 → 1.0.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.
@@ -0,0 +1,166 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Crowdin
4
+ module ApiResources
5
+ module Translations
6
+ def pre_translation_status(pre_translation_id = nil, project_id = config.project_id)
7
+ pre_translation_id || raise(ArgumentError, ':pre_translation_id is required')
8
+ project_id || raise(ArgumentError, ':project_id is required in parameters or when initialize Client')
9
+
10
+ request = Web::Request.new(
11
+ self,
12
+ :get,
13
+ "/projects/#{project_id}/pre-translations/#{pre_translation_id}"
14
+ )
15
+
16
+ request.perform
17
+ end
18
+
19
+ def apply_pre_translation(query = {}, project_id = config.project_id)
20
+ project_id || raise(ArgumentError, ':project_id is required in parameters or when initialize Client')
21
+
22
+ request = Web::Request.new(
23
+ self,
24
+ :post,
25
+ "/projects/#{project_id}/pre-translations",
26
+ query
27
+ )
28
+
29
+ request.perform
30
+ end
31
+
32
+ def build_project_directory_translation(directory_id = nil, query = {})
33
+ project_id = query[:project_id] || config.project_id
34
+
35
+ directory_id || raise(ArgumentError, ':directory_id is required')
36
+ project_id || raise(ArgumentError, ':project_id is required in parameters or when initialize Client')
37
+
38
+ request = Web::Request.new(
39
+ self,
40
+ :post,
41
+ "/projects/#{project_id}/translations/builds/directories/#{directory_id}",
42
+ query
43
+ )
44
+
45
+ request.perform
46
+ end
47
+
48
+ def build_project_file_translation(file_id = nil, query = {})
49
+ project_id = query[:project_id] || config.project_id
50
+
51
+ file_id || raise(ArgumentError, ':file_id is required')
52
+ project_id || raise(ArgumentError, ':project_id is required in parameters or when initialize Client')
53
+
54
+ headers = query[:eTag] ? { 'If-None-Match' => query[:eTag] } : {}
55
+
56
+ request = Web::Request.new(
57
+ self,
58
+ :post,
59
+ "/projects/#{project_id}/translations/builds/files/#{file_id}",
60
+ query,
61
+ headers
62
+ )
63
+
64
+ request.perform
65
+ end
66
+
67
+ def list_project_builds(query = {}, project_id = config.project_id)
68
+ project_id || raise(ArgumentError, ':project_id is required in parameters or when initialize Client')
69
+
70
+ request = Web::Request.new(
71
+ self,
72
+ :get,
73
+ "/projects/#{project_id}/translations/builds",
74
+ query
75
+ )
76
+
77
+ request.perform
78
+ end
79
+
80
+ def build_project_translation(query = {}, project_id = config.project_id)
81
+ project_id || raise(ArgumentError, ':project_id is required in parameters or when initialize Client')
82
+
83
+ request = Web::Request.new(
84
+ self,
85
+ :post,
86
+ "/projects/#{project_id}/translations/builds",
87
+ query
88
+ )
89
+
90
+ request.perform
91
+ end
92
+
93
+ def upload_translations(language_id = nil, query = {})
94
+ project_id = query[:project_id] || config.project_id
95
+
96
+ language_id || raise(ArgumentError, ':language_id is required')
97
+ project_id || raise(ArgumentError, ':project_id is required in parameters or when initialize Client')
98
+
99
+ request = Web::Request.new(
100
+ self,
101
+ :post,
102
+ "/projects/#{project_id}/translations/#{language_id}",
103
+ query
104
+ )
105
+
106
+ request.perform
107
+ end
108
+
109
+ def download_project_translations(destinaton = nil, build_id = nil, project_id = config.project_id)
110
+ destinaton || raise(ArgumentError, ':destination is required for downlaods')
111
+ build_id || raise(ArgumentError, ':build_id is required')
112
+ project_id || raise(ArgumentError, ':project_id is required in parameters or when initialize Client')
113
+
114
+ request = Web::Request.new(
115
+ self,
116
+ :get,
117
+ "/projects/#{project_id}/translations/builds/#{build_id}/download",
118
+ {},
119
+ {},
120
+ destinaton
121
+ )
122
+
123
+ request.perform
124
+ end
125
+
126
+ def check_project_build_status(build_id = nil, project_id = config.project_id)
127
+ build_id || raise(ArgumentError, ':build_id is required')
128
+ project_id || raise(ArgumentError, ':project_id is required in parameters or when initialize Client')
129
+
130
+ request = Web::Request.new(
131
+ self,
132
+ :get,
133
+ "/projects/#{project_id}/translations/builds/#{build_id}"
134
+ )
135
+
136
+ request.perform
137
+ end
138
+
139
+ def cancel_build(build_id = nil, project_id = config.project_id)
140
+ build_id || raise(ArgumentError, ':build_id is required')
141
+ project_id || raise(ArgumentError, ':project_id is required in parameters or when initialize Client')
142
+
143
+ request = Web::Request.new(
144
+ self,
145
+ :delete,
146
+ "/projects/#{project_id}/translations/builds/#{build_id}"
147
+ )
148
+
149
+ request.perform
150
+ end
151
+
152
+ def export_project_translation(query = {}, project_id = config.project_id)
153
+ project_id || raise(ArgumentError, ':project_id is required in parameters or when initialize Client')
154
+
155
+ request = Web::Request.new(
156
+ self,
157
+ :post,
158
+ "/projects/#{project_id}/translations/exports",
159
+ query
160
+ )
161
+
162
+ request.perform
163
+ end
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The Crowdin::Client library is used for interactions with a crowdin.com website.
4
+ #
5
+ # == Example
6
+ #
7
+ # require 'crowdin-api'
8
+ #
9
+ # crowdin = Crowdin::Client.new do |config|
10
+ # config.api_token = 'YOUR_API_TOKEN'
11
+ # end
12
+ #
13
+ module Crowdin
14
+ class Client
15
+ # A wrapper and interface to the Crowdin api. Please visit the Crowdin developers
16
+ # site for a full explanation of what each of the Crowdin api methods
17
+ # expect and perform.
18
+ #
19
+ # https://support.crowdin.com/api/v2/
20
+ #
21
+ include ApiResources::Languages
22
+ include ApiResources::Projects
23
+ include ApiResources::SourceFiles
24
+ include ApiResources::Storages
25
+ include ApiResources::TranslationStatus
26
+ include ApiResources::Translations
27
+
28
+ attr_reader :config
29
+ attr_reader :options
30
+ attr_reader :connection
31
+
32
+ def initialize
33
+ raise ArgumentError, 'block with configurations not given' unless block_given?
34
+
35
+ @config = Crowdin::Configuration.new
36
+ yield config
37
+
38
+ check_logger
39
+
40
+ set_rest_client_proxy!
41
+
42
+ build_options
43
+ build_connection
44
+ end
45
+
46
+ def log!(message)
47
+ return true unless config.logger_enabled?
48
+
49
+ logger.debug(message)
50
+ end
51
+
52
+ def logger=(logger)
53
+ @logger = logger
54
+ config.enable_logger = true
55
+ end
56
+
57
+ protected
58
+
59
+ def build_options
60
+ @options = config.options
61
+ options[:headers] = config.headers
62
+ end
63
+
64
+ def build_connection
65
+ @connection = ::RestClient::Resource.new(config.base_url, options)
66
+ end
67
+
68
+ private
69
+
70
+ def set_rest_client_proxy!
71
+ ENV['http_proxy'] ? ::RestClient.proxy = ENV['http_proxy'] : false
72
+ end
73
+
74
+ def check_logger
75
+ config.enable_logger ||= false
76
+ end
77
+
78
+ def logger
79
+ @logger ||= Logger.new($stderr)
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Crowdin
4
+ class Configuration
5
+ attr_accessor :api_token
6
+ attr_accessor :project_id
7
+ attr_accessor :organization_domain
8
+ attr_accessor :enable_logger
9
+
10
+ attr_reader :target_api_url
11
+
12
+ def initialize
13
+ @target_api_url = '/api/v2'
14
+ end
15
+
16
+ def options
17
+ {
18
+ headers: {},
19
+ timeout: nil,
20
+ json: true
21
+ }
22
+ end
23
+
24
+ def headers
25
+ {
26
+ 'Accept' => 'application/json',
27
+ 'Authorization' => "Bearer #{api_token}",
28
+ 'Content-Type' => 'application/json',
29
+ 'User-Agent' => "crowdin-rb/#{Crowdin::Client::VERSION}/#{RUBY_VERSION}/#{RUBY_PLATFORM}"
30
+ }
31
+ end
32
+
33
+ def base_url
34
+ organization_domain ? "https://#{organization_domain}.api.crowdin.com" : 'https://api.crowdin.com'
35
+ end
36
+
37
+ def logger_enabled?
38
+ enable_logger
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Crowdin
4
+ class Client
5
+ VERSION = '1.0.0'
6
+ end
7
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Crowdin
4
+ module Errors
5
+ class Error < StandardError
6
+ attr_reader :key, :error_code, :error_message
7
+
8
+ def initialize(key, error_code, error_message)
9
+ @key = key
10
+ @error_code = error_code.to_i
11
+ @error_message = error_message
12
+ @message = "#{key} => #{error_code}: #{error_message}"
13
+ end
14
+
15
+ def to_s
16
+ @message
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Crowdin
4
+ module Web
5
+ class Payload
6
+ attr_reader :method, :query
7
+
8
+ def initialize(method, query)
9
+ @method = method
10
+ @query = query
11
+ end
12
+
13
+ def perform
14
+ return @query if @query.is_a?(File)
15
+
16
+ @method.eql?(:get) ? { params: fetch_cleared_query } : fetch_cleared_query.to_json
17
+ end
18
+
19
+ private
20
+
21
+ def fetch_cleared_query
22
+ @query.reject { |_, value| value.nil? }
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Crowdin
4
+ module Web
5
+ class Request
6
+ attr_reader :client
7
+
8
+ def initialize(client, method, path, query = {}, headers = {}, destination = nil)
9
+ @client = client
10
+ @method = method
11
+ @full_path = client.config.target_api_url + path
12
+ @payload = Payload.new(method, query).perform
13
+ @headers = headers
14
+ @destination = destination
15
+ @errors = []
16
+ end
17
+
18
+ def perform
19
+ process_request!
20
+ process_response!
21
+ end
22
+
23
+ def process_request!
24
+ return @response = client.connection[@full_path].delete if delete_request?
25
+ return @response = client.connection[@full_path].get(@payload) if get_request?
26
+
27
+ client.connection[@full_path].send(@method, @payload, @headers) { |response, _, _| @response = response }
28
+ rescue StandardError => error
29
+ client.log! error.class
30
+
31
+ @errors << "Something went wrong while proccessing request. Details - #{error.class}"
32
+ end
33
+
34
+ def process_response!
35
+ return fetch_errors if @errors.any?
36
+
37
+ begin
38
+ if @response
39
+ doc = JSON.parse(@response.body)
40
+
41
+ client.log! "args: #{@response.request.args}"
42
+ client.log! "body: #{doc}"
43
+
44
+ data = fetch_response_data(doc)
45
+
46
+ @errors.any? ? fetch_errors : data
47
+ end
48
+ rescue StandardError => error
49
+ client.log! error
50
+
51
+ @errors << "Something went wrong while proccessing response. Details - #{error.class}"
52
+
53
+ fetch_errors
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ def fetch_errors
60
+ @errors.join(';')
61
+ end
62
+
63
+ def download_file(url)
64
+ download = URI.parse(url).open
65
+ IO.copy_stream(download, @destination)
66
+
67
+ @destination
68
+ rescue StandardError => error
69
+ client.log! error
70
+
71
+ @errors << "Something went wrong while downloading file. Details - #{error.class}"
72
+ end
73
+
74
+ def fetch_response_data(doc)
75
+ if doc['data'].is_a?(Hash) && doc['data']['url'] && doc['data']['url'].scan(/response-content-disposition/)
76
+ download_file(doc['data']['url'])
77
+ else
78
+ doc
79
+ end
80
+ end
81
+
82
+ def get_request?
83
+ @method.eql?(:get)
84
+ end
85
+
86
+ def delete_request?
87
+ @method.eql?(:delete)
88
+ end
89
+ end
90
+ end
91
+ end
data/lib/crowdin-api.rb CHANGED
@@ -1,128 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Libs
1
4
  require 'json'
5
+ require 'logger'
6
+ require 'open-uri'
2
7
  require 'rest-client'
3
8
 
4
- require "crowdin-api/errors"
5
- require "crowdin-api/methods"
6
- require "crowdin-api/version"
7
-
8
- # The Crowdin::API library is used for interactions with a crowdin.com website.
9
- #
10
- # == Example
11
- #
12
- # require 'crowdin-api'
13
- # require 'logger'
14
- #
15
- # crowdin = Crowdin::API.new(:api_key => API_KEY, :project_id => PROJECT_ID)
16
- # crowdin.log = Logger.new($stderr)
17
- #
18
- module Crowdin
19
- class API
20
-
21
- class << self
22
- # Default logger for all Crowdin::API instances
23
- #
24
- # Crowdin::API.log = Logger.new($stderr)
25
- #
26
- attr_accessor :log
27
- end
28
-
29
- # Create a new API object using the given parameters.
30
- #
31
- # @param [String] api_key the authentication API key can be found on the project settings page
32
- # @param [String] project_id the project identifier.
33
- # @param [String] account_key the account API Key
34
- # @param [String] base_url the url of the Crowdin API
35
- #
36
- def initialize(options = {})
37
- @api_key = options.delete(:api_key)
38
- @project_id = options.delete(:project_id)
39
- @account_key = options.delete(:account_key)
40
- @base_url = options.delete(:base_url) || 'https://api.crowdin.com'
41
-
42
- @log = nil
43
-
44
- options = {
45
- :headers => {},
46
- :params => {},
47
- :timeout => nil,
48
- :open_timeout => nil,
49
- :key => @api_key,
50
- :'account-key' => @account_key,
51
- :json => true
52
- }.merge(options)
53
-
54
- options[:headers] = {
55
- 'Accept' => 'application/json',
56
- 'User-Agent' => "crowdin-rb/#{Crowdin::API::VERSION}",
57
- 'X-Ruby-Version' => RUBY_VERSION,
58
- 'X-Ruby-Platform' => RUBY_PLATFORM
59
- }.merge(options[:headers])
60
-
61
- options[:params] = {
62
- :key => @api_key,
63
- :'account-key' => @account_key,
64
- :json => true
65
- }.merge(options[:params])
66
-
67
- RestClient.proxy = ENV['http_proxy'] if ENV['http_proxy']
68
- @connection = RestClient::Resource.new(@base_url, options)
69
- end
70
-
71
- def request(params, &block)
72
- # Returns a query hash with non nil values.
73
- params[:query].reject! { |_, value| value.nil? } if params[:query]
74
-
75
- case params[:method]
76
- when :post
77
- query = @connection.options.merge(params[:query] || {})
78
- @connection[params[:path]].post(query) { |response, _, _|
79
- @response = response
80
- }
81
- when :get
82
- query = @connection.options[:params].merge(params[:query] || {})
83
- @connection[params[:path]].get(:params => query) { |response, _, _|
84
- @response = response
85
- }
86
- end
87
-
88
- log.debug("args: #{@response.args}") if log
89
-
90
- if @response.headers[:content_disposition]
91
- filename = params[:output] || @response.headers[:content_disposition][/attachment; filename="(.+?)"/, 1]
92
- body = @response.body
93
- file = open(filename, 'wb')
94
- file.write(body)
95
- file.close
96
- return true
97
- else
98
- doc = JSON.load(@response.body)
99
- log.debug("body: #{doc}") if log
100
-
101
- if doc.kind_of?(Hash) && doc['success'] == false
102
- code = doc['error']['code']
103
- message = doc['error']['message']
104
- error = Crowdin::API::Errors::Error.new(code, message)
105
- raise(error)
106
- else
107
- return doc
108
- end
109
- end
110
-
111
- end
112
-
113
- # The current logger. If no logger has been set Crowdin::API.log is used.
114
- #
115
- def log
116
- @log || Crowdin::API.log
117
- end
118
-
119
- # Sets the +logger+ used by this instance of Crowdin::API
120
- #
121
- def log= logger
122
- @log = logger
123
- end
124
-
125
- private
126
-
127
- end
128
- end
9
+ # Core modules
10
+ require 'crowdin-api/core/payload'
11
+ require 'crowdin-api/core/request'
12
+ require 'crowdin-api/core/errors'
13
+
14
+ # Api modules
15
+ require 'crowdin-api/api-resources/languages'
16
+ require 'crowdin-api/api-resources/projects'
17
+ require 'crowdin-api/api-resources/source_files'
18
+ require 'crowdin-api/api-resources/storages'
19
+ require 'crowdin-api/api-resources/translation_status'
20
+ require 'crowdin-api/api-resources/translations'
21
+
22
+ # Client
23
+ require 'crowdin-api/client/version'
24
+ require 'crowdin-api/client/configuration'
25
+ require 'crowdin-api/client/client'
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe 'Config instance' do
4
+ it 'should have a project_id' do
5
+ @crowdin = Crowdin::Client.new do |config|
6
+ config.project_id = 1
7
+ end
8
+
9
+ expect(@crowdin.config.project_id).to_not be_nil
10
+ end
11
+
12
+ it 'should have a api_token' do
13
+ @crowdin = Crowdin::Client.new do |config|
14
+ config.api_token = 'api_token'
15
+ end
16
+
17
+ expect(@crowdin.config.api_token).to_not be_nil
18
+ end
19
+
20
+ it 'should have a base_url' do
21
+ @crowdin = Crowdin::Client.new do |config|
22
+ config.api_token = 'api_token'
23
+ end
24
+
25
+ expect(@crowdin.config.base_url).to_not be_nil
26
+ end
27
+
28
+ it 'should have a enable_logger set to false by default' do
29
+ @crowdin = Crowdin::Client.new do |config|
30
+ config.api_token = 'api_token'
31
+ end
32
+
33
+ expect(@crowdin.config.enable_logger).eql? false
34
+ end
35
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Crowdin::Client do
4
+ it 'should have a version' do
5
+ expect(Crowdin::Client::VERSION).to_not be_nil
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'crowdin-api'