Add redditor following
This commit is contained in:
parent
895dc87448
commit
c1972bd5da
1 changed files with 136 additions and 9 deletions
|
@ -9,7 +9,18 @@ from asyncpraw.models.reddit.submission import Submission
|
|||
from asyncpraw.models.reddit.submission import Subreddit as Sub
|
||||
from asyncprawcore.exceptions import Forbidden, NotFound, Redirect
|
||||
from jarvis_core.db import q
|
||||
from jarvis_core.db.models import Subreddit, SubredditFollow, UserSetting
|
||||
from jarvis_core.db.models import (
|
||||
Redditor,
|
||||
RedditorFollow,
|
||||
Subreddit,
|
||||
SubredditFollow,
|
||||
UserSetting,
|
||||
)
|
||||
|
||||
from jarvis import const
|
||||
from jarvis.config import JarvisConfig
|
||||
from jarvis.utils import build_embed
|
||||
from jarvis.utils.permissions import admin_or_permissions
|
||||
from naff import Client, Extension, InteractionContext, Permissions
|
||||
from naff.client.utils.misc_utils import get
|
||||
from naff.models.discord.channel import ChannelTypes, GuildText
|
||||
|
@ -23,13 +34,9 @@ from naff.models.naff.application_commands import (
|
|||
)
|
||||
from naff.models.naff.command import check
|
||||
|
||||
from jarvis import const
|
||||
from jarvis.config import JarvisConfig
|
||||
from jarvis.utils import build_embed
|
||||
from jarvis.utils.permissions import admin_or_permissions
|
||||
|
||||
DEFAULT_USER_AGENT = f"python:JARVIS:{const.__version__} (by u/zevaryx)"
|
||||
sub_name = re.compile(r"\A[A-Za-z0-9][A-Za-z0-9_]{2,20}\Z")
|
||||
user_name = re.compile(r"[A-Za-z0-9_-]+")
|
||||
image_link = re.compile(r"https?://(?:www)?\.?preview\.redd\.it\/(.*\..*)\?.*")
|
||||
|
||||
|
||||
|
@ -124,8 +131,126 @@ class RedditCog(Extension):
|
|||
return embeds
|
||||
|
||||
reddit = SlashCommand(name="reddit", description="Manage Reddit follows")
|
||||
follow = reddit.group(name="follow", description="Add a follow")
|
||||
unfollow = reddit.group(name="unfollow", description="Remove a follow")
|
||||
|
||||
@reddit.subcommand(sub_cmd_name="follow", sub_cmd_description="Follow a Subreddit")
|
||||
@follow.subcommand(sub_cmd_name="redditor", sub_cmd_description="Follow a Redditor")
|
||||
@slash_option(
|
||||
name="name",
|
||||
description="Redditor name",
|
||||
opt_type=OptionTypes.STRING,
|
||||
required=True,
|
||||
)
|
||||
@slash_option(
|
||||
name="channel",
|
||||
description="Channel to post to",
|
||||
opt_type=OptionTypes.CHANNEL,
|
||||
channel_types=[ChannelTypes.GUILD_TEXT],
|
||||
required=True,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
async def _redditor_follow(
|
||||
self, ctx: InteractionContext, name: str, channel: GuildText
|
||||
) -> None:
|
||||
if not user_name.match(name):
|
||||
await ctx.send("Invalid Redditor name", ephemeral=True)
|
||||
return
|
||||
|
||||
if not isinstance(channel, GuildText):
|
||||
await ctx.send("Channel must be a text channel", ephemeral=True)
|
||||
return
|
||||
|
||||
try:
|
||||
redditor = await self.api.redditor(name)
|
||||
await redditor.load()
|
||||
except (NotFound, Forbidden, Redirect) as e:
|
||||
self.logger.debug(f"Redditor {name} raised {e.__class__.__name__} on add")
|
||||
await ctx.send("Redditor may be deleted or nonexistent.", ephemeral=True)
|
||||
return
|
||||
|
||||
exists = await RedditorFollow.find_one(q(name=redditor.name, guild=ctx.guild.id))
|
||||
if exists:
|
||||
await ctx.send("Redditor already being followed in this guild", ephemeral=True)
|
||||
return
|
||||
|
||||
count = len([i async for i in SubredditFollow.find(q(guild=ctx.guild.id))])
|
||||
if count >= 12:
|
||||
await ctx.send("Cannot follow more than 12 Redditors", ephemeral=True)
|
||||
return
|
||||
|
||||
sr = await Redditor.find_one(q(name=redditor.name))
|
||||
if not sr:
|
||||
sr = Redditor(name=redditor.name)
|
||||
await sr.commit()
|
||||
|
||||
srf = RedditorFollow(
|
||||
name=redditor.name,
|
||||
channel=channel.id,
|
||||
guild=ctx.guild.id,
|
||||
admin=ctx.author.id,
|
||||
)
|
||||
await srf.commit()
|
||||
|
||||
await ctx.send(f"Now following `u/{name}` in {channel.mention}")
|
||||
|
||||
@unfollow.subcommand(sub_cmd_name="redditor", sub_cmd_description="Unfollow Redditor")
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
async def _redditor_unfollow(self, ctx: InteractionContext) -> None:
|
||||
subs = RedditorFollow.find(q(guild=ctx.guild.id))
|
||||
redditors = []
|
||||
async for sub in subs:
|
||||
redditors.append(sub)
|
||||
if not redditors:
|
||||
await ctx.send("You need to follow a redditor first", ephemeral=True)
|
||||
return
|
||||
|
||||
options = []
|
||||
names = []
|
||||
for idx, redditor in enumerate(redditors):
|
||||
sub = await Redditor.find_one(q(name=redditor.name))
|
||||
names.append(sub.name)
|
||||
option = SelectOption(label=sub.name, value=str(idx))
|
||||
options.append(option)
|
||||
|
||||
select = Select(
|
||||
options=options, custom_id="to_delete", min_values=1, max_values=len(redditors)
|
||||
)
|
||||
|
||||
components = [ActionRow(select)]
|
||||
block = "\n".join(x for x in names)
|
||||
message = await ctx.send(
|
||||
content=f"You are following the following redditors:\n```\n{block}\n```\n\n"
|
||||
"Please choose redditors to unfollow",
|
||||
components=components,
|
||||
)
|
||||
|
||||
try:
|
||||
context = await self.bot.wait_for_component(
|
||||
check=lambda x: ctx.author.id == x.context.author.id,
|
||||
messages=message,
|
||||
timeout=60 * 5,
|
||||
)
|
||||
for to_delete in context.context.values:
|
||||
follow = get(redditors, guild=ctx.guild.id, name=names[int(to_delete)])
|
||||
try:
|
||||
await follow.delete()
|
||||
except Exception:
|
||||
self.logger.debug("Ignoring deletion error")
|
||||
for row in components:
|
||||
for component in row.components:
|
||||
component.disabled = True
|
||||
|
||||
block = "\n".join(names[int(x)] for x in context.context.values)
|
||||
await context.context.edit_origin(
|
||||
content=f"Unfollowed the following:\n```\n{block}\n```", components=components
|
||||
)
|
||||
except asyncio.TimeoutError:
|
||||
for row in components:
|
||||
for component in row.components:
|
||||
component.disabled = True
|
||||
await message.edit(components=components)
|
||||
|
||||
@follow.subcommand(sub_cmd_name="subreddit", sub_cmd_description="Follow a Subreddit")
|
||||
@slash_option(
|
||||
name="name",
|
||||
description="Subreddit display name",
|
||||
|
@ -140,7 +265,9 @@ class RedditCog(Extension):
|
|||
required=True,
|
||||
)
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
async def _reddit_follow(self, ctx: InteractionContext, name: str, channel: GuildText) -> None:
|
||||
async def _subreddit_follow(
|
||||
self, ctx: InteractionContext, name: str, channel: GuildText
|
||||
) -> None:
|
||||
if not sub_name.match(name):
|
||||
await ctx.send("Invalid Subreddit name", ephemeral=True)
|
||||
return
|
||||
|
@ -191,7 +318,7 @@ class RedditCog(Extension):
|
|||
|
||||
await ctx.send(f"Now following `r/{name}` in {channel.mention}")
|
||||
|
||||
@reddit.subcommand(sub_cmd_name="unfollow", sub_cmd_description="Unfollow Subreddits")
|
||||
@unfollow.subcommand(sub_cmd_name="subreddit", sub_cmd_description="Unfollow Subreddits")
|
||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||
async def _subreddit_unfollow(self, ctx: InteractionContext) -> None:
|
||||
subs = SubredditFollow.find(q(guild=ctx.guild.id))
|
||||
|
|
Loading…
Add table
Reference in a new issue