Exemplo n.º 1
0
def parse_tag(line, extra_tags=[]):
    if not line:
        return None

    i = 0
    if not is_capital(line[i]):
        return None

    i += 1
    while i < len(line) and (is_capital(line[i]) or is_lower(line[i]) or line[i] == "-"):
        i += 1

    if i == len(line) or line[i] != ":":
        return None

    key = format_tag_name(line[0:i])
    value = line[i + 1 :].strip()

    if key not in (config.get_email_tags() + extra_tags) or not value:
        return None

    return {key: [value]}
Exemplo n.º 2
0
def parse_tag(line, extra_tags=[]):
    if not line:
        return None

    i = 0
    if not is_capital(line[i]):
        return None

    i += 1
    while i < len(line) and (is_capital(line[i]) or
                             is_lower(line[i]) or
                             line[i] == '-'):
        i += 1

    if i == len(line) or line[i] != ':':
        return None

    key = format_tag_name(line[0:i])
    value = line[i + 1:].strip()

    if key not in (config.get_email_tags() + extra_tags) or not value:
        return None

    return { key: [value] }
Exemplo n.º 3
0
def add_tags(message, tags):
    lines = []
    payload = get_payload(message)

    in_sob = False
    done = False
    whitespace = []
    for line in payload.split("\n"):
        # if we've added our tags, we're done
        if done:
            lines.append(line)
            continue

        # is this line a tag
        tag = parse_tag(line, config.get_email_tags())
        if not in_sob and tag:
            in_sob = True

        if in_sob:
            # if it's a blank line, queue it for now
            if not line.strip():
                whitespace.append(line)
                continue

            if tag:
                key = tag.keys()[0]
                value = tag[key]

                # always drop message-id tags
                if key == "Message-id":
                    continue

                # if we hit a tag and there's whitespace before the tag, preserve it
                if whitespace:
                    lines += whitespace
                    whitespace = []
                lines.append(line)

                # Don't duplicate tags
                if key in tags and value[0] in tags[key]:
                    tags[key] = list(set(tags[key]) - set(value))
            else:
                # we hit a non-blank line that isn't a tag
                done = True
                in_sob = False

                # append our tags before this line
                for key in tags:
                    for val in tags[key]:
                        if val:
                            lines.append("%s: %s" % (key, val))

                mid = message.get_message_id()
                if mid:
                    lines.append("Message-id: %s" % mid)

                # but before any whitespace preceeding this line
                if whitespace:
                    lines += whitespace
                    whitespace = []
                lines.append(line)
        else:
            lines.append(line)

    return "\n".join(lines)
Exemplo n.º 4
0
def eval_query_term(series, term, scope):
    if term.find(':') != -1:
        command, args = term.split(':', 1)
    else:
        command = None

    if command == 'status':
        status = args.lower()

        if status == 'broken':
            return is_broken(series)
        elif status == 'obsolete':
            return is_obsolete(series)
        elif status == 'pull-request':
            return is_pull_request(series)
        elif status == 'rfc':
            return is_rfc(series)
        elif status == 'committed':
            return is_committed(series)
        elif status == 'reviewed':
            return is_reviewed(series)
        else:
            raise Exception("Unknown status `%s'" % status)
    elif command == 'label':
        txt = config.get_label(args)
        if txt == None:
            raise Exception('Invalid label %s' % args)
        tks = tokenize_query(txt)
        t, _ = parse_query(tks)
        return eval_query(series, t, scope)
    elif command == 'from':
        def fn(msg):
            return match_email_address(msg['from'], args)
        return eval_messages(series, fn, scope)
    elif command == 'committer':
        def fn(msg):
            if 'pull-request' in msg and 'commit' in msg['pull-request']:
                ret = match_email_address(msg['pull-request']['commit']['committer'], args)
                return ret
            elif 'committer' in msg:
                return match_email_address(msg['committer'], args)
            return False
        return eval_messages(series, fn, scope, cover=False)
    elif command == 'to':
        def fn(msg):
            for to in msg['to'] + msg['cc']:
                if match_email_address(to, args):
                    return True
            return False
        return eval_messages(series, fn, scope)
    elif command == 'id':
        def fn(msg):
            return msg['message-id'] == args
        return eval_messages(series, fn, scope)
    elif command == 'tag':
        def fn(msg):
            if not args:
                return 'subject-tags' in msg
            return 'subject-tags' in msg and args.upper() in msg['subject-tags']
        return eval_messages(series, fn, scope)
    elif command == 'release':
        def fn(msg):
            return 'for-release' in msg and msg['for-release'] == args
        return eval_messages(series, fn, scope)
    elif command and command.startswith('buildbot['):
        name = command[9:].split(']', 1)[0]
        if 'buildbots' in series and name in series['buildbots']:
            bot = series['buildbots'][name]
            steps = bot['steps']

            item = args
            fail = False
            if item[0] == '+':
                item = item[1:]
            elif item[0] == '-':
                item = item[1:]
                fail = True

            if item == 'status':
                if fail:
                    return bool(bot['status'])
                else:
                    return bool(not bot['status'])

            for step, status, output in steps:
                if step == item:
                    if fail:
                        return bool(status)
                    else:
                        return bool(not status)
            return False
    elif command != None:
        command = message.format_tag_name(command)
        email_tags = config.get_email_tags()

        def fn(msg):
            if command not in msg['tags']:
                return False
            if not args:
                return True
            if command in email_tags:
                for addr in msg['tags'][command]:
                    if match_flat_email_address(addr, args):
                        return True
                return False
            return args in msg['tags'][command]
        return eval_messages(series, fn, scope, cover=False)
    else:
        def fn(msg):
            return msg['subject'].lower().find(term.lower()) != -1
        return eval_messages(series, fn, scope)
