#dev-contrib

1 messages · Page 168 of 1

clever wraith
#

this is pycharm

#

yeah it's running on the poetry enviroment

#

only

gritty wind
#

Alright uh

#

Try running poetry update

clever wraith
#

doing it

gritty wind
#

While you wait, be sure to get the issue approved before you start work, or you run the risk of your contribution being rejected

clever wraith
gritty wind
#

Alright that’s cool

clever wraith
#

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'
brisk brook
#

Have you ran docker build to rebuild the container?

fervent sage
#

Same smh

static canyon
#
    @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?
fallen patrol
fallen patrol
#

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

static canyon
#

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

fallen patrol
static canyon
#

I'll just return if it's None

fallen patrol
#

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

static canyon
#

Do we have the guild_id?

#

Yeah, seems to

#

!d discord.RawMessageUpdateEvent.guild_id

stable mountainBOT
static canyon
#

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
fallen patrol
#

ye, I think so

#

isn't there a util for that tho, one second

static canyon
#

Util for what?

#

All I changed was L4+5

fallen patrol
#

the int(event.data[]) ... thing

#

looks good to me, I think

static canyon
#

I can't see it though

fallen patrol
#

there isn't

#

or well

#

it's a private method

#

_try_snowflake iirc

static canyon
#

Let's just leave it then. It's fine as-is

fallen patrol
#

yeah, ofc

static canyon
#

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?
stable mountainBOT
#

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:```
static canyon
#

Apparently it's a property, so I guess that's why. PyCharm just doesn't like it

#

Pushed: bot#2085

dusky shoreBOT
static canyon
#

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?

rapid swallow
static canyon
#

Seems to be, thank you!

static canyon
sleek steppe
#

I just use the vscode GitHub extension 🙃

vale ibex
#

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

brisk brook
austere hornet
sleek steppe
static canyon
#

We've unloaded the cog for now

austere hornet
#

Ah ok

lost inlet
austere hornet
#

(That wasn't meant in a bad way, sorry if that came out a little rude)

placid ermine
#

it got un-unloaded on restart

solemn vine
#

@crude gyro where should be the new resource command created ?

crude gyro
solemn vine
#

yeah

#

which file ?

crude gyro
#

I don't have a strong opinion. probably in bot/exts/info, maybe a new file.

solemn vine
stable mountainBOT
#

bot/exts/info/help.py line 467

class Help(Cog):```
crude gyro
#

seems very strange to put it into that file

solemn vine
#

i see

crude gyro
#

that file has its own very specific purpose

solemn vine
#

alright

crude gyro
#

we have a rules command in that file, which is close.

#

pretty close

solemn vine
#

mhmm

#

ok sure

sleek steppe
#

Sorry for all that waiting, I had forgotten this PR wasn't merged yet. sir-lancebot#778 is already approved and ready for merge. 😄

dusky shoreBOT
vale ibex
#

Nice 👌 thanks @sleek steppe

fallen patrol
#

oh finally

#

sir-lancebot#778

dusky shoreBOT
fallen patrol
#

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 😄

cold island
#

.c unload advent_of_code

dusky shoreBOT
#

:ok_hand: Extension successfully unloaded: bot.exts.events.advent_of_code.

cold island
#

hmmm

#

.src

dusky shoreBOT
austere hornet
fallen patrol
#

it was

#

but then the bot restarts

#

and then it loads itself back up

austere hornet
#

Ohhhhh

vale ibex
#

I re-enabled the cog for now and stopped the task instead. Have sir-lancebot#1029 up

dusky shoreBOT
fallen patrol
#

neat

austere hornet
#

Ah 👍

thorny spade
#

how do you post /r/Python top daily post?

sleek steppe
sleek steppe
#

no, where is that?

stable mountainBOT
#

bot/exts/utilities/reddit.py line 82

text = escape_markdown(text).replace("[", "⦋").replace("]", "⦌")```
thorny spade
#

toxic where are you

sleek steppe
thorny spade
magic arch
#

probably to escape it intentionally so it doesn't link

sleek steppe
thorny spade
thorny spade
#

also can i use black for linting?

tawdry vapor
# thorny spade 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.

thorny spade
#

i installed flake8. ❤️

thorny spade
dim pelican
static canyon
#
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

clever wraith
#

What does the interaction look like if you print it?

static canyon
#

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

cold island
static canyon
#

Snooze feature for reminders

static canyon
dusky shoreBOT
cold island
#

Where do you get the error? when you create the interaction? when you press a button?

static canyon
cold island
#

What "..."?

#

Oh you mean the animation thingy when you press a button

static canyon
#

Yeah

#

I get the animation, then "interaction failed", and then select from the dropdown which gives above traceback

cold island
#

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?

static canyon
#
    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)
        ...```
