transync 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +4 -2
- data/bin/transync +0 -0
- data/lib/transync.rb +16 -15
- data/lib/transync/gdoc_trans/gdoc_trans_reader.rb +14 -18
- data/lib/transync/gdoc_trans/gdoc_trans_writer.rb +19 -14
- data/lib/transync/sync/init.rb +8 -20
- data/lib/transync/sync/sync_util.rb +12 -13
- data/lib/transync/sync/translation_sync.rb +50 -0
- data/lib/transync/{gdoc_trans/gdoc_trans.rb → transync_config.rb} +18 -7
- data/lib/transync/version.rb +1 -1
- data/lib/transync/xliff_trans/xliff_trans_reader.rb +29 -45
- data/lib/transync/xliff_trans/xliff_trans_writer.rb +11 -16
- data/test/fixtures/test.de.xliff +4 -0
- data/test/fixtures/test.en.xliff +4 -0
- data/test/fixtures/validators.en.xliff +5 -1
- data/test/g2x_spec.rb +50 -0
- data/test/x2g_spec.rb +57 -0
- metadata +10 -8
- data/lib/transync/sync/gdoc_2_xliff_main.rb +0 -39
- data/lib/transync/sync/gdoc_to_xliff.rb +0 -50
- data/lib/transync/sync/xliff_2_gdoc_main.rb +0 -41
- data/lib/transync/sync/xliff_to_gdoc.rb +0 -64
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5e731d0853faec16a75252dfc64f65ae783d6a69
|
4
|
+
data.tar.gz: c26ef0c56ef0652d1a6a7cc93472965053fdbb83
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 92476f9124ea09d46e7b98574a07df504f73d5aa0bca336b39ebb87249253b38aa9d75791c91f9771996424c70319834b7cf04c47c718afb40271acdfad7b1e3
|
7
|
+
data.tar.gz: 6c5a099fca0df65ecbbf957ba6918e1d76b7d3936a1ca33403ea56b05432f973aabdb8bc34d12bbfb2d8d66c2828d40cb39ea489de0a6d0786d27a72658ba38b
|
data/README.md
CHANGED
@@ -47,6 +47,8 @@ Updating GDoc from our xliff files. It won't delete any key, it will only add ne
|
|
47
47
|
|
48
48
|
Gem docs available at http://gimite.net/doc/google-drive-ruby
|
49
49
|
|
50
|
-
#
|
50
|
+
# TODO
|
51
51
|
|
52
|
-
|
52
|
+
- more tests, edge cases
|
53
|
+
- more OOP
|
54
|
+
- update for more than 2 languages
|
data/bin/transync
CHANGED
File without changes
|
data/lib/transync.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
require_relative 'transync/sync/
|
2
|
-
require_relative 'transync/sync/gdoc_2_xliff_main'
|
1
|
+
require_relative 'transync/sync/translation_sync'
|
3
2
|
require_relative 'transync/sync/init'
|
4
3
|
require_relative 'transync/sync/sync_util'
|
5
4
|
|
@@ -7,16 +6,11 @@ module Transync
|
|
7
6
|
|
8
7
|
def self.run(mode)
|
9
8
|
FileUtils.mkdir('.transync_log') unless Dir.exist?('.transync_log')
|
10
|
-
path =
|
9
|
+
path = TransyncConfig::CONFIG['XLIFF_FILES_PATH']
|
11
10
|
|
12
|
-
if mode == 'x2g'
|
13
|
-
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
if mode == 'g2x'
|
18
|
-
g2x = Gdoc2XliffMain.new(path)
|
19
|
-
g2x.run
|
11
|
+
if mode == 'x2g' or mode == 'g2x'
|
12
|
+
sync = TranslationSync.new(path, mode)
|
13
|
+
sync.run(mode)
|
20
14
|
end
|
21
15
|
|
22
16
|
if mode == 'init'
|
@@ -25,15 +19,22 @@ module Transync
|
|
25
19
|
end
|
26
20
|
|
27
21
|
if mode == 'test'
|
28
|
-
|
29
|
-
SyncUtil::check_and_get_xliff_files(
|
22
|
+
TransyncConfig::CONFIG['FILES'].each do |file|
|
23
|
+
SyncUtil::check_and_get_xliff_files(TransyncConfig::CONFIG['LANGUAGES'], path, file)
|
30
24
|
end
|
31
25
|
end
|
32
26
|
|
33
27
|
if mode == 'update'
|
34
|
-
|
35
|
-
|
28
|
+
TransyncConfig::CONFIG['FILES'].each do |file|
|
29
|
+
valid, _, all_translations_for_language =
|
30
|
+
SyncUtil::check_and_get_xliff_files(TransyncConfig::CONFIG['LANGUAGES'], path, file)
|
31
|
+
|
32
|
+
unless valid
|
33
|
+
xliff_trans_writer = XliffTransWriter.new(path, file)
|
34
|
+
xliff_trans_writer.write(all_translations_for_language)
|
35
|
+
end
|
36
36
|
end
|
37
|
+
p 'All xliff files should now have all the keys!'
|
37
38
|
end
|
38
39
|
end
|
39
40
|
|
@@ -1,27 +1,23 @@
|
|
1
|
-
|
2
|
-
require_relative 'gdoc_trans'
|
1
|
+
require_relative '../transync_config'
|
3
2
|
|
4
3
|
class GdocTransReader
|
5
|
-
|
4
|
+
attr_reader :worksheet
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
# select the right tab from worksheet
|
12
|
-
self.worksheet = worksheet_tabs.detect{ |w| w.title == tab }
|
13
|
-
abort("#{tab} tab is not defined in GDoc") if self.worksheet.nil?
|
6
|
+
# file represents tab in spreadsheet
|
7
|
+
def initialize(file)
|
8
|
+
@worksheet = TransyncConfig::WORKSHEETS.detect{ |w| w.title == file }
|
9
|
+
abort("#{file} tab is not defined in GDoc") if @worksheet.nil?
|
14
10
|
end
|
15
11
|
|
16
|
-
def
|
17
|
-
trans_hash = {
|
18
|
-
|
19
|
-
|
20
|
-
language_column = GdocTrans::WORKSHEET_COLUMNS[language.to_sym]
|
12
|
+
def translations(language)
|
13
|
+
trans_hash = { file: @worksheet.title, language: language, translations: {} }
|
14
|
+
key_column = TransyncConfig::WORKSHEET_COLUMNS[:key]
|
15
|
+
language_column = TransyncConfig::WORKSHEET_COLUMNS[language.to_sym]
|
21
16
|
|
22
|
-
(
|
23
|
-
|
24
|
-
|
17
|
+
(TransyncConfig::START_ROW..@worksheet.num_rows).to_a.each do |row|
|
18
|
+
key = @worksheet[row, key_column]
|
19
|
+
value = @worksheet[row, language_column]
|
20
|
+
trans_hash[:translations][key] = value
|
25
21
|
end
|
26
22
|
|
27
23
|
trans_hash
|
@@ -1,28 +1,33 @@
|
|
1
1
|
require 'google_drive'
|
2
|
-
require_relative 'gdoc_trans'
|
3
2
|
|
4
3
|
class GdocTransWriter
|
5
|
-
attr_accessor :worksheet
|
6
4
|
|
7
5
|
def initialize(worksheet)
|
8
6
|
@worksheet = worksheet
|
9
7
|
end
|
10
8
|
|
11
|
-
def write(
|
12
|
-
|
13
|
-
|
9
|
+
def write(trans_hash)
|
10
|
+
language = trans_hash[:language]
|
11
|
+
lang_column = get_language_column_index(language)
|
12
|
+
abort("Language (#{language}) not found in worksheet (#{@worksheet.title})!") if lang_column == 0
|
13
|
+
|
14
|
+
row = 2
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
@worksheet[new_row, col] = ''
|
21
|
-
@worksheet[new_row + 1, col] = cell
|
22
|
-
end
|
16
|
+
trans_hash[:translations].keys.each do |trans_key|
|
17
|
+
trans_value = trans_hash[:translations][trans_key]
|
18
|
+
@worksheet[row, 1] = trans_key
|
19
|
+
@worksheet[row, lang_column] = trans_value
|
20
|
+
row += 1
|
23
21
|
end
|
24
22
|
|
25
|
-
@worksheet
|
23
|
+
@worksheet.save
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_language_column_index(language)
|
27
|
+
(2..@worksheet.num_cols).each do |column|
|
28
|
+
return column if @worksheet[1, column].downcase == language.downcase
|
29
|
+
end
|
30
|
+
0
|
26
31
|
end
|
27
32
|
|
28
33
|
end
|
data/lib/transync/sync/init.rb
CHANGED
@@ -1,26 +1,15 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
require_relative '../gdoc_trans/gdoc_trans_writer'
|
3
|
-
require_relative 'xliff_to_gdoc'
|
4
|
-
|
5
1
|
class Init
|
6
|
-
attr_reader :path, :config
|
7
2
|
|
8
3
|
def initialize(path)
|
9
|
-
@path
|
10
|
-
@config =
|
11
|
-
@gdoc_access = @config['GDOC']
|
4
|
+
@path = path
|
5
|
+
@config = TransyncConfig::CONFIG
|
12
6
|
end
|
13
7
|
|
14
8
|
def run
|
15
|
-
# first we want to add all the files to spreadsheet as worksheets (tabs)
|
16
|
-
# add_worksheet(title, max_rows = 100, max_cols = 20)
|
17
|
-
session = GoogleDrive.login(@gdoc_access['email'], @gdoc_access['password'])
|
18
|
-
spreadsheet = session.spreadsheet_by_key(@gdoc_access['key'])
|
19
|
-
|
20
9
|
@config['FILES'].each do |file|
|
21
|
-
worksheet =
|
10
|
+
worksheet = TransyncConfig::WORKSHEETS.detect{ |s| s.title == file }
|
22
11
|
if worksheet.nil?
|
23
|
-
worksheet =
|
12
|
+
worksheet = TransyncConfig::SPREADSHEET.add_worksheet(file)
|
24
13
|
p "Adding #{file} worksheet to spreadsheet with first row (key and languages)"
|
25
14
|
end
|
26
15
|
|
@@ -31,11 +20,10 @@ class Init
|
|
31
20
|
worksheet.save
|
32
21
|
end
|
33
22
|
|
34
|
-
#
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
x2g.run
|
23
|
+
# re-init spreadsheet after new worksheets were created
|
24
|
+
TransyncConfig.init_spreadsheet
|
25
|
+
sync = TranslationSync.new(@path, 'x2g')
|
26
|
+
sync.run('x2g')
|
39
27
|
end
|
40
28
|
|
41
29
|
end
|
@@ -3,23 +3,22 @@ require_relative '../xliff_trans/xliff_trans_reader'
|
|
3
3
|
|
4
4
|
module SyncUtil
|
5
5
|
|
6
|
-
def self.check_and_get_xliff_files(languages, path, file
|
6
|
+
def self.check_and_get_xliff_files(languages, path, file)
|
7
|
+
valid = true
|
7
8
|
xliff_translations = []
|
8
|
-
|
9
|
+
all_translations_for_language = {}
|
9
10
|
|
10
11
|
languages.each do |language|
|
11
|
-
xliff_reader = XliffTransReader.new(path, file,
|
12
|
-
if xliff_reader.valid?
|
13
|
-
xliff_translations << xliff_reader.
|
12
|
+
xliff_reader = XliffTransReader.new(path, file, languages)
|
13
|
+
if xliff_reader.valid?
|
14
|
+
xliff_translations << xliff_reader.translations(language)
|
14
15
|
else
|
15
|
-
|
16
|
-
|
16
|
+
valid = false
|
17
|
+
all_translations_for_language = xliff_reader.all_translations_for_language
|
17
18
|
end
|
18
19
|
end
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
xliff_translations
|
21
|
+
return valid, xliff_translations, all_translations_for_language
|
23
22
|
end
|
24
23
|
|
25
24
|
def self.info_clean(file, language, message)
|
@@ -27,8 +26,9 @@ module SyncUtil
|
|
27
26
|
SyncUtil.log_and_puts(msg)
|
28
27
|
end
|
29
28
|
|
30
|
-
def self.info_diff(file, language, operation,
|
31
|
-
msg = "#{file} (#{language}) - #{operation}: '#{
|
29
|
+
def self.info_diff(file, language, operation, trans_key, trans_value)
|
30
|
+
msg = "#{file} (#{language}) - #{operation}: '#{trans_key}'"
|
31
|
+
msg += " to '#{trans_value}'" unless trans_value.nil?
|
32
32
|
SyncUtil.log_and_puts(msg)
|
33
33
|
end
|
34
34
|
|
@@ -38,7 +38,6 @@ module SyncUtil
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def self.create_logger(direction)
|
41
|
-
# gdoc2xliff or xliff2gdoc
|
42
41
|
@logger = Logger.new(".transync_log/#{direction}.log", 'monthly')
|
43
42
|
end
|
44
43
|
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require_relative '../gdoc_trans/gdoc_trans_reader'
|
2
|
+
require_relative '../gdoc_trans/gdoc_trans_writer'
|
3
|
+
require_relative '../xliff_trans/xliff_trans_writer'
|
4
|
+
|
5
|
+
class TranslationSync
|
6
|
+
|
7
|
+
def initialize(path, direction, file = nil)
|
8
|
+
@path = path
|
9
|
+
@file = file
|
10
|
+
@config = TransyncConfig::CONFIG
|
11
|
+
SyncUtil.create_logger(direction)
|
12
|
+
end
|
13
|
+
|
14
|
+
def run(direction)
|
15
|
+
@config['FILES'].each do |file|
|
16
|
+
valid, _ = SyncUtil::check_and_get_xliff_files(@config['LANGUAGES'], @path, file)
|
17
|
+
abort('Fix your Xliff translations first!') unless valid
|
18
|
+
|
19
|
+
@config['LANGUAGES'].each do |language|
|
20
|
+
trans_sync = TranslationSync.new(@path, direction, file)
|
21
|
+
trans_hash = trans_sync.sync(language, direction)
|
22
|
+
|
23
|
+
if direction == 'x2g'
|
24
|
+
gdoc_trans_reader = GdocTransReader.new(file)
|
25
|
+
gdoc_trans_writer = GdocTransWriter.new(gdoc_trans_reader.worksheet)
|
26
|
+
gdoc_trans_writer.write(trans_hash)
|
27
|
+
else
|
28
|
+
xliff_trans_writer = XliffTransWriter.new(@path, file)
|
29
|
+
xliff_trans_writer.write(trans_hash)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def sync(language, direction)
|
36
|
+
gdoc_trans_reader = GdocTransReader.new(@file)
|
37
|
+
xliff_trans_reader = XliffTransReader.new(@path, @file, nil) # we dont need languages for translations method
|
38
|
+
|
39
|
+
g_trans_hash = gdoc_trans_reader.translations(language)
|
40
|
+
x_trans_hash = xliff_trans_reader.translations(language)
|
41
|
+
|
42
|
+
# We need to merge on translations hash, not whole hash since it will only merge first level
|
43
|
+
x2g_merged_translations = g_trans_hash[:translations].merge(x_trans_hash[:translations])
|
44
|
+
g2x_merged_translations = x_trans_hash[:translations].merge(g_trans_hash[:translations])
|
45
|
+
|
46
|
+
merged_translations = direction == 'x2g' ? x2g_merged_translations : g2x_merged_translations
|
47
|
+
{file: @file, language: language, translations: merged_translations}
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -1,11 +1,26 @@
|
|
1
|
-
|
1
|
+
require 'yaml'
|
2
|
+
require 'google_drive'
|
3
|
+
|
4
|
+
module TransyncConfig
|
5
|
+
# Result of WORKSHEET_COLUMNS should be something like this
|
6
|
+
# depends on LANGUAGES set in settings yaml file
|
7
|
+
# WORKSHEET_COLUMNS = { key: 1, en: 2, de: 3 }
|
2
8
|
WORKSHEET_COLUMNS = { key: 1 }
|
3
9
|
START_ROW = 2
|
4
10
|
|
11
|
+
def self.init_spreadsheet
|
12
|
+
session = GoogleDrive.login(CONFIG['GDOC']['email'], CONFIG['GDOC']['password'])
|
13
|
+
spreadsheet = session.spreadsheet_by_key(CONFIG['GDOC']['key'])
|
14
|
+
worksheets = spreadsheet.worksheets
|
15
|
+
|
16
|
+
return spreadsheet, worksheets
|
17
|
+
end
|
18
|
+
|
5
19
|
begin
|
6
20
|
CONFIG = YAML.load(File.open('transync.yml'))
|
7
|
-
|
8
|
-
|
21
|
+
SPREADSHEET, WORKSHEETS = TransyncConfig.init_spreadsheet
|
22
|
+
rescue => e
|
23
|
+
p e.message
|
9
24
|
exit(1)
|
10
25
|
end
|
11
26
|
|
@@ -15,8 +30,4 @@ module GdocTrans
|
|
15
30
|
value = index + 2
|
16
31
|
WORKSHEET_COLUMNS[key.to_sym] = value
|
17
32
|
end
|
18
|
-
|
19
|
-
# Result of WORKSHEET_COLUMNS should be something like this
|
20
|
-
# depends on LANGUAGES set in settings yaml file
|
21
|
-
# WORKSHEET_COLUMNS = { key: 1, en: 2, de: 3 }
|
22
33
|
end
|
data/lib/transync/version.rb
CHANGED
@@ -1,29 +1,27 @@
|
|
1
1
|
require 'nokogiri'
|
2
2
|
|
3
3
|
class XliffTransReader
|
4
|
-
attr_accessor :
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
self.
|
4
|
+
attr_accessor :path,
|
5
|
+
:file,
|
6
|
+
:languages,
|
7
|
+
:all_translations_for_language
|
8
|
+
|
9
|
+
def initialize(path, file, languages)
|
10
|
+
self.path = path
|
11
|
+
self.file = file
|
12
|
+
self.languages = languages
|
13
|
+
self.all_translations_for_language = {file: file, language: nil, translations: {}}
|
11
14
|
end
|
12
15
|
|
13
|
-
def
|
14
|
-
data = {
|
15
|
-
language: language,
|
16
|
-
translations: []
|
17
|
-
}
|
16
|
+
def translations(language)
|
17
|
+
data = { file: file, language: language, translations: {} }
|
18
18
|
|
19
|
-
open_file do |doc|
|
20
|
-
# hacky hack, xliff is dirty as hell
|
19
|
+
open_file(language) do |doc|
|
21
20
|
doc.remove_namespaces!
|
22
21
|
doc.xpath('//trans-unit').each do |node|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
}
|
22
|
+
key = node.xpath('source').text
|
23
|
+
value = node.xpath('target').text
|
24
|
+
data[:translations][key] = value
|
27
25
|
end
|
28
26
|
end
|
29
27
|
|
@@ -31,49 +29,35 @@ class XliffTransReader
|
|
31
29
|
end
|
32
30
|
|
33
31
|
# will go through each and find if any xliff is missing keys for translations
|
34
|
-
def valid?
|
32
|
+
def valid?
|
35
33
|
missing = 0
|
36
|
-
missing_translation_text =
|
37
|
-
all_translations_for_language = {language: nil, translations: []}
|
34
|
+
missing_translation_text = TransyncConfig::CONFIG['MISSING_TRANSLATION_TEXT'] || '#MISSING-TRANS#'
|
38
35
|
|
39
|
-
self.
|
36
|
+
self.translations(self.languages.first)[:translations].keys.each do |x_trans_key|
|
40
37
|
self.languages.each do |key_lang|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
xliff_lang = xliff_reader.get_translations[:translations]
|
45
|
-
xliff_lang_value = xliff_lang.detect{ |xt| xt[:key] == x_trans[:key] }
|
38
|
+
xliff_reader = XliffTransReader.new(self.path, self.file, self.languages)
|
39
|
+
xliff_lang = xliff_reader.translations(key_lang)[:translations]
|
40
|
+
xliff_lang_value = xliff_lang[x_trans_key]
|
46
41
|
|
47
42
|
all_translations_for_language[:language] = key_lang
|
48
43
|
|
49
44
|
if xliff_lang_value.nil?
|
50
|
-
p "#{file}.#{key_lang} is missing translation for key '#{
|
51
|
-
|
52
|
-
|
53
|
-
p "#{missing + 1}. #{file}.#{key_lang} was missing translation for key '#{x_trans[:key]}'."
|
54
|
-
all_translations_for_language[:translations] << {
|
55
|
-
key: x_trans[:key],
|
56
|
-
value: "#{missing_translation_text} - #{x_trans[:key]}"
|
57
|
-
}
|
45
|
+
p "#{file}.#{key_lang} is missing translation for key '#{x_trans_key}'"
|
46
|
+
all_translations_for_language[:translations][x_trans_key] = "#{missing_translation_text} - #{x_trans_key}"
|
58
47
|
missing += 1
|
59
48
|
else
|
60
|
-
all_translations_for_language[:translations]
|
49
|
+
all_translations_for_language[:translations][x_trans_key] = xliff_lang_value
|
61
50
|
end
|
62
51
|
end
|
63
52
|
end
|
64
53
|
|
65
|
-
if missing > 0 and create
|
66
|
-
xliff_trans_writer = XliffTransWriter.new(dir, file, all_translations_for_language)
|
67
|
-
xliff_trans_writer.save
|
68
|
-
end
|
69
|
-
|
70
54
|
missing == 0
|
71
55
|
end
|
72
56
|
|
73
57
|
# Reading from source tags in xliff
|
74
|
-
def open_file
|
58
|
+
def open_file(language)
|
75
59
|
begin
|
76
|
-
xml_file = File.open(file_path)
|
60
|
+
xml_file = File.open(file_path(language))
|
77
61
|
doc = Nokogiri::XML(xml_file)
|
78
62
|
yield doc
|
79
63
|
rescue Errno::ENOENT => e
|
@@ -83,8 +67,8 @@ class XliffTransReader
|
|
83
67
|
|
84
68
|
private
|
85
69
|
|
86
|
-
def file_path
|
87
|
-
"#{
|
70
|
+
def file_path(language)
|
71
|
+
"#{path}/#{file}.#{language}.xliff"
|
88
72
|
end
|
89
73
|
|
90
74
|
end
|
@@ -1,20 +1,15 @@
|
|
1
1
|
require 'builder'
|
2
2
|
|
3
3
|
class XliffTransWriter
|
4
|
-
attr_accessor :data,
|
5
|
-
:path,
|
6
|
-
:file,
|
7
|
-
:language
|
8
4
|
|
9
|
-
def initialize(path, file
|
5
|
+
def initialize(path, file)
|
10
6
|
@path = path
|
11
7
|
@file = file
|
12
|
-
@language = data[:language]
|
13
|
-
@data = data
|
14
8
|
end
|
15
9
|
|
16
|
-
def
|
17
|
-
|
10
|
+
def write(trans_hash)
|
11
|
+
language = trans_hash[:language]
|
12
|
+
translations = trans_hash[:translations]
|
18
13
|
|
19
14
|
xml = Builder::XmlMarkup.new( :indent => 4 )
|
20
15
|
xml.instruct! :xml, :encoding => 'UTF-8'
|
@@ -22,10 +17,10 @@ class XliffTransWriter
|
|
22
17
|
xliff.file :'source-language' => language, :datatype => 'plaintext', :original => 'file.ext' do |file|
|
23
18
|
file.body do |body|
|
24
19
|
|
25
|
-
translations.each do |
|
26
|
-
body.tag! 'trans-unit', :id =>
|
27
|
-
trans_unit.source
|
28
|
-
trans_unit.target
|
20
|
+
translations.keys.each do |trans_key|
|
21
|
+
body.tag! 'trans-unit', :id => trans_key do |trans_unit|
|
22
|
+
trans_unit.source trans_key
|
23
|
+
trans_unit.target translations[trans_key]
|
29
24
|
end
|
30
25
|
end
|
31
26
|
|
@@ -33,13 +28,13 @@ class XliffTransWriter
|
|
33
28
|
end
|
34
29
|
end
|
35
30
|
|
36
|
-
File.open(file_path, 'w') { |file| file.write(xml.target!) }
|
31
|
+
File.open(file_path(language), 'w') { |file| file.write(xml.target!) }
|
37
32
|
end
|
38
33
|
|
39
34
|
private
|
40
35
|
|
41
|
-
def file_path
|
42
|
-
"#{path}/#{file}.#{language}.xliff"
|
36
|
+
def file_path(language)
|
37
|
+
"#{@path}/#{@file}.#{language}.xliff"
|
43
38
|
end
|
44
39
|
|
45
40
|
end
|
data/test/fixtures/test.de.xliff
CHANGED
data/test/fixtures/test.en.xliff
CHANGED
@@ -1,11 +1,15 @@
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
2
2
|
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
3
|
-
<file source-language="
|
3
|
+
<file source-language="en" datatype="plaintext" original="file.ext">
|
4
4
|
<body>
|
5
5
|
<trans-unit id="title">
|
6
6
|
<source>title</source>
|
7
7
|
<target>Titel</target>
|
8
8
|
</trans-unit>
|
9
|
+
<trans-unit id="end_test_2">
|
10
|
+
<source>end_test_2</source>
|
11
|
+
<target>End test 2</target>
|
12
|
+
</trans-unit>
|
9
13
|
<trans-unit id="round">
|
10
14
|
<source>round</source>
|
11
15
|
<target>Rund</target>
|
data/test/g2x_spec.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'minitest/spec'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
|
4
|
+
require_relative '../lib/transync/transync_config'
|
5
|
+
require_relative '../lib/transync/gdoc_trans/gdoc_trans_reader'
|
6
|
+
require_relative '../lib/transync/sync/sync_util'
|
7
|
+
require_relative '../lib/transync/sync/translation_sync'
|
8
|
+
|
9
|
+
# Expects this data in test worksheet
|
10
|
+
# Key EN DE
|
11
|
+
# title Title Titel
|
12
|
+
# round Round Rund
|
13
|
+
# end_test meh xxx
|
14
|
+
describe 'g2x' do
|
15
|
+
before do
|
16
|
+
@file = 'test' # file or worksheet title aka spreadsheet tab
|
17
|
+
@path = 'test/fixtures'
|
18
|
+
@language = 'en'
|
19
|
+
SyncUtil.create_logger('g2x_test')
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'google doc translation reader should build correct trans hash' do
|
23
|
+
gdoc_trans_reader = GdocTransReader.new(@file)
|
24
|
+
trans_hash = gdoc_trans_reader.translations(@language)
|
25
|
+
trans_hash[:file].must_equal @file
|
26
|
+
trans_hash[:language].must_equal @language
|
27
|
+
trans_hash[:translations].keys.size.must_equal 3
|
28
|
+
|
29
|
+
trans_hash[:translations]['title'].must_equal 'Title'
|
30
|
+
trans_hash[:translations]['round'].must_equal 'Round'
|
31
|
+
trans_hash[:translations]['end_test'].must_equal 'meh'
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'g2x sync should build new hash before writing it to xliff' do
|
35
|
+
_, xliff_translations = SyncUtil::check_and_get_xliff_files(%w(en), @path, @file)
|
36
|
+
xliff_translations[0][:file].must_equal @file
|
37
|
+
xliff_translations[0][:language].must_equal @language
|
38
|
+
xliff_translations[0][:translations].keys.size.must_equal 4
|
39
|
+
|
40
|
+
trans_sync = TranslationSync.new(@path, 'g2x', @file)
|
41
|
+
new_xliff_hash = trans_sync.sync(@language, 'g2x')
|
42
|
+
|
43
|
+
new_xliff_hash[:file].must_equal @file
|
44
|
+
new_xliff_hash[:language].must_equal @language
|
45
|
+
new_xliff_hash[:translations].size.must_equal 4
|
46
|
+
|
47
|
+
new_xliff_hash[:translations]['end_test'].must_equal 'meh'
|
48
|
+
new_xliff_hash[:translations]['end_test_2'].must_equal 'End test 2'
|
49
|
+
end
|
50
|
+
end
|
data/test/x2g_spec.rb
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'minitest/spec'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
|
4
|
+
require_relative '../lib/transync/transync_config'
|
5
|
+
require_relative '../lib/transync/gdoc_trans/gdoc_trans_reader'
|
6
|
+
require_relative '../lib/transync/gdoc_trans/gdoc_trans_writer'
|
7
|
+
require_relative '../lib/transync/sync/sync_util'
|
8
|
+
require_relative '../lib/transync/sync/translation_sync'
|
9
|
+
require_relative '../lib/transync/xliff_trans/xliff_trans_reader'
|
10
|
+
|
11
|
+
describe 'x2g' do
|
12
|
+
before do
|
13
|
+
@file = 'test'
|
14
|
+
@path = 'test/fixtures'
|
15
|
+
@language = 'en'
|
16
|
+
@languages = %w(en de)
|
17
|
+
SyncUtil.create_logger('x2g_test')
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'test if xliff files are valid' do
|
21
|
+
xliff_trans_reader = XliffTransReader.new(@path, 'test', @languages)
|
22
|
+
valid = xliff_trans_reader.valid?
|
23
|
+
valid.must_equal true
|
24
|
+
|
25
|
+
xliff_trans_reader = XliffTransReader.new(@path, 'validators', @languages)
|
26
|
+
valid = xliff_trans_reader.valid?
|
27
|
+
valid.must_equal false, 'validators translations should not be valid, because we do not have all keys in german file.'
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'test if all keys in all language files are presented' do
|
31
|
+
valid, _, _ = SyncUtil::check_and_get_xliff_files(TransyncConfig::CONFIG['LANGUAGES'], @path, 'test')
|
32
|
+
valid.must_equal true, 'test file should have all keys in both languages'
|
33
|
+
|
34
|
+
valid, _, all_trans = SyncUtil::check_and_get_xliff_files(TransyncConfig::CONFIG['LANGUAGES'], @path, 'validators')
|
35
|
+
valid.must_equal false, 'validators.de file is should have one key less then validators.en xliff file'
|
36
|
+
all_trans[:translations].size.must_equal 4
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'x2g sync should build correct new hash before writing it back to google doc' do
|
40
|
+
trans_sync = TranslationSync.new(@path, 'x2g', @file)
|
41
|
+
trans_hash = trans_sync.sync(@language, 'x2g')
|
42
|
+
|
43
|
+
trans_hash[:file].must_equal @file
|
44
|
+
trans_hash[:language].must_equal @language
|
45
|
+
trans_hash[:translations].keys.size.must_equal 4
|
46
|
+
|
47
|
+
trans_hash[:translations]['title'].must_equal 'Title'
|
48
|
+
trans_hash[:translations]['round'].must_equal 'Round'
|
49
|
+
trans_hash[:translations]['end_test'].must_equal 'End test'
|
50
|
+
trans_hash[:translations]['end_test_2'].must_equal 'End test 2'
|
51
|
+
|
52
|
+
gdoc_trans_reader = GdocTransReader.new(@file)
|
53
|
+
gdoc_trans_writer = GdocTransWriter.new(gdoc_trans_reader.worksheet)
|
54
|
+
gdoc_trans_writer.get_language_column_index('en').must_equal 2
|
55
|
+
gdoc_trans_writer.get_language_column_index('DE').must_equal 3
|
56
|
+
end
|
57
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: transync
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- zigomir
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-08-
|
11
|
+
date: 2013-08-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: google_drive
|
@@ -82,15 +82,12 @@ files:
|
|
82
82
|
- Rakefile
|
83
83
|
- bin/transync
|
84
84
|
- lib/transync.rb
|
85
|
-
- lib/transync/gdoc_trans/gdoc_trans.rb
|
86
85
|
- lib/transync/gdoc_trans/gdoc_trans_reader.rb
|
87
86
|
- lib/transync/gdoc_trans/gdoc_trans_writer.rb
|
88
|
-
- lib/transync/sync/gdoc_2_xliff_main.rb
|
89
|
-
- lib/transync/sync/gdoc_to_xliff.rb
|
90
87
|
- lib/transync/sync/init.rb
|
91
88
|
- lib/transync/sync/sync_util.rb
|
92
|
-
- lib/transync/sync/
|
93
|
-
- lib/transync/
|
89
|
+
- lib/transync/sync/translation_sync.rb
|
90
|
+
- lib/transync/transync_config.rb
|
94
91
|
- lib/transync/version.rb
|
95
92
|
- lib/transync/xliff_trans/xliff_trans_reader.rb
|
96
93
|
- lib/transync/xliff_trans/xliff_trans_writer.rb
|
@@ -98,6 +95,8 @@ files:
|
|
98
95
|
- test/fixtures/test.en.xliff
|
99
96
|
- test/fixtures/validators.de.xliff
|
100
97
|
- test/fixtures/validators.en.xliff
|
98
|
+
- test/g2x_spec.rb
|
99
|
+
- test/x2g_spec.rb
|
101
100
|
- transync.SAMPLE.yml
|
102
101
|
- transync.gemspec
|
103
102
|
homepage: ''
|
@@ -120,7 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
119
|
version: '0'
|
121
120
|
requirements: []
|
122
121
|
rubyforge_project:
|
123
|
-
rubygems_version: 2.0.
|
122
|
+
rubygems_version: 2.0.3
|
124
123
|
signing_key:
|
125
124
|
specification_version: 4
|
126
125
|
summary: Synchronize XLIFF translations with Google Drive document
|
@@ -129,3 +128,6 @@ test_files:
|
|
129
128
|
- test/fixtures/test.en.xliff
|
130
129
|
- test/fixtures/validators.de.xliff
|
131
130
|
- test/fixtures/validators.en.xliff
|
131
|
+
- test/g2x_spec.rb
|
132
|
+
- test/x2g_spec.rb
|
133
|
+
has_rdoc:
|
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
require_relative '../gdoc_trans/gdoc_trans_reader'
|
3
|
-
require_relative '../xliff_trans/xliff_trans_writer'
|
4
|
-
require_relative 'gdoc_to_xliff'
|
5
|
-
require_relative 'sync_util'
|
6
|
-
|
7
|
-
class Gdoc2XliffMain
|
8
|
-
attr_reader :path, :config
|
9
|
-
|
10
|
-
def initialize(path)
|
11
|
-
@path = path
|
12
|
-
@config = GdocTrans::CONFIG
|
13
|
-
SyncUtil.create_logger('gdoc2xliff')
|
14
|
-
end
|
15
|
-
|
16
|
-
def run
|
17
|
-
@config['FILES'].each do |file|
|
18
|
-
xliff_translations = SyncUtil::check_and_get_xliff_files(@config['LANGUAGES'], path, file)
|
19
|
-
gdoc_trans_reader = GdocTransReader.new(@config['GDOC'], file)
|
20
|
-
|
21
|
-
@config['LANGUAGES'].each do |language|
|
22
|
-
options = {
|
23
|
-
xliff_translations: xliff_translations,
|
24
|
-
gdoc_trans_reader: gdoc_trans_reader,
|
25
|
-
language: language
|
26
|
-
}
|
27
|
-
|
28
|
-
gdoc_to_xliff = GdocToXliff.new(options)
|
29
|
-
dirty, new_xliff_hash = gdoc_to_xliff.sync
|
30
|
-
|
31
|
-
xliff_trans_writer = XliffTransWriter.new(path, file, new_xliff_hash)
|
32
|
-
xliff_trans_writer.save if dirty
|
33
|
-
|
34
|
-
SyncUtil.info_clean(file, language, 'was clean. Already has same keys and values inside Xliff') unless dirty
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
require_relative 'sync_util'
|
2
|
-
|
3
|
-
class GdocToXliff
|
4
|
-
attr_accessor :xliff_translations,
|
5
|
-
:gdoc_trans_reader,
|
6
|
-
:language
|
7
|
-
|
8
|
-
def initialize(options = {})
|
9
|
-
self.xliff_translations = options[:xliff_translations]
|
10
|
-
self.gdoc_trans_reader = options[:gdoc_trans_reader]
|
11
|
-
self.language = options[:language]
|
12
|
-
end
|
13
|
-
|
14
|
-
def sync
|
15
|
-
dirty = false
|
16
|
-
gdoc_tab_language = gdoc_trans_reader.build_trans_hash(language)
|
17
|
-
file = gdoc_tab_language[:title]
|
18
|
-
|
19
|
-
new_xliff_hash = {
|
20
|
-
language: language,
|
21
|
-
file: file,
|
22
|
-
translations: []
|
23
|
-
}
|
24
|
-
|
25
|
-
xliff_for_language = xliff_translations.detect{ |x| x[:language] == language }[:translations]
|
26
|
-
gdoc_tab_language[:translations].each do |gdoc_trans|
|
27
|
-
x_trans = xliff_for_language.detect{ |x| x[:key] == gdoc_trans[:key] }
|
28
|
-
|
29
|
-
# whole key is missing
|
30
|
-
if x_trans.nil?
|
31
|
-
SyncUtil.info_diff(file, language, 'Adding', gdoc_trans)
|
32
|
-
|
33
|
-
new_xliff_hash[:translations] << gdoc_trans
|
34
|
-
dirty = true
|
35
|
-
elsif gdoc_trans[:value] != x_trans[:value]
|
36
|
-
SyncUtil.info_diff(file, language, 'Changing', gdoc_trans)
|
37
|
-
|
38
|
-
x_trans[:value] = gdoc_trans[:value]
|
39
|
-
new_xliff_hash[:translations] << x_trans
|
40
|
-
dirty = true
|
41
|
-
else
|
42
|
-
# nothing new
|
43
|
-
new_xliff_hash[:translations] << gdoc_trans
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
return dirty, new_xliff_hash
|
48
|
-
end
|
49
|
-
|
50
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
require_relative '../gdoc_trans/gdoc_trans_reader'
|
3
|
-
require_relative '../gdoc_trans/gdoc_trans_writer'
|
4
|
-
require_relative 'xliff_to_gdoc'
|
5
|
-
require_relative 'sync_util'
|
6
|
-
|
7
|
-
class Xliff2GdocMain
|
8
|
-
attr_reader :path, :config
|
9
|
-
|
10
|
-
def initialize(path)
|
11
|
-
@path = path
|
12
|
-
@config = GdocTrans::CONFIG
|
13
|
-
SyncUtil.create_logger('xliff2gdoc')
|
14
|
-
end
|
15
|
-
|
16
|
-
def run
|
17
|
-
@config['FILES'].each do |file|
|
18
|
-
xliff_translations = SyncUtil::check_and_get_xliff_files(@config['LANGUAGES'], path, file)
|
19
|
-
|
20
|
-
gdoc_trans_reader = GdocTransReader.new(@config['GDOC'], file)
|
21
|
-
gdoc_trans_writer = GdocTransWriter.new(gdoc_trans_reader.worksheet)
|
22
|
-
|
23
|
-
@config['LANGUAGES'].each do |language|
|
24
|
-
options = {
|
25
|
-
xliff_translations: xliff_translations,
|
26
|
-
gdoc_trans_reader: gdoc_trans_reader,
|
27
|
-
gdoc_trans_writer: gdoc_trans_writer,
|
28
|
-
language: language,
|
29
|
-
languages: @config['LANGUAGES']
|
30
|
-
}
|
31
|
-
xliff_to_gdoc = XliffToGdoc.new(options)
|
32
|
-
dirty = xliff_to_gdoc.sync
|
33
|
-
|
34
|
-
# save it back on google drive
|
35
|
-
gdoc_trans_writer.worksheet.save if dirty
|
36
|
-
SyncUtil.info_clean(file, language, 'was clean. Already has same keys and values inside GDoc') unless dirty
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
require_relative 'sync_util'
|
2
|
-
|
3
|
-
class XliffToGdoc
|
4
|
-
attr_accessor :xliff_translations,
|
5
|
-
:gdoc_trans_reader,
|
6
|
-
:gdoc_trans_writer,
|
7
|
-
:language,
|
8
|
-
:languages,
|
9
|
-
:logger
|
10
|
-
|
11
|
-
def initialize(options = {})
|
12
|
-
self.xliff_translations = options[:xliff_translations]
|
13
|
-
self.gdoc_trans_reader = options[:gdoc_trans_reader]
|
14
|
-
self.gdoc_trans_writer = options[:gdoc_trans_writer]
|
15
|
-
self.language = options[:language]
|
16
|
-
self.languages = options[:languages]
|
17
|
-
end
|
18
|
-
|
19
|
-
def sync
|
20
|
-
gdoc_tab_language = gdoc_trans_reader.build_trans_hash(language)
|
21
|
-
dirty = false
|
22
|
-
file = gdoc_tab_language[:title]
|
23
|
-
|
24
|
-
xliff_for_language = xliff_translations.detect{ |x| x[:language] == language }
|
25
|
-
xliff_for_language[:translations].each_with_index do |x_trans, index|
|
26
|
-
|
27
|
-
# for current xliff translation find the same trans key in google doc
|
28
|
-
gdoc_trans = gdoc_tab_language[:translations].detect{ |g_trans| g_trans[:key] == x_trans[:key] }
|
29
|
-
current_row = index + GdocTrans::START_ROW
|
30
|
-
|
31
|
-
# whole key is missing
|
32
|
-
if gdoc_trans.nil?
|
33
|
-
# heavy coupling
|
34
|
-
gdoc_trans_reader.worksheet = gdoc_trans_writer.shift_up(current_row, xliff_for_language[:translations].length)
|
35
|
-
# recalculate hashes after shift
|
36
|
-
gdoc_tab_language = gdoc_trans_reader.build_trans_hash(language)
|
37
|
-
|
38
|
-
gdoc_trans_writer.write(current_row, 'key', x_trans[:key])
|
39
|
-
gdoc_trans_writer.write(current_row, language, x_trans[:value])
|
40
|
-
|
41
|
-
SyncUtil.info_diff(file, language, 'Adding', x_trans)
|
42
|
-
|
43
|
-
# Go for all other languages if key was missing
|
44
|
-
languages.each do |key_lang|
|
45
|
-
next if key_lang == language
|
46
|
-
|
47
|
-
xliff_lang = xliff_translations.detect{ |xt| xt[:language] == key_lang }
|
48
|
-
xliff_lang_value = xliff_lang[:translations].detect{ |xt| xt[:key] == x_trans[:key] }
|
49
|
-
|
50
|
-
gdoc_trans_writer.write(current_row, key_lang, xliff_lang_value[:value])
|
51
|
-
end
|
52
|
-
|
53
|
-
dirty = true
|
54
|
-
elsif gdoc_trans[:value] != x_trans[:value]
|
55
|
-
gdoc_trans_writer.write(current_row, language, x_trans[:value])
|
56
|
-
SyncUtil.info_diff(file, language, 'Changing', x_trans)
|
57
|
-
dirty = true
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
dirty
|
62
|
-
end
|
63
|
-
|
64
|
-
end
|