getting classy

This commit is contained in:
2025-06-04 21:36:43 -05:00
parent 39b821ff7f
commit 82561f050f
5 changed files with 105 additions and 101 deletions

View File

@ -6,8 +6,7 @@ import subprocess
from garfpy import( from garfpy import(
logger, is_private, logger, is_private,
kroger_token, find_store, search_product, kroger_token, find_store, search_product,
garfpic, process_image_requests, generate_chat, aod_message, wikisum, generate_qr, GarfAI, GarfbotRespond)
aod_message, wikisum, generate_qr, GarfbotRespond)
gapikey = config.GIF_TOKEN gapikey = config.GIF_TOKEN
@ -21,14 +20,16 @@ intents.messages = True
intents.message_content = True intents.message_content = True
garfbot = discord.Client(intents=intents) garfbot = discord.Client(intents=intents)
garf_respond = GarfbotRespond() garf_respond = GarfbotRespond()
garfield = GarfAI()
@garfbot.event @garfbot.event
async def on_ready(): async def on_ready():
try: try:
asyncio.create_task(process_image_requests())
garf_respond.load_responses() garf_respond.load_responses()
asyncio.create_task(garfield.process_image_requests())
logger.info(f"Logged in as {garfbot.user.name} running {txtmodel} and {imgmodel}.") logger.info(f"Logged in as {garfbot.user.name} running {txtmodel} and {imgmodel}.")
except Exception as e: except Exception as e:
logger.error(e) logger.error(e)
@ -49,7 +50,7 @@ async def on_message(message):
if lower.startswith("hey garfield") or isinstance(message.channel, discord.DMChannel): if lower.startswith("hey garfield") or isinstance(message.channel, discord.DMChannel):
question = content[12:] if lower.startswith("hey garfield") else message.content question = content[12:] if lower.startswith("hey garfield") else message.content
answer = await generate_chat(question) answer = await garfield.generate_chat(question)
logger.info(f"Chat Request - User: {user}, Server: {guild}, Prompt: {question}") logger.info(f"Chat Request - User: {user}, Server: {guild}, Prompt: {question}")
await message.channel.send(answer) await message.channel.send(answer)
@ -57,7 +58,7 @@ async def on_message(message):
prompt = content[8:] prompt = content[8:]
logger.info(f"Image Request - User: {user}, Server: {guild}, Prompt: {prompt}") logger.info(f"Image Request - User: {user}, Server: {guild}, Prompt: {prompt}")
await message.channel.send(f"`Please wait... image generation queued: {prompt}`") await message.channel.send(f"`Please wait... image generation queued: {prompt}`")
await garfpic(message, prompt) await garfield.garfpic(message, prompt)
# Wikipedia # Wikipedia
if lower.startswith('garfwiki '): if lower.startswith('garfwiki '):
@ -87,7 +88,7 @@ async def on_message(message):
try: try:
logger.info(f"Ping Request - User: {user}, Server: {guild}, Target: {target}") logger.info(f"Ping Request - User: {user}, Server: {guild}, Target: {target}")
if is_private(target): if is_private(target):
rejection = await generate_chat("Hey Garfield, explain to me why I am dumb for trying to hack your private computer network.") rejection = await garfield.generate_chat("Hey Garfield, explain to me why I am dumb for trying to hack your private computer network.")
await message.channel.send(rejection) await message.channel.send(rejection)
else: else:
result = subprocess.run(['ping', '-c', '4', target], capture_output=True, text=True) result = subprocess.run(['ping', '-c', '4', target], capture_output=True, text=True)
@ -99,7 +100,7 @@ async def on_message(message):
try: try:
logger.info(f"NSLookup Request - User: {user}, Server: {guild}, Target: {target}") logger.info(f"NSLookup Request - User: {user}, Server: {guild}, Target: {target}")
if is_private(target): if is_private(target):
rejection = await generate_chat("Hey Garfield, explain to me why I am dumb for trying to hack your private computer network.") rejection = await garfield.generate_chat("Hey Garfield, explain to me why I am dumb for trying to hack your private computer network.")
await message.channel.send(rejection) await message.channel.send(rejection)
else: else:
result = subprocess.run(['nslookup', target], capture_output=True, text=True) result = subprocess.run(['nslookup', target], capture_output=True, text=True)
@ -111,7 +112,7 @@ async def on_message(message):
try: try:
logger.info(f"Nmap Request - User: {user}, Server: {guild}, Target: {target}") logger.info(f"Nmap Request - User: {user}, Server: {guild}, Target: {target}")
if is_private(target): if is_private(target):
rejection = await generate_chat("Hey Garfield, explain to me why I am dumb for trying to hack your private computer network.") rejection = await garfield.generate_chat("Hey Garfield, explain to me why I am dumb for trying to hack your private computer network.")
await message.channel.send(rejection) await message.channel.send(rejection)
else: else:
await message.channel.send(f"`Scanning {target}...`") await message.channel.send(f"`Scanning {target}...`")

View File

