示例#1
0
async def cmd_move_message(ctx):
    if not IS_READY:
        raise BotException(ExceptionType.BOT_NOT_READY, True)

    args = ctx.content.split(' ')
    if len(args) <= 2:
        raise BotException(ExceptionType.WRONG_COMMAND_ARGS, True,
                           f'사용법 : {bot.command_prefix}이동 [메시지ID] [채널]')

    message_id = args[1]
    channel_id = args[2]

    if channel_id.startswith('<#') and channel_id.endswith('>'):
        channel_id = channel_id[2:-1]

    try:
        message = await ctx.channel.fetch_message(message_id)
        await move_message(message, channel_id)
    except Exception as e:
        if e.code == 10008:
            e = '메시지가 탐색되지 않았습니다.'
        elif e.code == 50001:
            e = '해당 채널에 접근할 수 없습니다.'
        elif e.code == 50035:
            e = '채널ID 혹은 메시지 ID가 올바르지 않습니다.'
        log(from_text(ctx), e)
        await ctx.channel.send(e)

    return
示例#2
0
    def getInputFromRequest(self,
                            input,
                            param,
                            error=ErrorMessages.GENERAL,
                            required=False):
        if BotConstants.RESULT in input:

            result = input[BotConstants.RESULT]

            if BotConstants.PARAMETERS in result:

                parameters = result[BotConstants.PARAMETERS]

                param_value = ''
                if param in parameters:
                    param_value = parameters[param]

                if param_value is not None and (param_value == "" or len(
                        str(param_value)) == 0) and required:
                    raise BotException(error)

                return param_value

        if not required:
            raise BotException(error)
示例#3
0
async def cmd_spoiler_convert(ctx, is_spoiler):
    if not IS_READY:
        raise BotException(ExceptionType.BOT_NOT_READY, True)

    args = ctx.content.split(' ')
    if len(args) <= 1:
        raise BotException(ExceptionType.WRONG_COMMAND_ARGS, True,
                           f'사용법 : {bot.command_prefix}[스포일러|언스포일러] [메시지ID]')

    message_id = args[1]

    try:
        message = await ctx.channel.fetch_message(message_id)
        await spoiler_convert(is_spoiler, message, ctx.author)
    except Exception as e:
        if e.code == 10008:
            e = '메시지가 탐색되지 않았습니다.'
        if e.code == 50001:
            e = '해당 채널에 접근할 수 없습니다.'
        elif e.code == 50035:
            e = '메시지 ID가 올바르지 않습니다.'
        log(from_text(ctx), e)
        await ctx.channel.send(e)

    return
示例#4
0
async def on_reaction_add(reaction, user):
    if user.bot:
        return

    if not IS_READY:
        raise BotException(ExceptionType.BOT_NOT_READY, True)

    emoji = reaction.emoji
    target_emoji = None

    for ve in get_valid_emojies():
        if ve.encode('unicode-escape') in emoji.encode('unicode-escape'):
            target_emoji = ve
            break

    if target_emoji:
        message = reaction.message
        emoji = target_emoji

        if bot_env.get_env('USE_GAMIE_REACTION_MODE') is True:
            if emoji == bot_env.get_env('GAMIE_EMOJI'):
                if not IS_READY:
                    raise BotException(ExceptionType.BOT_NOT_READY)
                log(from_text(message), '개미 이모지 발견')
                await message.add_reaction(bot_env.get_env('GAMIE_EMOJI'))
                return

        if bot_env.get_env('USE_SPOILER_REACTION_MODE') is True:
            if emoji == bot_env.get_env('SPOILER_REACTION_EMOJI'):
                log(from_text(message), '스포일러 이모지 발견')
                await spoiler_convert(True, message, user)
                return
            elif emoji == bot_env.get_env('UNSPOILER_REACTION_EMOJI'):
                log(from_text(message), '언스포일러 이모지 발견')
                await spoiler_convert(False, message, user)
                return

        if bot_env.get_env('USE_IMPORTANT_CHANNEL_REACTION_MODE') is True:
            if emoji == bot_env.get_env('IMPORTANT_CHANNEL_REACTION_EMOJI'):
                log(from_text(message), '중요 채널 이모지 발견')
                channel_id = bot_env.get_env('IMPORTANT_CHANNEL_ID')
                await move_message(message, channel_id)
                return

        if bot_env.get_env('USE_TRASH_CHANNEL_REACTION_MODE') is True:
            if emoji == bot_env.get_env('TRASH_CHANNEL_REACTION_EMOJI'):
                log(from_text(message), '휴지통 채널 이모지 발견')
                channel_id = bot_env.get_env('TRASH_CHANNEL_ID')
                await move_message(message, channel_id)
                return
