I'm not sure if users would find DMs annoying. I'm OK with this idea. Perhaps the informational message ("you're message has been deleted cause xyz") could also be moved to DMs to reduce clutter (assuming they have DMs enabled).
#dev-log
1 messages ยท Page 48 of 1
Build 20200616.1 succeeded
Requested by
GitHub
Duration
00:04:21
Build pipeline
Bot
Connected!
[python-discord/bot] New branch created: bug/mod/bot\-2a/webhook\-clyde
e935a9f Fix 400 when "clyde" is in webhook username - MarkKoz
Discord just disallows this name.
Build 20200616.2 succeeded
Requested by
GitHub
Duration
00:02:15
Build pipeline
Bot
Build 20200616.3 succeeded
Requested by
GitHub
Duration
00:02:27
Build pipeline
Bot
Sentry Issue: BOT-5G
ClientPayloadError: Response payload is not completed
File "bot/cogs/sync/cog.py", line 35, in sync_guild
await syncer.sync(guild)
File "bot/cogs/sync/syncers.py", line 195, in sync
diff = await self._get_diff(guild)
File "bot/cogs/sync/syncers.py", line 285, in _get_diff
users = await self.bot.api_client.get('bot/users')
File "bot/api.py", line 119, i...
This was fixed by 63f5028641e9b78c61d3bcfe3bbaa6f80c8a288a but I will leave this open to try to address the race condition.
Sentry Issue: BOT-37
RuntimeError: Session is closed
File "bot/cogs/reddit.py", line 106, in revoke_access_token
response = await self.bot.http_session.post(
File "aiohttp/client.py", line 357, in _request
raise RuntimeError('Session is closed')
Task exception was never retrieved
future: <Task finished name='Task-7817977' coro= exception=RuntimeError('Session is closed')>
`r...
Sentry Issue: BOT-54
RuntimeError: Session is closed
File "discord/abc.py", line 856, in send
data = await state.http.send_message(channel.id, content, tts=tts, embed=embed, nonce=nonce)
File "discord/http.py", line 165, in request
async with self.__session.request(method, url, **kwargs) as r:
File "aiohttp/client.py", line 1012, in __aenter__
self._resp = await self._coro
...
Postgres backup completed!
attr = attr[5:] # Remove "root." prefix.
The rest of the file uses the latter, and I think the intention is still clear given the comment right next to the statement.
Instead,
on_user_updateshould be used. Should this event be implemented, or are logs for the user, discriminator, and avatar not needed?
Given that we sync the name and discriminator of Users to the database and not just Members I am inclined to say yes.
Build 20200616.4 succeeded
Requested by
GitHub
Duration
00:02:15
Build pipeline
Bot
LGTM. Implemented a trivial change suggested by Mark, and updated the docstring for RedisCache to reflect the new boolean type available for values.
3527b58 Converters: handle ValueError when year for dur... - MarkKoz
9692093 Test for out of range datetime in the Duration ... - MarkKoz
298389f Remove redundant parenthesis from test values - MarkKoz
837bc23 Use await instead of asyncio.run in converter t... - MarkKoz
1e4766d Fix exception message assertions in converter t... - MarkKoz
Build 20200616.5 succeeded
Requested by
GitHub
Duration
00:02:36
Build pipeline
Bot
876b484 Add support for bool values in RedisCache - lemonsaurus
699760a Refactor help_channels.py to use RedisCache. - lemonsaurus
fc4eddc Store booleans as integers instead of strings. - lemonsaurus
94f096f Store epoch timestamps instead of strings. - lemonsaurus
40a774e Fix potential race condition. - lemonsaurus
[python-discord/bot] branch deleted: help\_channel\_rediscache
Build 20200616.6 succeeded
Requested by
GitHub
Duration
00:04:13
Build pipeline
Bot
Connected!
2426ea2 Revise inaccurate typehint for Optional reason - kosayoda
Rock solid. Updated typehints for reason to reflect that it can be None.
Build 20200616.7 succeeded
Requested by
GitHub
Duration
00:02:23
Build pipeline
Bot
@kosayoda IMO, the optional type annotations are mostly unnecessary and hurt readability. The reason already has a default value of None, which should be enough to clue readers in that it's optional. I already have a commit I can push with the annotations removed.
I like type hints with the explicit Optional type hint.
OK. Should there be extra indentation for the parameters? PEP 8 suggests this because it argues that they'd otherwise not be distinguishable from the function body. However, they don't put the closing parenthesis and colon on a separate line, which I argue does adequately distinguish parameters from the body along with the mandatory docstring.
I'm honestly not married on either (the Optional type hint) and/or the indentation we choose, but my personal preference is to use the Optional, but not add additional indentation.
If you feel like it greatly increases readability by leaving the Optional out, I'm fine by that as well; what's the general style throughout the bot? I personally probably always add the Optional explicitly.
I generally agree that it should be explicit. But I think it's also okay to break consistency to improve readability. Ultimately, these type annotations are supposed to help us, not hurt us. I honestly find most parameter splitting to be ugly, like in this case, so I'd rather avoid it. I also find long function signatures ugly, but what can we do ๐คท .
I'll leave the explicit type hints but remove the extra indentation since it's more consistent with other code. We should consider updating o...
Build 20200616.8 succeeded
Requested by
GitHub
Duration
00:02:28
Build pipeline
Bot
Build 20200616.9 succeeded
Requested by
GitHub
Duration
00:02:16
Build pipeline
Bot
I believe the cyrillic ะต would be better here and seems to look the same as a normal e
with the desktop client.
The e's case is now also "destroyed" when it goes through the sub, so I think it wouldn't hurt to find something that looks like an E, if there is something like that and is worth the effort.
Do we also need to sub the names in reddit/python_news? The consistency is nice but having clyde in those is extremely unlikely
In that case, I'll base a new branch off this one and refactor the cog along with adding on_user_update. There's currently a lot of redundant code. I'll leave this PR alone cause it doesn't remove any functionality we didn't already have.
Postgres backup completed!
In what case username can be None? So much how I see, this should pass str every time.
I don't want to spam with same review comments, but L50 on sync cog and L151 issues is repeating over their files.
[python-discord/bot] New review comment on pull request #1002: Sync: ignore events from other guilds
You have to pass MockGuild here and adding this ID after fixing cog L50's issue.
[python-discord/bot] New review comment on pull request #1002: Sync: ignore events from other guilds
This is not working. This have to be role.guild.id != constants.Guild.id. The current statement is always True.
Build 20200617.1 succeeded
Requested by
Joseph Banks
Duration
00:04:22
Build pipeline
Bot
Connected!
09f53ca Check infraction reason isn't None before short... - MarkKoz
08c96f9 Fix check for bot actor in infractions - MarkKoz
2426ea2 Revise inaccurate typehint for Optional reason - kosayoda
6fe0bc1 Add optional type annotations to reason in pard... - MarkKoz
20a8b6f Format parameters with a more consistent style - MarkKoz
[python-discord/bot] branch deleted: bug/mod/bot\-68/ban\-strips\-none
[python-discord/bot] New review comment on pull request #1002: Sync: ignore events from other guilds
Good catch. Can't rely on the tests when I write the tests incorrectly too ๐
Build 20200617.2 succeeded
Requested by
GitHub
Duration
00:03:56
Build pipeline
Bot
Connected!
It's optional here though every use of that function passes a name.
I don't see a problem with leaving it optional anyway.
I believe the cyrillic ะต would be better here and seems to look the same as a normal e
Good find. The website I used didn't show Cyrillic characters as characters based on "e" (probably only considered latin alphabet). Cyrillic also has an upper case E so I will use that too. I wonder if there's a good way to do a case sensitive substitution. May just be easiest to chain two substitutions.
Do we also need to sub the names in reddit/python_news? The consistency is nice but having cly...
Thanks for working through all my requested changes.
8570bd2 Create cooldown.md - crazygmr101
97710d5 Update cooldown.md - crazygmr101
06d8ab2 Rename to customcooldown.md - crazygmr101
b71ff0f Update example to not be in a cog - crazygmr101
b2195f1 Move the not rate-limited message into else - crazygmr101
Build 20200617.3 succeeded
Requested by
GitHub
Duration
00:04:07
Build pipeline
Bot
Connected!
Build 20200617.4 failed
Requested by
GitHub
Duration
00:00:47
Build pipeline
Bot
Build 20200617.5 succeeded
Requested by
GitHub
Duration
00:02:19
Build pipeline
Bot
9b8d688 Autodelete offensive messages after one week. - Akarys42
59914bf Revert whitespace changes - Akarys42
9c78146 Move offensive message delete time to config file. - Akarys42
f67378c Remove the possibility that we send a message t... - Akarys42
1eb057b Rename offensive_msg flag to schedule_deletion. - Akarys42
Build 20200617.6 succeeded
Requested by
Joseph Banks
Duration
00:03:52
Build pipeline
Bot
Connected!
When a message trips the filter on the bot it is removed after a period of time. During this period it is a record in the database.
When this deletion date is reached the bot will attempt to remove the message from Discord and remove the record from the offensive message table. We currently handle for the message being not found (deleted) but if another error occurs resulting in the message not being deleted we still continue to delete the database record, causing the message to be left ar...
Site issue: python-discord/site#364
The site issue contains most of the details here:
When a message trips the filter on the bot it is removed after a period of time. During this period it is a record in the database.
When this deletion date is reached the bot will attempt to remove the message from Discord and remove the record from the offensive message table. We currently handle for the message being not found (deleted) but if another error occurs resulting in the message not...
This issue is blocking python-discord/bot#1013
Build 20200617.7 succeeded
Requested by
GitHub
Duration
00:02:28
Build pipeline
Bot
Build 20200618.1 succeeded
Requested by
GitHub
Duration
00:02:37
Build pipeline
Bot
Returning an exception rather than raising it is weird. I don't agree with this approach. I think that if the cog isn't loaded, it should not attempt to get the tag and let the BadArgument on like 38 be raised.
Technically, the cog could be unloaded between when the converter is used and this part of the code is reached. But this is an edge case that I don't think we should worry about, as it would overcomplicate the code.
Thought about the aliases/grouped signatures, we only fetch 3 to keep it short-er so which ones do you think should be included if more than 3 are present?
Going with the previous object.__lt__ example, we can't get them all because 6 separate codeblocks would be huge.
Collecting all the signatures under the fetched ones, and then searching up if there's still space left, or picking the fetched one and then going up from the bottom came to mind for how to do it
Brings improvements that will get listed here as implemented into the Doc cog
- relative urls are now resolved to absolute, allowing them to be used in discord
- doc get is now greedy to allow a few symbols like
not into be fetched - fetching docs from classes now doesn't try to also include methods when they fit within the character limit
Looking at the module I believe a slight refactor is also in order so I'll also be doing that as it comes up
Build 20200618.2 succeeded
Requested by
GitHub
Duration
00:02:28
Build pipeline
Bot
I'm going to close this because the PR was merged. Feel free to open a separate issue if you still think the reaction should be moved.
For each direction, there are probably cases where that direction is preferable, but that cannot be determined by the code. Therefore, I don't think it matters which ones you choose. Might be best to stick to displaying whatever is adjacent to the queried signature.
Build 20200618.3 succeeded
Requested by
GitHub
Duration
00:02:32
Build pipeline
Bot
This only works for the tag paths. It will fail for everything else:
ValueError: '/home/mark/repos/python/bot-pydis/bot/cogs/source.py' does not start with '/bot'
For everything else, you have to use the following (note this won't work on the tag paths)
Path(filename).relative_to(Path.cwd()).as_posix()
The as_posix() is added to solve a separate issue - to force forward slashes even on Windows. However, this will still fail for tags cause they are already r...
Postgres backup completed!
Build 20200618.4 succeeded
Requested by
GitHub
Duration
00:02:25
Build pipeline
Bot
Can you exclude "tag" from this message when the cog isn't loaded?
Added check in caa4210.
Build 20200618.5 failed
Requested by
GitHub
Duration
00:00:48
Build pipeline
Bot
Build 20200618.6 succeeded
Requested by
GitHub
Duration
00:02:23
Build pipeline
Bot
Build 20200618.7 failed
Requested by
GitHub
Duration
00:02:11
Build pipeline
Bot
Build 20200618.8 failed
Requested by
GitHub
Duration
00:02:11
Build pipeline
Bot
Full traceback:
timeout: The read operation timed out
File "urllib3/connectionpool.py", line 421, in _make_request
six.raise_from(e, None)
File "<string>", line 3, in raise_from
# Permission is hereby granted, free of charge, to any person obtaining a copy
File "urllib3/connectionpool.py", line 416, in _make_request
httplib_response = conn.getresponse()
File "http/client.py", line 1322, in getresponse
response.begin()
File "http/client.py", line 303, i...
Build 20200619.1 succeeded
Requested by
GitHub
Duration
00:02:55
Build pipeline
Bot
I updated to match most of the changes in #866, but I need a bit of help to get one more percentage coverage. I don't know how to test these 2 small areas that are 1%.
Postgres backup completed!
9b8d688 Autodelete offensive messages after one week. - Akarys42
59914bf Revert whitespace changes - Akarys42
9c78146 Move offensive message delete time to config file. - Akarys42
f67378c Remove the possibility that we send a message t... - Akarys42
1eb057b Rename offensive_msg flag to schedule_deletion. - Akarys42
Build 20200619.2 succeeded
Requested by
GitHub
Duration
00:02:40
Build pipeline
Bot
Build 20200619.3 succeeded
Requested by
GitHub
Duration
00:02:45
Build pipeline
Bot
9a58b45 Incidents tests: write tests for on_raw_reacti... - kwzrd [e760bd3](https://github.com/python-discord/bot/commit/e760bd38b5d625011318a9ddfc98bb52570d1c3a) Incidents: review log levels; use trace` where... - kwzrd
Build 20200619.4 succeeded
Requested by
GitHub
Duration
00:02:41
Build pipeline
Bot
Build 20200619.5 succeeded
Requested by
GitHub
Duration
00:02:16
Build pipeline
Bot
Is there something else I could have done this to mock an async iterator? This seems like unnecessary boilerplate, but I haven't found anything in unittest that would support an async for loop out of the box.
I find this super ew, but I just wasn't able to come up with anything better.
Should &PYNEWS_WEBHOOK be indented further? I didn't want to introduce extra unnecessary diff to the config file, but depending on how you look at it, the alignment is now "broken", although at the same time it's not an issue as everything fits.
This is now considered ready for review.
c8cbd1e Pipenv: add script for html coverage report - kwzrd
[python-discord/bot] New branch created: kwzrd/pipenv\-html\-script
Similarly to the report script defined just below, which allows us to type pipenv run report, this will allow us to omit the coverage from pipenv run coverage html.
Build 20200619.6 succeeded
Requested by
GitHub
Duration
00:03:12
Build pipeline
Bot
If this internally handles the None (and it does) then I agree the annotation is appropriate, but why does it handle it? Is it to be "shielded" from callers which may accidentally give a None? Won't that just push the error further, since something else that is expecting a string will get the declyded None?
None is a valid value for webhook username (acts like an empty string and defaults to the webhook name) that may get passed in so I don't think there's any problem with letting None through.
In that case I agree that this is perfectly fine.
These are all mostly just grammar and spelling mistakes. I think this should be all good after these comments are addressed.
"question": "What year was the IBM PC model 5150 introduced into the market?",
"question": "In what country is the Ebro river located?",
This should apply the clyde cleanse from #1009 once it is merged.
9b8d688 Autodelete offensive messages after one week. - Akarys42
59914bf Revert whitespace changes - Akarys42
9c78146 Move offensive message delete time to config file. - Akarys42
f67378c Remove the possibility that we send a message t... - Akarys42
1eb057b Rename offensive_msg flag to schedule_deletion. - Akarys42
There's one small thing that I'd like to see adjusted, but otherwise I think this is a good fix.
My personal approach would have been turning it into something like clyd[e] (if that fixes the 400) just because I'd see that as more predictable w.r.t. various fonts and platforms. It'd also feel more "direct" to me, i.e. fixing the issue rather than "hiding" it, but I don't have a problem with this approach (the only change requested is the "" -> None issue).
This will also return None if an empty string is given, which I suppose is fine if they are interchangeable in the webhook username field, but the docstring denies that. Explicitly checking for None on L131 seems like a better idea than adjusting the docstring though.
Build 20200619.7 succeeded
Requested by
GitHub
Duration
00:02:31
Build pipeline
Bot
Build 20200619.3 succeeded
Requested by
GitHub
Duration
00:00:56
Build pipeline
Seasonal Bot
Is this empty line required?
I think these should be in-file constants instead.
I think this should better like this:
return all(
message.channel.id == Channels.incidents, # Message sent in #incidents
not message.author.bot, # Not by a bot
not message.content.startswith("#"), # Doesn't start with a hash
not message.pinned, # And isn't header
)
c7373fa Token remover: ignore DMs - MarkKoz
2fa7429 Token remover: move bot check to on_message - MarkKoz
3aecf14 Token remover: exit early if message already de... - MarkKoz
0ad19a4 Webhook remover: ignore DMs and bot messages - MarkKoz
94a4f8e Webhook remover: exit early if message already ... - MarkKoz
[python-discord/bot] branch deleted: bug/filters/bot\-58/removers\-ignore\-dms
Build 20200619.8 succeeded
Requested by
GitHub
Duration
00:03:43
Build pipeline
Bot
Connected!
The all function doesn't take *args, it takes a single iterable.
I find both of these noisy and ugly:
return all((
# conditions
))
return (
(
# conditions
)
)
Would you prefer either of these? I personally think return all(conditions) is really nice.
The reason why I went for conditions = (...) over just:
return (
a
and b
and c
)
Is that I find the and/ors to also get noise when there's so many of them. The possible short-circuit can be attractive if there are performance implications to consider, but I don't think that's necessarily the case here, so I went for the solution that I found the most beautiful.
When my solution is possible, then I think the current solution is best.
These lines should be merged together.
Why? While set operations are neat, they can be difficult to read. I found the intermediate step fairly helpful: both the assignment and not missing_signals are quite expressive.
I'd find this a lot more difficult to digest:
return not ALLOWED_EMOJI - own_reactions(message)
I'm not saying you're wrong, I'm just wondering why you'd prefer this to be one-lined (especially if the comment won't fit).
Sure, that's fine. No need to close this though.
Build 20200619.4 succeeded
Requested by
GitHub
Duration
00:00:57
Build pipeline
Seasonal Bot
I'm sometimes quite generous with whitespace ~ I think this should be removed, yeah.
The archive method also has whitespace between the try-except-else blocks which can probably go. I'll look into it.
This should have a small comment about it. Then 1 line should better. But maybe is better to listen to someone else opinion too.
Webhook.send will return None if unless explicitly wait=True. See here.
The annotation is there because we have wait=True, so we can make a promise of what the type will be. I like these hints because then PyCharm tells me what methods there are, and what params they take. The d.py lib isn't annotated, so this cannot be inferred automatically.
Because I want the delete listener running concurrently with the delete request.
We do:
- Launch delete listener task
- Delete message
- Await listener finishing (maybe it has received the delete event already)
If we skip step 1. and only begin listening after dispatching the delete event, I think we risk missing the event (because d.py may receive it before we register the listener). For what it's worth, I was not able to replicate that - in the testing server, I always cau...
Also, type hint should Optional[discord.Message] ad L268
OK, now I understand. Just as a note that dpy have PR opened about adding type hinting.
Yeah, maybe, I'm not sure. I placed them here because I thought their purpose would be better understood when defined where they are used, especially since they are used in one place only, and because you don't really need to see these at the top of the module. In fact, the only reason why I defined them here rather than just passing them into history and sleep directly as literals is that I wanted to log them on line L131 before starting the loop.
I'm not opposed to putting them at ...
I generally prefer checking for None explicitly. I want to return if message is not None, not if message is truthy. I don't feel like "Message can never be falsey, so we can get away with this" is a good enough justification - explicit is better than implicit, after all - but yeah, I suppose it's more of a personal preference. If the check was implicit, and I were reviewing this and didn't know whether a Message can ever be falsey, I'd have to go searching for it. This way, I don't....
Build 20200619.9 succeeded
Requested by
GitHub
Duration
00:02:39
Build pipeline
Bot
Cleaned up the whitespace in b563063. It was needlessly spaced out considering the first clause only logs (that really doesn't have to be there, but I found myself appreciating it when testing).
Ended up not reducing the whitespace in archive as I feel the extra space makes it considerably more readable.
8659965 Add forms application and base form model - j03b
[python-discord/site] New branch created: joseph/add\-form\-system
This PR introduces a forms application which will allow for collection of survey and form results for data such as events sign ups, insights and so on, effectively replacing Google Forms which we use now.
Build 20200619.1 failed
Requested by
GitHub
Duration
00:01:34
Build pipeline
Site
Build 20200619.10 succeeded
Requested by
GitHub
Duration
00:04:59
Build pipeline
Bot
Connected!
Build 20200619.11 succeeded
Requested by
GitHub
Duration
00:02:12
Build pipeline
Bot
I prefer chaining logical operator but I'm not too fussed.
Isn't this the same as <= i.e. ALLOWED_EMOJI is a subset of own_reactions?
I don't think these are necessarily constants worthy, putting them at the top of the file seems fine IMO. Constants are useful for development when testing things like the offensive message remover (we don't want to sit waiting for a week to confirm it works) but I think there is little reason to change these and they are constant... constants. Putting them at the top of the file would be nicer though I think.
I prefer for log messages to specify the object(s) they pertain to. However, I suppose you can get away with it because of the event lock.
Specifying the message ID makes the logs more useful for debugging.
log.trace(f"Skipping message {message.id}: not an incident")
continue
if has_signals(message):
log.trace(f"Skipping message {message.id}: already has all signals")
Specifying exc_info is redundant when it's being logged within an except.
except Exception:
log.exception("Failed to archive incident to #incidents-archive")
I dislike type annotations on variables, but this is just a difference of opinion. Not going to hold it against you for using them.
581573f Write unit test for sub_clyde - kwzrd
Build 20200619.12 succeeded
Requested by
GitHub
Duration
00:02:12
Build pipeline
Bot
9b8d688 Autodelete offensive messages after one week. - Akarys42
59914bf Revert whitespace changes - Akarys42
9c78146 Move offensive message delete time to config file. - Akarys42
f67378c Remove the possibility that we send a message t... - Akarys42
1eb057b Rename offensive_msg flag to schedule_deletion. - Akarys42
Build 20200619.13 succeeded
Requested by
GitHub
Duration
00:02:04
Build pipeline
Bot
bcf6993 Fix 400 when "clyde" is in webhook username - MarkKoz
311326b Make sub_clyde case-sensitive and use Cyrillic e's - MarkKoz
55db81a Preserve empty string when substituting clyde - MarkKoz
581573f Write unit test for sub_clyde - kwzrd
28919b6 Merge branch 'master' into bug/mod/bot-2a/webho... - kwzrd
[python-discord/bot] branch deleted: bug/mod/bot\-2a/webhook\-clyde
Build 20200619.14 succeeded
Requested by
GitHub
Duration
00:04:17
Build pipeline
Bot
Connected!
Build 20200620.1 failed
Requested by
GitHub
Duration
00:01:58
Build pipeline
Site
Build 20200620.2 failed
Requested by
GitHub
Duration
00:01:58
Build pipeline
Site
Lint is failing because no tests have been written. I'll sort that out once I've built the feature.
Postgres backup completed!
662ca58 Incidents: remove redundant exc_info passing - kwzrd
20b27f3 Incidents: make logs contain the message id the... - kwzrd
6d3a91c Incidents: make crawl limit & sleep module-leve... - kwzrd
b8ada89 Incidents: simplify set operation in has_signals - kwzrd
98b8947 Incidents: try-except Signal creation - kwzrd
Build 20200620.1 succeeded
Requested by
GitHub
Duration
00:02:31
Build pipeline
Bot
I made them module-level constants in 6d3a91c. I'm still not entirely convinced that it's better in any way (now they need more documentation), but I don't feel strongly about it.
@MarkKoz Using issubset is an excellent suggestion, thank you for that. Applied in b8ada89, it's beautiful!
I'm going to keep it as is then if no one feels too strongly. Feel free to reopen the conversation.
@ks129 Please mark this as resolved if you're happy with the justification.
Yes, you're right, these should log the id. I reviewed my logs and added ids where I felt it was appropriate in 20b27f3.
It's an interesting problem because if you have a stream of trace/debug logs sprinkled throughout a function, you don't want to be logging the ids in each message. So I usually just log this information in the first one, and then it's clear that "message" refers to the same object. But if they are followed by an >= info log, it should probably log the id again, bec...
I tried it and ended up being very happy with it. The idea crossed my mind at one point but then I ended up not doing it, because I originally had both the role and emoji check as a single conditional - they both remove the react and abort. Eventually though I felt that it'd be nice to actually log why it was removed, and I ended up making them disjoint.
With this change, the ALLOWED_EMOJI variable is only used by has_signals so the name no longer makes much sense, and so I ended up ...
c7373fa Token remover: ignore DMs - MarkKoz
2fa7429 Token remover: move bot check to on_message - MarkKoz
3aecf14 Token remover: exit early if message already de... - MarkKoz
0ad19a4 Webhook remover: ignore DMs and bot messages - MarkKoz
94a4f8e Webhook remover: exit early if message already ... - MarkKoz
Fix from #1009 applied in a8b4e39 with f240a97 providing a simple test for it.
Build 20200620.2 succeeded
Requested by
GitHub
Duration
00:02:27
Build pipeline
Bot
@kwzrd This is OK. But only with write access or PR opener can mark reviews (even own reviews) resolved.
Perhaps class constants would be more fitting to give the names a bit more meaning without explaining it all
- b9d483c: Moved exception logging when cog is being unloaded and messages are still
not consumed fromcog_unloadtoconsume_messagesitself in
try-except block to avoid the case when requesting result too early
(before cancel finished). Resolves #1008 - ac302d3: When user left from guild before bot can add Muted role, then catch this
error and log. Resolves #1006. Also found the issue that when the user is muted and joins and quickly leave, then this fail too (tested in dev server)...
Build 20200620.3 succeeded
Requested by
GitHub
Duration
00:02:10
Build pipeline
Bot
What should happen if an attempt is made to schedule using a taken ID (meaning another task is currently scheduled with that ID)? Currently, only a debug log is sent. The problem is that the coroutine given will never be awaited and will eventually cause a warning.
A boolean value could be returned to indicate success or failure, which will put the burden on the caller to close the coroutine and prevent the warning. However, this is cumbersome; pretty much every caller will want to ensure...
Build 20200620.3 failed
Requested by
GitHub
Duration
00:01:43
Build pipeline
Site
5e02d5d Scheduler: use separate logger for each instance - MarkKoz
5ded965 Scheduler: directly take the awaitable to schedule - MarkKoz
4bb6bde Scheduler: name tasks - MarkKoz
5130611 Scheduler: add support for in operator - MarkKoz
c81d3bd Scheduler: use pop instead of get when cancelling - MarkKoz
[python-discord/bot] New branch created: feat/backend/800/scheduler\-redesign
Build 20200621.1 succeeded
Requested by
GitHub
Duration
00:02:16
Build pipeline
Bot
Build 20200621.2 succeeded
Requested by
GitHub
Duration
00:02:24
Build pipeline
Bot
Postgres backup completed!
Build 20200621.3 succeeded
Requested by
GitHub
Duration
00:02:33
Build pipeline
Bot
Build 20200621.4 succeeded
Requested by
GitHub
Duration
00:02:24
Build pipeline
Bot
So I added this to create the webhook username. It follows this format: reported_by | actioned_by. The format is easily adjustable so let me know if that doesn't work (using parens is an alternative).

Maximum webhook username length is 80 (request fails if above), so this will cut off anything above:

This is implemented as a check in the get subcommand when the symbol is empty, but to me the nicer behaviour would be that output only for me !doc and nothing for an empty get.
The set shadows the set symbol from the inventories, any opinions on handling it and other subcommands as symbols when the role check doesn't pass? Currently there's just ...
The get_pep_embed coro does a lot of stuff and I think it should be separated in some way (for example as suggested in my last review comment).
Its docstring is indescriptive and doesn't mention that it's sending out error embeds to through the ctx.
In the current PEP format, the PEP number can only contain 4 digits so we can dismiss any input that's above that to avoid refreshing the loaded PEP cache needlessly
This is no longer valid when used in multiple modules, now clearing the cache from the docs will also delete the PEP cache.
this can use # region: PEP and later # endregion to be collapsible in some editors
Build 20200622.1 succeeded
Requested by
GitHub
Duration
00:02:23
Build pipeline
Bot
4890cc5 Created tests for bot.cogs.logging connected ... - ks129
63be23c Merge branch 'master' into logging-tests - ks129
ededd18 Logging Tests: Simplify DEBUG_MODE False test - ks129
3e7e66c Merge branch 'master' into logging-tests - kosayoda
03b6131 Merge pull request #950 from ks129/logging-tests - kosayoda
Build 20200622.2 succeeded
Requested by
GitHub
Duration
00:04:09
Build pipeline
Bot
Connected!
Connected!
An anti-spam DeletionContext will re-upload attachments to the #attachment-log channel. The anti-malware cog will delete attachments that are blacklisted. This sometimes results in a 404 when anti-spam is trying to upload the attachments:
Sentry Issue: BOT-6D
NotFound: 404 Not Found (error code: 0): asset not found
File "bot/utils/messages.py", line 81, in send_attachments
a...
Postgres backup completed!
[python-discord/bot] New comment on issue #1018: Race condition between anti\-spam and anti\-malware
We seem to have multiple race conditions between our various message processing utilities and we've patched some of them already (e.g., the token removal and codeblock suggestion utilities).
There's also still the possibility that messages that get removed by one of our filtering tools (anti-spam, filtering, anti-malware) still trigger command responses from our bot, as both the on_message listeners as well as the command functions are obviously process asynchronously.
This makes me w...
[python-discord/bot] New review comment on pull request #1002: Sync: ignore events from other guilds
I really like the idea of checking membership first. Makes for a much nicer error should the test fail on it not being there, I should do this too.
9b8d688 Autodelete offensive messages after one week. - Akarys42
59914bf Revert whitespace changes - Akarys42
9c78146 Move offensive message delete time to config file. - Akarys42
f67378c Remove the possibility that we send a message t... - Akarys42
1eb057b Rename offensive_msg flag to schedule_deletion. - Akarys42
Build 20200622.3 succeeded
Requested by
GitHub
Duration
00:02:23
Build pipeline
Bot
Build 20200622.4 succeeded
Requested by
GitHub
Duration
00:04:09
Build pipeline
Bot
Connected!
@Numerlor I don't want to split get_pep_embed much. I made small changes there, is this better now?
Build 20200622.5 succeeded
Requested by
GitHub
Duration
00:02:24
Build pipeline
Bot
Build 20200622.1 succeeded
Requested by
GitHub
Duration
00:04:10
Build pipeline
Site
Just from playing out with it for a bit on a server.
Leading indentation breaks ast.parse with unexpected indents, so the detection doesn't pass in some relatively common cases.
And would accounting for ipython's repl be worth it? the users are usually a bit more advanced and there aren't that many but I guess it still happens sometimes. If they were to be implemented, both of these are somewhere in ipython as they're properly interpreted when posted into it if that helps.
@Numerlor Thanks for pointing out the indent issue. The original code did try to dedent, but I removed it because I thought it was only for making the output pretty.
Do you think textwrap.dedent is adequate, or should it try to keep the attempted fix of the original code? It tried to account for leading spaces of the first line of nested code not being copied. For example:
# wrong
def foo(self):
return bar
# correct
def foo(self):
return bar
...
9b8d688 Autodelete offensive messages after one week. - Akarys42
59914bf Revert whitespace changes - Akarys42
9c78146 Move offensive message delete time to config file. - Akarys42
f67378c Remove the possibility that we send a message t... - Akarys42
1eb057b Rename offensive_msg flag to schedule_deletion. - Akarys42
Build 20200623.1 succeeded
Requested by
GitHub
Duration
00:02:33
Build pipeline
Bot
Postgres backup completed!
I think the encrypt/decrypt/about is good. If you feel it's appropriate, encrypt could have an alias rightshift/rshift or similar.
The group command will also receive a Context object which should be aware of whether a sub-command was invoked, see here. Alternatively, it is possible to pass invoke_without_subcommand=True to the group decorator, which will make...
Thanks for the insight. I'll look into delegating the arguments to an encrypt subcommand by default; currently I just have the .caesarcipher command group display its help embed. I'll be working on it soon and I should make a PR once it's ready.
... currently I just have the .caesarcipher command group display its help embed
Yeah, that should probably stay, as it's the standard behaviour. It may become messy to only auto-invoke encrypt if the group receives valid params for it. Just having encrypt as a subcommand that has to be invoked explicitly is probably perfectly fine - the convenience of not having to invoke it directly isn't worth messy code, in my opinion. It's up to you - just wanted to share a couple of ideas.
Haven't read through the latter half of the test module yet but it looks decent. The comments and questions I've left mainly relate to code style, I think conceptually the approach taken when writing these tests is good!
This will now comfortably fit on one line.
Not asking you to change these, but wouldn't it be better to have a namedtuple or a similar construct to define the cases? The repeated subscription with string literals seems fragile and needlessly inconvenient.
What is the motivation for defining this here? As far as I can tell, only the tests use it. Perhaps it'd make more sense to have the definition in the test module?
Postgres backup completed!
Build 20200624.1 succeeded
Requested by
GitHub
Duration
00:02:28
Build pipeline
Bot
A few more comments - in general, I think it's nice when the tests are defined in the same order (top to bottom) as the tested code. Makes it a lot easier to navigate when you have them open side by side.
I'm not finding some_mock to be a particularly good name, if it's meant to represent something that is not a user, that's a useful piece of information that can be included in the variable name.
You're only setting the discriminator attr but later on you're accessing id and name too - is that by design?
I'd strongly prefer if the names you're assigning to matched the keys. This creates even more indirection between the definitions above and the code below. You're using 3 different names (key, local variable, subTest kwarg) for the same thing.
I don't like the amount of branching here too much.
if error:
...
else:
...
if not error:
...
else:
...
Can these be joined together?
You marked @MarkKoz's comment above as resolved, but is it? Why are you only checking if post was awaited if it won't raise?
Additionally I'm finding this fairly awkward:
if isinstance(test_user, MagicMock):
I don't think it's necessary to test whether a debug log was made (if that doesn't indicate that some other action was also performed). But it can stay. I'm just wondering whether we could come up with a nicer way of branching here.
Mock is awaited only when no errors raised.
That was just for avoiding error. I added now id and name too.
Build 20200624.2 succeeded
Requested by
GitHub
Duration
00:02:22
Build pipeline
Bot
Removed debug call assertion. Joined these if statements together. About only asserting post, what else this does? I'm also asserting returned result, but this calls nothing else what I could assert.
Is that so? Try removing the conditional - test passes just fine.
Correct me if I'm wrong, but with self.user.send being an AsyncMock, the side effect isn't actioned until after the send coro is awaited.
I removed these when moved to namedtuple.
user is now removed from the name.
Used here assertIn instead and in one other location.
I added namedtuple for some test cases, but for others, this will be such mess and no one will understand, what thing is what, especially these what have embeds/many keys.
I added the use case for this in the file.
For me, the test doesn't pass when I remove conditional: this says that it's awaited 0 times.
Build 20200625.1 succeeded
Requested by
GitHub
Duration
00:02:37
Build pipeline
Bot
Postgres backup completed!
Build 20200625.2 succeeded
Requested by
GitHub
Duration
00:02:43
Build pipeline
Bot
[python-discord/bot] branch deleted: \#364\-offensive\-msg\-autodeletion
[python-discord/bot] branch deleted: bug/info/\_fuzzy\_search/wrong\_annotation
Relevant Issues
Closes #420.
Description
This adds a .caesarcipher command group with decrypt, encrypt, and info subcommands in the Fun cog. The decrypt and encrypt subcommands also support message IDs and links similarly to other [Fun](https://github.com/python-discord/seasonalbot/blob/bb30d2904b4a3273d4b10dc9548c542d65f0c379/bot/exts/evergreen/f...
Build 20200625.1 succeeded
Requested by
GitHub
Duration
00:01:05
Build pipeline
Seasonal Bot
Quick review without actual testing.
I think better is use invoke_without_command=True in command.group decorator.
It's not a good idea to load this on every use. Better do this in __init__.
I think better is use Union[str, Message] converter instead converting this manually. Same in L163.
Build 20200625.3 succeeded
Requested by
GitHub
Duration
00:02:25
Build pipeline
Bot
Build 20200626.1 succeeded
Requested by
GitHub
Duration
00:01:01
Build pipeline
Seasonal Bot
Postgres backup completed!
Build 20200626.1 succeeded
Requested by
GitHub
Duration
00:02:20
Build pipeline
Bot
@MarkKoz Would you mind taking a look over this again and testing it when you get the chance? I believe that I've addressed all of the critical issues. I also ended up having to make some fixes for the way new pages are created, as I found out that some of the existing parts of LinePaginator.add_line() were causing issues with the continuation pages.
Also, apologies for the late follow-up on this. I've been rather busy recently, and some of fixes weren't quite as straightforward as I was...
Oops, this still needs to be updated to mention that it truncates the line instead of raising a RuntimeError. Heading to sleep now, but I should be able to find the time to make a quick fix tomorrow.
Build 20200626.2 succeeded
Requested by
GitHub
Duration
00:02:37
Build pipeline
Bot
I don't mind the current way, it's a fairly common pattern.
The problem with invoke_without_command afaik is that it allows sub-commands to bypass checks on the group cmd, which can be unexpected.
[python-discord/bot] Pull request review submitted: #981 Improve LinePaginator to support long lines
This is purely a code review, I wasn't able to do a feature test of this, so I don't think it should be merged before someone does a feature test.
I have a few minor stylistic nitpicks, but I think this looks like a nice, clean implementation overall. Nice work, @aeros.
I'm curious, is it useful at all to be able to set a prefix and suffix? Are we actually doing this anywhere or is it just some legacy code that has never been used?
I just can't imagine what we would use this for - posisbly for putting content before or after the block, I guess?
Could be useful to include the values of these two variables in the error output for debugging purposes.
raise ValueError(f"scale_to_size must be >= max_size. ({scale_to_size} < {max_size})")
I think this still needs a bit of work. It's not immediately clear to me how this works from this explanation. Furthermore, it fails to communicate why we need two variables to determine the length of this line.
I personally have no idea, but I can try to take a look at the current places where LinePaginator is used to see if there are any decent use cases for the prefix and suffix parameters. From looking at the git blame, it looks like it was all added at once a couple of years ago: https://github.com/python-discord/bot/pull/25. It could very well be a common case of feature bloat, but I'm not confident enough about the areas in which LinePaginator is used by the bot to know if those params are u...
Sounds good, I'm very rarely against adding additional potentially useful information to exception messages.
Hmm, okay. I'll try to work on expanding this docstring a bit. In hindsight, I agree that it doesn't really address the reasoning behind having both max_size and scale_to_size.
Me as well! I've only recently started to wrap my head around how it can be useful in real-world code. My use cases for it aren't incredibly common, but it's great when you want to avoid repeating yourself for a re-used value from a conditional.
Build 20200626.3 succeeded
Requested by
GitHub
Duration
00:02:38
Build pipeline
Bot
With the ambiguity that Python has with bool(obj), I put a lot of value is using the is_/has_ prefix to directly communicate to readers (and myself, later down the road) that it's referring to a strictly boolean value. In this case, a name like full might be obvious and is not full sounds great, but I personally find it to be more explicit.
Build 20200626.4 succeeded
Requested by
GitHub
Duration
00:02:21
Build pipeline
Bot
well, if it was added a couple of years ago, I suggest we could probably just remove these as arguments and make them constants if (and only if) there are zero usages in the codebase. If we've never used those arguments in 2 years, we're not gonna start using them tomorrow.
Would you mind taking a quick look to see if you can find any usages?
I may have been a little imprecise here, but this is actually a request for a docstring :grin:
So far I've only changed how the help embed is invoked when no subcommands are passed; I have to ask though:
allows subcommands to bypass checks
would there be any merit to using invoke_without_command given that I'm only invoking the help embed for the command group?
In this case I don't think it makes much of a difference (please correct me if I'm wrong).
Just to explain what I meant: if we use invoke_without_command=False (default), and apply some kind of a check, such as with_role from our utils, this check will also apply to all subcommands, which is generally what we want. This means that if you lock the group to mods only, all subcommands will also prevent non-mod users from invoking them.
With invoke_without_command=True, the group ca...
Looks good and works fine apart from the path problem. I haven't looked at the actual shift algorithm you have implemented in much detail yet, but it looks interesting. Defining the resource dict such that an embed can be built from it directly is a really cool idea.
There's a typo:
... named after > hte < Roman General Julius Caesar is ...
Could also use a comma after Caesar.
This fails on my system:
FileNotFoundError: [Errno 2] No such file or directory: 'bot\\resources\\evergreen\\caesar_info.json'
Ideally use a pathlib object, e.g.:
Path("bot", "resources", "evergreen", "caesar_info.json")
Also please specify the encoding as we've had issues with the default being different on various platforms: #411.
Since this PR will allow the paginator to handle long lines, I think that nomination reasons should not be shortened when looking at someone's nomination history.
You would just have to get rid of the textwrap.shorten call in these places:
https://github.com/python-discord/bot/blob/232cc68b0a0ef210027beacb9b4f50ffeeaddd00/bot/cogs/watchchannels/talentpool.py#L227
It would be nice for this to append an ellipses to the reduced words.
[python-discord/bot] Pull request review submitted: #981 Improve LinePaginator to support long lines
Looks like the blank page issue has been resolved. Apart from some of the other minor changes requested by others, including yourself, this is good to go.
I think Path("bot/resources/evergreen/caesar_info.json") looks better, and pathlib will normalize them in the same way
The dict.fromkeys constructor could be used here
I believe dedent should be fine here, checked ipython and they use this which acts almost exactly like dedent if I understood it correctly.
Line 718 in help_channels.py is still using the old self.is_in_category method, causing errors.
The PY_LANG_CODES var feels a bit hidden between the two regexes
I think just using a backtick directly here would be fine
Postgres backup completed!
Build 20200627.1 succeeded
Requested by
GitHub
Duration
00:01:06
Build pipeline
Seasonal Bot
Build 20200627.2 succeeded
Requested by
GitHub
Duration
00:01:00
Build pipeline
Seasonal Bot
I think adding a search bar will be a good idea because sometimes is hard to navigate between and search for pages.
If the bot has a way of interacting with staff as a whole:
- have a hardcoded retry limit bigger than 1 that will be decremented every time deleting the message is unsuccessful (not due to it being deleted)
- once limit is at 1, send a notification to staff as an embed; the embed has an up arrow and down arrow emoji
- if up arrow is selected, the retry limit is incremented
- if down arrow is selected the limit is decremented (to 0) and the message is deleted
- if nothing is selected, on ...
That really seems overkill IMO, we could just retry a fixed amount of time, and then forget about it.
I'm not sure how I feel about using the username to convey this stuff.
Could we ditch the webhook approach and post with the bot like so:
<img width="381" alt="image" src="https://user-images.githubusercontent.com/20439493/85921785-972a3980-b876-11ea-88bc-59b0d5b1b4fc.png">
I like @SebastiaanZ's suggested implementation. Let's do that.
I've recently noticed this has an incorrect annotation for its return type. Should this be corrected to Generator[str, None, None]?
Perhaps, matter of taste. ๐ฆ
Should I completely remove the constant then? I feel it helps with readability.
94017fd Code block: rename BadLanguage attributes - MarkKoz
8f37b6c Code block: make PY_LANG_CODES more visible - MarkKoz
b209997 Code block: use config constant for cooldown - MarkKoz
5075719 Code block: simplify channel cooldown dict crea... - MarkKoz
621043a Code block: clarify get_instructions's docstring - MarkKoz
I believe dedent should be fine here
Well, I know it will work. I was more wondering whether the indentation fixing feature should be retained, despite being inaccurate in some cases.
Build 20200627.1 succeeded
Requested by
GitHub
Duration
00:02:32
Build pipeline
Bot
Build 20200627.2 succeeded
Requested by
GitHub
Duration
00:02:23
Build pipeline
Bot
I think it helps in cases like here https://github.com/python-discord/bot/blob/201895180ffbe88c01e4dbc40dd9cd6c043e2be7/bot/cogs/codeblock/parsing.py#L86-L88 but imo a literal is better here and in _TICKS when it's already a string (or around other strings) and with the var name hinting on what it is if the small char is hard to read for some.
I see where you're coming from though so some other opinions would be beneficial
c7d466a Code block: fix BadLanguage creation - MarkKoz
Build 20200628.1 succeeded
Requested by
GitHub
Duration
00:02:33
Build pipeline
Bot
Well, I know it will work. I was more wondering whether the indentation fixing feature should be retained, despite being inaccurate in some cases.
Would the indentation matter somewhere in the parsing step? The cases where it malforms input will be fairly rare and I don't see the reason to keep the functionality around if it doesn't matter
Would the indentation matter somewhere in the parsing step?
It matters when parsing it with ast. It will fail if the indentation of the first line isn't fixed. Maybe it can just run it twice. One without the fix and one with.
The cases where it malforms input will be fairly rare and I don't see the reason to keep the functionality around if it doesn't matter
This sounds contradictory. Yes, the examples with the dict are rare, but isn't that a reason to keep the functionality? I ...
Would the indentation matter somewhere in the parsing step?
It matters when parsing it with ast. It will fail if the indentation of the first line isn't fixed. Maybe it can just run it twice. One without the fix and one with.
Sorry, meant the resulting fixed indentation after a dedent, and mixed up dedent and the fix of the current implementation when reading your reply before writing the comment.
If dedent can't mess up the parsing in any way when stripping out the common le...
The dedent doesn't mess up indentation. It's the user that messes up indentation. Dedent can fix all the code being indented too far, but it doesn't fix the user incorrectly copying their code such that the indentation of the first line is excluded. The latter is what all this code tried to fix (in addition to fixing indentation being too far):
def fix_indentation(msg: str) -> str:
"""Attempts to fix badly indented code."""
def unindent(code: str, skip_spaces: int = 0) -> ...
Right, didn't realize it also fixed the left out line 1 indent. In that case I think it should be brought back in some form
I think Iterator[str] ought be enough instead of the whole Generator typehint when it only yields
Does the url when adding an inventory through doc set need to be verified like here? https://github.com/python-discord/bot/blob/e37041622aebc8fef75d83fcd8970dc527c056bc/bot/cogs/doc.py#L126-L132 a mistake should be noticeable immediately after the command and while it's a fairly uncommon command to use it'll also reduce the needless requests.
I think this leads to worse ux or code; currently when the set_command is invoked it'll do 2 web requests out of 3 total before it sends out a t...
@lemonsaurus
From looking through all of the results in git grep "LinePaginator", I found just one actual usage for prefix in the bot repo:
Since this would require some additional investigation to see if the same functionality could be easily implemented without it, I think we should probably consider removal of prefix and suffix in a separate issue and PR (if at al...
Do we need the default listing of inventories behind get? ... the nicer behaviour would be that output only for me !doc and nothing for an empty get.
I kind of like it. I don't think it should be empty; it should at least show the help command, but showing the available inventories feels more useful since the get command is not complex enough for people to really need to see the help.
The set shadows the set symbol from the inventories, any opinions on handling it and other subcomman...
Build 20200628.2 succeeded
Requested by
GitHub
Duration
00:02:31
Build pipeline
Bot
I agree that it is better left for another PR, though I don't have a problem with it just being left as-is.
[python-discord/bot] Pull request review submitted: #981 Improve LinePaginator to support long lines
Sorry I didn't catch this earlier. The help command has an error:
ValueError: scale_to_size must be >= max_size. (2000 < 2040)
Is it better to require it to be explicitly set it to 2040 or should it automatically set it equal to max_size if unspecified and greater than the default value?
Every other use of the paginator appears to work.
Good catch @MarkKoz.
Is it better to require it to be explicitly set it to 2040 or should it automatically set it equal to max_size if unspecified and greater than the default value?
I'm not 100% certain on this. I think for most cases setting scale_to_size to max_size if it's unspecified and greater than the default of 2,000 would be fine, but it does result in an extra bit of added complexity to the constructor.
On a related note though, I discovered that there's a maximum (...
Yeah, a limit of 2000 is reasonable. Then we don't have to worry about changing scale_to_size since its default will already be the maximum.
Also, thanks for bringing up the nomination reasons @Den4200. I've removed the textwrap.shorten()s in a recent commit.
Build 20200628.3 succeeded
Requested by
GitHub
Duration
00:03:03
Build pipeline
Bot
I just saw another location that exceeds max_size of 2,000 (also in help.py), I'll fix that real quick:
bot/cogs/doc.py:371: await LinePaginator.paginate(lines, ctx, inventory_embed, max_size=400, empty=False)
bot/cogs/extensions.py:162: await LinePaginator.paginate(lines, ctx, embed, max_size=300, empty=False)
bot/cogs/help.py:302: max_size=2000,
bot/cogs/help.py:349: await LinePaginator.paginate(pages, self.context, embed=embed, max_lines...
Build 20200628.4 succeeded
Requested by
GitHub
Duration
00:02:34
Build pipeline
Bot
raise ValueError(f"scale_to_size must be <= 2,000 characters. ({scale_to_size} > 2000)")
Oops, thanks for the catch. Somehow I fixed the f-string but missed the message :-)
Build 20200628.5 succeeded
Requested by
GitHub
Duration
00:02:34
Build pipeline
Bot
Build 20200628.6 succeeded
Requested by
GitHub
Duration
00:02:46
Build pipeline
Bot
5f5a51b Improve LinePaginator to support long lines - aeros
a465a1e Fix docstring for _split_remaing_words() - aeros
974bf0f Fix _split_remaining_words() docstring summary - aeros
7264da7 Merge branch 'master' into issue926-paginate-lo... - aeros
98bbae2 Account for spaces in LinePaginator._split_rema... - aeros
Thanks for the extensive review and merging @MarkKoz. :-)
Build 20200628.7 succeeded
Requested by
GitHub
Duration
00:04:30
Build pipeline
Bot
Postgres backup completed!
Connected!
The set shadows the set symbol from the inventories, any opinions on handling it and other subcommands as symbols when the role check doesn't pass? Currently there's just no output from the bot.
Putting it in quotes works, so I'm not concerned about it:
!d "set"
There haven't been that many, but searching through the history there were a few instances where people seemingly though it just didn't work after a !doc set, !doc get set is usually the next step but I doubt someo...
I doubt someone would try the quotes
Fair enough
get set works perfectly fine so this would be just a small QoL improvement
Isn't get shadowed too? Would you propose renaming both commands? And to what? I don't really mind them being renamed since set is seldom used and non-public and get is usually used as !d g or just !d.
Do we care more about the response time and doing additional requests or the RAM space (or drive if it's stored there)?
I think response ti...
Isn't
getshadowed too? Would you propose renaming both commands? And to what? I don't really mind them being renamed sincesetis seldom used and non-public andgetis usually used as!d gor just!d.
get would be shadowed but the symbol doesn't exist in the current inventories. There shouldn't be many problems if it assumes the command was intended to be executed when the permissions are there; but renaming doesn't sound like a bad idea, although I don't know what to.
getdoc and setdoc? I don't think it really matters to pick a nice name since most of the time the aliases will be used. Just needs to be sensible and unlikely to shadow anything.
We could go with invalid identifiers like get-doc and set-doc to be completely safe but getdoc and setdoc sound good and should be future proof since there's almost no normal non python symbols that don't have the lib prefix
Build 20200629.1 succeeded
Requested by
GitHub
Duration
00:02:25
Build pipeline
Bot
Build 20200629.2 succeeded
Requested by
GitHub
Duration
00:02:45
Build pipeline
Bot
I have added it back in after refactoring it. I decided to go with parsing the code twice, once with and once without the fix, to avoid the shortcomings of the fix.
Postgres backup completed!
I've seen people annotate generators using just the yield type (such as here), but yeah using Iterator[str] would probably be best. The docs mention it as a valid alternative to Generator[str, None, None].
Build 20200629.1 succeeded
Requested by
GitHub
Duration
00:01:04
Build pipeline
Seasonal Bot
fr
@j03b Alright, let's use embeds ~ changed back to draft for now until I implement the necessary changes.
Do you think the doc suffix should also be added to the delete/remove and the refresh subcommands?
I will be taking on this task. @jodth07
Description
Steps to Reproduce
Expected Behaviour
Actual Behaviour
Known Impacted Platforms
- [ ] Web
- [ ] Desktop
- [ ] Android App
- [x] iOS App
Possible Solutions
Additional Details
Would you like to implement a fix?
Note: For high-priority or critical bugs, fixes may be implemented by staff.
- [ ] I'd like to implement the bug fix
- [x] Anyone can implement the bug fix
![C60A348A-EAA7-48B7-9DD1...
It all looks good overall, but I have not tested this yet.
You can use Fun._get_text_and_embed instead here, similar to how Fun.uwu_command does it.
Given an integer `offset`, translates and sends the given `msg`.
```I'm guessing you were referring to the `msg` parameter here, instead of `text`.
Yeah, wouldn't hurt. The commands are staff-only and seldom used. They'll still have convenient aliases anyway. Other options are a separate command group (possibly unintuitive) or a nested group (cumbersome?)
Unicode emoji are being used. It's a bug with the iOS app. Unicode flags are comprised of the regional indicators but the app doesn't realise displaying flags was not intended here. There seems to be no solution on our end. A workaround is to flip the top and side rows so that the letters are on the side.
I lost on my first move, which doesnโt happen in normal Minesweeper.
I don't necessarily consider this a bug. This behaviour depends on the version of the game being played. It's not...
I figured that it would be a bit redundant to use said method to manually convert the msg that's already handled by the Union[Message, str] converter. I
4fd2ff5 Scheduler: add details to class docstring - MarkKoz
c641f7f Scheduler: explain the name param in the docstring - MarkKoz
Build 20200630.1 succeeded
Requested by
GitHub
Duration
00:02:29
Build pipeline
Bot
Build 20200630.2 succeeded
Requested by
GitHub
Duration
00:02:43
Build pipeline
Bot
Hmm.. I see. It seems pretty redundant doing it either way then. Personally, I think I'd stick with using Fun._get_text_and_embed and just have the type annotation as str, so it's consistent with the other methods.
It's up to you though, you can do what you see fit.
You may want to not log the error if it's specifically CancelledError using something like this:
if exception and not isinstance(exception, asyncio.CancelledError):
I suspect that for the purposes of logging critical errors from scheduled tasks, CancelledError is not particularly useful.
I'll try to do a more in-depth look at it later, but here's a few comments for now:
It's pretty awesome to see that the results of our earlier experiment in #async proved to be of use for the scheduler. :-)
I would consider having an else block though to log if the coroutine is in another state other than CORO_CREATED and couldn't be closed. Might not be necessary, but I personally can't vouch for the reliability of using inspect.getcoroutinestate(coroutine) since I haven't seen it used in a production environment or used it myself extensively.
I'm not certain about the usage of coroutine.close() here, particularly without the inspect.getcoroutinestate() guarding it. If this will only be used internally with coroutines that haven't started running yet and won't be awaited later, it's okay, but if you somehow manage to close a running coroutine it will likely hang indefinitely or if it gets awaited later, a RuntimeError.
To be clear, I think it's safe to use with schedule_at() and schedule_later(), I'm more concerned abo...
Postgres backup completed!
Context
High profile channels such as #python-general have slowmode enabled to make chat traffic manageable. The amount of delay is adjusted based on current traffic in the channel.
Problem
The Discord GUI only allows @Admins to choose from a limited amount of options.

The API, however, [allows much more granular control](https://discordpy.readthedocs.io/en/lat...
Following the discussion that happened in meta today I would like to suggest a new feature to the bot: make it pin the first message sent in the newly opened help session, and, of course, un-pin it when the help channel is closed.
Reasoning: some help session tend to drag out for longer time and thus to have lots of messages. This makes it very hard for anyone who's willing to to help but has not ...
CancelledError will not be returned, it will be raised, right?
If the Task has been cancelled, this method raises a CancelledError exception.
Well this is a trace log so it won't even be seen in production. But it's a good point. I can up the level and add another log until it's determined to be stable in production (tbh, probably wouldn't bother taking out the log anyway).
This ties into this https://github.com/python-discord/bot/issues/800#issuecomment-647047778. After writing that comment, I recognised these other problems with the current approach but felt like it was too much of an edge case to care. Maybe not.
I don't want to make it private in case someone wants to schedule a coroutine immediately and still take advantage of the scheduler keeping track of it.
I think this would be a very useful command for the mods. I'd be willing to take this issue since it's quite simple ๐
Excellent, it's all yours. :+1:
Also, we can probably use the duration converter to set the slowmode instead of an int argument.
[python-discord/bot] New branch created: feat/util/1019/slowmode
7af6b6f Ensure slowmode delay is between 0 and 21600 se... - Den4200
Description
This new command will allow moderators+ to get and set the slowmode delay for a given text channel. Currently, only admins can control the slowmode delay, but only through int eval when we need more granular control. This command will make it much more convenient for the admins, and will actually allow the mods to control slowmode.
Closes #1019.
Command Showcase
:, it would instead return the CancelledError from exception = done_task.exception() if the task was cancelled instead of raising like it normally would. I just confirmed that was not the case, I forgot that it if the exception occurs under contextlib.suppress(), it continues after the block (rather than at the point the exception occurred). So, feel free to disregard the above suggestion.
...
I don't want to make it private in case someone wants to schedule a coroutine immediately and still take advantage of the scheduler keeping track of it.
That's definitely fair enough, but in that case, you probably want to at least leave a block comment above the coroutine.close(). I could see it being rather difficult to debug if someone mistakenly passes a coroutine that has started running or might be awaited later.
And maybe an `assert inspect.getcoroutinestate(coroutine) == "CO...
Sounds good to me.
I agree it will become complex so we can drop the persistence/scheduler design.
I don't think a new converter will be necessary. Just taking the current one and then seconds = (future_date - datetime.now()).total_seconds() should suffice.
Build 20200701.5 succeeded
Requested by
GitHub
Duration
00:02:46
Build pipeline
Bot
Ah yeah, that's smart. It feels a bit redundant since the converter adds the timedelta to the current time and now we're subtracting it back, but I don't think it matters too much.
I've tested this out, but there's a bit of a delay between conversion and when the function executes.

We could just add 1 to this, but that wouldn't be too reliable. I think I'll just create a new converter.
I wrote this idea to #meta too some times ago, but maybe should this have !slow to disable slowmode and when adding more os (!sloooooooow), then this should activate slowmode (without scheduler, so until disabling/changing), where every o except first is 1s of slowmode. Something like silence.
I don't really think that's a great idea. This feels like something that will typically be used in an internal channel to set a slowmode and in certain situations we may want to go into higher ranges (I don't want a thousand 'o's :smile:)
bd041ef Create DurationDelta converter and humanize tim... - Den4200
Build 20200701.6 failed
Requested by
GitHub
Duration
00:02:08
Build pipeline
Bot
Build 20200701.7 succeeded
Requested by
GitHub
Duration
00:02:09
Build pipeline
Bot
Build 20200701.8 succeeded
Requested by
GitHub
Duration
00:02:24
Build pipeline
Bot
Build 20200701.9 succeeded
Requested by
GitHub
Duration
00:02:20
Build pipeline
Bot
When this is gonna be approved, then I'd like to do this.
I forgot to mention that I would not mind to try it myself, but I think it's better that someone who knows bot internals already do it, as I never touched it, so with my workload it can take time :)
Postgres backup completed!
Proposal
Eval command should support passing message or nothing instead code. When you pass the message, this should try parse code block from this message. This should be implemented that way that in the message, there can be text to before and after message: this should ignore it. When passing nothing, then this should try to get the last message and parse this code block.
Additional ideas
Also, maybe when a message has multiple Python code block, this should ask from the user wi...
I may be interested in trying this, after I'm done with https://github.com/python-discord/bot/pull/993.
It seems like a nice project that'd allow me to learn more about Django and our site while not being critically important.
Build 20200702.1 succeeded
Requested by
GitHub
Duration
00:00:58
Build pipeline
Seasonal Bot
Added first (claiming) message pinning and unpinning on dormant for better access when help session is long and new peoples join to helping. Resolves #1020
Build 20200702.1 succeeded
Requested by
GitHub
Duration
00:02:15
Build pipeline
Bot
Because this repeat on L177, I think maybe is better to move it to _caesar_cipher.
caesarcipher_decrypt passes a negated offset to the _caesar_cipher method to perform a left shift though, because of how I've written the formula for the true_offset in L131.
Postgres backup completed!
Build 20200703.1 succeeded
Requested by
GitHub
Duration
00:02:30
Build pipeline
Bot
@j03b Incidents are now archived as embeds.

See: dd74105, 744aed5. Image-like attachments are also supported: 83544ca.
PR description & tests adjusted as necessary, this should now be ready for review again.
Collapsing this as we scrapped this.
Not clean, but as clean as I could get it. There's something oddly difficult here because we make the embed in make_embed, but there also has to be some branching here to determine whether a file should be passed to the send.
So if make_embed also looks at incident.attachments to determine whether set_image should be called, and this looks at incident.attachments to see whether a file should be passed, we're checking the same thing in two places and it feels ugly & fragile sinc...
How would you feel about using a cog check to lock the entire cog to mods, or decorating the group instead of the setters? Regular users can see the delay in the Discord GUI, I'm not sure whether it's at all needed to allow non-mods to use this cog.
Generally better to log before the operation rather than after - the log won't be made if something goes wrong above it.
Looking over the humanize_delta source, it wants a string for precision.
It will be matched against these:
units = (
("years", delta.years),
("months", delta.months),
("days", delta.days),
("hours", delta.hours),
("minutes", delta.minutes),
("seconds", delta.seconds),
)
The TypeError comes from here and is a result of an incorrect type being passed in:
https://github.com/python-discord/bot/blob/74de316657d5fed9d5474fa23d05cbe09d...
We have more than enough RAM for this (and we have alerts set up in case we don't (but we do)).
We average at around 4-5GB of RAM usage but the server has a total of 8GB (and 1GB swap as well).
<img width="1626" alt="image" src="https://user-images.githubusercontent.com/20439493/86466374-68efa280-bd2b-11ea-805c-c13e2cbc5e1f.png">
... Regular users can see the delay in the Discord GUI, I'm not sure whether it's at all needed to allow non-mods to use this cog.
Is the get command needed at all? Checking through the GUI will be more convenient and faster in most cases
It is needed, yes.
While the UI does present this it only allows it to be locked to the increments permitted through the UI, not what we want.
For example, consider I put a channel on a 2 second slowmode:
<img width="592" alt="image" src="https://user-images.githubusercontent.com/20439493/86467887-2f6c6680-bd2e-11ea-8e0d-01852b677f2f.png">
We can verify slowmode is enabled by looking at the bottom right of the client:
<img width="370" alt="Screenshot 2020-07-03 at 13 08 03" src="ht...
It should show including custom values on hover.

TIL hah. In that case I guess it is not needed.
Problem:
Currently the purge/clean command takes the number of messages to clean as the only way of specifying how far to clean, this can cause some difficulties when trying to clean lots of messages as you either have to guess roughly how many messages were sent or count them manually, and also makes it easy to go too far and delete messages you didn't want to.
Proposed Solution:
We could allow a message ID or link to be given as an argument instead of the number of messages. Th...
Build 20200703.1 succeeded
Requested by
Joseph Banks
Duration
00:02:10
Build pipeline
Seasonal Bot
Connected!
Build 20200703.2 succeeded
Requested by
Joseph Banks
Duration
00:04:00
Build pipeline
Bot
Connected!
I can work on that issue if that's possible.
I don't know how I missed this. I'll fix that up ๐
I don't mind locking the whole cog to mods, sounds good to me.
As for the get command, I added that so the cog would have a complete pair of get and set. I can get get rid of it though, but I don't see any harm in having it either.
It could be useful to have a timeit-like bot command to time code execution. Some ideas of features the command could have are:
- The ability to specify how many times the code should be run. It could also be interesting if this was calculated automatically like how the timeit Command-Line Interface does.
- The ability to take in multiple snippets of ...
Build 20200703.3 succeeded
Requested by
GitHub
Duration
00:02:23
Build pipeline
Bot
Build 20200703.4 succeeded
Requested by
GitHub
Duration
00:02:19
Build pipeline
Bot
Build 20200703.5 succeeded
Requested by
GitHub
Duration
00:02:23
Build pipeline
Bot
Forgot about it on the previous comment, this cog would be more fitting in the moderation subpackage
Postgres backup completed!
We currently have a feature !remind which will send the caller a reminder after a certain amount of time has passed.
But sometimes, a moderator or admin will want to create a reminder for his whole team. For example, maybe something needs to be followed up in 7 hours but the moderator or admin will not be available at that time.
It should also be possible to create a reminder for another user than yourself.
New command syntax
!remind .
For example, `!remind @Admins 7H23...
Reminders for yourself or for other users should be restricted to Helpers+
Do you mean that normal users can't create reminders anymore? Only Helpers+ can create reminders?
I'm not quite sure I understand the -4 but this doesn't fix the indentation if it's not copied on the first line for compound statements with multiple clauses like
if ...:
...
elif ...:
...
else:
...
If we do not care about those but only for definitions (since it's unlikely to happen and probably complex to account for) and it's for decreasing the indent, is it necessary? Python won't care about the width of indentation under one clause.
...
I'm not sure on the license stuff and haven't read BSD 3-clause, but could the license be placed in the codeblock directory? When I was doing something similar the main requirement seemed to be that it's clear on what's what.
With it being "hidden" in the directory it's clearer where it applies and doesn't add additional things to the root, maybe with a small notice in the module itself too
This seems a bit confusing to me, would a for loop that'd do something like this be more fitting?
for character in content:
if character == " ":
increment spaces
else:
return spaces
FWIW, I find the current version with a constant easier to read:
valid_ticks = f"\\{parsing.BACKTICK}" * 3
Compared to using a literal:
valid_ticks = f"\\`" * 3
It's a bit difficult to make out the backtick unless you're specifically looking for it. Depending on the font and zoom setting used, this could be even harder to see.
The nickname filtering introduced by #964 also matches on webhooks, causing false positives. Posts from webhooks should be ignored.
It certainly works fine for me with that example.
I may be biased since I wrote it, but I don't think it's confusing. Anyone else feel a for loop is clearer?
I'm not sure on the license stuff and haven't read BSD 3-clause, but could the license be placed in the codeblock directory?
Yeah it absolutely can be, but I decided to put it in the root instead. I feel it'd be more manageable to have all third party licenses in a single file. We could re-use licenses for unrelated pieces of code if they fall under a license already in the file. I was also concerned that putting the license inside the subpackage may mislead some into thinking all code i...
Postgres backup completed!
Each sub-package could be treated as an extension, but this limits control over which cogs are loaded.
I just had this thought earlier today and wanted to comment here, but I see you've already been thinking about this. I've been finding it a little awkward to not be able to reload a specific cog in the moderation package, for example, and wanted to propose that each cog is its own extension to alleviate this. The inability to unload a specific cog while keeping others intact seems like ...
Build 20200705.1 succeeded
Requested by
GitHub
Duration
00:01:06
Build pipeline
Seasonal Bot
I don't particularly think this fits in the moderation subpackage. The cogs should really be organized as a whole into separate subpackages, similar to as stated here: https://github.com/python-discord/bot/issues/160#issuecomment-643844893.
Then, I think this cog would be more fitting under the utils subpackage.
Using the function __name__ in the cache is still not safe because the functions don't necessarily have unique names and the user then needs to be aware of that functionality to clear the cache. Using a proper class without a shared state and exposing the clear etc. through methods would probably be most suited now.
Why would we not want to split up the get embed method for readability? I don't think moving the sending into a separate method particularly helped the fact that it does too ...
The docs mention that a teardown may not get ran when an exception happens in setUp. I don't think it's particularly likely with the current setup but using the cleanup instead of teardown will also future proof the code
Does this need to be attribute for all tests?
It's only used in two places where it fits within the line limit (One call to createteam already does this) and the name doesn't particularly hint on what those default args are for
This method feels a bit out of place at the end, all the tests except this one follow the order of the tested methods in the cog
I thought that it would be pretty cool if Discord could show the contents of a snippet link instead of just the link to the snippet, so I made a bot for that.
However, since adding third-party bots to the Python server was out of the question, I decided to add that functionality to the official server bot instead.

Build 20200705.1 failed
Requested by
GitHub
Duration
00:00:52
Build pipeline
Bot
Build 20200705.2 failed
Requested by
GitHub
Duration
00:00:48
Build pipeline
Bot
@dolphingarlic I don't think that this should good feature. Sending something every time when someone posts GitHub link is not a good idea. And all PRs have to have approved the linked issue, what this PR definitely don't have. Make issue first, then staff/core devs will discuss it and then decide will this come to bot or not.
Build 20200705.3 failed
Requested by
GitHub
Duration
00:00:48
Build pipeline
Bot
Build 20200705.4 succeeded
Requested by
GitHub
Duration
00:01:56
Build pipeline
Bot
Sorry, I didn't know that I should've created an issue first. (I don't think CONTRIBUTING.md mentioned that).
I think that printing out snippets would be quite useful since it means that people wouldn't have to open the links each time anymore. Sending embeds with details about repos basically just improves what Discord already does with repo links but with more details.
This could be moved up as a fail early check that returns, instead of if/else
Possible to comment or create a variable for what 0 and 21600 is?
Sort of doesn't add much?
The code itself explains what it does, but the comment could mention why we don't give 0 to time.humanize_delta(delay)
Looks good, but I got a few requests.
We shouldn't monkeypatch the functionality in our own utils inside of unrelated cogs. This is a code smell.
The change is fine, but if you're going to make this change it should be made inside of utils.time, not here.
It's unclear what this hardcoded 21600 represents. Either make a constant with a name that makes sense (SLOWMODE_MAX_DELAY?) , or add a block comment to explain what you're doing.
Maybe this can default to ctx.channel if no channel is provided?
I was going to suggest ignoring ABCs here, but it is is only for wherever deepdiff adds the brackets into the paths (didn't find that much in docs on the cases where it uses those).
I'm not sure if there is a fitting abc and this seems to work nicely for the intended purposes, but the comment was a bit misleading since we want strings here which are also sequences.
Yeah, that would make sense. Thanks for pointing this out.
I removed the monkeypatch there and applied the changes needed in bot.utils.time, as mentioned here: https://github.com/python-discord/bot/pull/1021#discussion_r449915881. There is no longer a need for this comment.
I think that it would be clearer to leave as an if/else in this situation. Does anyone else have thoughts on this?
2850a9d Merge branch 'master' of https://git.pydis.com/... - Den4200
c4c4dfa Create a constant for the max slowmode delay - Den4200
9804e84 Remove monkeypatch and apply appropriate change... - Den4200
539030a Default to the channel that slowmode get was ... - Den4200
758568f Default to the channel that slowmode reset wa... - Den4200
Build 20200706.1 succeeded
Requested by
GitHub
Duration
00:02:28
Build pipeline
Bot
I don't think the greedy converter is necessary here. typing.Optional should work fine, since we only want one channel.
b04c416 Default to the channel that slowmode set was ... - Den4200
Build 20200706.2 succeeded
Requested by
GitHub
Duration
00:02:25
Build pipeline
Bot
Build 20200706.3 succeeded
Requested by
GitHub
Duration
00:02:16
Build pipeline
Bot
Build 20200706.4 succeeded
Requested by
GitHub
Duration
00:02:38
Build pipeline
Bot
Build 20200706.5 succeeded
Requested by
GitHub
Duration
00:02:12
Build pipeline
Bot
Postgres backup completed!
Build 20200706.6 succeeded
Requested by
GitHub
Duration
00:02:40
Build pipeline
Bot
The newlines will be replaced by a single empty space when passed through textwrap.shorten:

I think it's confusing to have the newlines here in the template if we know they won't be shown on Discord.
I think then we should shorten reason only. How much this should display of reason? 1000 characters?
ah, yeah you're right. greedy would make sense if you wanted multiple, which doesn't make sense. Sorry, it was late.
With these latest changes, it looks good to me.
Sounds like a good idea, although this would ideally be answered by someone who knows more about the character limits in embeds, afaik there's a limit on the total and a limit on the description too? Fwiw this isn't a regression, there's no newlines on the master branch either.
The Discord.js guide has some clear documentation on embed limits
Does naming the constant SLOWMODE_MAX_DELAY add any kind of information? It feels like that's the one bit of information that is obvious from the conditional - it being the max delay.
Build 20200706.7 succeeded
Requested by
GitHub
Duration
00:02:30
Build pipeline
Bot
@dolphingarlic I don't think that this should good feature. Sending something every time when someone posts GitHub link is not a good idea. And all PRs have to have approved the linked issue, what this PR definitely don't have. Make issue first, then staff/core devs will discuss it and then decide will this come to bot or not.
I think this was discussed in the #meta channel over at PyDis and there was some merit in the linked idea. Personally I think it is useful, especially when getti...
Sorry, I didn't know that I should've created an issue first. (I don't think CONTRIBUTING.md mentioned that).
It's not mentioned because it's only a hard requirement for Seasonalbot. It's generally a good idea to make an issue first so you don't "waste" your time working on something that might not be merged, but since this seems to be something you've made for other reasons already it's a bit of a moo point.
I'm a bit meh on the repo link prettification, but the snippet formatting is...
Code and implementation looks good to me.
Yes - I've discussed it once in #meta a while ago
I can remove the repo link prettification if you'd like, but here's an example of when the snippet link feature is very useful:

Here, seeing just the single line linked in the snippet instead of having to open the link in a new tab is much more convenient. It would make debugging a lot faster.
How would you feel about using a cog check to lock the entire cog to mods, or decorating the group instead of the setters? Regular users can see the delay in the Discord GUI, I'm not sure whether it's at all needed to allow non-mods to use this cog.
Build 20200706.8 succeeded
Requested by
GitHub
Duration
00:02:34
Build pipeline
Bot
As Discord already embeds a link preview by default for GitHub-links, I'm not sure if I'm in favor of having the bot respond with a second embed containing some details about the repository. If we were to have "repository information" feature, I think it would be better as an explicitly invoked command. I'm just not sure whether or not such a command fits the scope of our community utility bot. (I really mean: "not sure"; it's not a euphemism for "I don't think it fits".)
I do like the sni...
If this were to be included, I'd prefer it to be a command or limited to maybe 3 lines without directly invoking it instead of looking up links in messages. Most github permalinks that I've seen get posted in discussion channels like python-language where this behavior wouldn't be as desired
While the repo information is nice I don't think the additional info like stars is particularly useful in most situations
I don't particularly think this fits in the moderation subpackage. The cogs should really be all organized into separate subpackages, similar to as stated here: #160 (comment).
Why do you feel like it wouldn't fit there? The slow mode is a moderation tool and the cog is restricted to moderators only. Maybe some others could weigh in here?
I agree that #160 needs to be realized in some way to declutter the cogs bu...
One more thing: When we do this, this should get filtering too. Maybe someone wants to write a message that gets deleted by filters, but then add this GitHub and post a link. And however, this should have some text filter.
What happens if we provide negative numbers, and should there be a test for that?
@Numerlor After some discussion in #dev-core, it would make sense to have it in the moderation directory. Also, waiting for #160 to happen will probably be quite a while from now.
Build 20200706.9 succeeded
Requested by
GitHub
Duration
00:02:32
Build pipeline
Bot
Also, waiting for #160 to happen will probably be quite a while from now.
Yeah, not trying to suggest that since this also partly blocks it
Build 20200706.10 failed
Requested by
GitHub
Duration
00:02:02
Build pipeline
Bot
Build 20200706.11 succeeded
Requested by
GitHub
Duration
00:02:38
Build pipeline
Bot
Build 20200706.12 succeeded
Requested by
GitHub
Duration
00:04:02
Build pipeline
Bot
Connected!
Unfortunately, that doesn't really resolve the problem, although still a nice addition to have.
For me, I want to:
- ensure all functions are statically typed.
- not add a return type to
__init__(), unless it is required to make it statically typed (i.e. there are no typed parameters).
Expected results:
def __init__(self, foo: int): pass
def __init__(self) -> None: pass
def __init__(self, foo): fail
def __init__(self): fail
def __init__(self, foo: int) -> None: Maybe fail (or just allow the redundant return type).
Ok. I guess we'll have to take another look at your specific use case.
How do we feel about removing the link from read more in truncated doc responses?
The link is already the embed's url, although it does not highlight on mobile so I've thought about removing the inline codeblocks from the title, which I think also ends up looking a bit more pleasing.

I'm rewriting the module and abstracting some things, so this would prove useful as one less thing to need to pass around.
LGTM. I didn't get the chance to feature test this to ensure the scheduler still works 100% correctly after the changes (such as for help channels, mod tools, and reminders), but all of the main async logic looks correct. Nicely done, Mark.
The only additional thing I could think of would be some unit tests for the scheduler (I didn't see any in tests/bot/utils/, but I'm assuming some of the existing tests might use it). Without dedicated unit tests, a complete feature test would be part...
Not at all necessary and functionally equivalent, but this would be a good reason to use the walrus operator:
if (delay := (time - datetime.utcnow()).total_seconds()) > 0:
coroutine = self._await_later(delay, task_id, coroutine)
I find that it's a minor improvement to readability by clearly communicating to the reader that the variable is only used within the scope of a statement, and makes the code a bit less repetitive.
Postgres backup completed!
PR looks solid to me. However the lines 560-569 could be simplified, discord.py has a HTTPClient.unpin_method method seen here which is exposed under bot.http which we could use instead, as that will directly be making call to API without needing to try and find the message in either cache or via fetch_message API call and will only need to handle HTTPException error, which will be just raised when message wasn't...
PR looks solid to me, appears to be working just fine locally, however, if moderator actions an incident while the bot is offline, bot won't take any actions (archive) on the message.
9b8d688 Autodelete offensive messages after one week. - Akarys42
59914bf Revert whitespace changes - Akarys42
9c78146 Move offensive message delete time to config file. - Akarys42
f67378c Remove the possibility that we send a message t... - Akarys42
1eb057b Rename offensive_msg flag to schedule_deletion. - Akarys42
Build 20200707.1 succeeded
Requested by
GitHub
Duration
00:02:28
Build pipeline
Bot
d9ed643 ModLog: fix AttributeError in on_member_update - MarkKoz
9133c4a ModLog: remove user diff in on_member_update - MarkKoz
17858e4 ModLog: fix excluded None values in on_member_u... - MarkKoz
35fc846 ModLog: refactor on_member_update - MarkKoz
b2972e0 Use int literal instead of len for slice - MarkKoz
[python-discord/bot] branch deleted: bug/mod/bot\-4r/modlog\-member\-update
Build 20200707.2 succeeded
Requested by
GitHub
Duration
00:04:09
Build pipeline
Bot
Connected!
I disagree because it makes the expression far too complicated. I wouldn't mind it if the expression started out simpler, but it already had a set of parenthesis and two function calls which just turns into a blob of parenthesis at a glance.
So since nobody seems to like the repo widget prettification feature, I removed that. To address the issue of people not wanting the bot to interrupt their conversations, I added the option for the author of the message to react with an โ emoji to delete the bot's message.
Build 20200707.3 succeeded
Requested by
GitHub
Duration
00:02:51
Build pipeline
Bot
Connected!
Build 20200707.4 failed
Requested by
GitHub
Duration
00:04:44
Build pipeline
Bot
Build 20200707.5 failed
Requested by
GitHub
Duration
00:01:05
Build pipeline
Bot
Build 20200707.6 failed
Requested by
Joseph Banks
Duration
00:00:44
Build pipeline
Bot
Build 20200707.7 failed
Requested by
Joseph Banks
Duration
00:00:51
Build pipeline
Bot
Build 20200707.8 failed
Requested by
GitHub
Duration
00:00:33
Build pipeline
Bot
Build 20200707.9 succeeded
Requested by
GitHub
Duration
00:05:43
Build pipeline
Bot
Connected!
Discord markdown in reddit post titles is left unhandled and can sometimes break the links:

For the basic markdown passing it through d.py's escape_markdown should work, but from a quick look I haven't found a way to escape brackets in post titles, which breaks the text links. A replacement with similar unicode chars is an option
Yeah, I can see that it could exceed the threshold of "reasonable amount of parenthesis". Either way, it's fairly subjective and not a huge deal, which is why I approved of the PR without it.
Postgres backup completed!
@Senjan21
... if moderator actions an incident while the bot is offline, bot won't take any actions (archive) on the message ...
The cog is designed to react to events just like any other listener the bot may have, and so it's limited in the same ways: you cannot distribute infractions while the bot is offline, you cannot schedule reminders, the paginator stops working, etc. You don't normally expect the bot to catch up with paginator reaction clicks after it connects; neither does it ...
Maybe should bot notice in #incidents channel that currently, this is not working (before shutdown)/that this is working again (on startup)?
In such case, I think I can approve the changes and see how it works in real life scenarios
If you believe that such functionality is necessary, for this cog in particular, I propose that a separate issue is written.
After thinking about it, I have to agree that it might not be a necessity, I suppose if any moderator will in fact want such functionality, they can make the issue.
4890cc5 Created tests for bot.cogs.logging connected ... - ks129
63be23c Merge branch 'master' into logging-tests - ks129
ededd18 Logging Tests: Simplify DEBUG_MODE False test - ks129
5f5a51b Improve LinePaginator to support long lines - aeros
a465a1e Fix docstring for _split_remaing_words() - aeros
Build 20200708.1 succeeded
Requested by
GitHub
Duration
00:02:39
Build pipeline
Bot
@ks129
Maybe should bot notice in #incidents channel that currently, this is not working (before shutdown)/that this is working again (on startup)?
I don't feel like there's anything inherently special about this cog that would require such a thing. The bot does not normally announce that it's going to restart, even if it makes much more critical features unavailable for the time being. In #mod-log, we can see new commits on master, which indicate a restart, and we can also see when ...
could we not use MODERATION_ROLES from constants.py here instead of listing the roles manually?
The problem
Right now, it is possible to exploit certain parts of the bot in order to make the bot post things a regular member would normally not be allowed to post.
These techniques can be used to circumvent our filters, which is somewhat problematic.
For example, by using eval to build a string containing a discord guild invite, you can circumvent our guild invite filter.
 symbol to the cog, which fails to be found in the inventories or fails to be parsed by the cog; if this is handled with BadArgument then a mostly unhelpful and irrelevant command help is sent alongside the message passed to BadArgument, while the user did inv...
We're going too far into the weeds. There is an immediate need to go through all instances where the bot directly pipes the user's input back out and make this not happen.
If for some reason we have so many cogs doing their own thing with error embeds then we can investigate some utility, monkeypatch, or whatever in another PR. Let's get the immediate problem fixed ASAP.
@sco1 is right that we need to get this solved ASAP. Also, I've tested the !doc command now, but it doesn't seem like this command can be used to circumvent the filters very effectively. It does include the input, but it includes that input inside a code block in an embed, so for instance:

A user who attempts this will trigger the filters with their initial message, and the bo...
Another solution to this problem is not processing commands if a message is flagged however practically that may be hard to implement as it would involve overwriting the core on_message
d6c775b Initial commit for proposed range-len command - swfarnsworth
[python-discord/bot] New branch created: range\-len\-message
Here's my implement:
- Convert
codeparameter to an instance ofint(if while the process is running ValueError is raised then it's actual code) [Go to 4] - Crawl on all channels using a
forloop to be able to fetch the message. (https://discordpy.readthedocs.io/en/latest/api.html#discord.abc.Messageable.fetch_message) - If the message is found, strip the prefix and convert it to a proper format. Else, display some fancy error message and return. (sanitize it eeeh)
- Execute ...
I tried to keep the message brief at the cost of things I'd like to say about iterating over collections that don't implement __getitem__ or which are unordered by design. I included the final section because potential applications of zip and enumerate are where I most often see people use range(len(...)) even when they know how standard iteration works, though that section might not be necessary given that messages for those two builtins exist.
Fixes #1031
This removes the argument from the BadArgument command and runs filters over !eval output, as requested.
Build 20200708.3 failed
Requested by
GitHub
Duration
00:02:28
Build pipeline
Bot
This only fixes one possible path in the error handler, not all of them, and also has missed the docs cog.
Using Python ^3.7 or ^3.8 in your pyproject.toml file prevents adding this package via poetry add:
[SolverProblemError]
The current project's Python requirement (^3.8) is not compatible with some of the required packages Python requirement:
- flake8-annotations requires Python >=3.6.1,<3.9
Because no versions of flake8-annotations match >2.2.0,<3.0.0
and flake8-annotations (2.2.0) requires Python >=3.6.1,<3.9, flake8-annotations is forbidden.
So, because tool-belt de...
This only fixes one possible path in the error handler, not all of them,
this is the only path that repeats the argument
also has missed the docs cog.
lemon mentioned in https://github.com/python-discord/bot/issues/1031#issuecomment-655702470 that the docs don't actually circumvent it very efficiently so it isn't really a problem
Can you please make a new issue? This isn't really related.
Thanks for the review. I did test things again and everything still seems to be in order. I'm not keen on writing tests any more; I need to study more before I can feel confident in writing tests again.
We effectively manually maintain a list of extensions when we load them in __main__. I haven't heard any complaints and I like the explicitness of it. We can turn this into an actual list that the extension management cog can use to know which modules are valid extensions to load/unload. It's based on the assumption that we want to load all extensions by default. If not, separate lists would be required.
This avoids any complicated extension detection code at the cost of being vulnerable...
So it highlights the title link on mobile if the code block is removed? If that's the case, I'm totally on board with removing the title code block and relying solely on the title link.
it is believed the user-sent messages can only contain one attachment at maximum.
This is true on Desktop, but not on mobile. It's been almost 2 years since I tested it though (was relevant for Big Brother). That being said, the implementation is fine the way it is; there's no way to include multiple images in a single embed, and many images would be noisy anyway.
Other thoughts:
- The webhook doesn't use the nickname. Should it?
- The "actioned"/"rejected" in the footer is a bit ...
This can fail. It wouldn't hurt to catch the exceptions here and give up on trying to set an image.
archivation is not a "real" word as far as I know.
Mind sorting these alphabetically?
@AtieP I think better converter should Union[discord.Message, str, None]? Then you don't have to do so much parsing. When None, this should parse last message.
Postgres backup completed!
Good idea, didn't thought about it.
But what do you mean "last message"?
Crawl on all channels using a for loop to be able to fetch the message. (https://discordpy.readthedocs.io/en/latest/api.html#discord.abc.Messageable.fetch_message)
Ignoring the rest of the implementation details for now, in what kind of situation do you expect this command to be executed? I think we'd need a very good reason to try and fetch a message on every channel in our guild and I'm not sure this command is enough reason for such an API call heavy implementation. Wouldn't the comma...
Your points are right. Personally I don't expect much usage of this feature and this is really heavy for the Discord API, and the bot as well.
@AtieP Last message is message that is sent to channel exactly before command execution message.
Sentry Issue: BOT-6Q
The infractions viewset doesn't support deleting infractions, but it's done here:
This is to delete infractions when they fail to apply on the Discord side of things. Should DELETE support be added to the API or can we re-order things to not h...
Sentry Issue: BOT-6S
In the case below, I believe they left the guild after the muted role was added but before it could attempt to kick them from a voice channel.
NotFound: 404 Not Found (error code: 10007): Unknown Member
File "bot/cogs/moderation/scheduler.py", line 155, in apply_infraction
await action_coro
File "bot/cogs/moderation/infractions.py", line 229, in action
...
It really is not, but at the time I was struggling to express it in a valid way. I suppose "to be archived" will do.
@MarkKoz
[re: only 1 user-sent attachment] This is true on Desktop, but not on mobile.
Thanks for mentioning this, I didn't think to test on mobile.
The webhook doesn't use the nickname. Should it?
Good question, I don't know. I think I went with name because we don't otherwise store the incident author identity (only avatar and name at the time or archivation<sup>sorry</sup>), and I figured if someone changes their nickname to something memey temporarily it may end up being di...
Good point, this should be addressed. But I'm already anxious thinking about how to write this so that it's not too ugly. I'll ponder upon it.
I think this is more or less a complete solution. There may be edge cases that aren't caught by this, but it's a big enough step in the right direction that I'm comfortable moving forward with it.
The code quality is quite excellent, too. Nice work.
await ctx.send("Bad argument: Please double-check your input arguments and try again.\n")
It seems the more correct form is to hyphenate here.
Actually I wonder if this should abort entirely? If this fails for some reason with the attachment being valid & important but we still relay, we will lose potentially important information.
Build 20200709.1 succeeded
Requested by
GitHub
Duration
00:02:28
Build pipeline
Bot
Kaizened in 54891b4, also indented the &PYNEWS_WEBHOOK further since I was already making changes.
The config files (both the yaml and the .py) could use some more refactoring, I noticed that the spacing between classes is inconsistent (1 or 2 empty lines), and some other constants are probably not sorted properly. But I consider those beyond the scope of this PR.
Sure, that's my bad: 54891b4
I've included my suggestion in https://github.com/python-discord/bot/pull/927/commits/077a1ef1eb4eb07325dde5b6b625a84ccb5669ee when moving the upload logic, the PR should be ready to go after an another review so you can skip that if you'd like
Build 20200709.2 succeeded
Requested by
GitHub
Duration
00:02:28
Build pipeline
Bot
@MarkKoz I've tried a few things to sneak in the Signal emoji, this is an option:

The author field requires a name but it'll take \U0000200B (zero-width character). We need to resolve the emoji cdn url somehow.
A prettier option would be using the footer icon, but I enjoy having the moderator avatar there. The footer otherwise won't display the emoji (with `<:emojiname:123...
Describe the bug
Using Python ^3.7 or ^3.8 in your pyproject.toml file (i.e. the default values that Poetry generates) prevents adding this package via poetry add:
[SolverProblemError]
The current project's Python requirement (^3.8) is not compatible with some of the required packages Python requirement:
- flake8-annotations requires Python >=3.6.1,2.2.0,=3.6.1,<3.9, flake8-annotations is forbidden.
So, because tool-belt depends on flake8-annotations (^2.2.0), vers...
Build 20200709.3 failed
Requested by
GitHub
Duration
00:02:12
Build pipeline
Bot
Build 20200709.4 failed
Requested by
GitHub
Duration
00:02:03
Build pipeline
Bot
So this PR now makes an attempt at fixing the regression reported in #meta recently:

The approach taken seems reasonable. The tests look good and we should move forward merging this soon, but since we added this change which affects a lot of code, I will need to test it properly and perhaps discuss with other core devs.
What is the motivation behind choosing 1000 as the ...
About
Have notification/video link+details posted in discord when a YouTuber uploads a video. Here the YouTubers can be those that make content related to python, a specific field(web dev), etc. A few notable examples are Corey MS, Traversy Media, FreeCodeCamp, JustDjango, CodingEntrepreneurs, etc.
Implementation
This can be achieved using YouTube Data API (v3) which supports push notifications via PubSubHubbub.
(**[Link](https://developers.google.com/youtube/v3/guides/push_noti...
This would be a message we could whip out when we see range(len(...)) for loops during help sessions. I intentionally left out a lot of interesting details to keep the message concise.
I recall there being a RealPython article about "pythonic loops" and was hoping to link to it, but it looks like it's now paid content. I saw that our guides are under construction and I'd be happy to write a guide on loops with an emphasis on pythonicness.
I don't know that linking to the official Pyth...
Thank you for contributing to Python Discord!
Please check out the following documents:
- Join the Discord server! - If you have not already, join the Discord server and introduce yourself in our #dev-contrib channel.
- Python Discord Contributor Wiki - A set of resources about setting up our services
- Python Discord Code of Conduct - Code of conduct for our commu...
Build 20200709.5 succeeded
Requested by
GitHub
Duration
00:02:43
Build pipeline
Bot
Build 20200709.6 succeeded
Requested by
GitHub
Duration
00:02:14
Build pipeline
Bot
Thanks for the ping
Looks like this has also been asked upstream: https://github.com/python-poetry/poetry/issues/2646
And answered: https://github.com/python-poetry/poetry/issues/1930#issuecomment-653906544
The default caret requirement of, say ^3.8 tells Poetry that your project is compatible with [3.8, 4.0), but we currently do not guarantee compatibility with >=3.9 so this is technically an incompatibility. This can be solved with a tilde requirement, ~3.8, which would descr...
Here's what the tag ends up looking like in Discord:

I think this is well written and I'm happy to approve it.
Some tags that we have will show an interactive session to demonstrate what the output looks like, for example:

This gives a more tangible exa...
ac7add5 Revert Python version dependency pin change - sco1
[python-discord/flake8-annotations] New branch created: fix\-python\-pin
Changelog
[v2.2.1]
Fixed
- #89 Revert change to Python version pinning to prevent unnecessary locking headaches
Closes #89
@kwzrd Because the limit is 2048, and 1000 is about half, so half is still available for other things.
[python-discord/bot] branch deleted: feat/test/765/command\-shadowing\-simple
@kwzrd I see what you're saying about displaying the REPL output. I think people who use range(len(...)) are familiar with iteration in general (and probably use it that way in a C-style language); if the concept of iteration itself is where they're struggling, they probably don't know why they have range(len(...)) in their code, and a tailored approach would be needed to teach them that concept. If we find that the current message isn't effective, we could see if a REPL display is what w...
[python-discord/bot] branch deleted: free\-tag
[python-discord/bot] branch deleted: unittest\-utils
[python-discord/bot] branch deleted: Hemlock/newline\_alternative
[python-discord/bot] branch deleted: autoconfig
Build 20200709.7 succeeded
Requested by
GitHub
Duration
00:05:35
Build pipeline
Bot
Connected!
I'm not sure we need the icon โ colour gives away enough imo.
You can fall back to linking the attachment or add a note that there was supposed to be one but it failed.
This is perfectly fine in my opinion.
But I don't mind using nickname at all if you or anyone else prefers it, I basically don't have any opinion on it.
Neither do I. I'm fine with how it is.
A prettier option would be using the footer icon:
I like it in the footer, but I'm willing to try out the colour only. I will complain later if I find it too subtle in practice ๐
Looks good! However, since we do have !zip and !enumerate tags, maybe they could be mentioned in this tag?
Postgres backup completed!
How would you feel about using the author name field?

It can be made to link the attachment proxy url, but I think that stops being functional some time after the original message is deleted.
@Den4200 Do we have any other messages that suggest that you run a command to get another message? The idea sounds a bit weird to me, but our messages would probably be more informative for our intended audience than the Python docs.
[python-discord/flake8-annotations] branch deleted: fix\-python\-pin
[python-discord/flake8-annotations] New tag created: v2\.2\.1
974b2a7 Add flag for suppressing return hint errors for... - sco1
[python-discord/flake8-annotations] New branch created: dev\-next
Changelog
[v2.3.0]
Added
- #87 Add
--mypy-style-init-returnto allow omission of a return type hint for__init__if at least one argument is annotated.
Additional Details
To help provide compatibility with Mypy for maintainers that wish to do so, the --mypy-init-return flag has been introduced to mimic Mypy's allowance for the omission of return type hints for __init__ methods that are not dynamically typed (at least one argument is annotated).
For example, from...
Hopefully I got it right this time, would you be interested in checking out the dev-next branch (#91) to verify that we are able to provide a behavior that Mypy users would expect?
You forgot to update the version in pyproject.toml
* #87 Add `--mypy-init-return` to allow omission of a return type hint for `__init__` if at least one argument is annotated. See [mypy's documentation](https://mypy.readthedocs.io/en/stable/class_basics.html?#annotating-init-methods) for additional details.
ba3c0c0 Fix missed flag name change in changelog - sco1
Hmm, I don't think there are any tags that mention other ones. It's just the docs from what I can tell, so I'll leave it up to you to decide.
39651d0 Update discord.py to fix issue with overwrites - MarkKoz
6220c8a Merge branch 'master' into range-len-message - Den4200
Build 20200710.1 succeeded
Requested by
GitHub
Duration
00:02:30
Build pipeline
Bot
After some discussion in #organisation, it looks like the tag is ready to go.
[python-discord/bot] branch deleted: range\-len\-message
Build 20200710.2 succeeded
Requested by
GitHub
Duration
00:04:56
Build pipeline
Bot
Connected!
My first though would be to put it at the end of the description so that the message content "takes priority". However, I am fine with your proposal as well.
I do log the exception so we'll get a Sentry notif if this happens.
I don't think NotFound and any 500's are worth being notified for, though we should probably consider ignoring all 500s at a larger scale rather than here.
While there was not much use for the link itself, I think the highlight showed a bit better that it wasn't a part of the text. I think just the text read more blends in a bit too much, but haven't found an alternative I was entirely satisfied with

Do you think it's fine as it - but without the link, or some of the alternatives I fit into the image?
Postgres backup completed!
I think a simple ellipses would be fine.