cold island
#

What does the init of SnoozeSelectView look like

#

And what is self.parent_view?

static canyon
#

Gimme asec

cold island
#

You can push your code if you want to show

static canyon
#
    # 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)
static canyon
#
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
cold island
#

super().__init__(timeout = 60)# user has 300 seconds to snooze their reminder doesn't make sense 🤔

#

It says 60

cold island
#

Meaning, create the select object with the options and then add_item it to the view

static canyon
#

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

cold island
stable mountainBOT
#

bot/exts/info/help.py line 69

await message.edit(embed=embed, view=subcommand_view)```
static canyon
# cold island hmmm I did like you did in https://github.com/python-discord/bot/blob/main/bot/e...
    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 🤷

clever wraith
#

Oh right that is internal code

#

How weird

static canyon
#

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?

dusky shoreBOT
cold island
#

eeeh not sure I like that

hoary haven
#

lol i don't want the bot to shame my procrastination

clever wraith
hoary haven
#

yes i saw that yesterday!! pretty cool

static canyon
#

!remind 2h30M PR bot2045

stable mountainBOT
#
Of course!

Your reminder will arrive on <t:1644952706:F>!

static canyon
#

!reminder edit duration 4091 4h30M

stable mountainBOT
#
You're the boss!

That reminder has been edited successfully!

fallen patrol
#

you can essentially blame a part of this code on the issue

stable mountainBOT
#

discord/ui/view.py lines 359 to 361

await item.callback(interaction)
if not interaction.response._responded:
    await interaction.response.defer()```
fallen patrol
#

@stable mountain

#

where's the github autolink?

rapid swallow
#

wdym?

sleek steppe
fallen patrol
#

ah, they finally sent

#

this is my screen

sleek steppe
#

ah

fallen patrol
#

i tabbed off before I saw them

#

deleted the second one

fallen patrol
cold island
fallen patrol
#

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

cold island
#

oh.. hmm

#

I guess it makes sense... a bit weird but ok

fallen patrol
#

views and interactions were very efficiently designed 😃

hoary haven
fallen patrol
#

no but really there's a lot of bugs with views -- i'd just not use them

cold island
#

How else would you add buttons to a message?

fallen patrol
#

ah right there's no other interface for it

#

i forgot that we added that lol

cold island
#

Added what?

fallen patrol
#

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

cold island
#

yeah I understand

#

Well.. dpy is in alpha, so bugs are to be expected

fallen patrol
#

yeah

cold island
#

you're saying they're still buggy in disnake? or were those bugs fixed

fallen patrol
#

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

fallen patrol
cold island
#

What is the fundamental issue with views? if it's not complicated to explain

fallen patrol
#

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

cold island
fallen patrol
#

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

cold island
#

sounds fun

fallen patrol
#

it definitely is

#

I don't use views at all in my newest bot

cold island
#

How does using that components argument get around that?

fallen patrol
#

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

static canyon
stable mountainBOT
#

bot/exts/utils/reminders.py line 174

# No need to cancel the task too; it'll simply be done once this coroutine returns.```
vale ibex
#

so the coro returning means the coro has completed

static canyon
#

So if I'm within that function I NEVER have to care about manually cancelling?

stable mountainBOT
vale ibex
#

nope, the scheduled task is running that function

#

so once that function ends, the task is finished

static canyon
#
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????

static canyon
#

Yeah, that was it. I've fixed it now 👍

sleek steppe
#

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 😄

dusky shoreBOT
static canyon
#

Hopefully it'll be merged soon™️

fallen patrol
#

hmm

#

lmao the times

#

@static canyon btw could you send a screenshot of the snoozer?

static canyon
#

@brazen lichen might've gotten a sneak peek 👀

fallen patrol
#

I don't want to run it but i might

static canyon
fallen patrol
#

read_message_history means the user can also read the history-- just having read_messages does not allow a user to fetch the history

static canyon
#

Eh, ig

fallen patrol
#

