7 |
8 | Modern Levels is the most advanced open-source Discord Levelling Bot
9 |
10 |
11 |
Offers a plethora of config options to easily customise how the bot functions.
12 |
Functions for whatever you need, making development easier.
13 |
Keep your Discord server alive with the multiple options Modern Levels offers.
14 |
MongoDB & SQLite support
15 |
16 |
17 |
18 | Running into problems? Want to submit a bug report or suggestion? Join our [Support Server](https://discord.gg/UgvTHmuyNK)
19 |
20 | **Please do not use REPLIT to host the bot!**
21 |
22 |
23 | # The Rank Card
24 | 
25 | The Rank Card can easily have it's Blur Level, Background, Profile Border & Text Colour changed through commands.
26 |
27 | Modern Levels Allows you to switch between 3 Rank Card Generators:
28 |
29 | | Generator | Description |
30 | | ------------- |:-------------:|
31 | | Custom | The Rank Card by Kumo's Lab, supports all customisation options and will never go down. |
32 | | Vacefron | The Rank Card created by Vacefron, supports half the customisation options, regular down time. |
33 | | Text | The Rank Card to keep things simple and fast, currently with no customisations, but the fastest out of the 3. |
34 |
35 |
36 | # Features
37 | 
38 |
39 |
Levelling System
40 |
Paginated Leaderboards
41 |
Update-Notifier
42 |
Addon Manager
43 |
High Level of Customisation
44 |
Supports MongoDB and SQLite
45 |
Functions for easy development
46 |
3 Rank Generators
47 |
Ready to go in a few clicks
48 |
49 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ main ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ main ]
20 | schedule:
21 | - cron: '32 7 * * 5'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 |
28 | strategy:
29 | fail-fast: false
30 | matrix:
31 | language: [ 'python' ]
32 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
33 | # Learn more:
34 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
35 |
36 | steps:
37 | - name: Checkout repository
38 | uses: actions/checkout@v2
39 |
40 | # Initializes the CodeQL tools for scanning.
41 | - name: Initialize CodeQL
42 | uses: github/codeql-action/init@v1
43 | with:
44 | languages: ${{ matrix.language }}
45 | # If you wish to specify custom queries, you can do so here or in a config file.
46 | # By default, queries listed here will override any specified in a config file.
47 | # Prefix the list here with "+" to use these queries and those in the config file.
48 | # queries: ./path/to/local/query, your-org/your-repo/queries@main
49 |
50 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
51 | # If this step fails, then you should remove it and run the build manually (see below)
52 | - name: Autobuild
53 | uses: github/codeql-action/autobuild@v1
54 |
55 | # ℹ️ Command-line programs to run using the OS shell.
56 | # 📚 https://git.io/JvXDl
57 |
58 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
59 | # and modify them (or add more) to build your code if your project
60 | # uses a compiled language
61 |
62 | #- run: |
63 | # make bootstrap
64 | # make release
65 |
66 | - name: Perform CodeQL Analysis
67 | uses: github/codeql-action/analyze@v1
68 |
--------------------------------------------------------------------------------
/Commands/xpcolour.py:
--------------------------------------------------------------------------------
1 | import discord
2 | from discord.ext import commands
3 | from ruamel.yaml import YAML
4 | import random
5 |
6 | import KumosLab.Database.get
7 | import KumosLab.Database.set
8 |
9 | yaml = YAML()
10 | with open("Configs/config.yml", "r", encoding="utf-8") as file:
11 | config = yaml.load(file)
12 |
13 |
14 | # XP Colour Class
15 | class setcolour(commands.Cog):
16 | def __init__(self, client):
17 | self.client = client
18 |
19 | @commands.command(aliases=['setcolor'])
20 | async def setcolour(self, ctx, hex: str = None):
21 | if hex is None:
22 | embed = discord.Embed(
23 | description=f"🔴 **ERROR**: `Colour Change Failed! - {config['Prefix']}setcolour <#hexcode|random>`")
24 | await ctx.send(embed=embed)
25 | return
26 | try:
27 | member = ctx.author
28 | if hex.lower() == "random":
29 | random_number = random.randint(0, 16777215)
30 | hex_number = format(random_number, 'x')
31 | hex_number = '#' + hex_number
32 | await KumosLab.Database.set.colour(user=member,guild=member.guild, hex=hex_number)
33 | embed = discord.Embed(description=f"🟢 **SUCCESS**: `Colour Changed to {hex_number}`", color=int(str(hex_number).replace("#", "0x"), 16))
34 | await ctx.reply(embed=embed)
35 | else:
36 | # check if hex includes #
37 | if hex.startswith("#"):
38 | if len(hex) > 7 or len(hex) < 7:
39 | embed = discord.Embed(
40 | description=f"🔴 **ERROR**: `Colour Change Failed! - Invalid Hex Code`")
41 | await ctx.reply(embed=embed)
42 | else:
43 | await KumosLab.Database.set.colour(user=member,guild=member.guild, hex=hex)
44 | embed = discord.Embed(description=f"🟢 **SUCCESS**: `Colour Changed to {hex}`", color=int(str(hex).replace("#", "0x"), 16))
45 | await ctx.reply(embed=embed)
46 | # add # to hex
47 | else:
48 | new_hex = "#" + hex
49 | if len(hex) > 7 or len(new_hex) < 7:
50 | embed = discord.Embed(
51 | description=f"🔴 **ERROR**: `Colour Change Failed! - Invalid Hex Code`")
52 | await ctx.reply(embed=embed)
53 | else:
54 | await KumosLab.Database.set.colour(user=member,guild=member.guild, hex=new_hex)
55 | embed = discord.Embed(description=f"🟢 **SUCCESS**: `Colour Changed to {new_hex}`", color=int(str(new_hex).replace("#", "0x"), 16))
56 | await ctx.reply(embed=embed)
57 |
58 |
59 | except Exception as e:
60 | print(f"[XP-Colour Command] {e}")
61 |
62 | def setup(client):
63 | client.add_cog(setcolour(client))
--------------------------------------------------------------------------------
/KumosLab/Database/Create/ClanCard/clan_card.py:
--------------------------------------------------------------------------------
1 | import discord
2 | from discord import File
3 | from easy_pil import Editor, load_image_async, Font, load_image
4 | from ruamel.yaml import YAML
5 | import Commands.rank
6 |
7 |
8 | import KumosLab.Database.get
9 |
10 |
11 | yaml = YAML()
12 | with open("Configs/config.yml", "r", encoding="utf-8") as file:
13 | config = yaml.load(file)
14 | with open("Configs/clan_addon.yml", "r", encoding="utf-8") as file:
15 | clan_config = yaml.load(file)
16 |
17 | def translate(num):
18 | num = float('{:.3g}'.format(num))
19 | magnitude = 0
20 | while abs(num) >= 1000:
21 | magnitude += 1
22 | num /= 1000.0
23 | return '{}{}'.format('{:f}'.format(num).rstrip('0').rstrip('.'), ['', 'K', 'M', 'B', 'T'][magnitude])
24 |
25 | async def generate(user: discord.Member = None, guild: discord.Guild = None, clan_Name: str = None):
26 | if guild is None:
27 | print("[Custom] Guild is None")
28 | return
29 | if user is None:
30 | print("[Custom] User is None")
31 | return
32 | if clan_Name is None:
33 | print("[Custom] Clan_Name is None")
34 | return
35 | try:
36 | xp = await KumosLab.Database.get.clanXP(clan_Name=clan_Name, guild=guild)
37 | level = 1
38 |
39 | rank_colour = await KumosLab.Database.get.clanColour(clan_Name=clan_Name, guild=guild)
40 | clan_owner = await KumosLab.Database.get.clanOwner(clan_Name=clan_Name, guild=guild)
41 |
42 | blur = 0
43 |
44 | while True:
45 | if xp < ((config['xp_per_level'] / 2 * (level ** 2)) + (config['xp_per_level'] / 2 * level)):
46 | break
47 | level += 1
48 | xp -= ((config['xp_per_level'] / 2 * (level - 1) ** 2) + (config['xp_per_level'] / 2 * (level - 1)))
49 |
50 | next_level_xp = int(config['xp_per_level'] * 2 * ((1 / 2) * level))
51 |
52 | percentage = int((xp / next_level_xp) * 100)
53 |
54 | clan_logo = await KumosLab.Database.get.clanLogo(clan_Name=clan_Name, guild=guild)
55 | clan_background = clan_config['clan_card_background']
56 |
57 | background_image = load_image(str(clan_background))
58 | background = Editor(background_image).resize((1280, 720)).blur(amount=int(blur))
59 |
60 | profile_border = load_image(clan_config['clan_icon_border'])
61 | profile_border = Editor(profile_border).resize((250, 260))
62 |
63 | profile_image = load_image(clan_logo)
64 | profile = Editor(profile_image).resize((240, 250))
65 |
66 |
67 | font_25 = Font.poppins(size=35, variant="bold")
68 | font_60_bold = Font.poppins(size=60, variant="bold")
69 | font_40_bold = Font.poppins(size=50, variant="bold")
70 |
71 | background.paste(profile_border, (30, 40))
72 | background.paste(profile, (35, 45))
73 |
74 | background.text((300, 40), f"{clan_owner}", font=font_60_bold, color=rank_colour)
75 |
76 | background.text((270, 150), f"Level: {level:,}", font=font_25, color="white")
77 |
78 | background.rectangle((260, 190), width=600, height=40, radius=20)
79 | if percentage > 5:
80 | background.bar(
81 | (260, 190),
82 | max_width=600,
83 | height=40,
84 | percentage=percentage,
85 | fill=rank_colour,
86 | radius=20,
87 | )
88 |
89 | background.text(
90 | (845, 145), f"{translate(xp)} / {translate(next_level_xp)}", font=font_25, color="white", align="right"
91 | )
92 |
93 | card = File(fp=background.image_bytes, filename="rank_card.png")
94 | return card
95 |
96 | except Exception as e:
97 | print(f"[Custom Rank Card] {e}")
98 | raise e
99 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/Commands/talkchannels.py:
--------------------------------------------------------------------------------
1 | import discord
2 | from discord.ext import commands
3 | from ruamel.yaml import YAML
4 |
5 | import KumosLab.Database.get
6 | import KumosLab.Database.set
7 | import KumosLab.Database.add
8 |
9 | import vacefron
10 |
11 | yaml = YAML()
12 | with open("Configs/config.yml", "r", encoding="utf-8") as file:
13 | config = yaml.load(file)
14 |
15 |
16 | class talkchannel(commands.Cog):
17 | def __init__(self, client):
18 | self.client = client
19 |
20 | @commands.command(aliases=['tc'])
21 | async def talkchannel(self, ctx, case = None, channel: discord.TextChannel = None):
22 | if channel is None:
23 | embed = discord.Embed(description=f"🔴 **ERROR**: `Incorrect Usage - {config['Prefix']}tc <#channel>`")
24 | await ctx.reply(embed=embed)
25 | return
26 | if case is None:
27 | embed = discord.Embed(description=f"🔴 **ERROR**: `Incorrect Usage - {config['Prefix']}tc <#channel>`")
28 | await ctx.reply(embed=embed)
29 | return
30 | try:
31 | if case.lower() == "add":
32 | await KumosLab.Database.add.talkchannel(guild=ctx.guild, channel=channel)
33 | embed = discord.Embed(
34 | description=f"🟢 **SUCCESS**: `💭 Added Talk Channel: {channel}`")
35 | await ctx.reply(embed=embed)
36 | return
37 | elif case.lower() == "remove":
38 | await KumosLab.Database.remove.talkchannel(guild=ctx.guild, channel=channel)
39 | embed = discord.Embed(
40 | description=f"🟢 **SUCCESS**: `💭 Removed Talk Channel: {channel}`")
41 | await ctx.reply(embed=embed)
42 | return
43 | except Exception as e:
44 | print(f"[TalkChannel Command] {e}")
45 | embed = discord.Embed(description=f"🔴 **ERROR**: `Failed to add Talk Channel`")
46 | await ctx.reply(embed=embed)
47 | return
48 |
49 | @commands.command(aliases=['tcs'])
50 | async def talkchannels(self, ctx):
51 | try:
52 | channels = await KumosLab.Database.get.talkchannels(guild=ctx.guild)
53 | if channels is None or len(channels) == 0:
54 | embed = discord.Embed(description=f"💭: `You can gain XP anywhere!`")
55 | await ctx.reply(embed=embed)
56 | return
57 | else:
58 | channel_Array = []
59 | for channel in channels:
60 | channel_Array.append(channel)
61 | if channel_Array[0] is None:
62 | embed = discord.Embed(description=f"💭: `You can gain XP anywhere!`")
63 | await ctx.reply(embed=embed)
64 | return
65 | # convert channel id to channel object
66 | channel_List = []
67 | for x in channel_Array:
68 | channel = self.client.get_channel(int(x))
69 | channel_List.append(channel.name)
70 | embed = discord.Embed(description=f"💭: `You can gain XP in:`")
71 | embed.add_field(name="Talk Channels", value=f"`{channel_List}`".replace("[", "").replace("]", "").replace("'", "").replace(" ", ""))
72 | await ctx.reply(embed=embed)
73 | return
74 | except Exception as e:
75 | print(f"[TalkChannels Command] {e}")
76 | embed = discord.Embed(description=f"🔴 **ERROR**: `Failed to get Talk Channels`")
77 | await ctx.reply(embed=embed)
78 | return
79 |
80 | @commands.Cog.listener()
81 | async def on_guild_channel_delete(self, channel):
82 | try:
83 | channels = await KumosLab.Database.get.talkchannels(guild=channel.guild)
84 | if channel.id in channels:
85 | await KumosLab.Database.remove.talkchannel(guild=channel.guild, channel=channel)
86 | return
87 | except Exception as e:
88 | print(f"[TalkChannels Command] {e}")
89 | return
90 |
91 |
92 |
93 | def setup(client):
94 | client.add_cog(talkchannel(client))
95 |
--------------------------------------------------------------------------------
/KumosLab/Database/Create/RankCard/custom.py:
--------------------------------------------------------------------------------
1 | import discord
2 | from discord import File
3 | from easy_pil import Editor, load_image_async, Font, load_image
4 | from ruamel.yaml import YAML
5 | import Commands.rank
6 |
7 |
8 | import KumosLab.Database.get
9 |
10 |
11 | yaml = YAML()
12 | with open("Configs/config.yml", "r", encoding="utf-8") as file:
13 | config = yaml.load(file)
14 |
15 | def translate(num):
16 | num = float('{:.3g}'.format(num))
17 | magnitude = 0
18 | while abs(num) >= 1000:
19 | magnitude += 1
20 | num /= 1000.0
21 | return '{}{}'.format('{:f}'.format(num).rstrip('0').rstrip('.'), ['', 'K', 'M', 'B', 'T'][magnitude])
22 |
23 | async def generate(user: discord.Member = None, guild: discord.Guild = None):
24 | if guild is None:
25 | print("[Custom] Guild is None")
26 | return
27 | if user is None:
28 | print("[Custom] User is None")
29 | return
30 | try:
31 | xp = await KumosLab.Database.get.xp(user=user, guild=guild)
32 | level = 1
33 |
34 | rank_colour = await KumosLab.Database.get.colour(user=user, guild=guild)
35 |
36 | blur = await KumosLab.Database.get.blur(user=user, guild=guild)
37 |
38 | while True:
39 | if xp < ((config['xp_per_level'] / 2 * (level ** 2)) + (config['xp_per_level'] / 2 * level)):
40 | break
41 | level += 1
42 | xp -= ((config['xp_per_level'] / 2 * (level - 1) ** 2) + (config['xp_per_level'] / 2 * (level - 1)))
43 |
44 | next_level_xp = int(config['xp_per_level'] * 2 * ((1 / 2) * level))
45 |
46 | percentage = int((xp / next_level_xp) * 100)
47 |
48 | user_background = await KumosLab.Database.get.background(user=user, guild=guild)
49 | user_border = await KumosLab.Database.get.border(user=user, guild=guild)
50 |
51 | background_image = load_image(str(user_background))
52 | background = Editor(background_image).resize((1050, 300)).blur(amount=int(blur))
53 |
54 | user_ranking = await KumosLab.Database.get.rankings(user=user, guild=guild)
55 |
56 | profile_image = load_image(user.avatar_url)
57 | profile = Editor(profile_image).resize((200, 210))
58 | border_image = load_image(user_border)
59 | border = Editor(border_image).resize((210, 220))
60 |
61 |
62 | font_25 = Font.poppins(size=35, variant="bold")
63 | font_60_bold = Font.poppins(size=60, variant="bold")
64 | font_40_bold = Font.poppins(size=50, variant="bold")
65 |
66 | background.paste(border, (30, 40))
67 | background.paste(profile, (35, 45))
68 |
69 | if config['name_colour'] is True:
70 | background.text((260, 40), f"{user}", font=font_60_bold, color=rank_colour)
71 | background.text(
72 | (870, 190), f"#{translate(user_ranking)}", font=font_40_bold,
73 | color=rank_colour
74 | )
75 | else:
76 | background.text((250, 40), f"{user}",
77 | font=font_60_bold, color="white")
78 | background.text(
79 | (870, 190), f"#{await KumosLab.Database.get.rankings(user=user, guild=user.guild):,}", font=font_40_bold,
80 | color="white"
81 | )
82 | background.text((270, 150), f"Level: {level:,}", font=font_25, color="white")
83 |
84 | background.rectangle((260, 190), width=600, height=40, radius=20)
85 | if percentage > 5:
86 | background.bar(
87 | (260, 190),
88 | max_width=600,
89 | height=40,
90 | percentage=percentage,
91 | fill=rank_colour,
92 | radius=20,
93 | )
94 |
95 | background.text(
96 | (845, 145), f"{translate(xp)} / {translate(next_level_xp)}", font=font_25, color="white", align="right"
97 | )
98 |
99 | card = File(fp=background.image_bytes, filename="rank_card.png")
100 | return card
101 |
102 | except Exception as e:
103 | print(f"[Custom Rank Card] {e}")
104 | raise e
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/System/addonmanager.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import os
3 | from os import listdir
4 | import sys
5 |
6 | import discord
7 | from discord.ext import commands, tasks
8 | from ruamel import yaml
9 |
10 | import KumosLab.Database.get
11 |
12 |
13 | with open("Configs/config.yml", "r", encoding="utf-8") as file:
14 | config = yaml.load(file)
15 |
16 |
17 | class addonmanager(commands.Cog):
18 | def __init__(self, client):
19 | self.client = client
20 |
21 | @commands.command()
22 | async def addons(self, ctx):
23 | addons = []
24 | for file in listdir("Addons"):
25 | if file.endswith(".py"):
26 | addons.append(file.replace(".py", ""))
27 |
28 | if len(addons) == 0:
29 | embed = discord.Embed(title="Installed Addons", description="```No addons installed!```")
30 | await ctx.reply(embed=embed)
31 | else:
32 | embed = discord.Embed(title="Installed Addons", description=f"```{addons}```".replace("[", "").replace("]", "").replace("'", ""))
33 | await ctx.reply(embed=embed)
34 |
35 |
36 | @commands.command()
37 | async def addon(self, ctx, addon: str = None):
38 | if ctx.author.id == int(config['Bot_Owner']):
39 | if addon is None:
40 | embed = discord.Embed(title="📬 ADDON MANAGER")
41 | embed.add_field(name="📢 Vocal", value=f"`{config['Prefix']}addon vocal`", inline=False)
42 | embed.add_field(name="➕ Extras", value=f"`{config['Prefix']}addon extras`", inline=False)
43 | embed.add_field(name="👤 Status", value=f"`{config['Prefix']}addon status`", inline=False)
44 | await ctx.reply(embed=embed)
45 | else:
46 | if addon.title() not in ["Vocal", "Clan", "Extras", "Status", "Prestige"]:
47 | await ctx.reply("❌ **Addon not found**")
48 | else:
49 | link = "https://github.com/KumosLab/Discord-Levels-Bot.git"
50 | branch = addon.title()
51 |
52 | # git init into Downloads
53 | os.system(f"git init Downloads")
54 | os.system(f"cd Downloads && git remote add origin {link}")
55 | os.system(f"cd Downloads && git pull origin {branch}")
56 | os.system(f"cd Downloads && git checkout {branch}")
57 | os.system(f"cd Downloads && git pull")
58 |
59 |
60 |
61 |
62 | # get absolute path of Downloads
63 | path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "Downloads/Addons"))
64 | path2 = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "Downloads/Configs"))
65 | # get absolute path of addon folder
66 | addon_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "Addons"))
67 | # get absolute path of configs folder
68 | config_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "Configs"))
69 |
70 | # for files in path 1 move to addon_path
71 | for file in listdir(path):
72 | os.replace(os.path.join(path, file), os.path.join(addon_path, file))
73 |
74 | # for files in path 2 move to config_path
75 | for file in listdir(path2):
76 | os.replace(os.path.join(path2, file), os.path.join(config_path, file))
77 |
78 | await ctx.reply("`🟢` | Addon installed, starting addon...")
79 | for fn in listdir("Addons"):
80 | if fn.endswith(".py"):
81 | try:
82 | self.client.load_extension(f"Addons.{addon.title()}")
83 | await ctx.reply("`🟢` | Addon started")
84 | break
85 | except Exception as e:
86 | self.client.reload_extension(f"Addons.{addon.title()}")
87 | await ctx.reply("`🟢` | Addon started")
88 | break
89 |
90 |
91 | else:
92 | return
93 |
94 |
95 |
96 |
97 |
98 | def setup(client):
99 | client.add_cog(addonmanager(client))
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/System/user_check.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import functools
3 | import os
4 | import sqlite3
5 | import typing
6 |
7 | from discord.ext import commands
8 | from dotenv import load_dotenv
9 | from pymongo import MongoClient
10 | from ruamel.yaml import YAML
11 |
12 | yaml = YAML()
13 | with open("Configs/config.yml", "r", encoding="utf-8") as file:
14 | config = yaml.load(file)
15 |
16 | # Loads the .env file and gets the required information
17 | load_dotenv()
18 |
19 | if config['Database_Type'].lower() == 'mongodb':
20 | MONGODB_URI = os.environ['MONGODB_URI']
21 | COLLECTION = os.getenv("COLLECTION")
22 | DB_NAME = os.getenv("DATABASE_NAME")
23 | cluster = MongoClient(MONGODB_URI)
24 | levelling = cluster[COLLECTION][DB_NAME]
25 |
26 |
27 |
28 | class user_check(commands.Cog):
29 | def __init__(self, client):
30 | self.client = client
31 |
32 | async def check(self):
33 | # get database type from config file
34 | print(f"[User-Check] Checking for users & guilds...")
35 | db_type = config["Database_Type"]
36 | if db_type.lower() == "mongodb":
37 | for member in self.client.get_all_members():
38 | if not member.bot:
39 | if not levelling.find_one({"user_id": member.id, "guild_id": member.guild.id}):
40 | levelling.insert_one(
41 | {"guild_id": member.guild.id, "user_id": member.id, "name": str(member), "level": 1,
42 | "xp": 0,
43 | "background": config['Default_Background'], "xp_colour": config['Default_XP_Colour'],
44 | "blur": 0, "border": config['Default_Border']})
45 | print(f"[User-Check] Added {member.name} to MongoDB Database.")
46 | else:
47 | continue
48 | for guild in self.client.guilds:
49 | if not levelling.find_one({"guild": guild.id}):
50 | levelling.insert_one({"guild": guild.id, "main_channel": None, "admin_role": None, "roles": [],
51 | "role_levels": [], 'talkchannels': []})
52 | print(f"[User-Check] Added {guild.name} to MongoDB Database.")
53 | else:
54 | continue
55 | elif db_type.lower() == "local":
56 | for guild in self.client.guilds:
57 | db = sqlite3.connect("KumosLab/Database/Local/serverbase.sqlite")
58 | cursor = db.cursor()
59 | cursor.execute("SELECT * FROM levelling where guild_id = ?", (guild.id,))
60 | if cursor.fetchone() is None:
61 | sql = "INSERT INTO levelling (guild_id, admin_role, main_channel, talkchannels) VALUES (?, ?, ?, ?) "
62 | cursor.execute(sql, (guild.id, None, None, None))
63 | print(f"[User-Check] Added {guild.name} to SQLite Database.")
64 | db.commit()
65 | cursor.close()
66 | for member in guild.members:
67 | # check if member is a bot
68 | db = sqlite3.connect("KumosLab/Database/Local/userbase.sqlite")
69 | cursor = db.cursor()
70 | if not member.bot:
71 | cursor.execute("SELECT * FROM levelling WHERE user_id = ? AND guild_id = ?",
72 | (member.id, guild.id))
73 | result = cursor.fetchone()
74 | if result is None:
75 | sql = "INSERT INTO levelling (guild_id, user_id, name, level, xp, background, xp_colour, blur, border) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"
76 | val = (guild.id, member.id, str(member), 1, 0, config['Default_Background'],
77 | config['Default_XP_Colour'], 0, config['Default_Border'])
78 | cursor.execute(sql, val)
79 | print(f"[User-Check] Added {member.name} to SQLite Database.")
80 | db.commit()
81 | else:
82 | continue
83 |
84 |
85 |
86 | @commands.Cog.listener()
87 | async def on_ready(self):
88 | await self.client.wait_until_ready()
89 | if config['loader_type'].lower() == 'startup':
90 | await user_check.check(self)
91 |
92 |
93 |
94 | def setup(client):
95 | client.add_cog(user_check(client))
96 |
--------------------------------------------------------------------------------
/KumosLab/Database/check.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sqlite3
3 |
4 | import discord
5 | from pymongo import MongoClient
6 | from ruamel import yaml\
7 |
8 | import numpy as np
9 | from discord import File
10 |
11 | from easy_pil import Editor, load_image_async, Font, load_image
12 | import KumosLab.Database.add
13 | import KumosLab.Database.get
14 | import KumosLab.Database.set
15 | import KumosLab.Database.remove
16 |
17 | with open("Configs/config.yml", "r", encoding="utf-8") as file:
18 | config = yaml.load(file)
19 |
20 | def translate(num):
21 | num = float('{:.3g}'.format(num))
22 | magnitude = 0
23 | while abs(num) >= 1000:
24 | magnitude += 1
25 | num /= 1000.0
26 | return '{}{}'.format('{:f}'.format(num).rstrip('0').rstrip('.'), ['', 'K', 'M', 'B', 'T'][magnitude])
27 |
28 | async def levelUp(user: discord.Member = None, guild: discord.Guild = None):
29 | if user is None:
30 | print("Error in 'KumosLab/Database/check.py' - User is None for 'levelUp'")
31 | return
32 | if guild is None:
33 | print("Error in 'KumosLab/Database/check.py' - Guild is None for 'levelUp'")
34 | return
35 |
36 | try:
37 | user_xp = await KumosLab.Database.get.xp(user=user, guild=guild)
38 | lvl = 0
39 |
40 | while True:
41 | if user_xp < ((config['xp_per_level'] / 2 * (lvl ** 2)) + (config['xp_per_level'] / 2 * lvl)):
42 | break
43 | lvl += 1
44 | user_xp -= ((config['xp_per_level'] / 2 * ((lvl - 1) ** 2)) + (config['xp_per_level'] / 2 * (lvl - 1)))
45 | if await KumosLab.Database.get.level(user=user, guild=guild) != lvl:
46 | await KumosLab.Database.set.level(user=user, guild=guild, amount=lvl)
47 |
48 | background_image = load_image(config['level_up_background'])
49 | background = Editor(background_image).resize((900, 270)).blur(amount=config['level_up_blur'])
50 | profile_image = load_image(str(user.avatar_url))
51 | profile = Editor(profile_image).resize((200, 200)).circle_image()
52 |
53 | poppins_big = Font.poppins(variant="bold", size=50)
54 | poppins_mediam = Font.poppins(variant="bold", size=40)
55 | poppins_regular = Font.poppins(variant="regular", size=30)
56 |
57 | card_left_shape = [(0, 0), (0, 270), (330, 270), (260, 0)]
58 |
59 | background.polygon(card_left_shape, "#2C2F33")
60 | border_image = load_image(await KumosLab.Database.get.border(user=user, guild=guild))
61 | border = Editor(border_image).resize((210, 210)).circle_image()
62 | background.paste(border, (40, 30))
63 | background.paste(profile, (45, 35))
64 |
65 | background.text((600, 30), "LEVEL UP!", font=poppins_big, color="white", align="center")
66 | background.text(
67 | (600, 80), str(user), font=poppins_regular, color="white", align="center"
68 | )
69 | background.text(
70 | (600, 130), f"LEVEL {lvl:,}", font=poppins_mediam, color="white", align="center"
71 | )
72 | background.text(
73 | (600, 170), f"{translate(user_xp)}/{translate(int(config['xp_per_level'] * 2 * ((1 / 2) * lvl)))} XP",
74 | font=poppins_regular, color="white", align="center"
75 | )
76 |
77 | embed = discord.Embed()
78 |
79 | member = user
80 | if await KumosLab.Database.get.mainChannel(guild=guild) is None:
81 | channel = guild.system_channel
82 | else:
83 | channel = discord.utils.get(member.guild.channels,
84 | name=await KumosLab.Database.get.mainChannel(guild=member.guild))
85 | if channel is None:
86 | return
87 | if config['level_up_ping'] is True:
88 | await channel.send(f"{user.mention},")
89 |
90 | level_roles = np.asarray(await KumosLab.Database.get.roles(guild=guild))
91 | level_roles_num = np.asarray(await KumosLab.Database.get.roleLevel(guild=guild))
92 |
93 | for i in range(len(level_roles)):
94 | if lvl == int(level_roles_num[i]):
95 | await user.add_roles(
96 | discord.utils.get(user.guild.roles, name=level_roles[i]))
97 | background.text(
98 | (620, 225),
99 | f"ROLE UNLOCKED - {level_roles[i]}".replace("[", "").replace("]", "").replace("'", ''),
100 | font=poppins_regular,
101 | color="white",
102 | align="center",
103 | )
104 |
105 | # remove the previous role
106 | if i > 0:
107 | await user.remove_roles(
108 | discord.utils.get(user.guild.roles, name=level_roles[i - 1]))
109 | else:
110 | continue
111 |
112 | card = File(fp=background.image_bytes, filename="level_card.png")
113 | embed.set_image(url="attachment://level_card.png")
114 | await channel.send(file=card, embed=embed)
115 | except Exception as e:
116 | print(f"Error in 'KumosLab/Database/check.py' - {e}")
--------------------------------------------------------------------------------
/Commands/role.py:
--------------------------------------------------------------------------------
1 | import discord
2 | import numpy as np
3 | from discord.ext import commands
4 | from ruamel.yaml import YAML
5 |
6 | import KumosLab.Database.get
7 | import KumosLab.Database.set
8 | import KumosLab.Database.add
9 | import KumosLab.Database.remove
10 |
11 | from discord.ext.commands import RoleNotFound
12 |
13 | import vacefron
14 |
15 | yaml = YAML()
16 | with open("Configs/config.yml", "r", encoding="utf-8") as file:
17 | config = yaml.load(file)
18 |
19 |
20 |
21 | # Roles Class
22 | class role(commands.Cog):
23 | def __init__(self, client):
24 | self.client = client
25 |
26 | # Role Command
27 | @commands.command()
28 | async def role(self, ctx, state: str = None, role_name: discord.Role = None, role_level: int = None):
29 | if state is None:
30 | embed = discord.Embed(description=f"🔴 **ERROR**: `You must define add or remove! - {config['Prefix']}role `")
31 | await ctx.reply(embed=embed)
32 | return
33 | if role is None:
34 | embed = discord.Embed(description=f"🔴 **ERROR**: `You must define a role! - {config['Prefix']}role `")
35 | await ctx.send(embed=embed)
36 | return
37 | if role_level is None:
38 | embed = discord.Embed(description=f"🔴 **ERROR**: `You must define a role level! - {config['Prefix']}role `")
39 | await ctx.send(embed=embed)
40 | return
41 | try:
42 | if state.lower() == "add":
43 | exists = await KumosLab.Database.add.role(guild=ctx.guild, role_name=role_name, role_level=int(role_level))
44 | if exists == "error":
45 | embed = discord.Embed(description=f"🔴 **ERROR**: `Role already exists! - {config['Prefix']}role `")
46 | await ctx.reply(embed=embed)
47 | return
48 | else:
49 | embed = discord.Embed(description=f"🟢 **SUCCESS**: `Added {role_name} to unlock at Level {role_level}`")
50 | await ctx.reply(embed=embed)
51 | elif state.lower() == "remove":
52 | await KumosLab.Database.remove.role(guild=ctx.guild, role_name=role_name, role_level=int(role_level))
53 | embed = discord.Embed(
54 | description=f"🟢 **SUCCESS**: `Removed {role_name} from the Database!`")
55 | await ctx.reply(embed=embed)
56 |
57 | except RoleNotFound as e:
58 | embed = discord.Embed(description=f"🔴 **ERROR**: `Role not found! - {config['Prefix']}role `")
59 | await ctx.send(embed=embed)
60 | return
61 |
62 | # Role List Command
63 | @commands.command()
64 | async def roles(self, ctx):
65 | embed = discord.Embed(title="🔓 // LEVEL ROLES", description=f"**Level Roles for** `{ctx.guild.name}`")
66 | role_array = np.asarray(await KumosLab.Database.get.roles(guild=ctx.guild))
67 | role_level_array = np.asarray(await KumosLab.Database.get.roleLevel(guild=ctx.guild))
68 | if role_array is None or role_level_array is None:
69 | embed.add_field(name="Roles:", value="`There are no roles to unlock!`")
70 | embed.add_field(name="Level:", value="`No level required!`")
71 | return
72 | else:
73 | embed.add_field(name="Roles:", value=f"`{str(role_array).replace('[', '').replace(']', '')}`")
74 | embed.add_field(name="Level:", value=f"`{str(role_level_array).replace('[', '').replace(']', '')}`", inline=False)
75 | await ctx.send(embed=embed)
76 |
77 | @commands.command()
78 | async def creator(self, ctx, amount: int = None, prefix: str = None):
79 | if amount is None:
80 | embed = discord.Embed(description=f"🔴 **ERROR**: `You must define a amount! - {config['Prefix']}creator `")
81 | await ctx.reply(embed=embed)
82 | return
83 | if prefix is None:
84 | embed = discord.Embed(description=f"🔴 **ERROR**: `You must define a role-prefix! - {config['Prefix']}creator `")
85 | await ctx.reply(embed=embed)
86 | return
87 | if amount > 50 or amount < 1:
88 | embed = discord.Embed(description=f"🔴 **ERROR**: `You can only create 50 roles at a time! - {config['Prefix']}creator `")
89 | await ctx.reply(embed=embed)
90 | return
91 | if len(prefix) > 10 or len(prefix) < 1:
92 | embed = discord.Embed(description=f"🔴 **ERROR**: `You can only create a prefix with 10 characters! - {config['Prefix']}creator `")
93 | await ctx.reply(embed=embed)
94 | return
95 | # loop amount of times
96 | message = await ctx.send(f"🔓 **CREATING ROLES**: `Creating {amount} roles with prefix {prefix}. Please wait, this may take some time...`")
97 | for i in range(amount):
98 | # create role
99 | role = await ctx.guild.create_role(name=f"{prefix} {i + 1}")
100 | # add role to database
101 | await KumosLab.Database.add.role(guild=ctx.guild, role_name=role, role_level=i + 1)
102 |
103 | await message.edit(content=f"🔓 **CREATING ROLES**: `Created {amount} roles with prefix {prefix}.`")
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 | # Sets-up the cog for roles
116 | def setup(client):
117 | client.add_cog(role(client))
118 |
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | # Imports
2 | import sqlite3
3 | from os import listdir
4 |
5 | import ruamel.yaml.error
6 | from discord.ext import commands, ipc
7 | from discord.ext.commands import CommandNotFound, RoleNotFound, MemberNotFound
8 | import discord
9 | from ruamel.yaml import YAML
10 | import logging
11 | import os
12 | from dotenv import load_dotenv
13 | import warnings
14 | import pyfiglet
15 |
16 |
17 | load_dotenv()
18 |
19 | class client(commands.Bot):
20 | def __init__(self, *args, **kwargs):
21 | super().__init__(*args, **kwargs)
22 |
23 | self.ipc = ipc.Server(self, secret_key="ModernLevels")
24 |
25 | async def on_ipc_error(self, endpoint, error):
26 | print(f"IPC Error: {endpoint} raised {error}")
27 |
28 |
29 | # Opens the config and reads it, no need for changes unless you'd like to change the library (no need to do so unless having issues with ruamel)
30 | yaml = YAML()
31 | with open("Configs/config.yml", "r", encoding="utf-8") as file:
32 | config = yaml.load(file)
33 |
34 | warnings.simplefilter('ignore', ruamel.yaml.error.UnsafeLoaderWarning)
35 |
36 | # Command Prefix + Removes the default discord.py help command
37 | Client = client(command_prefix=commands.when_mentioned_or(config['Prefix']), intents=discord.Intents.all(), case_insensitive=True)
38 | Client.remove_command('help')
39 |
40 | # sends discord logging files which could potentially be useful for catching errors.
41 | os.close(os.open("Logs/logs.txt", os.O_CREAT))
42 | os.truncate("Logs/logs.txt", 1)
43 | FORMAT = '[%(asctime)s]:[%(levelname)s]: %(message)s'
44 | logging.basicConfig(filename='Logs/logs.txt', level=logging.DEBUG, format=FORMAT)
45 | logging.debug('Begin Logging')
46 | logging.info('Getting ready to login to Discord...')
47 |
48 |
49 | @Client.event # On Bot Startup, Will send some details about the bot and sets it's activity and status. Feel free to remove the print messages, but keep everything else.
50 | async def on_ready():
51 | if config['Database_Type'].lower() == 'local':
52 | print("Connecting to KumosLab/Database/Local/userbase.sqlite")
53 | db = sqlite3.connect('KumosLab/Database/Local/userbase.sqlite')
54 | cursor = db.cursor()
55 | cursor.execute("""CREATE TABLE IF NOT EXISTS levelling(
56 | user_id INTEGER,
57 | name TEXT,
58 | guild_id TEXT,
59 | level INTEGER,
60 | xp INTEGER,
61 | background TEXT,
62 | xp_colour TEXT,
63 | blur INTEGER,
64 | border TEXT
65 | )""")
66 | cursor.close()
67 | print("Connecting to KumosLab/Database/Local/serverbase.sqlite")
68 | db = sqlite3.connect('KumosLab/Database/Local/serverbase.sqlite')
69 | cursor = db.cursor()
70 | cursor.execute("""CREATE TABLE IF NOT EXISTS levelling(
71 | guild_id TEXT,
72 | admin_role TEXT,
73 | main_channel TEXT,
74 | talkchannels TEXT)""")
75 | cursor.close()
76 | print("Connecting to KumosLab/Database/Local/roles.sqlite")
77 | db = sqlite3.connect('KumosLab/Database/Local/roles.sqlite')
78 | cursor = db.cursor()
79 | cursor.execute("""CREATE TABLE IF NOT EXISTS levelling(
80 | guild_id TEXT,
81 | role TEXT,
82 | role_levels INTEGER
83 | )""")
84 | cursor.close()
85 |
86 | ascii_banner = pyfiglet.figlet_format("MODERN LEVELS")
87 | print(ascii_banner)
88 |
89 | print("Thank you for downloading Modern Levels 2.0 <3 \nIf you run into any issues, want to suggest a feature or "
90 | "want "
91 | "a place to hang out, join the Discord! discord.gg/UgvTHmuyNK\n")
92 | print('Logged In As:')
93 | print(f"Username: {Client.user.name}\nID: {Client.user.id}")
94 | print(f'Database Type: {str(config["Database_Type"]).title()}')
95 |
96 | @Client.event
97 | async def on_command_error(ctx, error):
98 | if isinstance(error, CommandNotFound):
99 | return
100 | if isinstance(error, RoleNotFound):
101 | embed = discord.Embed(
102 | description=f"🔴 **ERROR**: `Role not found! - {config['Prefix']}role `")
103 | await ctx.send(embed=embed)
104 | return
105 | if isinstance(error, MemberNotFound):
106 | embed = discord.Embed(
107 | description=f"🔴 **ERROR**: `Member not found!`")
108 | await ctx.send(embed=embed)
109 | return
110 | raise error
111 |
112 | logging.info("------------- Loading -------------")
113 | for fn in listdir("Commands"):
114 | if fn.endswith(".py"):
115 | logging.info(f"Loading: {fn}")
116 | Client.load_extension(f"Commands.{fn[:-3]}")
117 | logging.info(f"Loaded {fn}")
118 |
119 | for fn in listdir("Addons"):
120 | if fn.endswith(".py"):
121 | logging.info(f"Loading: {fn} Addon")
122 | Client.load_extension(f"Addons.{fn[:-3]}")
123 | logging.info(f"Loaded {fn} Addon")
124 |
125 | for fn in listdir("System"):
126 | if fn.endswith(".py"):
127 | logging.info(f"Loading: {fn} System")
128 | Client.load_extension(f"System.{fn[:-3]}")
129 | logging.info(f"Loaded {fn} System")
130 | logging.info("------------- Finished Loading -------------")
131 |
132 | # Uses the bot token to login, so don't remove this.
133 | token = os.getenv("DISCORD_TOKEN")
134 | Client.ipc.start()
135 | Client.run(token)
136 |
137 |
138 | # End Of Main
--------------------------------------------------------------------------------
/Configs/config.yml:
--------------------------------------------------------------------------------
1 | # ======================================================================================
2 | # WELCOME TO THE CONFIG
3 | # FOR
4 | # MODERN LEVELS 2.0
5 | # ======================================================================================
6 |
7 | # NOTE: BOT_TOKEN DETAILS ARE STORED IN THE .env FILE!
8 | # The prefix for the bots commands
9 | Prefix: "!"
10 |
11 | # Determines the database type to use. Note: MongoDB requires the details to be stored inside the .env file! **Note: Local is recommended**
12 | # MongoDB / Local
13 | Database_Type: "mongodb"
14 |
15 | # Member ID of the bot owner (In most cases, whoever is reading this sentence right now AKA you.) **YOU WILL RECEIVE ERRORS IF THIS IS NOT FILLED**
16 | Bot_Owner: "512760269764820993"
17 |
18 | # How the bot adds users to the database when the bot starts
19 | # startup - Adds all missing users to the database when the bot starts (Recommended for those with smaller member amounts - Not great performance for large servers)
20 | # message - Adds users to the database once they send a message (Recommended for those with any member amounts - Better performance for large servers)
21 | loader_type: "message"
22 |
23 | # The default background for each user when they get added to the database || Please do not leave this as nothing!! If you get errors, it means the url is invalid.
24 | # I recommend using imgur to get the link for your background.
25 | Default_Background: "https://coolbackgrounds.io/images/backgrounds/black/pure-black-background-f82588d3.jpg"
26 |
27 | # Default XP Colour for each user when they get added to the database
28 | Default_XP_Colour: "#ffffff"
29 |
30 | # The default border for the users profile picture on the rank card **ONLY IF THE RANK GENERATOR IS CUSTOM!!**
31 | Default_Border: "https://coolbackgrounds.io/images/backgrounds/black/pure-black-background-f82588d3.jpg"
32 |
33 | # Enables / Disables the help command (true = enabled, false = disabled)
34 | help_command: True
35 |
36 | # Notifies the bot owner when a new version is released (Bot_Owner must be filled)
37 | update_notify: True
38 |
39 | # If XP Chance is enabled or disabled (true = enabled, false = disabled)
40 | XP_Chance: True
41 |
42 | # Chance to earn XP when a user sends a message (Chance Rate, 1 to x) - If number = x, user gains xp
43 | XP_Chance_Rate: 2
44 |
45 |
46 | # ======================================================================================
47 | # XP
48 | # ======================================================================================
49 |
50 | # XP Type 'words' = User xp increases by how many words were said,
51 | # 'ranrange' = User xp increases by a random number between the min and max
52 | # 'normal' = User xp increases by set value
53 | xp_type: 'ranrange'
54 |
55 | # The amount of xp a user gets when they send a message -- This is only used if the xp_type is set to 'normal'
56 | xp_normal_amount: 10
57 |
58 | # The minimum amount of xp a user can gain -- This is only used if the xp_type is set to 'ranrange'
59 | xp_ranrange_min: 5
60 |
61 | # The maximum amount of xp a user can gain -- This is only used if the xp_type is set to 'ranrange'
62 | xp_ranrange_max: 50
63 |
64 | # How much XP is required per level (e.g - xp_per_level: 10 = Level 1 would require 10 xp to level up. Level 2 would require 20 xp to level up)
65 | xp_per_level: 100
66 |
67 |
68 | # ======================================================================================
69 | # LEADERBOARD
70 | # ======================================================================================
71 |
72 | # Set aliases for the leaderboard command
73 | leaderboard_alias: ['lb', 'leader', 'rankings']
74 |
75 |
76 | # ======================================================================================
77 | # RANK
78 | # ======================================================================================
79 | # Sets aliases for the rank command **DO NOT ADD 'RANK' AS AN ALIAS, RANK IS THE MAIN NAME FOR THE COMMAND!**
80 | rank_alias: ['r', 'level', 'l', 'stats', 'xp', 'progress']
81 |
82 | # Sends a ping to the user that levelled up
83 | level_up_ping: True
84 |
85 | # The background image for the level up card
86 | level_up_background: "https://wallpaperaccess.com/full/4956346.jpg"
87 |
88 | # The amount of blur on the background image for the level up card
89 | level_up_blur: 10
90 |
91 | # RankCard Generator (Vacefron, Custom, Text)
92 | # 'Vacefron' - Uses the Vacefron rank card generator (The API may go down occasionally, or you can be rate limited) 1050 x 300
93 | # 'Custom' - Uses the custom rank card generator (Will never go down / be rate limited) - 1050 x 240 - Can be most resource intensive at times
94 | # 'Text' - Uses the text rank card generator (Will never go down / be rate limited) - Most resource light
95 | rank_generator: 'custom'
96 |
97 | # If the rank generator is set to custom, the name of the user on the rank card is the colour of the users xp colour **ONLY IF RANK GENERATOR IS CUSTOM!!**
98 | name_colour: True
99 |
100 |
101 | # ======================================================================================
102 | # EMBED
103 | # ======================================================================================
104 |
105 |
106 | # Note Below these have not been fully implemented, in 2.0.1, they will be!
107 |
108 | # Rank Embed Colour | Must Be Hex Notation
109 | rank_embed_colour: 0x4863A0
110 |
111 | # Leaderboard Embed Colour | Must Be Hex Notation (Replace # with 0x)
112 | leaderboard_embed_colour: 0xffffff
113 |
114 | # Embed Colour | Must Be Hex Notation
115 | embed_colour: 0xffffff
116 |
117 | # Error Embed Colour | Must Be Hex Notation
118 | error_embed_colour: 0x4863A0
119 |
120 | # Success Embed Colour | Must Be Hex Notation
121 | success_embed_colour: 0x4863A0
122 |
123 |
124 | # ======================================================================================
125 | # THE END
126 | # ======================================================================================
127 |
--------------------------------------------------------------------------------
/KumosLab/Database/remove.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sqlite3
3 |
4 | import discord
5 | from pymongo import MongoClient
6 | from ruamel import yaml
7 |
8 | with open("Configs/config.yml", "r", encoding="utf-8") as file:
9 | config = yaml.load(file)
10 |
11 |
12 | if config['Database_Type'].lower() == 'mongodb':
13 | MONGODB_URI = os.environ['MONGODB_URI']
14 | COLLECTION = os.getenv("COLLECTION")
15 | DB_NAME = os.getenv("DATABASE_NAME")
16 | cluster = MongoClient(MONGODB_URI)
17 | levelling = cluster[COLLECTION][DB_NAME]
18 |
19 | async def xp(user: discord.Member = None, guild: discord.Guild = None, amount=None):
20 | if user is None:
21 | print("Error in 'KumosLab/Database/remove.py' - User is None for 'xp'")
22 | return
23 | if guild is None:
24 | print("Error in 'KumosLab/Database/remove.py' - Guild is None for 'xp'")
25 | return
26 | if amount is None:
27 | print("Error in 'KumosLab/Database/remove.py' - Amount is None for 'xp'")
28 | return
29 | try:
30 | if config['Database_Type'].lower() == "mongodb":
31 | user_search = levelling.find_one({'user_id': user.id, 'guild_id': guild.id})
32 | if user_search is None:
33 | print("User Not Found!")
34 | return
35 | # add xp
36 | levelling.update_one({'user_id': user.id, 'guild_id': guild.id}, {'$inc': {'xp': - amount}})
37 | return
38 | elif config['Database_Type'].lower() == "local":
39 | db = sqlite3.connect("KumosLab/Database/Local/userbase.sqlite")
40 | cursor = db.cursor()
41 | cursor.execute("SELECT xp FROM levelling WHERE user_id = ? AND guild_id = ?", (user.id, guild.id))
42 | result = cursor.fetchone()
43 | if result is None:
44 | print("User Not Found!")
45 | return
46 | # add xp
47 | cursor.execute("UPDATE levelling SET xp = xp - ? WHERE user_id = ? AND guild_id = ?", (amount, user.id, guild.id))
48 | db.commit()
49 | cursor.close()
50 | return
51 | except Exception as e:
52 | print("Error in 'KumosLab/Database/remove.py' - " + str(e))
53 | return
54 |
55 | async def level(user: discord.Member = None, guild: discord.Guild = None, amount=None):
56 | if user is None:
57 | print("Error in 'KumosLab/Database/remove.py' - User is None for 'level'")
58 | return
59 | if guild is None:
60 | print("Error in 'KumosLab/Database/remove.py' - Guild is None for 'level'")
61 | return
62 | if amount is None:
63 | print("Error in 'KumosLab/Database/remove.py' - Amount is None for 'level'")
64 | return
65 | try:
66 | if config['Database_Type'].lower() == "mongodb":
67 | member = levelling.find_one({'user_id': user.id, 'guild': guild.id})
68 | if member is None:
69 | print("User Not Found!")
70 | return
71 | # add level
72 | levelling.update_one({'user_id': user.id, 'guild_id': guild.id}, {'$inc': {'level': - amount}})
73 | return
74 | elif config['Database_Type'].lower() == "local":
75 | db = sqlite3.connect("KumosLab/Database/Local/userbase.sqlite")
76 | cursor = db.cursor()
77 | cursor.execute("SELECT level FROM levelling WHERE user_id = ? AND guild_id = ?", (user.id, guild.id))
78 | result = cursor.fetchone()
79 | if result is None:
80 | print("User Not Found!")
81 | return
82 | # add level
83 | cursor.execute("UPDATE levelling SET level = level - ? WHERE user_id = ? AND guild_id = ?", (amount, user.id, guild.id))
84 | db.commit()
85 | cursor.close()
86 | return
87 | except Exception as e:
88 | print("Error in 'KumosLab/Database/remove.py' - " + str(e))
89 | return
90 |
91 | async def role(guild: discord.Guild = None, role_name: discord.Role = None, role_level: int = None):
92 | if guild is None:
93 | print("Error in 'KumosLab/Database/remove.py' - Guild is None for 'role'")
94 | return
95 | if role is None:
96 | print("Error in 'KumosLab/Database/remove.py' - Role is None for 'role'")
97 | return
98 | if role_level is None:
99 | print("Error in 'KumosLab/Database/remove.py' - Role_Level is None for 'role'")
100 | return
101 | try:
102 | if config['Database_Type'].lower() == "mongodb":
103 | # add role
104 | levelling.update_one({'guild': guild.id}, {'$pull': {'roles': role_name.name, 'role_levels': int(role_level)}})
105 | return
106 | elif config['Database_Type'].lower() == "local":
107 | db = sqlite3.connect("KumosLab/Database/Local/roles.sqlite")
108 | cursor = db.cursor()
109 | # delete guild, role and level
110 | cursor.execute("DELETE FROM levelling WHERE guild_id = ? AND role = ? AND role_levels = ?", (guild.id, role_name.name, role_level))
111 | db.commit()
112 | cursor.close()
113 | return
114 | except Exception as e:
115 | print("Error in 'KumosLab/Database/remove.py' - " + str(e))
116 | return
117 |
118 | async def talkchannel(guild: discord.Guild = None, channel: discord.TextChannel = None):
119 | if guild is None:
120 | print("Error in 'KumosLab/Database/add.py' - Guild is None for 'talkchannel'")
121 | return
122 | if channel is None:
123 | print("Error in 'KumosLab/Database/add.py' - channel is None for 'talkchannel'")
124 | return
125 | try:
126 | if config['Database_Type'].lower() == "mongodb":
127 | # find if role is already in database
128 | talk_db = levelling.find_one({'guild': guild.id, 'talkchannels': channel.id})
129 | if talk_db is None:
130 | return "error"
131 | levelling.update_one({'guild': guild.id}, {'$pull': {'talkchannels': channel.id}})
132 | return
133 | elif config['Database_Type'].lower() == "local":
134 | db = sqlite3.connect("KumosLab/Database/Local/serverbase.sqlite")
135 | cursor = db.cursor()
136 | # set talkchannels to none
137 | cursor.execute("UPDATE levelling SET talkchannels = ? WHERE guild_id = ?", (None, guild.id))
138 | db.commit()
139 | cursor.close()
140 | return
141 | except Exception as e:
142 | print("Error in 'KumosLab/Database/remove.py' - " + str(e))
143 | return
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
--------------------------------------------------------------------------------
/Commands/help.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 |
3 | import discord
4 | from discord.ext import commands
5 | from ruamel.yaml import YAML
6 | import KumosLab.Database.get
7 | import KumosLab.Database.set
8 |
9 | import os
10 |
11 | yaml = YAML()
12 | with open("Configs/config.yml", "r", encoding="utf-8") as file:
13 | config = yaml.load(file)
14 |
15 | # Help Class
16 | class helpcommand(commands.Cog):
17 | def __init__(self, client):
18 | self.client = client
19 |
20 | @commands.command()
21 | async def help(self, ctx, value: str = None):
22 | try:
23 | prefix = config["Prefix"]
24 | if config['help_command'] is True:
25 | if value is None:
26 | embed = discord.Embed(
27 | title=f"{self.client.user.name}'s Command List")
28 | embed.set_thumbnail(url=self.client.user.avatar_url)
29 | embed.add_field(name="📷 Profile", value=f"`Profile Customisation`")
30 | embed.add_field(name="😃 Fun", value=f"`Fun Commands`")
31 | if ctx.author.guild_permissions.administrator:
32 | embed.add_field(name="🔧 Admin", value=f"`Admin Commands`")
33 | if ctx.author.id == int(config["Bot_Owner"]):
34 | embed.add_field(name="💼 Owner", value=f"`Owner Commands`")
35 | if os.path.isfile("Addons/Extras.py"):
36 | embed.add_field(name="🔗 Extras", value=f"`Extra Commands`")
37 |
38 | msg = await ctx.reply(embed=embed)
39 | await msg.add_reaction("📷")
40 | await msg.add_reaction("😃")
41 | if ctx.author.id == int(config["Bot_Owner"]):
42 | await msg.add_reaction("💼")
43 | if ctx.author.guild_permissions.administrator:
44 | await msg.add_reaction("🔧")
45 | if os.path.isfile("Addons/Extras.py"):
46 | await msg.add_reaction("🔗")
47 |
48 | def check(reaction, user):
49 | return user == ctx.author and reaction.message.id == msg.id
50 |
51 | try:
52 | reaction, user = await self.client.wait_for('reaction_add', timeout=60.0, check=check)
53 | if reaction.emoji == "📷":
54 | # remove all reactions
55 | await msg.clear_reactions()
56 | embed = discord.Embed(title="📷 Profile Commands", description="```background, setblur, setcolour, setborder```")
57 | embed.add_field(name="Examples:", value=f"```🖼️ {prefix}background - Changes your Rank Card background\n"
58 | f"⚪ {prefix}setcolour <#hex|random> - Sets your XP Bar to the chosen HEX code\n"
59 | f"👁️ {prefix}setblur - Blurs your Rank Cards background\n"
60 | f"🖼️ {prefix}setborder - Changes your Rank Cards profile picture border```")
61 | await msg.edit(embed=embed)
62 | elif reaction.emoji == "🔧":
63 | # remove all reactions
64 | await msg.clear_reactions()
65 | embed = discord.Embed(title="🔧 Admin Commands", description="```role, mainchannel, talkchannel, creator```")
66 | embed.add_field(name="Examples:", value=f"```🔨 {prefix}role <@role> - Adds or removes a role from being unlocked at a certain level\n"
67 | f"📢 {prefix}mainchannel <@channel> - Sets the main channel for level up and other sorts\n"
68 | f"🗣️ {prefix}talkchannel <@channel> - Adds or removes a channel that allows xp gain\n"
69 | f"🔧 {prefix}creator - Auto-create roles for the amount and adds to database```")
70 | await msg.edit(embed=embed)
71 |
72 | elif reaction.emoji == "💼":
73 | # remove all reactions
74 | await msg.clear_reactions()
75 | embed = discord.Embed(title="💼 Owner Commands", description="```addon, addons```")
76 | embed.add_field(name="Examples:", value=f"```🔨 {prefix}addon - Installs an addon\n"
77 | f"🔨 {prefix}addons - Lists all installed addons```")
78 | await msg.edit(embed=embed)
79 | elif reaction.emoji == "😃":
80 | # remove all reactions
81 | await msg.clear_reactions()
82 | embed = discord.Embed(title="😃 Fun Commands", description="```rank, leaderboard, roles, talkchannels```")
83 | embed.add_field(name="Examples:", value=f"```🏆 {prefix}rank <@user> - Displays the users Rank Card\n"
84 | f"📊 {prefix}leaderboard - Displays the rankings of all users in the guild or global\n"
85 | f"🔒 {prefix}roles - Displays all the roles you can unlock for levelling up\n"
86 | f"🗣️ {prefix}talkchannels - Displays all the channels that allow xp gain```")
87 | await msg.edit(embed=embed)
88 | elif reaction.emoji == "🔗":
89 | # remove all reactions
90 | await msg.clear_reactions()
91 | embed = discord.Embed(title="🔗 Extras", description="```addxp, removexp```")
92 | embed.add_field(name="Examples:", value=f"```🔧 {prefix}addxp <@user> - Adds XP to a user\n"
93 | f"🔧 {prefix}removexp <@user> - Removes XP from a user```")
94 | await msg.edit(embed=embed)
95 |
96 |
97 |
98 |
99 | except asyncio.TimeoutError:
100 | await msg.delete()
101 |
102 |
103 | except Exception as e:
104 | print(f"[Help Command] {e}")
105 |
106 |
107 |
108 | # Sets-up the cog for help
109 | def setup(client):
110 | client.add_cog(helpcommand(client))
--------------------------------------------------------------------------------
/KumosLab/Database/Create/Leaderboard/Local/leaderboard.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import sqlite3
3 |
4 | import discord
5 | from discord.ext import commands
6 | from ruamel.yaml import YAML
7 | import KumosLab.Database.conversion as conversion
8 |
9 |
10 | yaml = YAML()
11 | with open("Configs/config.yml", "r", encoding="utf-8") as file:
12 | config = yaml.load(file)
13 |
14 | async def leaderboard(self=None, ctx=None, guild=None, leader_type=None):
15 | if self is None:
16 | print("[Leaderboard-Local] Self is None")
17 | return
18 | if ctx is None:
19 | print("[Leaderboard-Local] Context is None")
20 | return
21 | if guild is None:
22 | print("[Leaderboard-Local] Guild is None")
23 | return
24 | if leader_type is None:
25 | print("[Leaderboard-Local] Type is None")
26 | return
27 | db = sqlite3.connect("KumosLab/Database/Local/userbase.sqlite")
28 | cursor = db.cursor()
29 | # sort by xp desc
30 | if leader_type.lower() == "local":
31 | cursor.execute(
32 | "SELECT * FROM levelling WHERE guild_id = ? ORDER BY xp DESC", (guild.id,))
33 | result = cursor.fetchall()
34 | embed = discord.Embed(title=f":trophy: {guild}'s Leaderboard", colour=config['leaderboard_embed_colour'])
35 | else:
36 | cursor.execute("SELECT * FROM levelling ORDER BY xp DESC")
37 | result = cursor.fetchall()
38 | embed = discord.Embed(title=f"🌎 Global Leaderboard", colour=config['leaderboard_embed_colour'])
39 | if result is None:
40 | return "Server Not Found!"
41 |
42 | users = []
43 | level = []
44 | xp = []
45 | guild = []
46 |
47 | for x in result:
48 | users.append(x[1])
49 | level.append(x[3])
50 | xp.append(x[4])
51 | guild_obj = self.client.get_guild(x[2])
52 | guild.append(guild_obj.name)
53 |
54 | pagination = list(zip(users, level, xp, guild))
55 | pages = [pagination[i:i + 10] for i in range(0, len(pagination), 10)]
56 | page = 0
57 | num = 0
58 | user_list = []
59 | level_list = []
60 | xp_list = []
61 | guild_list = []
62 | for i in pages:
63 | embed.clear_fields()
64 | for users, levels, xp, guild in i:
65 | num += 1
66 | if leader_type.lower() == "local":
67 | embed.add_field(name=f"#{num}: {users}", value=f"```Level: {levels:,} - {conversion.translate(xp)} XP```", inline=True)
68 | else:
69 | embed.add_field(name=f"#{num}: {users} - {guild}", value=f"```Level: {levels:,} - {conversion.translate(xp)} XP```", inline=True)
70 | embed.set_footer(text=f"Page {page + 1}/{len(pages)}")
71 | message = await ctx.send(embed=embed)
72 | page += 1
73 | await message.add_reaction("⬅")
74 | await message.add_reaction("➡")
75 | await message.add_reaction("❌")
76 |
77 | while True:
78 | def check(reaction, user):
79 | return user == ctx.author and str(reaction.emoji) in ["⬅", "➡", "❌"] and reaction.message.id == message.id
80 |
81 | try:
82 | reaction, user = await ctx.bot.wait_for("reaction_add", timeout=60.0, check=check)
83 |
84 | if str(reaction.emoji) == "⬅":
85 | if page == 1:
86 | pass
87 | else:
88 | page -= 1
89 | embed.clear_fields()
90 | for users, levels, xp, guild in pages[page - 1]:
91 | num -= 1
92 | user_list.append(users)
93 | level_list.append(levels)
94 | xp_list.append(xp)
95 | guild_list.append(guild)
96 | for x in range(0, len(user_list)):
97 | if leader_type.lower() == "local":
98 | embed.add_field(name=f"#{x + 1 + num - len(user_list)}: {user_list[x]}",
99 | value=f"```Level {level_list[x]:,} - {conversion.translate(xp_list[x])} XP```", inline=True)
100 | else:
101 | embed.add_field(
102 | name=f"#{x + 1 + num - len(user_list)}: {user_list[x]} - {guild_list[x]}",
103 | value=f"```Level {level_list[x]:,} - {conversion.translate(xp_list[x])} XP```",
104 | inline=True)
105 | user_list.clear()
106 | level_list.clear()
107 | xp_list.clear()
108 | guild_list.clear()
109 | embed.set_footer(text=f"Page {page}/{len(pages)}")
110 | await message.edit(embed=embed)
111 | await message.remove_reaction("⬅", user)
112 | await message.remove_reaction("➡", user)
113 | await message.remove_reaction("❌", user)
114 | elif str(reaction.emoji) == "➡":
115 | if page == 1:
116 | pass
117 | else:
118 | page += 1
119 | embed.clear_fields()
120 | for users, levels, xp, guild in pages[page - 1]:
121 | num += 1
122 | user_list.append(users)
123 | level_list.append(levels)
124 | xp_list.append(xp)
125 | guild_list.append(guild)
126 | for x in range(0, len(user_list)):
127 | if leader_type.lower() == "local":
128 | embed.add_field(name=f"#{x + 1 + num - len(user_list)}: {user_list[x]}",
129 | value=f"```Level {level_list[x]:,} - {conversion.translate(xp_list[x])} XP```",
130 | inline=True)
131 | else:
132 | embed.add_field(
133 | name=f"#{x + 1 + num - len(user_list)}: {user_list[x]} - {guild_list[x]}",
134 | value=f"```Level {level_list[x]:,} - {conversion.translate(xp_list[x])} XP```",
135 | inline=True)
136 | user_list.clear()
137 | level_list.clear()
138 | xp_list.clear()
139 | guild_list.clear()
140 | embed.set_footer(text=f"Page {page}/{len(pages)}")
141 | await message.edit(embed=embed)
142 | await message.remove_reaction("⬅", user)
143 | await message.remove_reaction("➡", user)
144 | await message.remove_reaction("❌", user)
145 | elif str(reaction.emoji) == "❌":
146 | await message.delete()
147 | return
148 | except asyncio.TimeoutError:
149 | await message.delete()
150 | return
151 |
152 |
153 |
154 |
--------------------------------------------------------------------------------
/KumosLab/Database/Create/Leaderboard/MongoDB/leaderboard.py:
--------------------------------------------------------------------------------
1 | import asyncio
2 | import os
3 | import sqlite3
4 |
5 | import discord
6 | from discord.ext import commands
7 | from pymongo import MongoClient
8 | from ruamel.yaml import YAML
9 | import KumosLab.Database.conversion as conversion
10 |
11 |
12 |
13 | yaml = YAML()
14 | with open("Configs/config.yml", "r", encoding="utf-8") as file:
15 | config = yaml.load(file)
16 |
17 | if config['Database_Type'].lower() == 'mongodb':
18 | MONGODB_URI = os.environ['MONGODB_URI']
19 | COLLECTION = os.getenv("COLLECTION")
20 | DB_NAME = os.getenv("DATABASE_NAME")
21 | cluster = MongoClient(MONGODB_URI)
22 | levelling = cluster[COLLECTION][DB_NAME]
23 |
24 | async def leaderboard(self=None, ctx=None, guild=None, leader_type=None):
25 | if self is None:
26 | print("[Leaderboard-MongoDB] Self is None")
27 | return
28 | if ctx is None:
29 | print("[Leaderboard-MongoDB] Context is None")
30 | return
31 | if guild is None:
32 | print("[Leaderboard-MongoDB] Guild is None")
33 | return
34 | if leader_type is None:
35 | print("[Leaderboard-MongoDB] Leaderboard Type is None")
36 | return
37 |
38 | if leader_type.lower() == 'local':
39 | result = levelling.find({"guild_id": ctx.guild.id, "xp": {"$exists": True}}).sort(
40 | "xp", -1)
41 | embed = discord.Embed(title=f":trophy: {guild}'s Leaderboard", colour=config['leaderboard_embed_colour'])
42 | else:
43 | result = levelling.find({"xp": {"$exists": True}}).sort(
44 | "xp", -1)
45 | embed = discord.Embed(title=f"🌎 Global Leaderboard", colour=config['leaderboard_embed_colour'])
46 |
47 | if result is None:
48 | print("Server Not Found!")
49 |
50 | users = []
51 | level = []
52 | xp = []
53 | guild = []
54 |
55 | for x in result:
56 | users.append(x["name"])
57 | level.append(x["level"])
58 | xp.append(x["xp"])
59 | # get guild object and append the name to the list
60 | guild.append(self.client.get_guild(x["guild_id"]))
61 |
62 | pagination = list(zip(users, level, xp, guild))
63 | pages = [pagination[i:i + 10] for i in range(0, len(pagination), 10)]
64 | page = 0
65 | num = 0
66 | user_list = []
67 | level_list = []
68 | xp_list = []
69 | guild_list = []
70 | for i in pages:
71 | embed.clear_fields()
72 | for users, levels, xp, guild in i:
73 | num += 1
74 | if leader_type.lower() == 'local':
75 | embed.add_field(name=f"#{num}: {users}", value=f"```Level: {levels:,} - {conversion.translate(xp)} XP```", inline=True)
76 | else:
77 | embed.add_field(name=f"#{num}: {users} - {guild}", value=f"```Level: {levels:,} - {conversion.translate(xp)} XP```", inline=True)
78 | embed.set_footer(text=f"Page {page + 1}/{len(pages)}")
79 | message = await ctx.send(embed=embed)
80 | page += 1
81 | await message.add_reaction("⬅")
82 | await message.add_reaction("➡")
83 | await message.add_reaction("❌")
84 |
85 | while True:
86 | def check(reaction, user):
87 | return user == ctx.author and str(reaction.emoji) in ["⬅", "➡", "❌"] and reaction.message.id == message.id
88 |
89 | try:
90 | reaction, user = await ctx.bot.wait_for("reaction_add", timeout=60.0, check=check)
91 |
92 | if str(reaction.emoji) == "⬅":
93 | if page == 1:
94 | pass
95 | else:
96 | page -= 1
97 | embed.clear_fields()
98 | for users, levels, xp, guild in pages[page - 1]:
99 | num -= 1
100 | user_list.append(users)
101 | level_list.append(levels)
102 | xp_list.append(xp)
103 | guild_list.append(guild)
104 | for x in range(0, len(user_list)):
105 | if leader_type.lower() == 'local':
106 | embed.add_field(name=f"#{x + 1 + num - len(user_list)}: {user_list[x]}",
107 | value=f"```Level: {level_list[x]:,} - {conversion.translate(xp_list[x])} XP```", inline=True)
108 | else:
109 | embed.add_field(name=f"#{x + 1 + num - len(user_list)}: {user_list[x]} - {guild_list[x]}",
110 | value=f"```Level: {level_list[x]:,} - {conversion.translate(xp_list[x])} XP```",
111 | inline=True)
112 | user_list.clear()
113 | level_list.clear()
114 | xp_list.clear()
115 | guild_list.clear()
116 | embed.set_footer(text=f"Page {page}/{len(pages)}")
117 | await message.edit(embed=embed)
118 | await message.remove_reaction("⬅", user)
119 | await message.remove_reaction("➡", user)
120 | await message.remove_reaction("❌", user)
121 | elif str(reaction.emoji) == "➡":
122 | if page == len(pages):
123 | pass
124 | else:
125 | page += 1
126 | embed.clear_fields()
127 | for users, levels, xp, guild in pages[page - 1]:
128 | num += 1
129 | user_list.append(users)
130 | level_list.append(levels)
131 | xp_list.append(xp)
132 | guild_list.append(guild)
133 | for x in range(0, len(user_list)):
134 | if leader_type.lower() == 'local':
135 | embed.add_field(name=f"#{x + 1 + num - len(user_list)}: {user_list[x]}",
136 | value=f"```Level: {level_list[x]:,} - {conversion.translate(xp_list[x])} XP```",
137 | inline=True)
138 | else:
139 | embed.add_field(
140 | name=f"#{x + 1 + num - len(user_list)}: {user_list[x]} - {guild_list[x]}",
141 | value=f"```Level: {level_list[x]:,} - {conversion.translate(xp_list[x])} XP```",
142 | inline=True)
143 | user_list.clear()
144 | level_list.clear()
145 | xp_list.clear()
146 | guild_list.clear()
147 | embed.set_footer(text=f"Page {page}/{len(pages)}")
148 | await message.edit(embed=embed)
149 | await message.remove_reaction("⬅", user)
150 | await message.remove_reaction("➡", user)
151 | await message.remove_reaction("❌", user)
152 | elif str(reaction.emoji) == "❌":
153 | await message.delete()
154 | return
155 | except asyncio.TimeoutError:
156 | await message.delete()
157 | return
158 |
159 |
160 |
161 |
--------------------------------------------------------------------------------
/System/levelsystem.py:
--------------------------------------------------------------------------------
1 | # Imports
2 | import random
3 |
4 | from discord.ext import commands
5 | from pymongo import MongoClient
6 | from ruamel.yaml import YAML
7 | import os
8 | from dotenv import load_dotenv
9 | import sqlite3
10 |
11 | import KumosLab.Database.get
12 | import KumosLab.Database.set
13 | import KumosLab.Database.add
14 | import KumosLab.Database.check
15 | import KumosLab.Database.insert
16 |
17 | yaml = YAML()
18 | with open("Configs/config.yml", "r", encoding="utf-8") as file:
19 | config = yaml.load(file)
20 |
21 | # Loads the .env file and gets the required information
22 | load_dotenv()
23 | if config['Database_Type'].lower() == 'mongodb':
24 | MONGODB_URI = os.environ['MONGODB_URI']
25 | COLLECTION = os.getenv("COLLECTION")
26 | DB_NAME = os.getenv("DATABASE_NAME")
27 | cluster = MongoClient(MONGODB_URI)
28 | levelling = cluster[COLLECTION][DB_NAME]
29 |
30 |
31 | class levelsys(commands.Cog):
32 | def __init__(self, client):
33 | self.client = client
34 |
35 | @commands.Cog.listener()
36 | async def on_message(self, ctx):
37 | if not ctx.author.bot:
38 | if ctx.content.startswith(config["Prefix"]):
39 | return
40 |
41 | if config['loader_type'].lower() == 'message':
42 | user_check = await KumosLab.Database.get.xp(user=ctx.author, guild=ctx.guild)
43 | if user_check == "User Not Found!":
44 | await KumosLab.Database.insert.userField(member=ctx.author, guild=ctx.guild)
45 |
46 | if config['XP_Chance'] is True:
47 | chance_rate = config['XP_Chance_Rate']
48 | random_num = random.randint(1, chance_rate)
49 | if random_num != chance_rate:
50 | return
51 |
52 | channels = await KumosLab.Database.get.talkchannels(guild=ctx.guild)
53 | channel_Array = []
54 | channel_List = []
55 | for channel in channels:
56 | channel_Array.append(channel)
57 | if len(channel_Array) < 1 or channel_Array[0] is None:
58 | pass
59 | else:
60 | for x in channel_Array:
61 | channel = self.client.get_channel(int(x))
62 | channel_List.append(channel.name)
63 |
64 | if str(channel_List) == "[]":
65 | pass
66 | elif channel_List is not None:
67 | if ctx.channel.name in channel_List:
68 | pass
69 | else:
70 | return
71 |
72 | xp_type = config['xp_type']
73 | if xp_type.lower() == "normal":
74 | to_add = config['xp_normal_amount']
75 | await KumosLab.Database.add.xp(user=ctx.author, guild=ctx.guild, amount=to_add)
76 | elif xp_type.lower() == "words":
77 | # get the length of the message
78 | res = len(ctx.content.split())
79 | message_length = int(res)
80 | await KumosLab.Database.add.xp(user=ctx.author, guild=ctx.guild, amount=message_length)
81 | elif xp_type.lower() == "ranrange":
82 | # get ranges from config
83 | min = config['xp_ranrange_min']
84 | max = config['xp_ranrange_max']
85 | num = random.randint(min, max)
86 | await KumosLab.Database.add.xp(user=ctx.author, guild=ctx.guild, amount=num)
87 |
88 | await KumosLab.Database.check.levelUp(user=ctx.author, guild=ctx.guild)
89 |
90 | # on guild join
91 | @commands.Cog.listener()
92 | async def on_guild_join(self, guild):
93 | # get database type from config file
94 | db_type = config["Database_Type"]
95 | if db_type.lower() == "mongodb":
96 | levelling.insert_one({"guild": guild.id, "main_channel": None, "admin_role": None, "roles": [],
97 | "role_levels": [], 'talkchannels': []})
98 | for member in guild.members:
99 | # check if member is a bot
100 | if not member.bot:
101 | levelling.insert_one(
102 | {"guild_id": guild.id, "user_id": member.id, "name": str(member), "level": 1, "xp": 0,
103 | "background": config['Default_Background'], "xp_colour": config['Default_XP_Colour'],
104 | "blur": 0, "border": config['Default_Border']})
105 | elif db_type.lower() == "local":
106 | db = sqlite3.connect("KumosLab/Database/Local/serverbase.sqlite")
107 | cursor = db.cursor()
108 | sql = "INSERT INTO levelling (guild_id, admin_role, main_channel, talkchannels) VALUES (?, ?, ?, ?)"
109 | val = (guild.id, None, None, None)
110 | cursor.execute(sql, val)
111 | db.commit()
112 | for member in guild.members:
113 | # check if member is a bot
114 | db = sqlite3.connect("KumosLab/Database/Local/userbase.sqlite")
115 | cursor = db.cursor()
116 | if not member.bot:
117 | sql = "INSERT INTO levelling (guild_id, user_id, name, level, xp, background, xp_colour, blur, border) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"
118 | val = (
119 | guild.id, member.id, str(member), 1, 0, config['Default_Background'], config['Default_XP_Colour'],
120 | 0, config['Default_Border'])
121 | cursor.execute(sql, val)
122 | db.commit()
123 | else:
124 | continue
125 | cursor.close()
126 |
127 | # on guild leave
128 | @commands.Cog.listener()
129 | async def on_guild_remove(self, guild):
130 | # get database type from config file
131 | db_type = config["Database_Type"]
132 | if db_type.lower() == "mongodb":
133 | levelling.delete_one({"guild": guild.id})
134 | for member in guild.members:
135 | levelling.delete_one({"guild_id": guild.id, "user_id": member.id})
136 | elif db_type.lower() == "local":
137 | db = sqlite3.connect("KumosLab/Database/Local/serverbase.sqlite")
138 | cursor = db.cursor()
139 | sql = "DELETE FROM levelling WHERE guild_id = ?"
140 | val = (guild.id,)
141 | cursor.execute(sql, val)
142 | db.commit()
143 | cursor.close()
144 | for member in guild.members:
145 | db = sqlite3.connect("KumosLab/Database/Local/userbase.sqlite")
146 | cursor = db.cursor()
147 | sql = "DELETE FROM levelling WHERE guild_id = ? AND user_id = ?"
148 | val = (guild.id, member.id)
149 | cursor.execute(sql, val)
150 | db.commit()
151 | cursor.close()
152 |
153 | # on member join
154 | @commands.Cog.listener()
155 | async def on_member_join(self, member):
156 | await KumosLab.Database.insert.userField(member=member, guild=member.guild)
157 |
158 | # on member leave
159 | @commands.Cog.listener()
160 | async def on_member_remove(self, member):
161 | # get database type from config file
162 | db_type = config["Database_Type"]
163 | if db_type.lower() == "mongodb":
164 | levelling.delete_one({"guild_id": member.guild.id, "user_id": member.id})
165 | elif db_type.lower() == "local":
166 | db = sqlite3.connect("KumosLab/Database/Local/userbase.sqlite")
167 | cursor = db.cursor()
168 | sql = "DELETE FROM levelling WHERE guild_id = ? AND user_id = ?"
169 | val = (member.guild.id, member.id)
170 | cursor.execute(sql, val)
171 | db.commit()
172 | cursor.close()
173 |
174 |
175 | def setup(client):
176 | client.add_cog(levelsys(client))
177 |
178 | # End Of Level System
179 |
--------------------------------------------------------------------------------
/KumosLab/Database/add.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sqlite3
3 |
4 | import discord
5 | from pymongo import MongoClient
6 | from ruamel import yaml
7 |
8 | with open("Configs/config.yml", "r", encoding="utf-8") as file:
9 | config = yaml.load(file)
10 |
11 |
12 | # check if clan.py in addon folder
13 | if os.path.isfile("Addons/clan.py"):
14 | with open("Configs/clan_addon.yml", "r", encoding="utf-8") as file:
15 | clan_config = yaml.load(file)
16 |
17 |
18 | if config['Database_Type'].lower() == 'mongodb':
19 | MONGODB_URI = os.environ['MONGODB_URI']
20 | COLLECTION = os.getenv("COLLECTION")
21 | DB_NAME = os.getenv("DATABASE_NAME")
22 | cluster = MongoClient(MONGODB_URI)
23 | levelling = cluster[COLLECTION][DB_NAME]
24 |
25 | async def xp(user: discord.Member = None, guild: discord.Guild = None, amount=None):
26 | if user is None:
27 | print("Error in 'KumosLab/Database/add.py' - User is None for 'xp'")
28 | return
29 | if guild is None:
30 | print("Error in 'KumosLab/Database/add.py' - Guild is None for 'xp'")
31 | return
32 | if amount is None:
33 | print("Error in 'KumosLab/Database/add.py' - Amount is None for 'xp'")
34 | return
35 | try:
36 | if config['Database_Type'].lower() == "mongodb":
37 | user_find = levelling.find_one({'user_id': user.id, 'guild_id': guild.id})
38 | if user_find is None:
39 | print("User Not Found!")
40 | return
41 | # add xp
42 | levelling.update_one({'user_id': user.id, 'guild_id': guild.id}, {'$inc': {'xp': + amount}})
43 | return
44 | elif config['Database_Type'].lower() == "local":
45 | db = sqlite3.connect("KumosLab/Database/Local/userbase.sqlite")
46 | cursor = db.cursor()
47 | cursor.execute("SELECT xp FROM levelling WHERE user_id = ? AND guild_id = ?", (user.id, guild.id))
48 | result = cursor.fetchone()
49 | if result is None:
50 | print("User Not Found!")
51 | return
52 | # add xp
53 | cursor.execute("UPDATE levelling SET xp = xp + ? WHERE user_id = ? AND guild_id = ?", (amount, user.id, guild.id))
54 | db.commit()
55 | cursor.close()
56 | return
57 | except Exception as e:
58 | print("Error in 'KumosLab/Database/add.py' - " + str(e))
59 | return
60 |
61 | async def level(user: discord.Member = None, guild: discord.Guild = None, amount=None):
62 | if user is None:
63 | print("Error in 'KumosLab/Database/add.py' - User is None for 'level'")
64 | return
65 | if guild is None:
66 | print("Error in 'KumosLab/Database/add.py' - Guild is None for 'level'")
67 | return
68 | if amount is None:
69 | print("Error in 'KumosLab/Database/add.py' - Amount is None for 'level'")
70 | return
71 | try:
72 | if config['Database_Type'].lower() == "mongodb":
73 | member = levelling.find_one({'user_id': user.id, 'guild_id': guild.id})
74 | if member is None:
75 | print("User Not Found!")
76 | return
77 | # add level
78 | levelling.update_one({'user_id': user.id, 'guild_id': guild.id}, {'$inc': {'level': + amount}})
79 | return
80 | elif config['Database_Type'].lower() == "local":
81 | db = sqlite3.connect("KumosLab/Database/Local/userbase.sqlite")
82 | cursor = db.cursor()
83 | cursor.execute("SELECT level FROM levelling WHERE user_id = ? AND guild_id = ?", (user.id, guild.id))
84 | result = cursor.fetchone()
85 | if result is None:
86 | print("User Not Found!")
87 | return
88 | # add level
89 | cursor.execute("UPDATE levelling SET level = level + ? WHERE user_id = ? AND guild_id = ?", (amount, user.id, guild.id))
90 | db.commit()
91 | cursor.close()
92 | return
93 | except Exception as e:
94 | print("Error in 'KumosLab/Database/add.py' - " + str(e))
95 | return
96 |
97 | async def role(guild: discord.Guild = None, role_name: discord.Role = None, role_level: int = None):
98 | if guild is None:
99 | print("Error in 'KumosLab/Database/add.py' - Guild is None for 'role'")
100 | return
101 | if role is None:
102 | print("Error in 'KumosLab/Database/add.py' - Role is None for 'role'")
103 | return
104 | if role_level is None:
105 | print("Error in 'KumosLab/Database/add.py' - Role_Level is None for 'role'")
106 | return
107 | try:
108 | if config['Database_Type'].lower() == "mongodb":
109 | # find if role is already in database
110 | role_db = levelling.find_one({'guild': guild.id, 'role_name': role_name.name})
111 | if role_db is not None:
112 | return "error"
113 | # add role
114 | levelling.update_one({'guild': guild.id}, {'$push': {'roles': role_name.name, 'role_levels': int(role_level)}})
115 | return
116 | elif config['Database_Type'].lower() == "local":
117 | db = sqlite3.connect("KumosLab/Database/Local/roles.sqlite")
118 | cursor = db.cursor()
119 | # find if role is already in database
120 | cursor.execute("SELECT * FROM levelling WHERE guild_id = ? AND role = ?", (guild.id, role_name.name))
121 | result = cursor.fetchone()
122 | if result is not None:
123 | return "error"
124 | # insert guild, role and level
125 | cursor.execute("INSERT INTO levelling (guild_id, role, role_levels) VALUES (?, ?, ?)", (guild.id, role_name.name, role_level))
126 | db.commit()
127 | cursor.close()
128 | return
129 | except Exception as e:
130 | print("Error in 'KumosLab/Database/add.py' - " + str(e))
131 | return
132 |
133 | async def talkchannel(guild: discord.Guild = None, channel: discord.TextChannel = None):
134 | if guild is None:
135 | print("Error in 'KumosLab/Database/add.py' - Guild is None for 'talkchannel'")
136 | return
137 | if channel is None:
138 | print("Error in 'KumosLab/Database/add.py' - Talk_Channel is None for 'talkchannel'")
139 | return
140 | try:
141 | if config['Database_Type'].lower() == "mongodb":
142 | talk_db = levelling.find_one({'guild': guild.id, 'talkchannels': channel.id})
143 | if talk_db is not None:
144 | return "error"
145 | levelling.update_one({'guild': guild.id}, {'$push': {'talkchannels': channel.id}})
146 | return
147 | elif config['Database_Type'].lower() == "local":
148 | db = sqlite3.connect("KumosLab/Database/Local/serverbase.sqlite")
149 | cursor = db.cursor()
150 | cursor.execute("SELECT * FROM levelling WHERE guild_id = ? AND talkchannels = ?", (guild.id, channel.id))
151 | result = cursor.fetchone()
152 | if result is not None:
153 | return "error"
154 | # update talkchannels to add channel to list
155 | cursor.execute("UPDATE levelling SET talkchannels = ? WHERE guild_id = ?", (channel.id, guild.id))
156 | db.commit()
157 | cursor.close()
158 | return
159 | except Exception as e:
160 | print("Error in 'KumosLab/Database/add.py' - " + str(e))
161 | return
162 |
163 | async def clan(guild: discord.Guild = None, clan_name: str = None, owner: discord.Member = None):
164 | if guild is None:
165 | print("Error in 'KumosLab/Database/add.py' - Guild is None for 'clan'")
166 | return
167 | if clan_name is None:
168 | print("Error in 'KumosLab/Database/add.py' - Clan Name is None for 'clan'")
169 | return
170 | if owner is None:
171 | print("Error in 'KumosLab/Database/add.py' - Owner is None for 'clan'")
172 | return
173 | try:
174 | if config['Database_Type'].lower() == "mongodb":
175 | role_db = levelling.find_one({'clans_guild': guild.id, 'clan_name': clan_name})
176 | if role_db is not None:
177 | return "error"
178 | levelling.insert_one({'clans_guild': guild.id, 'clan_name': clan_name, 'owner': owner.id, 'members': [owner.id], 'level': 1, 'xp': 0, 'logo': clan_config['default_logo'], 'colour': clan_config['default_colour']})
179 | return
180 | elif config['Database_Type'].lower() == "local":
181 | db = sqlite3.connect("KumosLab/Database/Local/clans.sqlite")
182 | cursor = db.cursor()
183 | cursor.execute("SELECT * FROM levelling WHERE clans_guild = ? AND clan_name = ?", (guild.id, clan_name))
184 | result = cursor.fetchone()
185 | if result is not None:
186 | return "error"
187 | cursor.execute("INSERT INTO levelling (clans_guild, clan_name, owner, members, level, xp, logo, colour) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", (guild.id, clan_name, str(owner.id), owner.id, 1, 0, clan_config['default_logo'], clan_config['default_colour']))
188 | db.commit()
189 | cursor.close()
190 | return
191 | except Exception as e:
192 | print("Error in 'KumosLab/Database/add.py' - " + str(e))
193 | return
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/KumosLab/Database/set.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sqlite3
3 |
4 | import discord
5 | from pymongo import MongoClient
6 | from ruamel import yaml
7 |
8 | with open("Configs/config.yml", "r", encoding="utf-8") as file:
9 | config = yaml.load(file)
10 |
11 |
12 | if config['Database_Type'].lower() == 'mongodb':
13 | MONGODB_URI = os.environ['MONGODB_URI']
14 | COLLECTION = os.getenv("COLLECTION")
15 | DB_NAME = os.getenv("DATABASE_NAME")
16 | cluster = MongoClient(MONGODB_URI)
17 | levelling = cluster[COLLECTION][DB_NAME]
18 |
19 | async def xp(user: discord.Member = None, guild: discord.Guild = None, amount=None):
20 | if user is None:
21 | print("Error in 'KumosLab/Database/set.py' - User is None for 'xp'")
22 | return
23 | if guild is None:
24 | print("Error in 'KumosLab/Database/set.py' - Guild is None for 'xp'")
25 | return
26 | if amount is None:
27 | print("Error in 'KumosLab/Database/set.py' - Amount is None for 'xp'")
28 | return
29 | try:
30 | if config['Database_Type'].lower() == "mongodb":
31 | member = levelling.find_one({'user_id': user.id, 'guild_id': guild.id})
32 | if member is None:
33 | print("User Not Found!")
34 | return
35 | # add xp
36 | levelling.update_one({'user_id': user.id, 'guild_id': guild.id}, {'$set': {'xp': amount}})
37 | return
38 | elif config['Database_Type'].lower() == "local":
39 | db = sqlite3.connect("KumosLab/Database/Local/userbase.sqlite")
40 | cursor = db.cursor()
41 | cursor.execute("SELECT xp FROM levelling WHERE user_id = ? AND guild_id = ?", (user.id, guild.id))
42 | result = cursor.fetchone()
43 | if result is None:
44 | print("User Not Found!")
45 | return
46 | # add xp
47 | cursor.execute("UPDATE levelling SET xp = ? WHERE user_id = ? AND guild_id = ?", (amount, user.id, guild.id))
48 | db.commit()
49 | cursor.close()
50 | return
51 | except Exception as e:
52 | print("Error in 'KumosLab/Database/add.py' - " + str(e))
53 | return
54 |
55 | async def level(user: discord.Member = None, guild: discord.Guild = None, amount=None):
56 | if user is None:
57 | print("Error in 'KumosLab/Database/set.py' - User is None for 'level'")
58 | return
59 | if guild is None:
60 | print("Error in 'KumosLab/Database/set.py' - Guild is None for 'level'")
61 | return
62 | if amount is None:
63 | print("Error in 'KumosLab/Database/set.py' - Amount is None for 'level'")
64 | return
65 | try:
66 | if config['Database_Type'].lower() == "mongodb":
67 | member = levelling.find_one({'user_id': user.id, 'guild_id': guild.id})
68 | if member is None:
69 | print("User Not Found!")
70 | return
71 | # add level
72 | levelling.update_one({'user_id': user.id, 'guild_id': guild.id}, {'$set': {'level': amount}})
73 | return
74 | elif config['Database_Type'].lower() == "local":
75 | db = sqlite3.connect("KumosLab/Database/Local/userbase.sqlite")
76 | cursor = db.cursor()
77 | cursor.execute("SELECT level FROM levelling WHERE user_id = ? AND guild_id = ?", (user.id, guild.id))
78 | result = cursor.fetchone()
79 | if result is None:
80 | print("User Not Found!")
81 | return
82 | # add level
83 | cursor.execute("UPDATE levelling SET level = ? WHERE user_id = ? AND guild_id = ?", (amount, user.id, guild.id))
84 | db.commit()
85 | cursor.close()
86 | return
87 | except Exception as e:
88 | print("Error in 'KumosLab/Database/set.py' - " + str(e))
89 | return
90 |
91 | async def background(user: discord.Member = None, guild: discord.Guild = None, link=None):
92 | if user is None:
93 | print("Error in 'KumosLab/Database/set.py' - User is None for 'background'")
94 | return
95 | if guild is None:
96 | print("Error in 'KumosLab/Database/set.py' - Guild is None for 'background'")
97 | return
98 | if link is None:
99 | print("Error in 'KumosLab/Database/set.py' - Link is None for 'background'")
100 | return
101 | try:
102 | if config['Database_Type'].lower() == "mongodb":
103 | member = levelling.find_one({'user_id': user.id, 'guild_id': guild.id})
104 | if member is None:
105 | print("User Not Found!")
106 | return
107 | # add background
108 | levelling.update_one({'user_id': user.id, 'guild_id': guild.id}, {'$set': {'background': link}})
109 | return
110 | elif config['Database_Type'].lower() == "local":
111 | db = sqlite3.connect("KumosLab/Database/Local/userbase.sqlite")
112 | cursor = db.cursor()
113 | cursor.execute("SELECT background FROM levelling WHERE user_id = ? AND guild_id = ?", (user.id, guild.id))
114 | result = cursor.fetchone()
115 | if result is None:
116 | print("User Not Found!")
117 | return
118 | # add level
119 | cursor.execute("UPDATE levelling SET background = ? WHERE user_id = ? AND guild_id = ?", (link, user.id, guild.id))
120 | db.commit()
121 | cursor.close()
122 | return
123 | except Exception as e:
124 | print("Error in 'KumosLab/Database/set.py' - " + str(e))
125 | return
126 |
127 | async def border(user: discord.Member = None, guild: discord.Guild = None, link=None):
128 | if user is None:
129 | print("Error in 'KumosLab/Database/set.py' - User is None for 'border'")
130 | return
131 | if guild is None:
132 | print("Error in 'KumosLab/Database/set.py' - Guild is None for 'border'")
133 | return
134 | if link is None:
135 | print("Error in 'KumosLab/Database/set.py' - Link is None for 'border'")
136 | return
137 | try:
138 | if config['Database_Type'].lower() == "mongodb":
139 | member = levelling.find_one({'user_id': user.id, 'guild_id': guild.id})
140 | if member is None:
141 | print("User Not Found!")
142 | return
143 | # add border
144 | levelling.update_one({'user_id': user.id, 'guild_id': guild.id}, {'$set': {'border': link}})
145 | return
146 | elif config['Database_Type'].lower() == "local":
147 | db = sqlite3.connect("KumosLab/Database/Local/userbase.sqlite")
148 | cursor = db.cursor()
149 | cursor.execute("SELECT border FROM levelling WHERE user_id = ? AND guild_id = ?", (user.id, guild.id))
150 | result = cursor.fetchone()
151 | if result is None:
152 | print("User Not Found!")
153 | return
154 | # add level
155 | cursor.execute("UPDATE levelling SET border = ? WHERE user_id = ? AND guild_id = ?", (link, user.id, guild.id))
156 | db.commit()
157 | cursor.close()
158 | return
159 | except Exception as e:
160 | print("Error in 'KumosLab/Database/set.py' - " + str(e))
161 | return
162 |
163 | async def colour(user: discord.Member = None, guild: discord.Guild = None, hex=None):
164 | if user is None:
165 | print("Error in 'KumosLab/Database/set.py' - User is None for 'colour'")
166 | return
167 | if guild is None:
168 | print("Error in 'KumosLab/Database/set.py' - Guild is None for 'colour'")
169 | return
170 | if hex is None:
171 | print("Error in 'KumosLab/Database/set.py' - Hex is None for 'colour'")
172 | return
173 | try:
174 | if config['Database_Type'].lower() == "mongodb":
175 | member = levelling.find_one({'user_id': user.id, 'guild_id': guild.id})
176 | if member is None:
177 | print("User Not Found!")
178 | return
179 | # add background
180 | levelling.update_one({'user_id': user.id, 'guild_id': guild.id}, {'$set': {'xp_colour': hex}})
181 | return
182 | elif config['Database_Type'].lower() == "local":
183 | db = sqlite3.connect("KumosLab/Database/Local/userbase.sqlite")
184 | cursor = db.cursor()
185 | cursor.execute("SELECT xp_colour FROM levelling WHERE user_id = ? AND guild_id = ?", (user.id, guild.id))
186 | result = cursor.fetchone()
187 | if result is None:
188 | print("User Not Found!")
189 | return
190 | # add level
191 | cursor.execute("UPDATE levelling SET xp_colour = ? WHERE user_id = ? AND guild_id = ?", (hex, user.id, guild.id))
192 | db.commit()
193 | cursor.close()
194 | return
195 | except Exception as e:
196 | print("Error in 'KumosLab/Database/set.py' - " + str(e))
197 | return
198 |
199 | async def blur(user: discord.Member = None, guild: discord.Guild = None, amount=None):
200 | if user is None:
201 | print("Error in 'KumosLab/Database/set.py' - User is None for 'blur'")
202 | return
203 | if guild is None:
204 | print("Error in 'KumosLab/Database/set.py' - Guild is None for 'blur'")
205 | return
206 | if amount is None:
207 | print("Error in 'KumosLab/Database/set.py' - Amount is None for 'blur'")
208 | return
209 | try:
210 | if config['Database_Type'].lower() == "mongodb":
211 | member = levelling.find_one({'user_id': user.id, 'guild_id': guild.id})
212 | if member is None:
213 | print("User Not Found!")
214 | return
215 | # add background
216 | levelling.update_one({'user_id': user.id, 'guild_id': guild.id}, {'$set': {'blur': amount}})
217 | return
218 | elif config['Database_Type'].lower() == "local":
219 | db = sqlite3.connect("KumosLab/Database/Local/userbase.sqlite")
220 | cursor = db.cursor()
221 | cursor.execute("SELECT blur FROM levelling WHERE user_id = ? AND guild_id = ?", (user.id, guild.id))
222 | result = cursor.fetchone()
223 | if result is None:
224 | print("User Not Found!")
225 | return
226 | # add level
227 | cursor.execute("UPDATE levelling SET blur = ? WHERE user_id = ? AND guild_id = ?", (amount, user.id, guild.id))
228 | db.commit()
229 | cursor.close()
230 | return
231 | except Exception as e:
232 | print("Error in 'KumosLab/Database/set.py' - " + str(e))
233 | return
234 |
235 | async def mainChannel(guild: discord.Guild = None, channel: discord.TextChannel = None):
236 | if guild is None:
237 | print("Error in 'KumosLab/Database/set.py' - Guild is None for 'mainChannel'")
238 | return
239 | if channel is None:
240 | print("Error in 'KumosLab/Database/set.py' - Channel is None for 'mainChannel'")
241 | return
242 | try:
243 | if config['Database_Type'].lower() == "mongodb":
244 | levelling.update_one({'guild': guild.id}, {'$set': {'main_channel': channel.name}})
245 | return
246 | elif config['Database_Type'].lower() == "local":
247 | db = sqlite3.connect("KumosLab/Database/Local/serverbase.sqlite")
248 | cursor = db.cursor()
249 | cursor.execute("UPDATE levelling SET main_channel = ? WHERE guild_id = ?", (channel.name, guild.id))
250 | db.commit()
251 | cursor.close()
252 | return
253 | except Exception as e:
254 | print("Error in 'KumosLab/Database/set.py' - " + str(e))
255 | return
256 |
257 |
258 |
259 |
260 |
261 |
--------------------------------------------------------------------------------
/KumosLab/Database/get.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sqlite3
3 | import urllib.request
4 | import json
5 |
6 | import discord
7 | from pymongo import MongoClient
8 | from ruamel import yaml
9 |
10 | with open("Configs/config.yml", "r", encoding="utf-8") as file:
11 | config = yaml.load(file)
12 |
13 |
14 | if config['Database_Type'].lower() == 'mongodb':
15 | MONGODB_URI = os.environ['MONGODB_URI']
16 | COLLECTION = os.getenv("COLLECTION")
17 | DB_NAME = os.getenv("DATABASE_NAME")
18 | cluster = MongoClient(MONGODB_URI)
19 | levelling = cluster[COLLECTION][DB_NAME]
20 |
21 | async def xp(user: discord.Member = None, guild: discord.Guild = None):
22 | if user is None:
23 | print("Error in 'KumosLab/Database/get.py' - User is None for 'xp'")
24 | return
25 | if guild is None:
26 | print("Error in 'KumosLab/Database/get.py' - Guild is None for 'xp'")
27 | return
28 | try:
29 | if config['Database_Type'].lower() == "mongodb":
30 | member = levelling.find_one({'user_id': user.id, 'guild_id': guild.id})
31 | if user is None:
32 | return "User Not Found!"
33 | return member['xp']
34 | elif config['Database_Type'].lower() == "local":
35 | db = sqlite3.connect("KumosLab/Database/Local/userbase.sqlite")
36 | cursor = db.cursor()
37 | cursor.execute("SELECT xp FROM levelling WHERE user_id = ? AND guild_id = ?", (user.id, guild.id))
38 | result = cursor.fetchone()
39 | if result is None:
40 | return "User Not Found!"
41 | cursor.close()
42 | return result[0]
43 |
44 | except Exception as e:
45 | print("Error in 'KumosLab/Database/get.py' - " + str(e))
46 | return
47 |
48 | async def background(user: discord.Member = None, guild: discord.Guild = None):
49 | if user is None:
50 | print("Error in 'KumosLab/Database/get.py' - User is None for 'background'")
51 | return
52 | if guild is None:
53 | print("Error in 'KumosLab/Database/get.py' - Guild is None for 'background'")
54 | return
55 | try:
56 | if config['Database_Type'].lower() == "mongodb":
57 | member = levelling.find_one({'user_id': user.id, 'guild_id': guild.id})
58 | if member is None:
59 | print("User Not Found!")
60 | return
61 | return member['background']
62 | elif config['Database_Type'].lower() == "local":
63 | db = sqlite3.connect("KumosLab/Database/Local/userbase.sqlite")
64 | cursor = db.cursor()
65 | cursor.execute("SELECT background FROM levelling WHERE user_id = ? AND guild_id = ?", (user.id, guild.id))
66 | result = cursor.fetchone()
67 | if result is None:
68 | print("User Not Found!")
69 | return
70 | cursor.close()
71 | return result[0]
72 | except Exception as e:
73 | print("Error in 'KumosLab/Database/get.py' - " + str(e))
74 | return
75 |
76 | async def border(user: discord.Member = None, guild: discord.Guild = None):
77 | if user is None:
78 | print("Error in 'KumosLab/Database/get.py' - User is None for 'border'")
79 | return
80 | if guild is None:
81 | print("Error in 'KumosLab/Database/get.py' - Guild is None for 'border'")
82 | return
83 | try:
84 | if config['Database_Type'].lower() == "mongodb":
85 | member = levelling.find_one({'user_id': user.id, 'guild_id': guild.id})
86 | if member is None:
87 | print("User Not Found!")
88 | return
89 | return member['border']
90 | elif config['Database_Type'].lower() == "local":
91 | db = sqlite3.connect("KumosLab/Database/Local/userbase.sqlite")
92 | cursor = db.cursor()
93 | cursor.execute("SELECT border FROM levelling WHERE user_id = ? AND guild_id = ?", (user.id, guild.id))
94 | result = cursor.fetchone()
95 | if result is None:
96 | print("User Not Found!")
97 | return
98 | cursor.close()
99 | return result[0]
100 | except Exception as e:
101 | print("Error in 'KumosLab/Database/get.py' - " + str(e))
102 | return
103 |
104 | async def colour(user: discord.Member = None, guild: discord.Guild = None):
105 | if user is None:
106 | print("Error in 'KumosLab/Database/get.py' - User is None for 'background'")
107 | return
108 | if guild is None:
109 | print("Error in 'KumosLab/Database/get.py' - Guild is None for 'background'")
110 | return
111 | try:
112 | if config['Database_Type'].lower() == "mongodb":
113 | member = levelling.find_one({'user_id': user.id, 'guild_id': guild.id})
114 | if member is None:
115 | print("User Not Found!")
116 | return
117 | return member['xp_colour']
118 | elif config['Database_Type'].lower() == "local":
119 | db = sqlite3.connect("KumosLab/Database/Local/userbase.sqlite")
120 | cursor = db.cursor()
121 | cursor.execute("SELECT xp_colour FROM levelling WHERE user_id = ? AND guild_id = ?", (user.id, guild.id))
122 | result = cursor.fetchone()
123 | if result is None:
124 | print("User Not Found!")
125 | return
126 | cursor.close()
127 | return result[0]
128 | except Exception as e:
129 | print("Error in 'KumosLab/Database/get.py' - " + str(e))
130 | return
131 |
132 | async def blur(user: discord.Member = None, guild: discord.Guild = None):
133 | if user is None:
134 | print("Error in 'KumosLab/Database/get.py' - User is None for 'blur'")
135 | return
136 | if guild is None:
137 | print("Error in 'KumosLab/Database/get.py' - Guild is None for 'blur'")
138 | return
139 | try:
140 | if config['Database_Type'].lower() == "mongodb":
141 | member = levelling.find_one({'user_id': user.id, 'guild_id': guild.id})
142 | if member is None:
143 | print("User Not Found!")
144 | return
145 | return member['blur']
146 | elif config['Database_Type'].lower() == "local":
147 | db = sqlite3.connect("KumosLab/Database/Local/userbase.sqlite")
148 | cursor = db.cursor()
149 | cursor.execute("SELECT blur FROM levelling WHERE user_id = ? AND guild_id = ?", (user.id, guild.id))
150 | result = cursor.fetchone()
151 | if result is None:
152 | print("User Not Found!")
153 | return
154 | cursor.close()
155 | return result[0]
156 | except Exception as e:
157 | print("Error in 'KumosLab/Database/get.py' - " + str(e))
158 | return
159 |
160 |
161 | async def level(user: discord.Member = None, guild: discord.Guild = None):
162 | if user is None:
163 | print("Error in 'KumosLab/Database/get.py' - User is None for 'level'")
164 | return
165 | if guild is None:
166 | print("Error in 'KumosLab/Database/get.py' - Guild is None for 'level'")
167 | return
168 | try:
169 | if config['Database_Type'].lower() == "mongodb":
170 | member = levelling.find_one({'user_id': user.id, 'guild_id': guild.id})
171 | if member is None:
172 | print("User Not Found!")
173 | return
174 | return member['level']
175 | elif config['Database_Type'].lower() == "local":
176 | db = sqlite3.connect("KumosLab/Database/Local/userbase.sqlite")
177 | cursor = db.cursor()
178 | cursor.execute("SELECT level FROM levelling WHERE user_id = ? AND guild_id = ?", (user.id, guild.id))
179 | result = cursor.fetchone()
180 | if result is None:
181 | print("User Not Found!")
182 | return
183 | cursor.close()
184 | return result[0]
185 | except Exception as e:
186 | print("Error in 'KumosLab/Database/get.py' - " + str(e))
187 | return
188 |
189 | async def rankings(user: discord.Member = None, guild: discord.Guild = None):
190 | if guild is None:
191 | print("Error in 'KumosLab/Database/get.py' - Guild is None for 'rankings'")
192 | return
193 | try:
194 | if config['Database_Type'].lower() == "mongodb":
195 | stats = levelling.find_one({"guild_id": guild.id, "user_id": user.id})
196 | rankings = levelling.find({"guild_id": guild.id}).sort("xp", -1)
197 | rank = 0
198 | for x in rankings:
199 | rank += 1
200 | if stats["user_id"] == x["user_id"]:
201 | break
202 | return rank
203 | elif config['Database_Type'].lower() == "local":
204 | db = sqlite3.connect("KumosLab/Database/Local/userbase.sqlite")
205 | cursor = db.cursor()
206 | rankings = cursor.execute("SELECT * FROM levelling WHERE guild_id = ? ORDER BY xp DESC", (guild.id,))
207 | rank = 0
208 | for x in rankings:
209 | rank += 1
210 | if user.id == x[0]:
211 | break
212 | cursor.close()
213 | return rank
214 | except Exception as e:
215 | print("Error in 'KumosLab/Database/get.py' - " + str(e))
216 | return
217 |
218 | async def mainChannel(guild: discord.Guild = None):
219 | if guild is None:
220 | print("Error in 'KumosLab/Database/get.py' - Guild is None for 'mainChannel'")
221 | return
222 | try:
223 | if config['Database_Type'].lower() == "mongodb":
224 | server = levelling.find_one({"guild": guild.id})
225 | if server is None:
226 | print("Server Not Found!")
227 | return
228 | return server["main_channel"]
229 | elif config['Database_Type'].lower() == "local":
230 | db = sqlite3.connect("KumosLab/Database/Local/serverbase.sqlite")
231 | cursor = db.cursor()
232 | cursor.execute("SELECT main_channel FROM levelling WHERE guild_id = ?", (guild.id,))
233 | result = cursor.fetchone()
234 | if result is None:
235 | print("Server Not Found!")
236 | return
237 | cursor.close()
238 | return result[0]
239 | except Exception as e:
240 | print("Error in 'KumosLab/Database/get.py' - " + str(e))
241 | return
242 |
243 | async def roles(guild: discord.Guild = None):
244 | if guild is None:
245 | print("Error in 'KumosLab/Database/get.py' - Guild is None for 'roles'")
246 | return
247 | try:
248 | if config['Database_Type'].lower() == "mongodb":
249 | server = levelling.find_one({"guild": guild.id})
250 | if server is None:
251 | print("Server Not Found!")
252 | return
253 | return server["roles"]
254 | elif config['Database_Type'].lower() == "local":
255 | db = sqlite3.connect("KumosLab/Database/Local/roles.sqlite")
256 | cursor = db.cursor()
257 | # get all roles
258 | cursor.execute("SELECT role FROM levelling WHERE guild_id = ?", (guild.id,))
259 | result = cursor.fetchall()
260 | if result is None:
261 | print("Server Not Found!")
262 | return
263 | cursor.close()
264 | return result
265 | except Exception as e:
266 | print("Error in 'KumosLab/Database/get.py' - " + str(e))
267 | return
268 |
269 | async def roleLevel(guild: discord.Guild = None):
270 | if guild is None:
271 | print("Error in 'KumosLab/Database/get.py' - Guild is None for 'roleLevel'")
272 | return
273 | try:
274 | if config['Database_Type'].lower() == "mongodb":
275 | server = levelling.find_one({"guild": guild.id})
276 | if server is None:
277 | print("Server Not Found!")
278 | return
279 | return server["role_levels"]
280 | elif config['Database_Type'].lower() == "local":
281 | db = sqlite3.connect("KumosLab/Database/Local/roles.sqlite")
282 | cursor = db.cursor()
283 | cursor.execute("SELECT role_levels FROM levelling WHERE guild_id = ?", (guild.id,))
284 | result = cursor.fetchall()
285 | if result is None:
286 | print("Server Not Found!")
287 | return
288 | cursor.close()
289 | # convert to an int array
290 | return [int(x[0]) for x in result]
291 |
292 | except Exception as e:
293 | print("Error in 'KumosLab/Database/get.py' - " + str(e))
294 | return
295 |
296 | async def talkchannels(guild: discord.Guild = None):
297 | if guild is None:
298 | print("Error in 'KumosLab/Database/get.py' - Guild is None for 'talkchannels'")
299 | return
300 | try:
301 | if config['Database_Type'].lower() == "mongodb":
302 | server = levelling.find_one({"guild": guild.id})
303 | if server is None:
304 | print("Server Not Found!")
305 | return
306 | return server["talkchannels"]
307 | elif config['Database_Type'].lower() == "local":
308 | db = sqlite3.connect("KumosLab/Database/Local/serverbase.sqlite")
309 | cursor = db.cursor()
310 | cursor.execute("SELECT talkchannels FROM levelling WHERE guild_id = ?", (guild.id,))
311 | result = cursor.fetchall()
312 | if result is None:
313 | print("Server Not Found!")
314 | return
315 | cursor.close()
316 | # convert to an int array
317 | return [x[0] for x in result]
318 |
319 | except Exception as e:
320 | print("Error in 'KumosLab/Database/get.py' - " + str(e))
321 | return
322 |
323 | async def clan(guild: discord.Guild = None, clan_Name: str = None):
324 | if guild is None:
325 | print("Error in 'KumosLab/Database/get.py' - Guild is None for 'clan'")
326 | return
327 | if clan_Name is None:
328 | print("Error in 'KumosLab/Database/get.py' - Clan Name is None for 'clan'")
329 | return
330 | try:
331 | if config['Database_Type'].lower() == "mongodb":
332 | server = levelling.find_one({"clans_guild": guild.id, "clan_name": clan_Name})
333 | if server is None:
334 | return "error"
335 | return server["clan_name"]
336 | elif config['Database_Type'].lower() == "local":
337 | db = sqlite3.connect("KumosLab/Database/Local/clans.sqlite")
338 | cursor = db.cursor()
339 | cursor.execute("SELECT clan_Name FROM levelling WHERE clans_guild = ? AND clan_name = ?", (guild.id, clan_Name))
340 | result = cursor.fetchone()
341 | if result is None:
342 | return "error"
343 | cursor.close()
344 | return result[0]
345 |
346 | except Exception as e:
347 | print("Error in 'KumosLab/Database/get.py' - " + str(e))
348 | return
349 |
350 | async def clanXP(guild: discord.Guild = None, clan_Name: str = None):
351 | if guild is None:
352 | print("Error in 'KumosLab/Database/get.py' - Guild is None for 'clanXP'")
353 | return
354 | if clan_Name is None:
355 | print("Error in 'KumosLab/Database/get.py' - Clan Name is None for 'clanXP'")
356 | return
357 | try:
358 | if config['Database_Type'].lower() == "mongodb":
359 | server = levelling.find_one({"clans_guild": guild.id, "clan_name": clan_Name})
360 | if server is None:
361 | return "error"
362 | return server["xp"]
363 | elif config['Database_Type'].lower() == "local":
364 | db = sqlite3.connect("KumosLab/Database/Local/clans.sqlite")
365 | cursor = db.cursor()
366 | cursor.execute("SELECT xp FROM levelling WHERE clans_guild = ? AND clan_name = ?", (guild.id, clan_Name))
367 | result = cursor.fetchone()
368 | if result is None:
369 | return "error"
370 | cursor.close()
371 | return result[0]
372 |
373 | except Exception as e:
374 | print("Error in 'KumosLab/Database/get.py' - " + str(e))
375 | return
376 |
377 | async def clanOwner(guild: discord.Guild = None, clan_Name: str = None):
378 | if guild is None:
379 | print("Error in 'KumosLab/Database/get.py' - Guild is None for 'clanXP'")
380 | return
381 | if clan_Name is None:
382 | print("Error in 'KumosLab/Database/get.py' - Clan Name is None for 'clanXP'")
383 | return
384 | try:
385 | if config['Database_Type'].lower() == "mongodb":
386 | server = levelling.find_one({"clans_guild": guild.id, "clan_name": clan_Name})
387 | if server is None:
388 | return "error"
389 | return server["owner"]
390 | elif config['Database_Type'].lower() == "local":
391 | db = sqlite3.connect("KumosLab/Database/Local/clans.sqlite")
392 | cursor = db.cursor()
393 | cursor.execute("SELECT owner FROM levelling WHERE clans_guild = ? AND clan_name = ?", (guild.id, clan_Name))
394 | result = cursor.fetchone()
395 | if result is None:
396 | return "error"
397 | cursor.close()
398 | client = discord.Client()
399 | return client.get_user(result[0])
400 |
401 | except Exception as e:
402 | print("Error in 'KumosLab/Database/get.py' - " + str(e))
403 | return
404 |
405 | async def clanLevel(guild: discord.Guild = None, clan_Name: str = None):
406 | if guild is None:
407 | print("Error in 'KumosLab/Database/get.py' - Guild is None for 'clanXP'")
408 | return
409 | if clan_Name is None:
410 | print("Error in 'KumosLab/Database/get.py' - Clan Name is None for 'clanXP'")
411 | return
412 | try:
413 | if config['Database_Type'].lower() == "mongodb":
414 | server = levelling.find_one({"clans_guild": guild.id, "clan_name": clan_Name})
415 | if server is None:
416 | return "error"
417 | return server["level"]
418 | elif config['Database_Type'].lower() == "local":
419 | db = sqlite3.connect("KumosLab/Database/Local/clans.sqlite")
420 | cursor = db.cursor()
421 | cursor.execute("SELECT level FROM levelling WHERE clans_guild = ? AND clan_name = ?", (guild.id, clan_Name))
422 | result = cursor.fetchone()
423 | if result is None:
424 | return "error"
425 | cursor.close()
426 | return result[0]
427 |
428 | except Exception as e:
429 | print("Error in 'KumosLab/Database/get.py' - " + str(e))
430 | return
431 |
432 | async def clanLogo(guild: discord.Guild = None, clan_Name: str = None):
433 | if guild is None:
434 | print("Error in 'KumosLab/Database/get.py' - Guild is None for 'clanXP'")
435 | return
436 | if clan_Name is None:
437 | print("Error in 'KumosLab/Database/get.py' - Clan Name is None for 'clanXP'")
438 | return
439 | try:
440 | if config['Database_Type'].lower() == "mongodb":
441 | server = levelling.find_one({"clans_guild": guild.id, "clan_name": clan_Name})
442 | if server is None:
443 | return "error"
444 | return server["logo"]
445 | elif config['Database_Type'].lower() == "local":
446 | db = sqlite3.connect("KumosLab/Database/Local/clans.sqlite")
447 | cursor = db.cursor()
448 | cursor.execute("SELECT logo FROM levelling WHERE clans_guild = ? AND clan_name = ?", (guild.id, clan_Name))
449 | result = cursor.fetchone()
450 | if result is None:
451 | return "error"
452 | cursor.close()
453 | return result[0]
454 |
455 | except Exception as e:
456 | print("Error in 'KumosLab/Database/get.py' - " + str(e))
457 | return
458 |
459 | async def clanColour(guild: discord.Guild = None, clan_Name: str = None):
460 | if guild is None:
461 | print("Error in 'KumosLab/Database/get.py' - Guild is None for 'clanXP'")
462 | return
463 | if clan_Name is None:
464 | print("Error in 'KumosLab/Database/get.py' - Clan Name is None for 'clanXP'")
465 | return
466 | try:
467 | if config['Database_Type'].lower() == "mongodb":
468 | server = levelling.find_one({"clans_guild": guild.id, "clan_name": clan_Name})
469 | if server is None:
470 | return "error"
471 | return server["colour"]
472 | elif config['Database_Type'].lower() == "local":
473 | db = sqlite3.connect("KumosLab/Database/Local/clans.sqlite")
474 | cursor = db.cursor()
475 | cursor.execute("SELECT colour FROM levelling WHERE clans_guild = ? AND clan_name = ?", (guild.id, clan_Name))
476 | result = cursor.fetchone()
477 | if result is None:
478 | return "error"
479 | cursor.close()
480 | return result[0]
481 |
482 | except Exception as e:
483 | print("Error in 'KumosLab/Database/get.py' - " + str(e))
484 | return
485 |
486 | async def clanMembers(guild: discord.Guild = None, clan_Name: str = None):
487 | if guild is None:
488 | print("Error in 'KumosLab/Database/get.py' - Guild is None for 'clanXP'")
489 | return
490 | if clan_Name is None:
491 | print("Error in 'KumosLab/Database/get.py' - Clan Name is None for 'clanXP'")
492 | return
493 | try:
494 | if config['Database_Type'].lower() == "mongodb":
495 | server = levelling.find_one({"clans_guild": guild.id, "clan_name": clan_Name})
496 | if server is None:
497 | return "error"
498 | return server["members"]
499 | elif config['Database_Type'].lower() == "local":
500 | db = sqlite3.connect("KumosLab/Database/Local/clans.sqlite")
501 | cursor = db.cursor()
502 | cursor.execute("SELECT members FROM levelling WHERE clans_guild = ? AND clan_name = ?", (guild.id, clan_Name))
503 | result = cursor.fetchone()
504 | if result is None:
505 | return "error"
506 | cursor.close()
507 | return result[0]
508 |
509 | except Exception as e:
510 | print("Error in 'KumosLab/Database/get.py' - " + str(e))
511 | return
512 |
513 | async def latestVersion():
514 | with urllib.request.urlopen("https://api.github.com/repos/KumosLab/Discord-Levels-Bot/releases/latest") as url:
515 | data = json.loads(url.read().decode())
516 | return data["tag_name"]
517 |
518 |
519 |
520 |
521 |
522 |
--------------------------------------------------------------------------------