<commit_before>"""
Wrappers for Webhook objects.

.. currentmodule:: curious.dataclasses.webhook
"""

import typing

from curious.dataclasses import channel as dt_channel, embed as dt_embed, guild as dt_guild, \
    user as dt_user
from curious.dataclasses.bases import Dataclass
from curious.util import base64ify


class Webhook(Dataclass):
    """
    Represents a webhook on the guild.
    Messages in a guild can be sent by either a Member or a Webhook object - curious makes a key distinction between 
    them. These classes are *mostly* compatible and don't require much effort to use them generically.
    
    .. code-block:: python3
    
        @event("message_create")
        async def handle_messages(ctx, message: Message):
            author = message.author  # can be Webhook or Member

    :ivar id: The ID of the webhook.
    """

    __slots__ = "user", "guild_id", "channel_id", "token", "owner", \
                "_default_name", "_default_avatar"

    def __init__(self, client, **kwargs):
        # Use the webhook ID is provided (i.e created from a message object).
        # If that doesn't exist, we use the ID of the data instead (it's probably right!).
        super().__init__(kwargs.get("webhook_id", kwargs.get("id")), cl=client)

        #: The user object associated with this webhook.
        self.user = None  # type: dt_user.User

        #: The ID of the Guild associated with this object.
        self.guild_id = None  # type: int

        #: The ID of the Channel associated with this object.
        self.channel_id = None  # type: int

        #: The token associated with this webhook.
        #: This is None if the webhook was received from a Message object.
        self.token = kwargs.get("token", None)  # type: str

        #: The owner of this webhook.
        self.owner = None  # type: dt_user.User

        #: The default name of this webhook.
        self._default_name = None  # type: str

        #: The default avatar of this webhook.
        self._default_avatar = None  # type: str

    def __repr__(self):
        return "<Webhook id={} name={} channel={} owner={}>".format(self.id, self.name,
                                                                    repr(self.channel),
                                                                    repr(self.owner))

    __str__ = __repr__

    @property
    def default_name(self) -> str:
        """
        :return: The default name of this webhook.
        """
        return self._default_name

    @property
    def default_avatar_url(self) -> str:
        """
        :return: The default avatar URL for this webhook.
        """
        return "https://cdn.discordapp.com/avatars/{}/{}.png".format(self.id, self._default_avatar)

    @property
    def avatar_url(self) -> str:
        """
        :return: The computed avatar URL for this webhook.
        """
        if self.user.avatar_hash is None:
            return self.default_avatar_url
        return self.user.avatar_url

    @property
    def name(self) -> str:
        """
        :return: The computed name for this webhook.
        """
        # this is kept so you can easily do `message.author.name` all the time.
        return self.user.name or self.default_name

    @property
    def guild(self) -> 'dt_guild.Guild':
        """
        :return: The :class:`~.Guild` this webhook is in.
        """
        return self._bot.guilds.get(self.guild_id)

    @property
    def channel(self) -> 'dt_channel.Channel':
        """
        :return: The :class:`~.Channel` this webhook is in. 
        """
        if self.guild is None:
            return None

        return self.guild.channels.get(self.channel_id)

    @classmethod
    async def create(cls, channel: 'dt_channel.Channel', *,
                     name: str, avatar: bytes) -> 'Webhook':
        """
        Creates a new webhook.

        :param channel: The :class:`~.Channel` to create the webhook in.
        :param name: The name of the webhook to create.
        :param avatar: The bytes data for the webhook's default avatar.
        :return: A new :class:`~.Webhook`.
        """
        return await channel.create_webhook(name=name, avatar=avatar)

    async def get_token(self) -> str:
        """
        Gets the token for this webhook, if no token was set earlier.
        :return: The token for the webhook.
        """
        if self.token:
            return self.token

        us = await self._bot.http.get_webhook(self.id)
        self.token = us.get("token")
        return self.token

    async def delete(self) -> None:
        """
        Deletes the webhook.

        You must either be the owner of this webhook, or the webhook must have a token associated to delete it.
        """
        if self.token is not None:
            return await self._bot.http.delete_webhook_with_token(self.id, self.token)
        else:
            return await self.guild.delete_webhook(self)

    async def edit(self, *,
                   name: str = None, avatar: bytes = None) -> 'Webhook':
        """
        Edits this webhook.

        :param name: The new name for this webhook.
        :param avatar: The bytes-encoded content of the new avatar.
        :return: The webhook object.
        """
        if avatar is not None:<commit_msg>Fix some line wrapping.<commit_after>"""
Wrappers for Webhook objects.

.. currentmodule:: curious.dataclasses.webhook
"""

import typing