its not really a problem in this server but its a better practice

static canyon
#

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

stable mountainBOT
#

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```
fallen patrol
#

read_message_history will never be true when read_messages is false

static canyon
#

Added images btw @fallen patrol

fallen patrol
#

hmm

static canyon
fallen patrol
#

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
static canyon
#

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

fallen patrol
#

may i ask why?

static canyon
#

It saves an API call

#

At the end you only have to remove one view instead of removing 2

fallen patrol
#

i suppose

static canyon
#

Also I don't understand your .rsplit comment

#

How is it any different?

fallen patrol
#

its a nitpick

static canyon
#

I don't think a PR is a place to be nitpicking code from outside the PR

#

Just an unnecessary diff change 🤷

patent pivot
#

@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.

thorny obsidian
patent pivot
#

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.

thorny obsidian
patent pivot
#

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.

thorny obsidian
#

Okay. That will most likely significantly hamper some efforts for events and developing new features since we now have to use site API.

cold island
patent pivot
#

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.

thorny obsidian
#

Also django and how the site repo/folders is set up isn't really the most approachable, especially when compared to redis.

patent pivot
#

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

cold island
#

losing modpings data isn't a huge deal, but regardless I'm not sure I'll be able to give it attention

thorny obsidian
patent pivot
thorny obsidian
patent pivot
patent pivot
#

It doesn't require Docker

thorny obsidian
thorny obsidian
patent pivot
patent pivot
cold island
#

If we're making lance contribs use WSL we might as well make them use Docker honestly

patent pivot
#

I think it'll still run on Windows-proper, just haven't tried it, there is a Windows installer iirc

thorny obsidian
cold island
#

Are we actually losing persistency quality in any capacity, or is it just a policy thing?

patent pivot
#

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

cold island
#

Still, if we wanted to migrate a cache, we could, techincially, just export a json and then load it back

patent pivot
#

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

thorny obsidian
#

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.

cold island
#

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

patent pivot
#

hmmmmm

#

I guess alternatively, we could build a generic key-val system into django that can be reused

cold island
#

Although tbh IMO some events stuff should live in Python

patent pivot
#

or, realistically, KKV

thorny obsidian
cold island
#

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

thorny obsidian
thorny obsidian
cold island
#

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

patent pivot
#

lancebot targeting April 21st, bot is targeting May 8th as deadlines

crude gyro
#

happy to be involved in any future discussion about this, I've missed previous ones.

fallen patrol
#

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

short snow
#

Afaik KeyDB is compatible pithink I did the same with one of my projects sometime back.

patent pivot
#

Drop in replacement != same underneath storage system

fallen patrol
#

exact quote that said it wasn't:

We're moving from Redis to KeyDB, which aren't compatible, so it eases the migration.

patent pivot
#

Of course they have different data directories, that's why KeyDB is able to achieve the things it does

fallen patrol
#

unless you meant are compatiable

patent pivot
#

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

fallen patrol
#

ah ok

green oriole
#

KeyDB aims to have much more permanent data, compared to Redis, doesn't it

patent pivot
#

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

fallen patrol
#

oki

green oriole
#

wait so far we considered redis as persistent

#

there is some data there that shouldn't be dropped, at least with the current implementations

fallen patrol
#

that's why its being moved to site and site is becoming a requirement for lance

green oriole
#

so site + postgres?

fallen patrol
#

yeap

green oriole
#

wasn't the goal to keep lance easy to set up?

fallen patrol
#

yeap

green oriole
#

running on the host will be quite painful, as compared to just having keydb to set up

fallen patrol
#

yeap

#

basically gonna require docker

green oriole
#

considering the mess that docker desktop became, not sure if this is a great idea

fallen patrol
#

i agree 😃

green oriole
fallen patrol
#

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)

green oriole
#

is it not paid

cold island
#

I haven't paid anything so far

#

It has a pro version

fallen patrol
green oriole
#

did they roll it back

cold island
#

Don't think I was ever required to pay

green oriole
#

I believe they said it will become paid

#

seems like they never did it

short snow
green oriole
#

okay, so that's not a problem

short snow
#

But still setting up postgres+site for lance, can sometimes be a pain

fallen patrol
#

that too

#

lance is extremely easy to tinker with

#

i wouldn't have worked on lance if site had been required when i started

cold island
#

Anyway, don't be alarmed by the changes to redis storage, we'll find proper solutions to everything

green oriole
#

what if a mock is added to sir lance, the same way it has fakeredis atm?

fallen patrol
green oriole
#

so you can just keep everything in memory and have no actual dev dep

short snow
fallen patrol
#

I agree with that, akarys

#

but the problem (likely) is, as always, finding someone to implement it

green oriole
#

sounds fun

cold island
stable mountainBOT
#

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
    )```
