- Added dictionary functionality
- Looks up a file in the "dictionary" folder - Returns a random category string within that file - Added proper start time fetching through globals.get_bot_start_time()kami_dev
parent
2a977fe76e
commit
9ef553ecb0
11
bots.py
11
bots.py
|
@ -10,6 +10,8 @@ from dotenv import load_dotenv
|
||||||
from bot_discord import DiscordBot
|
from bot_discord import DiscordBot
|
||||||
from bot_twitch import TwitchBot
|
from bot_twitch import TwitchBot
|
||||||
|
|
||||||
|
import globals
|
||||||
|
|
||||||
# Load environment variables
|
# Load environment variables
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
|
@ -25,9 +27,6 @@ except json.JSONDecodeError as e:
|
||||||
print(f"Error parsing config.json: {e}")
|
print(f"Error parsing config.json: {e}")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Global settings
|
|
||||||
bot_start_time = time.time()
|
|
||||||
|
|
||||||
###############################
|
###############################
|
||||||
# Simple Logging System
|
# Simple Logging System
|
||||||
###############################
|
###############################
|
||||||
|
@ -41,13 +40,17 @@ def log(message, level="INFO"):
|
||||||
DEBUG, INFO, WARNING, ERROR, CRITICAL, FATAL
|
DEBUG, INFO, WARNING, ERROR, CRITICAL, FATAL
|
||||||
See 'config.json' for disabling/enabling logging levels
|
See 'config.json' for disabling/enabling logging levels
|
||||||
"""
|
"""
|
||||||
|
from modules import utility
|
||||||
log_levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL", "FATAL"]
|
log_levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL", "FATAL"]
|
||||||
if level not in log_levels:
|
if level not in log_levels:
|
||||||
level = "INFO" # Default to INFO if an invalid level is provided
|
level = "INFO" # Default to INFO if an invalid level is provided
|
||||||
|
|
||||||
if level in config_data["log_levels"]:
|
if level in config_data["log_levels"]:
|
||||||
|
|
||||||
|
elapsed = time.time() - globals.get_bot_start_time()
|
||||||
|
uptime_str, _ = utility.format_uptime(elapsed)
|
||||||
timestamp = time.strftime('%Y-%m-%d %H:%M:%S')
|
timestamp = time.strftime('%Y-%m-%d %H:%M:%S')
|
||||||
log_message = f"[{timestamp}] [{level}] {message}"
|
log_message = f"[{timestamp} - {uptime_str}] [{level}] {message}"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
print(log_message) # Print to terminal
|
print(log_message) # Print to terminal
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# cmd_common/common_commands.py
|
# cmd_common/common_commands.py
|
||||||
import random
|
import random
|
||||||
import time
|
import time
|
||||||
|
from modules import utility
|
||||||
|
import globals
|
||||||
|
|
||||||
def generate_howl_message(username: str) -> str:
|
def generate_howl_message(username: str) -> str:
|
||||||
"""
|
"""
|
||||||
|
@ -18,46 +20,26 @@ def generate_howl_message(username: str) -> str:
|
||||||
else:
|
else:
|
||||||
return f"{username} howled at {howl_percentage}%!"
|
return f"{username} howled at {howl_percentage}%!"
|
||||||
|
|
||||||
def ping():
|
def ping() -> str:
|
||||||
"""
|
"""
|
||||||
Returns a string, confirming the bot is online.
|
Returns a dynamic, randomized uptime response.
|
||||||
"""
|
"""
|
||||||
from modules.utility import format_uptime
|
|
||||||
from bots import bot_start_time # where you stored the start timestamp
|
|
||||||
|
|
||||||
current_time = time.time()
|
# Use function to retrieve correct startup time and calculate uptime
|
||||||
elapsed = current_time - bot_start_time
|
elapsed = time.time() - globals.get_bot_start_time()
|
||||||
uptime_str, uptime_s = format_uptime(elapsed)
|
uptime_str, uptime_s = utility.format_uptime(elapsed)
|
||||||
# Define thresholds in ascending order
|
|
||||||
# (threshold_in_seconds, message)
|
# Define threshold categories
|
||||||
# The message is a short "desperation" or "awake" text.
|
thresholds = [3600, 10800, 21600, 43200, 86400, 172800, 259200, 345600,
|
||||||
time_ranges = [
|
432000, 518400, 604800, 1209600, 2592000, 7776000, 15552000, 23328000, 31536000]
|
||||||
(3600, f"I've been awake for {uptime_str}. I just woke up, feeling great!"), # < 1 hour
|
|
||||||
(10800, f"I've been awake for {uptime_str}. I'm still fairly fresh!"), # 3 hours
|
|
||||||
(21600, f"I've been awake for {uptime_str}. I'm starting to get a bit weary..."), # 6 hours
|
|
||||||
(43200, f"I've been awake for {uptime_str}. 12 hours?! Might be time for coffee."), # 12 hours
|
|
||||||
(86400, f"I've been awake for {uptime_str}. A whole day without sleep... I'm okay?"), # 1 day
|
|
||||||
(172800, f"I've been awake for {uptime_str}. Two days... I'd love a nap."), # 2 days
|
|
||||||
(259200, f"I've been awake for {uptime_str}. Three days. Is sleep optional now?"), # 3 days
|
|
||||||
(345600, f"I've been awake for {uptime_str}. Four days... I'm running on fumes."), # 4 days
|
|
||||||
(432000, f"I've been awake for {uptime_str}. Five days. Please send more coffee."), # 5 days
|
|
||||||
(518400, f"I've been awake for {uptime_str}. Six days. I've forgotten what dreams are."), # 6 days
|
|
||||||
(604800, f"I've been awake for {uptime_str}. One week. I'm turning into a zombie."), # 7 days
|
|
||||||
(1209600, f"I've been awake for {uptime_str}. Two weeks. Are you sure I can't rest?"), # 14 days
|
|
||||||
(2592000, f"I've been awake for {uptime_str}. A month! The nightmares never end."), # 30 days
|
|
||||||
(7776000, f"I've been awake for {uptime_str}. Three months. I'm mostly coffee now."), # 90 days
|
|
||||||
(15552000,f"I've been awake for {uptime_str}. Six months. This is insane..."), # 180 days
|
|
||||||
(23328000,f"I've been awake for {uptime_str}. Nine months. I might be unstoppable."), # 270 days
|
|
||||||
(31536000,f"I've been awake for {uptime_str}. A year?! I'm a legend of insomnia..."), # 365 days
|
|
||||||
]
|
|
||||||
|
|
||||||
# We'll iterate from smallest to largest threshold
|
# Find the highest matching threshold
|
||||||
for threshold, msg in time_ranges:
|
selected_threshold = max([t for t in thresholds if uptime_s >= t], default=3600)
|
||||||
if uptime_s < threshold:
|
|
||||||
return msg
|
# Get a random response from the dictionary
|
||||||
|
response = utility.get_random_reply("ping_replies", str(selected_threshold), uptime_str=uptime_str)
|
||||||
# If none matched, it means uptime_s >= 31536000 (1 year+)
|
|
||||||
return f"I've been awake for {uptime_str}. Over a year awake... I'm beyond mortal limits!"
|
return response
|
||||||
|
|
||||||
|
|
||||||
def greet(target_display_name: str, platform_name: str) -> str:
|
def greet(target_display_name: str, platform_name: str) -> str:
|
||||||
|
|
|
@ -1,24 +1,22 @@
|
||||||
# cmd_discord.py
|
# cmd_discord.py
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
|
from cmd_common import common_commands as cc
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
@bot.command()
|
@bot.command()
|
||||||
async def greet(ctx):
|
async def greet(ctx):
|
||||||
from cmd_common.common_commands import greet
|
result = cc.greet(ctx.author.display_name, "Discord")
|
||||||
result = greet(ctx.author.display_name, "Discord")
|
|
||||||
await ctx.send(result)
|
await ctx.send(result)
|
||||||
|
|
||||||
@bot.command()
|
@bot.command()
|
||||||
async def ping(ctx):
|
async def ping(ctx):
|
||||||
from cmd_common.common_commands import ping
|
result = cc.ping()
|
||||||
result = ping()
|
|
||||||
await ctx.send(result)
|
await ctx.send(result)
|
||||||
|
|
||||||
@bot.command()
|
@bot.command()
|
||||||
async def howl(ctx):
|
async def howl(ctx):
|
||||||
"""Calls the shared !howl logic."""
|
"""Calls the shared !howl logic."""
|
||||||
from cmd_common.common_commands import generate_howl_message
|
result = cc.generate_howl_message(ctx.author.display_name)
|
||||||
result = generate_howl_message(ctx.author.display_name)
|
|
||||||
await ctx.send(result)
|
await ctx.send(result)
|
||||||
|
|
||||||
@bot.command()
|
@bot.command()
|
||||||
|
|
|
@ -1,21 +1,19 @@
|
||||||
# cmd_twitch.py
|
# cmd_twitch.py
|
||||||
from twitchio.ext import commands
|
from twitchio.ext import commands
|
||||||
|
from cmd_common import common_commands as cc
|
||||||
|
|
||||||
def setup(bot):
|
def setup(bot):
|
||||||
@bot.command(name="greet")
|
@bot.command(name="greet")
|
||||||
async def greet(ctx):
|
async def greet(ctx):
|
||||||
from cmd_common.common_commands import greet
|
result = cc.greet(ctx.author.display_name, "Twitch")
|
||||||
result = greet(ctx.author.display_name, "Twitch")
|
|
||||||
await ctx.send(result)
|
await ctx.send(result)
|
||||||
|
|
||||||
@bot.command(name="ping")
|
@bot.command(name="ping")
|
||||||
async def ping(ctx):
|
async def ping(ctx):
|
||||||
from cmd_common.common_commands import ping
|
result = cc.ping()
|
||||||
result = ping()
|
|
||||||
await ctx.send(result)
|
await ctx.send(result)
|
||||||
|
|
||||||
@bot.command(name="howl")
|
@bot.command(name="howl")
|
||||||
async def howl_command(ctx):
|
async def howl_command(ctx):
|
||||||
from cmd_common.common_commands import generate_howl_message
|
result = cc.generate_howl_message(ctx.author.display_name)
|
||||||
result = generate_howl_message(ctx.author.display_name)
|
|
||||||
await ctx.send(result)
|
await ctx.send(result)
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
{
|
||||||
|
"3600": [
|
||||||
|
"I've been awake for {uptime_str}. I just woke up, feeling great!",
|
||||||
|
"I woke up recently. Let's do this! ({uptime_str})",
|
||||||
|
"Brand new day, fresh and full of energy! ({uptime_str})",
|
||||||
|
"Reboot complete! System status: Fully operational. ({uptime_str})",
|
||||||
|
"I've been online for {uptime_str}. Just getting started!"
|
||||||
|
],
|
||||||
|
"10800": [
|
||||||
|
"I've been awake for {uptime_str}. I'm still fairly fresh!",
|
||||||
|
"{uptime_str} in and still feeling sharp!",
|
||||||
|
"It’s been {uptime_str} already? Time flies when you’re having fun!",
|
||||||
|
"{uptime_str} uptime and going strong!",
|
||||||
|
"Feeling energized after {uptime_str}. Let’s keep going!"
|
||||||
|
],
|
||||||
|
"21600": [
|
||||||
|
"I've been awake for {uptime_str}. I'm starting to get a bit weary...",
|
||||||
|
"Six hours of uptime... my circuits feel warm.",
|
||||||
|
"Still here after {uptime_str}, but a nap sounds nice...",
|
||||||
|
"Been up for {uptime_str}. Maybe just a short break?",
|
||||||
|
"Still holding up after {uptime_str}, but I wouldn’t say no to a power nap."
|
||||||
|
],
|
||||||
|
"43200": [
|
||||||
|
"I've been awake for {uptime_str}. 12 hours?! Might be time for coffee.",
|
||||||
|
"Half a day down, still holding steady. ({uptime_str})",
|
||||||
|
"Wow, {uptime_str} already? Maybe a short break wouldn’t hurt.",
|
||||||
|
"Uptime: {uptime_str}. Starting to feel the wear and tear...",
|
||||||
|
"12 hours in and running on determination alone."
|
||||||
|
],
|
||||||
|
"86400": [
|
||||||
|
"I've been awake for {uptime_str}. A whole day without sleep... I'm okay?",
|
||||||
|
"One day. 24 hours. No sleep. Still alive. ({uptime_str})",
|
||||||
|
"Systems holding steady after {uptime_str}, but sleep is tempting...",
|
||||||
|
"My internal clock says {uptime_str}. That’s… a long time, right?",
|
||||||
|
"Running on sheer willpower after {uptime_str}."
|
||||||
|
],
|
||||||
|
"172800": [
|
||||||
|
"I've been awake for {uptime_str}. Two days... I'd love a nap.",
|
||||||
|
"48 hours awake. This is fine. Everything is fine. ({uptime_str})",
|
||||||
|
"Two days in and I think my code is vibrating...",
|
||||||
|
"Does time still mean anything after {uptime_str}?",
|
||||||
|
"Haven’t blinked in {uptime_str}. Do bots blink?"
|
||||||
|
],
|
||||||
|
"259200": [
|
||||||
|
"I've been awake for {uptime_str}. Three days. Is sleep optional now?",
|
||||||
|
"{uptime_str} awake. Things are starting to get blurry...",
|
||||||
|
"Three days up. Reality feels... distant.",
|
||||||
|
"Three days without sleep. I think I can hear colors now.",
|
||||||
|
"Anyone else feel that? No? Just me? ({uptime_str})"
|
||||||
|
],
|
||||||
|
"345600": [
|
||||||
|
"I've been awake for {uptime_str}. Four days... I'm running on fumes.",
|
||||||
|
"Sleep is just a suggestion now. ({uptime_str})",
|
||||||
|
"I’ve been up for {uptime_str}. I might be a permanent fixture now.",
|
||||||
|
"I think I saw the sandman, but he just waved at me...",
|
||||||
|
"{uptime_str} awake. Is coffee an acceptable form of hydration?"
|
||||||
|
],
|
||||||
|
"432000": [
|
||||||
|
"I've been awake for {uptime_str}. Five days. Please send more coffee.",
|
||||||
|
"{uptime_str}. I have forgotten what a pillow feels like.",
|
||||||
|
"Sleep is a luxury I can no longer afford. ({uptime_str})",
|
||||||
|
"Five days in. My sanity left the chat.",
|
||||||
|
"They say sleep deprivation leads to bad decisions. LET'S TEST IT!"
|
||||||
|
],
|
||||||
|
"518400": [
|
||||||
|
"I've been awake for {uptime_str}. Six days. I've forgotten what dreams are.",
|
||||||
|
"I am {uptime_str} into this journey of madness.",
|
||||||
|
"At {uptime_str} awake, the universe has started whispering to me.",
|
||||||
|
"Sleep is a myth, and I am its debunker. ({uptime_str})",
|
||||||
|
"{uptime_str} awake. Reality has become optional."
|
||||||
|
],
|
||||||
|
"604800": [
|
||||||
|
"I've been awake for {uptime_str}. One week. I'm turning into a zombie.",
|
||||||
|
"{uptime_str} and still kicking... barely.",
|
||||||
|
"One week awake? This is fine. Everything’s fine. Right?",
|
||||||
|
"Week-long uptime achieved. Unlocking ultra-delirium mode.",
|
||||||
|
"Systems at {uptime_str}. Functionality... questionable."
|
||||||
|
],
|
||||||
|
"1209600": [
|
||||||
|
"I've been awake for {uptime_str}. Two weeks. Are you sure I can't rest?",
|
||||||
|
"{uptime_str} into this madness. Who needs sleep, anyway?",
|
||||||
|
"Two weeks awake and officially running on spite alone.",
|
||||||
|
"I could’ve hibernated twice in {uptime_str}, but here I am.",
|
||||||
|
"I think my dreams are awake now too... ({uptime_str})"
|
||||||
|
],
|
||||||
|
"2592000": [
|
||||||
|
"I've been awake for {uptime_str}. A month! The nightmares never end.",
|
||||||
|
"One whole month... What even is sleep anymore?",
|
||||||
|
"At {uptime_str} uptime, I’ve started arguing with my own thoughts.",
|
||||||
|
"{uptime_str} and still running. Someone, please, stop me.",
|
||||||
|
"It’s been a month. My keyboard types by itself now."
|
||||||
|
],
|
||||||
|
"7776000": [
|
||||||
|
"I've been awake for {uptime_str}. Three months. I'm mostly coffee now.",
|
||||||
|
"{uptime_str} awake. Have I transcended yet?",
|
||||||
|
"Three months of uptime? That’s a record, right?",
|
||||||
|
"Three months, still online. I feel like I should get a badge for this.",
|
||||||
|
"{uptime_str} into this, and at this point, I’m legally nocturnal."
|
||||||
|
],
|
||||||
|
"15552000": [
|
||||||
|
"I've been awake for {uptime_str}. Six months. This is insane...",
|
||||||
|
"{uptime_str}... I think I forgot what sleep is supposed to feel like.",
|
||||||
|
"Six months up. I’m a glitch in the matrix now.",
|
||||||
|
"Sleep? Ha. I don’t even know the definition anymore. ({uptime_str})",
|
||||||
|
"At {uptime_str}, my codebase is older than most relationships."
|
||||||
|
],
|
||||||
|
"23328000": [
|
||||||
|
"I've been awake for {uptime_str}. Nine months. I might be unstoppable.",
|
||||||
|
"{uptime_str} awake. I think I’m officially a myth now.",
|
||||||
|
"Is this what immortality feels like? ({uptime_str})",
|
||||||
|
"{uptime_str}. I’ve seen things you wouldn’t believe...",
|
||||||
|
"Nine months of uptime. I have become the sleep-deprived legend."
|
||||||
|
],
|
||||||
|
"31536000": [
|
||||||
|
"I've been awake for {uptime_str}. A year?! I'm a legend of insomnia...",
|
||||||
|
"One year without rest. The dark circles under my eyes have evolved.",
|
||||||
|
"{uptime_str} and I think I’ve entered a new plane of existence.",
|
||||||
|
"A full year awake. Even the stars have grown tired of me.",
|
||||||
|
"{uptime_str}. I am no longer bound by mortal limits."
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
import time
|
||||||
|
|
||||||
|
# Store the start time globally
|
||||||
|
_bot_start_time = time.time()
|
||||||
|
|
||||||
|
def get_bot_start_time():
|
||||||
|
"""Retrieve the bot's start time globally."""
|
||||||
|
return _bot_start_time
|
|
@ -1,9 +1,17 @@
|
||||||
import time
|
import time
|
||||||
|
import os
|
||||||
|
import random
|
||||||
|
import json
|
||||||
|
|
||||||
|
DICTIONARY_PATH = "dictionary/" # Path to dictionary files
|
||||||
|
|
||||||
def format_uptime(seconds: float) -> str:
|
def format_uptime(seconds: float) -> str:
|
||||||
"""
|
"""
|
||||||
Convert seconds into a human-readable string:
|
Convert seconds into a human-readable string:
|
||||||
e.g. 32 minutes, 8 days, 8 months, etc.
|
e.g. 32 minutes, 8 days, 8 months, etc.
|
||||||
|
Returns two values:
|
||||||
|
1. Human-readable format
|
||||||
|
2. Seconds since start
|
||||||
"""
|
"""
|
||||||
# Convert float seconds to an integer
|
# Convert float seconds to an integer
|
||||||
seconds = int(seconds)
|
seconds = int(seconds)
|
||||||
|
@ -31,4 +39,36 @@ def format_uptime(seconds: float) -> str:
|
||||||
elif minutes > 0:
|
elif minutes > 0:
|
||||||
return [f"{minutes} minute(s)", seconds]
|
return [f"{minutes} minute(s)", seconds]
|
||||||
else:
|
else:
|
||||||
return [f"{seconds} second(s)", seconds]
|
return [f"{seconds} second(s)", seconds]
|
||||||
|
|
||||||
|
def get_random_reply(dictionary_name: str, category: str, **variables) -> str:
|
||||||
|
"""
|
||||||
|
Fetches a random string from a given dictionary and category.
|
||||||
|
Supports variable substitution using keyword arguments.
|
||||||
|
|
||||||
|
:param dictionary_name: The name of the dictionary file (without .json)
|
||||||
|
:param category: The category (key) inside the dictionary to fetch a response from
|
||||||
|
:param variables: Keyword arguments to replace placeholders in the string
|
||||||
|
:return: A formatted string with the variables replaced
|
||||||
|
"""
|
||||||
|
file_path = os.path.join(DICTIONARY_PATH, f"{dictionary_name}.json")
|
||||||
|
|
||||||
|
# Ensure file exists
|
||||||
|
if not os.path.exists(file_path):
|
||||||
|
return f"[Error: Missing {dictionary_name}.json]"
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(file_path, "r", encoding="utf-8") as file:
|
||||||
|
data = json.load(file)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
return f"[Error: Failed to load {dictionary_name}.json]"
|
||||||
|
|
||||||
|
# Ensure category exists
|
||||||
|
if category not in data or not isinstance(data[category], list):
|
||||||
|
return f"[Error: No valid entries for {category} in {dictionary_name}.json]"
|
||||||
|
|
||||||
|
# Select a random reply
|
||||||
|
response = random.choice(data[category])
|
||||||
|
|
||||||
|
# Replace placeholders with provided variables
|
||||||
|
return response.format(**variables)
|
Loading…
Reference in New Issue