the translation update
This commit is contained in:
parent
2e3c6942b6
commit
d122c5ffe9
22 changed files with 345 additions and 84 deletions
27
assets/cogs/README.md
Normal file
27
assets/cogs/README.md
Normal 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
66
assets/cogs/cogmanager.py
Normal 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))
|
48
assets/cogs/filesharing.py
Normal file
48
assets/cogs/filesharing.py
Normal 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))
|
29
assets/cogs/grabtemplate.py
Normal file
29
assets/cogs/grabtemplate.py
Normal 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
83
assets/cogs/lastfm.py
Normal 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))
|
22
assets/cogs/slashcomandexample.py
Normal file
22
assets/cogs/slashcomandexample.py
Normal 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))
|
33
assets/cogs/songchanger.py
Normal file
33
assets/cogs/songchanger.py
Normal 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
155
assets/cogs/tf.py.disabled
Normal 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))
|
113
assets/cogs/webscraper.py.disabled
Normal file
113
assets/cogs/webscraper.py.disabled
Normal 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
880
assets/cogs/webserver.py
Normal 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
24
assets/cogs/whoami.py
Normal 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
123
assets/locales/en.json
Normal 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
77
assets/locales/es.json
Normal 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
120
assets/locales/fi.json
Normal 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
81
assets/locales/fr.json
Normal 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
122
assets/locales/it.json
Normal 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}```"
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue