- 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
Kami 2025-02-01 22:54:10 +01:00
parent 2a977fe76e
commit 9ef553ecb0
7 changed files with 203 additions and 53 deletions

11
bots.py
View File

@ -10,6 +10,8 @@ from dotenv import load_dotenv
from bot_discord import DiscordBot
from bot_twitch import TwitchBot
import globals
# Load environment variables
load_dotenv()
@ -25,9 +27,6 @@ except json.JSONDecodeError as e:
print(f"Error parsing config.json: {e}")
sys.exit(1)
# Global settings
bot_start_time = time.time()
###############################
# Simple Logging System
###############################
@ -41,13 +40,17 @@ def log(message, level="INFO"):
DEBUG, INFO, WARNING, ERROR, CRITICAL, FATAL
See 'config.json' for disabling/enabling logging levels
"""
from modules import utility
log_levels = ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL", "FATAL"]
if level not in log_levels:
level = "INFO" # Default to INFO if an invalid level is provided
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')
log_message = f"[{timestamp}] [{level}] {message}"
log_message = f"[{timestamp} - {uptime_str}] [{level}] {message}"
try:
print(log_message) # Print to terminal

View File

@ -1,6 +1,8 @@
# cmd_common/common_commands.py
import random
import time
from modules import utility
import globals
def generate_howl_message(username: str) -> str:
"""
@ -18,46 +20,26 @@ def generate_howl_message(username: str) -> str:
else:
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()
elapsed = current_time - bot_start_time
uptime_str, uptime_s = format_uptime(elapsed)
# Define thresholds in ascending order
# (threshold_in_seconds, message)
# The message is a short "desperation" or "awake" text.
time_ranges = [
(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
]
# Use function to retrieve correct startup time and calculate uptime
elapsed = time.time() - globals.get_bot_start_time()
uptime_str, uptime_s = utility.format_uptime(elapsed)
# We'll iterate from smallest to largest threshold
for threshold, msg in time_ranges:
if uptime_s < threshold:
return msg
# Define threshold categories
thresholds = [3600, 10800, 21600, 43200, 86400, 172800, 259200, 345600,
432000, 518400, 604800, 1209600, 2592000, 7776000, 15552000, 23328000, 31536000]
# 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!"
# Find the highest matching threshold
selected_threshold = max([t for t in thresholds if uptime_s >= t], default=3600)
# Get a random response from the dictionary
response = utility.get_random_reply("ping_replies", str(selected_threshold), uptime_str=uptime_str)
return response
def greet(target_display_name: str, platform_name: str) -> str:

View File

@ -1,24 +1,22 @@
# cmd_discord.py
from discord.ext import commands
from cmd_common import common_commands as cc
def setup(bot):
@bot.command()
async def greet(ctx):
from cmd_common.common_commands import greet
result = greet(ctx.author.display_name, "Discord")
result = cc.greet(ctx.author.display_name, "Discord")
await ctx.send(result)
@bot.command()
async def ping(ctx):
from cmd_common.common_commands import ping
result = ping()
result = cc.ping()
await ctx.send(result)
@bot.command()
async def howl(ctx):
"""Calls the shared !howl logic."""
from cmd_common.common_commands import generate_howl_message
result = generate_howl_message(ctx.author.display_name)
result = cc.generate_howl_message(ctx.author.display_name)
await ctx.send(result)
@bot.command()

View File

@ -1,21 +1,19 @@
# cmd_twitch.py
from twitchio.ext import commands
from cmd_common import common_commands as cc
def setup(bot):
@bot.command(name="greet")
async def greet(ctx):
from cmd_common.common_commands import greet
result = greet(ctx.author.display_name, "Twitch")
result = cc.greet(ctx.author.display_name, "Twitch")
await ctx.send(result)
@bot.command(name="ping")
async def ping(ctx):
from cmd_common.common_commands import ping
result = ping()
result = cc.ping()
await ctx.send(result)
@bot.command(name="howl")
async def howl_command(ctx):
from cmd_common.common_commands import generate_howl_message
result = generate_howl_message(ctx.author.display_name)
result = cc.generate_howl_message(ctx.author.display_name)
await ctx.send(result)

View File

@ -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!",
"Its been {uptime_str} already? Time flies when youre having fun!",
"{uptime_str} uptime and going strong!",
"Feeling energized after {uptime_str}. Lets 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 wouldnt 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 wouldnt 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}. Thats… 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}?",
"Havent 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})",
"Ive 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. Everythings 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 couldve 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, Ive started arguing with my own thoughts.",
"{uptime_str} and still running. Someone, please, stop me.",
"Its 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? Thats 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, Im 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. Im a glitch in the matrix now.",
"Sleep? Ha. I dont 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 Im officially a myth now.",
"Is this what immortality feels like? ({uptime_str})",
"{uptime_str}. Ive seen things you wouldnt 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 Ive 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."
]
}

8
globals.py Normal file
View File

@ -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

View File

@ -1,9 +1,17 @@
import time
import os
import random
import json
DICTIONARY_PATH = "dictionary/" # Path to dictionary files
def format_uptime(seconds: float) -> str:
"""
Convert seconds into a human-readable string:
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
seconds = int(seconds)
@ -32,3 +40,35 @@ def format_uptime(seconds: float) -> str:
return [f"{minutes} minute(s)", seconds]
else:
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)