Skip to content
This repository was archived by the owner on Oct 2, 2023. It is now read-only.

Commit ab4803d

Browse files
authored
Merge branch 'develop' into feature/color-picker
2 parents c645406 + 4fc429e commit ab4803d

File tree

35 files changed

+298
-121
lines changed

35 files changed

+298
-121
lines changed

administration/roles/cog.py

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
from typing import Optional, Union, Dict, List
22

3-
from discord import Role, Embed, Member, Status, Guild, NotFound, User, Forbidden
3+
from discord import Role, Embed, Member, Status, Guild, NotFound, User, Forbidden, Permissions
44
from discord.ext import commands
55
from discord.ext.commands import CommandError, Context, guild_only, UserInputError, Group
66

77
from PyDrocsid.cog import Cog
88
from PyDrocsid.command import reply, docs, optional_permissions
9-
from PyDrocsid.config import Contributor, Config
9+
from PyDrocsid.config import Config
1010
from PyDrocsid.converter import UserMemberConverter
1111
from PyDrocsid.database import db, select, filter_by
1212
from PyDrocsid.embeds import send_long_embed
@@ -18,6 +18,7 @@
1818
from .colors import Colors
1919
from .models import RoleAuth, PermaRole
2020
from .permissions import RolesPermission
21+
from ...contributor import Contributor
2122
from ...pubsub import send_to_changelog, send_alert
2223

2324
tg = t.g
@@ -90,7 +91,7 @@ async def inner(_, ctx: Context, *, role: Role):
9091

9192

9293
class RolesCog(Cog, name="Roles"):
93-
CONTRIBUTORS = [Contributor.Defelo]
94+
CONTRIBUTORS = [Contributor.Defelo, Contributor.NekoFanatic]
9495

9596
def __init__(self):
9697
super().__init__()
@@ -241,6 +242,42 @@ async def roles_add(self, ctx: Context, member: Member, *, role: Role):
241242
await member.add_roles(role)
242243
await ctx.message.add_reaction(name_to_emoji["white_check_mark"])
243244

245+
@roles.command(name="clone", aliases=["cl"])
246+
@RolesPermission.roles_clone.check
247+
@docs(t.commands.roles_clone)
248+
async def roles_clone(self, ctx: Context, *, role: Role):
249+
if not ctx.me.guild_permissions.manage_roles:
250+
raise CommandError(t.clone_no_permission)
251+
252+
cloned_permissions = role.permissions.value & ctx.me.guild_permissions.value
253+
254+
missing_permissions = "\n".join(
255+
f":small_blue_diamond: `{permission}`"
256+
for permission, value in Permissions(role.permissions.value & ~ctx.me.guild_permissions.value)
257+
if value
258+
)
259+
260+
await ctx.guild.create_role(
261+
name=role.name,
262+
color=role.color,
263+
permissions=Permissions(cloned_permissions),
264+
hoist=role.hoist,
265+
mentionable=role.mentionable,
266+
)
267+
268+
if missing_permissions:
269+
await send_long_embed(
270+
ctx,
271+
Embed(
272+
title=t.failed_to_clone_role_permissions,
273+
description=missing_permissions,
274+
color=Colors.MissingPermissions,
275+
),
276+
paginate=True,
277+
)
278+
279+
await ctx.message.add_reaction(name_to_emoji["white_check_mark"])
280+
244281
@roles.command(name="remove", aliases=["r", "del", "d", "-"])
245282
@optional_permissions(RolesPermission.auth_write)
246283
@docs(t.commands.roles_remove)
@@ -361,7 +398,7 @@ async def roles_list(self, ctx: Context, *, role: Role):
361398
out.append(f":grey_question: <@{member_id}> (@{member_name}) :shield:")
362399

363400
if out:
364-
embed = Embed(title=t.member_list_cnt(len(out)), colour=0x256BE6, description="\n".join(out))
401+
embed = Embed(title=t.member_list_cnt(role.name, cnt=len(out)), colour=0x256BE6, description="\n".join(out))
365402
else:
366403
embed = Embed(title=t.member_list, colour=0xCF0606, description=t.no_members)
367404
await send_long_embed(ctx, embed, paginate=True)

