Add reddit hot command

This commit is contained in:
Zeva Rose 2022-05-01 20:09:02 -06:00
parent 2282ca5cd8
commit a8af888e7a

View file

@ -1,13 +1,17 @@
"""JARVIS Reddit cog."""
import asyncio
import logging
from typing import List, Optional
from asyncpraw import Reddit
from asyncpraw.models.reddit.submission import Submission
from asyncpraw.models.reddit.submission import Subreddit as Sub
from asyncprawcore.exceptions import Forbidden, NotFound, Redirect
from dis_snek import InteractionContext, Permissions, Scale, Snake
from dis_snek.client.utils.misc_utils import get
from dis_snek.models.discord.channel import ChannelTypes, GuildText
from dis_snek.models.discord.components import ActionRow, Select, SelectOption
from dis_snek.models.discord.embed import Embed
from dis_snek.models.snek.application_commands import (
OptionTypes,
SlashCommand,
@ -19,6 +23,7 @@ from jarvis_core.db.models import Subreddit, SubredditFollow
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)"
@ -34,6 +39,70 @@ class RedditCog(Scale):
config.reddit["user_agent"] = config.reddit.get("user_agent", DEFAULT_USER_AGENT)
self.api = Reddit(**config.reddit)
async def post_embeds(self, sub: Sub, post: Submission) -> Optional[List[Embed]]:
"""
Build a post embeds.
Args:
post: Post to build embeds
"""
url = "https://reddit.com" + post.permalink
await post.author.load()
author_url = f"https://reddit.com/u/{post.author.name}"
images = []
content = f"**{post.title}**"
if "url" in vars(post):
if any(post.url.endswith(x) for x in ["jpeg", "jpg", "png", "gif"]):
images = [post.url]
if "media_metadata" in vars(post):
for k, v in post.media_metadata.items():
if v["status"] != "valid" or v["m"] not in ["image/jpg", "image/png", "image/gif"]:
continue
ext = v["m"].split("/")[-1]
i_url = f"https://i.redd.it/{k}.{ext}"
images.append(i_url)
if len(images) == 4:
break
if "selftext" in vars(post) and post.selftext:
content += "\n\n" + post.selftext
if len(content) > 600:
content = content[:600] + "..."
content += f"\n\n[View this post]({url})"
if not images and not content:
self.logger.debug(f"Post {post.id} had neither content nor images?")
return None
color = "#FF4500"
if "primary_color" in vars(sub):
color = sub.primary_color
base_embed = build_embed(
title="",
description=content,
fields=[],
timestamp=post.created_utc,
url=url,
color=color,
)
base_embed.set_author(
name="u/" + post.author.name, url=author_url, icon_url=post.author.icon_img
)
base_embed.set_footer(
text="Reddit", icon_url="https://www.redditinc.com/assets/images/site/reddit-logo.png"
)
embeds = [base_embed]
if len(images) > 0:
embeds[0].set_image(url=images[0])
for image in images[1:4]:
embed = Embed(url=url)
embed.set_image(url=image)
embeds.append(embed)
return embeds
reddit = SlashCommand(name="reddit", description="Manage Reddit follows")
@reddit.subcommand(sub_cmd_name="follow", sub_cmd_description="Follow a Subreddit")
@ -160,6 +229,32 @@ class RedditCog(Scale):
component.disabled = True
await message.edit(components=components)
@reddit.subcommand(sub_cmd_name="hot", sub_cmd_description="Get the hot post of a subreddit")
@slash_option(
name="name", description="Subreddit name", opt_type=OptionTypes.STRING, required=True
)
async def _subreddit_hot(self, ctx: InteractionContext, name: str) -> None:
name = name.replace("r/", "")
if len(name) > 20 or len(name) < 3:
await ctx.send("Invalid Subreddit name", ephemeral=True)
return
try:
subreddit = await self.api.subreddit(name)
await subreddit.load()
except (NotFound, Forbidden, Redirect) as e:
self.logger.debug(f"Subreddit {name} raised {e.__class__.__name__} in hot")
await ctx.send("Subreddit may be private, quarantined, or nonexistent.", ephemeral=True)
return
try:
hot = [x async for x in subreddit.hot(limit=1)][0]
except Exception as e:
self.logger.error(f"Failed to get hot from {name}", exc_info=e)
await ctx.send("Well, this is awkward. Something went wrong", ephemeral=True)
return
embeds = await self.post_embeds(subreddit, hot)
await ctx.send(embeds=embeds)
def setup(bot: Snake) -> None:
"""Add RedditCog to JARVIS"""