Add reddit hot command
This commit is contained in:
parent
2282ca5cd8
commit
a8af888e7a
1 changed files with 95 additions and 0 deletions
|
@ -1,13 +1,17 @@
|
||||||
"""JARVIS Reddit cog."""
|
"""JARVIS Reddit cog."""
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
from typing import List, Optional
|
||||||
|
|
||||||
from asyncpraw import Reddit
|
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 asyncprawcore.exceptions import Forbidden, NotFound, Redirect
|
||||||
from dis_snek import InteractionContext, Permissions, Scale, Snake
|
from dis_snek import InteractionContext, Permissions, Scale, Snake
|
||||||
from dis_snek.client.utils.misc_utils import get
|
from dis_snek.client.utils.misc_utils import get
|
||||||
from dis_snek.models.discord.channel import ChannelTypes, GuildText
|
from dis_snek.models.discord.channel import ChannelTypes, GuildText
|
||||||
from dis_snek.models.discord.components import ActionRow, Select, SelectOption
|
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 (
|
from dis_snek.models.snek.application_commands import (
|
||||||
OptionTypes,
|
OptionTypes,
|
||||||
SlashCommand,
|
SlashCommand,
|
||||||
|
@ -19,6 +23,7 @@ from jarvis_core.db.models import Subreddit, SubredditFollow
|
||||||
|
|
||||||
from jarvis import const
|
from jarvis import const
|
||||||
from jarvis.config import JarvisConfig
|
from jarvis.config import JarvisConfig
|
||||||
|
from jarvis.utils import build_embed
|
||||||
from jarvis.utils.permissions import admin_or_permissions
|
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)"
|
||||||
|
@ -34,6 +39,70 @@ class RedditCog(Scale):
|
||||||
config.reddit["user_agent"] = config.reddit.get("user_agent", DEFAULT_USER_AGENT)
|
config.reddit["user_agent"] = config.reddit.get("user_agent", DEFAULT_USER_AGENT)
|
||||||
self.api = Reddit(**config.reddit)
|
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 = SlashCommand(name="reddit", description="Manage Reddit follows")
|
||||||
|
|
||||||
@reddit.subcommand(sub_cmd_name="follow", sub_cmd_description="Follow a Subreddit")
|
@reddit.subcommand(sub_cmd_name="follow", sub_cmd_description="Follow a Subreddit")
|
||||||
|
@ -160,6 +229,32 @@ class RedditCog(Scale):
|
||||||
component.disabled = True
|
component.disabled = True
|
||||||
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")
|
||||||
|
@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:
|
def setup(bot: Snake) -> None:
|
||||||
"""Add RedditCog to JARVIS"""
|
"""Add RedditCog to JARVIS"""
|
||||||
|
|
Loading…
Add table
Reference in a new issue