Advertisement
Guest User

Daddy halp async kthx

a guest
Mar 1st, 2018
145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 16.22 KB | None | 0 0
  1. from discord.ext import commands
  2. import discord, pymysql, config, time, random, math, datetime, requests, re, logging
  3. from io import BytesIO
  4. from PIL import Image, ImageDraw, ImageFont
  5. from textwrap import wrap
  6. from .utils import chat_formatting
  7.  
  8. log = logging.getLogger("NekoBot")
  9.  
  10. connection = pymysql.connect(user=config.db.user,
  11.                              password=config.db.password,
  12.                              host=config.db.host,
  13.                              port=config.db.port,
  14.                              database=config.db.database)
  15. db = connection.cursor()
  16.  
  17. sqlCHAR = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "A", "a", "B", "b", "C", "c", "D", "d", "E", "e", "F", "f",
  18.            "G", "g", "H", "h", "I", "i", "j", "J", "K", "k", "L", "l", "M", "m", "N", "n", "O", "o", "P", "p", "Q", "q",
  19.            "R", "r", "S", "s", "T", "t", "U", "u", "V", "v", "W", "w", "X", "x", "Y", "y", "Z", "z"]
  20.  
  21. class Levels:
  22.     """Levelling System OwO"""
  23.  
  24.     def __init__(self, bot):
  25.         self.bot = bot
  26.  
  27.     # @commands.command()
  28.     # async def profile(self, ctx, user : discord.Member = None):
  29.     #     if user == None:
  30.     #         user = ctx.message.author
  31.     #     try:
  32.     #         db.execute("SELECT level FROM levels WHERE userid = {}".format(user.id))
  33.     #         levels = db.fetchone()[0]
  34.     #         db.execute("SELECT rep FROM levels WHERE userid = {}".format(user.id))
  35.     #         REP = db.fetchone()[0]
  36.     #         db.execute("SELECT title FROM levels WHERE userid = {}".format(user.id))
  37.     #         title = db.fetchone()[0]
  38.     #         db.execute("SELECT info FROM levels WHERE userid = {}".format(user.id))
  39.     #         desc = db.fetchone()[0]
  40.     #     except:
  41.     #         levels = 0
  42.     #         REP = 0
  43.     #         title = ""
  44.     #         desc = ""
  45.     #
  46.     #     try:
  47.     #         db.execute("select balance from economy where userid = {}".format(user.id))
  48.     #         balance = db.fetchone()[0]
  49.     #     except:
  50.     #         balance = 0
  51.     #
  52.     #     color = user.color
  53.     #     embed = discord.Embed(color=color,
  54.     #                           title=str(title),
  55.     #                           description=str(desc))
  56.     #     embed.set_author(name=f"{user.name}")
  57.     #     embed.set_thumbnail(url=user.avatar_url)
  58.     #     embed.add_field(name="Level", value=f"**{self._find_level(levels)}**")
  59.     #     embed.add_field(name="Rep", value=f"**{REP}**")
  60.     #     embed.add_field(name="Balance", value=f"{balance}")
  61.     #     embed.set_footer(text=f"Total XP: {levels}, {self._level_exp(self._find_level(levels))}/{self._required_exp(self._find_level(levels))}")
  62.     #
  63.     #     await ctx.send(embed=embed)
  64.  
  65.     @commands.command()
  66.     async def profile(self, ctx, user : discord.Member = None):
  67.         if user == None:
  68.             user = ctx.message.author
  69.         try:
  70.             db.execute("SELECT level FROM levels WHERE userid = {}".format(user.id))
  71.             levels = db.fetchone()[0]
  72.             db.execute("SELECT rep FROM levels WHERE userid = {}".format(user.id))
  73.             REP = db.fetchone()[0]
  74.             db.execute("SELECT title FROM levels WHERE userid = {}".format(user.id))
  75.             title = db.fetchone()[0]
  76.             db.execute("SELECT info FROM levels WHERE userid = {}".format(user.id))
  77.             desc = db.fetchone()[0]
  78.         except:
  79.             levels = 0
  80.             REP = 0
  81.             title = ""
  82.             desc = ""
  83.  
  84.         try:
  85.             db.execute(f"SELECT osu FROM osu WHERE userid = {user.id}")
  86.             osu = db.fetchone()[0]
  87.         except:
  88.             osu = "None"
  89.  
  90.         try:
  91.             db.execute("SELECT balance FROM economy WHERE userid = {}".format(user.id))
  92.             balance = db.fetchone()[0]
  93.         except:
  94.             balance = 0
  95.  
  96.         color = str(user.color).replace("#", "")
  97.  
  98.         self._build_profile(user, title, desc, REP, levels, color, balance, osu)
  99.         await ctx.send(file=discord.File(f"data/profiles/{user.id}.png"))
  100.  
  101.     @commands.command()
  102.     async def settitle(self, ctx, *, title : str):
  103.         """Set profile title"""
  104.         if not db.execute('SELECT 1 FROM levels WHERE userid = {}'.format(ctx.message.author.id)):
  105.             await ctx.send("Error finding your profile.")
  106.             return
  107.         if '"' in title:
  108.             log.info(f"{ctx.message.author.id} {ctx.message.author.name} forbidden char")
  109.             return
  110.         elif "'" in title:
  111.             log.info(f"{ctx.message.author.id} {ctx.message.author.name} forbidden char")
  112.             return
  113.         elif ";" in title:
  114.             log.info(f"{ctx.message.author.id} {ctx.message.author.name} forbidden char")
  115.             return
  116.         if len(title) > 24:
  117.             await ctx.send("Your title is over 24 characters...")
  118.             return
  119.         try:
  120.             db.execute(f"UPDATE levels SET title = \"{title}\" WHERE userid = {ctx.message.author.id}")
  121.             connection.commit()
  122.             await ctx.send("Title Updated!")
  123.         except Exception as e:
  124.             await ctx.send("Problem updating title to database...")
  125.  
  126.     @commands.command()
  127.     async def setdesc(self, ctx, *, description : str):
  128.         """Set profile description"""
  129.         if not db.execute('SELECT 1 FROM levels WHERE userid = {}'.format(ctx.message.author.id)):
  130.             await ctx.send("Error finding your profile.")
  131.             return
  132.         if '"' in description:
  133.             log.info(f"{ctx.message.author.id} {ctx.message.author.name} forbidden char")
  134.             return
  135.         elif "'" in description:
  136.             log.info(f"{ctx.message.author.id} {ctx.message.author.name} forbidden char")
  137.             return
  138.         elif ";" in description:
  139.             log.info(f"{ctx.message.author.id} {ctx.message.author.name} forbidden char")
  140.             return
  141.         if len(description) > 50:
  142.             await ctx.send("Your description is too long.")
  143.             return
  144.         try:
  145.             db.execute(f"UPDATE levels SET info = \"{description}\" WHERE userid = {ctx.message.author.id}")
  146.             connection.commit()
  147.             await ctx.send("Description Updated!")
  148.         except Exception as e:
  149.             await ctx.send("Problem updating description to database...")
  150.  
  151.     @commands.command()
  152.     @commands.cooldown(1, 30, commands.BucketType.user)
  153.     async def rep(self, ctx, user : discord.Member):
  154.         """Rep a user."""
  155.         if user == ctx.message.author:
  156.             await ctx.send("You can't rep yourself 😦")
  157.             return
  158.         elif user.bot:
  159.             await ctx.send("You can't rep a bot 😦")
  160.             return
  161.         else:
  162.             if not db.execute('SELECT 1 FROM levels WHERE userid = {}'.format(user.id)):
  163.                 await ctx.send("That user doesn't have an account yet")
  164.                 return
  165.             db.execute(f"SELECT lastrep FROM levels WHERE userid = {ctx.message.author.id}")
  166.             getdb = db.fetchone()[0]
  167.             timenow = datetime.datetime.utcfromtimestamp(time.time()).strftime("%d")
  168.             timecheck = datetime.datetime.utcfromtimestamp(int(getdb)).strftime("%d")
  169.             if timecheck == timenow:
  170.                 await ctx.send("You already used your rep today 😦")
  171.                 return
  172.             db.execute("SELECT rep FROM levels WHERE userid = {}".format(user.id))
  173.             rep_curr = int(db.fetchone()[0])
  174.             db.execute(f"UPDATE levels SET rep = {rep_curr + 1} WHERE userid = {user.id}")
  175.             connection.commit()
  176.             db.execute(f"UPDATE levels SET lastrep = {int(time.time())} WHERE userid = {ctx.message.author.id}")
  177.             connection.commit()
  178.             await ctx.send(f"{ctx.message.author.name} gave {user.mention} rep!")
  179.  
  180.     @commands.command()
  181.     @commands.is_owner()
  182.     async def imgbuild(self, ctx):
  183.         """IMG Build"""
  184.         user = ctx.message.author
  185.         color = str(user.color).replace("#", "")
  186.         fox = "The quick brown fox jumps over the lazy dog"
  187.         self._build_profile(user, fox, fox, 5, 500, color, 500)
  188.         await ctx.send(file=discord.File(f"data/imgwelcome/{user.id}.png"))
  189.  
  190.     @commands.command()
  191.     @commands.is_owner()
  192.     async def sql(self, ctx, *, sql: str):
  193.         """Inject SQL"""
  194.         try:
  195.             db.execute(sql)
  196.             connection.commit()
  197.         except Exception as e:
  198.             await ctx.send(f"`{e}`")
  199.  
  200.     async def _handle_on_message(self, message):
  201.         user = message.author
  202.         text = message.content
  203.         userinfo = user.id
  204.         await self._create_user(user)
  205.         curr_time = time.time()
  206.         db.execute(f"SELECT lastxp FROM levels WHERE userid = {user.id}")
  207.         if float(curr_time) - float(db.fetchone()[0]) >= 120:
  208.             await self._process_exp(message, userinfo, random.randint(15, 20))
  209.             #await self._give_chat_credit(user)
  210.             db.execute(f"UPDATE levels SET lastxp = {time.time()} WHERE userid = {userinfo}")
  211.             connection.commit()
  212.  
  213.     async def _process_exp(self, message, userinfo, exp : int):
  214.         db.execute("SELECT level FROM levels WHERE userid = {}".format(userinfo))
  215.         levels = db.fetchone()[0]
  216.         db.execute(f"UPDATE levels SET level = {levels + exp} WHERE userid = {userinfo}")
  217.         connection.commit()
  218.  
  219.     # async def _give_chat_credit(self, user):
  220.     #     db.execute("select balance from economy where userid = {}".format(user.id))
  221.     #     eco = int(db.fetchone())
  222.     #     db.execute(f"UPDATE economy SET balance = {eco + 100} WHERE userid = {user.id}")
  223.     #     connection.commit()
  224.  
  225.     async def _create_user(self, user):
  226.         try:
  227.             if not db.execute('SELECT 1 FROM levels WHERE userid = {}'.format(user.id)):
  228.                 #userid, info, title, level, rep, lastxp, lastrep
  229.                 db.execute(f"INSERT IGNORE INTO levels VALUES ({user.id}, info, title, 0, 0, 0, 0)")
  230.                 connection.commit()
  231.                 log.info(f"Made account for {user.name} ({user.id})")
  232.             else:
  233.                 pass
  234.         except AttributeError:
  235.             pass
  236.  
  237.     def _required_exp(self, level: int):
  238.         if level < 0:
  239.             return 0
  240.         return 139 * level + 65
  241.  
  242.     def _level_exp(self, level: int):
  243.         return level * 65 + 139 * level * (level - 1) // 2
  244.  
  245.     def _find_level(self, total_exp):
  246.         # this is specific to the function above
  247.         return int((1 / 278) * (9 + math.sqrt(81 + 1112 * (total_exp))))
  248.  
  249.     def _hex_to_rgb(self, hex_num: str, a: int):
  250.         h = hex_num.lstrip('#')
  251.  
  252.         # if only 3 characters are given
  253.         if len(str(h)) == 3:
  254.             expand = ''.join([x*2 for x in str(h)])
  255.             h = expand
  256.  
  257.         colors = [int(h[i:i+2], 16) for i in (0, 2, 4)]
  258.         colors.append(a)
  259.         return tuple(colors)
  260.  
  261.     def _build_profile(self, user, title : str, desc : str, rep : int, xp : int, color, balance : int, osu : str):
  262.         """v2 of build profile - ReKT#0001, Hex to RGB - stackoverflow.com"""
  263.         darken = 20
  264.         lighten = 20
  265.  
  266.         osu = str(osu)
  267.         level = self._find_level(xp)
  268.         joined = user.created_at.strftime("%d %b %Y %H:%M")
  269.         title = title.title()
  270.         if len(title) > 22:
  271.             title = title[:22] + "..."
  272.         desc = "\n".join(wrap(desc, 35))
  273.  
  274.         color = self._hex_to_rgb(color, 255)
  275.         black = (0, 0, 0)
  276.         white = (255, 255, 255)
  277.  
  278.         if color[0] < 127 :
  279.             top_color = (color[0] + lighten,
  280.                          color[1] + lighten,
  281.                          color[2] + lighten,
  282.                          255)
  283.             text_color = (255, 255, 255)
  284.         else:
  285.             top_color = (color[0] - darken,
  286.                          color[1] - darken,
  287.                          color[2] - darken,
  288.                          255)
  289.             text_color = (0, 0, 0)
  290.  
  291.         if len(str(level)) > 1:
  292.             level_len = (145, 125)
  293.             level_text = (10, 90)
  294.         else:
  295.             level_len = (125, 125)
  296.             level_text = (40, 90)
  297.  
  298.         img = Image.new("RGBA", (362, 333), (225, 226, 225, 255))
  299.         top_layer = Image.new('RGB', (362, 23), top_color)
  300.         bar = Image.new('RGB', (362, 65), color)
  301.         level_box = Image.new('RGB', level_len, (255, 255, 255))
  302.         level_box_shadow = Image.new('RGBA', level_len, (64, 64, 64, 220))
  303.  
  304.         draw = ImageDraw.Draw(img)
  305.         text = ImageFont.truetype("data/fonts/material/Roboto-Light.ttf", 35)
  306.         title_font = ImageFont.truetype("data/fonts/material/Roboto-Light.ttf", 25)
  307.         unicode_font = ImageFont.truetype("data/fonts/unifont.ttf", 15)
  308.         joined_font = ImageFont.truetype("data/fonts/material/Roboto-Light.ttf", 17)
  309.         user_title = ImageFont.truetype("data/fonts/material/Roboto-Regular.ttf", 27)
  310.         user_description = ImageFont.truetype("data/fonts/material/Roboto-Light.ttf", 20)
  311.         level_font = ImageFont.truetype("data/fonts/material/Roboto-Thin.ttf", 125)
  312.  
  313.         img.paste(top_layer, (0, 0))
  314.         img.paste(bar, (0, 23))
  315.         img.alpha_composite(level_box_shadow, (20, 110))
  316.         img.paste(level_box, (10, 100))
  317.  
  318.         osu_dest = (301, 25)
  319.  
  320.         if osu != "None":
  321.             draw.text((300, 25), "OSU: ✓", text_color, font=unicode_font)
  322.         else:
  323.             draw.text((300, 25), "OSU: ✖", text_color, font=unicode_font)
  324.  
  325.         draw.text((15, 32), f"{user.name + '#' + user.discriminator}", text_color, font=text)
  326.         # draw.text((20, 105), "Level", black, font=title)
  327.         draw.text((165, 120), f"{rep} Rep", black, font=title_font)
  328.         draw.text((165, 150), f"${balance}", black, font=title_font)
  329.         draw.text((165, 185), f"Joined on\n{joined}", black, font=joined_font)
  330.         draw.text((10, 240), str(title), black, font=user_title)
  331.         draw.text((10, 270), str(desc), black, font=user_description)
  332.         draw.text(level_text, str(level), black, font=level_font)
  333.  
  334.         img.save(f"data/profiles/{user.id}.png")
  335.  
  336.     # def _build_profile(self, user, title : str, desc : str, rep : int, xp : int):
  337.     #     img = Image.new('RGBA', (300, 300), (255, 255, 255, 255))
  338.     #     bg = Image.open("data/backgrounds/default.jpg").resize((300, 300))
  339.     #     titlebg = Image.new('RGBA', (187, 25), (100, 100, 100, 130))
  340.     #     badgebg = Image.new('RGBA', (100, 160), (80, 80, 80, 140))
  341.     #     descbg = Image.new('RGBA', (178, 170), (100, 100, 100, 130))
  342.     #     layer1 = Image.new('RGBA', (290, 180), (130, 130, 130, 130))
  343.     #     avatar = user.avatar_url
  344.     #     avatar = requests.get(avatar).content
  345.     #     avatar = Image.open(BytesIO(avatar)).convert("RGBA").resize((90, 90))
  346.     #
  347.     #     img.paste(bg)
  348.     #     img.alpha_composite(titlebg, (105, 95))
  349.     #     img.alpha_composite(layer1, (5, 120))
  350.     #     img.alpha_composite(badgebg, (10, 135))
  351.     #     img.alpha_composite(descbg, (110, 125))
  352.     #     img.paste(avatar, (15, 60))
  353.     #
  354.     #     draw = ImageDraw.Draw(img)
  355.     #     titlet = ImageFont.truetype("data/fonts/win10/corbel.ttf", 16)
  356.     #     rept = ImageFont.truetype("data/fonts/win10/verdana.ttf", 15)
  357.     #     desct = ImageFont.truetype("data/fonts/win10/lucon.ttf", 13)
  358.     #     levelt = ImageFont.truetype("data/fonts/win10/courbd.ttf", 40)
  359.     #     leveltt = ImageFont.truetype("data/fonts/win10/courbd.ttf", 20)
  360.     #     font1 = ImageFont.truetype("data/fonts/win10/courbd.ttf", 12)
  361.     #
  362.     #     desc = "\n".join(wrap(desc, 22))
  363.     #     level = self._find_level(xp)
  364.     #
  365.     #     draw.text((115, 100), title[:24], (255, 255, 255), font=titlet)
  366.     #     draw.text((30, 155), f"Rep: {rep}", (255, 255, 255), font=rept)
  367.     #     draw.line(((130, 220), (267, 220)), (200, 200, 200), 1)
  368.     #     draw.text((120, 230), desc, (255, 255, 255), font=desct)
  369.     #     draw.text((180, 150), str(level), (255, 255, 255), font=levelt)
  370.     #     draw.text((160, 190), "LEVEL", (255, 255, 255), font=leveltt)
  371.     #     draw.text((120, 130), f"{user.name}", (255, 255, 255), font=font1)
  372.     #     draw.text((120, 145), f"XP: {xp}", (255, 255, 255), font=font1)
  373.     #     print(f"Built profile {user.name} ({user.id})")
  374.     #     img.save(f"data/profiles/{user.id}.png")
  375.  
  376. def setup(bot):
  377.     n = Levels(bot)
  378.     bot.add_listener(n._handle_on_message, "on_message")
  379.     bot.add_cog(n)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement