bisu 1.3.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ae037a0d6145c6c2517b9ada533931cce6fbb028
4
- data.tar.gz: bb08d97f16d8a1fe65a8eced03d785961e7369d2
3
+ metadata.gz: 352d33d3ac9d54082135084e8cd3e03a6ace04d5
4
+ data.tar.gz: 3f07ec0e51bde13656405514a72aedefd63f9f65
5
5
  SHA512:
6
- metadata.gz: 3bf229024552eb4081d51aeaeffcb014c2f2787e8592eb166a5d2aa04fc980fa9789c605b4f796c1be68d6a56b5763a2b9662b8480c2ac472dd3e66fe3135254
7
- data.tar.gz: 3b2fdc69cade70b5a7d6d14e615dd129e8296adb2ab57b7ba82ca57fd17d9e0cf858391f84af839694b9cbed354284cdd5c7a8c29782d5c0ce7fd1f2e166646d
6
+ metadata.gz: 3126fa41a9805d8b1fb028e73c2ac4674ea73e981c5808b2cfc28324b31546f6ada14436294941fbf8278148f4987b32afe5dd0a3d2d1138fe3d8923aa6a9a12
7
+ data.tar.gz: 5f76fd4c33ac8dea50f8c5a9b5472d09f7ad245897b749af15a2c0327df603b04167739ae78244c15d750a33362561ce6c89e8d607048fc69dc48f3ac81b5e88
data/Gemfile CHANGED
@@ -4,6 +4,7 @@ ruby '2.3.1'
4
4
  gem 'safe_yaml', '~> 1.0'
5
5
  gem 'colorize', '~> 0.7'
6
6
  gem 'xml-simple', '~> 1.1'
7
+ gem 'onesky-ruby'
7
8
 
8
9
  gem 'webmock', '~> 1.20'
9
10
  gem 'rspec'
data/Gemfile.lock CHANGED
@@ -6,7 +6,19 @@ GEM
6
6
  crack (0.4.3)
7
7
  safe_yaml (~> 1.0.0)
8
8
  diff-lcs (1.2.5)
9
+ domain_name (0.5.20161021)
10
+ unf (>= 0.0.5, < 1.0.0)
9
11
  hashdiff (0.3.0)
12
+ http-cookie (1.0.3)
13
+ domain_name (~> 0.5)
14
+ mime-types (2.99.3)
15
+ netrc (0.11.0)
16
+ onesky-ruby (1.0.1)
17
+ rest-client (~> 1.8)
18
+ rest-client (1.8.0)
19
+ http-cookie (>= 1.0.2, < 2.0)
20
+ mime-types (>= 1.16, < 3.0)
21
+ netrc (~> 0.7)
10
22
  rspec (3.5.0)
11
23
  rspec-core (~> 3.5.0)
12
24
  rspec-expectations (~> 3.5.0)
@@ -24,6 +36,9 @@ GEM
24
36
  rspec-support (~> 3.5.0)
25
37
  rspec-support (3.5.0)
26
38
  safe_yaml (1.0.4)
39
+ unf (0.1.4)
40
+ unf_ext
41
+ unf_ext (0.0.7.2)
27
42
  webmock (1.24.6)
28
43
  addressable (>= 2.3.6)
29
44
  crack (>= 0.3.2)
@@ -35,6 +50,7 @@ PLATFORMS
35
50
 
36
51
  DEPENDENCIES
37
52
  colorize (~> 0.7)
53
+ onesky-ruby
38
54
  rspec
39
55
  rspec-its
40
56
  safe_yaml (~> 1.0)
data/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  Bisu 홀
2
2
  ========
3
3
 
4
- Bisu manages your app iOS and Android localization files for you. No more copy+paste induced errors!
4
+ Bisu manages your app iOS, Android and RoR localization files for you. No more copy+paste induced errors!
5
5
 
6
6
  ---
7
7
 
8
8
  Instalation
9
9
  -----
10
-
10
+
11
11
  ```
12
12
  gem install bisu
13
13
  ```
@@ -24,25 +24,40 @@ Usage
24
24
  Configuration
25
25
  -----
26
26
 
27
- 1. Create in your **iOS/Android** app project base folder a translatable.yml:
27
+ 1. Create in your project base folder a translatable.yml:
28
28
 
