<commit_before>#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
""" ASF PMC style voting plugin """
from lib import constants, voter

def tallyAP(votes, issue):
    """ Simple YNA tallying
    :param votes: The JSON object from $issueid.json.votes
    :return: y,n,a as numbers
    """
    y = n = a = 0
    by = bn = 0
    for vote in votes.values():
        if vote == 'y':
            y += 1
        elif vote == 'n':
            n += 1
        elif vote == 'a':
            a += 1
        elif vote == 'by':
            by += 1
        elif vote == 'bn':
            bn += 1
        else:
            raise Exception("Invalid vote found in votes db!")

    js = {
        'votes': len(votes),
        'yes': y,
        'no': n,
        'abstain': a,
        'binding_yes': by,
        'binding_no': bn
    }
    
    return js, """
Yes:            %4u
No:             %4u
Abstain:        %4u
Binding Yes:    %4u
Binding No:     %4u
""" % (y,n,a,by,bn)


def validateAP(vote, issue):
    "Tries to validate a vote, returns why if not valid, None otherwise"
    letters = ['y','n','a', 'by', 'bn']
    if len(vote) >= 3 or not vote in letters:
        return "Invalid vote. Accepted votes are: %s" % ", ".join(letters)
    return None


# Verification process
def verifyAP(basedata, issueID, voterID, vote):
    "Invalidate a binding vote if not allowed to cast such"
    email = voter.get(basedata['id'], basedata, voterID)
    if vote.startswith('b'):
        # Simple check example: if not apache committer, discard vote if binding
        if not email.endswith("@apache.org"):
            raise Exception("You are not allowed to cast a binding vote!")


constants.appendVote(
    {
        'key': "ap",
        'description': "ASF PMC Style vote (YNA with binding votes)",<commit_msg>uid is now passed to validator, no need to fetch it ourselves<commit_after>#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
""" ASF PMC style voting plugin """
from lib import constants

def tallyAP(votes, issue):
    """ Simple YNA tallying
    :param votes: The JSON object from $issueid.json.votes
    :return: dict with y,n,a,by,bn numbers as well as pretty-printed version
    """
    y = n = a = 0
    by = bn = 0
    # For each vote cast, tally it
    for vote in votes.values():
        if vote == 'y':
            y += 1
        elif vote == 'n':
            n += 1
        elif vote == 'a':
            a += 1
        elif vote == 'by':
            by += 1
        elif vote == 'bn':
            bn += 1
        else:
            raise Exception("Invalid vote found in votes db!")

    js = {
        'votes': len(votes),
        'yes': y,
        'no': n,
        'abstain': a,
        'binding_yes': by,
        'binding_no': bn
    }
    
    return js, """
Yes:            %4u
No:             %4u
Abstain:        %4u
Binding Yes:    %4u
Binding No:     %4u
""" % (y,n,a,by,bn)


def validateAP(vote, issue):
    "Tries to validate a vote, returns why if not valid, None otherwise"
    letters = ['y','n','a', 'by', 'bn']
    if len(vote) >= 3 or not vote in letters:
        return "Invalid vote. Accepted votes are: %s" % ", ".join(letters)
    return None


# Verification process
def verifyAP(basedata, issueID, voterID, vote, uid):
    "Invalidate a binding vote if not allowed to cast such"
    if vote.startswith('b'):
        # Simple check example: if not apache committer, discard vote if binding
        if not uid.endswith("@apache.org"):
            raise Exception("You are not allowed to cast a binding vote!")


constants.appendVote(
    {
        'key': "ap",
        'description': "ASF PMC Style vote (YNA with binding votes)",
{'fraction_non_alphanumeric': 0.10678662233522394, 'fraction_numerical': 0.006649716409153139, 'mean_word_length': 2.4884038199181444, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7288086', 'n_tokens_mistral': 1512, 'n_tokens_neox': 1470, 'n_words': 634}