Commit cd4ca351 authored by Daniel W Bond's avatar Daniel W Bond
Browse files

Merge branch 'new_apps' into amherst

parents dda169d1 7aa11ad4
...@@ -4,13 +4,8 @@ from __future__ import absolute_import, print_function ...@@ -4,13 +4,8 @@ from __future__ import absolute_import, print_function
from django import forms from django import forms
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.utils.encoding import force_text
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.utils.translation import ugettext as _
# third party imports # third party imports
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit, Layout
from crispy_forms.bootstrap import PrependedText, AppendedText
from multiselectfield import MultiSelectFormField from multiselectfield import MultiSelectFormField
# imports from your apps # imports from your apps
from .models import Student, Major from .models import Student, Major
...@@ -104,47 +99,3 @@ class StudentUpdateForm(forms.Form): ...@@ -104,47 +99,3 @@ class StudentUpdateForm(forms.Form):
valid = super(StudentUpdateForm, self).is_valid() valid = super(StudentUpdateForm, self).is_valid()
#print(valid) #print(valid)
return valid return valid
class WelcomeNameForm(forms.Form):
first_name = forms.CharField( required=False)
last_name = forms.CharField(required=False)
gender = MultiSelectFormField(choices=Student.GENDER_CHOICES, required=False)
show_gender = BooleanRadioField()
class WelcomePrivacyForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(WelcomePrivacyForm, self).__init__(*args, **kwargs)
if self.instance.recent_changes() > 2:
self.fields['room'].widget = forms.widgets.HiddenInput()
else:
self.fields['room'] = SelectRoomField(queryset=Room.objects.all(), required=False)
on_campus = BooleanRadioField()
def clean(self):
cleaned_data = super(WelcomePrivacyForm, self).clean()
form_room = cleaned_data.get('room')
if not(form_room is None):
students_in_room = Student.objects.filter(room=form_room).count()
#print(students_in_room)
# like in bookshare, I have no idea why the form errors don't display.
if students_in_room > 12:
raise ValidationError(_('Too many students in room (%d).' % students_in_room), code='invalid')
class Meta:
model = Student
fields = ('room', 'privacy', 'on_campus')
class WelcomeSocialForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(WelcomeSocialForm, self).__init__(*args, **kwargs)
self.fields['completedSocial'].widget = forms.widgets.HiddenInput()
class Meta:
model = Student
fields = ('completedSocial', )
...@@ -5,8 +5,7 @@ from django.conf.urls import patterns, include, url ...@@ -5,8 +5,7 @@ from django.conf.urls import patterns, include, url
# imports from your apps # imports from your apps
from .views import (DetailStudent, UpdateStudent, DetailStudentSettings, from .views import (DetailStudent, UpdateStudent, DetailStudentSettings,
DetailCurrentStudent, DetailCurrentStudentSettings, ListMajors, DetailCurrentStudent, DetailCurrentStudentSettings, ListMajors,
DetailMajor, WelcomeName, WelcomePrivacy, WelcomeMajor, DetailMajor, CreateConfirmation, DeleteConfirmation)
WelcomeSocial, CreateConfirmation, DeleteConfirmation)
from .adapter import RemoveSocialConfirmationView from .adapter import RemoveSocialConfirmationView
...@@ -48,25 +47,4 @@ urlpatterns = patterns('', ...@@ -48,25 +47,4 @@ urlpatterns = patterns('',
# delete # delete
url(r'^student/(?P<student_slug>[\w-]+)/flag/(?P<slug>[\w-]+)/$', url(r'^student/(?P<student_slug>[\w-]+)/flag/(?P<slug>[\w-]+)/$',
DeleteConfirmation.as_view(), name='deleteConfirmation'), DeleteConfirmation.as_view(), name='deleteConfirmation'),
# first welcome page
# let's verify your name and optionally select a gender
url(r'^welcome/(?P<slug>[\w-]+)/1/$',
WelcomeName.as_view(), name='welcomeName'),
# second welcome page
# let's set your room and privacy
url(r'^welcome/(?P<slug>[\w-]+)/2/$',
WelcomePrivacy.as_view(), name='welcomePrivacy'),
# third welcome page
# let's verify your major
url(r'^welcome/(?P<slug>[\w-]+)/3/$',
WelcomeMajor.as_view(), name='welcomeMajor'),
# fourth welcome page
# set your social media links
url(r'^welcome/(?P<slug>[\w-]+)/4/$',
WelcomeSocial.as_view(), name='welcomeSocial'),
) )
...@@ -20,15 +20,10 @@ from ratelimit.decorators import ratelimit ...@@ -20,15 +20,10 @@ from ratelimit.decorators import ratelimit
# imports from your apps # imports from your apps
from .models import Student, Major, Confirmation from .models import Student, Major, Confirmation
from housing.models import Building, Floor, Room from housing.models import Building, Floor, Room
from .forms import (StudentUpdateForm, WelcomeNameForm, WelcomePrivacyForm, from .forms import StudentUpdateForm
WelcomeSocialForm)
settings_redirect = """You've already finished the welcome walkthrough.
Your user settings can now be changed here on this page."""
######### #########
bug_reporting = """Welcome back to SRCT Roomlist. This project is the bug_reporting = """Welcome back to SRCT Roomlist. This project is the
<a href="https://srct.gmu.edu/projects/">collaborative work <a href="https://srct.gmu.edu/projects/">collaborative work
of students like you</a>. If you see anything amiss, or have ideas for of students like you</a>. If you see anything amiss, or have ideas for
...@@ -61,6 +56,7 @@ open_source = """Welcome back to SRCT Roomlist. For the curious at heart, ...@@ -61,6 +56,7 @@ open_source = """Welcome back to SRCT Roomlist. For the curious at heart,
<a href="https://git.gmu.edu/srct/roomlist/tree/master">source code</a>. <a href="https://git.gmu.edu/srct/roomlist/tree/master">source code</a>.
Come <a href="https://srct.gmu.edu/">to a meeting</a> and learn how to Come <a href="https://srct.gmu.edu/">to a meeting</a> and learn how to
contribute!""" contribute!"""
#########
return_messages = [bug_reporting, privacy_reminder, disclaimer, whatsopen_plug, open_source] return_messages = [bug_reporting, privacy_reminder, disclaimer, whatsopen_plug, open_source]
...@@ -74,17 +70,13 @@ def custom_cas_login(request, *args, **kwargs): ...@@ -74,17 +70,13 @@ def custom_cas_login(request, *args, **kwargs):
if not request.user.student.totally_done(): if not request.user.student.totally_done():
if not request.user.student.completedName: if not request.user.student.completedName:
return HttpResponseRedirect(reverse('welcomeName', return HttpResponseRedirect(reverse('welcomeName'))
kwargs={'slug':request.user.username}))
elif not request.user.student.completedPrivacy: elif not request.user.student.completedPrivacy:
return HttpResponseRedirect(reverse('welcomePrivacy', return HttpResponseRedirect(reverse('welcomePrivacy'))
kwargs={'slug':request.user.username}))
elif not request.user.student.completedMajor: elif not request.user.student.completedMajor:
return HttpResponseRedirect(reverse('welcomeMajor', return HttpResponseRedirect(reverse('welcomeMajor'))
kwargs={'slug':request.user.username}))
elif not request.user.completedSocial: elif not request.user.completedSocial:
return HttpResponseRedirect(reverse('welcomeSocial', return HttpResponseRedirect(reverse('welcomeSocial'))
kwargs={'slug':request.user.username}))
else: else:
welcome_back = random.choice(return_messages) welcome_back = random.choice(return_messages)
messages.add_message(request, messages.INFO, mark_safe(welcome_back)) messages.add_message(request, messages.INFO, mark_safe(welcome_back))
...@@ -323,229 +315,6 @@ class UpdateStudent(LoginRequiredMixin, FormValidMessageMixin, FormView): ...@@ -323,229 +315,6 @@ class UpdateStudent(LoginRequiredMixin, FormValidMessageMixin, FormView):
kwargs={'slug':self.request.user.username}) kwargs={'slug':self.request.user.username})
# welcome pages
class WelcomeName(LoginRequiredMixin, FormView):
template_name = 'welcome_name.html'
form_class = WelcomeNameForm
login_url = 'login'
def get(self, request, *args, **kwargs):
current_url = self.request.get_full_path()
url_uname = current_url.split('/')[3]
if not(url_uname == self.request.user.username):
return HttpResponseForbidden()
elif self.request.user.student.totally_done():
messages.add_message(request, messages.INFO, settings_redirect)
return reverse('updateStudent',
kwargs={'slug':self.request.user.username})
else:
return super(WelcomeName, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(WelcomeName, self).get_context_data(**kwargs)
me = Student.objects.get(user=self.request.user)
form = WelcomeNameForm(initial={'first_name': me.user.first_name,
'last_name': me.user.last_name,
'gender': me.gender,
'show_gender': me.show_gender, })
form.fields['first_name'].widget.attrs['class'] = 'form-control'
form.fields['last_name'].widget.attrs['class'] = 'form-control'
context['my_form'] = form
return context
@ratelimit(key='user', rate='5/m', method='POST', block=True)
@ratelimit(key='user', rate='10/d', method='POST', block=True)
def post(self, request, *args, **kwargs):
return super(WelcomeName, self).post(request, *args, **kwargs)
def form_valid(self, form):
me = Student.objects.get(user=self.request.user)
me.user.first_name = form.data['first_name']
me.user.last_name = form.data['last_name']
me.gender = form.data.getlist('gender')
me.show_gender = strtobool(form.data.get('show_gender', 'False'))
me.completedName = True
me.user.save()
me.save()
return super(WelcomeName, self).form_valid(form)
def get_success_url(self):
return reverse('welcomePrivacy',
kwargs={'slug':self.request.user.username})
class WelcomePrivacy(LoginRequiredMixin, UpdateView):
model = Student
form_class = WelcomePrivacyForm
context_object_name = 'student'
template_name = 'welcome_privacy.html'
login_url = 'login'
def get(self, request, *args, **kwargs):
current_url = self.request.get_full_path()
url_uname = current_url.split('/')[3]
if not(url_uname == self.request.user.username):
return HttpResponseForbidden()
elif self.request.user.student.totally_done():
messages.add_message(request, messages.INFO, settings_redirect)
return reverse('updateStudent',
kwargs={'slug':self.request.user.username})
else:
return super(WelcomePrivacy, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(WelcomePrivacy, self).get_context_data(**kwargs)
me = Student.objects.get(user=self.request.user)
form = WelcomePrivacyForm()
form.fields['room'].widget.user = self.request.user
form.fields['on_campus'].initial = self.request.user.student.on_campus
context['my_form'] = form
return context
@ratelimit(key='user', rate='5/m', method='POST', block=True)
@ratelimit(key='user', rate='10/d', method='POST', block=True)
def post(self, request, *args, **kwargs):
return super(WelcomePrivacy, self).post(request, *args, **kwargs)
def form_valid(self, form):
me = self.get_object()
current_room = me.room
# if you somehow got around the hidden widget, you're still outta luck
if me.recent_changes() > 2:
form_room = current_room
else:
try:
form_room = Room.objects.get(pk=form.data['room'])
except:
form_room = None
# casts to an integer, 0 or 1
on_campus = strtobool(form.data.get('on_campus', 'True'))
# no room if you move off campus
if not on_campus:
form_room = None
if current_room != form_room:
form.instance.times_changed_room += 1
Confirmation.objects.filter(student=me).delete()
form.instance.completedPrivacy = True
form.instance.on_campus = on_campus
form.instance.room = form_room
return super(WelcomePrivacy, self).form_valid(form)
def get_success_url(self):
return reverse('welcomeMajor',
kwargs={'slug':self.request.user.username})
class WelcomeMajor(LoginRequiredMixin, UpdateView):
model = Student
fields = ['major', 'graduating_year', ]
context_object_name = 'student'
template_name = 'welcome_major.html'
login_url = 'login'
def get(self, request, *args, **kwargs):
current_url = self.request.get_full_path()
url_uname = current_url.split('/')[3]
if not(url_uname == self.request.user.username):
return HttpResponseForbidden()
elif self.request.user.student.totally_done():
messages.add_message(request, messages.INFO, settings_redirect)
return reverse('updateStudent',
kwargs={'slug':self.request.user.username})
else:
return super(WelcomeMajor, self).get(request, *args, **kwargs)
@ratelimit(key='user', rate='5/m', method='POST', block=True)
@ratelimit(key='user', rate='10/d', method='POST', block=True)
def post(self, request, *args, **kwargs):
return super(WelcomeMajor, self).post(request, *args, **kwargs)
def form_valid(self, form):
form.instance.completedMajor = True
return super(WelcomeMajor, self).form_valid(form)
def get_success_url(self):
return reverse('welcomeSocial',
kwargs={'slug':self.request.user.username})
class WelcomeSocial(LoginRequiredMixin, UpdateView):
model = Student
form_class = WelcomeSocialForm
context_object_name = 'student'
template_name = 'welcome_social.html'
login_url = 'login'
def get(self, request, *args, **kwargs):
current_url = self.request.get_full_path()
url_uname = current_url.split('/')[3]
if not(url_uname == self.request.user.username):
return HttpResponseForbidden()
elif self.request.user.student.totally_done():
messages.add_message(request, messages.INFO, settings_redirect)
return reverse('updateStudent',
kwargs={'slug':self.request.user.username})
else:
return super(WelcomeSocial, self).get(request, *args, **kwargs)
@ratelimit(key='user', rate='5/m', method='POST', block=True)
@ratelimit(key='user', rate='10/d', method='POST', block=True)
def post(self, request, *args, **kwargs):
return super(WelcomeSocial, self).post(request, *args, **kwargs)
def form_valid(self, form):
form.instance.completedSocial = True
return super(WelcomeSocial, self).form_valid(form)
def get_success_url(self):
if self.request.user.student.totally_done():
messages.add_message(self.request, messages.SUCCESS,
"You successfully finished the welcome walkthrough!")
return reverse('detail_student',
kwargs={'slug':self.request.user.username})
# majors pages # majors pages
class ListMajors(LoginRequiredMixin, ListView): class ListMajors(LoginRequiredMixin, ListView):
model = Major model = Major
......
...@@ -71,6 +71,7 @@ INSTALLED_APPS = ( ...@@ -71,6 +71,7 @@ INSTALLED_APPS = (
'api', 'api',
'housing', 'housing',
'accounts', 'accounts',
'welcome',
# packages # packages
'crispy_forms', 'crispy_forms',
'django_gravatar', 'django_gravatar',
......
...@@ -25,6 +25,7 @@ urlpatterns = patterns('', ...@@ -25,6 +25,7 @@ urlpatterns = patterns('',
# app-level urls # app-level urls
url(r'^housing/', include('housing.urls')), url(r'^housing/', include('housing.urls')),
url(r'^accounts/', include('accounts.urls')), url(r'^accounts/', include('accounts.urls')),
url(r'^welcome/', include('welcome.urls')),
# search # search
url(r'^search/', login_required(SearchView(), login_url='login'), name='search'), url(r'^search/', login_required(SearchView(), login_url='login'), name='search'),
......
from django.contrib import admin
# Register your models here.
# standard library imports
from __future__ import absolute_import, print_function
# core django imports
from django import forms
from django.core.exceptions import ValidationError
# third party imports
from multiselectfield import MultiSelectFormField
# imports from your apps
from accounts.models import Student, Major
from accounts.forms import SelectRoomField, BooleanRadioField
from housing.models import Room
class WelcomeNameForm(forms.Form):
first_name = forms.CharField(required=False)
last_name = forms.CharField(required=False)
gender = MultiSelectFormField(choices=Student.GENDER_CHOICES, required=False)
show_gender = BooleanRadioField()
class WelcomePrivacyForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(WelcomePrivacyForm, self).__init__(*args, **kwargs)
if self.instance.recent_changes() > 2:
self.fields['room'].widget = forms.widgets.HiddenInput()
else:
self.fields['room'] = SelectRoomField(queryset=Room.objects.all(), required=False)
on_campus = BooleanRadioField()
def clean(self):
cleaned_data = super(WelcomePrivacyForm, self).clean()
form_room = cleaned_data.get('room')
if not(form_room is None):
students_in_room = Student.objects.filter(room=form_room).count()
#print(students_in_room)
# like in bookshare, I have no idea why the form errors don't display.
if students_in_room > 12:
raise ValidationError(_('Too many students in room (%d).' % students_in_room), code='invalid')
class Meta:
model = Student
fields = ('room', 'privacy', 'on_campus')
class WelcomeMajorForm(forms.ModelForm):
class Meta:
model = Student
fields = ('major', 'graduating_year', )
class WelcomeSocialForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(WelcomeSocialForm, self).__init__(*args, **kwargs)
self.fields['completedSocial'].widget = forms.widgets.HiddenInput()
class Meta:
model = Student
fields = ('completedSocial', )
from django.db import models
# Create your models here.
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
<div class="panel-body"> <div class="panel-body">
<form action="" method="post">{% csrf_token %} <form action="" method="post">{% csrf_token %}
{{ form.as_p }} {{ my_form.as_p }}
<input type="submit" value="Save" class="btn btn-primary"/> <input type="submit" value="Save" class="btn btn-primary"/>
</form> </form>
</div> </div>
......
...@@ -85,7 +85,7 @@ ...@@ -85,7 +85,7 @@
</form> </form>
{% endspaceless %} {% endspaceless %}
{% else %} {% else %}
<a href="{% url 'welcomeMajor' request.user.username %}"> <a href="{% url 'welcomeMajor' %}">
<button type="button" class="btn btn-primary">Continue</button> <button type="button" class="btn btn-primary">Continue</button>
</a> </a>
{% endif %} {% endif %}
......
from django.test import TestCase
# Create your tests here.
# standard library imports
from __future__ import absolute_import, print_function
# core django imports
from django.conf.urls import patterns, include, url
from django.views.generic import RedirectView
from django.core.urlresolvers import reverse_lazy
# imports from your apps
from .views import WelcomeName, WelcomePrivacy, WelcomeMajor, WelcomeSocial
urlpatterns = patterns('',
# first welcome page
# let's verify your name and optionally select a gender
url(r'^1/$',
WelcomeName.as_view(), name='welcomeName'),
# thought it made sense to redirect without the number
url(r'^$',
RedirectView.as_view(url=reverse_lazy('welcomeName'), permanent=True)),
# second welcome page
# let's set your room and privacy
url(r'^2/$',
WelcomePrivacy.as_view(), name='welcomePrivacy'),
# third welcome page
# let's verify your major
url(r'^3/$',
WelcomeMajor.as_view(), name='welcomeMajor'),
# fourth welcome page
# set your social media links
url(r'^4/$',
WelcomeSocial.as_view(), name='welcomeSocial'),
)
# standard library imports
from __future__ import absolute_import, print_function
from distutils.util import strtobool
# core django imports
from django.shortcuts import render
from django.views.generic import FormView
from django.core.urlresolvers import reverse
from django.contrib import messages
# third party imports
from braces.views import LoginRequiredMixin
from ratelimit.decorators import ratelimit
# imports from your apps
from accounts.models import Student, Confirmation
from housing.models import Room