ricotta 0.0.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.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,29 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ricotta (0.0.1)
5
+ commander (~> 4.1.2)
6
+ faraday (~> 0.8.0)
7
+ faraday_middleware (~> 0.9.0)
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ commander (4.1.3)
13
+ highline (~> 1.6.11)
14
+ faraday (0.8.7)
15
+ multipart-post (~> 1.1)
16
+ faraday_middleware (0.9.0)
17
+ faraday (>= 0.7.4, < 0.9)
18
+ highline (1.6.19)
19
+ multipart-post (1.2.0)
20
+ rake (0.9.6)
21
+ rspec (0.6.4)
22
+
23
+ PLATFORMS
24
+ ruby
25
+
26
+ DEPENDENCIES
27
+ rake (~> 0.9.2)
28
+ ricotta!
29
+ rspec (~> 0.6.1)
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2013 Erik Sundin
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,87 @@
1
+ Ricotta is a web based translation management tool, with complimentary build
2
+ tools, to efficiently manage localized resources in your software project.
3
+
4
+ - http://ricotta-open.appspot.com
5
+ - https://github.com/sosandstrom/ricotta
6
+
7
+ ## About
8
+
9
+ The ricotta gem integrates with the Ricotta translation tool to make it easier
10
+ to keep translations up to date in your software projects, all from the command line.
11
+
12
+ ## Installation
13
+
14
+ gem install ricotta
15
+
16
+ ## Usage
17
+
18
+ $ ricotta
19
+
20
+ Download translations from Ricotta
21
+
22
+ Commands:
23
+ dump Dump translations from Ricotta into local files.
24
+ help Display global or [command] help documentation.
25
+ install:xcode Fetch translations from Ricotta and install them into an Xcode project
26
+
27
+ Global Options:
28
+ -h, --help Display help documentation
29
+ -v, --version Display version information
30
+ -t, --trace Display backtrace when an error occurs
31
+
32
+ ### Install into an Xcode project
33
+
34
+ $ cd projects/MyXcodeProject
35
+ $ ricotta install:xcode -u http://ricotta-open.appspot.com \
36
+ -p MyRicottaProject \
37
+ -l en
38
+
39
+ Or by recommendation, create a `.ricottarc` file (see below) and execute.
40
+
41
+ $ ricotta install:xcode
42
+
43
+ ## Configuration
44
+
45
+ You can configure ricotta by using a ricotta configuration file.
46
+ The recommended name is `.ricottarc` but a custom file can be passed by using the `-c` option.
47
+
48
+ # My Ricotta configuration
49
+ url: http://ricotta-open.appspot.com
50
+ project: MyProject
51
+ language: en,es,pt
52
+ branch: staging
53
+ template: my_translation_template
54
+
55
+ Ricotta automatically searches for `.ricottarc` in the current working directory and in the users home directory.
56
+ Multiple configurations are automatically merged.
57
+
58
+ Multiple configurations example:
59
+
60
+ # Global config in ~/.ricottarc
61
+ url: http://ricotta.mycompany.com
62
+ subset: ios
63
+
64
+ App configurations
65
+
66
+ # /Users/es/dev/projects/MyiOSApp
67
+ project: MyApp
68
+ language: en,es
69
+ name_token: appName
70
+
71
+ And
72
+
73
+ # /Users/es/dev/projects/MyOtheriOSApp
74
+ project: MyOtherApp
75
+ language: en,pt,ru
76
+ name_token: applicationName
77
+ subset: iphone #override global config
78
+
79
+ ## Contact
80
+
81
+ Erik Sundin
82
+
83
+ - erik@eriksundin.se
84
+
85
+ ## License
86
+
87
+ Ricotta gem is available under the MIT license. See the LICENSE file for more info.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler"
2
+ Bundler.setup
3
+
4
+ gemspec = eval(File.read("ricotta.gemspec"))
5
+
6
+ task :build => "#{gemspec.full_name}.gem"
7
+
8
+ file "#{gemspec.full_name}.gem" => gemspec.files + ["ricotta.gemspec"] do
9
+ system "gem build ricotta.gemspec"
10
+ end
data/bin/ricotta ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'commander/import'
4
+
5
+ $:.push File.expand_path("../../lib", __FILE__)
6
+ require 'ricotta'
7
+
8
+ HighLine.track_eof = false # Fix for built-in Ruby
9
+
10
+ program :version, Ricotta::VERSION
11
+ program :description, 'Download translations from Ricotta'
12
+
13
+ program :help, 'Author', 'Erik Sundin <erik@eriksundin.se>'
14
+ program :help, 'Website', 'http://github.com/eriksundin'
15
+ program :help_formatter, :compact
16
+
17
+ default_command :help
18
+
19
+ require 'ricotta/commands'
data/lib/ricotta.rb ADDED
@@ -0,0 +1,6 @@
1
+ module Ricotta
2
+ VERSION = '0.0.1'
3
+ end
4
+
5
+ require 'ricotta/fetcher'
6
+ require 'ricotta/configuration'
@@ -0,0 +1,4 @@
1
+ $:.push File.expand_path('../', __FILE__)
2
+
3
+ require 'commands/dump'
4
+ require 'commands/xcode'
@@ -0,0 +1,69 @@
1
+ require 'yaml'
2
+
3
+ command :'dump' do |c|
4
+ c.syntax = "ricotta dump [options]"
5
+ c.summary = "Dump translations from Ricotta into local files."
6
+ c.description = "Fetched translations will written to one file per language"
7
+ c.option '-u', '--url URL', "Ricotta application URL"
8
+ c.option '-p', '--project PROJECT', "The Ricotta project"
9
+ c.option '-l', '--language LANGUAGE', "Comma separated list of language codes"
10
+ c.option '-T', '--template TEMPLATE', "Template name"
11
+ c.option '--subset SUBSET', "The subset name"
12
+ c.option '--branch BRANCH', "The branch name ('trunk' if not set)"
13
+ c.option '--config FILE', "Load default options from a configuration file"
14
+
15
+ c.action do |args, options|
16
+ options.default :branch => 'trunk'
17
+
18
+ global_config = Ricotta::Configuration::Config.new(options.config)
19
+ options.url = global_config[:url] unless options.url
20
+ options.project = global_config[:project] unless options.project
21
+ options.language = global_config[:language] unless options.language
22
+ options.subset = global_config[:subset] unless options.subset
23
+ options.template = global_config[:template] unless options.template
24
+ options.branch = global_config[:branch] if global_config[:branch] and options.branch.eql?('trunk')
25
+
26
+
27
+ determine_url! unless @url = options.url
28
+ determine_project! unless @project = options.project
29
+ determine_language! unless @language = options.language
30
+ determine_template! unless @template = options.template
31
+
32
+ languages = @language.split(',')
33
+
34
+ client = Ricotta::Fetcher::Client.new(@url)
35
+
36
+ languages.each do |language|
37
+
38
+ response = client.fetch(@project, options.branch, language, @template, options.subset)
39
+ case response.status
40
+ when 200
41
+ output = "#{@project}.#{language}"
42
+ File.open(output, 'w') { |file| file.write("#{response.body}") }
43
+ say_ok "#{language} translations downloaded to #{output}"
44
+ else
45
+ say_error "Failed to download translations for #{language}: #{response.status} #{response.body}\n"
46
+ abort
47
+ end
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ def determine_url!
54
+ @url ||= ask "Ricotta URL:"
55
+ end
56
+
57
+ def determine_project!
58
+ @project ||= ask "Project:"
59
+ end
60
+
61
+ def determine_template!
62
+ @template ||= ask "Template:"
63
+ end
64
+
65
+ def determine_language!
66
+ @language ||= ask "Language(s):"
67
+ end
68
+
69
+ end
@@ -0,0 +1,96 @@
1
+
2
+ command :'install:xcode' do |c|
3
+ c.syntax = "ricotta install:xcode [options]"
4
+ c.summary = "Fetch translations from Ricotta and install them into an Xcode project"
5
+ c.description = "Execute this command in the root of the Xcode project."
6
+ c.option '-u', '--url URL', "Ricotta application URL"
7
+ c.option '-p', '--project PROJECT', "The Ricotta project"
8
+ c.option '-l', '--language LANGUAGE', "Comma separated list of language codes"
9
+ c.option '--subset SUBSET', "Subset name"
10
+ c.option '--name_token NAMETOKEN', "A token within the translations to install as the localized CFBundleDisplayName"
11
+ c.option '--lproj_dir LPROJDIR', "Home dir of the localized Xcode project folders (default: scans the working directory)"
12
+ c.option '--template TEMPLATE', "The template (default: 'localizable_strings_padding')"
13
+ c.option '--branch BRANCH', "The branch name (default: 'trunk')"
14
+ c.option '--config FILE', "Load default options from a configuration file"
15
+
16
+ c.action do |args, options|
17
+ options.default :branch => 'trunk', :template => 'localizable_strings_padding'
18
+
19
+ global_config = Ricotta::Configuration::Config.new(options.config)
20
+ options.url = global_config[:url] unless options.url
21
+ options.project = global_config[:project] unless options.project
22
+ options.language = global_config[:language] unless options.language
23
+ options.subset = global_config[:subset] unless options.subset
24
+ options.template = global_config[:template] if global_config[:template] and options.template.eql?('localizable_strings_padding')
25
+ options.branch = global_config[:branch] if global_config[:branch] and options.branch.eql?('trunk')
26
+
27
+ options.name_token = global_config[:name_token] unless options.name_token
28
+ options.lproj_dir = global_config[:lproj_dir] unless options.lproj_dir
29
+
30
+ determine_url! unless @url = options.url
31
+ determine_project! unless @project = options.project
32
+ determine_language! unless @language = options.language
33
+
34
+ unless @resource_path = options.lproj_dir
35
+ resource_dir_lookup = Dir.glob('**/*.lproj').first
36
+ @resource_path = File.dirname(resource_dir_lookup) if resource_dir_lookup
37
+ end
38
+
39
+ determine_resource_path! unless @resource_path
40
+ @resource_path = File.expand_path(@resource_path)
41
+ say_error "The directory #{@resource_path} does not exist" and abort unless File.directory?(@resource_path)
42
+
43
+ languages = @language.split(',')
44
+ client = Ricotta::Fetcher::Client.new(@url)
45
+
46
+ languages.each do |language|
47
+ say_ok "processing #{language}"
48
+ response = client.fetch(@project, options.branch, language, options.template, options.subset)
49
+ case response.status
50
+ when 200
51
+ lproj_base_dir = "#{@resource_path}/#{language}.lproj"
52
+ Dir.mkdir(lproj_base_dir) unless File.directory?(lproj_base_dir)
53
+ strings_file = "#{lproj_base_dir}/Localizable.strings"
54
+ File.open(strings_file, 'w') { |file| file.write("#{response.body}") }
55
+ say_ok "created #{strings_file}"
56
+
57
+ if options.name_token
58
+ File.open(strings_file).each do |line|
59
+ if line.start_with?(options.name_token)
60
+ app_name = line.split('=').last.strip.split('"')[1]
61
+ say_error "The token #{options.name_token} is missing or empty for language #{language}" and abort unless app_name.length > 0
62
+
63
+ info_plist_strings = "#{lproj_base_dir}/InfoPlist.strings"
64
+ File.open(info_plist_strings, 'w') { |file| file.write("CFBundleDisplayName=\"#{app_name}\";\n") }
65
+ say_ok "created #{info_plist_strings} with CFBundleDisplayName '#{app_name}'"
66
+
67
+ break
68
+ end
69
+ end
70
+ end
71
+ else
72
+ say_error "Failed to download translations for #{language}: #{response.status} #{response.body}\n" and abort
73
+ end
74
+ end
75
+ say_ok "translations for #{@project} installed"
76
+ end
77
+
78
+ private
79
+
80
+ def determine_resource_path!
81
+ @resource_path ||= ask "Destination for .lproj folders:"
82
+ end
83
+
84
+ def determine_url!
85
+ @url ||= ask "Ricotta URL:"
86
+ end
87
+
88
+ def determine_project!
89
+ @project ||= ask "Project:"
90
+ end
91
+
92
+ def determine_language!
93
+ @language ||= ask "Language(s):"
94
+ end
95
+
96
+ end
@@ -0,0 +1,26 @@
1
+ require 'yaml'
2
+
3
+ module Ricotta::Configuration
4
+ class Config
5
+
6
+ def initialize(rcfile)
7
+ @config = Hash.new
8
+ parse(File.expand_path('~/.ricottarc'))
9
+ parse('.ricottarc')
10
+ parse(rcfile)
11
+ end
12
+
13
+ def [](key)
14
+ return @config["#{key}"]
15
+ end
16
+
17
+ private
18
+
19
+ def parse(file)
20
+ if file and File.exist?(file)
21
+ YAML.load_file(file).each {|key, value| @config[key] = value }
22
+ end
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,23 @@
1
+ require 'faraday'
2
+ require 'faraday_middleware'
3
+
4
+ module Ricotta::Fetcher
5
+ class Client
6
+
7
+ def initialize(url)
8
+ @connection = Faraday.new(:url => url) do |builder|
9
+ builder.use FaradayMiddleware::FollowRedirects
10
+ builder.adapter :net_http
11
+ end
12
+ end
13
+ def fetch(project, branch, language, template, subset)
14
+ path = "/proj/#{project}/branch/#{branch}/lang/#{language}/templ/#{template}/"
15
+ path.concat("subset/#{subset}/") if subset
16
+
17
+ @connection.get(path).on_complete do |env|
18
+ yield env[:status], env[:body] if block_given?
19
+ end
20
+ end
21
+ end
22
+ end
23
+
data/ricotta.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ricotta"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ricotta"
7
+ s.authors = ["Erik Sundin"]
8
+ s.email = "erik@eriksundin.se"
9
+ s.homepage = "http://github.com/eriksundin/ricotta-gem"
10
+ s.version = Ricotta::VERSION
11
+ s.platform = Gem::Platform::RUBY
12
+ s.summary = "Ricotta"
13
+ s.description = "Tool for downloading translations from Ricotta"
14
+
15
+ s.add_development_dependency "rspec", "~> 0.6.1"
16
+ s.add_development_dependency "rake", "~> 0.9.2"
17
+
18
+ s.add_dependency "commander", "~> 4.1.2"
19
+ s.add_dependency "faraday", "~> 0.8.0"
20
+ s.add_dependency "faraday_middleware", "~> 0.9.0"
21
+
22
+ s.files = Dir["./**/*"].reject { |file| file =~ /\.\/(bin|log|pkg|script|spec|test|vendor)/ }
23
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
25
+ s.require_paths = ["lib"]
26
+ end
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ricotta
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Erik Sundin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-05-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.6.1
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.6.1
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 0.9.2
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 0.9.2
46
+ - !ruby/object:Gem::Dependency
47
+ name: commander
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 4.1.2
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 4.1.2
62
+ - !ruby/object:Gem::Dependency
63
+ name: faraday
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 0.8.0
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 0.8.0
78
+ - !ruby/object:Gem::Dependency
79
+ name: faraday_middleware
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 0.9.0
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 0.9.0
94
+ description: Tool for downloading translations from Ricotta
95
+ email: erik@eriksundin.se
96
+ executables:
97
+ - ricotta
98
+ extensions: []
99
+ extra_rdoc_files: []
100
+ files:
101
+ - ./Gemfile
102
+ - ./Gemfile.lock
103
+ - ./lib/ricotta/commands/dump.rb
104
+ - ./lib/ricotta/commands/xcode.rb
105
+ - ./lib/ricotta/commands.rb
106
+ - ./lib/ricotta/configuration.rb
107
+ - ./lib/ricotta/fetcher.rb
108
+ - ./lib/ricotta.rb
109
+ - ./LICENSE
110
+ - ./Rakefile
111
+ - ./README.md
112
+ - ./ricotta.gemspec
113
+ - bin/ricotta
114
+ homepage: http://github.com/eriksundin/ricotta-gem
115
+ licenses: []
116
+ post_install_message:
117
+ rdoc_options: []
118
+ require_paths:
119
+ - lib
120
+ required_ruby_version: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ requirements: []
133
+ rubyforge_project:
134
+ rubygems_version: 1.8.25
135
+ signing_key:
136
+ specification_version: 3
137
+ summary: Ricotta
138
+ test_files: []