from curious.dataclasses import channel as dt_channel, embed as dt_embed, guild as dt_guild, \
    user as dt_user
from curious.dataclasses.bases import Dataclass
from curious.util import base64ify


class Webhook(Dataclass):
    """
    Represents a webhook on the guild.
    Messages in a guild can be sent by either a Member or a Webhook object - curious makes a key
    distinction between them. These classes are *mostly* compatible and don't require much
    effort to use them generically.
    
    .. code-block:: python3
    
        @event("message_create")
        async def handle_messages(ctx, message: Message):
            author = message.author  # can be Webhook or Member

    :ivar id: The ID of the webhook.
    """

    __slots__ = "user", "guild_id", "channel_id", "token", "owner", \
                "_default_name", "_default_avatar"

    def __init__(self, client, **kwargs):
        # Use the webhook ID is provided (i.e created from a message object).
        # If that doesn't exist, we use the ID of the data instead (it's probably right!).
        super().__init__(kwargs.get("webhook_id", kwargs.get("id")), cl=client)

        #: The user object associated with this webhook.
        self.user = None  # type: dt_user.User

        #: The ID of the Guild associated with this object.
        self.guild_id = None  # type: int

        #: The ID of the Channel associated with this object.
        self.channel_id = None  # type: int

        #: The token associated with this webhook.
        #: This is None if the webhook was received from a Message object.
        self.token = kwargs.get("token", None)  # type: str

        #: The owner of this webhook.
        self.owner = None  # type: dt_user.User

        #: The default name of this webhook.
        self._default_name = None  # type: str

        #: The default avatar of this webhook.
        self._default_avatar = None  # type: str

    def __repr__(self):
        return "<Webhook id={} name={} channel={} owner={}>".format(self.id, self.name,
                                                                    repr(self.channel),
                                                                    repr(self.owner))

    __str__ = __repr__

    @property
    def default_name(self) -> str:
        """
        :return: The default name of this webhook.
        """
        return self._default_name

    @property
    def default_avatar_url(self) -> str:
        """
        :return: The default avatar URL for this webhook.
        """
        return "https://cdn.discordapp.com/avatars/{}/{}.png".format(self.id, self._default_avatar)

    @property
    def avatar_url(self) -> str:
        """
        :return: The computed avatar URL for this webhook.
        """
        if self.user.avatar_hash is None:
            return self.default_avatar_url
        return self.user.avatar_url

    @property
    def name(self) -> str:
        """
        :return: The computed name for this webhook.
        """
        # this is kept so you can easily do `message.author.name` all the time.
        return self.user.name or self.default_name

    @property
    def guild(self) -> 'dt_guild.Guild':
        """
        :return: The :class:`~.Guild` this webhook is in.
        """
        return self._bot.guilds.get(self.guild_id)

    @property
    def channel(self) -> 'dt_channel.Channel':
        """
        :return: The :class:`~.Channel` this webhook is in. 
        """
        if self.guild is None:
            return None

        return self.guild.channels.get(self.channel_id)

    @classmethod
    async def create(cls, channel: 'dt_channel.Channel', *,
                     name: str, avatar: bytes) -> 'Webhook':
        """
        Creates a new webhook.

        :param channel: The :class:`~.Channel` to create the webhook in.
        :param name: The name of the webhook to create.
        :param avatar: The bytes data for the webhook's default avatar.
        :return: A new :class:`~.Webhook`.
        """
        return await channel.create_webhook(name=name, avatar=avatar)

    async def get_token(self) -> str:
        """
        Gets the token for this webhook, if no token was set earlier.
        :return: The token for the webhook.
        """
        if self.token:
            return self.token

        us = await self._bot.http.get_webhook(self.id)
        self.token = us.get("token")
        return self.token

    async def delete(self) -> None:
        """
        Deletes the webhook.

        You must either be the owner of this webhook, or the webhook must have a token associated
        to delete it.
        """
        if self.token is not None:
            return await self._bot.http.delete_webhook_with_token(self.id, self.token)
        else:
            return await self.guild.delete_webhook(self)

    async def edit(self, *,
                   name: str = None, avatar: bytes = None) -> 'Webhook':
        """
        Edits this webhook.

        :param name: The new name for this webhook.
        :param avatar: The bytes-encoded content of the new avatar.
        :return: The webhook object.
        """
        if avatar is not None:
{'fraction_non_alphanumeric': 0.099163455211956, 'fraction_numerical': 0.0005639627784566219, 'mean_word_length': 1.9954954954954955, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 25, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '792675', 'n_tokens_mistral': 3090, 'n_tokens_neox': 2945, 'n_words': 1026}