#dev-contrib
1 messages Β· Page 36 of 1
Ah I see now, inside the self._process_deletion_context you are checking the other dictionary, that's why it did not crash
So we can still use the delay, but we need to delete the messages after we upload the context
No, I don't think that's right for the antispam filter
It should not wait 10 seconds to delete the messages after triggering, but it should take action as soon as possible
However, since you are going to relay the attachments (right?), that's something that could happen earlier
@gusty sonnet That does look like a mistake, yeah
I'm not sure why it's there or what it is doing, I think I wanted to save a reference to the task, but there's no code to remove it once it's processed either
The DeletionContext tracks the messages that should be deleted
The add method of that class seems like a good place to relay the attachments and save the links to those
That happens before the messages are deleted
Okay iβm going to change it as soon as possible
Here is the nondocker guide (bot + site) for win 10 home https://gist.github.com/Akarys42/989dcfa41536c9f3b15c844ea4f04d72 !
if someone gets time, please review https://github.com/python-discord/bot/pull/546
it only requires one more review and it can be merged
noticed the constants are a bit messy, should I group them in some way or order them?
up to you
if you think it's able to be improved, you're welcome to throw in another commit
ping me if you do, as i've now approved a review so the change would be best to be rechecked.
looks fine
30 commits 
right to the top
i look so sad down there
That only count commits to master? yes it does
@hardy gorge would you mind taking a look at my tests please? (if you have time) https://github.com/python-discord/site/pull/300
wait @hardy gorge what's this now
commit contributions on bot master
in what time period?
For the month
aha
I don't remember having committed anything this month
I thought I only did duck pond
Yeah, not alltime
but that's not merged
maybe a suggested edit
no, not 12 suggested edits
You did a PR https://github.com/python-discord/bot/pull/480 in October
But there was only 2 commits in it
Oh yeah
It's not this month, but about a month of time (30-31 days depending on the month and ignoring February, like any programmer should)
@green oriole I'm looking at it
scargly is on fire today
@green oriole I think the only thing I'm missing is that you don't test the GET method (or I'm overlooking it)
I see tests for creation (including validation), deletion, and not allowing update methods
Hmm yeah I may have missed it
It is half tested in the deletion test but doesn't have a proper test
It's probably better for that test not to rely on the GET, but rather to check the database directly
Well I copied the test process from another test suite
You could do an assertFalse with OffensiveMessage.objects.filter(id=id).exists()
Hmm, I'm just thinking about making these tests fully independent
Yeah that's logic
In principle, we could go for an API design in which we don't allow someone to get a list using GET, but still allow DELETE (and maybe individual GET lookups based on pk)
Not likely here
but just for the general pattern
That's crazy the amount of code redundancy we have in the test suites
I wonder if there is a way to make reusable tests
Anyway I'm going to fix those two things as soon as I'm on my computer
Some tests can be shortened, yeah, but it's quite a project
Anyway, there's also a value in keeping testing logic simple; the more complex you make it, the easier it is for a test not to actually test what you're trying to test
That said, a lot of tests are "this specific payload for this endpoint", execute, "check if I get the specific response for this endpoint"
+1 for keeping tests simple. they should be readable and intuitively understood, much more abstraction might hurt that.
something that isn't always understood is that tests can serve other functions than just preventing breaking changes from being introduced. A good test should serve as a showcase for how to interact with the implementation it is testing, and what the expected response is for each component. If the tests were written by the author of the code, the tests may even serve as a window into the authors intentions.
this can be a really powerful way to quickly understand complex moving parts in a system.
so it is imperative that we keep the tests readable.
also because my eyes glaze over if i have to force myself to be acquainted with unreadable code and that's super hard to push through
pls don't do this to me

wew, ok i went through all issues
repos?
lol
gotta do PRs first
thankfully there's only a bit over a dozen of them
that is one very strange picture
i'd expect it to be more like a giant man-wombat with the power of sending magpies to swoop people
He should at least have a pouch
or be poisonous and venomous
@tawdry vapor
Here's your reminder: 651.
Jump back to when you created the reminder
That feels cryptic
my bank pin
So guys have you checked out the nondocker guide iβve written? There is probably some things that could be improved
So we can quickly get in on the site
not yet, i've been busy actioning the labels task first
once it's done i'll turn to it
Okay nice
i would also love to hear what non staff people think about it, so if you want to check it, it is in the pins π
so it turns out users with numeric usernames make it impossible for me to mention some users by ID in #592000283102674944 when I'm using the actual Discord client
If user event stuff is gonna be integrated into the pydis systems, then I think that'd help, but I dunno what else to do really
Figured out a stopgap for now anyway
Hi I am trying to design the UI for the whitelisting task. I am clear about the listing operation. But for the edit operation I have a doubt. Is it possible to make a command like !whitelist edit channels add 1233445? This will add 1233445 to channel whitelist or !whitelist edit channels remove 1233445 will remove 1233445 from channels whitelist
I saw the edit operations for !tags command. But In that case we are overriding the list of tags.
What you could do is have !whitelist channels list the channels whitelist and have !whitelist channels add and !whitelist channel remove as mutation subcommands
or is channels a dynamic name?
I wouldn't be opposed to !whitelist add <type> <item> and !whitelist remove <type> <item>
That will keep the commands shorter
we can not add a new type with the command. Only the existing types whitelists can be modified. Still, I think this looks good.
No, not to add a type, just to be able to specify which type you're adding an item to
Cool!
I also need some direction regarding the model design for the whitelisting table. My plan is to have a model like this
class Whitelist(ModelReprMixin, models.Model):
"""Whitelisted items for a type."""
GUILD_INVITE = "guild invite"
FILE_EXTENSION = "file extension"
CHANNEL = "channel"
ROLE = "role"
TYPE_CHOICES = (
("guild_invite", GUILD_INVITE),
("file_extension", FILE_EXTENSION),
("channel", CHANNEL),
("role", ROLE)
)
type = models.CharField(
choices=TYPE_CHOICES,
max_length=100,
help_text=(
"Type for which the whitelist is stored."
),
primary_key=True
)
whitelisted_items = pgfields.ArrayField(
models.CharField(max_length=200),
help_text=(
"List of items to be whitelisted."
)
)
def __str__(self):
"""Returns the type of this whitelist, for display purposes."""
return self.type
what are your thoughts on this?
I like it. It would make it fairly easy to extend it in the future.
Yup
Will this !whitelist add <type> <item> allow to have type with spaces in them?
It does, but not easily: It would require quotes around the name
okay, So think it's better to keep the types snake cased
Or single words on the discord.py side
I think invites or invite is enough to know what we're talking about when it comes to guild invites for instance
Yeah! I think we can go with the single words. Thanks!
Hi @hardy gorge, can you recheck my tests please, I've updated them like you asked https://github.com/python-discord/site/pull/300
(the new labels colors are way better than the old ones)
@hardy gorge @woeful thorn If you can also please re-review https://github.com/python-discord/bot/pull/617/ so we can get this functionality added
@tawdry vapor regarding https://github.com/python-discord/bot/pull/651#discussion_r347077635 should the User object be converted to a Member with get_member to get the nick?
No, I don't think it's really worth it. It'd have to be fetch so that means making an API call.
The code would get a bit complex too to handle potential exceptions
I've searched and asked around, is there other way to get it?
Just don't show a nick for the proxy user
yeah but the normal objects are Users too and you can't get nicks from there neither as far as I can tell
there's display_name but that returned the user name too
alright
There was another pr that got closed related to this
I suggested using fetch but it got complicated like I said
Then realised the api can return user info since we sync that to the db
So for the infraction search you could make it always display the nickname by using the api
But you don't have to if you don't want to
I'll look into it
got the issue to get my feet wet around the moderation stuff so won't hurt to look at the other things with it too
@tawdry vapor actually, it looks like only the scheduler gets User objects and management + superstarify get Members with management fetching them from the guild. Should I be consistent or do usernames in one and nicks in the others?
Get the nickname where available (without using fetch_member). Otherwise, fall back to the username (without discriminator). If neither available, just don't show anything extra.
I don't think consistently really matters since their nick/username should not be used to actually refer to the users - that's what the ID is for. It's just there to quickly identify who someone is, particularly in the case of the mention "failing" due to the user not being in the client's cache.
That's only my view of it though.
Maybe someone else thinks it's worth doing an API call to get user info.
But considering we've gotten by fine without that so far, it doesn't seem necessary to me.
Thanks, if there are different views there are also multiple reviewers so it can be caught there
Yeah but ideally it should be decided before you go and implement something. You can do it now but you may end up changing it, so up to you. In retrospect, I admit the issue I posted wasn't fully fleshed out with details.
the method in the scheduler have union of Member and User hinted for the user, although I haven't seen a member so far when trying a few command is it worth checking if it's an instance of member and then using nick? (if you know when it gets the member by chance)
Sorry, which method are you referring to?
apply_infraction in InfractionScheduler for example
Yeah, you should. It's meant to be kind of general purpose and it's not a lot of code to check for that
I think you should check for the nick attribute instead of checking the type
here's that other issue by the way https://github.com/python-discord/bot/pull/508#pullrequestreview-307675298
oh, I see, sorry for taking up so much time with this but at line 112 in the scheduler the user is redefined for the case where the user is a ProxyUser but that also redefines it when the user is a Member which I don't think make a whole lot of sense and results in the nick being unavailable even though it's passes as an arg to the command. Assume that's not the indented behaviour?
You could say that. More like it wasn't a consideration when it was written so it didn't matter if the object was overwritten for what the code was trying to accomplish at the time.
should it be rewritten now to get that functionality back?
Sure
I think all you need to do is check the current user type instead of always assuming the user needs to be fetched
yeah, will also take some unecessary load off of the api
with regard to the comment linked above, does the api keep the nicknames of the users? Haven't found anything apart from the username
only the name is there afaik but to make sure I'm not missing anything because the comment suggests it does exist
yes, the website does track the nicknames
Where are they kept? Haven't had much luck finding it
can anyone help me with the build failing https://dev.azure.com/python-discord/Python Discord/_build/results?buildId=4715
It doesn't seem to track the nick
@austere veldt You have a file that isn't fully covered by your unit tests
pydis_site/apps/api/models/bot/whitelist.py
That file
the str of the class defined there
Thanks @brazen charm and @molten bough
If you're working with the login system.. Hm, no, that won't give you the nickname either
When I am running the tests locally. I don't get that error
Run it with coverage enabled
@brazen charm You are talking about the __str__ of the Whitelist model?
Some IDEs will also be able to run the tests with coverage for you and show which lines aren't covered
PyCharm can do that for example, though it may be a pro feature
yes the line 35
@tawdry vapor Should the member and the nick be fetched from the discord api for the search then when they're not kept in the server's api?
@molten bough I have the pycharm pro, How do I run the test using that?
It's in the top toolbar (turn it on in the view menu if you haven't), near the run/debug buttons
@brazen charm How do I add test for that? And I am confused, as I haven't test case for the entire model, then why it just throws error for the str method?
@brazen charm Yes. Alternative would be to change the endpoint to support saving nicknames but that's more work since it would also involve having to use the bot as a one-off to fetch the member for all existing users in the db.
That's a bit beyond what I can achieve for now π
Maybe I'll get around to that eventually
There's no reason the syncer can't handle that
oh, also wanted to ask; what are the # region: name # endregion for?
they allow collapsing in editors
if you define a region, a small - icon shows near the line number
it'll auto collapse the entire defined region
Folding is reeeeally useful
how are the infraction searches used? Wondering if it'd be worth to keep some sort of short timed cache around the fetching
it's not really worth it, no
only the bot interacts with it so it's not like we're dealing with lots of traffic, and we want the data to be up to date
By the way you can still use the expanded api to get the username if fetch_member fails
Looking at the search_user using the UserConverter ([discord.User, ProxyUser]), can that even get to a ProxyUser when the user is fetched from the discord api before it reaches that?
discord.User doesn't fetch from the api
discord.User fetches still from cache but global
it's almost useless to our bot though
it gets passed to InfractionSearchQuery before it reaches that method
which does a fetch user
and has a wrong typehint
when you do an infraction search, it triggers the search command at L163 in management.py
give me a minute. i'll open github in a second then
but it sounds like it's just reusing a generic union converter that's used fine elsewhere
okay, so you're talking about the subcommand being invoked via the parent group
the search triggers search_user if the query got converted to an User, so it shouldn't then need a converter for a ProxyUser typehinted in it
when the group is invoked instead of the specific child search commands, it will fetch
but the InfractionSearchQuery isn't used for the child commands alone
search_user when used directly (!infr search user) will use proxy_user still
it's rare to occur, but for example if someone is given a note before joining the server
tbh i don't even like the usage of fetch_user here in the InfractionSearchQuery either
oh well
oh right, thanks so it's kina a roundabout check through the proxyuser
it's only for checking if the given string matches a valid discord user id so it knows to search via infr search user
since id's don't have information about the type of object they're created for, that's one of the most simple methods to do so
I was thinking about implementing the nick fetching that was talked above by adding member fetching into the InfractionSearchQuery and then checking instances and creating a passable nick from that in the commands
i'm not really up to speed on what you're working on atm
showing the user's nick when you search infractions
and trying to find a nicer implementation
oh no problem, least I found is that wrong typehint π
it's not really wrong though
it's only useless in the case the parent command invokes it
meant the one in InfractionSearchQuery's convert that fetches Users but has a Member hinted
thanks for clearing up the above for me
no probs. sorry for taking a bit to get up to speed
adding member fetching into the InfractionSearchQuery
this sounds fine
in which case if you add it, the return hint would need to still add discord.User but discord.Member can stay
wheres this nickname going to show anyway
yep, just when the subcommands are executed directly. Not sure if it's the best way to add that to the converter Union or some other way
the subcommand doesn't need anything different
the InfractionSearchQuery does
oh the UserConverter doesn't have the Member type in it
right
that makes more sense
yes, you can just add discord.Member to UserConverter but i think we have a similar typehint elsewhere
if that's the case we could probs just reuse what's necessary
if you adjust the management.py one, it's best to see if these unions are taken into consideration and ensure we keep things DRY as possible
the discord converters only .get, and what was proposed is .fetching the Member from the api for the nick so it appears if possible. So I was thinking about doing it in the InfractionSearchQuery by fetching the Member and if that fails doing an User like mentioned above, but when the command is invoked directly, that doesn't happen and it's inconsistend because it only gets the User user instead of trying to .fetch it which also has the disadvantage of nick never being available and a higher chance of failing
yeah for the nick if it's possible to get it from the guild
right now making a superclass of the InfractionSearchQuery is going around my mind that doesn't return a string but fails it as the User not existing in discord will also mean it can't have any infractions
Hi, I have been using docker to run the bot and site till now. I have added a new API to the site and want to access that in the bot. How can I run them locally and connect without docker?
I was able to make some progress on this. I am running django server locally and have set the SITE_URL=api.pythondiscord.local:8000 . Still the bot is trying to connect to api.web:8000
have you added the bot to the site compose project?
you mean docker compose?
They're trying to do it without docker
Just update your config for the bot so it has the right domain
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.
right here
Have you tried that?
@molten bough You got it right. I want to run it without docker
Which config do I need to change?
Oh you donβt use docker?
See the link above
@green oriole I do but I am trying to debug something. So I think running locally will be easier to debug
If you want to ditch docker, we have this (temporary) guide right here https://gist.github.com/Akarys42/989dcfa41536c9f3b15c844ea4f04d72
@molten bough there is still missing output with docker or it has been resolved?
I have no idea
You still doesnβt use docker?
I haven't bothered with it, no
Oki
I think I got it. I need to change site url in default-config. Thanks!
No luck yet! Even after doing the changes I am getting this on running pipenv run start
raise ClientConnectorError(req.connection_key, exc) from exc
aiohttp.client_exceptions.ClientConnectorError: Cannot connect to host api.web:8000 ssl:None [Name or service not known]
Oh yeah try to change in the config site to pythondiscord.local:8000
my bad! I did changes in the config-defualt.yml instead of config.yml
git checkout -- config-default.yml to revert changes
I've done that so many times....
Surprisingly enough, it haven't done it yet..
And finally! it worked.
Nice
congrats
I wonder, is it safe to rename my fork on github while I have a PR open?
I think so
Yep it is
So guys, what about the nondocker guide? You're still stuck with the labels?
if i could get two reviews on this please, it would be appreciated
There's one for you anyway
thank
ah yes
wonder how he went
@snow zealot did you happen to poke around our repos a bit?
@glass pecan yes, yeah
I'm finding it moderately difficult since I've actually never done anything opensource before so it takes me a while to understand other people's codes..
I'm learning albeit slowly.. and yeah, I had an idea which umm I dunno if people think is cool, but nevertheless I opened my first issue on there :D
I honestly think there's a loooot more python I need to know before I can be of value.. atleast that's what week 1 of trying-to-git-gud-at-bot-dev tells me
Also, I think I'm going to be away for the next 2 weeks owing to my semester exams, so I think I'll try to grind again after that
Mm but yeah this thing y'all do is hard xd, you guys are crazy smart, and have perhaps put in a lot of time and effort to get there
hahaha, sounds like you've at least dipped your toes though
yeah well I read every message posted on this channel this week, tried to see how much of it made sense
make sure to ask questions to clarify things that seem confusing though, that's absolutely fine to do
like when Shirayuki pointed that dictionary thing ves zappa's code, that was like big brain
i probs missed that
yeah, definitely will.. Infact I love asking questions here for I always get more than what I expect π
noice
well keep it up
hope the enthusiam is maintained and if there's ever anything you need just ask
yeah, absolutely.. I'll hang in around here more often and try to pick up something from y'all.. mm brb in a couple of weeks
also I think
I should probably educate myself a little more in making basic bots themselves before trying to do fancy things with python so that's that
So I thought I should probably create a dummy server and make a real simple bot and get it in there, and start playin around to get a feel for it
but yeah, I do feel good gettin into this so thanks for that
go for it
making a basic botto is a great way to get familiar with working with them
yup, thanks. π
im trying to set up pycharm to help me write better code for seasonalbot, but there must me something im doing incorrectly as it keeps telling me the discord package isn't installed
[kwzrd@kwzrd-thinkpad pydis-seasonalbot]$ pipenv shell
Loading .env environment variablesβ¦
Launching subshell in virtual environmentβ¦
. /home/kwzrd/.local/share/virtualenvs/pydis-seasonalbot-yCADgX3-/bin/activate
[kwzrd@kwzrd-thinkpad pydis-seasonalbot]$ . /home/kwzrd/.local/share/virtualenvs/pydis-seasonalbot-yCADgX3-/bin/activate
(pydis-seasonalbot) [kwzrd@kwzrd-thinkpad pydis-seasonalbot]$ pip list
Package Version
-------------------- -------
...
...
discord.py 1.2.3
...
i added the interpreter via pycharm's settings, pointing it to a 3.7.5 pyenv install and checked install packages from pipfile
anyone know what could be causing pycharm to not see the package?
i havent used pycharm nor pipenv much
You clicked the install link in the banner, I take it?
yeah, it runs some process installing packages for a few secs, then the banner comes back same as before
i can run the project just fine via pipenv run start
mm ok, thanks for checking anyway
works fine when i install via pipenv sync --dev and then add the interpreter as a virtual envrionement, but just wont work when added as a pipenv environment, weird
I have a similar problem everytime I checkout a new branch, if that can help
Oh wait only with discord.py? That's because the package name is discord but it is noted discord.py in the pip list
Hmm weird on my computer it is saying discord not discord.py
Was confused why a branch wasn't checking out
took me too long to realise that it's cause the branch's name starts with a # so the shell thought it's a comment
I'm not sure what's wrong but I cannot trigger the mentions filter when testing. I can trigger other ones though
is your role getting whitelisted?
That is odd. We do still get the occasion mention spam alert, but they are fairly rare. Now I'm hoping that we're not missing half of the events or something.
Did you spam with repeated identical mentions or different mentions in a message?
It only counts unique mentions in a message
Oh they weren't unique
I spent some time today exploring discord.py and reading parts of the source code for @stable mountain and learning a bit from it too
discord.py looks huge but not hard
is there something like a documentation for @stable mountain, or relevant tags?
No, we have no special documentation, other than the docstrings, but you can always ask questions.
I see
thanks
well I'd need someone really patient honestly, maybe I should poke Scragly after all
since he volunteered for the pain
There are probably more people that can help you, but he did volunteer.
i recently started looking into python's code myself and its very well written and easy to understand
Anyway, it's bed time for me. Only 7 hours of sleep left.
had no issues
good night @hardy gorge
sleep tight Ves
Guys, it is still okay for contributors to leave reviews?
yes
Yours count towards the required too I think
Correct
it does, but we require at least 1 core dev still
you know it
i was thinking of it before i even hit enter
HA
Well, letβs share the load then π
we definitely want you to leave reviews, if you can.
and reviewing is a skill
you'll need practice to get good at it
this is a good place to find that practice.
Sadly we canβt find it anymore π¦ π
The PEP8 linter doesn't seem to check for multi-line [fbcu]-strings
?
s = (
f'{this} is a long '
'string that has '
'been spread '
f'across {n} lines'
)```
is it preferred to f the ones that dont need to be f'd too?
yes
Huh, I didn't know that
It doesn't explicitly say so in PEP8 but it follows from the aligning guidelines
for once my desire to align everything isnt antipep
- core devs have said "do it"

textwrap.unindent?
Yeah I think that's it
might work
I think uh
inspect.cleandoc or whatever
is better
I don't like either personally though
Unless we're wanting to remove the newline characters
I think I'm just confused by the intent
Hmm, I think I've just added the f prefix to the lines that needed it in the past
I'm more afraid that the linter would trigger of there is a f without any formating
Wait, does it actually?
the linter isn't the only one i'm afraid of triggering when i format for my eye's pleasure
Is there actually a plugin to enforce this?
I don't think so, Hem
I've seen dozens of reviews saying "this doesn't need an f", so we should probably stop doing that if we buy this
It's definitely not consistently enforced in any of the repos
and I think I buy the alignment argument. does help readability a little.
I don't really have an opinion. I like it fine without the additional f there, but I'm not opposed to adding it
I just don't think relying on us noticing it in reviews is going to work consistently
And, some reviewers not present here have commented to remove the unnecessary fs in the past
We could probably catch the latter pretty easily, but I don't think we can consistently enforce it that easily
s = f"{this} is a long " "string that has " "been spread " f"across {n} lines" lol
ill eat brb
Not enough people can be convinced to add black anyway
At least to anything that isn't a new start
Yeah, I noticed a couple oddities with black too
I think this one does not change the logic of the code (four separate strings that will be combined implicitly), while black reformatting it to one explicitly joined string in the source code would do that. It would also have to perform logic to see which prefixes the entire string should get and the prefixes may be incompatible.
The second one could have {} in it not meant for formatting (no prefix)
What I mean is, this is not broken; what else should it do?
This fits one line, so it goes on one line
yeah, but that looks ridiculous.
I agree, yeah
I can see why it'd do that
but black can't resolve it within the style framework it works in
if it was gonna reformat it to a oneliner, it ought to have put it inside a single f string.
What happens if they're all f-strings?
It can't do that, lemon
sure it can.
What if the second one had a literal {a} in it?
it's just code.
They're not the same type of string, technically
It would have to start parsing the strings to know if it should escape those and changing the actual code
yes.
I'm not saying that's what the black devs should've done, just that I agree with Ava that this example is terrible.
and it's the kind of thing that makes half of us not be open to using black.
on the pydis repos anyway
The existing ones at least
flake8-annotations is black formatted and nobody's noticed
The reason it doesn't work is that it (the code) doesn't follow the devs' undocumented recommendation
I wonder if that should have been in a PEP too
Might be worth raising an issue for
@hardy gorge I'd probably prefer modlog over message change log for the attachments deletion. Though the advantage of a discrete channel means we can more easily look for how often the filter is triggered & by what attachments so we can see if the rule needs adjusting
Another channel isn't going to bother me, most of it is muted and collapsed anyway
Hmm, true
I don't mind any of the solutions, I just think it would be a mostly dormant channel to begin with
We rarely ever relay messages from antispam and it's even rarer for them to contain attachments
Guess it doesn't really matter
Okay, let's do another log channel then. I'm not sure I'd like it in mod-log, since it's a channel that has actual information some people (or maybe just me) want to look at to see what's been happening
@gusty sonnet I use kind of the reverse approach in my old bot ```py
intervals = (
('week', 604_800), # 60 * 60 * 24 * 7
('day', 86_400), # 60 * 60 * 24
('hour', 3_600), # 60 * 60
('minute', 60),
('second', 1),
)
def display_time(seconds: int) -> str:
"""
Turns seconds into human readable time.
"""
message = ''
for name, amount in intervals:
n, seconds = divmod(seconds, amount)
if n == 0:
continue
message += f'{n} {name + "s" * (n != 1)} '
return message.strip()```
Hah!
That does look cleaner actually, in term of not having to reverse the result
But then you gotta do the multiplying beforehand
In term of performance I love your approach
I went with the easier to read lol
Imma steal your 's' approach @ornate moat
That is a damn clever way
I learned it from a fizzbuzz that I learned about a week into my python career
(and said fizzbuzz I think is one of the nicest piece of code even though it's not maybe the mots readable)
'Fizz' * (not n % 3) + 'Buzz' * (not n % 5) or n for n in range(1, 101)```
's' * (amount > 1) is readable enough lol
Hmm, or should I still stick with the 's' if amount > 1 else ''
Meh.
The latter is more readable
We arenβt all doing esoteric python! π
I edited the code, I realized a pitfall with years ( dividing int by 1 always gives 0 remainder ), added more tests, and added Ava's method
I have to mention it!
I would put it outside the f-string
something like plural = 's' if ... else '' f'{thing}{plural}'
That way fstring stays simple and naive, it will just assemble values into a string
Thanks Ava
Also Imma stick to .0f instead of int()
Would this be useful to include in our guides? https://guides.github.com/introduction/flow/
mm github have a lot of great guides
it'll be worth adding some links in when we make appropriate sections for them
I've used it in an older version, I remember giving up after getting frustrated
I essentially created a video instead of a gif, I think
like, photoshop says it's a video
so I can't export to gif
I can only export it as an mp4 or something
but when I try to convert it to a "frame animation", then the transform options disappear
and all the work I did is gone
so I tried to convert the mp4 to a gif
but that makes it really dirty looking
in one software I tried
and full of artifacts in the other
maybe @tough imp has some advice how I can possibly export this in a way that doesn't suck.
here it is guttersized.
the big version looks a bit shit but the tiny version looks alright I think.
okay, think I found a solution
@hardy gorge whatchu think honeycomb
That looks good to me. The larger one has a few artifacts and we were super critical of them with the first animated icons, but I think that comes with the gif format ultimately and they're not visible at server icon size anyway
does it?
just my poor excuse for a dust cloud, I think
the whole thing looks like an artifact 
but I do think the smaller one looks alright.
No, my screen is showing a couple of ligher "lines" in the blurple snake, but maybe it's just the downsize Discord does when embedding
Anyway, looks good
i think the last one came out alright
i use the export for web (legacy) option
and then mostly defaults
most of the artifacting i was seeing was compression on discord's side
mostly present with colour changes, the spinny one was a headache
just make sure you check loop forever, because the gifs dont loop by default using the web exporter
im still not happy with the christmas one tbh, it somehow ends up looking blurry
hmm.
yeah.
can the insides of the snakes maybe be a bit less transparent?
I think that's why it looks blurry
@crude gyro looks like the glow is the culprit, if i remove the glow its a lot more crisp, but the icon looks more poor
but i can have the glow come in on hover
this is a screenshot from my phone
first one has no glow and transparent fill
i think i prefer the first one, let me know what you think
yeah sorry lol the first screenshot is phone, second is computer
but the logos are the same
I'm still confused which one is the one you are suggesting
is the top one the old one?
anyway both of the bottom ones look pretty good to me.
you mean both logos on bottom screenshot or bottom logo on both screenshots (im sorry)
lol
the latter
but honestly those screenshots suck
they're very pixelated and it's hard to tell what's what.
the bottom logo on both screenshots looks brighter and has more contrast
i think it helps a lot to make the background darker
can you try this on the test server
alright im also fairly happy with it
did you change the hex too?
yep thats done
okay, cool. let's go with that, then

