ntq_tools 0.3.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.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +8 -0
- data/app/assets/config/ntq_tools_manifest.js +1 -0
- data/app/assets/stylesheets/ntq_tools/application.css +15 -0
- data/app/controllers/ntq_tools/application_controller.rb +4 -0
- data/app/controllers/ntq_tools/impersonation_controller.rb +46 -0
- data/app/controllers/ntq_tools/translations_controller.rb +29 -0
- data/app/helpers/ntq_tools/application_helper.rb +4 -0
- data/app/jobs/ntq_tools/application_job.rb +4 -0
- data/app/mailers/ntq_tools/application_mailer.rb +6 -0
- data/app/models/ntq_tools/application_record.rb +5 -0
- data/app/views/layouts/ntq_tools/application.html.erb +15 -0
- data/config/routes.rb +8 -0
- data/lib/generators/ntq_tools/graphql_scaffold_generator.rb +221 -0
- data/lib/generators/ntq_tools/install_generator.rb +11 -0
- data/lib/generators/templates/ntq_tools.rb +9 -0
- data/lib/ntq_tools/engine.rb +7 -0
- data/lib/ntq_tools/translations/hash_utils.rb +15 -0
- data/lib/ntq_tools/translations/translation_tool.rb +92 -0
- data/lib/ntq_tools/translations/yaml_tool.rb +40 -0
- data/lib/ntq_tools/version.rb +3 -0
- data/lib/ntq_tools.rb +16 -0
- data/lib/tasks/ntq_tools_tasks.rake +4 -0
- metadata +104 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: cbeb5958ef479f90d380f74d13512a988936a16636845f8873360a3160412b31
|
4
|
+
data.tar.gz: a36e413a12bab5fcd370c60e059bf6767c42fdf16ffcddbed73356e829a0145a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e3e4cfedca1eeaa752ca79fdac1d6c577d88cdcc7cf20b247bd843265c66f4409424dd7921d2000f9939e0ba6433c31d9c06413c980b5515f01aa18376b80e63
|
7
|
+
data.tar.gz: e4b558b3b6869bedc70c052af4ead39a5e5d06ca334ab18f46df0a22321076b691e85bcf8c7157b52241f7eecd936eed589a0dd1e2ad232d202b3f823a0c37b6
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2023 Kevin
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# NtqTools
|
2
|
+
Short description and motivation.
|
3
|
+
|
4
|
+
## Usage
|
5
|
+
How to use my plugin.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem "ntq_tools", git: "https://github.com/9troisquarts/ntq_tools"
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
```bash
|
16
|
+
$ bundle
|
17
|
+
```
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
```bash
|
21
|
+
$ gem install ntq_tools
|
22
|
+
```
|
23
|
+
|
24
|
+
## Contributing
|
25
|
+
Contribution directions go here.
|
26
|
+
|
27
|
+
## License
|
28
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
//= link_directory ../stylesheets/ntq_tools .css
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module NtqTools
|
2
|
+
class ImpersonationController < ::ApplicationController
|
3
|
+
|
4
|
+
before_action :check_impersonation_enabled, except: [:config]
|
5
|
+
before_action :model_name_is_valid?, only: [:sign_in]
|
6
|
+
|
7
|
+
def index
|
8
|
+
data = {}
|
9
|
+
NtqTools.impersonation_user_models.each do |model|
|
10
|
+
data[model.underscore] = model.constantize.all.map{|user| {
|
11
|
+
id: user.id,
|
12
|
+
label: label_for_user(user),
|
13
|
+
}}
|
14
|
+
end
|
15
|
+
render json: { data: data }
|
16
|
+
end
|
17
|
+
|
18
|
+
def signin
|
19
|
+
@resource = params[:model_name].camelize.constantize.find params[:id]
|
20
|
+
sign_in(@resource)
|
21
|
+
return redirect_to @resource.after_impersonation_path if @resource.respond_to?(:after_impersonation_path)
|
22
|
+
|
23
|
+
redirect_to after_sign_in_path_for(@resource)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def label_for_user(user, config = nil)
|
29
|
+
return user.impersonation_label if user.respond_to?(:impersonation_label)
|
30
|
+
|
31
|
+
return user.full_name if user.respond_to?(:full_name)
|
32
|
+
|
33
|
+
return user.email if user.respond_to?(:email)
|
34
|
+
|
35
|
+
user.id
|
36
|
+
end
|
37
|
+
|
38
|
+
def model_name_is_valid?
|
39
|
+
return render json: {}, status: 404 unless params[:model_name].present? && NtqTools.impersonation_user_models.include?(params[:model_name].camelize)
|
40
|
+
end
|
41
|
+
|
42
|
+
def check_impersonation_enabled
|
43
|
+
return render json: {}, status: 404 unless NtqTools.impersonation_enabled && NtqTools.impersonation_user_models.present?
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'ntq_tools/translations/translation_tool'
|
2
|
+
module NtqTools
|
3
|
+
class TranslationsController < NtqTools::ApplicationController
|
4
|
+
skip_before_action :verify_authenticity_token
|
5
|
+
before_action :check_presence_of_key
|
6
|
+
|
7
|
+
def show
|
8
|
+
return render json: { data: nil }, status: 404 unless I18n.exists?(params[:key].to_s)
|
9
|
+
|
10
|
+
render json: {
|
11
|
+
data: I18n.t(params[:key])
|
12
|
+
}, status: 200
|
13
|
+
end
|
14
|
+
|
15
|
+
def update
|
16
|
+
return render json: { status: "NOK", message: "value is missing" }, status: 400 unless params[:value].present?
|
17
|
+
|
18
|
+
NtqTools::Translations::TranslationTool.modify(params[:key].to_s, { "#{I18n.locale}": params[:value] })
|
19
|
+
|
20
|
+
render json: { data: true }, status: 200
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def check_presence_of_key
|
26
|
+
return render json: { status: "NOK", message: "key params is missing" }, status: 400 unless params[:key].present?
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
NtqTools::Engine.routes.draw do
|
2
|
+
resource :translation, only: [:update, :show]
|
3
|
+
|
4
|
+
if NtqTools.impersonation_enabled && NtqTools.impersonation_user_models.any? && defined?(Devise)
|
5
|
+
get '/impersonation/users' => "impersonation#index"
|
6
|
+
get "/impersonation/:model_name/:id/sign_in" => "impersonation#signin"
|
7
|
+
end
|
8
|
+
end
|
@@ -0,0 +1,221 @@
|
|
1
|
+
module NtqTools
|
2
|
+
module Generators
|
3
|
+
SKIPPED_ATTRIBUTE_NAMES = %w[created_at updated_at]
|
4
|
+
class GraphqlScaffoldGenerator < Rails::Generators::NamedBase
|
5
|
+
source_root File.expand_path('../templates', __dir__)
|
6
|
+
|
7
|
+
def create_type_file
|
8
|
+
singular_name = plural_name.singularize
|
9
|
+
return unless defined?(class_name.constantize) && class_name.constantize.respond_to?(:columns_hash)
|
10
|
+
|
11
|
+
definition = []
|
12
|
+
class_name.constantize.columns_hash.map do |k, v|
|
13
|
+
next if SKIPPED_ATTRIBUTE_NAMES.include?(k)
|
14
|
+
|
15
|
+
case v.type
|
16
|
+
when :string, :text
|
17
|
+
definition << "field :#{k}, String"
|
18
|
+
when :integer
|
19
|
+
definition << if k.include?('_id') || k == 'id'
|
20
|
+
"field :#{k}, ID"
|
21
|
+
else
|
22
|
+
"field :#{k}, Integer"
|
23
|
+
end
|
24
|
+
when :boolean
|
25
|
+
definition << "field :#{k}, Boolean"
|
26
|
+
when :decimal
|
27
|
+
definition << "field :#{k}, Float"
|
28
|
+
when :date, :datetime
|
29
|
+
definition << "field :#{k}, Types::TimeType"
|
30
|
+
else
|
31
|
+
raise "Type non défini: #{v.type.inspect}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
attributes = []
|
36
|
+
class_name.constantize.columns_hash.map do |k, v|
|
37
|
+
next if SKIPPED_ATTRIBUTE_NAMES.include?(k)
|
38
|
+
|
39
|
+
case v.type
|
40
|
+
when :string, :text
|
41
|
+
attributes << "argument :#{k}, String, required: false"
|
42
|
+
when :integer
|
43
|
+
attributes << if k.include?('_id') || k == 'id'
|
44
|
+
"argument :#{k}, ID, required: false"
|
45
|
+
else
|
46
|
+
"argument :#{k}, Integer, required: false"
|
47
|
+
end
|
48
|
+
when :boolean
|
49
|
+
attributes << "argument :#{k}, Boolean, required: false"
|
50
|
+
when :decimal
|
51
|
+
attributes << "argument :#{k}, Float, required: false"
|
52
|
+
when :date, :datetime
|
53
|
+
attributes << "argument :#{k}, Types::TimeType, required: false"
|
54
|
+
else
|
55
|
+
raise "Type non défini: #{v.type.inspect}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
associations = []
|
60
|
+
%i[belongs_to has_one].each do |association_type|
|
61
|
+
class_name.constantize.reflect_on_all_associations(association_type).each do |asso|
|
62
|
+
class_name = asso.options.dig(:class_name) || asso.name.to_s.singularize.camelcase
|
63
|
+
associations << "field :#{asso.name}, Types::#{class_name}Type"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
[:has_many].each do |association_type|
|
67
|
+
class_name.constantize.reflect_on_all_associations(association_type).each do |asso|
|
68
|
+
class_name = asso.options.dig(:class_name) || asso.name.to_s.singularize.camelcase
|
69
|
+
next if class_name == 'PaperTrail::Version'
|
70
|
+
|
71
|
+
associations << "field :#{asso.name}, [Types::#{class_name}Type]"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Type file
|
76
|
+
create_file "app/graphql/types/#{plural_name}/#{singular_name}_type.rb", <<~FILE
|
77
|
+
module Types
|
78
|
+
module #{plural_name.camelcase}
|
79
|
+
class #{singular_name.camelcase}Type < BaseObject
|
80
|
+
include Resolvers::TimestampsFields
|
81
|
+
|
82
|
+
#{definition.join('
|
83
|
+
')}
|
84
|
+
|
85
|
+
## Associations
|
86
|
+
|
87
|
+
#{associations.join('
|
88
|
+
')}
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
FILE
|
93
|
+
|
94
|
+
# Attributes file
|
95
|
+
create_file "app/graphql/input_object/#{singular_name}_attributes.rb", <<~FILE
|
96
|
+
module InputObject
|
97
|
+
class #{singular_name.camelcase}Attributes < AttributesInputObject
|
98
|
+
#{attributes.join('
|
99
|
+
')}
|
100
|
+
end
|
101
|
+
end
|
102
|
+
FILE
|
103
|
+
|
104
|
+
# Attributes file
|
105
|
+
create_file "app/graphql/input_object/search_#{plural_name}_attributes.rb", <<~FILE
|
106
|
+
module InputObject
|
107
|
+
class Search#{plural_name.camelcase}Attributes < AttributesInputObject
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
111
|
+
FILE
|
112
|
+
|
113
|
+
# Create mutation
|
114
|
+
create_file "app/graphql/mutations/#{plural_name}/create_#{singular_name}.rb", <<~FILE
|
115
|
+
module Mutations
|
116
|
+
class #{plural_name.camelcase}::Create#{singular_name.camelcase} < BaseMutation
|
117
|
+
field :flash_messages, [Types::JsonType], null: false
|
118
|
+
|
119
|
+
argument :attributes, InputObject::#{singular_name.camelcase}Attributes, required: true
|
120
|
+
|
121
|
+
def authorized?(attributes:)
|
122
|
+
context[:current_user].can?(:create, #{singular_name})
|
123
|
+
end
|
124
|
+
|
125
|
+
def resolve(attributes:)
|
126
|
+
#{singular_name} = ::#{singular_name.camelcase}.new
|
127
|
+
#{singular_name}.attributes = attributes
|
128
|
+
#{singular_name}.save!
|
129
|
+
{
|
130
|
+
#{singular_name}: #{singular_name},
|
131
|
+
flash_messages: [
|
132
|
+
{
|
133
|
+
type: 'success',
|
134
|
+
message: I18n.t(:'flashes.#{plural_name}.create.success')
|
135
|
+
}
|
136
|
+
]
|
137
|
+
}
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
FILE
|
142
|
+
|
143
|
+
# Update mutation
|
144
|
+
create_file "app/graphql/mutations/#{plural_name}/update_#{singular_name}.rb", <<~FILE
|
145
|
+
module Mutations
|
146
|
+
class #{plural_name.camelcase}::Update#{singular_name.camelcase} < BaseMutation
|
147
|
+
field :flash_messages, [Types::JsonType], null: false
|
148
|
+
|
149
|
+
argument :id, ID, required: true
|
150
|
+
argument :attributes, InputObject::#{singular_name.camelcase}Attributes, required: true
|
151
|
+
|
152
|
+
def authorized?(attributes:, id:)
|
153
|
+
#{singular_name} = ::#{singular_name.camelcase}.find id
|
154
|
+
context[:current_user].can?(:update, #{singular_name})
|
155
|
+
end
|
156
|
+
|
157
|
+
def resolve(attributes:, id:)
|
158
|
+
#{singular_name} = ::#{singular_name.camelcase}.find id
|
159
|
+
#{singular_name}.attributes = attributes
|
160
|
+
#{singular_name}.save!
|
161
|
+
{
|
162
|
+
flash_messages: [
|
163
|
+
#{singular_name}: #{singular_name},
|
164
|
+
{
|
165
|
+
type: 'success',
|
166
|
+
message: I18n.t(:'flashes.#{plural_name}.update.success')
|
167
|
+
}
|
168
|
+
]
|
169
|
+
}
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
FILE
|
174
|
+
|
175
|
+
# Delete mutation
|
176
|
+
create_file "app/graphql/mutations/#{plural_name}/delete_#{singular_name}.rb", <<~FILE
|
177
|
+
module Mutations
|
178
|
+
class #{plural_name.camelcase}::Delete#{singular_name.camelcase} < BaseMutation
|
179
|
+
field :flash_messages, [Types::JsonType], null: false
|
180
|
+
|
181
|
+
argument :id, ID, required: true
|
182
|
+
|
183
|
+
def authorized?(id:)
|
184
|
+
#{singular_name} = ::#{singular_name.camelcase}.find id
|
185
|
+
context[:current_user].can?(:destroy, #{singular_name})
|
186
|
+
end
|
187
|
+
|
188
|
+
def resolve(id:)
|
189
|
+
#{singular_name} = ::#{singular_name.camelcase}.find id
|
190
|
+
#{singular_name}.destroy!
|
191
|
+
{
|
192
|
+
flash_messages: [
|
193
|
+
{
|
194
|
+
type: 'success',
|
195
|
+
message: I18n.t(:'flashes.#{plural_name}.delete.success')
|
196
|
+
}
|
197
|
+
]
|
198
|
+
}
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
FILE
|
203
|
+
|
204
|
+
puts 'Do you want to create the payload file ? (y/n)'
|
205
|
+
input = $stdin.gets.strip
|
206
|
+
if input == 'y'
|
207
|
+
create_file "app/graphql/types/#{singular_name}/#{singular_name}_list_payload.rb", <<~FILE
|
208
|
+
module Types
|
209
|
+
module #{singular_name.camelcase}
|
210
|
+
class #{singular_name.camelcase}ListPayload < BaseObject
|
211
|
+
field :#{plural_name}, [#{singular_name.camelcase}::#{singular_name.camelcase}Type], null: true
|
212
|
+
field :pagination, PaginationType, null: true
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
FILE
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module NtqTools
|
2
|
+
module Generators
|
3
|
+
class InstallGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path("../../templates", __FILE__)
|
5
|
+
|
6
|
+
def copy_initializer_file
|
7
|
+
template "ntq_tools.rb", "config/initializers/ntq_tools.rb"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
NtqTools.setup do |config|
|
2
|
+
|
3
|
+
# Impersonation allow to sign in as user without password or Oauth
|
4
|
+
## impersonation_label can be defined on model for customizing the select label
|
5
|
+
## after_impersonation_path can be defined for specifying path redirection of resource
|
6
|
+
config.impersonation_enabled = true
|
7
|
+
config.impersonation_user_models = ["User"]
|
8
|
+
|
9
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module NtqTools
|
2
|
+
module Translations
|
3
|
+
module HashUtils
|
4
|
+
def dig_set(obj, keys, value)
|
5
|
+
key = keys.first
|
6
|
+
if keys.length == 1
|
7
|
+
obj[key] = value
|
8
|
+
else
|
9
|
+
obj[key] = {} unless obj[key]
|
10
|
+
dig_set(obj[key], keys.slice(1..-1), value)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'ntq_tools/translations/yaml_tool'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module NtqTools
|
5
|
+
module Translations
|
6
|
+
class TranslationTool
|
7
|
+
@@yamls_by_language = nil
|
8
|
+
|
9
|
+
def self.load_files(file_pathnames)
|
10
|
+
@@yamls_by_language = {}
|
11
|
+
I18n.available_locales.each do |locale|
|
12
|
+
@@yamls_by_language[locale.to_s] = {} unless @@yamls_by_language[locale.to_s]
|
13
|
+
|
14
|
+
locales_file = file_pathnames.select{|path| path.include?("#{locale}.yml")}
|
15
|
+
locales_file.each do |path|
|
16
|
+
next if @@yamls_by_language[locale.to_s][path]
|
17
|
+
|
18
|
+
@@yamls_by_language[locale.to_s][path] = YamlTool.new(path)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.path_for_scope(locale, scope = nil)
|
24
|
+
filename = [scope, locale.to_s, "yml"].reject(&:blank?).join(".")
|
25
|
+
"#{::Rails.root}/config/locales/#{filename}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.file_exists_for_scope?(locale, scope = nil)
|
29
|
+
File.exists?(path_for_scope(locale, scope))
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.create_locale_file(locale, scope = nil)
|
33
|
+
puts "Creating a file at #{path_for_scope(locale, scope)}"
|
34
|
+
path = path_for_scope(locale, scope)
|
35
|
+
File.open(path, "w+") { |file| file.write({ "#{locale.to_s}": nil }.to_yaml) }
|
36
|
+
@@yamls_by_language[locale.to_s] = {} unless @@yamls_by_language[locale.to_s]
|
37
|
+
@@yamls_by_language[locale.to_s][path] = YamlTool.new(path)
|
38
|
+
true
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.key_is_in_file(file, locale, key)
|
42
|
+
key = [locale.to_s, key].join('.') if file.get_value(locale.to_s)
|
43
|
+
file.get_value(key).present?
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.search_key_for_locale(locale, searched_key)
|
47
|
+
files = @@yamls_by_language[locale.to_s] || []
|
48
|
+
files.each do |pathname, file|
|
49
|
+
found = key_is_in_file(file, locale, searched_key)
|
50
|
+
|
51
|
+
return file if found
|
52
|
+
|
53
|
+
k = searched_key.split(".")
|
54
|
+
if k[0..-2].length > 0
|
55
|
+
file = search_key_for_locale(locale, k[0..-2].join("."))
|
56
|
+
return file if file
|
57
|
+
end
|
58
|
+
end
|
59
|
+
nil
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.modify(key, values)
|
63
|
+
puts key
|
64
|
+
puts values.inspect
|
65
|
+
config_folder = "#{::Rails.root}/config/locales/*.yml"
|
66
|
+
file_pathnames = Dir[config_folder]
|
67
|
+
return unless file_pathnames && file_pathnames.size > 0
|
68
|
+
|
69
|
+
load_files(file_pathnames) unless @@yamls_by_language
|
70
|
+
|
71
|
+
available_locales = I18n.available_locales.map(&:to_s)
|
72
|
+
|
73
|
+
default_scope = search_key_for_locale(I18n.default_locale, key)&.filename
|
74
|
+
default_scope = "" unless default_scope
|
75
|
+
|
76
|
+
values.each do |locale, v|
|
77
|
+
next unless available_locales.include?(locale.to_s) || v.blank?
|
78
|
+
|
79
|
+
scope = search_key_for_locale(locale, key)&.filename
|
80
|
+
if !scope
|
81
|
+
create_locale_file(locale, default_scope) unless file_exists_for_scope?(locale, default_scope)
|
82
|
+
scope = default_scope
|
83
|
+
end
|
84
|
+
yaml = @@yamls_by_language[locale.to_s][path_for_scope(locale, scope)]
|
85
|
+
key = [locale.to_s, key].join('.') if yaml.get_value(locale.to_s)
|
86
|
+
yaml.set_value(key, v) if yaml
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'ntq_tools/translations/hash_utils'
|
3
|
+
|
4
|
+
module NtqTools
|
5
|
+
module Translations
|
6
|
+
class YamlTool
|
7
|
+
include HashUtils
|
8
|
+
|
9
|
+
attr_accessor :filepath, :file, :content, :filename
|
10
|
+
|
11
|
+
def initialize(filepath)
|
12
|
+
@filepath = filepath
|
13
|
+
@file = File.open(filepath)
|
14
|
+
@content = YAML.load(@file.read)
|
15
|
+
name = filepath.split("/").last.split(".")
|
16
|
+
name = name.size <= 2 ? nil : name.first
|
17
|
+
@filename = name
|
18
|
+
end
|
19
|
+
|
20
|
+
def write_content
|
21
|
+
return false unless @content
|
22
|
+
|
23
|
+
File.write(filepath, @content.to_yaml)
|
24
|
+
true
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_value(key)
|
28
|
+
keys = (key.is_a?(Array) ? key : key.split('.')).map(&:to_s)
|
29
|
+
@content.dig(*keys)
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_value(key, value)
|
33
|
+
keys = (key.is_a?(Array) ? key : key.split('.')).map(&:to_s)
|
34
|
+
new_content = dig_set(@content, keys, value)
|
35
|
+
write_content
|
36
|
+
new_content
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/ntq_tools.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "ntq_tools/version"
|
2
|
+
require "ntq_tools/engine"
|
3
|
+
|
4
|
+
module NtqTools
|
5
|
+
|
6
|
+
mattr_accessor :impersonation_enabled
|
7
|
+
@@impersonation_enabled = false
|
8
|
+
|
9
|
+
mattr_accessor :impersonation_user_models
|
10
|
+
@@impersonation_user_models = []
|
11
|
+
|
12
|
+
def self.setup
|
13
|
+
yield self
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ntq_tools
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kevin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-02-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "<"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '8'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '6'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "<"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '8'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '6'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: missing_translation
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "<"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 1.0.0
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "<"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 1.0.0
|
47
|
+
description: Boite à outil de 9troisquarts
|
48
|
+
email:
|
49
|
+
- kevin@9troisquarts.com
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- MIT-LICENSE
|
55
|
+
- README.md
|
56
|
+
- Rakefile
|
57
|
+
- app/assets/config/ntq_tools_manifest.js
|
58
|
+
- app/assets/stylesheets/ntq_tools/application.css
|
59
|
+
- app/controllers/ntq_tools/application_controller.rb
|
60
|
+
- app/controllers/ntq_tools/impersonation_controller.rb
|
61
|
+
- app/controllers/ntq_tools/translations_controller.rb
|
62
|
+
- app/helpers/ntq_tools/application_helper.rb
|
63
|
+
- app/jobs/ntq_tools/application_job.rb
|
64
|
+
- app/mailers/ntq_tools/application_mailer.rb
|
65
|
+
- app/models/ntq_tools/application_record.rb
|
66
|
+
- app/views/layouts/ntq_tools/application.html.erb
|
67
|
+
- config/routes.rb
|
68
|
+
- lib/generators/ntq_tools/graphql_scaffold_generator.rb
|
69
|
+
- lib/generators/ntq_tools/install_generator.rb
|
70
|
+
- lib/generators/templates/ntq_tools.rb
|
71
|
+
- lib/ntq_tools.rb
|
72
|
+
- lib/ntq_tools/engine.rb
|
73
|
+
- lib/ntq_tools/translations/hash_utils.rb
|
74
|
+
- lib/ntq_tools/translations/translation_tool.rb
|
75
|
+
- lib/ntq_tools/translations/yaml_tool.rb
|
76
|
+
- lib/ntq_tools/version.rb
|
77
|
+
- lib/tasks/ntq_tools_tasks.rake
|
78
|
+
homepage: https://github.com
|
79
|
+
licenses:
|
80
|
+
- MIT
|
81
|
+
metadata:
|
82
|
+
homepage_uri: https://github.com
|
83
|
+
source_code_uri: https://github.com
|
84
|
+
changelog_uri: https://github.com
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options: []
|
87
|
+
require_paths:
|
88
|
+
- lib
|
89
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
requirements: []
|
100
|
+
rubygems_version: 3.3.7
|
101
|
+
signing_key:
|
102
|
+
specification_version: 4
|
103
|
+
summary: Toolkit 9tq
|
104
|
+
test_files: []
|