babelish 0.3.0 → 0.3.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 CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- YmY3NGRmN2Q0MjljZmE1MDFiMjI2MjRkYmY1Y2UyMDZiYjI2NGIyNg==
5
- data.tar.gz: !binary |-
6
- ZmZkYjAxZDhmNjk0NWNjYjcyYmJlMTczMzVlYjJhMWQ4MGY5NGIxOA==
2
+ SHA1:
3
+ metadata.gz: be34046268e439e572bf6a6a2396d5a7f4eb4144
4
+ data.tar.gz: b303dbab56fbc3a9fb05cdf8ee8b96ad492f7a48
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- ZTAzZjgyMDA2NmNhMjEyMGZlNTYyYTFhMThhMTUxNzA4MmU1Y2M1Y2E0NDg5
10
- MDk5ODhiMjMwNTdkYjgyNDk5ODgxMWU4YmY4N2VhNzM4Zjc4MjY0MmM2NDdh
11
- NTcwNzkwNDM4YWU1ZDdmZjI4OTlhY2Q0NDYyZTc3MzQ3MzRlZGI=
12
- data.tar.gz: !binary |-
13
- ZDJmMmM3ZThkMmJlZTU0ZWQzNjBjMGNkYjk1NTI0OTIxNWU3NDVlNGEwZGI1
14
- ODMyMzVkZTdlMmRkNzgzOWZiNGZlNjU1Yjg0M2NiODdhYTkwY2Q1MGFmZjFi
15
- ZjY2MmU3MDY1ZTQzODZmYzQyOTI2OWQ5Mjc2ZWVmMGFmY2QyMTQ=
6
+ metadata.gz: 05b8e867c1393e9c71b44000fcac86879313b863b698d349596920fabc17f2b231044c6a482f4f15ecc4476f1956c26aed7b7c20f9c1600e1850bc76d3fd4cbf
7
+ data.tar.gz: 534309b822c8587a37ab88aaea78e739db384c15aa39408a0b0393ed58e17f06489815ef18608c9980e8e4c56b9cd546ca2cb364924c45fff2cc6521a383c583
data/.babelish.sample CHANGED
@@ -23,4 +23,9 @@ langs: # Languages to convert. i.e. English:en
23
23
  # state-column: 3 # Position of column for state if any
24
24
  # keys-column: 0 # Position of column for keys
25
25
  # default-lang: "English" # Default language to use for empty values if any
