kakimasu 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.rubocop.yml +31 -0
- data/.travis.yml +8 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +135 -0
- data/Rakefile +6 -0
- data/app/controllers/kakimasu/home_controller.rb +18 -0
- data/app/controllers/kakimasu/keys_controller.rb +89 -0
- data/app/controllers/kakimasu/translations_controller.rb +37 -0
- data/app/helpers/counting_helper.rb +11 -0
- data/app/helpers/formatting_helper.rb +6 -0
- data/app/helpers/grouping_helper.rb +11 -0
- data/app/helpers/pagination_helper.rb +15 -0
- data/app/helpers/search_key_helper.rb +66 -0
- data/app/helpers/search_translations_helper.rb +101 -0
- data/app/models/translation.rb +2 -0
- data/app/policies/translation_policy.rb +9 -0
- data/app/views/kakimasu/home/index.html.erb +35 -0
- data/app/views/kakimasu/keys/create.js.erb +1 -0
- data/app/views/kakimasu/keys/index.html.erb +183 -0
- data/app/views/kakimasu/shared/_navbar.html.erb +15 -0
- data/app/views/kakimasu/translations/create.js.erb +1 -0
- data/app/views/kakimasu/translations/index.html.erb +168 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/config/initializers/i18n.rb +58 -0
- data/config/initializers/i18n_backend.rb +5 -0
- data/config/locales/en.yml +34 -0
- data/config/routes.rb +10 -0
- data/kakimasu.gemspec +49 -0
- data/lib/generators/kakimasu/backup_generator.rb +101 -0
- data/lib/generators/kakimasu/policy_generator.rb +18 -0
- data/lib/generators/kakimasu/restore_backup_generator.rb +89 -0
- data/lib/generators/kakimasu/views_generator.rb +22 -0
- data/lib/kakimasu.rb +11 -0
- data/lib/kakimasu/engine.rb +3 -0
- data/lib/kakimasu/version.rb +3 -0
- data/vendor/assets/javascripts/components/activation_button.coffee +10 -0
- data/vendor/assets/javascripts/components/modal.coffee +48 -0
- data/vendor/assets/javascripts/components/translate.coffee +93 -0
- data/vendor/assets/javascripts/components/translation_key_table.coffee +5 -0
- data/vendor/assets/javascripts/components/translation_navigation.coffee +13 -0
- data/vendor/assets/javascripts/components/translation_panel_table.coffee +5 -0
- data/vendor/assets/javascripts/components/translation_percent_chart.coffee +39 -0
- data/vendor/assets/javascripts/components/translation_popover.coffee +90 -0
- data/vendor/assets/javascripts/jquery/jquery.circliful.min.js +1 -0
- data/vendor/assets/javascripts/kakimasu.coffee +18 -0
- data/vendor/assets/stylesheets/circliful.scss +38 -0
- data/vendor/assets/stylesheets/components/_homepage.scss +17 -0
- data/vendor/assets/stylesheets/components/_key_management.scss +53 -0
- data/vendor/assets/stylesheets/components/_navbar.scss +52 -0
- data/vendor/assets/stylesheets/components/_translate_modal.scss +36 -0
- data/vendor/assets/stylesheets/components/_translation_panel.scss +31 -0
- data/vendor/assets/stylesheets/components/_translation_popover.scss +31 -0
- data/vendor/assets/stylesheets/font-awesome/HELP-US-OUT.txt +7 -0
- data/vendor/assets/stylesheets/font-awesome/css/font-awesome.css +2337 -0
- data/vendor/assets/stylesheets/font-awesome/css/font-awesome.min.css +4 -0
- data/vendor/assets/stylesheets/font-awesome/fonts/FontAwesome.otf +0 -0
- data/vendor/assets/stylesheets/font-awesome/fonts/fontawesome-webfont.eot +0 -0
- data/vendor/assets/stylesheets/font-awesome/fonts/fontawesome-webfont.svg +2671 -0
- data/vendor/assets/stylesheets/font-awesome/fonts/fontawesome-webfont.ttf +0 -0
- data/vendor/assets/stylesheets/font-awesome/fonts/fontawesome-webfont.woff +0 -0
- data/vendor/assets/stylesheets/font-awesome/fonts/fontawesome-webfont.woff2 +0 -0
- data/vendor/assets/stylesheets/font-awesome/less/animated.less +34 -0
- data/vendor/assets/stylesheets/font-awesome/less/bordered-pulled.less +25 -0
- data/vendor/assets/stylesheets/font-awesome/less/core.less +12 -0
- data/vendor/assets/stylesheets/font-awesome/less/fixed-width.less +6 -0
- data/vendor/assets/stylesheets/font-awesome/less/font-awesome.less +18 -0
- data/vendor/assets/stylesheets/font-awesome/less/icons.less +789 -0
- data/vendor/assets/stylesheets/font-awesome/less/larger.less +13 -0
- data/vendor/assets/stylesheets/font-awesome/less/list.less +19 -0
- data/vendor/assets/stylesheets/font-awesome/less/mixins.less +60 -0
- data/vendor/assets/stylesheets/font-awesome/less/path.less +15 -0
- data/vendor/assets/stylesheets/font-awesome/less/rotated-flipped.less +20 -0
- data/vendor/assets/stylesheets/font-awesome/less/screen-reader.less +5 -0
- data/vendor/assets/stylesheets/font-awesome/less/stacked.less +20 -0
- data/vendor/assets/stylesheets/font-awesome/less/variables.less +800 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_animated.scss +34 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_bordered-pulled.scss +25 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_core.scss +12 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_fixed-width.scss +6 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_icons.scss +789 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_larger.scss +13 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_list.scss +19 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_mixins.scss +60 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_path.scss +15 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_rotated-flipped.scss +20 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_screen-reader.scss +5 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_stacked.scss +20 -0
- data/vendor/assets/stylesheets/font-awesome/scss/_variables.scss +800 -0
- data/vendor/assets/stylesheets/font-awesome/scss/font-awesome.scss +18 -0
- data/vendor/assets/stylesheets/kakimasu.scss +35 -0
- 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 '«'.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 '»'.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">×</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>
|
data/bin/console
ADDED
@@ -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__)
|
data/bin/setup
ADDED
@@ -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,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!
|
data/config/routes.rb
ADDED
@@ -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
|
data/kakimasu.gemspec
ADDED
@@ -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
|