NAFF 2.0 support

This commit is contained in:
Zeva Rose 2022-12-28 01:34:31 -07:00
parent 97d15f2f6b
commit 93a3cfb047
7 changed files with 108 additions and 153 deletions

View file

@ -2,7 +2,7 @@
from jarvis_core.db import q from jarvis_core.db import q
from jarvis_core.db.models import Action, Modlog, Note, Phishlist, Reminder, Star from jarvis_core.db.models import Action, Modlog, Note, Phishlist, Reminder, Star
from naff import listen from naff import listen
from naff.api.events.internal import Button from naff.api.events.internal import ButtonPressed
from naff.models.discord.embed import EmbedField from naff.models.discord.embed import EmbedField
from naff.models.discord.enums import Permissions from naff.models.discord.enums import Permissions
@ -10,7 +10,7 @@ from jarvis.utils import build_embed
class ComponentEventMixin: class ComponentEventMixin:
async def _handle_modcase_button(self, event: Button) -> None: async def _handle_modcase_button(self, event: ButtonPressed) -> None:
context = event.context context = event.context
if not context.custom_id.startswith("modcase|"): if not context.custom_id.startswith("modcase|"):
@ -33,17 +33,11 @@ class ComponentEventMixin:
): ):
name, parent = action_data.split("|")[:2] name, parent = action_data.split("|")[:2]
action = Action(action_type=name, parent=parent) action = Action(action_type=name, parent=parent)
note = Note( note = Note(admin=context.author.id, content="Moderation case opened via message")
admin=context.author.id, content="Moderation case opened via message" modlog = await Modlog.find_one(q(user=user.id, guild=context.guild.id, open=True))
)
modlog = await Modlog.find_one(
q(user=user.id, guild=context.guild.id, open=True)
)
if modlog: if modlog:
self.logger.debug("User already has active case in guild") self.logger.debug("User already has active case in guild")
await context.send( await context.send(f"User already has open case: {modlog.nanoid}", ephemeral=True)
f"User already has open case: {modlog.nanoid}", ephemeral=True
)
else: else:
modlog = Modlog( modlog = Modlog(
user=user.id, user=user.id,
@ -85,7 +79,7 @@ class ComponentEventMixin:
await self.redis.delete(user_key) await self.redis.delete(user_key)
await self.redis.delete(action_key) await self.redis.delete(action_key)
async def _handle_delete_button(self, event: Button) -> None: async def _handle_delete_button(self, event: ButtonPressed) -> None:
context = event.context context = event.context
if not context.custom_id.startswith("delete|"): if not context.custom_id.startswith("delete|"):
@ -110,7 +104,7 @@ class ComponentEventMixin:
await context.message.delete() await context.message.delete()
await context.send("Message deleted", ephemeral=True) await context.send("Message deleted", ephemeral=True)
async def _handle_copy_button(self, event: Button) -> None: async def _handle_copy_button(self, event: ButtonPressed) -> None:
context = event.context context = event.context
if not context.custom_id.startswith("copy|"): if not context.custom_id.startswith("copy|"):
@ -136,7 +130,7 @@ class ComponentEventMixin:
await context.send("Reminder copied!", ephemeral=True) await context.send("Reminder copied!", ephemeral=True)
async def _handle_phishlist_button(self, event: Button) -> None: async def _handle_phishlist_button(self, event: ButtonPressed) -> None:
context = event.context context = event.context
if not context.custom_id.startswith("pl|"): if not context.custom_id.startswith("pl|"):
return return
@ -167,7 +161,7 @@ class ComponentEventMixin:
await context.send("Confirmed! Thank you for confirming this URL.") await context.send("Confirmed! Thank you for confirming this URL.")
@listen() @listen()
async def on_button(self, event: Button) -> None: async def on_button(self, event: ButtonPressed) -> None:
"""Process button events.""" """Process button events."""
await self._handle_modcase_button(event) await self._handle_modcase_button(event)
await self._handle_delete_button(event) await self._handle_delete_button(event)

View file

@ -19,7 +19,7 @@ from jarvis_core.db.models import (
from naff import Client, Extension, InteractionContext, Permissions from naff import Client, Extension, InteractionContext, Permissions
from naff.client.utils.misc_utils import get from naff.client.utils.misc_utils import get
from naff.models.discord.channel import ChannelTypes, GuildText from naff.models.discord.channel import ChannelTypes, GuildText
from naff.models.discord.components import ActionRow, Select, SelectOption from naff.models.discord.components import ActionRow, SelectOption, StringSelectMenu
from naff.models.discord.embed import Embed, EmbedField from naff.models.discord.embed import Embed, EmbedField
from naff.models.naff.application_commands import ( from naff.models.naff.application_commands import (
OptionTypes, OptionTypes,
@ -150,9 +150,7 @@ class RedditCog(Extension):
required=True, required=True,
) )
@check(admin_or_permissions(Permissions.MANAGE_GUILD)) @check(admin_or_permissions(Permissions.MANAGE_GUILD))
async def _redditor_follow( async def _redditor_follow(self, ctx: InteractionContext, name: str, channel: GuildText) -> None:
self, ctx: InteractionContext, name: str, channel: GuildText
) -> None:
if not user_name.match(name): if not user_name.match(name):
await ctx.send("Invalid Redditor name", ephemeral=True) await ctx.send("Invalid Redditor name", ephemeral=True)
return return
@ -213,9 +211,7 @@ class RedditCog(Extension):
option = SelectOption(label=sub.name, value=str(idx)) option = SelectOption(label=sub.name, value=str(idx))
options.append(option) options.append(option)
select = Select( select = StringSelectMenu(options=options, custom_id="to_delete", min_values=1, max_values=len(redditors))
options=options, custom_id="to_delete", min_values=1, max_values=len(redditors)
)
components = [ActionRow(select)] components = [ActionRow(select)]
block = "\n".join(x for x in names) block = "\n".join(x for x in names)
@ -266,9 +262,7 @@ class RedditCog(Extension):
required=True, required=True,
) )
@check(admin_or_permissions(Permissions.MANAGE_GUILD)) @check(admin_or_permissions(Permissions.MANAGE_GUILD))
async def _subreddit_follow( async def _subreddit_follow(self, ctx: InteractionContext, name: str, channel: GuildText) -> None:
self, ctx: InteractionContext, name: str, channel: GuildText
) -> None:
if not sub_name.match(name): if not sub_name.match(name):
await ctx.send("Invalid Subreddit name", ephemeral=True) await ctx.send("Invalid Subreddit name", ephemeral=True)
return return
@ -285,9 +279,7 @@ class RedditCog(Extension):
await ctx.send("Subreddit may be private, quarantined, or nonexistent.", ephemeral=True) await ctx.send("Subreddit may be private, quarantined, or nonexistent.", ephemeral=True)
return return
exists = await SubredditFollow.find_one( exists = await SubredditFollow.find_one(q(display_name=subreddit.display_name, guild=ctx.guild.id))
q(display_name=subreddit.display_name, guild=ctx.guild.id)
)
if exists: if exists:
await ctx.send("Subreddit already being followed in this guild", ephemeral=True) await ctx.send("Subreddit already being followed in this guild", ephemeral=True)
return return
@ -338,9 +330,7 @@ class RedditCog(Extension):
option = SelectOption(label=sub.display_name, value=str(idx)) option = SelectOption(label=sub.display_name, value=str(idx))
options.append(option) options.append(option)
select = Select( select = StringSelectMenu(options=options, custom_id="to_delete", min_values=1, max_values=len(subreddits))
options=options, custom_id="to_delete", min_values=1, max_values=len(subreddits)
)
components = [ActionRow(select)] components = [ActionRow(select)]
block = "\n".join(x for x in names) block = "\n".join(x for x in names)
@ -377,9 +367,7 @@ class RedditCog(Extension):
await message.edit(components=components) await message.edit(components=components)
@reddit.subcommand(sub_cmd_name="hot", sub_cmd_description="Get the hot post of a subreddit") @reddit.subcommand(sub_cmd_name="hot", sub_cmd_description="Get the hot post of a subreddit")
@slash_option( @slash_option(name="name", description="Subreddit name", opt_type=OptionTypes.STRING, required=True)
name="name", description="Subreddit name", opt_type=OptionTypes.STRING, required=True
)
async def _subreddit_hot(self, ctx: InteractionContext, name: str) -> None: async def _subreddit_hot(self, ctx: InteractionContext, name: str) -> None:
if not sub_name.match(name): if not sub_name.match(name):
await ctx.send("Invalid Subreddit name", ephemeral=True) await ctx.send("Invalid Subreddit name", ephemeral=True)
@ -401,9 +389,7 @@ class RedditCog(Extension):
embeds = await self.post_embeds(subreddit, post) embeds = await self.post_embeds(subreddit, post)
if post.over_18 and not ctx.channel.nsfw: if post.over_18 and not ctx.channel.nsfw:
setting = await UserSetting.find_one( setting = await UserSetting.find_one(q(user=ctx.author.id, type="reddit", setting="dm_nsfw"))
q(user=ctx.author.id, type="reddit", setting="dm_nsfw")
)
if setting and setting.value: if setting and setting.value:
try: try:
await ctx.author.send(embeds=embeds) await ctx.author.send(embeds=embeds)
@ -414,9 +400,7 @@ class RedditCog(Extension):
await ctx.send(embeds=embeds) await ctx.send(embeds=embeds)
@reddit.subcommand(sub_cmd_name="top", sub_cmd_description="Get the top post of a subreddit") @reddit.subcommand(sub_cmd_name="top", sub_cmd_description="Get the top post of a subreddit")
@slash_option( @slash_option(name="name", description="Subreddit name", opt_type=OptionTypes.STRING, required=True)
name="name", description="Subreddit name", opt_type=OptionTypes.STRING, required=True
)
@slash_option( @slash_option(
name="time", name="time",
description="Top time", description="Top time",
@ -452,9 +436,7 @@ class RedditCog(Extension):
embeds = await self.post_embeds(subreddit, post) embeds = await self.post_embeds(subreddit, post)
if post.over_18 and not ctx.channel.nsfw: if post.over_18 and not ctx.channel.nsfw:
setting = await UserSetting.find_one( setting = await UserSetting.find_one(q(user=ctx.author.id, type="reddit", setting="dm_nsfw"))
q(user=ctx.author.id, type="reddit", setting="dm_nsfw")
)
if setting and setting.value: if setting and setting.value:
try: try:
await ctx.author.send(embeds=embeds) await ctx.author.send(embeds=embeds)
@ -464,12 +446,8 @@ class RedditCog(Extension):
else: else:
await ctx.send(embeds=embeds) await ctx.send(embeds=embeds)
@reddit.subcommand( @reddit.subcommand(sub_cmd_name="random", sub_cmd_description="Get a random post of a subreddit")
sub_cmd_name="random", sub_cmd_description="Get a random post of a subreddit" @slash_option(name="name", description="Subreddit name", opt_type=OptionTypes.STRING, required=True)
)
@slash_option(
name="name", description="Subreddit name", opt_type=OptionTypes.STRING, required=True
)
async def _subreddit_random(self, ctx: InteractionContext, name: str) -> None: async def _subreddit_random(self, ctx: InteractionContext, name: str) -> None:
if not sub_name.match(name): if not sub_name.match(name):
await ctx.send("Invalid Subreddit name", ephemeral=True) await ctx.send("Invalid Subreddit name", ephemeral=True)
@ -491,9 +469,7 @@ class RedditCog(Extension):
embeds = await self.post_embeds(subreddit, post) embeds = await self.post_embeds(subreddit, post)
if post.over_18 and not ctx.channel.nsfw: if post.over_18 and not ctx.channel.nsfw:
setting = await UserSetting.find_one( setting = await UserSetting.find_one(q(user=ctx.author.id, type="reddit", setting="dm_nsfw"))
q(user=ctx.author.id, type="reddit", setting="dm_nsfw")
)
if setting and setting.value: if setting and setting.value:
try: try:
await ctx.author.send(embeds=embeds) await ctx.author.send(embeds=embeds)
@ -503,12 +479,8 @@ class RedditCog(Extension):
else: else:
await ctx.send(embeds=embeds) await ctx.send(embeds=embeds)
@reddit.subcommand( @reddit.subcommand(sub_cmd_name="rising", sub_cmd_description="Get a rising post of a subreddit")
sub_cmd_name="rising", sub_cmd_description="Get a rising post of a subreddit" @slash_option(name="name", description="Subreddit name", opt_type=OptionTypes.STRING, required=True)
)
@slash_option(
name="name", description="Subreddit name", opt_type=OptionTypes.STRING, required=True
)
async def _subreddit_rising(self, ctx: InteractionContext, name: str) -> None: async def _subreddit_rising(self, ctx: InteractionContext, name: str) -> None:
if not sub_name.match(name): if not sub_name.match(name):
await ctx.send("Invalid Subreddit name", ephemeral=True) await ctx.send("Invalid Subreddit name", ephemeral=True)
@ -530,9 +502,7 @@ class RedditCog(Extension):
embeds = await self.post_embeds(subreddit, post) embeds = await self.post_embeds(subreddit, post)
if post.over_18 and not ctx.channel.nsfw: if post.over_18 and not ctx.channel.nsfw:
setting = await UserSetting.find_one( setting = await UserSetting.find_one(q(user=ctx.author.id, type="reddit", setting="dm_nsfw"))
q(user=ctx.author.id, type="reddit", setting="dm_nsfw")
)
if setting and setting.value: if setting and setting.value:
try: try:
await ctx.author.send(embeds=embeds) await ctx.author.send(embeds=embeds)
@ -543,9 +513,7 @@ class RedditCog(Extension):
await ctx.send(embeds=embeds) await ctx.send(embeds=embeds)
@reddit.subcommand(sub_cmd_name="post", sub_cmd_description="Get a specific submission") @reddit.subcommand(sub_cmd_name="post", sub_cmd_description="Get a specific submission")
@slash_option( @slash_option(name="sid", description="Submission ID", opt_type=OptionTypes.STRING, required=True)
name="sid", description="Submission ID", opt_type=OptionTypes.STRING, required=True
)
async def _reddit_post(self, ctx: InteractionContext, sid: str) -> None: async def _reddit_post(self, ctx: InteractionContext, sid: str) -> None:
await ctx.defer() await ctx.defer()
try: try:
@ -558,9 +526,7 @@ class RedditCog(Extension):
embeds = await self.post_embeds(post.subreddit, post) embeds = await self.post_embeds(post.subreddit, post)
if post.over_18 and not ctx.channel.nsfw: if post.over_18 and not ctx.channel.nsfw:
setting = await UserSetting.find_one( setting = await UserSetting.find_one(q(user=ctx.author.id, type="reddit", setting="dm_nsfw"))
q(user=ctx.author.id, type="reddit", setting="dm_nsfw")
)
if setting and setting.value: if setting and setting.value:
try: try:
await ctx.author.send(embeds=embeds) await ctx.author.send(embeds=embeds)
@ -570,14 +536,10 @@ class RedditCog(Extension):
else: else:
await ctx.send(embeds=embeds) await ctx.send(embeds=embeds)
@reddit.subcommand( @reddit.subcommand(sub_cmd_name="dm_nsfw", sub_cmd_description="DM NSFW posts if channel isn't NSFW")
sub_cmd_name="dm_nsfw", sub_cmd_description="DM NSFW posts if channel isn't NSFW"
)
@slash_option(name="dm", description="Send DM?", opt_type=OptionTypes.BOOLEAN, required=True) @slash_option(name="dm", description="Send DM?", opt_type=OptionTypes.BOOLEAN, required=True)
async def _reddit_dm(self, ctx: InteractionContext, dm: bool) -> None: async def _reddit_dm(self, ctx: InteractionContext, dm: bool) -> None:
setting = await UserSetting.find_one( setting = await UserSetting.find_one(q(user=ctx.author.id, type="reddit", setting="dm_nsfw"))
q(user=ctx.author.id, type="reddit", setting="dm_nsfw")
)
if not setting: if not setting:
setting = UserSetting(user=ctx.author.id, type="reddit", setting="dm_nsfw", value=dm) setting = UserSetting(user=ctx.author.id, type="reddit", setting="dm_nsfw", value=dm)
setting.value = dm setting.value = dm

View file

@ -14,7 +14,12 @@ from naff import (
listen, listen,
) )
from naff.client.utils.misc_utils import get from naff.client.utils.misc_utils import get
from naff.models.discord.components import ActionRow, Button, Select, SelectOption from naff.models.discord.components import (
ActionRow,
Button,
SelectOption,
StringSelectMenu,
)
from naff.models.discord.embed import EmbedField from naff.models.discord.embed import EmbedField
from naff.models.discord.enums import ButtonStyles from naff.models.discord.enums import ButtonStyles
from naff.models.discord.role import Role from naff.models.discord.role import Role
@ -115,9 +120,7 @@ class RolegiverCog(Extension):
embed.set_thumbnail(url=ctx.guild.icon.url) embed.set_thumbnail(url=ctx.guild.icon.url)
embed.set_footer(text=f"{ctx.author.username}#{ctx.author.discriminator} | {ctx.author.id}") embed.set_footer(text=f"{ctx.author.username}#{ctx.author.discriminator} | {ctx.author.id}")
components = Button( components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
)
await ctx.send(embeds=embed, components=components) await ctx.send(embeds=embed, components=components)
if ctx.guild.id not in self.cache: if ctx.guild.id not in self.cache:
@ -168,9 +171,7 @@ class RolegiverCog(Extension):
EmbedField(name="Remaining Role(s)", value="\n".join([x.mention for x in remaining])), EmbedField(name="Remaining Role(s)", value="\n".join([x.mention for x in remaining])),
] ]
embed = build_embed( embed = build_embed(title="Rolegiver Updated", description="Role removed from rolegiver", fields=fields)
title="Rolegiver Updated", description="Role removed from rolegiver", fields=fields
)
embed.set_thumbnail(url=ctx.guild.icon.url) embed.set_thumbnail(url=ctx.guild.icon.url)
@ -211,9 +212,7 @@ class RolegiverCog(Extension):
embed.set_thumbnail(url=ctx.guild.icon.url) embed.set_thumbnail(url=ctx.guild.icon.url)
embed.set_footer(text=f"{ctx.author.username}#{ctx.author.discriminator} | {ctx.author.id}") embed.set_footer(text=f"{ctx.author.username}#{ctx.author.discriminator} | {ctx.author.id}")
components = Button( components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
)
await ctx.send(embeds=embed, components=components) await ctx.send(embeds=embed, components=components)
@rolegiver.subcommand(sub_cmd_name="get", sub_cmd_description="Get a role") @rolegiver.subcommand(sub_cmd_name="get", sub_cmd_description="Get a role")
@ -230,7 +229,7 @@ class RolegiverCog(Extension):
option = SelectOption(label=role.name, value=str(role.id)) option = SelectOption(label=role.name, value=str(role.id))
options.append(option) options.append(option)
select = Select( select = StringSelectMenu(
options=options, options=options,
placeholder="Select roles to add", placeholder="Select roles to add",
min_values=1, min_values=1,
@ -277,9 +276,7 @@ class RolegiverCog(Extension):
icon_url=ctx.author.display_avatar.url, icon_url=ctx.author.display_avatar.url,
) )
embed.set_footer( embed.set_footer(text=f"{ctx.author.username}#{ctx.author.discriminator} | {ctx.author.id}")
text=f"{ctx.author.username}#{ctx.author.discriminator} | {ctx.author.id}"
)
for row in components: for row in components:
for component in row.components: for component in row.components:
@ -311,7 +308,7 @@ class RolegiverCog(Extension):
option = SelectOption(label=role.name, value=str(role.id)) option = SelectOption(label=role.name, value=str(role.id))
options.append(option) options.append(option)
select = Select( select = StringSelectMenu(
options=options, options=options,
custom_id="to_remove", custom_id="to_remove",
placeholder="Select roles to remove", placeholder="Select roles to remove",
@ -355,9 +352,7 @@ class RolegiverCog(Extension):
embed.set_thumbnail(url=ctx.guild.icon.url) embed.set_thumbnail(url=ctx.guild.icon.url)
embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.display_avatar.url) embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.display_avatar.url)
embed.set_footer( embed.set_footer(text=f"{ctx.author.username}#{ctx.author.discriminator} | {ctx.author.id}")
text=f"{ctx.author.username}#{ctx.author.discriminator} | {ctx.author.id}"
)
for row in components: for row in components:
for component in row.components: for component in row.components:
@ -371,9 +366,7 @@ class RolegiverCog(Extension):
component.disabled = True component.disabled = True
await message.edit(components=components) await message.edit(components=components)
@rolegiver.subcommand( @rolegiver.subcommand(sub_cmd_name="cleanup", sub_cmd_description="Removed deleted roles from rolegiver")
sub_cmd_name="cleanup", sub_cmd_description="Removed deleted roles from rolegiver"
)
@check(admin_or_permissions(Permissions.MANAGE_GUILD)) @check(admin_or_permissions(Permissions.MANAGE_GUILD))
async def _rolegiver_cleanup(self, ctx: InteractionContext) -> None: async def _rolegiver_cleanup(self, ctx: InteractionContext) -> None:
setting = await Rolegiver.find_one(q(guild=ctx.guild.id)) setting = await Rolegiver.find_one(q(guild=ctx.guild.id))

