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

pep8 me

parent f6ed6ce5
# standard library imports # standard library imports
from __future__ import absolute_import, print_function from __future__ import absolute_import, print_function
from datetime import datetime, timedelta
# core django imports # core django imports
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.views.generic import FormView
from django.contrib import messages from django.contrib import messages
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
# third party imports # third party imports
from allauth.socialaccount.adapter import DefaultSocialAccountAdapter from allauth.socialaccount.adapter import DefaultSocialAccountAdapter
from allauth.socialaccount.views import ConnectionsView from allauth.socialaccount.views import ConnectionsView
from allauth.socialaccount.forms import DisconnectForm
from allauth.exceptions import ImmediateHttpResponse from allauth.exceptions import ImmediateHttpResponse
from braces.views import LoginRequiredMixin from braces.views import LoginRequiredMixin
class AccountAdapter(DefaultSocialAccountAdapter): class AccountAdapter(DefaultSocialAccountAdapter):
"""A custom implementation of a portion of the allauth social media package. """A custom implementation of a portion of the allauth social media package.
...@@ -25,8 +23,8 @@ class AccountAdapter(DefaultSocialAccountAdapter): ...@@ -25,8 +23,8 @@ class AccountAdapter(DefaultSocialAccountAdapter):
# the request processed by the adapter is one from the successful oauth callback # the request processed by the adapter is one from the successful oauth callback
# uncomment this method to print what URL you are arriving from # uncomment this method to print what URL you are arriving from
#def pre_social_login(self, request, sociallogin): # def pre_social_login(self, request, sociallogin):
#print(request.get_full_path(), 'pre_login') # print(request.get_full_path(), 'pre_login')
def populate_user(self, request, sociallogin, data): def populate_user(self, request, sociallogin, data):
# This is a hook to populate User attributes, but we expressly don't actually # This is a hook to populate User attributes, but we expressly don't actually
...@@ -71,9 +69,10 @@ class AccountAdapter(DefaultSocialAccountAdapter): ...@@ -71,9 +69,10 @@ class AccountAdapter(DefaultSocialAccountAdapter):
messages.add_message(request, messages.ERROR, error_message) messages.add_message(request, messages.ERROR, error_message)
update_redirect = HttpResponseRedirect(reverse('update_student', kwargs={ update_redirect = HttpResponseRedirect(reverse('update_student', kwargs={
'slug': request.user.username, 'slug': request.user.username,
})) }))
raise ImmediateHttpResponse(update_redirect) raise ImmediateHttpResponse(update_redirect)
class RemoveSocialConfirmationView(LoginRequiredMixin, ConnectionsView): class RemoveSocialConfirmationView(LoginRequiredMixin, ConnectionsView):
"""To customize where users are sent when removing their social media connections. """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 We have written our own template to handle this feature that is much prettier than
...@@ -86,7 +85,7 @@ class RemoveSocialConfirmationView(LoginRequiredMixin, ConnectionsView): ...@@ -86,7 +85,7 @@ class RemoveSocialConfirmationView(LoginRequiredMixin, ConnectionsView):
if not request.user.socialaccount_set.all(): if not request.user.socialaccount_set.all():
# no social media accounts? back to the settings page with you! # no social media accounts? back to the settings page with you!
return HttpResponseRedirect(reverse('update_student', return HttpResponseRedirect(reverse('update_student',
kwargs={'slug':self.request.user.username})) kwargs={'slug': self.request.user.username}))
else: else:
return super(RemoveSocialConfirmationView, self).get(request, *args, **kwargs) return super(RemoveSocialConfirmationView, self).get(request, *args, **kwargs)
...@@ -95,4 +94,4 @@ class RemoveSocialConfirmationView(LoginRequiredMixin, ConnectionsView): ...@@ -95,4 +94,4 @@ class RemoveSocialConfirmationView(LoginRequiredMixin, ConnectionsView):
def get_success_url(self): def get_success_url(self):
return reverse('update_student', 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 ...@@ -5,6 +5,7 @@ from django.contrib import admin
# imports from your apps # imports from your apps
from .models import Student, Major, Confirmation from .models import Student, Major, Confirmation
class StudentAdmin(admin.ModelAdmin): class StudentAdmin(admin.ModelAdmin):
list_display = ("get_name", "room", "privacy", "major", "created") list_display = ("get_name", "room", "privacy", "major", "created")
......
...@@ -4,7 +4,6 @@ from __future__ import absolute_import, print_function ...@@ -4,7 +4,6 @@ from __future__ import absolute_import, print_function
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.conf import settings from django.conf import settings
from django.contrib import messages
# third party imports # third party imports
import requests import requests
# imports from your apps # imports from your apps
......
...@@ -83,22 +83,21 @@ class StudentUpdateForm(forms.Form): ...@@ -83,22 +83,21 @@ class StudentUpdateForm(forms.Form):
major = forms.ModelChoiceField(queryset=Major.objects.all(), required=False) major = forms.ModelChoiceField(queryset=Major.objects.all(), required=False)
graduating_year = forms.IntegerField() graduating_year = forms.IntegerField()
def clean(self): def clean(self):
cleaned_data = super(StudentUpdateForm, self).clean() cleaned_data = super(StudentUpdateForm, self).clean()
form_room = cleaned_data.get('room') form_room = cleaned_data.get('room')
if not(form_room is None): if not(form_room is None):
students_in_room = Student.objects.filter(room=form_room).count() 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. # like in bookshare, I have no idea why the form errors don't display.
if students_in_room > 12: if students_in_room > 12:
raise ValidationError(_('Too many students in room (%d).' % students_in_room), code='invalid') raise ValidationError(_('Too many students in room (%d).' % students_in_room), code='invalid')
def is_valid(self): def is_valid(self):
# errors are not printed in form.as_p? # errors are not printed in form.as_p?
#print("In is_valid.") # print("In is_valid.")
#print(self.is_bound, 'is bound') # print(self.is_bound, 'is bound')
#print(self.errors, type(self.errors), 'errors') # print(self.errors, type(self.errors), 'errors')
valid = super(StudentUpdateForm, self).is_valid() valid = super(StudentUpdateForm, self).is_valid()
#print(valid) # print(valid)
return valid return valid
from django.core.management.base import BaseCommand, CommandError from django.core.management.base import BaseCommand
from accounts.models import Student from accounts.models import Student
class Command(BaseCommand): class Command(BaseCommand):
args = "" args = ""
help = "Deletes all students' rooms at the end of the semester" help = "Deletes all students' rooms at the end of the semester"
def handle(self, *args, **kwargs): def handle(self, *args, **kwargs):
count = 0 count = 0
for student in Student.objects.all(): for student in Student.objects.all():
student.room = None student.room = None
count += 1 count += 1
self.stdout.write("Successfully overwrote %d student room(s)." % count) self.stdout.write("Successfully overwrote %d student room(s)." % count)
...@@ -8,8 +8,6 @@ from django.utils import timezone ...@@ -8,8 +8,6 @@ from django.utils import timezone
from model_utils.models import TimeStampedModel from model_utils.models import TimeStampedModel
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.utils.text import slugify
from django.contrib import messages
# third party imports # third party imports
from autoslug import AutoSlugField from autoslug import AutoSlugField
from randomslugfield import RandomSlugField from randomslugfield import RandomSlugField
...@@ -222,7 +220,6 @@ class Student(TimeStampedModel): ...@@ -222,7 +220,6 @@ class Student(TimeStampedModel):
# must be int-- floor function # must be int-- floor function
third_years = (days // (30 * 4)) + 1 third_years = (days // (30 * 4)) + 1
return (self.times_changed_room // third_years) return (self.times_changed_room // third_years)
def get_floor(self): def get_floor(self):
...@@ -248,7 +245,7 @@ class Student(TimeStampedModel): ...@@ -248,7 +245,7 @@ class Student(TimeStampedModel):
def profile_image_url(self): def profile_image_url(self):
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 "https://graph.facebook.com/{}/picture?width=175&height=175".format(fb_uid[0].uid) return "https://graph.facebook.com/{}/picture?width=175&height=175".format(fb_uid[0].uid)
...@@ -269,13 +266,13 @@ class Student(TimeStampedModel): ...@@ -269,13 +266,13 @@ class Student(TimeStampedModel):
return self.user.username return self.user.username
else: else:
return self.user.get_short_name() return self.user.get_short_name()
def get_last_name_or_uname(self): def get_last_name_or_uname(self):
if not(self.user.last_name): if not(self.user.last_name):
return self.user.username return self.user.username
else: else:
return self.user.last_name return self.user.last_name
def get_full_name_or_uname(self): def get_full_name_or_uname(self):
if not(self.user.get_full_name()): if not(self.user.get_full_name()):
return self.user.username return self.user.username
...@@ -301,12 +298,12 @@ class Student(TimeStampedModel): ...@@ -301,12 +298,12 @@ class Student(TimeStampedModel):
return unicode(self.user.username) return unicode(self.user.username)
# uncomment if there's something going awry while saving # uncomment if there's something going awry while saving
#def save(self, *args, **kwargs): # def save(self, *args, **kwargs):
#print('we be savin\'!') # print('we be savin\'!')
#from django.db.models.signals import pre_save, post_save # from django.db.models.signals import pre_save, post_save
#for signal in [pre_save, post_save]: # for signal in [pre_save, post_save]:
#print(signal, signal.receivers) # print(signal, signal.receivers)
#super(Student, self).save(*args, **kwargs) # super(Student, self).save(*args, **kwargs)
class Confirmation(TimeStampedModel): class Confirmation(TimeStampedModel):
......
...@@ -22,7 +22,8 @@ disclaimer = """Welcome back to SRCT Roomlist. Just to be perfectly clear, this ...@@ -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? whatsopen_plug = """Welcome back to SRCT Roomlist. Wondering what's open at this hour?
Check out another one of our Check out another one of our
<a href="https://srct.gmu.edu/projects/">student-built and hosted</a> <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, 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 <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, ...@@ -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 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]
...@@ -3,8 +3,7 @@ from __future__ import absolute_import, print_function ...@@ -3,8 +3,7 @@ from __future__ import absolute_import, print_function
# core django imports # core django imports
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, ListMajors,
DetailCurrentStudent, DetailCurrentStudentSettings, ListMajors,
DetailMajor, CreateConfirmation, DeleteConfirmation) DetailMajor, CreateConfirmation, DeleteConfirmation)
from .adapter import RemoveSocialConfirmationView from .adapter import RemoveSocialConfirmationView
......
...@@ -5,10 +5,8 @@ from distutils.util import strtobool ...@@ -5,10 +5,8 @@ from distutils.util import strtobool
from operator import attrgetter from operator import attrgetter
from itertools import chain from itertools import chain
# core django imports # core django imports
from django.shortcuts import get_object_or_404
from django.http import HttpResponseForbidden, HttpResponseRedirect from django.http import HttpResponseForbidden, HttpResponseRedirect
from django.views.generic import (CreateView, ListView, DetailView, UpdateView, from django.views.generic import CreateView, ListView, DetailView, FormView, DeleteView
FormView, DeleteView)
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.contrib import messages from django.contrib import messages
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
...@@ -19,7 +17,7 @@ from cas.views import login as cas_login ...@@ -19,7 +17,7 @@ from cas.views import login as cas_login
from ratelimit.decorators import ratelimit 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 Room
from .forms import StudentUpdateForm from .forms import StudentUpdateForm
from .student_messages import return_messages from .student_messages import return_messages
...@@ -99,6 +97,7 @@ class DetailStudent(LoginRequiredMixin, DetailView): ...@@ -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("Students are not supposed to be able to make more than one flag per student.")
print(e) print(e)
# recognizably too complex
def onFloor(): def onFloor():
floor_status = False floor_status = False
if requesting_student.get_floor() == self.get_object().get_floor(): if requesting_student.get_floor() == self.get_object().get_floor():
...@@ -185,17 +184,17 @@ class UpdateStudent(LoginRequiredMixin, FormValidMessageMixin, FormView): ...@@ -185,17 +184,17 @@ class UpdateStudent(LoginRequiredMixin, FormValidMessageMixin, FormView):
@ratelimit(key='user', rate='5/m', method='POST', block=True) @ratelimit(key='user', rate='5/m', method='POST', block=True)
@ratelimit(key='user', rate='10/d', method='POST', block=True) @ratelimit(key='user', rate='10/d', method='POST', block=True)
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
#for key, value in request.POST.iteritems(): # for key, value in request.POST.iteritems():
#print(key, value) # print(key, value)
return super(UpdateStudent, self).post(request, *args, **kwargs) return super(UpdateStudent, self).post(request, *args, **kwargs)
def form_valid(self, form): def form_valid(self, form):
me = Student.objects.get(user=self.request.user) 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(): # for key, value in form.data.iteritems():
#print(key, value) # print(key, value)
current_room = me.room current_room = me.room
...@@ -247,7 +246,7 @@ class UpdateStudent(LoginRequiredMixin, FormValidMessageMixin, FormView): ...@@ -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.') 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', return reverse('detail_student',
kwargs={'slug':self.request.user.username}) kwargs={'slug': self.request.user.username})
# majors pages # majors pages
...@@ -269,41 +268,39 @@ class DetailMajor(LoginRequiredMixin, DetailView): ...@@ -269,41 +268,39 @@ class DetailMajor(LoginRequiredMixin, DetailView):
context = super(DetailMajor, self).get_context_data(**kwargs) context = super(DetailMajor, self).get_context_data(**kwargs)
requesting_student = Student.objects.get(user=self.request.user) requesting_student = Student.objects.get(user=self.request.user)
# retrieve every room that has a student with the major in question # retrieve every room that has a student with the major in question
neighbourhoods = ("aq", "ra", "sh") neighbourhoods = ("aq", "ra", "sh")
visible_by_neighbourhood = {} visible_by_neighbourhood = {}
for neighbourhood in neighbourhoods: for neighbourhood in neighbourhoods:
rooms = [ rooms = [
room room
for room in Room.objects.filter(floor__building__neighbourhood=neighbourhood) for room in Room.objects.filter(floor__building__neighbourhood=neighbourhood)
if room.student_set.filter(major=self.get_object()) if room.student_set.filter(major=self.get_object())
] ]
# identify if the student(s) in that room are visible to the requesting student # 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 # '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 # we sort each of the lists of students by their username
# as elsewhere, this is imperfect if a student changes their display name # 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 # this is necessary as a separate step because .visible returns a list type
# note we're using '.' instead of '__', because who likes syntactical consistency # note we're using '.' instead of '__', because who likes syntactical consistency
visible_by_neighbourhood[neighbourhood] = sorted(list(chain(*[ visible_by_neighbourhood[neighbourhood] = sorted(list(chain(*[
Student.objects.visible(requesting_student, room) Student.objects.visible(requesting_student, room)
for room in rooms for room in rooms
])), key=attrgetter('user.username')) ])), key=attrgetter('user.username'))
# print(visible_by_neighbourhood)
# see what students are left over (aren't visible) # see what students are left over (aren't visible)
hidden = set(Student.objects.filter(major=self.get_object()).order_by('user__username')) hidden = set(Student.objects.filter(major=self.get_object()).order_by('user__username'))
# print(hidden) # print(hidden)
for visible in visible_by_neighbourhood.values(): for visible in visible_by_neighbourhood.values():
# print('visible', visible) # print('visible', visible)
hidden = hidden.difference(set(visible)) hidden = hidden.difference(set(visible))
# print(hidden) # print(hidden)
for neighbourhood, visible in visible_by_neighbourhood.iteritems(): for neighbourhood, visible in visible_by_neighbourhood.iteritems():
context['%s_location_visible' % neighbourhood] = visible context['%s_location_visible' % neighbourhood] = visible
context['location_hidden'] = hidden context['location_hidden'] = hidden
return context return context
...@@ -344,7 +341,6 @@ class CreateConfirmation(LoginRequiredMixin, CreateView): ...@@ -344,7 +341,6 @@ class CreateConfirmation(LoginRequiredMixin, CreateView):
return super(CreateConfirmation, self).get(request, *args, **kwargs) return super(CreateConfirmation, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(CreateConfirmation, self).get_context_data(**kwargs) context = super(CreateConfirmation, self).get_context_data(**kwargs)
...@@ -380,7 +376,7 @@ class CreateConfirmation(LoginRequiredMixin, CreateView): ...@@ -380,7 +376,7 @@ class CreateConfirmation(LoginRequiredMixin, CreateView):
def get_success_url(self): def get_success_url(self):
# redirect to the flagged student page when saving # redirect to the flagged student page when saving
return reverse('detail_student', return reverse('detail_student',
kwargs={'slug':self.object.student.slug}) kwargs={'slug': self.object.student.slug})
class DeleteConfirmation(LoginRequiredMixin, DeleteView): class DeleteConfirmation(LoginRequiredMixin, DeleteView):
...@@ -400,4 +396,4 @@ class DeleteConfirmation(LoginRequiredMixin, DeleteView): ...@@ -400,4 +396,4 @@ class DeleteConfirmation(LoginRequiredMixin, DeleteView):
def get_success_url(self): def get_success_url(self):
return reverse('detail_student', return reverse('detail_student',
kwargs={'slug':self.object.student.slug}) kwargs={'slug': self.object.student.slug})
...@@ -50,10 +50,10 @@ class BuildingRetrieve(RetrieveAPIView): ...@@ -50,10 +50,10 @@ class BuildingRetrieve(RetrieveAPIView):
lookup_field = 'building_name' lookup_field = 'building_name'
#class FloorList(ListAPIView): # class FloorList(ListAPIView):
# queryset = Floor.objects.all() # queryset = Floor.objects.all()
# serializer_class = FloorSerializer # serializer_class = FloorSerializer
# pagination_class = HousingPagination # pagination_class = HousingPagination
class FloorRetrieve(MultipleFieldLookupMixin, RetrieveAPIView): class FloorRetrieve(MultipleFieldLookupMixin, RetrieveAPIView):
...@@ -71,10 +71,10 @@ class RoomRetrieve(MultipleFieldLookupMixin, RetrieveAPIView): ...@@ -71,10 +71,10 @@ class RoomRetrieve(MultipleFieldLookupMixin, RetrieveAPIView):
'floor__building__building_name') 'floor__building__building_name')
#class RoomList(ListAPIView): # kek # class RoomList(ListAPIView): # kek
# queryset = Room.objects.all() # queryset = Room.objects.all()
# serializer_class = RoomSerializer # serializer_class = RoomSerializer
# pagination_class = HousingPagination # pagination_class = HousingPagination
# major apis # major apis
......
...@@ -5,11 +5,8 @@ from django import forms ...@@ -5,11 +5,8 @@ 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 localflavor.us.us_states import US_STATES as states from localflavor.us.us_states import US_STATES as states
# imports from your apps
#class YesNoBooleanWidget(forms.widget.RadioWidget):
class AddressWidget(forms.widgets.Widget): class AddressWidget(forms.widgets.Widget):
template_name = 'address_widget.html' template_name = 'address_widget.html'
......
# core django imports
from django.db import models
# third party imports
from localflavor.us.models import USStateField, USZipCodeField from localflavor.us.models import USStateField, USZipCodeField
from model_utils.models import TimeStampedModel
# buildings on campus don't have separate addresses yet # buildings on campus don't have separate addresses yet
class Address(TimeStampedModel): class Address(TimeStampedModel):
......
...@@ -15,47 +15,47 @@ from housing.models import Building, Floor, Room ...@@ -15,47 +15,47 @@ from housing.models import Building, Floor, Room
# check if there are rooms already in the database # check if there are rooms already in the database
# building name, neighborhood # building name, neighborhood
mason_housing = { 'Adams': 'sh', mason_housing = {'Adams': 'sh',
'Apartment 1': 'aq', 'Apartment 1': 'aq',
'Apartment 2': 'aq', 'Apartment 2': 'aq',
'Apartment 3': 'aq', 'Apartment 3': 'aq',
'Apartment 4': 'aq', 'Apartment 4': 'aq',
'Apartment 5': 'aq', 'Apartment 5': 'aq',
'Apartment 6': 'aq', 'Apartment 6': 'aq',
'Apartment 7': 'aq', 'Apartment 7': 'aq',
'Apartment 8': 'aq', 'Apartment 8': 'aq',
'Apartment 9': 'aq', 'Apartment 9': 'aq',
'Amherst': 'ra', 'Amherst': 'ra',
'Blue Ridge': 'ra', 'Blue Ridge': 'ra',
'Brunswick': 'ra', 'Brunswick': 'ra',
'Carroll': 'ra', <