示例#5
0
async def on_message(ctx):
    if ctx.author.bot:
        return

    try:
        if ctx.content.startswith(f'{bot.command_prefix}도움'):
            await cmd_help(ctx)
            return
        elif ctx.content.startswith(f'{bot.command_prefix}이동'):
            await cmd_move_message(ctx)
            return
        elif ctx.content.startswith(f'{bot.command_prefix}스포일러'):
            await cmd_spoiler_convert(ctx, True)
            return
        elif ctx.content.startswith(f'{bot.command_prefix}언스포일러'):
            await cmd_spoiler_convert(ctx, False)
            return

        if bot_env.get_env('USE_GAMIE_MODE') is True:
            if ('개미' in ctx.content) or ('미개' in ctx.content):
                if not IS_READY:
                    raise BotException(ExceptionType.BOT_NOT_READY)

                log(from_text(ctx), '개미 발견')
                await ctx.add_reaction(bot_env.get_env('GAMIE_EMOJI'))
                log(from_text(ctx), '개미 이모지 달았음')
                return

    except BotException as be:
        log(from_text(ctx), be)
        if be._notice:
            await ctx.channel.send(be._reason)
    except Exception as e:
        log(from_text(ctx), e)
        await ctx.channel.send(e)
示例#6
0
async def spoiler_convert(is_spoiler, message, requester):
    if not IS_READY:
        raise BotException(ExceptionType.BOT_NOT_READY, True)

    log(from_text(message), '메시지 변환 시작...')

    channel = message.channel

    await channel.trigger_typing()  # 봇 상태를 타이핑중으로 변경.

    is_mention = bot_env.get_env('SPOILER_MENTION')

    try:
        msg = Message(message)
        if is_spoiler:
            if msg._bot_edited_type is BotEditType.SPOILED:
                raise BotException(ExceptionType.ALREADY_SPOILER)
        else:
            if msg._bot_edited_type is BotEditType.UNSPOILED:
                raise BotException(ExceptionType.ALREADY_SPOILER)

        bot_edit_type = BotEditType.SPOILED if is_spoiler else BotEditType.UNSPOILED

        # extract header & content from message obj
        header, content = await msg.split_header(requester, is_mention)
        header = str(bot_edit_type) + ' ' + header
        edited_msg = await msg.edit(is_spoiler, header, content)

        await send_edited(channel, msg._message_type, edited_msg)

    except BotException as be:
        if be._exception_type in [
                ExceptionType.ALREADY_SPOILER, ExceptionType.ALREADY_UNSPOILER
        ]:
            log(from_text(message), be)
        else:
            await channel.send(be)
    except Exception as e:
        await channel.send(e)
    else:
        try:
            await message.delete()
        except:
            log(from_text(message), '기존 메시지 삭제 실패')
        log(from_text(message), '메시지 변환 완료')
    def getGroupId(self, group_name, groups):

        if group_name is None or group_name == '' or len(group_name) == 0:
            return -1
        group_name = group_name.lower()
        for group in groups:
            if group_name == group.getName().lower():
                return group.getId()

        raise BotException(ErrorMessages.GROUP)
示例#8
0
    def graph(args, queryThing):

        #Initialize lists of stats and locations
        locations = []
        stats = []

        # If @ is at this location, there is one stat and multiple locations. This will be a bar graph
        if args[1] == "@":
            # Add the single stat to the list of stats
            stats.append(args[0])
            #Add all locations to the list of locations
            for i in range(2, len(args)):
                locations.append(args[i])

        # If @ is anywhere else, it is assumed there is one location and multiple stats
        else:
            #  Add the stats, when you find the @, take the next element because that is your only location
            for i in range(0, len(args)):
                if args[i] == "@":
                    locations.append(args[i + 1])
                    break
                stats.append(args[i])

        # If there is more than one location, there has to be one stat and vice versa. This creates the bar graph.
        if len(locations) > 1 and not len(stats) > 1:

            # Some setup
            plt.rcdefaults()
            fig, ax = plt.subplots()

            # Pointless, honestly
            labels = locations

            # Initialize list of locations numbers
            locationNumbers = []

            # Add to the list of the locations numbers
            for i in range(len(locations)):
                locationNumbers.append(
                    queryThing.requestStatAtLocation([stats[0], locations[i]]))

            # Create the bar graph
            plt.bar(locations, locationNumbers)

            # Make it look official
            plt.title(stats[0] + " per location")
            plt.xlabel("Location")
            plt.ylabel(stats[0])
            plt.xticks(rotation=45)

            # Save the image
            plt.savefig('image\\graph.png', bbox_inches='tight')

        # This creates the pie chart
        elif len(stats) > 1 and not len(locations) > 1:

            plt.title(locations[0])

            # Also pointless, just lazy
            labels = stats

            # intialize the stat numbers
            statNumbers = []

            # add to the stat numbers
            for i in range(len(stats)):
                num = queryThing.requestStatAtLocation(
                    [stats[i], locations[0]])
                statNumbers.append(num)

            # some setup
            gig1, ax1 = plt.subplots()

            # Create the pie chart
            ax1.pie(statNumbers,
                    labels=labels,
                    autopct="%1.1f%%",
                    shadow=True,
                    startangle=90)

            # Idk what this does
            ax1.axis('equal')

            ax1.set_title(locations[0])

            # Redundant
            plt.savefig('image\\graph.png', bbox_inches='tight')

        # This screams at you if you try to break it
        else:
            BotException(
                "Invalid argments. Check spelling and make sure there is either one"
                +
                "stat and multiple countries, or multiple stats and one country"
            )
