forms.py 7.24 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
    # Custom target URL field
    target = forms.URLField(
        required=True,
19
        label='Long URL (Required)',
20
21
        max_length=1000,
        widget=forms.URLInput(attrs={
22
            'placeholder': 'https://yoursite.com/'
23
24
25
26
27
28
29
30
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
        })
    )

    # 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,
59
        label='Expiration (Required)',
60
61
62
63
64
65
        choices=EXPIRATION_CHOICES,
        initial=NEVER,
        widget=forms.RadioSelect(),
    )

    def __init__(self, *args, **kwargs):
66
        super(URLForm, self).__init__(*args, **kwargs)
67
        self.helper = FormHelper()
68
        self.helper.form_method = 'POST'
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

        self.helper.form_class = 'form-horizontal'
        self.helper.label_class = 'col-md-1'
        self.helper.field_class = 'col-md-6'


        self.helper.layout = Layout(
            Fieldset(
                '',
                Accordion(
                    AccordionGroup('Step 1: Long URL',
                        Div(
                            HTML("""
                                <h4>Paste the URL you would like to shorten:</h4>
                                <br />
                            """),
85
                            'target',
86
87
88
89
                            style="background: rgb(#F6F6F6);",
                            title="target_url",
                            css_class="first_group",
                        ),
90
91
92
                        css_id='firstCollapse',
                        active=True,
                        template='crispy/accordian-group.html',
93
94
95
96
97
                    ),
                    AccordionGroup('Step 2: Short URL',
                        Div(
                            HTML("""
                                <h4>Create a custom Go address:</h4>
98
                                <br />
99
100
                            """),
                            PrependedText('short',
101
                            'https://go.gmu.edu/',
102
103
104
105
                            ),
                            style="background: rgb(#F6F6F6);",
                            title="short_url",
                            css_class="second_group",
106
107
                        ),
                        css_id='secondCollapse',
108
                        active=True,
109
                        template='crispy/accordian-group.html',
110
111
112
113
114
                    ),
                    AccordionGroup('Step 3: URL Expiration',
                        Div(
                            HTML("""
                                <h4>Set when you would like your Go address to expire:</h4>
115
                                <br />
116
117
118
119
120
                            """),
                            'expires',
                            style="background: rgb(#F6F6F6);",
                            title="expires_url",
                            css_class="third_group",
121
122
                        ),
                        css_id='thirdCollapse',
123
                        active=True,
124
125
126
127
                        template='crispy/accordian-group.html',
                    ),
                    css_id='accordian',
                    template='crispy/accordian.html'
128
129
130
131
                ),
            HTML("""
                <br />
            """),
David Haynes's avatar
David Haynes committed
132
            StrictButton('Shorten', css_class="btn btn-primary btn-md col-md-4", type='submit'),
133
134
135
        )
    )

136

137
138
139
140
141
142
    class Meta:
        model = URL
        fields = ('target',)
        exclude = ('owner', 'short', 'date_created', 'clicks', 'expires')


143
class SignupForm(forms.ModelForm):
144
145
146
147
148
149
150
151

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

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

    def clean_username(self):
        # Prevent hax: (non-staff) Users cannot signup for other users
        cleaned_data = super(SignupForm, self).clean()
        data_username = cleaned_data.get("username")

        if not self.request.user.is_staff:
            if self.request.user.username not in data_username:
                self.add_error('username', "This is not your NetID!")
        return data_username
196

197
198
199
200
201

    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
202
        self.helper = FormHelper()
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
        self.helper.form_class = 'form-horizontal'
        self.helper.label_class = 'col-md-4'
        self.helper.field_class = 'col-md-6'

        self.helper.layout = Layout(
            Fieldset(
                '',
                Div(
                    Div(
                        'username',
                        'full_name',
                        'organization',
                        'description',
                        'tos_box',
                        css_class='well',
                    ),
                    StrictButton('Submit',css_class='btn btn-primary btn-md col-md-4', type='submit'),
                    css_class='col-md-6',
                ),
            )
        )
224
225
    class Meta:
        model = RegisteredUser
226
        fields = '__all__'