lit 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/lit/api/v1/localizations_controller.rb +9 -17
- data/app/models/lit/incomming_localization.rb +13 -27
- data/app/models/lit/localization.rb +6 -14
- data/app/services/remote_interactor_service.rb +2 -1
- data/app/services/synchronize_source_service.rb +4 -8
- data/lib/lit/adapters/redis_storage.rb +4 -3
- data/lib/lit/cache.rb +23 -2
- data/lib/lit/middleware.rb +29 -0
- data/lib/lit/rails.rb +1 -0
- data/lib/lit/railtie.rb +6 -7
- data/lib/lit/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a051d3c6a1e4a1db24c3818aae84d51f42df73a907c23b787f6f5b3c40f798aa
|
4
|
+
data.tar.gz: e080032aebf0428fdfd9ca2bc3a0c75964774b774c1caed2329cbb337d70cd9e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 679930cd3c4ee3d0c506dce93b471b8df4edbaac0772ef05d0a9caac3878d284d467599234bed06f77876af6dff2a25bded7f8a1f223bfbabfde2ddfe8ab7ed1
|
7
|
+
data.tar.gz: 5c6908710836b9f2c11a5da6933e616883e8fdb8ff497908c5cd2ad37c4279ab2b558fb46b1b87f07ae35adceb11143e093ac82393244cf9b6cf440ad4d79a84
|
@@ -2,34 +2,26 @@ module Lit
|
|
2
2
|
class Api::V1::LocalizationsController < Api::V1::BaseController
|
3
3
|
def index
|
4
4
|
@localizations = fetch_localizations
|
5
|
-
render json:
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
]
|
12
|
-
)
|
5
|
+
render json:
|
6
|
+
@localizations.as_json(
|
7
|
+
root: false,
|
8
|
+
only: %i[id localization_key_id locale_id],
|
9
|
+
methods: %i[value localization_key_str locale_str localization_key_is_deleted],
|
10
|
+
)
|
13
11
|
end
|
14
12
|
|
15
13
|
def last_change
|
16
14
|
@localization = Localization.order(updated_at: :desc).first
|
17
|
-
render json: @localization.as_json(
|
18
|
-
root: false, only: [], methods: [:last_change]
|
19
|
-
)
|
15
|
+
render json: @localization.as_json(root: false, only: [], methods: [:last_change])
|
20
16
|
end
|
21
17
|
|
22
18
|
private
|
23
19
|
|
24
20
|
def fetch_localizations
|
25
|
-
scope = Localization.includes(
|
26
|
-
:locale,
|
27
|
-
:localization_key
|
28
|
-
)
|
21
|
+
scope = Localization.includes(:locale, :localization_key)
|
29
22
|
|
30
23
|
if params[:after].present?
|
31
|
-
after_date = Time.parse("#{params[:after]} #{Time.zone.name}")
|
32
|
-
.in_time_zone
|
24
|
+
after_date = Time.parse("#{params[:after]} #{Time.zone.name}").in_time_zone
|
33
25
|
scope.after(after_date).to_a
|
34
26
|
else
|
35
27
|
scope.all
|
@@ -36,39 +36,27 @@ module Lit
|
|
36
36
|
def duplicated?(val)
|
37
37
|
set_localization
|
38
38
|
return false if localization_has_changed?
|
39
|
-
|
40
|
-
|
41
|
-
if localization.is_changed? && !translated_value.nil?
|
42
|
-
translated_value == val
|
43
|
-
else
|
44
|
-
localization.read_attribute_before_type_cast('default_value') == val
|
45
|
-
end
|
39
|
+
|
40
|
+
localization.translation == val
|
46
41
|
end
|
47
42
|
|
48
43
|
private
|
49
44
|
|
50
45
|
def set_localization
|
51
46
|
return if locale.blank? || localization_key.blank?
|
52
|
-
self.localization = localization_key.localizations
|
53
|
-
.find_by(locale_id: locale_id)
|
47
|
+
self.localization = localization_key.localizations.find_by(locale_id: locale_id)
|
54
48
|
end
|
55
49
|
|
56
50
|
def localization_has_changed?
|
57
|
-
localization.blank? ||
|
58
|
-
localization.is_deleted != localization_key_is_deleted
|
51
|
+
localization.blank? || localization.is_deleted != localization_key_is_deleted
|
59
52
|
end
|
60
53
|
|
61
54
|
def update_existing_localization_data
|
62
|
-
localization.update!(
|
63
|
-
translated_value: translated_value,
|
64
|
-
is_changed: true
|
65
|
-
)
|
55
|
+
localization.update!(translated_value: translated_value, is_changed: true)
|
66
56
|
end
|
67
57
|
|
68
58
|
def update_existing_localization_key_data
|
69
|
-
localization_key.update!(
|
70
|
-
is_deleted: localization_key_is_deleted
|
71
|
-
)
|
59
|
+
localization_key.update!(is_deleted: localization_key_is_deleted)
|
72
60
|
end
|
73
61
|
|
74
62
|
def assign_new_localization_data
|
@@ -83,25 +71,23 @@ module Lit
|
|
83
71
|
|
84
72
|
def assign_new_localization_key
|
85
73
|
self.localization_key =
|
86
|
-
Lit::LocalizationKey.where(
|
87
|
-
|
88
|
-
is_deleted: localization_key_is_deleted
|
89
|
-
).first_or_create!
|
74
|
+
Lit::LocalizationKey.where(localization_key: localization_key_str, is_deleted: localization_key_is_deleted)
|
75
|
+
.first_or_create!
|
90
76
|
end
|
91
77
|
|
92
78
|
def assign_new_localization
|
93
79
|
self.localization =
|
94
|
-
Lit::Localization
|
95
|
-
|
96
|
-
|
80
|
+
Lit::Localization
|
81
|
+
.where(localization_key_id: localization_key.id)
|
82
|
+
.where(locale_id: locale.id)
|
83
|
+
.first_or_initialize
|
97
84
|
localization.translated_value = translated_value
|
98
85
|
localization.is_changed = true
|
99
86
|
localization.save!
|
100
87
|
end
|
101
88
|
|
102
89
|
def update_cache
|
103
|
-
Lit.init.cache.update_cache localization.full_key,
|
104
|
-
localization.translation
|
90
|
+
Lit.init.cache.update_cache localization.full_key, localization.translation
|
105
91
|
end
|
106
92
|
end
|
107
93
|
end
|
@@ -6,19 +6,14 @@ module Lit
|
|
6
6
|
## SCOPES
|
7
7
|
scope :changed, -> { where is_changed: true }
|
8
8
|
scope :not_changed, -> { where is_changed: false }
|
9
|
+
|
9
10
|
# @HACK: dirty, find a way to round date to full second
|
10
|
-
scope :after, lambda { |dt|
|
11
|
-
|
12
|
-
.where(is_changed: true)
|
13
|
-
}
|
14
|
-
scope :active, lambda {
|
15
|
-
joins(:localization_key)
|
16
|
-
.where(Lit::LocalizationKey.table_name => { is_deleted: false })
|
17
|
-
}
|
11
|
+
scope :after, lambda { |dt| where('updated_at >= ?', dt + 1.second).where(is_changed: true) }
|
12
|
+
scope :active, lambda { joins(:localization_key).where(Lit::LocalizationKey.table_name => { is_deleted: false }) }
|
18
13
|
|
19
14
|
## ASSOCIATIONS
|
20
|
-
belongs_to :locale
|
21
|
-
belongs_to :localization_key, touch: true
|
15
|
+
belongs_to :locale, required: true
|
16
|
+
belongs_to :localization_key, touch: true, required: true
|
22
17
|
has_many :localization_versions, dependent: :destroy
|
23
18
|
has_many :versions, class_name: '::Lit::LocalizationVersion'
|
24
19
|
|
@@ -31,9 +26,7 @@ module Lit
|
|
31
26
|
## ACCESSORS
|
32
27
|
attr_accessor :full_key_str
|
33
28
|
|
34
|
-
unless defined?(::ActionController::StrongParameters)
|
35
|
-
attr_accessible :translated_value, :locale_id
|
36
|
-
end
|
29
|
+
attr_accessible :translated_value, :locale_id unless defined?(::ActionController::StrongParameters)
|
37
30
|
|
38
31
|
## BEFORE & AFTER
|
39
32
|
with_options if: :translated_value_changed? do |o|
|
@@ -94,6 +87,5 @@ module Lit
|
|
94
87
|
translated_value = translated_value_was || default_value
|
95
88
|
localization_versions.new(translated_value: translated_value)
|
96
89
|
end
|
97
|
-
|
98
90
|
end
|
99
91
|
end
|
@@ -27,7 +27,7 @@ class RemoteInteractorService
|
|
27
27
|
|
28
28
|
def initialize_request(uri)
|
29
29
|
req = Net::HTTP::Get.new(uri.request_uri)
|
30
|
-
req.add_field('Authorization',
|
30
|
+
req.add_field('Authorization', "Token token=\"#{@source.api_key}\"")
|
31
31
|
req
|
32
32
|
end
|
33
33
|
|
@@ -41,6 +41,7 @@ class RemoteInteractorService
|
|
41
41
|
def perform_request(connection, request)
|
42
42
|
res = connection.start { |http| http.request(request) }
|
43
43
|
return res unless res.is_a?(Net::HTTPSuccess)
|
44
|
+
|
44
45
|
JSON.parse(res.body)
|
45
46
|
end
|
46
47
|
end
|
@@ -12,8 +12,7 @@ class SynchronizeSourceService
|
|
12
12
|
|
13
13
|
def synchronize_localizations
|
14
14
|
after_date = @source.last_updated_at&.to_s(:db)
|
15
|
-
result = interactor.send_request Lit::Source::LOCALIZATIONS_PATH,
|
16
|
-
after: after_date
|
15
|
+
result = interactor.send_request Lit::Source::LOCALIZATIONS_PATH, after: after_date
|
17
16
|
return unless result&.is_a?(Array)
|
18
17
|
result.each { |loc| synchronize_localization loc }
|
19
18
|
end
|
@@ -28,19 +27,16 @@ class SynchronizeSourceService
|
|
28
27
|
inc_loc.localization_key = find_localization_key(inc_loc)
|
29
28
|
inc_loc.translated_value = loc['value']
|
30
29
|
return if inc_loc.duplicated?(loc['value'])
|
30
|
+
|
31
31
|
inc_loc.save!
|
32
32
|
end
|
33
33
|
|
34
34
|
def find_incomming_localization(localization)
|
35
|
-
Lit::IncommingLocalization.find_or_initialize_by(
|
36
|
-
incomming_id: localization['id']
|
37
|
-
)
|
35
|
+
Lit::IncommingLocalization.find_or_initialize_by(incomming_id: localization['id'])
|
38
36
|
end
|
39
37
|
|
40
38
|
def find_localization_key(inc_loc)
|
41
|
-
Lit::LocalizationKey.find_by(
|
42
|
-
localization_key: inc_loc.localization_key_str
|
43
|
-
)
|
39
|
+
Lit::LocalizationKey.find_by(localization_key: inc_loc.localization_key_str)
|
44
40
|
end
|
45
41
|
|
46
42
|
def localization_key_deleted?(loc)
|
@@ -22,14 +22,15 @@ module Lit
|
|
22
22
|
def exists?(key)
|
23
23
|
# Use recommended binary-returning method create [with this redis-rb commit](https://github.com/redis/redis-rb/commit/bf42fc9e0db4a1719d9b1ecc65aeb20425d44427).
|
24
24
|
return Lit.redis.exists?(key) if Lit.redis.respond_to?(:exists?)
|
25
|
+
|
25
26
|
# Fall back with older gem
|
26
27
|
Lit.redis.exists(key)
|
27
28
|
end
|
28
29
|
|
29
30
|
def [](key)
|
30
|
-
if
|
31
|
+
if exists?(_prefixed_key_for_array(key))
|
31
32
|
Lit.redis.lrange(_prefixed_key(key), 0, -1)
|
32
|
-
elsif
|
33
|
+
elsif exists?(_prefixed_key_for_nil(key))
|
33
34
|
nil
|
34
35
|
else
|
35
36
|
val = Lit.redis.get(_prefixed_key(key))
|
@@ -69,7 +70,7 @@ module Lit
|
|
69
70
|
end
|
70
71
|
|
71
72
|
def has_key?(key)
|
72
|
-
|
73
|
+
exists?(_prefixed_key(key))
|
73
74
|
end
|
74
75
|
alias key? has_key?
|
75
76
|
|
data/lib/lit/cache.rb
CHANGED
@@ -18,6 +18,9 @@ end
|
|
18
18
|
|
19
19
|
module Lit
|
20
20
|
class Cache
|
21
|
+
@@last_update = nil
|
22
|
+
@@localization_cache = {}
|
23
|
+
|
21
24
|
def initialize
|
22
25
|
@hits_counter = Lit.get_key_value_engine
|
23
26
|
@request_info_store = Lit.get_key_value_engine
|
@@ -32,6 +35,7 @@ module Lit
|
|
32
35
|
|
33
36
|
def [](key)
|
34
37
|
value = nil
|
38
|
+
check_and_clean_if_required
|
35
39
|
unless localization_cache.key?(key)
|
36
40
|
value = localizations[key]
|
37
41
|
localization_cache[key] = value
|
@@ -81,6 +85,7 @@ module Lit
|
|
81
85
|
locale = find_locale(locale_key)
|
82
86
|
localization = find_localization(locale, key_without_locale, value: value, force_array: force_array, update_value: true)
|
83
87
|
return localization.translation if startup_process && localization.is_changed?
|
88
|
+
|
84
89
|
localizations[key] = localization.translation if localization
|
85
90
|
localization_cache[key] = localizations[key]
|
86
91
|
end
|
@@ -120,6 +125,7 @@ module Lit
|
|
120
125
|
@localization_object_cache.delete(key)
|
121
126
|
localization = find_localization(locale, key_without_locale, default_fallback: true)
|
122
127
|
localizations[key] = localization.translation if localization
|
128
|
+
clear_localization_cache
|
123
129
|
end
|
124
130
|
|
125
131
|
def delete_key(key)
|
@@ -175,11 +181,26 @@ module Lit
|
|
175
181
|
end
|
176
182
|
|
177
183
|
def localization_cache
|
178
|
-
Thread.current[:lit_thread_cache] ||= {}
|
184
|
+
# Thread.current[:lit_thread_cache] ||= {}
|
185
|
+
@@localization_cache ||= {}
|
179
186
|
end
|
180
187
|
|
181
188
|
def clear_localization_cache
|
182
|
-
Thread.current[:lit_thread_cache] = {}
|
189
|
+
# Thread.current[:lit_thread_cache] = {}
|
190
|
+
@@localization_cache = {}
|
191
|
+
end
|
192
|
+
|
193
|
+
def check_and_clean_if_required
|
194
|
+
# we want this method to run only once during a request or background job
|
195
|
+
return if Thread.current[:localization_cache_valid]
|
196
|
+
|
197
|
+
# get most recently updated translation and compare with what we store in class var
|
198
|
+
last_up = Lit::Localization.order(updated_at: :desc).limit(1).pluck(:updated_at).first.to_i
|
199
|
+
if last_up != @@last_update
|
200
|
+
clear_localization_cache
|
201
|
+
@@last_update = last_up
|
202
|
+
end
|
203
|
+
Thread.current[:localization_cache_valid] = true
|
183
204
|
end
|
184
205
|
|
185
206
|
private
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'rack/body_proxy'
|
2
|
+
|
3
|
+
# A middleware that ensures the lit thread value is cleared after
|
4
|
+
# the last part of the body is rendered. This is useful when
|
5
|
+
# using streaming.j
|
6
|
+
#
|
7
|
+
# Uses Rack::BodyProxy, adapted from Rack::Lock's usage of the
|
8
|
+
# same pattern.
|
9
|
+
#
|
10
|
+
|
11
|
+
module Lit
|
12
|
+
class Middleware
|
13
|
+
def initialize(app)
|
14
|
+
@app = app
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(env)
|
18
|
+
Thread.current[:localization_cache_valid] = false
|
19
|
+
response = @app.call(env)
|
20
|
+
|
21
|
+
# for streaming support wrap request in Rack::BodyProxy
|
22
|
+
response << Rack::BodyProxy.new(response.pop) do
|
23
|
+
Thread.current[:localization_cache_valid] = false
|
24
|
+
end
|
25
|
+
ensure
|
26
|
+
Thread.current[:localization_cache_valid] = false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/lit/rails.rb
CHANGED
data/lib/lit/railtie.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
module Lit
|
2
2
|
class Railtie < ::Rails::Railtie
|
3
|
-
|
4
|
-
|
5
|
-
# Lit::Rails.initialize
|
6
|
-
end
|
3
|
+
initializer :lit_middleware do |app|
|
4
|
+
app.config.middleware.insert_after ActionDispatch::RequestId, Lit::Middleware
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
ActiveSupport::Reloader.to_complete do
|
7
|
+
Thread.current[:localization_cache_valid] = false
|
8
|
+
end
|
9
|
+
end
|
11
10
|
end
|
12
11
|
end
|
data/lib/lit/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maciej Litwiniuk
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2021-03-08 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rails
|
@@ -319,6 +319,7 @@ files:
|
|
319
319
|
- lib/lit/i18n_backend.rb
|
320
320
|
- lib/lit/import.rb
|
321
321
|
- lib/lit/loader.rb
|
322
|
+
- lib/lit/middleware.rb
|
322
323
|
- lib/lit/rails.rb
|
323
324
|
- lib/lit/railtie.rb
|
324
325
|
- lib/lit/services/localization_keys_to_hash_service.rb
|
@@ -343,7 +344,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
343
344
|
- !ruby/object:Gem::Version
|
344
345
|
version: '0'
|
345
346
|
requirements: []
|
346
|
-
rubygems_version: 3.
|
347
|
+
rubygems_version: 3.0.3
|
347
348
|
signing_key:
|
348
349
|
specification_version: 4
|
349
350
|
summary: Database powered i18n backend with web gui
|