Exemplo n.º 1
0
def scrape_server(token: str,
                  server_name: str,
                  messages_number: int = DEFAULT_MESSAGES_NUMBER,
                  timeout: float = DEFAULT_TIMEOUT):
    loop = asyncio.new_event_loop()
    client = Client(is_bot=False, loop=loop, max_messages=messages_number)
    server_data = {}

    @client.event
    async def on_ready():
        __log__.info("logged in as: {}".format(client.user.id))

        for server in client.servers:
            if server.name != server_name:
                continue
            server: Server = server
            __log__.info("obtained server: name: {} id: {}".format(
                server.name, server.id))
            server_data.update(
                {
                    "name": server.name,
                    "id": server.id,
                    "channels": []
                }
            )

            for channel in server.channels:
                channel: Channel = channel
                __log__.info("obtained channel: name: {} id: {}".format(
                    channel.name, channel.id))
                channel_data = {
                    "name": channel.name,
                    "id": channel.id,
                    "messages": []
                }

                try:
                    async for message in client.logs_from(channel,
                                                          limit=messages_number):
                        message: Message = message
                        __log__.info(
                            "obtained message: author: {} content: {}".format(
                                message.author.id, message.content))
                        author: Member = message.author
                        message_data = {
                            "author": {
                                "name": author.name,
                                "id": author.id
                            },
                            "server": message.server.name,
                            "channel": message.channel.name,
                            "timestamp": str(message.timestamp),
                            "content": message.content,
                            "mentions": [
                                dict(
                                    name=mentioned_member.name,
                                    id=mentioned_member.id
                                )
                                for mentioned_member in message.mentions
                            ]
                        }
                        channel_data["messages"].append(message_data)
                except Forbidden:  # cant access channel
                    pass
                except NotFound:  # cant find channel
                    pass
                except HTTPException:  # discord likely down
                    pass
                server_data["channels"].append(channel_data)
        client.close()

    loop.run_until_complete(client.login(token, bot=False))
    try:
        loop.run_until_complete(
            asyncio.wait_for(client.connect(), timeout, loop=loop))
    except asyncio.TimeoutError:
        pass
    loop.run_until_complete(client.logout())
    loop.close()
    return server_data
Exemplo n.º 2
0
class DiscordHandler(GenericHandler):
    def __init__(self):
        super(DiscordHandler, self).__init__()
        self.bot = Client()
        self.message_handlers = WeakSet()
        self.channels = WeakValueDictionary()

    async def setup(self, token, client_secret):
        await self.bot.login(token=token, bot=True)
        asyncio.ensure_future(self.bot.connect(reconnect=True))
        await self.bot.wait_until_ready()
        print("Logged into Discord")
        self.bot.event(self.on_message)
        self.bot.event(self.on_guild_channel_create)
        self.bot.event(self.on_guild_channel_delete)
        self.bot.event(self.on_guild_channel_update)

    def get_channel(self, serialised) -> Optional[DiscordChannel]:
        channel_id = serialised.get("id")
        try:
            return self.channels[channel_id]
        except KeyError:
            pass
        try:
            channel = self.bot.get_channel(int(channel_id))
        except ValueError:
            return
        if not channel:
            return
        rtn = DiscordChannel(channel)
        self.message_handlers.add(rtn.on_message_handler)
        self.channels[channel_id] = rtn
        return rtn

    @property
    def serialised_channels(self):
        return [{
            "type": "discord",
            "id": f"{channel.id}",
            "name": channel.name,
            "server": {
                "id": f"{channel.guild.id}",
                "name": channel.guild.name,
                "icon": str(channel.guild.icon_url_as(format="png", size=256))
            }
        } for channel in self.bot.get_all_channels()
                if (channel.permissions_for(channel.guild.me).manage_webhooks
                    and isinstance(channel, TextChannel))]

    async def on_message(self, message):
        await asyncio.gather(
            *[handler(message) for handler in self.message_handlers])

    async def on_guild_channel_create(self, channel):
        await self.process_channel_handlers()

    async def on_guild_channel_delete(self, channel):
        await self.process_channel_handlers()

    async def on_guild_channel_update(self, before, after):
        await self.process_channel_handlers()