#dev-contrib
1 messages · Page 75 of 1
Caveat* based on the description saying it could be an invalid message, it probably returns the last message received, not the actual last message in the channel
Since we want it to be a rather inexpensive operation that might be the way to go, although some verification might be necessary to make sure you're not editing the wrong message
how could i handle that?
the existing #❓|how-to-get-help is sent by a webhook, not the python bot
If it’s not available, just manually fetch it from all messages?
all messages in channel.history?
hmm yeah, so editing will fail if it's the wrong message
yep
So I'd try and see where it leads you. If you can't fetch the message ID you'll probably need to look at the channel history
In this case the message limit doesn't really matter
but I'd set it to 1 or something anyway
message = await channel.fetch_message(channel.last_message_id)
channels = _channel.get_category_channels(constants.Categories.help_available)
string = AVAILABLE_CHANNELS_MESSAGE.format(len(channels), ", ".join(channels))
# Attempt to get the message from channel.history if last_message_id fails.
if message is None:
history = await channel.history()
message = await history.flatten()[0]
# Edit the message if it exists, send it if it doesn't.
if message is None:
log.info("Couldn't fetch the latest message in the help instructions message; creating one.")
await channel.send(string)
else:
await message.edit(string)
does this look good? now im just looking through the source code for functions i can use for the .format() in line 2
i think i got it one sec
this is AVAILABLE_CHANNELS_MESSAGE:
AVAILABLE_CHANNELS_MESSAGE = """
There are currently {} help channels available: {}
"""
also should i be doing it in get_available_candidate? sorry for all the questions this is my first contribution to the repo lol
I didn't dive too deeply into that cog, but I think you can get the channel ID while it's being moved from dormant. That would also be what triggers the change. Also those two channels aren't the only thing there, there's also the cooldown channel
ah right
so i would have to filter the cooldown channel from the output of _channel.get_category_channels?
yes, but I would try and see if I can avoid getting all the channels in the category, since you really only need to know which channel was removed and which is being added, which happens when a help session begins.
It might not be necessarily possible, but that's something I would try to achieve before fetching the category
wait but i need to know all the channels in the category, not necessarily the ones that have been added/removed
If you store which channels are there when the bot starts, then you only need to know the changes
hm
I would try and see if I can avoid getting all the channels in the category
why though?
i don't see the benefit
Because if it's going to be edited often, it would be nice to limit it to one API call
It's marked as beginner level, so that might not have been the intention
how would i get the channel being added/removed to/from the available category then?
i don't think im doing it in the right function
you have the on_message event where you can see which channel is being moved to occupied, and at the bottom you move another channel to available
The move to available has the assumption that it might wait indefinitely to do that, so it's possible this will require two edits
Make sure to run the entire bot, not just your file
Do so by going up to the bot directory
And running pipenv run
The instructions should be in the setup guide on the website
@clever wraith In addition, you'll need to run the package as a module. From the root directory of the repository, run python -m bot or pipenv run start (if you're using pipenv to manage the virtual environment).
Hey so I had an idea for the help channels, instead of it being initialized when the cog is loaded, why not make a command which
Activates the help channels,
Deactivates the help channels,
And a command which gets all the help channels no matter which category they are in and moves them back to dormant.
Why though?
Like, what benefits/disadvantages would that have over the current system, and what might the process look like for a user?
It wouldn't change anything for the user, but in certain situations in which the help channels are displaced, i feel like would be reliable on command which reorganizes the help channels
There is already a command for deactivating help channels, !close, as for activation and mass-deactivation, the cog handles that on launch, and will deactivate non-cached channels too
There were situations where things broke
and just a cog reload fixed it
Wouldn't that just sort of be what you're describing, but done automatically?
Hello!
hi
How is this bot hosted?
@ember cloud we host it on a VPS (Linode). Is that what you’re asking?
yes
technically not a VPS anymore, @obsidian patio @ember cloud
it's running in a kubernetes cluster.
Right. It’s a kubernetes cluster
still on Linode
What is that?
it's an orchestration platform
it's a bit hard to explain in a few words, but essentially instead of renting a server that you set up to run your applications, you set up a cluster where applications can live. the cluster can be distributed across many servers, can automatically scale up and down, and all your applications are self-contained
I'm dramatically oversimplifying
you'll have to do some reading to understand it more fully.
@crude gyro what’s up in dev voice?
nothing, as you can see
Hahah
I mostly meant since you’ve been in voice for a few hours or something, alone. Are you just hanging out there?
I'm fixing a critical issue
Ah, I see. Nice
@cold island I finished migrating the environment variable reference, give it a look when you have time
Affected pages:
https://pythondiscord.com/pages/contributing/sir-lancebot/ env vars removed
https://pythondiscord.com/pages/contributing/bot/ env vars removed
https://pythondiscord.com/pages/contributing/site/ env vars removed
https://pythondiscord.com/pages/contributing/configure-environment-variables/ All vars collated on this page
https://github.com/python-discord/sir-lancebot/issues/545
what do you guys think about this?
Not all roles and channels is required
I feel like this should wait after our new config system though
Like AoC
we can just cache required ones
Also @eternal owl how you can add labels?
It is thanks to the template
Oh, I thought that Iceman can add labels. This is really confusing. This should be GitHub added labels ... instead, but we can't do anything.
lol
Sorry, should have been more clear. I think the env vars are ok on each page, just that for sir-lancebot there are so many we could show a small subset on https://pythondiscord.com/pages/contributing/sir-lancebot/ and then direct to a subpage with "for a more complete list of possible env vars, see here:"
Oh, yeah I got that. I thought they'd work better on a single page however, so it could serve as a quick reference while you're working on various projects
Uuuhh, why did we change that?
I added a bunch of env vars to sir-lancebot yesterday which flooded the page a bit
It's easy enough to implement this though
I think the setup guide was already fragmented across enough pages haha
Yeah, I'm not necessarily against this approach, but I would like to hear more opinions
You can never have enough fragmentation
I personally don't like that
Would you prefer the subpage approach, or something else?
Hopefully the env vars are gone in the near future anyway, I'd have kept everything on the same page
with the reddit migration, we dont need reddit client and pass on the Bot project env vars
What would be the replacement? it's not just about channel ID's
You have various tokens in there as well
By fragmenting the pages, we are making easier and easier to overlook something
smartconfig will accept user provided settings
Including tokens and whatsoever
I would personally argue it makes it harder to overlook, compared to having the main variables with a subpage, or having one giant blob of text
We shouldn't need any env var soon-ish
Ok, so let's add the extra sir-lancebot vars to a subpage for now
We would have a configuration file, like we have right now on the bot
Give me a second to do that
Honestly, I don't think it is worth spending more time on this
The guides will get obliterated soon 
I mean, the work is already done, it's pretty easy to do the change
When the change is implemented we can talk about obliterating stuff lol
^^^^ In the meantime ^^^^
There really should be a preview button on new articles
Oh wait, its just a different button
That doesn't do the actual rendering <.<
lol
I think when we do dewikification (contributions section), we should make that every project help documents is in this project repo and site loads them. Then like env variables can be updated in same PR.
@cold island @green oriole give it another look now
Just sir-lancebot tho
I'm still reverting the other pages
You could place the full link under the tabe, it looks good
Both links, or just the full reference?
Should I make idea issue for this?
the full reference
How would that work for contributors only using some of the projects
The site is already vaguely a requirement for running the bot, but you can still run it fine without it
What you mean? This should do HTTP requests to GH and listing should be in site (name -> URL mapping)
Ah, I thought you meant make a request to the site's api
No, dewikification means static content
Ok, site and env var page were rolled back, bot and sir-lancebot were edited
Nice, thank you
why are my github checks failing but when i run flake8 locally everything is fine?
im so confused
How are you running flake8?
That'll run all the checks so that'd be a good idea
Do you have pipenv on path?
A lot of tools rely on that, looks like including the pre commit which pipenv run lint invokes
You'll need to add the Scripts folder of the python you installed it with to path.
It looks like the flake8 that you're running is missing the required plugins, did you also install the dev packages?
If anyone wants a very small forms PR to approve I'll take a contrib review on this https://github.com/python-discord/forms-backend/pull/25
I believe you need to include the -d/--dev flag
I believe flake8 will work now properly when you run it like you did the first time, but I'd still recommend installing precommit (and putting pipenv on path). How did you install python that python is on path but the Scripts folder isn't? You'll need to find python's install folder, then copy the path of that + /Scripts and add it to your path env var
Running the bot locally with docker I get an error along when trying to run !eval, ```aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host snekbox.default.svc.cluster.local:80 ssl:default [None]
(full traceback here) https://paste.pythondiscord.com/jerutijofe.txt
Is it something to do with this line in the config, `snekbox_eval_api: "http://snekbox.default.svc.cluster.local/eval"`? That sounds like something to do with kubernetes, so do I have to change that? Or am I misunderstanding something.
You need to change that in the config to snekbox I think
Let me check
url.snekbox_eval_api should be set to http://snekbox:8060/eval I think, can you try that @timid sentinel ?
Cool!
That should probably be added to the contributing guide
.issue <numbers> [repository=sir-lancebot] [user=python-discord]
Can also use: pr
Command to retrieve issue(s) from a GitHub repository.
@mossy wolf was wondering if this is really what the config is for the duplicates rule:
duplicates:
interval: 10
max: 3
I'm not sure who actually deploys the bot. Is it Lemon?
What do you mean by that?
Oh I was just wondering what the current setting here is on the limit of when it deleted and muted for spam
so how many messages per interval?
The config-default file is basically a template for creating the real config file, yes?
4 duplicates would trigger the rule; 3 messages is the allowed max
No
config-default is the settings file that is used in production
Ah
so after the 4 spammed message it triggers the auto mute? thanks for the answer
If you add a config.yaml locally, you can overwrite values for you dev environment locally
without having to touch the original file (or replicate it completely)
It's basically a chainmap(config.yaml, config-default.yaml)
that's a near little thing. well thanks for the quick answer :D
I didn't realize it handled that dynamically. I thought you always had to manually create a file named config.yaml
Yes, that's correct. It counts the messages in the window and if the current message brings it to 4 or more, the punish subroutine starts
You create a manual config.yaml, but all keys that are not defined in it will be taken from config-default.yaml
also thanks @trim cradle for pointing me in the right direction
What are you working on?
no i was just wondering what you guys set for it....just a tad curious on how you guys manage this server and whatnot
We just got to discussing the workings of the bot when I unmuted someone for thanking them... like ten times?
aaaah right
was helping someone in a help channel and they wanted to thank me and suddenly they got muted for being a bit excessive with saying thank you :p
Was that the major race condition mute we had?
This is basically the reason for it:
So I was quickly looking at the rules (spam filters) code on how it detects. And maybe one way to get a small step in the right direction is to ditch the duplicates.py. It seems to have the exactly same code as burst.py, expect with an and to check if the content is the same. So if someone were to send duplicates text it would always trigger both burst and duplicate. And that makes me believe duplicate is redundant
Unless I’m interpreting the function wrong
I think the interpretation is correct. I don't know if bursts and duplicates should be treated differently?
I think they have a different threshold, currently
antispam could very well do with a bit of a rewrite
it's a bit of a mess
Isn't there some race condition associated with it
yeah
I remember looking into it earlier this year
I described it in the screenshot above
Its the exact thing I’m responding to :p
We could have a lock per user
Maybe not
I was thinking of this https://github.com/python-discord/bot/issues/1004
I was thinking something similar, but does this specific problem cause issues other than aesthetics?
Well it's not a huge fix, and it's a bit annoying seeing the bot bugging out. But that's just me
It could maybe help with the disabled burst_shared
It does cause a few issues
If triggered in quick succession, which happened during raids and/or mass ping exploits, the bot basically starts a Denial of Service attack on itself. As it start lagging, it starts failing more and more, as the window for the race condition gets larger and larger. It's why we had to disable burst_shared.
We had a few raids that ended with 100s of bot messages.
I think a simple "shared resource" could do a good job here, but I haven't studied this bug deeply
Similar to what we did for duckpond
What I know from my experience is that in discord making a good anti spam is a very difficult thing if you want to cover a decent amount of specific rules
Hmmm why are we creating a task for punishing the user instead of creating it for handling the entire rule?
We could then just await the punishment
that won't really change anything
The next "on_message" event will run in a separate task anyway
The idea is - find an applicable rule -> if the user is not locked, acquire the lock -> create a task -> the tast awaits the punishment, and when it's over the lock is freed
With a lock, it works,
We can check for a lock before we even look for a rule
Will the new messages after the first trigger be deleted as well?
:x: According to my records, this user already has a mute infraction. See infraction #24686.
:incoming_envelope: :ok_hand: applied mute to @grim mica until 2020-12-14 22:23 (9 minutes and 59 seconds) (reason: burst rule: sent 10 messages in 10s).
Thank you for the demonstration
If it's an alt it's not one I recognize
Seems like they're not fast enough 😦
That does sound like a plan. The moment it finds something it locks them and every rule check has a lock check first before doing anything else
Right, but Mushi makes a good point
Currently the race condition allows the bot to delete messages after a rule starts being applied
I have 2 ideas but not sure if they're good
- cache the messages for triggers whose user is already locked somewhere and delete them later
- the first trigger records its timestamp and goes back to the server to delete all the messages by that user after that timestamp
The first one seems good to me
I'm not sure how discord works and not sure if the second is even viable
The second one is viable since we're caching messages anyway, but the first one seems simpler
Creating a lock on the infraction task may be easier than having a rule acquire the lock. This is because the lock decorator I implemented is currently set up to abort any calls to a function which is locked.
However, this assumes that the infraction will always suceed.
If it fails then there wouldn't be away for the next violated rule to try again.
I can't think of a situation where retrying would be useful in that case. Chances are if the first rule failed then so will the rest since they retry within a short window of time
And it could be mitigated by putting a retry loop within the task that applies the infraction rather than relying on maybe another rule violation to effectively retry applying it
yeah, in the design above we could make it retry n times or until success within the task
And by lock I meant it as an abstract idea, I'm not that familiar with your design. We can work out the details of course
I agree that the idea of caching messages to delete sounds better
They can be cached in a set to avoid duplicates caused by messages that violated multiple rules.
Despite writing up that issue, I don't remember anymore how the message deletion is currently set up.
Having to send them to the API complicates things
# that the sleep doesn't block further tasks```
Not sure I see where the sleep is
In the punishment part
If anyone has time for a review, we could get @dusky shore's status countdown task for the Advent of Code working again: https://github.com/python-discord/sir-lancebot/pull/535
I'll look over it now
Hey, I had an idea for seasonal bot.
So we would have a command called .tr,
and then it would give u a text in an image, and it you would have to type that text, and it would give your wpm based on that, obviously the wpm wouldn't be accurate but it would still be fun.
What’s tr for?
But maybe that could be a multiplayer game, where people get to raced each other and see who’s the fastest. Like typeracer (maybe that’s what you meant by tr?)
well ye it would stand for typerace, but it could be multiplayer as well as single
its just a name of the command that i came up with
I like the idea
and having the text in an image makes it so that they can't copy the text
My only concern would be that it would be a worse version of things like monkeytype and typeracer. Why would they do it on the server, instead of just opening a well build site and do it?
Yep
It would be fun i guess and for one race why would u want to open up another site, when u could just do it here?
The other sites are probably better and more well build, but honestly, I think the idea could work
Then ig I will get to work
Is there a tag or something with information about how to get started contributing to the PyDis projects? If not, that would be useful.
also is there a tag for users to see how to install a library in different ways? (putting from #community-meta )
because many ppl ask that question or get stuck there
That would be a good idea, yeah
What do you mean by "in different ways"?
Like a page that lists the different OSS projects/repos we have and links to contribution guides.
Open an issue, and make sure that it’s approved by a core developer first
no different ways, but like:
• Installing pip
• how to install with multiple python versions.
• still not able to install? install it dynamically thro code
• etc.
• still not able to install? install it dynamically thro code
what does this mean?
like, if someone has many python versions isntalled or something else, they can just run this code:
import subprocess
import sys
subprocess.check_call([sys.executable, "-m", "pip", "install", "--upgrade", "library"])
I quite like the first two points, but not the last one
Automatically installing dependencies is something that is usually advised against, except for very specific reasons
installing from git should be covered
That's also a good point
Dynamically installing dependencies is not something I can get behind
We should not recommend it to our users as something appropriate to do
Either package your project in appropriate way so that pip can resolve the dependencies or write down solid instructions for your end users
I don’t think that was a suggestion for distribution, but a way to make sure you install dependencies into the same interpreter that is running your program, which is a problem that I’ve seen many times in the help channels
Basically, don't "ninja" install anything from within a Python application itself
I don’t think it should be a tag though
I think you should then explain to someone how they could make sure to install it appropriately
Instead of suggesting that you should use a subprocess to install dependencies
I’d usually use a similar trick to get someone that is failing to get to it any other way to list their installed depends, to show they are running different versions
But that’s why I don’t think it should be a tag
It’ll be misused
Yeah, but that's not the same as actually recommending someone to install something dynamically
A import sys; print(sys.executable) is not the same as suggesting that dynamically installing dependencies is a good practice
@hardy gorge your aoc pr is approved. I'm not sure if you just haven't noticed or if you're waiting on something.
I noticed, but I've been a bit busy today to address that comment
Suddenly job interviews everywhere
Scaleios made one comment there, but I think this is not change that should be done
Yes I don't think it has to be addressed either
Yeah I left an approval and put it as a possible suggestion, but it can be skipped
So basically this is now ready for merge
about setting up the bot and the config.yml:
- there are a lot of channels mentioned in the yaml which are not in the discord template.
- currently i have no way of knowing which channel is in which category, which is bad for people that dont have access to every category (non-staff).
because of these issues it would also be really hard to make a script that sets up the server automatically (which has been considered AFAIK). for any non-staff it would require a lot of trial and error to figure out the staff categories, and the script would have to keep the server layout as separate data. Formatted comments that mention the category in a machine-readable way or a re-structuring of the yaml would be needed to address this.
We are aware this is a huge pain and are working towards a solution. It is not as infeasible as you are suggesting to automatically set up a server.
Well, it is currently.
it is infeasible to do it based on the config.yml though
But not with the planned changes
Regarding categories, there are few features that rely on specific categories. Only help channels and an admin category come to mind. The latter is a simpler way to whitelist where certain admin commands can run; it doesn't matter which channels are actually in there.
But I understand that is not clearly documented
its really not and its such a hassle to set up all ~85 channel/category/webhook ids that im quite sure im not the only one who s turned off contributing because of this
Most of the channels, webhooks, etc. are not strictly necessary. For one, they are tied to specific features so you only need them if using specific features. Furthermore, it's fine to use the same channel ID for most of the configuration - it just may be a mess if multiple features start dumping text to the same channel. There is a plan to address this fact so that the channel list can be reduced to something more sane. This is just for visual sake - automatic channel creation would take away the more major concern of having to create channels yourself.
I've already written code that replaces the config system. It just needs polish. I think support for smaller channel lists may come at a later time since it's not critical.
There's no code yet to take the config and auto create a server though
is there any data to match channels to categories though?
because i would be willing to create a simple script to set up a server if theres any data thats suffecient for the task.
No but an admin could probably do an eval to get a mapping of category and channel names for you
There are no plans to create categories for test servers except those that are strictly needed for features to work.
okay, but which are those? also, the test server template has categories which leads me to believe that they should be created
It has categories just to make it easier to navigate through channels
The categories in the yaml file are the only ones that are needed
which channels do they contain though?
I don't believe it matters
Code that relies on categories just checks if a channel is in the category. It never checks both a specific channel id and specific category ID
If you really want to throw something hacky together, create a template that orders things the way they are ordered in the config, with minimal categories, and just have the script read and assign them from top to bottom
Well, maybe that's a bold statement. There could be something that does. I'm not familiar with every feature using them.
aight, thanks. im going to work off of that for now, but the issue is that any change will require a new dump
It's not an issue because as I said, we don't rely on specific channels being in specific categories.
I'd say the best way to set it up now would just be to create channels that the bot needs to work normally and for the features you're working on when it raises an exception for an invalid channel for you. You only need a few set for it to work
alright!
how is everything here?
Hello, @gusty crow, I think everything's fine here.
Hey @clever wraith!
It looks like you tried to attach file type(s) that we do not allow (.rar). We currently allow the following file types: .3gp, .3g2, .avi, .bmp, .gif, .h264, .jpg, .jpeg, .mkv, .mov, .mp4, .mpeg, .mpg, .png, .tiff, .wmv, .svg, .psd, .ai, .aep, .xcf, .mp3, .wav, .ogg, .webm, .webp, .flac, .afdesign, .m4a, .csv.
Feel free to ask in #community-meta if you think this is a mistake.
@patent pivot Do you mean Docker build args for sentry releases?
I can make env var from build arg in Dockerfile
Yeah that sounds good
You can fetch it from the .git folder from inside the container
@patent pivot I pushed changes to @dusky shore Sentry branch. What do you think about this way?
Does this need changing release prefix in workflow too?
Made changes
@cold moon confirmation: someone asked you to move this string to a constant?
https://github.com/python-discord/bot/pull/1269#discussion_r546333040
I was just thinking of putting it in the one place that is used, which is here:
https://github.com/RohanJnr/bot/blob/user_events_management/bot/exts/fun/user_events.py#L544
Why not replace that constant with the string "Live"?
When this is used only in one place, yeah, constants doesn't have point.
Right. Thank you for the confirmation. Have a good day!
If you use it to specify a new state, it is usually clearer to have a constant for that, even though it is only used once
You'd usually even use an enum to order the different possible states
our contributor review policy is now enforced by policy bot, meaning that an approval from a contributor will make it go green (providing your name is here https://github.com/python-discord/.github/blob/main/review-policies/core-developers.yml#L37-L45)
Is there no way for it to request the contrib list from the site when running checks?
not really, we use an external tool for review policy enforcement
and alongside that we don't have a centralised store of our contributors github details, since they don't have github access anymore, it's a cosmetic role
well, it's slightly more than cosmetic now, but not to the point of github access because of the permission issues
We coulddd request it from the site, that requests it from the bot, right?
Not that it would be pretty
well, i mean, yeah, if we stored those details
what problem is this trying to solve (fetching from the site/bot)
but discord names ≠ github names
Ah, right
we don't hold a centralised list of github names, nor can bots see connections
we've shutdown the old github bot, so we're replacing the few features it had using existing workflow tools
Yeahhh. Can’t we add the contribs as outside collaborators though? Not sure what that would really mean, but it might allow us to keep a record of them?
Cc @patent pivot lol
Oh? I thought that could be set per org
- we've already wanted to do away with the permissions that it grants
the reason was that there was little granularity provided
Yeah
so we decided to restrict org access to org members and enforce contributor policies using third party integrations
I’ve mostly only seen the term outside contribs when changing permissions of my orgs, so I just knew something called that existed but not really what it is
Yeah, I see
external collaborators is giving someone access to a specific repo without giving org access
so if I added someone to the site repo but not the whole org they are an external collaborator
Ah, I see
Why were contribs not part of the org now again? I don’t recall the reasoning
That is the reasoning, it grants permissions that were deemed unsafe and GitHub does not provide the granularity we need
It is way simpler in terms of administration to restrict organisation access at the base level to our staff team and then use other integrations to provide contributor functionality (e.g. policy bot for making reviews count)
What kind of things would make it unsafe?
branch access is one thing
like we allow force pushes on non-main branches, since advanced git users use them frequently
but it does mean anyone could force push over someone elses work
but as well as that
in terms of access control
it's much easier to have a centralised list of staff
@patent pivot Yeahh, true. I think contribs should generally be people who kind of known what they’re doing. And there are teams. But honestly, if they’re that good, they’ll probably just become staff either way
It's more security rather than inexperience
It's just not something that larger OSS projects do
Hmm okay
What version of discord.py is the bot running currently?
is it actually the master branch from github rather than a named release?
It is, yeah
reason is that we needed to make use of a new flag when we moved to the native gate
I figured as much--I'm getting a certain attribute error
!int e ```py
print(author.pending)
import discord
print(discord.version)
In [4]: print(author.pending)
...: import discord
...: print(discord.__version__)
...:
False
1.6.0a```
you can probably guess which one
ye
yeah, it'll just be because the stable doesn't have that flag, it'll be 1.5.X
1.6.X has pending support
I guess the real problem is that I'm not sure how I'm going to test !verify on the bot test server
if not user.pending: user.add_role(developer); user.remove_role(developer)
riiight
at least for now. I guess.
yeah, we'll change to announcements eventually
so we're going to delete the developers role for sure?
it'll either be deleted or have a new purpose
but we haven't concluded that for definite
either way it's a single line change for this PR so it's not critical that we plan ahead
as for testing
I can just make it announcements for now so that it isn't extra work if we delete the role later.
yeah that doesn't sound terrible
hahahahahaha
then everyone can say they've been an owner
500ms to destroy python discord
ye
testing wise I don't have many suggestions other than faking the boolean sadly
you mean, for unit testing?
nah for testing on the test server
leave and rejoin till you rate limit the bot -> infinite time
like we'll just have to work under the guarantee that user.pending will flip correctly in production — which it should unless discord is broken
let me figure out the environment situation
Can someone who has worked on the content most recently added to the bot send me their pipenv file? I clearly didn't upgrade to the correct version of discord.py
what do you get if you do pipenv run python -c 'import discord; print(discord.__version__)'
good question. I shall report back in 20 minutes when pycharm boots up.
llol
I'll wait all day for my five-star Python snail hotel if I have to.
1.6.0a; does the minor release matter?
that's the correct version huh
Are there any other environment considerations that the recent updates involve?
@cold moonWhy am I resolving conflicts?
There is conflicts with master and usually PR authors is responsible for resolving them
I get that, but why are we doing it now
The PR still has other issues to solve first, before we bother getting it ready for merge
This seems having pretty big conflicts and these should be solved before testing, because they may have an effect on functionality
They only appear large because someone renamed a variable
Well, should be fixed now
Okay, I will review soon
Thank you
Can anyone redirect me to the !d command for the bot?
I'd like to see the code
(ping with response)
thanks
!source d
Lookup documentation for Python symbols.
@ember cloud here’s your ping
No problems 😄
!paste
this appears to be the error that kills my local instance of the bot: https://paste.pythondiscord.com/tivahemaxe.apache
I'll be looking into it on my own though
I think that's an error connecting to the site
what do you get when you visit http://172.18.0.5:8000/
*change site to redis
In which case, that changes the question to do you have redis setup locally
If not, add the fake redis option to the env variables
I don't recall having had to do anything redis related in the past
Its not fun to setup on windows either, you'll be fine using fakeredis
Its line 10 in the config
I feel like it's-not-fun-to-setup-on-windows could be an otn
too long sadly
but I don't want to start that war in case anyone enjoys windows
windows=not-fun
that's not really a consideration with ot names
two of the ot names today are "too long".
lol
• microsoft-teams-is-great-software
I can feel the sarcasm from here
And I refuse to believe someone was serious adding this
then you're picking up on what Joe was saying when he said that.
some person: "Microsoft teams."
Joe: "Ah yes, Microsoft teams. What a great suite of software."
let's see
I'll restart the bot
redis:
host: "redis"
port: 6379
password: !ENV "REDIS_PASSWORD"
use_fakeredis: true
same error.
Do you have the username/pass set in the env file?
yes, I don't think that would have been changed when I pulled from master, no?
It shouldn't
Hmm
I'm actually getting a similar error now too
Though my problem has more to do with a 400 instead of a connection refusal
I guess, does anything show up on http://api.web:8000/
Do you get a django error page, or just a regular 404
That's just a regular 404 then
There should be a button in docker desktop to open a container in browser
Can you try that on the site
Specifically site_web_1
let's see
what about bot_web_1? I don't see site_web_1
That might possibly be the same
huh
Is it grouped with a postgres instance
You will need to rebuild the latest changes, but that won't solve the 404
Try it anyways, and see if it makes a difference
fuck there's red text in the terminal
Red text > no text
"discord.py" = {git = "https://github.com/Rapptz/discord.py.git", ref = "93f102ca907af6722ee03638766afd53dfe93a7f"}
93f102ca907af6722ee03638766afd53dfe93a7f = {git = "https://github.com/Rapptz/discord.py.git"}
ede7b4762a34df9b36bf6221b316873eb38fa694 = {git = "https://github.com/Rapptz/discord.py.git"}
I'm thinking... I only need one of these?
Is that the lockfile?
it's just the regular Pipfile
The red text was the error that killed it.
Oh you're starting the site from the bot
Hmm, I don't have experience running it like that, but it shouldn't error out I don't think
I'm trying to run the docker container, give me a sec to start it
I'm getting the first error you were getting
Its not ideal, but could you try to run the site from the repo directly
I'm not completely sure what you mean by this.
So fetch the site repo from github, and run docker-compose up there
Then run the bot locally
I'm going to try commenting out the first and last line of that sample from earlier
Go for it
for what it's worth, I'm generally afraid to ask for help unless I've completely exhausted online resources, so I appreciate you enabling my lazy behavior.
however I ultimately only have experience with academic software and the expectation is that everyone is running linux and has no sense of taste as far as software design goes 🤷
Lol I've flooded this channel with more questions than I can count because of windows
Don't worry about it
let's test that
you have 482 messages in this channel.
and they're all within the last month
On this account 👀
Wouldn't it be easier to just take someone's config file? or are you doing something special?
I don't think what I'm trying to do is "special" per se.
Are you doing something that can't be done if you use docker for both bot and site?
I think all along I just needed to rebuild my docker container, if "to rebuild a docker container" is even a thing.
maybe not the container, but the image
fwiw whenever there are version changes etc I do
git pull
docker-compose pull
docker-compose up --build
thanks!
(assuming you're on master)
Oh it says the website is offline
It's alright, thanks for reporting
Cloudflare is dead, once again
Tfw the could not connect screen has more uptime than the actual website
Though cloudflare is reporting it as a host error to me
as per usual CF pushes blame away
You guys getting direct connections to the server?
And is it configured to ping every single second
Nope, but the issue is really intermittent
Let me guess, thats down too 🤡
yep
I'm not convinced the website was up when it was unreachable, but I understand why it is that way
yeah the reporting worked lul
@gritty wind so this is an issue with how discord.py converts docstrings to help? https://github.com/python-discord/bot/pull/1285
I believe the library just uses them directly, but the line len limit in embeds with the wrapping messes it up
Yeah the embeds pretty much wrap the lines like they are fed in, so we either leave the couple broken paragraphs, change up a bunch of doc strings and add it to the style guide, code in the edge cases that break my initial solution, or ignore it
How you can send a tag just by doing !TAGNAME instead of !tags get TAGNAME?
It's a fallback in the error handler
Probably under exts/backend
I find user.pending counter intuitive because what I really want is a boolean for if they're verified or not. And this is the opposite. Would having user_is_verified = not user.pending and then using that variable once be horribly offensive to anyone?
When using this only once, then this is not very good idea
Feels a bit redundant with only one use, if it was something more complicated I'd say use a comment but in this case leaving it is probably the best idea
@cold moon @brazen charm I'm generally of a mind that if you can do with code what you would have done with a comment, code is better.
I'd fine with both solutions
A comment can be inline, code mostly shouldn't
I went with neither 💥
I'm ok with showing verified instead of pending, was considering it myself
sounds like a good change
I haven’t played around with the new version, but in what way is it confusing?
I was talking about something else, but I think we're talking about the !user command now. (Is that right, @cold island?)
discord.py tells us if a user is "pending", which is True until they get full access to the server. But I think a lot of us are thinking about it in reverse. The question we want answered is "Is this user verified?"
ye
you were talking about something else?
I was talking about the source code for the verify command.
I had if user.pending as the condition that was intended to mean "if the user is verified, do ...". But it's the opposite. And instead of taking responsibility for that failure, I blame the asymmetry between the semantics I want that if statement to have and the semantics it has.
Ah yes, deflecting responsibility is definitely one way to do it
I never accept responsibility in any aspect of my life despite being the common denominator in all my problems.
where is the source for https://paste.pythondiscord.com site available?
That's a locally hosted hastebin
that's what i thought, thanks
Do you know where to find that source?
nope
I'm not totally sure, but I assume that you found the right one
damn i was hoping it would be written in django
Hahah, not everything is written in python
i realize that
because i wanted to make a paste service for my website and i was hoping to find something i can fork
it is that one yes
nice
Yeah that’s what I assumed
I think you can rework your code so it makes linguistic sense, but your solution is fine too
one question how u guys manage role id when i make changes and push to github ,github detects the changes in id
how u avoid those
like in main server role id are different and in development role id are different
and in constants.py role id we change
isn't constants.py dynamic?
role id are not dynamic there 😓
I'm guessing that the configuration file is gitignored
and any configuration files you see on the github is just an example
yeah, constants.py will load the ids from the configs
From the readme, you create a copy called config.yaml which is gitignored
The default is not
Though there are only minor changes, because all the IDS are public
Its only things like tokens that change
That's all just in the config file
Anything sensitive gets loaded from the env file
which should almost always be gitignored
I think we use load-dotenv to load it
os module we use
We don't manually parse it
We load it into the system's environment
and fetch it with os.environ
So we don't change anything in the server, and if we do, we reflect that in the config
Since its IDs, that allows us to change the name, description, place, etc, but to create or delete a channel, you have to add the ID
In some cases, we also use category IDs
I'm not sure what you mean by default variable?
That's loaded from the environment variables, and os.environ allows you to set a default if it isn't found
debug = environ.get("BOT_DEBUG", "").lower() == "true"
That's used in setting the state of the logger
Then if something should only show up in development, you log it with a level lower than what you set
For example
Sir lancebot uses INFO by default
But in debug mode, it goes as low as trace
actually i have two server but problem is that if i make changes in id github will detect it
so i just scrolled the repo and try to get idea
how u guys do it
The IDs are already public, so that's fine, we just commit them
If you want a system that allows for a more private config file, check the main bot
but i wnt to use id of development server
ok
I don't see why that can't be public either
But again, bot config system, or environment variables
actually thats not the problem i just wnt to use different role id
Ok, I think I get you now
If you setup something similar to the debug variable from sir-lancebot, you should be able to select the ID based on debug state
And commit both development and actual IDs
If you want to avoid commiting both, you can do so by replicating the main bot's system, where you have the default config which you place in the repo, and another config that is git-ignored and you update manually
is it normal for the lint test to fail if you only created a new .md for a tag? Since it's not actually code but just text?
Run export PIP_USER=0; SKIP=flake8 pre-commit run --all-files
Check for merge conflicts................................................Passed
Check Toml...............................................................Passed
Check Yaml...............................................................Passed
Fix End of Files.........................................................Failed
- hook id: end-of-file-fixer
- exit code: 1
- files were modified by this hook
Fixing bot/resources/tags/json.md
Mixed line ending........................................................Passed
Trim Trailing Whitespace.................................................Passed
check blanket noqa.......................................................Passed
Flake8..................................................................Skipped
Error: Process completed with exit code 1.
Yeah it's because of the line ending in the text file
ah i'll check it out
i cannot find anything about the formatting of end of files in the guidelines, are you able to help me out on what is wrong?
should it have 1 empty line at the end?
Yes
okay that's truly amazing and hilarious
I like how the jump link gave me a message totally different haha
But yes, Lint before you Push turly is a masterpiece
i see now. thanks
but i cannot find anything in the guidelines about how a file should be formatted
just "run precommit"
and nothing specified about the exact rules used
.issue 60 meta
Yeah, that's the right one
Would you mind adding a comment here?
That should totally be in the guides
It’s a pretty standard coding practice
done
Cool, thanks!
ah now the lint passed after adding an extra blank line and replacing the : on line ends with .
thanks for the help peeps
@staticmethod
def role_can_read(channel: GuildChannel, role: Role) -> bool:
"""Return True if `role` can read messages in `channel`."""
overwrites = channel.overwrites_for(role)
return overwrites.read_messages is True
shouldn't use is True, yes?
Can run it through bool directly but that looks more clearer to me
I was going to change it to return channel.overwrites_for(role).read_messages. Shouldn't it go without saying that the return value is a bool?
overwrites can also be None
ah
so... return bool(channel.overwrites_for(role).read_messages)
some might find that unwieldy, I guess.
but if overwrites can be None, wouldn't we need to handle that before we can even have overwrites.read_messages?
Meant the individual attributes for discord perm overwrites, not the var. I believe it'll always return a PermissionOverwrite obj
@green oriole I realize that there are no return annotations within your ConfigEntry metaclass for the smartconfig package. I haven't worked with a metaclass, is this intentional?
Yeah, I kinda missed that
It seems like they'd all be either None or Any, not sure if it is reaaally worth annotating?
Well I mean, I don't see why not. Some of them do return NoReturn, which is actually something I haven't seen before. After looking it up, it seems that some functions would actually return more than None or Any.
Before smart config, smart annotate
lol
@green oriole Optional[NoReturn] isn't a thing, right? Since NoReturn indicates that the function/method never returns anything.
No
I think there's a different annotation I'm looking for, since the function may not return anything, but also could return None
Union[None, NoReturn]
Optional[T] is an alias for Union[None, T]
aka Optional[NoReturn]
So Optional[NoReturn] would work
I guess I'll go with that
I think Union is clearer here, if at all
imo Optional is more clear here, since it's telling the reader "this function has the possibility of returning None, or whatever is inside my square brackets."
which is what Union says too, right?
this is true
Optional[x] means that the main return type is x, but it might also not return anything (i.e None). But NoReturn isn't a return type really
I interpret Optional as Union[None, Whatever] in my head
It's more a matter of semantics than technical meaning
NoReturn is much more of an annotation then a return type, yeah.
So I guess we can go with Union[None, NoReturn]?
or just None
Maaybe.. I haven't actually seen a practical use of NoReturn
All in all, most tools don't understand the meaning of NoReturn, so that's up to you
I used it in my _abort function in the soon-to-be-dead YAML-like parser
The only way to exit the function is through an exception
why is it soon to be dead?
an exception is raised
Actually, I'm not sure if saying that maybe it won't return anything, maybe None make sense
exiting the parser as a whole iirc
We decided that we will use PyYAML to avoid the technical debt of mating a parser ourselves
Well, it is also killed by the _abort function, heh
I think I'll just go with None since the NoReturn function explicitly wants nothing, ever.
If you break out the actual non-returning part into its own function
You can avoid the confusion
Is that what you meant?
@green oriole In this case you're correct, most methods within the metaclass are either None or Optional[Any]
Honestly if it has a chance of returning I wouldn't put any NoReturn here or in the caller, which would be the same thing
Ai'ght
I might try to fully typehint them later
I think I've caught all the return method annotations that were missing
I don't think so, I think.
@green oriole lol it was literally 75% None
Um, Could u link me the project?
Thankyou
I have a question about snekbox. How are users not able to access the files that the sandbox has? How does snekbox handle malicious/untrusted code that could potentially delete application files
The code runs in a sandboxed environment, which is mostly handled by NSJail
Yep totally got that!
So NsJail also prevents users from accessing the local files?
What if I wanted to install a library in my container running NsJail
Will that prevent users from accessing that library?
So for your first question, I’m not too sure, I’d have to check their page, but I know that only one system thread is allowed to run at a time according to our settings, which might be a factor
In terms of your second question, we do have libraries installed on snekbox so it is possible
I’d think you’d just add it as part of your interpreter, but be careful that certain libraries if handled incorrectly may provide attack vectors
I see
The best way to learn more about nsjail though, would be taking some time and reading through all the documentation
Yeah actually I am using Gvisor
I came here because this was an interesting use case
But would you recommend NsJail over Gvisor
Just for running untrusted code
I dont really see the difference between the two, except from what I have read is that Gvisor provides an extra layer of security
Gvisor actually has a section about file systems, interesting
I can’t personally speak to either’s quality so some one else will have to answer that
Ah no worries
Another question, so snekbox executes code using python subprocess?
I mean
Is the user input written to file first?
No, it's just passed as an argument via python -c "code here"
wait, whats the -c flag for?
snekbox doesn't use subprocess for python, it uses it for nsjail
yeah
nsjail in turn launches python by creating a new process with the fork syscall
the -c flag is used to specify python code to be executed
I see
so how does this work
Oh I thought the bot maintains the user's state as well
But the state gets lost on the next input?
I think that’ll error out because of the limits we set for nsjail
gvisor isolates the host kernel from the application's kernel. nsjail doesn't - it uses a kernel feature called namespaces to do isolation, but namespaces are contentious in linux since there have been security bugs before (I haven't looked into it too much). The intent of gvisor seems to be summed up by this:
While using a single, shared kernel allows for efficiency and performance gains, it also means that container escape is possible with a single vulnerability.
Nsjail has features to impose limits on the process (resource limits with cgroups and syscall restrictions via seccomp-bpf), but gvisor doesn't because that's not its focus - it's mainly a kernel.
In fact, I should look into gvisor more and consider adding it to snekbox
I mean yeah
Thats an extra layer of security
There are kata containers too
and a bunch of other cool things you guys could add
I'm not sure if it'd work with nsjail but it may imply that it would
It's probably fine as it is but it's an extra layer of security like you said. Again, nsjail and docker both use namespaces.
Yeah
A nicer feature would be to maintain user's state
Like if I execute import subprocess then this shouldnt be lost
for atleast some time
It executes a new python process for each api call
I am saying what if we could preserve the state
I'm not sure how state would be saved. However, I feel like it's not the intent of the eval feature (for our needs).
Well a naïve approach is to save all lines executed and re-execute them for every subsequent api call. But that's slow.
Hm so according to you, I cant do that restriction to file system thing with gvisor?
That's my interpretation of their readme.
gVisor should not be confused with technologies and tools to harden containers against external threats, provide additional integrity checks, or limit the scope of access for a service. One should always be careful about what data is made available to a container.
No? gvisor is a kernel and nsjail isn't
It literally says it's an application kernel
Essentially it's a container runtime only it has an isolated kernel
It's a paravirtualisation of the OS
gVisor can be thought of as an extremely paravirtualized operating system with a flexible resource footprint and lower fixed cost than a full VM.
If I wanted to make a "user can see channel" function that could be used anywhere in the bot, where do we put that kind of thing?
python bot
bot.utils.channel I'd say
👍
part of me feels like the code for handling infractions is really hard to follow
It isn't you, it is pretty hard to follow haha
but then again, trying to break it down means interrelated functionality becomes more spread out...
My first impression would be to have classes for each infraction type that implement the "send DM" and "put infraction in database" steps separately
but that could easily become the kind of OOP weirdness that I abhor.
Infractions are complicated to dealt with, yeah
You have to find the right amount of OOP you want, otherwise it just ends up in an OOP madness, or an if-elif-else madness
Scragly is working on OOPifying stuff
Which one would be worse? Lol
You need to find the right amount to avoid those two haha
hello
@tawdry vapor how does one properly test the validity of the change in this PR for flake8? https://github.com/python-discord/bot/pull/1334
It does seem to be working when I make changes that flake8 doesn't like
What's the point in having a checks module and a decorater module?
Why not just have one?
may I know what other ways?
Sure. Checks are just functions, so they can be used as regular functions as well.
If you look at source code for the !user command, you'll see a usage of the in_whitelist_check function
!source information
!source user
line 207
ohhh ok. Thankyou
Hey @cold moon, what's the difference between the two?
full_load is shortcut of Loader=yaml.FullLoader
Okay, cool
Is there a specific command for raw strings and escape sequences
If you're talking about a tag that describes raw strings, I don't think there is one
But you can suggest tags in #community-meta
You have to try to make a commit through pycharms ui so that the ide triggers the hook. If it successfully runs then that means it works.
Do we get to decide what the timeout is for re-writing your code when you use !e? I find it painfully short.
It wouldn't hurt to increase it
But it's not something users can control on their own
Right, I wasn't sure if it's a limitation of the API or a constant that we set.
Or secret option 3.
It's the later
I noticed your license badge isn't working properly, it doesn't seem to detect the MIT license:
Yeah github returns null for the license on that repo, which in turn means the badge site returns that 🤷♂️
The files that copyright applies to are described in that file
seems like it only applies to a single function?
There is another licence at the top
wouldn't it be enough to just list that under MIT and mention the source in some different file, BSD is permissive it should be possible, or am I wrong?
it would probably make more sense to just do something like COPYRIGHT which lists the sources, but as long as they're under permissive license, you should be able to re-license them
that way it won't confuse github as to which license the repository is under
License are a headache. At the time I preferred to follow the licenses to a T rather than make inferences on what is and isn't permissible. If there's someone that can assert with 100% confidence something can be re-licensed or simplified, then go for it.
I didn't foresee GH's confusion with the file name. COPYRIGHT would be fine or even THIRD-PARTY-LICENSES would probably fix the confusion
I'm not certain that the confusion is there because of the file name or because of the file content, which contains the whole license, I'm not that familiar with github's licensing name conventions.
From the BSD 3-Clause License, I'm pretty sure you can relicense with the only condition being that you have to mention the original source, I'm not entirely certain about PSF license though
The confusion is from the name, because it tries to decipher both files, and it can't do the second one
We just have to indicate that the other licence is not intended to be read by github
How I understand it from the first clause of bsd is that you can't relicense the source if you're not the copyright holder
first clause only requires the copyright notice, not the whole license
The PSF license must be included as stated in clause 2 of the license
yeah, that's possible, I'm not too familiar with that one
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
That covers the whole license
oh, that's interesting, I always assumed it wasn't required, guess I should take a look at my things too
Alright, thank you. I shall test sometime soon.
What counts as a "contribution" that would reward the contributor role?
Like I know contributing to the bot is technically a contribution, but what counts as a contribution that is enough to reward the role
you can't just be labeled that for changing like 1 tiny thing like a grammar fix or something right?, so how heavy should a contribution be?
There isn't anything like an amount of changed lines that'll automatically get you the role; most probably not a single contribution though
so what's an example of what would get you the role?
Like what does it depend on
the amount of contributions or the weight of it
like if you contribute something, just 1 thing, but it's really heavy as in really important or helpful, should that suffice?
no, you must make several significant contributions to our repositories
We're a large, friendly community focused around the Python programming language. Our community is open to those who wish to learn the language, as well as those looking to help others.
I wrote a small Python script that can get you all of the file extensions within a folder. You can also configure blacklisted extensions in case you want to skip these. For example, I skip files that do not have an extension.
import os
directory = 'path/to/directory'
blacklist = ['']
extensions = []
for dir_path, dirs, file_names in os.walk(directory):
[extensions.append(ext) for file, ext in [os.path.splitext(fullpath) for fullpath in [os.path.join(dir_path, file_name) for file_name in file_names]] if not ext in blacklist and ext not in extensions]
print(extensions)
Hey, this channel is about python-discord projects specifically. If you'd like to show off your work, try the general or off-topic channels (see rule 6 and 7)
Where is the section where the Muted command is kept?
!source mute
Temporarily mute a user for the given reason and duration.
Here it is. You can find the source code for any command by using the source command
Would this code be able to work in my personal bot with little to no config?
Not really. We use a Postgres database and the bot requires the site to be set up to work. If you want to implement a mute command, you could try to use the code for the command, but you'll need to alter it to work with your bot and setup
Generally, when and how do you guys decide that its time to upgrade to the latest python version? like current site is using 3.8, and 3.9 is out
what do you look at before actually upgrading to 3.9
literally just dependency compatibility @eternal owl
so
we did try bump site to 3.9
however the wiki package that we used was completely broken
and so site is blocking on us removing the wiki
@tawdry vapor Did the screenshot in this PR have enough information?
https://github.com/python-discord/bot/pull/1334#pullrequestreview-559406006
Yes that's good, thanks
No problem, glad to help!
This fix will eventually have to make its way to the other repos
Very cool.
@crude gyro I'm not sure if you intend to support all this but the connection string for pgsql doesn't necessarily follow the format your regex expects
yeah we're just supporting a simplified version of it right now.
my current idea is that everything will be a simple connstring in black-box initially, we can add more complexity later if it becomes necessary.
even stuff like google drive access credentials can be a connstring
I just mean that all of the host, port, user, and password are optional.
But I like your idea
right right. the regex should perhaps just use * quantifiers and provide some defaults if nothing is provided
like, 5432 for port, localhost for host, etcetera.
Can it instead rely on postgres to use the defaults? Or does what you're doing expect explicit values always?
yeah.. I think it would work without host and port, but the approach would fail without a password provided
well, I don't know.
I haven't actually tested it
it's possible that, say, if you're logged in as the postgres user and running pg_dumpall on localhost you don't need to provide fuck all
I suppose in that case the connstring could just be postgres://:@:
or maybe make a special accommodation for postgres://
I don't know about pgdump specifically but yes that seems to be the case when using connection strings normally
It'd be more intuitive
Just pasta string without having to think about tweaking it for this project
I wonder if mongo connstrings adhere to the same rules