green oriole
#

I would be willing to implement it

fallen patrol
#

🤡

#

nah it removes all groups of ||

green oriole
#

I don't really know

cold island
#

Except I tried it on a test string and it doesn't exactly thinkmon

fallen patrol
#

||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

short snow
#

screw that (deleted)

green oriole
#

!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)
stable mountainBOT
#

@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']
green oriole
#

makes sense

fallen patrol
#

!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])

stable mountainBOT
#

@fallen patrol :white_check_mark: Your eval job has completed with return code 0.

['', '||eg this ||', "message's", '|| content ||', 'will', '|| become||', '']
green oriole
#

although weird that it keeps the ||

#

maybe they are stripped somewhere else

short snow
#

yeah that confused me

fallen patrol
#

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])

stable mountainBOT
#

@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||']
fallen patrol
#

yeah i have no idea what its actually doing

#

@crude gyro you got any idea? the blame defers this to you

green oriole
#

@cold island so it returns a join of the unspoilered text, the spoilered text and then the source (mixed) text

cold island
#

Hmm

#

OK thanks. Maybe I'll make it drop the pipes or something

green oriole
crude gyro
#

did I really write that?

#

I don't like it very much

placid ermine
#

mood

green oriole
#

It lacks examples haha

late geyser
green oriole
#

hi @thorny obsidian

#

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)

patent pivot
#

it became paid if your company grossed over a certain threshold

#

it was never going to become paid for everyone

hoary haven
#

arl was saying something about needing windows professional, as opposed to windows home, i guess? is that a factor?

vale ibex
#

Yea, windows pro is needed if you don't have admin on the user running docker

#

iirc

gritty wind
#

Don’t you… need admin to install any software in the first place

hoary haven
#

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

hoary haven
#

is this expected? after creating a new branch locally i

git fetch upstream
git merge upstream/main

it made a file called git Thinking_chief ?

#

upstream is main repo
remote is my fork

vocal wolf
fallen patrol
fallen patrol
hoary haven
#

that's v weird. is that a limitation from windows side?

fallen patrol
#

yes

vocal wolf
#

@static canyon you're going to kill me with all the PRs you're adding to the bot lmao

static canyon
#

lol

#

At least they're relatively small 😄

vocal wolf
#

it would be great if we're able to clear out the old PRs, but they're mostly waiting on authors

static canyon
#

I think the two I posted in dev-core should be fine

#

Just need approval

green oriole
#

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 peeposhrug

vocal wolf
brisk brook
#

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

sleek steppe
dusky shoreBOT
vocal wolf
#

oh wait doesn't this one just need to be merged

#

yeah green button is green

brisk brook
#

🎉

#

Do we want to make more in-depth tests to break the surrounding time code?

vocal wolf
#

@brisk brook were you eventually planning to test in depth?

#

oh

#

lol

brisk brook
#

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

sleek steppe
brisk brook
#

Again though, someone could probably just override it yet another time and break the output 🤷‍♂️

brisk brook
sleek steppe
#

Ah

#

Breaking sys.stdout won’t matter, it’ll just give them an output that they won’t want from the timeit command

brisk brook
#

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

hoary haven
vale ibex
#

it looks like you merged upstream/main with a branch

sleek steppe
vale ibex
#

could you try checking out main, then merging upstream/main?

hoary haven
#

after fetch upstream yes?

brisk brook
#

😅

vale ibex
hoary haven
#
(.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?
vale ibex
#

but when you merge without giving a source and target, it infers the target to be the current branch

fallen patrol
#

Scaleios 🤡

hoary haven
#

is there an easy command to check that i'm at the same commit as upstream/main?

vale ibex
#

git status

#

that'll show you the difference between the currently checked out branch, and the remote branch it's tracking

fallen patrol
#

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

dusky shoreBOT
fallen patrol
#

!src

stable mountainBOT
fallen patrol
#

okay so that one is allowed, good

hoary haven
#

@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

vale ibex
#

Yea, the django logo isn't transparent, so we alter the colour values to match the footer colour

hoary haven
#

what if i hop onto the django server and demand a svg will they give me one? lol

hoary haven
austere hornet
# dusky shore

I'm surprised this wasn't a thing this whole time, didn't even realize it was locked in this channel until now

crude gyro
#

if so, that sounds not too difficult to fix.

hoary haven
#

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

crude gyro
#

this is what chris means

#

without that it looks like this

hoary haven
#

ic ic

crude gyro
#

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

vale ibex
#

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

crude gyro
#

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

vale ibex
#

cool cool

crude gyro
vale ibex
#

we could do some caching in CF too ig

crude gyro
#

we definitely do

fallen patrol
crude gyro
#

woooow dice_3

static canyon
#

@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?

dusky shoreBOT
crude gyro
vale ibex
#

@austere hornet regarding sir-lancebot#1022 I can't merge this as you didn't allow commits from maintainers on your PR

dusky shoreBOT
molten perch
vale ibex
#

Could you update the branch when you get some time?

static canyon
molten perch
static canyon
#

In which case I think we can just close the issue

molten perch
#

I'll a take a look at it later this week. Thanks! 😄

static canyon
#

👌

brazen charm
#

just fix it with some existing pr

#

there's no reason to log useless info

crude gyro
hoary haven
#

lol yeah the sizing of the logos are Thinking_chief

#

ty lemon

crude gyro
#

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

vale ibex
#

Alright, forcepushed bot#2033 to squash fixup commits

dusky shoreBOT
vale ibex
#

gonna do a final test then merge

#

It's live on test server with & prefix if anyone wants to test too

austere hornet
#

Thanks for letting me know

vale ibex
#

nice, thanks

austere hornet
#

👍

#

For some reason .topic is not working in #pedagogy, did I forget to do something?

vale ibex
#

.src topic

dusky shoreBOT
#
Command: topic

Responds with a random topic to start a conversation.

Source Code
vale ibex
#

you might have done it before the bot started up with the changes

static canyon
#

.src spookyavatar

dusky shoreBOT
#
Command: avatar_modify spookyavatar

Spookify a user's avatar.

Source Code
fallen patrol
#

those are different comments

static canyon
#

?

fallen patrol
#

lance annoyingly deleted its error response

static canyon
#

Well, still, I don't see the code that prevents it

fallen patrol
#

so 1032 is about lance deleting its error response -- specifically not allowing src here

static canyon
#

Hmm

fallen patrol
#

.src

#

that is what 1032 is about

static canyon
#

Right

#

I did see that

fallen patrol
#

the thing for avatar is that the footer has a different avatar than was acted on

static canyon
#

I'm referring to the .src thing

#

Can you invoke again please @fallen patrol

fallen patrol
#

.src

#

.src spookyavatar

static canyon
#

Thanks

fallen patrol
#

the code is the global check

green oriole
#

whitelist something something

static canyon
#

Right

vale ibex
#

there's a global check on sirlance, so it needs to bee overridden with the whitelist deco

static canyon
#

So we just need to override

#

Yeah

stable mountainBOT
#

bot/__main__.py line 10

bot.add_check(whitelist_check(channels=WHITELISTED_CHANNELS, roles=STAFF_ROLES))```
static canyon
#

Thanks

green oriole
#

there is a decorator to override it

#

it has been ages, I don't remember how

#

but that's very copy pastable

stable mountainBOT
#

bot/exts/utilities/cheatsheet.py line 83

@whitelist_override(categories=[Categories.help_in_use])```
vale ibex
#

from bot.utils.decorators import whitelist_override

#

A small gotcha, this is a complete override, not add these channels on top of defaults

static canyon
#

👍

vale ibex
#

it supports channels, categories and roles kwargs

green oriole
#

how does this thing even work

#

also

#

is discord seriously going to flag every single github link

#

ooh, because it ends with .py

vale ibex
green oriole
#

that's is soooooo stupid

vale ibex
#

and whitelist_check looks at them

static canyon
#

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:

green oriole
green oriole
#

not sure if you need to explicit roles

vale ibex
green oriole
#

also might as well add meta to the mix?

static canyon
#

And do I need the roles kwarg or not? @vale ibex

vale ibex
#

not iirc

#

if you don't specify the roles kwarg, it'll use the default

green oriole
#

did y'all move the decorators to the utils folder?

static canyon
#

Sopy @whitelist_override(channels=WHITELISTED_CHANNELS+[Channels.dev_contrib])

vale ibex
#

looks good

static canyon
#

I suppose I should test before pushing

vale ibex
#

Yea, maybe add community_meta too

#

Ak suggested it and I agree

static canyon
#

Yep

static canyon
vale ibex
#

huh, guess lance has never used it

green oriole
#

surprising

static canyon
#

Might also rename bot and community_bot_commands to be clearer whilst I'm at it

vale ibex
#

👌

fallen patrol
#

after i only had to experience it for.... 3 days but longest three days of my life

static canyon
#

Am I okay to also rename the "CHANNEL_COMMUNITY_BOT_COMMANDS" env? @vale ibex

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

static canyon
#

Eh, I'll just leave then

vale ibex
#

👍

static canyon
#

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

sleek steppe
#

@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'
static canyon
#

See sir-lancebot#1033

dusky shoreBOT
static canyon
#

It looks correct

sleek steppe
vale ibex
#

ah right, cool

green oriole
#

yeah looks correct

sleek steppe
fallen patrol
vale ibex
#

Need toif hasattr(thread_update.after, "archived") and thread_update.after.archived:

#

since thread_update.after will only include the attrs that changed

sleek steppe
#

ah 👍

fallen patrol
#

hm is there a raw thread update event?

#

!d discord.on_thread_update

stable mountainBOT
#

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.
vale ibex
#

this is from the audit log

fallen patrol
#

there is not

#

yeah ik

tribal gazelle
#

hello i have a probleme

fallen patrol
#

but there's a newly_created flag flag that is set when you... get a payload where the thread is actually newly created

vale ibex
#

I've pushed another fixup commit toxic if you wanted to pull changes

fallen patrol
#

because lets face it, threads are a gateway mess

vale ibex
fallen patrol
#

they aren't even actually right, tested them

fallen patrol
#

but ye

#

if you have any thread questions don't hesitate to ask, been reworking how they're dispatched and documenting the specific cases

sleek steppe
vale ibex
#

true

#

pushed 2 commits, one that actions your comment by refactoring that function, and another for that convertor.

stable mountainBOT
#

bot/exts/utils/thread_bumper.py line 60

thread = channel.get_or_fetch_channel(thread_id)```
vale ibex
#

wheee

#

Pushed

#

it would have helped if I had a thread in the bump cache when I tested it by running 😅

sleek steppe
# vale ibex it would have helped if I had a thread in the bump cache when I tested it by run...

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
vale ibex
#

huh

#

wut

#

oh

#

yes

#

line 131

#

Thanks for the review toxic 😄

#

I've squashed the fixups

hoary haven
stable mountainBOT
#

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] + "..."```
sleek steppe
hoary haven
#

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?

sleek steppe
#

yeah, looking at the file you linked, I can see cases where content isn't passed

hoary haven
#

when does this trigger..

    if content:
        content = f"<@&{Roles.moderators}>\n{content}"```
sleek steppe
#

ah I read your message wrong 😅

hoary haven
#

let me back up, the reason i'm asking is under the scope of bot#2088

dusky shoreBOT
hoary haven
#

i'm just running bot in debugger and triggering filters and watching things in debug mode

sleek steppe
stable mountainBOT
#

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_}"
)```
hoary haven
#

ic ic ty. did you just use your editor to find all references of that function?

#

oh gh has it too

fallen patrol
#

and below that it just sets content to a mod ping

hoary haven
hoary haven
#

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)

