<commit_before>import re

from django import forms
from django.contrib.auth import get_user_model
from django.core.exceptions import ObjectDoesNotExist
from django.db import IntegrityError, transaction
from django.db.models import Q
from django.utils.text import slugify

from recurrence.forms import RecurrenceField
from utils.db import get_max_order
from utils import colors
from utils.user_utils import date_hash

from . models import Action, Behavior, Category, Goal, Trigger
from . permissions import ContentPermissions
from . utils import read_uploaded_csv
from . widgets import TimeSelectWidget


class ActionForm(forms.ModelForm):
    """A Form for creating/updating actions. This form orders related behaviors
    alphabetically."""

    # Initial content for differnt types of Actions
    INITIAL = {
        Action.TINY: {
            'title': 'Try a tiny version',
            'notification_text': 'Try a tiny version',
            'description': (
                "Large tasks can seem intimidating and difficult. Instead of "
                "trying to tackle them all at once, try starting with a "
                "“tiny action.”"
            ),
            'more_info': (
                "A tiny action is simply a tinier version of your target task. "
                "Tiny versions will make you feel successful and motivated to "
                "take on your larger goal. So try whittling your goal down to "
                "its smallest parts, and start celebrating tiny victories on "
                "your path to achievement!"
            ),
            'action_type': Action.TINY,
        },
        Action.STARTER: {
            'title': 'Try a starter step',
            'notification_text': 'Try a starter step',
            'description': (
                "Sometimes we let the little things prevent us from starting "
                "the tasks we want to do. Make activities more manageable by "
                "taking a “starter step.”"
            ),
            'more_info': (
                "A starter step is the first small action in a sequence of "
                "actions that lead to your ultimate goal. When you perform "
                "these small steps, you make your task more manageable and "
                "prepare yourself for success."
            ),
            'action_type': Action.STARTER,
        },
        Action.RESOURCE: {
            'title': 'Try a helpful tool',
            'notification_text': 'Try a helpful tool',
            'description': (
                "We’ve picked some of the best tools and resources to help "
                "you succeed. Give them a try."
            ),
            'action_type': Action.RESOURCE,
        },
        Action.NOW: {
            'title': 'Do it now',
            'notification_text': 'Do it now',
            'description': (
                "When it comes to achieving your goals, there’s no time like "
                "the present. Consider performing this action right now, while "
                "it’s fresh on your mind."
            ),
            'action_type': Action.NOW,
        },
        Action.LATER: {
            'title': 'Do it later',
            'notification_text': 'Do it later',
            'description': (
                "Life is demanding. If you can’t do this right now, don’t "
                "worry! Set a reminder to do it later."
            ),
            'action_type': Action.LATER,
        },
        Action.CUSTOM: {
            'action_type': Action.CUSTOM,
        },
    }

    behavior = forms.ModelChoiceField(
        queryset=Behavior.objects.all().order_by("title")
    )

    # Note: this field's value should always get in the initial data
    action_type = forms.CharField(
        max_length=32,
        widget=forms.HiddenInput(),
    )

    class Meta:
        model = Action
        fields = [
            'notification_text', 'sequence_order', 'behavior', 'title',
            'description', 'more_info', 'external_resource',
            'source_link', 'source_notes', 'notes', 'icon', 'action_type',
        ]
        labels = {"notes": "Scratchpad"}

    class Media:
        js = (
            "foundation/js/vendor/jquery.js",
            "js/action_form.js",
        )


class BehaviorForm(forms.ModelForm):
    """A Form for creating/updating behaviors. This form orders related
    goals alphabetically."""
    goals = forms.ModelMultipleChoiceField(
        queryset=Goal.objects.all().order_by("title")
    )

    class Meta:
        model = Behavior
        fields = [
            'title', 'description', 'more_info', 'informal_list', 'notes',
            'external_resource', 'goals', 'icon', 'source_link', 'source_notes',
        ]
        labels = {"notes": "Scratchpad", 'informal_list': 'Action List'}


def _contributors():
    """Returns a QuerySet of Users that can be Package Contributors.

    Those users are either staff or have ContentPermissions.

    """
    User = get_user_model()
    return User.objects.filter(
        Q(user_permissions__codename__in=ContentPermissions.all_codenames) |
        Q(is_staff=True)
    ).distinct()


class ContributorChoiceField(forms.ModelMultipleChoiceField):
    def label_from_instance(self, obj):
            return obj.get_full_name()


class CategoryForm(forms.ModelForm):
    """A Form for creating/updateing Categories. This form customizes the widget
    for the color field."""

    package_contributors = ContributorChoiceField(queryset=_contributors())

    class Meta:
        model = Category
        fields = [
            'packaged_content', 'package_contributors', 'order', 'title',
            'description', 'icon', 'image', 'color', 'secondary_color', 'notes',
        ]
        labels = {"order": "Default Order", "notes": "Scratchpad"}
        widgets = {
            "color": forms.TextInput(attrs={'class': 'color-picker', 'type': 'color'}),
            "secondary_color": forms.TextInput(attrs={'class': 'color-picker', 'type': 'color'}),
        }

    def __init__(self, *args, **kwargs):
        initial = kwargs.get('initial', {})
        instance = kwargs.get('instance')<commit_msg>check groups for appropriate permissions to populate the contributors options<commit_after>import re

from django import forms
from django.contrib.auth import get_user_model
from django.core.exceptions import ObjectDoesNotExist
from django.db import IntegrityError, transaction
from django.db.models import Q
from django.utils.text import slugify