administration/roles/colors.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33

44
class Colors(MaterialColors):
55
Roles = MaterialColors.blue["a700"]
6+
MissingPermissions = MaterialColors.yellow["a700"]

administration/roles/permissions.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ def description(self) -> str:
1414
auth_read = auto()
1515
auth_write = auto()
1616
list_members = auto()
17+
roles_clone = auto()

administration/roles/translations/en.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ permissions:
44
auth_read: read role assignment permissions
55
auth_write: write role assignment permissions
66
list_members: list role members
7+
roles_clone: clones existing roles
78

89
commands:
910
roles: manage roles
@@ -12,6 +13,7 @@ commands:
1213
roles_auth_add: add a new role assignment authorization
1314
roles_auth_remove: remove a role assignment authorization
1415
roles_add: assign a role to a member
16+
roles_clone: clone an existing role
1517
roles_remove: remove a role from a member
1618
roles_perma_add: assign a role permanently to a member
1719
roles_perma_unset: remove the perma flag from a member role
@@ -38,7 +40,9 @@ role_auth_removed: Role assignment authorization has been removed successfully.
3840
log_role_auth_removed: Role assignment authorization `@{}` -> `@{}` has been removed.
3941
role_not_authorized: You are not allowed to manage this role.
4042
member_list: Member List
41-
member_list_cnt: Member List ({})
43+
member_list_cnt:
44+
one: "Member List of @{} ({cnt} Member)"
45+
many: "Member List of @{} ({cnt} Members)"
4246
member_list_line: ":small_orange_diamond: {} ({})"
4347
no_members: No member was found with this role.
4448
role_already_assigned: Role has already been assigned to this member.
@@ -50,3 +54,5 @@ perma_reassigned: Perma role {} has been reassigned to {} ({}). If you want to r
5054
no_perma_roles: No permanent role assignments.
5155
perma_roles: Permanent Role Assignments
5256
could_not_reassign: Could not reassign perma role {} to {} ({}).
57+
clone_no_permission: I cannot clone this role because I don't have `manage_roles` permission on this server.
58+
failed_to_clone_role_permissions: ":warning: Could not clone following permissions:"

administration/sudo/cog.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ async def sudo(self, ctx: Context, *, cmd: str):
5858
@commands.command()
5959
@SudoPermission.clear_cache.check
6060
async def clear_cache(self, ctx: Context):
61-
await redis.flushall()
61+
await redis.flushdb()
6262
await ctx.message.add_reaction(name_to_emoji["white_check_mark"])
6363

6464
@commands.command()

contributor.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ class Contributor(ContributorBase):
1111
Tristan = (277069925678317568, "MDQ6VXNlcjQ1MzMwNjY3")
1212
Tert0 = (621330363167539210, "MDQ6VXNlcjYyMDM2NDY0")
1313
MarcelCoding = (398895973490884608, "MDQ6VXNlcjM0ODE5NTI0")
14+
NekoFanatic = (544956941643022356, "MDQ6VXNlcjgzODgzODQ5")

