cogs/emotes: support customizing more aspects of the HTTP stuff

This commit is contained in:
Io Mintz 2019-09-19 20:45:47 +00:00
parent 77f27cf6d0
commit 319456e9de
3 changed files with 36 additions and 14 deletions

View File

@ -33,12 +33,27 @@ class Emotes(commands.Cog):
def __init__(self, bot): def __init__(self, bot):
self.bot = bot self.bot = bot
self.http = aiohttp.ClientSession(loop=self.bot.loop, read_timeout=30, headers={
'User-Agent': connector = None
self.bot.config['user_agent'] + ' ' socks5_url = self.bot.config.get('socks5_proxy_url')
+ self.bot.http.user_agent if socks5_url:
}) from aiohttp_socks import SocksConnector
self.aioec = aioec.Client(loop=self.bot.loop) connector = SocksConnector.from_url(socks5_url, rdns=True)
self.http = aiohttp.ClientSession(
loop=self.bot.loop,
read_timeout=self.bot.config.get('http_read_timeout', 60),
connector=connector if self.bot.config.get('use_socks5_for_all_connections') else None,
headers={
'User-Agent':
self.bot.config['user_agent'] + ' '
+ self.bot.http.user_agent
})
self.aioec = aioec.Client(
loop=self.bot.loop,
connector=connector,
base_url=self.bot.config.get('ec_api_base_url'))
# keep track of paginators so we can end them when the cog is unloaded # keep track of paginators so we can end them when the cog is unloaded
self.paginators = weakref.WeakSet() self.paginators = weakref.WeakSet()
@ -167,9 +182,7 @@ class Emotes(commands.Cog):
f'Original emote author: {utils.format_user(self.bot, emote.author)}') f'Original emote author: {utils.format_user(self.bot, emote.author)}')
async with context.typing(): async with context.typing():
message = await self.add_safe(context.guild, name, utils.emote.url( message = await self.add_safe(context.guild, name, emote.url, context.author.id, reason=reason)
emote.id, animated=emote.animated
), context.author.id, reason=reason)
await context.send(message) await context.send(message)
@ -230,6 +243,8 @@ class Emotes(commands.Cog):
return 'Error: retrieving the image took too long.' return 'Error: retrieving the image took too long.'
except ValueError: except ValueError:
return 'Error: Invalid URL.' return 'Error: Invalid URL.'
except aiohttp.ClientResponseError as exc:
raise errors.HTTPException(exc.status)
async def add_safe_bytes(self, guild, name, author_id, image_data: bytes, *, reason=None): async def add_safe_bytes(self, guild, name, author_id, image_data: bytes, *, reason=None):
"""Try to add an emote from bytes. On error, return a string that should be sent to the user.""" """Try to add an emote from bytes. On error, return a string that should be sent to the user."""
@ -246,8 +261,7 @@ class Emotes(commands.Cog):
async def fetch(self, url, valid_mimetypes=None): async def fetch(self, url, valid_mimetypes=None):
valid_mimetypes = valid_mimetypes or self.IMAGE_MIMETYPES valid_mimetypes = valid_mimetypes or self.IMAGE_MIMETYPES
def validate_headers(response): def validate_headers(response):
if response.reason != 'OK': response.raise_for_status()
raise errors.HTTPException(response.status)
# some dumb servers also send '; charset=UTF-8' which we should ignore # some dumb servers also send '; charset=UTF-8' which we should ignore
mimetype, options = cgi.parse_header(response.headers.get('Content-Type', '')) mimetype, options = cgi.parse_header(response.headers.get('Content-Type', ''))
if mimetype not in valid_mimetypes: if mimetype not in valid_mimetypes:
@ -258,10 +272,12 @@ class Emotes(commands.Cog):
async with request as response: async with request as response:
validate_headers(response) validate_headers(response)
return await response.read() return await response.read()
except aiohttp.ClientResponseError:
raise
except aiohttp.ClientError as exc: except aiohttp.ClientError as exc:
raise errors.EmoteManagerError('An error occurred while retrieving the file: {exc}') raise errors.EmoteManagerError('An error occurred while retrieving the file: {exc}')
await validate(self.http.head(url, timeout=5)) await validate(self.http.head(url, timeout=self.bot.config.get('http_head_timeout', 10)))
return await validate(self.http.get(url)) return await validate(self.http.get(url))
async def create_emote_from_bytes(self, guild, name, author_id, image_data: bytes, *, reason=None): async def create_emote_from_bytes(self, guild, name, author_id, image_data: bytes, *, reason=None):

View File

@ -28,7 +28,12 @@
}, },
}, },
'user_agent': 'EmoteManagerBot (https://github.com/bmintz/emote-manager-bot)', 'socks5_proxy_url': None, # required for connecting to the EC API over a Tor onion service
'use_socks5_for_all_connections': False, # whether to use socks5 for all HTTP operations (other than discord.py)
'user_agent': 'EmoteManagerBot (https://github.com/iomintz/emote-manager-bot)',
'ec_api_base_url': None, # set to None to use the default of https://ec.emote.bot/api/v0
'http_head_timeout': 10, # timeout for the initial HEAD request before retrieving any images (up this if using Tor)
'http_read_timeout': 60, # timeout for retrieving an image
# emotes that the bot may use to respond to you # emotes that the bot may use to respond to you
# If not provided, the bot will use '❌', '✅' instead. # If not provided, the bot will use '❌', '✅' instead.

View File

@ -1,4 +1,5 @@
aioec aioec>=0.6.0
aiohttp_socks
bot_bin>=1.0.0,<2.0.0 bot_bin>=1.0.0,<2.0.0
discord.py>=1.0.1,<2.0.0 discord.py>=1.0.1,<2.0.0
jishaku jishaku