jekyll-chatgpt-translate 0.0.6 → 0.0.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3b2375ac0c0ab9bc728d9e1d6684b4cb1f1424ae5718095a8644a447b91487e8
4
- data.tar.gz: bf13ed8a50dad4ca6f4cdd1d719728a57e0c7081a16eda4d56bb6dbbcae5bb3d
3
+ metadata.gz: 951ecc1df96633e4552be477e42c43977b0187282978d9cb1c07bedc3913e8fa
4
+ data.tar.gz: 9fb20f291797eaee903f0ca20aaf0adcc7ed65fd77626dda6afbe3c6390418cd
5
5
  SHA512:
6
- metadata.gz: 26dbc8403f36f4bfb8c127efac666dd8884823be38b9fda7a7c92800c50f6805cfe7aa8b04251830412025ae3582a799331fdff0e8336507a6c2004fbbbbf49c
7
- data.tar.gz: 5f5cd81fd192d7945f57b23148df57ebd95f09ff8b917190ffd89cb2a8dc4d44f49afffc78d7032c0194a6a0e0aa25ce95b80d97a210cfd1cbfe9965e0a44f6c
6
+ metadata.gz: d94a2be708d58bb23427a707660276ce7d42dc90372924644b76558933c631834d3eeece4b1bb46c5b89221c3d758b62e71958137e355edb02451ef671fc9f03
7
+ data.tar.gz: 623f0e383d89805288678b37d9304d365b3adf6995d60c9bec4e7a9e6c85e2be44cb51e4a1001892cb5919a55799f99dfe9e174c5edf931f9f2e641d24ffed37
data/Gemfile CHANGED
@@ -32,3 +32,4 @@ gem 'rake', '13.0.6', require: false
32
32
  gem 'rubocop', '1.55.1', require: false
33
33
  gem 'rubocop-rspec', '2.23.2', require: false
34
34
  gem 'simplecov', '0.22.0', require: false
35
+ gem 'webmock', '3.18.1', require: false
data/features/cli.feature CHANGED
@@ -13,11 +13,11 @@ Feature: Simple site building
13
13
  targets:
14
14
  -
15
15
  language: cn
16
- permalink: :year-:month-:day-:title-chinese.html
16
+ permalink: :year-:month-:day-:slug-chinese.html
17
17
  layout: chinese-translated
18
18
  -
19
19
  language: fr
20
- permalink: :year/:title-french.html
20
+ permalink: :year/:slug-french.html
21
21
  """
22
22
  And I have a "_layouts/default.html" file with content:
23
23
  """
@@ -30,13 +30,15 @@ Feature: Simple site building
30
30
  And I have a "_posts/2023-01-01-hello.md" file with content:
31
31
  """
32
32
  ---
33
+ title: Hello, world!
33
34
  layout: default
34
35
  ---
35
36
  Hello, world!
36
37
  """
37
38
  Then I build Jekyll site
39
+ Then File "_chatgpt-translated/cn/2023-01-01-hello-cn.md" exists
38
40
  Then File "_site/2023/01/01/hello.html" exists
39
- Then File "_site/2023-01-01-Hello-chinese.html" exists
40
- Then File "_site/2023/Hello-french.html" exists
41
+ Then File "_site/2023-01-01-hello-chinese.html" exists
42
+ Then File "_site/2023/hello-french.html" exists
41
43
  And Exit code is zero
42
44
 
@@ -50,7 +50,7 @@ Then(/^Stdout contains "([^"]*)"$/) do |txt|
50
50
  end
51
51
 
52
52
  Then(/^File "([^"]*)" exists$/) do |name|
53
- raise unless File.exist?(name)
53
+ raise "The file \"#{name}\" is absent:\n#{`tree`}" unless File.exist?(name)
54
54
  end
55
55
 
56
56
  Then(/^Stdout is empty$/) do
@@ -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.6'
31
+ s.version = '0.0.7'
32
32
  s.license = 'MIT'
33
33
  s.summary = 'Translate Jekyll Pages Through ChatGPT'
34
34
  s.description = [
@@ -65,7 +65,7 @@ class GptTranslate::ChatGPT
65
65
  private
66
66
 
67
67
  def translate_par(par)
68
- Time.now
68
+ start = Time.now
69
69
  t = nil
70
70
  attempt = 0
71
71
  begin
@@ -80,26 +80,21 @@ class GptTranslate::ChatGPT
80
80
  }
81
81
  )
82
82
  t = response.dig('choices', 0, 'message', 'content')
