localeapp 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +4 -0
- data/.gitignore +7 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/.travis.yml +7 -0
- data/Gemfile +2 -0
- data/README.textile +147 -0
- data/Rakefile +11 -0
- data/bin/localeapp +61 -0
- data/cucumber.yml +8 -0
- data/features/localeapp_binary.feature +116 -0
- data/features/step_definitions/cli_steps.rb +27 -0
- data/features/support/env.rb +21 -0
- data/features/support/hooks.rb +3 -0
- data/init.rb +1 -0
- data/lib/locale_app/api_call.rb +9 -0
- data/lib/locale_app/api_caller.rb +77 -0
- data/lib/locale_app/cli/install.rb +41 -0
- data/lib/locale_app/cli/pull.rb +34 -0
- data/lib/locale_app/cli/push.rb +49 -0
- data/lib/locale_app/cli/update.rb +19 -0
- data/lib/locale_app/configuration.rb +93 -0
- data/lib/locale_app/exception_handler.rb +21 -0
- data/lib/locale_app/key_checker.rb +43 -0
- data/lib/locale_app/missing_translations.rb +36 -0
- data/lib/locale_app/poller.rb +61 -0
- data/lib/locale_app/rails/2_3_translation_helper_monkeypatch.rb +36 -0
- data/lib/locale_app/rails/controller.rb +34 -0
- data/lib/locale_app/rails/flatten.rb +113 -0
- data/lib/locale_app/rails.rb +53 -0
- data/lib/locale_app/routes.rb +80 -0
- data/lib/locale_app/sender.rb +49 -0
- data/lib/locale_app/tasks/locale_app.rake +20 -0
- data/lib/locale_app/updater.rb +63 -0
- data/lib/locale_app/version.rb +3 -0
- data/lib/locale_app.rb +98 -0
- data/lib/localeapp.rb +1 -0
- data/localeapp.gemspec +35 -0
- data/run_ci +5 -0
- data/spec/fixtures/en.yml +6 -0
- data/spec/fixtures/es.yml +6 -0
- data/spec/locale_app/api_call_spec.rb +15 -0
- data/spec/locale_app/api_caller_spec.rb +157 -0
- data/spec/locale_app/cli/install_spec.rb +42 -0
- data/spec/locale_app/cli/pull_spec.rb +45 -0
- data/spec/locale_app/cli/push_spec.rb +30 -0
- data/spec/locale_app/cli/update_spec.rb +18 -0
- data/spec/locale_app/configuration_spec.rb +119 -0
- data/spec/locale_app/exception_handler_spec.rb +21 -0
- data/spec/locale_app/key_checker_spec.rb +19 -0
- data/spec/locale_app/missing_translations_spec.rb +28 -0
- data/spec/locale_app/poller_spec.rb +61 -0
- data/spec/locale_app/rails/controller_spec.rb +117 -0
- data/spec/locale_app/routes_spec.rb +134 -0
- data/spec/locale_app/sender_spec.rb +49 -0
- data/spec/locale_app/updater_spec.rb +89 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/support/locale_app_integration_data.rb +33 -0
- data/spec/support/locale_app_synchronization_data.rb +21 -0
- metadata +300 -0
data/.autotest
ADDED
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm ruby-1.9.2@locale_app
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.textile
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
h1. Locale
|
2
|
+
|
3
|
+
The localeapp gem connects your rails app to the Locale service on
|
4
|
+
"localeapp.com":http://www.localeapp.com. Locale makes hand editing translation
|
5
|
+
files something you don't have to do.
|
6
|
+
|
7
|
+
The gem hooks into the i18n exception mechanism to send missing translations to
|
8
|
+
the app. When translated content has been added it's automatically pulled down
|
9
|
+
so you can see it straight away.
|
10
|
+
|
11
|
+
We're still in private beta but if you think Locale would be useful to you and
|
12
|
+
are willing to provide feedback then please get in touch at info@localeapp.com
|
13
|
+
and we'll see what we can do.
|
14
|
+
|
15
|
+
h2. Installation
|
16
|
+
|
17
|
+
h3. Rails 3
|
18
|
+
|
19
|
+
Add the localeapp gem to your Gemfile and install it:
|
20
|
+
|
21
|
+
<pre>
|
22
|
+
echo "gem 'localeapp'" >> Gemfile
|
23
|
+
bundle install
|
24
|
+
</pre>
|
25
|
+
|
26
|
+
Create a project on localeapp.com and get the api key. Then run:
|
27
|
+
|
28
|
+
<pre>
|
29
|
+
bundle exec localeapp install <YOUR_API_KEY>
|
30
|
+
</pre>
|
31
|
+
|
32
|
+
This will check everything looks good and create
|
33
|
+
config/initializers/localeapp.rb for you.
|
34
|
+
|
35
|
+
h3. Rails 2.3
|
36
|
+
|
37
|
+
Define localeapp in config/environment.rb:
|
38
|
+
|
39
|
+
<pre>
|
40
|
+
config.gem 'localeapp'
|
41
|
+
</pre>
|
42
|
+
|
43
|
+
Install the gem:
|
44
|
+
|
45
|
+
<pre>
|
46
|
+
rake gems:install
|
47
|
+
</pre>
|
48
|
+
|
49
|
+
Create a project on localeapp.com and get the api key. Then run:
|
50
|
+
|
51
|
+
<pre>
|
52
|
+
localeapp install <YOUR_API_KEY>
|
53
|
+
</pre>
|
54
|
+
|
55
|
+
h2. Importing existing content
|
56
|
+
|
57
|
+
You can import via localeapp.com or with the command line tool. To import
|
58
|
+
existing translations do:
|
59
|
+
|
60
|
+
<pre>
|
61
|
+
localeapp import config/locales/en.yml
|
62
|
+
</pre>
|
63
|
+
|
64
|
+
This will queue importing the file. The projects pages on localeapp.com will
|
65
|
+
automatically refresh so you can see the import progress.
|
66
|
+
|
67
|
+
If you've more than one locale to import you can zip up the yml files. Both
|
68
|
+
localeapp.com and the localeapp import command accept zip files.
|
69
|
+
|
70
|
+
h2. Automatically sending missing translations
|
71
|
+
|
72
|
+
Missing translations are automatically sent only in the development environment
|
73
|
+
by default. When a page is refreshed any missing translations will be sent to
|
74
|
+
localeapp.com.
|
75
|
+
|
76
|
+
If you want to disable sending missing translations in the development
|
77
|
+
environment then edit config/initializers/localeapp.rb to include:
|
78
|
+
|
79
|
+
<pre>
|
80
|
+
config.disabled_sending_environments << 'development'
|
81
|
+
</pre>
|
82
|
+
|
83
|
+
This is just an array, so you can configure it to match any environment you
|
84
|
+
wish.
|
85
|
+
|
86
|
+
h2. Automatically pulling translations
|
87
|
+
|
88
|
+
There are two ways to do this, one that suits a single developer working the
|
89
|
+
code locally and one where the translations are being pulled down to a staging
|
90
|
+
(or live) server.
|
91
|
+
|
92
|
+
h3. Single developer
|
93
|
+
|
94
|
+
In this mode the gem pulls any updated translations from localeapp.com at the
|
95
|
+
beginning of each request. This is the default setting so you don't need to do
|
96
|
+
anything special.
|
97
|
+
|
98
|
+
h3. Staging server
|
99
|
+
|
100
|
+
In this mode you configure the individual listeners to not poll every request
|
101
|
+
and instead run localeapp in daemon mode to fetch updated translations. This is
|
102
|
+
useful when you have more than one listener and don't want them to race to
|
103
|
+
update the translations.
|
104
|
+
|
105
|
+
h4. Disabling polling
|
106
|
+
|
107
|
+
Edit config/initializers/localeapp.rb to include:
|
108
|
+
|
109
|
+
<pre>
|
110
|
+
config.disabled_polling_environments << 'development'
|
111
|
+
</pre>
|
112
|
+
|
113
|
+
Run the daemon with:
|
114
|
+
|
115
|
+
<pre>
|
116
|
+
localeapp daemon
|
117
|
+
</pre>
|
118
|
+
|
119
|
+
The listeners will automatically reload translations when they see there are
|
120
|
+
new ones.
|
121
|
+
|
122
|
+
h3. Disabling Reloading
|
123
|
+
|
124
|
+
Automatic reloading is disabled everywhere but the development environment, and
|
125
|
+
can be disabled there in a similar way to polling and sending:
|
126
|
+
|
127
|
+
<pre>
|
128
|
+
config.disabled_reloading_environments << 'development'
|
129
|
+
</pre>
|
130
|
+
|
131
|
+
h3. Inviting other developers and translators
|
132
|
+
|
133
|
+
You can invite other developers and translators via localeapp.com. Developers
|
134
|
+
have access to all the content and all the locales. Translators are restricted
|
135
|
+
to editing only the locales you give them access too.
|
136
|
+
|
137
|
+
h3. Adding a locale
|
138
|
+
|
139
|
+
If we find an unknown locale during an import we'll add it to your project.
|
140
|
+
You can also add a new locale to a project via localeapp.com. This will create
|
141
|
+
missing translations for every translation key. You will need to restart any
|
142
|
+
listeners completely to pick up the new locale.
|
143
|
+
|
144
|
+
h3. Support and feedback
|
145
|
+
|
146
|
+
You can contact us via the support link at the bottom of the page, emailing
|
147
|
+
info@localeapp.com, or on campfire at https://localeapp.campfirenow.com/d77b5
|
data/Rakefile
ADDED
data/bin/localeapp
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$LOAD_PATH.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
|
3
|
+
|
4
|
+
require 'locale_app'
|
5
|
+
|
6
|
+
# Don't connect to the net if we're running under cucumber for testing
|
7
|
+
# Use FakeWeb to simulate api.localeapp.com
|
8
|
+
if ENV['FAKE_WEB_DURING_CUCUMBER_RUN'] && fake_data_as_json = ENV['FAKE_WEB_FAKES']
|
9
|
+
require 'fakeweb'
|
10
|
+
FakeWeb.allow_net_connect = false
|
11
|
+
fakes = JSON.parse(fake_data_as_json)
|
12
|
+
fakes.each do |fake|
|
13
|
+
FakeWeb.register_uri fake['method'].to_sym, fake['uri'], { :body => fake['body'], :status => fake['status'] }.merge(fake['headers'])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
args = ARGV.dup
|
18
|
+
|
19
|
+
command = args.shift.strip rescue nil
|
20
|
+
|
21
|
+
unless %w{help install}.include?(command)
|
22
|
+
unless LocaleApp.include_config_file
|
23
|
+
puts "Could not load config file"
|
24
|
+
exit
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
case command
|
29
|
+
when 'install'
|
30
|
+
key = args.shift.strip rescue nil
|
31
|
+
installer = LocaleApp::CLI::Install.new
|
32
|
+
if installer.execute(key)
|
33
|
+
exit 0
|
34
|
+
else
|
35
|
+
exit 1
|
36
|
+
end
|
37
|
+
when 'pull'
|
38
|
+
LocaleApp::CLI::Pull.new.execute
|
39
|
+
when 'push'
|
40
|
+
file = args.shift.strip rescue nil
|
41
|
+
pusher = LocaleApp::CLI::Push.new
|
42
|
+
pusher.execute(file)
|
43
|
+
when 'update'
|
44
|
+
LocaleApp::CLI::Update.new.execute
|
45
|
+
when 'daemon'
|
46
|
+
while true do
|
47
|
+
LocaleApp::CLI::Update.new.execute
|
48
|
+
sleep 5
|
49
|
+
end
|
50
|
+
else
|
51
|
+
puts <<-HELP
|
52
|
+
Usage: localeapp COMMAND [ARGS]
|
53
|
+
|
54
|
+
Commands:
|
55
|
+
install <api_key> - Creates new configuration files and confirms key works
|
56
|
+
pull - Pulls all translations from LocaleApp.com
|
57
|
+
push <file> - Pushes a translation file to LocaleApp.com
|
58
|
+
update - Gets any changes since the last poll and updates the yml files
|
59
|
+
daemon - Simple daemon that checks every 5 seconds for new translations
|
60
|
+
HELP
|
61
|
+
end
|
data/cucumber.yml
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
<%
|
2
|
+
rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : ""
|
3
|
+
rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}"
|
4
|
+
std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} --strict --tags ~@wip"
|
5
|
+
%>
|
6
|
+
default: <%= std_opts %> features
|
7
|
+
wip: --tags @wip:3 --wip features
|
8
|
+
rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip
|
@@ -0,0 +1,116 @@
|
|
1
|
+
Feature: localeapp executable
|
2
|
+
|
3
|
+
Scenario: Viewing help
|
4
|
+
In order to see what options I have
|
5
|
+
When I run `localeapp help`
|
6
|
+
Then the output should contain:
|
7
|
+
"""
|
8
|
+
Usage: localeapp COMMAND [ARGS]
|
9
|
+
|
10
|
+
Commands:
|
11
|
+
install <api_key> - Creates new configuration files and confirms key works
|
12
|
+
pull - Pulls all translations from LocaleApp.com
|
13
|
+
"""
|
14
|
+
|
15
|
+
Scenario: Running install
|
16
|
+
In order to configure my project and check my api key is correct
|
17
|
+
When I have a valid project on localeapp.com with api key "MYAPIKEY"
|
18
|
+
And I run `localeapp install MYAPIKEY`
|
19
|
+
Then the output should contain:
|
20
|
+
"""
|
21
|
+
LocaleApp Install
|
22
|
+
|
23
|
+
Checking API key: MYAPIKEY
|
24
|
+
Success!
|
25
|
+
Project: Test Project
|
26
|
+
Default Locale: en (English)
|
27
|
+
"""
|
28
|
+
And a file named "config/initializers/localeapp.rb" should exist
|
29
|
+
And the exit status should be 0
|
30
|
+
|
31
|
+
Scenario: Running install with bad api key
|
32
|
+
In order to configure my project and check my api key is correct
|
33
|
+
When I have a valid project on localeapp.com but an incorrect api key "BADAPIKEY"
|
34
|
+
And I run `localeapp install BADAPIKEY`
|
35
|
+
Then the output should contain:
|
36
|
+
"""
|
37
|
+
LocaleApp Install
|
38
|
+
|
39
|
+
Checking API key: BADAPIKEY
|
40
|
+
ERROR: Project not found
|
41
|
+
"""
|
42
|
+
And a file named "config/initializers/locale_app.rb" should not exist
|
43
|
+
And the exit status should not be 0
|
44
|
+
|
45
|
+
Scenario: Running pull
|
46
|
+
In order to retreive my translations
|
47
|
+
Given I have a translations on localeapp.com for the project with api key "MYAPIKEY"
|
48
|
+
And a file named "config/initializers/locale_app.rb" with:
|
49
|
+
"""
|
50
|
+
require 'locale_app/rails'
|
51
|
+
LocaleApp.configure do |config|
|
52
|
+
config.api_key = 'MYAPIKEY'
|
53
|
+
end
|
54
|
+
"""
|
55
|
+
And a directory named "config/locales"
|
56
|
+
When I run `localeapp pull`
|
57
|
+
Then the output should contain:
|
58
|
+
"""
|
59
|
+
LocaleApp Pull
|
60
|
+
|
61
|
+
Fetching translations:
|
62
|
+
Success!
|
63
|
+
Updating backend:
|
64
|
+
Success!
|
65
|
+
"""
|
66
|
+
And a file named "config/locales/en.yml" should exist
|
67
|
+
|
68
|
+
Scenario: Running push
|
69
|
+
In order to send my translations
|
70
|
+
When I have a valid project on localeapp.com with api key "MYAPIKEY"
|
71
|
+
And a file named "config/initializers/locale_app.rb" with:
|
72
|
+
"""
|
73
|
+
require 'locale_app/rails'
|
74
|
+
LocaleApp.configure do |config|
|
75
|
+
config.api_key = 'MYAPIKEY'
|
76
|
+
end
|
77
|
+
"""
|
78
|
+
And an empty file named "config/locales/en.yml"
|
79
|
+
When I run `localeapp push config/locales/en.yml`
|
80
|
+
Then the output should contain:
|
81
|
+
"""
|
82
|
+
LocaleApp Push
|
83
|
+
|
84
|
+
Pushing file:
|
85
|
+
Success!
|
86
|
+
|
87
|
+
config/locales/en.yml queued for processing.
|
88
|
+
"""
|
89
|
+
|
90
|
+
Scenario: Running update
|
91
|
+
In order to receive the translations that have been updated since the last check
|
92
|
+
When I have a valid project on localeapp.com with api key "MYAPIKEY"
|
93
|
+
And a file named "config/initializers/locale_app.rb" with:
|
94
|
+
"""
|
95
|
+
require 'locale_app/rails'
|
96
|
+
LocaleApp.configure do |config|
|
97
|
+
config.api_key = 'MYAPIKEY'
|
98
|
+
end
|
99
|
+
"""
|
100
|
+
And a file named "log/locale_app.yml" with:
|
101
|
+
"""
|
102
|
+
---
|
103
|
+
:updated_at: 120
|
104
|
+
:polled_at: 130
|
105
|
+
"""
|
106
|
+
And new translations for the api key "MYAPIKEY" since "120" with time "140"
|
107
|
+
And a directory named "config/locales"
|
108
|
+
When I run `localeapp update`
|
109
|
+
Then the output should contain:
|
110
|
+
"""
|
111
|
+
LocaleApp update: checking for translations since 120
|
112
|
+
Found and updated new translations
|
113
|
+
"""
|
114
|
+
And a file named "config/locales/en.yml" should exist
|
115
|
+
# check the content here
|
116
|
+
# and the localeapp.yml file
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
When /^I have a valid project on localeapp\.com with api key "([^"]*)"$/ do |api_key|
|
5
|
+
uri = "http://api.localeapp.com/v1/projects/#{api_key}.json"
|
6
|
+
body = valid_project_data.to_json
|
7
|
+
add_fake_web_uri(:get, uri, ['200', 'OK'], body)
|
8
|
+
add_fake_web_uri(:post, "http://api.localeapp.com/v1/projects/#{api_key}/import/", ['202', 'OK'], '')
|
9
|
+
end
|
10
|
+
|
11
|
+
When /^I have a valid project on localeapp\.com but an incorrect api key "([^"]*)"$/ do |bad_api_key|
|
12
|
+
uri = "http://api.localeapp.com/v1/projects/#{bad_api_key}.json"
|
13
|
+
body = valid_project_data.to_json
|
14
|
+
add_fake_web_uri(:get, uri, ['404', 'Not Found'], body)
|
15
|
+
end
|
16
|
+
|
17
|
+
When /^I have a translations on localeapp\.com for the project with api key "([^"]*)"$/ do |api_key|
|
18
|
+
uri = "http://api.localeapp.com/v1/projects/#{api_key}/translations.json"
|
19
|
+
body = valid_translation_data.to_json
|
20
|
+
add_fake_web_uri(:get, uri, ['200', 'OK'], body)
|
21
|
+
end
|
22
|
+
|
23
|
+
When /^new translations for the api key "([^"]*)" since "([^"]*)" with time "([^"]*)"$/ do |api_key, update_time, new_time|
|
24
|
+
uri = "http://api.localeapp.com/v1/projects/#{api_key}/translations.json?updated_at=#{update_time}"
|
25
|
+
body = valid_translation_data.to_json
|
26
|
+
add_fake_web_uri(:get, uri, ['200', 'OK'], body, 'date' => Time.at(new_time.to_i).httpdate)
|
27
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'aruba/cucumber'
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '../../spec/support/locale_app_integration_data'))
|
3
|
+
World(LocaleAppIntegrationData)
|
4
|
+
|
5
|
+
ENV['PATH'] = "#{File.expand_path(File.dirname(__FILE__) + '/../../bin')}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
|
6
|
+
|
7
|
+
module FakeWebHelper
|
8
|
+
def add_fake_web_uri(method, uri, status, body, headers = {})
|
9
|
+
fakes = JSON.parse(ENV['FAKE_WEB_FAKES'] || '[]')
|
10
|
+
fakes << {
|
11
|
+
'method' => method,
|
12
|
+
'uri' => uri,
|
13
|
+
'status' => status,
|
14
|
+
'body' => body,
|
15
|
+
'headers' => headers
|
16
|
+
}
|
17
|
+
ENV['FAKE_WEB_FAKES'] = fakes.to_json
|
18
|
+
end
|
19
|
+
end
|
20
|
+
World(FakeWebHelper)
|
21
|
+
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'locale_app'
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module LocaleApp
|
2
|
+
class ApiCaller
|
3
|
+
include ::LocaleApp::Routes
|
4
|
+
|
5
|
+
NonHTTPResponse = Struct.new(:code)
|
6
|
+
|
7
|
+
DEFAULT_RETRY_LIMIT = 1
|
8
|
+
|
9
|
+
# we can retry more in the gem than we can
|
10
|
+
# when running in process
|
11
|
+
attr_accessor :max_connection_attempts
|
12
|
+
|
13
|
+
attr_reader :endpoint, :options, :connection_attempts
|
14
|
+
|
15
|
+
def initialize(endpoint, options = {})
|
16
|
+
@endpoint, @options = endpoint, options
|
17
|
+
@connection_attempts = 0
|
18
|
+
@max_connection_attempts = options[:max_connection_attempts] || DEFAULT_RETRY_LIMIT
|
19
|
+
end
|
20
|
+
|
21
|
+
def call(obj)
|
22
|
+
method, url = send("#{endpoint}_endpoint", options[:url_options] || {})
|
23
|
+
LocaleApp.debug("API CALL: #{method} #{url}")
|
24
|
+
success = false
|
25
|
+
while connection_attempts < max_connection_attempts
|
26
|
+
sleep_if_retrying
|
27
|
+
response = make_call(method, url)
|
28
|
+
LocaleApp.debug("RESPONSE: #{response.code}")
|
29
|
+
valid_response_codes = (200..207).to_a
|
30
|
+
if valid_response_codes.include?(response.code.to_i)
|
31
|
+
if options[:success]
|
32
|
+
LocaleApp.debug("CALLING SUCCESS HANDLER: #{options[:success]}")
|
33
|
+
obj.send(options[:success], response)
|
34
|
+
end
|
35
|
+
success = true
|
36
|
+
break
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
if !success && options[:failure]
|
41
|
+
obj.send(options[:failure], response)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
def make_call(method, url)
|
47
|
+
begin
|
48
|
+
@connection_attempts += 1
|
49
|
+
LocaleApp.debug("ATTEMPT #{@connection_attempts}")
|
50
|
+
request_options = options[:request_options] || {}
|
51
|
+
if method == :post
|
52
|
+
RestClient.send(method, url, options[:payload], request_options)
|
53
|
+
else
|
54
|
+
RestClient.send(method, url, request_options)
|
55
|
+
end
|
56
|
+
rescue RestClient::ResourceNotFound,
|
57
|
+
RestClient::NotModified,
|
58
|
+
RestClient::InternalServerError,
|
59
|
+
RestClient::BadGateway,
|
60
|
+
RestClient::ServiceUnavailable,
|
61
|
+
RestClient::GatewayTimeout => error
|
62
|
+
return error.response
|
63
|
+
rescue Errno::ECONNREFUSED => error
|
64
|
+
LocaleApp.debug("ERROR: Connection Refused")
|
65
|
+
return NonHTTPResponse.new(-1)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def sleep_if_retrying
|
70
|
+
if @connection_attempts > 0
|
71
|
+
time = @connection_attempts * 5
|
72
|
+
LocaleApp.debug("Sleeping for #{time} before retrying")
|
73
|
+
sleep time
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module LocaleApp
|
2
|
+
module CLI
|
3
|
+
class Install
|
4
|
+
def execute(key, output = $stdout)
|
5
|
+
output.puts "LocaleApp Install"
|
6
|
+
output.puts ""
|
7
|
+
output.puts "Checking API key: #{key}"
|
8
|
+
if key.nil?
|
9
|
+
output.puts "ERROR: You must supply an API key"
|
10
|
+
return
|
11
|
+
end
|
12
|
+
valid_key, project_data = check_key(key)
|
13
|
+
if valid_key
|
14
|
+
output.puts "Success!"
|
15
|
+
output.puts "Project: #{project_data['name']}"
|
16
|
+
locale_app_default_code = project_data['default_locale']['code']
|
17
|
+
output.puts "Default Locale: #{locale_app_default_code} (#{project_data['default_locale']['name']})"
|
18
|
+
if I18n.default_locale.to_s != locale_app_default_code
|
19
|
+
output.puts "WARNING: I18n.default_locale is #{I18n.default_locale}, change in config/environment.rb (Rails 2) or config/application.rb (Rails 3)"
|
20
|
+
end
|
21
|
+
config_file_path = "config/initializers/localeapp.rb"
|
22
|
+
output.puts "Writing configuration file to #{config_file_path}"
|
23
|
+
write_configuration_file config_file_path
|
24
|
+
true
|
25
|
+
else
|
26
|
+
output.puts "ERROR: Project not found"
|
27
|
+
false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
def check_key(key)
|
33
|
+
LocaleApp::KeyChecker.new.check(key)
|
34
|
+
end
|
35
|
+
|
36
|
+
def write_configuration_file(path)
|
37
|
+
LocaleApp.configuration.write_initial(path)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module LocaleApp
|
2
|
+
module CLI
|
3
|
+
class Pull
|
4
|
+
include ::LocaleApp::ApiCall
|
5
|
+
|
6
|
+
def initialize(output = $stdout)
|
7
|
+
@output = output
|
8
|
+
end
|
9
|
+
|
10
|
+
def execute
|
11
|
+
@output.puts "LocaleApp Pull"
|
12
|
+
@output.puts ""
|
13
|
+
|
14
|
+
@output.puts "Fetching translations:"
|
15
|
+
api_call :translations,
|
16
|
+
:success => :update_backend,
|
17
|
+
:failure => :report_failure,
|
18
|
+
:max_connection_attempts => 3
|
19
|
+
end
|
20
|
+
|
21
|
+
def update_backend(response)
|
22
|
+
@output.puts "Success!"
|
23
|
+
@output.puts "Updating backend:"
|
24
|
+
LocaleApp.updater.update(JSON.parse(response))
|
25
|
+
@output.puts "Success!"
|
26
|
+
LocaleApp.poller.write_synchronization_data!(Time.now.to_i, Time.now.to_i)
|
27
|
+
end
|
28
|
+
|
29
|
+
def report_failure(response)
|
30
|
+
@output.puts "Failed!"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module LocaleApp
|
2
|
+
module CLI
|
3
|
+
class Push
|
4
|
+
include ::LocaleApp::ApiCall
|
5
|
+
|
6
|
+
def initialize(output = $stdout)
|
7
|
+
@output = output
|
8
|
+
end
|
9
|
+
|
10
|
+
def execute(file_path = nil)
|
11
|
+
@output.puts "LocaleApp Push"
|
12
|
+
@output.puts ""
|
13
|
+
|
14
|
+
@file_path = file_path
|
15
|
+
|
16
|
+
file = sanitize_file(file_path)
|
17
|
+
if file
|
18
|
+
@output.puts "Pushing file:"
|
19
|
+
api_call :import,
|
20
|
+
:payload => { :file => file },
|
21
|
+
:success => :report_success,
|
22
|
+
:failure => :report_failure,
|
23
|
+
:max_connection_attempts => 3
|
24
|
+
else
|
25
|
+
@output.puts "Could not load file"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def report_success(response)
|
30
|
+
@output.puts "Success!"
|
31
|
+
@output.puts ""
|
32
|
+
@output.puts "#{@file_path} queued for processing."
|
33
|
+
end
|
34
|
+
|
35
|
+
def report_failure(response)
|
36
|
+
@output.puts "Failed!"
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
def sanitize_file(file_path)
|
41
|
+
if File.exist?(file_path)
|
42
|
+
File.new(file_path)
|
43
|
+
else
|
44
|
+
nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module LocaleApp
|
2
|
+
module CLI
|
3
|
+
class Update
|
4
|
+
def initialize(output = $stdout)
|
5
|
+
@output = output
|
6
|
+
end
|
7
|
+
|
8
|
+
def execute
|
9
|
+
poller = LocaleApp::Poller.new
|
10
|
+
@output.puts("LocaleApp update: checking for translations since #{poller.updated_at}")
|
11
|
+
if poller.poll!
|
12
|
+
@output.puts "Found and updated new translations"
|
13
|
+
else
|
14
|
+
@output.puts "No new translations"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|