the translation update

This commit is contained in:
WhatDidYouExpect 2025-07-01 16:21:34 +02:00
parent 2e3c6942b6
commit d122c5ffe9
22 changed files with 345 additions and 84 deletions

27
assets/cogs/README.md Normal file
View file

@ -0,0 +1,27 @@
# goobers custom commands
[Hello World!](https://github.com/WhatDidYouExpect/goober/blob/main/cogs/hello.py)
by expect
[WhoAmI (lists username and nickname)](https://github.com/WhatDidYouExpect/goober/blob/main/cogs/whoami.py)
by PowerPCFan
[Cog Manager](https://github.com/WhatDidYouExpect/goober/blob/main/cogs/cogmanager.py)
by expect
[TensorFlow integration](https://github.com/WhatDidYouExpect/goober/blob/main/cogs/tf.py)
by SuperSilly2 (requires Python 3.7 - 3.10, tensorflow-metal/tensorflow-gpu and tensorflow/tensorflow-macos)
[Web Scraper](https://raw.githubusercontent.com/WhatDidYouExpect/goober/refs/heads/main/cogs/webscraper.py)
by expect (requires goober version 0.11.7.2 or higher)
[Status Changer](https://raw.githubusercontent.com/WhatDidYouExpect/goober/refs/heads/main/cogs/songchanger.py)
by expect (requires goober version 0.11.8 or higher)
[Status Changer](https://raw.githubusercontent.com/WhatDidYouExpect/goober/refs/heads/main/cogs/songchanger.py)
by expect (requires goober version 0.11.8 or higher)
[webUI](https://raw.githubusercontent.com/WhatDidYouExpect/goober/refs/heads/main/cogs/webserver.py)
by expect (requires goober version 0.11.8 or higher)
[LastFM](https://raw.githubusercontent.com/WhatDidYouExpect/goober/refs/heads/main/cogs/webserver.py)
by expect (no idea what version it needs i've only tried it on 1.0.3)

66
assets/cogs/cogmanager.py Normal file
View file

@ -0,0 +1,66 @@
import discord
from discord.ext import commands
import os
from modules.globalvars import ownerid
class CogManager(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.command()
async def load(self, ctx, cog_name: str = None):
if ctx.author.id != ownerid:
await ctx.send("You do not have permission to use this command.")
return
if cog_name is None:
await ctx.send("Please provide the cog name to load.")
return
try:
await self.bot.load_extension(f"cogs.{cog_name}")
await ctx.send(f"Loaded cog `{cog_name}` successfully.")
except Exception as e:
await ctx.send(f"Error loading cog `{cog_name}`: {e}")
@commands.command()
async def unload(self, ctx, cog_name: str = None):
if ctx.author.id != ownerid:
await ctx.send("You do not have permission to use this command.")
return
if cog_name is None:
await ctx.send("Please provide the cog name to unload.")
return
try:
await self.bot.unload_extension(f"cogs.{cog_name}")
await ctx.send(f"Unloaded cog `{cog_name}` successfully.")
except Exception as e:
await ctx.send(f"Error unloading cog `{cog_name}`: {e}")
@commands.command()
async def reload(self, ctx, cog_name: str = None):
if ctx.author.id != ownerid:
await ctx.send("You do not have permission to use this command.")
return
if cog_name is None:
await ctx.send("Please provide the cog name to reload.")
return
try:
await self.bot.unload_extension(f"cogs.{cog_name}")
await self.bot.load_extension(f"cogs.{cog_name}")
await ctx.send(f"Reloaded cog `{cog_name}` successfully.")
except Exception as e:
await ctx.send(f"Error reloading cog `{cog_name}`: {e}")
@commands.command()
async def listcogs(self, ctx):
"""Lists all currently loaded cogs in an embed."""
cogs = list(self.bot.cogs.keys())
if not cogs:
await ctx.send("No cogs are currently loaded.")
return
embed = discord.Embed(title="Loaded Cogs", description="Here is a list of all currently loaded cogs:")
embed.add_field(name="Cogs", value="\n".join(cogs), inline=False)
await ctx.send(embed=embed)
async def setup(bot):
await bot.add_cog(CogManager(bot))

View file

@ -0,0 +1,48 @@
import discord
from discord.ext import commands
from modules.globalvars import ownerid
class FileSync(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.mode = None
self.peer_id = None
self.awaiting_file = False
@commands.command()
async def syncfile(self, ctx, mode: str, peer: discord.User):
self.mode = mode.lower()
self.peer_id = peer.id
if ctx.author.id != ownerid:
await ctx.send("You don't have permission to execute this command.")
return
if self.mode == "s":
await ctx.send(f"<@{self.peer_id}> FILE_TRANSFER_REQUEST")
await ctx.send(file=discord.File("memory.json"))
await ctx.send("File sent in this channel.")
elif self.mode == "r":
await ctx.send("Waiting for incoming file...")
self.awaiting_file = True
else:
await ctx.send("Invalid mode, use 's' or 'r'.")
@commands.Cog.listener()
async def on_message(self, message):
if message.author == self.bot.user or not self.awaiting_file:
return
if message.author.id != self.peer_id:
return
if message.content == "FILE_TRANSFER_REQUEST":
print("Ping received. Awaiting file...")
if message.attachments:
for attachment in message.attachments:
if attachment.filename.endswith(".json"):
filename = "received_memory.json"
await attachment.save(filename)
print(f"File saved as {filename}")
await message.channel.send("File received and saved.")
self.awaiting_file = False
async def setup(bot):
await bot.add_cog(FileSync(bot))

View file

@ -0,0 +1,29 @@
import discord
from discord.ext import commands
import os
import requests
import ast
from modules.globalvars import VERSION_URL
class grabTemplate(commands.Cog):
def __init__(self, bot):
self.bot = bot
def download_json():
response = requests.get(f"{VERSION_URL}/goob/template.json")
if response.status_code == 200:
if os.path.exists("memory.json"):
return
else:
userinput = input("Do you want to download the template json instead of starting from scratch?\n(Y/N)\n")
if userinput.lower() == "y":
with open("memory.json", "w", encoding="utf-8") as file:
file.write(response.text)
else:
print("Starting from scratch...")
elif response.status_code == 404:
print("File not found on goober central!!")
download_json()
async def setup(bot):
await bot.add_cog(grabTemplate(bot))

83
assets/cogs/lastfm.py Normal file
View file

@ -0,0 +1,83 @@
import os
import discord
from discord.ext import commands, tasks
import aiohttp
from dotenv import load_dotenv
load_dotenv()
#stole most of this code from my old expect bot so dont be suprised if its poorly made
LASTFM_API_KEY = os.getenv("LASTFM_API_KEY")
LASTFM_USERNAME = os.getenv("LASTFM_USERNAME")
class LastFmCog(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.current_track = None
self.update_presence_task = None
self.ready = False
bot.loop.create_task(self.wait_until_ready())
async def wait_until_ready(self):
await self.bot.wait_until_ready()
self.ready = True
self.update_presence.start()
@tasks.loop(seconds=60)
async def update_presence(self):
print("Looped!")
if not self.ready:
return
track = await self.fetch_current_track()
if track and track != self.current_track:
self.current_track = track
artist, song = track
activity_name = f"{artist} - {song}"
await self.bot.change_presence(activity=discord.Activity(type=discord.ActivityType.listening, name=activity_name))
print(f"Updated song to {artist} - {song}")
else:
print("LastFM gave me the same track! not updating...")
@update_presence.before_loop
async def before_update_presence(self):
await self.bot.wait_until_ready()
@commands.command(name="lastfm")
async def lastfm_command(self, ctx):
track = await self.fetch_current_track()
if not track:
await ctx.send("No track currently playing or could not fetch data")
return
self.current_track = track
artist, song = track
activity_name = f"{artist} - {song}"
await self.bot.change_presence(activity=discord.Activity(type=discord.ActivityType.listening, name=activity_name))
await ctx.send(f"Updated presence to: Listening to {activity_name}")
async def fetch_current_track(self):
url = (
f"http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks"
f"&user={LASTFM_USERNAME}&api_key={LASTFM_API_KEY}&format=json&limit=1"
)
async with aiohttp.ClientSession() as session:
async with session.get(url) as resp:
if resp.status != 200:
return None
data = await resp.json()
recenttracks = data.get("recenttracks", {}).get("track", [])
if not recenttracks:
return None
track = recenttracks[0]
if '@attr' in track and track['@attr'].get('nowplaying') == 'true':
artist = track.get('artist', {}).get('#text', 'Unknown Artist')
song = track.get('name', 'Unknown Song')
return artist, song
return None
async def setup(bot):
if not LASTFM_API_KEY and LASTFM_USERNAME:
return
await bot.add_cog(LastFmCog(bot))

View file

@ -0,0 +1,22 @@
import discord
from discord.ext import commands
from discord import app_commands
class Ping(commands.Cog):
def __init__(self, bot):
self.bot = bot
@app_commands.command(name="slashcommand", description="slashcommandexample")
async def ping(self, interaction: discord.Interaction):
await interaction.response.defer()
exampleembed = discord.Embed(
title="Pong!!",
description="The Beretta fires fast and won't make you feel any better!",
color=discord.Color.blue()
)
exampleembed.set_footer(text=f"Requested by {interaction.user.name}", icon_url=interaction.user.avatar.url)
await interaction.followup.send(embed=exampleembed)
async def setup(bot):
await bot.add_cog(Ping(bot))

View file

@ -0,0 +1,33 @@
import discord
from discord.ext import commands
from modules.globalvars import RED, GREEN, RESET, LOCAL_VERSION_FILE
import os
class songchange(commands.Cog):
def __init__(self, bot):
self.bot = bot
def get_local_version():
if os.path.exists(LOCAL_VERSION_FILE):
with open(LOCAL_VERSION_FILE, "r") as f:
return f.read().strip()
return "0.0.0"
global local_version
local_version = get_local_version()
@commands.command()
async def changesong(self, ctx):
if LOCAL_VERSION_FILE > "0.11.8":
await ctx.send(f"Goober is too old! you must have version 0.11.8 you have {local_version}")
return
await ctx.send("Check the terminal! (this does not persist across restarts)")
song = input("\nEnter a song:\n")
try:
await self.bot.change_presence(activity=discord.Activity(type=discord.ActivityType.listening, name=f"{song}"))
print(f"{GREEN}Changed song to {song}{RESET}")
except Exception as e:
print(f"{RED}An error occurred while changing songs..: {str(e)}{RESET}")
async def setup(bot):
await bot.add_cog(songchange(bot))

155
assets/cogs/tf.py.disabled Normal file
View file

@ -0,0 +1,155 @@
import discord
from discord.ext import commands
import os
import numpy as np
import json
import pickle
import functools
import re
import time
import asyncio
ready = True
MODEL_MATCH_STRING = r"[0-9]{2}_[0-9]{2}_[0-9]{4}-[0-9]{2}_[0-9]{2}"
try:
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.models import Sequential, load_model
from tensorflow.keras.layers import Embedding, LSTM, Dense
from tensorflow.keras.backend import clear_session
if tf.config.list_physical_devices('GPU'):
print("Using GPU acceleration")
elif tf.config.list_physical_devices('Metal'):
print("Using Metal for macOS acceleration")
except ImportError:
print("ERROR: Failed to import TensorFlow. Ensure you have the correct dependencies:")
print("tensorflow>=2.15.0")
print("For macOS (Apple Silicon): tensorflow-metal")
ready = False
class TFCallback(keras.callbacks.Callback):
def __init__(self, bot, progress_embed: discord.Embed, message):
self.embed = progress_embed
self.bot = bot
self.message = message
self.times = [time.time()]
async def send_message(self, message: str, description: str, **kwargs):
if "epoch" in kwargs:
self.times.append(time.time())
avg_epoch_time = np.mean(np.diff(self.times))
description = f"ETA: {round(avg_epoch_time)}s"
self.embed.add_field(name=f"<t:{round(time.time())}:t> - {message}", value=description, inline=False)
await self.message.edit(embed=self.embed)
def on_train_end(self, logs=None):
self.bot.loop.create_task(self.send_message("Training stopped", "Training has been stopped."))
def on_epoch_begin(self, epoch, logs=None):
self.bot.loop.create_task(self.send_message(f"Starting epoch {epoch}", "This might take a while", epoch=True))
def on_epoch_end(self, epoch, logs=None):
self.bot.loop.create_task(self.send_message(f"Epoch {epoch} ended", f"Accuracy: {round(logs.get('accuracy', 0.0), 4)}"))
class Ai:
def __init__(self):
model_path = settings.get("model_path")
if model_path:
self.__load_model(model_path)
self.is_loaded = model_path is not None
self.batch_size = 64
def generate_model_name(self):
return time.strftime('%d_%m_%Y-%H_%M', time.localtime())
def __load_model(self, model_path):
clear_session()
self.model = load_model(os.path.join(model_path, "model.h5"))
model_name = os.path.basename(model_path)
try:
with open(os.path.join(model_path, "tokenizer.pkl"), "rb") as f:
self.tokenizer = pickle.load(f)
except FileNotFoundError:
print("Failed to load tokenizer, using default.")
self.tokenizer = Tokenizer()
with open("memory.json", "r") as f:
self.tokenizer.fit_on_texts(json.load(f))
self.is_loaded = True
def reload_model(self):
clear_session()
model_path = settings.get("model_path")
if model_path:
self.__load_model(model_path)
self.is_loaded = True
async def run_async(self, func, bot, *args, **kwargs):
return await bot.loop.run_in_executor(None, functools.partial(func, *args, **kwargs))
class Learning(Ai):
def create_model(self, memory, epochs=2):
memory = memory[:2000]
tokenizer = Tokenizer()
tokenizer.fit_on_texts(memory)
sequences = tokenizer.texts_to_sequences(memory)
X, y = [], []
for seq in sequences:
for i in range(1, len(seq)):
X.append(seq[:i])
y.append(seq[i])
maxlen = max(map(len, X))
X = pad_sequences(X, maxlen=maxlen, padding="pre")
y = np.array(y)
model = Sequential([
Embedding(input_dim=VOCAB_SIZE, output_dim=128, input_length=maxlen),
LSTM(64),
Dense(VOCAB_SIZE, activation="softmax")
])
model.compile(optimizer="adam", loss="sparse_categorical_crossentropy", metrics=["accuracy"])
history = model.fit(X, y, epochs=epochs, batch_size=64, callbacks=[tf_callback])
self.save_model(model, tokenizer, history)
def save_model(self, model, tokenizer, history, name=None):
name = name or self.generate_model_name()
model_dir = os.path.join("models", name)
os.makedirs(model_dir, exist_ok=True)
with open(os.path.join(model_dir, "info.json"), "w") as f:
json.dump(history.history, f)
with open(os.path.join(model_dir, "tokenizer.pkl"), "wb") as f:
pickle.dump(tokenizer, f)
model.save(os.path.join(model_dir, "model.h5"))
class Generation(Ai):
def generate_sentence(self, word_amount, seed):
if not self.is_loaded:
return False
for _ in range(word_amount):
token_list = self.tokenizer.texts_to_sequences([seed])[0]
token_list = pad_sequences([token_list], maxlen=self.model.input_shape[1], padding="pre")
predicted_word_index = np.argmax(self.model.predict(token_list, verbose=0), axis=-1)[0]
output_word = next((w for w, i in self.tokenizer.word_index.items() if i == predicted_word_index), "")
seed += " " + output_word
return seed
VOCAB_SIZE = 100_000
settings = {}
learning = Learning()
generation = Generation()
tf_callback = None
async def setup(bot):
await bot.add_cog(Tf(bot))

View file

@ -0,0 +1,113 @@
import discord
from discord.ext import commands
import aiohttp
from bs4 import BeautifulSoup
import json
import asyncio
from urllib.parse import urljoin
from config import ownerid
class WebScraper(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.visited_urls = set()
async def fetch(self, session, url):
"""Fetch the HTML content of a URL."""
try:
async with session.get(url, timeout=10) as response:
return await response.text()
except Exception as e:
print(f"Failed to fetch {url}: {e}")
return None
def extract_sentences(self, text):
"""Extract sentences from text."""
sentences = text.split('.')
return [sentence.strip() for sentence in sentences if sentence.strip()]
def save_to_json(self, sentences):
"""Save sentences to memory.json."""
try:
try:
with open("memory.json", "r") as file:
data = json.load(file)
except (FileNotFoundError, json.JSONDecodeError):
data = []
data.extend(sentences)
with open("memory.json", "w") as file:
json.dump(data, file, indent=4)
except Exception as e:
print(f"Failed to save to JSON: {e}")
def undo_last_scrape(self):
"""Undo the last scrape by removing the most recent sentences."""
try:
with open("memory.json", "r") as file:
data = json.load(file)
if not data:
print("No data to undo.")
return False
data = data[:-1]
with open("memory.json", "w") as file:
json.dump(data, file, indent=4)
return True
except (FileNotFoundError, json.JSONDecodeError):
print("No data to undo or failed to load JSON.")
return False
except Exception as e:
print(f"Failed to undo last scrape: {e}")
return False
async def scrape_links(self, session, url, depth=2):
print(f"Scraping: {url}")
self.visited_urls.add(url)
html = await self.fetch(session, url)
if not html:
return
soup = BeautifulSoup(html, "html.parser")
for paragraph in soup.find_all('p'):
sentences = self.extract_sentences(paragraph.get_text())
self.save_to_json(sentences)
@commands.command()
async def start_scrape(self, ctx, start_url: str):
"""Command to start the scraping process."""
if ctx.author.id != ownerid:
await ctx.send("You do not have permission to use this command.")
return
if not start_url.startswith("http"):
await ctx.send("Please provide a valid URL.")
return
await ctx.send(f"Starting scrape from {start_url}... This may take a while!")
async with aiohttp.ClientSession() as session:
await self.scrape_links(session, start_url)
await ctx.send("Scraping complete! Sentences saved to memory.json.")
@commands.command()
async def undo_scrape(self, ctx):
"""Command to undo the last scrape."""
if ctx.author.id != ownerid:
await ctx.send("You do not have permission to use this command.")
return
success = self.undo_last_scrape()
if success:
await ctx.send("Last scrape undone successfully.")
else:
await ctx.send("No data to undo or an error occurred.")
async def setup(bot):
await bot.add_cog(WebScraper(bot))

880
assets/cogs/webserver.py Normal file
View file

@ -0,0 +1,880 @@
import discord
from discord.ext import commands, tasks
import asyncio
from aiohttp import web
import psutil
import os
import json
from datetime import datetime
import time
import aiohttp
import re
from aiohttp import WSMsgType
from modules.globalvars import VERSION_URL
import sys
import subprocess
class GooberWeb(commands.Cog):
def __init__(self, bot):
self.bot = bot
self.app = web.Application()
self.runner = None
self.site = None
self.last_command = "No commands executed yet"
self.last_command_time = "Never"
self.start_time = time.time()
self.websockets = set()
self.app.add_routes([
web.get('/', self.handle_index),
web.get('/changesong', self.handle_changesong),
web.get('/stats', self.handle_stats),
web.get('/data', self.handle_json_data),
web.get('/ws', self.handle_websocket),
web.get('/styles.css', self.handle_css),
web.get('/settings', self.handle_settings),
web.post('/update_settings', self.handle_update_settings),
web.post('/restart_bot', self.handle_restart_bot),
])
self.bot.loop.create_task(self.start_web_server())
self.update_clients.start()
async def restart_bot(self):
await asyncio.sleep(1)
python = sys.executable
os.execl(python, python, *sys.argv)
async def handle_restart_bot(self, request):
asyncio.create_task(self.restart_bot())
return web.Response(text="Bot is restarting...")
async def get_blacklisted_users(self):
blacklisted_ids = os.getenv("BLACKLISTED_USERS", "").split(",")
blacklisted_users = []
for user_id in blacklisted_ids:
if not user_id.strip():
continue
try:
user = await self.bot.fetch_user(int(user_id))
blacklisted_users.append({
"name": f"{user.name}#{user.discriminator}",
"avatar_url": str(user.avatar.url) if user.avatar else str(user.default_avatar.url),
"id": user.id
})
except discord.NotFound:
blacklisted_users.append({
"name": f"Unknown User ({user_id})",
"avatar_url": "",
"id": user_id
})
except discord.HTTPException as e:
print(f"Error fetching user {user_id}: {e}")
continue
return blacklisted_users
async def get_enhanced_guild_info(self):
guilds = sorted(self.bot.guilds, key=lambda g: g.member_count, reverse=True)
guild_info = []
for guild in guilds:
icon_url = str(guild.icon.url) if guild.icon else ""
guild_info.append({
"name": guild.name,
"member_count": guild.member_count,
"icon_url": icon_url,
"id": guild.id
})
return guild_info
async def start_web_server(self):
self.runner = web.AppRunner(self.app)
await self.runner.setup()
self.site = web.TCPSite(self.runner, '0.0.0.0', 8080)
await self.site.start()
print("Goober web server started on port 8080")
async def stop_web_server(self):
await self.site.stop()
await self.runner.cleanup()
print("Web server stopped")
def cog_unload(self):
self.update_clients.cancel()
self.bot.loop.create_task(self.stop_web_server())
@tasks.loop(seconds=5)
async def update_clients(self):
if not self.websockets:
return
stats = await self.get_bot_stats()
message = json.dumps(stats)
for ws in set(self.websockets):
try:
await ws.send_str(message)
except ConnectionResetError:
self.websockets.remove(ws)
except Exception as e:
print(f"Error sending to websocket: {e}")
self.websockets.remove(ws)
async def handle_websocket(self, request):
ws = web.WebSocketResponse()
await ws.prepare(request)
self.websockets.add(ws)
try:
async for msg in ws:
if msg.type == WSMsgType.ERROR:
print(f"WebSocket error: {ws.exception()}")
finally:
self.websockets.remove(ws)
return ws
async def handle_css(self, request):
css_path = os.path.join(os.path.dirname(__file__), 'styles.css')
if os.path.exists(css_path):
return web.FileResponse(css_path)
return web.Response(text="CSS file not found", status=404)
@commands.Cog.listener()
async def on_message(self, message):
if message.author.bot:
return
ctx = await self.bot.get_context(message)
if ctx.valid and ctx.command:
self._update_command_stats(ctx.command.name, ctx.author)
@commands.Cog.listener()
async def on_app_command_completion(self, interaction, command):
self._update_command_stats(command.name, interaction.user)
def _update_command_stats(self, command_name, user):
self.last_command = f"{command_name} (by {user.name}#{user.discriminator})"
self.last_command_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
if self.websockets:
asyncio.create_task(self.update_clients())
async def get_bot_stats(self):
process = psutil.Process(os.getpid())
mem_info = process.memory_full_info()
cpu_percent = psutil.cpu_percent()
process_cpu = process.cpu_percent()
memory_json_size = "N/A"
if os.path.exists("memory.json"):
memory_json_size = f"{os.path.getsize('memory.json') / 1024:.2f} KB"
guild_info = await self.get_enhanced_guild_info()
blacklisted_users = await self.get_blacklisted_users()
uptime_seconds = int(time.time() - self.start_time)
uptime_str = f"{uptime_seconds // 86400}d {(uptime_seconds % 86400) // 3600}h {(uptime_seconds % 3600) // 60}m {uptime_seconds % 60}s"
return {
"ram_usage": f"{mem_info.rss / 1024 / 1024:.2f} MB",
"cpu_usage": f"{process_cpu}%",
"system_cpu": f"{cpu_percent}%",
"memory_json_size": memory_json_size,
"guild_count": len(guild_info),
"bl_count": len(blacklisted_users),
"guilds": guild_info,
"blacklisted_users": blacklisted_users,
"last_command": self.last_command,
"last_command_time": self.last_command_time,
"bot_uptime": uptime_str,
"latency": f"{self.bot.latency * 1000:.2f} ms",
"bot_name": self.bot.user.name,
"bot_avatar_url": str(self.bot.user.avatar.url) if self.bot.user.avatar else "",
"authenticated": os.getenv("gooberauthenticated"),
"lastmsg": os.getenv("gooberlatestgen"),
"localversion": os.getenv("gooberlocal_version"),
"latestversion": os.getenv("gooberlatest_version"),
"owner": os.getenv("ownerid")
}
async def handle_update(self, request):
if os.path.exists("goob/update.py"):
return web.FileResponse("goob/update.py")
return web.Response(text="Update file not found", status=404)
async def handle_changesong(self, request):
song = request.query.get('song', '')
if song:
await self.bot.change_presence(activity=discord.Activity(type=discord.ActivityType.listening, name=song))
return web.Response(text=f"Changed song to: {song}")
return web.Response(text="Please provide a song parameter", status=400)
async def handle_changes(self, request):
if os.path.exists("goob/changes.txt"):
return web.FileResponse("goob/changes.txt")
return web.Response(text="Changelog not found", status=404)
async def read_env_file(self):
env_vars = {}
try:
with open('.env', 'r') as f:
for line in f:
line = line.strip()
if not line or line.startswith('#') or '=' not in line:
continue
key, value = line.split('=', 1)
key = key.strip()
if key in ['splashtext', 'DISCORD_BOT_TOKEN']:
continue
env_vars[key] = value.strip('"\'')
except FileNotFoundError:
print(".env file not found")
return env_vars
async def handle_settings(self, request):
env_vars = await self.read_env_file()
# Get config.py variables
config_vars = {}
try:
with open('config.py', 'r') as f:
for line in f:
if line.startswith('VERSION_URL'):
config_vars['VERSION_URL'] = line.split('=', 1)[1].strip().strip('"')
except FileNotFoundError:
pass
settings_html = """
<!DOCTYPE html>
<html>
<head>
<title>Goober Settings</title>
<style>
body { background-color: #121212; color: #ffffff; font-family: 'Segoe UI', sans-serif; }
h1 { color: #ff5555; text-align: center; }
.settings-container { max-width: 800px; margin: auto; background-color: #1e1e1e; padding: 20px; border-radius: 8px; }
.form-group { margin-bottom: 15px; }
label { display: block; margin-bottom: 5px; color: #ff9999; }
input { width: 100%; padding: 8px; background-color: #252525; color: white; border: 1px solid #444; border-radius: 4px; }
button { background-color: #5f1b1b; color: white; border: none; padding: 10px; border-radius: 4px; cursor: pointer; }
button:hover { background-color: #7a2323; }
</style>
</head>
<body>
<div class='settings-container'>
<h1>Goober Settings</h1>
<form id='settingsForm' action='/update_settings' method='post'>
"""
for key, value in env_vars.items():
settings_html += f"""
<div class='form-group'>
<label for='{key}'>{key}</label>
<input type='text' id='{key}' name='{key}' value='{value}'>
</div>
"""
for key, value in config_vars.items():
settings_html += f"""
<div class='form-group'>
<label for='{key}'>{key}</label>
<input type='text' id='{key}' name='{key}' value='{value}'>
</div>
"""
settings_html += """
<button type='submit'>Save Settings</button>
</form>
<form action="/restart_bot" method="POST">
<button type="submit">Restart</button>
</form>
</div>
</body>
</html>
"""
return web.Response(text=settings_html, content_type='text/html')
async def handle_update_settings(self, request):
data = await request.post()
env_text = ""
try:
with open('.env', 'r') as f:
env_text = f.read()
except FileNotFoundError:
pass
def replace_match(match):
key = match.group(1)
value = match.group(2)
if key in ['splashtext', 'DISCORD_BOT_TOKEN']:
return match.group(0)
if key in data:
new_value = data[key]
if not (new_value.startswith('"') and new_value.endswith('"')):
new_value = f'"{new_value}"'
return f'{key}={new_value}'
return match.group(0)
env_text = re.sub(r'^(\w+)=([\s\S]+?)(?=\n\w+=|\Z)', replace_match, env_text, flags=re.MULTILINE)
with open('.env', 'w') as f:
f.write(env_text.strip() + '\n')
if 'VERSION_URL' in data:
config_text = ""
try:
with open('config.py', 'r') as f:
config_text = f.read()
except FileNotFoundError:
pass
config_text = re.sub(r'^(VERSION_URL\s*=\s*").+?"', f'\\1{data["VERSION_URL"]}"', config_text, flags=re.MULTILINE)
with open('config.py', 'w') as f:
f.write(config_text.strip() + '\n')
return aiohttp.web.Response(text="Settings updated successfully!")
async def handle_index(self, request):
stats = await self.get_bot_stats()
guild_list_html = ""
for guild in stats['guilds']:
icon_html = f'<img src="{guild["icon_url"]}" alt="guild icon" class="guild-icon">' if guild["icon_url"] else '<div class="guild-icon-placeholder"></div>'
guild_list_html += f"""
<div class="guild-item">
{icon_html}
<div class="guild-info">
<div class="guild-name">{guild["name"]}</div>
<div class="guild-members">{guild["member_count"]} members</div>
</div>
</div>
"""
blacklisted_users_html = ""
for user in stats['blacklisted_users']:
avatar_html = f'<img src="{user["avatar_url"]}" alt="user avatar" class="user-avatar">' if user["avatar_url"] else '<div class="user-avatar-placeholder"></div>'
blacklisted_users_html += f"""
<div class="blacklisted-user">
{avatar_html}
<div class="user-info">
<div class="user-name">{user["name"]}</div>
<div class="user-id">ID: {user["id"]}</div>
</div>
</div>
"""
owner_id = stats.get('owner')
owner = None
owner_username = "Owner"
owner_pfp = ""
if owner_id:
try:
owner = await self.bot.fetch_user(int(owner_id))
owner_username = f"{owner.name}#{owner.discriminator}"
owner_pfp = str(owner.avatar.url) if owner and owner.avatar else ""
except:
pass
html_content = f"""
<!DOCTYPE html>
<html>
<head>
<title>goobs central</title>
<style>
#loading-screen {{
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #000;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 9999;
transition: opacity 1.5s ease-out;
}}
#loading-screen.fade-out {{
opacity: 0;
pointer-events: none;
}}
#welcome-message {{
color: #fff;
font-size: 2em;
margin-bottom: 20px;
text-align: center;
text-shadow: 0 0 10px #ff5555;
}}
#owner-avatar {{
width: 100px;
height: 100px;
border-radius: 50%;
object-fit: cover;
border: 3px solid #5f1b1b;
box-shadow: 0 0 20px #ff5555;
}}
body {{
background-color: #121212;
color: #ffffff;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
margin: 0;
padding: 0;
line-height: 1.6;
}}
.topnav {{
background-color: #2a0a0a;
overflow: hidden;
display: flex;
flex-wrap: wrap;
justify-content: center;
padding: 10px;
gap: 15px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
}}
.stat-item {{
gap: 5px;
color: white;
font-size: 14px;
background-color: #1a1a1a;
padding: 8px 15px;
border-radius: 6px;
align-items: center;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
position: relative;
transition: all 0.3s ease;
}}
.stat-item:hover {{
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.4);
}}
.stat-item::after {{
content: '';
position: absolute;
bottom: -5px;
left: 50%;
transform: translateX(-50%);
width: 60%;
height: 3px;
background: linear-gradient(90deg, transparent, #ff5555, transparent);
opacity: 0;
transition: opacity 0.3s ease;
}}
.stat-item:hover::after {{
opacity: 1;
}}
.stat-title {{
font-weight: bold;
color: #ff9999;
}}
.stat-item span:not(.stat-title) {{
font-weight: bold;
color: #ffffff;
}}
.center {{
text-align: center;
max-width: 800px;
margin: 20px auto;
padding: 0 20px;
}}
.bot-info {{
display: flex;
align-items: center;
justify-content: center;
gap: 15px;
margin-bottom: 10px;
}}
.bot-avatar {{
width: 80px;
height: 80px;
border-radius: 50%;
border: 3px solid #5f1b1b;
object-fit: cover;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
}}
hr {{
border: 0;
height: 1px;
background-image: linear-gradient(to right, transparent, #5f1b1b, transparent);
margin: 20px 0;
}}
.stat-container-row {{
display: flex;
justify-content: space-between;
gap: 30px;
max-width: 1200px;
margin: 0 auto;
padding: 0 20px;
}}
.stat-container {{
flex: 1;
background-color: #1e1e1e;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
min-width: 0;
}}
.stat-title {{
color: #ff5555;
font-size: 1.1em;
margin-bottom: 10px;
border-bottom: 1px solid #333;
padding-bottom: 5px;
}}
.guild-item {{
display: flex;
align-items: center;
gap: 15px;
padding: 10px;
margin: 5px 0;
background-color: #252525;
border-radius: 5px;
transition: background-color 0.2s;
}}
.guild-item:hover {{
background-color: #333;
}}
.guild-icon {{
width: 48px;
height: 48px;
border-radius: 50%;
object-fit: cover;
}}
.guild-icon-placeholder {{
width: 48px;
height: 48px;
border-radius: 50%;
background-color: #7289da;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bold;
}}
.guild-info {{
display: flex;
flex-direction: column;
flex-grow: 1;
min-width: 0;
}}
.guild-name {{
font-weight: bold;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}}
.guild-members {{
font-size: 0.8em;
color: #99aab5;
}}
.blacklisted-user {{
display: flex;
align-items: center;
gap: 15px;
padding: 10px;
margin: 5px 0;
background-color: #2a1a1a;
border-radius: 5px;
border-left: 3px solid #ff5555;
}}
.user-avatar {{
width: 48px;
height: 48px;
border-radius: 50%;
object-fit: cover;
}}
.user-avatar-placeholder {{
width: 48px;
height: 48px;
border-radius: 50%;
background-color: #7289da;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bold;
}}
.user-info {{
display: flex;
flex-direction: column;
}}
.user-name {{
font-weight: bold;
color: #ff5555;
}}
.user-id {{
font-size: 0.8em;
color: #99aab5;
}}
input[type="text"] {{
background-color: #252525;
color: white;
border: 1px solid #444;
padding: 8px;
border-radius: 4px;
width: 200px;
margin-right: 10px;
}}
button {{
background-color: #5f1b1b;
color: white;
border: none;
padding: 8px 15px;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.2s;
}}
button:hover {{
background-color: #7a2323;
}}
#guild-list, #blacklisted-users {{
max-height: 400px;
overflow-y: auto;
padding-right: 5px;
}}
#guild-list::-webkit-scrollbar, #blacklisted-users::-webkit-scrollbar {{
width: 6px;
}}
#guild-list::-webkit-scrollbar-track, #blacklisted-users::-webkit-scrollbar-track {{
background: #1a1a1a;
}}
#guild-list::-webkit-scrollbar-thumb, #blacklisted-users::-webkit-scrollbar-thumb {{
background-color: #5f1b1b;
border-radius: 3px;
}}
@media (max-width: 768px) {{
.stat-container-row {{
flex-direction: column;
}}
.topnav {{
gap: 10px;
padding: 10px 5px;
}}
.stat-item {{
font-size: 12px;
padding: 8px 12px;
}}
}}
</style>
</head>
<body>
<div id="loading-screen">
<img id="owner-avatar" src="{owner_pfp}" onerror="this.style.display='none'">
<div id="welcome-message"><b>Welcome, {owner_username}</b></div>
</div>
<div class="topnav">
<div class="stat-item" id="ram-usage">
<span class="stat-title">RAM:</span>
<span>{stats['ram_usage']}</span>
</div>
<div class="stat-item" id="system-cpu">
<span class="stat-title">CPU:</span>
<span>{stats['system_cpu']}</span>
</div>
<div class="stat-item" id="latency">
<span class="stat-title">Latency:</span>
<span>{stats['latency']}</span>
</div>
<div class="stat-item" id="json-size">
<span class="stat-title">JSON Size:</span>
<span>{stats['memory_json_size']}</span>
</div>
<div class="stat-item" id="uptime">
<span class="stat-title">Uptime:</span>
<span>{stats['bot_uptime']}</span>
</div>
</div>
<div class="center">
<div class="bot-info">
<img src="{stats['bot_avatar_url']}" alt="botvatar" class="bot-avatar" id="bot-avatar">
<h1 id="bot-name">{stats['bot_name']}</h1>
</div>
<hr>
<p>your stupid little goober that learns off other people's messages</p>
</div>
<div class="stat-container-row">
<div class="stat-container">
<div class="stat-title">Last Command</div>
<div id="last-command">{stats['last_command']}</div>
<div style="font-size: 0.9em; color: #999;" id="last-command-time">at {stats['last_command_time']}</div>
<br>
<div class="stat-title">Logged into goober central</div>
<div id="last-command">{stats['authenticated']}</div>
<br>
<div class="stat-title">Last generated message</div>
<div id="last-command">{stats['lastmsg']}</div>
<br>
<div class="stat-title">Version</div>
<div id="last-command">Installed Version: {stats['localversion']}</div>
<div id="last-command">Latest Version: {stats['latestversion']}</div>
<br>
<div class="stat-title">goober-central URL</div>
<div id="last-command">{VERSION_URL}</div>
<br>
<div class="stat-title">Change song</div>
<form action="/changesong" method="get">
<input type="text" name="song" placeholder="Enter song name...">
<button type="submit">
change song
</button>
</form>
</div>
<div class="stat-container">
<div class="stat-title">Servers (<span id="guild-count">{stats['guild_count']}</span>)</div>
<div id="guild-list">
{guild_list_html}
</div>
<br>
<div class="stat-title">Blacklisted Users (<span id="guild-count">{stats['bl_count']})</div>
<div id="blacklisted-users">
{blacklisted_users_html if stats['blacklisted_users'] else "<div>No blacklisted users</div>"}
</div>
</div>
</div>
<script>
window.addEventListener('load', function() {{
setTimeout(function() {{
const loadingScreen = document.getElementById('loading-screen');
loadingScreen.classList.add('fade-out');
setTimeout(function() {{
loadingScreen.remove();
}}, 1500);
}}, 1500);
}});
const ws = new WebSocket('ws://' + window.location.host + '/ws');
ws.onmessage = function(event) {{
const data = JSON.parse(event.data);
document.getElementById('ram-usage').innerHTML = `<span class="stat-title">RAM:</span> <span>${{data.ram_usage}}</span>`;
document.getElementById('cpu-usage').innerHTML = `<span class="stat-title">CPU:</span> <span>${{data.cpu_usage}}</span>`;
document.getElementById('system-cpu').innerHTML = `<span class="stat-title">System CPU:</span> <span>${{data.system_cpu}}</span>`;
document.getElementById('latency').innerHTML = `<span class="stat-title">Latency:</span> <span>${{data.latency}}</span>`;
document.getElementById('json-size').innerHTML = `<span class="stat-title">JSON Size:</span> <span>${{data.memory_json_size}}</span>`;
document.getElementById('uptime').innerHTML = `<span class="stat-title">Uptime:</span> <span>${{data.bot_uptime}}</span>`;
document.getElementById('bot-name').textContent = data.bot_name;
const botAvatar = document.getElementById('bot-avatar');
if (botAvatar.src !== data.bot_avatar_url) {{
botAvatar.src = data.bot_avatar_url;
}}
document.getElementById('last-command').textContent = data.last_command;
document.getElementById('last-command-time').textContent = `at ${{data.last_command_time}}`;
document.getElementById('guild-count').textContent = data.guild_count;
let guildListHtml = '';
data.guilds.forEach(guild => {{
const iconHtml = guild.icon_url
? `<img src="${{guild.icon_url}}" alt="guild icon" class="guild-icon">`
: '<div class="guild-icon-placeholder"></div>';
guildListHtml += `
<div class="guild-item">
${{iconHtml}}
<div class="guild-info">
<div class="guild-name">${{guild.name}}</div>
<div class="guild-members">${{guild.member_count}} members</div>
</div>
</div>
`;
}});
document.getElementById('guild-list').innerHTML = guildListHtml;
let blacklistedUsersHtml = '';
if (data.blacklisted_users && data.blacklisted_users.length > 0) {{
data.blacklisted_users.forEach(user => {{
const avatarHtml = user.avatar_url
? `<img src="${{user.avatar_url}}" alt="user avatar" class="user-avatar">`
: '<div class="user-avatar-placeholder"></div>';
blacklistedUsersHtml += `
<div class="blacklisted-user">
${{avatarHtml}}
<div class="user-info">
<div class="user-name">${{user.name}}</div>
<div class="user-id">ID: ${{user.id}}</div>
</div>
</div>
`;
}});
}} else {{
blacklistedUsersHtml = '<div>No blacklisted users</div>';
}}
document.getElementById('blacklisted-users').innerHTML = blacklistedUsersHtml;
}};
ws.onclose = function() {{
console.log('WebSocket disconnected');
}};
</script>
</body>
</html>
"""
return web.Response(text=html_content, content_type='text/html')
async def handle_stats(self, request):
return await self.handle_index(request)
async def handle_json_data(self, request):
stats = await self.get_bot_stats()
return web.json_response(stats)
async def setup(bot):
await bot.add_cog(GooberWeb(bot))

24
assets/cogs/whoami.py Normal file
View file

@ -0,0 +1,24 @@
import discord
from discord.ext import commands
class whoami(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.command()
async def whoami(self, ctx):
user_id = ctx.author.id
username = ctx.author.name
embed = discord.Embed(
title="User Information",
description=f"Your User ID is: {user_id}\n"
f"Your username is: {username}\n"
f"Your nickname in this server is: <@{user_id}>",
color=discord.Color.blue()
)
await ctx.send(embed=embed)
async def setup(bot):
await bot.add_cog(whoami(bot))

123
assets/locales/en.json Normal file
View file

@ -0,0 +1,123 @@
{
"already_started": "I've already started! I'm not updating...",
"please_restart": "Please Restart goober!",
"local_ahead": "Local {remote}/{branch} is ahead and/or up to par. Not Updating...",
"remote_ahead": "Remote {remote}/{branch} is ahead. Updating...",
"cant_find_local_version": "I can't find the local_version variable! Or it's been tampered with and it's not an integer!",
"running_prestart_checks": "Running pre-start checks...",
"continuing_in_seconds": "Continuing in {seconds} seconds... Press any key to skip.",
"missing_requests_psutil": "Missing requests and psutil! Please install them using pip: `pip install requests psutil`",
"requirements_not_found": "requirements.txt not found at {path} was it tampered with?",
"warning_failed_parse_imports": "Warning: Failed to parse imports from {filename}: {error}",
"cogs_dir_not_found": "Cogs directory not found at {path}, skipping scan.",
"std_lib_local_skipped": "STD LIB / LOCAL {package} (skipped check)",
"ok_installed": "OK",
"missing_package": "MISSING",
"missing_package2": "is not installed",
"missing_packages_detected": "Missing packages detected:",
"telling_goober_central": "Telling goober central at {url}",
"failed_to_contact": "Failed to contact {url}: {error}",
"all_requirements_satisfied": "All requirements are satisfied.",
"ping_to": "Ping to {host}: {latency} ms",
"high_latency": "High latency detected! You may experience delays in response times.",
"could_not_parse_latency": "Could not parse latency.",
"ping_failed": "Ping to {host} failed.",
"error_running_ping": "Error running ping: {error}",
"memory_usage": "Memory Usage: {used} GB / {total} GB ({percent}%)",
"memory_above_90": "Memory usage is above 90% ({percent}%). Consider freeing up memory.",
"total_memory": "Total Memory: {total} GB",
"used_memory": "Used Memory: {used} GB",
"low_free_memory": "Low free memory detected! Only {free} GB available.",
"measuring_cpu": "Measuring CPU usage per core...",
"core_usage": "Core {idx}: [{bar}] {usage}%",
"total_cpu_usage": "Total CPU Usage: {usage}%",
"high_avg_cpu": "High average CPU usage: {usage}%",
"really_high_cpu": "Really high CPU load! System may throttle or hang.",
"memory_file": "Memory file: {size} MB",
"memory_file_large": "Memory file is 1GB or higher, consider clearing it to free up space.",
"memory_file_corrupted": "Memory file is corrupted! JSON decode error: {error}",
"consider_backup_memory": "Consider backing up and recreating the memory file.",
"memory_file_encoding": "Memory file has encoding issues: {error}",
"error_reading_memory": "Error reading memory file: {error}",
"memory_file_not_found": "Memory file not found.",
"modification_warning": "Goober has been modified! Any changes will be lost in an update!",
"reported_version": "Reported Version:",
"current_hash": "Current Hash:",
"not_found": "is not found!",
"version_error": "Unable to fetch version info. Status code",
"loaded_cog": "Loaded cog:",
"loaded_cog2": "Loaded module:",
"cog_fail": "Failed to load cog:",
"cog_fail2": "Failed to load module:",
"no_model": "No saved Markov model found. Starting from scratch.",
"folder_created": "Folder '{folder_name}' created.",
"folder_exists": "Folder '{folder_name}' already exists. skipping...",
"logged_in": "Logged in as",
"synced_commands": "Synced",
"synced_commands2": "commands!",
"fail_commands_sync": "Failed to sync commands:",
"started": "{name} has started!",
"name_check": "Error checking name availability:",
"name_taken": "Name is already taken. Please choose a different name.",
"name_check2": "Error during name availability check:",
"add_token": "Token: {token}\nPlease add this token to your .env file as",
"token_exists": "Token already exists in .env. Continuing with the existing token.",
"registration_error": "Error during registration:",
"version_backup": "Backup created:",
"backup_error": "Error: {LOCAL_VERSION_FILE} not found for backup.",
"model_loaded": "Markov model loaded from",
"fetch_update_fail": "Could not fetch update information.",
"invalid_server": "Error: Invalid version information received from server.",
"goober_server_alert": "Alert from goober central!\n",
"new_version": "New version available: {latest_version} (Current: {local_version})",
"changelog": "Check {VERSION_URL}/goob/changes.txt to check out the changelog\n\n",
"invalid_version": "The version: {local_version} isnt valid!",
"invalid_version2": "If this is intended then ignore this message, else press Y to pull a valid version from the server regardless of the version of goober currently running",
"invalid_version3": "The current version will be backed up to current_version.bak..",
"input": "(Y or any other key to ignore....)",
"modification_ignored": "You've modified",
"modification_ignored2": "IGNOREWARNING is set to false..",
"latest_version": "You're using the latest version:",
"latest_version2": "Check {VERSION_URL}/goob/changes.txt to check out the changelog",
"pinging_disabled": "Pinging is disabled! Not telling the server im on...",
"goober_ping_success": "Logged into goober central as {NAME}",
"goober_ping_fail": "Failed to send data. Server returned status code:",
"goober_ping_fail2": "An error occurred while sending data:",
"sentence_positivity": "Positivity of sentence is:",
"command_edit_fail": "Failed to edit message:",
"command_desc_retrain": "Retrains the Markov model manually.",
"command_markov_retrain": "Retraining the Markov model... Please wait.",
"command_markov_memory_not_found": "Error: memory file not found!",
"command_markov_memory_is_corrupt": "Error: memory file is corrupt!",
"command_markov_retraining": "Processing {processed_data}/{data_size} data points...",
"command_markov_retrain_successful": "Markov model retrained successfully using {data_size} data points!",
"command_desc_talk":"talks n like stuf",
"command_talk_insufficent_text": "I need to learn more from messages before I can talk.",
"command_talk_generation_fail": "I have nothing to say right now!",
"command_desc_help": "help",
"command_help_embed_title": "Bot Help",
"command_help_embed_desc": "List of commands grouped by category.",
"command_help_categories_general": "General",
"command_help_categories_admin": "Administration",
"command_help_categories_custom": "Custom Commands",
"command_ran": "Info: {message.author.name} ran {message.content}",
"command_ran_s": "Info: {interaction.user} ran ",
"command_desc_ping": "ping",
"command_ping_embed_desc": "Bot Latency:",
"command_ping_footer": "Requested by",
"command_about_desc": "about",
"command_about_embed_title": "About me",
"command_about_embed_field1": "Name",
"command_about_embed_field2name": "Version",
"command_about_embed_field2value": "Local: {local_version} \nLatest: {latest_version}",
"command_desc_stats": "stats",
"command_stats_embed_title": "Bot stats",
"command_stats_embed_desc": "Data about the the bot's memory.",
"command_stats_embed_field1name": "File Stats",
"command_stats_embed_field1value": "Size: {file_size} bytes\nLines: {line_count}",
"command_stats_embed_field2name": "Version",
"command_stats_embed_field2value": "Local: {local_version} \nLatest: {latest_version}",
"command_stats_embed_field3name": "Variable Info",
"command_stats_embed_field3value": "Name: {NAME} \nPrefix: {PREFIX} \nOwner ID: {ownerid} \nCooldown: {cooldown_time} \nPing line: {PING_LINE} \nMemory Sharing Enabled: {showmemenabled} \nUser Training Enabled: {USERTRAIN_ENABLED}\nSong: {song} \nSplashtext: ```{splashtext}```"
}

77
assets/locales/es.json Normal file
View file

@ -0,0 +1,77 @@
{
"modification_warning": "Goober ha sido modificado! Se omiten las comprobaciones del servidor por completo...",
"reported_version": "Version reportada:",
"current_hash": "Hash actual:",
"not_found": "no existe!",
"version_error": "No se puede obtener la informacion de la version. Codigo de estado",
"loaded_cog": "Engranaje cog:",
"cog_fail": "No se pudo cargar el cog:",
"no_model": "No se encontro ningún modelo de Markov guardado. Empezando desde cero.",
"folder_created": "Directorio '{folder_name}' creado.",
"folder_exists": "El directorio '{folder_name}' ya existe. Se omite...",
"logged_in": "Inicio sesion como",
"synced_commands": "Sincronizado",
"synced_commands2": "comandos!",
"fail_commands_sync": "Error al sincronizar comandos:",
"started": "{name} ha empezado!",
"name_check": "Error al comprobar la disponibilidad del nombre:",
"name_taken": "El nombre ya está en uso. Elija otro.",
"name_check2": "Error durante la comprobacion de disponibilidad del nombre:",
"add_token": "Token: {token}\nAgregue este token a su archivo .env como",
"token_exists": "Hay un token en el archivo .env. Continue con el token existente.",
"registration_error": "Error durante el registro:",
"version_backup": "Copia de seguridad creada:",
"backup_error": "Error: {LOCAL_VERSION_FILE} no encontrado para la copia de seguridad.",
"model_loaded": "Modelo de Markov cargado desde",
"fetch_update_fail": "No se pudo obtener la informacion de actualizacion.",
"invalid_server": "Error: Se recibio informacion de version no valida del servidor.",
"new_version": "Nueva version disponible: {latest_version} (Version actual: {local_version})",
"changelog": "Consulte {VERSION_URL}/goob/changes.txt para ver el registro de cambios\n\n",
"invalid_version": "La version: {local_version} no es valida!",
"invalid_version2": "Si esto es lo que pretende, ignore este mensaje; si no, haga clic en Y en su teclado para descargar una version valida del servidor, independientemente de la version que se este ejecutando actualmente.",
"invalid_version3": "La version actual se copiara a current_version.bak..",
"input": "(Y o cualquier otra tecla para ignorar....)",
"modification_ignored": "Has modificado",
"modification_ignored2": "IGNOREWARNING es falso",
"latest_version": "Usando la ultima version:",
"latest_version2": "Consulte {VERSION_URL}/goob/changes.txt para ver el registro de cambios",
"pinging_disabled": "El ping esta deshabilitado",
"goober_ping_success": "Envie ping a Goober Central!",
"goober_ping_fail": "Error al enviar datos. El servidor devolvio el codigo de estado:",
"goober_ping_fail2": "Se produjo un error al enviar los datos:",
"sentence_positivity": "La positividad de la sentencia es:",
"command_edit_fail": "No se pudo editar el mensaje:",
"command_desc_retrain": "Vuelve a entrenar el modelo de Markov manualmente.",
"command_markov_retrain": "Reentrenando el modelo de Markov... Por favor espere",
"command_markov_memory_not_found": "Error: no hay archivo de memoria!",
"command_markov_memory_is_corrupt": "Error: el archivo de memoria esta danado!",
"command_markov_retraining": "Procesando {processed_data}/{data_size} puntos de datos...",
"command_markov_retrain_successful": "Modelo de Markov reentrenado exitosamente usando {data_size} puntos de datos!",
"command_desc_talk":"hace que el bot hable",
"command_talk_insufficent_text": "Necesito aprender más sobre los mensajes antes de hablar.",
"command_talk_generation_fail": "No tengo nada que decir ahora!",
"command_desc_help": "Ayuda",
"command_help_embed_title": "Ayuda del bot",
"command_help_embed_desc": "Lista de comandos agrupados por categoria",
"command_help_categories_general": "General",
"command_help_categories_admin": "Administracion",
"command_help_categories_custom": "Comandos personalizados",
"command_ran": "Informacion: {message.author.name} ejecuto {message.content}",
"command_desc_ping": "ping",
"command_ping_embed_desc": "Latencia del bot:",
"command_ping_footer": "Solicitado por",
"command_about_desc": "Acerca",
"command_about_embed_title": "Acerca de mi",
"command_about_embed_field1": "Nombre",
"command_about_embed_field2name": "Version",
"command_about_embed_field2value": "Version local: {local_version} \nUltima version: {latest_version}",
"command_desc_stats": "Estadistica",
"command_stats_embed_title": "Estadisticas de bot",
"command_stats_embed_desc": "Datos sobre la memoria del bot",
"command_stats_embed_field1name": "Estadisticas",
"command_stats_embed_field1value": "Tamano: {file_size} bytes\nLineas: {line_count}",
"command_stats_embed_field2name": "Version",
"command_stats_embed_field2value": "Version local: {local_version} \nUltima version: {latest_version}",
"command_stats_embed_field3name": "informacion sobre las variables",
"command_stats_embed_field3value": "Nombre: {NAME} \nPrefijo: {PREFIX} \nID del propietario: {ownerid} \nTiempo de reutilizacion: {cooldown_time} \nLinea de ping: {PING_LINE} \nCompartir memoria habilitada: {showmemenabled} \nEntrenamiento de usuario habilitado: {USERTRAIN_ENABLED} \nCancion: {song} \nTexto de bienvenida: ```{splashtext}```"
}

120
assets/locales/fi.json Normal file
View file

@ -0,0 +1,120 @@
{
"already_started": "Olen jo käynnistynyt! En päivitä...",
"please_restart": "Käynnistä uudelleen, hölmö!",
"local_ahead": "Paikallinen {remote}/{branch} on edellä ja/tai ajan tasalla. Ei päivitystä...",
"remote_ahead": "Etärepositorio {remote}/{branch} on edellä. Päivitetään...",
"cant_find_local_version": "En löydä muuttujaa local_version! Tai sitä on muokattu eikä se ole kokonaisluku!",
"running_prestart_checks": "Suoritetaan esikäynnistystarkistuksia...",
"continuing_in_seconds": "Jatketaan {seconds} sekunnin kuluttua... Paina mitä tahansa näppäintä ohittaaksesi.",
"missing_requests_psutil": "Kirjastot requests ja psutil puuttuvat! Asenna ne komennolla: `pip install requests psutil`",
"requirements_not_found": "Tiedostoa requirements.txt ei löytynyt polusta {path} onko sitä muokattu?",
"warning_failed_parse_imports": "Varoitus: Tuontien jäsentäminen epäonnistui tiedostossa {filename}: {error}",
"cogs_dir_not_found": "Cogs-hakemistoa ei löytynyt polusta {path}, ohitetaan tarkistus.",
"std_lib_local_skipped": "STD LIB / PAIKALLINEN {package} (tarkistus ohitettu)",
"ok_installed": "OK",
"missing_package": "PUUTTUU",
"missing_package2": "ei ole asennettu",
"missing_packages_detected": "Puuttuvia kirjastoja havaittu:",
"telling_goober_central": "Ilmoitetaan goober-keskukselle osoitteessa {url}",
"failed_to_contact": "Yhteyden muodostus epäonnistui osoitteeseen {url}: {error}",
"all_requirements_satisfied": "Kaikki vaatimukset täyttyvät.",
"ping_to": "Ping osoitteeseen {host}: {latency} ms",
"high_latency": "Korkea viive havaittu! Vasteajat saattavat hidastua.",
"could_not_parse_latency": "Viivettä ei voitu tulkita.",
"ping_failed": "Ping osoitteeseen {host} epäonnistui.",
"error_running_ping": "Virhe ping-komennon suorittamisessa: {error}",
"memory_usage": "Muistin käyttö: {used} GB / {total} GB ({percent}%)",
"memory_above_90": "Muistin käyttö ylittää 90 % ({percent}%). Harkitse muistintilan vapauttamista.",
"total_memory": "Kokonaismuisti: {total} GB",
"used_memory": "Käytetty muisti: {used} GB",
"low_free_memory": "Vähän vapaata muistia! Vain {free} GB jäljellä.",
"measuring_cpu": "Mitataan suorittimen käyttöä ytimittäin...",
"core_usage": "Ydin {idx}: [{bar}] {usage}%",
"total_cpu_usage": "Kokonaisprosessorin käyttö: {usage}%",
"high_avg_cpu": "Korkea keskimääräinen prosessorin käyttö: {usage}%",
"really_high_cpu": "Erittäin korkea prosessorikuorma! Järjestelmä saattaa hidastua tai jumittua.",
"memory_file": "Muistitiedosto: {size} MB",
"memory_file_large": "Muistitiedosto on 1 GB tai suurempi harkitse sen tyhjentämistä tilan vapauttamiseksi.",
"memory_file_corrupted": "Muistitiedosto on vioittunut! JSON purkuvirhe: {error}",
"consider_backup_memory": "Harkitse muistitiedoston varmuuskopioimista ja uudelleenluontia.",
"memory_file_encoding": "Muistitiedostossa on koodausongelmia: {error}",
"error_reading_memory": "Virhe muistitiedoston lukemisessa: {error}",
"memory_file_not_found": "Muistitiedostoa ei löytynyt.",
"modification_warning": "Gooberia on muokattu! Ohitetaan palvelimen tarkistus kokonaan...",
"reported_version": "Ilmoitettu versio:",
"current_hash": "Tämänhetkinen hash:",
"not_found": "ei löytynyt!",
"version_error": "Versiotietojen saanti epäonnistui.. Tilakoodi:",
"loaded_cog": "Ladatut cogit:",
"cog_fail": "Cogin lataus epäonnistui kohteelle:",
"no_model": "Olemassaolevaa markov-mallia ei löydetty. Aloitetaan alusta.",
"folder_created": "Kansio '{folder_name}' luotu.",
"folder_exists": "Kansio '{folder_name}' on jo olemassa...",
"logged_in": "Kirjauduttiin sisään käyttäjänä",
"synced_commands": "Synkronoitiin",
"synced_commands2": "komennot!",
"fail_commands_sync": "Komentojen synkronointi epäonnistui:",
"started": "{name} on käynnistynyt!",
"name_check": "Nimen saatavuuden tarkistus epäonnistui:",
"name_taken": "Nimi on jo käytössä. Valitse toinen nimi.",
"name_check2": "Virhe tapahtui nimen saatavuuden tarkistamisessa:",
"add_token": "Token: {token}\nLisää tämä .env-tiedostoosi nimellä",
"token_exists": "Token on jo olemassa .env-tiedostossa. Jatketaan määritetyllä tokenilla.",
"registration_error": "Virhe rekisteröinnissä:",
"version_backup": "Varmuuskopio luotu:",
"backup_error": "Virhe: {LOCAL_VERSION_FILE}-tiedostoa ei löytynyt varmuuskopiota varten.",
"model_loaded": "Markov-malli ladattu",
"fetch_update_fail": "Päivitystietojen hankkiminen epäonnistui.",
"invalid_server": "Virhe: Palvelin antoi virheellisen versiotietoraportin.",
"new_version": "Uusi versio saatavilla: {latest_version} (Tämänhetkinen: {local_version})",
"changelog": "Mene osoitteeseen {VERSION_URL}/goob/changes.txt katsotakseen muutoslokin\n\n",
"invalid_version": "Versio: {local_version} on virheellinen!",
"invalid_version2": "Jos tämä on tahallista, voit jättää tämän viestin huomiotta. Jos tämä ei ole tahallista, paina Y-näppäintä hankkiaksesi kelvollisen version, riippumatta Gooberin tämänhetkisestä versiosta.",
"invalid_version3": "Tämänhetkinen versio varmuuskopioidaan kohteeseen current_version.bak..",
"input": "(Y:tä tai mitä vaan muuta näppäintä jättää tämän huomioimatta....)",
"modification_ignored": "Olet muokannut",
"modification_ignored2": "IGNOREWARNING on asetettu false:ksi..",
"latest_version": "Käytät uusinta versiota:",
"latest_version2": "Tarkista {VERSION_URL}/goob/changes.txt katsotakseen muutosloki",
"pinging_disabled": "Pingaus on poistettu käytöstä! En kerro palvelimelle, että olen päällä...",
"goober_ping_success": "Lähetettiin olemassaolo ping goober centraliin!",
"goober_ping_fail": "Tiedon lähetys epäonnistui. Palvelin antoi tilakoodin:",
"goober_ping_fail2": "Tiedon lähettämisen aikana tapahtui virhe:",
"sentence_positivity": "Lauseen positiivisuus on:",
"command_edit_fail": "Viestin muokkaus epäonnistui:",
"command_desc_retrain": "Uudelleenkouluttaa markov-mallin manuaalisesti.",
"command_markov_retrain": "Uudelleenkoulutetaan markov-mallia... Odota.",
"command_markov_memory_not_found": "Virhe: muistitiedostoa ei löytynyt!",
"command_markov_memory_is_corrupt": "Virhe: muistitiedosto on korruptoitu!",
"command_markov_retraining": "Käsitellään {processed_data}/{data_size} datapisteestä...",
"command_markov_retrain_successful": "Markov-malli koulutettiin uudestaan {data_size} datapisteellä!",
"command_desc_talk":"puhuu ja sillei",
"command_talk_insufficent_text": "Minun pitää oppia lisää viesteistä ennen kun puhun.",
"command_talk_generation_fail": "Minulla ei ole mitään sanottavaa!",
"command_desc_help": "auta",
"command_help_embed_title": "Botin apu",
"command_help_embed_desc": "Komennot ryhmitelty kategorioilla",
"command_help_categories_general": "Yleiset",
"command_help_categories_admin": "Ylläpito",
"command_help_categories_custom": "Mukautetut komennot",
"command_ran": "Tietoa: {message.author.name} suoritti {message.content}",
"command_desc_ping": "ping",
"command_ping_embed_desc": "Botin viive:",
"command_ping_footer": "Pyytäjä: ",
"command_about_desc": "tietoa",
"command_about_embed_title": "Tietoa minusta",
"command_about_embed_field1": "Nimi",
"command_about_embed_field2name": "Versio",
"command_about_embed_field2value": "Paikallinen: {local_version} \nUusin: {latest_version}",
"command_desc_stats": "statistiikat",
"command_stats_embed_title": "Botin statistiikat",
"command_stats_embed_desc": "Tietoa botin muistista.",
"command_stats_embed_field1name": "Tiedostostatistiikat",
"command_stats_embed_field1value": "Koko: {file_size} tavua\nLinjoja: {line_count}",
"command_stats_embed_field2name": "Versio",
"command_stats_embed_field2value": "Paikallinen: {local_version} \nUusin: {latest_version}",
"command_stats_embed_field3name": "Muuttajainformaatio",
"command_stats_embed_field3value": "Nimi: {NAME} \nEtuliite: {PREFIX} \nOmistajan ID: {ownerid} \nJäähtymisaika: {cooldown_time} \nPing-linja: {PING_LINE} \nMuistin jako päällä: {showmemenabled} \nOppiminen käyttäjistä: {USERTRAIN_ENABLED}\nLaulu: {song} \nRoisketeksti: ```{splashtext}```"
}

81
assets/locales/fr.json Normal file
View file

@ -0,0 +1,81 @@
{
"modification_warning": "Goober a été modifié ! Toutes les modifications seront perdues lors d'une mise à jour !",
"reported_version": "Version rapportée :",
"current_hash": "Hachage actuel :",
"not_found": "n'est pas trouvé !",
"version_error": "Impossible de récupérer les informations de version. Code d'état",
"loaded_cog": "Cog chargé :",
"loaded_cog2": "Module chargé :",
"cog_fail": "Échec du chargement du cog :",
"cog_fail2": "Échec du chargement du module :",
"no_model": "Aucun modèle Markov sauvegardé trouvé. Démarrage à partir de zéro.",
"folder_created": "Dossier '{folder_name}' créé.",
"folder_exists": "Le dossier '{folder_name}' existe déjà. Ignorons...",
"logged_in": "Connecté en tant que",
"synced_commands": "Synchronisé",
"synced_commands2": "commandes !",
"fail_commands_sync": "Échec de la synchronisation des commandes :",
"started": "{name} a démarré !",
"name_check": "Erreur lors de la vérification de la disponibilité du nom :",
"name_taken": "Le nom est déjà pris. Veuillez choisir un autre nom.",
"name_check2": "Erreur lors de la vérification de la disponibilité du nom :",
"add_token": "Token : {token}\nVeuillez ajouter ce token à votre fichier .env comme",
"token_exists": "Le token existe déjà dans .env. Utilisation du token existant.",
"registration_error": "Erreur lors de l'enregistrement :",
"version_backup": "Sauvegarde créée :",
"backup_error": "Erreur : {LOCAL_VERSION_FILE} introuvable pour la sauvegarde.",
"model_loaded": "Modèle Markov chargé depuis",
"fetch_update_fail": "Impossible de récupérer les informations de mise à jour.",
"invalid_server": "Erreur : Informations de version invalides reçues du serveur.",
"goober_server_alert": "Alerte du serveur Goober central !\n",
"new_version": "Nouvelle version disponible : {latest_version} (Actuelle : {local_version})",
"changelog": "Consultez {VERSION_URL}/goob/changes.txt pour voir les modifications\n\n",
"invalid_version": "La version : {local_version} n'est pas valide !",
"invalid_version2": "Si c'est intentionnel, ignorez ce message. Sinon, appuyez sur Y pour récupérer une version valide depuis le serveur, quelle que soit la version actuelle de Goober.",
"invalid_version3": "La version actuelle sera sauvegardée dans current_version.bak..",
"input": "(Y ou toute autre touche pour ignorer...)",
"modification_ignored": "Vous avez modifié",
"modification_ignored2": "IGNOREWARNING est désactivé..",
"latest_version": "Vous utilisez la dernière version :",
"latest_version2": "Consultez {VERSION_URL}/goob/changes.txt pour voir les modifications",
"pinging_disabled": "Le ping est désactivé ! Je ne préviens pas le serveur que je suis en ligne...",
"goober_ping_success": "Connecté à Goober central en tant que {NAME}",
"goober_ping_fail": "Échec de l'envoi des données. Le serveur a retourné le code d'état :",
"goober_ping_fail2": "Une erreur est survenue lors de l'envoi des données :",
"sentence_positivity": "La positivité de la phrase est :",
"command_edit_fail": "Échec de la modification du message :",
"command_desc_retrain": "Réentraîne manuellement le modèle Markov.",
"command_markov_retrain": "Réentraînement du modèle Markov... Veuillez patienter.",
"command_markov_memory_not_found": "Erreur : fichier de mémoire introuvable !",
"command_markov_memory_is_corrupt": "Erreur : le fichier de mémoire est corrompu !",
"command_markov_retraining": "Traitement de {processed_data}/{data_size} points de données...",
"command_markov_retrain_successful": "Modèle Markov réentraîné avec succès en utilisant {data_size} points de données !",
"command_desc_talk": "parle et tout ça",
"command_talk_insufficent_text": "Je dois apprendre plus de messages avant de pouvoir parler.",
"command_talk_generation_fail": "Je n'ai rien à dire pour le moment !",
"command_desc_help": "aide",
"command_help_embed_title": "Aide du bot",
"command_help_embed_desc": "Liste des commandes regroupées par catégorie.",
"command_help_categories_general": "Général",
"command_help_categories_admin": "Administration",
"command_help_categories_custom": "Commandes personnalisées",
"command_ran": "Info : {message.author.name} a exécuté {message.content}",
"command_ran_s": "Info : {interaction.user} a exécuté ",
"command_desc_ping": "ping",
"command_ping_embed_desc": "Latence du bot :",
"command_ping_footer": "Demandé par",
"command_about_desc": "à propos",
"command_about_embed_title": "À propos de moi",
"command_about_embed_field1": "Nom",
"command_about_embed_field2name": "Version",
"command_about_embed_field2value": "Locale : {local_version} \nDernière : {latest_version}",
"command_desc_stats": "statistiques",
"command_stats_embed_title": "Statistiques du bot",
"command_stats_embed_desc": "Données sur la mémoire du bot.",
"command_stats_embed_field1name": "Statistiques du fichier",
"command_stats_embed_field1value": "Taille : {file_size} octets\nLignes : {line_count}",
"command_stats_embed_field2name": "Version",
"command_stats_embed_field2value": "Locale : {local_version} \nDernière : {latest_version}",
"command_stats_embed_field3name": "Informations variables",
"command_stats_embed_field3value": "Nom : {NAME} \nPréfixe : {PREFIX} \nID du propriétaire : {ownerid} \nTemps de recharge : {cooldown_time} \nLigne de ping : {PING_LINE} \nPartage de mémoire activé : {showmemenabled} \nEntraînement utilisateur activé : {USERTRAIN_ENABLED} \nChanson : {song} \nTexte de démarrage : ```{splashtext}```"
}

122
assets/locales/it.json Normal file
View file

@ -0,0 +1,122 @@
{
"already_started": "Sono già avviato! Non aggiorno...",
"please_restart": "Riavvia goober!",
"local_ahead": "Il ramo locale {remote}/{branch} è aggiornato o avanti. Nessun aggiornamento...",
"remote_ahead": "Il ramo remoto {remote}/{branch} è avanti. Aggiornamento in corso...",
"cant_find_local_version": "Impossibile trovare la variabile local_version! O è stata manomessa e non è un intero!",
"running_prestart_checks": "Esecuzione dei controlli pre-avvio...",
"continuing_in_seconds": "Continuo tra {seconds} secondi... Premi un tasto per saltare.",
"missing_requests_psutil": "Mancano requests e psutil! Installali con pip: `pip install requests psutil`",
"requirements_not_found": "requirements.txt non trovato in {path} è stato manomesso?",
"warning_failed_parse_imports": "Attenzione: impossibile analizzare le importazioni da {filename}: {error}",
"cogs_dir_not_found": "Cartella cogs non trovata in {path}, scansione saltata.",
"std_lib_local_skipped": "LIB STD / LOCALE {package} (controllo saltato)",
"ok_installed": "OK",
"missing_package": "MANCATE",
"missing_package2": "non è installato",
"missing_packages_detected": "Pacchetti mancanti rilevati:",
"telling_goober_central": "Segnalazione a goober central su {url}",
"failed_to_contact": "Impossibile contattare {url}: {error}",
"all_requirements_satisfied": "Tutti i requisiti sono soddisfatti.",
"ping_to": "Ping a {host}: {latency} ms",
"high_latency": "Latenza elevata rilevata! Potresti riscontrare ritardi nelle risposte.",
"could_not_parse_latency": "Impossibile analizzare la latenza.",
"ping_failed": "Ping a {host} fallito.",
"error_running_ping": "Errore durante l'esecuzione del ping: {error}",
"memory_usage": "Utilizzo memoria: {used} GB / {total} GB ({percent}%)",
"memory_above_90": "Utilizzo memoria sopra il 90% ({percent}%). Considera di liberare memoria.",
"total_memory": "Memoria totale: {total} GB",
"used_memory": "Memoria usata: {used} GB",
"low_free_memory": "Poca memoria libera! Solo {free} GB disponibili.",
"measuring_cpu": "Misurazione utilizzo CPU per core...",
"core_usage": "Core {idx}: [{bar}] {usage}%",
"total_cpu_usage": "Utilizzo totale CPU: {usage}%",
"high_avg_cpu": "Utilizzo medio CPU elevato: {usage}%",
"really_high_cpu": "Carico CPU molto alto! Il sistema potrebbe rallentare o bloccarsi.",
"memory_file": "File memoria: {size} MB",
"memory_file_large": "Il file di memoria è 1GB o più, valuta di svuotarlo.",
"memory_file_corrupted": "File memoria corrotto! Errore JSON decode: {error}",
"consider_backup_memory": "Valuta di fare un backup e ricreare il file di memoria.",
"memory_file_encoding": "Problemi di codifica nel file memoria: {error}",
"error_reading_memory": "Errore nella lettura del file memoria: {error}",
"memory_file_not_found": "File memoria non trovato.",
"modification_warning": "Goober è stato modificato! Verifiche del server saltate completamente...",
"reported_version": "Versione segnalata:",
"current_hash": "Hash attuale:",
"not_found": "non trovato!",
"version_error": "Impossibile recuperare le informazioni sulla versione. Codice di stato",
"loaded_cog": "Cog caricato:",
"cog_fail": "Impossibile caricare il cog:",
"loaded_cog2": "Module caricato:",
"cog_fail2": "Impossibile caricare il module:",
"no_model": "Nessun modello Markov salvato trovato. Iniziamo da zero.",
"folder_created": "Cartella '{folder_name}' creata.",
"folder_exists": "La cartella '{folder_name}' esiste già. Saltando...",
"logged_in": "Accesso effettuato come",
"synced_commands": "Sincronizzati",
"synced_commands2": "comandi!",
"fail_commands_sync": "Impossibile sincronizzare i comandi:",
"started": "{name} è stato avviato!",
"name_check": "Errore nel controllo disponibilità del nome:",
"name_taken": "Il nome è già preso. Scegli un nome diverso.",
"name_check2": "Errore durante il controllo della disponibilità del nome:",
"add_token": "Token: {token}\nAggiungi questo token al tuo file .env come",
"token_exists": "Il token esiste già in .env. Continuando con il token esistente.",
"goober_server_alert": "Avviso da goober central!\n",
"registration_error": "Errore durante la registrazione:",
"version_backup": "Backup creato:",
"backup_error": "Errore: {LOCAL_VERSION_FILE} non trovato per il backup.",
"model_loaded": "Modello Markov caricato da",
"fetch_update_fail": "Impossibile recuperare le informazioni sull'aggiornamento.",
"invalid_server": "Errore: informazioni sulla versione non valide ricevute dal server.",
"new_version": "Nuova versione disponibile: {latest_version} (Attuale: {local_version})",
"changelog": "Controlla {VERSION_URL}/goob/changes.txt per vedere il changelog\n\n",
"invalid_version": "La versione: {local_version} non è valida!",
"invalid_version2": "Se è intenzionale ignora questo messaggio, altrimenti premi Y per scaricare una versione valida dal server indipendentemente dalla versione attuale di goober",
"invalid_version3": "La versione attuale sarà salvata come current_version.bak..",
"input": "(Y o qualsiasi altro tasto per ignorare....)",
"modification_ignored": "Hai modificato",
"modification_ignored2": "IGNOREWARNING è impostato su false..",
"latest_version": "Stai utilizzando l'ultima versione:",
"latest_version2": "Controlla {VERSION_URL}/goob/changes.txt per vedere il changelog",
"pinging_disabled": "Il ping è disabilitato! Non dico al server che sono online...",
"goober_ping_success": "Accesso a goober central come {NAME}",
"goober_ping_fail": "Impossibile inviare i dati. Il server ha restituito il codice di stato:",
"goober_ping_fail2": "Si è verificato un errore durante l'invio dei dati:",
"sentence_positivity": "La positività della frase è:",
"command_edit_fail": "Impossibile modificare il messaggio:",
"command_desc_retrain": "Rafforza manualmente il modello Markov.",
"command_markov_retrain": "Rafforzamento del modello Markov in corso... Attendere.",
"command_markov_memory_not_found": "Errore: file di memoria non trovato!",
"command_markov_memory_is_corrupt": "Errore: file di memoria corrotto!",
"command_markov_retraining": "Elaborazione di {processed_data}/{data_size} punti dati...",
"command_markov_retrain_successful": "Modello Markov rafforzato con successo utilizzando {data_size} punti dati!",
"command_desc_talk": "parla n come stuf",
"command_talk_insufficent_text": "Ho bisogno di imparare di più dai messaggi prima di poter parlare.",
"command_talk_generation_fail": "Non ho nulla da dire in questo momento!",
"command_desc_help": "aiuto",
"command_help_embed_title": "Aiuto Bot",
"command_help_embed_desc": "Elenco dei comandi raggruppati per categoria.",
"command_help_categories_general": "Generale",
"command_help_categories_admin": "Amministrazione",
"command_help_categories_custom": "Comandi personalizzati",
"command_ran": "Info: {message.author.name} ha eseguito {message.content}",
"command_desc_ping": "ping",
"command_ping_embed_desc": "Latenza del bot:",
"command_ping_footer": "Richiesto da",
"command_about_desc": "informazioni",
"command_about_embed_title": "Informazioni su di me",
"command_about_embed_field1": "Nome",
"command_about_embed_field2name": "Versione",
"command_about_embed_field2value": "Locale: {local_version} \nUltima: {latest_version}",
"command_desc_stats": "statistiche",
"command_stats_embed_title": "Statistiche del bot",
"command_stats_embed_desc": "Dati sulla memoria del bot.",
"command_stats_embed_field1name": "Statistiche del file",
"command_stats_embed_field1value": "Dimensione: {file_size} byte\nLinee: {line_count}",
"command_stats_embed_field2name": "Versione",
"command_stats_embed_field2value": "Locale: {local_version} \nUltima: {latest_version}",
"command_stats_embed_field3name": "Informazioni sulle variabili",
"command_stats_embed_field3value": "Nome: {NAME} \nPrefisso: {PREFIX} \nID Proprietario: {ownerid} \nCooldown: {cooldown_time} \nLinea ping: {PING_LINE} \nMemoria Condivisa Abilitata: {showmemenabled} \nAddestramento Utente Abilitato: {USERTRAIN_ENABLED}\nCanzone: {song} \nSplashtext: ```{splashtext}```"
}