lit 0.0.4.3 → 0.1.0
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.
- data/README.md +27 -35
- data/app/assets/javascripts/lit/localizations.js.coffee +8 -1
- data/app/assets/stylesheets/lit/application.css +4 -0
- data/app/controllers/lit/api/v1/base_controller.rb +19 -0
- data/app/controllers/lit/api/v1/locales_controller.rb +14 -0
- data/app/controllers/lit/api/v1/localization_keys_controller.rb +16 -0
- data/app/controllers/lit/api/v1/localizations_controller.rb +18 -0
- data/app/controllers/lit/application_controller.rb +1 -1
- data/app/controllers/lit/incomming_localizations_controller.rb +42 -0
- data/app/controllers/lit/localization_keys_controller.rb +2 -2
- data/app/controllers/lit/localizations_controller.rb +8 -2
- data/app/controllers/lit/sources_controller.rb +60 -0
- data/app/helpers/lit/localizations_helper.rb +1 -1
- data/app/helpers/lit/sources_helper.rb +4 -0
- data/app/models/lit/incomming_localization.rb +60 -0
- data/app/models/lit/locale.rb +3 -2
- data/app/models/lit/localization.rb +33 -3
- data/app/models/lit/localization_key.rb +2 -1
- data/app/models/lit/localization_version.rb +12 -0
- data/app/models/lit/source.rb +87 -0
- data/app/views/layouts/lit/_navigation.html.erb +3 -0
- data/app/views/lit/incomming_localizations/index.html.erb +47 -0
- data/app/views/lit/localization_keys/_localization_row.html.erb +11 -0
- data/app/views/lit/localization_keys/index.html.erb +12 -5
- data/app/views/lit/localizations/_form.html.erb +9 -1
- data/app/views/lit/localizations/_previous_versions_rows.html.erb +15 -0
- data/app/views/lit/localizations/previous_versions.js.erb +3 -0
- data/app/views/lit/localizations/update.js.erb +2 -2
- data/app/views/lit/sources/_form.html.erb +35 -0
- data/app/views/lit/sources/edit.html.erb +6 -0
- data/app/views/lit/sources/index.html.erb +36 -0
- data/app/views/lit/sources/new.html.erb +5 -0
- data/app/views/lit/sources/show.html.erb +18 -0
- data/config/routes.rb +32 -1
- data/db/migrate/20130921071304_create_lit_localization_versions.rb +11 -0
- data/db/migrate/20130923162141_create_lit_sources.rb +12 -0
- data/db/migrate/20130924151910_create_lit_incomming_localizations.rb +21 -0
- data/lib/generators/lit/install/templates/initializer.rb +34 -0
- data/lib/generators/lit/install_generator.rb +73 -0
- data/lib/lit.rb +2 -0
- data/lib/lit/adapters/hash_storage.rb +2 -2
- data/lib/lit/adapters/redis_storage.rb +25 -5
- data/lib/lit/cache.rb +30 -22
- data/lib/lit/i18n_backend.rb +9 -7
- data/lib/lit/version.rb +1 -1
- metadata +42 -2
@@ -0,0 +1,18 @@
|
|
1
|
+
<p id="notice"><%= notice %></p>
|
2
|
+
|
3
|
+
<strong>Indetifier:</strong>
|
4
|
+
<%= @source.identifier %>
|
5
|
+
<br/>
|
6
|
+
<strong>Url:</strong>
|
7
|
+
<%= @source.url %>
|
8
|
+
<br/>
|
9
|
+
<strong>API key:</strong>
|
10
|
+
<%= @source.api_key %>
|
11
|
+
<br/>
|
12
|
+
<strong>Last updated at:</strong>
|
13
|
+
<%= @source.last_updated_at.to_s(:db) unless @source.last_updated_at.nil? %>
|
14
|
+
<br/>
|
15
|
+
|
16
|
+
|
17
|
+
<%= link_to 'Edit', edit_source_path(@source) %> |
|
18
|
+
<%= link_to 'Back', sources_path %>
|
data/config/routes.rb
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
Lit::Engine.routes.draw do
|
2
2
|
|
3
|
+
|
4
|
+
if Lit.api_enabled
|
5
|
+
namespace :api do
|
6
|
+
namespace :v1 do
|
7
|
+
get '/last_change' => 'localizations#last_change'
|
8
|
+
resources :locales, :only=>[:index]
|
9
|
+
resources :localization_keys, :only=>[:index]
|
10
|
+
resources :localizations, :only=>[:index] do
|
11
|
+
get 'last_change', :on=>:collection
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
3
16
|
resources :locales, :only=>[:index, :destroy] do
|
4
17
|
put :hide, :on=>:member
|
5
18
|
end
|
@@ -10,7 +23,25 @@ Lit::Engine.routes.draw do
|
|
10
23
|
collection do
|
11
24
|
get :starred
|
12
25
|
end
|
13
|
-
resources :localizations
|
26
|
+
resources :localizations, :only=>[:edit, :update] do
|
27
|
+
member do
|
28
|
+
get :previous_versions
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
resources :sources do
|
33
|
+
member do
|
34
|
+
get :synchronize
|
35
|
+
end
|
36
|
+
resources :incomming_localizations, :only=>[:index, :destroy] do
|
37
|
+
member do
|
38
|
+
get :accept
|
39
|
+
end
|
40
|
+
collection do
|
41
|
+
get :accept_all
|
42
|
+
post :reject_all
|
43
|
+
end
|
44
|
+
end
|
14
45
|
end
|
15
46
|
|
16
47
|
root :to=>"dashboard#index"
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class CreateLitLocalizationVersions < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :lit_localization_versions do |t|
|
4
|
+
t.text :translated_value
|
5
|
+
t.references :localization
|
6
|
+
|
7
|
+
t.timestamps
|
8
|
+
end
|
9
|
+
add_index :lit_localization_versions, :localization_id
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class CreateLitIncommingLocalizations < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :lit_incomming_localizations do |t|
|
4
|
+
t.text :translated_value
|
5
|
+
t.references :locale
|
6
|
+
t.references :localization_key
|
7
|
+
t.references :localization
|
8
|
+
t.string :locale_str
|
9
|
+
t.string :localization_key_str
|
10
|
+
t.references :source
|
11
|
+
t.integer :incomming_id
|
12
|
+
|
13
|
+
t.timestamps
|
14
|
+
end
|
15
|
+
add_index :lit_incomming_localizations, :locale_id
|
16
|
+
add_index :lit_incomming_localizations, :localization_key_id
|
17
|
+
add_index :lit_incomming_localizations, :localization_id
|
18
|
+
add_index :lit_incomming_localizations, :source_id
|
19
|
+
add_index :lit_incomming_localizations, :incomming_id
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
# Which authentication function to use (ie. :authenticate_user!)? When set to
|
3
|
+
# `nil` will let everyone in.
|
4
|
+
Lit.authentication_function = <%= @authentication_function || 'nil' %>
|
5
|
+
|
6
|
+
# Either 'redis' or 'hash'. Hash is the fastest, but will fail in multiprocess
|
7
|
+
# environment
|
8
|
+
Lit.key_value_engine = "<%= @key_value_engine %>"
|
9
|
+
|
10
|
+
# Pass extra options to key_value_neinge, ie. prefix for redis (only one
|
11
|
+
# supported at the moment)
|
12
|
+
# Lit.storage_options = { :prefix=>"my_project" }
|
13
|
+
|
14
|
+
# Translations without default will be humanized (default string will be added)
|
15
|
+
# ie. scope.page_header will become "Page header"
|
16
|
+
# If `false` then will serve nil instead (but translation will be wrapped in
|
17
|
+
# <span title="translation missing string"></span>
|
18
|
+
Lit.humanize_key = false
|
19
|
+
|
20
|
+
# Decide if missing translations will fallback to first found translated value
|
21
|
+
# (same key, different language)
|
22
|
+
Lit.fallback = true
|
23
|
+
|
24
|
+
# API enabled? API allows third party browsing your translations, as well as
|
25
|
+
# synchronizing them between environments
|
26
|
+
Lit.api_enabled = false
|
27
|
+
|
28
|
+
# API key is required to authorize third party, if API is enabled
|
29
|
+
Lit.api_key = "<%= @api_key %>"
|
30
|
+
|
31
|
+
# Initialize lit
|
32
|
+
Lit.init
|
33
|
+
|
34
|
+
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
module Lit
|
3
|
+
module Generators
|
4
|
+
class InstallGenerator < ::Rails::Generators::Base
|
5
|
+
class_option "key-value-engine", :type => :string
|
6
|
+
class_option "authentication-function", :type => :string
|
7
|
+
class_option "no-migrate", :type => :boolean
|
8
|
+
|
9
|
+
source_root File.expand_path("../install/templates", __FILE__)
|
10
|
+
|
11
|
+
desc "Automates Lit installation"
|
12
|
+
|
13
|
+
def copy_migrations
|
14
|
+
puts "Copying Lit migrations..."
|
15
|
+
Dir.chdir(::Rails.root) do
|
16
|
+
`rake lit:install:migrations`
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def set_authentication_function
|
21
|
+
@authentication_function = options["authentication-function"].presence ||
|
22
|
+
ask("What's the authentication function, ie. :authenticate_user! :").presence ||
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def set_key_value_engine
|
27
|
+
@key_value_engine = options["key-value-engine"].presence ||
|
28
|
+
ask("What's the key value engine? ([hash] OR redis):").presence ||
|
29
|
+
:hash
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_redis_dependency
|
33
|
+
if @key_value_engine == 'redis'
|
34
|
+
puts "Adding redis dependency"
|
35
|
+
gem 'redis'
|
36
|
+
Bundler.with_clean_env do
|
37
|
+
run "bundle install"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def generate_api_key
|
43
|
+
@api_key = SecureRandom.base64 32
|
44
|
+
end
|
45
|
+
|
46
|
+
def add_lit_initializer
|
47
|
+
path = "#{::Rails.root}/config/initializers/lit.rb"
|
48
|
+
if File.exists?(path)
|
49
|
+
puts "Skipping config/initializers/lit.rb creation, file already exists!"
|
50
|
+
else
|
51
|
+
puts "Adding lit initializer (config/initializers/lit.rb)..."
|
52
|
+
template "initializer.rb", path
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def run_migrations
|
57
|
+
unless options["no-migrate"]
|
58
|
+
puts "Running rake db:migrate"
|
59
|
+
`rake db:migrate`
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def clear_cache
|
64
|
+
Lit.init.cache.reset
|
65
|
+
end
|
66
|
+
|
67
|
+
def mount_engine
|
68
|
+
puts "Mounting Lit::Engine at \"/lit\" in config/routes.rb..."
|
69
|
+
route "mount Lit::Engine => '/lit'"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/lit.rb
CHANGED
@@ -11,15 +11,29 @@ module Lit
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def [](key)
|
14
|
-
Lit.redis.
|
14
|
+
if Lit.redis.exists(_prefixed_key_for_array(key))
|
15
|
+
Lit.redis.lrange(_prefixed_key(key), 0, -1)
|
16
|
+
else
|
17
|
+
Lit.redis.get(_prefixed_key(key))
|
18
|
+
end
|
15
19
|
end
|
16
20
|
|
17
21
|
def []=(k, v)
|
18
|
-
|
22
|
+
if v.is_a?(Array)
|
23
|
+
delete(k)
|
24
|
+
Lit.redis.set(_prefixed_key_for_array(k), "1")
|
25
|
+
v.each do |ve|
|
26
|
+
Lit.redis.rpush(_prefixed_key(k), ve.to_s)
|
27
|
+
end
|
28
|
+
else
|
29
|
+
Lit.redis.del(_prefixed_key_for_array(k))
|
30
|
+
Lit.redis.set(_prefixed_key(k), v) unless v.nil?
|
31
|
+
end
|
19
32
|
end
|
20
33
|
|
21
34
|
def delete(k)
|
22
|
-
Lit.redis.del
|
35
|
+
Lit.redis.del(_prefixed_key_for_array(k))
|
36
|
+
Lit.redis.del(_prefixed_key(k))
|
23
37
|
end
|
24
38
|
|
25
39
|
def clear
|
@@ -45,12 +59,18 @@ module Lit
|
|
45
59
|
end
|
46
60
|
|
47
61
|
private
|
48
|
-
def
|
62
|
+
def _prefix
|
49
63
|
prefix = "lit:"
|
50
64
|
if Lit.storage_options.is_a?(Hash)
|
51
65
|
prefix += "#{Lit.storage_options[:prefix]}:" if Lit.storage_options.has_key?(:prefix)
|
52
66
|
end
|
53
|
-
prefix
|
67
|
+
prefix
|
68
|
+
end
|
69
|
+
def _prefixed_key(key="")
|
70
|
+
_prefix+key.to_s
|
71
|
+
end
|
72
|
+
def _prefixed_key_for_array(key="")
|
73
|
+
_prefix+"array_flags:"+key.to_s
|
54
74
|
end
|
55
75
|
end
|
56
76
|
end
|
data/lib/lit/cache.rb
CHANGED
@@ -9,13 +9,23 @@ module Lit
|
|
9
9
|
|
10
10
|
def [](key)
|
11
11
|
update_hits_count(key)
|
12
|
-
@localizations[key]
|
12
|
+
ret = @localizations[key]
|
13
|
+
ret
|
13
14
|
end
|
14
15
|
|
15
16
|
def []=(key, value)
|
16
17
|
update_locale(key, value)
|
17
18
|
end
|
18
19
|
|
20
|
+
def init_key_with_value(key, value)
|
21
|
+
update_locale(key, value, true)
|
22
|
+
end
|
23
|
+
|
24
|
+
def has_key?(key)
|
25
|
+
# @TODO: change into correct has_key? call
|
26
|
+
@localizations.has_key?(key)
|
27
|
+
end
|
28
|
+
|
19
29
|
def sync
|
20
30
|
@localizations.clear
|
21
31
|
end
|
@@ -24,16 +34,15 @@ module Lit
|
|
24
34
|
@localizations.keys
|
25
35
|
end
|
26
36
|
|
27
|
-
def update_locale(key, value)
|
37
|
+
def update_locale(key, value, force_array=false)
|
28
38
|
key = key.to_s
|
29
39
|
locale_key, key_without_locale = split_key(key)
|
30
40
|
locale = find_locale(locale_key)
|
31
|
-
localization = find_localization(locale, key_without_locale, value)
|
41
|
+
localization = find_localization(locale, key_without_locale, value, force_array, true)
|
32
42
|
@localizations[key] = localization.get_value if localization
|
33
43
|
end
|
34
44
|
|
35
45
|
def load_all_translations(oninit=false)
|
36
|
-
Lit.init.logger.info "loading all translations"
|
37
46
|
doinit = false
|
38
47
|
first = Localization.order('id ASC').first
|
39
48
|
last = Localization.order('id DESC').first
|
@@ -51,7 +60,6 @@ module Lit
|
|
51
60
|
|
52
61
|
def refresh_key(key)
|
53
62
|
key = key.to_s
|
54
|
-
Lit.init.logger.info "refreshing key: #{key}"
|
55
63
|
locale_key, key_without_locale = split_key(key)
|
56
64
|
locale = find_locale(locale_key)
|
57
65
|
localization = find_localization(locale, key_without_locale)
|
@@ -60,7 +68,6 @@ module Lit
|
|
60
68
|
|
61
69
|
def delete_key(key)
|
62
70
|
key = key.to_s
|
63
|
-
Lit.init.logger.info "deleting key: #{key}"
|
64
71
|
@localizations.delete(key)
|
65
72
|
key_without_locale = split_key(key).last
|
66
73
|
@localization_keys.delete(key_without_locale)
|
@@ -80,7 +87,6 @@ module Lit
|
|
80
87
|
locale_key = locale_key.to_s
|
81
88
|
@locale_cache ||= {}
|
82
89
|
unless @locale_cache.has_key?(locale_key)
|
83
|
-
#Lit.init.logger.info "looking for locale: #{locale_key}"
|
84
90
|
locale = Lit::Locale.where(:locale=>locale_key).first_or_create!
|
85
91
|
@locale_cache[locale_key] = locale
|
86
92
|
end
|
@@ -131,19 +137,22 @@ module Lit
|
|
131
137
|
|
132
138
|
private
|
133
139
|
|
134
|
-
def find_localization(locale, key_without_locale, value=nil)
|
140
|
+
def find_localization(locale, key_without_locale, value=nil, force_array=false, update_value=false)
|
135
141
|
unless value.is_a?(Hash)
|
136
142
|
localization_key = find_localization_key(key_without_locale)
|
137
143
|
localization = Lit::Localization.where(:locale_id=>locale.id).
|
138
|
-
where(:localization_key_id=>localization_key.id).
|
144
|
+
where(:localization_key_id=>localization_key.id).first_or_initialize
|
145
|
+
if update_value || localization.new_record?
|
139
146
|
if value.is_a?(Array)
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
147
|
+
unless force_array
|
148
|
+
new_value = nil
|
149
|
+
value_clone = value.dup
|
150
|
+
while (v = value_clone.shift) && v.present?
|
151
|
+
pv = parse_value(v, locale)
|
152
|
+
new_value = pv unless pv.nil?
|
153
|
+
end
|
154
|
+
value = new_value
|
145
155
|
end
|
146
|
-
value = new_value
|
147
156
|
else
|
148
157
|
value = parse_value(value, locale) unless value.nil?
|
149
158
|
end
|
@@ -157,14 +166,14 @@ module Lit
|
|
157
166
|
end
|
158
167
|
end
|
159
168
|
end
|
160
|
-
value = key_without_locale.split('.').last.humanize if value.nil? &&
|
169
|
+
value = key_without_locale.split('.').last.humanize if value.nil? &&
|
161
170
|
Lit.humanize_key
|
162
171
|
end
|
163
|
-
|
172
|
+
localization.default_value = value
|
173
|
+
localization.save!
|
164
174
|
end
|
165
|
-
localization
|
175
|
+
return localization
|
166
176
|
else
|
167
|
-
Lit.init.logger.info "returning value for hash: #{key_without_locale}: #{value.to_s}"
|
168
177
|
nil
|
169
178
|
end
|
170
179
|
end
|
@@ -211,14 +220,13 @@ module Lit
|
|
211
220
|
end
|
212
221
|
|
213
222
|
def find_or_create_localization_key(key_without_locale)
|
214
|
-
|
215
|
-
localization_key = Lit::LocalizationKey.where(:localization_key=>key_without_locale).first_or_create!
|
223
|
+
localization_key = Lit::LocalizationKey.where(:localization_key=>key_without_locale).first_or_create!
|
216
224
|
@localization_keys[key_without_locale] = localization_key.id
|
217
225
|
localization_key
|
218
226
|
end
|
219
227
|
|
220
228
|
def update_hits_count(key)
|
221
|
-
if @hits_counter_working
|
229
|
+
if @hits_counter_working
|
222
230
|
key_without_locale = split_key(key).last
|
223
231
|
@hits_counter.incr('hits_counter.'+key)
|
224
232
|
@hits_counter.incr('global_hits_counter.'+key_without_locale)
|
data/lib/lit/i18n_backend.rb
CHANGED
@@ -27,7 +27,6 @@ module Lit
|
|
27
27
|
# @param [Hash] data nested key-value pairs to be added as blurbs
|
28
28
|
def store_translations(locale, data, options = {})
|
29
29
|
super
|
30
|
-
#Lit.init.logger.info "store translation: #{locale}, data: #{data}, options: #{options}"
|
31
30
|
store_item(locale, data)
|
32
31
|
end
|
33
32
|
|
@@ -37,14 +36,17 @@ module Lit
|
|
37
36
|
def lookup(locale, key, scope = [], options = {})
|
38
37
|
parts = I18n.normalize_keys(locale, key, scope, options[:separator])
|
39
38
|
key_with_locale = parts.join('.')
|
40
|
-
|
39
|
+
|
41
40
|
## check in cache or in simple backend
|
42
41
|
content = @cache[key_with_locale] || super
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
42
|
+
newly_created = false
|
43
|
+
unless @cache.has_key?(key_with_locale)
|
44
|
+
@cache.init_key_with_value(key_with_locale, content)
|
45
|
+
newly_created = true
|
46
|
+
end
|
47
|
+
if content.nil? || (newly_created && options[:default].present?)
|
48
|
+
@cache[key_with_locale] = options[:default]
|
49
|
+
content = @cache[key_with_locale]
|
48
50
|
end
|
49
51
|
## return translated content
|
50
52
|
content
|