babelish 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
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: