ruby-lokalise-api 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/CODE_OF_CONDUCT.md +46 -0
- data/.github/CONTRIBUTING.md +14 -0
- data/.github/ISSUE_TEMPLATE.md +13 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +11 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/README.md +917 -0
- data/Rakefile +16 -0
- data/lib/ruby-lokalise-api.rb +60 -0
- data/lib/ruby-lokalise-api/client.rb +22 -0
- data/lib/ruby-lokalise-api/collections/base.rb +46 -0
- data/lib/ruby-lokalise-api/collections/contributor.rb +13 -0
- data/lib/ruby-lokalise-api/collections/file.rb +13 -0
- data/lib/ruby-lokalise-api/collections/key.rb +13 -0
- data/lib/ruby-lokalise-api/collections/key_comment.rb +13 -0
- data/lib/ruby-lokalise-api/collections/project.rb +13 -0
- data/lib/ruby-lokalise-api/collections/project_comment.rb +13 -0
- data/lib/ruby-lokalise-api/collections/project_language.rb +13 -0
- data/lib/ruby-lokalise-api/collections/screenshot.rb +13 -0
- data/lib/ruby-lokalise-api/collections/snapshot.rb +13 -0
- data/lib/ruby-lokalise-api/collections/system_language.rb +13 -0
- data/lib/ruby-lokalise-api/collections/task.rb +13 -0
- data/lib/ruby-lokalise-api/collections/team.rb +13 -0
- data/lib/ruby-lokalise-api/collections/team_user.rb +13 -0
- data/lib/ruby-lokalise-api/collections/translation.rb +13 -0
- data/lib/ruby-lokalise-api/connection.rb +17 -0
- data/lib/ruby-lokalise-api/data/attributes.json +127 -0
- data/lib/ruby-lokalise-api/error.rb +47 -0
- data/lib/ruby-lokalise-api/request.rb +60 -0
- data/lib/ruby-lokalise-api/resources/base.rb +117 -0
- data/lib/ruby-lokalise-api/resources/contributor.rb +13 -0
- data/lib/ruby-lokalise-api/resources/file.rb +25 -0
- data/lib/ruby-lokalise-api/resources/key.rb +13 -0
- data/lib/ruby-lokalise-api/resources/key_comment.rb +15 -0
- data/lib/ruby-lokalise-api/resources/project.rb +18 -0
- data/lib/ruby-lokalise-api/resources/project_comment.rb +7 -0
- data/lib/ruby-lokalise-api/resources/project_language.rb +15 -0
- data/lib/ruby-lokalise-api/resources/screenshot.rb +13 -0
- data/lib/ruby-lokalise-api/resources/snapshot.rb +17 -0
- data/lib/ruby-lokalise-api/resources/system_language.rb +7 -0
- data/lib/ruby-lokalise-api/resources/task.rb +13 -0
- data/lib/ruby-lokalise-api/resources/team.rb +6 -0
- data/lib/ruby-lokalise-api/resources/team_user.rb +13 -0
- data/lib/ruby-lokalise-api/resources/translation.rb +13 -0
- data/lib/ruby-lokalise-api/rest/comments.rb +57 -0
- data/lib/ruby-lokalise-api/rest/contributors.rb +54 -0
- data/lib/ruby-lokalise-api/rest/files.rb +33 -0
- data/lib/ruby-lokalise-api/rest/keys.rb +75 -0
- data/lib/ruby-lokalise-api/rest/languages.rb +63 -0
- data/lib/ruby-lokalise-api/rest/projects.rb +58 -0
- data/lib/ruby-lokalise-api/rest/screenshots.rb +54 -0
- data/lib/ruby-lokalise-api/rest/snapshots.rb +43 -0
- data/lib/ruby-lokalise-api/rest/tasks.rb +54 -0
- data/lib/ruby-lokalise-api/rest/team_users.rb +44 -0
- data/lib/ruby-lokalise-api/rest/teams.rb +12 -0
- data/lib/ruby-lokalise-api/rest/translations.rb +35 -0
- data/lib/ruby-lokalise-api/utils/attribute_helpers.rb +52 -0
- data/lib/ruby-lokalise-api/utils/string_utils.rb +21 -0
- data/lib/ruby-lokalise-api/version.rb +3 -0
- data/ruby-lokalise-api.gemspec +32 -0
- data/spec/lib/ruby-lokalise-api/error_spec.rb +23 -0
- data/spec/lib/ruby-lokalise-api/rest/comments_spec.rb +78 -0
- data/spec/lib/ruby-lokalise-api/rest/contributors_spec.rb +79 -0
- data/spec/lib/ruby-lokalise-api/rest/files_spec.rb +53 -0
- data/spec/lib/ruby-lokalise-api/rest/keys_spec.rb +119 -0
- data/spec/lib/ruby-lokalise-api/rest/languages_spec.rb +91 -0
- data/spec/lib/ruby-lokalise-api/rest/projects_spec.rb +79 -0
- data/spec/lib/ruby-lokalise-api/rest/screenshots_spec.rb +76 -0
- data/spec/lib/ruby-lokalise-api/rest/snapshots_spec.rb +61 -0
- data/spec/lib/ruby-lokalise-api/rest/tasks_spec.rb +89 -0
- data/spec/lib/ruby-lokalise-api/rest/team_users_spec.rb +56 -0
- data/spec/lib/ruby-lokalise-api/rest/teams_spec.rb +22 -0
- data/spec/lib/ruby-lokalise-api/rest/translations_spec.rb +54 -0
- data/spec/lib/ruby-lokalise-api/utils/snakecase_spec.rb +17 -0
- data/spec/lib/ruby-lokalise-api_spec.rb +13 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/test_client.rb +5 -0
- data/spec/support/vcr.rb +8 -0
- metadata +255 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
module Lokalise
|
2
|
+
class Error < StandardError
|
3
|
+
ClientError = Class.new(self)
|
4
|
+
ServerError = Class.new(self)
|
5
|
+
|
6
|
+
BadRequest = Class.new(ClientError)
|
7
|
+
Unauthorized = Class.new(ClientError)
|
8
|
+
NotAcceptable = Class.new(ClientError)
|
9
|
+
NotFound = Class.new(ClientError)
|
10
|
+
Conflict = Class.new(ClientError)
|
11
|
+
TooManyRequests = Class.new(ClientError)
|
12
|
+
Forbidden = Class.new(ClientError)
|
13
|
+
Locked = Class.new(ClientError)
|
14
|
+
|
15
|
+
NotImplemented = Class.new(ServerError)
|
16
|
+
BadGateway = Class.new(ServerError)
|
17
|
+
ServiceUnavailable = Class.new(ServerError)
|
18
|
+
GatewayTimeout = Class.new(ServerError)
|
19
|
+
|
20
|
+
ERRORS = {
|
21
|
+
400 => Lokalise::Error::BadRequest,
|
22
|
+
401 => Lokalise::Error::Unauthorized,
|
23
|
+
403 => Lokalise::Error::Forbidden,
|
24
|
+
404 => Lokalise::Error::NotFound,
|
25
|
+
406 => Lokalise::Error::NotAcceptable,
|
26
|
+
409 => Lokalise::Error::Conflict,
|
27
|
+
423 => Lokalise::Error::Locked,
|
28
|
+
429 => Lokalise::Error::TooManyRequests,
|
29
|
+
500 => Lokalise::Error::ServerError,
|
30
|
+
502 => Lokalise::Error::BadGateway,
|
31
|
+
503 => Lokalise::Error::ServiceUnavailable,
|
32
|
+
504 => Lokalise::Error::GatewayTimeout
|
33
|
+
}.freeze
|
34
|
+
|
35
|
+
class << self
|
36
|
+
# Create a new error from an HTTP response
|
37
|
+
def from_response(body)
|
38
|
+
new body['error']['message'].to_s
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Initializes a new Error object
|
43
|
+
def initialize(message = '')
|
44
|
+
super(message)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Lokalise
|
2
|
+
module Request
|
3
|
+
include Lokalise::Connection
|
4
|
+
|
5
|
+
PAGINATION_HEADERS = %w[x-pagination-total-count x-pagination-page-count x-pagination-limit x-pagination-page].freeze
|
6
|
+
|
7
|
+
def get(path, client, params = {})
|
8
|
+
respond_with(
|
9
|
+
connection(client.token).get(prepare(path), params),
|
10
|
+
client
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
def post(path, client, params = {})
|
15
|
+
respond_with(
|
16
|
+
connection(client.token).post(prepare(path), MultiJson.dump(params)),
|
17
|
+
client
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def put(path, client, params = {})
|
22
|
+
respond_with(
|
23
|
+
connection(client.token).put(prepare(path), MultiJson.dump(params)),
|
24
|
+
client
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def delete(path, client, params = {})
|
29
|
+
respond_with(
|
30
|
+
connection(client.token).run_request(:delete, prepare(path), MultiJson.dump(params), {}),
|
31
|
+
client
|
32
|
+
)
|
33
|
+
# TODO: current version of Faraday does not allow to pass DELETE body request
|
34
|
+
# As soon as this PR https://github.com/lostisland/faraday/issues/693 is merged,
|
35
|
+
# replace above with:
|
36
|
+
# delete(path, MultiJson.dump(params))
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def prepare(path)
|
42
|
+
path.gsub /\/\//, '/'
|
43
|
+
end
|
44
|
+
|
45
|
+
def respond_with(response, client)
|
46
|
+
body = MultiJson.load response.body
|
47
|
+
respond_with_error(response.status, body) if body.respond_to?(:has_key?) && body.key?('error')
|
48
|
+
response.
|
49
|
+
headers.
|
50
|
+
keep_if { |k, _v| PAGINATION_HEADERS.include?(k) }.
|
51
|
+
merge(content: body, client: client)
|
52
|
+
end
|
53
|
+
|
54
|
+
def respond_with_error(code, body)
|
55
|
+
raise(Lokalise::Error, body['error']) unless Lokalise::Error::ERRORS.key? code
|
56
|
+
|
57
|
+
raise Lokalise::Error::ERRORS[code].from_response(body)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
module Lokalise
|
2
|
+
module Resources
|
3
|
+
class Base
|
4
|
+
extend Lokalise::Request
|
5
|
+
extend Lokalise::Utils::AttributeHelpers
|
6
|
+
include Lokalise::Utils::AttributeHelpers
|
7
|
+
|
8
|
+
attr_reader :raw_data, :project_id, :client
|
9
|
+
|
10
|
+
def initialize(response)
|
11
|
+
populate_attributes_for response['content']
|
12
|
+
|
13
|
+
@raw_data = response['content']
|
14
|
+
@project_id = response['content']['project_id']
|
15
|
+
@client = response['client']
|
16
|
+
end
|
17
|
+
|
18
|
+
class << self
|
19
|
+
# Dynamically add attribute readers for each inherited class.
|
20
|
+
# Attributes are defined in the `data/attributes.json` file.
|
21
|
+
# Also set the `ATTRIBUTES` constant to assign values to each attribute later when
|
22
|
+
# the response arrives from the API
|
23
|
+
def inherited(subclass)
|
24
|
+
klass_attributes = attributes_for subclass
|
25
|
+
subclass.class_exec do
|
26
|
+
const_set :ATTRIBUTES, klass_attributes
|
27
|
+
attr_reader(*klass_attributes)
|
28
|
+
end
|
29
|
+
super
|
30
|
+
end
|
31
|
+
|
32
|
+
# Fetches a single record
|
33
|
+
def find(client, endpoint_ids, resource_id = '', params = {})
|
34
|
+
new get("#{endpoint(*endpoint_ids)}/#{resource_id}",
|
35
|
+
client,
|
36
|
+
params)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Creates one or multiple records
|
40
|
+
def create(client, endpoint_ids, params, object_key = nil)
|
41
|
+
response = post(endpoint(*endpoint_ids),
|
42
|
+
client,
|
43
|
+
body_from(params, object_key))
|
44
|
+
|
45
|
+
object_from response
|
46
|
+
end
|
47
|
+
|
48
|
+
# Updates one or multiple records
|
49
|
+
def update(client, endpoint_ids, resource_id, params, object_key = nil)
|
50
|
+
response = put("#{endpoint(*endpoint_ids)}/#{resource_id}",
|
51
|
+
client,
|
52
|
+
body_from(params, object_key))
|
53
|
+
|
54
|
+
object_from response
|
55
|
+
end
|
56
|
+
|
57
|
+
# Destroys records by given ids
|
58
|
+
#
|
59
|
+
# @param client [Lokalise::Client]
|
60
|
+
# @return [Hash]
|
61
|
+
# @param endpoint_ids [String, Integer, Array]
|
62
|
+
# @param resource_id [String, Integer, Hash<Array>]
|
63
|
+
def destroy(client, endpoint_ids, resource_id)
|
64
|
+
path = endpoint(*endpoint_ids).to_s
|
65
|
+
if resource_id.is_a?(Hash)
|
66
|
+
delete path, client, resource_id
|
67
|
+
else
|
68
|
+
delete "#{path}/#{resource_id}", client
|
69
|
+
end['content']
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
# Converts `params` to hash with arrays under the `object_key` key.
|
75
|
+
# Used in bulk operations
|
76
|
+
#
|
77
|
+
# @return [Hash]
|
78
|
+
def body_from(params, object_key)
|
79
|
+
return params unless object_key
|
80
|
+
|
81
|
+
params = [params] unless params.is_a?(Array)
|
82
|
+
Hash[object_key, params]
|
83
|
+
end
|
84
|
+
|
85
|
+
# Instantiates a new resource or collection based on the given response
|
86
|
+
def object_from(response)
|
87
|
+
model_class = name.base_class_name
|
88
|
+
data_key_plural = data_key_for model_class, true
|
89
|
+
|
90
|
+
if response['content'].key? data_key_plural
|
91
|
+
Module.const_get("Lokalise::Collections::#{model_class}").new response
|
92
|
+
else
|
93
|
+
new response
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
# Store all resources attributes under the corresponding instance variables.
|
101
|
+
# `ATTRIBUTES` is defined inside resource-specific classes
|
102
|
+
def populate_attributes_for(content)
|
103
|
+
data_key = data_key_for self.class.name.base_class_name
|
104
|
+
|
105
|
+
self.class.const_get(:ATTRIBUTES).each do |attr|
|
106
|
+
value = if content.key?(data_key) && content[data_key].is_a?(Hash)
|
107
|
+
content[data_key][attr]
|
108
|
+
else
|
109
|
+
content[attr]
|
110
|
+
end
|
111
|
+
|
112
|
+
instance_variable_set "@#{attr}", value
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Lokalise
|
2
|
+
module Resources
|
3
|
+
class File < Base
|
4
|
+
class << self
|
5
|
+
def download(client, project_id, params)
|
6
|
+
up_down client, endpoint(project_id), params, 'download'
|
7
|
+
end
|
8
|
+
|
9
|
+
def upload(client, project_id, params)
|
10
|
+
up_down client, endpoint(project_id), params, 'upload'
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def up_down(client, path, params, action)
|
16
|
+
post("#{path}/#{action}", client, params)['content']
|
17
|
+
end
|
18
|
+
|
19
|
+
def endpoint(project_id)
|
20
|
+
"projects/#{project_id}/files"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Lokalise
|
2
|
+
module Resources
|
3
|
+
class Project < Base
|
4
|
+
class << self
|
5
|
+
def clear(client, project_id)
|
6
|
+
put("#{endpoint(project_id)}/empty", client)['content']
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def endpoint(project_id = nil)
|
12
|
+
'projects' unless project_id
|
13
|
+
"projects/#{project_id}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Lokalise
|
2
|
+
module Resources
|
3
|
+
class Snapshot < Base
|
4
|
+
class << self
|
5
|
+
def restore(client, project_id, snapshot_id)
|
6
|
+
Lokalise::Resources::Project.new post(endpoint(project_id, snapshot_id), client)
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def endpoint(project_id, snapshot_id = nil)
|
12
|
+
"projects/#{project_id}/snapshots/#{snapshot_id}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Lokalise
|
2
|
+
class Client
|
3
|
+
# Returns a single comment for the given key
|
4
|
+
#
|
5
|
+
# @see https://lokalise.co/api2docs/ruby/#transition-retrieve-a-comment-get
|
6
|
+
# @return [Lokalise::Resources::Comment]
|
7
|
+
# @param project_id [String]
|
8
|
+
# @param key_id [String, Integer]
|
9
|
+
# @param comment_id [String, Integer]
|
10
|
+
def comment(project_id, key_id, comment_id)
|
11
|
+
Lokalise::Resources::KeyComment.find self, [project_id, key_id], comment_id
|
12
|
+
end
|
13
|
+
|
14
|
+
# Returns all comments for all keys inside the given project
|
15
|
+
#
|
16
|
+
# @see https://lokalise.co/api2docs/ruby/#transition-list-project-comments-get
|
17
|
+
# @return [Lokalise::Collection::Comment<Lokalise::Resources::Comment>]
|
18
|
+
# @param project_id [String]
|
19
|
+
# @param params [Hash]
|
20
|
+
def project_comments(project_id, params = {})
|
21
|
+
Lokalise::Collections::ProjectComment.all self, params, project_id
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns all comments for the given key inside the given project
|
25
|
+
#
|
26
|
+
# @see https://lokalise.co/api2docs/ruby/#transition-list-key-comments-get
|
27
|
+
# @return [Lokalise::Collection::Comment<Lokalise::Resources::Comment>]
|
28
|
+
# @param project_id [String]
|
29
|
+
# @param key_id [String, Integer]
|
30
|
+
# @param params [Hash]
|
31
|
+
def comments(project_id, key_id, params = {})
|
32
|
+
Lokalise::Collections::KeyComment.all self, params, project_id, key_id
|
33
|
+
end
|
34
|
+
|
35
|
+
# Creates one or more comments for the given key inside the given project
|
36
|
+
#
|
37
|
+
# @see https://lokalise.co/api2docs/ruby/#transition-create-comments-post
|
38
|
+
# @return [Lokalise::Collection::Comment<Lokalise::Resources::Comment>]
|
39
|
+
# @param project_id [String]
|
40
|
+
# @param key_id [String, Integer]
|
41
|
+
# @param params [Hash, Array<Hash>]
|
42
|
+
def create_comments(project_id, key_id, params)
|
43
|
+
Lokalise::Resources::KeyComment.create self, [project_id, key_id], params, :comments
|
44
|
+
end
|
45
|
+
|
46
|
+
# Deletes comment for the given key inside the given project
|
47
|
+
#
|
48
|
+
# @see https://lokalise.co/api2docs/ruby/#transition-delete-a-comment-delete
|
49
|
+
# @return [Hash]
|
50
|
+
# @param project_id [String]
|
51
|
+
# @param key_id [String, Integer]
|
52
|
+
# @param comment_id [String, Integer]
|
53
|
+
def delete_comment(project_id, key_id, comment_id)
|
54
|
+
Lokalise::Resources::KeyComment.destroy self, [project_id, key_id], comment_id
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|