tr8n_core 4.0.17 → 4.2
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.
- 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
|