Esempio n. 1
0
    async def on_server_remove(self, server, **_):
        # Deletes server data
        server_ids = [s.id for s in self.client.servers]
        self.handler._delete_old_servers(server_ids)

        # Log
        log_to_file("Removed from server: {}".format(server.name))
Esempio n. 2
0
    async def start(self):
        while self.running:
            # Run the backup every day
            await sleep(self.time)

            log_to_file("Creating a backup...")
            self.backup()
Esempio n. 3
0
async def start():
    if not parser.has_option("Credentials", "token"):
        log.fatal("Token not found. Check your settings.ini")
        log_to_file("Could not start: Token not specified")

    token = parser.get("Credentials", "token")

    await client.login(token)
    await client.connect()
Esempio n. 4
0
    async def on_server_join(self, server, **_):
        # Say hi to the server
        await self.client.send_message(server.default_channel, nano_welcome)

        # Create server settings
        self.handler.server_setup(server)

        # Log
        log_to_file("Joined server: {}".format(server.name))
Esempio n. 5
0
def main():
    try:
        print("Connecting to Discord...", end="")
        loop.run_until_complete(start())

    except Exception as e:
        loop.run_until_complete(client.logout())
        log.fatal(
            "Something went wrong, quitting (see log for exception info).")
        log_to_file("Something went wrong: {}".format(e))

    finally:
        loop.close()
Esempio n. 6
0
async def on_ready():
    # Just prints "Resumed connection" if that's the way it is
    global IS_RESUME
    if IS_RESUME:
        print("Resumed connection...")
        return
    IS_RESUME = True

    print("connected!")
    print("BOT name: {} ({})".format(client.user.name, client.user.id))

    log_to_file("Connected as {} ({})".format(client.user.name,
                                              client.user.id))

    await nano.dispatch_event(ON_READY)
Esempio n. 7
0
    async def random_cat(self, type_="gif"):
        # structure:
        # response -> data -> images -> image -> url
        try:
            data = await self.req.get_html(self.url,
                                           api_key=self.key,
                                           format=self.format,
                                           size=self.size,
                                           type=type_)
            link = BeautifulSoup(data, "lxml").find("img").get("src")
        except (APIFailure, Exception) as e:
            log_to_file("CAT: {}".format(e))
            return None

        return link
Esempio n. 8
0
async def on_ready():
    # Just prints "Resumed connection" if that's the way it is
    global is_resume
    if is_resume:
        print("Resumed connection...")
        return
    is_resume = True

    print("connected!")
    print("Username: "******"ID: " + str(client.user.id))

    log_to_file("Connected as {} ({})".format(client.user.name,
                                              client.user.id))

    await nano.dispatch_event(ON_READY)
Esempio n. 9
0
    async def start(self):
        while self.running:
            # Run the backup every day
            await sleep(self.time)

            # Full backup counter
            self.keep_buffer -= 1

            if self.keep_buffer <= 0:
                dated_backup = True
                self.keep_buffer = int(self.keep_every)
            else:
                dated_backup = False

            log_to_file("Creating a backup...")
            self.backup(dated_backup)
Esempio n. 10
0
def main():
    try:
        print("Connecting to Discord...", end="")
        loop.run_until_complete(start())

    except Exception as e:
        loop.run_until_complete(client.logout())
        log.critical(
            "Something went wrong, quitting (see log for exception info).")
        log_to_file("CRITICAL, shutting down: {}".format(e))

        # Attempts to save plugin state
        log.critical("Dispatching ON_SHUTDOW...")
        loop.run_until_complete(nano.dispatch_event(ON_SHUTDOWN))
        log.critical("done, shutting down...")

    finally:
        loop.close()
Esempio n. 11
0
    async def run(self):
        await self.client.wait_until_ready()

        await self.change_status(initial_status)

        # Shuffle the game list
        shuffle(game_list)
        await sleep(self.time)

        while not self.client.is_closed:
            for game in game_list:

                if self.client.is_closed:
                    break

                await self.change_status(game)
                await sleep(self.time)

            shuffle(game_list)

        log_to_file("Exited status changer")
Esempio n. 12
0
    async def on_error(event, *args, **kwargs):
        e_type, _, _ = sys.exc_info()

        # Ignore Forbidden errors (but log them anyways)
        if e_type == errors.Forbidden:
            log.warn("Forbidden: 403")

            if isinstance(args[0], Message):
                log_to_file("Forbidden 403. Server: {}, channel: {}".format(
                    args[0].server, args[0].channel))

            elif isinstance(args[0], Member):
                log_to_file("Forbidden 403. Server: {}, member: {}:{}".format(
                    args[0].server, args[0].name, args[0].id))

            else:
                log_to_file("Forbidden 403. Unknown instance: {}:{}".format(
                    type(args[0]), args[0].__dict__))

        else:
            print('Ignoring exception in {}'.format(event), file=sys.stderr)
            traceback.print_exc()
