def main(): check() # init github_api_url = 'https://api.github.com' github_id = str(setting['github_id']) github_token = setting['github_token'] search_topic = setting['search_topic'] search_month_range = int(setting['search_month_range'] or 6) search_location = setting['search_location'] my_auth = (github_id, github_token) now_datetime = datetime.datetime.now() limit_datetime = relativedelta(months=-search_month_range) + now_datetime while now_datetime > limit_datetime: page = 1 while True: search_base_time = str(now_datetime.strftime('%Y-%m-%d')) topics = requests.get( url=github_api_url + f'/search/repositories?q=topic:{search_topic}+created:{search_base_time}&page={page}', auth=my_auth, headers={ 'Accept': 'application/vnd.github.mercy-preview+json' }).json() time.sleep(5) # https://docs.github.com/en/free-pro-team@latest/rest/reference/search # To satisfy that need, the GitHub Search API provides up to 1,000 results for each search. if int(len(topics['items'])) == 0: break print( f'search base time : {search_base_time}, ', f'now time : {datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")}, ', f'page : {page}, ', f'user_count : {len(topics["items"])}, ', f'total_count : {topics["total_count"]}') for topic in topics['items']: user_id = topic['owner']['login'] user = requests.get(url=github_api_url + f'/users/{user_id}', auth=my_auth).json() time.sleep(0.5) # https://docs.github.com/en/free-pro-team@latest/rest/overview/resources-in-the-rest-api#rate-limiting # For API requests using Basic Authentication or OAuth, you can make up to 5,000 requests per hour. if 'location' in user and user[ 'location'] is not None and search_location in user[ 'location']: print( f'Found it! = createdat : {topic["created_at"]}, repository : {topic["html_url"]}' ) page = page + 1 now_datetime = now_datetime + datetime.timedelta(days=-1)
async def join(self, ctx): if settings.check(ctx.message.guild.id, "get", "cross"): # ok cos I can't really be bothered, whenever I refer to a server's id in this bit, I mean the channel, not server global waiting global servers if waiting == None: # if no one is in the list, join it await ctx.send("Ok, added you to the waiting list") waiting = ctx.message.channel.id # sets the waitlist to your server id elif waiting == ctx.message.channel.id: # if the waitlist is your server id, don't do anything await ctx.send( "You are the only one in the list right now. Do -leave to take youself out of the list" ) elif ctx.message.channel.id in servers: await ctx.send("You are currently in a conversation") else: # ok this is the funky bit. If someone else is in the list, we start a conversation with them # gets the other server and stores it into a variable for safekeeping otherchannel = waiting # creates a dict entry with the key being the other server's id and the value as this server's id servers[otherchannel] = ctx.message.channel.id # same as above but the other way around servers[ctx.message.channel.id] = otherchannel waiting = None try: waiting.remove[ctx.message.channel.id] except: pass # empties the wait list so other servers can join await ctx.send("Ok, connected you to another server") address = self.bot.get_channel(int(otherchannel)) await address.send( "Ok, you are connected to another server now") else: await ctx.send( "Sorry, cross server chat is disabled for this server")
async def leave(self, ctx): global waiting global servers if settings.check(ctx.message.guild.id, "get", "cross"): if ctx.message.channel.id not in servers: # if you are not connected to any servers but you are in the waitlist, remove you from that if waiting == ctx.message.channel.id: await ctx.send("Removed you from the waiting list") waiting = None else: # if you are not in either, do nothing await ctx.send("You are not in the waiting list") else: # gets the other server's id otherserver = servers[ctx.message.channel.id] # remove the dict entires for both servers servers.pop(ctx.message.channel.id) servers.pop(otherserver) # get the other channel's id so you can inform them that you left address = self.bot.get_channel(int(otherserver)) await ctx.send("You have disconnected") await address.send("You have disconnected") else: await ctx.send( "Sorry, cross server chat is disabled for this server")
def updateLibrary(): if (not settings.check()): xbmc.executebuiltin('Addon.OpenSettings(%s)'%(__addonid__)) return movieIds = getMovieIdsToUpdate() for movie in movieIds: setWatched(movie) showNotification(str(len(movieIds)) + " movies were marked as watched")
async def add(self, ctx, arg1, target: discord.Member): utils.log(ctx) if settings.check(ctx.message.guild.id, "get", "economy"): if ctx.message.author.id == 451643725475479552: sql.add(float(arg1), target.id, "money") await ctx.send(f"\\{notation(float(arg1))} added") else: await ctx.send("Nope") else: await ctx.send("Sorry, economy is disabled on this server")
async def set(self, ctx, arg1, target: discord.Member): utils.log(ctx) if settings.check(ctx.message.guild.id, "get", "economy"): if ctx.message.author.id == 451643725475479552: arg1 = float(arg1) sql.set(arg1, target.id, "money") await ctx.send(f"Balance set to {notation(arg1)} for {target}") else: await ctx.send("Nope") else: await ctx.send("Sorry, economy is disabled on this server")
async def setstock(self, ctx, arg1, target: discord.Member): utils.log(ctx) if settings.check(ctx.message.guild.id, "get", "economy"): if ctx.message.author.id == 451643725475479552: arg1 = int(arg1) sql.set(arg1, target.id, "stocks") await ctx.send(f"Stocks set to {arg1} for {target}") else: await ctx.send("Nope") else: await ctx.send("Sorry, economy is disabled on this server")
async def search(ctx, *, val=None): if settings.check(ctx.message.guild.id, "get", "search"): if val == None: await ctx.send("You need to give me a query") else: isbad2 = better_profanity.profanity.contains_profanity(val) if money.ranktoid(ctx.message.author.id) >= 3: if ((isbad2) or (val in badsearch)): badresponse = random.choice([ "This is why your parents don't love you", "Really?", "You are just an asshole. You know that?", "God has abandoned us", "Horny bastard" ]) await ctx.send(badresponse) print( f"\u001b[33;1m{ctx.message.author} tried to search '{val}'\u001b[31m" ) elif (val.find("urbandictionary")): await ctx.send("Lol no") elif "://" in val: await ctx.send("You think I'm stupid? Don't answer that.") if botlib.check_banned(ctx): # create the Search client (uses Google by default-) client = async_cse.Search( "AIzaSyAIc3NVCXoMDUzvY4sTr7hPyRQREdPUVg4") # returns a list of async_cse.Result objects results = await client.search(val, safesearch=True) first_result = results[0] # Grab the first result if "urbandictionary" in first_result.url: await ctx.send( "Thanks to <@567522840752947210>, urban dictionary is banned" ) else: await ctx.send( f"**{first_result.title}**\n{first_result.url}") await client.close() f = open(f"{filepath}/logs.txt", "a") f.write( f"{datetime.datetime.now()} - {ctx.message.guild.name} | {ctx.message.author} : !search {val} -> {first_result.url}\n" ) f.close() else: await ctx.send(botlib.nope) else: await ctx.send("You don't have a high enough rank for this") else: await ctx.send("Sorry, searches are disabled for this server")
async def bb(self, ctx, *, args): utils.log(ctx) if settings.check(ctx.message.guild.id, "get", "bb"): if botlib.check_banned(ctx): async with ctx.channel.typing(): tokens = len(args) / 4 if tokens >= 75: await ctx.send( "Sorry, that input was too big. Please try something smaller" ) return if sql.doesexist(ctx.author.id) is False: await ctx.send( "You don't have an economy account yet. Please make one with -bal" ) return if sql.get(ctx.author.id, "money") < 3: await ctx.send( "Sorry, you need more money to use the bot") else: sql.take(3, ctx.author.id, "money") ctx.message.channel.typing() with open(filepath + "/convfile.txt") as f: response = openai.Completion.create( engine="curie", prompt=(f.read()).format(args), temperature=0.9, max_tokens=100, top_p=1, frequency_penalty=0, presence_penalty=0.6, stop=[" Human:", " AI:", "\n"], ) bot = response.choices[0].text print( f"{datetime.datetime.now()} - {ctx.message.guild.name} | {ctx.message.author} : -bb: {args} -> {bot}\n" ) f = open(f"{filepath}/logs.txt", "a") f.write( f"{datetime.datetime.now()} - {ctx.message.guild.name} | {ctx.message.author} : -bb: {args} -> {bot}\n" ) f.close() await ctx.reply(bot) else: # there are a few people banned from using this command. These are their ids await ctx.reply(botlib.nope()) else: await ctx.send("Sorry, the chatbot is disabled for this server")
async def daily(self, ctx): utils.log(ctx) if settings.check(ctx.message.guild.id, "get", "economy"): if sql.doesexist(int(ctx.message.author.id)): r = random.randint(20, 50) if (sql.get(ctx.message.author.id, "money") + r <= ranks[sql.get(ctx.author.id, "rank")]["cap"]): amnt = taxrate(ctx, r) sql.add(amnt, ctx.message.author.id, "money") await ctx.send( f"{notation(amnt)} was added to your account") else: await ctx.send("Sorry, that goes over your wallet cap") else: await ctx.send( "You do not have an account. Do -account to make one") else: await ctx.send("Sorry, economy is disabled on this server")
async def bb(ctx, *, args): global ttst if settings.check(ctx.message.guild.id, "get", "bb"): async with ctx.channel.typing(): if canbb == False: await ctx.send("No, f**k off") else: ctx.message.channel.typing() if money.ranktoid(ctx.message.author.id) >= 2: if botlib.check_banned: try: cb.browser.get(cb.url) except: print("There was an error so we exited") await ctx.send("Something isn't working right") cb.browser.close() try: cb.get_form() except: print("There was an error so we exited") await ctx.send("Something isn't working right") userInput = args cb.send_input(userInput) bot = cb.get_response() print( f"\u001b[33;1m{datetime.datetime.now()} - {ctx.message.guild.name} | {ctx.message.author} : -bb: {args} -> {bot}\n\u001b[31m" ) f = open(f"{filepath}/logs.txt", "a") f.write( f"{datetime.datetime.now()} - {ctx.message.guild.name} | {ctx.message.author} : -bb: {args} -> {bot}\n" ) f.close() await ctx.send(bot) else: # there are a few people banned from using this command. These are their ids await ctx.send(botlib.nope) else: await ctx.send( "Sorry, you don't have" + ' a high enough rank. You will need to buy silver. Use "-rank" to see the price' ) else: await ctx.send("Sorry, the chatbot is disabled for this server")
async def pay(self, ctx, amount, target: discord.Member = null): # paying someone if settings.check(ctx.message.guild.id, "get", "economy"): # finds the balance of the sender urval = int(sql.get(ctx.message.author.id, "money")) thrid = target.id # target's ID if sql.doesexist(thrid) is False: await ctx.send("That user does not have an account set up") elif (amount.isnumeric is False ): # if you try paying someone something that isn't a number await ctx.send("You need to give me a number") elif thrid == ctx.message.author.id: # if you try paying yourself await ctx.send("You can't pay yourself") elif int(amount) < 1: await ctx.send("You can't pay less than $1 to someone") # if either you have less than $1 or you try and pay more than you have elif (int(amount) >= urval) or (urval - int(amount) < 0): await ctx.send("Sorry, you don't have enough money") elif sql.get(thrid, "money") + int(amount) > int(ranks[sql.get( thrid, "rank")]["cap"]): await ctx.send("Sorry, that goes over their wallet cap") else: # if you can actually pay them amount = int(amount) sql.take(amount, ctx.author.id, "money") sql.add(amount, target.id, "money") # inform the person that they were paid await ctx.send( f"{notation(amount)} was transferred to {target.name}") # send dm to target. Still not working await target.send( f"{ctx.message.author} just payed you {notation(amount)}!\n({ctx.guild.name})" ) else: await ctx.send("Sorry, economy has been turned off for this server" )
async def module(self, ctx, module=None, type=None): utils.log(ctx) global valids serverid = ctx.message.guild.id if (ctx.message.author.guild_permissions.administrator) or ( ctx.message.author.id == 451643725475479552): if os.path.isdir(filepath + "/settings/" + str(serverid)) is False: os.mkdir(filepath + "/settings/" + str(serverid)) if (os.path.isfile(filepath + "/settings/" + str(serverid) + ".json") is False): with open(filepath + "/settings/" + str(serverid) + ".json", "w") as f: json.dump({"economy": True}, f) f = open(f"{filepath}/settings/{serverid}.json", "r") f.close() if module is None: embed = discord.Embed( title="Modules", description= "Use -modules <module id> <on/off> to enable and disable parts of the bot", ) embed.add_field( name="Economy (economy)", value= f'{settings.check(ctx.message.guild.id, "get", "economy")}', inline=True, ) embed.add_field( name="Cross server chat (cross)", value= f'{settings.check(ctx.message.guild.id, "get", "cross")}', inline=True, ) embed.add_field( name="Search (search)", value= f'{settings.check(ctx.message.guild.id, "get", "search")}', inline=True, ) embed.add_field( name="Image Search (image)", value= f'{settings.check(ctx.message.guild.id, "get", "image")}', inline=True, ) embed.add_field( name="Chatbot (bb)", value= f'{settings.check(ctx.message.guild.id, "get", "bb")}', inline=True, ) embed.add_field( name="Store (store)", value= f'{settings.check(ctx.message.guild.id, "get", "store")}', inline=True, ) embed.add_field( name="Bounties (bounty)", value= f'{settings.check(ctx.message.guild.id, "get", "bounty")}', inline=True, ) await ctx.send(embed=embed) elif module is None and type is None: await ctx.send("Please enter on or off") elif module not in [ "economy", "search", "image", "bb", "store", "bounty" ]: await ctx.send("That is not a valid module id") else: if type == "on": settings.check(ctx.message.guild.id, "set", module, True) await ctx.send(f"Ok, {module} was set to {type}") elif type == "off": settings.check(ctx.message.guild.id, "set", module, False) await ctx.send(f"Ok, {module} was set to {type}") else: await ctx.send("Please enter on or off") else: await ctx.send("Sorry, only admins can change settings")
async def module(self, ctx, module=None, type=None): global valids serverid = ctx.message.guild.id if (ctx.message.author.guild_permissions.administrator) or ( ctx.message.author.id == 451643725475479552): f = open(f"{filepath}/serversettings/{serverid}/settings.json", "r") v = json.loads(f.read()) f.close() if module == None: embed = discord.Embed( title="Modules", description= "Use -modules <module id> <on/off> to enable and disable parts of the bot" ) embed.add_field( name="Economy (economy)", value= f'{settings.check(ctx.message.guild.id, "get", "economy")}', inline=True) embed.add_field( name="Cross server chat (cross)", value= f'{settings.check(ctx.message.guild.id, "get", "cross")}', inline=True) embed.add_field( name="Search (search)", value= f'{settings.check(ctx.message.guild.id, "get", "search")}', inline=True) embed.add_field( name="Image Search (image)", value= f'{settings.check(ctx.message.guild.id, "get", "image")}', inline=True) embed.add_field( name="Chatbot (bb)", value= f'{settings.check(ctx.message.guild.id, "get", "bb")}', inline=True) embed.add_field( name="Store (store)", value= f'{settings.check(ctx.message.guild.id, "get", "store")}', inline=True) embed.add_field( name="Bounties (bounty)", value= f'{settings.check(ctx.message.guild.id, "get", "bounty")}', inline=True) await ctx.send(embed=embed) elif module != None and type == None: await ctx.send("Please enter on or off") elif module not in v: await ctx.send("That is not a valid module id") else: if type == "on": settings.check(ctx.message.guild.id, "set", module, True) await ctx.send(f"Ok, {module} was set to {type}") elif type == "off": settings.check(ctx.message.guild.id, "set", module, False) await ctx.send(f"Ok, {module} was set to {type}") else: await ctx.send("Please enter on or off") else: await ctx.send("Sorry, only admins can change settings")
async def rank(self, ctx, ag1=null, rank=null): # allows someone to buy a rank if settings.check(ctx.message.guild.id, "get", "economy"): global ranks, namestorank # idk if this is needed but it can't hurt to have it # "user" is easier to type than "ctx.message.author.id" user = ctx.message.author.id if ag1 != "buy": # if they don't have "buy" as their first arg, send prices embed = discord.Embed( title="Ranks", description="The price of different ranks", color=0x1E00FF, ) embed.set_thumbnail( url= "https://lh3.googleusercontent.com/proxy/07h14DsTB_1a1UudwyVJz7OICAz9RSOE0uLEI3ox3vFTdjvM4hJolKhXaAEk0UeSeE2V92Qgv8ScFee0Zm9GoR-VKc6EadFPwYIVw93O6-EiSvI" ) for x in namestorank: if x != "bronze": # loops through all the ranks so I don't have to hardcode it embed.add_field( name=ranks[namestorank[x]]["name"], value=f"${ranks[namestorank[x]]['price']}", inline=True, ) embed.set_footer( text='Use "-rank buy [rank name]" to buy a rank') await ctx.send(embed=embed) else: # if they do have it, start doing stuff crank = sql.get(int(user), "rank") crankv = ranks[crank]["price"] if rank not in namestorank: await ctx.send("That rank doesn't exist") return val = ranks[namestorank[rank]]["price"] if rank == null: # if they don't enter a rank to buy await ctx.send("Please choose a rank to buy") elif (rank.lower() in namestorank) is False: # if the rank does not appear in the ranks list (dict) await ctx.send("That was not a valid rank") elif canbuy(val, user) is False: # explains itself await ctx.send("You do not have enough money to buy this") elif crankv > val: await ctx.send("You can't buy a lower rank") elif crankv == int(ranks[namestorank[rank.lower()]]["price"]): await ctx.send("You can't buy your current rank") else: cost = ( 0 - val ) # turn the value into a negative so you can buy it properly rnum = namestorank[rank] sql.set(rnum, user, "rank") # takes the money from the account (adds a negative value) sql.add(cost, user, "money") # let them know await ctx.send( f"Rank {rank} was bought for {notation(val)}") else: await ctx.send("Sorry, economy is disabled on this server")
async def stocks(self, ctx, action=null, count=null): utils.log(ctx) if settings.check(ctx.message.guild.id, "get", "economy"): global stock global cost global countdown user = int(ctx.message.author.id) if sql.get(user, "stocks") == null: await ctx.send( "You need to create an account with -account first") else: if action == "sell": if count == "all": # work out how many the can buy with their currant bal and then set that to the number they are trying to buy count = int(sql.get(user, "stocks")) if count <= 0: await ctx.send("Sorry, you don't own any stocks") elif action == "buy": if count == "all": bal = sql.get(user, "money") # if "all" is used, work out how many they can sell buy just setting number to sell as how many stocks they own count = math.floor(bal / cost) if count <= 0: await ctx.send("Sorry, you can't afford any stocks" ) return stockcount = sql.get(user, "stocks") bal = sql.get(ctx.message.author.id, "money") try: timeto = countdown - datetime.now() except NameError: pass if action == null: comment = botlib.stockcomment(ctx, cost) if comment[0] == "url": await ctx.send( f"Current price of stocks: **{notation(cost)}**\nYou currently own {stockcount} stocks\nTime until stock price change: {humanfriendly.format_timespan(timeto)}" ) await ctx.send(comment[1]) else: await ctx.send( f"Current price of stocks: **{notation(cost)}**\nYou currently own {stockcount} stocks\nTime until stock price change: {humanfriendly.format_timespan(timeto)}{comment}" ) # if no options are specified, show current price and hw many the user owns. else: count = int(count) fcost = round((float(count) * cost), 2) if count <= 0: await ctx.send( "You need to enter a number that is over 0" ) # if they own no stocks or can't afford any when using "all", or they try and enter a number below 1. Can't buy 0 stocks or negative stocks elif action == "buy" and (fcost > bal): # if they can't afford the number of stocks they specified await ctx.send("You don't have enough money") elif (action == "sell") and (count > int(stockcount)): # if they try sell more stocks than they own. await ctx.send("You don't own that many stocks") elif action == "buy": sql.take(taxrate(ctx, fcost), user, "money") sql.add(count, user, "stocks") # if they can actually buy stocks, run this to do all the account manipulaion. await ctx.send( f"{count} stocks bought for {notation(fcost)}") elif action == "sell": # Makes sure that the sold stocks won't exceed the wallet cap of their rank. if (sql.get(ctx.message.author.id, "money") + fcost <= ranks[sql.get(user, "rank")]["cap"]): sql.add(taxrate(ctx, fcost), user, "money") sql.take(count, user, "stocks") await ctx.send( f"{count} stocks sold for {notation(fcost)}") else: c = 1 while (cost * c + bal < ranks[sql.get( ctx.author.id, "rank")]["cap"]): c += 1 count = c - 1 fcost = cost * count sql.add(taxrate(ctx, fcost), user, "money") sql.take(count, user, "stocks") await ctx.send( f"Since that amount of sold stocks would go over your wallet cap, you are only selling {count} stocks for {notation(fcost)}" ) elif action == "calc": await ctx.send( # simply calculates how much the specified stocks would cost. f"{count} stocks at {notation(cost)} is worth ${round((count * cost), 2)}" ) else: await ctx.send("Sorry, economy is disabled on this server")
async def account(self, ctx, *, target: discord.Member = null): utils.log(ctx) if settings.check(ctx.message.guild.id, "get", "economy"): # If no target was specified set yourself as the target if target == null: # Check if you exist if sql.doesexist(ctx.author.id): # Set the target id, name and ctx as your own tid = ctx.author.id tname = ctx.author.name tuser = ctx.author else: # Create an account if you don't exist sql.adduser(ctx.author.id) sql.set(ctx.author.name, ctx.author.id, "name") # if the user does not have an account, create one await ctx.send("Account created!") return else: # If the target exists, great! Set the shit if sql.doesexist((target.id)): tid = target.id tname = target.name tuser = target else: # if the user pings someone who does not have an account, send this await ctx.send("That user does not have an account set up") return # Load the path to the user's image, even if it does not exist if str(tid) in os.listdir(filepath + "/static/banners"): banner = Image.open( f"{filepath}/static/banners/{tid}").convert("RGBA") else: banner = Image.open(f"{filepath}/static/banner.png").convert( "RGBA") imagepath = f"{filepath}/static/userimgs/{tuser.id}" # If we don't have the user's image, get it if str(ctx.author.id) not in os.listdir( f"{filepath}/static/userimgs"): await ctx.send("Gathering data...") await tuser.avatar_url.save(imagepath) # if it does exist, shove their ID in a thread to update the user's icon in the background else: try: threading.Thread( target=geticon, name=f"Icon finder for {ctx.author.name}", args=(ctx, ), daemon=True, ).start() # If for some reason we can't get the user's image, use a dummy pic except Exception: print("Users image not found") imagepath = filepath + "/static/unknown.png" # Open our lovely image. If it doesn't work, fall back to a dummy image try: img = Image.open(imagepath).convert("RGBA") except Exception: img = Image.open(filepath + "/static/unknown.png", "RGBA") # Bal, stocks, rank and wallet cap variables to make reading this code easier bal = round(sql.get(tid, "money"), 2) stocks = sql.get(tid, "stocks") rank = ranks[sql.get(tid, "rank")]["name"] cap = ranks[sql.get(tid, "rank")]["cap"] # For some reason, each letter is 27 pixels wide with the dummy thicc font namelen = 27 * len(tname) # Resize the pfp to a standard size, so we don't get timmy setting his pfp # to a 3.8TB image of heavy from tf2 then crashing this whole thing img = img.resize((180, 180), Image.ANTIALIAS) # Give me a red border and everyone else a black one. Cos I wanna be special. if tuser.id in secret_data.admins: img = ImageOps.expand(img, border=5, fill="red") else: img = ImageOps.expand(img, border=5, fill="black") # Resize the banner to a set size banner = banner.resize((745, 270), Image.ANTIALIAS) # Give the banner a nice black border banner = ImageOps.expand(banner, border=5, fill="black") # Stick the user's icon onto it now banner.paste(img, [45, 45]) # Set up the snake based drawing tablet d = ImageDraw.Draw(banner, mode="RGBA") # Draw a grey rectangle so we can see if people use a custom banner # Create a new plain image rect = Image.new("RGBA", (750, 270)) # Set up the snake based drawing tablet for the rectangle rectdraw = ImageDraw.Draw(rect, mode="RGBA") # Draw the f****r rectdraw.rectangle( ((270, 22.5), (722.5, 248.5)), fill=(255, 255, 255, 100), outline="black", ) # Paste it onto the banner banner.paste(rect, mask=rect) # Write the user's bal on there d.text((282, 75), f"Balance: {notation(bal)}", fill="black", font=font) # MMMMM STONKS d.text((283, 119), f"Owned stocks: {stocks}", fill="black", font=font) # Take a guess what this line does d.text((282, 163), f"Rank: {rank}", fill="black", font=font) # Add the user's wallet cap d.text((285, 208), f"Wallet cap: {notation(cap)}", fill="black", font=font) # Write the user's name in dummy thicc font d.text((285, 20), tname, fill="black", font=thiccfont) # Underline the user's name with some fucky maths d.line(((285, 70), ((285 + namelen), 70)), fill=(26, 26, 26), width=5) # Waaaa, uploads need to be files whaaaaaa! # Suck my fat juicy c**k Discord with BytesIO() as img_bin: banner.save(img_bin, "PNG", optimize=True) img_bin.seek(0) await ctx.send( file=discord.File(fp=img_bin, filename=f"{tname}.png")) else: await ctx.send("Sorry, economy is disabled on this server")