fallen patrol
#

its the only place i see that passes content

#

hm

#

kk should add cs to that

hoary haven
#

cs?

hoary haven
#

nvm i was looking elsewhere

hoary haven
sleek steppe
#

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

hoary haven
# dusky shore

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

sleek steppe
#

yeah, sounds good

hoary haven
#

ty ty. so much code lol

austere hornet
#

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!

dusky shoreBOT
fallen patrol
#

but that specific form of link is a valid autolink format minus the subdomain

hoary haven
#

ah. and how'd you get a cs link? just from using gh's search?

fallen patrol
#

from cs

#

closed beta rn

austere hornet
thorny obsidian
#

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.

gritty wind
#

Yup, that's usually a concern, but maybe possibly we don't have ratelimits on python anymore? idk, but we have other reasons too

vale ibex
#

we still have ratelimits

#

we just won't get banned by the api if we hit the anti spam limit

clever wraith
#

Hi, does Senor Lancebot have a wordle command?

thorny obsidian
#

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

austere hornet
#

Oh that might be fun to write, yeah certainly open an issue about it

static canyon
#

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?

vale ibex
#

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

static canyon
#

Hmm

vale ibex
#

Could also add an optional hard mode flag, where your guess need to use all the information given to you already

static canyon
#

Buttons have the benefit of having the letter on them

