locca 0.9.1 → 0.9.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/locca +22 -7
- data/lib/locca.rb +18 -0
- data/lib/locca/actions/sync_action.rb +84 -0
- data/lib/locca/collection_builder.rb +11 -5
- data/lib/locca/project.rb +6 -1
- data/lib/locca/sync/onesky.rb +70 -0
- data/lib/locca/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 80210a9c3fa5a0b6ff72aa7deb9e01189dd1a4c1
|
4
|
+
data.tar.gz: a57ecb711907788e14c9a17e24fbe716ff8dc85b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ae7c80f63fa7298442856284d45a38dd1b2ccc4afd4720299f03b12f26df974d75f80ed93b01e78f2c2e8785a29eddcc07c3bd45e07ab9f76f0a75608897adc
|
7
|
+
data.tar.gz: 40d0fbc0c067f87fcc89d1703db50a8c0e6bd52a60e9e2dd22f39607bf33ffb46e7b3cbdf3eaa566798c148eb0a6971766e3fb5a5f14d2487fd41e5cfde41383
|
data/bin/locca
CHANGED
@@ -45,14 +45,8 @@ command :build do |c|
|
|
45
45
|
if not work_dir
|
46
46
|
work_dir = Dir.getwd
|
47
47
|
end
|
48
|
-
project_dir_locator = Locca::ProjectDirLocator.new()
|
49
|
-
config_reader = Locca::ConfigReader.new()
|
50
|
-
config_validator = Locca::ConfigValidator.new(['code_dir', 'lang_dir'])
|
51
|
-
project_factory = Locca::ProjectFactory.new(project_dir_locator, config_reader, config_validator)
|
52
48
|
|
53
|
-
|
54
|
-
|
55
|
-
$locca.build(project)
|
49
|
+
$locca.build(project_in_dir(work_dir))
|
56
50
|
end
|
57
51
|
end
|
58
52
|
|
@@ -66,6 +60,18 @@ command :merge do |c|
|
|
66
60
|
end
|
67
61
|
end
|
68
62
|
|
63
|
+
desc 'Sync translations with external translation service'
|
64
|
+
command :sync do |c|
|
65
|
+
c.action do |global_options, options, args|
|
66
|
+
work_dir = global_options['work-dir'.to_sym]
|
67
|
+
if not work_dir
|
68
|
+
work_dir = Dir.getwd
|
69
|
+
end
|
70
|
+
|
71
|
+
$locca.sync(project_in_dir(work_dir))
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
69
75
|
pre do |global, command, options, args|
|
70
76
|
$locca = Locca::Locca.new()
|
71
77
|
true
|
@@ -84,4 +90,13 @@ on_error do |exception|
|
|
84
90
|
true
|
85
91
|
end
|
86
92
|
|
93
|
+
def project_in_dir(dir)
|
94
|
+
project_dir_locator = Locca::ProjectDirLocator.new()
|
95
|
+
config_reader = Locca::ConfigReader.new()
|
96
|
+
config_validator = Locca::ConfigValidator.new(['code_dir', 'lang_dir', 'base_lang'])
|
97
|
+
project_factory = Locca::ProjectFactory.new(project_dir_locator, config_reader, config_validator)
|
98
|
+
|
99
|
+
project = project_factory.new_project(dir)
|
100
|
+
end
|
101
|
+
|
87
102
|
exit run(ARGV)
|
data/lib/locca.rb
CHANGED
@@ -33,6 +33,9 @@ require 'locca/config_validator'
|
|
33
33
|
|
34
34
|
require 'locca/actions/build_action'
|
35
35
|
require 'locca/actions/merge_action'
|
36
|
+
require 'locca/actions/sync_action'
|
37
|
+
|
38
|
+
require 'locca/sync/onesky'
|
36
39
|
|
37
40
|
require 'locca/collections_generator'
|
38
41
|
require 'locca/collection_merger'
|
@@ -66,6 +69,21 @@ module Locca
|
|
66
69
|
action.execute()
|
67
70
|
end
|
68
71
|
|
72
|
+
def sync(project)
|
73
|
+
if not project
|
74
|
+
raise 'Can\'t initialize Locca with nil project'
|
75
|
+
end
|
76
|
+
|
77
|
+
genstrings = Genstrings.new()
|
78
|
+
collection_builder = collection_builder()
|
79
|
+
collections_generator = CollectionsGenerator.new(genstrings, collection_builder)
|
80
|
+
|
81
|
+
onesky = Onesky.new(project.config_value_for_key('onesky_project_id'), project.config_value_for_key('onesky_public_key'), project.config_value_for_key('onesky_secret_key'))
|
82
|
+
|
83
|
+
action = SyncAction.new(project, collection_builder, collection_writer(), collections_generator, collection_merger(), onesky)
|
84
|
+
action.execute()
|
85
|
+
end
|
86
|
+
|
69
87
|
def collection_builder()
|
70
88
|
parser = Babelyoda::StringsParser.new(Babelyoda::StringsLexer.new())
|
71
89
|
return CollectionBuilder.new(File, parser)
|
@@ -0,0 +1,84 @@
|
|
1
|
+
#
|
2
|
+
# The MIT License (MIT)
|
3
|
+
#
|
4
|
+
# Copyright (c) 2014 Evgeny Shurakov
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
# of this software and associated documentation files (the "Software"), to deal
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
11
|
+
# furnished to do so, subject to the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be included in all
|
14
|
+
# copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
22
|
+
# SOFTWARE.
|
23
|
+
#
|
24
|
+
|
25
|
+
# 1. Fetch translations from one sky app
|
26
|
+
# 2. Merge translated values with local translations
|
27
|
+
# 3. Run 'build' action
|
28
|
+
# 4. Upload base language translations to one sky app
|
29
|
+
|
30
|
+
require 'locca/collection_merger'
|
31
|
+
|
32
|
+
module Locca
|
33
|
+
class SyncAction
|
34
|
+
def initialize(project, collection_builder, collection_writer, collections_generator, collection_merger, onesky)
|
35
|
+
@project = project
|
36
|
+
@collections_generator = collections_generator
|
37
|
+
@collection_merger = collection_merger
|
38
|
+
@collection_builder = collection_builder
|
39
|
+
@collection_writer = collection_writer
|
40
|
+
@onesky = onesky
|
41
|
+
end
|
42
|
+
|
43
|
+
def execute()
|
44
|
+
langs = @project.langs()
|
45
|
+
generated_collections = @collections_generator.generate(@project.code_dir())
|
46
|
+
|
47
|
+
# 1
|
48
|
+
generated_collections.each do |generated_collection|
|
49
|
+
langs.each do |lang|
|
50
|
+
print "\t* fetch: #{lang}/#{generated_collection.name}.strings\n"
|
51
|
+
data = @onesky.fetch_translations(lang, "#{generated_collection.name}.strings")
|
52
|
+
fetched_collection = @collection_builder.collection_from_datastring(data)
|
53
|
+
|
54
|
+
local_collection_path = @project.path_for_collection(generated_collection.name, lang)
|
55
|
+
local_collection = @collection_builder.collection_at_path(local_collection_path)
|
56
|
+
|
57
|
+
# 2
|
58
|
+
print "\t* merge: onesky -> #{lang}/#{generated_collection.name}.strings\n"
|
59
|
+
@collection_merger.merge(fetched_collection, local_collection, CollectionMerger::ACTION_ADD | CollectionMerger::ACTION_UPDATE)
|
60
|
+
@collection_writer.write_to_path(local_collection, local_collection_path)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# 3
|
65
|
+
generated_collections.each do |generated_collection|
|
66
|
+
langs.each do |lang|
|
67
|
+
print "\t* merge: code -> #{lang}/#{generated_collection.name}.strings\n"
|
68
|
+
|
69
|
+
collection_path = @project.path_for_collection(generated_collection.name, lang)
|
70
|
+
collection = @collection_builder.collection_at_path(collection_path)
|
71
|
+
@collection_merger.merge(generated_collection, collection, (CollectionMerger::ACTION_ADD | CollectionMerger::ACTION_DELETE))
|
72
|
+
@collection_writer.write_to_path(collection, collection_path)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# 4
|
77
|
+
generated_collections.each do |generated_collection|
|
78
|
+
print "\t* upload: #{@project.base_lang}/#{generated_collection.name}.strings\n"
|
79
|
+
collection_path = @project.path_for_collection(generated_collection.name, @project.base_lang())
|
80
|
+
@onesky.upload_file(collection_path)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -32,16 +32,22 @@ module Locca
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def collection_at_path(path)
|
35
|
-
|
36
|
-
collection = Collection.new(name)
|
35
|
+
collection = nil
|
37
36
|
|
38
37
|
@file_manager.open(path, 'rb:BOM|UTF-8:UTF-8') do |file|
|
39
|
-
|
40
|
-
|
41
|
-
end
|
38
|
+
collection = collection_from_datastring(file.read())
|
39
|
+
collection.name = File.basename(path, '.strings')
|
42
40
|
end
|
43
41
|
|
44
42
|
return collection
|
45
43
|
end
|
44
|
+
|
45
|
+
def collection_from_datastring(datastring)
|
46
|
+
collection = Collection.new()
|
47
|
+
@parser.parse(datastring) do |key, value, comment|
|
48
|
+
collection.add_item(CollectionItem.new(key, value, comment))
|
49
|
+
end
|
50
|
+
return collection
|
51
|
+
end
|
46
52
|
end
|
47
53
|
end
|
data/lib/locca/project.rb
CHANGED
@@ -27,11 +27,12 @@ module Locca
|
|
27
27
|
attr_reader :dir
|
28
28
|
attr_reader :code_dir
|
29
29
|
attr_reader :lang_dir
|
30
|
-
|
30
|
+
|
31
31
|
attr_reader :base_lang
|
32
32
|
|
33
33
|
def initialize(dir, config)
|
34
34
|
@dir = dir
|
35
|
+
@config = config
|
35
36
|
|
36
37
|
@code_dir = File.join(dir, config['code_dir'])
|
37
38
|
@lang_dir = File.join(dir, config['lang_dir'])
|
@@ -50,5 +51,9 @@ module Locca
|
|
50
51
|
def path_for_collection(collection_name, lang)
|
51
52
|
return File.join(@lang_dir, "#{lang}.lproj", "#{collection_name}.strings")
|
52
53
|
end
|
54
|
+
|
55
|
+
def config_value_for_key(key)
|
56
|
+
return @config[key]
|
57
|
+
end
|
53
58
|
end
|
54
59
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
#
|
2
|
+
# The MIT License (MIT)
|
3
|
+
#
|
4
|
+
# Copyright (c) 2014 Evgeny Shurakov
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
# of this software and associated documentation files (the "Software"), to deal
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
11
|
+
# furnished to do so, subject to the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be included in all
|
14
|
+
# copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
22
|
+
# SOFTWARE.
|
23
|
+
#
|
24
|
+
|
25
|
+
require 'json'
|
26
|
+
require 'digest/md5'
|
27
|
+
require 'rest_client'
|
28
|
+
|
29
|
+
module Locca
|
30
|
+
class Onesky
|
31
|
+
|
32
|
+
def initialize(project_id, public_key, secret_key)
|
33
|
+
@project_id = project_id
|
34
|
+
@public_key = public_key
|
35
|
+
@secret_key = secret_key
|
36
|
+
end
|
37
|
+
|
38
|
+
def upload_file(file_path)
|
39
|
+
fetch_response(:post, "files", {'file' => File.new(file_path), 'file_format' => 'IOS_STRINGS', 'is_keeping_all_strings' => 'false'})
|
40
|
+
end
|
41
|
+
|
42
|
+
def fetch_translations(lang, file_name)
|
43
|
+
return fetch_response(:get, "translations", {'locale' => lang, 'source_file_name' => file_name})
|
44
|
+
end
|
45
|
+
|
46
|
+
def authorization_params
|
47
|
+
timestamp = Time.now.to_i.to_s
|
48
|
+
{:"api_key" => @public_key, :timestamp => timestamp, :"dev_hash" => Digest::MD5.hexdigest(timestamp + @secret_key)}
|
49
|
+
end
|
50
|
+
|
51
|
+
def fetch_response(http_verb, path, params)
|
52
|
+
options = {:content_type => "application/json; charset=UTF-8", :accept => "application/json"}
|
53
|
+
params = authorization_params.merge(params)
|
54
|
+
|
55
|
+
path = "https://platform.api.onesky.io/1/projects/#{@project_id}/#{path}"
|
56
|
+
|
57
|
+
response = case http_verb
|
58
|
+
when :get
|
59
|
+
RestClient.get(path, {:params => params}.merge(options))
|
60
|
+
when :post
|
61
|
+
RestClient.post(path, params.merge(options))
|
62
|
+
else
|
63
|
+
raise "bad http verb"
|
64
|
+
end
|
65
|
+
|
66
|
+
return response
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
data/lib/locca/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: locca
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shurakov Evgeny
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-08-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -93,6 +93,7 @@ files:
|
|
93
93
|
- lib/babelyoda/strings_parser.rb
|
94
94
|
- lib/locca/actions/build_action.rb
|
95
95
|
- lib/locca/actions/merge_action.rb
|
96
|
+
- lib/locca/actions/sync_action.rb
|
96
97
|
- lib/locca/collection.rb
|
97
98
|
- lib/locca/collection_builder.rb
|
98
99
|
- lib/locca/collection_item.rb
|
@@ -107,6 +108,7 @@ files:
|
|
107
108
|
- lib/locca/project.rb
|
108
109
|
- lib/locca/project_dir_locator.rb
|
109
110
|
- lib/locca/project_factory.rb
|
111
|
+
- lib/locca/sync/onesky.rb
|
110
112
|
- lib/locca/version.rb
|
111
113
|
- lib/locca.rb
|
112
114
|
- README.rdoc
|
@@ -131,7 +133,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
131
133
|
version: '0'
|
132
134
|
requirements: []
|
133
135
|
rubyforge_project:
|
134
|
-
rubygems_version: 2.0.
|
136
|
+
rubygems_version: 2.0.14
|
135
137
|
signing_key:
|
136
138
|
specification_version: 4
|
137
139
|
summary: Application localization kit
|