from recurrence.forms import RecurrenceField
from utils.db import get_max_order
from utils import colors
from utils.user_utils import date_hash

from . models import Action, Behavior, Category, Goal, Trigger
from . permissions import ContentPermissions
from . utils import read_uploaded_csv
from . widgets import TimeSelectWidget


class ActionForm(forms.ModelForm):
    """A Form for creating/updating actions. This form orders related behaviors
    alphabetically."""

    # Initial content for differnt types of Actions
    INITIAL = {
        Action.TINY: {
            'title': 'Try a tiny version',
            'notification_text': 'Try a tiny version',
            'description': (
                "Large tasks can seem intimidating and difficult. Instead of "
                "trying to tackle them all at once, try starting with a "
                "“tiny action.”"
            ),
            'more_info': (
                "A tiny action is simply a tinier version of your target task. "
                "Tiny versions will make you feel successful and motivated to "
                "take on your larger goal. So try whittling your goal down to "
                "its smallest parts, and start celebrating tiny victories on "
                "your path to achievement!"
            ),
            'action_type': Action.TINY,
        },
        Action.STARTER: {
            'title': 'Try a starter step',
            'notification_text': 'Try a starter step',
            'description': (
                "Sometimes we let the little things prevent us from starting "
                "the tasks we want to do. Make activities more manageable by "
                "taking a “starter step.”"
            ),
            'more_info': (
                "A starter step is the first small action in a sequence of "
                "actions that lead to your ultimate goal. When you perform "
                "these small steps, you make your task more manageable and "
                "prepare yourself for success."
            ),
            'action_type': Action.STARTER,
        },
        Action.RESOURCE: {
            'title': 'Try a helpful tool',
            'notification_text': 'Try a helpful tool',
            'description': (
                "We’ve picked some of the best tools and resources to help "
                "you succeed. Give them a try."
            ),
            'action_type': Action.RESOURCE,
        },
        Action.NOW: {
            'title': 'Do it now',
            'notification_text': 'Do it now',
            'description': (
                "When it comes to achieving your goals, there’s no time like "
                "the present. Consider performing this action right now, while "
                "it’s fresh on your mind."
            ),
            'action_type': Action.NOW,
        },
        Action.LATER: {
            'title': 'Do it later',
            'notification_text': 'Do it later',
            'description': (
                "Life is demanding. If you can’t do this right now, don’t "
                "worry! Set a reminder to do it later."
            ),
            'action_type': Action.LATER,
        },
        Action.CUSTOM: {
            'action_type': Action.CUSTOM,
        },
    }

    behavior = forms.ModelChoiceField(
        queryset=Behavior.objects.all().order_by("title")
    )

    # Note: this field's value should always get in the initial data
    action_type = forms.CharField(
        max_length=32,
        widget=forms.HiddenInput(),
    )

    class Meta:
        model = Action
        fields = [
            'notification_text', 'sequence_order', 'behavior', 'title',
            'description', 'more_info', 'external_resource',
            'source_link', 'source_notes', 'notes', 'icon', 'action_type',
        ]
        labels = {"notes": "Scratchpad"}

    class Media:
        js = (
            "foundation/js/vendor/jquery.js",
            "js/action_form.js",
        )


class BehaviorForm(forms.ModelForm):
    """A Form for creating/updating behaviors. This form orders related
    goals alphabetically."""
    goals = forms.ModelMultipleChoiceField(
        queryset=Goal.objects.all().order_by("title")
    )

    class Meta:
        model = Behavior
        fields = [
            'title', 'description', 'more_info', 'informal_list', 'notes',
            'external_resource', 'goals', 'icon', 'source_link', 'source_notes',
        ]
        labels = {"notes": "Scratchpad", 'informal_list': 'Action List'}


def _contributors():
    """Returns a QuerySet of Users that can be Package Contributors.

    Those users are either staff or have ContentPermissions (either permissions
    directory or through a Group membership).

    """
    User = get_user_model()
    return User.objects.filter(
        Q(user_permissions__codename__in=ContentPermissions.all_codenames) |
        Q(groups__permissions__codename__in=ContentPermissions.all_codenames) |
        Q(is_staff=True)
    ).distinct()


class ContributorChoiceField(forms.ModelMultipleChoiceField):
    def label_from_instance(self, obj):
            return obj.get_full_name()


class CategoryForm(forms.ModelForm):
    """A Form for creating/updateing Categories. This form customizes the widget
    for the color field."""

    package_contributors = ContributorChoiceField(queryset=_contributors())

    class Meta:
        model = Category
        fields = [
            'packaged_content', 'package_contributors', 'order', 'title',
            'description', 'icon', 'image', 'color', 'secondary_color', 'notes',
        ]
        labels = {"order": "Default Order", "notes": "Scratchpad"}
        widgets = {
            "color": forms.TextInput(attrs={'class': 'color-picker', 'type': 'color'}),
            "secondary_color": forms.TextInput(attrs={'class': 'color-picker', 'type': 'color'}),
        }

    def __init__(self, *args, **kwargs):
        initial = kwargs.get('initial', {})
        instance = kwargs.get('instance')
{'fraction_non_alphanumeric': 0.10053587139086619, 'fraction_numerical': 0.00031992321842757736, 'mean_word_length': 2.1488290103248553, 'pattern_counts': {'":': 12, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '6118133', 'n_tokens_mistral': 3327, 'n_tokens_neox': 3229, 'n_words': 1053}