Skip to content

Commit

Permalink
Merge pull request #520 from edx/feature/kevin/email_notifications_panel
Browse files Browse the repository at this point in the history
Feature/kevin/email notifications panel
  • Loading branch information
Jim Abramson committed Jul 30, 2013
2 parents 0d10a87 + 05f31f8 commit 77a796e
Show file tree
Hide file tree
Showing 34 changed files with 2,756 additions and 261 deletions.
3 changes: 3 additions & 0 deletions common/static/coffee/src/discussion/discussion_router.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ if Backbone?

allThreads: ->
@nav.updateSidebar()
@nav.goHome()

setActiveThread: =>
if @thread
@nav.setActiveThread(@thread.get("id"))
else
@nav.goHome

showThread: (forum_name, thread_id) ->
@thread = @discussion.get(thread_id)
Expand Down
3 changes: 3 additions & 0 deletions common/static/coffee/src/discussion/utils.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ class @DiscussionUtil
user_profile : "/courses/#{$$course_id}/discussion/forum/users/#{param}"
followed_threads : "/courses/#{$$course_id}/discussion/forum/users/#{param}/followed"
threads : "/courses/#{$$course_id}/discussion/forum"
"enable_notifications" : "/notification_prefs/enable/"
"disable_notifications" : "/notification_prefs/disable/"
"notifications_status" : "/notification_prefs/status"
}[name]

@safeAjax: (params) ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ if Backbone?
class @DiscussionThreadListView extends Backbone.View
events:
"click .search": "showSearch"
"click .home": "goHome"
"click .browse": "toggleTopicDrop"
"keydown .post-search-field": "performSearch"
"click .sort-bar a": "sortThreads"
Expand Down Expand Up @@ -43,6 +44,7 @@ if Backbone?
if active
@setActiveThread(thread_id)


#TODO fix this entire chain of events
addAndSelectThread: (thread) =>
commentable_id = thread.get("commentable_id")
Expand Down Expand Up @@ -191,6 +193,25 @@ if Backbone?
@$(".browse").removeClass('is-open')
setTimeout (-> @$(".post-search-field").focus()), 200

goHome: ->
@template = _.template($("#discussion-home").html())
$(".discussion-column").html(@template)
$(".post-list a").removeClass("active")
$("input.email-setting").bind "click", @updateEmailNotifications
url = DiscussionUtil.urlFor("notifications_status",window.user.get("id"))
DiscussionUtil.safeAjax
url: url
type: "GET"
success: (response, textStatus) =>
if response.status
$('input.email-setting').attr('checked','checked')
else
$('input.email-setting').removeAttr('checked')
thread_id = null
@trigger("thread:removed")
#select all threads


toggleTopicDrop: (event) =>
event.preventDefault()
event.stopPropagation()
Expand Down Expand Up @@ -312,6 +333,7 @@ if Backbone?
if callback?
callback()


retrieveDiscussions: (discussion_ids) ->
@discussionIds = discussion_ids.join(',')
@mode = 'commentables'
Expand Down Expand Up @@ -418,3 +440,19 @@ if Backbone?
retrieveFollowed: (event)=>
@mode = 'followed'
@retrieveFirstPage(event)

updateEmailNotifications: () =>
if $('input.email-setting').attr('checked')
DiscussionUtil.safeAjax
url: DiscussionUtil.urlFor("enable_notifications")
type: "POST"
error: () =>
$('input.email-setting').removeAttr('checked')
else
DiscussionUtil.safeAjax
url: DiscussionUtil.urlFor("disable_notifications")
type: "POST"
error: () =>
$('input.email-setting').attr('checked','checked')


1 change: 0 additions & 1 deletion lms/djangoapps/django_comment_client/base/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
url(r'threads/(?P<thread_id>[\w\-]+)/follow$', 'follow_thread', name='follow_thread'),
url(r'threads/(?P<thread_id>[\w\-]+)/unfollow$', 'unfollow_thread', name='unfollow_thread'),
url(r'threads/(?P<thread_id>[\w\-]+)/close$', 'openclose_thread', name='openclose_thread'),

url(r'comments/(?P<comment_id>[\w\-]+)/update$', 'update_comment', name='update_comment'),
url(r'comments/(?P<comment_id>[\w\-]+)/endorse$', 'endorse_comment', name='endorse_comment'),
url(r'comments/(?P<comment_id>[\w\-]+)/reply$', 'create_sub_comment', name='create_sub_comment'),
Expand Down
3 changes: 2 additions & 1 deletion lms/djangoapps/django_comment_client/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,8 @@ def safe_content(content):
'updated_at', 'depth', 'type', 'commentable_id', 'comments_count',
'at_position_list', 'children', 'highlighted_title', 'highlighted_body',
'courseware_title', 'courseware_url', 'tags', 'unread_comments_count',
'read', 'group_id', 'group_name', 'group_string', 'pinned', 'abuse_flaggers'
'read', 'group_id', 'group_name', 'group_string', 'pinned', 'abuse_flaggers',
'stats'

]