and, uh, nice work.
i mean its your logo lol
naw, you're fixing it
this is interesting
Tempted to see how well it works with pipenv
That is interesting
@tawdry vapor I think it would be easier here
for every Message in messages, there is a corresponding list (which could be empty) in attachments
So.. they should both have the same lengh
OK you can resolve that then
Nice bit logo
@tough imp how's the logo coming along? we'll need it live on Sunday, so time is running out.
π¬
give me 1 sec
ill get back to you shortly
making some fixes
@crude gyro how do you feel about this
looks great in that size, but how does it look in gutter size I wonder
guess we gotta test it out and see
you can sort of preview it in server settings
and if you apply it you get to see the first frame in the gutter
live testing!
alternatively its possible to not have the fade-in, fade-out
but then the first frame has snow, not sure how that works with you
1 sec ill export
yeah but the server settings preview is also much larger than the gutter image
although it does look good there, too
would you like me to make one with the flakes bigger so that we can switch them on-demand if needed
Why don't we just actually do a live preview for 5 seconds
Then we can all look how it will look and it doesn't really matter
most people are celebrating thanksgiving anyway
Or so I've heard
check it on your phones as well
Okay, it clearly looks like snow to me
it looks good on both desktop and phone
let me change it to my runner
oh. guess I fucked up and lost it.
never mind then.
it must be in the history of this chat
I still have it but only in windows.
rebooting
<@&267629731250176001> check out the guild icon while it lasts
haha. whoops.
it ran away
the icon was nice
the snowy one is scheduled for december
we were just doing a quick test because you cant really preview it on a non-booster server
fair
it's only one boost to unlock animated icon, right?
we should probably move one boost to the test server.
but it's like.. we don't have any margin then
for level 3
2 boosts
i only have the cheap non-boosty nitro
1 boost level
otherwise i'd help out
https://github.com/python-discord/branding/pull/37 pushed the runner PR
let it snow, I'd say
I like the faded one better, I think
this way we can reduce the filesize greatly as the loop is actually only like 1 sec, and on hover it snows forever
ah
I don't really care if it fades or not, I think it looks good in both.
you did a great job making the snow look realistic.
quite impressive work
the fact that they're spinning makes all the difference.
sounds like you should learn AE
yes i really should
you should and you will. it's a holiday miracle!
ive actually been wanting to since primary school lol
when we made runescape videos the kids that used AE had better intros than us Vegasers
filthy vegasers
but they were using templates 
ok so, fade or nofade
we need someone to decide
actually Ves said he prefers fade
so lets go with that
fade it is. how big is the file?
3 MB roughly
its not bad
the ones coming out of PS were up to 20 lol
well in 1024x1024
would you like me to PR the t-shirt template as well
or should I just dm it to you
@crude gyro PR is ready
mkay
okay, so
the banner, with the updated logo, is font too dim now in comparison?
what do you guys all think
it's probably fine
here's the design on a shirt.
At the size it's gonna be at, I think it's fine too
that looks blurry af
it does. it's probably too glowy.
the mockup is probably a little shittier than it would actually look
but it's probably still too glowy
I feel like it'd look better without any glow on a shirt
yeah
im on it
I mean, since you don't get semi-transparency
i think its because it blends into white
rather than into the background colour
its the exact same logo as the one on the banner, just enlarged
well let's just try it with no glow
but thats ur glow not my glow 
i can remove your glow too just need a minute
ill have to extract it from the original psd because i converted the snakes to smart objects so that i could animate them
but now i dont have access to the effects
loving the filename
_final_final_final
that's a lot better
although I'm a little unhappy now with the layer mask around the eyes.
makes sense when the glow is there but without it, it's way too big
gives it giant rings around the eyes.
would you mind spending a minute cleaning up the excessive layer masking?
there's some along the edges too
im trying to figure out how you've done it
the bits are on a layer at the bottom of the snakes folder I think
and those have layer masks
iirc
which I mostly just drew in free-hand
alright
thats fine, i will commit to the PR and ping you once its ready
excellent. thanks a million for doing this
no problem at all, thanks a million for this community 
Guys, is it possible to disable check_run on the gh webhooks, since it is redundant the azure webhooks?
Yeah we probably should if that's possible
There's a check suite option; the Check runs is currently not enabled
Well check_run is the extended version of check_suite, so I think you should disable it
Yes, I've disabled it
The first is not exactly the extended version; it's just for different kind of events (individual checks vs a check suite)
Oh yeah my bad they didnβt affect the same part
Because every actions included in check_suite is also in check_run, I was confused
Looks like it has worked!
can someone fill me in on what that did?
Checks are basically what CI reports back to GH when the build is done running
removes the top webhook
Yup, was getting a link to that, haha
Plus all of them except the first one (normally)
You haven't disabled it on the seasonalbot?
No, I'd only disabled it for bot to see what was going to happen
It takes a bit of time to modify the webhooks for all repos, so I rather waited to see if this change is desirable
Oki
yeah let's do it on seasonalbot too
What's the deal with this? https://discordapp.com/channels/267624335836053506/303906556754395136/650031568869654531
Did two filters trigger simultaneously?
Basically.
They spammed a lot before the mute was finally effected
So, the antispam triggered twice, since to runs for each on_message and will trigger as long as the messages have not been removed yet.
Normally, the bot is quick enough, but sometimes there's a bit of lag
It triggered after the first four, but they were able to sent more messages before they were muted.
Oh, they were able two sent four duplicates twice, so, yeah, forget the previous for every on_message explanation. They may have just been able to trigger it twice in rapid succession.
Thanks. So nothing to really worry about?
No, I don't think so. The double mute failure is a bit ugly in a public channel, but it does now gather the deleted messages into a single deleted message content (as you can see, they're all in one screen). We used to get multiple smaller deleted messages contexts, too, but there's now a delay/consume task.
oh wow ok i fixed it
my computer's clock was one hour ahead and i previously fixed it by putting -1 on the time widget
all good now