Esempio n. 13
0
    async def on_message(self, message, **kwargs):
        assert isinstance(message, Message)
        assert isinstance(self.handler, ServerHandler)
        client = self.client
        prefix = kwargs.get("prefix")

        if not is_valid_command(message.content, valid_commands, prefix=prefix):
            return
        else:
            self.stats.add(MESSAGE)

        def startswith(*args):
            for a in args:
                if message.content.startswith(a):
                    return True

            return False

        # !vote start
        if startswith(prefix + "vote start"):
            if not self.handler.can_use_restricted_commands(message.author, message.channel.server):
                await client.send_message(message.channel, "You are not permitted to use this command.")

                self.stats.add(WRONG_PERMS)
                return

            if self.vote.in_progress(message.channel.server):
                await client.send_message(message.channel, IN_PROGRESS)
                return

            vote_content = message.content[len(prefix + "vote start "):]
            base = str(vote_content).split("\"")

            if len(base) != 3:
                await client.send_message(message.channel, "Incorrect usage. Check {}help vote start for info.".format(prefix))
                self.stats.add(WRONG_ARG)
                return

            title = str(base[1])
            vote_items = str(base[2]).split("|")
            vote_items = [a.strip(" ") for a in list(vote_items)]

            if len(vote_items) > VOTE_ITEM_LIMIT:
                await client.send_message(message.channel, StandardEmoji.WARNING + " Too many vote options "
                                                                                   "(max is **{}**, you put *{}*)".format(VOTE_ITEM_LIMIT, len(vote_items)))
                return

            if (len(title) + sum([len(a) for a in vote_items])) > VOTE_ITEM_MAX_LENGTH:
                await client.send_message(message.channel, StandardEmoji.WARNING + " The whole thing is too long! (max is {}, you have {}".format(VOTE_ITEM_MAX_LENGTH, sum([len(a) for a in vote_items])))

            self.vote.start_vote(message.author.name, message.server.id, title, vote_items)

            ch = "\n".join(["{}. {}".format(en + 1, ch) for en, ch in
                            enumerate(self.vote.get_choices(message.server.id))]).strip("\n")

            await client.send_message(message.channel, "Vote started:\n**{}**\n"
                                                       "```js\n{}```".format(self.vote.get_vote_title(message.server.id), ch))

        # !vote end
        elif startswith(prefix + "vote end"):
            if not self.handler.can_use_restricted_commands(message.author, message.server):
                await client.send_message(message.channel, "You are not permitted to use this command.")

                self.stats.add(WRONG_PERMS)
                return

            if not self.vote.in_progress(message.server):
                await client.send_message(message.channel, NO_VOTE)
                return

            votes = self.vote.get_votes(message.server.id)
            title = self.vote.get_vote_title(message.server.id)

            embed = Embed(title=title, colour=Colour(0x303F9F),
                          description="(In total, {} people voted)".format(sum(votes.values())))
            embed.set_footer(text="Voting ended")

            for name, val in votes.items():
                embed.add_field(name=name, value="{} votes".format(val))

            try:
                await client.send_message(message.channel, "Vote ended:", embed=embed)
            except errors.HTTPException as e:
                await client.send_message(message.channel, "Something went wrong when trying to end voting. It has been logged and will be inspected.")
                log_to_file("VOTING ({}): {}".format(e, embed.to_dict()))
                return

            # Actually end the voting
            self.vote.end_voting(message.server)

        # !vote status
        elif startswith(prefix + "vote status"):
            if not self.vote.in_progress(message.server):
                await client.send_message(message.channel, NO_VOTE)
                return

            header = self.vote.get_vote_title(message.server.id)
            votes = sum(self.vote.get_votes(message.server.id).values())

            if votes == 0:
                vote_disp = "no-one has voted yet"
            elif votes == 1:
                vote_disp = "only one person has voted"
            else:
                vote_disp = "{} people have voted".format(votes)

            await client.send_message(message.channel, "**Vote:** \"{}\"\n```So far, {}.```".format(header, vote_disp))

        # !vote
        elif startswith(prefix + "vote"):
            # Ignore if there is no vote going on instead of getting an exception
            if not self.vote.in_progress(message.server):
                print("not in progress")
                return

            # Get the choice, but tell the author if he/she didn't supply a number
            try:
                choice = int(message.content[len(prefix + "vote "):]) - 1
            except ValueError:
                m = await client.send_message(message.channel, "Vote argument must be a number.")
                await asyncio.sleep(1.5)
                await client.delete_message(m)
                return

            if choice < 0:
                return

            res = self.vote.plus_one(choice, message.author.id, message.channel.server)

            if res == -1:
                msg = await client.send_message(message.channel, "Cheater " + StandardEmoji.SMILE)

                await asyncio.sleep(1)
                await client.delete_message(msg)

            elif res:
                await client.add_reaction(message, OK_EMOJI)

            else:
                msg = await client.send_message(message.channel, "Something went wrong... " + StandardEmoji.FROWN2)

                await asyncio.sleep(1)
                await client.delete_message(msg)

            self.stats.add(VOTE)
