Skip to content

Commit 0ece32e

Browse files
committed
Squashed commit of the following:
commit b047d0c Author: skillor <[email protected]> Date: Fri Mar 18 18:15:52 2022 +0100 feat: add example module commit 73b4030 Author: skillor <[email protected]> Date: Fri Mar 18 18:15:35 2022 +0100 feat: paging for reactions commit 5d90370 Author: skillor <[email protected]> Date: Fri Mar 18 16:17:07 2022 +0100 feat: add blacklisted command
1 parent e9964bb commit 0ece32e

File tree

8 files changed

+184
-42
lines changed

8 files changed

+184
-42
lines changed

helpers/db.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,11 @@ def get_level_users(self, guild_id) -> List[LevelUser]:
179179
stmt = db.select(LevelUser).where(LevelUser.guild_id == guild_id)
180180
return session.scalars(stmt).all()
181181

182+
def get_blacklisted_level_users(self, guild_id, blacklisted) -> List[LevelUser]:
183+
session = self.Session()
184+
stmt = db.select(LevelUser).where(db.and_(LevelUser.guild_id == guild_id, LevelUser.blacklisted == blacklisted))
185+
return session.scalars(stmt).all()
186+
182187
def get_level_user_xp_boosts(self, guild_id, user_id, current_time=-1) -> List[XPBoost]:
183188
session = self.Session()
184189
stmt = db.select(XPBoost).where(db.and_(XPBoost.guild_id == guild_id, XPBoost.user_id == user_id,

helpers/view_helpers.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
from typing import *
2+
3+
import discord.ui
4+
5+
6+
class CustomButton(discord.ui.Button):
7+
def __init__(self,
8+
callback: Callable[['CustomButton', discord.Interaction], Coroutine] = None,
9+
data=None,
10+
*args, **kwargs):
11+
super().__init__(*args, **kwargs)
12+
self.data = data
13+
self.custom_callback = callback
14+
15+
async def callback(self, interaction: discord.Interaction):
16+
if self.custom_callback:
17+
await self.custom_callback(self, interaction)
18+
19+
20+
class ViewPaginator:
21+
def __init__(self,
22+
pages: List[discord.ui.View] = None,
23+
hide_empty=False
24+
):
25+
if pages is None:
26+
pages = []
27+
self.pages = pages
28+
self.hide_empty = hide_empty
29+
self.current_page = 0
30+
self.prev_page_label = '️'
31+
self.prev_page_emoji = '⬅'
32+
self.prev_page_style = discord.ButtonStyle.secondary
33+
self.current_page_label = '{}/{}'
34+
self.current_page_style = discord.ButtonStyle.secondary
35+
self.next_page_label = ''
36+
self.next_page_emoji = '➡'
37+
self.next_page_style = discord.ButtonStyle.secondary
38+
39+
def view(self):
40+
view = discord.ui.View()
41+
for child in self.pages[self.current_page].children:
42+
view.add_item(child)
43+
44+
if len(self.pages) > 1 or not self.hide_empty:
45+
async def cb(button, interaction: discord.Interaction):
46+
self.current_page += button.data
47+
await interaction.response.edit_message(view=self.view())
48+
49+
view.add_item(CustomButton(cb,
50+
data=-1,
51+
row=4,
52+
label=self.prev_page_label,
53+
emoji=self.prev_page_emoji,
54+
style=self.prev_page_style,
55+
disabled=self.current_page == 0))
56+
view.add_item(CustomButton(row=4,
57+
label=self.current_page_label.format(self.current_page + 1, len(self.pages)),
58+
style=self.current_page_style,
59+
disabled=True))
60+
view.add_item(CustomButton(cb,
61+
data=1,
62+
row=4,
63+
label=self.next_page_label,
64+
emoji=self.next_page_emoji,
65+
style=self.next_page_style,
66+
disabled=self.current_page == len(self.pages) - 1))
67+
return view

i18n.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@
6363
"LEVELSYSTEM_BLACKLIST_MEMBER_OPTION": "member to black- or whitelist",
6464
"LEVELSYSTEM_BLACKLIST_BLACKLIST_OPTION": "if user should be blacklisted",
6565
"LEVELSYSTEM_BLACKLIST_SUCCESSFUL": "User was blacklisted",
66+
"LEVELSYSTEM_BLACKLISTED_COMMAND": "blacklisted",
67+
"LEVELSYSTEM_BLACKLISTED_COMMAND_DESCRIPTION": "get blacklisted users",
68+
"LEVELSYSTEM_BLACKLISTED_TITLE": "Blacklisted",
6669
"LEVELSYSTEM_BLACKLIST_REMOVE_SUCCESSFUL": "User was removed from the blacklist",
6770
"LEVELSYSTEM_REMOVE_COMMAND": "remove",
6871
"LEVELSYSTEM_REMOVE_COMMAND_DESCRIPTION": "remove levelsystem by level",
@@ -136,7 +139,7 @@
136139
"EMOJI_REACTIONS_TITLE": "Emoji Reactions",
137140
"EMOJI_REACTIONS_CHOOSE_EMOJI_TITLE": "Choose emoji for reaction action",
138141
"EMOJI_REACTIONS_CHOOSE_EMOJI_PLACEHOLDER": "Choose the emoji...",
139-
"EMOJI_REACTIONS_CUSTOM_EMOJI": "©",
142+
"EMOJI_REACTIONS_CUSTOM_EMOJI": "🎇",
140143
"EMOJI_REACTIONS_CUSTOM_EMOJI_LABEL": "Custom emoji",
141144
"EMOJI_REACTIONS_CUSTOM_EMOJI_MESSAGE": "React to this message with your wanted emoji!",
142145
"EMOJI_REACTIONS_ACTION_TYPE_PLACEHOLDER": "Choose your wanted action type...",

modules/_example/__init__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from helpers.spark_module import SparkModule
2+
from .settings import SETTINGS
3+
from .web import API_PAGES
4+
5+
6+
class ExampleModule(SparkModule):
7+
name = 'example'
8+
title = 'Example Module'
9+
description = 'A module used as an example'
10+
api_pages = API_PAGES
11+
settings = SETTINGS
12+
13+
def __init__(self, bot):
14+
super().__init__(bot)
15+
16+
self.commands = []

modules/_example/settings.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from helpers.settings_manager import Setting
2+
3+
SETTINGS = {
4+
'EXAMPLE_SETTING': Setting(
5+
value=False,
6+
description='An example setting',
7+
itype='bool'
8+
),
9+
}

modules/_example/web.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import discord
2+
from flask import jsonify
3+
4+
from webserver import Page
5+
6+
from typing import TYPE_CHECKING
7+
8+
if TYPE_CHECKING:
9+
from . import ExampleModule
10+
11+
12+
async def example_func(module: 'ExampleModule',
13+
guild: discord.Guild,
14+
member: discord.Member):
15+
return jsonify({'msg': 'success'}), 200
16+
17+
18+
API_PAGES = [
19+
Page(path='example', view_func=example_func, methods=['POST']),
20+
]

modules/emoji_reactions/__init__.py

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
import math
23
from typing import *
34

45
import discord
@@ -8,6 +9,7 @@
89

910
from helpers import tools
1011
from helpers.spark_module import SparkModule
12+
from helpers.view_helpers import ViewPaginator, CustomButton
1113
from .settings import SETTINGS
1214

1315

@@ -65,16 +67,7 @@ def __init__(self, bot):
6567
@bot.has_permissions(administrator=True)
6668
async def add_emoji_action(ctx: discord.commands.context.ApplicationContext,
6769
message: discord.Message):
68-
async def response(dropdown1: CustomDropdown, interaction1: discord.Interaction):
69-
if dropdown1.values[0] != self.CUSTOM_EMOJI:
70-
emoji = get(ctx.guild.emojis, id=int(dropdown1.values[0]))
71-
if not emoji:
72-
return await ctx.edit(embed=discord.Embed(
73-
description=self.bot.i18n.get('UNKNOWN_ERROR'),
74-
color=discord.Color.red()))
75-
await self.add_emoji_reaction_action(ctx.guild, ctx, message, emoji)
76-
return
77-
70+
async def custom_emoji_response(button: CustomButton, interaction1: discord.Interaction):
7871
m = await ctx.send(embed=discord.Embed(
7972
description=self.bot.i18n.get('EMOJI_REACTIONS_CUSTOM_EMOJI_MESSAGE'),
8073
color=discord.Color.blue()))
@@ -84,33 +77,36 @@ async def response(dropdown1: CustomDropdown, interaction1: discord.Interaction)
8477

8578
self.activating_reactions[(m.channel.id, m.id)] = (ctx.author.id, ctx, message)
8679

87-
if len(ctx.guild.emojis) < 24:
88-
options = [discord.SelectOption(label=bot.i18n.get('EMOJI_REACTIONS_CUSTOM_EMOJI_LABEL'),
89-
emoji=bot.i18n.get('EMOJI_REACTIONS_CUSTOM_EMOJI'),
90-
value=self.CUSTOM_EMOJI)] + [
91-
discord.SelectOption(label=str(emoji.name),
92-
emoji=str(emoji),
93-
value=str(emoji.id)) for emoji in ctx.guild.emojis
94-
]
95-
80+
async def response(dropdown1: CustomDropdown, interaction1: discord.Interaction):
81+
emoji = get(ctx.guild.emojis, id=int(dropdown1.values[0]))
82+
if not emoji:
83+
return await ctx.edit(embed=discord.Embed(
84+
description=self.bot.i18n.get('UNKNOWN_ERROR'),
85+
color=discord.Color.red()))
86+
await self.add_emoji_reaction_action(ctx.guild, ctx, message, emoji)
87+
88+
options = [
89+
discord.SelectOption(label=str(emoji.name),
90+
emoji=str(emoji),
91+
value=str(emoji.id)) for emoji in ctx.guild.emojis
92+
]
93+
94+
pages = []
95+
for i in range(math.ceil(len(options) / 25)):
9696
view = discord.ui.View()
9797
view.add_item(
98-
CustomDropdown(response, bot.i18n.get('EMOJI_REACTIONS_CHOOSE_EMOJI_PLACEHOLDER'), options))
99-
100-
return await ctx.respond(
101-
embed=discord.Embed(title=self.bot.i18n.get('EMOJI_REACTIONS_CHOOSE_EMOJI_TITLE')),
102-
view=view,
103-
ephemeral=True)
104-
105-
else:
106-
m = await ctx.send(embed=discord.Embed(
107-
description=self.bot.i18n.get('EMOJI_REACTIONS_CUSTOM_EMOJI_MESSAGE'),
108-
color=discord.Color.blue()))
98+
CustomButton(custom_emoji_response,
99+
label=bot.i18n.get('EMOJI_REACTIONS_CUSTOM_EMOJI_LABEL'),
100+
emoji=bot.i18n.get('EMOJI_REACTIONS_CUSTOM_EMOJI')))
101+
view.add_item(
102+
CustomDropdown(response,
103+
bot.i18n.get('EMOJI_REACTIONS_CHOOSE_EMOJI_PLACEHOLDER'),
104+
options[i*25:(i+1)*25]))
105+
pages.append(view)
109106

110-
await ctx.respond(embed=discord.Embed(title=self.bot.i18n.get('EMOJI_REACTIONS_REACT_TO'),
111-
description=m.jump_url), ephemeral=True)
107+
paginator = ViewPaginator(pages, hide_empty=True)
112108

113-
self.activating_reactions[(m.channel.id, m.id)] = (ctx.author.id, ctx, message)
109+
await ctx.respond(view=paginator.view(), ephemeral=True)
114110

115111
@bot.has_permissions(administrator=True)
116112
async def get_emoji_reactions(ctx: discord.commands.context.ApplicationContext):
@@ -271,13 +267,21 @@ async def response2(dropdown2: CustomDropdown, interaction2: discord.Interaction
271267
role_name = role.name
272268
options.append(discord.SelectOption(label=role_name, emoji=role_emoji, value=str(role.id)))
273269

274-
view = discord.ui.View()
275-
view.add_item(CustomDropdown(response2,
276-
self.bot.i18n.get('EMOJI_REACTIONS_CHOOSE_ROLE_PLACEHOLDER'),
277-
options))
270+
pages = []
271+
for i in range(math.ceil(len(options) / 25)):
272+
view = discord.ui.View()
273+
274+
view.add_item(
275+
CustomDropdown(response2,
276+
self.bot.i18n.get('EMOJI_REACTIONS_CHOOSE_ROLE_PLACEHOLDER'),
277+
options[i * 25:(i + 1) * 25]))
278+
pages.append(view)
279+
280+
paginator = ViewPaginator(pages, hide_empty=True)
281+
278282
await ctx.edit(embed=discord.Embed(title=self.bot.i18n.get('EMOJI_REACTIONS_CHOOSE_ROLE_TITLE')
279283
.format(str(emoji), self.bot.i18n.get(self.reaction_types[v]))),
280-
view=view)
284+
view=paginator.view())
281285

282286
else:
283287
await ctx.edit(
@@ -349,6 +353,6 @@ async def on_raw_reaction_remove(self, payload: discord.RawReactionActionEvent):
349353
for action in actions:
350354
try:
351355
if action.action_type == self.TRIGGER_ROLE:
352-
await tools.remove_role(payload.member.guild, payload.member, int(action.action))
353-
except:
354-
pass
356+
await tools.remove_role(member.guild, member, int(action.action))
357+
except Exception as e:
358+
self.bot.logger.warning('{} for user {} in {}'.format(e, member, member.guild))

modules/levelsystem/__init__.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,18 @@ async def blacklist_user(ctx: discord.commands.context.ApplicationContext,
143143
description=self.bot.i18n.get('LEVELSYSTEM_BLACKLIST_REMOVE_SUCCESSFUL'),
144144
color=discord.Color.green()))
145145

146+
@bot.has_permissions(administrator=True)
147+
async def blacklisted_users(ctx: discord.commands.context.ApplicationContext):
148+
description = []
149+
for user in self.bot.db.get_blacklisted_level_users(ctx.guild.id, True):
150+
member = get(ctx.guild.members, id=int(user.user_id))
151+
if member is not None:
152+
description.append(str(member))
153+
return await ctx.respond(embed=discord.Embed(
154+
title=self.bot.i18n.get('LEVELSYSTEM_BLACKLISTED_TITLE'),
155+
description='\n'.join(description),
156+
color=discord.Color.green()))
157+
146158
async def profile(ctx: discord.commands.context.ApplicationContext,
147159
member: discord.commands.Option(
148160
discord.Member,
@@ -204,6 +216,12 @@ async def leaderboard(ctx: discord.commands.context.ApplicationContext):
204216
description=self.bot.i18n.get('LEVELSYSTEM_BLACKLIST_COMMAND_DESCRIPTION'),
205217
parent=levelsystem
206218
))
219+
levelsystem.subcommands.append(discord.SlashCommand(
220+
func=blacklisted_users,
221+
name=self.bot.i18n.get('LEVELSYSTEM_BLACKLISTED_COMMAND'),
222+
description=self.bot.i18n.get('LEVELSYSTEM_BLACKLISTED_COMMAND_DESCRIPTION'),
223+
parent=levelsystem
224+
))
207225
self.commands = [
208226
levelsystem,
209227
discord.SlashCommand(

0 commit comments

Comments
 (0)