lit 0.3.3 → 0.4.0.pre.alpha

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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +40 -6
  3. data/app/assets/javascripts/lit/lit_frontend.js +20 -12
  4. data/app/assets/stylesheets/lit/application.css +3 -0
  5. data/app/controllers/lit/api/v1/base_controller.rb +1 -1
  6. data/app/controllers/lit/api/v1/locales_controller.rb +1 -1
  7. data/app/controllers/lit/api/v1/localization_keys_controller.rb +12 -4
  8. data/app/controllers/lit/api/v1/localizations_controller.rb +25 -9
  9. data/app/controllers/lit/application_controller.rb +11 -8
  10. data/app/controllers/lit/concerns/request_info_store.rb +1 -0
  11. data/app/controllers/lit/incomming_localizations_controller.rb +22 -15
  12. data/app/controllers/lit/locales_controller.rb +1 -1
  13. data/app/controllers/lit/localization_keys_controller.rb +44 -18
  14. data/app/controllers/lit/localizations_controller.rb +16 -11
  15. data/app/controllers/lit/sources_controller.rb +9 -13
  16. data/app/helpers/lit/frontend_helper.rb +28 -16
  17. data/app/helpers/lit/localizations_helper.rb +2 -1
  18. data/app/jobs/lit/synchronize_source_job.rb +1 -1
  19. data/app/models/lit/incomming_localization.rb +71 -41
  20. data/app/models/lit/locale.rb +11 -13
  21. data/app/models/lit/localization.rb +26 -24
  22. data/app/models/lit/localization_key.rb +46 -55
  23. data/app/models/lit/source.rb +17 -74
  24. data/app/queries/localization_key_search_query.rb +80 -0
  25. data/app/services/remote_interactor_service.rb +45 -0
  26. data/app/services/synchronize_source_service.rb +63 -0
  27. data/app/views/kaminari/lit/_gap.html.erb +1 -1
  28. data/app/views/layouts/lit/_navigation.html.erb +1 -1
  29. data/app/views/lit/dashboard/index.html.erb +2 -2
  30. data/app/views/lit/incomming_localizations/index.html.erb +10 -6
  31. data/app/views/lit/localization_keys/_localization_row.html.erb +1 -1
  32. data/app/views/lit/localization_keys/_localizations_list.html.erb +84 -0
  33. data/app/views/lit/localization_keys/_sidebar.html.erb +66 -0
  34. data/app/views/lit/localization_keys/change_completed.js.erb +2 -0
  35. data/app/views/lit/localization_keys/index.html.erb +3 -121
  36. data/app/views/lit/localization_keys/not_translated.html.erb +9 -0
  37. data/app/views/lit/localization_keys/restore_deleted.js.erb +1 -0
  38. data/app/views/lit/localization_keys/visited_again.html.erb +9 -0
  39. data/app/views/lit/localizations/_previous_versions_rows.html.erb +2 -2
  40. data/app/views/lit/localizations/change_completed.js.erb +2 -0
  41. data/app/views/lit/localizations/update.js.erb +2 -0
  42. data/app/views/lit/sources/_form.html.erb +1 -1
  43. data/app/views/lit/sources/index.html.erb +1 -1
  44. data/config/routes.rb +5 -0
  45. data/db/migrate/20181017123839_lit_add_is_deleted_to_localization_keys.rb +8 -0
  46. data/db/migrate/20181018075955_lit_add_localization_key_is_deleted_to_localization_keys.rb +8 -0
  47. data/db/migrate/20181030111522_lit_add_is_visited_again_to_localization_keys.rb +8 -0
  48. data/lib/generators/lit/install/templates/initializer.rb +5 -1
  49. data/lib/lit.rb +1 -0
  50. data/lib/lit/adapters/redis_storage.rb +1 -1
  51. data/lib/lit/cache.rb +32 -54
  52. data/lib/lit/export.rb +80 -0
  53. data/lib/lit/i18n_backend.rb +12 -9
  54. data/lib/lit/import.rb +179 -0
  55. data/lib/lit/loader.rb +2 -0
  56. data/lib/lit/version.rb +1 -1
  57. data/lib/tasks/lit_tasks.rake +78 -13
  58. metadata +21 -6
@@ -4,46 +4,51 @@ module Lit
4
4
  before_action :find_localization
5
5
 
6
6
  def show
7
- render json: { value: @localization.get_value }
7
+ render json: { value: @localization.translation }
8
8
  end
