Skip to content

Commit 7a42219

Browse files
committed
basic implementation of send_after
1 parent 64bcafd commit 7a42219

File tree

3 files changed

+59
-16
lines changed

3 files changed

+59
-16
lines changed

intbot/core/bot/main.py

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from core.models import DiscordMessage
33
from discord.ext import commands, tasks
44
from django.conf import settings
5+
from django.db.models import Q
56
from django.utils import timezone
67

78
intents = discord.Intents.default()
@@ -38,19 +39,22 @@ async def wiki(ctx):
3839
suppress_embeds=True,
3940
)
4041

42+
4143
@bot.command()
4244
async def close(ctx):
4345
channel = ctx.channel
4446
author = ctx.message.author
4547

4648
# Check if it's a public or private post (thread)
47-
if channel.type in (discord.ChannelType.public_thread, discord.ChannelType.private_thread):
49+
if channel.type in (
50+
discord.ChannelType.public_thread,
51+
discord.ChannelType.private_thread,
52+
):
4853
parent = channel.parent
4954

5055
# Check if the post (thread) was sent in a forum,
5156
# so we can add a tag
5257
if parent.type == discord.ChannelType.forum:
53-
5458
# Get tag from forum
5559
tag = None
5660
for _tag in parent.available_tags:
@@ -65,18 +69,21 @@ async def close(ctx):
6569
await ctx.message.delete()
6670

6771
# Send notification to the thread
68-
await channel.send(f"# This was marked as done by {author.mention}", suppress_embeds=True)
72+
await channel.send(
73+
f"# This was marked as done by {author.mention}", suppress_embeds=True
74+
)
6975

7076
# We need to archive after adding tags in case it was a forum.
7177
await channel.edit(archived=True)
7278
else:
7379
# Remove command message
7480
await ctx.message.delete()
7581

76-
await channel.send("The !close command is intended to be used inside a thread/post",
77-
suppress_embeds=True,
78-
delete_after=5)
79-
82+
await channel.send(
83+
"The !close command is intended to be used inside a thread/post",
84+
suppress_embeds=True,
85+
delete_after=5,
86+
)
8087

8188

8289
@bot.command()
@@ -94,7 +101,10 @@ async def qlen(ctx):
94101

95102

96103
def get_messages():
97-
messages = DiscordMessage.objects.filter(sent_at__isnull=True)
104+
messages = DiscordMessage.objects.filter(
105+
Q(send_after__isnull=True) | Q(send_after__lte=timezone.now()),
106+
sent_at__isnull=True,
107+
)
98108
return messages
99109

100110

intbot/core/models.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ class DiscordMessage(models.Model):
4444
created_at = models.DateTimeField(auto_now_add=True)
4545
modified_at = models.DateTimeField(auto_now=True)
4646

47-
# Messages to be have null here
47+
# To delay messages to be sent after certain timestmap in the future
48+
send_after = models.DateTimeField(blank=True, null=True)
49+
50+
# Messages to be sent have null here
4851
sent_at = models.DateTimeField(blank=True, null=True)
4952

5053
def __str__(self):

intbot/tests/test_bot/test_main.py

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1+
import contextlib
2+
from datetime import timedelta
13
from unittest import mock
24
from unittest.mock import AsyncMock, patch
3-
import contextlib
4-
import discord
5-
6-
from django.db import connections
75

6+
import discord
87
import pytest
98
from asgiref.sync import sync_to_async
10-
from core.bot.main import ping, poll_database, qlen, source, version, wiki, close
9+
from core.bot.main import close, ping, poll_database, qlen, source, version, wiki
1110
from core.models import DiscordMessage
11+
from django.db import connections
1212
from django.utils import timezone
1313

1414
# NOTE(artcz)
@@ -101,6 +101,7 @@ async def test_wiki_command():
101101
suppress_embeds=True,
102102
)
103103

104+
104105
@pytest.mark.asyncio
105106
async def test_close_command_working():
106107
# Mock context
@@ -118,6 +119,7 @@ async def test_close_command_working():
118119
suppress_embeds=True,
119120
)
120121

122+
121123
@pytest.mark.asyncio
122124
async def test_close_command_notworking():
123125
# Mock context
@@ -131,7 +133,7 @@ async def test_close_command_notworking():
131133
ctx.channel.send.assert_called_once_with(
132134
"The !close command is intended to be used inside a thread/post",
133135
suppress_embeds=True,
134-
delete_after=5
136+
delete_after=5,
135137
)
136138

137139

@@ -235,12 +237,40 @@ async def test_polling_messages_sends_nothing_if_all_messages_are_sent():
235237

236238
@pytest.mark.asyncio
237239
@pytest.mark.django_db
238-
async def test_polling_messages_sends_message_if_not_sent_and_sets_sent_at():
240+
async def test_polling_messages_sends_nothing_if_all_messages_in_the_future():
241+
mock_channel = AsyncMock()
242+
mock_channel.send = AsyncMock()
243+
await DiscordMessage.objects.acreate(
244+
send_after=timezone.now() + timedelta(hours=3),
245+
sent_at=None,
246+
)
247+
248+
with patch("core.bot.main.bot.get_channel", return_value=mock_channel):
249+
await poll_database()
250+
251+
mock_channel.send.assert_not_called()
252+
253+
254+
@pytest.mark.asyncio
255+
@pytest.mark.django_db
256+
@pytest.mark.parametrize(
257+
"send_after",
258+
[
259+
None,
260+
timezone.now(),
261+
],
262+
ids=[
263+
"send_after_isnull",
264+
"send_after_is_in_the_past",
265+
],
266+
)
267+
async def test_polling_messages_sends_message_if_not_sent_and_sets_sent_at(send_after):
239268
start = timezone.now()
240269
dm = await DiscordMessage.objects.acreate(
241270
channel_id="1234",
242271
content="asdf",
243272
sent_at=None,
273+
send_after=send_after,
244274
)
245275
mock_channel = AsyncMock()
246276
mock_channel.send = AsyncMock()

0 commit comments

Comments
 (0)