Localization added, but not implemented yet.

This commit is contained in:
2026-01-06 17:18:29 -03:00
parent 1035b3d0ab
commit fc3c4787fe
9 changed files with 161 additions and 25 deletions

View File

@@ -3,4 +3,5 @@ source 'https://rubygems.org'
gem 'discordrb', git: 'https://github.com/shardlab/discordrb.git', branch: 'main' gem 'discordrb', git: 'https://github.com/shardlab/discordrb.git', branch: 'main'
gem 'dotenv' gem 'dotenv'
gem 'pg' gem 'pg'
gem 'i18n'

View File

@@ -17,6 +17,7 @@ GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
base64 (0.3.0) base64 (0.3.0)
concurrent-ruby (1.3.6)
domain_name (0.6.20240107) domain_name (0.6.20240107)
dotenv (3.2.0) dotenv (3.2.0)
event_emitter (0.2.6) event_emitter (0.2.6)
@@ -34,6 +35,8 @@ GEM
http-accept (1.7.0) http-accept (1.7.0)
http-cookie (1.1.0) http-cookie (1.1.0)
domain_name (~> 0.5) domain_name (~> 0.5)
i18n (1.14.8)
concurrent-ruby (~> 1.0)
logger (1.7.0) logger (1.7.0)
mime-types (3.7.0) mime-types (3.7.0)
logger logger
@@ -78,10 +81,12 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
discordrb! discordrb!
dotenv dotenv
i18n
pg pg
CHECKSUMS CHECKSUMS
base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab
discordrb (3.7.2) discordrb (3.7.2)
discordrb-webhooks (3.7.2) discordrb-webhooks (3.7.2)
domain_name (0.6.20240107) sha256=5f693b2215708476517479bf2b3802e49068ad82167bcd2286f899536a17d933 domain_name (0.6.20240107) sha256=5f693b2215708476517479bf2b3802e49068ad82167bcd2286f899536a17d933
@@ -100,6 +105,7 @@ CHECKSUMS
ffi (1.17.3-x86_64-linux-musl) sha256=086b221c3a68320b7564066f46fed23449a44f7a1935f1fe5a245bd89d9aea56 ffi (1.17.3-x86_64-linux-musl) sha256=086b221c3a68320b7564066f46fed23449a44f7a1935f1fe5a245bd89d9aea56
http-accept (1.7.0) sha256=c626860682bfbb3b46462f8c39cd470fd7b0584f61b3cc9df5b2e9eb9972a126 http-accept (1.7.0) sha256=c626860682bfbb3b46462f8c39cd470fd7b0584f61b3cc9df5b2e9eb9972a126
http-cookie (1.1.0) sha256=38a5e60d1527eebc396831b8c4b9455440509881219273a6c99943d29eadbb19 http-cookie (1.1.0) sha256=38a5e60d1527eebc396831b8c4b9455440509881219273a6c99943d29eadbb19
i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5
logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
mime-types (3.7.0) sha256=dcebf61c246f08e15a4de34e386ebe8233791e868564a470c3fe77c00eed5e56 mime-types (3.7.0) sha256=dcebf61c246f08e15a4de34e386ebe8233791e868564a470c3fe77c00eed5e56
mime-types-data (3.2025.0924) sha256=f276bca15e59f35767cbcf2bc10e023e9200b30bd6a572c1daf7f4cc24994728 mime-types-data (3.2025.0924) sha256=f276bca15e59f35767cbcf2bc10e023e9200b30bd6a572c1daf7f4cc24994728

View File

