ruby-lokalise-api 1.0.1
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.
- 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
|