jekyll-chatgpt-translate 0.0.9 → 0.0.11
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 +4 -4
- data/.rubocop.yml +2 -2
- data/README.md +11 -2
- data/jekyll-chatgpt-translate.gemspec +1 -2
- data/lib/jekyll-chatgpt-translate/generator.rb +14 -4
- data/lib/jekyll-chatgpt-translate/ping.rb +13 -4
- data/lib/jekyll-chatgpt-translate/plain.rb +4 -3
- data/lib/jekyll-chatgpt-translate/version.rb +1 -1
- data/test/test_ping.rb +7 -2
- data/test/test_plain.rb +8 -0
- metadata +2 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c02caba7176953aa1d0df4bbe92e40dcf7f1046b22f9f2af8dcd434179d36a00
|
4
|
+
data.tar.gz: 6d510fbdc601a7f7174194b39a17402e8e3aff08ff40190e8799d897eaf1aded
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a4224dd0584ed1d6ed56e876e4678de0dcba0a2338dba08bfa61a3147365ddec617116ed92f4616799b182c127f5d4509ab114e02659ca87dad1cd1e6fe9825c
|
7
|
+
data.tar.gz: ac6ed731ca359ccc2021be00c232c60271a212c0f68dd5ca4e0212ef7ebf6bb26c2a94decae2422fc17c80e5c880e52aea407d175b22a19ae0dd544da4d485e6
|
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -4,7 +4,10 @@
|
|
4
4
|
[](http://badge.fury.io/rb/jekyll-chatgpt-translate)
|
5
5
|
|
6
6
|
If you have a [Jekyll](https://jekyllrb.com/) static site, this plugin may help you automatically
|
7
|
-
translate its pages to another language, through [ChatGPT](https://chat.openai.com/).
|
7
|
+
translate its pages to another language, through [ChatGPT](https://chat.openai.com/). See how it
|
8
|
+
works for [my blog](https://github.com/yegor256/ru.yegor256.com),
|
9
|
+
for example [this page](https://ru.yegor256.com/2023-08-13-dictators.html) is translated to
|
10
|
+
[English]().
|
8
11
|
|
9
12
|
Install it first:
|
10
13
|
|
@@ -39,7 +42,8 @@ You can get your key [here](https://help.openai.com/en/articles/4936850-where-do
|
|
39
42
|
Inside the original page you can use `{{ page.translated-XX-url }}` in order to render the URL
|
40
43
|
of the translated page, where `XX` is the ISO-839-1 code of the target language..
|
41
44
|
Inside the translated page you can use `{{ page.translated-original-url }}` in order
|
42
|
-
to get the URL of the page that was translated.
|
45
|
+
to get the URL of the page that was translated. You can also use `{{ page.chatgpt-model }}`
|
46
|
+
inside both the original page and the translated one, to refer to the model of ChatGPT.
|
43
47
|
|
44
48
|
## Options
|
45
49
|
|
@@ -65,6 +69,11 @@ This layout will be specified for the pages generated by this plugin.
|
|
65
69
|
|
66
70
|
* `threshold` (optional) — maximum number of pages to generate in one build cycle.
|
67
71
|
|
72
|
+
* `version` (optional) — the version that will be attached to each generated page,
|
73
|
+
in order to avoid repetitive translations on one hand and enable re-translations
|
74
|
+
when the `version` is changed on another hand. By default, the version of
|
75
|
+
the plugin will be used here, unless you set your own value.
|
76
|
+
|
68
77
|
## How to Contribute
|
69
78
|
|
70
79
|
Make a fork and then test it locally like this:
|
@@ -28,7 +28,7 @@ Gem::Specification.new do |s|
|
|
28
28
|
s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
|
29
29
|
s.required_ruby_version = '>= 2.6'
|
30
30
|
s.name = 'jekyll-chatgpt-translate'
|
31
|
-
s.version = '0.0.
|
31
|
+
s.version = '0.0.11'
|
32
32
|
s.license = 'MIT'
|
33
33
|
s.summary = 'Translate Jekyll Pages Through ChatGPT'
|
34
34
|
s.description = [
|
@@ -45,7 +45,6 @@ Gem::Specification.new do |s|
|
|
45
45
|
s.add_runtime_dependency 'iri', '>= 0'
|
46
46
|
s.add_runtime_dependency 'iso-639', '>= 0'
|
47
47
|
s.add_runtime_dependency 'jekyll', '>= 3'
|
48
|
-
s.add_runtime_dependency 'liquid', '>= 4'
|
49
48
|
s.add_runtime_dependency 'redcarpet', '>= 3'
|
50
49
|
s.add_runtime_dependency 'ruby-openai', '>= 5'
|
51
50
|
s.metadata['rubygems_mfa_required'] = 'true'
|
@@ -50,6 +50,7 @@ class GptTranslate::Generator < Jekyll::Generator
|
|
50
50
|
return
|
51
51
|
end
|
52
52
|
layout = config['layout'] || 'translated'
|
53
|
+
version = config['version'] || GptTranslate::VERSION
|
53
54
|
threshold = config['threshold'] || 1_000_000_000
|
54
55
|
start = Time.now
|
55
56
|
total = 0
|
@@ -57,7 +58,7 @@ class GptTranslate::Generator < Jekyll::Generator
|
|
57
58
|
plain = GptTranslate::Plain.new(doc.content).to_s
|
58
59
|
config['targets'].each do |target|
|
59
60
|
link = GptTranslate::Permalink.new(doc, target['permalink']).to_path
|
60
|
-
next if GptTranslate::Ping.new(site, link).
|
61
|
+
next if GptTranslate::Ping.new(site, link).found?(doc.path)
|
61
62
|
lang = target['language']
|
62
63
|
raise 'Language must be defined for each target' if target.nil?
|
63
64
|
model = config['model'] || 'gpt-3.5-turbo'
|
@@ -82,14 +83,16 @@ class GptTranslate::Generator < Jekyll::Generator
|
|
82
83
|
"title: #{doc.data['title']}",
|
83
84
|
"permalink: #{link}",
|
84
85
|
"translated-original-url: #{doc.url}",
|
86
|
+
"chatgpt-model: #{model}",
|
85
87
|
'---',
|
86
88
|
'',
|
87
89
|
translated,
|
88
90
|
'',
|
89
|
-
"Translated by ChatGPT #{model}/#{
|
91
|
+
"Translated by ChatGPT #{model}/#{version}\n{: .jekyll-chatgpt-translate}"
|
90
92
|
].join("\n")
|
91
93
|
)
|
92
94
|
doc.data["translated-#{lang}-url"] = link
|
95
|
+
doc.data['chatgpt-model'] = model
|
93
96
|
site.pages << Jekyll::Page.new(site, site.source, File.dirname(path), File.basename(path))
|
94
97
|
total += 1
|
95
98
|
Jekyll.logger.info("Translated via ChatGPT: #{path}")
|
@@ -106,9 +109,16 @@ class GptTranslate::Generator < Jekyll::Generator
|
|
106
109
|
def api_key(config)
|
107
110
|
file = config['api_key_file']
|
108
111
|
key = if file.nil?
|
109
|
-
ENV.fetch('OPENAI_API_KEY', nil)
|
112
|
+
k = ENV.fetch('OPENAI_API_KEY', nil)
|
113
|
+
Jekyll.logger.info('The key is found in the OPENAI_API_KEY env variable') unless k.nil?
|
114
|
+
k
|
110
115
|
elsif File.exist?(file)
|
111
|
-
File.read(file).strip
|
116
|
+
k = File.read(file).strip
|
117
|
+
Jekyll.logger.info("The OpenAI API key taken from the file: \"#{file}\" (#{k.length} chars)")
|
118
|
+
k
|
119
|
+
else
|
120
|
+
Jekyll.logger.info("The file with the OpenAI API key is not found: \"#{file}\"")
|
121
|
+
nil
|
112
122
|
end
|
113
123
|
if key.nil? && Jekyll.env == 'development'
|
114
124
|
Jekyll.logger.info("OPENAI_API_KEY environment variable is not set, \
|
@@ -46,14 +46,23 @@ class GptTranslate::Ping
|
|
46
46
|
@path = path
|
47
47
|
end
|
48
48
|
|
49
|
-
def
|
49
|
+
def found?(file)
|
50
50
|
home = @site.config['url']
|
51
51
|
return false if home.nil?
|
52
52
|
uri = Iri.new(home).path(@path)
|
53
53
|
before = Net::HTTP.get_response(URI(uri.to_s))
|
54
|
-
if before.is_a?(Net::HTTPSuccess)
|
55
|
-
|
56
|
-
|
54
|
+
if before.is_a?(Net::HTTPSuccess)
|
55
|
+
html = before.body
|
56
|
+
if html.include?("/#{GptTranslate::VERSION}")
|
57
|
+
Jekyll.logger.info("No need to translate, the page exists at \
|
58
|
+
#{uri} (#{html.split.count} words), saved to #{file}")
|
59
|
+
File.mkdir_p(File.dirname(file))
|
60
|
+
File.write(file, html)
|
61
|
+
return true
|
62
|
+
end
|
63
|
+
Jekyll.logger.info("Re-translation required for #{uri}")
|
64
|
+
else
|
65
|
+
Jekyll.logger.info("The page is absent, will translate: #{uri}")
|
57
66
|
end
|
58
67
|
Jekyll.logger.debug("GET #{uri}: #{before.code}")
|
59
68
|
false
|
@@ -23,7 +23,6 @@
|
|
23
23
|
# SOFTWARE.
|
24
24
|
|
25
25
|
require 'redcarpet'
|
26
|
-
require 'liquid'
|
27
26
|
|
28
27
|
# The module we are in.
|
29
28
|
module GptTranslate; end
|
@@ -42,9 +41,11 @@ class GptTranslate::Plain
|
|
42
41
|
@markdown.split(/\n{2,}/).compact.map do |par|
|
43
42
|
par.gsub!("\n", ' ')
|
44
43
|
par.gsub!(/\s{2,}/, ' ')
|
44
|
+
# Liquid tags are removed, but this implementation is primitive
|
45
|
+
# Seehttps://stackoverflow.com/questions/
|
46
|
+
par.gsub!(/{{[^}]+}}/, '')
|
47
|
+
par.gsub!(/{%[^%]+%}/, '')
|
45
48
|
par.strip!
|
46
|
-
liquid = Liquid::Template.parse(par)
|
47
|
-
par = liquid.render({}, drop: NullDrop.new, registers: { removed: true })
|
48
49
|
Redcarpet::Markdown.new(Strip).render(par)
|
49
50
|
end.join("\n\n").gsub(/\n{2,}/, "\n\n").strip
|
50
51
|
end
|
data/test/test_ping.rb
CHANGED
@@ -25,6 +25,7 @@
|
|
25
25
|
require 'minitest/autorun'
|
26
26
|
require 'webmock/minitest'
|
27
27
|
require 'jekyll'
|
28
|
+
require 'tempfile'
|
28
29
|
require_relative '../lib/jekyll-chatgpt-translate/ping'
|
29
30
|
|
30
31
|
# Ping test.
|
@@ -44,14 +45,18 @@ class GptTranslate::PingTest < Minitest::Test
|
|
44
45
|
stub_request(:any, 'https://www.yegor256.com/about-me.html')
|
45
46
|
site = FakeSite.new({ 'url' => 'https://www.yegor256.com/' })
|
46
47
|
ping = GptTranslate::Ping.new(site, '/about-me.html')
|
47
|
-
|
48
|
+
Tempfile.open do |f|
|
49
|
+
assert(!ping.found?(f))
|
50
|
+
end
|
48
51
|
end
|
49
52
|
|
50
53
|
def test_when_not_exists
|
51
54
|
stub_request(:any, 'https://www.yegor256.com/absent.html').to_return(status: 404)
|
52
55
|
site = FakeSite.new({ 'url' => 'https://www.yegor256.com/' })
|
53
56
|
ping = GptTranslate::Ping.new(site, '/absent.html')
|
54
|
-
|
57
|
+
Tempfile.open do |f|
|
58
|
+
assert(!ping.found?(f))
|
59
|
+
end
|
55
60
|
end
|
56
61
|
|
57
62
|
def test_relative_path
|
data/test/test_plain.rb
CHANGED
@@ -81,5 +81,13 @@ class GptTranslate::PlainTest < Minitest::Test
|
|
81
81
|
'Hello, !',
|
82
82
|
GptTranslate::Plain.new('Hello, {{ Java }}!').to_s
|
83
83
|
)
|
84
|
+
assert_equal(
|
85
|
+
'Hello, dude !',
|
86
|
+
GptTranslate::Plain.new('Hello, {% if a %} dude {% endif %}!').to_s
|
87
|
+
)
|
88
|
+
assert_equal(
|
89
|
+
'Hello, !',
|
90
|
+
GptTranslate::Plain.new('Hello, {% Java %}!').to_s
|
91
|
+
)
|
84
92
|
end
|
85
93
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll-chatgpt-translate
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yegor Bugayenko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-08-
|
11
|
+
date: 2023-08-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: iri
|
@@ -52,20 +52,6 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: liquid
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '4'
|
62
|
-
type: :runtime
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '4'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: redcarpet
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|