Commit 6dbadece authored by Daniel W Bond's avatar Daniel W Bond
Browse files

Merge branch 'welcome' into 'master'

Welcome

issues #38 and #16

See merge request !10
parents ceb3073a 8cb96d36
......@@ -128,6 +128,20 @@ With your virtual environment active, run
Head over to localhost:8000 and see the site!
## Configuring the Social Media Applications
Head over to localhost:8000/admin. Under 'Social Accounts', click on 'Social Applications'. Click 'Add social application' in the upper right hand corner. Start off by adding Facebook.
To generate the name, id, key, and site for Facebook, you'll need to become a Facebook Developer and create a name.
Let's add localhost to our Available sites.
Now, to Instagram.
Next, to Twitter.
Finally, to Google.
### Notes on Cacheing
Roomlist's urls are set to be cached for periods of time set so that ordinary user experience will not be impacted, but a substantial load will be lifted from a deployment server. However, this can be annoying when you're making and want to check small changes rapidly on development. You can edit the respective apps' urls.py files and remove the cacheing configurations, but make sure that you do not include such edits in any pushes!
......
......@@ -12,6 +12,7 @@ django-gravatar2==1.1.4
django-haystack==2.3.1
django-localflavor==1.0
django-model-utils==2.2
django-multiselectfield==0.1.3
django-randomslugfield==0.3.0
django-redis-cache==0.13.0
flake8==2.4.0
......
# core django imports
from django.contrib.auth.models import User
from django.conf import settings
from django.contrib import messages
# third party imports
import requests
# imports from your apps
from .models import Student
from .models import Student, Major
def pfparse(pf_name_result):
# name comes in format of Anderson, Nicholas J
name_list = pf_name_result.split(',')
# there's random whitespace with the first name
first_name_section = name_list[1].strip()
# check if there's a middle initial
mi_q = first_name_section.split(' ')
# make sure that the additional elements aren't multiple names
if len(mi_q[-1]) == 1:
first_name = ' '.join(mi_q[:-1])
else:
first_name = first_name_section
new_name_list = [first_name, name_list[0]]
return new_name_list
def pfinfo(uname):
base_url = "http://peoplefinder.b1.akshaykarthik.com/"
base_url = settings.PF_URL
url = base_url + "basic/all/" + str(uname)
try:
metadata = requests.get(url)
......@@ -17,25 +34,72 @@ def pfinfo(uname):
print e
else:
pfjson = metadata.json()
name = pfjson['results'][0]['name']
return name.split(',')
try:
if len(pfjson['results']) == 1:
name_str = pfjson['results'][0]['name']
name = pfparse(name_str)
major = pfjson['results'][0]['major']
# could conceivably throw a key error
final_tuple = (name, major)
return final_tuple
else:
name_str = pfjson['results'][1]['name']
name = pfparse(name_str)
major = pfjson['results'][1]['major']
# could conceivably throw a key error
final_tuple = (name, major)
return final_tuple
# if the name is not in peoplefinder, return empty first and last name
except IndexError:
name = [u'', u'']
major = u''
final_tuple = (name, major)
return final_tuple
# if there's no major, just return that as an empty string
except KeyError:
final_tuple = (name, u'')
return final_tuple
def create_user(tree):
print "Parsing CAS information."
username = tree[0][0].text
user, user_created = User.objects.get_or_create(username=username)
if user_created:
user.email = "%s@%s" % (username, settings.ORGANIZATION_EMAIL_DOMAIN)
name_list = pfinfo(username)
user.first_name = name_list[1].rstrip()
user.last_name = name_list[0]
print "Created user object %s." % username
# set and save the user's email
email_str = "%s@%s" % (username, settings.ORGANIZATION_EMAIL_DOMAIN)
user.email = email_str
user.save()
print "Added user's email, %s." % email_str
info_tuple = pfinfo(username)
info_name = info_tuple[0]
# a list of empty strings is False
if not info_name:
user.first_name = info_name[0]
user.last_name = info_name[1]
user.save()
print "Added user's name, %s %s." % (info_name[0], info_name[1])
new_student = Student.objects.create(user=user)
new_student.save()
print "Created student object."
major_name = info_tuple[1]
try:
major_obj = Major.objects.get(name__contains=major_name)
new_student.major = major_obj
new_student.save()
print "Added student's major, %s." % major_name
# ironically, 'Computer Science' returns a MultipleObjectsReturned exception
# also Major.DoesNotExist Error, but the handling for both is the same...
except:
pass
print "User creation process completed."
print("Created user %s!" % username)
print "CAS callback successful."
......@@ -4,46 +4,24 @@ from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit, Layout
from crispy_forms.bootstrap import PrependedText, AppendedText
from multiselectfield import MultiSelectFormField
# imports from your apps
from .models import Student
from .models import Student, Room, Major
# form to create student
class StudentForm(forms.ModelForm):
class StudentUpdateForm(forms.Form):
def __init__(self, *args, **kwargs):
first_name = forms.CharField(label='First Name')
last_name = forms.CharField(label='Last Name')
gender = MultiSelectFormField(choices=Student.GENDER_CHOICES,
label='Gender Identity (please choose all that apply)')
room = forms.ModelChoiceField(queryset=Room.objects.all())
privacy = forms.ChoiceField(choices=Student.PRIVACY_CHOICES)
major = forms.ModelChoiceField(queryset=Major.objects.all())
self.helper = FormHelper()
self.helper.layout = Layout(
'user',
PrependedText('room', 'Room'),
'class',
AppendedText('major', 'Major'),
)
self.helper.form_method = 'post'
self.helper.add_input(Submit('submit', 'Submit'))
super(StudentForm, self).__init__(*args, **kwargs)
class WelcomeNameForm(forms.Form):
class Meta:
model = Student
class UserSettingsForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.helper = FormHelper()
self.helper.layout = Layout(
'user',
PrependedText('room', 'Room'),
'class',
AppendedText('major', 'Major'),
)
self.helper.form_method = 'post'
self.helper.add_input(Submit('submit', 'Submit'))
super(StudentForm, self).__init__(*args, **kwargs)
class Meta:
model = Student
first_name = forms.CharField(label='First Name')
last_name = forms.CharField(label='Last Name')
gender = MultiSelectFormField(choices=Student.GENDER_CHOICES, label='Gender Identity (please choose all that apply)')
......@@ -8,6 +8,7 @@ from django.core.urlresolvers import reverse
from django.utils.text import slugify
# third party imports
from autoslug import AutoSlugField
from multiselectfield import MultiSelectField
from allauth.socialaccount.models import SocialAccount
# imports from your apps
from housing.models import Room, Class
......@@ -103,14 +104,38 @@ class Student(TimeStampedModel):
(STUDENTS, 'All Students'),
)
FEMALE = 'female'
MALE = 'male'
TRANS = 'trans'
OTHER = 'other'
GENDER_CHOICES = (
(FEMALE, 'female'),
(MALE, 'male'),
(TRANS, 'trans'),
(OTHER, 'other'),
)
# selectmultiple in forms
gender = MultiSelectField(max_length=25, choices=GENDER_CHOICES, blank=True)
privacy = models.CharField(max_length=100, choices=PRIVACY_CHOICES, default=FLOOR)
room = models.ForeignKey(Room, null=True, blank=True)
clas = models.ForeignKey(Class, null=True, blank=True)
major = models.ForeignKey('Major', null=True, blank=True)
# from when first logged in through peoplefinder, stored for later
original_major = models.CharField(max_length=50, blank=True)
# social media accounts
# welcome walkthrough completion
completedName = models.BooleanField(default=False)
completedPrivacy = models.BooleanField(default=False)
completedMajor = models.BooleanField(default=False)
completedSocial = models.BooleanField(default=False)
slug = AutoSlugField(populate_from='user', unique=True)
objects = StudentManager()
......
......@@ -2,7 +2,7 @@
{% block title %} SRCT Roomlist | {{ student.user.first_name }} {{ student.user.last_name }} {% endblock %}
{% block reminder %}
{% block messsage_queue %}
{% endblock %}
{% block content %}
......
{% extends 'layouts/base.html' %}
{% block title %} SRCT Roomlist | New Student Setup {% endblock %}
{% block title %} SRCT Roomlist | Student | Update {% endblock %}
{% block reminder %}
{% block message_queue %}
{% endblock %}
{% block content %}
......@@ -10,7 +10,7 @@
<div class="page-header" id="banner">
<div class="row">
<div class="col-md-12 text-center">
<h1><strong>SRCT</strong>ROOMLIST</a></strong> Student Setup</h1>
<h1><strong>SRCT</strong>ROOMLIST</a></strong> Student Update</h1>
</div>
</div>
</div>
......@@ -20,12 +20,12 @@
<div class="panel panel-default">
<div class="panel-heading">
<h1 class="panel-title text-center"><strong>Welcome, {{ student.user.first_name }}!</strong></h1>
<h1 class="panel-title text-center"><strong>Welcome, {{ request.user.first_name }}!</strong></h1>
</div>
<div class="panel-body">
<form action="" method="post">{% csrf_token %}
{{ form.as_p }}
{{ my_form.as_p }}
<input type="submit" value="Save" class="btn btn-primary"/>
</form>
</div>
......
{% extends 'layouts/base.html' %}
{% block title %} SRCT Roomlist | Student Major {% endblock %}
{% block title %} SRCT RoomList | Welcome | Step 3 of 4 {% endblock %}
{% block reminder %}
{% block message_queue %}
{% endblock %}
{% block content %}
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="75" aria-valuemin="0" aria-valuemax="100" style="width: 75%;">
<span class="sr-only">75% complete</span>
</div>
</div>
<div class="page-header" id="banner">
<div class="row">
<div class="col-md-12 text-center">
<h1><strong>SRCT</strong>ROOMLIST</a></strong> Student Major</h1>
<h1>Welcome to <strong>SRCT</strong>ROOMLIST! <small>Step 3 of 4</small></h1>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<p class="text-center">Now let's verify your major. This lets others find you and others with their same major, which, for example, makes it easier to form study groups.</p>
</div>
</div>
<div class="row">
<div class="col-md-12 text-center">
<div class="alert alert-danger" role="alert">
<p><i class="fa fa-exclamation-circle fa-fw fa-lg"></i> <strong>Changing your major here serves only to make it easier for others to find you on this site.</strong></p>
<p>Talk with your academic advisor and file all necessary paperwork to officially change your major with the registrar.</p>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">
<h1 class="panel-title text-center"><strong>Set your major on ROOMLIST!</strong></h1>
<h1 class="panel-title text-center"><strong>Major</strong></h1>
</div>
<div class="panel-body">
......@@ -43,5 +46,14 @@
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2 text-center">
<div class="alert alert-danger" role="alert">
<p><i class="fa fa-exclamation-circle fa-fw fa-lg"></i> <strong>Changing your major here serves only to make it easier for others to find you on this site.</strong></p>
<p>Talk with your academic advisor and file all necessary paperwork to officially change your major with the registrar.</p>
</div>
</div>
</div>
{% endblock %}
{% extends 'layouts/base.html' %}
{% block title %} SRCT RoomList | Welcome | Step 1 of 4 {% endblock %}
{% block message_queue %}
{% endblock %}
{% block content %}
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="25" aria-valuemin="0" aria-valuemax="100" style="width: 25%;">
<span class="sr-only">25% complete</span>
</div>
</div>
<div class="page-header" id="banner">
<div class="row">
<div class="col-md-12 text-center">
<h1>Welcome to <strong>SRCT</strong>ROOMLIST! <small>Step 1 of 4</small></h1>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<p class="text-center">Welcome to Roomlist, and thank you for signing in! Let's get started by verifying your name and then optionally selecting a gender identity.<p>
<p class="text-center"></p>
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">
<h1 class="panel-title text-center"><strong>Name & Gender</strong></h1>
</div>
<div class="panel-body">
<form action="" method="post">{% csrf_token %}
{{ my_form.as_p }}
<input type="submit" value="Save" class="btn btn-primary"/>
</form>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2 text-center">
<div class="alert alert-danger" role="alert">
<p><i class="fa fa-exclamation-circle fa-fw fa-lg"></i> <strong>Changing your name here serves only to make it easier for others to find you on this particular site.</strong></p>
<p>Talk with the Registrar's Office to handle the paperwork necessary to change your name officially with the university.</p>
</div>
</div>
</div>
{% endblock %}
{% extends 'layouts/base.html' %}
{% block title %} SRCT RoomList | Welcome | Step 2 of 4 {% endblock %}
{% block message_queue %}
{% endblock %}
{% block content %}
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100" style="width: 50%;">
<span class="sr-only">50% complete</span>
</div>
</div>
<div class="page-header" id="banner">
<div class="row">
<div class="col-md-12 text-center">
<h1>Welcome to <strong>SRCT</strong>ROOMLIST! <small>Step 2 of 4</small></h1>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<p class="text-center">Great! Now to your housing information and settings. Here, you'll select which room you live in, and then choose who you want to be able to see that information.</p>
<p class="text-center"><strong>By default, your privacy is set to 'Floor'.</strong> That means only other students living on your floor can see your room.</p>
<p class="text-center">You can choose to set your privacy to 'Building', which will make your room visible to everyone living in your building, or to 'Campus', where it will be visible to anyone with a current Mason username and password.</p>
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">
<h1 class="panel-title text-center"><strong>Room & Privacy</strong></h1>
</div>
<div class="panel-body">
<form action="" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save" class="btn btn-primary"/>
</form>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2 text-center">
<div class="alert alert-danger" role="alert">
<p><i class="fa fa-exclamation-circle fa-fw fa-lg"></i> <strong>Changing your room here changes it only on this particular site.</strong></p>
<p>To actually switch your room, you'll need to go through a lengthy process with the Housing Office.</p>
</div>
</div>
</div>
{% endblock %}
{% extends 'layouts/base.html' %}
{% block title %} SRCT RoomList | Welcome | Step 4 of 4 {% endblock %}
{% block message_queue %}
{% endblock %}
{% block content %}
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%;">
<span class="sr-only">100% complete</span>
</div>
</div>
<div class="page-header" id="banner">
<div class="row">
<div class="col-md-12 text-center">
<h1>Welcome to <strong>SRCT</strong>ROOMLIST! <small>Step 4 of 4</small></h1>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<p class="text-center">We're not trying to recreate Facebook here. On this final step, you can choose point people to a variety of your social media accounts from your user page.</p>
<p class="text-center">You'll be asked to sign in, but that's just to verify the account actually belongs to you. With the exception of your choice to use your Facebook profile picture as your profile picture here, we don't see or use any information on these third-party sites.</p>
</div>
</div>
{% load socialaccount %} {% providers_media_js %}
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">
<h1 class="panel-title text-center"><strong>Social Media Accounts</strong></h1>
</div>
<div class="panel-body">
<div class="row text-center">
{% comment %} is it not possible to redirect the login failure? {% endcomment %}
<div class="col-md-3">
{% if verified %}
<p><i class="fa fa-check-square-o"></i> Verified!</p>
{% endif %}
<a href="{% provider_login_url 'facebook' method='js_sdk' process='connect' next='#' %}">
<h4><i class="fa fa-facebook fa-3x"></i></h4>
</a>
</div>
<div class="col-md-3">
{% if verified %}
<p><i class="fa fa-check-square-o"></i> Verified!</p>
{% endif %}
<a href="{% provider_login_url 'google' method='js_sdk' process='connect' next='#' %}">
<h4><i class="fa fa-google fa-3x"></i></h4>
</a>
</div>
<div class="col-md-3">
{% if verified %}
<p><i class="fa fa-check-square-o"></i> Verified!</p>
{% endif %}
<a href="{% provider_login_url 'twitter' method='js_sdk' process='connect' next='#' %}">
<h4><i class="fa fa-twitter fa-3x"></i></h4>
</a>
</div>
<div class="col-md-3">
{% if verified %}
<p><i class="fa fa-check-square-o"></i> Verified!</p>
{% endif %}
<a href="{% provider_login_url 'instagram' method='js_sdk' process='connect' next='#' %}">
<h4><i class="fa fa-instagram fa-3x"></i></h4>
</a>
</div>
</div>
<input type="submit" value="Finish" class="btn btn-primary"/>
</div>
</div>
</div>
</div>
{% endblock %}
......@@ -3,8 +3,8 @@ from django.conf.urls import patterns, include, url
from django.views.decorators.cache import cache_page
# imports from your apps
from .views import DetailStudent, UpdateStudent, DetailStudentSettings,\
DetailCurrentStudent, DetailCurrentStudentSettings, UpdateStudentMajor,\
ListMajors, DetailMajor
DetailCurrentStudent, DetailCurrentStudentSettings, ListMajors,\
DetailMajor, WelcomeName, WelcomePrivacy, WelcomeMajor, WelcomeSocial
urlpatterns = patterns('',
......@@ -31,12 +31,28 @@ urlpatterns = patterns('',
cache_page(60 * 15)(UpdateStudent.as_view()),
name='updateStudent'),
url(r'^(?P<slug>[\w-]+)/major/$',
cache_page(4)(UpdateStudentMajor.as_view()),
name='updateStudentMajor'),
url(r'^settings/$',
cache_page(4)(DetailCurrentStudentSettings.as_view()),
name='currentStudentSettings'),
# 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