Commit 0b0a563a authored by Jason Yeomans's avatar Jason Yeomans
Browse files

Merge branch 'master' of git.gmu.edu:srct/roomlist

parents b692f0bc c566cde1
...@@ -108,6 +108,8 @@ Finally, we need to enter the PostgreSQL command line interface to grant permiss ...@@ -108,6 +108,8 @@ Finally, we need to enter the PostgreSQL command line interface to grant permiss
Your PostgreSQL database should now be set up to work with the Roomlist project. Your PostgreSQL database should now be set up to work with the Roomlist project.
Type ``\q`` and hit enter to exit the PostgreSQL shell.
Copy the secret.py.template and config.py.template to secret.py and config.py respectively. For each, follow the comment instruction provided in each file. Copy the secret.py.template and config.py.template to secret.py and config.py respectively. For each, follow the comment instruction provided in each file.
Run `python manage.py syncdb` to set up the empty database tables. When you're prompted, say 'y' to setting up the superuser, but use your mason username and full mason email address (@masonlive.gmu.edu) for the account. This is because we use Mason's Central Authentication for our user signin, and your admin account needs to manage your CAS account. Run `python manage.py syncdb` to set up the empty database tables. When you're prompted, say 'y' to setting up the superuser, but use your mason username and full mason email address (@masonlive.gmu.edu) for the account. This is because we use Mason's Central Authentication for our user signin, and your admin account needs to manage your CAS account.
......
...@@ -13,8 +13,12 @@ django-haystack==2.3.1 ...@@ -13,8 +13,12 @@ django-haystack==2.3.1
django-localflavor==1.0 django-localflavor==1.0
django-model-utils==2.2 django-model-utils==2.2
django-randomslugfield==0.3.0 django-randomslugfield==0.3.0
flake8==2.4.0
mccabe==0.3
oauthlib==0.7.2 oauthlib==0.7.2
pep8==1.5.7
psycopg2==2.5.4 psycopg2==2.5.4
pyflakes==0.8.1
python-openid==2.2.5 python-openid==2.2.5
requests==2.5.1 requests==2.5.1
requests-oauthlib==0.4.2 requests-oauthlib==0.4.2
......
# standard library imports # standard library imports
from datetime import datetime, timedelta from datetime import datetime, timedelta
# core django imports # core django imports
from django.conf import settings
from django.shortcuts import resolve_url from django.shortcuts import resolve_url
# third party imports # third party imports
from allauth.account.adapter import DefaultAccountAdapter from allauth.account.adapter import DefaultAccountAdapter
...@@ -10,10 +9,10 @@ from allauth.account.adapter import DefaultAccountAdapter ...@@ -10,10 +9,10 @@ from allauth.account.adapter import DefaultAccountAdapter
class AccountAdapter(DefaultAccountAdapter): class AccountAdapter(DefaultAccountAdapter):
def get_login_redirect_url(self, request): def get_login_redirect_url(self, request):
threshold = 90 #seconds threshold = 90 # seconds
assert request.user.is_authenticated() assert request.user.is_authenticated()
if (request.user.last_login - request.user.date_joined).seconds < threshold: if ((request.user.last_login - request.user.date_joined).seconds < threshold):
url = '/accounts/student/' url = '/accounts/student/'
else: else:
url = '/accounts/student/' url = '/accounts/student/'
......
...@@ -20,6 +20,7 @@ def pfinfo(uname): ...@@ -20,6 +20,7 @@ def pfinfo(uname):
name = pfjson['results'][0]['name'] name = pfjson['results'][0]['name']
return name.split(',') return name.split(',')
def create_user(tree): def create_user(tree):
username = tree[0][0].text username = tree[0][0].text
......
...@@ -2,13 +2,14 @@ ...@@ -2,13 +2,14 @@
from django import forms from django import forms
# third party imports # third party imports
from crispy_forms.helper import FormHelper from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit, Layout, Field, HTML from crispy_forms.layout import Submit, Layout
from crispy_forms.bootstrap import PrependedText, AppendedText, FormActions from crispy_forms.bootstrap import PrependedText, AppendedText
# imports from your apps # imports from your apps
from .models import Student from .models import Student
# form to create student # form to create student
class StudentForm( forms.ModelForm ): class StudentForm(forms.ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
...@@ -28,7 +29,7 @@ class StudentForm( forms.ModelForm ): ...@@ -28,7 +29,7 @@ class StudentForm( forms.ModelForm ):
model = Student model = Student
class UserSettingsForm( forms.ModelForm ): class UserSettingsForm(forms.ModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
......
...@@ -9,21 +9,23 @@ from django.core.urlresolvers import reverse ...@@ -9,21 +9,23 @@ from django.core.urlresolvers import reverse
from autoslug import AutoSlugField from autoslug import AutoSlugField
from allauth.socialaccount.models import SocialAccount from allauth.socialaccount.models import SocialAccount
# imports from your apps # imports from your apps
from housing.models import Building, Room, Class from housing.models import Room, Class
class Major(TimeStampedModel): class Major(TimeStampedModel):
name = models.CharField(max_length = 50) name = models.CharField(max_length=50)
# I believe the longest is "Government and International Politics" # I believe the longest is "Government and International Politics"
def __str__(self): def __str__(self):
return self.name return self.name
def __unicode__(self): def __unicode__(self):
return unicode(self.name) return unicode(self.name)
class Meta: class Meta:
ordering = ['name'] ordering = ['name']
class StudentQuerySet(models.query.QuerySet): class StudentQuerySet(models.query.QuerySet):
def floor(self): def floor(self):
return self.filter(privacy='floor') return self.filter(privacy='floor')
...@@ -47,11 +49,11 @@ class StudentQuerySet(models.query.QuerySet): ...@@ -47,11 +49,11 @@ class StudentQuerySet(models.query.QuerySet):
students = self.students() students = self.students()
# using the function above results in UnboundLocalError excpetion # using the function above results in UnboundLocalError excpetion
#building_students = building_students()
building_students = list(building) + list(set(students) - set(building)) building_students = list(building) + list(set(students) - set(building))
return list(floor) + list(set(building_students) - set(floor)) return list(floor) + list(set(building_students) - set(floor))
class StudentManager(models.Manager): class StudentManager(models.Manager):
# this 'duplication' allows for queryset chaining # this 'duplication' allows for queryset chaining
...@@ -70,10 +72,11 @@ class StudentManager(models.Manager): ...@@ -70,10 +72,11 @@ class StudentManager(models.Manager):
def building_students(self): def building_students(self):
return self.get_queryset().building_students() return self.get_queryset().building_students()
def floor_building_students(self): def floor_building_students(self):
return self.get_queryset().floor_building_students() return self.get_queryset().floor_building_students()
class Student(TimeStampedModel): class Student(TimeStampedModel):
user = models.OneToOneField(User) user = models.OneToOneField(User)
# Django user includes a username, password, email, first name, and last name # Django user includes a username, password, email, first name, and last name
...@@ -118,19 +121,19 @@ class Student(TimeStampedModel): ...@@ -118,19 +121,19 @@ class Student(TimeStampedModel):
fb_uid = SocialAccount.objects.filter(user=self.user.id, provider='facebook') fb_uid = SocialAccount.objects.filter(user=self.user.id, provider='facebook')
print("profile_image") print("profile_image")
if len(fb_uid)>0: if len(fb_uid) > 0:
return "http://graph.facebook.com/{}/picture?width=175&height=175".format(fb_uid[0].uid) return "http://graph.facebook.com/{}/picture?width=175&height=175".format(fb_uid[0].uid)
return "http://www.gravatar.com/avatar/{}?s=175".format(hashlib.md5(self.user.email).hexdigest()) return "http://www.gravatar.com/avatar/{}?s=175".format(hashlib.md5(self.user.email).hexdigest())
def get_absolute_url(self): def get_absolute_url(self):
return reverse('detail_student', kwargs={'slug':self.slug}) return reverse('detail_student', kwargs={'slug': self.slug})
class Meta: class Meta:
ordering = ['user'] ordering = ['user']
def __str__(self): # __unicode__ on Python 2 def __str__(self): # __unicode__ on Python 2
return self.user.username return self.user.username
def __unicode__(self): def __unicode__(self):
return unicode(self.user.username) return unicode(self.user.username)
# standard libary imports
import datetime
# third party imports # third party imports
from haystack import indexes from haystack import indexes
# imports from your apps # imports from your apps
...@@ -15,11 +13,11 @@ class StudentIndex(indexes.SearchIndex, indexes.Indexable): ...@@ -15,11 +13,11 @@ class StudentIndex(indexes.SearchIndex, indexes.Indexable):
# with the fields that we want to display when returning results # with the fields that we want to display when returning results
# search filtering # search filtering
user = indexes.CharField( model_attr = 'user' ) user = indexes.CharField(model_attr='user')
def get_model(self): def get_model(self):
return Student return Student
def index_queryset(self, using=None): def index_queryset(self, using=None):
"""When the entire index for model is updated.""" """When the entire index for model is updated."""
return self.get_model().objects.all() return self.get_model().objects.all()
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
from django.conf.urls import patterns, include, url 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, UpdateStudentMajor DetailCurrentStudent, DetailCurrentStudentSettings, UpdateStudentMajor
urlpatterns = patterns('', urlpatterns = patterns('',
......
# core django imports # core django imports
from django.shortcuts import render, get_object_or_404 from django.shortcuts import get_object_or_404
from django.http import HttpResponseForbidden from django.http import HttpResponseForbidden
from django.views.generic import DetailView, ListView, UpdateView, UpdateView, DeleteView from django.views.generic import DetailView, UpdateView
# third party imports # third party imports
from braces.views import LoginRequiredMixin from braces.views import LoginRequiredMixin
# imports from your apps # imports from your apps
...@@ -11,7 +11,7 @@ from .models import Student ...@@ -11,7 +11,7 @@ from .models import Student
# update a student (students are *created* on first login via CAS) # update a student (students are *created* on first login via CAS)
class UpdateStudent(LoginRequiredMixin, UpdateView): class UpdateStudent(LoginRequiredMixin, UpdateView):
model = Student model = Student
fields = ['room', 'privacy',] fields = ['room', 'privacy', ]
context_object_name = 'student' context_object_name = 'student'
template_name = 'updateStudent.html' template_name = 'updateStudent.html'
...@@ -30,9 +30,10 @@ class UpdateStudent(LoginRequiredMixin, UpdateView): ...@@ -30,9 +30,10 @@ class UpdateStudent(LoginRequiredMixin, UpdateView):
else: else:
return super(UpdateStudent, self).get(request, *args, **kwargs) return super(UpdateStudent, self).get(request, *args, **kwargs)
class UpdateStudentMajor(LoginRequiredMixin, UpdateView): class UpdateStudentMajor(LoginRequiredMixin, UpdateView):
models = Student models = Student
fields = ['major',] fields = ['major', ]
template_name = 'updateStudentMajor.html' template_name = 'updateStudentMajor.html'
login_url = 'login' login_url = 'login'
...@@ -41,6 +42,7 @@ class UpdateStudentMajor(LoginRequiredMixin, UpdateView): ...@@ -41,6 +42,7 @@ class UpdateStudentMajor(LoginRequiredMixin, UpdateView):
# def get_object(self): # def get_object(self):
# return get_object_or_404(Student, pk=self.request.session['_auth_user_id']) # return get_object_or_404(Student, pk=self.request.session['_auth_user_id'])
# details about the student # details about the student
class DetailStudent(LoginRequiredMixin, DetailView): class DetailStudent(LoginRequiredMixin, DetailView):
model = Student model = Student
...@@ -73,17 +75,19 @@ class DetailStudent(LoginRequiredMixin, DetailView): ...@@ -73,17 +75,19 @@ class DetailStudent(LoginRequiredMixin, DetailView):
# if the student's privacy is floor and the requesting user is on their floor # if the student's privacy is floor and the requesting user is on their floor
if(self.get_object().privacy == 'floor') and onFloor(): if(self.get_object().privacy == 'floor') and onFloor():
student_shares = True student_shares = True
# if the student's privacy is building and the requesting users is on their floor or in their building # if the student's privacy is building and the requesting users is
# on their floor or in their building
elif(self.get_object().privacy == 'building') and inBuilding(): elif(self.get_object().privacy == 'building') and inBuilding():
student_shares = True student_shares = True
# if the student's privacy is set to 'student' # if the student's privacy is set to 'student'
elif(self.get_object().privacy == 'students'): elif(self.get_object().privacy == 'students'):
student_shares = True student_shares = True
return student_shares return student_shares
context['shares'] = shares() context['shares'] = shares()
return context return context
class DetailCurrentStudent(LoginRequiredMixin, DetailView): class DetailCurrentStudent(LoginRequiredMixin, DetailView):
model = Student model = Student
context_object_name = 'student' context_object_name = 'student'
...@@ -94,6 +98,7 @@ class DetailCurrentStudent(LoginRequiredMixin, DetailView): ...@@ -94,6 +98,7 @@ class DetailCurrentStudent(LoginRequiredMixin, DetailView):
def get_object(self): def get_object(self):
return get_object_or_404(Student, pk=self.request.session['_auth_user_id']) return get_object_or_404(Student, pk=self.request.session['_auth_user_id'])
# changeable student settings # changeable student settings
class DetailStudentSettings(LoginRequiredMixin, DetailView): class DetailStudentSettings(LoginRequiredMixin, DetailView):
model = Student model = Student
...@@ -102,6 +107,7 @@ class DetailStudentSettings(LoginRequiredMixin, DetailView): ...@@ -102,6 +107,7 @@ class DetailStudentSettings(LoginRequiredMixin, DetailView):
login_url = 'login' login_url = 'login'
class DetailCurrentStudentSettings(LoginRequiredMixin, DetailView): class DetailCurrentStudentSettings(LoginRequiredMixin, DetailView):
model = Student model = Student
context_object_name = 'student' context_object_name = 'student'
......
# core django imports
from django.http import HttpResponse from django.http import HttpResponse
# third party imports
import json import json
# imports from your apps
from housing.models import Building, Room from housing.models import Building, Room
# Create your views here.
def index(request): def index(request):
return HttpResponse("Hello, world. You're at the RoomList index.") return HttpResponse("Hello, world. You're at the RoomList index.")
def buildings_list(request): def buildings_list(request):
building_list = Building.objects.order_by('name')[:5] building_list = Building.objects.order_by('name')[:5]
jsons = '{"buildings":[' jsons = '{"buildings":['
...@@ -16,6 +18,7 @@ def buildings_list(request): ...@@ -16,6 +18,7 @@ def buildings_list(request):
jsons = jsons[:-1]+']}' jsons = jsons[:-1]+']}'
return HttpResponse(jsons) return HttpResponse(jsons)
def building(request, buildingName): def building(request, buildingName):
room_list = Room.objects.filter(building__name=''+buildingName).order_by('number') room_list = Room.objects.filter(building__name=''+buildingName).order_by('number')
jsons = 'Building does not exist' jsons = 'Building does not exist'
...@@ -34,6 +37,7 @@ def building(request, buildingName): ...@@ -34,6 +37,7 @@ def building(request, buildingName):
jsons = jsons[:-1] + ']}' jsons = jsons[:-1] + ']}'
return HttpResponse(jsons) return HttpResponse(jsons)
def room(request, building, room_number): def room(request, building, room_number):
room_obj = Room.objects.filter(building__name=''+building, number=room_number) room_obj = Room.objects.filter(building__name=''+building, number=room_number)
...@@ -52,6 +56,7 @@ def room(request, building, room_number): ...@@ -52,6 +56,7 @@ def room(request, building, room_number):
jsons += ']}' jsons += ']}'
return HttpResponse(jsons) return HttpResponse(jsons)
###################JASON trying to JSON in python, so confuzed: ###################JASON trying to JSON in python, so confuzed:
# if room_obj: # if room_obj:
# jsons = {'building':building, 'number':room_number, 'residents': []} # jsons = {'building':building, 'number':room_number, 'residents': []}
...@@ -65,6 +70,7 @@ def room(request, building, room_number): ...@@ -65,6 +70,7 @@ def room(request, building, room_number):
# jsons.residents[3] = 'bedD':p.bedD.__str__() # jsons.residents[3] = 'bedD':p.bedD.__str__()
# return HttpResponse(json.dumps(jsons)) # return HttpResponse(json.dumps(jsons))
def neighbourhood(request, nhood): def neighbourhood(request, nhood):
building_list = Building.objects.filter(neighbourhood=''+nhood).order_by('name') building_list = Building.objects.filter(neighbourhood=''+nhood).order_by('name')
jsons = 'That neighbourhood has no buildings or does not exist' jsons = 'That neighbourhood has no buildings or does not exist'
......
...@@ -22,8 +22,9 @@ class Building(TimeStampedModel): ...@@ -22,8 +22,9 @@ class Building(TimeStampedModel):
) )
neighbourhood = models.CharField(max_length=100, choices=NEIGHBOURHOOD_CHOICES, neighbourhood = models.CharField(max_length=100, choices=NEIGHBOURHOOD_CHOICES,
default=NONE) default=NONE)
#address = models.ForeignKey('Address')
# address = models.ForeignKey('Address')
PRINCE_WILLIAM = 'pw' PRINCE_WILLIAM = 'pw'
MASONVALE = 'mv' MASONVALE = 'mv'
...@@ -42,77 +43,80 @@ class Building(TimeStampedModel): ...@@ -42,77 +43,80 @@ class Building(TimeStampedModel):
def get_absolute_url(self): def get_absolute_url(self):
return reverse('detail_building', kwargs={ return reverse('detail_building', kwargs={
'building':self.building_name, 'building': self.building_name,
'slug':self.slug, 'slug': self.slug,
}) })
def __str__(self): # __unicode__ on Python 2 def __str__(self): # __unicode__ on Python 2
return self.name return self.name
def __unicode__(self): # __unicode__ on Python 2
def __unicode__(self): # __unicode__ on Python 2
return unicode(self.name) return unicode(self.name)
class Meta: class Meta:
ordering = ['name'] ordering = ['name']
class Floor(TimeStampedModel): class Floor(TimeStampedModel):
building = models.ForeignKey('Building') building = models.ForeignKey('Building')
number = models.IntegerField() number = models.IntegerField()
slug = RandomSlugField(length=6) slug = RandomSlugField(length=6)
floor_num = AutoSlugField(populate_from='number',# unique_with='building') floor_num = AutoSlugField(populate_from='number',) # unique_with='building')
)
def get_absolute_url(self): def get_absolute_url(self):
return reverse('detail_floor', kwargs={ return reverse('detail_floor', kwargs={
'building':self.building.building_name, 'building': self.building.building_name,
'floor':self.floor_num, 'floor': self.floor_num,
'slug':self.slug, 'slug': self.slug,
}) })
def __str__(self): # __unicode__ on Python 2 def __str__(self): # __unicode__ on Python 2
return self.building.__str__()+" "+self.number.__str__() return self.building.__str__()+" "+self.number.__str__()
class Meta: class Meta:
ordering = ['building', 'number'] ordering = ['building', 'number']
class Room(TimeStampedModel): class Room(TimeStampedModel):
number = models.IntegerField() number = models.IntegerField()
floor = models.ForeignKey('Floor') floor = models.ForeignKey('Floor')
slug = RandomSlugField(length=6) slug = RandomSlugField(length=6)
room_num = AutoSlugField(populate_from='number',# unique_with='floor') room_num = AutoSlugField(populate_from='number',) # unique_with='floor')
)
def get_absolute_url(self): def get_absolute_url(self):
return reverse('detail_room', kwargs={ return reverse('detail_room', kwargs={
'floor':self.floor.floor_num, 'floor': self.floor.floor_num,
'building':self.floor.building.building_name, 'building': self.floor.building.building_name,
'room':self.room_num, 'room': self.room_num,
'slug':self.slug, 'slug': self.slug,
}) })
def __str__(self): # __unicode__ on Python 2 def __str__(self): # __unicode__ on Python 2
return self.floor.building.__str__()+" "+self.number.__str__() return self.floor.building.__str__()+" "+self.number.__str__()
class Meta: class Meta:
ordering = ['number'] ordering = ['number']
# buildings on campus don't have separate addresses yet # buildings on campus don't have separate addresses yet
#class Address(TimeStampedModel): #class Address(TimeStampedModel):
# street = models.CharField(max_length=120) # street = models.CharField(max_length=120)
# city = models.CharField(max_length=120) # city = models.CharField(max_length=120)
# state = USStateField() # state = USStateField()
# zip_code = models.IntegerField(max_length=5) # zip_code = models.IntegerField(max_length=5)
# class Meta: # class Meta:
# verbose_name_plural = 'addresses' # verbose_name_plural = 'addresses'