Skip to content

Commit

Permalink
[Destiny] 1.9.1 Add new tweet command and automatic checker
Browse files Browse the repository at this point in the history
- This adds a new way to access Bungie Help tweets via bungiehelp.org, a third party site re-hosting twitter information for Bungie.
  • Loading branch information
TrustyJAID committed Mar 22, 2024
1 parent 3235215 commit 38c3739
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 5 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ TrustyJAID's Cogs for [Red-DiscordBot](https://github.com/Cog-Creators/Red-Disc
| Compliment | 1.0.0 | <details><summary>Compliment people in a creative way</summary>Compliment people in a creative way</details> | Airen, JennJenn, and TrustyJAID |
| Conversions | 1.3.2 | <details><summary>Conversions for currencies, crypto-currencies, and stocks.</summary>Conversions for currencies, crypto-currencies, and stocks.</details> | TrustyJAID |
| CrabRave | 1.1.3 | <details><summary>Make Crab rave videos, in discord!</summary>Create your very own Crab Rave videos with custom text! This cog requires FFMPEG, moviepy (https://github.com/Zulko/moviepy), and imagemagick to work. This cog downloads a template video and font file which is then saved locally and generates crab rave videos from the template. Old videos are deleted after uploading. This cog may consume heavy resources rendering videos.</details> | DankMemer Team, TrustyJAID, and thisisjvgrace |
| | 1.9.0 | <details><summary>Thanks for installing</summary></details> | |
| | 1.9.1 | <details><summary>Thanks for installing</summary></details> | |
| Elements | 1.1.1 | <details><summary>Periodic table of elements</summary>Get a plethora of information about elements on the periodic table.</details> | TrustyJAID |
| Encoding | 1.3.1 | <details><summary>Encode messages into various types of encoding.</summary>Encode messages into various types of encoding. Encoding types include: DNA, binary, Caeser cipher, hex, base 64, character, and braille.</details> | TrustyJAID |
| EventPoster | 2.1.3 | <details><summary>Admin approved announcments/events</summary>Allow users to setup and host events to be approved by admins.</details> | TrustyJAID |
Expand Down
7 changes: 7 additions & 0 deletions destiny/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

from .converter import (
STRING_VAR_RE,
BungieTweet,
DestinyActivityModeGroup,
DestinyActivityModeType,
DestinyComponents,
Expand Down Expand Up @@ -165,6 +166,12 @@ async def request_url(
log.error("Could not connect to the API: %s", resp.status)
raise Destiny2APIError

async def bungie_help(self) -> List[BungieTweet]:
url = "https://bungiehelp.org/data.json"
async with self.session.get(url) as resp:
data = await resp.json()
return [BungieTweet(**i) for i in data]

async def post_url(
self,
url: str,
Expand Down
28 changes: 28 additions & 0 deletions destiny/converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,34 @@
STRING_VAR_RE = re.compile(r"{var:(?P<hash>\d+)}")


@dataclass
class BungieTweet:
id: str
created_at: str
user: str
user_id: str
text: str
raw_text: str
lang: str
in_reply_to: Optional[str]
is_quote_status: bool
quote: str
possibly_sensitive: Optional[bool]
possibly_sensitive_editable: Optional[bool]
quote_count: int
reply_count: int
favorite_count: int
favorited: bool
view_count: str
retweet_count: int
editable_until_msecs: Optional[str]
is_translatable: bool
is_edit_eligible: bool
edits_remaining: Optional[str]
unix: float
url: str


@dataclass
class NewsArticle:
Title: str
Expand Down
101 changes: 99 additions & 2 deletions destiny/destiny.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
BaseMenu,
BasePages,
BungieNewsSource,
BungieTweetsSource,
ClanPendingView,
LoadoutPages,
PostmasterPages,
Expand All @@ -64,7 +65,7 @@ class Destiny(DestinyAPI, commands.Cog):
Get information from the Destiny 2 API
"""

__version__ = "1.9.0"
__version__ = "1.9.1"
__author__ = "TrustyJAID"

def __init__(self, bot):
Expand All @@ -82,12 +83,20 @@ def __init__(self, bot):
self.config = Config.get_conf(self, 35689771456)
self.config.register_global(**default_global)
self.config.register_user(oauth={}, account={}, characters={})
self.config.register_guild(clan_id=None, commands={}, news_channel=None, posted_news=[])
self.config.register_guild(
clan_id=None,
commands={},
news_channel=None,
posted_news=[],
posted_tweets=[],
tweets_channel=None,
)
self.throttle: float = 0
self.dashboard_authed: Dict[int, dict] = {}
self.session = aiohttp.ClientSession(headers={"User-Agent": "Red-TrustyCogs-DestinyCog"})
self.manifest_check_loop.start()
self.news_checker.start()
self.tweet_checker.start()
self._manifest: dict = {}
self._loadout_temp: dict = {}
self._repo = ""
Expand Down Expand Up @@ -163,6 +172,42 @@ async def on_oauth_receive(self, user_id: int, payload: dict):
return
self.dashboard_authed[int(user_id)] = payload

@tasks.loop(seconds=300)
async def tweet_checker(self):
try:
tweets = await self.bungie_help()
except Exception:
log.exception("Error Checking bungiehelp.org")
return
if len(tweets) < 1:
return

guilds = await self.config.all_guilds()
article_keys = [a.id for a in tweets]
for guild_id, data in guilds.items():
guild = self.bot.get_guild(guild_id)
if guild is None:
continue
channel = guild.get_channel(data["tweets_channel"])
if channel is None:
continue
if not channel.permissions_for(guild.me).send_messages:
continue
for tweet in tweets:
if tweet.id in data["posted_tweets"]:
continue
await channel.send(content=tweet.url)
data["posted_tweets"].append(tweet.id)
if len(data["posted_tweets"]) > 25:
for old in data["posted_tweets"].copy():
if old not in article_keys and len(data["posted_tweets"]) > 25:
data["posted_tweets"].remove(old)
await self.config.guild(guild).posted_news.set(data["posted_tweets"])

@tweet_checker.before_loop
async def before_tweet_checker(self):
await self.bot.wait_until_red_ready()

@tasks.loop(seconds=300)
async def news_checker(self):
try:
Expand Down Expand Up @@ -297,6 +342,44 @@ async def destiny_set_news(
await self.config.guild(ctx.guild).news_channel.clear()
await ctx.send(_("I will no longer automaticall post news articles in this server."))

@destiny_set.command(name="tweets")
@commands.mod_or_permissions(manage_messages=True)
async def destiny_set_tweets(
self, ctx: commands.Context, channel: Optional[discord.TextChannel] = None
):
"""
Setup a channel to receive Bungie Help tweets automatically
- `<channel>` The channel you want tweets posted in.
"""
if channel is not None:
if not channel.permissions_for(ctx.me).send_messages:
await ctx.send(
_("I don't have permission to send messages in {channel}.").format(
channel=channel.mention
)
)
return
try:
tweets = await self.bungie_help()
except Destiny2APIError:
await ctx.send(
_("There was an error getting the current news posts. Please try again later.")
)
return
current = [a.id for a in tweets]
await self.config.guild(ctx.guild).posted_tweets.set(current)
await self.config.guild(ctx.guild).tweets_channel.set(channel.id)
await ctx.send(
_("I will now post new Bungie Help tweets in {channel}.").format(
channel=channel.mention
)
)
else:
await self.config.guild(ctx.guild).posted_tweets.clear()
await self.config.guild(ctx.guild).tweets_channel.clear()
await ctx.send(_("I will no longer automaticall post Bungie Help in this server."))

async def send_error_msg(self, ctx: commands.Context, error: Exception):
if isinstance(error, ServersUnavailable):
msg = _("The Destiny API servers appear to be offline. Try again later.")
Expand Down Expand Up @@ -794,6 +877,20 @@ async def destiny_news(self, ctx: commands.Context) -> None:
source = BungieNewsSource(news)
await BaseMenu(source=source, cog=self).start(ctx=ctx)

@destiny.command(name="tweets")
@commands.bot_has_permissions(embed_links=True)
async def destiny_tweets(self, ctx: commands.Context) -> None:
"""
Get the latest news articles from Bungie.net
"""
async with MyTyping(ctx, ephemeral=False):
try:
tweets = await self.bungie_help()
except Destiny2APIError as e:
return await self.send_error_msg(ctx, e)
source = BungieTweetsSource(tweets)
await BaseMenu(source=source, cog=self).start(ctx=ctx)

async def get_seal_icon(self, record: dict) -> str:
if record["parentNodeHashes"]:
node_defs = await self.get_definition(
Expand Down
18 changes: 16 additions & 2 deletions destiny/menus.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from redbot.core.utils.chat_formatting import bold, humanize_list
from redbot.vendored.discord.ext import menus

from .converter import NewsArticle, NewsArticles
from .converter import BungieTweet, NewsArticle, NewsArticles
from .errors import Destiny2APIError

BASE_URL = "https://bungie.net"
Expand Down Expand Up @@ -483,7 +483,7 @@ def __init__(self, news_pages: NewsArticles):
for index, page in enumerate(self.pages):
self.select_options.append(
discord.SelectOption(
label=page.Title[:100], description=page.Description[:100], value=index
label=page.Title[:100], description=page.Description[:100], value=str(index)
)
)

Expand All @@ -504,6 +504,20 @@ async def format_page(self, menu: Optional[BaseMenu], page: NewsArticle):
return {"content": url, "embed": embed}


class BungieTweetsSource(menus.ListPageSource):
def __init__(self, tweets: List[BungieTweet]):
self.pages = tweets
super().__init__(self.pages, per_page=1)
self.select_options = []
for index, page in enumerate(self.pages):
self.select_options.append(
discord.SelectOption(label=page.text[:100], value=str(index))
)

async def format_page(self, menu: Optional[BaseMenu], page: BungieTweet):
return {"content": page.url}


class BaseMenu(discord.ui.View):
def __init__(
self,
Expand Down

0 comments on commit 38c3739

Please sign in to comment.