localeapp 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/.autotest +4 -0
  2. data/.gitignore +7 -0
  3. data/.rspec +2 -0
  4. data/.rvmrc +1 -0
  5. data/.travis.yml +7 -0
  6. data/Gemfile +2 -0
  7. data/README.textile +147 -0
  8. data/Rakefile +11 -0
  9. data/bin/localeapp +61 -0
  10. data/cucumber.yml +8 -0
  11. data/features/localeapp_binary.feature +116 -0
  12. data/features/step_definitions/cli_steps.rb +27 -0
  13. data/features/support/env.rb +21 -0
  14. data/features/support/hooks.rb +3 -0
  15. data/init.rb +1 -0
  16. data/lib/locale_app/api_call.rb +9 -0
  17. data/lib/locale_app/api_caller.rb +77 -0
  18. data/lib/locale_app/cli/install.rb +41 -0
  19. data/lib/locale_app/cli/pull.rb +34 -0
  20. data/lib/locale_app/cli/push.rb +49 -0
  21. data/lib/locale_app/cli/update.rb +19 -0
  22. data/lib/locale_app/configuration.rb +93 -0
  23. data/lib/locale_app/exception_handler.rb +21 -0
  24. data/lib/locale_app/key_checker.rb +43 -0
  25. data/lib/locale_app/missing_translations.rb +36 -0
  26. data/lib/locale_app/poller.rb +61 -0
  27. data/lib/locale_app/rails/2_3_translation_helper_monkeypatch.rb +36 -0
  28. data/lib/locale_app/rails/controller.rb +34 -0
  29. data/lib/locale_app/rails/flatten.rb +113 -0
  30. data/lib/locale_app/rails.rb +53 -0
  31. data/lib/locale_app/routes.rb +80 -0
  32. data/lib/locale_app/sender.rb +49 -0
  33. data/lib/locale_app/tasks/locale_app.rake +20 -0
  34. data/lib/locale_app/updater.rb +63 -0
  35. data/lib/locale_app/version.rb +3 -0
  36. data/lib/locale_app.rb +98 -0
  37. data/lib/localeapp.rb +1 -0
  38. data/localeapp.gemspec +35 -0
  39. data/run_ci +5 -0
  40. data/spec/fixtures/en.yml +6 -0
  41. data/spec/fixtures/es.yml +6 -0
  42. data/spec/locale_app/api_call_spec.rb +15 -0
  43. data/spec/locale_app/api_caller_spec.rb +157 -0
  44. data/spec/locale_app/cli/install_spec.rb +42 -0
  45. data/spec/locale_app/cli/pull_spec.rb +45 -0
  46. data/spec/locale_app/cli/push_spec.rb +30 -0
  47. data/spec/locale_app/cli/update_spec.rb +18 -0
  48. data/spec/locale_app/configuration_spec.rb +119 -0
  49. data/spec/locale_app/exception_handler_spec.rb +21 -0
  50. data/spec/locale_app/key_checker_spec.rb +19 -0
  51. data/spec/locale_app/missing_translations_spec.rb +28 -0
  52. data/spec/locale_app/poller_spec.rb +61 -0
  53. data/spec/locale_app/rails/controller_spec.rb +117 -0
  54. data/spec/locale_app/routes_spec.rb +134 -0
  55. data/spec/locale_app/sender_spec.rb +49 -0
  56. data/spec/locale_app/updater_spec.rb +89 -0
  57. data/spec/spec_helper.rb +24 -0
  58. data/spec/support/locale_app_integration_data.rb +33 -0
  59. data/spec/support/locale_app_synchronization_data.rb +21 -0
  60. metadata +300 -0
data/.autotest ADDED
@@ -0,0 +1,4 @@
1
+ Autotest.add_hook :initialize do |at|
2
+ at.add_exception %r{^\./\.git/}
3
+ at.add_exception %r{^\./tmp/}
4
+ end
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
4
+ Gemfile.lock
5
+ .yardoc/*
6
+ doc/*
7
+ tmp/*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ -I ./lib
2
+ -I ./spec
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm ruby-1.9.2@locale_app
data/.travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ rvm:
2
+ - 1.8.7
3
+ - 1.9.2
4
+ branches:
5
+ only:
6
+ - master
7
+ - develop
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source :rubyforge
2
+ gemspec
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
@@ -0,0 +1,11 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new
6
+
7
+ require 'cucumber/rake/task'
8
+ Cucumber::Rake::Task.new(:features)
9
+
10
+ task :default => [:spec, :features]
11
+
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
+
@@ -0,0 +1,3 @@
1
+ Before do
2
+ ENV['FAKE_WEB_DURING_CUCUMBER_RUN'] = '1'
3
+ end
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'locale_app'
@@ -0,0 +1,9 @@
1
+ module LocaleApp
2
+ module ApiCall
3
+ # creates an object to perform the call
4
+ def api_call(endpoint, options = {})
5
+ api_caller = LocaleApp::ApiCaller.new(endpoint, options)
6
+ api_caller.call(self)
7
+ end
8
+ end
9
+ end
@@ -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