<commit_before># Universal Subtitles, universalsubtitles.org
#
# Copyright (C) 2011 Participatory Culture Foundation
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see
# http://www.gnu.org/licenses/agpl-3.0.html.

from utils.translation import SUPPORTED_LANGUAGES_DICT
from teams.models import (
    Team, MembershipNarrowing, Workflow, TeamMember, Project, TeamVideoLanguage, Task
)

from teams.permissions_const import (
    ROLES_ORDER, ROLE_OWNER, ROLE_CONTRIBUTOR, ROLE_ADMIN, ROLE_MANAGER,
    ROLE_OUTSIDER
)


def _perms_equal_or_lower(role, include_outsiders=False):
    """Return a list of roles equal to or less powerful than the given role.

    If `include_outsiders` is given ROLE_OUTSIDER may be included.

    """
    roles = ROLES_ORDER

    if include_outsiders:
        roles = roles + [ROLE_OUTSIDER]

    return roles[roles.index(role):]

def _perms_equal_or_greater(role, include_outsiders=False):
    """Return a list of roles equal to or more powerful than the given role.

    If `include_outsiders` is given ROLE_OUTSIDER may be included.

    """
    roles = ROLES_ORDER

    if include_outsiders:
        roles = roles + [ROLE_OUTSIDER]

    return roles[:roles.index(role) + 1]


# Utility functions
def get_member(user, team):
    """Return the TeamMember object (or None) for the given user/team."""

    if not user.is_authenticated():
        return None

    try:
        return team.members.get(user=user)
    except TeamMember.DoesNotExist:
        return None

def get_role(member):
    """Return the member's general role in the team.

    Does NOT take narrowings into account!

    """
    if not member:
        return ROLE_OUTSIDER
    else:
        return member.role

def get_role_for_target(user, team, project=None, lang=None):
    """Return the role the given user effectively has for the given target.

    `lang` should be a string (the language code).

    """
    member = get_member(user, team)
    role = get_role(member)
    narrowings = get_narrowings(member)

    # If the user has no narrowings, just return their overall role.
    if not narrowings:
        return role

    # Otherwise the narrowings must match the target.
    project_narrowings = [n.project for n in narrowings if n.project]
    lang_narrowings = [n.language for n in narrowings if n.language]

    # The default project is the same as "no project".
    if project and project.is_default_project:
        project = None

    if project_narrowings and project not in project_narrowings:
        return ROLE_CONTRIBUTOR

    if lang_narrowings and lang not in lang_narrowings:
        return ROLE_CONTRIBUTOR

    return role


def roles_user_can_assign(team, user, to_user=None):
    """Return a list of the roles the given user can assign for the given team.

    Rules:

        * Unrestricted owners can assign all roles.
        * Unrestricted admins can assign any other role (for now).
        * No one else can assign any roles.
        * Admins cannot change the role of an owner.

    """
    user_role = get_role_for_target(user, team)

    if user_role == ROLE_OWNER:
        return ROLES_ORDER
    elif user_role == ROLE_ADMIN:
        if to_user:
            if get_role(get_member(to_user, team)) == ROLE_OWNER:
                return []
        return ROLES_ORDER[1:]
    else:
        return []

def roles_user_can_invite(team, user):
    """Return a list of the roles the given user can invite for the given team.

    Rules:

        * Unrestricted owners can invite all roles.
        * Unrestricted admins can invite any non-owner role.
        * Everyone else can only invite contributors.

    """
    user_role = get_role_for_target(user, team)

    if user_role == ROLE_OWNER:
        return ROLES_ORDER
    elif user_role == ROLE_ADMIN:
        return ROLES_ORDER[1:]
    else:
        return [ROLE_CONTRIBUTOR]


# Narrowings
def get_narrowings(member):
    """Return narrowings for the given member in the given team."""<commit_msg>Owners can't be assigned by team members.<commit_after># Universal Subtitles, universalsubtitles.org
