Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Selftimeout #574

Merged
merged 20 commits into from
May 30, 2023
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cogs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ Containing timeout commands and manipulating with timeout.\
- /timeout user
- /timeout remove
- /timeout list
- /selftimeout
**Tasks:**

- refresh_timeout
Expand Down
44 changes: 35 additions & 9 deletions cogs/timeout.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import utils
from cogs.base import Base
from config import cooldowns
from config.app_config import config
from config.messages import Messages
from permissions import permission_check
Expand Down Expand Up @@ -89,7 +90,7 @@ async def timeout_embed_listing(self, users, title, room, author):
embeds.append(embed)
await room.send(embeds=embeds)

async def timeout_perms(self, inter, user, duration, endtime, reason) -> bool:
async def timeout_perms(self, inter, user, duration, endtime, reason, isself=False) -> bool:
"""Set timeout for user or remove it and save in db"""
try:
await user.timeout(duration=duration, reason=reason)
Expand All @@ -98,15 +99,16 @@ async def timeout_perms(self, inter, user, duration, endtime, reason) -> bool:
else:
# convert to local time and remove timezone info
starttime = inter.created_at.astimezone(tz=utils.get_local_zone()).replace(tzinfo=None)
self.timeout_repo.add_timeout(user.id, inter.author.id, starttime, endtime, reason)
self.timeout_repo.add_timeout(user.id, inter.author.id, starttime, endtime, reason, isself)
return False
except disnake.Forbidden:
self.perms_users.append(user)
return True

async def timeout_parse(self, inter, user, endtime, reason):
async def timeout_parse(self, inter, user, endtime, reason, isself=False):
"""
Parse time argument to timedelta(length) or datetime object
Parse time argument to timedelta(length) or datetime object and
gives user timeout and adds it to db

Decision tree
-------------
Expand All @@ -127,13 +129,13 @@ async def timeout_parse(self, inter, user, endtime, reason):
now = inter.created_at.astimezone(tz=utils.get_local_zone()).replace(tzinfo=None)
if "forever" == endtime.lower():
endtime = now.replace(year=now.year+1000)
if await self.timeout_perms(inter, user, timedelta(days=28), endtime, reason):
if await self.timeout_perms(inter, user, timedelta(days=28), endtime, reason, isself):
return

elif endtime in timestamps:
timeout_duration = timedelta(hours=float(timestamps[endtime]))
endtime = now + timeout_duration
if await self.timeout_perms(inter, user, timeout_duration, endtime, reason):
if await self.timeout_perms(inter, user, timeout_duration, endtime, reason, isself):
return

else:
Expand Down Expand Up @@ -173,10 +175,10 @@ async def timeout_parse(self, inter, user, endtime, reason):

# maximum length for timeout is 28 days set by discord
if timeout_duration.days > 28:
if await self.timeout_perms(inter, user, timedelta(days=28), endtime, reason):
if await self.timeout_perms(inter, user, timedelta(days=28), endtime, reason, isself):
return
else:
if await self.timeout_perms(inter, user, timeout_duration, endtime, reason):
if await self.timeout_perms(inter, user, timeout_duration, endtime, reason, isself):
return
return endtime

Expand Down Expand Up @@ -275,11 +277,12 @@ async def remove_timeout(
async def timeout_list(
self,
inter: disnake.ApplicationCommandInteraction,
selftimeout: bool = commands.Param(default=False)
):
"""List all timed out users"""
await self.update_timeout()

users = self.timeout_repo.get_timeout_users()
users = self.timeout_repo.get_timeout_users_filter_self(selftimeout)
if not users:
await inter.send(Messages.timeout_list_none)
return
Expand Down Expand Up @@ -341,6 +344,29 @@ async def on_audit_log_entry_create(self, entry):

await self.submod_helper_room.send(embed=embed)

@cooldowns.default_cooldown
@commands.slash_command(
name="selftimeout",
description=Messages.self_timeout,
guild_ids=[config.guild_id]
)
async def self_timeout(
self,
inter: disnake.ApplicationCommandInteraction,
endtime: str = commands.Param(
autocomplete=autocomplete_times,
max_length=20, description=Messages.timeout_time
)
):
# Guild_id is used to prevent users from bypassing timeout
# given by moderator and using selftimeout in DMs

await inter.response.defer(ephemeral=True)

await self.timeout_parse(inter, inter.user, endtime, Messages.self_timeout_reason, True)
await inter.send(content=Messages.self_timeout_success)

@self_timeout.error
@timeout_user.error
async def timeout_error(self, inter: disnake.ApplicationCommandInteraction, error):
if isinstance(error, commands.BadArgument):
Expand Down
3 changes: 3 additions & 0 deletions config/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,9 @@ class Messages:
timeout_user_brief = "Použij tag uživatele/uživatelů"
timeout_list_none = "Nenalezeny žádné umlčení."
timeout_member_not_found = "{member} Nikoho takového jsem na serveru nenašel. Ujisti se, že jsi uživatele zadal @tagem."
self_timeout = "Dočasně si zakážeš interakce na serveru"
self_timeout_reason = "Sebeumlčení"
self_timeout_success = "Sebeumlčení proběhlo úspěšně"

# TIMEOUT WARS
timeout_wars_user = "Uživatel {user} byl umlčen na {time:.0f} minut."
Expand Down
3 changes: 2 additions & 1 deletion repository/database/timeout.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from sqlalchemy import BigInteger, Column, DateTime, Interval, String
from sqlalchemy import BigInteger, Boolean, Column, DateTime, Interval, String

from repository.database import database

Expand All @@ -12,3 +12,4 @@ class Timeout(database.base):
end = Column(DateTime)
length = Column(Interval)
reason = Column(String)
isself = Column(Boolean)
19 changes: 16 additions & 3 deletions repository/timeout_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,23 @@ def __init__(self):
def get_timeout_users(self) -> List[Timeout]:
return session.query(Timeout).all()

def get_timeout_users_filter_self(self, isself: bool = False) -> List[Timeout]:
return session.query(Timeout).filter(Timeout.isself == isself).all()

def get_timeout_user(self, user_id: int):
return session.query(Timeout).get(user_id)

def add_timeout(self, user_id: int, mod_id: int, start: datetime, end: datetime, reason: str):
def add_timeout(
self,
user_id: int,
mod_id: int,
start: datetime,
end: datetime,
reason: str,
isself: bool = False
):
"""
Add the user and their timeout to the database.
Add the user and their timeout/selftimeout to the database.
Save all datetimes in the database without timezone information.
"""
exists = self.get_timeout_user(user_id)
Expand All @@ -28,6 +39,7 @@ def add_timeout(self, user_id: int, mod_id: int, start: datetime, end: datetime,
exists.end = end
exists.length = end - start
exists.reason = reason
exists.isself = isself
session.commit()
return
try:
Expand All @@ -37,7 +49,8 @@ def add_timeout(self, user_id: int, mod_id: int, start: datetime, end: datetime,
start=start,
end=end,
length=end-start,
reason=reason
reason=reason,
isself=isself
)
session.add(timeout)
session.commit()
Expand Down