83
- rescue StandardError
83
+ rescue StandardError => e
84
84
  attempt += 1
85
85
  retry if attempt < 4
86
+ raise e
86
87
  end
87
- if t.nil?
88
- Jekyll.logger.error("Failed to translate #{par.split.count}
89
- #{@source.upcase} words after #{attempt} attempts :(")
90
- 'FAILED TO TRANSLATE THIS PARAGRAPH'
91
- else
92
- Jekyll.logger.debug("Translated #{par.split.count} #{@source.upcase} words
93
- to #{t.split.count} #{@target.upcase} words
94
- through #{@model} in #{(Time.now - pstart).round(2)}s")
95
- t
96
- end
88
+ Jekyll.logger.info("Translated #{par.split.count} #{@source.upcase} words \
89
+ to #{t.split.count} #{@target.upcase} words \
90
+ through #{@model} in #{(Time.now - start).round(2)}s")
91
+ t
97
92
  end
98
93
 
99
94
  def prompt
100
- if (source == 'ru') && (target == 'en')
95
+ if (@source == 'ru') && (@target == 'en')
101
96
  'Пожалуйста, переведи этот параграф на английский язык'
102
- elsif (source == 'en') && (target == 'ru')
97
+ elsif (@source == 'en') && (@target == 'ru')
103
98
  'Please, translate this paragraph to Russian'
104
99
  else
105
100
  [
@@ -43,11 +43,12 @@ class GptTranslate::Generator < Jekyll::Generator
43
43
  # Main plugin action, called by Jekyll-core
44
44
  def generate(site)
45
45
  @site = site
46
+ home = '_chatgpt-translated'
46
47
  key = ENV.fetch('OPENAI_API_KEY', nil)
47
48
  if key.nil? && Jekyll.env == 'development'
48
- Jekyll.logger.info('OPENAI_API_KEY environment variable is not set and
49
- we are in development mode, no actual translation will happen,
50
- but pages will be generated')
49
+ Jekyll.logger.info("OPENAI_API_KEY environment variable is not set and \
50
+ we are in development mode, no actual translation will happen, \
51
+ but pages will be generated")
51
52
  key = ''
52
53
  end
53
54
  if key.nil?
@@ -61,7 +62,7 @@ but pages will be generated')
61
62
  site.posts.docs.each do |doc|
62
63
  plain = GptTranslate::Plain.new(doc.content).to_s
63
64
  config['targets'].each do |target|
64
- link = GptTranslate::Permalink.new(doc, target['permalink']).to_s
65
+ link = GptTranslate::Permalink.new(doc, target['permalink']).to_path
65
66
  next if GptTranslate::Ping.new(site, link).exists?
66
67
  lang = target['language']
67
68
  raise 'Language must be defined for each target' if target.nil?
@@ -77,7 +78,7 @@ but pages will be generated')
77
78
  lang
78
79
  )
79
80
  translated = gpt.translate(plain)
80
- path = "_chatgpt-translated/#{doc.basename}"
81
+ path = File.join(home, lang, doc.basename.gsub(/\.md$/, "-#{lang}.md"))
81
82
  FileUtils.mkdir_p(File.dirname(path))
82
83
  File.write(
83
84
  path,
@@ -98,7 +99,7 @@ but pages will be generated')
98
99
  end
99
100
  break if total >= threshold
100
101
  end
101
- Jekyll.logger.info("#{total} pages generated in #{(Time.now - start).round(2)}s")
102
+ Jekyll.logger.info("#{total} pages translated in #{(Time.now - start).round(2)}s")
102
103
  end
103
104
 
104
105
  private
@@ -38,11 +38,14 @@ class GptTranslate::Permalink
38
38
  @template = template
39
39
  end
40
40
 
41
- def to_s
42
- @template
41
+ def to_path
42
+ path = @template
43
43
  .gsub(':year', format('%04d', @doc['date'].year))
44
44
  .gsub(':month', format('%02d', @doc['date'].month))
45
45
  .gsub(':day', format('%02d', @doc['date'].day))
46
46
  .gsub(':title', CGI.escape(@doc['title']))
47
+ .gsub(':slug', CGI.escape(@doc['slug']))
48
+ path = "/#{path}" unless path.start_with?('/')
49
+ path
47
50
  end
48
51
  end
@@ -40,15 +40,16 @@ module GptTranslate; end
40
40
  # License:: MIT
41
41
  class GptTranslate::Ping
42
42
  # Ctor.
43
- def initialize(site, link)
43
+ def initialize(site, path)
44
44
  @site = site
45
- @link = link
45
+ raise 'Permalink must start with a slash' unless path.start_with?('/')
46
+ @path = path
46
47
  end
47
48
 
48
49
  def exists?
49
50
  home = @site.config['url']
50
51
  return false if home.nil?
51
- uri = Iri.new(home).path(@link)
52
+ uri = Iri.new(home).path(@path)
52
53
  before = Net::HTTP.get_response(URI(uri.to_s))
53
54
  if before.is_a?(Net::HTTPSuccess) && before.body.include?("/#{GptTranslate::VERSION}")
54
55
  Jekyll.logger.info("No need to translate, page exists at #{uri} (#{before.body.split.count} words)")
data/test/test_chatgpt.rb CHANGED
@@ -23,6 +23,7 @@
23
23
  # SOFTWARE.
24
24
 
25
25
  require 'minitest/autorun'
26
+ require 'webmock/minitest'
26
27
  require_relative '../lib/jekyll-chatgpt-translate/chatgpt'
27
28
 
28
29
  # ChatGPT test.
@@ -44,4 +45,11 @@ class GptTranslate::ChatGPTTest < Minitest::Test
44
45
  chat = GptTranslate::ChatGPT.new('fake-key', 'gpt-3.5-turbo', 'en', 'ru')
45
46
  assert_equal('<img src="a"/>', chat.translate('<img src="a"/>'))
46
47
  end
48
+
49
+ def test_through_webmock
50
+ stub_request(:any, 'https://api.openai.com/v1/chat/completions')
51
+ .to_return(body: '{"choices":[{"message":{"content": "boom!"}}]}')
52
+ chat = GptTranslate::ChatGPT.new('fake-key', 'gpt-3.5-turbo', 'en', 'ru')
53
+ assert_equal('boom!', chat.translate('This is the text to send to OpenAI'))
54
+ end
47
55
  end
@@ -34,9 +34,9 @@ class GptTranslate::PermalinkTest < Minitest::Test
34
34
  assert_equal(
35
35
  '/2023.html',
36
36
  GptTranslate::Permalink.new(
37
- { 'date' => Time.parse('2023-01-01'), 'title' => 'Hello' },
38
- '/:year.html'
39
- ).to_s
37
+ { 'date' => Time.parse('2023-01-01'), 'title' => 'Hello', 'slug' => 'hello' },
38
+ ':year.html'
39
+ ).to_path
40
40
  )
41
41
  end
42
42
 
@@ -44,9 +44,9 @@ class GptTranslate::PermalinkTest < Minitest::Test
44
44
  assert_equal(
45
45
  '/2023-%23%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82.html',
46
46
  GptTranslate::Permalink.new(
47
- { 'date' => Time.parse('2023-01-01'), 'title' => '#привет' },
48
- '/:year-:title.html'
49
- ).to_s
47
+ { 'date' => Time.parse('2023-01-01'), 'title' => '#привет', 'slug' => 'hello' },
48
+ ':year-:title.html'
49
+ ).to_path
50
50
  )
51
51
  end
52
52
  end
data/test/test_ping.rb CHANGED
@@ -23,6 +23,7 @@
23
23
  # SOFTWARE.
24
24
 
25
25
  require 'minitest/autorun'
26
+ require 'webmock/minitest'
26
27
  require 'jekyll'
27
28
  require_relative '../lib/jekyll-chatgpt-translate/ping'
28
29
 
@@ -40,8 +41,22 @@ class GptTranslate::PingTest < Minitest::Test
40
41
  end
41
42
 
42
43
  def test_when_exists
44
+ stub_request(:any, 'https://www.yegor256.com/about-me.html')
43
45
  site = FakeSite.new({ 'url' => 'https://www.yegor256.com/' })
44
46
  ping = GptTranslate::Ping.new(site, '/about-me.html')
45
47
  assert(!ping.exists?)
46
48
  end
49
+
50
+ def test_when_not_exists
51
+ stub_request(:any, 'https://www.yegor256.com/absent.html').to_return(status: 404)
52
+ site = FakeSite.new({ 'url' => 'https://www.yegor256.com/' })
53
+ ping = GptTranslate::Ping.new(site, '/absent.html')
54
+ assert(!ping.exists?)
55
+ end
56
+
57
+ def test_relative_path
58
+ assert_raises do
59
+ GptTranslate::Ping.new({}, '404.html')
60
+ end
61
+ end
47
62
  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.6
4
+ version: 0.0.7
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-20 00:00:00.000000000 Z
11
+ date: 2023-08-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: iri