#

But yeah, I think emojis work better

vale ibex
#

Yea, I don't think buttons would work well for this,

#

since what would clicking on them do?

static canyon
#

I mean you'd disable them so they can't be clicked ig

vale ibex
#

Yea, seems like overcomplicating it for no reason imo

static canyon
#

Yeah

vale ibex
#

seems like a good proposal though, we'd likely approve an issue

static canyon
#

Yeah, I like the idea

thorny obsidian
cold island
#

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

static canyon
#

Unless the thread channel is like wordle-uid or something

cold island
#

yeah

#

that's what I was thinking

static canyon
#

Right, yeah

static canyon
#

Would we be able to have concurrent games (more than one happening at once)?

cold island
#

Don't see why not

rapid swallow
#

yeah/

static canyon
cold island
#

Might want to limit it though to X concurrent games

sleek steppe
#

One user probably shouldn’t be able to run two concurrent games

static canyon
green oriole
vale ibex
#

I think last time python got banned for DMing too many people Discord added it to some allow list

green oriole
#

That's cool

vale ibex
#

so we still get the same rate limits, but don't get hard blocked

green oriole
#

I wonder if that's a verified bot thing

vale ibex
#

not too sure

green oriole
#

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 pleased_akarys

clever wraith
#

Does Lancebot have modals?

brisk brook
thorny obsidian
clever wraith
#

I have no idea how this game words xd

fallen patrol
clever wraith
#

issue made 👀

fallen patrol
#

like, which library

fervent sage
fallen patrol
#

they're busy getting to a 5 day SLA!

clever wraith
cold island
#

setUp for unittests runs before each test in the class right?

brazen charm
#

Yes

clever wraith
#

Compacted everything into one message, might be final product

#

After I revise code ofc at home

molten perch
#

Hey, @obsidian patio! Was sir-lancebot#987 in the past sometime approved here on Discord?
I'm just going through issues and noticed it. 😄

dusky shoreBOT
static canyon
#

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

clever wraith
clever wraith
#

Only valid word, entered for the wordle? or for each guess

static canyon
clever wraith
#

I see

#

I don’t play this game bro 😭

#

Well in that case

#

I am sure maybe

  1. txt file of all 5 letter words
  2. API
#

One or the other, both simple to add

static canyon
#

I'd do 1. but use the official wordle list

clever wraith
#

Ooh there’s wha

#

Hol on can ya link

green oriole
#

Is wordle licensed

#

Because that'd be straight up ripping the source code

static canyon
# clever wraith Hol on can ya link
Gist

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

clever wraith
#

I only doing this cuz of a club competition man I don’t know all of these stuff

green oriole
#

People extracted the word lists from the wordle source code

clever wraith
#

Oh

green oriole
#

Which would be fairly illegal to copy and paste

wild prism
#

afaik you cannot copyright game mechanics

#

idk about word lists

green oriole
#

Well you can but that's beside the point

clever wraith
green oriole
#

The word lists are literal copy pastes from the source code

static canyon
green oriole
#

Yes

clever wraith
#

Wow

#

Well so be it if I go arrested

green oriole
#

I'd ask a core dev first if that'd okay

#

Because pydis has been quite conservative when it comes to licensing

clever wraith
#

Darn

molten perch
obsidian patio
#

Is there an issue with this in some way?

green oriole
#

Sir dorsan what do you think about the above?

#

Is taking the word list from the wordle source code okay or nah

thorny obsidian
molten perch
molten perch
green oriole
brazen charm
#

couldn't you get it by just playing anyway

molten perch
#

Is it available on Github or something I haven't really tried it out.

clever wraith
#

0-0

green oriole
#

I like how the girlfriend of the creator came up with the list of words usable for guesses

static canyon
#

I.e. we can just use the old list?

clever wraith
#

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

