Skip to content

Commit c6b4f53

Browse files
committed
Fix block logic and rewrite into helper function
1 parent ba4d6fb commit c6b4f53

File tree

5 files changed

+78
-80
lines changed

5 files changed

+78
-80
lines changed

bot.py

+13-28
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
)
4848
from core.thread import ThreadManager
4949
from core.time import human_timedelta
50-
from core.utils import normalize_alias, parse_alias, truncate, tryint
50+
from core.utils import extract_block_timestamp, normalize_alias, parse_alias, truncate, tryint
5151

5252
logger = getLogger(__name__)
5353

@@ -735,21 +735,13 @@ def check_manual_blocked_roles(self, author: discord.Member) -> bool:
735735
if str(r.id) in self.blocked_roles:
736736

737737
blocked_reason = self.blocked_roles.get(str(r.id)) or ""
738-
now = discord.utils.utcnow()
739-
740-
# etc "blah blah blah... until 2019-10-14T21:12:45.559948."
741-
end_time = re.search(r"until ([^`]+?)\.$", blocked_reason)
742-
if end_time is None:
743-
# backwards compat
744-
end_time = re.search(r"%([^%]+?)%", blocked_reason)
745-
if end_time is not None:
746-
logger.warning(
747-
r"Deprecated time message for role %s, block and unblock again to update.",
748-
r.name,
749-
)
738+
739+
try:
740+
end_time, after = extract_block_timestamp(blocked_reason, author.id)
741+
except ValueError:
742+
return False
750743

751744
if end_time is not None:
752-
after = (datetime.fromisoformat(end_time.group(1)) - now).total_seconds()
753745
if after <= 0:
754746
# No longer blocked
755747
self.blocked_roles.pop(str(r.id))
@@ -765,26 +757,19 @@ def check_manual_blocked(self, author: discord.Member) -> bool:
765757
return True
766758

767759
blocked_reason = self.blocked_users.get(str(author.id)) or ""
768-
now = discord.utils.utcnow()
769760

770761
if blocked_reason.startswith("System Message:"):
771762
# Met the limits already, otherwise it would've been caught by the previous checks
772763
logger.debug("No longer internally blocked, user %s.", author.name)
773764
self.blocked_users.pop(str(author.id))
774765
return True
775-
# etc "blah blah blah... until 2019-10-14T21:12:45.559948."
776-
end_time = re.search(r"until ([^`]+?)\.$", blocked_reason)
777-
if end_time is None:
778-
# backwards compat
779-
end_time = re.search(r"%([^%]+?)%", blocked_reason)
780-
if end_time is not None:
781-
logger.warning(
782-
r"Deprecated time message for user %s, block and unblock again to update.",
783-
author.name,
784-
)
766+
767+
try:
768+
end_time, after = extract_block_timestamp(blocked_reason, author.id)
769+
except ValueError:
770+
return False
785771

