jp_translator_from_gpt 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +32 -0
- data/CHANGELOG.md +13 -0
- data/LICENSE.txt +21 -0
- data/README.md +17 -0
- data/Rakefile +39 -0
- data/example.rb +13 -0
- data/how_to_publish.txt +10 -0
- data/lib/jp_translator_from_gpt/calculator.rb +76 -0
- data/lib/jp_translator_from_gpt/translator.rb +81 -0
- data/lib/jp_translator_from_gpt/version.rb +5 -0
- data/lib/jp_translator_from_gpt/writer.rb +105 -0
- data/lib/jp_translator_from_gpt.rb +7 -0
- data/rake_helper.rb +29 -0
- data/sig/jp_translator_from_gpt.rbs +4 -0
- metadata +90 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d259dbbb5640c1f7e1b806984fb3f98ea12499fa8c4c722d0e28ffe116f3139c
|
4
|
+
data.tar.gz: '059bf1056a77bb969665d72dce098ea79bee0db6a0dcbf05ad612242a9fc187b'
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 78cdc0c0c022749eca2864321466214e8ba9c314fc9dfbd4634f91fa756a38455be2fe21de31446b87d3d596f589e83782fa6aa8824f95800bbf9f71e2dfcfee
|
7
|
+
data.tar.gz: e96f63804629b36de2733dec301387dda7161fe98cd6fb0b59a7b90eda8282bfadd0c08ceb51d582f8a75a358ab0c25763f8659d91b7a089697e666e8708cd04
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 3.0
|
3
|
+
NewCops: enable
|
4
|
+
|
5
|
+
Style/StringLiterals:
|
6
|
+
EnforcedStyle: double_quotes
|
7
|
+
|
8
|
+
Style/StringLiteralsInInterpolation:
|
9
|
+
EnforcedStyle: double_quotes
|
10
|
+
|
11
|
+
Style/Documentation:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
Style/ParallelAssignment:
|
15
|
+
Enabled: false
|
16
|
+
|
17
|
+
Metrics/MethodLength:
|
18
|
+
CountComments: true
|
19
|
+
Max: 20
|
20
|
+
|
21
|
+
Lint/ScriptPermission:
|
22
|
+
Enabled: false
|
23
|
+
|
24
|
+
Style/FetchEnvVar:
|
25
|
+
Enabled: false
|
26
|
+
|
27
|
+
RSpec/ExampleLength:
|
28
|
+
Max: 10
|
29
|
+
|
30
|
+
require:
|
31
|
+
- rubocop-rake
|
32
|
+
- rubocop-rspec
|
data/CHANGELOG.md
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2024 milkeclair
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
## 概要
|
2
|
+
|
3
|
+
ChatGPTを使って文字列を日本語に翻訳する
|
4
|
+
OpenAIのAPIキーが必要
|
5
|
+
`.env`を作成し、`OPENAI_API_KEY=YOUR_API_KEY`を追加する
|
6
|
+
`ENV["OPENAI_MODEL"]`がない場合は、[gpt-4o-mini](https://openai.com/index/gpt-4o-mini-advancing-cost-efficient-intelligence/)をデフォルトで使用する
|
7
|
+
|
8
|
+
* 翻訳されたテキスト
|
9
|
+
* 使用したトークン数
|
10
|
+
* 掛かった金額([参考](https://openai.com/api/pricing/))
|
11
|
+
|
12
|
+
が出力される
|
13
|
+
|
14
|
+
## 使用例
|
15
|
+
|
16
|
+
詳しくは、example.rbを参照
|
17
|
+
`ruby example.rb "text"`で実行できる
|
data/Rakefile
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler/gem_tasks"
|
4
|
+
require "rspec/core/rake_task"
|
5
|
+
require "rubocop/rake_task"
|
6
|
+
require "yard"
|
7
|
+
require_relative "rake_helper"
|
8
|
+
|
9
|
+
desc "analysis"
|
10
|
+
task :analysis do
|
11
|
+
sh "bundle install"
|
12
|
+
|
13
|
+
RakeHelper.init_rake_tasks
|
14
|
+
|
15
|
+
puts "--- rspec ---"
|
16
|
+
Rake::Task[:spec].invoke
|
17
|
+
|
18
|
+
puts "--- rubocop ---"
|
19
|
+
Rake::Task[:rubocop].invoke
|
20
|
+
|
21
|
+
puts "--- yard ---"
|
22
|
+
Rake::Task[:yard].invoke
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "push to github packages and rubygems"
|
26
|
+
task :push do
|
27
|
+
sh "bundle install"
|
28
|
+
|
29
|
+
puts "--- build ---"
|
30
|
+
RakeHelper.build_gem
|
31
|
+
|
32
|
+
puts "--- push to github packages ---"
|
33
|
+
RakeHelper.push_to_github_packages
|
34
|
+
|
35
|
+
puts "--- push to rubygems ---"
|
36
|
+
RakeHelper.push_to_rubygems
|
37
|
+
end
|
38
|
+
|
39
|
+
task default: :analysis
|
data/example.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/jp_translator_from_gpt"
|
4
|
+
|
5
|
+
if ARGV.empty?
|
6
|
+
puts "引数が必要です: ruby example.rb \"text\""
|
7
|
+
exit
|
8
|
+
end
|
9
|
+
|
10
|
+
text = ARGV.join(" ")
|
11
|
+
translator =
|
12
|
+
JpTranslatorFromGpt::Translator.new(output_logs: false, except_words: ["hoge"])
|
13
|
+
translator.translate_to_jp(text)
|
data/how_to_publish.txt
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "writer"
|
4
|
+
|
5
|
+
module JpTranslatorFromGpt
|
6
|
+
class Calculator
|
7
|
+
class ArgumentError < StandardError; end
|
8
|
+
MODEL_ERROR_MESSAGE =
|
9
|
+
"設定に無いモデルです。モデルをmodules/writerに追加するか、ENV[\"OPENAI_MODEL\"]を変更してください。"
|
10
|
+
|
11
|
+
# トークン数から利用料金を計算する
|
12
|
+
#
|
13
|
+
# @param [Integer] used_tokens 使用したトークン数
|
14
|
+
# @param [String] token_type トークンの種類
|
15
|
+
# @return [Float] 利用料金
|
16
|
+
def self.calc_total_cost(used_tokens, token_type)
|
17
|
+
model = ENV["OPENAI_MODEL"] || "gpt-4o-mini"
|
18
|
+
rate = get_token_rate(model, token_type)
|
19
|
+
used_tokens * rate
|
20
|
+
end
|
21
|
+
|
22
|
+
# モデルとトークンの種類からトークンの単価を取得する
|
23
|
+
# モデルが設定に無い場合はエラーを投げる
|
24
|
+
#
|
25
|
+
# @param [String] model モデル名
|
26
|
+
# @param [String] token_type トークンの種類
|
27
|
+
# @return [Float] トークンの単価
|
28
|
+
def self.get_token_rate(model, token_type)
|
29
|
+
token_rate = token_rate_hash
|
30
|
+
validate_model(model, token_rate)
|
31
|
+
token_rate[model][token_type.to_sym]
|
32
|
+
end
|
33
|
+
|
34
|
+
# トークン単価のハッシュを返す
|
35
|
+
#
|
36
|
+
# @return [Hash] トークン単価のハッシュ
|
37
|
+
def self.token_rate_hash
|
38
|
+
one_million = 1_000_000
|
39
|
+
{
|
40
|
+
"gpt-4o" => {
|
41
|
+
input: 5.0 / one_million,
|
42
|
+
output: 15.0 / one_million
|
43
|
+
},
|
44
|
+
"gpt-4o-2024-08-06" => {
|
45
|
+
input: 2.5 / one_million,
|
46
|
+
output: 10.0 / one_million
|
47
|
+
},
|
48
|
+
"gpt-4o-mini" => {
|
49
|
+
input: 0.15 / one_million,
|
50
|
+
output: 0.6 / one_million
|
51
|
+
}
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
# モデルが存在するかどうかを確認する
|
56
|
+
#
|
57
|
+
# @param [String] model モデル名
|
58
|
+
# @param [Hash] token_rate トークンレートのハッシュ
|
59
|
+
# @raise [Calculator::ArgumentError] モデルが存在しない場合
|
60
|
+
def self.validate_model(model, token_rate)
|
61
|
+
return if token_rate.key?(model)
|
62
|
+
|
63
|
+
clear_files
|
64
|
+
raise Calculator::ArgumentError, MODEL_ERROR_MESSAGE
|
65
|
+
end
|
66
|
+
|
67
|
+
# ファイルの内容を削除する
|
68
|
+
#
|
69
|
+
# @return [void]
|
70
|
+
def self.clear_files
|
71
|
+
File.write(Writer.text_path("translated_text.txt"), "")
|
72
|
+
File.write(Writer.text_path("tokens.txt"), "")
|
73
|
+
File.write(Writer.text_path("cost.txt"), "")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "dotenv"
|
4
|
+
require "openai"
|
5
|
+
require_relative "writer"
|
6
|
+
|
7
|
+
module JpTranslatorFromGpt
|
8
|
+
class Translator
|
9
|
+
SYSTEM_CONTENT_BASE = <<~TEXT
|
10
|
+
Translate only. Return result only, no extra info. Keep symbols.
|
11
|
+
TEXT
|
12
|
+
|
13
|
+
def initialize(output_logs: true, except_words: [])
|
14
|
+
# 環境変数の読み込み
|
15
|
+
Dotenv.load
|
16
|
+
|
17
|
+
@client = OpenAI::Client.new(
|
18
|
+
access_token: ENV["OPENAI_API_KEY"],
|
19
|
+
log_errors: true # 好み
|
20
|
+
)
|
21
|
+
@output_logs = output_logs
|
22
|
+
@system_content = SYSTEM_CONTENT_BASE + except_option_text(except_words)
|
23
|
+
end
|
24
|
+
|
25
|
+
# テキストを日本語に翻訳し、結果をファイルに書き込む
|
26
|
+
#
|
27
|
+
# @param [String] text 翻訳するテキスト
|
28
|
+
# @return [void]
|
29
|
+
def translate_to_jp(text)
|
30
|
+
response = chat_to_api(text)
|
31
|
+
Writer.write_logs(response) if @output_logs
|
32
|
+
|
33
|
+
translated_text = response["choices"][0]["message"]["content"]
|
34
|
+
puts translated_text
|
35
|
+
translated_text
|
36
|
+
end
|
37
|
+
|
38
|
+
# レスポンスから使用したトークン数を取得する
|
39
|
+
#
|
40
|
+
# @param [Hash] response OpenAI APIからのレスポンス
|
41
|
+
# @param [String] token_type トークンの種類 (input or output)
|
42
|
+
# @return [Integer] 使用したトークン数
|
43
|
+
def self.dig_used_tokens(response, token_type)
|
44
|
+
if token_type == "input"
|
45
|
+
response["usage"]["prompt_tokens"]
|
46
|
+
elsif token_type == "output"
|
47
|
+
response["usage"]["completion_tokens"]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
# OpenAI APIにテキストを送信し、翻訳結果を取得する
|
54
|
+
#
|
55
|
+
# @param [String] text 翻訳するテキスト
|
56
|
+
# @return [Hash] OpenAI APIからのレスポンス
|
57
|
+
def chat_to_api(text)
|
58
|
+
@client.chat(
|
59
|
+
parameters: {
|
60
|
+
model: ENV["OPENAI_MODEL"] || "gpt-4o-mini",
|
61
|
+
messages: [
|
62
|
+
{ role: "system", content: @system_content },
|
63
|
+
{ role: "user", content: "please translate this to Japanese: #{text}" }
|
64
|
+
]
|
65
|
+
}
|
66
|
+
)
|
67
|
+
end
|
68
|
+
|
69
|
+
# 除外する単語を指定するプロンプト
|
70
|
+
#
|
71
|
+
# @param [Array<String>] except_words 除外する単語のリスト
|
72
|
+
# @return [String] 除外する単語を指定するテキスト
|
73
|
+
def except_option_text(except_words)
|
74
|
+
return "" if except_words.empty?
|
75
|
+
|
76
|
+
<<~TEXT
|
77
|
+
Words listed next are not translated: #{except_words.join(", ")}
|
78
|
+
TEXT
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "fileutils"
|
4
|
+
require_relative "calculator"
|
5
|
+
|
6
|
+
module JpTranslatorFromGpt
|
7
|
+
class Writer
|
8
|
+
# ログをファイルに書き込む
|
9
|
+
#
|
10
|
+
# @param [Hash] response OpenAI APIからのレスポンス
|
11
|
+
# @return [void]
|
12
|
+
def self.write_logs(response)
|
13
|
+
input_tokens = Translator.dig_used_tokens(response, "input")
|
14
|
+
output_tokens = Translator.dig_used_tokens(response, "output")
|
15
|
+
|
16
|
+
write_translated_text(response)
|
17
|
+
write_used_tokens(input_tokens, output_tokens)
|
18
|
+
write_total_cost(input_tokens, output_tokens)
|
19
|
+
end
|
20
|
+
|
21
|
+
# 出力先のテキストファイルのパスを返す
|
22
|
+
# main.rbから見たパスで指定している
|
23
|
+
#
|
24
|
+
# @param [String] under_logs_path translator_logsディレクトリ配下のパス
|
25
|
+
# @return [String] 出力先のテキストファイルのパス
|
26
|
+
def self.text_path(under_logs_path)
|
27
|
+
output_dir = "translator_logs"
|
28
|
+
FileUtils.mkdir_p(output_dir) unless File.directory?(output_dir)
|
29
|
+
File.join("translator_logs", under_logs_path)
|
30
|
+
end
|
31
|
+
|
32
|
+
# 翻訳されたテキストをファイルに書き込み、ターミナルに出力する
|
33
|
+
# テキストはファイルの末尾に追記される
|
34
|
+
#
|
35
|
+
# @param [Hash] response OpenAI APIからのレスポンス
|
36
|
+
# @return [void]
|
37
|
+
def self.write_translated_text(response)
|
38
|
+
log_file_path = text_path("translated_text.txt")
|
39
|
+
File.open(log_file_path, "a") do |file|
|
40
|
+
translated_text = response["choices"][0]["message"]["content"]
|
41
|
+
file.puts(translated_text)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# 使用したトークン数をファイルに書き込む
|
46
|
+
# ファイルのテキストは上書きされる
|
47
|
+
#
|
48
|
+
# @param [Integer] input_tokens 入力トークン数
|
49
|
+
# @param [Integer] output_tokens 出力トークン数
|
50
|
+
# @return [void]
|
51
|
+
def self.write_used_tokens(input_tokens, output_tokens)
|
52
|
+
log_file_path = text_path("tokens.txt")
|
53
|
+
existing_input_tokens, existing_output_tokens = read_existing_tokens(log_file_path)
|
54
|
+
|
55
|
+
total_input_tokens = existing_input_tokens + input_tokens
|
56
|
+
total_output_tokens = existing_output_tokens + output_tokens
|
57
|
+
|
58
|
+
File.open(log_file_path, "w") do |file|
|
59
|
+
file.puts("input: #{total_input_tokens}")
|
60
|
+
file.puts("output: #{total_output_tokens}")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# ファイルにあるトークン数を読み込む
|
65
|
+
#
|
66
|
+
# @param [String] log_file_path トークン数が書かれたファイルのパス
|
67
|
+
# @return [Array<Integer>] 入力トークン数と出力トークン数
|
68
|
+
def self.read_existing_tokens(log_file_path)
|
69
|
+
existing_input_tokens, existing_output_tokens = 0, 0
|
70
|
+
|
71
|
+
if File.exist?(log_file_path)
|
72
|
+
File.readlines(log_file_path).each do |line|
|
73
|
+
existing_input_tokens = line.split(":").last.strip.to_i if line.start_with?("input:")
|
74
|
+
existing_output_tokens = line.split(":").last.strip.to_i if line.start_with?("output:")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
[existing_input_tokens, existing_output_tokens]
|
79
|
+
end
|
80
|
+
|
81
|
+
# トークン数から利用料金を計算し、ファイルにある合計金額に加算して書き込む
|
82
|
+
# ファイルのテキストは上書きされる
|
83
|
+
#
|
84
|
+
# @param [Integer] input_tokens 入力トークン数
|
85
|
+
# @param [Integer] output_tokens 出力トークン数
|
86
|
+
# @return [void]
|
87
|
+
def self.write_total_cost(input_tokens, output_tokens)
|
88
|
+
log_file_path = text_path("cost.txt")
|
89
|
+
this_cost =
|
90
|
+
Calculator.calc_total_cost(input_tokens, "input") + Calculator.calc_total_cost(output_tokens, "output")
|
91
|
+
existing_cost =
|
92
|
+
if File.exist?(log_file_path)
|
93
|
+
File.read(log_file_path).gsub("$", "").to_f
|
94
|
+
else
|
95
|
+
0.0
|
96
|
+
end
|
97
|
+
total_cost = this_cost + existing_cost
|
98
|
+
|
99
|
+
File.open(log_file_path, "w") do |file|
|
100
|
+
# 小数点以下8桁まで表示
|
101
|
+
file.puts("$#{format("%.8f", total_cost)}")
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
data/rake_helper.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class RakeHelper
|
4
|
+
GITHUB_PACKAGES_PUSH_COMMAND =
|
5
|
+
"gem push --key github --host https://rubygems.pkg.github.com/milkeclair " \
|
6
|
+
"pkg/jp_translator_from_gpt-#{JpTranslatorFromGpt::VERSION}.gem".freeze
|
7
|
+
|
8
|
+
RUBYGEMS_PUSH_COMMAND =
|
9
|
+
"gem push --host https://rubygems.org " \
|
10
|
+
"pkg/jp_translator_from_gpt-#{JpTranslatorFromGpt::VERSION}.gem".freeze
|
11
|
+
|
12
|
+
def self.init_rake_tasks
|
13
|
+
RSpec::Core::RakeTask.new(:spec) { |task| task.verbose = false }
|
14
|
+
RuboCop::RakeTask.new
|
15
|
+
YARD::Rake::YardocTask.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.build_gem
|
19
|
+
abort("gemのビルドに失敗しました") unless system("rake build")
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.push_to_github_packages
|
23
|
+
abort("githubへのgemのpushに失敗しました") unless system(GITHUB_PACKAGES_PUSH_COMMAND)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.push_to_rubygems
|
27
|
+
abort("rubygemsへのgemのpushに失敗しました") unless system(RUBYGEMS_PUSH_COMMAND)
|
28
|
+
end
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jp_translator_from_gpt
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- milkeclair
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-10-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: dotenv
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.1.4
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.1.4
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: ruby-openai
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 7.1.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 7.1.0
|
41
|
+
description: gpt-4o-miniを使って日本語に翻訳する
|
42
|
+
email:
|
43
|
+
- milkeclair.noreply@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- ".rspec"
|
49
|
+
- ".rubocop.yml"
|
50
|
+
- CHANGELOG.md
|
51
|
+
- LICENSE.txt
|
52
|
+
- README.md
|
53
|
+
- Rakefile
|
54
|
+
- example.rb
|
55
|
+
- how_to_publish.txt
|
56
|
+
- lib/jp_translator_from_gpt.rb
|
57
|
+
- lib/jp_translator_from_gpt/calculator.rb
|
58
|
+
- lib/jp_translator_from_gpt/translator.rb
|
59
|
+
- lib/jp_translator_from_gpt/version.rb
|
60
|
+
- lib/jp_translator_from_gpt/writer.rb
|
61
|
+
- rake_helper.rb
|
62
|
+
- sig/jp_translator_from_gpt.rbs
|
63
|
+
homepage: https://github.com/milkeclair/jp_translator_from_gpt
|
64
|
+
licenses:
|
65
|
+
- MIT
|
66
|
+
metadata:
|
67
|
+
homepage_uri: https://github.com/milkeclair/jp_translator_from_gpt
|
68
|
+
source_code_uri: https://github.com/milkeclair/jp_translator_from_gpt/blob/main
|
69
|
+
changelog_uri: https://github.com/milkeclair/jp_translator_from_gpt/blob/main/CHANGELOG.md
|
70
|
+
rubygems_mfa_required: 'true'
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: 3.0.0
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
requirements: []
|
86
|
+
rubygems_version: 3.5.16
|
87
|
+
signing_key:
|
88
|
+
specification_version: 4
|
89
|
+
summary: translate to japanese
|
90
|
+
test_files: []
|