kakimasu 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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