@ -13,4 +13,5 @@ from .iputils import is_private
from .aod import aod_message from .aod import aod_message
from .wiki import wikisum from .wiki import wikisum
from .qr import generate_qr from .qr import generate_qr
from .garfai import GarfAI
from .respond import GarfbotRespond from .respond import GarfbotRespond

View File

@ -7,83 +7,85 @@ import discord
from openai import AsyncOpenAI from openai import AsyncOpenAI
from garfpy import logger from garfpy import logger
openaikey = config.OPENAI_TOKEN
txtmodel = config.TXT_MODEL class GarfAI:
imgmodel = config.IMG_MODEL def __init__(self):
self.openaikey = config.OPENAI_TOKEN
self.txtmodel = config.TXT_MODEL
self.imgmodel = config.IMG_MODEL
self.image_request_queue = asyncio.Queue()
image_request_queue = asyncio.Queue() async def garfpic(self, message, prompt):
await self.image_request_queue.put({'message': message, 'prompt': prompt})
async def garfpic(message, prompt): async def generate_image(self, prompt):
await image_request_queue.put({'message': message, 'prompt': prompt}) try:
client = AsyncOpenAI(api_key = self.openaikey)
response = await client.images.generate(
model=self.imgmodel,
prompt=prompt,
n=1,
size="1024x1024"
)
image_url = response.data[0].url
return image_url
except openai.BadRequestError as e:
return f"`GarfBot Error: ({e.status_code}) - Your request was rejected as a result of our safety system.`"
except openai.InternalServerError as e:
logger.error(e)
return f"`GarfBot Error: ({e.status_code}) - Monday`"
except Exception as e:
logger.error(e)
return f"`GarfBot Error: Lasagna`"
async def generate_image(prompt): async def process_image_requests(self):
try: async with aiohttp.ClientSession() as session:
client = AsyncOpenAI(api_key = openaikey) while True:
response = await client.images.generate( request = await self.image_request_queue.get()
model=imgmodel, message = request['message']
prompt=prompt, prompt = request['prompt']
n=1, image_url = await self.generate_image(prompt)
size="1024x1024" if "GarfBot Error" not in image_url:
) logger.info("Downloading & sending image...")
image_url = response.data[0].url async with session.get(image_url) as resp:
return image_url if resp.status == 200:
except openai.BadRequestError as e: image_data = await resp.read()
return f"`GarfBot Error: ({e.status_code}) - Your request was rejected as a result of our safety system.`" ram_image = io.BytesIO(image_data)
except openai.InternalServerError as e: ram_image.seek(0)
logger.error(e) timestamp = message.created_at.strftime('%Y%m%d%H%M%S')
return f"`GarfBot Error: ({e.status_code}) - Monday`" filename = f"{timestamp}_generated_image.png"
except Exception as e: sendfile = discord.File(fp=ram_image, filename=filename)
logger.error(e) try:
return f"`GarfBot Error: Lasagna`" await message.channel.send(file=sendfile)
except Exception as e:
logger.error(e)
else:
await message.channel.send("`GarfBot Error: Odie`")
else:
await message.channel.send(image_url)
self.image_request_queue.task_done()
await asyncio.sleep(2)
async def process_image_requests(): # GarfChats
async with aiohttp.ClientSession() as session: @staticmethod
while True: async def generate_chat(self, question):
request = await image_request_queue.get() try:
message = request['message'] client = AsyncOpenAI(api_key = self.openaikey)
prompt = request['prompt'] response = await client.chat.completions.create(
image_url = await generate_image(prompt) model=self.txtmodel,
if "GarfBot Error" not in image_url: messages=[
logger.info("Downloading & sending image...") {"role": "system", "content": "Pretend you are sarcastic Garfield."},
async with session.get(image_url) as resp: {"role": "user", "content": f"{question}"}
if resp.status == 200: ],
image_data = await resp.read() max_tokens=400
ram_image = io.BytesIO(image_data) )
ram_image.seek(0) answer = response.choices[0].message.content
timestamp = message.created_at.strftime('%Y%m%d%H%M%S') return answer.replace("an AI language model", "a cartoon animal")
filename = f"{timestamp}_generated_image.png" except openai.BadRequestError as e:
sendfile = discord.File(fp=ram_image, filename=filename) return f"`GarfBot Error: {e}`"
try: except openai.APIError as e:
await message.channel.send(file=sendfile) logger.info(e, flush=True)
except Exception as e: return f"`GarfBot Error: Monday`"
logger.error(e) except Exception as e:
else: logger.info(e, flush=True)
await message.channel.send("`GarfBot Error: Odie`") return f"`GarfBot Error: Lasagna`"
else:
await message.channel.send(image_url)
image_request_queue.task_done()
await asyncio.sleep(2)
# GarfChats
async def generate_chat(question):
try:
client = AsyncOpenAI(api_key = openaikey)
response = await client.chat.completions.create(
model=txtmodel,
messages=[
{"role": "system", "content": "Pretend you are sarcastic Garfield."},
{"role": "user", "content": f"{question}"}
],
max_tokens=400
)
answer = response.choices[0].message.content
return answer.replace("an AI language model", "a cartoon animal")
except openai.BadRequestError as e:
return f"`GarfBot Error: {e}`"
except openai.APIError as e:
logger.info(e, flush=True)
return f"`GarfBot Error: Monday`"
except Exception as e:
logger.info(e, flush=True)
return f"`GarfBot Error: Lasagna`"

