babelish 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.babelish.sample +26 -0
- data/.gitignore +30 -0
- data/.hound.yml +4 -0
- data/.travis.yml +13 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +20 -0
- data/README.md +43 -0
- data/Rakefile +17 -0
- data/babelish.gemspec +41 -0
- data/bin/android2csv +13 -0
- data/bin/babelish +6 -0
- data/bin/csv2android +13 -0
- data/bin/csv2json +13 -0
- data/bin/csv2php +13 -0
- data/bin/csv2strings +14 -0
- data/bin/json2csv +13 -0
- data/bin/php2csv +13 -0
- data/bin/strings2csv +13 -0
- data/lib/babelish/android2csv.rb +25 -0
- data/lib/babelish/base2csv.rb +98 -0
- data/lib/babelish/commandline.rb +114 -0
- data/lib/babelish/csv2android.rb +36 -0
- data/lib/babelish/csv2base.rb +148 -0
- data/lib/babelish/csv2json.rb +22 -0
- data/lib/babelish/csv2php.rb +24 -0
- data/lib/babelish/csv2strings.rb +30 -0
- data/lib/babelish/google_doc.rb +36 -0
- data/lib/babelish/json2csv.rb +20 -0
- data/lib/babelish/language.rb +25 -0
- data/lib/babelish/php2csv.rb +30 -0
- data/lib/babelish/strings2csv.rb +47 -0
- data/lib/babelish/version.rb +3 -0
- data/lib/babelish.rb +27 -0
- data/test/babelish/commands/test_command_android2csv.rb +60 -0
- data/test/babelish/commands/test_command_csv2android.rb +35 -0
- data/test/babelish/commands/test_command_csv2strings.rb +60 -0
- data/test/babelish/commands/test_command_strings2csv.rb +95 -0
- data/test/babelish/test_android2csv.rb +35 -0
- data/test/babelish/test_base2csv.rb +43 -0
- data/test/babelish/test_bins.rb +24 -0
- data/test/babelish/test_csv2android.rb +26 -0
- data/test/babelish/test_csv2base.rb +40 -0
- data/test/babelish/test_csv2json.rb +26 -0
- data/test/babelish/test_csv2php.rb +26 -0
- data/test/babelish/test_csv2strings.rb +20 -0
- data/test/babelish/test_json2csv.rb +35 -0
- data/test/babelish/test_php2csv.rb +74 -0
- data/test/babelish/test_strings2csv.rb +114 -0
- data/test/data/android-en.xml +8 -0
- data/test/data/android-fr.xml +8 -0
- data/test/data/android.xml +8 -0
- data/test/data/genstrings.strings +0 -0
- data/test/data/json.json +6 -0
- data/test/data/php_lang.php +8 -0
- data/test/data/test_data.csv +3 -0
- data/test/data/test_data.strings +2 -0
- data/test/data/test_data_multiple_langs.csv +3 -0
- data/test/data/test_en.strings +2 -0
- data/test/data/test_fr.strings +2 -0
- data/test/data/test_utf16.strings +0 -0
- data/test/data/test_with_nil.csv +3 -0
- data/test/data/test_with_nil.strings +4 -0
- data/test/data/xcode_empty.strings +7 -0
- data/test/test_helper.rb +17 -0
- metadata +248 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
YmY3NGRmN2Q0MjljZmE1MDFiMjI2MjRkYmY1Y2UyMDZiYjI2NGIyNg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZmZkYjAxZDhmNjk0NWNjYjcyYmJlMTczMzVlYjJhMWQ4MGY5NGIxOA==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZTAzZjgyMDA2NmNhMjEyMGZlNTYyYTFhMThhMTUxNzA4MmU1Y2M1Y2E0NDg5
|
10
|
+
MDk5ODhiMjMwNTdkYjgyNDk5ODgxMWU4YmY4N2VhNzM4Zjc4MjY0MmM2NDdh
|
11
|
+
NTcwNzkwNDM4YWU1ZDdmZjI4OTlhY2Q0NDYyZTc3MzQ3MzRlZGI=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZDJmMmM3ZThkMmJlZTU0ZWQzNjBjMGNkYjk1NTI0OTIxNWU3NDVlNGEwZGI1
|
14
|
+
ODMyMzVkZTdlMmRkNzgzOWZiNGZlNjU1Yjg0M2NiODdhYTkwY2Q1MGFmZjFi
|
15
|
+
ZjY2MmU3MDY1ZTQzODZmYzQyOTI2OWQ5Mjc2ZWVmMGFmY2QyMTQ=
|
data/.babelish.sample
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# This is a sample configuration file
|
2
|
+
|
3
|
+
# Base2CSV
|
4
|
+
|
5
|
+
## required, location of strings files (FILENAMES)
|
6
|
+
filenames: ["test/data/test_en.strings", "test/data/test_fr.strings"]
|
7
|
+
|
8
|
+
## optional
|
9
|
+
# headers: ["Constants", "English", "French"] # override headers of columns, default is name of input files and 'Variables' for reference
|
10
|
+
# csv_filename: "testconfig.csv" # location of output file
|
11
|
+
# dryrun: true # prints out content of hash without writing file
|
12
|
+
|
13
|
+
# CSV2Base
|
14
|
+
|
15
|
+
## required
|
16
|
+
filename: test/data/test_data.csv # CSV file (CSV_FILENAME) to convert from or name of file in Google Drive
|
17
|
+
langs: # Languages to convert. i.e. English:en
|
18
|
+
English: "en"
|
19
|
+
|
20
|
+
## optional
|
21
|
+
# fetch: true # set to true to get file(filename) from google drive
|
22
|
+
# excluded-states: ["Images", "Xib"] # Exclude rows with given state
|
23
|
+
# state-column: 3 # Position of column for state if any
|
24
|
+
# keys-column: 0 # Position of column for keys
|
25
|
+
# default-lang: "English" # Default language to use for empty values if any
|
26
|
+
# default-path: "resources/" # Path of output files
|
data/.gitignore
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Generated files
|
2
|
+
*.csv
|
3
|
+
*.strings
|
4
|
+
*.lproj
|
5
|
+
*.gem
|
6
|
+
*~
|
7
|
+
*#
|
8
|
+
#*#
|
9
|
+
|
10
|
+
# Config file
|
11
|
+
.babelish
|
12
|
+
|
13
|
+
# SimpleCov
|
14
|
+
coverage
|
15
|
+
|
16
|
+
# ignore Gemfile.lock as http://yehudakatz.com/2010/12/16/clarifying-the-roles-of-the-gemspec-and-gemfile/
|
17
|
+
# this should solve the fastercsv issue
|
18
|
+
Gemfile.lock
|
19
|
+
|
20
|
+
# Ruby package manager files
|
21
|
+
.ruby-version
|
22
|
+
.rbenv-version
|
23
|
+
.rvmrc
|
24
|
+
|
25
|
+
# Sublime Text
|
26
|
+
*.sublime-workspace
|
27
|
+
*.sublime-project
|
28
|
+
|
29
|
+
doc
|
30
|
+
.yardoc
|
data/.hound.yml
ADDED
data/.travis.yml
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 1.9.2
|
4
|
+
- 1.9.3
|
5
|
+
- 2.0.0
|
6
|
+
deploy:
|
7
|
+
provider: rubygems
|
8
|
+
api_key:
|
9
|
+
secure: Xjq+v+jEU6wK4BtyfnV1elegNcxK6Ah/O99Sn9c2IlkCmJ1wxLBouqzEiSorSJ4IOMa5H2y3gwo5GXOr6Y7d8huyGrPuBeCSGqAmH77wNCIv7G+jnLiYb1sRZbtKcPW2QaN6JF81qDIelwyspMfo6/ug1qN1x323UaxZl7f7nUE=
|
10
|
+
gem: babelish
|
11
|
+
on:
|
12
|
+
tags: true
|
13
|
+
repo: netbe/Babelish
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013 François Benaiteau
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
[![Build Status](https://secure.travis-ci.org/netbe/CSV-to-iOS-Localizable.strings-converter.png?branch=master)](http://travis-ci.org/netbe/CSV-to-iOS-Localizable.strings-converter)
|
2
|
+
[![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/netbe/CSV-to-iOS-Localizable.strings-converter)
|
3
|
+
[![Coverage Status](https://coveralls.io/repos/netbe/CSV-to-iOS-Localizable.strings-converter/badge.png)](https://coveralls.io/r/netbe/CSV-to-iOS-Localizable.strings-converter)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/csv2strings.png)](http://badge.fury.io/rb/csv2strings)
|
5
|
+
# Introduction
|
6
|
+
This script converts a csv file of translations into the below file formats and vice-versa:
|
7
|
+
* .strings (iOS)
|
8
|
+
* .xml (Android)
|
9
|
+
* .json
|
10
|
+
* .php
|
11
|
+
|
12
|
+
# Requirements
|
13
|
+
|
14
|
+
* Ruby 1.9.2 or above
|
15
|
+
|
16
|
+
# Setup
|
17
|
+
|
18
|
+
`gem install babelish`
|
19
|
+
|
20
|
+
# Usage
|
21
|
+
|
22
|
+
` babelish help`
|
23
|
+
|
24
|
+
* Use configuration file
|
25
|
+
|
26
|
+
You can use a configuration file to hold all your commandline arguments into a file.
|
27
|
+
Place a `.babelish` file in your repo where you will run the command.
|
28
|
+
See `.babelish.sample` as the possible values.
|
29
|
+
|
30
|
+
# Contributing
|
31
|
+
|
32
|
+
If you feel like it, just create a pull request with a branch like `feature/<nameofbranch>` to `develop` branch
|
33
|
+
|
34
|
+
|
35
|
+
## Development
|
36
|
+
|
37
|
+
Edge version can be found on `develop` branch.
|
38
|
+
|
39
|
+
Run `bundle install` to install all the dependencies. Tests are done with `Test::Unit` so run `rake test` to run all the test suite.
|
40
|
+
|
41
|
+
# Todo & Known issues
|
42
|
+
|
43
|
+
See GitHub issues
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'yard'
|
4
|
+
|
5
|
+
Rake::TestTask.new do |t|
|
6
|
+
t.libs << "test"
|
7
|
+
t.test_files = FileList['test/babelish/**/test_*.rb']
|
8
|
+
# t.warning = true
|
9
|
+
t.verbose = true
|
10
|
+
end
|
11
|
+
|
12
|
+
YARD::Rake::YardocTask.new do |t|
|
13
|
+
t.files = ['lib/**/*.rb']
|
14
|
+
# t.options = ['--any', '--extra', '--opts']
|
15
|
+
end
|
16
|
+
|
17
|
+
task :default => :test
|
data/babelish.gemspec
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'babelish/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = 'babelish'
|
8
|
+
s.version = Babelish::VERSION
|
9
|
+
s.date = '2014-04-10'
|
10
|
+
s.summary = "CSV converter for localization files"
|
11
|
+
s.description = "This set of commands converts a CSV file to the following formats:
|
12
|
+
- .strings (iOS)
|
13
|
+
- .xml (Android)
|
14
|
+
- .json
|
15
|
+
- .php"
|
16
|
+
s.authors = ["François Benaiteau", "Markus Paeschke"]
|
17
|
+
s.email = ['francois.benaiteau@gmail.com', 'markus.paeschke@gmail.com']
|
18
|
+
s.homepage = 'https://github.com/netbe/CSV-to-iOS-Localizable.strings-converter'
|
19
|
+
s.license = 'MIT'
|
20
|
+
|
21
|
+
s.add_dependency "thor"
|
22
|
+
|
23
|
+
s.add_dependency "google_drive"
|
24
|
+
# google_drive dependency to ask for mail and password
|
25
|
+
s.add_dependency "highline"
|
26
|
+
|
27
|
+
# android support
|
28
|
+
s.add_dependency "xml-simple"
|
29
|
+
# json support
|
30
|
+
s.add_dependency "json"
|
31
|
+
|
32
|
+
s.add_development_dependency "rake"
|
33
|
+
s.add_development_dependency "test-unit"
|
34
|
+
s.add_development_dependency "simplecov"
|
35
|
+
s.add_development_dependency "yard"
|
36
|
+
|
37
|
+
s.files = `git ls-files`.split("\n")
|
38
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
39
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
40
|
+
s.require_path = 'lib'
|
41
|
+
end
|
data/bin/android2csv
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$: << File.expand_path("../../lib", __FILE__)
|
3
|
+
require 'babelish'
|
4
|
+
require 'babelish/commandline'
|
5
|
+
|
6
|
+
puts "DEPRECATED: use babelish command"
|
7
|
+
args = [File.basename(__FILE__)]
|
8
|
+
if ARGV.first == "help"
|
9
|
+
args.insert(0, ARGV.first)
|
10
|
+
ARGV.delete(ARGV.first)
|
11
|
+
end
|
12
|
+
args += ARGV
|
13
|
+
Commandline.start(args)
|
data/bin/babelish
ADDED
data/bin/csv2android
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$: << File.expand_path("../../lib", __FILE__)
|
3
|
+
require 'babelish'
|
4
|
+
require 'babelish/commandline'
|
5
|
+
|
6
|
+
puts "DEPRECATED: use babelish command"
|
7
|
+
args = [File.basename(__FILE__)]
|
8
|
+
if ARGV.first == "help"
|
9
|
+
args.insert(0, ARGV.first)
|
10
|
+
ARGV.delete(ARGV.first)
|
11
|
+
end
|
12
|
+
args += ARGV
|
13
|
+
Commandline.start(args)
|
data/bin/csv2json
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$: << File.expand_path("../../lib", __FILE__)
|
3
|
+
require 'babelish'
|
4
|
+
require 'babelish/commandline'
|
5
|
+
|
6
|
+
puts "DEPRECATED: use babelish command"
|
7
|
+
args = [File.basename(__FILE__)]
|
8
|
+
if ARGV.first == "help"
|
9
|
+
args.insert(0, ARGV.first)
|
10
|
+
ARGV.delete(ARGV.first)
|
11
|
+
end
|
12
|
+
args += ARGV
|
13
|
+
Commandline.start(args)
|
data/bin/csv2php
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$: << File.expand_path("../../lib", __FILE__)
|
3
|
+
require 'babelish'
|
4
|
+
require 'babelish/commandline'
|
5
|
+
|
6
|
+
puts "DEPRECATED: use babelish command"
|
7
|
+
args = [File.basename(__FILE__)]
|
8
|
+
if ARGV.first == "help"
|
9
|
+
args.insert(0, ARGV.first)
|
10
|
+
ARGV.delete(ARGV.first)
|
11
|
+
end
|
12
|
+
args += ARGV
|
13
|
+
Commandline.start(args)
|
data/bin/csv2strings
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$: << File.expand_path("../../lib", __FILE__)
|
3
|
+
|
4
|
+
require 'babelish'
|
5
|
+
require 'babelish/commandline'
|
6
|
+
|
7
|
+
puts "DEPRECATED: use babelish command"
|
8
|
+
args = [File.basename(__FILE__)]
|
9
|
+
if ARGV.first == "help"
|
10
|
+
args.insert(0, ARGV.first)
|
11
|
+
ARGV.delete(ARGV.first)
|
12
|
+
end
|
13
|
+
args += ARGV
|
14
|
+
Commandline.start(args)
|
data/bin/json2csv
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$: << File.expand_path("../../lib", __FILE__)
|
3
|
+
require 'babelish'
|
4
|
+
require 'babelish/commandline'
|
5
|
+
|
6
|
+
puts "DEPRECATED: use babelish command"
|
7
|
+
args = [File.basename(__FILE__)]
|
8
|
+
if ARGV.first == "help"
|
9
|
+
args.insert(0, ARGV.first)
|
10
|
+
ARGV.delete(ARGV.first)
|
11
|
+
end
|
12
|
+
args += ARGV
|
13
|
+
Commandline.start(args)
|
data/bin/php2csv
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$: << File.expand_path("../../lib", __FILE__)
|
3
|
+
require 'babelish'
|
4
|
+
require 'babelish/commandline'
|
5
|
+
|
6
|
+
puts "DEPRECATED: use babelish command"
|
7
|
+
args = [File.basename(__FILE__)]
|
8
|
+
if ARGV.first == "help"
|
9
|
+
args.insert(0, ARGV.first)
|
10
|
+
ARGV.delete(ARGV.first)
|
11
|
+
end
|
12
|
+
args += ARGV
|
13
|
+
Commandline.start(args)
|
data/bin/strings2csv
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$: << File.expand_path("../../lib", __FILE__)
|
3
|
+
require 'babelish'
|
4
|
+
require 'babelish/commandline'
|
5
|
+
|
6
|
+
puts "DEPRECATED: use babelish command"
|
7
|
+
args = [File.basename(__FILE__)]
|
8
|
+
if ARGV.first == "help"
|
9
|
+
args.insert(0, ARGV.first)
|
10
|
+
ARGV.delete(ARGV.first)
|
11
|
+
end
|
12
|
+
args += ARGV
|
13
|
+
Commandline.start(args)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Babelish
|
2
|
+
require 'xmlsimple'
|
3
|
+
class Android2CSV < Base2Csv
|
4
|
+
|
5
|
+
def initialize(args = {:filenames => []})
|
6
|
+
super(args)
|
7
|
+
end
|
8
|
+
|
9
|
+
def load_strings(strings_filename)
|
10
|
+
strings = {}
|
11
|
+
raise Errno::ENOENT unless File.exist?(strings_filename)
|
12
|
+
|
13
|
+
xmlfile = XmlSimple.xml_in(strings_filename)
|
14
|
+
xmlfile['string'].each do |element|
|
15
|
+
if !element.nil? && !element['name'].nil?
|
16
|
+
content = element['content'].nil? ? '' : element['content']
|
17
|
+
strings.merge!({element['name'] => content})
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
strings
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module Babelish
|
2
|
+
class Base2Csv
|
3
|
+
attr_accessor :csv_filename, :headers, :filenames, :default_lang
|
4
|
+
|
5
|
+
def initialize(args = {:filenames => []})
|
6
|
+
raise ArgumentError.new("No filenames given") unless args[:filenames]
|
7
|
+
if args[:headers]
|
8
|
+
raise ArgumentError.new("number of headers and files don't match, don't forget the constant column") unless args[:headers].size == (args[:filenames].size + 1)
|
9
|
+
end
|
10
|
+
|
11
|
+
@filenames = args[:filenames]
|
12
|
+
|
13
|
+
@csv_filename = args[:csv_filename] || "translations.csv"
|
14
|
+
@default_lang = args[:default_lang]
|
15
|
+
@headers = args[:headers] || default_headers
|
16
|
+
end
|
17
|
+
|
18
|
+
public
|
19
|
+
|
20
|
+
# Process files and create csv
|
21
|
+
#
|
22
|
+
# @param [Boolean] write_to_file create or not the csv file
|
23
|
+
# @return [Hash] the translations formatted if write_to_file
|
24
|
+
def convert(write_to_file = true)
|
25
|
+
strings = {}
|
26
|
+
keys = nil
|
27
|
+
|
28
|
+
@filenames.each do |fname|
|
29
|
+
header = fname
|
30
|
+
strings[header] = load_strings(fname)
|
31
|
+
keys ||= strings[header].keys
|
32
|
+
end
|
33
|
+
|
34
|
+
if write_to_file
|
35
|
+
# Create csv file
|
36
|
+
puts "Creating #{@csv_filename}"
|
37
|
+
create_csv_file(keys, strings)
|
38
|
+
else
|
39
|
+
return keys, strings
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
protected
|
44
|
+
|
45
|
+
# Load all strings of a given file
|
46
|
+
#
|
47
|
+
# @param [String, #read] strings_filename filename of file containing translations
|
48
|
+
# for a given language
|
49
|
+
# @return [Hash] the translations for a given language
|
50
|
+
def load_strings(strings_filename)
|
51
|
+
return {}
|
52
|
+
end
|
53
|
+
|
54
|
+
# Give the default headers of csv file
|
55
|
+
#
|
56
|
+
# @return [Array] headers of csv
|
57
|
+
def default_headers
|
58
|
+
headers = ["Variables"]
|
59
|
+
@filenames.each do |fname|
|
60
|
+
headers << fname
|
61
|
+
end
|
62
|
+
headers
|
63
|
+
end
|
64
|
+
|
65
|
+
# Basename of given file
|
66
|
+
#
|
67
|
+
# @param [String, #read] file_path
|
68
|
+
# @return [String] basename
|
69
|
+
def basename(file_path)
|
70
|
+
filename = File.basename(file_path)
|
71
|
+
return filename.split('.')[0].to_sym if file_path
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
# Create the resulting file
|
77
|
+
#
|
78
|
+
# @param [Array] keys references of all translations
|
79
|
+
# @param [Array] strings translations of all languages
|
80
|
+
def create_csv_file(keys, strings)
|
81
|
+
raise "csv_filename must not be nil" unless @csv_filename
|
82
|
+
CSV.open(@csv_filename, "wb") do |csv|
|
83
|
+
csv << @headers
|
84
|
+
keys.each do |key|
|
85
|
+
line = [key]
|
86
|
+
default_val = strings[@default_lang][key] if strings[@default_lang]
|
87
|
+
@filenames.each do |fname|
|
88
|
+
lang = fname
|
89
|
+
current_val = (lang != default_lang && strings[lang][key] == default_val) ? '' : strings[lang][key]
|
90
|
+
line << current_val
|
91
|
+
end
|
92
|
+
csv << line
|
93
|
+
end
|
94
|
+
puts "Done"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'thor'
|
2
|
+
class Commandline < Thor
|
3
|
+
include Thor::Actions
|
4
|
+
class_option :verbose, :type => :boolean
|
5
|
+
map "-v" => :version
|
6
|
+
|
7
|
+
CSVCLASSES = [
|
8
|
+
{:name => "CSV2Strings", :ext => ".strings"},
|
9
|
+
{:name => "CSV2Android", :ext => ".xml"},
|
10
|
+
{:name => "CSV2JSON", :ext => ".json"},
|
11
|
+
{:name => "CSV2Php", :ext => ".php"},
|
12
|
+
]
|
13
|
+
|
14
|
+
CSVCLASSES.each do |klass|
|
15
|
+
desc "#{klass[:name].downcase}", "Convert CSV file to #{klass[:ext]}"
|
16
|
+
method_option :filename, :type => :string, :desc => "CSV file to convert from or name of file in Google Drive", :required => true
|
17
|
+
method_option :langs, :type => :hash, :aliases => "-L", :desc => "Languages to convert. i.e. English:en", :required => true
|
18
|
+
|
19
|
+
# optional options
|
20
|
+
method_option :excluded_states, :type => :array, :aliases => "-x", :desc => "Exclude rows with given state"
|
21
|
+
method_option :state_column, :type => :numeric, :aliases => "-s", :desc => "Position of column for state if any"
|
22
|
+
method_option :keys_column, :type => :numeric, :aliases => "-k", :desc => "Position of column for keys"
|
23
|
+
method_option :default_lang, :type => :string, :aliases => "-l", :desc => "Default language to use for empty values if any"
|
24
|
+
method_option :default_path, :type => :string, :aliases => "-p", :desc => "Path of output files"
|
25
|
+
method_option :fetch, :type => :boolean, :desc => "Download file from Google Drive"
|
26
|
+
define_method("#{klass[:name].downcase}") do
|
27
|
+
csv2base(klass[:name])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
BASECLASSES = [
|
32
|
+
{:name => "Strings2CSV", :ext => ".strings"},
|
33
|
+
{:name => "Android2CSV", :ext => ".xml"},
|
34
|
+
{:name => "JSON2CSV", :ext => ".json"},
|
35
|
+
{:name => "Php2CSV", :ext => ".php"},
|
36
|
+
]
|
37
|
+
|
38
|
+
BASECLASSES.each do |klass|
|
39
|
+
desc "#{klass[:name].downcase}", "Convert #{klass[:ext]} files to CSV file"
|
40
|
+
method_option :filenames, :type => :array, :aliases => "-i", :desc => "location of strings files (FILENAMES)", :required => true
|
41
|
+
|
42
|
+
# optional options
|
43
|
+
method_option :csv_filename, :type => :string, :aliases => "-o", :desc => "location of output file"
|
44
|
+
method_option :headers, :type => :array, :aliases => "-h", :desc => "override headers of columns, default is name of input files and 'Variables' for reference"
|
45
|
+
method_option :dryrun, :type => :boolean, :aliases => "-n", :desc => "prints out content of hash without writing file"
|
46
|
+
define_method("#{klass[:name].downcase}") do
|
47
|
+
base2csv(klass[:name])
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
desc "csv_download", "Download Google Spreadsheet containing translations"
|
52
|
+
method_option :gd_filename, :type => :string, :required => :true, :desc => "File to download from Google Drive"
|
53
|
+
method_option :output_filename, :type => :string, :desc => "Filepath of downloaded file"
|
54
|
+
def csv_download
|
55
|
+
download(options['gd_filename'], options['output_filename'])
|
56
|
+
end
|
57
|
+
|
58
|
+
desc "version", "Display current version"
|
59
|
+
def version
|
60
|
+
require "babelish/version"
|
61
|
+
say "Babelish #{Babelish::VERSION}"
|
62
|
+
end
|
63
|
+
|
64
|
+
no_tasks do
|
65
|
+
def download(filename, output_filename = nil)
|
66
|
+
gd = Babelish::GoogleDoc.new
|
67
|
+
if output_filename
|
68
|
+
file_path = gd.download filename.to_s, output_filename
|
69
|
+
else
|
70
|
+
file_path = gd.download filename.to_s
|
71
|
+
end
|
72
|
+
if file_path
|
73
|
+
say "File '#{filename}' downloaded to '#{file_path}'"
|
74
|
+
else
|
75
|
+
say "Could not download the requested file: #{filename}"
|
76
|
+
end
|
77
|
+
file_path
|
78
|
+
end
|
79
|
+
|
80
|
+
def csv2base(classname)
|
81
|
+
args = options.dup
|
82
|
+
if options[:fetch]
|
83
|
+
say "Fetching csv file #{options[:filename]} from Google Drive"
|
84
|
+
filename = download(options[:filename])
|
85
|
+
abort unless filename # no file downloaded
|
86
|
+
args.delete(:fetch)
|
87
|
+
else
|
88
|
+
filename = options[:filename]
|
89
|
+
end
|
90
|
+
args.delete(:langs)
|
91
|
+
args.delete(:filename)
|
92
|
+
|
93
|
+
class_object = eval "Babelish::#{classname}"
|
94
|
+
converter = class_object.new(filename, options[:langs], args)
|
95
|
+
say converter.convert
|
96
|
+
end
|
97
|
+
|
98
|
+
def base2csv(classname)
|
99
|
+
class_object = eval "Babelish::#{classname}"
|
100
|
+
converter = class_object.new(options)
|
101
|
+
|
102
|
+
debug_values = converter.convert(!options[:dryrun])
|
103
|
+
say debug_values.inspect if options[:dryrun]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
def options
|
109
|
+
original_options = super
|
110
|
+
return original_options unless File.exists?(".babelish")
|
111
|
+
defaults = ::YAML.load_file(".babelish") || {}
|
112
|
+
Thor::CoreExt::HashWithIndifferentAccess.new(defaults.merge(original_options))
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Babelish
|
2
|
+
class CSV2Android < Csv2Base
|
3
|
+
require 'xmlsimple'
|
4
|
+
|
5
|
+
attr_accessor :file_path
|
6
|
+
|
7
|
+
def initialize(filename, langs, args = {})
|
8
|
+
super(filename, langs, args)
|
9
|
+
|
10
|
+
@file_path = args[:default_path].to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
def language_filepaths(language)
|
14
|
+
require 'pathname'
|
15
|
+
filepath = Pathname.new(@file_path) + "values-#{language.code}" + "strings.xml"
|
16
|
+
return filepath ? [filepath] : []
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_row_format(row_key, row_value)
|
20
|
+
return "\t<string name=\"#{row_key}\">#{row_value}</string>\n"
|
21
|
+
end
|
22
|
+
|
23
|
+
def hash_to_output(content = {})
|
24
|
+
output = ''
|
25
|
+
if content && content.size > 0
|
26
|
+
output += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
27
|
+
output += "<resources>\n"
|
28
|
+
content.each do |key, value|
|
29
|
+
output += get_row_format(key, value)
|
30
|
+
end
|
31
|
+
output += "</resources>"
|
32
|
+
end
|
33
|
+
return output
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|