29
29
  ```
30
- type: <iOS/Android/RoR>
31
-
32
- sheet_id: <GOOGLE-DRIVE-SHEET-ID>
33
- keys_column: <GOOGLE-DRIVE-KEY-COLUMN-TITLE>
34
-
35
- in:
36
- - path/to/1st/file.translatable
37
- - path/to/2nd/file.translatable
38
-
39
- out_path: path/to/%{locale}.lproj/%{out_name}
40
- out:
30
+ type: <iOS|Android|RoR>
31
+
32
+ dictionary:
33
+ type: google_sheet
34
+ sheet_id: <GOOGLE-DRIVE-SHEET-ID>
35
+ keys_column: <GOOGLE-DRIVE-KEY-COLUMN-TITLE>
36
+
37
+ translate:
38
+ - in: path/to/1st/file.translatable
39
+ out: path/to/%{locale}/strings.xml
40
+ out_en: path/to/default/strings.xml
41
+ - in: path/to/2nd/file.translatable
42
+ out: path/to/2nd-%{locale}/strings.xml
43
+
44
+ languages:
41
45
  - locale: en
42
- language: english
43
- path: default_path/%{out_name}
44
- - locale: ko
45
- language: korean
46
+ language: en
47
+ - locale: en-US
48
+ language: en
49
+ - locale: pt
50
+ language: pt
51
+ ```
52
+
53
+ Also available [OneSky](https://www.oneskyapp.com) integration:
54
+ ```
55
+ dictionary:
56
+ type: one_sky
57
+ api_key: <ONE-SKY-API-KEY>
58
+ api_secret: <ONE-SKY-API-SECRET>
59
+ project_id: <ONE-SKY-PROJECT-ID>
60
+ file_name: <ONE-SKY-FILE-NAME>
46
61
  ```
47
62
 
48
63
  1. Create a \*.translatable version for your **iOS** localization files:
@@ -50,13 +65,13 @@ Configuration
50
65
  ```
51
66
  // $specialKComment1$
52
67
  // $specialKComment2$
53
-
68
+
54
69
  // Locale: $specialKLocale$; Language used: $specialKLanguage$
55
-
70
+
56
71
  /***********
57
72
  * General
58
73
  ************/
59
-
74
+
60
75
  "klGeneral_Delete" = "$kDelete$";
61
76
  "klGeneral_Cancel" = "$kCancel$";
62
77
  "klGeneral_Close" = "$kClose$";
@@ -67,11 +82,11 @@ Configuration
67
82
 
68
83
  ```
69
84
  <?xml version="1.0" encoding="utf-8"?>
70
-
85
+
71
86
  <!-- $specialKComment1$ -->
72
87
  <!-- $specialKComment2$ -->
73
88
  <!-- Locale: $specialKLocale$; Language used: $specialKLanguage$ -->
74
-
89
+
75
90
  <resources>
76
91
  <string name="delete">$kDelete$</string>
77
92
  <string name="cancel">$kCancel$</string>
@@ -79,7 +94,7 @@ Configuration
79
94
  <string name="request_name">$kRequestName%{user_name: %s}$</string>
80
95
  </resources>
81
96
  ```
82
-
97
+
83
98
  1. Create a \*.translatable version for your **RoR** localization files:
84
99
 
85
100
  ```
data/lib/bisu/config.rb CHANGED
@@ -2,7 +2,13 @@ module Bisu
2
2
  class Config
3
3
  def initialize(hash:)
4
4
  @hash = hash.deep_symbolize
5
- @hash.validate_structure!(EXPECTED_HASH)
5
+ @hash.validate_structure!(CONFIG_STRUCT)
6
+
7
+ unless dict_struct = DICTIONARY_STRUCT[@hash[:dictionary][:type]]
8
+ raise ArgumentError.new("unknown dictionary type '#{@hash[:dictionary][:type]}'")
9
+ end
10
+
11
+ @hash[:dictionary].validate_structure!(dict_struct)
6
12
  end
7
13
 
8
14
  def to_h
@@ -28,13 +34,12 @@ module Bisu
28
34
 
29
35
  private
30
36
 
31
- EXPECTED_HASH = {
37
+ CONFIG_STRUCT = {
32
38
  type: Hash,
33
39
  elements: {
34
40
  type: { type: String },
35
41
  dictionary: { type: Hash, elements: {
36
- sheet_id: { type: String },
37
- keys_column: { type: String }
42
+ type: { type: String }
38
43
  } },
39
44
  translate: { type: Array, elements: {
40
45
  type: Hash, elements: {
@@ -50,5 +55,29 @@ module Bisu
50
55
  } }
51
56
  }
52
57
  }
58
+
59
+ GOOGLE_SHEET_STRUCT = {
60
+ type: Hash,
61
+ elements: {
62
+ type: { type: String },
63
+ sheet_id: { type: String },
64
+ keys_column: { type: String }
65
+ }
66
+ }
67
+
68
+ ONE_SKY_STRUCT = {
69
+ type: Hash,
70
+ elements: {
71
+ api_key: { type: String },
72
+ api_secret: { type: String },
73
+ project_id: { type: Integer },
74
+ file_name: { type: String }
75
+ }
76
+ }
77
+
78
+ DICTIONARY_STRUCT = {
79
+ "google_sheet" => GOOGLE_SHEET_STRUCT,
80
+ "one_sky" => ONE_SKY_STRUCT
81
+ }
53
82
  end
54
83
  end
@@ -3,15 +3,15 @@ require "xmlsimple"
3
3
 
4
4
  module Bisu
5
5
  class GoogleSheet
6
- def initialize(sheet_id, keys_column_title)
6
+ def initialize(sheet_id, keys_column)
7
7
  @sheet_id = sheet_id
8
- @key_column = keys_column_title
8
+ @key_column = keys_column
9
9
  end
10
10
 
11
11
  def to_i18
12
12
  raw = raw_data(@sheet_id)
13
13
 
14
- Logger.info("Parsing Google Sheet...")
14
+ Logger.info("Downloading dictionary from Google Sheet...")
15
15
 
16
16
  non_language_columns = ["id", "updated", "category", "title", "content", "link", @key_column]
17
17
 
@@ -28,7 +28,7 @@ module Bisu
28
28
  end
29
29
 
30
30
  Logger.info("Google Sheet parsed successfully!")
31
- Logger.info("Found #{kb.count} keys in #{kb.values.first.keys.count} languages.")
31
+ Logger.info("Found #{kb.count} languages.")
32
32
 
33
33
  kb
34
34
  end
@@ -0,0 +1,31 @@
1
+ require 'onesky'
2
+
3
+ module Bisu
4
+ class OneSky
5
+ def initialize(api_key, api_secret, project_id, file_name)
6
+ @client = Onesky::Client.new(api_key, api_secret)
7
+ @project_id = project_id
8
+ @file_name = file_name
9
+ end
10
+
11
+ def to_i18
12
+ Logger.info("Downloading dictionary from OneSky...")
13
+
14
+ proj = @client.project(@project_id)
15
+ file = proj.export_multilingual(source_file_name: @file_name, file_format: "I18NEXT_MULTILINGUAL_JSON")
16
+
17
+ hash = JSON.parse(file)
18
+ hash.each do |lang, v|
19
+ hash[lang] = v["translation"]
20
+ hash[lang].each do |key, text|
21
+ hash[lang][key] = hash[lang][key].join("\n") if hash[lang][key].is_a? Array
22
+ end
23
+ end
24
+
25
+ Logger.info("OneSky response parsed successfully!")
26
+ Logger.info("Found #{hash.count} languages.")
27
+
28
+ hash
29
+ end
30
+ end
31
+ end
data/lib/bisu/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Bisu
2
- VERSION = '1.3.1'
3
- VERSION_UPDATED_AT = '2016-11-15'
2
+ VERSION = '1.4.0'
3
+ VERSION_UPDATED_AT = '2016-11-18'
4
4
  end
data/lib/bisu.rb CHANGED
@@ -5,6 +5,7 @@ require 'bisu/logger'
5
5
  require 'bisu/object_extension'
6
6
  require 'bisu/config'
7
7
  require 'bisu/google_sheet'
8
+ require 'bisu/one_sky'
8
9
  require 'bisu/dictionary'
9
10
  require 'bisu/localizer'
10
11
  require 'bisu/version'
@@ -17,8 +18,7 @@ module Bisu
17
18
 
18
19
  if config_file = open_file("translatable.yml", "r", true)
19
20
  config = Bisu::Config.new(hash: YAML::load(config_file))
20
- google_sheet = Bisu::GoogleSheet.new(config.dictionary[:sheet_id], config.dictionary[:keys_column])
21
- dictionary = Bisu::Dictionary.new(google_sheet.to_i18)
21
+ dictionary = dictionary_for(config: config.dictionary, save_to_path: options[:dictionary_save_path])
22
22
  localizer = Bisu::Localizer.new(dictionary, config.type)
23
23
 
24
24
  config.localize_files do |in_path, out_path, language, locale|
@@ -36,6 +36,26 @@ module Bisu
36
36
 
37
37
  private
38
38
 
39
+ def dictionary_for(config:, save_to_path:)
40
+ source =
41
+ case config[:type]
42
+ when "google_sheet"
43
+ Bisu::GoogleSheet.new(config[:sheet_id], config[:keys_column])
44
+ when "one_sky"
45
+ Bisu::OneSky.new(config[:api_key], config[:api_secret], config[:project_id], config[:file_name])
46
+ end
47
+
48
+ source = source.to_i18
49
+
50
+ if save_to_path && file = open_file(save_to_path, "w", false)
51
+ file.write(source.to_json)
52
+ file.flush
53
+ file.close
54
+ end
55
+
56
+ Bisu::Dictionary.new(source)
57
+ end
58
+
39
59
  def command_line_options(options)
40
60
  opts_hash = {}
41
61
 
@@ -44,6 +64,10 @@ module Bisu
44
64
  opts_hash[:default_language] = language
45
65
  end
46
66
 
67
+ opts.on("--save-dictionary PATH", "Save downloaded dictionary locally at given path") do |path|
68
+ opts_hash[:dictionary_save_path] = path
69
+ end
70
+
47
71
  opts.on_tail("-h", "--help", "Show this message") do
48
72
  puts opts
49
73
  exit
@@ -1,6 +1,7 @@
1
1
  type: iOS
2
2
 
3
3
  dictionary:
4
+ type: google_sheet
4
5
  sheet_id: sheet-id
5
6
  keys_column: keys-column
6
7
 
@@ -0,0 +1,29 @@
1
+ {
2
+ "en": {
3
+ "translation": {
4
+ "kConnectFacebook": "Connect with Facebook",
5
+ "kNoNoNoMr": "No, no, no. Mr %{name} not here"
6
+ }
7
+ },
8
+ "ja": {
9
+ "translation": {
10
+ "kConnectFacebook": "\u30d5\u30a7\u30a4\u30b9\u30d6\u30c3\u30af\u3078\u63a5\u7d9a"
11
+ }
12
+ },
13
+ "fr": {
14
+ "translation": {
15
+ "kConnectFacebook": "Connexion par Facebook"
16
+ }
17
+ },
18
+ "de": {
19
+ "translation": {
20
+ "kConnectFacebook": "Mit Facebook verbinden"
21
+ }
22
+ },
23
+ "ko": {
24
+ "translation": {
25
+ "kConnectFacebook": "\ud398\uc774\uc2a4\ubd81\uc73c\ub85c \uc811\uc18d",
26
+ "kTwitterServer": ["트위터 서버연결 실패. ", "잠시 후 재시도."]
27
+ }
28
+ }
29
+ }
@@ -4,8 +4,9 @@ describe Bisu::Config do
4
4
  let(:hash) { {
5
5
  type: "BisuOS",
6
6
  dictionary: {
7
- sheet_id: "abc1234567890",
8
- keys_column: "key_name"
7
+ type: "google_sheet",
8
+ sheet_id: "abc1234567890",
9
+ keys_column: "key_name"
9
10
  },
10
11
  translate: [
11
12
  { in: "path/to/file/to/1.ext.translatable",
@@ -30,9 +31,33 @@ describe Bisu::Config do
30
31
  it { expect { config }.to raise_error /missing keys/i }
31
32
  end
32
33
 
33
- its(:to_h) { should eq(hash) }
34
- its(:type) { should eq("BisuOS") }
35
- its(:dictionary) { should eq({ sheet_id: "abc1234567890", keys_column: "key_name" }) }
34
+ its(:to_h) { should eq(hash) }
35
+ its(:type) { should eq("BisuOS") }
36
+
37
+ describe "#dictionary" do
38
+ subject(:dictionary) { config.dictionary }
39
+
40
+ it { should eq({ type: "google_sheet", sheet_id: "abc1234567890", keys_column: "key_name" }) }
41
+
42
+ context "when given a OneSky type dictionary" do
43
+ before do
44
+ hash[:dictionary] = {
45
+ type: "one_sky",
46
+ api_key: "as387oavh48",
47
+ api_secret: "bp0s5avo8a59",
48
+ project_id: 328742,
49
+ file_name: "file.json"
50
+ }
51
+ end
52
+
53
+ it { should eq({ type: "one_sky", api_key: "as387oavh48", api_secret: "bp0s5avo8a59", project_id: 328742, file_name: "file.json" }) }
54
+ end
55
+
56
+ context "when given an unknown type dictionary" do
57
+ before { hash[:dictionary] = { type: "i_dunno" } }
58
+ it { expect { config }.to raise_error /unknown dictionary type 'i_dunno'/i }
59
+ end
60
+ end
36
61
 
37
62
  describe "#localize_files" do
38
63
  it "yields 5 times with the expected arguments" do
@@ -0,0 +1,36 @@
1
+ describe Bisu::OneSky do
2
+ subject(:to_i18) { Bisu::OneSky.new(api_key, api_secret, project_id, file_name).to_i18 }
3
+
4
+ let(:api_key) { "a123" }
5
+ let(:api_secret) { "b123" }
6
+ let(:project_id) { 98765 }
7
+ let(:file_name) { "file456.json" }
8
+
9
+ let(:os_response) { File.read("spec/fixtures/sample_one_sky_response.txt") }
10
+
11
+ before do
12
+ project = double("OSProject")
13
+ allow_any_instance_of(Onesky::Client).to receive(:project).with(project_id).and_return(project)
14
+ allow(project).to receive(:export_multilingual).with(source_file_name: file_name, file_format: "I18NEXT_MULTILINGUAL_JSON").and_return(os_response)
15
+ end
16
+
17
+ it { expect { to_i18 }.not_to raise_error }
18
+
19
+ it "returns an hash in i18 format" do
20
+ expect(to_i18).to eq({
21
+ "en" => { "kConnectFacebook" => "Connect with Facebook", "kNoNoNoMr" => "No, no, no. Mr %{name} not here" },
22
+ "ja" => { "kConnectFacebook" => "フェイスブックへ接続" },
23
+ "fr" => { "kConnectFacebook" => "Connexion par Facebook" },
24
+ "de" => { "kConnectFacebook" => "Mit Facebook verbinden" },
25
+ "ko" => { "kConnectFacebook" => "페이스북으로 접속", "kTwitterServer" => "트위터 서버연결 실패. \n잠시 후 재시도." }
26
+ })
27
+ end
28
+
29
+ context "when OneSky raises an error" do
30
+ before { allow_any_instance_of(Onesky::Client).to receive(:project).and_raise("ups... not allowed!") }
31
+
32
+ it "raises that same error" do
33
+ expect { to_i18 }.to raise_error /not allowed/
34
+ end
35
+ end
36
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bisu
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - joaoffcosta
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-15 00:00:00.000000000 Z
11
+ date: 2016-11-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: safe_yaml
@@ -90,16 +90,19 @@ files:
90
90
  - lib/bisu/localizer.rb
91
91
  - lib/bisu/logger.rb
92
92
  - lib/bisu/object_extension.rb
93
+ - lib/bisu/one_sky.rb
93
94
  - lib/bisu/version.rb
94
95
  - spec/fixtures/sample.translatable.yml
95
96
  - spec/fixtures/sample_kb_public_info.html
96
97
  - spec/fixtures/sample_kb_public_sheet.html
98
+ - spec/fixtures/sample_one_sky_response.txt
97
99
  - spec/lib/bisu/config_spec.rb
98
100
  - spec/lib/bisu/dictionary_spec.rb
99
101
  - spec/lib/bisu/google_sheet_spec.rb
100
102
  - spec/lib/bisu/localizer_spec.rb
101
103
  - spec/lib/bisu/logger_spec.rb
102
104
  - spec/lib/bisu/object_extension_spec.rb
105
+ - spec/lib/bisu/one_sky_spec.rb
103
106
  - spec/lib/bisu_spec.rb
104
107
  - spec/spec_helper.rb
105
108
  homepage: https://github.com/hole19/bisu