Example #1
0
def helpsearch(bot, trigger):
    '''Serves the help documentation.'''
    help_content = SEARCH_CMD_PARSER.format_help()
    help_content = help_content.replace('sopel', ',search')
    url = create_s3_paste(bot.config.banlogger.s3_bucket_name,
                          help_content,
                          wanted_title="searchcommandhelp")
    bot.reply(url)
Example #2
0
def helplog(bot, trigger):
    '''Serves the help information for the command.'''
    help_content = LOG_CMD_PARSER.format_help()
    help_content = help_content.replace('sopel', ',log')
    try:
        url = create_s3_paste(bot.config.banlogger.s3_bucket_name,
                              help_content,
                              wanted_title="logcommandhelp")
    except json.decoder.JSONDecodeError as err:
        bot.reply("The paste service is down :(")
        raise Exception(err)
    bot.reply(url)
Example #3
0
def log(bot, trigger):
    '''Bot function to log a ban in a given channel, has multiple options.'''

    extra_info = ''

    arguments = trigger.groups()[1]
    if arguments is None:
        arguments = ''
    try:
        args = LOG_CMD_PARSER.parse_args(shlex.split(arguments))
    except SystemExit:
        if '-h' in arguments or '--help' in arguments or 'help' in arguments:
            helplog(bot, trigger)
        else:
            bot.reply(
                'invalid arguments :(   To learn the command syntax, please use -h'
            )
        return

    log_content = read_log_file(bot, args.chan, args.linenumber)
    log_lines = log_content.split('\n')
    start_index = 0
    end_index = len(log_lines)
    action_index = get_action_line_index(log_lines, args.skip)
    if action_index is None:
        relevant_info = dict()
    else:  # duplicated, but I'm not comfortable because it's used below too
        relevant_info = get_action_relevant_info(log_lines[action_index])
        deduce_last_nickname_or_hostmask(log_lines[:action_index],
                                         relevant_info)
        if is_banner_bot(relevant_info['operator']):
            backtrack_index = max(0,
                                  action_index - APPROPRIATE_BACKTRACK_NUMBER)
            extract_macro_info(log_lines[backtrack_index:action_index],
                               relevant_info)

    prettified_lines = prettify_lines(log_lines[start_index:end_index])
    relevant_content = '\n'.join(prettified_lines)
    try:
        url_content = create_s3_paste(bot.config.banlogger.s3_bucket_name,
                                      relevant_content)
    except json.decoder.JSONDecodeError as err:
        bot.reply('The paste service is down :(')
        raise Exception(err)
    relevant_info['log_url'] = url_content
    relevant_info['channel'] = CHANNEL_FOR_LOG[args.chan]

    bot.memory['last_log_information'] = relevant_info
    bot.reply('Logged here: {} {}'.format(url_content, extra_info))
Example #4
0
def search(bot, trigger):
    '''Searches for a nick (fuzzy) for a part of a netmask in the spreadsheets.'''
    arguments = trigger.groups()[1]
    if arguments is None:
        bot.reply(
            'No arguments :(   To learn the command syntax, please use -h')
        return
    try:
        args = SEARCH_CMD_PARSER.parse_args(shlex.split(arguments))
    except SystemExit:
        if '-h' in arguments or '--help' in arguments:
            helpsearch(bot, trigger)
        else:
            bot.reply(
                'invalid arguments :(   To learn the command syntax, please use -h'
            )
        return

    if args.convert:
        search_terms = []
        for a_nick in args.terms:
            lowercase_users = dict()
            for user in bot.users:
                lowercase_users[user.lower()] = bot.users[user].host
            if a_nick.lower() in lowercase_users:
                host_term = lowercase_users[a_nick.lower()]
                search_terms.append(host_term)
                bot.say(
                    'Converted {} to {}, using it for the search...'.format(
                        a_nick, host_term))
            else:
                search_terms.append(a_nick)
                warn_msg = 'Could not convert {} to a host (not in channels). '.format(a_nick) + \
                           'Searching without conversion...'
                bot.say(warn_msg)
    else:
        search_terms = args.terms

    if bot.config.logtools.relevant_sheets[0] not in bot.memory:
        refresh_spreadsheet_content(bot)

    indexes_by_sheet = []
    for _ in bot.config.logtools.relevant_sheets:
        indexes_by_sheet.append([])

    for a_term in search_terms:
        if a_term is None:
            continue
        term_indexes_by_sheet = search_for_indexes(bot, a_term)
        for index, content in enumerate(term_indexes_by_sheet):
            indexes_by_sheet[index].extend(content)

    for i, _ in enumerate(indexes_by_sheet):
        indexes_by_sheet[i] = list(sorted(set(indexes_by_sheet[i])))

    instances_per_sheet = []
    for i, sheet in enumerate(bot.config.logtools.relevant_sheets):
        sheet_found_indexes = indexes_by_sheet[i]
        curr_sheet_instances = []
        for match_index in sheet_found_indexes:
            relevant_row = bot.memory[sheet][match_index]
            current_entry = create_entry_from_row(relevant_row, match_index)
            report_str = format_spreadsheet_line(current_entry, sheet)
            curr_sheet_instances.append(report_str)
        instances_per_sheet.append(curr_sheet_instances)

    instances = []
    for instance_list in instances_per_sheet:
        instances.extend(instance_list)

    if len(instances) > 3:
        answer = '\U0001F914 ' + create_s3_paste(
            bot.config.banlogger.s3_bucket_name, '\n'.join(instances))
        bot.say(answer, max_messages=3)
    elif not instances:
        bot.say('None found.')
    else:
        for an_instance in instances:
            answer = '\u25A0 ' + an_instance
            bot.say(answer, max_messages=2)