9
9
 
10
10
  def edit
11
- @localization.translated_value = @localization.get_value
11
+ @localization.translated_value = @localization.translation
12
12
  respond_to do |format|
13
13
  format.js
14
14
  end
15
15
  end
16
16
 
17
17
  def update
18
- if @localization.update_attributes(clear_params)
19
- @localization.update_column :is_changed, true
20
- Lit.init.cache.update_cache @localization.full_key, @localization.get_value
21
- end
22
- @localization.reload
18
+ after_update_operations if @localization.update_attributes(clear_params)
23
19
  respond_to do |f|
24
20
  f.js
25
21
  f.json do
26
- render json: { value: @localization.get_value }
22
+ render json: { value: @localization.reload.translation }
27
23
  end
28
24
  end
29
25
  end
30
26
 
27
+ def change_completed
28
+ @localization.toggle(:is_changed).save!
29
+ respond_to :js
30
+ end
31
+
31
32
  def previous_versions
32
- @versions = @localization.versions.order('created_at DESC')
33
+ @versions = @localization.versions.order(created_at: :desc)
33
34
  respond_to :js
34
35
  end
35
36
 
36
37
  private
37
38
 
38
39
  def find_localization_key
39
- @localization_key = Lit::LocalizationKey. \
40
- find(params[:localization_key_id])
40
+ @localization_key =
41
+ Lit::LocalizationKey.active.find(params[:localization_key_id])
41
42
  end
42
43
 
43
44
  def find_localization
44
45
  @localization = @localization_key.localizations.find(params[:id])
45
46
  end
46
47
 
48
+ def after_update_operations
49
+ @localization.update_column :is_changed, true
50
+ end
51
+
47
52
  def clear_params
48
53
  if params.respond_to?(:permit)
49
54
  # allow translated_value to be an array
@@ -2,37 +2,32 @@ require_dependency 'lit/application_controller'
2
2
 
3
3
  module Lit
4
4
  class SourcesController < ApplicationController
5
+ before_action :find_source, except: %i[index new create]
5
6
  def index
6
7
  @sources = Source.all
7
8
  end
8
9
 
9
- def show
10
- @source = Source.find(params[:id])
11
- end
10
+ def show; end
12
11
 
13
12
  def new
14
13
  @source = Source.new
15
14
  end
16
15
 
17
- def edit
18
- @source = Source.find(params[:id])
19
- end
16
+ def edit; end
20
17
 
21
18
  def synchronize
22
- @source = Source.find(params[:id])
23
19
  @source.update_column(:sync_complete, false)
24
20
  if defined?(ActiveJob)
25
21
  SynchronizeSourceJob.perform_later(@source)
26
22
  else
27
- @source.synchronize
23
+ SynchronizeSourceService.new(@source).execute
28
24
  end
29
25
  redirect_to lit.source_incomming_localizations_path(@source)
30
26
  end
31
27
 
32
28
  def touch
33
- @source = Source.find(params[:id])
34
29
  @source.touch_last_updated_at!
35
- redirect_to request.env['HTTP_REFERER'].present? ? :back : @source
30
+ redirect_to_back_or_default fallback_location: source_path(@source)
36
31
  end
37
32
 
38
33
  def create
@@ -45,7 +40,6 @@ module Lit
45
40
  end
46
41
 
47
42
  def update
48
- @source = Source.find(params[:id])
49
43
  if @source.update_attributes(clear_params)
50
44
  redirect_to @source, notice: 'Source was successfully updated.'
51
45
  else
@@ -54,18 +48,20 @@ module Lit
54
48
  end
55
49
 
56
50
  def destroy
57
- @source = Source.find(params[:id])
58
51
  @source.destroy
59
52
  redirect_to sources_url
60
53
  end
61
54
 
62
55
  def sync_complete
63
- @source = Source.find(params[:id])
64
56
  render json: { sync_complete: @source.sync_complete }
65
57
  end
66
58
 
67
59
  private
68
60
 
61
+ def find_source
62
+ @source = Source.find(params[:id])
63
+ end
64
+
69
65
  def clear_params
70
66
  if defined?(::ActionController::StrongParameters)
71
67
  params.require(:source).permit(:identifier, :url, :api_key)
@@ -1,15 +1,26 @@
1
1
  module Lit
2
2
  module FrontendHelper
3
3
  include ActionView::Helpers::TranslationHelper
4
+
4
5
  module TranslationKeyWrapper
