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 asyncpraw.models.reddit.submission import Subreddit as Sub
|
||||||
from asyncprawcore.exceptions import Forbidden, NotFound, Redirect
|
from asyncprawcore.exceptions import Forbidden, NotFound, Redirect
|
||||||
from jarvis_core.db import q
|
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 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
|
||||||
|
@ -23,13 +34,9 @@ from naff.models.naff.application_commands import (
|
||||||
)
|
)
|
||||||
from naff.models.naff.command import check
|
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)"
|
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")
|
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\/(.*\..*)\?.*")
|
image_link = re.compile(r"https?://(?:www)?\.?preview\.redd\.it\/(.*\..*)\?.*")
|
||||||
|
|
||||||
|
|
||||||
|
@ -124,8 +131,126 @@ class RedditCog(Extension):
|
||||||
return embeds
|
return embeds
|
||||||
|
|
||||||
reddit = SlashCommand(name="reddit", description="Manage Reddit follows")
|
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(
|
@slash_option(
|
||||||
name="name",
|
name="name",
|
||||||
description="Subreddit display name",
|
description="Subreddit display name",
|
||||||
|
@ -140,7 +265,9 @@ class RedditCog(Extension):
|
||||||
required=True,
|
required=True,
|
||||||
)
|
)
|
||||||
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
@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):
|
if not sub_name.match(name):
|
||||||
await ctx.send("Invalid Subreddit name", ephemeral=True)
|
await ctx.send("Invalid Subreddit name", ephemeral=True)
|
||||||
return
|
return
|
||||||
|
@ -191,7 +318,7 @@ class RedditCog(Extension):
|
||||||
|
|
||||||
await ctx.send(f"Now following `r/{name}` in {channel.mention}")
|
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))
|
@check(admin_or_permissions(Permissions.MANAGE_GUILD))
|
||||||
async def _subreddit_unfollow(self, ctx: InteractionContext) -> None:
|
async def _subreddit_unfollow(self, ctx: InteractionContext) -> None:
|
||||||
subs = SubredditFollow.find(q(guild=ctx.guild.id))
|
subs = SubredditFollow.find(q(guild=ctx.guild.id))
|
||||||
|
|
Loading…
Add table
Reference in a new issue