#dev-contrib
1 messages · Page 168 of 1
doing it
While you wait, be sure to get the issue approved before you start work, or you run the risk of your contribution being rejected
haha yes I know that but I just want to code, don't care if it gets rejected
Alright that’s cool
well this is kind of weird
sir-lancebot | discord.ext.commands.errors.ExtensionFailed: Extension 'bot.exts.fun.joke' raised an error: ModuleNotFoundError: No module named 'pyjokes'
Have you ran docker build to rebuild the container?
Same smh
@Cog.listener()
async def on_raw_message_edit(self, event: discord.RawMessageUpdateEvent) -> None:
"""Log raw message edit event to message change log."""
await self.bot.wait_until_guild_available()
try:
channel = self.bot.get_channel(int(event.data["channel_id"]))
message = await channel.fetch_message(event.message_id)
except discord.NotFound: # Was deleted before we got the event
return
if self.is_message_blacklisted(message):
return```RE bot#2010:
There's an issue whereby the channel could be a DM, which would mean that if it's not in cache then `bot.get_channel` still won't get the channel, and it will result in `None`.
The suggested solution was to move up the `if self.is_message_blacklisted(message)` check, but that's not possible since we don't have the message until after we get the channel.
From how I see it, we have two options:
1) If channel is `None`, then we just return early (possibly with a debug or something). Upside being no API call, downside being we don't log DM message edits.
2) Instead of using `bot.get_channel`, we use `utils.channels.get_or_fetch_channel()`. Upside: will ALWAYS return the channel object so we can log DM message edits, but downside is that it will possibly be at the expense of an API call.
Which approach do we want to use?
smh
what is the end goal
log dm message edits
considering they aren't relayed, why would you want to log their edits
additionally if the message isn't cached then it's not possible to compare the changes
yes?
Right. For some reason I was thinking we might want to relay DM edits, but then I realised we literally have the is_message_blacklisted to prevent that
keep in mind the dm relay cog was removed for user privacy or smth like that
I'll just return if it's None
I'd add a check here that if guild_id is none, return early, at the top of the method
even before the wait until guild available event
Do we have the guild_id?
Yeah, seems to
!d discord.RawMessageUpdateEvent.guild_id
The guild ID where the message got updated, if applicable.
New in version 1.7.
So... this?```py
@Cog.listener()
async def on_raw_message_edit(self, event: discord.RawMessageUpdateEvent) -> None:
"""Log raw message edit event to message change log."""
if event.guild_id is None:
return # ignore DM edits
await self.bot.wait_until_guild_available()
try:
channel = self.bot.get_channel(int(event.data["channel_id"]))
message = await channel.fetch_message(event.message_id)
except discord.NotFound: # Was deleted before we got the event
return
if self.is_message_blacklisted(message):
return
I mean if there is I can always change to use it
I can't see it though
Let's just leave it then. It's fine as-is
yeah, ofc
On a side note
# Shorten the message content if necessary
content = message.clean_content
...
if len(content) > remaining_chars:
...
```how comes this hasn't ever given an error? We're doing `len()` on a function?
bot/exts/moderation/modlog.py lines 592 to 596
# Shorten the message content if necessary
content = message.clean_content
remaining_chars = 4090 - len(response)
if len(content) > remaining_chars:```
Apparently it's a property, so I guess that's why. PyCharm just doesn't like it
Pushed: bot#2085
Is there an easy way to test a PR that's not on the pydis bot repo, without having to clone the user's repo?
https://stackoverflow.com/a/59704540 is this what you're looking for?
Seems to be, thank you!
.bm test other's PRs
I just use the vscode GitHub extension 🙃
got this in my .gitconfig ```
[alias]
cpr = "!cd ${GIT_PREFIX:-.} && git fetch origin refs/pull/${1}/head && git checkout FETCH_HEAD #"
which doesn't make a local branch, it just checks out the head commit
that will work for branches on your origin to do forks,. you'd need to add the fork as another remote and then change origin to the name of that remote
GitHub Desktop allows you to checkout PRs
.bm might be useful
What happened with Lance in #dev-log with the AoC sync? Just curious
For example: #dev-log message
Along with github CLI
The API token thingy expired
We've unloaded the cog for now
Ah ok
hey i wanted to know if i can do this issue for @dusky shore https://github.com/python-discord/sir-lancebot/issues/1007
Hmm, did you? I still see it #dev-log message
(That wasn't meant in a bad way, sorry if that came out a little rude)
it got un-unloaded on restart
@crude gyro where should be the new resource command created ?
where as in.. what. which file?
I don't have a strong opinion. probably in bot/exts/info, maybe a new file.
in my opinion maybe here https://github.com/python-discord/bot/blob/main/bot/exts/info/help.py#L467
bot/exts/info/help.py line 467
class Help(Cog):```
seems very strange to put it into that file
i see
that file has its own very specific purpose
alright
I'd say either in this file: https://github.com/python-discord/bot/blob/main/bot/exts/info/information.py
or in a new file.
we have a rules command in that file, which is close.
pretty close
Sorry for all that waiting, I had forgotten this PR wasn't merged yet. sir-lancebot#778 is already approved and ready for merge. 😄
Nice 👌 thanks @sleek steppe
finaaaaally
wooooo i can work on whichever pr adds enhancements which is already outdated because i kind of want to rewrite the cog to use graphql so it works on discussions lol
hey <@&267628507062992896> the aoc cog is live and flooding #dev-log again 😄
.c unload advent_of_code
:ok_hand: Extension successfully unloaded: bot.exts.events.advent_of_code.
Thanks, was going to do that because I was told by Tizzy that the cog was unloaded but it didn't seem to be because I kept seeing those messages. Anyway
Ohhhhh
I re-enabled the cog for now and stopped the task instead. Have sir-lancebot#1029 up
neat
Ah 👍
how do you post /r/Python top daily post?
@dusky shore fetches daily and weekly posts at midnight (utc) from the reddit API and uses the reddit webhook to send it to #reddit
thanks
is it intended?
no, where is that?
bot/exts/utilities/reddit.py line 82
text = escape_markdown(text).replace("[", "⦋").replace("]", "⦌")```
toxic where are you
Ah nvm, that's fine. We truncate the content of the reddit post and that will kinda ruin markdown
no i mean why is the ⦌ is used instead of ]?
probably to escape it intentionally so it doesn't link
yeah, there was an issue with markdown rendering (https://github.com/python-discord/sir-lancebot/issues/746)
thanks ❤️
https://github.com/python-discord/sir-lancebot/issues/1001
is anyone still working in this? if no i have a fork fixed this.
also can i use black for linting?
In practice, I think not because it would also format surrounding code, wouldn't it? That would lead to bigger diffs with unrelated changes. If it was a completely new file or you could only lint your changes, then it might be fine since black's format is pretty close to what we use anyway.
thanks.
i installed flake8. ❤️
https://github.com/python-discord/sir-lancebot/issues/1024
also can i be assigned to this?
@simple slate any updates on the PR or should it be re-assigned?
Ignoring exception in view <SnoozeButtonView timeout=60 children=1> for item <SnoozeButton style=<ButtonStyle.secondary: 2> url=None disabled=False label='Snooze Reminder' emoji=None row=None>:
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/discord/ui/view.py", line 361, in _scheduled_task
await interaction.response.defer()
File "/usr/local/lib/python3.9/site-packages/discord/interactions.py", line 423, in defer
await adapter.create_interaction_response(
File "/usr/local/lib/python3.9/site-packages/discord/webhook/async_.py", line 189, in request
raise NotFound(response, data)
discord.errors.NotFound: 404 Not Found (error code: 10062): Unknown interaction```does anyone have any ideas as to how I can debug this issue I'm getting with the a feature I'm trying to implement into bot?
I've been stuck on this for ~30mins and can't find what's happening
What does the interaction look like if you print it?
I've got no clue where I'm supposed to be printing it though
I don't know what line is causing this error or anything
All the lines I could think of I did a try/except but to no avail
It seems to be one of these three lines, but I've got no clue how they'd give a NotFoundpy self.parent_view.new_expiry = snooze_select_view.new_expiry self.parent_view.reminder_was_snoozed = True self.parent_view.stop() @clever wraith
Nvm, it's not those lines
Don't know where it is though
What are you trying to implement?
Snooze feature for reminders
bot#2045
Where do you get the error? when you create the interaction? when you press a button?
I click a button, which then loads a select menu.
I wait 3 seconds for the "..." of loading the select menu, and then click. ALL of the code then processes, and I then get this error. It's really weird because my code is all running
Yeah
I get the animation, then "interaction failed", and then select from the dropdown which gives above traceback
So you create a view with a button, and pressing the button creates a new view with a select, and then edit the message to use the new view?
Yes
async def callback(self, interaction: discord.Interaction) -> None:
"""Ensure the reminder author matches the user who clicked button and then display select view."""
if interaction.user.id != self.parent_view.reminder_author_id:
await interaction.response.send_message(":x: This is not your reminder to react to!", ephemeral=True)
return
snooze_select_view = SnoozeSelectView(
bot=self.parent_view.bot,
reminder_id=self.parent_view.reminder_id,
reminder_author_id=self.parent_view.reminder_author_id
)
m = await interaction.message.edit(view=snooze_select_view)
...```
Gimme asec
You can push your code if you want to show
# Snooze select view init
def __init__(self, bot: Bot, reminder_id: int, reminder_author_id: int):
super().__init__(timeout=30)
self.new_expiry: t.Optional[datetime] = None
self.reminder_was_snoozed = False
self.bot = bot
self.reminder_id = reminder_id
self.interaction_owner_id = reminder_author_id
self.dropdown: discord.ui.Select = self.children[0]
for duration in self.SNOOZE_DURATIONS:
self.dropdown.add_option(label=duration)
And self.parent_view is just a link inside SnoozeButton to the SnoozeButtonView instance
class SnoozeButtonView(discord.ui.View):
def __init__(self, bot: Bot, reminder_id: int, reminder_author_id: int):
super().__init__(timeout = 60)# user has 300 seconds to snooze their reminder over line limit
self.new_expiry: t.Optional[datetime] = None
self.reminder_was_snoozed = False
self.bot = bot
self.reminder_id = reminder_id
self.reminder_author_id = reminder_author_id
snooze_button = SnoozeButton(self)
self.add_item(snooze_button)
class SnoozeButton(discord.ui.Button):
def __init__(self, parent_view: SnoozeButtonView):
super().__init__(label="Snooze Reminder")
self.parent_view = parent_view
super().__init__(timeout = 60)# user has 300 seconds to snooze their reminder doesn't make sense 🤔
It says 60
Can you try to create the dropdown like you created the button?
Meaning, create the select object with the options and then add_item it to the view
Oh yeah it's 60 whilst I'm testing but in production it'll be 300
I've got the "over line limit" thing so I don't forget (will fail linting)
Might've fixed it by changing a interaction.message.edit to interaction.response.edit_message
hmmm I did like you did in https://github.com/python-discord/bot/blob/main/bot/exts/info/help.py#L69 and it worked fine
bot/exts/info/help.py line 69
await message.edit(embed=embed, view=subcommand_view)```
async def callback(self, interaction: discord.Interaction) -> None:
"""Ensure the reminder author matches the user who clicked button and then display select view."""
if interaction.user.id != self.parent_view.reminder_author_id:
await interaction.response.send_message(":x: This is not your reminder to react to!", ephemeral=True)
return
snooze_select_view = SnoozeSelectView(
bot=self.parent_view.bot,
reminder_id=self.parent_view.reminder_id,
reminder_author_id=self.parent_view.reminder_author_id
)
m = await interaction.message.edit(view=snooze_select_view)
```changing the last line to```py
m = await interaction.response.edit_message(view=snooze_select_view)```fixed it from the looks of things 🤷
Need to do some more robust testing but what was causing an error isn't anymore 🤷
Yeah, exactly. That's what confused me
Okay, so:
I've implemented the actual "snooze" feature of bot#2045, but there was also a suggestion to have progressively more "aggressive" arrival messages the more you snoozed.
This would mean a PR to site, updating the reminders database to have a "times_snoozed" integer field. Is this something we still want?
eeeh not sure I like that
lol i don't want the bot to shame my procrastination
yes i saw that yesterday!! pretty cool
Since both you and Zig disagree, I'll go ahead and PR what I've got (just the snoozing) when I get home 👍
!remind 2h30M PR bot2045
Your reminder will arrive on <t:1644952706:F>!
!reminder edit duration 4091 4h30M
That reminder has been edited successfully!
its not, response is publicly documented and you're supposed to use it
you can essentially blame a part of this code on the issue
discord/ui/view.py lines 359 to 361
await item.callback(interaction)
if not interaction.response._responded:
await interaction.response.defer()```
wdym?
The source?
ah
this should use interaction.response.edit_message, saves an api request
Why is it an extra API request 🤔
.
you aren't responding to the interaction when you use the first method
so dpy transparently responds to the api by deferring
which ends up being a second api request
when you use interaction.response.edit_message, you invoke this reply
which both updates and stops the loading state
views and interactions were very efficiently designed 😃
i won't oppose if someone really wants it, but i think it can be done in a separate issue/PR possibly
no but really there's a lot of bugs with views -- i'd just not use them
How else would you add buttons to a message?
Added what?
a components parameter to anything that takes a view
so you can just send, eg a button and then handle the callback and such yourself, eg with a listener or wait_for
not on dpy itself tho
yeah
you're saying they're still buggy in disnake? or were those bugs fixed
I think i've found most of bugs in views, but there's a fundamental issue with how they're stored which messes up all of the dispatching of them
partially can blame discord itself for that one
all of the ones except the one above that I'm aware of have been fixed
What is the fundamental issue with views? if it's not complicated to explain
The key issue is when responding to an application command, the api returns no useful information about the created message, or whatever action was taken. This is the endpoint used, and it returns a 204 on success...
this means that its impossible to have a message ID to link the view up to, which is how _ViewStore currently works
this means that the most recently added view matching the components is dispatched, even if it was not sent on that message
however, as messages contain a interaction reference the solution is to figure out how to reliably dispatch based on the interaction ID vs other information that we have access to when receiving an interaction from the api
So the interaction might create a response message, but you don't get the message ID from the API response?
correct
my current fix on my own bot to ensure they're stored correctly is to defer and then send my ephemeral view
that sends it to a different endpoint which functions exactly like making a webhook message: Create Followup Message
this returns the message sent and therefore allows it to be stored in the _ViewStore
sounds fun
How does using that components argument get around that?
using components means that you handle the callback yourself, so you define the custom_id of the button or select and anything else that you want to define, then check if the custom id is what you want
in my case i send the buttons then have static listeners for their callbacks, which have information stored in the custom id
RE https://github.com/python-discord/bot/blob/main/bot/exts/utils/reminders.py#L174:
What is it that implicitly cancels a schedule?
bot/exts/utils/reminders.py line 174
# No need to cancel the task too; it'll simply be done once this coroutine returns.```
it was a task that scheduled
so the coro returning means the coro has completed
So if I'm within that function I NEVER have to care about manually cancelling?
Here's your reminder: PR bot2045
[Jump back to when you created the reminder](#dev-contrib message)
nope, the scheduled task is running that function
so once that function ends, the task is finished
try:
m = await partial_message.reply(
content=f"{additional_mentions}",
embed=embed,
view=snooze_button_view
)
except discord.HTTPException as e:
log.info(
f"There was an error when trying to reply to a reminder invocation message, {e}, "
"fall back to using jump_url"
)
m = await channel.send(
content=f"<@{reminder_author_id}> {additional_mentions}",
embed=embed,
view=snooze_button_view
)
# Before deleting the reminder, see if the user wants to "snooze" it
await snooze_button_view.wait()
if not snooze_button_view.reminder_was_snoozed:
# User didn't snooze the reminder
log.debug(f"Deleting reminder #{reminder_id} ({reminder_author_id} has been reminded and didn't snooze).")
#self.scheduler.cancel(reminder_id) <--- LINE IN QUESTION
await self.bot.api_client.delete(f"bot/reminders/{reminder_id}")
with suppress(discord.NotFound):
await m.edit(view=None)
return
# Reminder was snoozed, so we need to reschedule it
log.debug(f"Snoozing reminder #{reminder_id}. New expiration: {snooze_button_view.new_expiry}")
await self._reschedule_reminder(reminder | {"expiration": snooze_button_view.new_expiry.isoformat()})```so I don't need to manually cancel after my `log.debug` (in the `if not ....`)?
I was also getting a LockedResourceError every so often from the code, but couldn't find out why and it doesn't seem to be consistent:py Traceback (most recent call last): File "/bot/bot/exts/utils/reminders.py", line 190, in reschedule_reminders await self.send_reminder(reminder, remind_at) File "/bot/bot/utils/lock.py", line 112, in wrapper raise LockedResourceError(str(namespace), id_) bot.errors.LockedResourceError: Cannot operate on reminder `66`; it is currently locked and in use by another operation.
I guess it's when it tries to send a reminder that's currently waiting to see if the user wants to snooze it????
That makes sense actually
Yeah, that was it. I've fixed it now 👍
I’d appreciate if a core dev merged bot#1602, it’s approved and it has been open for a relatively long amount of time 😄
Have relayed it internally 👍
Hopefully it'll be merged soon™️
hmm
lmao the times
@static canyon btw could you send a screenshot of the snoozer?
Yeah, I will be soon™️
@brazen lichen might've gotten a sneak peek 👀
I don't want to run it but i might
Why is read_message_history better?
read_message_history means the user can also read the history-- just having read_messages does not allow a user to fetch the history
Eh, ig
its not really a problem in this server but its a better practice
Yeah, in reality it won't make a difference in this server
But I guess I can change it
Actually that might break things
I'm not sure it's worth changing tbh
discord/abc.py lines 655 to 658
# if you can't read a channel then you have no permissions there
if not base.read_messages:
denied = Permissions.all_channel()
base.value &= ~denied.value```
read_message_history will never be true when read_messages is false
Added images btw @fallen patrol
hmm
I don't think I'm gonna bother with this unless a core dev thinks it matters.
this i think would look better ephemerally
- send reminder with snooze button
- user clicks, gets ephemeral message with the select on it
- user selects it
- take action and respond
That means sending a new message though, rather than editing the pre-existing one
An aim of this was to keep it all on one message
may i ask why?
It saves an API call
At the end you only have to remove one view instead of removing 2
i suppose
its a nitpick
I don't think a PR is a place to be nitpicking code from outside the PR
Just an unnecessary diff change 🤷
@thorny obsidian @cold island we're planning on dropping all persistent usages of rediscache, a couple of which are within your domains.
In events, we've got the AoC account links which will need to be migrated to site, and from Moderation we need to migrate modpings to using site for storage as well as the talent pool auto-review enable or not, and defcon settings.
Letting you two know since they're in your domains so I'll leave migration decisions up to you - the data will be fine until we migrate to Ansible+Netcup, when Redis data will be dropped, if you want to migrate before that I can assist with migrating the data, but these caches should be migrated to the site API.
why the dropping of rediscache for persistant usage?
We're moving from Redis to KeyDB, which aren't compatible, so it eases the migration. We've always been on the fence before about Redis for persistence, but we're going to set a line now during the migration where it makes sense that going forward rediscache should just be a cache.
so we won't have any redis?
Bots should be able to drop Redis data and work fine - anything which can't handle that should use site API.
We will have Redis, for data that needs a cache only
Stuff like help channel claimants, the verification pings queue, etc.
Okay. That will most likely significantly hamper some efforts for events and developing new features since we now have to use site API.
defcon settings don't need to be persistent, whatever redis provides is enough
What things in particular? Setting up a Redis-like table in site should be a fairly achievable task. We'll probably put the API wrapper in bot core so that both bots can use it.
👍, that's fine then
Because anything new we need will now require 2 PRs and when working with lance we now have to setup site.
Also django and how the site repo/folders is set up isn't really the most approachable, especially when compared to redis.
Right now though as far as I can see that's just AoC account links, which is a KV table, the PRs to site should be fairly small, just models, hooking into DRF and makemigrations
losing modpings data isn't a huge deal, but regardless I'm not sure I'll be able to give it attention
tbh for someone not familiar with django, dealing with DRF and navigating the site repo and the expectation of writing tests sounds ... demotivating
It's certainly better, and we can make things better. For example, we removed the need for /etc/hosts and stuff so now it's just install, setup postgres and run
but it will likely require docker to run, which a fair amount of contributors to lance don't do. They run it straight from poetry.
I think we can improve this with documentation/mentoring, there are several experienced Django/DRF folks on staff who would be happy to help, I'm not particularly familiar with it myself but get by well
I run site straight on my desktop, it was just a matter of poetry install, postgres install and run more or less
It doesn't require Docker
I dunno, I feel like there are only maybe 5 and most of them are very busy. Site's been pretty much neglected until volcyy made a push with the core devs for it.
A postgres install isn't exactly a simple thing. It's not hard, but it does involve a bit.
That's fine, in that case probably just best opening issues for migration in the long term
Again with guides on it I'm sure we can simplify that process, it's fairly simple on macOS/Linux with package managers, I haven't gone through the Windows process, but I've heard fairly alright things from WSL users
If we're making lance contribs use WSL we might as well make them use Docker honestly
I think it'll still run on Windows-proper, just haven't tried it, there is a Windows installer iirc
I have gone through it on Windows and it's still a serious step-up to now require that for lance, an entry-point for new contributors. It's going to make setting up features for events more tedious, because despite you saying it's a simple PR, it's still a whole PR and another framework you have to be familiar with and merging the two at the same time.
Are we actually losing persistency quality in any capacity, or is it just a policy thing?
Mainly policy, although we're probably not going to do backups once we've migrated, and because we're migrating from Redis to KeyDB we can't carry across the backups we've got
Still, if we wanted to migrate a cache, we could, techincially, just export a json and then load it back
hmm, we could, I'd still much rather we just move to the store which we're preferring usage of now, treating redis like what it is, a cache, is much less work intensive on devops and is the ideology we've been recommending for a long while
we've always made it clear that things requiring trustworthy persistence should working off postgres
it's just probably slipped and been not super enforced, but now we're migrating it's a natural point to start that enforcement
I don't really understand the reason for the enforcement besides just wanting to treat redis like a cache. It's worked well as a decent persistent storage for lance so that we don't need to require site for a repo intended for people new to contributing.
I understand your argument, but I think what kat is describing is a real issue. This is a bit of a step back from lancebot being beginner friendly
hmmmmm
I guess alternatively, we could build a generic key-val system into django that can be reused
Although tbh IMO some events stuff should live in Python
or, realistically, KKV
should it? I keep getting mixed responses that leads to the same place we are now. Where code jams live on python and everything else on lance
Well, I opened an events folder under extensions so it could house more things besides the codejam stuff
aoc is something we do yearly so I really wouldn't mind it being there
but I've gotten push back from core devs and admins that AoC isn't "our" event and therefore should remain on lance
I wasn't aware about this, I thought it would just be code jam
In my opinion a big event that we do consistently every year suits Python, but I can poke the other core devs about it
@patent pivot do you have a timeframe btw
lancebot targeting April 21st, bot is targeting May 8th as deadlines
I think all our planned events for this year are very much a core part of Python Discord at this point, and I'm strongly in favor of managing them from @stable mountain
happy to be involved in any future discussion about this, I've missed previous ones.
from Redis to KeyDB, which aren't compatible,
i thought this was going to be a drop in compatiable replacement, per what you previously said? @patent pivot
Afaik KeyDB is compatible
I did the same with one of my projects sometime back.
It is
Drop in replacement != same underneath storage system
exact quote that said it wasn't:
We're moving from Redis to KeyDB, which aren't compatible, so it eases the migration.
Of course they have different data directories, that's why KeyDB is able to achieve the things it does
unless you meant are compatiable
No, you're misunderstanding what a drop-in replacement is
When referring to a drop-in replacement in situations like these it's much more about protocols used and the POV from client user applications
It is not expected for data directories to carry across
What we've said is that our existing bots and tools will work out of the box with KeyDB, we don't need to make any code changes, they are 100% compatible
That does not mean that KeyDB will pick up our old Redis data, nor should it, we should be using Redis as a cache and be able to drop the data without major recoil
ah ok
KeyDB aims to have much more permanent data, compared to Redis, doesn't it
I don't recall there being a major difference, but from a policy perspective we're not favouring persistent data in redis/keydb
Hence why we're not going to do backups/do data migration and so on
oki
wait so far we considered redis as persistent
there is some data there that shouldn't be dropped, at least with the current implementations
that's why its being moved to site and site is becoming a requirement for lance
so site + postgres?
yeap
wasn't the goal to keep lance easy to set up?
yeap
running on the host will be quite painful, as compared to just having keydb to set up
considering the mess that docker desktop became, not sure if this is a great idea
i agree 😃
sorry for poking old messages, but bear in mind that docker desktop is now paid
? I'm using it
I had to by windows pro to use docker because i couldn't add my account to the docker user group because its a feature that is only in windows pro which i know that not everyone here has (on windows) (who is going to contribute)
is it not paid
did they roll it back
Don't think I was ever required to pay
okay, so that's not a problem
'cept this is
But still setting up postgres+site for lance, can sometimes be a pain
that too
lance is extremely easy to tinker with
i wouldn't have worked on lance if site had been required when i started
Anyway, don't be alarmed by the changes to redis storage, we'll find proper solutions to everything
what if a mock is added to sir lance, the same way it has fakeredis atm?

so you can just keep everything in memory and have no actual dev dep
including that just removes the point of it being beginner-friendly
I agree with that, akarys
but the problem (likely) is, as always, finding someone to implement it
sounds fun
Can someone explain this piece of code to me like I'm 5? https://github.com/python-discord/bot/blob/main/bot/exts/filters/filtering.py#L167-L173
bot/exts/filters/filtering.py lines 167 to 173
@staticmethod
def _expand_spoilers(text: str) -> str:
"""Return a string containing all interpretations of a spoilered message."""
split_text = SPOILER_RE.split(text)
return ''.join(
split_text[0::2] + split_text[1::2] + split_text
)```
I would be willing to implement it
like you're 5... hm. Text goes in, text comes out
🤡
nah it removes all groups of ||
I think what this is doing is if you have a||b||c it will return ac, b annnnd
I don't really know
Except I tried it on a test string and it doesn't exactly 
||eg this ||message's|| content ||will|| become||
eg this message's content will become
parses the || out of it
or well, it should
so totally bugged probably
screw that (deleted)
!e
import re
SPOILER_RE = re.compile(r"(\|\|.+?\|\|)", re.DOTALL)
split_text = SPOILER_RE.split("a||b||c||d||e")
print(split_text[0::2])
print(split_text[1::2])
print(split_text)
@green oriole :white_check_mark: Your eval job has completed with return code 0.
001 | ['a', 'c', 'e']
002 | ['||b||', '||d||']
003 | ['a', '||b||', 'c', '||d||', 'e']
makes sense
!e ```py
text = "||eg this ||message's|| content ||will|| become||"
import re
SPOILER_RE = re.compile(r"(||.+?||)", re.DOTALL)
split_text = SPOILER_RE.split(text)
print(split_text)
print(split_text[1:-1])
@fallen patrol :white_check_mark: Your eval job has completed with return code 0.
['', '||eg this ||', "message's", '|| content ||', 'will', '|| become||', '']
yeah that confused me
oh
!e ```py
text = "||eg this ||message's|| content ||will|| become||"
import re
SPOILER_RE = re.compile(r"(||.+?||)", re.DOTALL)
split_text = SPOILER_RE.split(text)
print(split_text)
print(split_text[1:-1])
@fallen patrol :white_check_mark: Your eval job has completed with return code 0.
001 | ['', '||eg this ||', "message's", '|| content ||', 'will', '|| become||', '']
002 | ['||eg this ||', "message's", '|| content ||', 'will', '|| become||']
yeah i have no idea what its actually doing
@crude gyro you got any idea? the blame defers this to you
@cold island so it returns a join of the unspoilered text, the spoilered text and then the source (mixed) text
I'd also recommend adding spaces between the three parts, because a few filters rely on word boundaries
mood
It lacks examples haha

hi @thorny obsidian
Yeah, I just had fun with the title, primer just sounds fancy
I didn't put any technical documentation in it, tell me if that's something you need (like what result is passed to the front-end and the format of the saved form result)
this isn't what it was
it became paid if your company grossed over a certain threshold
it was never going to become paid for everyone
arl was saying something about needing windows professional, as opposed to windows home, i guess? is that a factor?
Don’t you… need admin to install any software in the first place
at work i don't have admin, and a sysadmin installed docker for me
however that admin then is the only user in the docker-users group
so the admin then had to add my account to the docker-users group
so i run docker, but i'm not admin. i am on windows pro though
is this expected? after creating a new branch locally i
git fetch upstream
git merge upstream/main
it made a file called git
?
upstream is main repo
remote is my fork

cc @vale ibex when your user account is not the administrator you are unable to add your user account to the docker users group and allow it to use docker
basically this isn't possible on windows home
that's v weird. is that a limitation from windows side?
yes
@static canyon you're going to kill me with all the PRs you're adding to the bot lmao
lol
I've got more I'm planning too
(#dev-core)
At least they're relatively small 😄
it would be great if we're able to clear out the old PRs, but they're mostly waiting on authors
I wonder how that'd happen lmao
It looks like something got redirected to a file called git
Okay
That'd happen if you somehow typed git fetch upstream > git
So I guess that's what happened 
https://github.com/python-discord/bot/issues/1957 I require opinions
The issue felt like it overcomplicated things compared to what the PR changes. It's just one word. I assume someone nit-picked it once and now the author here is trying to prevent that in the future
speaking of cleaning out old pr’s, bot#1602 
Not really. I don't think it overall matters much, since the code is still inside snekbox. If someone wishes to break their own timeit output then why not? I mostly left the comment for clarity surrounding that
Perhaps a similar thing to what Scalious did in https://github.com/python-discord/forms-backend/pull/145 (also override sys.__stdout__) could improve the situation?
Most of the functionality is already covered in the original tests, it’s just the input processing methods, which I added
Again though, someone could probably just override it yet another time and break the output 🤷♂️
I am not talking about unit-tests. Manual tests that try to submit code that breaks your wrapper.
Ah
Breaking sys.stdout won’t matter, it’ll just give them an output that they won’t want from the timeit command
I'd probably vote for merging it now, and submitting another issue if users do end up finding ways to break it (accidentally I suppose, we don't care much if they try to break it)?
Rather than waiting a bit for letting someone to get some ideas in ways to break, and simultaneously fix that.. it's all in snekbox so it doesn't matter
was git merge upstream/main not the right thing to type?
https://paste.pythondiscord.com/owoguzetur.yaml is what i did
it looks like you merged upstream/main with a branch
The output formatting is the same as eval formatting, I wouldn’t expect it to break 🤷♂️
could you try checking out main, then merging upstream/main?
after fetch upstream yes?
No-no I am not talking about the Discord message formatting. I am talking about people somehow causing your wrapper to break by messing with sys.stdout - but we already agreed that if someone wishes to do that they are causing that themselves
😅
fetch upstream can be done on any branch
(.venv) PS C:\Projects\bot> git merge upstream/main
Updating 30fee62d..d10b7d2c
Fast-forward
README.md | 1 -
bot/exts/info/subscribe.py | 2 +-
bot/exts/moderation/incidents.py | 1 +
bot/exts/moderation/modlog.py | 3 +++
bot/exts/moderation/voice_gate.py | 4 ++--
bot/exts/utils/reminders.py | 15 +++++++--------
bot/resources/tags/traceback.md | 21 +++++++++------------
poetry.lock | 34 ++--------------------------------
pyproject.toml | 1 -
9 files changed, 25 insertions(+), 57 deletions(-)
(.venv) PS C:\Projects\bot>
```looks good?
Scalious
but when you merge without giving a source and target, it infers the target to be the current branch
Scaleios 🤡
that's what I'd expect yea
is there an easy command to check that i'm at the same commit as upstream/main?
git status
that'll show you the difference between the currently checked out branch, and the remote branch it's tracking
hm
any thoughts about making this take the same pfp for both things??
image: avatar or default_avatar
footer: display_avatar
.src spookyavatar
sir-lancebot#1032
!src
okay so that one is allowed, good
@crude gyro regarding the site footer, the warm grays in that footer really clashed with the cooler tone grays that we were leaning towards for dark theme. i also think chris mentioned one of the logos isn't actually transparent? or i might be misremembering
Yea, the django logo isn't transparent, so we alter the colour values to match the footer colour
what if i hop onto the django server and demand a svg will they give me one? lol
so you're saying they don't provide any transparent ones? https://www.djangoproject.com/community/logos/
alter thru code? or in an image editor
I'm surprised this wasn't a thing this whole time, didn't even realize it was locked in this channel until now
so, dark theme wants to change footer colors but the django logo ruins it. am I understanding it correctly?
if so, that sounds not too difficult to fix.
um depends what chris means by "we alter the color values" - that kinda sounds like we're doing it programmatically, but i'm not srue
ic ic
but I can just make a transparent django logo and stick it in the static files folder
it's easy to sort out
we're doing the same for this one, btw
and I mean, we already have all of these logos in static files, because the sponsor footer ones is using static files
Yea afaik, grayscale on that one works fine though
Yea, I think serving static isn't the end of the world
ideally we'd have a s3 or smth
we're using whitenoise
it's not a big deal
you don't really need production-level CDNs for, like, the couple hundred visitors we attract
whitenoise does fairly well. it handles caching, it has file manifests, we're not using vanilla django
cool cool
we could do some caching in CF too ig
we definitely do
will you guys be using blacknoise for the dark theme?

woooow 
@molten perch RE bot#1751
It looks like over time all of the issues have actually been fixed. The only case I can find after 30 minutes of searching is the log statement shown in one of the comments on the issue, which arguably isn't a big deal since it also has the humanized text with it (plus we don't actually log DEBUG in production). Is it worth PRing a fix for the log statement, or should we just close the issue?
anyway I'll fix this. Adding to my to-do.
@austere hornet regarding sir-lancebot#1022 I can't merge this as you didn't allow commits from maintainers on your PR
I could be the key to solve a problem in the future. So I'm not against you PRing it.
Could you update the branch when you get some time?
I mean not really, because it already has the humanized time with it
Oh, sorry didn't see it in your message. I'm a bit tired.
It's alright if it has the humanized time in it.
In which case I think we can just close the issue
I'll a take a look at it later this week. Thanks! 😄
👌
@spare plaza @hoary haven
might be a few days
before I can find the time
but it's on my list
and once something goes on my list
I do it
Alright, forcepushed bot#2033 to squash fixup commits
gonna do a final test then merge
It's live on test server with & prefix if anyone wants to test too
I saw, just updated the branch
Thanks for letting me know
nice, thanks
👍
For some reason .topic is not working in #pedagogy, did I forget to do something?
.src topic
seems to work fine
you might have done it before the bot started up with the changes
Ohhh
Can you try running again? I can't see anything in the code that limits the channels it can be used in?
.src spookyavatar
those are different comments
?
lance annoyingly deleted its error response
Well, still, I don't see the code that prevents it
so 1032 is about lance deleting its error response -- specifically not allowing src here
Hmm
the thing for avatar is that the footer has a different avatar than was acted on
Thanks
the code is the global check
that's just the default check
whitelist something something
Right
there's a global check on sirlance, so it needs to bee overridden with the whitelist deco
bot/__main__.py line 10
bot.add_check(whitelist_check(channels=WHITELISTED_CHANNELS, roles=STAFF_ROLES))```
Thanks
there is a decorator to override it
it has been ages, I don't remember how
but that's very copy pastable
bot/exts/utilities/cheatsheet.py line 83
@whitelist_override(categories=[Categories.help_in_use])```
from bot.utils.decorators import whitelist_override
A small gotcha, this is a complete override, not add these channels on top of defaults
👍
it supports channels, categories and roles kwargs
how does this thing even work
also
is discord seriously going to flag every single github link
ooh, because it ends with .py
it adds some args attrs to the wrapped function
that's is soooooo stupid
and whitelist_check looks at them
Does this look right?```py
@commands.command(name="source", aliases=("src",))
@whitelist_override(channels=[Channels.community_bot_commands, Channels.dev_contrib], roles=STAFF_ROLES)
async def source_command(self, ctx: commands.Context, *, source_item: SourceConverter = None) -> None:
wow that's so dirty can't believe anyone would do that
||https://github.com/Akarys42/StarBot/blob/main/starbot/decorators.py#L4-L7||
yep
not sure if you need to explicit roles
probably better to use bot.constants.WHITELISTED_CHANNELS, rather than just community_bot_commands
also might as well add meta to the mix?
And do I need the roles kwarg or not? @vale ibex
did y'all move the decorators to the utils folder?
Sopy @whitelist_override(channels=WHITELISTED_CHANNELS+[Channels.dev_contrib])
yes
looks good
I suppose I should test before pushing
Yep
Doesn't seem to exist in the constants, so do I just add it?
huh, guess lance has never used it
surprising
Might also rename bot and community_bot_commands to be clearer whilst I'm at it
👌
its been fixed on canary
after i only had to experience it for.... 3 days but longest three days of my life
Am I okay to also rename the "CHANNEL_COMMUNITY_BOT_COMMANDS" env? @vale ibex
Ah, that would be a breaking change
If we wanted to swap, we should update the site to the new version and support both for a bit
and print a deprecation notice to users still using the old one
Eh, I'll just leave then
👍
I would've pushed this about 15 minutes ago but I seem to have really messed up my branch somehow and it's including commits from my other branches when I go to push
@vale ibex I got this error when archiving a thread on the thread bumping PR:
bot_1 | Traceback (most recent call last):
bot_1 | File "/usr/local/lib/python3.9/site-packages/discord/client.py", line 351, in _run_event
bot_1 | await coro(*args, **kwargs)
bot_1 | File "/bot/bot/exts/utils/thread_bumper.py", line 127, in on_thread_update
bot_1 | await self.init_task
bot_1 | File "/bot/bot/exts/utils/thread_bumper.py", line 72, in ensure_bumped_threads_are_active
bot_1 | await self.unarchive_if_not_manually_archived(threads_to_maybe_bump)
bot_1 | File "/bot/bot/exts/utils/thread_bumper.py", line 40, in unarchive_if_not_manually_archived
bot_1 | if thread_update.after.archived:
bot_1 | AttributeError: 'AuditLogDiff' object has no attribute 'archived'
need help?
It looks correct
nvm I think my poetry wasn't updated
hmmm, it's documented as existing, I'll play around with it
ah right, cool
yeah looks correct
nvm, it was updated
ftr dotenv supports using other env vars in other env vars
it's still wrong
Need toif hasattr(thread_update.after, "archived") and thread_update.after.archived:
since thread_update.after will only include the attrs that changed
ah 👍
discord.on_thread_update(before, after)```
Called whenever a thread is updated.
This requires [`Intents.guilds`](https://discordpy.readthedocs.io/en/master/api.html#discord.Intents.guilds "discord.Intents.guilds") to be enabled.
New in version 2.0.
this is from the audit log
hello i have a probleme
but there's a newly_created flag flag that is set when you... get a payload where the thread is actually newly created
I've pushed another fixup commit toxic if you wanted to pull changes
because lets face it, threads are a gateway mess
these specifically https://discord.com/developers/docs/topics/threads#additional-context-on-the-the-threadlistsync-and-threadcreate-dispatches
Integrate your service with Discord — whether it's a bot or a game or whatever your wildest imagination can come up with.
Take a read of #❓|how-to-get-help for info on how to get held in this community. This channel is specifically for discussing python discord projects.
they aren't even actually right, tested them
thank you
but ye
if you have any thread questions don't hesitate to ask, been reworking how they're dispatched and documenting the specific cases
Review added. Have you considered using ThreadConverter instead of just int? So that you can't do !bump add 1234, but also you can use a thread mention
true
pushed 2 commits, one that actions your comment by refactoring that function, and another for that convertor.
bot/exts/utils/thread_bumper.py line 60
thread = channel.get_or_fetch_channel(thread_id)```
wheee
Pushed
it would have helped if I had a thread in the bump cache when I tested it by running 😅
new error!
bot_1 | Traceback (most recent call last):
bot_1 | File "/usr/local/lib/python3.9/site-packages/discord/client.py", line 351, in _run_event
bot_1 | await coro(*args, **kwargs)
bot_1 | File "/bot/bot/exts/utils/thread_bumper.py", line 131, in on_thread_update
bot_1 | await self.unarchive_if_not_manually_archived(after)
bot_1 | File "/bot/bot/exts/utils/thread_bumper.py", line 42, in unarchive_if_not_manually_archived
bot_1 | for thread in threads:
bot_1 | TypeError: 'Thread' object is not iterable
huh
wut
oh
yes
line 131
Thanks for the review toxic 😄
I've squashed the fixups
could i have help understanding this section in modlog.py
https://github.com/python-discord/bot/blob/7e8e95f07e343f1d7d9a8069b6cdb1a9fcbb00d7/bot/exts/moderation/modlog.py#L117-L125
when is content not None to start with and when is it longer than 2000 characters?
bot/exts/moderation/modlog.py lines 117 to 125
if ping_everyone:
if content:
content = f"<@&{Roles.moderators}>\n{content}"
else:
content = f"<@&{Roles.moderators}>"
# Truncate content to 2000 characters and append an ellipsis.
if content and len(content) > 2000:
content = content[:2000 - 3] + "..."```
Nitro users can send up to 4000 chars, and the content argument is annotated to Optional[str]
i guess send_log_message is used for lots of things, and i'm only looking at it from the perspective of messages we get in mod-alerts?
yeah, looking at the file you linked, I can see cases where content isn't passed
when does this trigger..
if content:
content = f"<@&{Roles.moderators}>\n{content}"```
ah I read your message wrong 😅
let me back up, the reason i'm asking is under the scope of bot#2088
i'm just running bot in debugger and triggering filters and watching things in debug mode
there's three cases in bot/exts/infractions/_scheduler.py where content is passed, one example being https://github.com/python-discord/bot/blob/main/bot/exts/moderation/infraction/_scheduler.py#L256-L269
bot/exts/moderation/infraction/_scheduler.py lines 256 to 269
await self.mod_log.send_log_message(
icon_url=icon,
colour=Colours.soft_red,
title=f"Infraction {log_title}: {' '.join(infr_type.split('_'))}",
thumbnail=user.display_avatar.url,
text=textwrap.dedent(f"""
Member: {messages.format_user(user)}
Actor: {ctx.author.mention}{dm_log_text}{expiry_log_text}
Reason: {reason}
{additional_info}
"""),
content=log_content,
footer=f"ID: {id_}"
)```
ic ic ty. did you just use your editor to find all references of that function?
oh gh has it too
when content is truthy, it adds the mod ping to it
and below that it just sets content to a mod ping
yeah I used vscode search
yeah i think i might have seen that happen like.... once? maybe? i don't recall what the context was
would be this then
nvm i was thinking of smth else. i can't think of a time i got a modping from @stable mountain that had other content in the message (besides an embed)
its the only place i see that passes content
GitHub Code Search (Preview)
hm
kk should add cs to that
cs?
it appears in this context it pings whoever did the infraction which subsequently failed, right?
nvm i was looking elsewhere
yeah that's right
ok let me ask some more veteran mods bc i can't think of a scenario where there'd be a moderator ping + some non-embed content
i'm sure i'm overlooking something
yeah there's never a case where ping_everyone is true and content is not none
but I guess that's there just in case that actually happens
but this is the right place to touch if i want to implement ^ issue right?
and add a new arg called user_id or smth
yeah, sounds good
ty ty. so much code lol
It seems like the person I was working with previously on sir-lancebot#985 has lost interest in working on the issue, so if someone else is willing and able to join me, I would greatly appreciate it. Just ping me here or feel free to DM me. Thanks!
subdomain of the above link is 'cs'
but that specific form of link is a valid autolink format minus the subdomain
ah. and how'd you get a cs link? just from using gh's search?
.bm
Isn't there also the broader concern about DM rate limits if we support commands/features in DMs? If Python hits that ratelimit that's going to impact our overall moderation.
Yup, that's usually a concern, but maybe possibly we don't have ratelimits on python anymore? idk, but we have other reasons too
we still have ratelimits
we just won't get banned by the api if we hit the anti spam limit
Hi, does Senor Lancebot have a wordle command?
it does not! You're welcome to make an issue about it and discuss what it would look like along with how one might implement it
Oh that might be fun to write, yeah certainly open an issue about it
Not quite sure how it'd be implemented though. Maybe with buttons, but there's no yellow button so would have to use something else. Maybe blue?
Is there even a blue one?
you could probably have it be .wordle <length> to start a game, then have it listen for messages from that user for guesses. After each guess, post the emoji 🟩⬜🟨 in the right places and also send the alphabet with what's already been guessed
then each consecutive guess just does the same
Hmm
Could also add an optional hard mode flag, where your guess need to use all the information given to you already
Buttons have the benefit of having the letter on them
But yeah, I think emojis work better
Yea, I don't think buttons would work well for this,
since what would clicking on them do?
I mean you'd disable them so they can't be clicked ig
Yea, seems like overcomplicating it for no reason imo
Yeah
seems like a good proposal though, we'd likely approve an issue
Yeah, I like the idea
threads threads threads threads threads
Starting a game puts it in a thread, bot will only respond to game starter in that thread in terms of wordle stuff. You guess, it replies with the emoji stuff
Would need to archive the thread when the game ends + we probably want the same thread to be re-opened when the user wants to start another game
I guess the latter part of that means storing a link between uids and thread channel ids
Unless the thread channel is like wordle-uid or something
Right, yeah
This would work
Would we be able to have concurrent games (more than one happening at once)?
Don't see why not
yeah/
Cool. Just wanted to make sure I wasn't missing something obvious
Might want to limit it though to X concurrent games
One user probably shouldn’t be able to run two concurrent games
So:
- No, we currently don't have a wordle game.
- However it would be cool to have one, so feel free to open an issue on our github: https://github.com/python-discord/sir-lancebot/issues/new?assignees=&labels=status%3A+planning%2C+type%3A+feature&template=feature.md
If you're not interested in developing this yourself, then I'd like to give it a try. You can do yourself if you'd like to though.
There is an API level exception for the pydis bots?
I think last time python got banned for DMing too many people Discord added it to some allow list
That's cool
so we still get the same rate limits, but don't get hard blocked
I wonder if that's a verified bot thing
not too sure
DM rate limits are very generous anyway
Opening new DMs is the real limit
Which is like a 5/10s iirc
Have y'all thought about some more stuff for the bot config?
If you still want to change it
Because if not I have some stuff to show 
I already have a working wordle generator!
Does Lancebot have modals?
Discord.py calls create_dm for each .send() call iirc 😬
No it doesn't, we're still on dpy
Ah, the way I implemented it was with modals.
I have no idea how this game words xd
@fervent sage did you ever get raptor back?
issue made 👀
how'd you do that, I'm curious
like, which library
nope its been almost a month and discord still havent responded to my ticket
I used an fork but I’m planning to switch to another one
setUp for unittests runs before each test in the class right?
Yes
Compacted everything into one message, might be final product
After I revise code ofc at home
Hey, @obsidian patio! Was sir-lancebot#987 in the past sometime approved here on Discord?
I'm just going through issues and noticed it. 😄
#dev-contrib message this kind of looks like an approval
The "solved in 1 guesses" isn't right.
It's 1 guess left
But looks pretty good
Do you have validation so only valid words can be entered?
Would also be nice to have hard mode support, although that could be added in a later PR
Yeah that’s one issue lol
What do you mean by this?
Only valid word, entered for the wordle? or for each guess
Wordle only allows you to enter valid 5 letter words for each move. So you can't enter for example "etlob" or something
I see
I don’t play this game bro 😭
Well in that case
I am sure maybe
- txt file of all 5 letter words
- API
One or the other, both simple to add
I'd do 1. but use the official wordle list
Possible solutions: https://gist.github.com/cfreshman/a03ef2cba789d8cf00c08f767e0fad7b
Possible user guesses: https://gist.github.com/cfreshman/cdcdf777450c5b5301e439061d29694c
Wordle answers from source code in alphabetical order. And if you write a solver, here's a leaderboard! https://freshman.dev/wordle/#/leaderboard - wordle-answers-alphabetical.txt
Wordle allowed guesses, not including answers: https://gist.github.com/cfreshman/a03ef2cba789d8cf00c08f767e0fad7b - wordle-allowed-guesses.txt
Say wat
I only doing this cuz of a club competition man I don’t know all of these stuff
People extracted the word lists from the wordle source code
Oh
Which would be fairly illegal to copy and paste
Well you can but that's beside the point
I’ll use the latter thanks
The word lists are literal copy pastes from the source code
But can you really copyright/license a list of words?
Yes
I'd ask a core dev first if that'd okay
Because pydis has been quite conservative when it comes to licensing
Darn
I mean, he wouldn't have asked him to make an issue if that was an approval 🙂
Is there an issue with this in some way?
Sir dorsan what do you think about the above?
Is taking the word list from the wordle source code okay or nah
The official list has changed since NYT acquired it
Not at all, I was just simply curious. Next it would be a good idea to wait for an explicit approval to avoid such confusions.
Wow, that sounds a bit sketchy. 😄 I'll have to take a look at it.

couldn't you get it by just playing anyway
Is it available on Github or something I haven't really tried it out.
0-0
I like how the girlfriend of the creator came up with the list of words usable for guesses
True
Would that mean copyright is voided?
I.e. we can just use the old list?
i don’t even know how to play this game the only reason i know the mechanics was because i saw my friend play it
Is it not the gf's list anymore? 
Well unless the orignal list was licensed it is the same issue
It's a refined version. Removing cusses and things like that
Oh, then I'm pretty sure they have strict policies.
I really don't think you can copyright a list of words. The code implementation, sure. Assets made for it, sure.
A list of 5 letter words? ... Like... is the dictionary copyrighted?
I mean Akarys said you can 🤷
It is just that obvious copy pasting can have some consequences
Even if it is just a list of words
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
this is right at the top of the file with the word lists in it
We do have a list of all words anyway on lancebot btw. So we could just filter that
Wot MS copyright?
Although some of those words are rather... Obscure
oh nvm it's somewhere in the middle of the file I'm wrong
it was at the top in the non pretty printed version
Do you have the link pls?
uhh, I just checked the inspect element to see if there was a license
Like, having to have dealt with copyright stuff previously, it's not reasonable to copyright a list of words. There's no criteria where that would be reasonable.
dictionaries are copyrighted, but mostly because of the definitions and other media
looks like selections of words are an open question
The argument could be that someone put efforts into manually sorting words
If it’s a manually curated list of words, I find it odd if you can’t copyright the specific selection. At least for such a long and niche list as this
Especially if it is a NYT worker
apparently effort is totally ignored by US copyright law
But like... The content is copyrighted? Webster owns the words and we're all fucked? No one else can make a dictionary?
The copyrights and trademarks with dictionaries is typically because of the name of the dictionary, like Webster's.
It's just some raw data, how would that be copyrighted?
isnt that every copyright?
It's not a creative work of any kind
they own the definitions, and maybe the set of words
not the words themselves
https://www.nytimes.com/games/wordle/main.18740dce.js that's the source code if y'all curious
no point continuing this, you've got my okay, list of 5 letter words is fine
The definitions are something they created. They own them. They do not own the set of words.
Interesting
In which case, you can go ahead with the links I gave @clever wraith
Well one would still have to manually sort "guesseable" words haha
🤷 I'm just reporting what I found from some quick googling, IMO copyright itself is absurd
Yay
Law is absurdly obscure, but you also can't just have people stealing things
🥴 (not sure if this will every show up as a word, but)
Jesus I go for like 10 minutes and it spiraled
frizz is a normal word though... why shouldn't it be in wordle?
it is, in fact, a totally normal word
lol
Okay but surely nobody knows what "saags" are, right
isnt that some sort of Indian dish
Haha, so it is manually sorted already
Oh, I thought it was the drug generator. My disappointment is immeasurable
Good to know, my password will now be "Saags2"
saag is
but yeah i highly doubt we will ever see trouble if we use the wordle list lol
i am not a lawyer, but putting it into our own work and modulating it should count as transformation to a stage where it is no longer a direct derivative work
especially since everyone and their mother is using it
I mean I doubt pydis will ever get a DMCA for anything haha
OK scratch that then 
Technically you DMCAed me once
Along with like half the pydis staff
There is no criteria for which a list of things would be copyrightable. Like... there's no originality with it. It's a list of things other people have created. Like the hallmark of an example is you can't copyright the list of names and addresses in a phonebook.
I still need to follow up on this. I was promised a community license and they ghosted me 😔
Who DMCAed you
merch-y stuff
there is a certain amount of collation you can do to copyright a set of words though, so the question is how much went into the list
lol i wasn't even thinking of that
we've had people get fussy over paste.pydis before is what I was thinking of
I think a better comparison would be a list of “names and addresses of people who look friendly.” I think it seems weird if you can’t copyright a list like that
I guess that makes sense
It just doesn't fit criteria of what should get a copyright (rightly so in my opinion)
as far as I'm aware when it comes to things like this: you can copyright source code, you (obviously) can't copyright the words within
so source code containing the words can be copyrighted
but not the words themselves
again, IANAL, but this is my understanding
if you make the reasonable assumption that they got the words from a dictionary or something similar, did they break their copyright?
If course you can’t copyright the words themselves, but if you curate that list to “words that look nice to you,” it’s not the words themselves that you’re copyrighting, but rather the subjective selection that’s been made
.bm
You can copyright a book because it's a creative work (and also it's a fixed medium). There is no way that you can copyright "a list of 5 letter words I liked"
the originality involved in that is not sufficient
i think the legal answer to that depends on how much Hasbro is willing to spend on lawyers
who cares. We can use a list of 5 letter words.
Sounds like a subjective decision to make. How can you be so certain that it is absolutely impossible for it to be deemed sufficient?
Because of prior courtcases and looking at the copyright criteria
(I have also spent more time than I have ever wanted to dealing with copyright for other stuff)
we can use the word list, if we receive a complaint we will amend as necessary
just shuffle the wordlist and use it. this is fine.
I agree with joe that we can just respond to any complaint we might get, but we won't get any complaints.
+1
dang
all of this started cuz i wanted to add wordle
sorry
ion wanna put lancebot in any trouble
haha, you're absolutely fine! Wordle in lance is something we definitely want and it won't get lance or us into any trouble.
Just some folks being cautious
You'll just have to use something else 🤷
Not that I know what modals is, but I saw you mention lancebot doesn't have it
It’s because modals were officially added a week or so ago
And dpy archived last August
First of all, what are modals?
Modals essentially are built in forms
I’ll send you a example
This is how a modal looks
Just use wait_for instead or something I guess