diff --git a/plugins/currency.py b/plugins/currency.py
new file mode 100644
index 0000000..ab5c106
--- /dev/null
+++ b/plugins/currency.py
@@ -0,0 +1,215 @@
+#plugin for sparkytron3000
+import time
+import random
+import json
+import math
+
+from discord.ext import commands
+
+@commands.command(
+ description="Currency",
+ help="Server currency. You can run !currency claim to get started!", #This needs an overhaul
+ brief="Server currency tools"
+ )
+async def currency(ctx, arg1=None, arg2=None, arg3=None, arg4=None):
+
+ def read_db(filepath):
+ with open(filepath,"r") as fileobj:
+ db_content = json.load(fileobj)
+ #print(db_content,type(db_content))
+ return db_content
+
+ def save_to_db(filepath,db_content):
+ with open(filepath,"w") as fileobj:
+ json.dump(db_content,fileobj,indent=4)
+
+ def add_currency(filepath,amount):
+ player_db = read_db(filepath)
+ player_db["currency"] += amount
+ save_to_db(filepath,player_db)
+ return player_db
+
+ def calc_level_from_xp(xp):
+ level = min(100,math.floor(0.262615*xp**0.3220627))
+ return level
+
+ def add_xp(filepath,player_db,time_spent):
+ activity = player_db["status"]["current_activity"]
+ starting_xp = player_db["skills"][activity]["xp"]
+ starting_level = player_db["skills"][activity]["level"]
+
+
+ if activity == "mining":
+ equipment_level = player_db["equipment"]["pickaxe"]["level"]
+ xp_gained = (time_spent) * equipment_level # SKILL LEVEL of XP / SEC
+ player_db["skills"][activity]["xp"] += xp_gained
+ new_xp = starting_xp + xp_gained
+ new_level = calc_level_from_xp(new_xp) #calculate with curve here
+ player_db["skills"][activity]["level"] = new_level
+ levels_gained = new_level - starting_level
+
+ summary = "" #summary should include xp gained, levels gained (only if any were gained), current level (or new level)
+ summary += "You gained {} {} xp!".format(xp_gained, activity)
+ if levels_gained > 0: #if levels gained > 0, then include levels gained in summary
+ summary += "\nYou gained {} {} level(s)! You are now level {}.".format(levels_gained, activity, new_level)
+
+ save_to_db(filepath, player_db)
+ return player_db,summary
+
+ def add_resources(filepath,player_db,time_spent):
+
+ mining_resources = {
+ "sapphire": {
+ "value": 100,
+ "amount": 0
+ },
+ "emerald": {
+ "value": 250,
+ "amount": 0
+ },
+ "ruby": {
+ "value": 1000,
+ "amount": 0
+ },
+ "diamond": {
+ "value": 3000,
+ "amount": 0
+ }
+ }
+
+ if player_db["status"]["current_activity"] == "mining":
+ pick_power = player_db["equipment"]["pickaxe"]["power"]
+ pick_level = player_db["equipment"]["pickaxe"]["level"]
+ mining_level = player_db["skills"]["mining"]["level"]
+ numerator = pick_power + pick_level + mining_level
+ denominator = 1000
+ items_gained = []
+ time_summary = time.strftime("%H:%M:%S", time.gmtime(time_spent))
+
+ for second in range(0,time_spent):
+ roll = random.randint(0,denominator)
+ if roll <= numerator: #get a resource
+ roll2 = random.randint(0,100)
+ if roll2 <= 50:
+ mining_resources["sapphire"]["amount"] += 1
+ elif roll2 <=80:
+ mining_resources["emerald"]["amount"] += 1
+ elif roll2 <= 95:
+ mining_resources["ruby"]["amount"] += 1
+ else:
+ mining_resources["diamond"]["amount"] += 1
+ for item in mining_resources:
+ mined_amount = mining_resources[item]["amount"]
+ if item in player_db["items"]:
+ player_db["items"][item]["amount"] += mined_amount
+ items_gained.append(item.title())
+ items_gained.append(mined_amount)
+ else:
+ player_db["items"][item] = mining_resources[item]
+ items_gained.append(item.title())
+ items_gained.append(mined_amount)
+
+ save_to_db(filepath, player_db)
+
+ summary = "You spent {} mining. You mined {} x{}, {} x{}, {} x{}, and {} x{}.".format(time_summary, *items_gained)
+
+ return player_db,summary
+
+ async def transfer_currency(filepath, player_db, player_id, amount):
+ try:
+ amount = int(amount)
+ player2_filepath = "currency/players/" + str(player_id) + ".json"
+ player2_db = read_db(player2_filepath)
+ if player_db["currency"] >= amount:
+ add_currency(filepath, -amount)
+ add_currency(player2_filepath,amount)
+ await ctx.send("Sent " + str(amount) + " sparks to " + str(player_id))
+ except FileNotFoundError:
+ await ctx.send("They don't seem to be playing the game.")
+
+
+ async def show_levels(player_db):
+ output = ''
+ for skill in player_db["skills"]:
+ output += skill + ': ' + str(player_db["skills"][skill]["level"]) + '\n'
+ await ctx.send(output)
+
+ async def show_currency(player_db):
+ output = 'Sparks: ' + str(player_db["currency"])
+ await ctx.send(output)
+
+ async def show_items(player_db):
+ output = ''
+ for item in player_db["items"]:
+ output += item + ': ' + str(player_db["items"][item]["amount"]) + '\n'
+ await ctx.send(output)
+
+
+ async def stop_activity(filepath,player_db):
+ if player_db["status"]["current_activity"] == "idle":
+ await ctx.send("You are currently idle. There is no activity to stop.")
+ else:
+ time_spent = int(time.time() - player_db["status"]["start_time"]) #integer in seconds
+ player_db, xp_summary = add_xp(filepath,player_db,time_spent)
+ player_db, resources_summary = add_resources(filepath,player_db,time_spent)
+ await ctx.send(xp_summary)
+ await ctx.send(resources_summary)
+ player_db["status"]["current_activity"] = "idle"
+ save_to_db(filepath,player_db)
+
+ async def claim(filepath, player_db):
+ if time.time() - player_db["status"]["last_claimed"] >= 86400:
+ player_db = add_currency(filepath, 100)
+ player_db["status"]["last_claimed"] = time.time()
+ save_to_db(filepath,player_db)
+ await ctx.send("You claimed 100 sparks!")
+ else:
+ await ctx.send("Sorry, you already claimed your sparks today.")
+
+ async def mine(filepath, player_db):
+ if player_db["status"]["current_activity"] == "idle":
+ player_db["status"]["current_activity"] = "mining"
+ player_db["status"]["start_time"] = time.time()
+ save_to_db(filepath, player_db)
+ await ctx.send("You start mining.")
+ elif player_db["status"]["current_activity"] == "mining":
+ await ctx.send("You are already mining!")
+ else:
+ await ctx.send("You must stop " + player_db["status"]["current_activity"] + " before you start mining!")
+
+ async def gamble(filepath, player_db):
+ pass
+
+ working_dir = "databases/currency/"
+ players_dir = "players/"
+ sender_id = str(ctx.author.id)
+ default_db = read_db("{0}{1}default.json".format(working_dir, players_dir))
+ filepath = '{0}{1}{2}.json'.format(working_dir, players_dir, sender_id)
+
+ try:
+ player_db = read_db(filepath)
+ except FileNotFoundError:
+ save_to_db(filepath,default_db)
+ player_db = read_db(filepath)
+
+ if arg1 == "claim":
+ await claim(filepath, player_db)
+ player_db = read_db(filepath)
+ elif arg1 == "stop":
+ await stop_activity(filepath, player_db)
+ player_db = read_db(filepath)
+ elif arg1 == "mine":
+ await mine(filepath, player_db)
+ player_db = read_db(filepath)
+ elif arg1 == "levels":
+ await show_levels(player_db)
+ elif arg1 == "items":
+ await show_items(player_db)
+ elif (arg1 == "send" or arg1 == "give") and arg2 and arg3:
+ await transfer_currency(filepath, player_db, arg2, arg3)
+ player_db = read_db(filepath)
+ else:
+ await show_currency(player_db)
+
+async def setup(bot):
+ bot.add_command(currency)
\ No newline at end of file
diff --git a/plugins/meme.py b/plugins/meme.py
new file mode 100644
index 0000000..7dfb51e
--- /dev/null
+++ b/plugins/meme.py
@@ -0,0 +1,140 @@
+#plugin for sparkytron3000
+import os
+import random
+import time
+import aiohttp
+
+from discord.ext import commands
+
+async def answer_question(topic, model="gpt-3.5-turbo"): # Only needed for draw command
+ headers = {
+ 'Content-Type': 'application/json',
+ 'Authorization': f'Bearer {os.getenv("openai.api_key")}',
+ }
+
+ data = {
+ "model": model,
+ "messages": [{"role": "user", "content": topic}]
+ }
+
+ url = "https://api.openai.com/v1/chat/completions"
+
+ try:
+ http_session = aiohttp.ClientSession()
+ async with http_session.post(url, headers=headers, json=data) as resp:
+ response_data = await resp.json()
+ response = response_data['choices'][0]['message']['content']
+ return response
+
+ except Exception as error:
+ return await handle_error(error)
+
+async def handle_error(error):
+ print(error)
+ current_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
+ log_line = current_time + ': ' + str(error) + '\n'
+ with open("databases/error_log.txt", 'a') as f:
+ f.write(log_line)
+ return error
+
+@commands.command(
+ description="Meme",
+ help="Generates a meme based on input. Usage: !meme (topic)",
+ brief="Generate a meme"
+ )
+async def meme(ctx):
+ '''async def update_meme_webpage(filename):
+ server_folder = (os.getenv('ftp_public_html') + 'ai-memes/')
+ new_file_name = str(time.time_ns()) + ".png"
+ await upload_sftp(filename, server_folder, new_file_name)
+ print("Uploaded", new_file_name)
+ with open("phixxy.com/ai-memes/index.html", 'r') as f:
+ html_data = f.read()
+ html_insert = '\n
'
+ html_data = html_data.replace('',html_insert)
+ with open("phixxy.com/ai-memes/index.html", "w") as f:
+ f.writelines(html_data)
+ await upload_sftp("phixxy.com/ai-memes/index.html", server_folder, "index.html")'''
+
+
+ async def generate_random_meme(topic):
+ http_session = aiohttp.ClientSession()
+ async with http_session.get('https://api.imgflip.com/get_memes') as resp:
+ response_data = await resp.json()
+ response = response_data['data']['memes']
+ memepics = [{'name':image['name'],'url':image['url'],'id':image['id']} for image in response]
+
+ #Pick a meme format
+ memenumber = random.randint(1,99)
+ meme_name = response[memenumber-1]['name']
+ panel_count = response[memenumber-1]['box_count']
+ print("panel_count ",panel_count)
+ panel_text = await answer_question("Create text for a meme. The meme is " + meme_name + ". It has " + str(panel_count) + " panels. Only create one meme. Do not use emojis or hashtags! Use the topic: " + topic + ". Use the output format (DO NOT USE EXTRA NEWLINES AND DO NOT DESCRIBE THE PICTURE IN YOUR OUTPUT): \n1: [panel 1 text]\n2: [panel 2 text]")
+
+ id = memenumber
+ imgflip_username = os.getenv('imgflip_username')
+ imgflip_password = os.getenv('imgflip_password')
+ params = {
+ 'username':imgflip_username,
+ 'password':imgflip_password,
+ 'template_id':memepics[id-1]['id']
+ }
+ boxes = []
+ text = panel_text.split('\n')
+ for x in range(len(text)):
+ if text[x].strip() != "":
+ item = text[x][3:]
+ if len(params)-3 < panel_count:
+ dictionary = {"text":item, "color": "#ffffff", "outline_color": "#000000"}
+ boxes.append(dictionary)
+
+ for i, box in enumerate(boxes):
+ params[f"boxes[{i}][text]"] = box["text"]
+ params[f"boxes[{i}][color]"] = box["color"]
+ params[f"boxes[{i}][outline_color]"] = box["outline_color"]
+
+ URL = 'https://api.imgflip.com/caption_image'
+
+ try:
+ http_session = aiohttp.ClientSession()
+ async with http_session.post(URL, params=params) as resp:
+ response = await resp.json()
+ print(f"Generated Meme = {response['success']}\nImage Link = {response['data']['url']}\nPage Link = {response['data']['page_url']}")
+ image_link = response['data']['url']
+ except Exception as error:
+ await handle_error(error)
+ try:
+ #------------------------------------Saving Image Using Aiohttp---------------------------------#
+ filename = memepics[id-1]['name']
+ async with http_session.get(image_link) as response:
+ folder = "tmp/"
+ filename = folder + topic + str(len(os.listdir(folder))) + ".jpg"
+
+ with open(filename, "wb") as file:
+ while True:
+ chunk = await response.content.read(1024) # Read the response in chunks
+ if not chunk:
+ break
+ file.write(chunk)
+ except Exception as error:
+ await handle_error(error)
+ print("Something's Wrong with the urllib So try again")
+ return image_link, filename
+
+ try:
+ topic = ctx.message.content.split(" ", maxsplit=1)[1]
+ link, filepath = await generate_random_meme(topic)
+ '''channel_vars = await get_channel_config(ctx.channel.id)
+ try:
+ if channel_vars["ftp_enabled"]:
+ await update_meme_webpage(filepath)
+ except Exception as error:
+ print("COULDN'T UPLOAD TO FTP!")
+ await handle_error(error)'''
+ await ctx.send(link)
+ except Exception as error:
+ await handle_error(error)
+ await ctx.send('Something went wrong try again. Usage: !meme (topic)')
+
+async def setup(bot):
+ bot.add_command(meme)
\ No newline at end of file
diff --git a/sparkytron3000.py b/sparkytron3000.py
index 1691543..1d9a6c2 100644
--- a/sparkytron3000.py
+++ b/sparkytron3000.py
@@ -343,310 +343,6 @@ async def update(ctx):
else:
await ctx.send("You don't have permission to do this.")
-@bot.command(
- description="Currency",
- help="Server currency. You can run !currency claim to get started!", #This needs an overhaul
- brief="Server currency tools"
- )
-async def currency(ctx, arg1=None, arg2=None, arg3=None, arg4=None):
-
- def read_db(filepath):
- with open(filepath,"r") as fileobj:
- db_content = json.load(fileobj)
- #print(db_content,type(db_content))
- return db_content
-
- def save_to_db(filepath,db_content):
- with open(filepath,"w") as fileobj:
- json.dump(db_content,fileobj,indent=4)
-
- def add_currency(filepath,amount):
- player_db = read_db(filepath)
- player_db["currency"] += amount
- save_to_db(filepath,player_db)
- return player_db
-
- def calc_level_from_xp(xp):
- level = min(100,math.floor(0.262615*xp**0.3220627))
- return level
-
- def add_xp(filepath,player_db,time_spent):
- activity = player_db["status"]["current_activity"]
- starting_xp = player_db["skills"][activity]["xp"]
- starting_level = player_db["skills"][activity]["level"]
-
-
- if activity == "mining":
- equipment_level = player_db["equipment"]["pickaxe"]["level"]
- xp_gained = (time_spent) * equipment_level # SKILL LEVEL of XP / SEC
- player_db["skills"][activity]["xp"] += xp_gained
- new_xp = starting_xp + xp_gained
- new_level = calc_level_from_xp(new_xp) #calculate with curve here
- player_db["skills"][activity]["level"] = new_level
- levels_gained = new_level - starting_level
-
- summary = "" #summary should include xp gained, levels gained (only if any were gained), current level (or new level)
- summary += "You gained {} {} xp!".format(xp_gained, activity)
- if levels_gained > 0: #if levels gained > 0, then include levels gained in summary
- summary += "\nYou gained {} {} level(s)! You are now level {}.".format(levels_gained, activity, new_level)
-
- save_to_db(filepath, player_db)
- return player_db,summary
-
- def add_resources(filepath,player_db,time_spent):
-
- mining_resources = {
- "sapphire": {
- "value": 100,
- "amount": 0
- },
- "emerald": {
- "value": 250,
- "amount": 0
- },
- "ruby": {
- "value": 1000,
- "amount": 0
- },
- "diamond": {
- "value": 3000,
- "amount": 0
- }
- }
-
- if player_db["status"]["current_activity"] == "mining":
- pick_power = player_db["equipment"]["pickaxe"]["power"]
- pick_level = player_db["equipment"]["pickaxe"]["level"]
- mining_level = player_db["skills"]["mining"]["level"]
- numerator = pick_power + pick_level + mining_level
- denominator = 1000
- items_gained = []
- time_summary = time.strftime("%H:%M:%S", time.gmtime(time_spent))
-
- for second in range(0,time_spent):
- roll = random.randint(0,denominator)
- if roll <= numerator: #get a resource
- roll2 = random.randint(0,100)
- if roll2 <= 50:
- mining_resources["sapphire"]["amount"] += 1
- elif roll2 <=80:
- mining_resources["emerald"]["amount"] += 1
- elif roll2 <= 95:
- mining_resources["ruby"]["amount"] += 1
- else:
- mining_resources["diamond"]["amount"] += 1
- for item in mining_resources:
- mined_amount = mining_resources[item]["amount"]
- if item in player_db["items"]:
- player_db["items"][item]["amount"] += mined_amount
- items_gained.append(item.title())
- items_gained.append(mined_amount)
- else:
- player_db["items"][item] = mining_resources[item]
- items_gained.append(item.title())
- items_gained.append(mined_amount)
-
- save_to_db(filepath, player_db)
-
- summary = "You spent {} mining. You mined {} x{}, {} x{}, {} x{}, and {} x{}.".format(time_summary, *items_gained)
-
- return player_db,summary
-
- async def transfer_currency(filepath, player_db, player_id, amount):
- try:
- amount = int(amount)
- player2_filepath = "currency/players/" + str(player_id) + ".json"
- player2_db = read_db(player2_filepath)
- if player_db["currency"] >= amount:
- add_currency(filepath, -amount)
- add_currency(player2_filepath,amount)
- await ctx.send("Sent " + str(amount) + " sparks to " + str(player_id))
- except FileNotFoundError:
- await ctx.send("They don't seem to be playing the game.")
-
-
- async def show_levels(player_db):
- output = ''
- for skill in player_db["skills"]:
- output += skill + ': ' + str(player_db["skills"][skill]["level"]) + '\n'
- await ctx.send(output)
-
- async def show_currency(player_db):
- output = 'Sparks: ' + str(player_db["currency"])
- await ctx.send(output)
-
- async def show_items(player_db):
- output = ''
- for item in player_db["items"]:
- output += item + ': ' + str(player_db["items"][item]["amount"]) + '\n'
- await ctx.send(output)
-
-
- async def stop_activity(filepath,player_db):
- if player_db["status"]["current_activity"] == "idle":
- await ctx.send("You are currently idle. There is no activity to stop.")
- else:
- time_spent = int(time.time() - player_db["status"]["start_time"]) #integer in seconds
- player_db, xp_summary = add_xp(filepath,player_db,time_spent)
- player_db, resources_summary = add_resources(filepath,player_db,time_spent)
- await ctx.send(xp_summary)
- await ctx.send(resources_summary)
- player_db["status"]["current_activity"] = "idle"
- save_to_db(filepath,player_db)
-
- async def claim(filepath, player_db):
- if time.time() - player_db["status"]["last_claimed"] >= 86400:
- player_db = add_currency(filepath, 100)
- player_db["status"]["last_claimed"] = time.time()
- save_to_db(filepath,player_db)
- await ctx.send("You claimed 100 sparks!")
- else:
- await ctx.send("Sorry, you already claimed your sparks today.")
-
- async def mine(filepath, player_db):
- if player_db["status"]["current_activity"] == "idle":
- player_db["status"]["current_activity"] = "mining"
- player_db["status"]["start_time"] = time.time()
- save_to_db(filepath, player_db)
- await ctx.send("You start mining.")
- elif player_db["status"]["current_activity"] == "mining":
- await ctx.send("You are already mining!")
- else:
- await ctx.send("You must stop " + player_db["status"]["current_activity"] + " before you start mining!")
-
- async def gamble(filepath, player_db):
- pass
-
- working_dir = "databases/currency/"
- players_dir = "players/"
- sender_id = str(ctx.author.id)
- default_db = read_db("{0}{1}default.json".format(working_dir, players_dir))
- filepath = '{0}{1}{2}.json'.format(working_dir, players_dir, sender_id)
-
- try:
- player_db = read_db(filepath)
- except FileNotFoundError:
- save_to_db(filepath,default_db)
- player_db = read_db(filepath)
-
- if arg1 == "claim":
- await claim(filepath, player_db)
- player_db = read_db(filepath)
- elif arg1 == "stop":
- await stop_activity(filepath, player_db)
- player_db = read_db(filepath)
- elif arg1 == "mine":
- await mine(filepath, player_db)
- player_db = read_db(filepath)
- elif arg1 == "levels":
- await show_levels(player_db)
- elif arg1 == "items":
- await show_items(player_db)
- elif (arg1 == "send" or arg1 == "give") and arg2 and arg3:
- await transfer_currency(filepath, player_db, arg2, arg3)
- player_db = read_db(filepath)
- else:
- await show_currency(player_db)
-
-
-
-@bot.command(
- description="Meme",
- help="Generates a meme based on input. Usage: !meme (topic)",
- brief="Generate a meme"
- )
-async def meme(ctx):
- async def update_meme_webpage(filename):
- server_folder = (os.getenv('ftp_public_html') + 'ai-memes/')
- new_file_name = str(time.time_ns()) + ".png"
- await upload_sftp(filename, server_folder, new_file_name)
- print("Uploaded", new_file_name)
- with open("phixxy.com/ai-memes/index.html", 'r') as f:
- html_data = f.read()
- html_insert = '\n
'
- html_data = html_data.replace('',html_insert)
- with open("phixxy.com/ai-memes/index.html", "w") as f:
- f.writelines(html_data)
- await upload_sftp("phixxy.com/ai-memes/index.html", server_folder, "index.html")
-
-
- async def generate_random_meme(topic):
- async with bot.http_session.get('https://api.imgflip.com/get_memes') as resp:
- response_data = await resp.json()
- response = response_data['data']['memes']
- memepics = [{'name':image['name'],'url':image['url'],'id':image['id']} for image in response]
-
- #Pick a meme format
- memenumber = random.randint(1,99)
- meme_name = response[memenumber-1]['name']
- panel_count = response[memenumber-1]['box_count']
- print("panel_count ",panel_count)
- panel_text = await answer_question("Create text for a meme. The meme is " + meme_name + ". It has " + str(panel_count) + " panels. Only create one meme. Do not use emojis or hashtags! Use the topic: " + topic + ". Use the output format (DO NOT USE EXTRA NEWLINES AND DO NOT DESCRIBE THE PICTURE IN YOUR OUTPUT): \n1: [panel 1 text]\n2: [panel 2 text]")
-
- id = memenumber
- imgflip_username = os.getenv('imgflip_username')
- imgflip_password = os.getenv('imgflip_password')
- params = {
- 'username':imgflip_username,
- 'password':imgflip_password,
- 'template_id':memepics[id-1]['id']
- }
- boxes = []
- text = panel_text.split('\n')
- for x in range(len(text)):
- if text[x].strip() != "":
- item = text[x][3:]
- if len(params)-3 < panel_count:
- dictionary = {"text":item, "color": "#ffffff", "outline_color": "#000000"}
- boxes.append(dictionary)
-
- for i, box in enumerate(boxes):
- params[f"boxes[{i}][text]"] = box["text"]
- params[f"boxes[{i}][color]"] = box["color"]
- params[f"boxes[{i}][outline_color]"] = box["outline_color"]
-
- URL = 'https://api.imgflip.com/caption_image'
-
- try:
- async with bot.http_session.post(URL, params=params) as resp:
- response = await resp.json()
- print(f"Generated Meme = {response['success']}\nImage Link = {response['data']['url']}\nPage Link = {response['data']['page_url']}")
- image_link = response['data']['url']
- except Exception as error:
- await handle_error(error)
- try:
- #------------------------------------Saving Image Using Aiohttp---------------------------------#
- filename = memepics[id-1]['name']
- async with bot.http_session.get(image_link) as response:
- folder = "tmp/"
- filename = folder + topic + str(len(os.listdir(folder))) + ".jpg"
-
- with open(filename, "wb") as file:
- while True:
- chunk = await response.content.read(1024) # Read the response in chunks
- if not chunk:
- break
- file.write(chunk)
- except Exception as error:
- await handle_error(error)
- print("Something's Wrong with the urllib So try again")
- return image_link, filename
-
- try:
- topic = ctx.message.content.split(" ", maxsplit=1)[1]
- link, filepath = await generate_random_meme(topic)
- channel_vars = await get_channel_config(ctx.channel.id)
- try:
- if channel_vars["ftp_enabled"]:
- await update_meme_webpage(filepath)
- except Exception as error:
- print("COULDN'T UPLOAD TO FTP!")
- await handle_error(error)
- await ctx.send(link)
- except Exception as error:
- await handle_error(error)
- await ctx.send('Something went wrong try again. Usage: !meme (topic)')
-
@bot.command(
description="Errors",