Commit a9375e40 authored by Daniel W Bond's avatar Daniel W Bond

pep8 me

parent f6ed6ce5
# standard library imports
from __future__ import absolute_import, print_function
from datetime import datetime, timedelta
# core django imports
from django.core.urlresolvers import reverse
from django.views.generic import FormView
from django.contrib import messages
from django.http import HttpResponseRedirect
# third party imports
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from allauth.socialaccount.views import ConnectionsView
from allauth.socialaccount.forms import DisconnectForm
from allauth.exceptions import ImmediateHttpResponse
from braces.views import LoginRequiredMixin
class AccountAdapter(DefaultSocialAccountAdapter):
"""A custom implementation of a portion of the allauth social media package.
......@@ -25,8 +23,8 @@ class AccountAdapter(DefaultSocialAccountAdapter):
# the request processed by the adapter is one from the successful oauth callback
# uncomment this method to print what URL you are arriving from
#def pre_social_login(self, request, sociallogin):
#print(request.get_full_path(), 'pre_login')
# def pre_social_login(self, request, sociallogin):
# print(request.get_full_path(), 'pre_login')
def populate_user(self, request, sociallogin, data):
# This is a hook to populate User attributes, but we expressly don't actually
......@@ -71,9 +69,10 @@ class AccountAdapter(DefaultSocialAccountAdapter):
messages.add_message(request, messages.ERROR, error_message)
update_redirect = HttpResponseRedirect(reverse('update_student', kwargs={
'slug': request.user.username,
}))
}))
raise ImmediateHttpResponse(update_redirect)
class RemoveSocialConfirmationView(LoginRequiredMixin, ConnectionsView):
"""To customize where users are sent when removing their social media connections.
We have written our own template to handle this feature that is much prettier than
......@@ -86,7 +85,7 @@ class RemoveSocialConfirmationView(LoginRequiredMixin, ConnectionsView):
if not request.user.socialaccount_set.all():
# no social media accounts? back to the settings page with you!
return HttpResponseRedirect(reverse('update_student',
kwargs={'slug':self.request.user.username}))
kwargs={'slug': self.request.user.username}))
else:
return super(RemoveSocialConfirmationView, self).get(request, *args, **kwargs)
......@@ -95,4 +94,4 @@ class RemoveSocialConfirmationView(LoginRequiredMixin, ConnectionsView):
def get_success_url(self):
return reverse('update_student',
kwargs={'slug':self.request.user.username})
kwargs={'slug': self.request.user.username})
......@@ -5,6 +5,7 @@ from django.contrib import admin
# imports from your apps
from .models import Student, Major, Confirmation
class StudentAdmin(admin.ModelAdmin):
list_display = ("get_name", "room", "privacy", "major", "created")
......
......@@ -4,7 +4,6 @@ from __future__ import absolute_import, print_function
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist
from django.conf import settings
from django.contrib import messages
# third party imports
import requests
# imports from your apps
......
......@@ -83,22 +83,21 @@ class StudentUpdateForm(forms.Form):
major = forms.ModelChoiceField(queryset=Major.objects.all(), required=False)
graduating_year = forms.IntegerField()
def clean(self):
cleaned_data = super(StudentUpdateForm, 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)
# 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')
def is_valid(self):
# errors are not printed in form.as_p?
#print("In is_valid.")
#print(self.is_bound, 'is bound')
#print(self.errors, type(self.errors), 'errors')
# print("In is_valid.")
# print(self.is_bound, 'is bound')
# print(self.errors, type(self.errors), 'errors')
valid = super(StudentUpdateForm, self).is_valid()
#print(valid)
# print(valid)
return valid
from django.core.management.base import BaseCommand, CommandError
from accounts.models import Student
from django.core.management.base import BaseCommand
from accounts.models import Student
class Command(BaseCommand):
args = ""
help = "Deletes all students' rooms at the end of the semester"
def handle(self, *args, **kwargs):
count = 0
for student in Student.objects.all():
student.room = None
count += 1
count += 1
self.stdout.write("Successfully overwrote %d student room(s)." % count)
......@@ -8,8 +8,6 @@ from django.utils import timezone
from model_utils.models import TimeStampedModel
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.utils.text import slugify
from django.contrib import messages
# third party imports
from autoslug import AutoSlugField
from randomslugfield import RandomSlugField
......@@ -222,7 +220,6 @@ class Student(TimeStampedModel):
# must be int-- floor function
third_years = (days // (30 * 4)) + 1
return (self.times_changed_room // third_years)
def get_floor(self):
......@@ -248,7 +245,7 @@ class Student(TimeStampedModel):
def profile_image_url(self):
fb_uid = SocialAccount.objects.filter(user=self.user.id, provider='facebook')
#print("profile_image")
# print("profile_image")
if len(fb_uid) > 0:
return "https://graph.facebook.com/{}/picture?width=175&height=175".format(fb_uid[0].uid)
......@@ -269,13 +266,13 @@ class Student(TimeStampedModel):
return self.user.username
else:
return self.user.get_short_name()
def get_last_name_or_uname(self):
if not(self.user.last_name):
return self.user.username
else:
return self.user.last_name
def get_full_name_or_uname(self):
if not(self.user.get_full_name()):
return self.user.username
......@@ -301,12 +298,12 @@ class Student(TimeStampedModel):
return unicode(self.user.username)
# uncomment if there's something going awry while saving
#def save(self, *args, **kwargs):
#print('we be savin\'!')
#from django.db.models.signals import pre_save, post_save
#for signal in [pre_save, post_save]:
#print(signal, signal.receivers)
#super(Student, self).save(*args, **kwargs)
# def save(self, *args, **kwargs):
# print('we be savin\'!')
# from django.db.models.signals import pre_save, post_save
# for signal in [pre_save, post_save]:
# print(signal, signal.receivers)
# super(Student, self).save(*args, **kwargs)
class Confirmation(TimeStampedModel):
......
......@@ -22,7 +22,8 @@ disclaimer = """Welcome back to SRCT Roomlist. Just to be perfectly clear, this
whatsopen_plug = """Welcome back to SRCT Roomlist. Wondering what's open at this hour?
Check out another one of our
<a href="https://srct.gmu.edu/projects/">student-built and hosted</a>
projects: <a href="https://whatsopen.gmu.edu/">whatsopen.gmu.edu</a>."""
projects:
<a href="https://whatsopen.gmu.edu/">whatsopen.gmu.edu</a>."""
open_source = """Welcome back to SRCT Roomlist. For the curious at heart,
<a href="http://www.gnu.org/philosophy/free-sw.en.html">you can always
......@@ -31,5 +32,5 @@ open_source = """Welcome back to SRCT Roomlist. For the curious at heart,
Come <a href="https://srct.gmu.edu/">to a meeting</a> and learn how to
contribute!"""
return_messages = [bug_reporting, privacy_reminder, disclaimer, whatsopen_plug, open_source]
return_messages = [bug_reporting, privacy_reminder, disclaimer,
whatsopen_plug, open_source]
......@@ -3,8 +3,7 @@ from __future__ import absolute_import, print_function
# core django imports
from django.conf.urls import patterns, include, url
# imports from your apps
from .views import (DetailStudent, UpdateStudent, DetailStudentSettings,
DetailCurrentStudent, DetailCurrentStudentSettings, ListMajors,
from .views import (DetailStudent, UpdateStudent, ListMajors,
DetailMajor, CreateConfirmation, DeleteConfirmation)
from .adapter import RemoveSocialConfirmationView
......
......@@ -5,10 +5,8 @@ from distutils.util import strtobool
from operator import attrgetter
from itertools import chain
# core django imports
from django.shortcuts import get_object_or_404
from django.http import HttpResponseForbidden, HttpResponseRedirect
from django.views.generic import (CreateView, ListView, DetailView, UpdateView,
FormView, DeleteView)
from django.views.generic import CreateView, ListView, DetailView, FormView, DeleteView
from django.core.urlresolvers import reverse
from django.contrib import messages
from django.utils.safestring import mark_safe
......@@ -19,7 +17,7 @@ from cas.views import login as cas_login
from ratelimit.decorators import ratelimit
# imports from your apps
from .models import Student, Major, Confirmation
from housing.models import Building, Floor, Room
from housing.models import Room
from .forms import StudentUpdateForm
from .student_messages import return_messages
......@@ -99,6 +97,7 @@ class DetailStudent(LoginRequiredMixin, DetailView):
print("Students are not supposed to be able to make more than one flag per student.")
print(e)
# recognizably too complex
def onFloor():
floor_status = False
if requesting_student.get_floor() == self.get_object().get_floor():
......@@ -185,17 +184,17 @@ class UpdateStudent(LoginRequiredMixin, FormValidMessageMixin, FormView):
@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):
#for key, value in request.POST.iteritems():
#print(key, value)
# for key, value in request.POST.iteritems():
# print(key, value)
return super(UpdateStudent, self).post(request, *args, **kwargs)
def form_valid(self, form):
me = Student.objects.get(user=self.request.user)
#print("In form valid method!")
# print("In form valid method!")
#for key, value in form.data.iteritems():
#print(key, value)
# for key, value in form.data.iteritems():
# print(key, value)
current_room = me.room
......@@ -247,7 +246,7 @@ class UpdateStudent(LoginRequiredMixin, FormValidMessageMixin, FormView):
messages.add_message(self.request, messages.WARNING, 'To safeguard everyone\'s privacy, you have just one remaining room change for the semester before you\'ll need to send us an email at roomlist@lists.srct.gmu.edu.')
return reverse('detail_student',
kwargs={'slug':self.request.user.username})
kwargs={'slug': self.request.user.username})
# majors pages
......@@ -269,41 +268,39 @@ class DetailMajor(LoginRequiredMixin, DetailView):
context = super(DetailMajor, self).get_context_data(**kwargs)
requesting_student = Student.objects.get(user=self.request.user)
# retrieve every room that has a student with the major in question
neighbourhoods = ("aq", "ra", "sh")
visible_by_neighbourhood = {}
for neighbourhood in neighbourhoods:
rooms = [
room
for room in Room.objects.filter(floor__building__neighbourhood=neighbourhood)
if room.student_set.filter(major=self.get_object())
]
# identify if the student(s) in that room are visible to the requesting student
# 'chain' is necessary if there are multiple students in one room with the same major
#
# we sort each of the lists of students by their username
# as elsewhere, this is imperfect if a student changes their display name
# this is necessary as a separate step because .visible returns a list type
# note we're using '.' instead of '__', because who likes syntactical consistency
visible_by_neighbourhood[neighbourhood] = sorted(list(chain(*[
Student.objects.visible(requesting_student, room)
for room in rooms
])), key=attrgetter('user.username'))
# print(visible_by_neighbourhood)
# retrieve every room that has a student with the major in question
neighbourhoods = ("aq", "ra", "sh")
visible_by_neighbourhood = {}
for neighbourhood in neighbourhoods:
rooms = [
room
for room in Room.objects.filter(floor__building__neighbourhood=neighbourhood)
if room.student_set.filter(major=self.get_object())
]
# identify if the student(s) in that room are visible to the requesting student
# 'chain' is necessary if there are multiple students in one room with the same major
#
# we sort each of the lists of students by their username
# as elsewhere, this is imperfect if a student changes their display name
# this is necessary as a separate step because .visible returns a list type
# note we're using '.' instead of '__', because who likes syntactical consistency
visible_by_neighbourhood[neighbourhood] = sorted(list(chain(*[
Student.objects.visible(requesting_student, room)
for room in rooms
])), key=attrgetter('user.username'))
# see what students are left over (aren't visible)
hidden = set(Student.objects.filter(major=self.get_object()).order_by('user__username'))
# print(hidden)
for visible in visible_by_neighbourhood.values():
for visible in visible_by_neighbourhood.values():
# print('visible', visible)
hidden = hidden.difference(set(visible))
hidden = hidden.difference(set(visible))
# print(hidden)
for neighbourhood, visible in visible_by_neighbourhood.iteritems():
context['%s_location_visible' % neighbourhood] = visible
context['location_hidden'] = hidden
for neighbourhood, visible in visible_by_neighbourhood.iteritems():
context['%s_location_visible' % neighbourhood] = visible
context['location_hidden'] = hidden
return context
......@@ -344,7 +341,6 @@ class CreateConfirmation(LoginRequiredMixin, CreateView):
return super(CreateConfirmation, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(CreateConfirmation, self).get_context_data(**kwargs)
......@@ -380,7 +376,7 @@ class CreateConfirmation(LoginRequiredMixin, CreateView):
def get_success_url(self):
# redirect to the flagged student page when saving
return reverse('detail_student',
kwargs={'slug':self.object.student.slug})
kwargs={'slug': self.object.student.slug})
class DeleteConfirmation(LoginRequiredMixin, DeleteView):
......@@ -400,4 +396,4 @@ class DeleteConfirmation(LoginRequiredMixin, DeleteView):
def get_success_url(self):
return reverse('detail_student',
kwargs={'slug':self.object.student.slug})
kwargs={'slug': self.object.student.slug})
......@@ -50,10 +50,10 @@ class BuildingRetrieve(RetrieveAPIView):
lookup_field = 'building_name'
#class FloorList(ListAPIView):
# queryset = Floor.objects.all()
# serializer_class = FloorSerializer
# pagination_class = HousingPagination
# class FloorList(ListAPIView):
# queryset = Floor.objects.all()
# serializer_class = FloorSerializer
# pagination_class = HousingPagination
class FloorRetrieve(MultipleFieldLookupMixin, RetrieveAPIView):
......@@ -71,10 +71,10 @@ class RoomRetrieve(MultipleFieldLookupMixin, RetrieveAPIView):
'floor__building__building_name')
#class RoomList(ListAPIView): # kek
# queryset = Room.objects.all()
# serializer_class = RoomSerializer
# pagination_class = HousingPagination
# class RoomList(ListAPIView): # kek
# queryset = Room.objects.all()
# serializer_class = RoomSerializer
# pagination_class = HousingPagination
# major apis
......
......@@ -5,11 +5,8 @@ from django import forms
from django.utils.safestring import mark_safe
from django.template.loader import render_to_string
from localflavor.us.us_states import US_STATES as states
# imports from your apps
#class YesNoBooleanWidget(forms.widget.RadioWidget):
class AddressWidget(forms.widgets.Widget):
template_name = 'address_widget.html'
......
# core django imports
from django.db import models
# third party imports
from localflavor.us.models import USStateField, USZipCodeField
from model_utils.models import TimeStampedModel
# buildings on campus don't have separate addresses yet
class Address(TimeStampedModel):
......
......@@ -15,47 +15,47 @@ from housing.models import Building, Floor, Room
# check if there are rooms already in the database
# building name, neighborhood
mason_housing = { 'Adams': 'sh',
'Apartment 1': 'aq',
'Apartment 2': 'aq',
'Apartment 3': 'aq',
'Apartment 4': 'aq',
'Apartment 5': 'aq',
'Apartment 6': 'aq',
'Apartment 7': 'aq',
'Apartment 8': 'aq',
'Apartment 9': 'aq',
'Amherst': 'ra',
'Blue Ridge': 'ra',
'Brunswick': 'ra',
'Carroll': 'ra',
'Commonwealth': 'ra', # weird floor numbers, use [1] instead of [0]
'Dickenson': 'ra',
'Dominion': 'ra', # ditto Commonwealth
'Eastern Shore': 'ra',
'Essex': 'ra',
'Franklin': 'ra',
'Grayson': 'ra',
'Hampton Roads': 'ra',
'Harrison': 'sh',
'Jackson': 'sh',
'Jefferson': 'sh',
'Kennedy': 'sh',
'Lincoln': 'sh',
'Liberty Square': 'sh', # wing letters precede room numbers
'Madison': 'sh',
'Monroe': 'sh',
'Northern Neck': 'ra',
'Piedmont': 'ra',
'Potomac Heights': 'sh',
'Rogers': 'aq',
'Roosevelt': 'sh',
'Sandbridge': 'ra',
'Tidewater': 'ra',
'Truman': 'sh',
'Washington': 'sh',
'Whitetop': 'aq',
'Wilson': 'sh', }
mason_housing = {'Adams': 'sh',
'Apartment 1': 'aq',
'Apartment 2': 'aq',
'Apartment 3': 'aq',
'Apartment 4': 'aq',
'Apartment 5': 'aq',
'Apartment 6': 'aq',
'Apartment 7': 'aq',
'Apartment 8': 'aq',
'Apartment 9': 'aq',
'Amherst': 'ra',
'Blue Ridge': 'ra',
'Brunswick': 'ra',
'Carroll': 'ra',
'Commonwealth': 'ra', # weird floor numbers, use [1] instead of [0]
'Dickenson': 'ra',
'Dominion': 'ra', # ditto Commonwealth
'Eastern Shore': 'ra',
'Essex': 'ra',
'Franklin': 'ra',
'Grayson': 'ra',
'Hampton Roads': 'ra',
'Harrison': 'sh',
'Jackson': 'sh',
'Jefferson': 'sh',
'Kennedy': 'sh',
'Lincoln': 'sh',
'Liberty Square': 'sh', # wing letters precede room numbers
'Madison': 'sh',
'Monroe': 'sh',
'Northern Neck': 'ra',
'Piedmont': 'ra',
'Potomac Heights': 'sh',
'Rogers': 'aq',
'Roosevelt': 'sh',
'Sandbridge': 'ra',
'Tidewater': 'ra',
'Truman': 'sh',
'Washington': 'sh',
'Whitetop': 'aq',
'Wilson': 'sh', }
# Townhouses -- really whacky naming
# Beacon Hall -- graduate students
......@@ -95,26 +95,28 @@ with open('housing/building_floors.txt') as buildings:
my_floor.save()
new_floors += 1
print("Created %d new floors, %d floors total." % (new_floors, Floor.objects.all().count()))
print("Created %d new floors, %d floors total." % (new_floors,
Floor.objects.all().count()))
print("Creating rooms...")
new_rooms = 0
with open('housing/building_rooms.txt') as rooms:
for line in rooms:
line = line.strip()
if re.match('^[a-z A-Z]*( {1}\d)?$', line):
current_building = Building.objects.get(name=line)
print(current_building)
else:
if current_building.name in ('Commonwealth', 'Dominion', 'Liberty Square'):
my_floor = Floor.objects.get(building=current_building, number=line[1])
else:
my_floor = Floor.objects.get(building=current_building, number=line[0])
my_room, room_created = Room.objects.get_or_create(floor=my_floor, number=line)
if room_created:
new_rooms += 1
my_room.save()
for line in rooms:
line = line.strip()
if re.match('^[a-z A-Z]*( {1}\d)?$', line):
current_building = Building.objects.get(name=line)
print(current_building)
else:
if current_building.name in ('Commonwealth', 'Dominion', 'Liberty Square'):
my_floor = Floor.objects.get(building=current_building, number=line[1])
else:
my_floor = Floor.objects.get(building=current_building, number=line[0])
my_room, room_created = Room.objects.get_or_create(floor=my_floor,
number=line)
if room_created:
new_rooms += 1
my_room.save()
print("Created %d new rooms, %d rooms total." % (new_rooms, Room.objects.all().count()))
end_time = datetime.now()
......
# installation configurations
# copy to config.py
# These configurations are set by default for a local development environment. Turning off debug mode will display 404 and 500 error pages instead of detailed logs.
# These configurations are set by default for a local development environment. Turning
# off debug mode will display 404 and 500 error pages instead of detailed logs.
# Don't run with debug turned on in production!!!
DEBUG = True
......
......@@ -6,7 +6,10 @@
SECRET_KEY = ''
# These configurations are partially set by default for a local development environment. Remember to use a strong passphrase for deployment. Use the username and password you configured creating the database while following the README. Change the database name, host, or port as necessary for deployment.
# These configurations are partially set by default for a local development environment.
# Remember to use a strong passphrase for deployment. Use the username and password you
# configured creating the database while following the README. Change the database name,
# host, or port as necessary for deployment.
DB_NAME = 'roomlist'
DB_USER = ''
......
......@@ -110,7 +110,7 @@ MIDDLEWARE_CLASSES = (
# for bootstrap css classes
from django.contrib.messages import constants as messages
MESSAGE_TAGS = {messages.ERROR: 'danger',}
MESSAGE_TAGS = {messages.ERROR: 'danger', }
ROOT_URLCONF = 'settings.urls'
......@@ -190,9 +190,9 @@ CAS_RESPONSE_CALLBACKS = (
)
HAYSTACK_CONNECTIONS = {
'default' : {
'ENGINE' : 'haystack.backends.whoosh_backend.WhooshEngine',
'PATH' : os.path.join(os.path.dirname(__file__), 'whoosh_index'),
'default': {
'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
'PATH': os.path.join(os.path.dirname(__file__), 'whoosh_index'),
},
}
......@@ -243,7 +243,7 @@ if not DEBUG:
},
# 'mail_admins' by default does not include a traceback attachment
# setting 'include_html' to True will attach an html traceback file to the email
# you can also set an addtional 'email_backend' arg to a custom email handler (e.g. SES)
# you can also set an additional 'email_backend' arg to a custom email handler (e.g. SES)
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler',
......
......@@ -8,6 +8,7 @@ import requests
webhook_url = 'https://hooks.slack.com/services/xxxxxxxxx/xxxxxxxxx/xxxxxxxxxxxxxxxxxxxxxxxx'
def slack_post(text, channel, username, icon_emoji):
try:
payload = {'text': text, 'channel': channel,
......
......@@ -5,9 +5,9 @@ from django.shortcuts import render
from django.views.generic import (View,