Expand Down
32 changes: 31 additions & 1 deletion lms/djangoapps/notification_prefs/tests.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import json

from django.contrib.auth.models import AnonymousUser
from django.core.exceptions import PermissionDenied
from django.http import Http404
Expand All @@ -7,7 +9,7 @@
from mock import Mock, patch

from notification_prefs import NOTIFICATION_PREF_KEY
from notification_prefs.views import ajax_enable, ajax_disable, unsubscribe
from notification_prefs.views import ajax_enable, ajax_disable, ajax_status, unsubscribe
from student.tests.factories import UserFactory
from user_api.models import UserPreference

Expand Down Expand Up @@ -57,6 +59,34 @@ def assertNotPrefExists(self, user):
UserPreference.objects.filter(user=user, key=NOTIFICATION_PREF_KEY).exists()
)

# AJAX status view

def test_ajax_status_get_0(self):
request = self.request_factory.get("dummy")
request.user = self.user
response = ajax_status(request)
self.assertEqual(response.status_code, 200)
self.assertEqual(json.loads(response.content), {"status":0})

def test_ajax_status_get_1(self):
self.create_prefs()
request = self.request_factory.get("dummy")
request.user = self.user
response = ajax_status(request)
self.assertEqual(response.status_code, 200)
self.assertEqual(json.loads(response.content), {"status":1})

def test_ajax_status_post(self):
request = self.request_factory.post("dummy")
request.user = self.user
response = ajax_status(request)
self.assertEqual(response.status_code, 405)

def test_ajax_status_anon_user(self):
request = self.request_factory.get("dummy")
request.user = AnonymousUser()
self.assertRaises(PermissionDenied, ajax_status, request)

# AJAX enable view

def test_ajax_enable_get(self):
Expand Down
20 changes: 20 additions & 0 deletions lms/djangoapps/notification_prefs/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from base64 import urlsafe_b64encode, urlsafe_b64decode
from hashlib import sha256
import json

from Crypto.Cipher import AES
from Crypto import Random
Expand Down Expand Up @@ -131,6 +132,25 @@ def ajax_disable(request):

return HttpResponse(status=204)

@require_GET
def ajax_status(request):
"""
A view that retrieves notifications status for the authenticated user.
This view should be invoked by an AJAX GET call. It returns status 200,
with a JSON-formatted payload, or an error.
"""
if not request.user.is_authenticated():
raise PermissionDenied


qs = UserPreference.objects.filter(
user=request.user,
key=NOTIFICATION_PREF_KEY
)

return HttpResponse(json.dumps({"status":len(qs)}), content_type="application/json")


@require_GET
def unsubscribe(request, token):
Expand Down
3 changes: 3 additions & 0 deletions lms/envs/aws.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,9 @@
MITX_FEATURES['AUTOMATIC_AUTH_FOR_LOAD_TESTING'] = ENV_TOKENS.get('AUTOMATIC_AUTH_FOR_LOAD_TESTING')
MITX_FEATURES['MAX_AUTO_AUTH_USERS'] = ENV_TOKENS.get('MAX_AUTO_AUTH_USERS')

# discussion home panel must be explicitly enabled
MITX_FEATURES['ENABLE_DISCUSSION_HOME_PANEL'] = ENV_TOKENS.get('ENABLE_DISCUSSION_HOME_PANEL', False)

############################## SECURE AUTH ITEMS ###############
# Secret things: passwords, access keys, etc.

Expand Down
3 changes: 3 additions & 0 deletions lms/envs/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@

'ENABLE_TEXTBOOK': True,
'ENABLE_DISCUSSION_SERVICE': True,
# discussion home panel, which includes a subscription on/off setting for discussion digest emails.
# this should remain off in production until digest notifications are online.
'ENABLE_DISCUSSION_HOME_PANEL': True,

'ENABLE_PSYCHOMETRICS': False, # real-time psychometrics (eg item response theory analysis in instructor dashboard)

Expand Down
5 changes: 5 additions & 0 deletions lms/lib/comment_client/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,8 @@ def _url_for_user_active_threads(user_id):

def _url_for_user_subscribed_threads(user_id):
return "{prefix}/users/{user_id}/subscribed_threads".format(prefix=settings.PREFIX, user_id=user_id)

def _url_for_user_stats(user_id,course_id):
return "{prefix}/users/{user_id}/stats?course_id={course_id}".format(prefix=settings.PREFIX, user_id=user_id,course_id=course_id)


Binary file added lms/static/fonts/vendor/FontAwesome.otf
Binary file not shown.
Binary file added lms/static/fonts/vendor/fontawesome-webfont.eot
Binary file not shown.
Loading

0 comments on commit 77a796e

Please sign in to comment.