26
- # default-path: "resources/" # Path of output files
26
+ # output-dir: "resources/" # Path of output files
27
+ # output-file: "myOnlyFile.strings" # --IGNORED-- Path of a single output file. Overrides 'output_dir'
28
+ # output-basenames:
29
+ # - Localizable
30
+ # - info
31
+ # ignore_lang_path: true # does not care about lang component path. i.e: en.lproj/
data/README.md CHANGED
@@ -1,40 +1,58 @@
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:
1
+ [![Build Status](https://secure.travis-ci.org/netbe/Babelish.png?branch=master)](http://travis-ci.org/netbe/Babelish)
2
+ [![Code Climate](https://codeclimate.com/github/netbe/Babelish.png)](https://codeclimate.com/github/netbe/Babelish)[![Coverage Status](https://coveralls.io/repos/netbe/Babelish/badge.png)](https://coveralls.io/r/netbe/Babelish)
3
+ [![Gem Version](https://badge.fury.io/rb/babelish.svg)](http://badge.fury.io/rb/babelish)
4
+
5
+ **Babelish : Chaotically confused, like Babel**
6
+
7
+ Originally created to deal with localizedStrings files (aka *CSV-to-iOS-Localizable.strings-converter*), this command tool now converts a csv file of translations into the below file formats and vice-versa:
7
8
  * .strings (iOS)
8
9
  * .xml (Android)
9
10
  * .json
10
11
  * .php
11
12
 
12
- # Requirements
13
+ It can also fetch the csv file from GoogleDrive.
13
14
 
14
- * Ruby 1.9.2 or above
15
-
16
- # Setup
15
+ # Installation
17
16
 
18
17
  `gem install babelish`
19
18
 
20
- # Usage
21
-
22
- ` babelish help`
19
+ Requires Ruby 1.9.2 or above.
23
20
 
24
- * Use configuration file
21
+ # Usage
25
22
 
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.
23
+ ```
24
+ babelish help
25
+ Commands:
26
+ babelish android2csv -i, --filenames=one two three # Convert .xml files to CSV file
27
+ babelish csv2android --filename=FILENAME -L, --langs=key:value # Convert CSV file to .xml
28
+ babelish csv2json --filename=FILENAME -L, --langs=key:value # Convert CSV file to .json
29
+ babelish csv2php --filename=FILENAME -L, --langs=key:value # Convert CSV file to .php
30
+ babelish csv2strings --filename=FILENAME -L, --langs=key:value # Convert CSV file to .strings
31
+ babelish csv_download --gd-filename=GD_FILENAME # Download Google Spreadsheet containing translations
32
+ babelish help [COMMAND] # Describe available commands or one specific command
33
+ babelish json2csv -i, --filenames=one two three # Convert .json files to CSV file
34
+ babelish php2csv -i, --filenames=one two three # Convert .php files to CSV file
35
+ babelish strings2csv -i, --filenames=one two three # Convert .strings files to CSV file
36
+ babelish version # Display current version
37
+
38
+ Options:
39
+ [--verbose], [--no-verbose]
40
+ ```
41
+
42
+ You can use a **configuration file** to hold all your commandline arguments into a file.
43
+ Place a `.babelish` file (YAML) in your repo where you will run the command.
44
+ See [.babelish.sample](.babelish.sample) file in the doc folder. as the possible values.
45
+
46
+ *For previous CSV-to-iOS-Localizable.strings-converter, rename your `.csvconverter` into `.babelish`.*
29
47
 
30
48
  # Contributing
31
49
 
32
- If you feel like it, just create a pull request with a branch like `feature/<nameofbranch>` to `develop` branch
50
+ Want to add another support for a new format or/and usage? Add a new feature? Fix a bug?
33
51
 
52
+ Just create a pull request with a branch like `feature/<nameofbranch>` or `hotfix/<nameofbranch>`.
34
53
 
35
- ## Development
36
54
 
37
- Edge version can be found on `develop` branch.
55
+ ## Development
38
56
 
39
57
  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
58
 
data/babelish.gemspec CHANGED
@@ -6,7 +6,7 @@ require 'babelish/version'
6
6
  Gem::Specification.new do |s|
7
7
  s.name = 'babelish'
8
8
  s.version = Babelish::VERSION
9
- s.date = '2014-04-10'
9
+ s.date = '2014-05-07'
10
10
  s.summary = "CSV converter for localization files"
11
11
  s.description = "This set of commands converts a CSV file to the following formats:
12
12
  - .strings (iOS)
@@ -13,15 +13,17 @@ class Commandline < Thor
13
13
 
14
14
  CSVCLASSES.each do |klass|
15
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
16
+ method_option :filename, :type => :string, :aliases => "-i", :desc => "CSV file to convert from or name of file in Google Drive"
17
+ method_option :langs, :type => :hash, :aliases => "-L", :desc => "Languages to convert. i.e. English:en"
18
18
 
19
19
  # optional options
20
20
  method_option :excluded_states, :type => :array, :aliases => "-x", :desc => "Exclude rows with given state"
21
21
  method_option :state_column, :type => :numeric, :aliases => "-s", :desc => "Position of column for state if any"
22
22
  method_option :keys_column, :type => :numeric, :aliases => "-k", :desc => "Position of column for keys"
23
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"
24
+ method_option :output_dir, :type => :string, :aliases => "-d", :desc => "Path of output files"
25
+ method_option :output_basenames, :type => :array, :aliases => "-o", :desc => "Basename of output files"
26
+ method_option :ignore_lang_path, :type => :boolean, :aliases => "-I", :default => false, :desc => "Ignore the path component of langs"
25
27
  method_option :fetch, :type => :boolean, :desc => "Download file from Google Drive"
26
28
  define_method("#{klass[:name].downcase}") do
27
29
  csv2base(klass[:name])
@@ -37,7 +39,7 @@ class Commandline < Thor
37
39
 
38
40
  BASECLASSES.each do |klass|
39
41
  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
42
+ method_option :filenames, :type => :array, :aliases => "-i", :desc => "location of strings files (FILENAMES)"
41
43
 
42
44
  # optional options
43
45
  method_option :csv_filename, :type => :string, :aliases => "-o", :desc => "location of output file"
@@ -49,10 +51,32 @@ class Commandline < Thor
49
51
  end
50
52
 
51
53
  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
+ method_option :gd_filename, :type => :string, :desc => "File to download from Google Drive."
55
+ method_option :sheet, :type => :numeric, :desc => "Index of worksheet to download. First index is 0."
56
+ method_option :all, :type => :boolean, :lazy_default => true, :desc => "Download all worksheets to individual csv files."
57
+ method_option :output_filename, :type => :string, :desc => "Filepath of downloaded file."
54
58
  def csv_download
55
- download(options['gd_filename'], options['output_filename'])
59
+ all = options[:sheet] ? false : options[:all]
60
+ filename = options['gd_filename']
61
+ raise ArgumentError.new("csv_download command : missing file to download") unless filename
62
+ if all
63
+ download(filename)
64
+ else
65
+ download(filename, options['output_filename'], options['sheet'])
66
+ end
67
+ end
68
+
69
+ desc "open FILE", "Open local csv file in default editor or Google Spreadsheet containing translations in default browser"
70
+ def open(file = "translations.csv")
71
+ filename = file || options["filename"]
72
+ if File.exists?(filename)
73
+ say "Opening local file '#{filename}'"
74
+ system "open \"#{filename}\""
75
+ else
76
+ say "Opening Google Drive file '#{filename}'"
77
+ gd = Babelish::GoogleDoc.new
78
+ gd.open filename.to_s
79
+ end
56
80
  end
57
81
 
58
82
  desc "version", "Display current version"
@@ -62,37 +86,47 @@ class Commandline < Thor
62
86
  end
63
87
 
64
88
  no_tasks do
65
- def download(filename, output_filename = nil)
89
+ def download(filename, output_filename = nil, worksheet_index = nil)
66
90
  gd = Babelish::GoogleDoc.new
67
- if output_filename
68
- file_path = gd.download filename.to_s, output_filename
91
+ if output_filename || worksheet_index
92
+ file_path = gd.download_spreadsheet filename.to_s, output_filename, worksheet_index
93
+ files = [file_path].compact
69
94
  else
70
- file_path = gd.download filename.to_s
95
+ files = gd.download filename.to_s
96
+ file_path = files.join("\n")
71
97
  end
98
+
72
99
  if file_path
73
- say "File '#{filename}' downloaded to '#{file_path}'"
100
+ say "File '#{filename}' downloaded to :\n#{file_path.to_s}"
74
101
  else
75
102
  say "Could not download the requested file: #{filename}"
76
103
  end
77
- file_path
104
+ files
78
105
  end
79
106
 
80
107
  def csv2base(classname)
81
108
  args = options.dup
82
109
  if options[:fetch]
83
110
  say "Fetching csv file #{options[:filename]} from Google Drive"
84
- filename = download(options[:filename])
85
- abort unless filename # no file downloaded
111
+ files = download(options[:filename])
112
+ abort if files.empty? # no file downloaded
86
113
  args.delete(:fetch)
87
114
  else
88
- filename = options[:filename]
115
+ files = [options[:filename]]
89
116
  end
90
117
  args.delete(:langs)
91
118
  args.delete(:filename)
92
119
 
93
- class_object = eval "Babelish::#{classname}"
94
- converter = class_object.new(filename, options[:langs], args)
95
- say converter.convert
120
+ files.each_with_index do |filename, index|
121
+ if options[:output_basenames]
122
+ args[:output_basename] = options[:output_basenames][index]
123
+ end
124
+
125
+ class_object = eval "Babelish::#{classname}"
126
+ args = Thor::CoreExt::HashWithIndifferentAccess.new(args)
127
+ converter = class_object.new(filename, options[:langs], args)
128
+ say converter.convert
129
+ end
96
130
  end
97
131
 
98
132
  def base2csv(classname)
@@ -104,7 +138,12 @@ class Commandline < Thor
104
138
  end
105
139
  end
106
140
 
141
+ def self.exit_on_failure?
142
+ true
143
+ end
144
+
107
145
  private
146
+
108
147
  def options
109
148
  original_options = super
110
149
  return original_options unless File.exists?(".babelish")
@@ -7,7 +7,7 @@ module Babelish
7
7
  def initialize(filename, langs, args = {})
8
8
  super(filename, langs, args)
9
9
 
10
- @file_path = args[:default_path].to_s
10
+ @file_path = args[:output_dir].to_s
11
11
  end
12
12
 
13
13
  def language_filepaths(language)
@@ -32,5 +32,9 @@ module Babelish
32
32
  end
33
33
  return output
34
34
  end
35
+
36
+ def extension
37
+ "xml"
38
+ end
35
39
  end
36
40
  end
@@ -1,6 +1,8 @@
1
+ require 'pathname'
1
2
  module Babelish
2
3
  class Csv2Base
3
- attr_accessor :default_path, :output_file
4
+ attr_accessor :output_dir, :output_basename
5
+ attr_accessor :ignore_lang_path
4
6
  attr_accessor :langs
5
7
  attr_accessor :csv_filename
6
8
  attr_accessor :default_lang
@@ -15,20 +17,23 @@ module Babelish
15
17
  }
16
18
 
17
19
  args = default_args.merge!(args)
18
-
20
+ args = Thor::CoreExt::HashWithIndifferentAccess.new(args)
19
21
  @langs = langs
22
+
23
+ # check input types
24
+ raise ArgumentError.new("wrong value of filename: #{filename.inspect}") unless filename.is_a?(String)
20
25
  if !@langs.is_a?(Hash) || @langs.size == 0
21
- raise "wrong format or/and langs parameter" + @langs.inspect
26
+ raise ArgumentError.new("wrong format or/and langs parameter: #{@langs.inspect}")
22
27
  end
23
28
 
24
- @output_file = args[:output_file]
25
- @default_path = args[:default_path].to_s
29
+ @output_basename = args[:output_basename]
30
+ @output_dir = args[:output_dir].to_s
26
31
  @csv_filename = filename
27
32
  @excluded_states = args[:excluded_states]
28
33
  @state_column = args[:state_column]
29
34
  @keys_column = args[:keys_column]
30
35
  @default_lang = args[:default_lang]
31
-
36
+ @ignore_lang_path = args[:ignore_lang_path]
32
37
  @languages = []
33
38
  end
34
39
 
@@ -43,6 +48,15 @@ module Babelish
43
48
  []
44
49
  end
45
50
 
51
+ def extension
52
+ #implement in subclass
53
+ ""
54
+ end
55
+
56
+ def default_filepath
57
+ Pathname.new(@output_dir) + "#{@output_basename}.#{extension}"
58
+ end
59
+
46
60
  def process_value(row_value, default_value)
47
61
  value = row_value.nil? ? default_value : row_value
48
62
  value = "" if value.nil?
@@ -50,99 +64,99 @@ module Babelish
50
64
  value.gsub!(/\s*(\n|\\\s*n)\s*/, "\\n") #replace new lines with \n + strip
51
65
  value.gsub!(/%\s+([a-zA-Z@])([^a-zA-Z@]|$)/, "%\\1\\2") #repair string formats ("% d points" etc)
52
66
  value.gsub!(/([^0-9\s\(\{\[^])%/, "\\1 %")
53
- value.strip!
54
- return value.to_utf8
55
- end
67
+ value.strip!
68
+ return value.to_utf8
69
+ end
56
70
 
57
- def get_row_format(row_key, row_value)
58
- return "\"" + row_key + "\" = \"" + row_value + "\""
59
- end
71
+ def get_row_format(row_key, row_value)
72
+ return "\"" + row_key + "\" = \"" + row_value + "\""
73
+ end
60
74
 
61
- # Convert csv file to multiple Localizable.strings files for each column
62
- def convert(name = @csv_filename)
63
- rowIndex = 0
64
- excludedCols = []
65
- defaultCol = 0
75
+ # Convert csv file to multiple Localizable.strings files for each column
76
+ def convert(name = @csv_filename)
77
+ rowIndex = 0
78
+ excludedCols = []
79
+ defaultCol = 0
66
80
 
67
- CSV.foreach(name, :quote_char => '"', :col_sep => ',', :row_sep => :auto) do |row|
81
+ CSV.foreach(name, :quote_char => '"', :col_sep => ',', :row_sep => :auto) do |row|
68
82
 
69
- if rowIndex == 0
70
- #check there's at least two columns
71
- return unless row.count > 1
72
- else
73
- #skip empty lines (or sections)
74
- next if row == nil or row[@keys_column].nil?
75
- end
83
+ if rowIndex == 0
84
+ #check there's at least two columns
85
+ return unless row.count > 1
86
+ else
87
+ #skip empty lines (or sections)
88
+ next if row == nil or row[@keys_column].nil?
89
+ end
76
90
 
77
- # go through columns
78
- row.size.times do |i|
79
- next if excludedCols.include? i
80
-
81
- #header
82
- if rowIndex == 0
83
- # ignore all headers not listed in langs to create files
84
- (excludedCols << i and next) unless @langs.has_key?(row[i])
85
-
86
- defaultCol = i if self.default_lang == row[i]
87
- language = Language.new(row[i])
88
- if @langs[row[i]].is_a?(Array)
89
- @langs[row[i]].each do |id|
90
- language.add_language_id(id.to_s)
91
- end
92
- else
93
- language.add_language_id(@langs[row[i]].to_s)
94
- end
95
- @languages[i] = language
96
- elsif !@state_column || (row[@state_column].nil? || row[@state_column] == '' || !@excluded_states.include?(row[@state_column]))
97
- # TODO: add option to strip the constant or referenced language
98
- key = row[@keys_column].strip
99
- value = self.process_value(row[i], row[defaultCol])
91
+ # go through columns
92
+ row.size.times do |i|
93
+ next if excludedCols.include? i
100
94
 
101
- @languages[i].add_content_pair(key, value)
95
+ #header
96
+ if rowIndex == 0
97
+ # ignore all headers not listed in langs to create files
98
+ (excludedCols << i and next) unless @langs.has_key?(row[i])
99
+
100
+ defaultCol = i if self.default_lang == row[i]
101
+ language = Language.new(row[i])
102
+ if @langs[row[i]].is_a?(Array)
103
+ @langs[row[i]].each do |id|
104
+ language.add_language_id(id.to_s)
105
+ end
106
+ else
107
+ language.add_language_id(@langs[row[i]].to_s)
102
108
  end
103
- end
109
+ @languages[i] = language
110
+ elsif !@state_column || (row[@state_column].nil? || row[@state_column] == '' || !@excluded_states.include?(row[@state_column]))
111
+ # TODO: add option to strip the constant or referenced language
112
+ key = row[@keys_column].strip
113
+ value = self.process_value(row[i], row[defaultCol])
104
114
 
105
- rowIndex += 1
115
+ @languages[i].add_content_pair(key, value)
116
+ end
106
117
  end
107
118
 
108
- write_content
119
+ rowIndex += 1
109
120
  end
110
121
 
111
- def write_content
112
- info = "List of created files:\n"
113
- count = 0
114
- @languages.each do |language|
115
- next if language.nil?
116
-
117
- files = []
118
- if @output_file
119
- files << create_file_from_path(@output_file)
120
- else
121
- language_filepaths(language).each do |filename|
122
- files << create_file_from_path(filename)
123
- end
124
- end
125
- files.each do |file|
126
- file.write hash_to_output(language.content)
127
- info += "#{file.path.to_s}\n"
128
- count += 1
122
+ write_content
123
+ end
129
124
 
130
- file.close
125
+ def write_content
126
+ info = "List of created files:\n"
127
+ count = 0
128
+ @languages.each do |language|
129
+ next if language.nil?
130
+
131
+ files = []
132
+ if @ignore_lang_path
133
+ files << create_file_from_path(default_filepath)
134
+ else
135
+ language_filepaths(language).each do |filename|
136
+ files << create_file_from_path(filename)
131
137
  end
132
138
  end
139
+ files.each do |file|
140
+ file.write hash_to_output(language.content)
141
+ info += "- #{File.absolute_path(file)}\n"
142
+ count += 1
133
143
 
134
- info = "Created #{count} files.\n" + info
135
- return info
144
+ file.close
145
+ end
136
146
  end
137
147
 
138
- def hash_to_output(content = {})
139
- output = ''
140
- if content && content.size > 0
141
- content.each do |key, value|
142
- output += get_row_format(key, value)
143
- end
148
+ info = "Created #{count} files.\n" + info
149
+ return info
150
+ end
151
+
152
+ def hash_to_output(content = {})
153
+ output = ''
154
+ if content && content.size > 0
155
+ content.each do |key, value|
156
+ output += get_row_format(key, value)
144
157
  end
145
- return output
146
158
  end
159
+ return output
147
160
  end
148
161
  end
162
+ end
@@ -1,22 +1,21 @@
1
1
  module Babelish
2
2
  require 'json'
3
3
  class CSV2JSON < Csv2Base
4
- attr_accessor :file_path
5
-
6
- def initialize(filename, langs, args = {})
7
- super(filename, langs, args)
8
-
9
- @file_path = args[:default_path].to_s
10
- end
11
4
 
12
5
  def language_filepaths(language)
13
6
  require 'pathname'
14
- filepath = Pathname.new("#{@file_path}#{language.code}.js")
7
+ filename = @output_basename || language.code
8
+ filepath = Pathname.new("#{@output_dir}#{filename}.js")
9
+
15
10
  return filepath ? [filepath] : []
16
11
  end
17
12
 
18
13
  def hash_to_output(content = {})
19
14
  return content.to_json
20
15
  end
16
+
17
+ def extension
18
+ "js"
19
+ end
21
20
  end
22
21
  end
@@ -1,18 +1,16 @@
1
1
  module Babelish
2
2
  class CSV2Php < Csv2Base
3
3
  attr_accessor :php_tag
4
- attr_accessor :file_path
5
4
 
6
5
  def initialize(filename, langs, args = {})
7
6
  super(filename, langs, args)
8
-
7
+ # TODO: list this arg in commandline
9
8
  @php_tag = args[:php_tag].nil? ? 'lang' : args[:php_tag]
10
- @file_path = args[:default_path].to_s
11
9
  end
12
10
 
13
11
  def language_filepaths(language)
14
12
  require 'pathname'
15
- filepath = Pathname.new(@file_path) + "#{language.code}" + "lang.php"
13
+ filepath = Pathname.new(@output_dir) + "#{language.code}" + "lang.php"
16
14
  return filepath ? [filepath] : []
17
15
  end
18
16
 
@@ -20,5 +18,8 @@ module Babelish
20
18
  return "$" + @php_tag + "['#{row_key}'] = \"#{row_value}\";\n"
21
19
  end
22
20
 
21
+ def extension
22
+ "php"
23
+ end
23
24
  end
24
25
  end
@@ -1,22 +1,16 @@
1
1
  module Babelish
2
2
  class CSV2Strings < Csv2Base
3
- attr_accessor :file_path
4
-
5
- def initialize(filename, langs, args = {})
6
- super(filename, langs, args)
7
-
8
- @file_path = args[:default_path].to_s
9
- end
10
3
 
11
4
  def language_filepaths(language)
12
5
  require 'pathname'
13
6
  filepaths = []
7
+ filename = @output_basename || 'Localizable'
14
8
 
15
9
  if language.regions.empty?
16
- filepaths << Pathname.new(@file_path) + "#{language.code}.lproj/Localizable.strings"
10
+ filepaths << Pathname.new(@output_dir) + "#{language.code}.lproj/#{filename}.strings"
17
11
  else
18
12
  language.regions.each do |region|
19
- filepaths << Pathname.new(@file_path) + "#{language.code}-#{region}.lproj/Localizable.strings"
13
+ filepaths << Pathname.new(@output_dir) + "#{language.code}-#{region}.lproj/#{filename}.strings"
20
14
  end
21
15
  end
22
16
  filepaths
@@ -26,5 +20,8 @@ module Babelish
26
20
  return "\"#{row_key}\" = \"#{row_value}\";\n"
27
21
  end
28
22
 
23
+ def extension
24
+ "strings"
25
+ end
29
26
  end
30
27
  end
@@ -12,25 +12,48 @@ module Babelish
12
12
  class GoogleDoc
13
13
  attr_accessor :session
14
14
 
15
+ def download(requested_filename)
16
+ file = file_with_name(requested_filename)
17
+ return [] unless file
18
+ files = []
19
+ file.worksheets.each_with_index do |worksheet, index|
20
+ files << download_spreadsheet(requested_filename, "translations_#{worksheet.title}.csv", index)
21
+ end
22
+ files
23
+ end
24
+
25
+ def download_spreadsheet(requested_filename, output_filename, worksheet_index = 0)
26
+ output_filename ||= "translations.csv"
27
+ file = file_with_name(requested_filename)
28
+ return nil unless file
29
+ file.export_as_file(output_filename, "csv", worksheet_index)
30
+ return output_filename
31
+ end
32
+
33
+ def open(requested_filename)
34
+ file = file_with_name(requested_filename)
35
+ if file
36
+ system "open \"#{file.human_url}\""
37
+ else
38
+ puts "can't open requested file"
39
+ end
40
+ end
41
+
15
42
  def authenticate
16
43
  # will try to get token from ~/.ruby_google_drive.token
17
44
  @session = GoogleDrive.saved_session
18
45
  end
19
46
 
20
- def download(requested_filename, worksheet_index = nil, output_filename = "translations.csv")
47
+ def file_with_name(name)
21
48
  unless @session
22
49
  authenticate
23
50
  end
24
- result = @session.file_by_title(requested_filename)
51
+ result = @session.file_by_title(name)
25
52
  if result.is_a? Array
26
53
  file = result.first
27
54
  else
28
55
  file = result
29
56
  end
30
- return nil unless file
31
- file.export_as_file(output_filename, "csv", worksheet_index)
32
- return output_filename
33
57
  end
34
-
35
58
  end
36
59
  end
@@ -1,3 +1,3 @@
1
1
  module Babelish
2
- VERSION = '0.3.0'
2
+ VERSION = '0.3.1'
3
3
  end
@@ -16,11 +16,11 @@ class TestCSV2AndroidCommand < Test::Unit::TestCase
16
16
  system("rm -rf ./values-fr/")
17
17
  end
18
18
 
19
- def test_csv2android_with_default_path
19
+ def test_csv2android_with_output_dir
20
20
  options = {
21
21
  :filename => "test/data/test_data_multiple_langs.csv",
22
22
  :langs => {"English" => "en", "French" => "fr"},
23
- :default_path => "mynewlocation"
23
+ :output_dir => "mynewlocation"
24
24
  }
25
25
 
26
26
  Commandline.new([], options).csv2android
@@ -16,17 +16,17 @@ class TestCSV2StringsCommand < Test::Unit::TestCase
16
16
  system("rm -rf ./fr.lproj/")
17
17
  end
18
18
 
19
- def test_csv2strings_with_default_path
19
+ def test_csv2strings_with_output_dir
20
20
  options = {
21
21
  :filename => "test/data/test_data_multiple_langs.csv",
22
22
  :langs => {"English" => "en", "French" => "fr"},
23
- :default_path => "mynewlocation"
23
+ :output_dir => "mynewlocation"
24
24
  }
25
25
  Commandline.new([], options).csv2strings
26
26
 
27
27
  # testing
28
- assert File.exist?("./mynewlocation/en.lproj/Localizable.strings"), "can't find output file for English"
29
- assert File.exist?("./mynewlocation/fr.lproj/Localizable.strings"), "can't find output file for French"
28
+ assert File.exist?("./mynewlocation/en.lproj/Localizable.strings"), "can't find output file for English in mynewlocation folder"
29
+ assert File.exist?("./mynewlocation/fr.lproj/Localizable.strings"), "can't find output file for French in mynewlocation folder"
30
30
 
31
31
  #clean up
32
32
  system("rm -rf ./mynewlocation")
@@ -35,13 +35,17 @@ class TestCSV2StringsCommand < Test::Unit::TestCase
35
35
  def test_csv2strings_with_fetch_google_doc
36
36
  omit if ENV['TRAVIS']
37
37
  options = {
38
- :filename => "my_trads",
38
+ :filename => "my_strings",
39
39
  :langs => {"English" => "en", "French" => "fr"},
40
40
  :fetch => true
41
41
  }
42
42
  assert_nothing_raised do
43
43
  Commandline.new([], options).csv2strings
44
44
  end
45
+
46
+ #clean up
47
+ system("rm -rf ./en.lproj/")
48
+ system("rm -rf ./fr.lproj/")
45
49
  end
46
50
 
47
51
  def test_csv2strings_with_config_file
@@ -51,6 +55,52 @@ class TestCSV2StringsCommand < Test::Unit::TestCase
51
55
  Commandline.new.csv2strings
52
56
  end
53
57
 
58
+ #clean up
59
+ system("rm -rf ./en.lproj/")
60
+ system("rm -rf ./fr.lproj/")
61
+ end
62
+
63
+ def test_csv2strings_with_output_basenames_option
64
+ omit if ENV['TRAVIS']
65
+ options = {
66
+ :filename => "my_strings",
67
+ :langs => {"English" => "en", "French" => "fr"},
68
+ :fetch => true,
69
+ :output_basenames => %w(sheet1 sheet2),
70
+ }
71
+
72
+ Commandline.new([], options).csv2strings
73
+ # testing
74
+ assert File.exist?("./en.lproj/sheet1.strings"), "can't find output file for sheet1 English"
75
+ assert File.exist?("./fr.lproj/sheet1.strings"), "can't find output file for sheet1 French"
76
+ assert File.exist?("./en.lproj/sheet2.strings"), "can't find output file for sheet2 English"
77
+ assert File.exist?("./fr.lproj/sheet2.strings"), "can't find output file for sheet2 French"
78
+
79
+ #clean up
80
+ system("rm -rf ./en.lproj/")
81
+ system("rm -rf ./fr.lproj/")
82
+ end
83
+
84
+ def test_csv2strings_with_ignore_lang_path_option
85
+ omit if ENV['TRAVIS']
86
+ options = {
87
+ :filename => "my_strings",
88
+ :langs => {"English" => "en", "French" => "fr"},
89
+ :fetch => true,
90
+ :ignore_lang_path => true,
91
+ :output_basenames => %w(sheet1 sheet2),
92
+ }
93
+
94
+ Commandline.new([], options).csv2strings
95
+ # testing
96
+ assert File.exist?("./sheet1.strings"), "can't find output file for sheet1 English with_ignore_lang_path_option"
97
+ assert File.exist?("./sheet1.strings"), "can't find output file for sheet1 French with_ignore_lang_path_option"
98
+ assert File.exist?("./sheet2.strings"), "can't find output file for sheet2 English with_ignore_lang_path_option"
99
+ assert File.exist?("./sheet2.strings"), "can't find output file for sheet2 French with_ignore_lang_path_option"
100
+
101
+ #clean up
102
+ system("rm -rf ./en.lproj/")
103
+ system("rm -rf ./fr.lproj/")
54
104
  end
55
105
 
56
106
  def teardown
@@ -4,11 +4,19 @@ class TestBins < Test::Unit::TestCase
4
4
  def test_csv2strings_with_google_doc
5
5
  omit if ENV['TRAVIS']
6
6
  assert_nothing_raised do
7
- system("./bin/csv2strings --fetch --filename test.csv")
7
+ system("./bin/csv2strings --fetch --filename my_strings --langs English:en")
8
8
  end
9
9
  assert_equal $?.exitstatus, 0
10
10
  end
11
11
 
12
+ def test_csv2strings_with_google_doc_missing_langs
13
+ omit if ENV['TRAVIS']
14
+ assert_nothing_raised do
15
+ system("./bin/csv2strings --fetch --filename my_strings")
16
+ end
17
+ assert_equal $?.exitstatus, 1
18
+ end
19
+
12
20
  def test_csv2strings_with_config_file
13
21
  system("cp .babelish.sample .babelish")
14
22
 
@@ -0,0 +1,103 @@
1
+ require 'test_helper'
2
+ class TestCommandLine < Test::Unit::TestCase
3
+
4
+ def test_csv2base_with_config_file_all_required_options
5
+ options = {
6
+ :filename => "test/data/test_data_multiple_langs.csv",
7
+ :langs => {"English" => "en", "French" => "fr"}
8
+ }
9
+ config_file = File.new(".babelish", "w")
10
+ config_file.write options.to_yaml
11
+ config_file.close
12
+
13
+ assert_nothing_raised do
14
+ Commandline.new.csv2strings
15
+ end
16
+
17
+ #clean up
18
+ system("rm -rf ./en.lproj/")
19
+ system("rm -rf ./fr.lproj/")
20
+ system("rm -f .babelish")
21
+ end
22
+
23
+
24
+ def test_csv2base_without_filename_fails
25
+ options = {
26
+ :langs => {"English" => "en", "French" => "fr"}
27
+ }
28
+ config_file = File.new(".babelish", "w")
29
+ config_file.write options.to_yaml
30
+ config_file.close
31
+
32
+ assert_raises do
33
+ Commandline.new.csv2strings
34
+ end
35
+
36
+ #clean up
37
+ system("rm -rf ./en.lproj/")
38
+ system("rm -rf ./fr.lproj/")
39
+ system("rm -f .babelish")
40
+ end
41
+
42
+ def test_base2csv_with_config_file_all_required_options
43
+ options = {
44
+ :filenames => ["test/data/test_en.strings", "test/data/test_fr.strings"],
45
+ }
46
+ config_file = File.new(".babelish", "w")
47
+ config_file.write options.to_yaml
48
+ config_file.close
49
+
50
+ assert_nothing_raised do
51
+ Commandline.new.strings2csv
52
+ end
53
+
54
+ #clean up
55
+ system("rm -f translations.csv")
56
+ system("rm -f .babelish")
57
+ end
58
+
59
+ def test_base2csv_with_config_without_filenames_fails
60
+ options = {}
61
+ config_file = File.new(".babelish", "w")
62
+ config_file.write options.to_yaml
63
+ config_file.close
64
+
65
+ assert_raises do
66
+ Commandline.new.strings2csv
67
+ end
68
+
69
+ #clean up
70
+ system("rm -f .babelish")
71
+ end
72
+
73
+ def test_csv_download_without_gd_filename_fails
74
+ options = {}
75
+ config_file = File.new(".babelish", "w")
76
+ config_file.write options.to_yaml
77
+ config_file.close
78
+
79
+ assert_raises do
80
+ Commandline.new.csv_download
81
+ end
82
+
83
+ #clean up
84
+ system("rm -f .babelish")
85
+ end
86
+
87
+
88
+ def test_csv_download_with_required_params
89
+ omit if ENV['TRAVIS']
90
+ options = {:gd_filename => "my_strings"}
91
+ config_file = File.new(".babelish", "w")
92
+ config_file.write options.to_yaml
93
+ config_file.close
94
+
95
+ assert_nothing_raised do
96
+ Commandline.new.csv_download
97
+ end
98
+
99
+ #clean up
100
+ system("rm -f .babelish")
101
+ end
102
+
103
+ end
@@ -16,7 +16,8 @@ class TestCSV2Android < Test::Unit::TestCase
16
16
  single_file = 'myApp.xml'
17
17
  converter = Babelish::CSV2Android.new(csv_file,
18
18
  {'English' => "en"},
19
- :output_file => single_file)
19
+ :output_basename => 'myApp',
20
+ :ignore_lang_path => true)
20
21
  converter.convert
21
22
  assert File.exists?(single_file), "the ouptut file does not exist"
22
23
 
@@ -16,7 +16,8 @@ class TestCSV2JSON < Test::Unit::TestCase
16
16
  single_file = 'myfile.js'
17
17
  converter = Babelish::CSV2JSON.new(csv_file,
18
18
  {'English' => "en"},
19
- :output_file => single_file)
19
+ :output_basename => 'myfile',
20
+ :ignore_lang_path => true)
20
21
  converter.convert
21
22
  assert File.exists?(single_file), "the ouptut file does not exist"
22
23
 
@@ -16,7 +16,8 @@ class TestCSV2Php < Test::Unit::TestCase
16
16
  single_file = 'myApp.php'
17
17
  converter = Babelish::CSV2Php.new(csv_file,
18
18
  {'English' => "en"},
19
- :output_file => single_file)
19
+ :output_basename => 'myApp',
20
+ :ignore_lang_path => true)
20
21
  converter.convert
21
22
  assert File.exists?(single_file), "the ouptut file does not exist"
22
23
 
@@ -13,7 +13,8 @@ class TestCSV2Strings < Test::Unit::TestCase
13
13
  single_file = 'myApp.strings'
14
14
  converter = Babelish::CSV2Strings.new(csv_file,
15
15
  {'English' => [:en]},
16
- :output_file => single_file)
16
+ :output_basename => 'myApp',
17
+ :ignore_lang_path => true)
17
18
  converter.convert
18
19
  assert File.exists?(single_file), "the ouptut file does not exist"
19
20
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: babelish
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - François Benaiteau
@@ -9,137 +9,140 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-04-10 00:00:00.000000000 Z
12
+ date: 2014-05-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - ! '>='
18
+ - - '>='
19
19
  - !ruby/object:Gem::Version
20
20
  version: '0'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - ! '>='
25
+ - - '>='
26
26
  - !ruby/object:Gem::Version
27
27
  version: '0'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: google_drive
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - ! '>='
32
+ - - '>='
33
33
  - !ruby/object:Gem::Version
34
34
  version: '0'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - ! '>='
39
+ - - '>='
40
40
  - !ruby/object:Gem::Version
41
41
  version: '0'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: highline
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
- - - ! '>='
46
+ - - '>='
47
47
  - !ruby/object:Gem::Version
48
48
  version: '0'
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - ! '>='
53
+ - - '>='
54
54
  - !ruby/object:Gem::Version
55
55
  version: '0'
56
56
  - !ruby/object:Gem::Dependency
57
57
  name: xml-simple
58
58
  requirement: !ruby/object:Gem::Requirement
59
59
  requirements:
60
- - - ! '>='
60
+ - - '>='
61
61
  - !ruby/object:Gem::Version
62
62
  version: '0'
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
- - - ! '>='
67
+ - - '>='
68
68
  - !ruby/object:Gem::Version
69
69
  version: '0'
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: json
72
72
  requirement: !ruby/object:Gem::Requirement
73
73
  requirements:
74
- - - ! '>='
74
+ - - '>='
75
75
  - !ruby/object:Gem::Version
76
76
  version: '0'
77
77
  type: :runtime
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
- - - ! '>='
81
+ - - '>='
82
82
  - !ruby/object:Gem::Version
83
83
  version: '0'
84
84
  - !ruby/object:Gem::Dependency
85
85
  name: rake
86
86
  requirement: !ruby/object:Gem::Requirement
87
87
  requirements:
88
- - - ! '>='
88
+ - - '>='
89
89
  - !ruby/object:Gem::Version
90
90
  version: '0'
91
91
  type: :development
92
92
  prerelease: false
93
93
  version_requirements: !ruby/object:Gem::Requirement
94
94
  requirements:
95
- - - ! '>='
95
+ - - '>='
96
96
  - !ruby/object:Gem::Version
97
97
  version: '0'
98
98
  - !ruby/object:Gem::Dependency
99
99
  name: test-unit
100
100
  requirement: !ruby/object:Gem::Requirement
101
101
  requirements:
102
- - - ! '>='
102
+ - - '>='
103
103
  - !ruby/object:Gem::Version
104
104
  version: '0'
105
105
  type: :development
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
- - - ! '>='
109
+ - - '>='
110
110
  - !ruby/object:Gem::Version
111
111
  version: '0'
112
112
  - !ruby/object:Gem::Dependency
113
113
  name: simplecov
114
114
  requirement: !ruby/object:Gem::Requirement
115
115
  requirements:
116
- - - ! '>='
116
+ - - '>='
117
117
  - !ruby/object:Gem::Version
118
118
  version: '0'
119
119
  type: :development
120
120
  prerelease: false
121
121
  version_requirements: !ruby/object:Gem::Requirement
122
122
  requirements:
123
- - - ! '>='
123
+ - - '>='
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
126
  - !ruby/object:Gem::Dependency
127
127
  name: yard
128
128
  requirement: !ruby/object:Gem::Requirement
129
129
  requirements:
130
- - - ! '>='
130
+ - - '>='
131
131
  - !ruby/object:Gem::Version
132
132
  version: '0'
133
133
  type: :development
134
134
  prerelease: false
135
135
  version_requirements: !ruby/object:Gem::Requirement
136
136
  requirements:
137
- - - ! '>='
137
+ - - '>='
138
138
  - !ruby/object:Gem::Version
139
139
  version: '0'
140
- description: ! "This set of commands converts a CSV file to the following formats:\n
141
- \ - .strings (iOS)\n - .xml (Android)\n -
142
- .json\n - .php"
140
+ description: |-
141
+ This set of commands converts a CSV file to the following formats:
142
+ - .strings (iOS)
143
+ - .xml (Android)
144
+ - .json
145
+ - .php
143
146
  email:
144
147
  - francois.benaiteau@gmail.com
145
148
  - markus.paeschke@gmail.com
@@ -196,6 +199,7 @@ files:
196
199
  - test/babelish/test_android2csv.rb
197
200
  - test/babelish/test_base2csv.rb
198
201
  - test/babelish/test_bins.rb
202
+ - test/babelish/test_commandline.rb
199
203
  - test/babelish/test_csv2android.rb
200
204
  - test/babelish/test_csv2base.rb
201
205
  - test/babelish/test_csv2json.rb
@@ -230,12 +234,12 @@ require_paths:
230
234
  - lib
231
235
  required_ruby_version: !ruby/object:Gem::Requirement
232
236
  requirements:
233
- - - ! '>='
237
+ - - '>='
234
238
  - !ruby/object:Gem::Version
235
239
  version: '0'
236
240
  required_rubygems_version: !ruby/object:Gem::Requirement
237
241
  requirements:
238
- - - ! '>='
242
+ - - '>='
239
243
  - !ruby/object:Gem::Version
240
244
  version: '0'
241
245
  requirements: []
@@ -244,5 +248,37 @@ rubygems_version: 2.2.2
244
248
  signing_key:
245
249
  specification_version: 4
246
250
  summary: CSV converter for localization files
247
- test_files: []
251
+ test_files:
252
+ - test/babelish/commands/test_command_android2csv.rb
253
+ - test/babelish/commands/test_command_csv2android.rb
254
+ - test/babelish/commands/test_command_csv2strings.rb
255
+ - test/babelish/commands/test_command_strings2csv.rb
256
+ - test/babelish/test_android2csv.rb
257
+ - test/babelish/test_base2csv.rb
258
+ - test/babelish/test_bins.rb
259
+ - test/babelish/test_commandline.rb
260
+ - test/babelish/test_csv2android.rb
261
+ - test/babelish/test_csv2base.rb
262
+ - test/babelish/test_csv2json.rb
263
+ - test/babelish/test_csv2php.rb
264
+ - test/babelish/test_csv2strings.rb
265
+ - test/babelish/test_json2csv.rb
266
+ - test/babelish/test_php2csv.rb
267
+ - test/babelish/test_strings2csv.rb
268
+ - test/data/android-en.xml
269
+ - test/data/android-fr.xml
270
+ - test/data/android.xml
271
+ - test/data/genstrings.strings
272
+ - test/data/json.json
273
+ - test/data/php_lang.php
274
+ - test/data/test_data.csv
275
+ - test/data/test_data.strings
276
+ - test/data/test_data_multiple_langs.csv
277
+ - test/data/test_en.strings
278
+ - test/data/test_fr.strings
279
+ - test/data/test_utf16.strings
280
+ - test/data/test_with_nil.csv
281
+ - test/data/test_with_nil.strings
282
+ - test/data/xcode_empty.strings
283
+ - test/test_helper.rb
248
284
  has_rdoc: