tr8n_core 4.0.17 → 4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +7 -9
- data/lib/tr8n/{api_client.rb → api/client.rb} +66 -30
- data/lib/tr8n/api/post_office.rb +71 -0
- data/lib/tr8n/application.rb +115 -102
- data/lib/tr8n/base.rb +1 -1
- data/lib/tr8n/cache.rb +13 -1
- data/lib/tr8n/cache_adapters/file.rb +18 -11
- data/lib/tr8n/cache_adapters/memcache.rb +5 -5
- data/lib/tr8n/cache_adapters/memory.rb +85 -0
- data/lib/tr8n/component.rb +4 -4
- data/lib/tr8n/config.rb +5 -5
- data/lib/tr8n/decorators/base.rb +9 -1
- data/lib/tr8n/decorators/default.rb +5 -1
- data/lib/tr8n/decorators/html.rb +43 -12
- data/lib/tr8n/language.rb +23 -16
- data/lib/tr8n/language_case.rb +5 -29
- data/lib/tr8n/language_case_rule.rb +8 -26
- data/lib/tr8n/language_context.rb +5 -15
- data/lib/tr8n/language_context_rule.rb +3 -18
- data/lib/tr8n/logger.rb +16 -4
- data/lib/tr8n/session.rb +71 -13
- data/lib/tr8n/source.rb +45 -11
- data/lib/tr8n/translation.rb +1 -44
- data/lib/tr8n/translation_key.rb +10 -22
- data/lib/tr8n/translator.rb +5 -13
- data/lib/tr8n/utils.rb +6 -2
- data/lib/tr8n_core.rb +3 -2
- data/lib/tr8n_core/ext/array.rb +1 -1
- data/lib/tr8n_core/ext/date.rb +1 -2
- data/lib/tr8n_core/ext/fixnum.rb +1 -1
- data/lib/tr8n_core/ext/hash.rb +1 -1
- data/lib/tr8n_core/ext/string.rb +1 -1
- data/lib/tr8n_core/ext/time.rb +1 -1
- data/lib/tr8n_core/generators/cache/base.rb +40 -18
- data/lib/tr8n_core/generators/cache/cdb.rb +1 -1
- data/lib/tr8n_core/generators/cache/file.rb +99 -21
- data/lib/tr8n_core/languages/{en-US.json → en.json} +2 -2
- data/lib/tr8n_core/version.rb +2 -2
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0baac64dd209fa38abfdbd9e9b74dc73a8bef620
|
4
|
+
data.tar.gz: 9c3aee8e89c3aad83151f5ce1ec5970d96de34e5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b8c57324b77a158776980bcbac2d4d439d150105aa2fabf3baeaf33c6f920ad04f7d064d263ed6e1f7db23cbaed62601bff4a5ea6b264f0f66b6d38aa5d7c78d
|
7
|
+
data.tar.gz: 1eb5e3b4a46aa22dbf63a99ae85755ac821e22bcb84f9e14206162d1cc447c644e79c0fe199123a12dec6e06f1c5338af4dc44e9027333030a8c63762bfc5f3d
|
data/README.md
CHANGED
@@ -13,8 +13,8 @@ Tr8n Core Library For Ruby
|
|
13
13
|
Tr8n core library for Ruby is a set of classes that provide translation functionality for any Ruby based application.
|
14
14
|
The library uses Tr8n's TML (Translation Markup Language) that allows you to encode complex language structures in simple, yet powerful forms.
|
15
15
|
|
16
|
-
The library works in conjunctions with
|
17
|
-
In order to use the library, you should sign up at
|
16
|
+
The library works in conjunctions with TranslationExchange.com service that provides machine and human translations for your application.
|
17
|
+
In order to use the library, you should sign up at TranslationExchange.com, create a new application and copy the application key and secret.
|
18
18
|
|
19
19
|
|
20
20
|
Rails Integration
|
@@ -38,7 +38,7 @@ gem install tr8n_core
|
|
38
38
|
Registering Your App
|
39
39
|
===================================
|
40
40
|
|
41
|
-
Before you can proceed with the integration, please register with
|
41
|
+
Before you can proceed with the integration, please register with http://translationexchange.com and create a new application.
|
42
42
|
|
43
43
|
At the end of the registration process you will be given a key and a secret. You will need to enter them in the initialization function of the Tr8n SDK.
|
44
44
|
|
@@ -208,23 +208,21 @@ irb(main)> russian.translate('This is a new phrase without translations')
|
|
208
208
|
Links
|
209
209
|
==================
|
210
210
|
|
211
|
-
* Register on TranslationExchange.com:
|
211
|
+
* Register on TranslationExchange.com: http://translationexchange.com
|
212
212
|
|
213
|
-
* Read TranslationExchange's documentation: http://
|
214
|
-
|
215
|
-
* Visit TranslationExchange's blog: http://blog.tr8nhub.com
|
213
|
+
* Read TranslationExchange's documentation: http://translationexchange.com/docs
|
216
214
|
|
217
215
|
* Follow TranslationExchange on Twitter: https://twitter.com/translationx
|
218
216
|
|
219
217
|
* Connect with TranslationExchange on Facebook: https://www.facebook.com/translationexchange
|
220
218
|
|
221
|
-
* If you have any questions or suggestions, contact us:
|
219
|
+
* If you have any questions or suggestions, contact us: feedback@translationexchange.com
|
222
220
|
|
223
221
|
|
224
222
|
Copyright and license
|
225
223
|
==================
|
226
224
|
|
227
|
-
Copyright (c)
|
225
|
+
Copyright (c) 2015 Translation Exchange, Inc
|
228
226
|
|
229
227
|
Permission is hereby granted, free of charge, to any person obtaining
|
230
228
|
a copy of this software and associated documentation files (the
|
@@ -32,38 +32,39 @@
|
|
32
32
|
|
33
33
|
require 'faraday'
|
34
34
|
|
35
|
-
class Tr8n::
|
36
|
-
API_HOST = 'https://translationexchange.com'
|
37
|
-
API_PATH = '/
|
35
|
+
class Tr8n::Api::Client < Tr8n::Base
|
36
|
+
API_HOST = 'https://api.translationexchange.com'
|
37
|
+
API_PATH = '/v1'
|
38
38
|
|
39
39
|
attributes :application
|
40
40
|
|
41
41
|
def access_token
|
42
42
|
application.access_token ||= begin
|
43
|
-
|
44
|
-
{
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
},
|
49
|
-
|
50
|
-
:host => application.host
|
51
|
-
}
|
52
|
-
)
|
43
|
+
Tr8n.cache.fetch("#{application.key}/access_token") do
|
44
|
+
api('oauth/token', {
|
45
|
+
:client_id => application.key,
|
46
|
+
:client_secret => application.secret,
|
47
|
+
:grant_type => :client_credentials
|
48
|
+
}, {:method => :post})
|
49
|
+
end
|
53
50
|
end
|
54
|
-
application.access_token[
|
51
|
+
application.access_token['access_token']
|
52
|
+
end
|
53
|
+
|
54
|
+
def results(path, params = {}, opts = {})
|
55
|
+
get(path, params, opts)['results']
|
55
56
|
end
|
56
57
|
|
57
58
|
def get(path, params = {}, opts = {})
|
58
|
-
api(path, params
|
59
|
+
api(path, params, opts.merge(:method => :get))
|
59
60
|
end
|
60
61
|
|
61
62
|
def post(path, params = {}, opts = {})
|
62
|
-
api(path, params
|
63
|
+
api(path, params, opts.merge(:method => :post))
|
63
64
|
end
|
64
65
|
|
65
66
|
def self.error?(data)
|
66
|
-
not data[
|
67
|
+
not data['error'].nil?
|
67
68
|
end
|
68
69
|
|
69
70
|
def host
|
@@ -79,9 +80,13 @@ class Tr8n::ApiClient < Tr8n::Base
|
|
79
80
|
end
|
80
81
|
|
81
82
|
def api(path, params = {}, opts = {})
|
83
|
+
if Tr8n.session.inline_mode?
|
84
|
+
return process_response(execute_request(path, params, opts), opts)
|
85
|
+
end
|
86
|
+
|
82
87
|
if opts[:method] == :get and opts[:cache_key]
|
83
88
|
data = Tr8n.cache.fetch(opts[:cache_key]) do
|
84
|
-
execute_request(path, params, opts)
|
89
|
+
Tr8n.cache.read_only? ? {} : execute_request(path, params, opts)
|
85
90
|
end
|
86
91
|
process_response(data, opts)
|
87
92
|
else
|
@@ -89,19 +94,49 @@ class Tr8n::ApiClient < Tr8n::Base
|
|
89
94
|
end
|
90
95
|
end
|
91
96
|
|
97
|
+
def paginate(path, params = {}, opts = {})
|
98
|
+
data = get(path, params, opts.merge({'raw' => true}))
|
99
|
+
|
100
|
+
while data
|
101
|
+
if data['results'].is_a?(Array)
|
102
|
+
data['results'].each do |result|
|
103
|
+
yield(result)
|
104
|
+
end
|
105
|
+
else
|
106
|
+
yield(data['results'])
|
107
|
+
end
|
108
|
+
|
109
|
+
if data['pagination'] and data['pagination']['links']['next']
|
110
|
+
data = get(data['pagination']['links']['next'], {}, opts.merge({'raw' => true}))
|
111
|
+
else
|
112
|
+
data = nil
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def prepare_api_path(path)
|
118
|
+
return path if path.index('oauth')
|
119
|
+
return path if path.match(/^https?:\/\//)
|
120
|
+
"#{API_PATH}#{path[0] == '/' ? '' : '/'}#{path}"
|
121
|
+
end
|
122
|
+
|
92
123
|
def execute_request(path, params = {}, opts = {})
|
93
124
|
response = nil
|
94
125
|
error = nil
|
95
126
|
|
96
|
-
|
127
|
+
# oauth path is separate from versioned APIs
|
128
|
+
path = prepare_api_path(path)
|
129
|
+
params = params.merge(:access_token => access_token) unless path.index('oauth')
|
130
|
+
|
131
|
+
Tr8n.logger.trace_api_call(path, params, opts) do
|
97
132
|
begin
|
98
133
|
if opts[:method] == :post
|
99
|
-
response = connection.post(
|
134
|
+
response = connection.post(path, params)
|
100
135
|
else
|
101
|
-
response = connection.get(
|
136
|
+
response = connection.get(path, params)
|
102
137
|
end
|
103
138
|
rescue Exception => ex
|
104
|
-
Tr8n.logger.error("Failed to execute request: #{ex}")
|
139
|
+
Tr8n.logger.error("Failed to execute request: #{ex.message[0..255]}")
|
105
140
|
error = ex
|
106
141
|
nil
|
107
142
|
end
|
@@ -115,11 +150,11 @@ class Tr8n::ApiClient < Tr8n::Base
|
|
115
150
|
begin
|
116
151
|
data = JSON.parse(response.body)
|
117
152
|
rescue Exception => ex
|
118
|
-
raise Tr8n::Exception.new("
|
153
|
+
raise Tr8n::Exception.new("Failed to parse response: #{ex.message[0..255]}")
|
119
154
|
end
|
120
155
|
|
121
|
-
|
122
|
-
raise Tr8n::Exception.new("Error: #{data[
|
156
|
+
if data.is_a?(Hash) and not data['error'].nil?
|
157
|
+
raise Tr8n::Exception.new("Error: #{data['error']}")
|
123
158
|
end
|
124
159
|
|
125
160
|
data
|
@@ -131,18 +166,19 @@ class Tr8n::ApiClient < Tr8n::Base
|
|
131
166
|
end
|
132
167
|
|
133
168
|
def process_response(data, opts)
|
134
|
-
if
|
135
|
-
|
136
|
-
|
169
|
+
return data if opts['raw']
|
170
|
+
|
171
|
+
if data.is_a?(Hash) and data['results']
|
172
|
+
#Tr8n.logger.debug("received #{data['results'].size} result(s)")
|
173
|
+
return data['results'] unless object_class(opts)
|
137
174
|
objects = []
|
138
|
-
data[
|
175
|
+
data['results'].each do |data|
|
139
176
|
objects << object_class(opts).new(data.merge(opts[:attributes] || {}))
|
140
177
|
end
|
141
178
|
return objects
|
142
179
|
end
|
143
180
|
|
144
181
|
return data unless object_class(opts)
|
145
|
-
#Tr8n.logger.debug("constructing #{object_class(opts).name}")
|
146
182
|
object_class(opts).new(data.merge(opts[:attributes] || {}))
|
147
183
|
end
|
148
184
|
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#--
|
3
|
+
# Copyright (c) 2014 Michael Berkovich, TranslationExchange.com
|
4
|
+
#
|
5
|
+
# _______ _ _ _ ______ _
|
6
|
+
# |__ __| | | | | (_) | ____| | |
|
7
|
+
# | |_ __ __ _ _ __ ___| | __ _| |_ _ ___ _ __ | |__ __ _____| |__ __ _ _ __ __ _ ___
|
8
|
+
# | | '__/ _` | '_ \/ __| |/ _` | __| |/ _ \| '_ \| __| \ \/ / __| '_ \ / _` | '_ \ / _` |/ _ \
|
9
|
+
# | | | | (_| | | | \__ \ | (_| | |_| | (_) | | | | |____ > < (__| | | | (_| | | | | (_| | __/
|
10
|
+
# |_|_| \__,_|_| |_|___/_|\__,_|\__|_|\___/|_| |_|______/_/\_\___|_| |_|\__,_|_| |_|\__, |\___|
|
11
|
+
# __/ |
|
12
|
+
# |___/
|
13
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
14
|
+
# a copy of this software and associated documentation files (the
|
15
|
+
# "Software"), to deal in the Software without restriction, including
|
16
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
17
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
18
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
19
|
+
# the following conditions:
|
20
|
+
#
|
21
|
+
# The above copyright notice and this permission notice shall be
|
22
|
+
# included in all copies or substantial portions of the Software.
|
23
|
+
#
|
24
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
25
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
26
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
27
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
28
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
29
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
30
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
31
|
+
#++
|
32
|
+
|
33
|
+
class Tr8n::Api::PostOffice < Tr8n::Api::Client
|
34
|
+
POST_OFFICE_HOST = 'https://postoffice.translationexchange.com'
|
35
|
+
POST_OFFICE_API_VERSION = 'v1'
|
36
|
+
|
37
|
+
attributes :application
|
38
|
+
|
39
|
+
def templates
|
40
|
+
api('templates', {
|
41
|
+
:access_token => access_token
|
42
|
+
})
|
43
|
+
end
|
44
|
+
|
45
|
+
def channels
|
46
|
+
api('channels', {
|
47
|
+
:access_token => access_token
|
48
|
+
})
|
49
|
+
end
|
50
|
+
|
51
|
+
def deliver(template, to, tokens = {}, options = {})
|
52
|
+
api("templates/#{template}/deliver", {
|
53
|
+
:access_token => access_token,
|
54
|
+
:tokens => tokens,
|
55
|
+
:to => to,
|
56
|
+
:via => options[:via],
|
57
|
+
:from => options[:from],
|
58
|
+
:locale => options[:locale],
|
59
|
+
:realtime => options[:realtime]
|
60
|
+
}, options.merge(:method => :post))
|
61
|
+
end
|
62
|
+
|
63
|
+
def host
|
64
|
+
application.tools['postoffice'] || POST_OFFICE_HOST
|
65
|
+
end
|
66
|
+
|
67
|
+
def prepare_api_path(path)
|
68
|
+
"/api/#{POST_OFFICE_API_VERSION}#{path.first == '/' ? '' : '/'}#{path}"
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
data/lib/tr8n/application.rb
CHANGED
@@ -33,11 +33,19 @@
|
|
33
33
|
require 'faraday'
|
34
34
|
|
35
35
|
class Tr8n::Application < Tr8n::Base
|
36
|
-
attributes :host, :key, :secret, :access_token, :name, :description, :threshold, :default_locale, :default_level
|
37
|
-
has_many :features, :languages, :featured_locales, :sources, :components, :tokens, :css, :shortcuts
|
36
|
+
attributes :host, :id, :key, :secret, :access_token, :name, :description, :threshold, :default_locale, :default_level, :tools
|
37
|
+
has_many :features, :languages, :featured_locales, :sources, :components, :tokens, :css, :shortcuts, :translations
|
38
|
+
|
39
|
+
def self.cache_key
|
40
|
+
'application'
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.translations_cache_key(locale)
|
44
|
+
"#{locale}/translations"
|
45
|
+
end
|
38
46
|
|
39
47
|
def fetch
|
40
|
-
update_attributes(api_client.get(
|
48
|
+
update_attributes(api_client.get('applications/current', {:definition => true}, {:cache_key => self.class.cache_key}))
|
41
49
|
rescue Tr8n::Exception => ex
|
42
50
|
Tr8n.logger.error("Failed to load application: #{ex}")
|
43
51
|
self
|
@@ -46,49 +54,26 @@ class Tr8n::Application < Tr8n::Base
|
|
46
54
|
def update_attributes(attrs)
|
47
55
|
super
|
48
56
|
|
49
|
-
self.host ||= "https://translationexchange.com"
|
50
|
-
|
51
57
|
self.attributes[:languages] = []
|
52
58
|
if hash_value(attrs, :languages)
|
53
59
|
self.attributes[:languages] = hash_value(attrs, :languages).collect{ |l| Tr8n::Language.new(l.merge(:application => self)) }
|
54
60
|
end
|
55
61
|
|
56
|
-
self.attributes[:sources] = []
|
57
|
-
if hash_value(attrs, :sources)
|
58
|
-
self.attributes[:sources] = hash_value(attrs, :sources).collect{ |l| Tr8n::Source.new(l.merge(:application => self)) }
|
59
|
-
end
|
60
|
-
|
61
|
-
self.attributes[:components] = []
|
62
|
-
if hash_value(attrs, :components)
|
63
|
-
self.attributes[:components] = hash_value(attrs, :components).collect{ |l| Tr8n::Component.new(l.merge(:application => self)) }
|
64
|
-
end
|
65
|
-
|
66
|
-
@translation_keys = {}
|
67
|
-
@sources_by_key = {}
|
68
|
-
@components_by_key = {}
|
69
|
-
|
70
|
-
@languages_by_locale = nil
|
71
|
-
@missing_keys_by_sources = nil
|
72
|
-
|
73
62
|
self
|
74
63
|
end
|
75
64
|
|
76
65
|
def language(locale = nil)
|
66
|
+
locale = nil if locale.strip == ''
|
77
67
|
locale ||= default_locale || Tr8n.config.default_locale
|
78
68
|
@languages_by_locale ||= {}
|
79
|
-
|
80
|
-
unless Tr8n.session.current_translator and Tr8n.session.current_translator.inline?
|
81
|
-
cache_key = "#{locale}/language"
|
82
|
-
end
|
83
|
-
|
84
69
|
@languages_by_locale[locale] ||= api_client.get(
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
70
|
+
"languages/#{locale}",
|
71
|
+
{:definition => true},
|
72
|
+
{
|
73
|
+
:class => Tr8n::Language,
|
74
|
+
:attributes => {:locale => locale, :application => self},
|
75
|
+
:cache_key => Tr8n::Language.cache_key(locale)
|
76
|
+
}
|
92
77
|
)
|
93
78
|
rescue Tr8n::Exception => e
|
94
79
|
Tr8n.logger.error(e)
|
@@ -110,76 +95,34 @@ class Tr8n::Application < Tr8n::Base
|
|
110
95
|
@locales ||= languages.collect{|lang| lang.locale}
|
111
96
|
end
|
112
97
|
|
113
|
-
def
|
114
|
-
|
98
|
+
def tools
|
99
|
+
@attributes[:tools] || {}
|
115
100
|
end
|
116
101
|
|
117
|
-
def
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
unless Tr8n.session.current_translator and Tr8n.session.current_translator.inline?
|
122
|
-
cache_key = Tr8n::Source.cache_key(key, locale)
|
123
|
-
end
|
102
|
+
def url_for(path)
|
103
|
+
"#{tools['assets']}#{path}"
|
104
|
+
end
|
124
105
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
:cache_key => cache_key
|
132
|
-
}
|
133
|
-
)
|
134
|
-
rescue
|
135
|
-
@sources_by_key[key] = Tr8n::Source.new(:source => key)
|
106
|
+
def source(source, locale)
|
107
|
+
self.sources ||= {}
|
108
|
+
self.sources[source] ||= Tr8n::Source.new(
|
109
|
+
:application => self,
|
110
|
+
:source => source
|
111
|
+
).fetch_translations(locale)
|
136
112
|
end
|
137
113
|
|
138
114
|
def component(key, register = true)
|
139
115
|
key = key.key if key.is_a?(Tr8n::Component)
|
140
116
|
|
141
|
-
return
|
117
|
+
return self.components[key] if self.components[key]
|
142
118
|
return nil unless register
|
143
119
|
|
144
|
-
|
145
|
-
end
|
146
|
-
|
147
|
-
def translation_keys
|
148
|
-
@translation_keys ||= {}
|
149
|
-
end
|
150
|
-
|
151
|
-
def translation_key(key)
|
152
|
-
translation_keys[key]
|
153
|
-
end
|
154
|
-
|
155
|
-
def cache_translation_key(tkey)
|
156
|
-
cached_key = translation_key(tkey.key)
|
157
|
-
|
158
|
-
if cached_key
|
159
|
-
# move translations from tkey to the cached key
|
160
|
-
tkey.translations.each do |locale, translations|
|
161
|
-
cached_key.set_language_translations(language(locale), translations)
|
162
|
-
end
|
163
|
-
return cached_key
|
164
|
-
end
|
165
|
-
|
166
|
-
tkey.set_application(self)
|
167
|
-
@translation_keys[tkey.key] = tkey
|
168
|
-
end
|
169
|
-
|
170
|
-
def cache_translation_keys(tkeys)
|
171
|
-
tkeys.each do |tkey|
|
172
|
-
cache_translation_key(tkey)
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
def reset_translation_cache
|
177
|
-
@translation_keys = {}
|
178
|
-
@sources_by_key = {}
|
179
|
-
@components_by_key = {}
|
120
|
+
self.components[key] ||= api_client.post('components/register', {:component => key}, {:class => Tr8n::Component, :attributes => {:application => self}})
|
180
121
|
end
|
181
122
|
|
182
123
|
def register_missing_key(source_key, tkey)
|
124
|
+
return if Tr8n.cache.read_only? and not Tr8n.session.inline_mode?
|
125
|
+
|
183
126
|
@missing_keys_by_sources ||= {}
|
184
127
|
@missing_keys_by_sources[source_key] ||= {}
|
185
128
|
@missing_keys_by_sources[source_key][tkey.key] ||= tkey
|
@@ -188,12 +131,14 @@ class Tr8n::Application < Tr8n::Base
|
|
188
131
|
|
189
132
|
def register_keys(keys)
|
190
133
|
params = []
|
191
|
-
keys.each do |
|
134
|
+
keys.each do |source_key, keys|
|
192
135
|
next unless keys.values.any?
|
193
|
-
|
136
|
+
source = Tr8n::Source.new(:source => source_key, :application => self)
|
137
|
+
params << {:source => source_key, :keys => keys.values.collect{|tkey| tkey.to_hash(:label, :description, :locale, :level)}}
|
138
|
+
source.reset_cache
|
194
139
|
end
|
195
140
|
|
196
|
-
api_client.post('
|
141
|
+
api_client.post('sources/register_keys', {:source_keys => params.to_json})
|
197
142
|
rescue Tr8n::Exception => e
|
198
143
|
Tr8n.logger.error('Failed to register missing translation keys...')
|
199
144
|
Tr8n.logger.error(e)
|
@@ -208,14 +153,82 @@ class Tr8n::Application < Tr8n::Base
|
|
208
153
|
|
209
154
|
def featured_languages
|
210
155
|
@featured_languages ||= begin
|
211
|
-
locales = api_client.get(
|
212
|
-
# use app languages, there is no need for rules for this call
|
156
|
+
locales = api_client.get('applications/current/featured_locales', {}, {:cache_key => 'featured_locales'})
|
213
157
|
(locales.nil? or locales.empty?) ? [] : languages.select{|l| locales.include?(l.locale)}
|
214
158
|
end
|
159
|
+
rescue
|
160
|
+
[]
|
215
161
|
end
|
216
162
|
|
217
163
|
def translators
|
218
|
-
@translators ||= api_client.get(
|
164
|
+
@translators ||= api_client.get('applications/current/translators', {}, {:class => Tr8n::Translator, :attributes => {:application => self}})
|
165
|
+
rescue
|
166
|
+
[]
|
167
|
+
end
|
168
|
+
|
169
|
+
def reset_translation_cache
|
170
|
+
self.sources = {}
|
171
|
+
self.translations = {}
|
172
|
+
@languages_by_locale = nil
|
173
|
+
@missing_keys_by_sources = nil
|
174
|
+
end
|
175
|
+
|
176
|
+
def fetch_translations(locale)
|
177
|
+
self.translations ||= {}
|
178
|
+
self.translations[locale] ||= begin
|
179
|
+
results = Tr8n.cache.fetch(Tr8n::Application.translations_cache_key(locale)) do
|
180
|
+
data = {}
|
181
|
+
unless Tr8n.cache.read_only?
|
182
|
+
api_client.paginate('applications/current/translations', :per_page => 1000) do |translations|
|
183
|
+
data.merge!(translations)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
data
|
187
|
+
end
|
188
|
+
|
189
|
+
translations_by_key = {}
|
190
|
+
results.each do |key, data|
|
191
|
+
translations_data = data.is_a?(Hash) ? data['translations'] : data
|
192
|
+
translations_by_key[key] = translations_data.collect do |t|
|
193
|
+
Tr8n::Translation.new(
|
194
|
+
:locale => t['locale'] || locale,
|
195
|
+
:label => t['label'],
|
196
|
+
:context => t['context']
|
197
|
+
)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
translations_by_key
|
201
|
+
end
|
202
|
+
rescue Tr8n::Exception => ex
|
203
|
+
{}
|
204
|
+
end
|
205
|
+
|
206
|
+
def cache_translations(locale, key, new_translations)
|
207
|
+
self.translations ||= {}
|
208
|
+
self.translations[locale] ||= {}
|
209
|
+
self.translations[locale][key] = new_translations.collect do |t|
|
210
|
+
Tr8n::Translation.new(
|
211
|
+
:locale => t['locale'] || locale,
|
212
|
+
:label => t['label'],
|
213
|
+
:context => t['context']
|
214
|
+
)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def cached_translations(locale, key)
|
219
|
+
return unless self.translations and self.translations[locale]
|
220
|
+
self.translations[locale][key]
|
221
|
+
end
|
222
|
+
|
223
|
+
def debug_translations
|
224
|
+
return 'no translations' unless self.translations
|
225
|
+
self.translations.each do |locale, keys|
|
226
|
+
pp [locale, keys.collect{|key, translations|
|
227
|
+
[key, translations.collect{|t|
|
228
|
+
[t.label, t.context]
|
229
|
+
}]
|
230
|
+
}]
|
231
|
+
end
|
219
232
|
end
|
220
233
|
|
221
234
|
def default_decoration_token(token)
|
@@ -230,12 +243,12 @@ class Tr8n::Application < Tr8n::Base
|
|
230
243
|
hash_value(features, key.to_s)
|
231
244
|
end
|
232
245
|
|
233
|
-
#######################################################################################################
|
234
|
-
## API Methods
|
235
|
-
#######################################################################################################
|
236
|
-
|
237
246
|
def api_client
|
238
|
-
@api_client ||= Tr8n::
|
247
|
+
@api_client ||= Tr8n::Api::Client.new(:application => self)
|
248
|
+
end
|
249
|
+
|
250
|
+
def postoffice
|
251
|
+
@postoffice ||= Tr8n::Api::PostOffice.new(:application => self)
|
239
252
|
end
|
240
253
|
|
241
254
|
end
|