786772
if end_time is not None:
787-
after = (datetime.fromisoformat(end_time.group(1)) - now).total_seconds()
788773
if after <= 0:
789774
# No longer blocked
790775
self.blocked_users.pop(str(author.id))
@@ -891,7 +876,7 @@ async def add_reaction(
891876
if reaction != "disable":
892877
try:
893878
await msg.add_reaction(reaction)
894-
except (discord.HTTPException, discord.InvalidArgument) as e:
879+
except (discord.HTTPException, discord.BadArgument) as e:
895880
logger.warning("Failed to add reaction %s: %s.", reaction, e)
896881
return False
897882
return True
@@ -1316,7 +1301,7 @@ async def handle_reaction_events(self, payload):
13161301
for msg in linked_messages:
13171302
await msg.remove_reaction(reaction, self.user)
13181303
await message.remove_reaction(reaction, self.user)
1319-
except (discord.HTTPException, discord.InvalidArgument) as e:
1304+
except (discord.HTTPException, discord.BadArgument) as e:
13201305
logger.warning("Failed to remove reaction: %s", e)
13211306

13221307
async def handle_react_to_contact(self, payload):

cogs/modmail.py

+8-49
Original file line numberDiff line numberDiff line change
@@ -1654,46 +1654,10 @@ async def blocked(self, ctx):
16541654
blocked_users = list(self.bot.blocked_users.items())
16551655
for id_, reason in blocked_users:
16561656
# parse "reason" and check if block is expired
1657-
# etc "blah blah blah... until <t:XX:f>."
1658-
end_time = re.search(r"until <t:(\d+):(?:R|f)>.$", reason)
1659-
attempts = [
1660-
# backwards compat
1661-
re.search(r"until ([^`]+?)\.$", reason),
1662-
re.search(r"%([^%]+?)%", reason),
1663-
]
1664-
if end_time is None:
1665-
for i in attempts:
1666-
if i is not None:
1667-
end_time = i
1668-
break
1669-
1670-
if end_time is not None:
1671-
# found a deprecated version
1672-
try:
1673-
after = (
1674-
datetime.fromisoformat(end_time.group(1)).replace(tzinfo=timezone.utc) - now
1675-
).total_seconds()
1676-
except ValueError:
1677-
logger.warning(
1678-
r"Broken block message for user %s, block and unblock again with a different message to prevent further issues",
1679-
id_,
1680-
)
1681-
continue
1682-
logger.warning(
1683-
r"Deprecated time message for user %s, block and unblock again to update.",
1684-
id_,
1685-
)
1686-
else:
1687-
try:
1688-
after = (
1689-
datetime.fromtimestamp(int(end_time.group(1))).replace(tzinfo=timezone.utc) - now
1690-
).total_seconds()
1691-
except ValueError:
1692-
logger.warning(
1693-
r"Broken block message for user %s, block and unblock again with a different message to prevent further issues",
1694-
id_,
1695-
)
1696-
continue
1657+
try:
1658+
end_time, after = extract_block_timestamp(reason, id_)
1659+
except ValueError:
1660+
continue
16971661

16981662
if end_time is not None:
16991663
if after <= 0:
@@ -1713,15 +1677,10 @@ async def blocked(self, ctx):
17131677
for id_, reason in blocked_roles:
17141678
# parse "reason" and check if block is expired
17151679
# etc "blah blah blah... until 2019-10-14T21:12:45.559948."
1716-
end_time = re.search(r"until ([^`]+?)\.$", reason)
1717-
if end_time is None:
1718-
# backwards compat
1719-
end_time = re.search(r"%([^%]+?)%", reason)
1720-
if end_time is not None:
1721-
logger.warning(
1722-
r"Deprecated time message for role %s, block and unblock again to update.",
1723-
id_,
1724-
)
1680+
try:
1681+
end_time, after = extract_block_timestamp(reason, id_)
1682+
except ValueError:
1683+
continue
17251684

17261685
if end_time is not None:
17271686
after = (datetime.fromisoformat(end_time.group(1)) - now).total_seconds()

core/thread.py

-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
from core.time import human_timedelta
2323
from core.utils import (
2424
is_image_url,
25-
days,
2625
parse_channel_topic,
2726
match_title,
2827
match_user_id,

core/time.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def __init__(self, argument: str, *, now: Optional[datetime.datetime] = None):
6363
if match is None or not match.group(0):
6464
match = self.discord_fmt.fullmatch(argument)
6565
if match is not None:
66-
self.dt = datetime.datetime.fromtimestamp(int(match.group("ts")), tz=datetime.timezone.utc)
66+
self.dt = datetime.datetime.utcfromtimestamp(int(match.group("ts")), tz=datetime.timezone.utc)
6767
return
6868
else:
6969
raise commands.BadArgument("invalid time provided")
@@ -209,7 +209,7 @@ async def convert(self, ctx: Context, argument: str) -> FriendlyTimeResult:
209209
match = ShortTime.discord_fmt.match(argument)
210210
if match is not None:
211211
result = FriendlyTimeResult(
212-
datetime.datetime.fromtimestamp(int(match.group("ts")), now, tz=datetime.timezone.utc)
212+
datetime.datetime.utcfromtimestamp(int(match.group("ts")), now, tz=datetime.timezone.utc)
213213
)
214214
remaining = argument[match.end() :].strip()
215215
await result.ensure_constraints(ctx, self, now, remaining)

core/utils.py

+55
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import functools
33
import re
44
import typing
5+
from datetime import datetime, timezone
56
from difflib import get_close_matches
67
from distutils.util import strtobool as _stb # pylint: disable=import-error
78
from itertools import takewhile, zip_longest
@@ -10,6 +11,9 @@
1011
import discord
1112
from discord.ext import commands
1213

14+
from core.models import getLogger
15+
16+
1317
__all__ = [
1418
"strtobool",
1519
"User",
@@ -34,9 +38,13 @@
3438
"tryint",
3539
"get_top_role",
3640
"get_joint_id",
41+
"extract_block_timestamp",
3742
]
3843

3944

45+
logger = getLogger(__name__)
46+
47+
4048
def strtobool(val):
4149
if isinstance(val, bool):
4250
return val
@@ -504,3 +512,50 @@ def get_joint_id(message: discord.Message) -> typing.Optional[int]:
504512
except ValueError:
505513
pass
506514
return None
515+
516+
517+
def extract_block_timestamp(reason, id_):
518+
# etc "blah blah blah... until <t:XX:f>."
519+
now = discord.utils.utcnow()
520+
end_time = re.search(r"until <t:(\d+):(?:R|f)>.$", reason)
521+
attempts = [
522+
# backwards compat
523+
re.search(r"until ([^`]+?)\.$", reason),
524+
re.search(r"%([^%]+?)%", reason),
525+
]
526+
after = None
527+
if end_time is None:
528+
for i in attempts:
529+
if i is not None:
530+
end_time = i
531+
break
532+
533+
if end_time is not None:
534+
# found a deprecated version
535+
try:
536+
after = (
537+
datetime.fromisoformat(end_time.group(1)).replace(tzinfo=timezone.utc) - now
538+
).total_seconds()
539+
except ValueError:
540+
logger.warning(
541+
r"Broken block message for user %s, block and unblock again with a different message to prevent further issues",
542+
id_,
543+
)
544+
raise
545+
logger.warning(
546+
r"Deprecated time message for user %s, block and unblock again to update.",
547+
id_,
548+
)
549+
else:
550+
try:
551+
after = (
552+
datetime.utcfromtimestamp(int(end_time.group(1))).replace(tzinfo=timezone.utc) - now
553+
).total_seconds()
554+
except ValueError:
555+
logger.warning(
556+
r"Broken block message for user %s, block and unblock again with a different message to prevent further issues",
557+
id_,
558+
)
559+
raise
560+
561+
return end_time, after

0 commit comments

Comments
 (0)