remote_translation_loader 1.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +130 -72
- data/lib/remote_translation_loader/fetchers/base_fetcher.rb +17 -0
- data/lib/remote_translation_loader/fetchers/file_fetcher.rb +16 -0
- data/lib/remote_translation_loader/fetchers/http_fetcher.rb +13 -0
- data/lib/remote_translation_loader/fetchers/s3_fetcher.rb +18 -0
- data/lib/remote_translation_loader/loader.rb +47 -0
- data/lib/remote_translation_loader/tasks/remote_translation_loader.rake +11 -0
- data/lib/remote_translation_loader/version.rb +1 -1
- data/lib/remote_translation_loader.rb +5 -48
- metadata +12 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 92eee5223d395967a5ed0da0f77e8b0082596974847bf384b39a4bec420f6c4f
|
4
|
+
data.tar.gz: 9353b66874cf73808bbf137ec49ddc0cb5f32b968fce808ff249ec7aa88e8308
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ea0fdabb80e283838537963f7e06c6cd26f0880e12d56398fb799437146775cf940a6a0f85df31409c1feebb1da0f69cb266b9731393f8626022dcbc385e39a3
|
7
|
+
data.tar.gz: 873aa22bd67fb54947a4e4eb66033891003d3d008da58a5189110ef69df45d3de0040df8b77accb26dde183ba8f5b9aef7bec1ea04e5ae760ad3d245d35f826c
|
data/README.md
CHANGED
@@ -1,15 +1,24 @@
|
|
1
|
-
#
|
1
|
+
# RemoteTranslationLoader
|
2
2
|
|
3
|
-
|
3
|
+
**RemoteTranslationLoader** is a Ruby gem designed to dynamically fetch and load translation files (YAML format) into your Ruby or Ruby on Rails application. It supports multiple sources such as HTTP URLs, local files, and AWS S3, allowing you to seamlessly integrate external translations.
|
4
4
|
|
5
|
-
|
5
|
+
---
|
6
6
|
|
7
|
-
|
8
|
-
- Merge remote translations with local translations
|
9
|
-
- Directly load translations into Rails I18n without writing to files
|
10
|
-
- Handles YAML parsing errors and HTTP request failures
|
7
|
+
## **Features**
|
11
8
|
|
12
|
-
|
9
|
+
- Fetch translations from multiple sources:
|
10
|
+
- **HTTP URLs**
|
11
|
+
- **Local files**
|
12
|
+
- **AWS S3 buckets**
|
13
|
+
- Supports deep merging of translations with existing `I18n` backend.
|
14
|
+
- Namespace support for isolating translations.
|
15
|
+
- Dry-run mode to simulate translation loading.
|
16
|
+
- Rake tasks for easy integration with Rails applications.
|
17
|
+
- CLI tool for manual loading.
|
18
|
+
|
19
|
+
---
|
20
|
+
|
21
|
+
## **Installation**
|
13
22
|
|
14
23
|
Add this line to your application's Gemfile:
|
15
24
|
|
@@ -17,120 +26,169 @@ Add this line to your application's Gemfile:
|
|
17
26
|
gem 'remote_translation_loader'
|
18
27
|
```
|
19
28
|
|
20
|
-
|
29
|
+
And then execute:
|
21
30
|
|
22
31
|
```bash
|
23
32
|
bundle install
|
24
33
|
```
|
25
34
|
|
26
|
-
Or install it
|
35
|
+
Or install it directly:
|
27
36
|
|
28
37
|
```bash
|
29
38
|
gem install remote_translation_loader
|
30
39
|
```
|
31
40
|
|
32
|
-
|
41
|
+
---
|
33
42
|
|
34
|
-
|
43
|
+
## **Usage**
|
35
44
|
|
36
|
-
|
45
|
+
### **Basic Usage**
|
37
46
|
|
38
|
-
|
47
|
+
#### **1. HTTP Fetching**
|
48
|
+
```ruby
|
49
|
+
require 'remote_translation_loader'
|
39
50
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
])
|
45
|
-
```
|
51
|
+
urls = ['https://example.com/en.yml', 'https://example.com/fr.yml']
|
52
|
+
loader = RemoteTranslationLoader::Loader.new(urls)
|
53
|
+
loader.fetch_and_load
|
54
|
+
```
|
46
55
|
|
47
|
-
2.
|
56
|
+
#### **2. Local File Fetching**
|
57
|
+
```ruby
|
58
|
+
require 'remote_translation_loader'
|
48
59
|
|
49
|
-
|
60
|
+
files = ['/path/to/local/en.yml', '/path/to/local/fr.yml']
|
61
|
+
loader = RemoteTranslationLoader::Loader.new(files, fetcher: RemoteTranslationLoader::Fetchers::FileFetcher.new)
|
62
|
+
loader.fetch_and_load
|
63
|
+
```
|
50
64
|
|
51
|
-
|
52
|
-
|
53
|
-
|
65
|
+
#### **3. AWS S3 Fetching**
|
66
|
+
```ruby
|
67
|
+
require 'remote_translation_loader'
|
68
|
+
|
69
|
+
bucket = 'your-s3-bucket'
|
70
|
+
s3_fetcher = RemoteTranslationLoader::Fetchers::S3Fetcher.new(bucket, region: 'us-east-1')
|
71
|
+
keys = ['translations/en.yml', 'translations/fr.yml']
|
54
72
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
- Merge the remote translations with your existing local translations
|
59
|
-
- Load the merged translations into Rails I18n
|
73
|
+
loader = RemoteTranslationLoader::Loader.new(keys, fetcher: s3_fetcher)
|
74
|
+
loader.fetch_and_load
|
75
|
+
```
|
60
76
|
|
61
|
-
|
77
|
+
---
|
62
78
|
|
79
|
+
### **Advanced Options**
|
80
|
+
|
81
|
+
#### **Namespace Support**
|
82
|
+
Add a namespace to group translations under a specific key:
|
63
83
|
```ruby
|
64
|
-
|
84
|
+
loader.fetch_and_load(namespace: 'remote')
|
85
|
+
# Translations will be grouped under the `remote` key, e.g., `remote.en.some_key`
|
86
|
+
```
|
65
87
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
88
|
+
#### **Dry-Run Mode**
|
89
|
+
Simulate the loading process without modifying the `I18n` backend:
|
90
|
+
```ruby
|
91
|
+
loader.fetch_and_load(dry_run: true)
|
92
|
+
# Outputs fetched translations to the console without loading them
|
93
|
+
```
|
71
94
|
|
72
|
-
|
73
|
-
loader.fetch_and_load
|
95
|
+
---
|
74
96
|
|
75
|
-
|
76
|
-
|
97
|
+
## **CLI Usage**
|
98
|
+
|
99
|
+
Install the gem globally and use the CLI tool:
|
100
|
+
|
101
|
+
```bash
|
102
|
+
remote_translation_loader https://example.com/en.yml /path/to/local/fr.yml
|
77
103
|
```
|
78
104
|
|
79
|
-
|
105
|
+
- The CLI fetches and loads the specified translations.
|
106
|
+
- Add the executable to your `$PATH` for easier access.
|
80
107
|
|
81
|
-
|
82
|
-
- **Invalid YAML Content**: If the remote YAML file is invalid, a `RuntimeError` will be raised with a message indicating a YAML parsing error.
|
83
|
-
- **HTTP Request Failures**: If fetching the remote YAML file fails, a `RuntimeError` will be raised with a message indicating the failure.
|
108
|
+
---
|
84
109
|
|
85
|
-
|
110
|
+
## **Rails Integration**
|
86
111
|
|
87
|
-
|
112
|
+
### **1. Rake Task**
|
113
|
+
Use the provided Rake task to fetch translations in a Rails application:
|
88
114
|
|
115
|
+
#### Add this to your `Rakefile`:
|
89
116
|
```ruby
|
90
|
-
|
91
|
-
|
92
|
-
rescue RuntimeError => e
|
93
|
-
puts "An error occurred: #{e.message}"
|
94
|
-
end
|
117
|
+
require 'remote_translation_loader'
|
118
|
+
load 'remote_translation_loader/tasks/remote_translation_loader.rake'
|
95
119
|
```
|
96
120
|
|
97
|
-
|
121
|
+
#### Run the task:
|
122
|
+
```bash
|
123
|
+
rake translations:load[https://example.com/en.yml,/path/to/local/fr.yml]
|
124
|
+
```
|
98
125
|
|
99
|
-
|
126
|
+
### **2. Automatic Loading**
|
100
127
|
|
101
|
-
|
128
|
+
Add an initializer to load translations on application startup:
|
102
129
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
130
|
+
#### `config/initializers/remote_translation_loader.rb`
|
131
|
+
```ruby
|
132
|
+
require 'remote_translation_loader'
|
133
|
+
|
134
|
+
urls = ['https://example.com/en.yml', '/path/to/local/fr.yml']
|
135
|
+
loader = RemoteTranslationLoader::Loader.new(urls)
|
136
|
+
loader.fetch_and_load(namespace: 'remote')
|
137
|
+
```
|
138
|
+
|
139
|
+
---
|
140
|
+
|
141
|
+
## **Contributing**
|
107
142
|
|
108
|
-
|
143
|
+
We welcome contributions! Follow these steps:
|
109
144
|
|
145
|
+
1. Fork the repository.
|
146
|
+
2. Create your feature branch:
|
110
147
|
```bash
|
111
|
-
|
148
|
+
git checkout -b feature/my-new-feature
|
149
|
+
```
|
150
|
+
3. Commit your changes:
|
151
|
+
```bash
|
152
|
+
git commit -m 'Add some feature'
|
112
153
|
```
|
154
|
+
4. Push the branch:
|
155
|
+
```bash
|
156
|
+
git push origin feature/my-new-feature
|
157
|
+
```
|
158
|
+
5. Create a pull request.
|
159
|
+
|
160
|
+
---
|
113
161
|
|
114
|
-
|
162
|
+
## **Development**
|
115
163
|
|
116
|
-
|
164
|
+
To work on the gem locally:
|
117
165
|
|
166
|
+
1. Clone the repository:
|
167
|
+
```bash
|
168
|
+
git clone https://github.com/gklsan/remote_translation_loader.git
|
169
|
+
cd remote_translation_loader
|
170
|
+
```
|
171
|
+
2. Install dependencies:
|
172
|
+
```bash
|
173
|
+
bundle install
|
174
|
+
```
|
175
|
+
3. Run tests:
|
118
176
|
```bash
|
119
|
-
|
177
|
+
rspec
|
120
178
|
```
|
121
179
|
|
122
|
-
|
180
|
+
---
|
123
181
|
|
124
|
-
|
182
|
+
## **License**
|
125
183
|
|
126
|
-
|
184
|
+
This gem is released under the MIT License. See the [LICENSE](LICENSE) file for details.
|
127
185
|
|
128
|
-
|
186
|
+
---
|
129
187
|
|
130
|
-
##
|
188
|
+
## **Acknowledgments**
|
131
189
|
|
132
|
-
|
190
|
+
A big thanks to the open-source community for the inspiration and support. Special mention to contributors who helped shape this gem!
|
133
191
|
|
134
|
-
|
192
|
+
---
|
135
193
|
|
136
|
-
For questions or
|
194
|
+
For questions, bug reports, or feature requests, feel free to [open an issue](https://github.com/gklsan/remote_translation_loader/issues). 🚀
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RemoteTranslationLoader
|
4
|
+
module Fetchers
|
5
|
+
class BaseFetcher
|
6
|
+
def fetch(_source)
|
7
|
+
raise NotImplementedError, "Subclasses must implement the `fetch` method"
|
8
|
+
end
|
9
|
+
|
10
|
+
def parse(content)
|
11
|
+
YAML.safe_load(content)
|
12
|
+
rescue Psych::SyntaxError => e
|
13
|
+
raise "Failed to parse content: #{e.message}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'http'
|
4
|
+
|
5
|
+
module RemoteTranslationLoader
|
6
|
+
module Fetchers
|
7
|
+
class HttpFetcher < BaseFetcher
|
8
|
+
def fetch(url)
|
9
|
+
response = HTTP.get(url)
|
10
|
+
raise "Failed to fetch data from #{url}" unless response.status.success?
|
11
|
+
|
12
|
+
parse(response.body.to_s)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'aws-sdk-s3'
|
4
|
+
|
5
|
+
module RemoteTranslationLoader
|
6
|
+
module Fetchers
|
7
|
+
class S3Fetcher < BaseFetcher
|
8
|
+
def initialize(s3_client = Aws::S3::Client.new)
|
9
|
+
@s3_client = s3_client
|
10
|
+
end
|
11
|
+
|
12
|
+
def fetch(bucket, key)
|
13
|
+
response = @s3_client.get_object(bucket: bucket, key: key)
|
14
|
+
parse(response.body.read)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'i18n'
|
2
|
+
|
3
|
+
module RemoteTranslationLoader
|
4
|
+
class Loader
|
5
|
+
def initialize(urls, fetcher: Fetchers::HttpFetcher.new)
|
6
|
+
@urls = urls
|
7
|
+
@fetcher = fetcher
|
8
|
+
end
|
9
|
+
|
10
|
+
def fetch_and_load(dry_run: false, namespace: nil)
|
11
|
+
@urls.each do |url|
|
12
|
+
content = @fetcher.fetch(url)
|
13
|
+
validate_translations!(content)
|
14
|
+
|
15
|
+
if dry_run
|
16
|
+
puts "Simulating loading for #{url}: #{content.inspect}"
|
17
|
+
else
|
18
|
+
merge_into_i18n(content, namespace: namespace)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def validate_translations!(translations)
|
26
|
+
raise "Invalid translations format!" unless translations.is_a?(Hash)
|
27
|
+
end
|
28
|
+
|
29
|
+
def merge_into_i18n(content, namespace: nil)
|
30
|
+
content.each do |locale, translations|
|
31
|
+
next unless translations.is_a?(Hash)
|
32
|
+
|
33
|
+
translations = { namespace => translations } if namespace
|
34
|
+
existing = I18n.backend.send(:translations)[locale.to_sym] || {}
|
35
|
+
merged = deep_merge(existing, translations)
|
36
|
+
I18n.backend.store_translations(locale.to_sym, merged)
|
37
|
+
end
|
38
|
+
puts "Translations loaded successfully!"
|
39
|
+
end
|
40
|
+
|
41
|
+
def deep_merge(existing, incoming)
|
42
|
+
existing.merge(incoming) do |_, old_val, new_val|
|
43
|
+
old_val.is_a?(Hash) && new_val.is_a?(Hash) ? deep_merge(old_val, new_val) : new_val
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
namespace :translations do
|
2
|
+
desc "Fetch and load remote translations"
|
3
|
+
task :load, [:urls] => :environment do |_task, args|
|
4
|
+
urls = args[:urls].to_s.split(',')
|
5
|
+
raise "No URLs provided" if urls.empty?
|
6
|
+
|
7
|
+
loader = RemoteTranslationLoader::Loader.new(urls)
|
8
|
+
loader.fetch_and_load
|
9
|
+
puts "Translations loaded successfully!"
|
10
|
+
end
|
11
|
+
end
|
@@ -1,54 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "remote_translation_loader/version"
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
require_relative "remote_translation_loader/loader"
|
5
|
+
require_relative "remote_translation_loader/fetchers/base_fetcher"
|
6
|
+
require_relative "remote_translation_loader/fetchers/http_fetcher"
|
7
|
+
require_relative "remote_translation_loader/fetchers/file_fetcher"
|
8
|
+
require_relative "remote_translation_loader/fetchers/s3_fetcher"
|
8
9
|
|
9
10
|
module RemoteTranslationLoader
|
10
|
-
class Loader
|
11
|
-
def initialize(urls)
|
12
|
-
@urls = urls
|
13
|
-
end
|
14
|
-
|
15
|
-
def fetch_and_load
|
16
|
-
@urls.each do |url|
|
17
|
-
yml_content = fetch_yaml(url)
|
18
|
-
merge_into_i18n(yml_content)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def fetch_yaml(url)
|
25
|
-
response = HTTP.get(url)
|
26
|
-
raise "Failed to fetch YAML from #{url}" unless response.status.success?
|
27
|
-
|
28
|
-
begin
|
29
|
-
YAML.safe_load(response.body.to_s)
|
30
|
-
rescue Psych::SyntaxError => e
|
31
|
-
raise "Failed to parse YAML from #{url}: #{e.message}"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def merge_into_i18n(yml_content)
|
36
|
-
yml_content.each do |locale, remote_translations|
|
37
|
-
if remote_translations.is_a?(Hash)
|
38
|
-
existing_translations = I18n.backend.send(:translations)[locale.to_sym] || {}
|
39
|
-
merged_translations = deep_merge(existing_translations, remote_translations)
|
40
|
-
|
41
|
-
I18n.backend.store_translations(locale.to_sym, merged_translations)
|
42
|
-
else
|
43
|
-
raise "Invalid data format for locale #{locale}"
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def deep_merge(existing, incoming)
|
49
|
-
existing.merge(incoming) do |key, oldval, newval|
|
50
|
-
oldval.is_a?(Hash) && newval.is_a?(Hash) ? deep_merge(oldval, newval) : newval
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
11
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: remote_translation_loader
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gokul (gklsan)
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-11-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: http
|
@@ -81,6 +81,12 @@ files:
|
|
81
81
|
- README.md
|
82
82
|
- Rakefile
|
83
83
|
- lib/remote_translation_loader.rb
|
84
|
+
- lib/remote_translation_loader/fetchers/base_fetcher.rb
|
85
|
+
- lib/remote_translation_loader/fetchers/file_fetcher.rb
|
86
|
+
- lib/remote_translation_loader/fetchers/http_fetcher.rb
|
87
|
+
- lib/remote_translation_loader/fetchers/s3_fetcher.rb
|
88
|
+
- lib/remote_translation_loader/loader.rb
|
89
|
+
- lib/remote_translation_loader/tasks/remote_translation_loader.rake
|
84
90
|
- lib/remote_translation_loader/version.rb
|
85
91
|
- sig/remote_translation_loader.rbs
|
86
92
|
homepage: https://github.com/gklsan/remote_translation_loader
|
@@ -90,7 +96,7 @@ metadata:
|
|
90
96
|
homepage_uri: https://github.com/gklsan/remote_translation_loader
|
91
97
|
source_code_uri: https://github.com/gklsan/remote_translation_loader
|
92
98
|
changelog_uri: https://github.com/gklsan/remote_translation_loader
|
93
|
-
post_install_message:
|
99
|
+
post_install_message:
|
94
100
|
rdoc_options: []
|
95
101
|
require_paths:
|
96
102
|
- lib
|
@@ -105,8 +111,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
105
111
|
- !ruby/object:Gem::Version
|
106
112
|
version: '0'
|
107
113
|
requirements: []
|
108
|
-
rubygems_version: 3.
|
109
|
-
signing_key:
|
114
|
+
rubygems_version: 3.0.3.1
|
115
|
+
signing_key:
|
110
116
|
specification_version: 4
|
111
117
|
summary: Fetches and loads remote YAML translation files into Rails I18n
|
112
118
|
test_files: []
|