Exemplo n.º 5
0
def add_tags(message, tags):
    lines = []
    payload = get_payload(message)

    in_sob = False
    done = False
    whitespace = []
    for line in payload.split('\n'):
        # if we've added our tags, we're done
        if done:
            lines.append(line)
            continue

        # is this line a tag
        tag = parse_tag(line, config.get_email_tags())
        if not in_sob and tag:
            in_sob = True

        if in_sob:
            # if it's a blank line, queue it for now
            if not line.strip():
                whitespace.append(line)
                continue

            if tag:
                key = tag.keys()[0]
                value = tag[key]

                # always drop message-id tags
                if key == 'Message-id':
                    continue

                # if we hit a tag and there's whitespace before the tag, preserve it
                if whitespace:
                    lines += whitespace
                    whitespace = []
                lines.append(line)

                # Don't duplicate tags
                if key in tags and value[0] in tags[key]:
                    tags[key] = list(set(tags[key]) - set(value))
            else:
                # we hit a non-blank line that isn't a tag
                done = True
                in_sob = False

                # append our tags before this line
                for key in tags:
                    for val in tags[key]:
                        if val:
                            lines.append('%s: %s' % (key, val))

                mid = message.get_message_id()
                if mid:
                    lines.append('Message-id: %s' % mid)

                # but before any whitespace preceeding this line
                if whitespace:
                    lines += whitespace
                    whitespace = []
                lines.append(line)
        else:
            lines.append(line)

    return '\n'.join(lines)
Exemplo n.º 6
0
def eval_query_term(series, term, scope):
    if term.find(':') != -1:
        command, args = term.split(':', 1)
    else:
        command = None

    if command == 'status':
        status = args.lower()

        if status == 'broken':
            return is_broken(series)
        elif status == 'obsolete':
            return is_obsolete(series)
        elif status == 'pull-request':
            return is_pull_request(series)
        elif status == 'rfc':
            return is_rfc(series)
        elif status == 'unapplied':
            return not (is_broken(series) or
                       is_obsolete(series) or
                       is_pull_request(series) or
                       is_rfc(series) or
                       is_committed(series) or
                       is_applied(series))
        elif status == 'committed':
            return is_committed(series)
        elif status == 'reviewed':
            return is_reviewed(series)
        elif status == 'applied':
            return is_applied(series)
        else:
            raise Exception("Unknown status `%s'" % status)
    elif command == 'label':
        txt = config.get_label(args)
        if txt == None:
            raise Exception('Invalid label %s' % args)
        tks = tokenize_query(txt)
        t, _ = parse_query(tks)
        return eval_query(series, t, scope)
    elif command == 'from':
        def fn(msg):
            return match_email_address(msg['from'], args)
        return eval_messages(series, fn, scope)
    elif command == 'committer':
        def fn(msg):
            if 'pull-request' in msg and 'commit' in msg['pull-request']:
                ret = match_email_address(msg['pull-request']['commit']['committer'], args)
                return ret
            elif 'committer' in msg:
                return match_email_address(msg['committer'], args)
            return False
        return eval_messages(series, fn, scope, cover=False)
    elif command == 'to':
        def fn(msg):
            for to in msg['to'] + msg['cc']:
                if match_email_address(to, args):
                    return True
            return False
        return eval_messages(series, fn, scope)
    elif command == 'id':
        def fn(msg):
            return msg['message-id'] == args
        return eval_messages(series, fn, scope)
    elif command == 'tag':
        def fn(msg):
            if not args:
                return 'subject-tags' in msg
            return 'subject-tags' in msg and args.upper() in msg['subject-tags']
        return eval_messages(series, fn, scope)
    elif command == 'release':
        def fn(msg):
            return 'for-release' in msg and msg['for-release'] == args
        return eval_messages(series, fn, scope)
    elif command and command.startswith('buildbot['):
        name = command[9:].split(']', 1)[0]
        if 'buildbots' in series and name in series['buildbots']:
            bot = series['buildbots'][name]
            steps = bot['steps']

            item = args
            fail = False
            if item[0] == '+':
                item = item[1:]
            elif item[0] == '-':
                item = item[1:]
                fail = True

            if item == 'status':
                if fail:
                    return bool(bot['status'])
                else:
                    return bool(not bot['status'])

            for step, status, output in steps:
                if step == item:
                    if fail:
                        return bool(status)
                    else:
                        return bool(not status)
            return False
    elif command != None:
        command = message.format_tag_name(command)
        email_tags = config.get_email_tags()

        def fn(msg):
            if command not in msg['tags']:
                return False
            if not args:
                return True
            if command in email_tags:
                for addr in msg['tags'][command]:
                    if match_flat_email_address(addr, args):
                        return True
                return False
            return args in msg['tags'][command]
        return eval_messages(series, fn, scope, cover=False)
    else:
        def fn(msg):
            return msg['subject'].lower().find(term.lower()) != -1
        return eval_messages(series, fn, scope)