kakimasu 1.0.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.
Files changed (98) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +12 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +31 -0
  6. data/.travis.yml +8 -0
  7. data/CODE_OF_CONDUCT.md +74 -0
  8. data/Gemfile +4 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +135 -0
  11. data/Rakefile +6 -0
  12. data/app/controllers/kakimasu/home_controller.rb +18 -0
  13. data/app/controllers/kakimasu/keys_controller.rb +89 -0
  14. data/app/controllers/kakimasu/translations_controller.rb +37 -0
  15. data/app/helpers/counting_helper.rb +11 -0
  16. data/app/helpers/formatting_helper.rb +6 -0
  17. data/app/helpers/grouping_helper.rb +11 -0
  18. data/app/helpers/pagination_helper.rb +15 -0
  19. data/app/helpers/search_key_helper.rb +66 -0
  20. data/app/helpers/search_translations_helper.rb +101 -0
  21. data/app/models/translation.rb +2 -0
  22. data/app/policies/translation_policy.rb +9 -0
  23. data/app/views/kakimasu/home/index.html.erb +35 -0
  24. data/app/views/kakimasu/keys/create.js.erb +1 -0
  25. data/app/views/kakimasu/keys/index.html.erb +183 -0
  26. data/app/views/kakimasu/shared/_navbar.html.erb +15 -0
  27. data/app/views/kakimasu/translations/create.js.erb +1 -0
  28. data/app/views/kakimasu/translations/index.html.erb +168 -0
  29. data/bin/console +14 -0
  30. data/bin/setup +8 -0
  31. data/config/initializers/i18n.rb +58 -0
  32. data/config/initializers/i18n_backend.rb +5 -0
  33. data/config/locales/en.yml +34 -0
  34. data/config/routes.rb +10 -0
  35. data/kakimasu.gemspec +49 -0
  36. data/lib/generators/kakimasu/backup_generator.rb +101 -0
  37. data/lib/generators/kakimasu/policy_generator.rb +18 -0
  38. data/lib/generators/kakimasu/restore_backup_generator.rb +89 -0
  39. data/lib/generators/kakimasu/views_generator.rb +22 -0
  40. data/lib/kakimasu.rb +11 -0
  41. data/lib/kakimasu/engine.rb +3 -0
  42. data/lib/kakimasu/version.rb +3 -0
  43. data/vendor/assets/javascripts/components/activation_button.coffee +10 -0
  44. data/vendor/assets/javascripts/components/modal.coffee +48 -0
  45. data/vendor/assets/javascripts/components/translate.coffee +93 -0
  46. data/vendor/assets/javascripts/components/translation_key_table.coffee +5 -0
  47. data/vendor/assets/javascripts/components/translation_navigation.coffee +13 -0
  48. data/vendor/assets/javascripts/components/translation_panel_table.coffee +5 -0
  49. data/vendor/assets/javascripts/components/translation_percent_chart.coffee +39 -0
  50. data/vendor/assets/javascripts/components/translation_popover.coffee +90 -0
  51. data/vendor/assets/javascripts/jquery/jquery.circliful.min.js +1 -0
  52. data/vendor/assets/javascripts/kakimasu.coffee +18 -0
  53. data/vendor/assets/stylesheets/circliful.scss +38 -0
  54. data/vendor/assets/stylesheets/components/_homepage.scss +17 -0
  55. data/vendor/assets/stylesheets/components/_key_management.scss +53 -0
  56. data/vendor/assets/stylesheets/components/_navbar.scss +52 -0
  57. data/vendor/assets/stylesheets/components/_translate_modal.scss +36 -0
  58. data/vendor/assets/stylesheets/components/_translation_panel.scss +31 -0
  59. data/vendor/assets/stylesheets/components/_translation_popover.scss +31 -0
  60. data/vendor/assets/stylesheets/font-awesome/HELP-US-OUT.txt +7 -0
  61. data/vendor/assets/stylesheets/font-awesome/css/font-awesome.css +2337 -0
  62. data/vendor/assets/stylesheets/font-awesome/css/font-awesome.min.css +4 -0
  63. data/vendor/assets/stylesheets/font-awesome/fonts/FontAwesome.otf +0 -0
  64. data/vendor/assets/stylesheets/font-awesome/fonts/fontawesome-webfont.eot +0 -0
  65. data/vendor/assets/stylesheets/font-awesome/fonts/fontawesome-webfont.svg +2671 -0
  66. data/vendor/assets/stylesheets/font-awesome/fonts/fontawesome-webfont.ttf +0 -0
  67. data/vendor/assets/stylesheets/font-awesome/fonts/fontawesome-webfont.woff +0 -0
  68. data/vendor/assets/stylesheets/font-awesome/fonts/fontawesome-webfont.woff2 +0 -0
  69. data/vendor/assets/stylesheets/font-awesome/less/animated.less +34 -0
  70. data/vendor/assets/stylesheets/font-awesome/less/bordered-pulled.less +25 -0
  71. data/vendor/assets/stylesheets/font-awesome/less/core.less +12 -0
  72. data/vendor/assets/stylesheets/font-awesome/less/fixed-width.less +6 -0
  73. data/vendor/assets/stylesheets/font-awesome/less/font-awesome.less +18 -0
  74. data/vendor/assets/stylesheets/font-awesome/less/icons.less +789 -0
  75. data/vendor/assets/stylesheets/font-awesome/less/larger.less +13 -0
  76. data/vendor/assets/stylesheets/font-awesome/less/list.less +19 -0
  77. data/vendor/assets/stylesheets/font-awesome/less/mixins.less +60 -0
  78. data/vendor/assets/stylesheets/font-awesome/less/path.less +15 -0
  79. data/vendor/assets/stylesheets/font-awesome/less/rotated-flipped.less +20 -0
  80. data/vendor/assets/stylesheets/font-awesome/less/screen-reader.less +5 -0
  81. data/vendor/assets/stylesheets/font-awesome/less/stacked.less +20 -0
  82. data/vendor/assets/stylesheets/font-awesome/less/variables.less +800 -0
  83. data/vendor/assets/stylesheets/font-awesome/scss/_animated.scss +34 -0
  84. data/vendor/assets/stylesheets/font-awesome/scss/_bordered-pulled.scss +25 -0
  85. data/vendor/assets/stylesheets/font-awesome/scss/_core.scss +12 -0
  86. data/vendor/assets/stylesheets/font-awesome/scss/_fixed-width.scss +6 -0
  87. data/vendor/assets/stylesheets/font-awesome/scss/_icons.scss +789 -0
  88. data/vendor/assets/stylesheets/font-awesome/scss/_larger.scss +13 -0
  89. data/vendor/assets/stylesheets/font-awesome/scss/_list.scss +19 -0
  90. data/vendor/assets/stylesheets/font-awesome/scss/_mixins.scss +60 -0
  91. data/vendor/assets/stylesheets/font-awesome/scss/_path.scss +15 -0
  92. data/vendor/assets/stylesheets/font-awesome/scss/_rotated-flipped.scss +20 -0
  93. data/vendor/assets/stylesheets/font-awesome/scss/_screen-reader.scss +5 -0
  94. data/vendor/assets/stylesheets/font-awesome/scss/_stacked.scss +20 -0
  95. data/vendor/assets/stylesheets/font-awesome/scss/_variables.scss +800 -0
  96. data/vendor/assets/stylesheets/font-awesome/scss/font-awesome.scss +18 -0
  97. data/vendor/assets/stylesheets/kakimasu.scss +35 -0
  98. metadata +364 -0