View File

@ -7,37 +7,37 @@ import re
class GarfbotRespond: class GarfbotRespond:
def __init__(self): def __init__(self):
self.garfbot_guild_responses = {} self.guild_responses = {}
self.responses_file = 'responses.json' self.responses_file = 'responses.json'
def load_responses(self): def load_responses(self):
if os.path.exists(self.responses_file): if os.path.exists(self.responses_file):
try: try:
with open(self.responses_file, 'r', encoding='utf-8') as f: with open(self.responses_file, 'r', encoding='utf-8') as f:
self.garfbot_guild_responses = json.load(f) self.guild_responses = json.load(f)
self.garfbot_guild_responses = {int(k): v for k, v in self.garfbot_guild_responses.items()} self.guild_responses = {int(k): v for k, v in self.guild_responses.items()}
total_responses = sum(len(responses) for responses in self.garfbot_guild_responses.values()) total_responses = sum(len(responses) for responses in self.guild_responses.values())
logger.info(f"Loaded responses for {len(self.garfbot_guild_responses)} server(s), ({total_responses} total responses)") logger.info(f"Loaded responses for {len(self.guild_responses)} server(s), ({total_responses} total responses)")
except Exception as e: except Exception as e:
logger.info(f"Error loading responses: {e}") logger.info(f"Error loading responses: {e}")
self.garfbot_guild_responses = {} self.guild_responses = {}
else: else:
self.garfbot_guild_responses = {} self.guild_responses = {}
def save_responses(self): def save_responses(self):
try: try:
save_data = {str(k): v for k, v in self.garfbot_guild_responses.items()} save_data = {str(k): v for k, v in self.guild_responses.items()}
with open(self.responses_file, 'w', encoding='utf-8') as f: with open(self.responses_file, 'w', encoding='utf-8') as f:
json.dump(save_data, f, indent=2, ensure_ascii=False) json.dump(save_data, f, indent=2, ensure_ascii=False)
total_responses = sum(len(responses) for responses in self.garfbot_guild_responses.values()) total_responses = sum(len(responses) for responses in self.guild_responses.values())
logger.info(f"Saved responses for {len(self.garfbot_guild_responses)} servers ({total_responses} total responses)") logger.info(f"Saved responses for {len(self.guild_responses)} servers ({total_responses} total responses)")
except Exception as e: except Exception as e:
logger.info(f"Error saving responses: {e}") logger.info(f"Error saving responses: {e}")
def get_responses(self, guild_id): def get_responses(self, guild_id):
if guild_id not in self.garfbot_guild_responses: if guild_id not in self.guild_responses:
self.garfbot_guild_responses[guild_id] = {} self.guild_responses[guild_id] = {}
return self.garfbot_guild_responses[guild_id] return self.guild_responses[guild_id]
async def garfbot_response(self, message, content): async def garfbot_response(self, message, content):
guild_id = message.guild.id guild_id = message.guild.id
@ -86,7 +86,7 @@ class GarfbotRespond:
responses = self.get_responses(guild_id) responses = self.get_responses(guild_id)
responses[trigger] = response_text responses[trigger] = response_text
self.garfbot_guild_responses[guild_id] = responses self.guild_responses[guild_id] = responses
self.save_responses() self.save_responses()
embed = discord.Embed( embed = discord.Embed(
@ -105,7 +105,7 @@ class GarfbotRespond:
if trigger in responses: if trigger in responses:
removed_response = responses[trigger] removed_response = responses[trigger]
del responses[trigger] del responses[trigger]
self.garfbot_guild_responses[guild_id] = responses self.guild_responses[guild_id] = responses
self.save_responses() self.save_responses()
embed = discord.Embed( embed = discord.Embed(
@ -123,7 +123,7 @@ class GarfbotRespond:
if key.lower() == trigger.lower(): if key.lower() == trigger.lower():
removed_response = responses[key] removed_response = responses[key]
del responses[key] del responses[key]
self.garfbot_guild_responses[guild_id] = responses self.guild_responses[guild_id] = responses
self.save_responses() self.save_responses()
embed = discord.Embed( embed = discord.Embed(

View File

@ -1,10 +1,10 @@
import wikipedia import wikipedia
from garfpy import generate_chat from garfpy import GarfAI
async def wikisum(search_term): async def wikisum(search_term):
try: try:
summary = wikipedia.summary(search_term) summary = wikipedia.summary(search_term)
garfsum = await generate_chat(f"Please summarize in your own words: {summary}") garfsum = await GarfAI.generate_chat(f"Please summarize in your own words: {summary}")
return garfsum return garfsum