View file

@ -7,7 +7,12 @@ from jarvis_core.db.models import Star, Starboard
from naff import Client, Extension, InteractionContext, Permissions from naff import Client, Extension, InteractionContext, Permissions
from naff.client import errors from naff.client import errors
from naff.models.discord.channel import GuildText from naff.models.discord.channel import GuildText
from naff.models.discord.components import ActionRow, Button, Select, SelectOption from naff.models.discord.components import (
ActionRow,
Button,
SelectOption,
StringSelectMenu,
)
from naff.models.discord.enums import ButtonStyles from naff.models.discord.enums import ButtonStyles
from naff.models.discord.message import Message from naff.models.discord.message import Message
from naff.models.naff.application_commands import ( from naff.models.naff.application_commands import (
@ -150,9 +155,7 @@ class StarboardCog(Extension):
if c and isinstance(c, GuildText): if c and isinstance(c, GuildText):
channel_list.append(c) channel_list.append(c)
else: else:
self.logger.warning( self.logger.warning(f"Starboard {starboard.channel} no longer valid in {ctx.guild.name}")
f"Starboard {starboard.channel} no longer valid in {ctx.guild.name}"
)
to_delete.append(starboard) to_delete.append(starboard)
for starboard in to_delete: for starboard in to_delete:
@ -166,11 +169,9 @@ class StarboardCog(Extension):
if x: if x:
select_channels.append(SelectOption(label=x.name, value=str(idx))) select_channels.append(SelectOption(label=x.name, value=str(idx)))
select_channels = [ select_channels = [SelectOption(label=x.name, value=str(idx)) for idx, x in enumerate(channel_list)]
SelectOption(label=x.name, value=str(idx)) for idx, x in enumerate(channel_list)
]
select = Select( select = StringSelectMenu(
options=select_channels, options=select_channels,
min_values=1, min_values=1,
max_values=1, max_values=1,
@ -232,9 +233,7 @@ class StarboardCog(Extension):
embed.set_footer(text=ctx.guild.name + " | " + channel.name) embed.set_footer(text=ctx.guild.name + " | " + channel.name)
if image_url: if image_url:
embed.set_image(url=image_url) embed.set_image(url=image_url)
star_components = Button( star_components = Button(style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}")
style=ButtonStyles.DANGER, emoji="🗑️", custom_id=f"delete|{ctx.author.id}"
)
star = await starboard.send(embeds=embed, components=star_components) star = await starboard.send(embeds=embed, components=star_components)
await Star( await Star(

View file

@ -8,7 +8,7 @@ from jarvis_core.db.models import TwitterAccount, TwitterFollow
from naff import Client, Extension, InteractionContext, Permissions from naff import Client, Extension, InteractionContext, Permissions
from naff.client.utils.misc_utils import get from naff.client.utils.misc_utils import get
from naff.models.discord.channel import GuildText from naff.models.discord.channel import GuildText
from naff.models.discord.components import ActionRow, Select, SelectOption from naff.models.discord.components import ActionRow, SelectOption, StringSelectMenu
from naff.models.naff.application_commands import ( from naff.models.naff.application_commands import (
OptionTypes, OptionTypes,
SlashCommand, SlashCommand,
@ -27,9 +27,7 @@ class TwitterCog(Extension):
self.bot = bot self.bot = bot
self.logger = logging.getLogger(__name__) self.logger = logging.getLogger(__name__)
config = JarvisConfig.from_yaml() config = JarvisConfig.from_yaml()
auth = tweepy.AppAuthHandler( auth = tweepy.AppAuthHandler(config.twitter["consumer_key"], config.twitter["consumer_secret"])
config.twitter["consumer_key"], config.twitter["consumer_secret"]
)
self.api = tweepy.API(auth) self.api = tweepy.API(auth)
self._guild_cache = {} self._guild_cache = {}
self._channel_cache = {} self._channel_cache = {}
@ -43,9 +41,7 @@ class TwitterCog(Extension):
sub_cmd_name="follow", sub_cmd_name="follow",
sub_cmd_description="Follow a Twitter acount", sub_cmd_description="Follow a Twitter acount",
) )
@slash_option( @slash_option(name="handle", description="Twitter account", opt_type=OptionTypes.STRING, required=True)
name="handle", description="Twitter account", opt_type=OptionTypes.STRING, required=True
)
@slash_option( @slash_option(
name="channel", name="channel",
description="Channel to post tweets to", description="Channel to post tweets to",
@ -75,9 +71,7 @@ class TwitterCog(Extension):
account = await asyncio.to_thread(self.api.get_user, screen_name=handle) account = await asyncio.to_thread(self.api.get_user, screen_name=handle)
latest_tweet = (await asyncio.to_thread(self.api.user_timeline, screen_name=handle))[0] latest_tweet = (await asyncio.to_thread(self.api.user_timeline, screen_name=handle))[0]
except Exception: except Exception:
await ctx.send( await ctx.send("Unable to get user timeline. Are you sure the handle is correct?", ephemeral=True)
"Unable to get user timeline. Are you sure the handle is correct?", ephemeral=True
)
return return
exists = await TwitterFollow.find_one(q(twitter_id=account.id, guild=ctx.guild.id)) exists = await TwitterFollow.find_one(q(twitter_id=account.id, guild=ctx.guild.id))
@ -130,9 +124,7 @@ class TwitterCog(Extension):
option = SelectOption(label=account.handle, value=str(twitter.twitter_id)) option = SelectOption(label=account.handle, value=str(twitter.twitter_id))
options.append(option) options.append(option)
select = Select( select = StringSelectMenu(options=options, custom_id="to_delete", min_values=1, max_values=len(twitters))
options=options, custom_id="to_delete", min_values=1, max_values=len(twitters)
)
components = [ActionRow(select)] components = [ActionRow(select)]
block = "\n".join(x for x in handlemap.values()) block = "\n".join(x for x in handlemap.values())
@ -196,9 +188,7 @@ class TwitterCog(Extension):
option = SelectOption(label=account.handle, value=str(twitter.twitter_id)) option = SelectOption(label=account.handle, value=str(twitter.twitter_id))
options.append(option) options.append(option)
select = Select( select = StringSelectMenu(options=options, custom_id="to_update", min_values=1, max_values=len(twitters))
options=options, custom_id="to_update", min_values=1, max_values=len(twitters)
)
components = [ActionRow(select)] components = [ActionRow(select)]
block = "\n".join(x for x in handlemap.values()) block = "\n".join(x for x in handlemap.values())

75
poetry.lock generated
View file

@ -139,14 +139,15 @@ test = ["pytest", "pytest-asyncio", "pytest-cov"]
[[package]] [[package]]
name = "asyncpraw" name = "asyncpraw"
version = "7.5.0" version = "7.6.1"
description = "Async PRAW, an abbreviation for `Asynchronous Python Reddit API Wrapper`, is a python package that allows for simple access to reddit's API." description = "Async PRAW, an abbreviation for \"Asynchronous Python Reddit API Wrapper\", is a python package that allows for simple access to Reddit's API."
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.6" python-versions = ">=3.7"
[package.dependencies] [package.dependencies]
aiofiles = "<=0.6.0" aiofiles = "<1"
aiohttp = "<4"
aiosqlite = "<=0.17.0" aiosqlite = "<=0.17.0"
asyncio-extras = "<=1.3.2" asyncio-extras = "<=1.3.2"
asyncprawcore = ">=2.1,<3" asyncprawcore = ">=2.1,<3"
@ -154,10 +155,10 @@ update-checker = ">=0.18"
[package.extras] [package.extras]
ci = ["coveralls"] ci = ["coveralls"]
dev = ["asynctest (>=0.13.0)", "mock (>=0.8)", "packaging", "pre-commit", "pytest (>=2.7.3)", "pytest-asyncio", "pytest-vcr", "sphinx", "sphinx-rtd-theme", "sphinxcontrib-trio", "testfixtures (>4.13.2,<7)", "vcrpy (==4.1.1)"] dev = ["asynctest (>=0.13.0)", "mock (>=0.8)", "packaging", "pre-commit", "pytest (>=7.2.0,<7.3.0)", "pytest-asyncio", "pytest-vcr", "sphinx", "sphinx-rtd-dark-mode", "sphinx-rtd-theme", "sphinxcontrib-trio", "testfixtures (>4.13.2,<7)", "vcrpy (>=4.1.1)"]
lint = ["pre-commit", "sphinx", "sphinx-rtd-theme", "sphinxcontrib-trio"] lint = ["pre-commit", "sphinx", "sphinx-rtd-dark-mode", "sphinx-rtd-theme", "sphinxcontrib-trio"]
readthedocs = ["sphinx", "sphinx-rtd-theme", "sphinxcontrib-trio"] readthedocs = ["sphinx", "sphinx-rtd-dark-mode", "sphinx-rtd-theme", "sphinxcontrib-trio"]
test = ["asynctest (>=0.13.0)", "mock (>=0.8)", "pytest (>=2.7.3)", "pytest-asyncio", "pytest-vcr", "testfixtures (>4.13.2,<7)", "vcrpy (==4.1.1)"] test = ["asynctest (>=0.13.0)", "mock (>=0.8)", "pytest (>=7.2.0,<7.3.0)", "pytest-asyncio", "pytest-vcr", "testfixtures (>4.13.2,<7)", "vcrpy (>=4.1.1)"]
[[package]] [[package]]
name = "asyncprawcore" name = "asyncprawcore"
@ -361,6 +362,17 @@ category = "main"
optional = false optional = false
python-versions = ">=3.6" python-versions = ">=3.6"
[[package]]
name = "emoji"
version = "2.2.0"
description = "Emoji for Python"
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[package.extras]
dev = ["coverage", "coveralls", "pytest"]
[[package]] [[package]]
name = "frozenlist" name = "frozenlist"
version = "1.3.0" version = "1.3.0"
@ -401,11 +413,11 @@ gitdb = ">=4.0.1,<5"
[[package]] [[package]]
name = "h11" name = "h11"
version = "0.13.0" version = "0.14.0"
description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.6" python-versions = ">=3.7"
[[package]] [[package]]
name = "idna" name = "idna"
@ -545,7 +557,7 @@ python-versions = "*"
[[package]] [[package]]
name = "naff" name = "naff"
version = "1.12.0" version = "2.0.0"
description = "Not another freaking fork" description = "Not another freaking fork"
category = "main" category = "main"
optional = false optional = false
@ -555,11 +567,13 @@ python-versions = ">=3.10"
aiohttp = "*" aiohttp = "*"
attrs = "*" attrs = "*"
discord-typings = ">=0.5.1" discord-typings = ">=0.5.1"
emoji = "*"
tomli = "*" tomli = "*"
[package.extras] [package.extras]
all = ["Brotli", "PyNaCl (>=1.5.0,<1.6)", "aiodns", "orjson", "sentry-sdk"] all = ["Brotli", "PyNaCl (>=1.5.0,<1.6)", "aiodns", "jurigged", "orjson", "sentry-sdk"]
docs = ["Brotli", "PyNaCl (>=1.5.0,<1.6)", "aiodns", "mkdocs-autorefs", "mkdocs-awesome-pages-plugin", "mkdocs-git-committers-plugin-2", "mkdocs-git-revision-date-localized-plugin", "mkdocs-material", "mkdocs-minify-plugin", "mkdocstrings-python", "orjson", "sentry-sdk"] docs = ["Brotli", "PyNaCl (>=1.5.0,<1.6)", "aiodns", "jurigged", "mkdocs-autorefs", "mkdocs-awesome-pages-plugin", "mkdocs-git-committers-plugin-2", "mkdocs-git-revision-date-localized-plugin", "mkdocs-material", "mkdocs-minify-plugin", "mkdocstrings-python", "orjson", "sentry-sdk"]
jurigged = ["jurigged"]
sentry = ["sentry-sdk"] sentry = ["sentry-sdk"]
speedup = ["Brotli", "aiodns", "orjson"] speedup = ["Brotli", "aiodns", "orjson"]
tests = ["pytest", "pytest-asyncio", "pytest-cov", "pytest-recording", "python-dotenv", "typeguard"] tests = ["pytest", "pytest-asyncio", "pytest-cov", "pytest-recording", "python-dotenv", "typeguard"]
@ -571,19 +585,19 @@ version = "0.1.0"
description = "A stat tracker client for NAFF" description = "A stat tracker client for NAFF"
category = "main" category = "main"
optional = false optional = false
python-versions = "^3.10" python-versions = ">=3.10"
develop = false develop = false
[package.dependencies] [package.dependencies]
naff = {version = "^1.7.1", extras = ["orjson"]} naff = {version = "^2.0.0", extras = ["orjson"]}
prometheus-client = "^0.14.1" prometheus-client = "^0.14.1"
uvicorn = "^0.18.2" uvicorn = "^0.18.2"
[package.source] [package.source]
type = "git" type = "git"
url = "https://github.com/artem30801/nafftrack.git" url = "https://github.com/zevaryx/nafftrack.git"
reference = "master" reference = "HEAD"
resolved_reference = "ac5ece577f67faad01602d1b945e08c72f43d093" resolved_reference = "493e4824d034e7e27a5d9eae8684d1764344cc25"
[[package]] [[package]]
name = "nanoid" name = "nanoid"
@ -1166,7 +1180,7 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
[[package]] [[package]]
name = "uvicorn" name = "uvicorn"
version = "0.18.2" version = "0.18.3"
description = "The lightning-fast ASGI server." description = "The lightning-fast ASGI server."
category = "main" category = "main"
optional = false optional = false
@ -1177,7 +1191,7 @@ click = ">=7.0"
h11 = ">=0.8" h11 = ">=0.8"
[package.extras] [package.extras]
standard = ["PyYAML (>=5.1)", "colorama (>=0.4)", "httptools (>=0.4.0)", "python-dotenv (>=0.13)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.0)"] standard = ["colorama (>=0.4)", "httptools (>=0.4.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.0)"]
[[package]] [[package]]
name = "watchdog" name = "watchdog"
@ -1246,7 +1260,7 @@ testing = ["func-timeout", "jaraco.itertools", "pytest (>=6)", "pytest-black (>=
[metadata] [metadata]
lock-version = "1.1" lock-version = "1.1"
python-versions = "^3.10" python-versions = "^3.10"
content-hash = "57bd23e6265cf41781732790f7aea43c6985f3711ecd9977f8058b81b2689460" content-hash = "44ee3a6f02922fc25bb1f97e17de4699cacbc8f44130f5702d4b1d70cc169223"
[metadata.files] [metadata.files]
aiofile = [ aiofile = [
@ -1368,8 +1382,8 @@ asyncio-extras = [
{file = "asyncio_extras-1.3.2.tar.gz", hash = "sha256:084b62bebc19c6ba106d438a274bbb5566941c469128cd4af1a85f00a2c81f8d"}, {file = "asyncio_extras-1.3.2.tar.gz", hash = "sha256:084b62bebc19c6ba106d438a274bbb5566941c469128cd4af1a85f00a2c81f8d"},
] ]
asyncpraw = [ asyncpraw = [
{file = "asyncpraw-7.5.0-py3-none-any.whl", hash = "sha256:b40f3db3464077a7a7e30a89181ba15ba4c5bc550dc2642e815b235f42ad8eb2"}, {file = "asyncpraw-7.6.1-py3-none-any.whl", hash = "sha256:b7a424d9357ff5991de71341ddf8d0f133b0b28cbc7f65e20e4e399e334e0d2b"},
{file = "asyncpraw-7.5.0.tar.gz", hash = "sha256:61aabf05052472d8b29e0f0500a6ec8b483129374d36dad286d94e4b6864572d"}, {file = "asyncpraw-7.6.1.tar.gz", hash = "sha256:17567c517afa06bb33996a01632ee7f1d733307fd2820ed982da9bfb13adb98a"},
] ]
asyncprawcore = [ asyncprawcore = [
{file = "asyncprawcore-2.3.0-py3-none-any.whl", hash = "sha256:46c52e6cfe91801a8c9490a0ee29a85cbc6713ccc535d5c704d448aee9729e5b"}, {file = "asyncprawcore-2.3.0-py3-none-any.whl", hash = "sha256:46c52e6cfe91801a8c9490a0ee29a85cbc6713ccc535d5c704d448aee9729e5b"},
@ -1466,6 +1480,9 @@ distro = [
{file = "distro-1.7.0-py3-none-any.whl", hash = "sha256:d596311d707e692c2160c37807f83e3820c5d539d5a83e87cfb6babd8ba3a06b"}, {file = "distro-1.7.0-py3-none-any.whl", hash = "sha256:d596311d707e692c2160c37807f83e3820c5d539d5a83e87cfb6babd8ba3a06b"},
{file = "distro-1.7.0.tar.gz", hash = "sha256:151aeccf60c216402932b52e40ee477a939f8d58898927378a02abbe852c1c39"}, {file = "distro-1.7.0.tar.gz", hash = "sha256:151aeccf60c216402932b52e40ee477a939f8d58898927378a02abbe852c1c39"},
] ]
emoji = [
{file = "emoji-2.2.0.tar.gz", hash = "sha256:a2986c21e4aba6b9870df40ef487a17be863cb7778dcf1c01e25917b7cd210bb"},
]
frozenlist = [ frozenlist = [
{file = "frozenlist-1.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d2257aaba9660f78c7b1d8fea963b68f3feffb1a9d5d05a18401ca9eb3e8d0a3"}, {file = "frozenlist-1.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d2257aaba9660f78c7b1d8fea963b68f3feffb1a9d5d05a18401ca9eb3e8d0a3"},
{file = "frozenlist-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4a44ebbf601d7bac77976d429e9bdb5a4614f9f4027777f9e54fd765196e9d3b"}, {file = "frozenlist-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4a44ebbf601d7bac77976d429e9bdb5a4614f9f4027777f9e54fd765196e9d3b"},
@ -1540,8 +1557,8 @@ gitpython = [
{file = "GitPython-3.1.27.tar.gz", hash = "sha256:1c885ce809e8ba2d88a29befeb385fcea06338d3640712b59ca623c220bb5704"}, {file = "GitPython-3.1.27.tar.gz", hash = "sha256:1c885ce809e8ba2d88a29befeb385fcea06338d3640712b59ca623c220bb5704"},
] ]
h11 = [ h11 = [
{file = "h11-0.13.0-py3-none-any.whl", hash = "sha256:8ddd78563b633ca55346c8cd41ec0af27d3c79931828beffb46ce70a379e7442"}, {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"},
{file = "h11-0.13.0.tar.gz", hash = "sha256:70813c1135087a248a4d38cc0e1a0181ffab2188141a93eaf567940c3957ff06"}, {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"},
] ]
idna = [ idna = [
{file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"},
@ -1638,8 +1655,8 @@ mypy-extensions = [
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
] ]
naff = [ naff = [
{file = "naff-1.12.0-py3-none-any.whl", hash = "sha256:37b595f0c9fed1672b5fe6f511374da4a33e818ae8451c710d745231d7cbd941"}, {file = "naff-2.0.0-py3-none-any.whl", hash = "sha256:afd3906acbdaf6f87ea6e618f07e97f059f9adf8011afd1e3b73fb55d03d153a"},
{file = "naff-1.12.0.tar.gz", hash = "sha256:21d1ce708e1a7cfe08ae59e7d79576cff103a027424b032c9ac8c33dbe2d0a5d"}, {file = "naff-2.0.0.tar.gz", hash = "sha256:eb51697ddf91ba0047a3d35951ad5a4daceb97301698b0078781dee969eb3f99"},
] ]
nafftrack = [] nafftrack = []
nanoid = [ nanoid = [
@ -2243,8 +2260,8 @@ urllib3 = [
{file = "urllib3-1.26.8.tar.gz", hash = "sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"}, {file = "urllib3-1.26.8.tar.gz", hash = "sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"},
] ]
uvicorn = [ uvicorn = [
{file = "uvicorn-0.18.2-py3-none-any.whl", hash = "sha256:c19a057deb1c5bb060946e2e5c262fc01590c6529c0af2c3d9ce941e89bc30e0"}, {file = "uvicorn-0.18.3-py3-none-any.whl", hash = "sha256:0abd429ebb41e604ed8d2be6c60530de3408f250e8d2d84967d85ba9e86fe3af"},
{file = "uvicorn-0.18.2.tar.gz", hash = "sha256:cade07c403c397f9fe275492a48c1b869efd175d5d8a692df649e6e7e2ed8f4e"}, {file = "uvicorn-0.18.3.tar.gz", hash = "sha256:9a66e7c42a2a95222f76ec24a4b754c158261c4696e683b9dadc72b590e0311b"},
] ]
watchdog = [ watchdog = [
{file = "watchdog-2.1.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:676263bee67b165f16b05abc52acc7a94feac5b5ab2449b491f1a97638a79277"}, {file = "watchdog-2.1.8-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:676263bee67b165f16b05abc52acc7a94feac5b5ab2449b491f1a97638a79277"},

View file

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "jarvis" name = "jarvis"
version = "2.3.0" version = "2.4.0"
description = "JARVIS admin bot" description = "JARVIS admin bot"
authors = ["Zevaryx <zevaryx@gmail.com>"] authors = ["Zevaryx <zevaryx@gmail.com>"]
@ -25,13 +25,13 @@ rook = "^0.1.170"
rich = "^12.3.0" rich = "^12.3.0"
jurigged = "^0.5.0" jurigged = "^0.5.0"
aioredis = "^2.0.1" aioredis = "^2.0.1"
naff = { version = "^1.2.0", extras = ["orjson"] } naff = { version = "^2.0.0", extras = ["orjson"] }
nafftrack = {git = "https://github.com/artem30801/nafftrack.git", rev = "master"}
ansitoimg = "^2022.1" ansitoimg = "^2022.1"
nest-asyncio = "^1.5.5" nest-asyncio = "^1.5.5"
thefuzz = {extras = ["speedup"], version = "^0.19.0"} thefuzz = {extras = ["speedup"], version = "^0.19.0"}
beautifulsoup4 = "^4.11.1" beautifulsoup4 = "^4.11.1"
calculator = {git = "https://git.zevaryx.com/zevaryx/calculator.git"} calculator = {git = "https://git.zevaryx.com/zevaryx/calculator.git"}
nafftrack = {git = "https://github.com/zevaryx/nafftrack.git"}
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
black = {version = "^22.3.0", allow-prereleases = true} black = {version = "^22.3.0", allow-prereleases = true}