jekyll-chatgpt-translate 0.0.21 → 0.0.22

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: bae88d4bb6c95da76a68c64321f5d308611a19981158f69cd2aa8763d0f4f8f0
4
- data.tar.gz: b820a3d53adafd3ea91f365e95851bf848e05890281d1cc7d85bc6a19692af3b
3
+ metadata.gz: daa42e099235943fc1a5473a83796abe90b7949d1365c9d9b7349c7c86be7406
4
+ data.tar.gz: 6c7559aea364339a8b2ac5eac397e314491166b77cfff92565218f6cdd04499b
5
5
  SHA512:
6
- metadata.gz: 554c9a981763d2957c83b396098fec3b75c23fd98f73a180b33528db97a43406cc2b6595893b1e848a59829e614ec4eb4c70f50d63301d6b93047caf12a81e19
7
- data.tar.gz: 695cbae5292d6e81ad69d81657e5ded96f69f2c970bfa2d0ad4b8da23c8c8f412cd77e3944ec09e064417114b0c2ae3518b61b80c3af3a2d4d376e0d0dd8c6b0
6
+ metadata.gz: e651bfae3d35ddf473555eb168cf3301ba6dacda8352fd00a610613c9a2dc8821a1188064089f701ae94c4e4b2277f41b5d635842ae4132f92e9242828ecc0ac
7
+ data.tar.gz: a18e7007a9f40cfdba340285c8ef665c8c47d8e829ac6f76d304b77cec89b14ce9e9c1d56ddfd72f010429d4620f712ee773ed7011942d771c49993799bcef23
data/features/cli.feature CHANGED
@@ -31,6 +31,11 @@ Feature: Simple site building
31
31
  Chinese: {{ content }}
32
32
  The original: {{ page.translated-original-url }}
33
33
  """
34
+ And I have a "_layouts/translated.html" file with content:
35
+ """
36
+ French: {{ content }}
37
+ The original: {{ page.translated-original-url }}
38
+ """
34
39
  And I have a "_posts/2023-01-01-hello.md" file with content:
35
40
  """
36
41
  ---
@@ -50,3 +55,33 @@ Feature: Simple site building
50
55
  And File "_site/2023-01-01-hello-chinese.html" contains "The original: /2023/01/01/hello.html"
51
56
  And File "_site/2023/hello-french.html" exists
52
57
 
58
+ Scenario: Simple download of existing page
59
+ Given I have a "_config.yml" file with content:
60
+ """
61
+ url: https://www.yegor256.com
62
+ markdown: kramdown
63
+ plugins:
64
+ - jekyll-chatgpt-translate
65
+ chatgpt-translate:
66
+ source: en
67
+ version: ""
68
+ api_key: "it-is-not-used, because EN to EN translation"
69
+ layout: should-not-be-used
70
+ targets:
71
+ -
72
+ language: en
73
+ permalink: about-me.html
74
+ """
75
+ And I have a "_posts/2023-01-01-hello.md" file with content:
76
+ """
77
+ ---
78
+ title: foo
79
+ ---
80
+ foo
81
+ """
82
+ Then I build Jekyll site
83
+ And Exit code is zero
84
+ And Stdout contains "No need to translate, the page exists"
85
+ And File "_site/2023/01/01/hello.html" exists
86
+ And File "_site/about-me.html" exists
87
+ And File "_site/about-me.html" contains "Yegor Bugayenko"
@@ -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.21'
31
+ s.version = '0.0.22'
32
32
  s.license = 'MIT'
33
33
  s.summary = 'Translate Jekyll Pages Through ChatGPT'
34
34
  s.description = [
@@ -81,9 +81,8 @@ class GptTranslate::Generator < Jekyll::Generator
81
81
  '---'
82
82
  ].join("\n")
83
83
  )
84
- url = Jekyll::Page.new(site, site.source, File.dirname(path), File.basename(path)).url
85
84
  ping = GptTranslate::Ping.new(site, link)
86
- if config['no_download'].nil? && ping.found?(File.join(site.dest, url), version.empty? ? '' : marker)
85
+ if config['no_download'].nil? && ping.found?(version.empty? ? '' : marker)
87
86
  copied += 1
88
87
  elsif translated >= threshold
