Passed
Pull Request — main (#453)
by
unknown
02:00
created

welcome   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 91
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 10
eloc 62
dl 0
loc 91
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A Welcome.on_guild_member_add() 0 4 1
A Welcome.on_ready() 0 3 1
A Welcome._build_html() 0 14 2
A Welcome.generate_welcome_for_user() 0 30 4
A Welcome.__init__() 0 6 2
1
"""
2
Properly welcome your new members into your server!
3
"""
4
from __future__ import annotations
5
6
import json
7
import logging
8
from asyncio import sleep
9
from os import getenv
10
from typing import TYPE_CHECKING
11
12
from aiohttp import ClientSession
13
14
from pincer import Cog, Client
15
from pincer.objects import File, Message
16
from pincer.objects.events.guild import GuildMemberAddEvent
17
18
if TYPE_CHECKING:
19
    from pincer.objects import Channel, User
20
21
22
class Welcome(Cog):
23
    channel: Channel
0 ignored issues
show
introduced by
The variable Channel does not seem to be defined in case TYPE_CHECKING on line 18 is False. Are you sure this can never be the case?
Loading history...
24
    BASE_API_URL = "https://api.xiler.net"
25
    REQUEST_HEADERS = {
26
        "Content-Type": "application/json",
27
    }
28
29
    def __init__(self, client: Client):
30
        super().__init__(client)
31
        self.__session: ClientSession = ClientSession(self.BASE_API_URL)
32
33
        with open("./cogs/templates/welcome.html", "r") as f:
34
            self.template = f.read()
35
36
    def _build_html(self, user: User) -> str:
37
        """Build a HTML template to welcome new users!"""
38
        arguments = {
39
            "icon": user.get_avatar_url(256),
40
            "username": user.username,
41
            "discriminator": user.discriminator
42
        }
43
44
        res = self.template
45
46
        for key, value in arguments.items():
47
            res = res.replace(f"%{key}%", value)
48
49
        return res
50
51
    async def generate_welcome_for_user(self, user: User, ttl=0) -> File:
52
        """Generate the welcome file, this gets sent to discord!"""
53
        body = {
54
            "html": self._build_html(user),
55
            "config": {
56
                "format": "png",
57
                "width": 700,
58
                "height": 258,
59
                "transparent": True,
60
            }
61
        }
62
63
        async with self.__session.post(
64
            "/v1/html-to-image",
65
            data=json.dumps(body),
66
            headers=self.REQUEST_HEADERS
67
        ) as res:
68
            if res.ok:
69
                image_bytes = await res.read()
70
                return File(image_bytes, "png", f"welcome-{user.id}.png")
71
72
            logging.error(await res.read())
73
74
            # Allow a maximum of 5 retries
75
            if ttl < 5:
76
                await sleep(0.5)
77
                return await self.generate_welcome_for_user(user, ttl + 1)
78
79
            raise RuntimeError(
80
                "TTL Exceeded, not retrying request! (failed for welcomes)"
81
            )
82
83
    @Client.event
84
    async def on_ready(self):
85
        self.channel = await self.client.get_channel(int(getenv("WELCOME_CHANNEL")))
86
87
    @Client.event
88
    async def on_guild_member_add(self, event: GuildMemberAddEvent):
89
        banner = await self.generate_welcome_for_user(event)
90
        await self.channel.send(Message(attachments=[banner]))
91