5
6
  def translate(key, options = {})
7
+ count = options[:count]
6
8
  options = options.with_indifferent_access
7
9
  key = scope_key_by_partial(key)
8
- ret = super(key, options)
10
+ key = pluralized_key(key, count) if count
11
+
12
+ content = super(key, options)
9
13
  if !options[:skip_lit] && lit_authorized?
10
- ret = get_translateable_span(key, ret)
14
+ content = get_translateable_span(key, content)
11
15
  end
12
- ret
16
+ content
17
+ end
18
+
19
+ def pluralized_key(key, count)
20
+ pluralizer = I18n.backend.send(:pluralizer, locale)
21
+ return unless pluralizer.respond_to?(:call)
22
+ last = count.zero? ? :zero : pluralizer.call(count)
23
+ format '%<key>s.%<last>s', key: key, last: last
13
24
  end
14
25
 
15
26
  def t(key, options = {})
@@ -32,7 +43,7 @@ module Lit
32
43
  '',
33
44
  value: lit.find_localization_localization_keys_path,
34
45
  name: 'lit-url-base'
35
- safe_join([javascript_lit_tag, stylesheet_lit_tag, meta])
46
+ safe_join [javascript_lit_tag, stylesheet_lit_tag, meta]
36
47
  end
37
48
 
38
49
  def lit_translations_info
@@ -41,23 +52,24 @@ module Lit
41
52
  content_tag :div, class: 'lit-translations-info collapsed' do
42
53
  concat content_tag :span, 'Show translations', class: 'lit-open-button'
43
54
  concat content_tag :span, 'X', class: 'lit-close-button'
44
- concat(content_tag(:ul, class: 'lit-translations-list') do
45
- Lit.init.cache.request_keys.each do |k, v|
46
- concat(content_tag(:li) do
47
- concat content_tag :code, "#{k}:"
48
- concat get_translateable_span(k, v, alternative_text: '[empty]')
49
- end)
55
+ concat translations_list_content_tag
56
+ end
57
+ end
58
+
59
+ def translations_list_content_tag
60
+ content_tag :ul, class: 'lit-translations-list' do
61
+ Lit.init.cache.request_keys.each do |k, v|
62
+ concat content_tag(:li) do
63
+ concat content_tag :code, "#{k}:"
64
+ concat get_translateable_span(k, v, alternative_text: '[empty]')
50
65
  end
51
- end)
66
+ end
52
67
  end
53
68
  end
54
69
 
55
70
  def lit_authorized?
56
- if Lit.authentication_verification.present?
57
- send(Lit.authentication_verification)
58
- else
59
- true
60
- end
71
+ return false if Lit.authentication_verification.blank?
72
+ send Lit.authentication_verification
61
73
  end
62
74
 
63
75
  def get_translateable_span(key, localization, alternative_text: nil)
@@ -1,7 +1,8 @@
1
1
  module Lit
2
2
  module LocalizationsHelper
3
3
  def draw_icon(icon, opts = {})
4
- raw("<i class=\"fa fa-#{icon} #{opts[:class]}\" title=\"#{opts[:title]}\" ></i>")
4
+ raw "<i class=\"fa fa-#{icon} #{opts[:class]}\" " \
5
+ "title=\"#{opts[:title]}\" ></i>"
5
6
  end
6
7
 
7
8
  def ejs(val)
@@ -4,7 +4,7 @@ module Lit
4
4
  queue_as :default
5
5
 
6
6
  def perform(source)
7
- source.synchronize
7
+ SynchronizeSourceService.new(source).execute
8
8
  end
9
9
  end
10
10
  end
@@ -8,14 +8,13 @@ module Lit
8
8
  belongs_to :localization
9
9
  belongs_to :source
10
10
 
11
- unless defined?(::ActionController::StrongParameters)
12
- attr_accessible
13
- end
11
+ ## ACCESSORS
12
+ attr_accessible unless defined?(::ActionController::StrongParameters)
14
13
 
15
14
  ## BEFORE & AFTER
16
- before_create :set_localization_id
15
+ before_validation :set_localization, on: :create
17
16
 
18
- def get_value
17
+ def translation
19
18
  translated_value
20
19
  end
21
20
 
@@ -25,53 +24,84 @@ module Lit
25
24
 
26
25
  def accept
27
26
  if localization.present?
28
- localization.translated_value = translated_value
29
- localization.is_changed = true
30
- localization.save
27
+ update_existing_localization_data
28
+ update_existing_localization_key_data
31
29
  else