示例#9
0
async def cmd_help(ctx):
    if not IS_READY:
        raise BotException(ExceptionType.BOT_NOT_READY, True)

    log(from_text(ctx), '도움')
    embed = discord.Embed(title='유틸리티 봇입니다.',
                          description='자세한 기능은 아래를 참조하세요.',
                          color=EMBED_COLOR)

    PREFIX = str(bot.command_prefix)

    USE_GAMIE_MODE = 'ON' if bot_env.get_env('USE_GAMIE_MODE') else 'OFF'
    USE_GAMIE_REACTION_MODE = 'ON' if bot_env.get_env(
        'USE_GAMIE_REACTION_MODE') else 'OFF'
    GAMIE_EMOJI = bot_env.get_env('GAMIE_EMOJI')

    USE_SPOILER_REACTION_MODE = 'ON' if bot_env.get_env(
        'USE_SPOILER_REACTION_MODE') else 'OFF'
    SPOILER_MENTION = 'ON' if bot_env.get_env('SPOILER_MENTION') else 'OFF'
    SPOILER_REACTION_EMOJI = bot_env.get_env('SPOILER_REACTION_EMOJI')
    UNSPOILER_REACTION_EMOJI = bot_env.get_env('UNSPOILER_REACTION_EMOJI')

    MOVE_MENTION = 'ON' if bot_env.get_env('MOVE_MENTION') else 'OFF'
    USE_IMPORTANT_CHANNEL_REACTION_MODE = 'ON' if bot_env.get_env(
        'USE_IMPORTANT_CHANNEL_REACTION_MODE') else 'OFF'
    IMPORTANT_CHANNEL_ID = bot_env.get_env('IMPORTANT_CHANNEL_ID')
    IMPORTANT_CHANNEL_REACTION_EMOJI = bot_env.get_env(
        'IMPORTANT_CHANNEL_REACTION_EMOJI')

    USE_TRASH_CHANNEL_REACTION_MODE = 'ON' if bot_env.get_env(
        'USE_TRASH_CHANNEL_REACTION_MODE') else 'OFF'
    TRASH_CHANNEL_ID = bot_env.get_env('TRASH_CHANNEL_ID')
    TRASH_CHANNEL_REACTION_EMOJI = bot_env.get_env(
        'TRASH_CHANNEL_REACTION_EMOJI')

    embed.add_field(name='스포일러 리액션 옵션-' + USE_SPOILER_REACTION_MODE + ' 멘션-' + SPOILER_MENTION,
                    value='메시지에 스포일러 이모지 ' + SPOILER_REACTION_EMOJI + ' 가 달리면 메시지를 스포일러로 바꿉니다.\n' + \
                        '메시지에 언스포일러 이모지 ' + UNSPOILER_REACTION_EMOJI + ' 가 달리면 스포일러된 메시지를 공개합니다.\n' + \
                        '``` 혹은 > 같은 마크다운 텍스트는 지원하지 않습니다.\n',
                   inline=False)
    embed.add_field(name='중요 채널 리액션 옵션-' + USE_IMPORTANT_CHANNEL_REACTION_MODE + ' 멘션-' + MOVE_MENTION,
                    value='메시지에 중요 이모지 ' + IMPORTANT_CHANNEL_REACTION_EMOJI + ' 를 달면 중요 채널로 이동시킵니다.\n' + \
                        '중요 채널 : ' +  f'<#{IMPORTANT_CHANNEL_ID}> (ID:' + IMPORTANT_CHANNEL_ID + ')',
                   inline=False)
    embed.add_field(name='휴지통 채널 리액션 옵션-' + USE_TRASH_CHANNEL_REACTION_MODE + ' 멘션-' + MOVE_MENTION,
                    value='메시지에 휴지통 이모지 ' + TRASH_CHANNEL_REACTION_EMOJI + ' 를 달면 휴지통 채널로 이동시킵니다.\n' + \
                        '휴지통 채널 : ' +  f'<#{TRASH_CHANNEL_ID}> (ID:' + TRASH_CHANNEL_ID + ')',
                   inline=False)
    embed.add_field(
        name='메시지 스포일러',
        value=
        f'{PREFIX}스포일러 [메시지ID] 로 메시지를 명령어로 스포일러 혹은 언스포일러 처리 할 수 있습니다.\n(언스포일러는 {PREFIX}언스포일러 [메시지ID]',
        inline=False)
    embed.add_field(
        name='메시지 이동',
        value=f'{PREFIX}이동 [메시지ID] [채널ID] 로 메시지를 명령어로 채널간 이동시킬 수 있습니다.',
        inline=False)
    embed.add_field(name='개미옵션-' + USE_GAMIE_MODE,
                    value='개미, 미개한 메시지가 보이면 개미 이모지를 답니다.',
                    inline=False)
    embed.add_field(name='개미 리액션 옵션-' + USE_GAMIE_REACTION_MODE,
                    value=f'메시지에 개미 이모지 {GAMIE_EMOJI} 가 달리면 동조합니다.',
                    inline=False)

    embed.set_footer(text='Embed 스포일러는 정상적으로 작동하지 않을 수 있습니다.')
    await ctx.channel.send(embed=embed)
