1
0
Fork 0
mirror of synced 2024-06-27 02:31:04 +12:00
Bonfire/cogs/da.py

130 lines
6.3 KiB
Python
Raw Normal View History

import aiohttp
import asyncio
import discord
import re
from discord.ext import commands
from .utils import config
from .utils import checks
class Deviantart:
def __init__(self, bot):
self.base_url = "https://www.deviantart.com/api/v1/oauth2/gallery/all"
self.bot = bot
self.headers = {"User-Agent": "Bonfire/1.0.0"}
self.session = aiohttp.ClientSession()
bot.loop.create_task(self.get_token())
2016-10-08 11:56:44 +13:00
# Lets start the task a few seconds after, to ensure our token gets set
bot.loop.call_later(5, self.post_task)
async def post_task(self):
while(True):
await check_posts()
await asyncio.sleep(300)
async def get_token(self):
# We need a token to create requests, it doesn't seem this token goes away
# To get this token, we need to make a request and retrieve that
url = 'https://www.deviantart.com/oauth2/token'
params = {'client_id': config.da_id,
'client_secret': config.da_secret,
'grant_type': 'client_credentials'}
async with self.session.get(url, headers=self.headers, params=params) as response:
data = await response.json()
# Make sure we refresh our token, based on when they tell us it expires
# Ensure we call it a few seconds earlier, to give us enough time to set the new token
# If there was an issue, lets call this in a minute again
self.bot.loop.call_later(data.get('expires_in', 65) - 5, get_token)
self.token = data.get('access_token', None)
self.params = {'access_token': self.token}
2016-10-08 11:56:44 +13:00
async def check_posts(self):
content = await config.get_content('deviantart')
# People might sub to the same person, so lets cache every person and their last update
cache = {}
for entry in content:
user = discord.utils.get(self.bot.get_all_members(), id=entry['member_id'])
# If we're sharded, we might not be able to find this user. If the bot is not in the server with the member either
if user is None:
continue
params = self.params.copy()
# Now loop through the subscriptions
for da_name in entry['subbed']:
# Check what the last updated content we sent to this user was
# Since we cannot go back in time, if this doesn't match the last uploaded from the user
# Assume we need to notify the user of this post
last_updated_id = entry['last_updated'].get(da_name, None)
# Check if this user has been requested already, if so we don't need to make another request
result = cache.get(da_name, None)
if result is None:
params['username'] = da_name
async with self.session.get(self.base_url, headers=self.headers, params=params) as response:
data = await response.json()
result = data['results'][0]
cache[da_name] = result
# This means that our last update to this user, for this author, is not the same
if last_updated_id != result['deviationid']:
# First lets check if the last updated ID was None, if so...then we haven't alerted them yet
# We don't want to alert them, we just want to act like the artist's most recent update was the last notified
# So just notify the user if this is not None
if last_updated_id is not None:
fmt = "**Title:** {}\n**User:** {}\n**Category:** {}\n**URL:** {}".format(
title = result['title'],
artist = result['author']['username'],
url = result['url'],
category = result['category'])
await self.bot.send_message(user, fmt)
# Now we can update the user's last updated for this DA
# We want to do this whether or not our last if statement was met
r_filter = {'member_id': user.id}
update = {'last_updated': {da_name: result['deviationid']}}
await config.update_content('deviantart', update, r_filter)
@commands.group()
@checks.custom_perms(send_messages=True)
2016-10-08 11:51:16 +13:00
async def da(self):
pass
@da.command(pass_context=True, name='sub', aliases=['add', 'subscribe'])
@checks.custom_perms(send_messages=True)
async def da_sub(self, ctx, *, username):
"""This can be used to add a feed to your notifications.
Provide a username, and when posts are made from this user, you will be notified"""
r_filter = {'member_id': ctx.message.author.id}
content = await config.get_content('deviantart', r_filter)
# TODO: Ensure the user provided is a real user
if content is None:
entry = {'member_id': ctx.message.author.id, 'subbed': [username], 'last_entry': {}}
await config.add_content('deviantart', entry, r_filter)
elif username in content[0]['subbed']:
await self.bot.say("You are already subscribed to that user!")
else:
await config.update_content('deviantart', {'subbed': r.row['subbed'].append(username)}, r_filter)
await self.bot.say("You have just subscribed to {}!".format(username))
@da.command(pass_context=True, name='unsub', aliases=['delete', 'remove', 'unsubscribe'])
@checks.custom_perms(send_messages=True)
async def da_unsub(self, ctx, *, username):
""""This command can be used to unsub from the specified user"""
r_filter = {'member_id': ctx.message.author.id}
content = await config.get_content('deviantart', r_filter)
if content is None:
await self.bot.say("You are not subscribed to anyone at the moment!")
elif username in content[0]['subbed']:
await config.update_content('deviantart', {'subbed': r.row['subbed'].remove(username)}, r_filter)
await self.bot.say("You have just unsubscribed from {}!".format(username))
else:
await self.bot.say("You are not subscribed to that user!")
2016-10-08 11:56:44 +13:00
def setup(bot):
bot.add_cog(Deviantart(bot))