green oriole
green oriole
static canyon
molten perch
thorny obsidian
static canyon
green oriole
#

It is just that obvious copy pasting can have some consequences

#

Even if it is just a list of words

vocal prairie
#
/*! *****************************************************************************
  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

static canyon
#

We do have a list of all words anyway on lancebot btw. So we could just filter that

green oriole
#

Wot MS copyright?

static canyon
#

Although some of those words are rather... Obscure

green oriole
#

Okay then it is fine haha

vocal prairie
#

it was at the top in the non pretty printed version

green oriole
#

Do you have the link pls?

vocal prairie
#

uhh, I just checked the inspect element to see if there was a license

thorny obsidian
#

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.

wild prism
#

looks like selections of words are an open question

green oriole
#

The argument could be that someone put efforts into manually sorting words

obsidian patio
green oriole
#

Especially if it is a NYT worker

wild prism
#

apparently effort is totally ignored by US copyright law

thorny obsidian
brazen charm
#

It's just some raw data, how would that be copyrighted?

wild prism
#

isnt that every copyright?

brazen charm
#

It's not a creative work of any kind

wild prism
#

not the words themselves

patent pivot
#

uhhhhh

#

we can copy a list of words

#

lol

green oriole
patent pivot
#

no point continuing this, you've got my okay, list of 5 letter words is fine

thorny obsidian
green oriole
#

Interesting

patent pivot
#

if very concerned, cat /usr/share/dict/cracklib-small | ack "^[A-Za-z]{5}$"

#

lol

static canyon
green oriole
wild prism
green oriole
#

So you don't get like frizz in your wordle

#

Which is a funky looking word

brazen charm
#

Law is absurdly obscure, but you also can't just have people stealing things

vocal prairie
clever wraith
#

Jesus I go for like 10 minutes and it spiraled

thorny obsidian
green oriole
#

Thonk it is, in fact, a totally normal word

patent pivot
#

lol

green oriole
#

Okay but surely nobody knows what "saags" are, right

patent pivot
#

i picked cracklib because it's a password cracking list

#

and people are morons

wild prism
#

isnt that some sort of Indian dish

green oriole
#

Haha, so it is manually sorted already

obsidian patio
green oriole
#

Good to know, my password will now be "Saags2"

patent pivot
vocal prairie
patent pivot
#

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

wild prism
#

especially since everyone and their mother is using it

patent pivot
#

if we do get into trouble, we swap it out

#

yeah

green oriole
#

I mean I doubt pydis will ever get a DMCA for anything haha

patent pivot
#

eh

#

we've had dmca

#

just not for silly things

green oriole
#

OK scratch that then mmwhereismynose

#

Technically you DMCAed me once

#

Along with like half the pydis staff

thorny obsidian
thorny obsidian
green oriole
#

Who DMCAed you

patent pivot
#

community license for what

#

being dmcad

#

epic 😎

thorny obsidian
patent pivot
#

ohhhhhhhh

#

yeah

wild prism
patent pivot
#

lol i wasn't even thinking of that

#

we've had people get fussy over paste.pydis before is what I was thinking of

obsidian patio
green oriole
#

I guess that makes sense

thorny obsidian
patent pivot
#

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

brazen charm
#

if you make the reasonable assumption that they got the words from a dictionary or something similar, did they break their copyright?

obsidian patio
wild prism
#

right, like at some point it's an unordered book

#

and you can copyright a book

thorny obsidian
#

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

wild prism
#

i think the legal answer to that depends on how much Hasbro is willing to spend on lawyers

thorny obsidian
#

who cares. We can use a list of 5 letter words.

obsidian patio
thorny obsidian
patent pivot
#

we can use the word list, if we receive a complaint we will amend as necessary

crude gyro
#

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.

patent pivot
#

+1

clever wraith
#

dang

#

all of this started cuz i wanted to add wordle

#

sorry

#

ion wanna put lancebot in any trouble

thorny obsidian
clever wraith
#

ah

#

second pressing issue

#

my impl uses modals

static canyon
#

Not that I know what modals is, but I saw you mention lancebot doesn't have it

clever wraith
#

It’s because modals were officially added a week or so ago

#

And dpy archived last August

static canyon
#

First of all, what are modals?

clever wraith
#

I’ll send you a example

#

This is how a modal looks

static canyon
#

Just use wait_for instead or something I guess