|
import discord |
|
import os |
|
import threading |
|
import gradio as gr |
|
import requests |
|
import json |
|
import random |
|
import time |
|
import re |
|
from discord import Embed, Color |
|
from discord.ext import commands |
|
|
|
from gradio_client import Client |
|
from PIL import Image |
|
|
|
|
|
import asyncio |
|
import concurrent.futures |
|
import multiprocessing |
|
|
|
import shutil |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GRADIOTEST_TOKEN = os.getenv('HF_TOKEN') |
|
DISCORD_TOKEN = os.environ.get("GRADIOTEST_TOKEN", None) |
|
|
|
df = Client("huggingface-projects/IF", GRADIOTEST_TOKEN) |
|
jojogan = Client("akhaliq/JoJoGAN", GRADIOTEST_TOKEN) |
|
|
|
|
|
intents = discord.Intents.default() |
|
intents.message_content = True |
|
|
|
bot = commands.Bot(command_prefix='!', intents=intents) |
|
|
|
|
|
|
|
@bot.event |
|
async def on_ready(): |
|
print('Logged on as', bot.user) |
|
bot.log_channel = bot.get_channel(1100458786826747945) |
|
|
|
async def safetychecks(ctx): |
|
try: |
|
if ctx.author.bot: |
|
print(f"Error: The bot is not allowed to use its own commands.") |
|
return False |
|
|
|
|
|
offline_bot_role_id = 1103676632667017266 |
|
bot_member = ctx.guild.get_member(bot.user.id) |
|
if any(role.id == offline_bot_role_id for role in bot_member.roles): |
|
print(f"Error: The bot is offline or under maintenance. (Remove the offline-bot role to bring it online)") |
|
return False |
|
|
|
|
|
channel_id = 1100458786826747945 |
|
if ctx.channel.id != 1100458786826747945: |
|
print(f"Error: This is not a permitted channel for that command. (bot-test is the correct channel)") |
|
return False |
|
|
|
|
|
guild_id = 879548962464493619 |
|
required_role_id = 900063512829755413 |
|
guild = bot.get_guild(guild_id) |
|
required_role = guild.get_role(required_role_id) |
|
if required_role not in ctx.author.roles: |
|
print(f"Error: The user does not have the required role to use that command. ({required_role} is the correct role)") |
|
return False |
|
|
|
return True |
|
|
|
except Exception as e: |
|
print(f"Error: safetychecks failed somewhere, command will not continue.") |
|
await ctx.message.reply(f"<@811235357663297546> SC failed somewhere") |
|
|
|
|
|
@bot.command() |
|
async def jojo(ctx): |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try: |
|
if await safetychecks(ctx): |
|
await ctx.message.add_reaction('π€') |
|
thread = await ctx.message.create_thread(name=f'{ctx.author} Jojo Thread') |
|
if ctx.message.attachments: |
|
await thread.send(f'{ctx.author.mention}Generating images in thread, can take ~1 minute...yare yare, daze ...') |
|
attachment = ctx.message.attachments[0] |
|
style = 'JoJo' |
|
|
|
im = await asyncio.get_running_loop().run_in_executor(None, jojogan.predict, attachment.url, style) |
|
|
|
await thread.send(f'{ctx.author.mention}Here is the {style} version of it', file=discord.File(im)) |
|
await ctx.message.add_reaction('β
') |
|
else: |
|
await thread.send(f"{ctx.author.mention}No attachments to be found...Can't animify dat! Try sending me an image π") |
|
await ctx.message.add_reaction('β') |
|
except Exception as e: |
|
print(f"Error: {e}") |
|
await thread.send(f"{ctx.author.mention}Error: {e}") |
|
await ctx.message.add_reaction('β') |
|
|
|
|
|
|
|
@bot.command() |
|
async def disney(ctx): |
|
try: |
|
if await safetychecks(ctx): |
|
await ctx.message.add_reaction('π€') |
|
thread = await ctx.message.create_thread(name=f'{ctx.author} disney Thread') |
|
if ctx.message.attachments: |
|
await thread.send(f'{ctx.author.mention}Generating images in thread, can take ~1 minute...') |
|
attachment = ctx.message.attachments[0] |
|
style = 'disney' |
|
im = await asyncio.get_running_loop().run_in_executor(None, jojogan.predict, attachment.url, 'disney') |
|
await thread.send(f'{ctx.author.mention}Here is the {style} version of it', file=discord.File(im)) |
|
await ctx.message.add_reaction('β
') |
|
else: |
|
await thread.send(f"{ctx.author.mention}No attachments to be found...Can't animify dat! Try sending me an image π") |
|
await ctx.message.add_reaction('β') |
|
except Exception as e: |
|
print(f"Error: {e}") |
|
await thread.send(f"{ctx.author.mention}Error: {e}") |
|
await ctx.message.add_reaction('β') |
|
|
|
|
|
|
|
@bot.command() |
|
async def spiderverse(ctx): |
|
try: |
|
if await safetychecks(ctx): |
|
await ctx.message.add_reaction('π€') |
|
thread = await ctx.message.create_thread(name=f'{ctx.author} spider-verse Thread') |
|
if ctx.message.attachments: |
|
await thread.send(f'{ctx.author.mention}Generating images in thread, can take ~1 minute...') |
|
attachment = ctx.message.attachments[0] |
|
style = 'Spider-Verse' |
|
im = await asyncio.get_running_loop().run_in_executor(None, jojogan.predict, attachment.url, style) |
|
await thread.send(f'{ctx.author.mention}Here is the {style} version of it', file=discord.File(im)) |
|
await ctx.message.add_reaction('β
') |
|
else: |
|
await thread.send(f"{ctx.author.mention}No attachments to be found...Can't animify dat! Try sending me an image π") |
|
await ctx.message.add_reaction('β') |
|
except Exception as e: |
|
print(f"Error: {e}") |
|
await thread.send(f"{ctx.author.mention}Error: {e}") |
|
await ctx.message.add_reaction('β') |
|
|
|
|
|
|
|
@bot.command() |
|
async def sketch(ctx): |
|
try: |
|
if await safetychecks(ctx): |
|
await ctx.message.add_reaction('π€') |
|
thread = await ctx.message.create_thread(name=f'{ctx.author} sketch Thread') |
|
if ctx.message.attachments: |
|
await thread.send(f'{ctx.author.mention}Generating images in thread, can take ~1 minute...') |
|
attachment = ctx.message.attachments[0] |
|
|
|
im = await asyncio.get_running_loop().run_in_executor(None, jojogan.predict, attachment.url, 'sketch') |
|
await thread.send(f'{ctx.author.mention}Here is the sketch version of it', file=discord.File(im)) |
|
await ctx.message.add_reaction('β
') |
|
else: |
|
await thread.send(f"{ctx.author.mention}No attachments to be found...Can't animify dat! Try sending me an image π") |
|
await ctx.message.add_reaction('β') |
|
except Exception as e: |
|
print(f"Error: {e}") |
|
await thread.send(f"{ctx.author.mention}Error: {e}") |
|
await ctx.message.add_reaction('β') |
|
|
|
|
|
@bot.command() |
|
async def deepfloydif(ctx, *, prompt: str): |
|
try: |
|
try: |
|
if await safetychecks(ctx): |
|
await ctx.message.add_reaction('π€') |
|
dfif_command_message_id = ctx.message.id |
|
thread = await ctx.message.create_thread(name=f'{ctx.author} DeepfloydIF Image Upscaling Thread ') |
|
|
|
|
|
|
|
|
|
|
|
negative_prompt = '' |
|
seed = random.randint(0, 1000) |
|
|
|
number_of_images = 4 |
|
guidance_scale = 7 |
|
custom_timesteps_1 = 'smart50' |
|
number_of_inference_steps = 50 |
|
api_name = '/generate64' |
|
|
|
await thread.send(f'{ctx.author.mention}Generating images in thread, can take ~1 minute...') |
|
|
|
except Exception as e: |
|
print(f"Error: {e}") |
|
await ctx.reply('stage 1 error -> pre generation') |
|
await ctx.message.add_reaction('β') |
|
|
|
try: |
|
|
|
|
|
|
|
stage_1_results, stage_1_param_path, stage_1_result_path = await asyncio.get_running_loop().run_in_executor( |
|
None, df.predict, prompt, negative_prompt, seed, number_of_images, guidance_scale, custom_timesteps_1, number_of_inference_steps, |
|
api_name) |
|
|
|
partialpath = stage_1_result_path[5:] |
|
except Exception as e: |
|
print(f"Error: {e}") |
|
await ctx.reply('stage 1 error -> during generation') |
|
await ctx.message.add_reaction('β') |
|
|
|
try: |
|
png_files = [f for f in os.listdir(stage_1_results) if f.endswith('.png')] |
|
|
|
if png_files: |
|
first_png = png_files[0] |
|
second_png = png_files[1] |
|
third_png = png_files[2] |
|
fourth_png = png_files[3] |
|
|
|
first_png_path = os.path.join(stage_1_results, first_png) |
|
second_png_path = os.path.join(stage_1_results, second_png) |
|
third_png_path = os.path.join(stage_1_results, third_png) |
|
fourth_png_path = os.path.join(stage_1_results, fourth_png) |
|
|
|
img1 = Image.open(first_png_path) |
|
img2 = Image.open(second_png_path) |
|
img3 = Image.open(third_png_path) |
|
img4 = Image.open(fourth_png_path) |
|
|
|
combined_image = Image.new('RGB', (img1.width * 2, img1.height * 2)) |
|
|
|
combined_image.paste(img1, (0, 0)) |
|
combined_image.paste(img2, (img1.width, 0)) |
|
combined_image.paste(img3, (0, img1.height)) |
|
combined_image.paste(img4, (img1.width, img1.height)) |
|
|
|
combined_image_path = os.path.join(stage_1_results, f'{partialpath}{dfif_command_message_id}.png') |
|
combined_image.save(combined_image_path) |
|
|
|
with open(combined_image_path, 'rb') as f: |
|
combined_image_dfif = await thread.send(f'{ctx.author.mention}React with the image number you want to upscale!', file=discord.File( |
|
f, f'{partialpath}{dfif_command_message_id}.png')) |
|
|
|
async def react1234(emoji, combined_image_dfif): |
|
for emoji in ['1οΈβ£', '2οΈβ£', '3οΈβ£', '4οΈβ£']: |
|
await combined_image_dfif.add_reaction(emoji) |
|
|
|
await react1234(emoji, combined_image_dfif) |
|
|
|
''' individual images |
|
if png_files: |
|
for i, png_file in enumerate(png_files): |
|
png_file_path = os.path.join(stage_1_results, png_file) |
|
img = Image.open(png_file_path) |
|
image_path = os.path.join(stage_1_results, f'{i+1}{partialpath}.png') |
|
img.save(image_path) |
|
with open(image_path, 'rb') as f: |
|
await thread.send(f'{ctx.author.mention}Image {i+1}', file=discord.File(f, f'{i+1}{partialpath}.png')) |
|
await asyncio.sleep(1) |
|
|
|
''' |
|
|
|
except Exception as e: |
|
print(f"Error: {e}") |
|
await ctx.reply('stage 1 error -> posting images in thread') |
|
await ctx.message.add_reaction('β') |
|
|
|
|
|
except Exception as e: |
|
print(f"Error: {e}") |
|
await ctx.reply('An error occurred in stage 1 for deepfloydif') |
|
await ctx.message.add_reaction('β') |
|
|
|
|
|
|
|
async def dfif2(index: int, stage_1_result_path, thread, dfif_command_message_id): |
|
try: |
|
await thread.send(f"inside dfif2, upscaling") |
|
selected_index_for_stage_2 = index |
|
seed_2 = 0 |
|
guidance_scale_2 = 4 |
|
custom_timesteps_2 = 'smart50' |
|
number_of_inference_steps_2 = 50 |
|
result_path = df.predict(stage_1_result_path, selected_index_for_stage_2, seed_2, |
|
guidance_scale_2, custom_timesteps_2, number_of_inference_steps_2, api_name='/upscale256') |
|
|
|
await thread.send(f"upscale done") |
|
with open(result_path, 'rb') as f: |
|
await thread.send(f'Here is the upscaled image! :) ', file=discord.File(f, 'result.png')) |
|
|
|
|
|
emoji_guild = thread.guild |
|
confirm_emoji_id = 1098629085955113011 |
|
confirm_emoji = discord.utils.get(emoji_guild.emojis, id=confirm_emoji_id) |
|
|
|
|
|
|
|
parent_channel = thread.parent |
|
dfif_command_message = await parent_channel.fetch_message(dfif_command_message_id) |
|
|
|
|
|
await dfif_command_message.add_reaction(confirm_emoji) |
|
await thread.send(f"upscale posted") |
|
|
|
|
|
|
|
''' |
|
try: |
|
dfif_command_message = await channel.fetch_message(dfif_command_message_id) |
|
await dfif_command_message.add_reaction('β
') |
|
''' |
|
|
|
except Exception as e: |
|
print(f"Error: {e}") |
|
|
|
|
|
|
|
|
|
@bot.event |
|
async def on_reaction_add(reaction, user): |
|
try: |
|
|
|
''' |
|
if user.bot: |
|
return |
|
|
|
#offline bot check β |
|
offline_bot_role_id = 1103676632667017266 |
|
bot_member = reaction.message.guild.get_member(bot.user.id) |
|
if any(role.id == offline_bot_role_id for role in bot_member.roles): |
|
return |
|
|
|
# verified role check β |
|
guild = reaction.message.guild |
|
required_role_id = 900063512829755413 # @verified for now |
|
required_role = guild.get_role(required_role_id) |
|
if required_role not in user.roles: |
|
return |
|
|
|
#channel check β |
|
if reaction.message.channel.id != 1100458786826747945: |
|
return |
|
|
|
''' |
|
|
|
thread = reaction.message.channel |
|
threadparentid = thread.parent.id |
|
|
|
if not user.bot: |
|
if threadparentid == 1100458786826747945: |
|
|
|
if reaction.message.attachments: |
|
if user.id == reaction.message.mentions[0].id: |
|
|
|
await reaction.message.channel.send("reaction detected") |
|
attachment = reaction.message.attachments[0] |
|
image_name = attachment.filename |
|
|
|
partialpathmessageid = image_name[:-4] |
|
|
|
partialpath = partialpathmessageid[:11] |
|
messageid = partialpathmessageid[11:] |
|
|
|
fullpath = "/tmp/" + partialpath |
|
await reaction.message.channel.send(f"fullpath extracted, {fullpath}") |
|
emoji = reaction.emoji |
|
|
|
if emoji == "1οΈβ£": |
|
index = 0 |
|
elif emoji == "2οΈβ£": |
|
index = 1 |
|
elif emoji == "3οΈβ£": |
|
index = 2 |
|
elif emoji == "4οΈβ£": |
|
index = 3 |
|
|
|
await reaction.message.channel.send(f"index extracted, {index}") |
|
index = index |
|
stage_1_result_path = fullpath |
|
thread = reaction.message.channel |
|
dfif_command_message_id = messageid |
|
await reaction.message.channel.send(f"calling dfif2") |
|
await dfif2(index, stage_1_result_path, thread, dfif_command_message_id) |
|
|
|
''' |
|
|
|
if reaction.message.attachments: |
|
if user.id == reaction.message.mentions[0].id: # all we care about is upscaling whatever image this is |
|
|
|
# magic begins |
|
attachment = reaction.message.attachments[0] |
|
image_name = attachment.filename |
|
# we know image_name will be something like 1tmpgtv4qjix.png |
|
# remove .png first |
|
indexpartialpath = image_name[:-4] # should be 1tmpgtv4qjix |
|
# extract index as an integer (dfif2 needs integer) |
|
index = int(indexpartialpath[0]) - 1# should be 1 |
|
# extract partialpath |
|
partialpath = indexpartialpath[1:] # should be tmpgtv4qjix |
|
# add /tmp/ to partialpath, save as new variable |
|
fullpath = "/tmp/" + partialpath # should be /tmp/tmpgtv4qjix |
|
|
|
stage_1_result_path = fullpath |
|
index = index |
|
await dfif2(index, stage_1_result_path, thread) |
|
|
|
''' |
|
|
|
|
|
except Exception as e: |
|
print(f"Error: {e}") |
|
|
|
|
|
|
|
|
|
|
|
|
|
def run_bot(): |
|
bot.run(DISCORD_TOKEN) |
|
|
|
threading.Thread(target=run_bot).start() |
|
|
|
def greet(name): |
|
return "Hello " + name + "!" |
|
|
|
demo = gr.Interface(fn=greet, inputs="text", outputs="text") |
|
demo.queue(concurrency_count=10) |
|
demo.launch() |