How to add warn count to warn command with sqlite? - python

So im trying to make a warn command using sqlite3
everything is fine
it warns them and stores the reason, guild id and user id in the database
but i want to check for how many warns the user got using sqlite3
i tried so many things but nothing worked
any type of help will be appreciated!..
my code :-
import discord
from discord.ext import commands
import sqlite3
class warn(commands.Cog):
def __init__(self, bot):
self.bot = bot
#commands.command()
async def warn(self, ctx, member: discord.Member, reason=None):
db = sqlite3.connect("warn.db")
cursor = db.cursor()
sql = ("INSERT INTO main (user_id, reason, guild) VALUES (?, ?, ?)")
val = (member.id, reason, ctx.guild.id)
cursor.execute(sql, val)
em = discord.Embed(
description=f"<:zztick:1067013663535411280> | warned **{member.mention}** for the reason: *{reason}*",
color=0x2F3136
)
em.set_footer(text=f"warn no. {DO SOMETHING}")
await ctx.send(embed=em)
db.commit()
db.close()
async def setup(bot):
await bot.add_cog(warn(bot))
thanks for reading...

You can do something like this:
#commands.command()
async def warn(self, ctx, member: discord.Member, reason=None):
db = sqlite3.connect("warn.db")
cursor = db.cursor()
# Just for checking if user already exists in table
check_user_sql = ("SELECT COUNT(*) FROM main WHERE user_id = ? AND guild = ?")
check_user_val = (member.id, ctx.guild.id)
cursor.execute(check_user_sql, check_user_val)
user_exists = cursor.fetchone()[0]
if user_exists:
# If user exists in table, it will update their warn count
update_warn_count_sql = ("UPDATE main SET warn_count = warn_count + 1 WHERE user_id = ? AND guild = ?")
cursor.execute(update_warn_count_sql, check_user_val)
else:
# If user not exists, insert a new row with a warn count of 0
insert_user_sql = ("INSERT INTO main (user_id, reason, guild, warn_count) VALUES (?, ?, ?, 0)")
insert_user_val = (member.id, reason, ctx.guild.id)
cursor.execute(insert_user_sql, insert_user_val)
# To get current warn count of user
warn_count_sql = ("SELECT warn_count FROM main WHERE user_id = ? AND guild = ?")
cursor.execute(warn_count_sql, check_user_val)
warn_count = cursor.fetchone()[0]

Related

Nothing gets put into the database nor any message is sent. Have any ideas?

#commands.command()
async def Money(self, ctx, member:discord.Member):
member = ctx.message.author.name
member_id = ctx.message.author.id
db = sqlite3.connect("main.sqlite")
cursor = db.cursor()
cursor.execute(f"SELECT member_id FROM main WHERE member_id = {member_id}")
result = cursor.fetchone()
if result is None:
sql = (f"INSERT INTO main(member_id, money) VALUES(?,?)")
val = (member_id, 500)
cursor.execute(sql, val)
db.commit()
await ctx.send("Because you didn't have an account, I just made one for you!")
else:
embed = discord.Embed(title = f"{member}'s Money", description = f"{result[1]} <:BitCoin:929595745500274689>", color = discord.Colour.random)
await ctx.send(embed=embed)
cursor.close()
db.close()
Nothing gets put into the database nor any message is sent. The command seems to fail.

sqlite3 can't get database to stay updated