32
- unless locale.present?
33
- self.locale = Lit::Locale.where(locale: locale_str).first_or_create
34
- end
35
- unless localization_key.present?
36
- self.localization_key = Lit::LocalizationKey.
37
- where(localization_key: localization_key_str).
38
- first_or_create
39
- end
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
- end
30
+ assign_new_localization_data
49
31
  end
50
- Lit.init.cache.update_cache localization.full_key, localization.get_value
32
+ update_cache
51
33
  destroy
52
34
  end
53
35
 
54
- def is_duplicate?(val)
55
- set_localization_id unless localization.present?
56
- if localization
57
- translated_value = localization.
58
- read_attribute_before_type_cast('translated_value')
59
- if localization.is_changed? && !translated_value.nil?
60
- translated_value == val
61
- else
62
- localization.read_attribute_before_type_cast('default_value') == val
63
- end
36
+ def duplicated?(val)
37
+ set_localization
38
+ return false if localization_has_changed?
39
+ translated_value =
40
+ localization.read_attribute_before_type_cast('translated_value')
41
+ if localization.is_changed? && !translated_value.nil?
42
+ translated_value == val
64
43
  else
65
- false
44
+ localization.read_attribute_before_type_cast('default_value') == val
66
45
  end
67
46
  end
68
47
 
69
48
  private
70
49
 
71
- def set_localization_id
72
- if locale.present? && localization_key.present?
73
- self.localization = localization_key.localizations.where(locale_id: locale_id).first
74
- end
50
+ def set_localization
51
+ return if locale.blank? || localization_key.blank?
52
+ self.localization = localization_key.localizations
53
+ .find_by(locale_id: locale_id)
54
+ end
55
+
56
+ def localization_has_changed?
57
+ localization.blank? ||
58
+ localization.is_deleted != localization_key_is_deleted
59
+ end
60
+
61
+ def update_existing_localization_data
62
+ localization.update_attributes!(
63
+ translated_value: translated_value,
64
+ is_changed: true
65
+ )
66
+ end
67
+
68
+ def update_existing_localization_key_data
69
+ localization_key.update_attributes!(
70
+ is_deleted: localization_key_is_deleted
71
+ )
72
+ end
73
+
74
+ def assign_new_localization_data
75
+ assign_new_locale unless locale.present?
76
+ assign_new_localization_key unless localization_key.present?
77
+ assign_new_localization unless localization.present?
78
+ end
79
+
80
+ def assign_new_locale
81
+ self.locale = Lit::Locale.where(locale: locale_str).first_or_create
82
+ end
83
+
84
+ def assign_new_localization_key
85
+ self.localization_key =
86
+ Lit::LocalizationKey.where(
87
+ localization_key: localization_key_str,
88
+ is_deleted: localization_key_is_deleted
89
+ ).first_or_create!
90
+ end
91
+
92
+ def assign_new_localization
93
+ self.localization =
94
+ Lit::Localization.where(localization_key_id: localization_key.id)
95
+ .where(locale_id: locale.id)
96
+ .first_or_initialize
97
+ localization.translated_value = translated_value
98
+ localization.is_changed = true
99
+ localization.save!
100
+ end
101
+
102
+ def update_cache
103
+ Lit.init.cache.update_cache localization.full_key,
104
+ localization.translation
75
105
  end
76
106
  end
77
107
  end
@@ -1,23 +1,21 @@
1
1
  module Lit
2
2
  class Locale < ActiveRecord::Base
3
3
  ## SCOPES
4
- scope :ordered, proc { order('locale ASC') }
5
- scope :visible, proc { where(is_hidden: false) }
4
+ scope :ordered, -> { order(locale: :asc) }
5
+ scope :visible, -> { where(is_hidden: false) }
6
6
 
7
7
  ## ASSOCIATIONS
8
8
  has_many :localizations, dependent: :destroy
9
9
 
10
10
  ## VALIDATIONS
11
- validates :locale,
12
- presence: true,
13
- uniqueness: true
11
+ validates :locale, presence: true, uniqueness: true
14
12
 
15
13
  ## BEFORE & AFTER
16
14
  after_save :reset_available_locales_cache
17
15
  after_destroy :reset_available_locales_cache
18
16
 
17
+ ## ACCESSORS
19
18
  unless defined?(::ActionController::StrongParameters)