#
# Copyright (C) 2011 Participatory Culture Foundation
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see
# http://www.gnu.org/licenses/agpl-3.0.html.

from utils.translation import SUPPORTED_LANGUAGES_DICT
from teams.models import (
    Team, MembershipNarrowing, Workflow, TeamMember, Project, TeamVideoLanguage, Task
)

from teams.permissions_const import (
    ROLES_ORDER, ROLE_OWNER, ROLE_CONTRIBUTOR, ROLE_ADMIN, ROLE_MANAGER,
    ROLE_OUTSIDER
)


def _perms_equal_or_lower(role, include_outsiders=False):
    """Return a list of roles equal to or less powerful than the given role.

    If `include_outsiders` is given ROLE_OUTSIDER may be included.

    """
    roles = ROLES_ORDER

    if include_outsiders:
        roles = roles + [ROLE_OUTSIDER]

    return roles[roles.index(role):]

def _perms_equal_or_greater(role, include_outsiders=False):
    """Return a list of roles equal to or more powerful than the given role.

    If `include_outsiders` is given ROLE_OUTSIDER may be included.

    """
    roles = ROLES_ORDER

    if include_outsiders:
        roles = roles + [ROLE_OUTSIDER]

    return roles[:roles.index(role) + 1]


# Utility functions
def get_member(user, team):
    """Return the TeamMember object (or None) for the given user/team."""

    if not user.is_authenticated():
        return None

    try:
        return team.members.get(user=user)
    except TeamMember.DoesNotExist:
        return None

def get_role(member):
    """Return the member's general role in the team.

    Does NOT take narrowings into account!

    """
    if not member:
        return ROLE_OUTSIDER
    else:
        return member.role

def get_role_for_target(user, team, project=None, lang=None):
    """Return the role the given user effectively has for the given target.

    `lang` should be a string (the language code).

    """
    member = get_member(user, team)
    role = get_role(member)
    narrowings = get_narrowings(member)

    # If the user has no narrowings, just return their overall role.
    if not narrowings:
        return role

    # Otherwise the narrowings must match the target.
    project_narrowings = [n.project for n in narrowings if n.project]
    lang_narrowings = [n.language for n in narrowings if n.language]

    # The default project is the same as "no project".
    if project and project.is_default_project:
        project = None

    if project_narrowings and project not in project_narrowings:
        return ROLE_CONTRIBUTOR

    if lang_narrowings and lang not in lang_narrowings:
        return ROLE_CONTRIBUTOR

    return role


def roles_user_can_assign(team, user, to_user=None):
    """Return a list of the roles the given user can assign for the given team.

    Rules:

        * Unrestricted admins and owners can assign any role but owners.
        * No one else can assign any roles.
        * Admins cannot change the role of an owner.

    """
    user_role = get_role_for_target(user, team)

    if user_role == ROLE_OWNER:
        return ROLES_ORDER[1:]
    elif user_role == ROLE_ADMIN:
        if to_user:
            if get_role(get_member(to_user, team)) == ROLE_OWNER:
                return []
        return ROLES_ORDER[1:]
    else:
        return []

def roles_user_can_invite(team, user):
    """Return a list of the roles the given user can invite for the given team.

    Rules:

        * Unrestricted owners can invite all roles.
        * Unrestricted admins can invite any non-owner role.
        * Everyone else can only invite contributors.

    """
    user_role = get_role_for_target(user, team)

    if user_role == ROLE_OWNER:
        return ROLES_ORDER
    elif user_role == ROLE_ADMIN:
        return ROLES_ORDER[1:]
    else:
        return [ROLE_CONTRIBUTOR]


# Narrowings
def get_narrowings(member):
    """Return narrowings for the given member in the given team."""
{'fraction_non_alphanumeric': 0.06929497034922029, 'fraction_numerical': 0.002306171754886888, 'mean_word_length': 3.1339083068542894, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, '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': '3187279', 'n_tokens_mistral': 2765, 'n_tokens_neox': 2664, 'n_words': 1002}