From fa4785f0737976aa2364837738cbf9c7b0103325 Mon Sep 17 00:00:00 2001 From: Zevaryx Date: Fri, 4 Feb 2022 09:49:43 -0700 Subject: [PATCH] Move reminder and twitter tasks to tasks/ --- jarvis/tasks/__init__.py | 3 +- jarvis/tasks/reminder.py | 46 +++++++++++++++++++++++++++ jarvis/tasks/twitter.py | 67 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 jarvis/tasks/reminder.py create mode 100644 jarvis/tasks/twitter.py diff --git a/jarvis/tasks/__init__.py b/jarvis/tasks/__init__.py index e5cd73c..9825337 100644 --- a/jarvis/tasks/__init__.py +++ b/jarvis/tasks/__init__.py @@ -1,5 +1,5 @@ """J.A.R.V.I.S. background task handlers.""" -from jarvis.tasks import unban, unlock, unwarn +from jarvis.tasks import twitter, unban, unlock, unwarn def init() -> None: @@ -7,3 +7,4 @@ def init() -> None: unban.unban.start() unlock.unlock.start() unwarn.unwarn.start() + twitter.tweets.start() diff --git a/jarvis/tasks/reminder.py b/jarvis/tasks/reminder.py new file mode 100644 index 0000000..a4b1601 --- /dev/null +++ b/jarvis/tasks/reminder.py @@ -0,0 +1,46 @@ +"""J.A.R.V.I.S. reminder background task handler.""" +from asyncio import to_thread +from datetime import datetime, timedelta + +from dis_snek.ext.tasks.task import Task +from dis_snek.ext.tasks.triggers import IntervalTrigger + +import jarvis +from jarvis.db.models import Reminder +from jarvis.utils import build_embed + + +async def _remind() -> None: + """J.A.R.V.I.S. reminder blocking task.""" + reminders = Reminder.objects(remind_at__lte=datetime.utcnow() + timedelta(seconds=30)) + for reminder in reminders: + if reminder.remind_at <= datetime.utcnow(): + user = await jarvis.jarvis.fetch_user(reminder.user) + if not user: + reminder.delete() + continue + embed = build_embed( + title="You have a reminder", + description=reminder.message, + fields=[], + ) + embed.set_author( + name=user.name + "#" + user.discriminator, + icon_url=user.display_avatar, + ) + embed.set_thumbnail(url=user.display_avatar) + try: + await user.send(embed=embed) + except Exception: + guild = jarvis.jarvis.fetch_guild(reminder.guild) + channel = guild.get_channel(reminder.channel) if guild else None + if channel: + await channel.send(f"{user.mention}", embed=embed) + finally: + reminder.delete() + + +@Task.create(trigger=IntervalTrigger(seconds=15)) +async def remind() -> None: + """J.A.R.V.I.S. reminder background task.""" + await to_thread(_remind) diff --git a/jarvis/tasks/twitter.py b/jarvis/tasks/twitter.py new file mode 100644 index 0000000..fe1a9c1 --- /dev/null +++ b/jarvis/tasks/twitter.py @@ -0,0 +1,67 @@ +"""J.A.R.V.I.S. twitter background task handler.""" +import logging +from asyncio import to_thread + +import tweepy +from dis_snek.ext.tasks.task import Task +from dis_snek.ext.tasks.triggers import IntervalTrigger + +import jarvis +from jarvis.config import get_config +from jarvis.db.models import Twitter + +logger = logging.getLogger("jarvis") + +__auth = tweepy.AppAuthHandler( + get_config().twitter["consumer_key"], get_config().twitter["consumer_secret"] +) +__api = tweepy.API(__auth) + + +async def _tweets() -> None: + """J.A.R.V.I.S. twitter blocking task.""" + guild_cache = dict() + channel_cache = dict() + twitters = Twitter.objects(active=True) + handles = Twitter.objects.distinct("handle") + twitter_data = dict() + for handle in handles: + try: + data = __api.user_timeline(screen_name=handle) + twitter_data[handle] = data + except Exception as e: + logger.error(f"Error with fetching: {e}") + for twitter in twitters: + try: + tweets = list(filter(lambda x: x.id > twitter.last_tweet, twitter_data[twitter.handle])) + if tweets: + guild_id = twitter.guild + channel_id = twitter.channel + tweets = sorted(tweets, key=lambda x: x.id) + if guild_id not in guild_cache: + guild_cache[guild_id] = await jarvis.jarvis.get_guild(guild_id) + guild = guild_cache[twitter.guild] + if channel_id not in channel_cache: + channel_cache[channel_id] = await guild.fetch_channel(channel_id) + channel = channel_cache[channel_id] + for tweet in tweets: + retweet = "retweeted_status" in tweet.__dict__ + if retweet and not twitter.retweets: + continue + timestamp = int(tweet.created_at.timestamp()) + url = f"https://twitter.com/{twitter.handle}/status/{tweet.id}" + verb = "re" if retweet else "" + await channel.send( + f"`@{twitter.handle}` {verb}tweeted this at : {url}" + ) + newest = max(tweets, key=lambda x: x.id) + twitter.last_tweet = newest.id + twitter.save() + except Exception as e: + logger.error(f"Error with tweets: {e}") + + +@Task.create(trigger=IntervalTrigger(minutes=1)) +async def tweets() -> None: + """J.A.R.V.I.S. twitter background task.""" + await to_thread(_tweets)