def log(bot, trigger):
    '''Bot function to log a ban in a given channel, has multiple options.'''

    extra_info = ''

    arguments = trigger.groups()[1]
    if arguments is None:
        bot.reply('No arguments :(   To learn the command syntax, please use -h')
        return
    try:
        args = LOG_CMD_PARSER.parse_args(shlex.split(arguments))
    except SystemExit:
        if '-h' in arguments or '--help' in arguments or 'help' in arguments:
            helplog(bot, trigger)
        else:
            bot.reply('invalid arguments :(   To learn the command syntax, please use -h')
        return

    if args.mode == 'recent':
        log_content = read_log_file(bot, args.chan, args.linenumber)
        log_lines = log_content.split('\n')
        start_index = 0
        end_index = len(log_lines)
        action_index = get_action_line_index(log_lines, args.skip)
        if action_index is None:
            relevant_info = dict()
        else:  # duplicated, but I'm not comfortable because it's used below too
            relevant_info = get_action_relevant_info(log_lines[action_index])
            deduce_last_nickname_or_hostmask(log_lines[:action_index], relevant_info)
            if is_banner_bot(relevant_info['operator']):
                backtrack_index = max(0, action_index-APPROPRIATE_BACKTRACK_NUMBER)
                extract_macro_info(log_lines[backtrack_index:action_index], relevant_info)
    elif args.mode == 'auto':
        log_content = read_log_file(bot, args.chan, args.maxautolines)
        log_lines = log_content.split('\n')
        log_length = len(log_lines)

        action_index = get_action_line_index(log_lines, args.skip)
        if action_index is None:
            bot.reply('I did not find any action in the past {} lines :('.format(args.maxautolines))
            return
        end_index = min(log_length, action_index+args.followinglines+1)  # +1 to include the index

        relevant_info = get_action_relevant_info(log_lines[action_index])
        deduce_last_nickname_or_hostmask(log_lines[:action_index], relevant_info)
        if is_banner_bot(relevant_info['operator']):
            backtrack_index = max(0, action_index-APPROPRIATE_BACKTRACK_NUMBER)
            extract_macro_info(log_lines[backtrack_index:action_index], relevant_info)

        if 'host' not in relevant_info or 'nick' not in relevant_info:
            print(relevant_info)
            bot.reply('For some strange reason I do not have the hostmask yet, stopping search')
            return

        start_index = get_first_index(log_lines[:action_index], relevant_info)
        if start_index is None:
            extra_info = extra_info + '(could not find join of user, log may miss some context) '
            start_index = 0

        if end_index - start_index > args.maxlogautolines:
            extra_info += 'only using {} lines, use -b if needed '.format(args.maxlogautolines)
            start_index = end_index - args.maxlogautolines

    prettified_lines = prettify_lines(log_lines[start_index:end_index])
    relevant_content = '\n'.join(prettified_lines)
    try:
        url_content = create_s3_paste(bot.config.banlogger.s3_bucket_name, relevant_content)
    except json.decoder.JSONDecodeError as err:
        bot.reply('The paste service is down :(')
        raise Exception(err)
    relevant_info['log_url'] = url_content
    relevant_info['channel'] = CHANNEL_FOR_LOG[args.chan]

    bot.memory['last_log_information'] = relevant_info
    bot.reply('Logged here: {} {}'.format(url_content, extra_info))