20
- ## ACCESSIBLE
21
19
  attr_accessible :locale
22
20
  end
23
21
 
@@ -25,17 +23,17 @@ module Lit
25
23
  locale
26
24
  end
27
25
 
28
- def get_translated_percentage
29
- total = get_all_localizations_count
30
- total > 0 ? (get_changed_localizations_count * 100 / total) : 0
26
+ def translated_percentage
27
+ total = all_localizations_count
28
+ total > 0 ? (changed_localizations_count * 100 / total) : 0
31
29
  end
32
30
 
33
- def get_changed_localizations_count
34
- localizations.changed.count(:id)
31
+ def changed_localizations_count
32
+ localizations.active.changed.count(:id)
35
33
  end
36
34
 
37
- def get_all_localizations_count
38
- localizations.count(:id)
35
+ def all_localizations_count
36
+ localizations.active.count(:id)
39
37
  end
40
38
 
41
39
  private
@@ -4,11 +4,16 @@ module Lit
4
4
  serialize :default_value
5
5
 
6
6
  ## SCOPES
7
- scope :changed, proc { where(is_changed: true) }
7
+ scope :changed, -> { where is_changed: true }
8
+ scope :not_changed, -> { where is_changed: false }
8
9
  # @HACK: dirty, find a way to round date to full second
9
- scope :after, proc { |dt|
10
+ scope :after, lambda { |dt|
10
11
  where('updated_at >= ?', dt + 1.second)
11
- .where('is_changed = true')
12
+ .where(is_changed: true)
13
+ }
14
+ scope :active, lambda {
15
+ joins(:localization_key)
16
+ .where(Lit::LocalizationKey.table_name => { is_deleted: false })
12
17
  }
13
18
 
14
19
  ## ASSOCIATIONS
@@ -17,42 +22,47 @@ module Lit
17
22
  has_many :localization_versions, dependent: :destroy
18
23
  has_many :versions, class_name: '::Lit::LocalizationVersion'
19
24
 
25
+ ## DELEGATIONS
26
+ delegate :is_deleted, to: :localization_key
27
+
20
28
  ## VALIDATIONS
21
- validates :locale_id,
22
- presence: true
29
+ validates :locale, presence: true
23
30
 
31
+ ## ACCESSORS
24
32
  unless defined?(::ActionController::StrongParameters)
25
- ## ACCESSIBLE
26
33
  attr_accessible :translated_value, :locale_id
27
34
  end
28
35
 
29
36
  ## BEFORE & AFTER
30
37
  with_options if: :translated_value_changed? do |o|
31
- o.before_update :update_should_mark_localization_key_completed
32
38
  o.before_update :create_version
33
39
  end
34
- after_update :mark_localization_key_completed
40
+ after_commit :update_cache, on: :update
35
41
 
36
42
  def to_s
37
- get_value
43
+ translation
38
44
  end
39
45
 
40
46
  def full_key
41
47
  [locale.locale, localization_key.localization_key].join('.')
42
48
  end
43
49
 
44
- def get_value
50
+ def translation
45
51
  is_changed? && !translated_value.nil? ? translated_value : default_value
46
52
  end
47
53
 
48
54
  def value
49
- get_value
55
+ translation
50
56
  end
51
57
 
52
58
  def localization_key_str
53
59
  localization_key.localization_key
54
60
  end
55
61
 
62
+ def localization_key_is_deleted
63
+ localization_key.is_deleted
64
+ end
65
+
56
66
  def locale_str
57
67
  locale.locale
58
68
  end
@@ -73,22 +83,14 @@ module Lit
73
83
 
74
84
  private
75
85
 
76
- def update_should_mark_localization_key_completed
77
- return if translated_value == translated_value_was
78
- @should_mark_localization_key_completed = true
79
- end
80
-
81
- def mark_localization_key_completed
82
- return if !instance_variable_defined?(:@should_mark_localization_key_completed) || \
83
- @should_mark_localization_key_completed
84
- localization_key.mark_completed!
86
+ def update_cache
87
+ Lit.init.cache.update_cache full_key, translation
85
88
  end
86
89
 
87
90
  def create_version
88
- if translated_value.present?
89
- l = localization_versions.new
90
- l.translated_value = translated_value_was || default_value
91
- end
91
+ return if translated_value.blank?
92
+ translated_value = translated_value_was || default_value
93
+ localization_versions.new(translated_value: translated_value)
92
94
  end
93
95
  end
94
96
  end