Let me explain:
if config == "create":
if str(user.id) in submissions:
await ctx.send(embed=discord.Embed(title="ERROR", description='you already have a submission!', color=discord.Color.red()))
return
if len(submission_full) > 2 and len(submission_full) < 100:
submissions[str(user.id)] = {}
submissions[str(user.id)]["submission"] = submission_full
Basically what I have here is a discordpy submission command that creates a submission and dumps it into a json file. I am currently working on a command that does the same thing but reversed, so it deletes your submission if you want to undo.
My first thought was doing this:
if config.lower() in ["delete","remove","undo","cancel"]:
await ctx.send(embed=discord.Embed(title="Removing Current Submission..", description="You will no longer have any submissions. You can create a new one at any time!", color=0xFFD700))
submissions[str(user.id)] = None
But it simply replaces your submission with "null".
Here is the output in the json file:
{"710826704259645450": null}
Help appreciated!
You want:
del submissions[str(user.id)]
You can use :
submissions.pop(str(user.id))
And then dump it
Related
What I'm trying to do: I had some people abuse my bot's commands, so I wanted to put a stop to this. Therefore, after reviewing multiple sources of code, I got as far as inserting member ids into a .txt document.
My problem: My 'custom check' has been having errors. All the custom check examples that I had found were in cogs or were not related to what I was trying to do, therefore I haven't gotten mine to work as expected yet. Note that I am not using cogs, either.
Code:
def blacklist(ctx): # this is the def used for the check, it reads the .txt file for user
file = open("blacklist.txt", "r")
members_banned = file.readlines()
if str(ctx.author.id) not in members_banned:
return ctx.author.id not in members_banned
#client.command() # this command is used for adding people to the blacklist. This is most likely not the problem..
#commands.is_owner()
async def blacklist(ctx, member: discord.Member):
file = open("blacklist.txt", "r")
anything = False
while anything == False:
content = file.read()
things = content.split("\n")
for line in things:
if str(line) == str(member.id):
await ctx.send(f"{member.name} is already in blacklist, please remove manually!")
anything = True
else:
pass
if anything == False:
thing = open("blacklist.txt", "a")
thing.write(f"\n{member.id}")
thing.close()
anything = True
await ctx.send(f"{ctx.author.mention}: {member.name} has been blacklisted, hopefully")
file.close()
break
#client.command()
#commands.check(blacklist) # This is the code I used to test the custom check for the blacklist
async def bltest(ctx):
await ctx.send("Cool, you're not blacklisted")
Errors: (via this code)
return await self.callback(*args, **kwargs)
TypeError: blacklist() missing 1 required positional argument: 'member'
The above error doesn't make any sense to me.
Others:
The .txt file
Other code I have looked at:
Code found after looking through previous questions asked in the discord.py server
Code found while trying to look for check examples, this is in a cog
The discord.py documentation
Both of your functions have the same name. The command is named blacklist with the ctx and member parameter, while the function's name is blacklist with just ctx as a parameter. This means if the wrong one is chosen, you're calling a function that expects 2 arguments & only giving it 1.
Give the first function (the one that reads the file) a different name, like "check_blacklist" or "blacklisted" or whatever suits you best.
As it says in the error in the first line of code add member as an argument to the function blacklist. You need it because in this function you are dealing with member of the discord server.
So i'm making some scoring system type thing in python with json and discord.py, this is its code:
import json
def getPoints(bot, user):
f = open('points.json', 'r')
points = json.load(f)
name = str(user)
f.close()
return points.get(name)
#later on down the line
#bot.group()
async def pointSystem(ctx):
pass
#pointSystem.command()
async def enable(ctx):
f = open('points.json', 'r')
points = json.load(f)
if points.get(str(ctx.author)) != None:
await ctx.send('Already enabled for this user!')
return
io = await ui.prompt(ctx, 'This command enables the point system\nAre you sure you want to enable this?')
if io == 'yes':
await ctx.send('Ok, enabling...')
points[str(ctx.author)] = 0
f.close()
f = open('points.json', 'w')
json.dump(points, f, indent=4)
f.close()
await ctx.send('Enabled for this user!')
else:
await ctx.send('Alright, stopping command execution...')
f.close()
in points.json i should have:
{}
And that's what i put in there originally, but sometimes, i look into points.json and i see a string with some random word in it. It doesn't give an error of any kind, it just does what i described, which doesn't make much sense, because i don't think i have any code that would set it to a string of any kind. I have no reproduction code, as i don't know the real culprit of this problem, i would point you towards doing something like what i did, which is creating a discord bot with this scoring system thing, but i don't really think even that would reproduce it.
Edit: Okay, this is getting really weird. 3 months later, with completely new code, I still have a file named "points.json" in my root directory, and it contains the random string I mentioned above, that literally makes no sense. Even when I remove it, a couple weeks later it will come back.
I recently made a command that saves the information into a JSON file. So basically, I have 2 commands, first command sets the global variable, and the second command uses the variables provided to add into the JSON file. And once I tested it, it saves the text as a global variable, and then it saved into the JSON file as {'test'}. I don't want the {''}, so is there a way to don't have {''}, only the text test?
Script:
#global variables
namereg = None
cbreg = None #more
bdreg = None
descreg = None
libreg = None
invreg = None
btreg = None
ssreg = None
slugreg = None
#client.command(pass_context=True)
async def namereg(ctx, *, arg):
global namereg
namereg = {arg}
embed = discord.Embed(title='Registed Name.',description=f'Set the name as {arg}',colour=discord.Color.dark_green())
print(f'{arg}')
await ctx.send(embed = embed)
#client.command(pass_context=True)
async def add(ctx):
role_names = [role.name for role in ctx.message.author.roles]
if "Server Moderator" in role_names:
def write_json(data, filename='bots.json'):
with open (filename, "w") as f:
json.dump(data, f, indent=4)
with open ('bots.json') as json_file:
data = json.load(json_file)
temp = data["bots"]
y = {"name": f"{namereg}"}
temp.append(y)
write_json(data)
embed = discord.Embed(title='Added!',description='Successfully added with the following!',timestamp=ctx.message.created_at,colour=discord.Color.dark_green())
await ctx.send(embed = embed)
If there is a way to not have {''}, please reply to this thread! Thank you.
If you're writing it to a JSON file, the quotes will be added every time as part of JSON syntax. If you just need to write a dictionary to a file (which is also readable), you can write it to a normal .txt file.
Issues:
namereg = None
#client.command(pass_context=True)
async def namereg(ctx, *, arg):
global namereg
This is broken. Functions at the top level of your code are global variables, and are in the same namespace. Give it a different name from the storage variable.
namereg = {arg}
This takes the string that came from the user's input, and creates a set with a single element. That is not what you want. You wanted the input string to be the registered name, so just assign it directly.
y = {"name": f"{namereg}"}
I assume you did this fancy formatting because you were getting an error before (because the json will not serialize sets by default, because the JSON data format does not have a direct way to represent them). You should have listened to this error message more closely, by questioning why you had data of the invalid type in the first place. The {} and '' in your output come from the string representation of the set that you stringify using the string formatting. The plain string that you want to use does not require any formatting to convert to string, because it is already a string.
I am new to python.
Tell me how to implement saving the value of a variable to a file so that you don't receive unnecessary notifications when the program is restarted.
The program pings the servers and sends a message when the status changes. When you restart the program, it does not save the history of its checks. It is very uncomfortable.
I hope I explained the problem correctly?
I need to constantly save the check result to a file and use this data when comparing new checks.
def ping_host(address):
status = ping_url(address.address)
if status != address.status:
send_message(( "! " if status is None else "+ " if status else
"- ") + address.comment)
address.status = status
This function checks the status, if it has changed, then a new message is sent.
If your file does not need to be portable the simplest solution is to use python pickling. The drawback is that you cannot inspect the file manually or modify it for debuging purpose vs text based saving (eg ini files, json or simple txt). The main advantage is the ease of use as you can serialyze this way any python basic type.
Here is a simple example on how to use it:
import pickle
def get_status():
with open('status','rb') as f:
status = pickle.load(f)
return status
def set_status(status:bool):
with open('status','wb') as f:
pickle.dump(status,f)
set_status(True)
s = get_status()
assert s
set_status(False)
s = get_status()
assert not s
You can make a file history.txt, and then on startup open it, and read the last state, and if its different overwrite that state in the file and save.
from what you wrote in comments I would change it to this:
import json
ping_data = dict()
with open('C:\ping_data.json') as file:
data = json.load(file)
def ping_host(address):
status = ping_url(address.address)
if data['address.status'] != status:
ping_data['address.status'] = status
send_message(("! " if status is None else "+ " if status else "- ") + address.comment)
ping_host(youraddress)
with open('C:\ping_data.json', 'w') as file:
json.dump(ping_data, file, indent=2)
the way I would do this is using json library
import json
next thing I would create a dictionary in your script
saved_data = dict()
then whenever I receive an update I would store the value in dictionary
saved_data['info'] = updated_info
and export? it to a json file
with open('saved_data.json', 'w') as file:
json.dump(saved_data, file, indent=2)
now whenever I open the program it would read that file like this
with open('saved_data.json') as file:
data = json.load(file)
and then I would access variable data as a dictionary
for k in data:
for info in data[k]:
if info != updated_info
saved_data['info'] = updated_info
I am currently writing a program in Python that asks if you have a log in. If no, they proceed to create a username and password. If yes, they log in and their details are checked against a text file. The text file looks like this (Username then password):
whitehallj27
EXpass%20
Username2
EXPASSWORD%%%
james_27
password1234
I am trying to figure out a way of programming this as simply as possible. It seems to work, but isn't nearly as simple and doesn't really work how I thought it would. Here is the code snippet:
logins={}
usernames_passwords=open("UsernamesAndPasswords.txt","r")
count=0
for line in usernames_passwords:
count=count+1
count=count/2
usernames_passwords.close()
usernames_passwords=open("UsernamesAndPasswords.txt","r")
try:
for x in range(count):
username=usernames_passwords.readline()
password=usernames_passwords.readline()
logins[username]=password
except TypeError:
count=int(count+0.5)
for x in range(count):
username=usernames_passwords.readline()
password=usernames_passwords.readline()
logins[username]=password
usernames_passwords.close()
print(logins)
Also, how would I go about authenticating the username and password to check it's correct.
Many thanks,
James Duxbury
Assuming that variables user and passwd have the username and password provided by the user, then just read the file in two lines:
file_contents = []
with open("UsernamesAndPasswords.txt","r") as f: #use "with", it will auotamtically close the file
file_contents = f.readlines()
usernames = file_contents[0::2] #step by 2, take all elements starting at index 0
passwords = file_contents[1::2] #step by 2, take all elements starting at index 1
found_at_index = -1
for i in range(0,len(usernames)):
if user == usernames[i] and passwd == passwrods[i]:
found_at_index = i
break
if found_at_index >= 0 :
#do whatever you want, there is match
else:
#I don't know what you wanted to do in this case
Please read this for the with keyword and this for how to read a file nicelly.
Also this about the [::] syntax.
You could create a dictionary with the user names and passwords like this:
dict = {
'user-name': 'password-hashing',
'another-user': 'another-password'
}
after you've done it you can save this dict in a json file, and load its content when the user asks for login.
the docs for handling json files with python: https://docs.python.org/3/library/json.html
obs.: it will look simpler, but its not the best way of doing this king of thing