translation_api 0.1.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b64c85dab791be051f77b9e20ad887cfe8c7ee817ae6099641633642d0291680
4
+ data.tar.gz: 66c9c79aba80565a03875bca2d4fdf64bc64a9b315b39faf3a8f5a06f8645855
5
+ SHA512:
6
+ metadata.gz: ccad42571b28c04503c8f8d6d256e1a54a711305d1fd186b1522f85f68dd57b4a0f1b816572c860ca1907ad01f7b94989d638fd6272cd655d6533ee286cb0784
7
+ data.tar.gz: ff862ecc8885bbc7f5f8ba25a7a31ab57f920340a09b7f23e0f412d05b0f390625ac46f18cdcc5a4ab9e29a30ddd7128e850db2cb36fda22a6c0385b9a4002a6
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
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
@@ -0,0 +1,27 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2024-09-29
4
+
5
+ - Initial release
6
+
7
+ ## [1.0.0] - 2024-09-30
8
+
9
+ - ログの出力をするかどうかと除外する単語をオプションとして追加
10
+
11
+ ## [1.0.2] - 2024-09-30
12
+
13
+ - リファクタリングのみ
14
+
15
+ ## [1.1.0] - 2024-10-4
16
+
17
+ - 日本語以外に翻訳できるように、`exchange_language`オプションを追加
18
+ - それに伴い、翻訳のメソッド名を`translate_to_jp` -> `translate`に変更
19
+ - 空白文字はそのまま返すように変更
20
+
21
+ ## [0.1.0] - 2024-11-12
22
+
23
+ - 他のAPIに対応できるようにリファクタリング
24
+
25
+ ## [0.1.1] - 2025-03-31
26
+
27
+ - ライブラリの更新
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,28 @@
1
+ # TranslationAPI
2
+
3
+ Translate using APIs.
4
+ Requires api key.
5
+
6
+ ## For OpenAI
7
+
8
+ 1. `touch .env`
9
+ 2. Add `OPENAI_API_KEY=YOUR_API_KEY`
10
+ 3. Optional: `ENV["OPENAI_MODEL"]`(default: gpt-4o-mini)
11
+ 4. `TranslationAPI::Mediator.new.translate("text")`
12
+
13
+ ### Init Options
14
+
15
+ * output_logs (default: true)
16
+ * language (default: "japanese")
17
+ * agent (default: :openai)
18
+ * except_words (default: [])
19
+
20
+ ### Output
21
+
22
+ * Translated_text
23
+ * Used Tokens
24
+ * Cost Spent(https://openai.com/api/pricing/)
25
+
26
+ ## Example
27
+
28
+ Exec `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,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/translation_api/mediator"
4
+
5
+ if ARGV.empty?
6
+ puts "引数が必要です: ruby example.rb \"text\""
7
+ exit
8
+ end
9
+
10
+ text = ARGV.join(" ")
11
+ translator =
12
+ TranslationAPI::Mediator.new(
13
+ output_logs: true,
14
+ language: "japanese",
15
+ agent: :openai,
16
+ except_words: %w[hoge fuga]
17
+ )
18
+ translated_text = translator.translate(text)
19
+ p translated_text
@@ -0,0 +1,10 @@
1
+ some code change
2
+ version.rb change
3
+ changelog.md change
4
+
5
+ $rake analysis
6
+
7
+ $git commit
8
+ $git push
9
+
10
+ $rake push
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "writer"
4
+
5
+ module TranslationAPI
6
+ class Calculator
7
+ class ArgumentError < StandardError; end
8
+ MODEL_ERROR_MESSAGE =
9
+ "設定に無いモデルです。.envを確認してください。"
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
+ raise Calculator::ArgumentError, MODEL_ERROR_MESSAGE
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dotenv"
4
+ require "deepl"
5
+
6
+ module TranslationAPI
7
+ class DeepL
8
+ SYSTEM_CONTENT_BASE = <<~TEXT
9
+ Keep symbols
10
+ TEXT
11
+
12
+ def initialize(output_logs: true, except_words: [], language: "japanese", pro: false)
13
+ Dotenv.load
14
+ setup_deepl_config!(pro: pro)
15
+ @supported_languages = fetch_supported_languages
16
+ validate_supported!(language)
17
+ @system_content = SYSTEM_CONTENT_BASE + except_option_text(except_words)
18
+ @language = @supported_languages[language.to_sym]
19
+ end
20
+
21
+ def translate(text)
22
+ return text if text.strip.empty?
23
+
24
+ p ::DeepL.translate(text, nil, @language, context: @system_content).text
25
+ end
26
+
27
+ private
28
+
29
+ def setup_deepl_config!(pro:)
30
+ validate_api_key!
31
+
32
+ ::DeepL.configure do |config|
33
+ config.auth_key = ENV["DEEPL_API_KEY"] || ENV["DEEPL_AUTH_KEY"]
34
+ config.host = pro ? "https://api.deepl.com" : "https://api-free.deepl.com"
35
+ end
36
+ end
37
+
38
+ def validate_supported!(lang)
39
+ raise "This language is unsupported by DeepL" unless supported?(lang)
40
+ end
41
+
42
+ def validate_api_key!
43
+ raise "API key is not found" unless ENV["DEEPL_API_KEY"] || ENV["DEEPL_AUTH_KEY"]
44
+ end
45
+
46
+ def fetch_supported_languages
47
+ ::DeepL.languages.to_h { |lang| [lang.name.downcase.to_sym, lang.code] }
48
+ end
49
+
50
+ def supported?(lang)
51
+ @supported_languages.key?(lang.to_sym)
52
+ end
53
+
54
+ def except_option_text(except_words)
55
+ return "" if except_words.empty?
56
+
57
+ <<~TEXT
58
+ Words listed next are not translated: [#{except_words.join(", ")}]
59
+ TEXT
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "writer"
4
+ require_relative "openai"
5
+ require_relative "deepl"
6
+
7
+ module TranslationAPI
8
+ class Mediator
9
+ # @param [Boolean] output_logs ログを出力するかどうか
10
+ # @param [String] language 翻訳先の言語
11
+ # @param [Symbol] agent 翻訳エージェント
12
+ # @param [Array<String>] except_words 除外する単語のリスト
13
+ # @return [TranslationAPI::Mediator]
14
+ def initialize(
15
+ output_logs: true, language: "japanese", agent: :openai, except_words: []
16
+ )
17
+ @output_logs = output_logs
18
+ @language = language
19
+ @agent = agent
20
+ @except_words = except_words
21
+ end
22
+
23
+ # テキストを翻訳する
24
+ #
25
+ # @param [String] text 翻訳するテキスト
26
+ # @return [String] 翻訳されたテキスト
27
+ def translate(text)
28
+ agent = init_agent
29
+ agent.translate(text)
30
+ end
31
+
32
+ # エージェントのインスタンスを初期化する
33
+ #
34
+ # @return [Object] 翻訳エージェントのインスタンス
35
+ def init_agent
36
+ agent_class.new(
37
+ output_logs: @output_logs, except_words: @except_words, language: @language
38
+ )
39
+ end
40
+
41
+ # エージェントのクラスを返す
42
+ #
43
+ # @return [Class] エージェントのクラス
44
+ def agent_class
45
+ case @agent
46
+ when :openai
47
+ OpenAI
48
+ when :deepl
49
+ DeepL
50
+ else
51
+ class_name = camelize(@agent.to_s)
52
+ Object.const_get("TranslationAPI::#{class_name}")
53
+ end
54
+ end
55
+
56
+ # スネークケースの文字列をキャメルケースに変換する
57
+ #
58
+ # @param [String] str スネークケースの文字列
59
+ # @return [String] キャメルケースの文字列
60
+ def camelize(str)
61
+ str.split("_").map(&:capitalize).join
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dotenv"
4
+ require "openai"
5
+ require_relative "writer"
6
+
7
+ module TranslationAPI
8
+ class OpenAI
9
+ SYSTEM_CONTENT_BASE = <<~TEXT
10
+ Translate only.
11
+ Return result only, no extra info
12
+ Keep symbols
13
+ TEXT
14
+
15
+ # OpenAI APIを使用してテキストを翻訳する
16
+ #
17
+ # @param [Boolean] output_logs ログを出力するかどうか
18
+ # @param [Array<String>] except_words 除外する単語のリスト
19
+ # @param [String] language 翻訳先の言語
20
+ # @return [void]
21
+ def initialize(output_logs: true, except_words: [], language: "japanese")
22
+ # 環境変数の読み込み
23
+ Dotenv.load
24
+ raise "API key is not found" unless ENV["OPENAI_API_KEY"]
25
+
26
+ @client = ::OpenAI::Client.new(
27
+ access_token: ENV["OPENAI_API_KEY"],
28
+ log_errors: true # 好み
29
+ )
30
+ @output_logs = output_logs
31
+ @system_content = SYSTEM_CONTENT_BASE + except_option_text(except_words)
32
+ @language = language
33
+ end
34
+
35
+ # テキストを日本語に翻訳し、結果をファイルに書き込む
36
+ #
37
+ # @param [String] text 翻訳するテキスト
38
+ # @return [void]
39
+ def translate(text)
40
+ # 空白文字は翻訳する必要がない
41
+ return text if text.strip.empty?
42
+
43
+ response = chat_to_api(text)
44
+ Writer.write_logs(self, response) if @output_logs
45
+
46
+ response["choices"][0]["message"]["content"]
47
+ end
48
+
49
+ # レスポンスから使用したトークン数を取得する
50
+ #
51
+ # @param [Hash] response OpenAI APIからのレスポンス
52
+ # @param [String] token_type トークンの種類 (input or output)
53
+ # @return [Integer] 使用したトークン数
54
+ def self.dig_used_tokens(response, token_type)
55
+ if token_type == "input"
56
+ response["usage"]["prompt_tokens"]
57
+ elsif token_type == "output"
58
+ response["usage"]["completion_tokens"]
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ # OpenAI APIにテキストを送信し、翻訳結果を取得する
65
+ #
66
+ # @param [String] text 翻訳するテキスト
67
+ # @return [Hash] OpenAI APIからのレスポンス
68
+ def chat_to_api(text)
69
+ @client.chat(
70
+ parameters: {
71
+ model: ENV["OPENAI_MODEL"] || "gpt-4o-mini",
72
+ messages: [
73
+ { role: "system", content: @system_content },
74
+ { role: "user", content: user_prompt_text(text) }
75
+ ]
76
+ }
77
+ )
78
+ end
79
+
80
+ # 除外する単語を指定するプロンプト
81
+ #
82
+ # @param [Array<String>] except_words 除外する単語のリスト
83
+ # @return [String] 除外する単語を指定するテキスト
84
+ def except_option_text(except_words)
85
+ return "" if except_words.empty?
86
+
87
+ <<~TEXT
88
+ Words listed next are not translated: [#{except_words.join(", ")}]
89
+ TEXT
90
+ end
91
+
92
+ # ユーザー入力のプロンプト
93
+ #
94
+ # @param [String] text テキスト
95
+ # @return [String] ユーザー入力のプロンプト
96
+ def user_prompt_text(text)
97
+ <<~TEXT
98
+ Please translate this text to #{@language}: #{text}
99
+ TEXT
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TranslationAPI
4
+ VERSION = "0.1.1"
5
+ end
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+ require_relative "calculator"
5
+ require_relative "openai"
6
+
7
+ module TranslationAPI
8
+ class Writer
9
+ @agent = nil
10
+
11
+ # ログをファイルに書き込む
12
+ #
13
+ # @param [Object] agent 翻訳エージェントのインスタンス
14
+ # @param [Hash] response 翻訳した結果
15
+ # @return [void]
16
+ def self.write_logs(agent, response)
17
+ # 例: "Hoge::Fuga" => "fuga"
18
+ @agent = agent.class.to_s.split("::").last.downcase
19
+ handle_agent(response)
20
+ end
21
+
22
+ # エージェントに対応したログ書き込み用メソッドを呼び出す
23
+ #
24
+ # @param [Hash] response 翻訳した結果
25
+ # @return [void]
26
+ def self.handle_agent(response)
27
+ method_name = "write_#{@agent}_logs"
28
+ send(method_name, response)
29
+ end
30
+
31
+ # OpenAIのログをファイルに書き込む
32
+ #
33
+ # @param [Hash] response OpenAI APIからのレスポンス
34
+ # @return [void]
35
+ def self.write_openai_logs(response)
36
+ input_tokens = OpenAI.dig_used_tokens(response, "input")
37
+ output_tokens = OpenAI.dig_used_tokens(response, "output")
38
+
39
+ write_translated_text(response["choices"][0]["message"]["content"])
40
+ write_used_tokens(input_tokens, output_tokens)
41
+ write_total_cost(input_tokens, output_tokens)
42
+ end
43
+
44
+ # 出力先のテキストファイルのパスを返す
45
+ # example.rbから見たパスで指定している
46
+ #
47
+ # @param [String] under_logs_path translator_logsディレクトリ配下のパス
48
+ # @return [String] 出力先のテキストファイルのパス
49
+ def self.text_path(under_logs_path)
50
+ output_dir = "translator_logs/#{@agent}"
51
+ FileUtils.mkdir_p(output_dir) unless File.directory?(output_dir)
52
+ File.join(output_dir, under_logs_path)
53
+ end
54
+
55
+ # 翻訳されたテキストをファイルに書き込み、ターミナルに出力する
56
+ # テキストはファイルの末尾に追記される
57
+ #
58
+ # @param [Hash] translated_text 翻訳されたテキスト
59
+ # @return [void]
60
+ def self.write_translated_text(translated_text)
61
+ log_file_path = text_path("translated_text.txt")
62
+ File.open(log_file_path, "a") do |file|
63
+ file.puts(translated_text)
64
+ end
65
+ end
66
+
67
+ # 使用したトークン数をファイルに書き込む
68
+ # ファイルのテキストは上書きされる
69
+ #
70
+ # @param [Integer] input_tokens 入力トークン数
71
+ # @param [Integer] output_tokens 出力トークン数
72
+ # @return [void]
73
+ def self.write_used_tokens(input_tokens, output_tokens)
74
+ log_file_path = text_path("tokens.txt")
75
+ existing_input_tokens, existing_output_tokens = read_existing_tokens(log_file_path)
76
+
77
+ total_input_tokens = existing_input_tokens + input_tokens
78
+ total_output_tokens = existing_output_tokens + output_tokens
79
+
80
+ File.open(log_file_path, "w") do |file|
81
+ file.puts("input: #{total_input_tokens}")
82
+ file.puts("output: #{total_output_tokens}")
83
+ end
84
+ end
85
+
86
+ # ファイルにあるトークン数を読み込む
87
+ #
88
+ # @param [String] log_file_path トークン数が書かれたファイルのパス
89
+ # @return [Array<Integer>] 入力トークン数と出力トークン数
90
+ def self.read_existing_tokens(log_file_path)
91
+ existing_input_tokens, existing_output_tokens = 0, 0
92
+
93
+ if File.exist?(log_file_path)
94
+ File.readlines(log_file_path).each do |line|
95
+ existing_input_tokens = line.split(":").last.strip.to_i if line.start_with?("input:")
96
+ existing_output_tokens = line.split(":").last.strip.to_i if line.start_with?("output:")
97
+ end
98
+ end
99
+
100
+ [existing_input_tokens, existing_output_tokens]
101
+ end
102
+
103
+ # トークン数から利用料金を計算し、ファイルにある合計金額に加算して書き込む
104
+ # ファイルのテキストは上書きされる
105
+ #
106
+ # @param [Integer] input_tokens 入力トークン数
107
+ # @param [Integer] output_tokens 出力トークン数
108
+ # @return [void]
109
+ def self.write_total_cost(input_tokens, output_tokens)
110
+ log_file_path = text_path("cost.txt")
111
+ this_cost =
112
+ Calculator.calc_total_cost(input_tokens, "input") + Calculator.calc_total_cost(output_tokens, "output")
113
+ existing_cost =
114
+ if File.exist?(log_file_path)
115
+ File.read(log_file_path).gsub("$", "").to_f
116
+ else
117
+ 0.0
118
+ end
119
+ total_cost = this_cost + existing_cost
120
+
121
+ File.open(log_file_path, "w") do |file|
122
+ # 小数点以下8桁まで表示
123
+ file.puts("$#{format("%.8f", total_cost)}")
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "translation_api/version"
4
+ require_relative "translation_api/mediator"
5
+
6
+ module TranslationAPI; 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/translation_api-#{TranslationAPI::VERSION}.gem".freeze
7
+
8
+ RUBYGEMS_PUSH_COMMAND =
9
+ "gem push --host https://rubygems.org " \
10
+ "pkg/translation_api-#{TranslationAPI::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
@@ -0,0 +1,4 @@
1
+ module TranslationAPI
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: translation_api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - milkeclair
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 2025-03-30 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: dotenv
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: 3.1.4
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: 3.1.4
26
+ - !ruby/object:Gem::Dependency
27
+ name: ruby-openai
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: 7.1.0
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 7.1.0
40
+ description: translate
41
+ email:
42
+ - milkeclair.noreply@gmail.com
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - ".rspec"
48
+ - ".rubocop.yml"
49
+ - CHANGELOG.md
50
+ - LICENSE.txt
51
+ - README.md
52
+ - Rakefile
53
+ - example.rb
54
+ - how_to_publish.txt
55
+ - lib/translation_api.rb
56
+ - lib/translation_api/calculator.rb
57
+ - lib/translation_api/deepl.rb
58
+ - lib/translation_api/mediator.rb
59
+ - lib/translation_api/openai.rb
60
+ - lib/translation_api/version.rb
61
+ - lib/translation_api/writer.rb
62
+ - rake_helper.rb
63
+ - sig/translation_api.rbs
64
+ homepage: https://github.com/milkeclair/translation_api
65
+ licenses:
66
+ - MIT
67
+ metadata:
68
+ homepage_uri: https://github.com/milkeclair/translation_api
69
+ source_code_uri: https://github.com/milkeclair/translation_api/blob/main
70
+ changelog_uri: https://github.com/milkeclair/translation_api/blob/main/CHANGELOG.md
71
+ rubygems_mfa_required: 'true'
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.6.2
87
+ specification_version: 4
88
+ summary: translate
89
+ test_files: []