@@ -0,0 +1,15 @@
1
+ <div class="kakimasu-navigation" data-component="TranslationNavigation">
2
+ <nav class="navbar">
3
+ <div class="container-fluid">
4
+ <ul class="nav navbar-nav">
5
+ <li class="home-icon">
6
+ <%= link_to kakimasu_path do %>
7
+ <i class="fa fa-home" aria-hidden="true"></i>
8
+ <% end %>
9
+ </li>
10
+ <li class="<%= 'active' if @active_tab == 'keys' %>"><%= link_to t('translation_key_management'), kakimasu_keys_path, class: 'translation-navbar-link' %></li>
11
+ <li class="<%= 'active' if @active_tab == 'translations' %>"><%= link_to t('translation_panel'), kakimasu_translations_path, class: 'translation-navbar-link'%></li>
12
+ </ul>
13
+ </div>
14
+ </nav>
15
+ </div>
@@ -0,0 +1 @@
1
+ window.location.reload()
@@ -0,0 +1,168 @@
1
+ <%= render 'kakimasu/shared/navbar' %>
2
+
3
+ <div class="container" data-component="TranslationModal">
4
+ <h1><%= t('translation_panel') %></h1>
5
+
6
+ <div class="row">
7
+ <div class="col-md-3 translation-form">
8
+ <h2><%=t('add_translation')%></h2>
9
+
10
+ <!-- Translation form -->
11
+ <%= form_tag kakimasu_translations_path do %>
12
+ <div class="form-group">
13
+ <%= label_tag :locale %><br />
14
+ <%= select_tag :language, options_for_select(I18n.available_locales), class: "form-control" %>
15
+ </div>
16
+ <div class="form-group">
17
+ <%= label_tag :key %><br />
18
+ <%= text_field_tag :key, nil, class: "form-control" %>
19
+ </div>
20
+ <div class="form-group">
21
+ <%= label_tag :value %><br />
22
+ <%= text_area_tag :value, nil, class: "form-control" %>
23
+ </div>
24
+ <div class="form-group">
25
+ <%= button_tag(class: "btn btn-primary w-50") do %>
26
+ <% t('save') %>
27
+ <% end %>
28
+ </div>
29
+ <% end %>
30
+ </div>
31
+
32
+ <div class="col-md-9 translation-panel-table">
33
+ <!-- Translation table -->
34
+ <% if @grouped_keys.keys.count %>
35
+ <div data-component="TranslationPanelTable">
36
+ <table class="table table-hover translations-table">
37
+ <thead>
38
+ <tr>
39
+ <th><%= t('key') %></th>
40
+ <% I18n.available_locales.each do |locale| %>
41
+ <th><%= locale.upcase %></th>
42
+ <% end %>
43
+ <th></th>
44
+ </tr>
45
+ </thead>
46
+
47
+ <tbody>
48
+ <% @grouped_keys.each_with_index do |group, index| %>
49
+
50
+ <%-# Check if this key translations are in current page -%>
51
+ <% if get_page_size * (params[:page].to_i - 1) <= index && index < get_page_size * params[:page].to_i %>
52
+ <tr>
53
+ <td><%=group.first%></td>
54
+ <% translations = [] %>
55
+ <% I18n.available_locales.each do |locale| %>
56
+ <td>
57
+ <% missing = true %>
58
+ <% group_by_language(group.last).each do |key, value| %>
59
+ <% if key.to_s == locale.to_s %>
60
+ <% missing = false %>
61
+ <% translation = @translations[value.first] %>
62
+ <% translation&.gsub!('\u0026#39;', "'") %>
63
+ <% translation&.gsub!('\"', '"') %>
64
+ <% end %>
65
+
66
+ <%= translation %>
67
+ <% end %>
68
+ <% if missing %>
69
+ <span class="translation_missing"></span>
70
+ <% end %>
71
+ </td>
72
+ <% unless group.first.blank? %>
73
+ <% translations.push t(group.first, locale: locale) %>
74
+ <% end %>
75
+ <% end %>
76
+ <td class="text-center">
77
+ <%= content_tag 'button', class: 'translate-key-button', data: {toggle: 'modal', target: '#translateModal', key: "#{group.first}", translations: translations, locales: I18n.available_locales} do %>
78
+ <i class="fa fa-pencil" aria-hidden="true"></i>
79
+ <% end %>
80
+ </td>
81
+ </tr>
82
+ <% end %>
83
+ <% end %>
84
+ </tbody>
85
+ </table>
86
+
87
+ <% else %>
88
+ <h3><%= t('no_translations_were_found') %></h3>
89
+ <% end %>
90
+
91
+
92
+ <!-- Pagination -->
93
+ <div class="text-center">
94
+ <% if total_pages(@grouped_keys.keys) > 1 %>
95
+ <ul class="pagination">
96
+ <li>
97
+ <% if params[:page].to_i > 1 %>
98
+ <%= link_to '&laquo;'.html_safe, page: params[:page].to_i - 1, keys_category: @category %>
99
+ <% end %>
100
+ </li>
101
+ <% for i in 1..total_pages(@grouped_keys.keys) %>
102
+ <% if params[:page].to_i == i %>
103
+ <li class="active"><%= link_to i, page: i, keys_category: @category %></li>
104
+ <% else %>
105
+ <li><%= link_to i, page: i, keys_category: @category %></li>
106
+ <% end %>
107
+ <% end %>
108
+ <li>
109
+ <% unless params[:page].to_i == total_pages(@grouped_keys.keys) %>
110
+ <%= link_to '&raquo;'.html_safe, page: params[:page].to_i + 1, keys_category: @category %>
111
+ <% end %>
112
+ </li>
113
+ </ul>
114
+ <% end %>
115
+ </div>
116
+ </div>
117
+ </div>
118
+
119
+ <!-- Modal -->
120
+ <div class="modal fade" id="translateModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
121
+ <div class="modal-dialog" role="document">
122
+ <div class="modal-content">
123
+ <div class="modal-header">
124
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
125
+ </div>
126
+ <div class="modal-body">
127
+ <%= form_tag kakimasu_keys_path(keys_category: @category), id: 'translation-modal-form', remote: true do %>
128
+ <p>
129
+ <%= hidden_field_tag :key %>
130
+ </p>
131
+ <p>
132
+ <%= hidden_field_tag :path %>
133
+ </p>
134
+ <% I18n.available_locales.each_with_index do |locale, index| %>
135
+ <div class="form-group">
136
+ <div class="row">
137
+ <div class="col-xs-1">
138
+ <%= label_tag locale %>
139
+ </div>
140
+ <div class="col-xs-7 translation-input">
141
+ <%= text_area_tag locale, nil, class: "form-control" %>
142
+ </div>
143
+ <div class="col-xs-4">
144
+ <div class="suggested-translation-link">
145
+ <a href='<%="#modal-translation-#{index}"%>' data-toggle="collapse"><%=t('suggested_translations')%></a>
146
+ <div id='<%="modal-translation-#{index}"%>' class="collapse suggested-translation">
147
+ <p></p>
148
+ </div>
149
+ </div>
150
+ </div>
151
+ </div>
152
+ </div>
153
+ <% end %>
154
+ <% if @category == 'missing_translations' || @category == 'all_translation_keys' %>
155
+ <div id='lazy-lookup-checkbox'></div>
156
+ <% end %>
157
+ <p class="text-right">
158
+ <%= button_tag(class: "btn btn-primary") do%>
159
+ <% t('save') %>
160
+ <% end %>
161
+ </p>
162
+ <% end %>
163
+ </div>
164
+ </div>
165
+ </div>
166
+ </div>
167
+ </div>
168
+ </div>
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'kakimasu'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,58 @@
1
+ I18n.class_eval do
2
+ def self.translate(*args)
3
+ options = args.last.is_a?(Hash) ? args.pop.dup : {}
4
+ key = args.shift
5
+ backend = config.backend
6
+ locale = options.delete(:locale) || config.locale
7
+ handling = options.delete(:throw) && :throw || options.delete(:raise) && :raise
8
+ enforce_available_locales!(locale)
9
+ raise I18n::ArgumentError if key.is_a?(String) && key.empty?
10
+
11
+ result = catch(:exception) do
12
+ if key.is_a?(Array)
13
+ key.map { |k| backend.translate(locale, k, options) }
14
+ else
15
+ backend.translate(locale, key, options)
16
+ end
17
+ end
18
+
19
+ # For sending available translations to javascript
20
+ all_translations = []
21
+ if Thread.current[:show_translation_key] == true
22
+ # For array is needed just translations without <span> tags as it would be if show_translation_key would be false
23
+ Thread.current[:show_translation_key] = false
24
+ I18n.available_locales.each do |l|
25
+ translation = catch(:exception) do
26
+ if key.is_a?(Array)
27
+ all_translations.push(key.map { |k| backend.translate(l, k, options) })
28
+ else
29
+ all_translations.push(backend.translate(l, key, options))
30
+ end
31
+ end
32
+ all_translations.push('') if translation.is_a?(I18n::MissingTranslation)
33
+ end
34
+ Thread.current[:show_translation_key] = true
35
+ end
36
+
37
+ if result.is_a?(I18n::MissingTranslation)
38
+ if Thread.current[:show_translation_key] == true && !Array.wrap(options[:scope]).flatten.join('.').include?('simple_form')
39
+ "<span class='translation_missing translation-with-key' data-component='TranslationPopover' data-content='#{key}'"\
40
+ "data-locales='#{I18n.available_locales}' data-translations='#{all_translations}'"\
41
+ "data-unique=#{(key.to_s.include?('.') && key.to_s.split('.').first != 'activerecord')}>#{key}</span>".html_safe
42
+ else
43
+ handle_exception(handling, result, locale, key, options)
44
+ end
45
+ elsif result.is_a?(String) && Thread.current[:show_translation_key] && (result.present? || !Array.wrap(options[:scope]).flatten.join('.').include?('simple_form'))
46
+ # Monkey patching for getting key and putting into spans
47
+ s = options[:scope] if options[:scope]
48
+ d = Array.wrap(options[:default]).first if options[:default]
49
+ k = d if key.to_s.blank?
50
+ k = [s, key].flatten.compact.join('.')
51
+ "<span class='translation-with-key' data-component='TranslationPopover' data-content='#{k}'"\
52
+ "data-locales='#{I18n.available_locales}' data-translations='#{all_translations}'"\
53
+ "data-unique=#{(k.to_s.include?('.') && k.to_s.split('.').first != 'activerecord')}>#{result}</span>".html_safe
54
+ else
55
+ result.to_s.html_safe
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,5 @@
1
+ require 'rubygems'
2
+ require 'redis'
3
+
4
+ TRANSLATION_STORE = Redis.new
5
+ I18n.backend = I18n::Backend::Chain.new(I18n::Backend::KeyValue.new(TRANSLATION_STORE), I18n.backend)
@@ -0,0 +1,34 @@
1
+ en:
2
+ deactivate_translation_mode: Deactivate translation mode
3
+ activate_translation_mode: Activate translation mode
4
+ hello_from_kakimasu: Hello, translator!
5
+ translations: Translations
6
+ translation_key_management: Translation key management
7
+ available_locales: Available languages
8
+
9
+ translation_panel: Translation Panel
10
+ translation_keys: Translation keys
11
+ back: Back
12
+ missing_translations: Missing translations
13
+ key: Key
14
+ path: Path
15
+ active_record_attribute_translations: Active record attribute translations
16
+ active_record_model_translations: Active record model translations
17
+
18
+ home: Home
19
+ add_translation: Add translation
20
+ available_translations: Available translations
21
+ edit: Edit
22
+
23
+ unique: Unique
24
+ save: Save
25
+
26
+ total_translation_keys: Total number of keys
27
+ total_keys_with_missing_translation: With missing translation
28
+ translation_percentage: Translation percentage
29
+
30
+ translation_succesfully_stored: Translation successfully saved!
31
+ nothing_was_changed: Nothing was changed
32
+
33
+ no_untranslated_keys: There is no untranslated key!
34
+ no_translation_keys_found: There was no translation keys found!
@@ -0,0 +1,10 @@
1
+ Rails.application.routes.draw do
2
+ get 'translations' => 'kakimasu/home#index', as: 'translations'
3
+ get 'kakimasu' => 'kakimasu/home#index', as: 'kakimasu'
4
+
5
+ namespace :kakimasu do
6
+ resources :translations, only: [:index, :create, :edit, :update]
7
+ resources :keys, only: [:index, :create]
8
+ resource :home, only: :index
9
+ end
10
+ end
@@ -0,0 +1,49 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'kakimasu/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'kakimasu'
8
+ spec.version = Kakimasu::VERSION
9
+ spec.authors = ['Roberts Groza']
10
+ spec.email = ['roberts.groza23@gmail.com']
11
+
12
+ spec.summary = 'Gem makes app translation very easy'
13
+ spec.homepage = 'https://github.com/RobertsGroza/kakimasu'
14
+ spec.license = 'MIT'
15
+
16
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
17
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
18
+ #if spec.respond_to?(:metadata)
19
+ # spec.metadata['allowed_push_host'] = "https://github.com/RobertsGroza/kakimasu"
20
+ #else
21
+ # raise 'RubyGems 2.0 or newer is required to protect against ' \
22
+ # 'public gem pushes.'
23
+ #end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
26
+ f.match(%r{^(test|spec|features)/})
27
+ end
28
+ spec.bindir = 'exe'
29
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ['lib']
31
+
32
+ spec.add_development_dependency 'bundler', '~> 1.14'
33
+ spec.add_development_dependency 'rake', '~> 10.0'
34
+ spec.add_development_dependency 'rspec', '~> 3.0'
35
+ spec.add_development_dependency 'guard'
36
+ spec.add_development_dependency 'guard-rspec'
37
+ spec.add_development_dependency 'coveralls'
38
+ spec.add_development_dependency 'rubocop'
39
+ spec.add_development_dependency 'rails'
40
+
41
+ spec.add_dependency 'redis'
42
+ spec.add_dependency 'sass-rails'
43
+ spec.add_dependency 'bootstrap-sass'
44
+ spec.add_dependency 'uglifier'
45
+ spec.add_dependency 'coffee-rails'
46
+ spec.add_dependency 'jquery-rails'
47
+ spec.add_dependency 'pundit'
48
+ spec.add_dependency 'font-awesome-sass'
49
+ end
@@ -0,0 +1,101 @@
1
+ module Kakimasu
2
+ module Generators
3
+ class BackupGenerator < Rails::Generators::Base
4
+ # Groups all added keys from TRANSLATION_STORE
5
+ grouped_keys_by_locale = TRANSLATION_STORE.keys.group_by { |el| el.partition('.').first }
6
+
7
+ # Checks if there is at least one translation in TRANSLATION_STORE
8
+ if TRANSLATION_STORE.keys.count == 0
9
+ puts '**************************************************'
10
+ puts 'Backup can not be done. There are no translations!'
11
+ puts '**************************************************'
12
+ else
13
+
14
+ backup_file = '.kakimasu_backup.yml'
15
+
16
+ # Check if backup file already exists
17
+ unless File.file?(backup_file)
18
+ puts 'Creating backup_file...'
19
+
20
+ # If there is no backup file then it is created here
21
+ File.write(backup_file, "")
22
+ end
23
+
24
+ # Read Kakimasu backup file
25
+ file_content = File.read(backup_file)
26
+
27
+ # Modify file content - write all translations in there
28
+ I18n.available_locales.each do |locale|
29
+ position = 0 # Position in string where to start write
30
+ exists = false # Tells if this locale is saved in backup (if not then after all translations will be writed 'new line character' to seperate languages)
31
+
32
+ # Search where to start insert new translations in string (Searching goes by lines)
33
+ file_content.each_line do |line|
34
+ position += line.length
35
+
36
+ # If locale is found then break the loop
37
+ if line.start_with?("#{locale}:")
38
+ exists = true
39
+ break
40
+ end
41
+ end
42
+
43
+ # If locale doesn't exist in the file already then start writing from file start and insert new line just to seperate languages
44
+ unless exists
45
+ position = 0
46
+ file_content.insert(0, "\n")
47
+ end
48
+
49
+ # If there is at least one translation in current language just then will insert new translations
50
+ unless grouped_keys_by_locale[locale.to_s].nil?
51
+ grouped_keys_by_locale[locale.to_s].each do |key|
52
+ splitted_key = key.split('.')
53
+
54
+ # Case if translation is not unique (it can be normally saved without special indentation requirements)
55
+ if splitted_key.count == 2
56
+ translation_key = key.partition('.').last
57
+ translation = TRANSLATION_STORE[key]
58
+
59
+ file_content.insert(position, " #{translation_key}: #{translation}\n")
60
+
61
+ # Case if translation is unique (Special indentation requirements)
62
+ elsif splitted_key.count > 2
63
+ unique_translation = '' # Variable for unique translation with indentation
64
+
65
+ splitted_key.each_with_index do |subkey, index|
66
+ unless index == 0
67
+ indentation = ' ' * index
68
+ translation = TRANSLATION_STORE[key]
69
+
70
+ # Last 'subkey' after colon has translation
71
+ if index == splitted_key.count - 1
72
+ unique_translation += "#{indentation}#{subkey}: #{translation}\n"
73
+ else
74
+ unique_translation += "#{indentation}#{subkey}:\n"
75
+ end
76
+ end
77
+ end
78
+
79
+ file_content.insert(position, unique_translation)
80
+ end
81
+ end
82
+ end
83
+
84
+ # Insert locale in front of all its translations if it wasnt already there
85
+ file_content.insert(0, "#{locale}:\n") unless exists
86
+ end
87
+
88
+ # Open Kakimasu backup file and write new content
89
+ File.open(backup_file, 'w+') do |f|
90
+ f.write(file_content)
91
+ end
92
+
93
+ # Success message
94
+ puts ''
95
+ puts "*********************************************************"
96
+ puts "Translations successfully stored in #{backup_file}!"
97
+ puts "*********************************************************"
98
+ end
99
+ end
100
+ end
101
+ end