<commit_before>import re

from distutils.util import strtobool
from string import digits  # pylint: disable=deprecated-module

import arrow

from autoslug import AutoSlugField

from django.contrib.auth.models import AnonymousUser
from django.contrib.postgres.fields import ArrayField
from django.db import models, router
from django.db.models.deletion import Collector

from oauth2_provider.models import AccessToken, Application, RefreshToken

from common.utils import app_label_to_verbose_name, generate_id
from data_import.models import DataFile
from open_humans.models import Member
from open_humans.storage import PublicStorage

active_help_text = """"Active" status is required to perform authorization
processes, including during drafting stage. If a project is not active, it
won't show up in listings of activities that can be joined by participants, and
new data sharing authorizations cannot occur. Projects which are "active" but
not approved may have some information shared in an "In Development" section,
so Open Humans members can see potential upcoming studies. Removing "active"
status from a project will not remove any uploaded files from a project
member's profile."""

post_sharing_url_help_text = """If provided, after authorizing sharing the
member will be taken to this URL. If this URL includes "PROJECT_MEMBER_ID"
within it, we will replace that with the member's project-specific
project_member_id. This allows you to direct them to an external survey you
operate (e.g. using Google Forms) where a pre-filled project_member_id field
allows you to connect those responses to corresponding data in Open Humans."""


def now_plus_24_hours():
    """
    Return a datetime 24 hours in the future.
    """
    return arrow.utcnow().replace(hours=+24).datetime


def id_label_to_project(id_label):
    """
    Given a project's id_label, return the project.
    """
    match = re.match(r'direct-sharing-(?P<id>\d+)', id_label)

    if match:
        project = DataRequestProject.objects.get(id=int(match.group('id')))
        return project


def app_label_to_verbose_name_including_dynamic(label):
    """
    Given an app's name, return its verbose name.
    """
    try:
        return app_label_to_verbose_name(label)
    except LookupError:
        match = re.match(r'direct-sharing-(?P<id>\d+)', label)

        if match:
            project = DataRequestProject.objects.get(id=int(match.group('id')))

            return project.name


def badge_upload_path(instance, filename):
    """
    Construct the upload path for a project's badge image.
    """
    return 'direct-sharing/badges/{0}/{1}'.format(instance.id, filename)


def get_visible_user_projects(member):
    """
    Returns a list of projects where membership is publicly
    visible.
    """
    projects = []
    project_ids = DataRequestProjectMember.objects.filter(visible=True,
                                                          member_id=member.id).values_list(
                                                              'project_id', flat=True)
    for project_id in project_ids:
        projects.append(DataRequestProject.objects.get(id=project_id))
    return projects


def project_membership_visible(member, source):
    """
    Determine if the user's membership in a project is visible or not.
    """
    project = id_label_to_project(source)

    if project is not None:
        if DataRequestProjectMember.objects.filter(member=member).exists():
            project_member = DataRequestProjectMember.objects.get(member=member,
                                                                  project=project)
            return bool(project_member.visible)

    return False


def toggle_membership_visibility(user, source, state):
    """
    Change the state of whether a member's data sharing is publicly visible or not.
    """
    project = id_label_to_project(source)<commit_msg>Filter badges on approved (#852)<commit_after>import re

from distutils.util import strtobool
from string import digits  # pylint: disable=deprecated-module

import arrow

from autoslug import AutoSlugField

from django.contrib.auth.models import AnonymousUser
from django.contrib.postgres.fields import ArrayField
from django.db import models, router
from django.db.models.deletion import Collector

from oauth2_provider.models import AccessToken, Application, RefreshToken

from common.utils import app_label_to_verbose_name, generate_id
from data_import.models import DataFile
from open_humans.models import Member
from open_humans.storage import PublicStorage

active_help_text = """"Active" status is required to perform authorization
processes, including during drafting stage. If a project is not active, it
won't show up in listings of activities that can be joined by participants, and
new data sharing authorizations cannot occur. Projects which are "active" but
not approved may have some information shared in an "In Development" section,
so Open Humans members can see potential upcoming studies. Removing "active"
status from a project will not remove any uploaded files from a project
member's profile."""

post_sharing_url_help_text = """If provided, after authorizing sharing the
member will be taken to this URL. If this URL includes "PROJECT_MEMBER_ID"
within it, we will replace that with the member's project-specific
project_member_id. This allows you to direct them to an external survey you
operate (e.g. using Google Forms) where a pre-filled project_member_id field
allows you to connect those responses to corresponding data in Open Humans."""


def now_plus_24_hours():
    """
    Return a datetime 24 hours in the future.
    """
    return arrow.utcnow().replace(hours=+24).datetime


def id_label_to_project(id_label):
    """
    Given a project's id_label, return the project.
    """
    match = re.match(r'direct-sharing-(?P<id>\d+)', id_label)

    if match:
        project = DataRequestProject.objects.get(id=int(match.group('id')))
        return project


def app_label_to_verbose_name_including_dynamic(label):
    """
    Given an app's name, return its verbose name.
    """
    try:
        return app_label_to_verbose_name(label)
    except LookupError:
        match = re.match(r'direct-sharing-(?P<id>\d+)', label)

        if match:
            project = DataRequestProject.objects.get(id=int(match.group('id')))

            return project.name


def badge_upload_path(instance, filename):
    """
    Construct the upload path for a project's badge image.
    """
    return 'direct-sharing/badges/{0}/{1}'.format(instance.id, filename)


def get_visible_user_projects(member):
    """
    Returns a list of projects where membership is publicly
    visible.
    """
    projects = DataRequestProjectMember.objects.select_related('project').filter(
        visible=True, project__approved=True,
        member_id=member.id)

    return [project_member.project for project_member in projects]


def project_membership_visible(member, source):
    """
    Determine if the user's membership in a project is visible or not.
    """
    project = id_label_to_project(source)

    if project is not None:
        if DataRequestProjectMember.objects.filter(member=member).exists():
            project_member = DataRequestProjectMember.objects.get(member=member,
                                                                  project=project)
            return bool(project_member.visible)

    return False


def toggle_membership_visibility(user, source, state):
    """
    Change the state of whether a member's data sharing is publicly visible or not.
    """
    project = id_label_to_project(source)
{'fraction_non_alphanumeric': 0.07701344472001044, 'fraction_numerical': 0.0027411565069834225, 'mean_word_length': 3.512367491166078, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4707144', 'n_tokens_mistral': 2094, 'n_tokens_neox': 1990, 'n_words': 701}