Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
R
roomlist
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
23
Issues
23
List
Boards
Labels
Service Desk
Milestones
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
SRCT
roomlist
Commits
1f8de306
Commit
1f8de306
authored
Sep 27, 2016
by
Daniel W Bond
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added comments to the accounts app
parent
867e0dc0
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
95 additions
and
164 deletions
+95
-164
roomlist/accounts/adapter.py
roomlist/accounts/adapter.py
+21
-7
roomlist/accounts/forms.py
roomlist/accounts/forms.py
+3
-0
roomlist/accounts/models.py
roomlist/accounts/models.py
+29
-11
roomlist/accounts/student_messages.py
roomlist/accounts/student_messages.py
+35
-0
roomlist/accounts/templates/studentSettings.html
roomlist/accounts/templates/studentSettings.html
+0
-70
roomlist/accounts/urls.py
roomlist/accounts/urls.py
+1
-8
roomlist/accounts/views.py
roomlist/accounts/views.py
+6
-68
No files found.
roomlist/accounts/adapter.py
View file @
1f8de306
...
...
@@ -14,26 +14,33 @@ 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.
# the request processed by the adapter is one from the successful oauth callback
We're overriding a number of aspects of the allauth account adapter to support
our special use of the package. We are using CAS, not Django's built-in
authentication. Accordingly we change the where directed when successfully
connecting an account and how errors are dealt with. Additionally, we are not using
the social media accounts to verify or overwrite any aspect of the User model.
"""
# 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
populate_user
(
self
,
request
,
sociallogin
,
data
):
# we don't actually want to overwrite anything from the
# social media account user
# This is a hook to populate User attributes, but we expressly don't actually
# want to overwrite anything from the social media account user. It's intended
# in the package for when you are using social media for login.
user
=
sociallogin
.
user
return
user
def
get_connect_redirect_url
(
self
,
request
,
socialaccount
):
# where the user is sent if the social account is indeed authenticated
assert
request
.
user
.
is_authenticated
()
#print(request.get_full_path())
#if 'welcome' in request.get_full_path():
# ergo, we go with more of an approximation (at least for now)
# we are approximating that if a user has not completed the welcome walkthough,
# it is likely the page on which they started-- see the pre_social_login method
if
not
request
.
user
.
student
.
completedSocial
:
return
reverse
(
'welcomeSocial'
,
kwargs
=
{
'slug'
:
request
.
user
.
username
,
...
...
@@ -45,6 +52,7 @@ class AccountAdapter(DefaultSocialAccountAdapter):
def
authentication_error
(
self
,
request
,
provider_id
,
error
=
None
,
exception
=
None
,
extra_context
=
None
):
"""Adds a custom message to the message queue if social media auth fails."""
error_message
=
"""Looks like something went awry with your social
authentication. Wait a moment and try your username and
...
...
@@ -52,6 +60,8 @@ class AccountAdapter(DefaultSocialAccountAdapter):
sending an email to roomlist@lists.srct.gmu.edu."""
if
not
request
.
user
.
student
.
completedSocial
:
# as a reminder, here is how django handles messages
# https://docs.djangoproject.com/en/1.8/ref/contrib/messages/
messages
.
add_message
(
request
,
messages
.
ERROR
,
error_message
)
social_redirect
=
HttpResponseRedirect
(
reverse
(
'welcomeSocial'
,
kwargs
=
{
'slug'
:
request
.
user
.
username
,
...
...
@@ -65,6 +75,10 @@ class AccountAdapter(DefaultSocialAccountAdapter):
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
the one provided by allauth."""
template_name
=
"remove_social.html"
login_url
=
'login'
...
...
roomlist/accounts/forms.py
View file @
1f8de306
...
...
@@ -13,6 +13,7 @@ from housing.models import Building, Floor, Room
class
SelectRoomWidget
(
forms
.
widgets
.
Select
):
"""A series of dropdowns in which a student can filter through housing options."""
template_name
=
'room_select_widget.html'
...
...
@@ -47,6 +48,7 @@ class SelectRoomWidget(forms.widgets.Select):
class
SelectRoomField
(
forms
.
models
.
ModelChoiceField
):
"""A special field for room selection, using the room selection widget."""
widget
=
SelectRoomWidget
# should raise error if user hasn't actually selected room, made it to end of selectors
...
...
@@ -54,6 +56,7 @@ class SelectRoomField(forms.models.ModelChoiceField):
class
BooleanRadioField
(
forms
.
TypedChoiceField
):
"""Displays booleans as a radio selector, rather than checkboxes."""
def
__init__
(
self
,
*
args
,
**
kwargs
):
boolean_choices
=
((
True
,
'Yes'
),
(
False
,
'No'
))
...
...
roomlist/accounts/models.py
View file @
1f8de306
# standard library imports
from
__future__
import
absolute_import
,
print_function
from
__future__
import
absolute_import
,
print_function
,
division
import
hashlib
from
datetime
import
date
# core django imports
...
...
@@ -46,6 +46,12 @@ class Major(TimeStampedModel):
class
StudentQuerySet
(
models
.
query
.
QuerySet
):
"""Set theory defining groups of students based on their housing locations.
Used in determining privacy."""
# allows calling .floor or .building or .students when referencing a students'
# privacy to simplify life syntactically
def
floor
(
self
):
return
self
.
filter
(
privacy
=
'floor'
)
...
...
@@ -73,6 +79,10 @@ class StudentQuerySet(models.query.QuerySet):
return
list
(
floor
)
+
list
(
set
(
building_students
)
-
set
(
floor
))
def
visible
(
self
,
student
,
housing
):
"""Returns a list of students visible to the student reviewing a housing object.
Example usage:
Student.objects.visible(request.user.student, floor)"""
if
isinstance
(
housing
,
Room
):
rooms
=
[
housing
]
elif
isinstance
(
housing
,
Floor
):
...
...
@@ -96,8 +106,8 @@ class StudentQuerySet(models.query.QuerySet):
class
StudentManager
(
models
.
Manager
):
# this 'duplication' allows for queryset chaining
# https://docs.djangoproject.com/en/1.8/topics/db/managers/
def
get_queryset
(
self
):
return
StudentQuerySet
(
self
.
model
,
using
=
self
.
_db
)
...
...
@@ -173,9 +183,9 @@ class Student(TimeStampedModel):
original_first_name
=
models
.
CharField
(
max_length
=
100
,
blank
=
True
)
original_last_name
=
models
.
CharField
(
max_length
=
100
,
blank
=
True
)
# social media accounts
# welcome walkthrough completion
# each of these booleans is toggled when a student submits the form
# on the associated page
completedName
=
models
.
BooleanField
(
default
=
False
)
completedPrivacy
=
models
.
BooleanField
(
default
=
False
)
completedMajor
=
models
.
BooleanField
(
default
=
False
)
...
...
@@ -186,7 +196,7 @@ class Student(TimeStampedModel):
objects
=
StudentManager
()
# this doesn't take into account superseniors or graduate students or negative values
# hence private method
# hence private method
; not yet suggested for use
def
_get_class
(
self
):
time_to_graduate
=
self
.
graduating_year
-
self
.
current_year
if
time_to_graduate
>=
4
:
...
...
@@ -201,17 +211,19 @@ class Student(TimeStampedModel):
return
"magic"
def
recent_changes
(
self
):
#
part of TimeStampedModel
#
timezone.now takes into account timezones, which a local machine may not
now
=
timezone
.
now
()
# part of TimeStampedModel
created
=
self
.
created
# could make this more formal with dateutil, but...
days
=
(
now
-
created
).
days
# 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
):
try
:
...
...
@@ -228,6 +240,7 @@ class Student(TimeStampedModel):
return
None
def
totally_done
(
self
):
"""To assess if a user has completed the welcome walkthrough."""
if
self
.
completedName
and
self
.
completedPrivacy
and
self
.
completedMajor
and
self
.
completedSocial
:
return
True
else
:
...
...
@@ -248,7 +261,9 @@ class Student(TimeStampedModel):
def
get_flag_count
(
self
):
my_flag_num
=
Confirmation
.
objects
.
filter
(
student
=
self
,
lives_there
=
False
).
count
()
return
my_flag_num
# displays the student's username if the student if they choose to delete their name
def
get_first_name_or_uname
(
self
):
if
not
(
self
.
user
.
get_short_name
()):
return
self
.
user
.
username
...
...
@@ -267,6 +282,7 @@ class Student(TimeStampedModel):
else
:
return
self
.
user
.
get_full_name
()
# how recently has the student joined roomlist? changes some messages displayed
def
is_noob
(
self
):
now
=
timezone
.
now
()
days
=
(
now
-
self
.
created
).
days
...
...
@@ -283,8 +299,9 @@ class Student(TimeStampedModel):
def
__unicode__
(
self
):
return
unicode
(
self
.
user
.
username
)
# def save(self, *args, **kwargs):
# 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]:
...
...
@@ -293,6 +310,7 @@ class Student(TimeStampedModel):
class
Confirmation
(
TimeStampedModel
):
"""Tracks relations between two students in crowdsourcing the room validity."""
confirmer
=
models
.
ForeignKey
(
Student
,
related_name
=
'confirmer_set'
)
student
=
models
.
ForeignKey
(
Student
,
related_name
=
'student_set'
)
...
...
roomlist/accounts/student_messages.py
0 → 100644
View file @
1f8de306
bug_reporting
=
"""Welcome back to SRCT Roomlist. This project is the
<a href="https://srct.gmu.edu/projects/">collaborative work
of students like you</a>. If you see anything amiss, or have ideas for
features or a better user experience, please send an email to
roomlist@lists.srct.gmu.edu, tweet
<a href="https://twitter.com/MasonSRCT/">@MasonSRCT</a>, or, for the
more technically experienced, review our
<a href="https://git.gmu.edu/srct/roomlist/issues">issues page</a>."""
privacy_reminder
=
"""Welcome back to SRCT Roomlist. A friendly reminder you can change
your privacy settings at any time on your settings page by
clicking the cog in the upper right of your screen."""
disclaimer
=
"""Welcome back to SRCT Roomlist. Just to be perfectly clear, this project
is provided as a service by the
<a href="https://gmu.collegiatelink.net/organization/srct">registered
student organization</a>
<a href="https://srct.gmu.edu/">Student-Run Computing and Technology</a>.
We are not a part of <a href="http://housing.gmu.edu/">Mason Housing</a>:
all information is voluntarily provided by participating students."""
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>."""
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
review</a> this project's
<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
contribute!"""
return_messages
=
[
bug_reporting
,
privacy_reminder
,
disclaimer
,
whatsopen_plug
,
open_source
]
roomlist/accounts/templates/studentSettings.html
deleted
100644 → 0
View file @
867e0dc0
{% extends 'layouts/base.html' %}
{% block title %} SRCT Roomlist | {{ student.get_full_name_or_uname }} {% endblock %}
{% block messsage_queue %}
{% endblock %}
{% block content %}
{% load socialaccount %} {% load gravatar %}
<div
class=
"page-header"
id=
"banner"
>
<div
class=
"row"
>
<div
class=
"col-md-8 col-md-offset-2 text-center"
>
<img
class=
"img-circle img-responsive center center-block"
src=
"{{ student.profile_image_url }}"
alt=
"{{ student.get_first_name_or_uname }} Gravatar picture"
>
<h1>
{{ student.get_full_name_or_uname }} , {{ student.user.username }}
</h1>
</div>
</div>
</div>
{% load socialaccount %} {% providers_media_js %}
<legend>
Account Settings
</legend>
<div
class=
"row"
>
{{ student }} text text text {{ request.user }}
<a
href=
"{% url 'update_student' request.user.student.slug %}"
>
<div
class=
"col-md-3 text-center"
>
<h4><i
class=
"fa fa-lock fa-5x"
></i></h4>
<h4>
Set Your Room and Privacy
</h4>
</div>
</a>
<a
href=
"{% url 'update_student_major' request.user.student.slug %}"
>
<div
class=
"col-md-3 text-center"
>
<h4><i
class=
"fa fa-graduation-cap fa-5x"
></i></h4>
<h4>
Set Your Major
</h4>
</div>
</a>
{% comment %} email was here; a good idea {% endcomment %}
</div>
<legend
style=
"margin-top: 50px"
>
Social Media Settings
</legend>
<div
class=
"row"
style=
"margin-top: 50px"
>
<a
href=
"{% provider_login_url 'facebook' method='js_sdk' process='connect' next='/accounts/student/' %}"
>
<div
class=
"col-md-3 text-center"
>
<h4><i
class=
"fa fa-facebook fa-5x"
></i></h4>
<h4>
Link to your Facebook
</h4>
</div>
</a>
<a
href=
"{% provider_login_url 'google' process='connect' next='/accounts/student/' %}"
>
<div
class=
"col-md-3 text-center"
>
<h4><i
class=
"fa fa-google fa-5x"
></i></h4>
<h4>
Link to your Google
</h4>
</div>
</a>
<a
href=
"{% provider_login_url 'twitter' process='connect' next='/accounts/student/' %}"
>
<div
class=
"col-md-3 text-center"
>
<h4><i
class=
"fa fa-twitter fa-5x"
></i></h4>
<h4>
Link to your Twitter
</h4>
</div>
</a>
<div
class=
"col-md-3 text-center"
>
<!--<a href="{% provider_login_url 'instagram' process='connect' next='/accounts/student/' %}"><i class="fa fa-instagram fa-5x"></i></a>-->
<h4><i
class=
"fa fa-instagram fa-5x"
></i></h4>
<h4>
Link to your Instagram (Soon!)
</h4>
</div>
</div>
{% endblock %}
roomlist/accounts/urls.py
View file @
1f8de306
...
...
@@ -24,22 +24,15 @@ urlpatterns = patterns('',
url
(
r
'^student/(?P<slug>[\w-]+)/$'
,
DetailStudent
.
as_view
(),
name
=
'detail_student'
),
#url(r'^student/$',
#cache_page(60 * 2)(DetailCurrentStudent.as_view()),
#name='detailCurrentStudent'),
# student settings
url
(
r
'^student/(?P<slug>[\w-]+)/settings/$'
,
UpdateStudent
.
as_view
(),
name
=
'update_student'
),
# custom allauth page to disconnect a social media account
url
(
r
'^student/(?P<slug>[\w-]+)/settings/social/remove/$'
,
RemoveSocialConfirmationView
.
as_view
(),
name
=
'remove_social'
),
#url(r'^settings/$',
#cache_page(4)(DetailCurrentStudentSettings.as_view()),
#name='currentStudentSettings'),
# student confirmation pages
url
(
r
'^student/(?P<student_slug>[\w-]+)/flag/$'
,
CreateConfirmation
.
as_view
(),
name
=
'createConfirmation'
),
...
...
roomlist/accounts/views.py
View file @
1f8de306
...
...
@@ -21,47 +21,11 @@ from ratelimit.decorators import ratelimit
from
.models
import
Student
,
Major
,
Confirmation
from
housing.models
import
Building
,
Floor
,
Room
from
.forms
import
StudentUpdateForm
#########
bug_reporting
=
"""Welcome back to SRCT Roomlist. This project is the
<a href="https://srct.gmu.edu/projects/">collaborative work
of students like you</a>. If you see anything amiss, or have ideas for
features or a better user experience, please send an email to
roomlist@lists.srct.gmu.edu, tweet
<a href="https://twitter.com/MasonSRCT/">@MasonSRCT</a>, or, for the
more technically experienced, review our
<a href="https://git.gmu.edu/srct/roomlist/issues">issues page</a>."""
privacy_reminder
=
"""Welcome back to SRCT Roomlist. A friendly reminder you can change
your privacy settings at any time on your settings page by
clicking the cog in the upper right of your screen."""
disclaimer
=
"""Welcome back to SRCT Roomlist. Just to be perfectly clear, this project
is provided as a service by the
<a href="https://gmu.collegiatelink.net/organization/srct">registered
student organization</a>
<a href="https://srct.gmu.edu/">Student-Run Computing and Technology</a>.
We are not a part of <a href="http://housing.gmu.edu/">Mason Housing</a>:
all information is voluntarily provided by participating students."""
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>."""
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
review</a> this project's
<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
contribute!"""
#########
return_messages
=
[
bug_reporting
,
privacy_reminder
,
disclaimer
,
whatsopen_plug
,
open_source
]
from
.student_messages
import
return_messages
def
custom_cas_login
(
request
,
*
args
,
**
kwargs
):
"""If a student has not completed the welcome walkthrough, go there on login."""
response
=
cas_login
(
request
,
*
args
,
**
kwargs
)
# returns HttpResponseRedirect
...
...
@@ -84,6 +48,7 @@ def custom_cas_login(request, *args, **kwargs):
return
response
# only two students on the same floor can confirm one another (crowdsourced verification)
def
on_the_same_floor
(
student
,
confirmer
):
if
student
==
confirmer
:
# Student is confirmer
...
...
@@ -168,36 +133,6 @@ class DetailStudent(LoginRequiredMixin, DetailView):
return
context
class
DetailCurrentStudent
(
LoginRequiredMixin
,
DetailView
):
model
=
Student
context_object_name
=
'student'
template_name
=
'detailStudent.html'
login_url
=
'login'
def
get_object
(
self
):
return
get_object_or_404
(
Student
,
pk
=
self
.
request
.
session
[
'_auth_user_id'
])
# changeable student settings
class
DetailStudentSettings
(
LoginRequiredMixin
,
DetailView
):
model
=
Student
context_object_name
=
'student'
template_name
=
'studentSettings.html'
login_url
=
'login'
class
DetailCurrentStudentSettings
(
LoginRequiredMixin
,
DetailView
):
model
=
Student
context_object_name
=
'student'
template_name
=
'studentSettings.html'
login_url
=
'login'
def
get_object
(
self
):
return
get_object_or_404
(
Student
,
pk
=
self
.
request
.
session
[
'_auth_user_id'
])
# update a student, but FormView to allow name update on same page
class
UpdateStudent
(
LoginRequiredMixin
,
FormValidMessageMixin
,
FormView
):
template_name
=
'update_student.html'
...
...
@@ -374,6 +309,9 @@ class DetailMajor(LoginRequiredMixin, DetailView):
class
CreateConfirmation
(
LoginRequiredMixin
,
CreateView
):
"""Students on the same floor may flag one another.
This is our attempt at crowdsourced verification."""
model
=
Confirmation
fields
=
[]
template_name
=
'create_confirmation.html'
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment