2025-01-05 21:03:49 +01:00
import discord
from discord . ext import commands , tasks
from discord import app_commands
import json
import markovify
import nltk
from nltk . tokenize import word_tokenize
import random
import os
import time
import re
import os
import requests
import platform
import subprocess
import psutil
import pickle
2025-02-26 19:36:19 +01:00
import hashlib
2025-01-05 21:03:49 +01:00
from better_profanity import profanity
2025-01-05 23:29:45 +01:00
from config import *
2025-02-26 19:36:19 +01:00
import traceback
import shutil
2025-07-18 01:50:58 +02:00
from volta import *
2025-03-24 21:31:45 +01:00
from nltk . sentiment . vader import SentimentIntensityAnalyzer
analyzer = SentimentIntensityAnalyzer ( )
2025-03-16 16:39:26 +01:00
2025-01-05 21:03:49 +01:00
print ( splashtext ) # you can use https://patorjk.com/software/taag/ for 3d text or just remove this entirely
2025-03-16 16:39:26 +01:00
2025-04-03 20:47:30 +02:00
os . makedirs ( " memories " , exist_ok = True )
os . makedirs ( " models " , exist_ok = True )
2025-03-16 16:39:26 +01:00
def download_json ( ) :
2025-03-16 19:37:48 +01:00
locales_dir = " locales "
2025-03-16 16:39:26 +01:00
response = requests . get ( f " { VERSION_URL } /goob/locales/ { LOCALE } .json " )
if response . status_code == 200 :
2025-03-16 19:37:48 +01:00
2025-03-16 16:39:26 +01:00
if not os . path . exists ( locales_dir ) :
os . makedirs ( locales_dir )
file_path = os . path . join ( locales_dir , f " { LOCALE } .json " )
if os . path . exists ( file_path ) :
return
else :
with open ( file_path , " w " , encoding = " utf-8 " ) as file :
file . write ( response . text )
if not os . path . exists ( os . path . join ( locales_dir , " en.json " ) ) :
2025-03-16 19:37:48 +01:00
2025-03-16 16:39:26 +01:00
response = requests . get ( f " { VERSION_URL } /goob/locales/en.json " )
if response . status_code == 200 :
with open ( os . path . join ( locales_dir , " en.json " ) , " w " , encoding = " utf-8 " ) as file :
file . write ( response . text )
download_json ( )
def load_translations ( ) :
translations = { }
translations_dir = os . path . join ( os . path . dirname ( __file__ ) , " locales " )
for filename in os . listdir ( translations_dir ) :
if filename . endswith ( " .json " ) :
lang_code = filename . replace ( " .json " , " " )
with open ( os . path . join ( translations_dir , filename ) , " r " , encoding = " utf-8 " ) as f :
translations [ lang_code ] = json . load ( f )
return translations
translations = load_translations ( )
2025-01-05 21:03:49 +01:00
def save_markov_model ( model , filename = ' markov_model.pkl ' ) :
2025-04-03 20:47:30 +02:00
model_file = f " models/ { filename } "
with open ( model_file , " wb " ) as f :
2025-01-05 21:03:49 +01:00
pickle . dump ( model , f )
2025-04-03 20:47:30 +02:00
print ( f " { GREEN } Markov model saved to { model_file } { RESET } " )
2025-01-05 21:03:49 +01:00
2025-04-03 20:47:30 +02:00
def load_markov_model ( server_id = None ) :
if server_id :
filename = f " markov_model_ { server_id } .pkl "
else :
filename = " markov_model.pkl "
model_file = f " models/ { filename } "
2025-01-05 21:03:49 +01:00
def get_latest_version_info ( ) :
try :
response = requests . get ( UPDATE_URL , timeout = 5 )
if response . status_code == 200 :
return response . json ( )
else :
2025-03-16 16:39:26 +01:00
print ( f " { RED } { get_translation ( LOCALE , ' version_error ' ) } { response . status_code } { RESET } " )
2025-01-05 21:03:49 +01:00
return None
except requests . RequestException as e :
2025-03-16 16:39:26 +01:00
print ( f " { RED } { get_translation ( LOCALE , ' version_error ' ) } { e } { RESET } " )
2025-01-05 21:03:49 +01:00
return None
2025-02-26 19:36:19 +01:00
2025-01-05 21:03:49 +01:00
async def load_cogs_from_folder ( bot , folder_name = " cogs " ) :
for filename in os . listdir ( folder_name ) :
if filename . endswith ( " .py " ) and not filename . startswith ( " _ " ) :
cog_name = filename [ : - 3 ]
try :
await bot . load_extension ( f " { folder_name } . { cog_name } " )
2025-03-16 16:39:26 +01:00
print ( f " { GREEN } { get_translation ( LOCALE , ' loaded_cog ' ) } { cog_name } { RESET } " )
2025-01-05 21:03:49 +01:00
except Exception as e :
2025-03-16 16:39:26 +01:00
print ( f " { RED } { get_translation ( LOCALE , ' cog_fail ' ) } { cog_name } { e } { RESET } " )
2025-02-26 19:36:19 +01:00
traceback . print_exc ( )
currenthash = " "
def generate_sha256_of_current_file ( ) :
global currenthash
sha256_hash = hashlib . sha256 ( )
with open ( __file__ , " rb " ) as f :
for byte_block in iter ( lambda : f . read ( 4096 ) , b " " ) :
sha256_hash . update ( byte_block )
currenthash = sha256_hash . hexdigest ( )
2025-01-05 21:03:49 +01:00
latest_version = " 0.0.0 "
2025-04-03 20:47:30 +02:00
local_version = " rewrite/seperate-memories "
2025-03-30 18:53:57 +02:00
os . environ [ ' gooberlocal_version ' ] = local_version
2025-03-30 20:24:39 +02:00
2025-01-05 21:03:49 +01:00
def check_for_update ( ) :
2025-07-18 01:50:58 +02:00
return
2025-01-05 21:03:49 +01:00
def get_file_info ( file_path ) :
try :
file_size = os . path . getsize ( file_path )
with open ( file_path , " r " ) as f :
lines = f . readlines ( )
return { " file_size_bytes " : file_size , " line_count " : len ( lines ) }
except Exception as e :
return { " error " : str ( e ) }
nltk . download ( ' punkt ' )
2025-04-03 20:47:30 +02:00
def load_memory ( server_id = None ) :
if server_id :
memory_file = f " memories/memory_ { server_id } .json "
else :
memory_file = " memories/memory.json "
2025-01-05 21:03:49 +01:00
data = [ ]
try :
2025-04-03 20:47:30 +02:00
with open ( memory_file , " r " ) as f :
2025-01-05 21:03:49 +01:00
data = json . load ( f )
except FileNotFoundError :
pass
2025-04-03 20:47:30 +02:00
except json . JSONDecodeError :
print ( f " { RED } Error decoding memory file { memory_file } { RESET } " )
2025-01-05 21:03:49 +01:00
return data
2025-04-03 20:47:30 +02:00
def save_memory ( memory , server_id = None ) :
if server_id :
memory_file = f " memories/memory_ { server_id } .json "
else :
memory_file = " memories/memory.json "
with open ( memory_file , " w " ) as f :
2025-01-05 21:03:49 +01:00
json . dump ( memory , f , indent = 4 )
2025-04-03 20:47:30 +02:00
def train_markov_model ( memory , additional_data = None , server_id = None ) :
2025-01-05 21:03:49 +01:00
if not memory :
return None
2025-04-03 20:47:30 +02:00
2025-01-05 21:03:49 +01:00
text = " \n " . join ( memory )
if additional_data :
text + = " \n " + " \n " . join ( additional_data )
2025-04-03 20:47:30 +02:00
try :
model = markovify . NewlineText ( text , state_size = 2 )
if server_id :
model_filename = f " markov_model_ { server_id } .pkl "
save_markov_model ( model , model_filename )
return model
except Exception as e :
print ( f " { RED } Error training model: { e } { RESET } " )
return None
2025-01-05 21:03:49 +01:00
#this doesnt work and im extremely pissed and mad
def append_mentions_to_18digit_integer ( message ) :
pattern = r ' \ b \ d {18} \ b '
2025-02-26 19:36:19 +01:00
return re . sub ( pattern , lambda match : f " " , message )
2025-01-05 21:03:49 +01:00
def preprocess_message ( message ) :
message = append_mentions_to_18digit_integer ( message )
tokens = word_tokenize ( message )
tokens = [ token for token in tokens if token . isalnum ( ) ]
return " " . join ( tokens )
intents = discord . Intents . default ( )
intents . messages = True
intents . message_content = True
2025-03-31 23:23:22 -04:00
bot = commands . Bot ( command_prefix = PREFIX , intents = intents , allowed_mentions = discord . AllowedMentions ( everyone = False , roles = False , users = False , replied_user = True ) )
2025-01-05 21:03:49 +01:00
memory = load_memory ( )
markov_model = load_markov_model ( )
if not markov_model :
2025-03-16 16:39:26 +01:00
print ( f " { get_translation ( LOCALE , ' no_model ' ) } " )
2025-01-05 21:03:49 +01:00
memory = load_memory ( )
markov_model = train_markov_model ( memory )
generated_sentences = set ( )
used_words = set ( )
slash_commands_enabled = False
@bot.event
async def on_ready ( ) :
2025-03-16 16:39:26 +01:00
2025-01-05 21:03:49 +01:00
folder_name = " cogs "
if not os . path . exists ( folder_name ) :
os . makedirs ( folder_name )
2025-03-16 16:39:26 +01:00
print ( f " { GREEN } { get_translation ( LOCALE , ' folder_created ' ) . format ( folder_name = folder_name ) } { RESET } " )
2025-01-05 21:03:49 +01:00
else :
2025-03-16 16:39:26 +01:00
print ( f " { DEBUG } { get_translation ( LOCALE , ' folder_exists ' ) . format ( folder_name = folder_name ) } { RESET } " )
2025-01-05 21:03:49 +01:00
markov_model = train_markov_model ( memory )
2025-01-21 16:44:42 +01:00
await load_cogs_from_folder ( bot )
2025-01-05 21:03:49 +01:00
global slash_commands_enabled
2025-03-16 16:39:26 +01:00
print ( f " { GREEN } { get_translation ( LOCALE , ' logged_in ' ) } { bot . user } { RESET } " )
2025-01-05 21:03:49 +01:00
try :
synced = await bot . tree . sync ( )
2025-03-16 16:39:26 +01:00
print ( f " { GREEN } { get_translation ( LOCALE , ' synced_commands ' ) } { len ( synced ) } { get_translation ( LOCALE , ' synced_commands2 ' ) } { RESET } " )
2025-01-05 21:03:49 +01:00
slash_commands_enabled = True
2025-03-16 16:39:26 +01:00
print ( f " { GREEN } { get_translation ( LOCALE , ' started ' ) . format ( ) } { RESET } " )
2025-01-05 21:03:49 +01:00
except Exception as e :
2025-03-16 16:39:26 +01:00
print ( f " { RED } { get_translation ( LOCALE , ' fail_commands_sync ' ) } { e } { RESET } " )
traceback . print_exc ( )
quit ( )
2025-01-05 21:03:49 +01:00
if not song :
return
await bot . change_presence ( activity = discord . Activity ( type = discord . ActivityType . listening , name = f " { song } " ) )
2025-07-18 01:50:58 +02:00
positive_gifs = os . getenv ( " POSITIVEGIFS " ) . split ( ' , ' )
2025-01-05 21:03:49 +01:00
def is_positive ( sentence ) :
2025-03-24 21:31:45 +01:00
scores = analyzer . polarity_scores ( sentence )
sentiment_score = scores [ ' compound ' ]
# forcin this fucker
debug_message = f " { DEBUG } { get_translation ( LOCALE , ' sentence_positivity ' ) } { sentiment_score } { RESET } "
print ( debug_message )
2025-03-24 21:58:26 +01:00
2025-02-26 20:28:50 +01:00
return sentiment_score > 0.1
2025-01-05 21:03:49 +01:00
async def send_message ( ctx , message = None , embed = None , file = None , edit = False , message_reference = None ) :
if edit and message_reference :
try :
# Editing the existing message
await message_reference . edit ( content = message , embed = embed )
except Exception as e :
2025-03-16 16:39:26 +01:00
await ctx . send ( f " { RED } { get_translation ( LOCALE , ' edit_fail ' ) } { e } { RESET } " )
2025-01-05 21:03:49 +01:00
else :
if hasattr ( ctx , " respond " ) :
# For slash command contexts
sent_message = None
if embed :
sent_message = await ctx . respond ( embed = embed , ephemeral = False )
elif message :
sent_message = await ctx . respond ( message , ephemeral = False )
if file :
sent_message = await ctx . respond ( file = file , ephemeral = False )
else :
sent_message = None
if embed :
sent_message = await ctx . send ( embed = embed )
elif message :
sent_message = await ctx . send ( message )
if file :
sent_message = await ctx . send ( file = file )
return sent_message
2025-04-03 20:47:30 +02:00
@bot.hybrid_command ( description = " Retrain Markov models for servers " )
@app_commands.choices ( option = [
app_commands . Choice ( name = " Retrain current server " , value = " current " ) ,
app_commands . Choice ( name = " Retrain all servers " , value = " all " ) ,
app_commands . Choice ( name = " Select servers to retrain " , value = " select " )
] )
2025-04-04 00:16:10 +02:00
async def retrain_models ( ctx , option : str = None ) :
if option is None and not ctx . interaction :
options_text = " all, current, select "
return await ctx . send ( f " Please specify an option: \n { options_text } " )
if isinstance ( option , app_commands . Choice ) :
option = option . value
2025-04-04 00:05:42 +02:00
if ctx . author . id == ownerid :
2025-04-04 00:16:10 +02:00
if option == " current " :
2025-04-04 00:05:42 +02:00
server_id = ctx . guild . id if ctx . guild else " DM "
await retrain_single_server ( ctx , server_id )
2025-04-04 00:16:10 +02:00
elif option == " all " :
2025-04-04 00:05:42 +02:00
await retrain_all_servers ( ctx )
2025-04-04 00:16:10 +02:00
elif option == " select " :
2025-04-04 00:05:42 +02:00
await show_server_selection ( ctx )
else :
if ctx . guild and ( ctx . author . guild_permissions . administrator or any ( role . permissions . administrator for role in ctx . author . roles ) ) :
2025-04-04 00:16:10 +02:00
if option == " current " :
2025-04-04 00:05:42 +02:00
server_id = ctx . guild . id
await retrain_single_server ( ctx , server_id )
else :
await ctx . send ( " You can only retrain the current server. " , ephemeral = True )
else :
await ctx . send ( " You don ' t have permission to use this command. " , ephemeral = True )
2025-04-03 20:47:30 +02:00
async def retrain_single_server ( ctx , server_id ) :
memory_file = f " memories/memory_ { server_id } .json "
model_file = f " models/markov_model_ { server_id } .pkl "
2025-01-05 21:03:49 +01:00
try :
2025-04-03 20:47:30 +02:00
with open ( memory_file , ' r ' ) as f :
2025-01-05 21:03:49 +01:00
memory = json . load ( f )
except FileNotFoundError :
2025-04-03 20:47:30 +02:00
return await ctx . send ( f " No memory data found for server { server_id } " , ephemeral = True )
2025-01-05 21:03:49 +01:00
2025-04-03 20:47:30 +02:00
processing_msg = await ctx . send ( f " Retraining model for server { server_id } ... " )
model = train_markov_model ( memory , server_id = server_id )
if model :
await processing_msg . edit ( content = f " Successfully retrained model for server { server_id } " )
else :
await processing_msg . edit ( content = f " Failed to retrain model for server { server_id } " )
2025-01-05 21:03:49 +01:00
2025-04-03 20:47:30 +02:00
async def retrain_all_servers ( ctx ) :
memory_files = [ f for f in os . listdir ( " memories/ " ) if f . startswith ( " memory_ " ) and f . endswith ( " .json " ) ]
if not memory_files :
return await ctx . send ( " No server memory files found to retrain. " , ephemeral = True )
progress_msg = await ctx . send ( f " Retraining models for { len ( memory_files ) } servers... " )
success_count = 0
for mem_file in memory_files :
try :
server_id = mem_file . replace ( " memory_ " , " " ) . replace ( " .json " , " " )
with open ( f " memories/ { mem_file } " , ' r ' ) as f :
memory = json . load ( f )
model = train_markov_model ( memory , server_id = server_id )
if model :
success_count + = 1
if success_count % 5 == 0 :
await progress_msg . edit ( content = f " Retraining in progress... { success_count } / { len ( memory_files ) } completed " )
except Exception as e :
print ( f " Error retraining { mem_file } : { e } " )
await progress_msg . edit ( content = f " Retraining complete successfully retrained { success_count } / { len ( memory_files ) } servers " )
async def show_server_selection ( ctx ) :
memory_files = [ f for f in os . listdir ( " memories/ " ) if f . startswith ( " memory_ " ) and f . endswith ( " .json " ) ]
if not memory_files :
return await ctx . send ( " No server memory files found. " , ephemeral = True )
options = [ ]
for mem_file in memory_files :
server_id = mem_file . replace ( " memory_ " , " " ) . replace ( " .json " , " " )
server_name = f " Server { server_id } "
if server_id != " DM " :
guild = bot . get_guild ( int ( server_id ) )
if guild :
server_name = guild . name
options . append ( discord . SelectOption ( label = server_name , value = server_id ) )
select_menus = [ ]
for i in range ( 0 , len ( options ) , 25 ) :
chunk = options [ i : i + 25 ]
select = discord . ui . Select (
placeholder = f " Select servers to retrain ( { i + 1 } - { min ( i + 25 , len ( options ) ) } ) " ,
min_values = 1 ,
max_values = len ( chunk ) ,
options = chunk
)
select_menus . append ( select )
view = discord . ui . View ( )
for menu in select_menus :
menu . callback = lambda interaction , m = menu : handle_server_selection ( interaction , m )
view . add_item ( menu )
2025-04-04 00:16:10 +02:00
if ctx . interaction :
await ctx . send ( " Select which servers to retrain: " , view = view )
else :
await ctx . reply ( " Select which servers to retrain: " , view = view )
2025-04-03 20:47:30 +02:00
async def handle_server_selection ( interaction , select_menu ) :
await interaction . response . defer ( )
selected_servers = select_menu . values
if not selected_servers :
return await interaction . followup . send ( " No servers selected. " , ephemeral = True )
progress_msg = await interaction . followup . send ( f " Retraining { len ( selected_servers ) } selected servers... " )
success_count = 0
for server_id in selected_servers :
try :
memory_file = f " memories/memory_ { server_id } .json "
with open ( memory_file , ' r ' ) as f :
memory = json . load ( f )
model = train_markov_model ( memory , server_id = server_id )
if model :
success_count + = 1
if success_count % 5 == 0 :
await progress_msg . edit ( content = f " Retraining in progress... { success_count } / { len ( selected_servers ) } completed " )
except Exception as e :
print ( f " Error retraining { server_id } : { e } " )
await progress_msg . edit ( content = f " Retraining complete Successfully retrained { success_count } / { len ( selected_servers ) } selected servers " )
2025-01-05 21:03:49 +01:00
2025-03-16 16:39:26 +01:00
@bot.hybrid_command ( description = f " { get_translation ( LOCALE , ' command_desc_talk ' ) } " )
2025-03-23 20:18:52 +01:00
async def talk ( ctx , sentence_size : int = 5 ) :
2025-04-03 20:47:30 +02:00
server_id = ctx . guild . id if ctx . guild else " DM "
markov_model = load_markov_model ( server_id )
2025-01-05 21:03:49 +01:00
if not markov_model :
2025-04-03 20:47:30 +02:00
memory = load_memory ( server_id )
markov_model = train_markov_model ( memory , server_id = server_id )
if not markov_model :
await send_message ( ctx , f " { get_translation ( LOCALE , ' command_talk_insufficent_text ' ) } " )
return
2025-01-05 21:03:49 +01:00
response = None
2025-03-23 20:18:52 +01:00
for _ in range ( 20 ) :
if sentence_size == 1 :
response = markov_model . make_short_sentence ( max_chars = 100 , tries = 100 )
if response :
response = response . split ( ) [ 0 ]
else :
response = markov_model . make_sentence ( tries = 100 , max_words = sentence_size )
2025-01-05 21:03:49 +01:00
if response and response not in generated_sentences :
2025-03-23 20:18:52 +01:00
if sentence_size > 1 :
response = improve_sentence_coherence ( response )
2025-01-05 21:03:49 +01:00
generated_sentences . add ( response )
break
if response :
cleaned_response = re . sub ( r ' [^ \ w \ s] ' , ' ' , response ) . lower ( )
coherent_response = rephrase_for_coherence ( cleaned_response )
if random . random ( ) < 0.9 and is_positive ( coherent_response ) :
gif_url = random . choice ( positive_gifs )
combined_message = f " { coherent_response } \n [jif]( { gif_url } ) "
else :
combined_message = coherent_response
2025-03-30 18:53:57 +02:00
print ( combined_message )
os . environ [ ' gooberlatestgen ' ] = combined_message
2025-01-05 21:03:49 +01:00
await send_message ( ctx , combined_message )
else :
2025-03-16 16:39:26 +01:00
await send_message ( ctx , f " { get_translation ( LOCALE , ' command_talk_generation_fail ' ) } " )
2025-01-05 21:03:49 +01:00
2025-04-03 20:47:30 +02:00
2025-01-05 21:03:49 +01:00
def improve_sentence_coherence ( sentence ) :
sentence = sentence . replace ( " i " , " I " )
return sentence
def rephrase_for_coherence ( sentence ) :
words = sentence . split ( )
coherent_sentence = " " . join ( words )
return coherent_sentence
bot . help_command = None
2025-03-16 16:39:26 +01:00
@bot.hybrid_command ( description = f " { get_translation ( LOCALE , ' command_desc_help ' ) } " )
2025-01-05 21:03:49 +01:00
async def help ( ctx ) :
embed = discord . Embed (
2025-03-16 16:39:26 +01:00
title = f " { get_translation ( LOCALE , ' command_help_embed_title ' ) } " ,
description = f " { get_translation ( LOCALE , ' command_help_embed_desc ' ) } " ,
2025-01-05 21:03:49 +01:00
color = discord . Color . blue ( )
)
command_categories = {
2025-03-16 16:39:26 +01:00
f " { get_translation ( LOCALE , ' command_help_categories_general ' ) } " : [ " mem " , " talk " , " about " , " ping " ] ,
f " { get_translation ( LOCALE , ' command_help_categories_admin ' ) } " : [ " stats " , " retrain " ]
2025-01-05 21:03:49 +01:00
}
custom_commands = [ ]
for cog_name , cog in bot . cogs . items ( ) :
for command in cog . get_commands ( ) :
2025-03-16 19:37:48 +01:00
if command . name not in command_categories [ f " { get_translation ( LOCALE , ' command_help_categories_general ' ) } " ] and command . name not in command_categories [ f " { get_translation ( LOCALE , ' command_help_categories_admin ' ) } " ] :
2025-01-05 21:03:49 +01:00
custom_commands . append ( command . name )
if custom_commands :
2025-03-16 16:39:26 +01:00
embed . add_field ( name = f " { get_translation ( LOCALE , ' command_help_categories_custom ' ) } " , value = " \n " . join ( [ f " { PREFIX } { command } " for command in custom_commands ] ) , inline = False )
2025-01-05 21:03:49 +01:00
for category , commands_list in command_categories . items ( ) :
commands_in_category = " \n " . join ( [ f " { PREFIX } { command } " for command in commands_list ] )
embed . add_field ( name = category , value = commands_in_category , inline = False )
await send_message ( ctx , embed = embed )
@bot.event
async def on_message ( message ) :
if message . author . bot :
return
if str ( message . author . id ) in BLACKLISTED_USERS :
return
if message . content . startswith ( ( f " { PREFIX } talk " , f " { PREFIX } mem " , f " { PREFIX } help " , f " { PREFIX } stats " , f " { PREFIX } " ) ) :
2025-03-16 16:39:26 +01:00
print ( f " { get_translation ( LOCALE , ' command_ran ' ) . format ( message = message ) } " )
2025-01-05 21:03:49 +01:00
await bot . process_commands ( message )
return
if profanity . contains_profanity ( message . content ) :
return
2025-04-03 20:47:30 +02:00
if message . content and USERTRAIN_ENABLED :
server_id = message . guild . id if message . guild else " DM "
memory = load_memory ( server_id )
2025-01-05 21:03:49 +01:00
formatted_message = append_mentions_to_18digit_integer ( message . content )
cleaned_message = preprocess_message ( formatted_message )
2025-04-03 20:47:30 +02:00
2025-01-05 21:03:49 +01:00
if cleaned_message :
memory . append ( cleaned_message )
2025-04-03 20:47:30 +02:00
save_memory ( memory , server_id )
2025-01-05 21:03:49 +01:00
await bot . process_commands ( message )
2025-03-30 21:01:20 +02:00
2025-03-30 18:53:57 +02:00
@bot.event
async def on_interaction ( interaction ) :
2025-04-03 20:47:30 +02:00
try :
if interaction . type == discord . InteractionType . application_command :
command_name = interaction . data . get ( ' name ' , ' unknown ' )
print ( f " { get_translation ( LOCALE , ' command_ran_s ' ) . format ( interaction = interaction ) } { command_name } " )
except Exception as e :
print ( f " { RED } Error handling interaction: { e } { RESET } " )
traceback . print_exc ( )
2025-03-30 18:53:57 +02:00
2025-03-30 21:01:20 +02:00
@bot.check
async def block_blacklisted ( ctx ) :
if str ( ctx . author . id ) in BLACKLISTED_USERS :
try :
if isinstance ( ctx , discord . Interaction ) :
if not ctx . response . is_done ( ) :
await ctx . response . send_message ( " You are blacklisted. " , ephemeral = True )
else :
await ctx . followup . send ( " You are blacklisted. " , ephemeral = True )
else :
await ctx . send ( " You are blacklisted. " , ephemeral = True )
except :
pass
return False
return True
2025-03-16 16:39:26 +01:00
@bot.hybrid_command ( description = f " { get_translation ( LOCALE , ' command_desc_ping ' ) } " )
2025-01-05 21:03:49 +01:00
async def ping ( ctx ) :
await ctx . defer ( )
latency = round ( bot . latency * 1000 )
LOLembed = discord . Embed (
title = " Pong!! " ,
description = (
f " { PING_LINE } \n "
2025-03-16 16:39:26 +01:00
f " ` { get_translation ( LOCALE , ' command_ping_embed_desc ' ) } : { latency } ms` \n "
2025-01-05 21:03:49 +01:00
) ,
color = discord . Color . blue ( )
)
2025-03-16 16:39:26 +01:00
LOLembed . set_footer ( text = f " { get_translation ( LOCALE , ' command_ping_footer ' ) } { ctx . author . name } " , icon_url = ctx . author . avatar . url )
2025-01-05 21:03:49 +01:00
await ctx . send ( embed = LOLembed )
2025-03-16 16:39:26 +01:00
@bot.hybrid_command ( description = f " { get_translation ( LOCALE , ' command_about_desc ' ) } " )
2025-01-05 21:03:49 +01:00
async def about ( ctx ) :
2025-03-16 16:39:26 +01:00
embed = discord . Embed ( title = f " { get_translation ( LOCALE , ' command_about_embed_title ' ) } " , description = " " , color = discord . Color . blue ( ) )
embed . add_field ( name = f " { get_translation ( LOCALE , ' command_about_embed_field1 ' ) } " , value = f " { NAME } " , inline = False )
2025-07-18 01:50:58 +02:00
embed . add_field ( name = f " { get_translation ( LOCALE , ' command_about_embed_field2name ' ) } " , value = f " { get_translation ( LOCALE , ' command_about_embed_field2value ' ) . format ( local_version = local_version , latest_version = ' I have not been updated with the new version checking! ' ) } " , inline = False )
2025-01-05 21:03:49 +01:00
await send_message ( ctx , embed = embed )
@bot.hybrid_command ( description = " stats " )
async def stats ( ctx ) :
if ctx . author . id != ownerid :
return
2025-03-16 16:39:26 +01:00
print ( " ----------------------------------- \n \n " )
2025-01-05 21:03:49 +01:00
try :
check_for_update ( )
except Exception as e :
pass
print ( " ----------------------------------- " )
memory_file = ' memory.json '
file_size = os . path . getsize ( memory_file )
with open ( memory_file , ' r ' ) as file :
line_count = sum ( 1 for _ in file )
2025-03-16 16:39:26 +01:00
embed = discord . Embed ( title = f " { get_translation ( LOCALE , ' command_stats_embed_title ' ) } " , description = f " { get_translation ( LOCALE , ' command_stats_embed_desc ' ) } " , color = discord . Color . blue ( ) )
embed . add_field ( name = f " { get_translation ( LOCALE , ' command_stats_embed_field1name ' ) } " , value = f " { get_translation ( LOCALE , ' command_stats_embed_field1value ' ) . format ( file_size = file_size , line_count = line_count ) } " , inline = False )
embed . add_field ( name = f " { get_translation ( LOCALE , ' command_stats_embed_field2name ' ) } " , value = f " { get_translation ( LOCALE , ' command_stats_embed_field2value ' ) . format ( local_version = local_version , latest_version = latest_version ) } " , inline = False )
embed . add_field ( name = f " { get_translation ( LOCALE , ' command_stats_embed_field3name ' ) } " , value = f " { get_translation ( LOCALE , ' command_stats_embed_field3value ' ) . format ( NAME = NAME , PREFIX = PREFIX , ownerid = ownerid , cooldown_time = cooldown_time , PING_LINE = PING_LINE , showmemenabled = showmemenabled , USERTRAIN_ENABLED = USERTRAIN_ENABLED , last_random_talk_time = last_random_talk_time , song = song , splashtext = splashtext ) } " , inline = False )
2025-01-05 21:03:49 +01:00
await send_message ( ctx , embed = embed )
@bot.hybrid_command ( )
async def mem ( ctx ) :
if showmemenabled != " true " :
return
2025-04-03 20:47:30 +02:00
server_id = ctx . guild . id if ctx . guild else " DM "
memory_file = f " memories/memory_ { server_id } .json " if server_id else " memories/memory.json "
try :
with open ( memory_file , " r " ) as f :
await send_message ( ctx , file = discord . File ( f , memory_file ) )
except FileNotFoundError :
await send_message ( ctx , f " No memory file found at { memory_file } " )
2025-01-05 21:03:49 +01:00
def improve_sentence_coherence ( sentence ) :
sentence = sentence . replace ( " i " , " I " )
return sentence
2025-03-31 23:23:22 -04:00
bot . run ( TOKEN )