120 lines
6.2 KiB
Python
120 lines
6.2 KiB
Python
|
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())
|
||
|
|
||
|
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}
|
||
|
|
||
|
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) 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)
|
||
|
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!")
|