diff --git a/extensions/phixxycom.py b/extensions/phixxycom.py index 7703506..48a3956 100644 --- a/extensions/phixxycom.py +++ b/extensions/phixxycom.py @@ -2,6 +2,7 @@ import os import io import base64 import time +import json import asyncssh from PIL import Image, PngImagePlugin from discord.ext import commands, tasks @@ -16,6 +17,7 @@ class PhixxyCom(commands.Cog): self.working_dir = "tmp/phixxy.com/" self.data_dir = "data/phixxy.com/" self.folder_setup() + self.stable_diffusion_log = "data/stable_diffusion/stable_diffusion.log" self.phixxy_loop.start() def folder_setup(self): @@ -27,6 +29,16 @@ class PhixxyCom(commands.Cog): except: print("PhixxyCom failed to make directories") + def find_prompt_from_filename(self, sd_log, filename): + with open(sd_log, 'r') as f: + lines = f.readlines() + for line in reversed(lines): + if filename in line: + prompt = line[line.index("Prompt: ") + 7:line.index("Filename: ")] + prompt = ''.join(prompt.rsplit(',', 1)) # Remove the last comma + return prompt + return "Unknown Prompt" + async def upload_sftp(self, local_filename, server_folder, server_filename): remotepath = server_folder + server_filename async with asyncssh.connect(self.SERVER, username=self.USERNAME, password=self.PASSWORD) as conn: @@ -141,8 +153,7 @@ class PhixxyCom(commands.Cog): for filename in os.listdir(folder): if filename[-4:] == '.png': filepath = folder + filename - prompt = "Unknown Prompt" # Will have to update this later - + prompt = self.find_prompt_from_filename(self.stable_diffusion_log, filename) html_file = "phixxy.com/ai-images/index.html" html_insert = '''
diff --git a/extensions/pokemon.py b/extensions/pokemon.py index 67f7e52..fac549a 100644 --- a/extensions/pokemon.py +++ b/extensions/pokemon.py @@ -1,5 +1,4 @@ #plugin file for sparkytron 3000 - from discord.ext import commands import discord import random @@ -7,268 +6,295 @@ import os import json import math import time -import aiohttp +class PokemonGame(commands.Cog): + def __init__(self, bot): + self.bot = bot + self.working_dir = "tmp/pokemon/" + self.data_dir = "data/pokemon/" + self.folder_setup() -async def get_json(url): - http_session = aiohttp.ClientSession() - async with http_session.get(url) as resp: - json_data = await resp.json() - return json_data + def folder_setup(self): + try: + if not os.path.exists(self.working_dir): + os.mkdir(self.working_dir) + if not os.path.exists(self.data_dir): + os.mkdir(self.data_dir) + except: + print("PokemonGame failed to make directories") -@commands.command( - description="Pokemon", - help="Pokemon game", - brief="Pokemon Game", - aliases=['pkmn'], - hidden=True - ) -async def pokemon(ctx, arg1=None, arg2=None, arg3=None, arg4=None): - async def starter_picker(id): #id = pokedex number - url = "https://pokeapi.co/api/v2/pokemon-species/" + str(id) - json_data = await get_json(url) - if (json_data["evolves_from_species"] == None) and (not json_data['is_mythical']) and (not json_data['is_legendary']): - return True - else: - return False - - async def shiny_roll(): - roll = random.randint(0,2047) - return not roll - - async def save_pokemon(discord_id, pokemon_dict): - if not os.path.isdir("databases/pokemon/"): - os.makedirs("databases/pokemon/") - - path = "databases/pokemon/"+str(discord_id)+".json" - pokemon_dict = json.dumps(pokemon_dict) - with open(path, 'w') as f: - f.writelines(pokemon_dict) - return True - - async def load_pokemon(discord_id): - if not os.path.isdir("databases/pokemon/"): - os.makedirs("databases/pokemon/") - if os.path.isfile("databases/pokemon/"+str(discord_id)+".json"): - with open("databases/pokemon/"+str(discord_id)+".json", 'r') as f: - json_data = json.loads(f.readline()) - return json_data - else: - return False - - async def generate_starter(discord_id): - random.seed(discord_id) - json_data = await get_json('https://pokeapi.co/api/v2/pokemon-species/') - pokemon_count = json_data['count'] - base_pokemon = False - while not base_pokemon: - starter_id = random.randint(1,pokemon_count) - base_pokemon = await starter_picker(starter_id) - random.seed() - return starter_id - - async def get_pkmn_from_id(id): - url = 'https://pokeapi.co/api/v2/pokemon/' + str(id) - json_data = await get_json(url) + async def get_json(self, url): + async with self.bot.http_session.get(url) as resp: + json_data = await resp.json() return json_data - - async def give_buddy_food(pkmn_data): - try: - last_food = pkmn_data['last_food'] - except: - last_food = 0 - this_food = time.time() - if (this_food - last_food) >= 1800: - pkmn_data['last_food'] = this_food - level = await calc_pkmn_buddy_level(pkmn_data) - pkmn_data['buddy_xp'] += (4*level) - return pkmn_data, True - else: - return pkmn_data, False - async def give_buddy_affection(pkmn_data): - try: - last_hug = pkmn_data['last_hug'] - except: - last_hug = 0 - this_hug = time.time() - if (this_hug - last_hug) >= 600: - pkmn_data['last_hug'] = this_hug - level = await calc_pkmn_buddy_level(pkmn_data) - pkmn_data['buddy_xp'] += (3*level) - return pkmn_data, True - else: - return pkmn_data, False - - async def calc_pkmn_buddy_level(pkmn_json): #this uses the 'fast' xp rate - buddy_xp = pkmn_json['buddy_xp'] - return min(math.floor(((5*buddy_xp)/4)**(1/3)),100) - - async def make_pmkn_embed(pkmn_dict): - if pkmn_dict['nickname']: - title = pkmn_dict['nickname'] + ' (' + pkmn_dict['name'].capitalize() + ')' - else: - title = pkmn_dict['name'].capitalize() - embed=discord.Embed(title=title) - if pkmn_dict['shiny']: - embed.set_image(url=pkmn_dict['sprites']['front_shiny']) - else: - embed.set_image(url=pkmn_dict['sprites']['front_default']) - nature = pkmn_dict['nature'] - buddy_level = await calc_pkmn_buddy_level(pkmn_dict) - buddy_xp = pkmn_dict['buddy_xp'] - types = [] - for key in pkmn_dict['types']: - types.append(key['type']['name'].capitalize()) - type_str = ', '.join(types) - embed.add_field(name="Nature", value=nature.capitalize(), inline=False) - embed.add_field(name="Buddy Level", value=buddy_level , inline=True) - embed.add_field(name="Buddy XP", value=buddy_xp, inline=True) - embed.add_field(name="Types", value=type_str, inline=False) - return embed - - if arg1=='start': - if not os.path.isdir("databases/pokemon/"): - os.makedirs("databases/pokemon/") - if not os.path.isfile("databases/pokemon/"+str(ctx.author.id)+'.json'): - uniq_id = time.time() - starter_id = await generate_starter(ctx.author.id) - json_data = await get_pkmn_from_id(starter_id) - is_shiny = await shiny_roll() - nature = random.randint(0,19) - nature_data = await get_json('https://pokeapi.co/api/v2/nature/') - nature = nature_data['results'][nature]['name'] - json_data['shiny'] = is_shiny - json_data['nickname'] = None - json_data['unique_id'] = uniq_id - json_data['nature'] = nature - json_data['buddy_level'] = 1 - json_data['buddy_xp'] = 0 - json_data['last_food'] = 0 - json_data['last_hug'] = 0 - await save_pokemon(ctx.author.id, json_data) - embed = await make_pmkn_embed(json_data) - await ctx.channel.send(embed=embed) - return - else: - await ctx.channel.send("You already have a pokemon!") - return + @commands.command( + description="Pokemon", + help="Pokemon game", + brief="Pokemon Game", + aliases=['pkmn'], + hidden=True + ) + async def pokemon(self, ctx, *args): + async def starter_picker(id): #id = pokedex number + url = "https://pokeapi.co/api/v2/pokemon-species/" + str(id) + json_data = await self.get_json(url) + if (json_data["evolves_from_species"] == None) and (not json_data['is_mythical']) and (not json_data['is_legendary']): + return True + else: + return False - elif arg1 == 'nick' or arg1 == 'nickname': - nickname = arg2 - json_data = await load_pokemon(ctx.author.id) - json_data['nickname'] = nickname - await save_pokemon(ctx.author.id, json_data) - message = "You gave " + nickname + ' a new name!' - await ctx.channel.send(message) - return - - elif arg1 == 'feed': - json_data = await load_pokemon(ctx.author.id) - json_data, fed = await give_buddy_food(json_data) - if fed: - await save_pokemon(ctx.author.id, json_data) - if json_data['nickname']: - message = "You " + arg1 + ' ' + json_data['nickname'] - else: - message = "You " + arg1 + ' ' + json_data['name'] - await ctx.channel.send(message) - return - else: - if json_data['nickname']: - message = "Your " + json_data['nickname'] + " isn't hungry!" - else: - message = "Your " + json_data['name'] + " isn't hungry!" - await ctx.channel.send(message) - return - - elif arg1 == 'hug': - json_data = await load_pokemon(ctx.author.id) - json_data, hugged = await give_buddy_affection(json_data) - if hugged: - await save_pokemon(ctx.author.id, json_data) - if json_data['nickname']: - message = "You " + arg1 + ' ' + json_data['nickname'] - else: - message = "You " + arg1 + ' ' + json_data['name'] - await ctx.channel.send(message) - return - else: - if json_data['nickname']: - message = "You hugged " + json_data['nickname'] + " but " + json_data['nickname'] + " has been hugged recently." - else: - message = "You hugged " + json_data['name'] + " but " + json_data['name'] + " has been hugged recently." - await ctx.channel.send(message) - return + async def shiny_roll(): + roll = random.randint(0,2047) + return not roll + + async def save_pokemon(discord_id, pokemon_dict): + if not os.path.isdir("databases/pokemon/"): + os.makedirs("databases/pokemon/") - #Default !pokemon behavior (Load and show pokemon embed) - discord_id = ctx.author.id - buddy_json = await load_pokemon(discord_id) - if not buddy_json: - await ctx.channel.send("You don't have a buddy yet. Type ```!pokemon start``` to start your Pokemon journey!") - else: - embed = await make_pmkn_embed(buddy_json) - message = await ctx.channel.send(embed=embed) - return + path = "databases/pokemon/"+str(discord_id)+".json" + pokemon_dict = json.dumps(pokemon_dict) + with open(path, 'w') as f: + f.writelines(pokemon_dict) + return True + + async def load_pokemon(discord_id): + if not os.path.isdir("databases/pokemon/"): + os.makedirs("databases/pokemon/") + if os.path.isfile("databases/pokemon/"+str(discord_id)+".json"): + with open("databases/pokemon/"+str(discord_id)+".json", 'r') as f: + json_data = json.loads(f.readline()) + return json_data + else: + return False -@commands.command( - description="Pokedex", - help="Get information on pokemon", - brief="Pokedex", - aliases=['pdex'], - hidden=False - ) -async def pokedex(ctx): - pokemon = ctx.message.content.split(" ", maxsplit=1)[1] - try: - shiny = False - if 'shiny ' in pokemon: - shiny = True - pokemon = pokemon.replace('shiny ', '') - url = "https://pokeapi.co/api/v2/pokemon/" + pokemon - dex_url = "https://pokeapi.co/api/v2/pokemon-species/" + pokemon - #try: - data = await get_json(url) - name = data['name'] - height_str = str(int(data['height'])/10) + 'm' - weight_str = str(int(data['weight'])/10) + 'kg' - type1 = data['types'][0]['type']['name'] + async def generate_starter(discord_id): + random.seed(discord_id) + json_data = await self.get_json('https://pokeapi.co/api/v2/pokemon-species/') + pokemon_count = json_data['count'] + base_pokemon = False + while not base_pokemon: + starter_id = random.randint(1,pokemon_count) + base_pokemon = await starter_picker(starter_id) + random.seed() + return starter_id + + async def get_pkmn_from_id(id): + url = 'https://pokeapi.co/api/v2/pokemon/' + str(id) + json_data = await self.get_json(url) + return json_data + + async def give_buddy_food(pkmn_data): + try: + last_food = pkmn_data['last_food'] + except: + last_food = 0 + this_food = time.time() + if (this_food - last_food) >= 1800: + pkmn_data['last_food'] = this_food + level = await calc_pkmn_buddy_level(pkmn_data) + pkmn_data['buddy_xp'] += (4*level) + return pkmn_data, True + else: + return pkmn_data, False + + async def give_buddy_affection(pkmn_data): + try: + last_hug = pkmn_data['last_hug'] + except: + last_hug = 0 + this_hug = time.time() + if (this_hug - last_hug) >= 600: + pkmn_data['last_hug'] = this_hug + level = await calc_pkmn_buddy_level(pkmn_data) + pkmn_data['buddy_xp'] += (3*level) + return pkmn_data, True + else: + return pkmn_data, False + + async def calc_pkmn_buddy_level(pkmn_json): #this uses the 'fast' xp rate + buddy_xp = pkmn_json['buddy_xp'] + return min(math.floor(((5*buddy_xp)/4)**(1/3)),100) + + async def make_pmkn_embed(pkmn_dict): + if pkmn_dict['nickname']: + title = pkmn_dict['nickname'] + ' (' + pkmn_dict['name'].capitalize() + ')' + else: + title = pkmn_dict['name'].capitalize() + embed=discord.Embed(title=title) + if pkmn_dict['shiny']: + embed.set_image(url=pkmn_dict['sprites']['front_shiny']) + else: + embed.set_image(url=pkmn_dict['sprites']['front_default']) + nature = pkmn_dict['nature'] + buddy_level = await calc_pkmn_buddy_level(pkmn_dict) + buddy_xp = pkmn_dict['buddy_xp'] + types = [] + for key in pkmn_dict['types']: + types.append(key['type']['name'].capitalize()) + type_str = ', '.join(types) + embed.add_field(name="Nature", value=nature.capitalize(), inline=False) + embed.add_field(name="Buddy Level", value=buddy_level , inline=True) + embed.add_field(name="Buddy XP", value=buddy_xp, inline=True) + embed.add_field(name="Types", value=type_str, inline=False) + return embed try: - type2 = data['types'][1]['type']['name'] - type_str = type1.capitalize() + ', ' + type2.capitalize() + if args[0]=='start': + if not os.path.isdir("databases/pokemon/"): + os.makedirs("databases/pokemon/") + if not os.path.isfile("databases/pokemon/"+str(ctx.author.id)+'.json'): + uniq_id = time.time() + starter_id = await generate_starter(ctx.author.id) + json_data = await get_pkmn_from_id(starter_id) + is_shiny = await shiny_roll() + nature = random.randint(0,19) + nature_data = await self.get_json('https://pokeapi.co/api/v2/nature/') + nature = nature_data['results'][nature]['name'] + json_data['shiny'] = is_shiny + json_data['nickname'] = None + json_data['unique_id'] = uniq_id + json_data['nature'] = nature + json_data['buddy_level'] = 1 + json_data['buddy_xp'] = 0 + json_data['last_food'] = 0 + json_data['last_hug'] = 0 + await save_pokemon(ctx.author.id, json_data) + embed = await make_pmkn_embed(json_data) + await ctx.channel.send(embed=embed) + return + else: + await ctx.channel.send("You already have a pokemon!") + return + + elif args[0] == 'nick' or args[0] == 'nickname': + nickname = args[1] + json_data = await load_pokemon(ctx.author.id) + json_data['nickname'] = nickname + await save_pokemon(ctx.author.id, json_data) + message = "You gave " + nickname + ' a new name!' + await ctx.channel.send(message) + return + + elif args[0] == 'feed': + json_data = await load_pokemon(ctx.author.id) + json_data, fed = await give_buddy_food(json_data) + if fed: + await save_pokemon(ctx.author.id, json_data) + if json_data['nickname']: + message = "You " + args[0] + ' ' + json_data['nickname'] + else: + message = "You " + args[0] + ' ' + json_data['name'] + await ctx.channel.send(message) + return + else: + if json_data['nickname']: + message = "Your " + json_data['nickname'] + " isn't hungry!" + else: + message = "Your " + json_data['name'] + " isn't hungry!" + await ctx.channel.send(message) + return + + elif args[0] == 'hug': + json_data = await load_pokemon(ctx.author.id) + json_data, hugged = await give_buddy_affection(json_data) + if hugged: + await save_pokemon(ctx.author.id, json_data) + if json_data['nickname']: + message = "You " + args[0] + ' ' + json_data['nickname'] + else: + message = "You " + args[0] + ' ' + json_data['name'] + await ctx.channel.send(message) + return + else: + if json_data['nickname']: + message = "You hugged " + json_data['nickname'] + " but " + json_data['nickname'] + " has been hugged recently." + else: + message = "You hugged " + json_data['name'] + " but " + json_data['name'] + " has been hugged recently." + await ctx.channel.send(message) + return except: - type2 = "None" - type_str = type1.capitalize() - sprite = data["sprites"]["front_default"] - if shiny: - sprite = data["sprites"]["front_shiny"] - dex_data = await get_json(dex_url) - generation = dex_data['generation']['name'].upper().replace("GENERATION","Generation") - for entry in dex_data['flavor_text_entries']: - if entry['language']['name'] == 'en': - dex_desc = entry['flavor_text'].replace("\u000c", '\n') - dex_desc_game = entry['version']['name'].capitalize() - break - for entry in dex_data['genera']: - if entry['language']['name'] == 'en': - genus = entry['genus'] - break - footer = generation + ' | Pokédex entry from Pokémon ' + dex_desc_game - dex_num = dex_data['pokedex_numbers'][0]['entry_number'] - embed=discord.Embed(title=name.capitalize()) - embed.set_image(url=sprite) - embed.add_field(name="Number", value=dex_num, inline=False) - embed.add_field(name=genus, value=dex_desc, inline=False) - embed.add_field(name="Weight", value=weight_str , inline=True) - embed.add_field(name="Height", value=height_str, inline=True) - embed.add_field(name="Types", value=type_str, inline=True) - embed.set_footer(text=footer) - await ctx.send(embed=embed) - except: - message = "No data for " + str(pokemon) - await ctx.channel.send(message) + #Default !pokemon behavior (Load and show pokemon embed) + discord_id = ctx.author.id + buddy_json = await load_pokemon(discord_id) + if not buddy_json: + await ctx.channel.send("You don't have a buddy yet. Type ```!pokemon start``` to start your Pokemon journey!") + else: + embed = await make_pmkn_embed(buddy_json) + message = await ctx.channel.send(embed=embed) + return + + async def pkmn_msg(self, discord_id): + path = "databases/pokemon/"+str(discord_id)+'.json' + if os.path.isfile(path): + with open(path, 'r') as f: + json_data = json.loads(f.readline()) + json_data['buddy_xp'] += random.randint(1,5) + json_data = json.dumps(json_data) + with open(path, 'w') as f: + f.writelines(json_data) + + @commands.Cog.listener() + async def on_message(self, message: discord.Message): + await self.pkmn_msg(message.author.id) + + + @commands.command( + description="Pokedex", + help="Get information on pokemon", + brief="Pokedex", + aliases=['pdex'], + hidden=False + ) + async def pokedex(self, ctx): + pokemon = ctx.message.content.split(" ", maxsplit=1)[1] + try: + shiny = False + if 'shiny ' in pokemon: + shiny = True + pokemon = pokemon.replace('shiny ', '') + url = "https://pokeapi.co/api/v2/pokemon/" + pokemon + dex_url = "https://pokeapi.co/api/v2/pokemon-species/" + pokemon + #try: + data = await self.get_json(url) + name = data['name'] + height_str = str(int(data['height'])/10) + 'm' + weight_str = str(int(data['weight'])/10) + 'kg' + type1 = data['types'][0]['type']['name'] + try: + type2 = data['types'][1]['type']['name'] + type_str = type1.capitalize() + ', ' + type2.capitalize() + except: + type2 = "None" + type_str = type1.capitalize() + sprite = data["sprites"]["front_default"] + if shiny: + sprite = data["sprites"]["front_shiny"] + dex_data = await self.get_json(dex_url) + generation = dex_data['generation']['name'].upper().replace("GENERATION","Generation") + for entry in dex_data['flavor_text_entries']: + if entry['language']['name'] == 'en': + dex_desc = entry['flavor_text'].replace("\u000c", '\n') + dex_desc_game = entry['version']['name'].capitalize() + break + for entry in dex_data['genera']: + if entry['language']['name'] == 'en': + genus = entry['genus'] + break + footer = generation + ' | Pokédex entry from Pokémon ' + dex_desc_game + dex_num = dex_data['pokedex_numbers'][0]['entry_number'] + embed=discord.Embed(title=name.capitalize()) + embed.set_image(url=sprite) + embed.add_field(name="Number", value=dex_num, inline=False) + embed.add_field(name=genus, value=dex_desc, inline=False) + embed.add_field(name="Weight", value=weight_str , inline=True) + embed.add_field(name="Height", value=height_str, inline=True) + embed.add_field(name="Types", value=type_str, inline=True) + embed.set_footer(text=footer) + await ctx.send(embed=embed) + except: + message = "No data for " + str(pokemon) + await ctx.channel.send(message) async def setup(bot): - bot.add_command(pokedex) - bot.add_command(pokemon) + await bot.add_cog(PokemonGame(bot)) diff --git a/extensions/stable_diffusion.py b/extensions/stable_diffusion.py index 19c217b..48f1a23 100644 --- a/extensions/stable_diffusion.py +++ b/extensions/stable_diffusion.py @@ -257,11 +257,12 @@ class StableDiffusion(commands.Cog): folder = self.working_dir + "sfw/" except: folder = self.working_dir - my_filename = folder + str(time.time_ns()) + ".png" - image.save(my_filename, pnginfo=pnginfo) + my_filename = str(time.time_ns()) + ".png" + filepath = folder + my_filename + image.save(filepath, pnginfo=pnginfo) - with open(my_filename, "rb") as fh: - f = discord.File(fh, filename=my_filename) + with open(filepath, "rb") as fh: + f = discord.File(fh, filename=filepath) log_data = f'Author: {ctx.author.name}, Prompt: {prompt}, Filename: {my_filename}\n' with open(f"{self.data_dir}stable_diffusion.log", 'a') as log_file: diff --git a/sparkytron3000.py b/sparkytron3000.py index 835767d..aba7cf4 100644 --- a/sparkytron3000.py +++ b/sparkytron3000.py @@ -8,7 +8,6 @@ import time import os import asyncio from dotenv import load_dotenv - import aiohttp #Stable Diffusion @@ -34,7 +33,6 @@ intents.message_content = True bot = commands.Bot(command_prefix='!', intents=intents) #discord setup END - async def handle_error(error): print(error) @@ -44,6 +42,7 @@ async def handle_error(error): f.write(log_line) return error + def create_channel_config(filepath): config_dict = { "personality":"average", @@ -213,17 +212,6 @@ async def on_reaction_add(reaction, user): message = reaction.message emoji = reaction.emoji await message.add_reaction(emoji) - - -async def pkmn_msg(discord_id): - path = "databases/pokemon/"+str(discord_id)+'.json' - if os.path.isfile(path): - with open(path, 'r') as f: - json_data = json.loads(f.readline()) - json_data['buddy_xp'] += random.randint(1,5) - json_data = json.dumps(json_data) - with open(path, 'w') as f: - f.writelines(json_data) @bot.event @@ -233,9 +221,6 @@ async def on_message(ctx): channel_vars = await get_channel_config(ctx.channel.id) chat_history_string = await log_chat_and_get_history(ctx, logfile, channel_vars) - #add pokemon xp - await pkmn_msg(ctx.author.id) - #handle non-text channels (dms, etc) if ctx.channel.type.value != 0 and ctx.author.id != 242018983241318410: #This used to notify the user it cannot respond in this channel, but that spammed threads @@ -243,7 +228,7 @@ async def on_message(ctx): await react_to_msg(ctx, channel_vars["react_to_msgs"]) #emoji reactions - if channel_vars["commands_enabled"] or (ctx.author.id == 242018983241318410 and ctx.content[0] == "!"): + if channel_vars["commands_enabled"] or (ctx.author.id == 242018983241318410 and ctx.content[0] == "?"): await bot.process_commands(ctx) if not channel_vars["commands_enabled"]: await ctx.channel.send("This command only ran because you set it to allow to run even when commands are disabled")