89
88
  next
@@ -113,7 +112,8 @@ class GptTranslate::Generator < Jekyll::Generator
113
112
  doc.data['chatgpt-model'] = model
114
113
  end
115
114
  end
116
- Jekyll.logger.info("#{translated} pages translated and #{copied} pages copied in #{(Time.now - start).round(2)}s")
115
+ Jekyll.logger.info("jekyll-chatgpt-translate #{GptTranslate::VERSION}: \
116
+ #{translated} pages translated and #{copied} pages copied in #{(Time.now - start).round(2)}s")
117
117
  end
118
118
 
119
119
  private
@@ -134,6 +134,10 @@ class GptTranslate::Generator < Jekyll::Generator
134
134
  Jekyll.logger.info("The file with the OpenAI API key is not found: #{file.inspect}")
135
135
  nil
136
136
  end
137
+ if key.nil? && config['api_key']
138
+ Jekyll.logger.info("The OpenAI API key is found in 'api_key' of _config.yml")
139
+ key = config['api_key']
140
+ end
137
141
  if key.nil? && Jekyll.env == 'development'
138
142
  Jekyll.logger.info("OPENAI_API_KEY environment variable is not set, \
139
143
  the `api_key_file` option is not specified in the _config.yml, and \
@@ -25,6 +25,7 @@
25
25
  require 'iri'
26
26
  require 'net/http'
27
27
  require 'uri'
28
+ require 'jekyll'
28
29
  require 'fileutils'
29
30
  require_relative 'version'
30
31
 
@@ -47,7 +48,7 @@ class GptTranslate::Ping
47
48
  @path = path
48
49
  end
49
50
 
50
- def found?(file, marker)
51
+ def found?(marker)
51
52
  home = @site.config['url']
52
53
  return false if home.nil?
53
54
  uri = Iri.new(home).path(@path).to_s
@@ -57,9 +58,8 @@ class GptTranslate::Ping
57
58
  html = before.body
58
59
  if html.include?(marker)
59
60
  Jekyll.logger.info("No need to translate, the page exists at \
60
- #{uri.inspect} (#{html.split.count} words), saved to #{file.inspect}")
61
- FileUtils.mkdir_p(File.dirname(file))
62
- File.write(file, html)
61
+ #{uri.inspect} (#{html.split.count} words)")
62
+ @site.static_files << DownloadedFile.new(@site, @path, html)
63
63
  return true
64
64
  end
65
65
  Jekyll.logger.info("Re-translation required for #{uri.inspect}")
@@ -67,10 +67,25 @@ class GptTranslate::Ping
67
67
  Jekyll.logger.info("The page is absent, will translate #{uri.inspect} (#{before.code})")
68
68
  end
69
69
  Jekyll.logger.debug("GET #{uri.inspect}: #{before.code}")
70
- rescue StandardError => e
70
+ rescue Errno::ECONNREFUSED, Errno::EADDRNOTAVAIL => e
71
71
  Jekyll.logger.debug("Failed to ping #{uri.inspect}: #{e.message}")
72
72
  Jekyll.logger.info("The page is absent (#{e.class.name}): #{uri.inspect}")
73
73
  end
74
74
  false
75
75
  end
76
+
77
+ # The file we just downloaded.
78
+ class DownloadedFile < Jekyll::StaticFile
79
+ def initialize(site, path, html)
80
+ super(site, site.dest, '', path)
81
+ @html = html
82
+ end
83
+
84
+ def write(_dest)
85
+ FileUtils.mkdir_p(File.dirname(path))
86
+ File.write(path, @html)
87
+ Jekyll.logger.info("Saved #{@html.split.count} words to #{path.inspect}")
88
+ true
89
+ end
90
+ end
76
91
  end
@@ -23,5 +23,5 @@
23
23
  # SOFTWARE.
24
24
 
25
25
  module GptTranslate
26
- VERSION = '0.0.21'
26
+ VERSION = '0.0.22'
27
27
  end
data/test/test__helper.rb CHANGED
@@ -27,3 +27,107 @@ SimpleCov.start
27
27
 
28
28
  require 'jekyll'
29
29
  Jekyll.logger.adjust_verbosity(verbose: true)
30
+
31
+ # The module we are in.
32
+ module GptTranslate; end
33
+
34
+ # Fake.
35
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
36
+ # Copyright:: Copyright (c) 2023 Yegor Bugayenko
37
+ # License:: MIT
38
+ class GptTranslate::FakeSite
39
+ attr_reader :config, :pages, :static_files
40
+
41
+ def initialize(config, docs = [])
42
+ @config = config
43
+ @docs = docs
44
+ @pages = []
45
+ @static_files = []
46
+ end
47
+
48
+ def posts
49
+ GptTranslate::FakePosts.new(@docs)
50
+ end
51
+
52
+ def permalink_style
53
+ ''
54
+ end
55
+
56
+ def frontmatter_defaults
57
+ Jekyll::FrontmatterDefaults.new(self)
58
+ end
59
+
60
+ def converters
61
+ [Jekyll::Converters::Markdown.new({ 'markdown_ext' => 'md' })]
62
+ end
63
+
64
+ def source
65
+ ''
66
+ end
67
+
68
+ def dest
69
+ return '' if @docs.empty?
70
+ File.dirname(@docs[0])
71
+ end
72
+
73
+ def in_theme_dir(base, _foo = nil, _bar = nil)
74
+ base
75
+ end
76
+
77
+ def in_dest_dir(*paths)
78
+ paths[0].dup
79
+ end
80
+ end
81
+
82
+ # Fake.
83
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
84
+ # Copyright:: Copyright (c) 2023 Yegor Bugayenko
85
+ # License:: MIT
86
+ class GptTranslate::FakeDocument
87
+ attr_reader :data
88
+
89
+ def initialize(path)
90
+ @path = path
91
+ @data = { 'date' => Time.now, 'title' => 'Hello!' }
92
+ end
93
+
94
+ def content
95
+ 'Hello, world!'
96
+ end
97
+
98
+ def []=(key, value)
99
+ @data[key] = value
100
+ end
101
+
102
+ def [](key)
103
+ @data[key] || ''
104
+ end
105
+
106
+ def relative_path
107
+ @path
108
+ end
109
+
110
+ def url
111
+ '2023-01-01-hello.html'
112
+ end
113
+
114
+ def basename
115
+ '2023-01-01-hello.md'
116
+ end
117
+ end
118
+
119
+ # Fake.
120
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
121
+ # Copyright:: Copyright (c) 2023 Yegor Bugayenko
122
+ # License:: MIT
123
+ class GptTranslate::FakePosts
124
+ attr_reader :config
125
+
126
+ def initialize(docs)
127
+ @docs = docs
128
+ end
129
+
130
+ def docs
131
+ @docs.map { |d| GptTranslate::FakeDocument.new(d) }
132
+ end
133
+ end
@@ -33,98 +33,11 @@ require_relative '../lib/jekyll-chatgpt-translate/generator'
33
33
  # Copyright:: Copyright (c) 2023 Yegor Bugayenko
34
34
  # License:: MIT
35
35
  class GptTranslate::GeneratorTest < Minitest::Test
36
- class FakeSite
37
- attr_reader :config, :pages
38
-
39
- def initialize(config, docs)
40
- @config = config
41
- @docs = docs
42
- @pages = []
43
- end
44
-
45
- def posts
46
- FakePosts.new(@docs)
47
- end
48
-
49
- def permalink_style
50
- ''
51
- end
52
-
53
- def frontmatter_defaults
54
- Jekyll::FrontmatterDefaults.new(self)
55
- end
56
-
57
- def converters
58
- [Jekyll::Converters::Markdown.new({ 'markdown_ext' => 'md' })]
59
- end
60
-
61
- def source
62
- ''
63
- end
64
-
65
- def dest
66
- File.dirname(@docs[0])
67
- end
68
-
69
- def in_theme_dir(base, _foo = nil, _bar = nil)
70
- base
71
- end
72
-
73
- def in_dest_dir(*paths)
74
- paths[0].dup
75
- end
76
- end
77
-
78
- class FakeDocument
79
- attr_reader :data
80
-
81
- def initialize(path)
82
- @path = path
83
- @data = { 'date' => Time.now, 'title' => 'Hello!' }
84
- end
85
-
86
- def content
87
- 'Hello, world!'
88
- end
89
-
90
- def []=(key, value)
91
- @data[key] = value
92
- end
93
-
94
- def [](key)
95
- @data[key] || ''
96
- end
97
-
98
- def relative_path
99
- @path
100
- end
101
-
102
- def url
103
- '2023-01-01-hello.html'
104
- end
105
-
106
- def basename
107
- '2023-01-01-hello.md'
108
- end
109
- end
110
-
111
- class FakePosts
112
- attr_reader :config
113
-
114
- def initialize(docs)
115
- @docs = docs
116
- end
117
-
118
- def docs
119
- @docs.map { |d| FakeDocument.new(d) }
120
- end
121
- end
122
-
123
36
  def test_simple_scenario
124
37
  Dir.mktmpdir do |home|
125
38
  post = File.join(home, '2023-01-01-hello.md')
126
39
  File.write(post, "---\ntitle: Hello\n---\n\nHello, world!")
127
- site = FakeSite.new(
40
+ site = GptTranslate::FakeSite.new(
128
41
  {
129
42
  'url' => 'https://www.yegor256.com/',
130
43
  'chatgpt-translate' => {
@@ -150,7 +63,7 @@ class GptTranslate::GeneratorTest < Minitest::Test
150
63
  Dir.mktmpdir do |home|
151
64
  post = File.join(home, '2023-01-01-hello.md')
152
65
  File.write(post, "---\ntitle: Hello\n---\n\nHello, world!")
153
- site = FakeSite.new(
66
+ site = GptTranslate::FakeSite.new(
154
67
  {
155
68
  'chatgpt-translate' => {
156
69
  'threshold' => 1,
data/test/test_ping.rb CHANGED
@@ -34,39 +34,28 @@ require_relative '../lib/jekyll-chatgpt-translate/ping'
34
34
  # Copyright:: Copyright (c) 2023 Yegor Bugayenko
35
35
  # License:: MIT
36
36
  class GptTranslate::PingTest < Minitest::Test
37
- class FakeSite
38
- attr_reader :config
39
-
40
- def initialize(config)
41
- @config = config
42
- end
43
- end
44
-
45
37
  def test_when_exists
46
- stub_request(:any, 'https://www.yegor256.com/about-me.html')
47
- site = FakeSite.new({ 'url' => 'https://www.yegor256.com/' })
38
+ stub_request(:any, 'https://www.yegor256.com/about-me.html').to_return(body: 'Hello!')
39
+ site = GptTranslate::FakeSite.new({ 'url' => 'https://www.yegor256.com/' })
48
40
  ping = GptTranslate::Ping.new(site, '/about-me.html')
49
- Tempfile.open do |f|
50
- assert(ping.found?(f, ''))
51
- end
41
+ assert(ping.found?(''))
42
+ assert_equal(1, site.static_files.size)
52
43
  end
53
44
 
54
45
  def test_when_not_exists
55
46
  stub_request(:any, 'https://www.yegor256.com/absent.html').to_return(status: 404)
56
- site = FakeSite.new({ 'url' => 'https://www.yegor256.com/' })
47
+ site = GptTranslate::FakeSite.new({ 'url' => 'https://www.yegor256.com/' })
57
48
  ping = GptTranslate::Ping.new(site, '/absent.html')
58
- Tempfile.open do |f|
59
- assert(!ping.found?(f, ''))
60
- end
49
+ assert(!ping.found?(''))
50
+ assert_equal(0, site.static_files.size)
61
51
  end
62
52
 
63
53
  def test_wrong_address
64
54
  WebMock.allow_net_connect!
65
- site = FakeSite.new({ 'url' => 'https://localhost:1/' })
55
+ site = GptTranslate::FakeSite.new({ 'url' => 'https://localhost:1/' })
66
56
  ping = GptTranslate::Ping.new(site, '/boom.html')
67
- Tempfile.open do |f|
68
- assert(!ping.found?(f, ''))
69
- end
57
+ assert(!ping.found?(''))
58
+ assert_equal(0, site.static_files.size)
70
59
  end
71
60
 
72
61
  def test_relative_path
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-chatgpt-translate
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.21
4
+ version: 0.0.22
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko