localeapp 0.0.7

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.
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