@@ -15,10 +15,22 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
require 'discordrb' require 'discordrb'
require 'i18n'
require_relative 'database' require_relative 'database'
require_relative 'utils/locales_helper'
class FrugalityBot class FrugalityBot
def initialize def initialize
I18n.config.enforce_available_locales = false
locales_path = File.join(File.dirname(__dir__), 'locales')
I18n.load_path += Dir["#{locales_path}/*.yml"]
I18n.backend.load_translations
I18n.default_locale = :en
@bot = Discordrb::Bot.new( @bot = Discordrb::Bot.new(
token: ENV['BOT_TOKEN'], token: ENV['BOT_TOKEN'],
intents: [:servers, :server_messages] intents: [:servers, :server_messages]

View File

@@ -14,25 +14,40 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
require 'i18n'
module Commands module Commands
module Add module Add
extend self extend self
def register(bot, db)
command_key = :add
arg_amount_key = :amount
arg_reason_key = :reason
cmd_desc = I18n.t('commands.add.description', locale: :en)
amount_desc = I18n.t('commands.add.args.amount_desc', locale: :en)
reason_desc = I18n.t('commands.add.args.reason_desc', locale: :en)
bot.register_application_command(command_key, cmd_desc, server_id: ENV['TEST_SERVER_ID']) do |cmd|
cmd.integer(arg_amount_key, amount_desc, required: true)
cmd.string(arg_reason_key, reason_desc, required: false)
end
bot.application_command(command_key) do |event|
db_lang = db.get_language(event.user.id)
discord_lang = event.locale.to_s[0..1]
I18n.locale = db_lang || (I18n.available_locales.include?(discord_lang.to_sym) ? discord_lang : :en)
user_id = event.user.id
amount = event.options['amount']
reason = event.options['reason'] || 'income'
def register(bot, db) db.update_balance(user_id, amount, reason)
bot.register_application_command(:add, 'Adds money to the wallet.', server_id: ENV['TEST_SERVER_ID']) do |cmd|
cmd.integer('amount', 'The amount you want to add.', required: true)
cmd.string('reason', "Reason you're adding money to the wallet. Leave empty for default.", required: false)
end
bot.application_command(:add) do |event| msg = I18n.t('responses.add.success', amount: amount, reason: reason, default: "Added #{amount} (Reason: #{reason})")
user_id = event.user.id event.respond(content: msg)
amount = event.options['amount'] end
reason = event.options['reason'] ||= 'transaction'
db.update_balance(user_id, amount, reason)
event.respond(content: "Added: #{amount} to the wallet.\nReason: #{reason}")
end
end
end end
end
end end

View File

@@ -15,13 +15,13 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>. # along with this program. If not, see <https://www.gnu.org/licenses/>.
module Commands module Commands
module Currency module Balance
extend self extend self
def register(bot, db) def register(bot, db)
bot.register_application_command(:currency, 'Get your currency', server_id: ENV['TEST_SERVER_ID']) bot.register_application_command(:balance, 'Get your currency', server_id: ENV['TEST_SERVER_ID'])
bot.application_command(:currency) do |event| bot.application_command(:balance) do |event|
# 1. Get the User ID from the event # 1. Get the User ID from the event
user_id = event.user.id user_id = event.user.id

View File

@@ -50,19 +50,23 @@ class Database
@conn.exec(sql_wallet) @conn.exec(sql_wallet)
@conn.exec(sql_ledger) @conn.exec(sql_ledger)
@conn.exec(sql_index) @conn.exec(sql_index)
begin
@conn.exec("ALTER TABLE wallets ADD COLUMN IF NOT EXISTS locale VARCHAR(5) DEFAULT 'en'")
rescue PG::Error => e
puts "Migration note: #{e.message}"
end
puts "Database tables have been initialized." puts "Database tables have been initialized."
end end
# We pass the user_id
def get_currency(user_id) def get_currency(user_id)
# 1. Run the query using parameters ($1) to prevent SQL injection # Run the query using parameters ($1) to prevent SQL injection
result = @conn.exec_params("SELECT amount FROM wallets WHERE user_id = $1", [user_id]) result = @conn.exec_params("SELECT amount FROM wallets WHERE user_id = $1", [user_id])
# 2. Check if the user exists
if result.num_tuples.zero? if result.num_tuples.zero?
return 0 # User has no money/row yet return 0 # User has no money/row yet
else else
# 3. Return the value (don't print it)
return result[0]['amount'].to_i return result[0]['amount'].to_i
end end
end end
@@ -106,4 +110,23 @@ class Database
net: row['net_change'].to_i net: row['net_change'].to_i
} }
end end
def get_language(user_id)
result = @conn.exec("SELECT locale FROM wallets WHERE user_id = $1", [user_id])
return nil if result.num_tuples.zero?
return result[0]['locale']
end
def set_language(user_id, locale)
sql = <<~SQL
INSERT INTO wallets(user_id, amount, locale)
VALUES ($1, 0, $2)
ON CONFLICT (user_id)
DO UPDATE SET locale = $2
SQL
@conn.exec(sql, [user_id, locale])
end
end end

19
src/locales/en.yml Normal file
View File

@@ -0,0 +1,19 @@
en:
commands:
add:
name: "add"
description: "Add money to the wallet."
args:
amount: "amount"
amount_desc: "How much money you're adding to the wallet."
reason: "reason"
reason_desc: "Reason you're adding money. Leave blank for deafult."
balance:
name: "balance"
description: "Check your wallet."
responses:
add:
success: "Added **%{amount}** coins to the wallet. Reason: **%{reason}**"
balance:
view: "You have **%{balance}** coins."

19
src/locales/es.yml Normal file
View File

@@ -0,0 +1,19 @@
es:
commands:
add:
name: "añadir"
description: "Añade monedas a la billetera."
args:
amount: "cantidad"
amount_desc: "La cantidad de monedas que añades."
reason: "motivo"
reason_desc: "El motivo por el cual añades monedas. Déjalo vacío para default."
balance:
name: "saldo"
description: "Revisa tu billetera."
responses:
add:
success: "Se añadieron **%{amount}** monedas a la billetera. Motivo: **%{reason}**"
balance:
view: "Tienes **%{balance}** monedas."

View File

@@ -0,0 +1,41 @@
# FrugalityBot
# Copyright (C) 2026 Eri (csxkdv/nxkdv) nxkdv@thenight.club
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
require 'i18n'
module LocalesHelper
def self.generate(key_path)
locales_map = {}
discord_map = {
:en => 'en-US',
:es => 'es-ES'
}
I18n.available_locales.each do |lang|
next if lang == :en
text = I18n.t(key_path, locale: lang, default: nil)
if text && text != 'nil'
discord_code = discord_map[lang] || lang.to_s
locales_map[discord_code] = text
end
end
return locales_map
end
end