Esempio n. 14
0
    async def on_error(event, *args, **kwargs):
        e_type, value, _ = sys.exc_info()

        # Ignore Forbidden errors (but log them anyways)
        if e_type == errors.Forbidden:
            log.warning("Forbidden 403")

            if isinstance(args[0], Message):
                log_to_file("Forbidden 403. Server: {}, channel: {}".format(args[0].server, args[0].channel))

            elif isinstance(args[0], Member):
                log_to_file("Forbidden 403. Server: {}, member: {}:{}".format(args[0].server, args[0].name, args[0].id))

            else:
                try:
                    items = args[0].__dict__
                except AttributeError:
                    items = args[0].__slots__

                log_to_file("Forbidden 403. Unknown instance: {}:{}".format(type(args[0]), items))

        elif e_type == errors.HTTPException and str(value).startswith("BAD REQUEST"):
            log.warning("Bad Request 400")
            log_to_file("Bad Request 400: \nTraceback: {}".format(kwargs), "bug")

        elif e_type == errors.NotFound:
            log.warning("Not Found 404")
            log_to_file("Not Found 404: {}".format(value))

        else:
            if isinstance(args[0], (User, Member)):
                readable = "{}:{}".format(args[0].name, args[0].id)
            elif isinstance(args[0], Message):
                readable = "'{}' by {}".format(args[0].content, args[0].author.name)
            elif isinstance(args[0], Server):
                readable = "{} (server)({})".format(args[0].name, args[0].id)
            else:
                try:
                    readable = "__dict__ of {}: ".format(type(args[0]), args[0].__dict__)
                except AttributeError:
                    readable = "__slots__ of {}: ".format(type(args[0]), args[0].__slots__)

            log_to_file("EXCEPTION in {}: {}".format(event, readable), "bug")

            exc = traceback.format_exc()
            log_to_file(exc, "bug")

            log.warning("New exception, see bugs.txt")
Esempio n. 15
0
    async def change_status(self, name):
        log.debug("Changing status to {}".format(name))
        log_to_file("Changing status to {}".format(name))

        await self.client.change_presence(game=Game(name=str(name)))
Esempio n. 16
0
    async def on_message(self, message, **kwargs):
        assert isinstance(message, Message)
        client = self.client

        prefix = kwargs.get("prefix")

        if not is_valid_command(message.content, valid_commands,
                                prefix=prefix):
            return
        else:
            self.stats.add(MESSAGE)

        def startswith(*args):
            for a in args:
                if message.content.startswith(a):
                    return True

            return False

        # !cat gif/jpg/png
        if startswith(prefix + "cat"):
            args = str(message.content[len(prefix + "cat"):]).strip(" ")

            # GIF is the default type!
            type_ = "gif"
            if len(args) != 0:
                if args == "jpg":
                    type_ = "jpg"
                elif args == "png":
                    type_ = "png"

            pic = await self.cat.random_cat(type_)

            if not pic:
                await client.send_message(
                    message.channel, "Could not get a random cat picture... " +
                    StandardEmoji.CRY)
            else:
                await client.send_message(message.channel, pic)

            self.stats.add(IMAGE_SENT)

        # !xkcd random/number/latest
        elif startswith(prefix + "xkcd"):
            args = str(message.content[len(prefix + "xkcd"):]).strip(" ")

            # Decides mode
            fetch = "random"
            if len(args) != 0:
                if is_number(args):
                    # Check if number is valid
                    if int(args) > self.xkcd.last_num:
                        await client.send_message(
                            message.channel,
                            "Such XKCD number does not exist.")
                        return
                    else:
                        fetch = "number"
                elif args == "random":
                    # Already random mode
                    pass
                else:
                    fetch = "latest"

            if fetch == "random":
                xkcd = await self.xkcd.get_random_xkcd()
            elif fetch == "number":
                xkcd = await self.xkcd.get_xkcd_by_number(args)
            else:
                xkcd = await self.xkcd.get_latest_xkcd()

            if not xkcd:
                await client.send_message(
                    message.channel,
                    "Could not fetch xkcd " + StandardEmoji.CRY +
                    ". Error has been logged for inspection.")
                log_to_file("XKCD: string {}, fetch: {}, got None".format(
                    args, fetch))
            else:
                await client.send_message(
                    message.channel,
                    "**XKCD number {}:**\n{}".format(xkcd.num, xkcd.img))

        # !joke (yo mama/chuck norris)
        elif startswith(prefix + "joke"):
            arg = str(message.content[len(prefix + "joke"):]).strip(" ")

            if arg.lower() == "yo mama":
                joke = await self.joke.get_joke(0)
            elif arg.lower() == "chuck norris":
                joke = await self.joke.get_joke(1)
            else:
                # Already random
                joke = await self.joke.get_joke()

            if not joke:
                await client.send_message(
                    message.channel,
                    "Could not get a proper joke... " + StandardEmoji.CRY)
                return

            await client.send_message(message.channel, str(joke))
Esempio n. 17
0
    async def on_server_remove(self, server, **_):
        # Deletes server data
        self.handler.delete_server(server.id)

        # Log
        log_to_file("Removed from server: {}".format(server.name))