jp_translator_from_gpt 1.0.3
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 +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: []
|