forms.py 7.07 KB
Newer Older
1
# Django Imports
2
from django import forms
3
from django.core.exceptions import ValidationError
4
from django.utils.safestring import mark_safe
5 6 7 8 9

# App Imports
from go.models import URL, RegisteredUser

# Other Imports
David Haynes's avatar
David Haynes committed
10
from crispy_forms.helper import FormHelper
11 12
from crispy_forms.layout import Layout, Fieldset, Submit, HTML, Div, Field
from crispy_forms.bootstrap import StrictButton, PrependedText, Accordion, AccordionGroup
13 14

class URLForm(forms.ModelForm):
15

16 17 18 19 20 21 22 23
    # Prevent redirect loop links
    def clean_target(self):
        target = self.cleaned_data.get('target')
        if self.host in target:
            raise ValidationError("You can't make a Go link to Go silly!")
        else:
            return target

24 25 26
    # Custom target URL field
    target = forms.URLField(
        required=True,
27
        label='Long URL (Required)',
28 29
        max_length=1000,
        widget=forms.URLInput(attrs={
30
            'placeholder': 'https://yoursite.com/'
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
        })
    )

    # Check to make sure the short url has not been used
    def unique_short(value):
        try:
            URL.objects.get(short__iexact=value)
        except URL.DoesNotExist:
            return
        raise ValidationError('Short url already exists.')

    # Custom short-url field with validators.
    short = forms.SlugField(
        required=False,
        label='Short URL (Optional)',
        widget=forms.TextInput(),
        validators=[unique_short],
        max_length=20,
        min_length=3,
    )

    DAY = '1 Day'
    WEEK = '1 Week'
    MONTH = '1 Month'
    NEVER = 'Never'

    EXPIRATION_CHOICES = (
        (DAY, DAY),
        (WEEK, WEEK),
        (MONTH, MONTH),
        (NEVER, NEVER),
    )

    # Add a custom expiration choice field.
    expires = forms.ChoiceField(
        required=True,
67
        label='Expiration (Required)',
68 69 70 71 72
        choices=EXPIRATION_CHOICES,
        initial=NEVER,
        widget=forms.RadioSelect(),
    )

73

74
    def __init__(self, *args, **kwargs):
75 76
        # Grab that host info
        self.host = kwargs.pop('host', None)
77
        super(URLForm, self).__init__(*args, **kwargs)
78
        # Define the basics for crispy-forms
79
        self.helper = FormHelper()
80
        self.helper.form_method = 'POST'
81

82
        # Some xtra vars for form css purposes
83 84 85 86
        self.helper.form_class = 'form-horizontal'
        self.helper.label_class = 'col-md-1'
        self.helper.field_class = 'col-md-6'

87
        # The main "layout" defined
88
        self.helper.layout = Layout(
89 90
            Fieldset('',
            #######################
91
                Accordion(
92
                    # Step 1: Long URL
93 94 95 96
                    AccordionGroup('Step 1: Long URL',
                        Div(
                            HTML("""
                                <h4>Paste the URL you would like to shorten:</h4>
97
                                <br />"""),
98
                            'target',
99
                            style="background: rgb(#F6F6F6);"),
100
                        active=True,
101 102 103
                        template='crispy/accordian-group.html'),

                    # Step 2: Short URL
104 105 106 107
                    AccordionGroup('Step 2: Short URL',
                        Div(
                            HTML("""
                                <h4>Create a custom Go address:</h4>
108 109 110 111
                                <br />"""),
                            PrependedText(
                            'short', 'https://go.gmu.edu/'),
                            style="background: rgb(#F6F6F6);"),
112
                        active=True,
113 114 115
                        template='crispy/accordian-group.html',),

                    # Step 3: Expiration
116 117 118 119
                    AccordionGroup('Step 3: URL Expiration',
                        Div(
                            HTML("""
                                <h4>Set when you would like your Go address to expire:</h4>
120
                                <br />"""),
121
                            'expires',
122
                            style="background: rgb(#F6F6F6);"),
123
                        active=True,
124
                        template='crispy/accordian-group.html'),
125

126 127 128 129 130 131
                    # FIN
                    template='crispy/accordian.html'),
            #######################
            HTML("""
                <br />"""),
            StrictButton('Shorten', css_class="btn btn-primary btn-md col-md-4", type='submit')))
132

133 134 135 136 137 138
    class Meta:
        model = URL
        fields = ('target',)
        exclude = ('owner', 'short', 'date_created', 'clicks', 'expires')


139
class SignupForm(forms.ModelForm):
140 141 142 143 144 145 146 147

    def validate_username(username):
        try:
            registered = RegisteredUser.objects.get(username=username)
            raise ValidationError('Username "%s" is already in use.' % username)
        except RegisteredUser.DoesNotExist:
            return

148 149 150 151 152 153 154
    def clean_username(self):
        # Prevent hax: (non-staff) Users cannot signup for other users
        data_username = self.cleaned_data.get("username")

        if not self.request.user.is_staff:
            if self.request.user.username not in data_username:
                raise ValidationError('username', "This is not your NetID!")
155
        return data_username
156

157
    username = forms.CharField(
158
        required=True,
159
        label='Mason NetID (Required)',
160
        max_length=30,
161
        validators=[validate_username],
162
        widget=forms.TextInput(attrs={
163 164 165
        }),
    )
    full_name = forms.CharField(
166
        required=True,
167
        label='Full Name (Required)',
168 169
        max_length=100,
        widget=forms.TextInput(attrs={
170 171
        }),
    )
172 173 174 175 176 177 178
    organization = forms.CharField(
        required=True,
        label='Organization (Required)',
        max_length=100,
        widget=forms.TextInput(attrs={
        })
    )
179
    description = forms.CharField(
180 181 182 183
        required=False,
        label='Description (Optional)',
        max_length=200,
        widget=forms.Textarea(attrs={
184 185
        }),
    )
186 187
    tos_box = forms.BooleanField(
        required=True,
188
        # Need to add a Terms of Service Page and replace the href below
189 190 191
        label = mark_safe('Do you accept the <a href="#" target="_blank">Terms of Service</a>?'),
    )

192 193 194 195
    def __init__(self, request, *args, **kwargs):
        # Necessary to call request in forms.py, is otherwise restricted to views.py and models.py
        self.request = request
        super(SignupForm, self).__init__(*args, **kwargs)
David Haynes's avatar
David Haynes committed
196
        self.helper = FormHelper()
197 198 199 200 201
        self.helper.form_class = 'form-horizontal'
        self.helper.label_class = 'col-md-4'
        self.helper.field_class = 'col-md-6'

        self.helper.layout = Layout(
202
            Fieldset('',
203
                Div(
204
                    # Place in form fields
205 206 207 208 209 210
                    Div(
                        'username',
                        'full_name',
                        'organization',
                        'description',
                        'tos_box',
211 212 213
                        css_class='well'),

                    # Extras at bottom
214
                    StrictButton('Submit',css_class='btn btn-primary btn-md col-md-4', type='submit'),
215
                    css_class='col-md-6')))
216 217
    class Meta:
        model = RegisteredUser
218
        fields = '__all__'