@sleek mason https://github.com/python-discord/bot/pull/643 can you look at this soon, it's a bit stale.
yes indeed, i'll do that soon :)
am not proffesional and all
but did someone looked after this ?
https://discordapp.com/channels/267624335836053506/635950537262759947/639484028012986369
probably no . cuz the thing it supposed to fix is still there
You can try searching through gh issues, and if there is none for it (opened or closed) you could open one @clever wraith
i will do it when i get home . in 24 hour
can someone slip in a quick sanity review for https://github.com/python-discord/seasonalbot/pull/319
@tough imp maybe we should fix the hex, it does suck a bit that one of the bits is outside the frame if we're gonna print it on a t-shirt..
and I had the idea that maybe it should just be a link to the advent of code website instead
it sort of.. makes it the aoc t-shirt, you know?
yeah
Moving from #esoteric-python:
Add -save and -load to eval to allow using a previous snippet multiple times to allow easier esoteric testing. The suggested implementation was to simply prepend the saved code to the new snippets.
Things that need discussing:
- Memory usage
Saving strings of up to 2k characters can take up a lot of space. We need to find ways to clean this somehow, maybe if unused for x hours it gets removed. Alternatively, we could try precompiling this, but this would come with limitations too. - Argument parsing
We need to parse -save and -load, and we want this to be as clean as possible (preferably not a code.split()[0] check)
A task to autoremove unused code after x hours sounds good, to prevent hogging memories
a way to deal with -save and -load would be adding more alias to !e and then we check the ctx.invoked_with or whatever it was
like !e-save / !e-load
Then we dont introduce extra args to the commands and have to deal with complicated of checking
I mean I had an ArgumentParserCommand somewhere in my old codebase that literally used argparse for command parsing
Same, I used to do that
Also, implementing a re-run emoji on the input message (something like π) to run the same code again in case it was edited to avoid copy pasting, could be nice
I think you're overthinking the arguments thing
That's a nice idea @green oriole
Maybe we could just use a LiteralArgumentConverter which could take an optional keyword, where it would return a literal if in the list of literals passed or return None/raise ArgumentError depending on optional param if not present
class LiteralConverter(Converter):
def __init__(self, *literals: str, optional: bool = False):
self.literals = literals
self.optional = optional
async def convert(self, ctx: Context, argument: str):
if argument in self.literals:
return argument
if self.optional:
return None
raise BadArgument(f"Expected literal: {self.literals}")
@command()
def eval(ctx: Context, action: LiteralConverter("-save", "-load", optional=True), *, code: str):
...
@spring ermine have you opened an issue so we donβt forget in 1 hour? π
That looks great @spring ermine
Btw, I see people structuring their issue with paragraph named abstract, specification, rationale and motivation, is it a good practice?
Yes, if you actually have that much to say.
You don't have to though
enforcing it would feel too bureaucratic
I feel like giving an introduction like that gives a clear picture of what we want, why we want it, and how we'd implement it, answering the 3 most common questions you could have as maintainer
Abstract:
In order to get the community involved with a project, the codebase should be united, clean, and structured. <insert 5 more paragraph>
Rationale:
If we have multiple ways to format / structure codes, it will make reading the codebase once it grows larger very hard. <insert 20 PEP>
Motivation:
When I was younger, with my first steps into the field, I have always wanted to join projects. First part is always be able to know what it is doing, hence good structures are amazing. <insert 20 more personal experience>
Specification:
@client.command()
async def hello():
print('Hello command was called for testing')
should be
@client.command()
async def hello(ctx):
...```
Jokes aside, it depends on how complicated / the level of details of your issue
If it's new features / enhancements, more often than not, if you can do that, please do
But whatβs the difference between the rationale and the motivation?
Β―\_(γ)_/Β―
Thatβs great!
hmm
so the converter seems to consume the parameter
i.e. it doesn't show up in the code parameter
this seem overengineered
why don't we just use a command group instead of parsing -save and -load flags
I actually have it working with what Danny gave me and it's a pretty clean solution
I just don't get why we would need that if we can use existing discord.py features for it
I asked him what he recommended we do tho
I don't really care what danny thinks we should do.
oh
I too was wondering why we didn't use a command group
but I'd just woken up so I wasn't sure if I was crazy
so, flags would make sense if you need to pass multiple flags at the same time
in that case I'll leave it up to someone else to impl since I don't have the experience nor time to implement command groups
but I can't think of a reason why we would do both -save and -load
yeah honestly we use command groups in a bunch of places already and it's as easy as using a decorator
it's absolutely trivial
I mean I have 7 minutes to do it if I want to do it in the next few days :P
@spring ermine you should run pipenv run precommit In your local copy of the bot so your code is linted before being commited
Yeah, but we have a special flake8 config so..
and it also means you're all set if the pre-commit config changes
Creating a virtualenv for this projectβ¦
Pipfile: /home/mart/git/bot/Pipfile
Using /home/mart/.pyenv/versions/3.7.0/bin/python3 (3.7.0) to create virtualenvβ¦
β Ό Creating virtual environment...Already using interpreter /home/mart/.pyenv/versions/3.7.0/bin/python3
Using base prefix '/home/mart/.pyenv/versions/3.7.0'
New python executable in /home/mart/.local/share/virtualenvs/bot-vQrXOkDg/bin/python3
Also creating executable in /home/mart/.local/share/virtualenvs/bot-vQrXOkDg/bin/python
Installing setuptools, pip, wheel...
done.
Running virtualenv with interpreter /home/mart/.pyenv/versions/3.7.0/bin/python3
β Successfully created virtual environment!
Virtualenv location: /home/mart/.local/share/virtualenvs/bot-vQrXOkDg
Error: the command pre-commit (from precommit) could not be found within PATH.
did you use pipenv sync --dev specifically with the dev flag
why does it even create a new venv when I already put it in a pyenv 
yeah you don't use other virtual envs, you have to let pipenv create it as it appends a hash after the project name that it tracks
no matter what project is involved, there's usually one established way to set it up. it's why there's contributors guidelines and setup docs.
The best part about programming XKCDs is that Randall isn't a programmer, haha
Then how is it always so accurate 
Hmm @green oriole is there a reason why we initialize to None and then reassign later in the __init__()
self.countdown_task = None
self.status_task = None
countdown_coro = day_countdown(self.bot)
self.countdown_task = asyncio.ensure_future(self.bot.loop.create_task(countdown_coro))
status_coro = countdown_status(self.bot)
self.status_task = asyncio.ensure_future(self.bot.loop.create_task(status_coro))```
Dunno, I wasnβt even on the server when the cog was created
I can delete it if you want
Hmm, yeah, refactor should be another PR
Adding cog_unload in itself is worth a PR i believe
yes it's an unnecessary part of init
i seen it too but the PR scope was worth just approving
pipenv run lint if you haven't setup precommit
Both
Hmm, anyone knows how to round ... relativedelta?
Still setup precommit
I'm running into 4 days 23 hours 59 minutes 59 seconds
With max 2 units it's 4 days 23 hours
The problem is that that date is from the api
So I wont know if it's lacking 1 second or 7 seconds
Well if it is always 59 seconds, you lack one second right?
The api is pretty fast
But I don't understand how the api could influence that
I have a feeling it's the microseconds
Let me try crazy stuff
Oh well, it'll be good enough xD
Any status on the Feature request ? Cuz i completed its code ;-;
I am so proud of myself today ;-;
@crude gyro
Please don't ping staff randomly
He asked for that last night
we all know when an issue ticket has been created
@glass pecan What should i do next , add a PR ?
you just have to be patient sometimes, you only added it less than a day ago
no, the issue hasn't even been approved yet
yeah I don't really have time to look at this atm
ok will wait
whats up?
So i have several question and answers to the comment you did an hour ago
then can you please address them in the ticket?
if it's directly related to the ticket, no it's best to keep discussion about the feature itself within the issue so it's not lost and other contribs can reference it
if it's generally about contributing such as linting and such, then you can ask it here
@green oriole there ?
Yep!
@clever wraith having the full project also imply some thing, for example using a config entry for emojis
Setup it? There is the guide in the pin
The guide have just been written, if have any issue, ping me :)
You have to start by the site first, that's the bottom file
Also if you spot any typo, that would be nice if you tell me about it :)
Yep this button
where to find that
And then enter https://github.com/python-discord/site
Oh yeah, tbh I would suggest you to go with command line :)
I think you need to close your currently opened project to make it appear
But I'm not a PyCharm pro
downloading git
got my dad's hotspot , it speed time
17 KB/s
wtf with git website its too slow
Don't think that's git fault of you do 17KB/s
Nice!
Why are you downloading kosa's fork π
F
You need to make you own fork and download it
I know I know, that's not a problem π
You can disable Windows Explorer Integrations and keep everything else
Yep this one
You did pipenv sync --devright?
yeah