示例#10
0
 def getExpenses(splitwise_obj, limit, date):
     try:
         expenses = splitwise_obj.getExpenses(limit=limit, dated_after=date)
         return expenses
     except Exception:
         raise BotException(ErrorMessages.GENERAL)
示例#11
0
 def process(self, input):
     app.logger.debug("Processing Unknown Request")
     raise BotException(random.choice(ErrorMessages.UNKNOWN))
示例#12
0
    def process(self, input):
        app.logger.debug("Processing New Transaction Request")

        output = BotConstants.NEW_EXPENSE_OUTPUT
        splitwise_obj = SplitwiseProcessor.getSplitwiseObject(input)

        current_user = splitwise_obj.getCurrentUser()
        friends_list = splitwise_obj.getFriends()

        user_list = []
        split = SplitwiseProcessor.getInputFromRequest(
            input, TransactionProcessor.SplitType.SPLIT, ErrorMessages.SPLIT,
            True)
        split = split.lower()

        if split not in TransactionProcessor.SplitType.getSplitList():
            raise BotException(ErrorMessages.WRONG_SPLIT)

        name = SplitwiseProcessor.getInputFromRequest(input, BotConstants.NAME,
                                                      ErrorMessages.NAME, True)
        currency = SplitwiseProcessor.getInputFromRequest(
            input, BotConstants.CURRENCY)
        description = SplitwiseProcessor.getInputFromRequest(
            input, BotConstants.DESCRIPTION)

        if description == "":
            description = BotConstants.FROM_BOT

        amount = 0

        if BotConstants.AMOUNT in currency:
            amount = currency[BotConstants.AMOUNT]
        else:
            amount = SplitwiseProcessor.getInputFromRequest(
                input, BotConstants.AMOUNT, self.getAmountError(split), True)

        group = str(
            SplitwiseProcessor.getInputFromRequest(input, BotConstants.GROUP))
        group_id = self.getGroupId(group, splitwise_obj.getGroups())

        expense = Expense()
        expense.setCost(amount)

        if not group_id == -1:
            expense.setGroupId(group_id)

        mode = split.lower()

        expense.setDescription(description)

        # current user
        paid, owed = self.getDistribution(mode, amount)
        expense_user = self.getExpenseUser(current_user, paid, owed)
        user_list.append(expense_user)

        match = False
        for friend in friends_list:
            if friend.getFirstName().lower() == name.lower():
                expense_user = self.getExpenseUser(friend, owed, paid)
                match = True
                if mode != TransactionProcessor.SplitType.PAID and mode != TransactionProcessor.SplitType.OWE:
                    expense_user.setPaidShare(str(0))
                    expense_user.setOwedShare(str(owed))

                output += friend.getFirstName()
                user_list.append(expense_user)
                break

        if not match:
            raise BotException(ErrorMessages.NO_FRIEND.format(name=name))

        expense.setUsers(user_list)

        expense = splitwise_obj.createExpense(expense)

        if expense.getId() is None:
            raise BotException(ErrorMessages.GENERAL)

        app.logger.debug("New Expense is created")

        return output