lit 0.2.4 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +17 -0
- data/Rakefile +1 -4
- data/app/controllers/lit/api/v1/base_controller.rb +5 -5
- data/app/controllers/lit/api/v1/locales_controller.rb +2 -2
- data/app/controllers/lit/api/v1/localization_keys_controller.rb +2 -3
- data/app/controllers/lit/api/v1/localizations_controller.rb +2 -2
- data/app/controllers/lit/application_controller.rb +12 -11
- data/app/controllers/lit/dashboard_controller.rb +1 -1
- data/app/controllers/lit/incomming_localizations_controller.rb +13 -6
- data/app/controllers/lit/locales_controller.rb +5 -5
- data/app/controllers/lit/localization_keys_controller.rb +57 -57
- data/app/controllers/lit/localizations_controller.rb +16 -15
- data/app/controllers/lit/sources_controller.rb +13 -12
- data/app/helpers/lit/application_helper.rb +0 -1
- data/app/helpers/lit/localizations_helper.rb +1 -1
- data/app/models/lit/incomming_localization.rb +29 -26
- data/app/models/lit/locale.rb +21 -11
- data/app/models/lit/localization.rb +27 -26
- data/app/models/lit/localization_key.rb +19 -20
- data/app/models/lit/localization_version.rb +1 -1
- data/app/models/lit/source.rb +51 -47
- data/app/views/lit/incomming_localizations/accept.js.erb +2 -0
- data/app/views/lit/incomming_localizations/destroy.js.erb +1 -0
- data/app/views/lit/incomming_localizations/index.html.erb +5 -5
- data/app/views/lit/localization_keys/index.html.erb +1 -1
- data/app/views/lit/localizations/_form.html.erb +1 -1
- data/app/views/lit/localizations/_previous_versions_rows.html.erb +2 -2
- data/app/views/lit/sources/index.html.erb +4 -1
- data/lib/generators/lit/install_generator.rb +16 -16
- data/lib/lit.rb +13 -8
- data/lib/lit/adapters/hash_storage.rb +1 -1
- data/lib/lit/adapters/redis_storage.rb +30 -22
- data/lib/lit/cache.rb +128 -125
- data/lib/lit/engine.rb +1 -2
- data/lib/lit/i18n_backend.rb +59 -12
- data/lib/lit/loader.rb +1 -2
- data/lib/lit/railtie.rb +5 -5
- data/lib/lit/version.rb +1 -1
- data/lib/tasks/lit_tasks.rake +3 -3
- metadata +38 -32
@@ -15,45 +15,47 @@ module Lit
|
|
15
15
|
## BEFORE & AFTER
|
16
16
|
before_create :set_localization_id
|
17
17
|
|
18
|
-
|
19
18
|
def get_value
|
20
|
-
|
19
|
+
translated_value
|
21
20
|
end
|
22
21
|
|
23
22
|
def full_key
|
24
|
-
[
|
23
|
+
[locale_str, localization_key_str].join('.')
|
25
24
|
end
|
26
25
|
|
27
26
|
def accept
|
28
|
-
if
|
29
|
-
|
30
|
-
|
27
|
+
if localization.present?
|
28
|
+
localization.translated_value = translated_value
|
29
|
+
localization.is_changed = true
|
30
|
+
localization.save
|
31
31
|
else
|
32
|
-
unless
|
33
|
-
self.locale = Lit::Locale.
|
34
|
-
self.locale.locale = self.locale_str
|
35
|
-
self.locale.save!
|
32
|
+
unless locale.present?
|
33
|
+
self.locale = Lit::Locale.where(locale: locale_str).first_or_create
|
36
34
|
end
|
37
|
-
unless
|
38
|
-
self.localization_key = Lit::LocalizationKey.
|
39
|
-
|
40
|
-
|
35
|
+
unless localization_key.present?
|
36
|
+
self.localization_key = Lit::LocalizationKey.
|
37
|
+
where(localization_key: localization_key_str).
|
38
|
+
first_or_create
|
41
39
|
end
|
42
|
-
unless
|
43
|
-
self.localization = Lit::Localization.
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
40
|
+
unless localization.present?
|
41
|
+
self.localization = Lit::Localization.
|
42
|
+
where(localization_key_id: self.localization_key.id).
|
43
|
+
where(locale_id: self.locale.id).
|
44
|
+
first_or_initialize
|
45
|
+
localization.translated_value = translated_value
|
46
|
+
localization.is_changed = true
|
47
|
+
localization.save!
|
48
48
|
end
|
49
49
|
end
|
50
|
-
|
50
|
+
Lit.init.cache.update_cache localization.full_key, localization.get_value
|
51
|
+
destroy
|
51
52
|
end
|
52
53
|
|
53
54
|
def is_duplicate?(val)
|
54
55
|
set_localization_id unless localization.present?
|
55
56
|
if localization
|
56
|
-
translated_value = localization.
|
57
|
+
translated_value = localization.
|
58
|
+
read_attribute_before_type_cast('translated_value')
|
57
59
|
if localization.is_changed? && !translated_value.nil?
|
58
60
|
translated_value == val
|
59
61
|
else
|
@@ -65,10 +67,11 @@ module Lit
|
|
65
67
|
end
|
66
68
|
|
67
69
|
private
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
70
|
+
|
71
|
+
def set_localization_id
|
72
|
+
if locale.present? && localization_key.present?
|
73
|
+
self.localization = localization_key.localizations.where(locale_id: locale_id).first
|
72
74
|
end
|
75
|
+
end
|
73
76
|
end
|
74
77
|
end
|
data/app/models/lit/locale.rb
CHANGED
@@ -1,17 +1,20 @@
|
|
1
1
|
module Lit
|
2
2
|
class Locale < ActiveRecord::Base
|
3
|
-
|
4
3
|
## SCOPES
|
5
|
-
scope :ordered, proc{ order('locale ASC') }
|
6
|
-
scope :visible, proc{ where(:
|
4
|
+
scope :ordered, proc { order('locale ASC') }
|
5
|
+
scope :visible, proc { where(is_hidden: false) }
|
7
6
|
|
8
7
|
## ASSOCIATIONS
|
9
|
-
has_many :localizations, :
|
8
|
+
has_many :localizations, dependent: :destroy
|
10
9
|
|
11
10
|
## VALIDATIONS
|
12
11
|
validates :locale,
|
13
|
-
:
|
14
|
-
:
|
12
|
+
presence: true,
|
13
|
+
uniqueness: true
|
14
|
+
|
15
|
+
## BEFORE & AFTER
|
16
|
+
after_save :reset_available_locales_cache
|
17
|
+
after_destroy :reset_available_locales_cache
|
15
18
|
|
16
19
|
unless defined?(::ActionController::StrongParameters)
|
17
20
|
## ACCESSIBLE
|
@@ -19,20 +22,27 @@ module Lit
|
|
19
22
|
end
|
20
23
|
|
21
24
|
def to_s
|
22
|
-
|
25
|
+
locale
|
23
26
|
end
|
24
27
|
|
25
28
|
def get_translated_percentage
|
26
|
-
total =
|
27
|
-
total > 0 ? (
|
29
|
+
total = get_all_localizations_count
|
30
|
+
total > 0 ? (get_changed_localizations_count * 100 / total) : 0
|
28
31
|
end
|
29
32
|
|
30
33
|
def get_changed_localizations_count
|
31
|
-
|
34
|
+
localizations.changed.count(:id)
|
32
35
|
end
|
33
36
|
|
34
37
|
def get_all_localizations_count
|
35
|
-
|
38
|
+
localizations.count(:id)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def reset_available_locales_cache
|
44
|
+
return unless I18n.backend.respond_to?(:reset_available_locales_cache)
|
45
|
+
I18n.backend.reset_available_locales_cache
|
36
46
|
end
|
37
47
|
end
|
38
48
|
end
|
@@ -4,19 +4,19 @@ module Lit
|
|
4
4
|
serialize :default_value
|
5
5
|
|
6
6
|
## SCOPES
|
7
|
-
scope :changed, proc{ where(:
|
7
|
+
scope :changed, proc { where(is_changed: true) }
|
8
8
|
# @HACK: dirty, find a way to round date to full second
|
9
|
-
scope :after, proc{|dt| where('updated_at >= ?', dt+1.second) }
|
9
|
+
scope :after, proc { |dt| where('updated_at >= ?', dt + 1.second) }
|
10
10
|
|
11
11
|
## ASSOCIATIONS
|
12
12
|
belongs_to :locale
|
13
|
-
belongs_to :localization_key
|
13
|
+
belongs_to :localization_key, touch: true
|
14
14
|
has_many :localization_versions, dependent: :destroy
|
15
15
|
has_many :versions, class_name: '::Lit::LocalizationVersion'
|
16
16
|
|
17
17
|
## VALIDATIONS
|
18
18
|
validates :locale_id,
|
19
|
-
:
|
19
|
+
presence: true
|
20
20
|
|
21
21
|
unless defined?(::ActionController::StrongParameters)
|
22
22
|
## ACCESSIBLE
|
@@ -24,22 +24,22 @@ module Lit
|
|
24
24
|
end
|
25
25
|
|
26
26
|
## BEFORE & AFTER
|
27
|
-
with_options :
|
28
|
-
o.before_update :
|
27
|
+
with_options if: :translated_value_changed? do |o|
|
28
|
+
o.before_update :update_is_changed_attribute
|
29
29
|
o.before_update :create_version
|
30
30
|
end
|
31
31
|
after_update :mark_localization_key_completed
|
32
32
|
|
33
33
|
def to_s
|
34
|
-
|
34
|
+
get_value
|
35
35
|
end
|
36
36
|
|
37
37
|
def full_key
|
38
|
-
[
|
38
|
+
[locale.locale, localization_key.localization_key].join('.')
|
39
39
|
end
|
40
40
|
|
41
41
|
def get_value
|
42
|
-
(is_changed? && (
|
42
|
+
(is_changed? && (!translated_value.nil?)) ? translated_value : default_value
|
43
43
|
end
|
44
44
|
|
45
45
|
def value
|
@@ -47,15 +47,15 @@ module Lit
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def localization_key_str
|
50
|
-
|
50
|
+
localization_key.localization_key
|
51
51
|
end
|
52
52
|
|
53
53
|
def locale_str
|
54
|
-
|
54
|
+
locale.locale
|
55
55
|
end
|
56
56
|
|
57
57
|
def last_change
|
58
|
-
|
58
|
+
updated_at.to_s(:db)
|
59
59
|
end
|
60
60
|
|
61
61
|
def update_default_value(value)
|
@@ -65,22 +65,23 @@ module Lit
|
|
65
65
|
end
|
66
66
|
|
67
67
|
private
|
68
|
-
def update_is_changed
|
69
|
-
unless is_changed?
|
70
|
-
self.is_changed = true
|
71
|
-
@should_mark_localization_key_completed = true
|
72
|
-
end
|
73
|
-
end
|
74
68
|
|
75
|
-
|
76
|
-
|
77
|
-
|
69
|
+
def update_is_changed_attribute
|
70
|
+
return if attributes['is_changed'] == true
|
71
|
+
|
72
|
+
self[:is_changed] = true
|
73
|
+
@should_mark_localization_key_completed = true
|
74
|
+
end
|
75
|
+
|
76
|
+
def mark_localization_key_completed
|
77
|
+
localization_key.mark_completed! if @should_mark_localization_key_completed
|
78
|
+
end
|
78
79
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
end
|
80
|
+
def create_version
|
81
|
+
if translated_value.present?
|
82
|
+
l = localization_versions.new
|
83
|
+
l.translated_value = translated_value_was || default_value
|
84
84
|
end
|
85
|
+
end
|
85
86
|
end
|
86
87
|
end
|
@@ -3,19 +3,19 @@ module Lit
|
|
3
3
|
attr_accessor :interpolated_key
|
4
4
|
|
5
5
|
## SCOPES
|
6
|
-
scope :completed, proc{ where(:
|
7
|
-
scope :not_completed, proc{ where(:
|
8
|
-
scope :starred, proc{ where(:
|
9
|
-
scope :ordered, proc{ order('localization_key asc') }
|
10
|
-
scope :after, proc{|dt| where('updated_at >= ?', dt) }
|
6
|
+
scope :completed, proc { where(is_completed: true) }
|
7
|
+
scope :not_completed, proc { where(is_completed: false) }
|
8
|
+
scope :starred, proc { where(is_starred: true) }
|
9
|
+
scope :ordered, proc { order('localization_key asc') }
|
10
|
+
scope :after, proc { |dt| where('updated_at >= ?', dt) }
|
11
11
|
|
12
12
|
## ASSOCIATIONS
|
13
|
-
has_many :localizations, :
|
13
|
+
has_many :localizations, dependent: :destroy
|
14
14
|
|
15
15
|
## VALIDATIONS
|
16
16
|
validates :localization_key,
|
17
|
-
:
|
18
|
-
:
|
17
|
+
presence: true,
|
18
|
+
uniqueness: { if: :localization_key_changed? }
|
19
19
|
|
20
20
|
unless defined?(::ActionController::StrongParameters)
|
21
21
|
## ACCESSIBLE
|
@@ -23,37 +23,37 @@ module Lit
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def to_s
|
26
|
-
|
26
|
+
localization_key
|
27
27
|
end
|
28
28
|
|
29
29
|
def clone_localizations
|
30
30
|
new_created = false
|
31
31
|
Lit::Locale.find_each do |locale|
|
32
|
-
|
32
|
+
localizations.where(locale_id: locale.id).first_or_create do |l|
|
33
33
|
l.default_value = interpolated_key
|
34
34
|
new_created = true
|
35
35
|
end
|
36
36
|
end
|
37
37
|
if new_created
|
38
|
-
Lit::LocalizationKey.update_all ['is_completed=?', false], ['id=? and is_completed=?',
|
38
|
+
Lit::LocalizationKey.update_all ['is_completed=?', false], ['id=? and is_completed=?', id, false]
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
42
|
def mark_completed
|
43
|
-
self.is_completed =
|
43
|
+
self.is_completed = localizations.changed.count(:id) == localizations.count
|
44
44
|
end
|
45
45
|
|
46
46
|
def mark_completed!
|
47
|
-
|
47
|
+
save if mark_completed
|
48
48
|
end
|
49
49
|
|
50
50
|
def mark_all_completed!
|
51
|
-
|
51
|
+
localizations.update_all(['is_changed=?', true])
|
52
52
|
mark_completed!
|
53
53
|
end
|
54
54
|
|
55
55
|
def self.order_options
|
56
|
-
[
|
56
|
+
['localization_key asc', 'localization_key desc', 'created_at asc', 'created_at desc', 'updated_at asc', 'updated_at desc']
|
57
57
|
end
|
58
58
|
|
59
59
|
# it can be overridden in parent application, for example: {:order => "created_at desc"}
|
@@ -61,12 +61,12 @@ module Lit
|
|
61
61
|
{}
|
62
62
|
end
|
63
63
|
|
64
|
-
def self.search(options={})
|
64
|
+
def self.search(options = {})
|
65
65
|
options = options.reverse_merge(default_search_options)
|
66
66
|
s = self
|
67
67
|
if options[:order] && order_options.include?(options[:order])
|
68
|
-
column, order = options[:order].split(
|
69
|
-
s = s.order("#{Lit::LocalizationKey.quoted_table_name}.#{connection.quote_column_name(column)} #{order}"
|
68
|
+
column, order = options[:order].split(' ')
|
69
|
+
s = s.order("#{Lit::LocalizationKey.quoted_table_name}.#{connection.quote_column_name(column)} #{order}")
|
70
70
|
else
|
71
71
|
s = s.ordered
|
72
72
|
end
|
@@ -86,11 +86,10 @@ module Lit
|
|
86
86
|
)
|
87
87
|
s = s.joins([:localizations]).where(cond)
|
88
88
|
end
|
89
|
-
|
89
|
+
unless options[:include_completed].to_i == 1
|
90
90
|
s = s.not_completed
|
91
91
|
end
|
92
92
|
s
|
93
93
|
end
|
94
|
-
|
95
94
|
end
|
96
95
|
end
|
data/app/models/lit/source.rb
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
require 'net/http'
|
2
2
|
module Lit
|
3
3
|
class Source < ActiveRecord::Base
|
4
|
-
LOCALES_PATH =
|
5
|
-
LOCALIZATION_KEYS_PATH =
|
6
|
-
LOCALIZATIONS_PATH =
|
7
|
-
LAST_CHANGE_PATH =
|
4
|
+
LOCALES_PATH = '/api/v1/locales.json'
|
5
|
+
LOCALIZATION_KEYS_PATH = '/api/v1/localization_keys.json'
|
6
|
+
LOCALIZATIONS_PATH = '/api/v1/localizations.json'
|
7
|
+
LAST_CHANGE_PATH = '/api/v1/last_change.json'
|
8
8
|
|
9
9
|
## ASSOCIATIONS
|
10
10
|
has_many :incomming_localizations
|
11
11
|
|
12
12
|
## VALIDATIONS
|
13
13
|
validates :api_key, :identifier, :url,
|
14
|
-
:
|
14
|
+
presence: true
|
15
15
|
validates :url,
|
16
|
-
:
|
16
|
+
format: { with: /\Ahttps?:\/\/.*\/.*[^\/]\Z/i }
|
17
17
|
|
18
18
|
unless defined?(::ActionController::StrongParameters)
|
19
19
|
attr_accessible :api_key, :identifier, :url
|
@@ -23,33 +23,32 @@ module Lit
|
|
23
23
|
before_create :set_last_updated_at_upon_creation
|
24
24
|
after_validation :check_if_url_is_valid
|
25
25
|
|
26
|
-
|
27
26
|
def get_last_change
|
28
27
|
result = get_from_remote(LAST_CHANGE_PATH)
|
29
|
-
result[
|
28
|
+
result['last_change'] unless result.nil?
|
30
29
|
end
|
31
30
|
|
32
31
|
def synchronize
|
33
|
-
after =
|
34
|
-
result = get_from_remote(LOCALIZATIONS_PATH,
|
32
|
+
after = last_updated_at.nil? ? nil : last_updated_at.to_s(:db)
|
33
|
+
result = get_from_remote(LOCALIZATIONS_PATH, after: after)
|
35
34
|
unless result.nil?
|
36
35
|
if result.is_a?(Array)
|
37
36
|
result.each do |r|
|
38
37
|
il = IncommingLocalization.new
|
39
38
|
if ::Rails::VERSION::MAJOR < 4
|
40
|
-
il = IncommingLocalization.where(:
|
39
|
+
il = IncommingLocalization.where(incomming_id: r['id']).first_or_initialize
|
41
40
|
else
|
42
|
-
il = IncommingLocalization.find_or_initialize_by(:
|
41
|
+
il = IncommingLocalization.find_or_initialize_by(incomming_id: r['id'])
|
43
42
|
end
|
44
43
|
il.source = self
|
45
|
-
il.locale_str = r[
|
46
|
-
il.locale = Locale.where(:
|
47
|
-
il.localization_key_str = r[
|
48
|
-
il.localization_key = LocalizationKey.where(:
|
44
|
+
il.locale_str = r['locale_str']
|
45
|
+
il.locale = Locale.where(locale: il.locale_str).first
|
46
|
+
il.localization_key_str = r['localization_key_str']
|
47
|
+
il.localization_key = LocalizationKey.where(localization_key: il.localization_key_str).first
|
49
48
|
unless il.is_duplicate?(r['value'])
|
50
49
|
il.save!
|
51
|
-
IncommingLocalization.where(:
|
52
|
-
update_all ['translated_value=?', r[
|
50
|
+
IncommingLocalization.where(id: il.id).
|
51
|
+
update_all ['translated_value=?', r['value']]
|
53
52
|
end
|
54
53
|
end
|
55
54
|
last_change = get_last_change
|
@@ -66,41 +65,46 @@ module Lit
|
|
66
65
|
end
|
67
66
|
|
68
67
|
private
|
69
|
-
def touch_last_updated_at(time=nil)
|
70
|
-
self.last_updated_at = time || Time.now
|
71
|
-
end
|
72
68
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
69
|
+
def touch_last_updated_at(time = nil)
|
70
|
+
self.last_updated_at = time || Time.now
|
71
|
+
end
|
72
|
+
|
73
|
+
def check_if_url_is_valid
|
74
|
+
if errors.empty? && (self.new_record? || self.url_changed?)
|
75
|
+
errors.add(:url, 'is not accessible') if get_last_change.nil?
|
77
76
|
end
|
77
|
+
end
|
78
78
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
79
|
+
def get_from_remote(path, query_values = {})
|
80
|
+
result = nil
|
81
|
+
begin
|
82
|
+
uri = URI(url + path)
|
83
|
+
query_values.each do |k, v|
|
84
|
+
params = URI.decode_www_form(uri.query || '') << [k, v]
|
85
|
+
uri.query = URI.encode_www_form(params)
|
86
|
+
end
|
87
|
+
req = Net::HTTP::Get.new(uri.request_uri)
|
88
|
+
req.add_field('Authorization', %(Token token="#{api_key}"))
|
89
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
90
|
+
http.use_ssl = (uri.port == 443)
|
91
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
92
|
+
res = http.start do |http|
|
93
|
+
http.request(req)
|
94
|
+
end
|
95
|
+
if res.is_a?(Net::HTTPSuccess)
|
96
|
+
result = JSON.parse(res.body)
|
96
97
|
end
|
97
|
-
|
98
|
+
rescue => e
|
99
|
+
::Rails.logger.error { "Lit remote error: #{e}" } if defined?(Rails)
|
98
100
|
end
|
101
|
+
result
|
102
|
+
end
|
99
103
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
end
|
104
|
+
def set_last_updated_at_upon_creation
|
105
|
+
if last_updated_at.blank?
|
106
|
+
touch_last_updated_at if Lit.set_last_updated_at_upon_creation
|
104
107
|
end
|
108
|
+
end
|
105
109
|
end
|
106
110
|
end
|