jekyll-chatgpt-translate 0.0.10 → 0.0.12
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 +14 -2
- data/jekyll-chatgpt-translate.gemspec +1 -2
- data/lib/jekyll-chatgpt-translate/generator.rb +14 -8
- data/lib/jekyll-chatgpt-translate/ping.rb +4 -3
- data/lib/jekyll-chatgpt-translate/plain.rb +4 -3
- data/lib/jekyll-chatgpt-translate/version.rb +1 -1
- data/test/test_ping.rb +2 -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: ed6617e3b8bf46db264f484e1286ea1f91295f4fb47512cb983a6fc59c7922df
|
4
|
+
data.tar.gz: a0f6c744cd4bf2b2558d7b5568f1ca961a3f854e5264b9d64bb8b24249f03e3a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d58f41b76840e524e9f1d72c2a4816b33d9e57ad6b207f54baa226abf68ae6cca848cb8cce80cf1f4502a3ad9b52871db7f7708463bf4101fdbf8c21e5f99bb
|
7
|
+
data.tar.gz: f85b41ad75176c9989a8a3715fd84485b3a2fcbe03e6cca879b7a201ac4b5745dda0aa16695f26cbaad1ec901b84c6837f983f7a04cee94aa26752d13ef41593
|
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
|
|
@@ -64,6 +68,14 @@ This layout will be specified for the pages generated by this plugin.
|
|
64
68
|
* `layout` (optional) — the name of the file in the `_layouts` directory
|
65
69
|
|
66
70
|
* `threshold` (optional) — maximum number of pages to generate in one build cycle.
|
71
|
+
The default value is 1024. It is recommended to use smaller number, in order
|
72
|
+
to avoid too long builds. You can re-run the build again and missing pages
|
73
|
+
will be generated. Thus, in a few builds the entire site will be translated.
|
74
|
+
|
75
|
+
* `version` (optional) — the version that will be attached to each generated page,
|
76
|
+
in order to avoid repetitive translations on one hand and enable re-translations
|
77
|
+
when the `version` is changed on another hand. By default, the version of
|
78
|
+
the plugin will be used here, unless you set your own value.
|
67
79
|
|
68
80
|
## How to Contribute
|
69
81
|
|
@@ -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.12'
|
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,17 +50,19 @@ class GptTranslate::Generator < Jekyll::Generator
|
|
50
50
|
return
|
51
51
|
end
|
52
52
|
layout = config['layout'] || 'translated'
|
53
|
-
|
53
|
+
version = config['version'] || GptTranslate::VERSION
|
54
|
+
threshold = config['threshold'] || 1024
|
54
55
|
start = Time.now
|
55
56
|
total = 0
|
56
|
-
|
57
|
+
model = config['model'] || 'gpt-3.5-turbo'
|
58
|
+
marker = "Translated by ChatGPT #{model}/#{version}"
|
59
|
+
site.posts.docs.shuffle.each do |doc|
|
57
60
|
plain = GptTranslate::Plain.new(doc.content).to_s
|
58
61
|
config['targets'].each do |target|
|
59
62
|
link = GptTranslate::Permalink.new(doc, target['permalink']).to_path
|
60
|
-
next if GptTranslate::Ping.new(site, link).found?(doc.path)
|
63
|
+
next if GptTranslate::Ping.new(site, link).found?(doc.path, version)
|
61
64
|
lang = target['language']
|
62
65
|
raise 'Language must be defined for each target' if target.nil?
|
63
|
-
model = config['model'] || 'gpt-3.5-turbo'
|
64
66
|
if total >= threshold
|
65
67
|
Jekyll.logger.info("Already generated #{total} pages, that's enough for today")
|
66
68
|
break
|
@@ -82,14 +84,16 @@ class GptTranslate::Generator < Jekyll::Generator
|
|
82
84
|
"title: #{doc.data['title']}",
|
83
85
|
"permalink: #{link}",
|
84
86
|
"translated-original-url: #{doc.url}",
|
87
|
+
"chatgpt-model: #{model}",
|
85
88
|
'---',
|
86
89
|
'',
|
87
90
|
translated,
|
88
91
|
'',
|
89
|
-
"
|
92
|
+
"#{marker}\n{: .jekyll-chatgpt-translate}"
|
90
93
|
].join("\n")
|
91
94
|
)
|
92
95
|
doc.data["translated-#{lang}-url"] = link
|
96
|
+
doc.data['chatgpt-model'] = model
|
93
97
|
site.pages << Jekyll::Page.new(site, site.source, File.dirname(path), File.basename(path))
|
94
98
|
total += 1
|
95
99
|
Jekyll.logger.info("Translated via ChatGPT: #{path}")
|
@@ -110,10 +114,12 @@ class GptTranslate::Generator < Jekyll::Generator
|
|
110
114
|
Jekyll.logger.info('The key is found in the OPENAI_API_KEY env variable') unless k.nil?
|
111
115
|
k
|
112
116
|
elsif File.exist?(file)
|
113
|
-
|
114
|
-
|
117
|
+
k = File.read(file).strip
|
118
|
+
Jekyll.logger.info("The OpenAI API key taken from the file: \"#{file}\" (#{k.length} chars)")
|
119
|
+
k
|
115
120
|
else
|
116
|
-
Jekyll.logger.info("The file is not found: #{file}")
|
121
|
+
Jekyll.logger.info("The file with the OpenAI API key is not found: \"#{file}\"")
|
122
|
+
nil
|
117
123
|
end
|
118
124
|
if key.nil? && Jekyll.env == 'development'
|
119
125
|
Jekyll.logger.info("OPENAI_API_KEY environment variable is not set, \
|
@@ -25,6 +25,7 @@
|
|
25
25
|
require 'iri'
|
26
26
|
require 'net/http'
|
27
27
|
require 'uri'
|
28
|
+
require 'fileutils'
|
28
29
|
require_relative 'version'
|
29
30
|
|
30
31
|
# see https://stackoverflow.com/a/6048451/187141
|
@@ -46,17 +47,17 @@ class GptTranslate::Ping
|
|
46
47
|
@path = path
|
47
48
|
end
|
48
49
|
|
49
|
-
def found?(file)
|
50
|
+
def found?(file, marker)
|
50
51
|
home = @site.config['url']
|
51
52
|
return false if home.nil?
|
52
53
|
uri = Iri.new(home).path(@path)
|
53
54
|
before = Net::HTTP.get_response(URI(uri.to_s))
|
54
55
|
if before.is_a?(Net::HTTPSuccess)
|
55
56
|
html = before.body
|
56
|
-
if html.include?(
|
57
|
+
if html.include?(marker)
|
57
58
|
Jekyll.logger.info("No need to translate, the page exists at \
|
58
59
|
#{uri} (#{html.split.count} words), saved to #{file}")
|
59
|
-
|
60
|
+
FileUtils.mkdir_p(File.dirname(file))
|
60
61
|
File.write(file, html)
|
61
62
|
return true
|
62
63
|
end
|
@@ -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
@@ -46,7 +46,7 @@ class GptTranslate::PingTest < Minitest::Test
|
|
46
46
|
site = FakeSite.new({ 'url' => 'https://www.yegor256.com/' })
|
47
47
|
ping = GptTranslate::Ping.new(site, '/about-me.html')
|
48
48
|
Tempfile.open do |f|
|
49
|
-
assert(
|
49
|
+
assert(ping.found?(f, ''))
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -55,7 +55,7 @@ class GptTranslate::PingTest < Minitest::Test
|
|
55
55
|
site = FakeSite.new({ 'url' => 'https://www.yegor256.com/' })
|
56
56
|
ping = GptTranslate::Ping.new(site, '/absent.html')
|
57
57
|
Tempfile.open do |f|
|
58
|
-
assert(!ping.found?(f))
|
58
|
+
assert(!ping.found?(f, ''))
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
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.12
|
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
|