general/news/cog.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ async def news_send(
143143

144144
content = ""
145145
send_embed = Embed(title=t.news, description=message, colour=Colors.News)
146-
send_embed.set_footer(text=t.sent_by(ctx.author, ctx.author.id), icon_url=ctx.author.avatar_url)
146+
send_embed.set_footer(text=t.sent_by(ctx.author, ctx.author.id), icon_url=ctx.author.display_avatar.url)
147147

148148
if authorization.notification_role_id is not None:
149149
role: Optional[Role] = ctx.guild.get_role(authorization.notification_role_id)

general/polls/cog.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import re
22
import string
3-
from datetime import datetime
43
from typing import Optional, Tuple
54

65
from discord import Embed, Message, PartialEmoji, Member, Forbidden, Guild
76
from discord.ext import commands
87
from discord.ext.commands import Context, guild_only, CommandError
8+
from discord.utils import utcnow
99

1010
from PyDrocsid.cog import Cog
1111
from PyDrocsid.embeds import EmbedLimits
@@ -53,10 +53,10 @@ async def send_poll(
5353
if any(len(str(option)) > EmbedLimits.FIELD_VALUE for option in options):
5454
raise CommandError(t.option_too_long(EmbedLimits.FIELD_VALUE))
5555

56-
embed = Embed(title=title, description=question, color=Colors.Polls, timestamp=datetime.utcnow())
57-
embed.set_author(name=str(ctx.author), icon_url=ctx.author.avatar_url)
56+
embed = Embed(title=title, description=question, color=Colors.Polls, timestamp=utcnow())
57+
embed.set_author(name=str(ctx.author), icon_url=ctx.author.display_avatar.url)
5858
if allow_delete:
59-
embed.set_footer(text=t.created_by(ctx.author, ctx.author.id), icon_url=ctx.author.avatar_url)
59+
embed.set_footer(text=t.created_by(ctx.author, ctx.author.id), icon_url=ctx.author.display_avatar.url)
6060

6161
if len(set(map(lambda x: x.emoji, options))) < len(options):
6262
raise CommandError(t.option_duplicated)
@@ -216,8 +216,8 @@ async def team_yesno(self, ctx: Context, *, text: str):
216216
Starts a yes/no poll and shows, which teamler has not voted yet.
217217
"""
218218

219-
embed = Embed(title=t.team_poll, description=text, color=Colors.Polls, timestamp=datetime.utcnow())
220-
embed.set_author(name=str(ctx.author), icon_url=ctx.author.avatar_url)
219+
embed = Embed(title=t.team_poll, description=text, color=Colors.Polls, timestamp=utcnow())
220+
embed.set_author(name=str(ctx.author), icon_url=ctx.author.display_avatar.url)
221221

222222
embed.add_field(name=tg.status, value=await self.get_reacted_teamlers(), inline=False)
223223

general/utils/cog.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ async def encode(self, ctx: Context, *, user: UserMemberConverter):
7474
user: Union[User, Member]
7575

7676
embed = Embed(color=Colors.Utils)
77-
embed.set_author(name=str(user), icon_url=user.avatar_url)
77+
embed.set_author(name=str(user), icon_url=user.display_avatar.url)
7878
embed.add_field(name=t.username, value=str(user.name.encode())[2:-1], inline=False)
7979
if isinstance(user, Member) and user.nick:
8080
embed.add_field(name=t.nickname, value=str(user.nick.encode())[2:-1], inline=False)

general/voice_channel/cog.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import asyncio
22
import random
3-
from datetime import datetime
43
from os import getenv
54
from pathlib import Path
65
from typing import Optional, Union
@@ -25,6 +24,7 @@
2524
from discord.abc import Messageable
2625
from discord.ext import commands, tasks
2726
from discord.ext.commands import guild_only, Context, UserInputError, CommandError, Greedy
27+
from discord.utils import utcnow
2828

2929
from PyDrocsid.async_thread import gather_any, GatherAnyException
3030
from PyDrocsid.cog import Cog
@@ -213,7 +213,7 @@ def prepare(self) -> bool:
213213
return bool(self.names)
214214

215215
def _get_name_list(self, guild_id: int) -> str:
216-
r = random.Random(f"{guild_id}{datetime.utcnow().date().isoformat()}")
216+
r = random.Random(f"{guild_id}{utcnow().date().isoformat()}")
217217
return r.choice(sorted(self.names))
218218

219219
def _random_channel_name(self, guild_id: int, avoid: set[str]) -> Optional[str]:
@@ -277,7 +277,7 @@ async def send_voice_msg(self, channel: DynChannel, title: str, msg: str, force_
277277
text_channel,
278278
title,
279279
"",
280-
datetime.utcnow().strftime("%d.%m.%Y %H:%M:%S"),
280+
utcnow().strftime("%d.%m.%Y %H:%M:%S"),
281281
msg,
282282
colour=color,
283283
force_new_embed=force_new_embed,

0 commit comments

Comments
 (0)