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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 39a20a05a27f27a7ee285c238b407b1d0053dcaf3e13d00a4c921e55e7046df9
4
- data.tar.gz: d804308dbeebe07dc34f6910cae12d795399912c502d93d2c46f35925dac9162
3
+ metadata.gz: 92eee5223d395967a5ed0da0f77e8b0082596974847bf384b39a4bec420f6c4f
4
+ data.tar.gz: 9353b66874cf73808bbf137ec49ddc0cb5f32b968fce808ff249ec7aa88e8308
5
5
  SHA512:
6
- metadata.gz: 490ec23b5607c361c6872e1cdd7d1265980744c51714e35d36d461c1946d4715a8c89ba74e375efd78a00c20763d0e573ff07d1b38bd43aa6a76c011ecadceeb
7
- data.tar.gz: 8c2e25fe0bf39717e51e76001c8387a307a8a001cc875afbf3ae9370e2670aabb1e43a1c53703d86fcc8a243e5af032b4f1302f6eeec5907d43e054c11177a62
6
+ metadata.gz: ea0fdabb80e283838537963f7e06c6cd26f0880e12d56398fb799437146775cf940a6a0f85df31409c1feebb1da0f69cb266b9731393f8626022dcbc385e39a3
7
+ data.tar.gz: 873aa22bd67fb54947a4e4eb66033891003d3d008da58a5189110ef69df45d3de0040df8b77accb26dde183ba8f5b9aef7bec1ea04e5ae760ad3d245d35f826c
data/README.md CHANGED
@@ -1,15 +1,24 @@
1
- # Remote Translation Loader [![Gem Version](https://badge.fury.io/rb/remote_translation_loader.svg)](https://badge.fury.io/rb/remote_translation_loader)
1
+ # RemoteTranslationLoader
2
2
 
3
- `remote_translation_loader` is a Ruby gem for fetching YAML translation files from remote sources and dynamically loading them into your Ruby on Rails application’s I18n translations. This gem is useful for applications that need to integrate external translations without writing them to local files.
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
- ## Features
5
+ ---
6
6
 
7
- - Fetch translation files from remote URLs
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
- ## Installation
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
- Then execute:
29
+ And then execute:
21
30
 
22
31
  ```bash
23
32
  bundle install
24
33
  ```
25
34
 
26
- Or install it yourself as:
35
+ Or install it directly:
27
36
 
28
37
  ```bash
29
38
  gem install remote_translation_loader
30
39
  ```
31
40
 
32
- ## Usage
41
+ ---
33
42
 
34
- ### Basic Setup
43
+ ## **Usage**
35
44
 
36
- 1. **Initialize the Loader**
45
+ ### **Basic Usage**
37
46
 
38
- Create an instance of the `RemoteTranslationLoader::Loader` class with a list of remote YAML URLs:
47
+ #### **1. HTTP Fetching**
48
+ ```ruby
49
+ require 'remote_translation_loader'
39
50
 
40
- ```ruby
41
- loader = RemoteTranslationLoader::Loader.new([
42
- 'https://example.com/translations/en.yml',
43
- 'https://example.com/translations/fr.yml'
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. **Fetch and Load Translations**
56
+ #### **2. Local File Fetching**
57
+ ```ruby
58
+ require 'remote_translation_loader'
48
59
 
49
- Call the `fetch_and_load` method to fetch and load the translations:
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
- ```ruby
52
- loader.fetch_and_load
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
- This will:
56
- - Fetch the YAML files from the specified URLs
57
- - Parse the YAML content
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
- ### Example
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
- require 'remote_translation_loader'
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
- # Initialize the loader with remote YAML URLs
67
- loader = RemoteTranslationLoader::Loader.new([
68
- 'https://example.com/translations/en.yml',
69
- 'https://example.com/translations/fr.yml'
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
- # Fetch and load translations
73
- loader.fetch_and_load
95
+ ---
74
96
 
75
- # Now you can use the loaded translations in your application
76
- puts I18n.t('greetings.hello') # Output will depend on the remote translation files
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
- ### Handling Errors
105
+ - The CLI fetches and loads the specified translations.
106
+ - Add the executable to your `$PATH` for easier access.
80
107
 
81
- The gem will raise errors in case of:
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
- ### Customizing Error Handling
110
+ ## **Rails Integration**
86
111
 
87
- You can customize the error handling by rescuing from `RuntimeError` or any other specific exceptions as needed:
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
- begin
91
- loader.fetch_and_load
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
- ## Development
121
+ #### Run the task:
122
+ ```bash
123
+ rake translations:load[https://example.com/en.yml,/path/to/local/fr.yml]
124
+ ```
98
125
 
99
- To contribute to the development of `remote_translation_loader`, follow these steps:
126
+ ### **2. Automatic Loading**
100
127
 
101
- 1. **Clone the Repository**
128
+ Add an initializer to load translations on application startup:
102
129
 
103
- ```bash
104
- git clone https://github.com/gklsan/remote_translation_loader.git
105
- cd remote_translation_loader
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
- 2. **Install Dependencies**
143
+ We welcome contributions! Follow these steps:
109
144
 
145
+ 1. Fork the repository.
146
+ 2. Create your feature branch:
110
147
  ```bash
111
- bundle install
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
- 3. **Run Tests**
162
+ ## **Development**
115
163
 
116
- Run the test suite to ensure everything is working correctly:
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
- bundle exec rspec
177
+ rspec
120
178
  ```
121
179
 
122
- 4. **Make Your Changes**
180
+ ---
123
181
 
124
- Implement your changes or features and ensure they are covered by tests.
182
+ ## **License**
125
183
 
126
- 5. **Submit a Pull Request**
184
+ This gem is released under the MIT License. See the [LICENSE](LICENSE) file for details.
127
185
 
128
- Push your changes to your forked repository and submit a pull request with a clear description of the changes.
186
+ ---
129
187
 
130
- ## License
188
+ ## **Acknowledgments**
131
189
 
132
- `remote_translation_loader` is licensed under the MIT License. See the [LICENSE](LICENSE) file for more details.
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
- ## Contact
192
+ ---
135
193
 
136
- For questions or support, please open an issue on [GitHub](https://github.com/gklsan/remote_translation_loader/issues).
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,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RemoteTranslationLoader
4
+ module Fetchers
5
+ class FileFetcher < BaseFetcher
6
+ def fetch(path)
7
+ raise "File not found: #{path}" unless File.exist?(path)
8
+
9
+ parse(File.read(path))
10
+ end
11
+ end
12
+ end
13
+ 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,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RemoteTranslationLoader
4
- VERSION = "1.0.3"
4
+ VERSION = "1.0.4"
5
5
  end
@@ -1,54 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "remote_translation_loader/version"
4
-
5
- require 'http'
6
- require 'yaml'
7
- require 'i18n'
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.3
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-09-08 00:00:00.000000000 Z
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.5.17
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: []