This is for a discord bot to store a users game data. As long as the bot never goes off this works, but if I turn it off, it re-initializes the database. I've tried commenting out the initial user insertion similarly to how I commented out the creation of the database itself, but this makes the reference to "row" in line 57 not work correctly.
import discord
import os
import sqlite3
conn = sqlite3.connect('test.db')
print("Opened database successfully")
#CREATED DATABASE
#conn.execute('''CREATE TABLE MEMBERS
# (ID INT NOT NULL,
# NAME TEXT NOT NULL,
# LEVEL INT NOT NULL,
# CP INT,
# CLASS CHAR(25))''')
#print ("Table created successfully")
#INSERT USER
conn.execute("INSERT INTO MEMBERS (ID,NAME,LEVEL,CP,CLASS) \
VALUES (229039794787713025, 'Solumn', 125, 5525391, 'Mage')");
conn.execute("INSERT INTO MEMBERS (ID,NAME,LEVEL,CP,CLASS) \
VALUES (624678639778267136, 'SacredPugsly', 0, 0, 'None')");
conn.execute("INSERT INTO MEMBERS (ID,NAME,LEVEL,CP,CLASS) \
VALUES (159985870458322944, 'Noxis', 124, 10, 'Huntard')");
bot = discord.Client()
#bot.event
async def on_ready():
guild_count = 0
for guild in bot.guilds:
print(f"- {guild.id} (name: {guild.name})")
guild_count = guild_count + 1
print("AlienBot is in " + str(guild_count) + " servers.")
def check(message):
try:
int(message.content)
return True
except ValueError:
return False
#bot.event
async def on_message(message):
#debug to check user ID'set
print(message.author.id)
if message.content.startswith('!show'):
#SELECT USER
cursor = conn.execute("SELECT * from MEMBERS WHERE id=?", (message.author.id,))
for row in cursor:
print ("ID = ", row[0])
response = discord.Embed(title=row[1],color=0x3498db)
response.add_field(name="Level", value=row[2], inline=False)
response.add_field(name="CP", value=row[3], inline=False)
response.add_field(name="Class", value=row[4], inline=False)
await message.channel.send(embed=response)
if message.content.startswith('!updatecp'):
await message.channel.send("Enter your CP")
cp = await bot.wait_for('message',timeout = 60, check=check)
attempt = int(cp.content)
cursor = conn.execute("UPDATE MEMBERS SET cp=? WHERE id=?", (int(attempt),message.author.id))
if message.content.startswith('!updatelevel'):
await message.channel.send("Enter your Level")
lvl = await bot.wait_for('message',timeout = 60, check=check)
attempt = int(lvl.content)
cursor = conn.execute("UPDATE MEMBERS SET LEVEL=? WHERE id=?", (attempt, message.author.id))
if message.content.startswith('!help'):
response = discord.Embed(title='Bot Commands',color=0x3498db)
response.add_field(name="!updatecp", value='Allows you to adjust your CP', inline=False)
response.add_field(name="!updatelevel", value='Allows you to adjust your level', inline=False)
response.add_field(name="!show", value='Shows you your character data', inline=False)
await message.channel.send(embed=response)
#conn.close()
from dotenv import load_dotenv
load_dotenv()
bot.run(os.getenv("DISCORD_TOKEN"))```
You never seem to commit your written data. Either do conn.commit() after inserting or set your connections isolation_level to None.
Documentation

How to setup on_message with sqlite3 in discord.py?

Hi I created the following event. It takes input one time after that it stores the guild id , channel id and role id in sqlite db . After that when someone in that particular guild mentions minimum 3 users in a particular channel , the bot gives them new role.
class ScrimsCog(commands.Cog, name='Scrims-Commands') :
def __init__(self,bot):
self.bot = bot
#commands.Cog.listener()
async def on_message(self, message):
if message.guild:
db = sqlite3.connect('main.sqlite')
cursor = db.cursor()
cursor.execute(
f"SELECT * FROM main WHERE guild_id = ?", (message.guild.id, ))
result = cursor.fetchone()
if result:
channel = self.bot.get_channel(result[2])
role = message.guild.get_role(result[1])
if role:
if message.channel == channel:
if len(message.mentions) >= 3:
await message.add_reaction(emoji="<a:tick:748476262640779276>")
user = message.author
await user.add_roles(role)
await self.bot.process_commands(message)
#commands.group(invoke_without_command=True)
async def scrimsmod(self,ctx):
await ctx.send('Available Setup Commands: \nscrimsmod channel <#channel>\nscrimsmod role <message>')
#scrimsmod.command()
async def channel(self, ctx, channel:discord.TextChannel):
if ctx.message.author.guild_permissions.manage_messages:
db = sqlite3.connect('main.sqlite')
cursor = db.cursor()
cursor.execute(f"SELECT channel_id FROM main WHERE guild_id = {ctx.guild.id}")
result = cursor.fetchone()
if result is None:
sql = ("INSERT INTO main(guild_id, channel_id) VALUES(?,?)")
val = (ctx.guild.id, channel.id)
await ctx.send(f" Default Registration Channel has been set to {channel.mention}")
elif result is not None:
sql = ("UPDATE main SET channel_id = ? WHERE guild_id = ?")
val = (channel.id, ctx.guild.id)
await ctx.send(f"Default Registration Channel has been updated to {channel.mention}")
cursor.execute(sql, val)
db.commit()
cursor.close()
db.close()
#scrimsmod.command()
async def role(self, ctx,role: discord.Role):
if ctx.message.author.guild_permissions.manage_messages:
db = sqlite3.connect('main.sqlite')
cursor = db.cursor()
cursor.execute(f"SELECT role FROM main WHERE guild_id = {ctx.guild.id}")
result = cursor.fetchone()
if result is None:
sql = ("INSERT INTO main(guild_id, role) VALUES(?,?)")
val = (ctx.guild.id, role.id)
await ctx.send(f"Default role to give on correct registration have been set to `{role}`")
elif result is not None:
sql = ("UPDATE main SET role = ? WHERE guild_id = ?")
val = (role.id, ctx.guild.id)
await ctx.send(f"Default role to give on correct registration have been updated to `{role}`")
cursor.execute(sql, val)
db.commit()
cursor.close()
db.close()
Well, I believe the code is fine it doesn't throw any error . The issue is that it perfectly take input without any error but doesn't store it into db.
I believe the problem is with my db,
code -
db = sqlite3.connect('main.sqlite',timeout=10)
cursor = db.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS main(
guild_id INTEGER,
role INTEGER,
channel_id INTEGER
)
''')
I believe the problem is here , I should take TEXT in place INTEGER but I am not sure. Answer me with What do you I am doing wrong and how should I fix that.
I answered your last question with assuming that role and channel is TEXT type in the table and that answer should've solve your problem. If you change them, it will work fine and also it will be more efficient if you define the database variable and cursor on top of the on_message event just for once. So you don't have do connect to the database everytime.

Optimizing Python SQL result loop

I have the following working code:
async def loadnames(self, ctx):
"""
Load the current alias of every member in the database.
Useful after joining a new guild or after a long downtime.
"""
async with ctx.message.channel.typing():
message = await ctx.send(f'Adding members to the database... {ctx.author.mention}')
db = await aiomysql.connect(host=globals.mysql_host,user=globals.mysql_user,password=globals.mysql_passwd,db=globals.mysql_db)
cur = await db.cursor()
#await cur.execute("SELECT discord,name FROM aliases WHERE discord=%s AND name=%s", (member.id,str(member)))
#result = await cur.fetchall()
count = 0
for member in ctx.guild.members:
try:
result = await cur.execute("SELECT * FROM aliases WHERE discord=%s AND name=%s", (member.id,str(member)))
if result == 0:
count = count + 1
await cur.execute("INSERT INTO aliases (discord,name) VALUES(%s,%s)", (member.id,str(member)))
await db.commit()
except:
await ctx.send(f'Error adding `{member}`! {ctx.author.mention}')
await cur.close()
db.close()
await message.edit(content=f'{count} members added to the database! {ctx.author.mention}')
Now, this works perfectly fine, the only issue I see with this is that I'm executing a new SELECT query for every iteration of my loop. So I'd like to put the SELECT statement outside of the loop, using cur.fetchall() to put it in a list (see commented lines in the code above), but I don't know after that how to check if a pair of (member.id,str(member)) is in my results.
Consider a single insert-select query in loop using the well know duplicate avoidance in SQL: NOT IN vs. NOT EXISTS vs. LEFT JOIN / IS NULL. Below runs the LEFT JOIN / IS NULL approach:
for member in ctx.guild.members:
try:
sql = """INSERT INTO aliases (discord, name)
SELECT a1.discord, a1.name
FROM aliases a1
LEFT JOIN aliases a2
ON a1.discord = a2.discord
AND a1.name = a2.name
AND a1.discord=%s AND a2.name=%s
WHERE a2.name IS NULL AND a2.discord IS NULL
"""
result = await cur.execute(sql, (member.id, str(member)))
count = cur.rowcount
await db.commit()
except:
await ctx.send(f'Error adding `{member}`! {ctx.author.mention}')
Even better, populate member IDs in a temp table and join to above query for only one query for all member IDs. SQL's set-based processing beats out application layer looping!
# CLEAN AND POPULATE TEMP TABLE
await cur.execute("DELETE FROM mytempTable")
members_list = [(member.id, str(member)) for member in ctx.guild.members]
await cur.executemany("INSERT INTO mytempTable (discord, name) VALUES (%s, %s)",
members_list)
await db.commit()
# ONLY ONE INSERT QUERY
sql = """INSERT INTO aliases (discord, name)
SELECT a1.discord, a1.name
FROM aliases a1
INNER JOIN mytempTable t
ON a1.discord = t.discord
AND a1.name = t.name
LEFT JOIN aliases a2
ON a1.discord = a2.discord
AND a1.name = a2.name
WHERE a2.name IS NULL AND a2.discord IS NULL
"""
result = await cur.execute(sql, (member.id, str(member)))
count = cur.rowcount
await db.commit()
Derived from Parfait's answer, I ended up with this:
async def loadnames(self, ctx):
"""
Load the current alias of every member in the database.
Useful after joining a new guild or after a long downtime.
"""
async with ctx.message.channel.typing():
count = 0
message = await ctx.send(f'Adding members to the database... {ctx.author.mention}')
db = await aiomysql.connect(host=globals.mysql_host,user=globals.mysql_user,password=globals.mysql_passwd,db=globals.mysql_db)
cur = await db.cursor()
await cur.execute("SELECT discord, name FROM aliases")
result = await cur.fetchall()
new_member_list = [(member.id, str(member)) for member in ctx.guild.members]
member_list = [(member[0],member[1]) for member in result]
diff_list = [member for member in new_member_list if member not in member_list]
count = await cur.executemany("INSERT INTO aliases (discord, name) VALUES (%s, %s)", diff_list)
await db.commit()
await cur.close()
db.close()
if count is None: count = 0
await message.edit(content=f'{count} members added to the database! {ctx.author.mention}')
Only one SELECT query at the beginning, then we play with the different lists to get the executemany INSERT statement which will do only the required number of insertions.

How can I tag a member in my python discord bot

So I have this leveling system in python but I wanna add an #tag so the bot mentions the member that leveled up... But I got no idea how. I already tried multiple things but they all don't work.
from discord.ext import commands
import discord
import logging
import yaml
import sqlite3
import time
import random
import re
logging.basicConfig(level=logging.INFO)
bot = commands.Bot(command_prefix='l>', description='Hype Levels')
def threshold(n):
level_threshold = 5*(n**2)+50*n+100
return level_threshold
#bot.command(pass_context=True)
async def rank(ctx):
try:
_, member = (ctx.message.content).split(' ', 1)
member = re.sub("[^0-9]", "", member)
except:
member = ctx.message.author.id
db = sqlite3.connect('users.db')
c = db.cursor()
c.execute('SELECT user.*, (SELECT count(*) FROM users AS members WHERE members.rawexp > user.rawexp) as Rank FROM users AS user WHERE id = ?',
(ctx.message.author.id, ))
user = c.fetchone()
db.close()
rank = str(user[6] + 1)
embed = discord.Embed(title='{}\'s Information'.format(ctx.message.author.name)) \
.set_thumbnail(url=ctx.message.author.avatar_url) \
.add_field(name='Rank', value='#' + rank) \
.add_field(name='Level', value=user[2]) \
.add_field(name='EXP', value='{}/{}'.format(user[3], threshold(user[2]))) \
.add_field(name='Raw EXP', value=user[4]) \
await ctx.send(embed=embed)
#bot.event
async def on_message(message):
if message.author == bot.user:
return
if message.author.bot:
return
if message.content.startswith('l>'):
await bot.process_commands(message)
return
db = sqlite3.connect('users.db')
c = db.cursor()
c.execute('SELECT * FROM users WHERE id= ?', (message.author.id,))
user = c.fetchone()
if user is None:
await message.channel.send('Looks like you\'re new! Welcome to level 1. Initializing player...')
c.execute('INSERT INTO users(id, name, level, exp, rawexp, time) VALUES(?,?,?,?,?,?)', (message.author.id, message.author.name, 1, 0, 0, time.time()))
db.commit()
db.close()
return
if message.author.name != user[1]:
c.execute('UPDATE users SET name = ? WHERE id= ?', (message.author.name, message.author.id))
if (time.time() - user[5]) > 60:
addedexp = random.randint(10, 25)
exp = user[3] + addedexp
rawexp = user[4] + addedexp
c.execute('UPDATE users SET exp = ?, rawexp = ?, name = ?, time = ? WHERE id= ?', (exp, rawexp, message.author.name, time.time(), message.author.id))
if (exp > threshold(user[2])):
level = user[2] + 1
c.execute('UPDATE users SET exp = ?, level = ? WHERE id= ?', (0, level, message.author.id))
await message.channel.send('Wowza! You leveled up! Your level is now **{}**.'.format(level))
db.commit()
db.close()
await bot.process_commands(message)
#bot.event
async def on_ready():
print("HypeLevels V1.1")
print("Made by: Garbodonk#6347")
print("Bot Name: " + str(bot.user.name))
print("Bot ID: " + str(bot.user.id))
await bot.change_presence(activity=discord.Streaming(name='some HYPE', url="https://www.twitch.tv/hypepixelbot", type=1))
#Initialize database.
db = sqlite3.connect('users.db')
c = db.cursor()
c.execute('CREATE TABLE IF NOT EXISTS users(id INTEGER PRIMARY KEY, name TEXT, level INT, exp INTEGER, rawexp INTEGER, time REAL)')
db.commit()
bot.run('Token')
But I want to add an #tag when people level up so they get tagged
if (exp > threshold(user[2])):
level = user[2] + 1
c.execute('UPDATE users SET exp = ?, level = ? WHERE id= ?', (0, level, message.author.id))
await message.channel.send('Wowza! You leveled up! Your level is now **{}**.'.format(level))
anyone who knows how to do this? To ask me questions or something just add me on discord: Garbodonk#6347
async def command(ctx, member : discord.Member, *, reason=None) :
await ctx.send(f" can place text here if you want {member.mention} can place text here as well")```
I hope this helps.

Categories