Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
b124485e
Commit
b124485e
authored
Apr 09, 2015
by
Nimisha Asthagiri
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MA-611, MA-613 Mobile Push Notification Studio Backend; Integration with Parse
parent
c2a1870f
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
128 additions
and
8 deletions
+128
-8
cms/djangoapps/contentstore/course_info_model.py
+9
-3
cms/djangoapps/contentstore/push_notification.py
+62
-0
cms/djangoapps/contentstore/tasks.py
+10
-0
cms/djangoapps/contentstore/views/course.py
+3
-1
cms/djangoapps/contentstore/views/tests/test_course_updates.py
+38
-4
cms/envs/aws.py
+5
-0
cms/static/js/spec/views/course_info_spec.js
+0
-0
requirements/edx/github.txt
+1
-0
No files found.
cms/djangoapps/contentstore/course_info_model.py
View file @
b124485e
...
...
@@ -23,6 +23,7 @@ from xmodule.modulestore.django import modulestore
from
xmodule.html_module
import
CourseInfoModule
from
xmodule_modifiers
import
get_course_update_items
from
cms.djangoapps.contentstore.push_notification
import
enqueue_push_course_update
# # This should be in a class which inherits from XmlDescriptor
log
=
logging
.
getLogger
(
__name__
)
...
...
@@ -44,9 +45,13 @@ def get_course_updates(location, provided_id, user_id):
def
update_course_updates
(
location
,
update
,
passed_id
=
None
,
user
=
None
):
"""
Either add or update the given course update. It will add it if the passed_id is absent or None. It will update it if
it has an passed_id which has a valid value. Until updates have distinct values, the passed_id is the location url + an index
into the html structure.
Either add or update the given course update.
Add:
If the passed_id is absent or None, the course update is added.
If push_notification_selected is set in the update, a celery task for the push notification is created.
Update:
It will update it if it has a passed_id which has a valid value.
Until updates have distinct values, the passed_id is the location url + an index into the html structure.
"""
try
:
course_updates
=
modulestore
()
.
get_item
(
location
)
...
...
@@ -73,6 +78,7 @@ def update_course_updates(location, update, passed_id=None, user=None):
"status"
:
CourseInfoModule
.
STATUS_VISIBLE
}
course_update_items
.
append
(
course_update_dict
)
enqueue_push_course_update
(
update
,
location
.
course_key
)
# update db record
save_course_update_items
(
location
,
course_updates
,
course_update_items
,
user
)
...
...
cms/djangoapps/contentstore/push_notification.py
0 → 100644
View file @
b124485e
"""
Helper methods for push notifications from Studio.
"""
from
django.conf
import
settings
from
logging
import
exception
as
log_exception
from
contentstore.tasks
import
push_course_update_task
from
contentstore.models
import
PushNotificationConfig
from
xmodule.modulestore.django
import
modulestore
from
parse_rest.installation
import
Push
from
parse_rest.connection
import
register
from
parse_rest.core
import
ParseError
def
push_notification_enabled
():
"""
Returns whether the push notification feature is enabled.
"""
return
PushNotificationConfig
.
is_enabled
()
def
enqueue_push_course_update
(
update
,
course_key
):
"""
Enqueues a task for push notification for the given update for the given course if
(1) the feature is enabled and
(2) push_notification is selected for the update
"""
if
push_notification_enabled
()
and
update
.
get
(
"push_notification_selected"
):
course
=
modulestore
()
.
get_course
(
course_key
)
if
course
:
push_course_update_task
.
delay
(
unicode
(
course_key
),
course
.
clean_id
(
padding_char
=
'_'
),
course
.
display_name
)
def
send_push_course_update
(
course_key_string
,
course_subscription_id
,
course_display_name
):
"""
Sends a push notification for a course update, given the course's subscription_id and display_name.
"""
if
settings
.
PARSE_KEYS
:
try
:
register
(
settings
.
PARSE_KEYS
[
"APPLICATION_ID"
],
settings
.
PARSE_KEYS
[
"REST_API_KEY"
],
)
Push
.
alert
(
data
=
{
"course-id"
:
course_key_string
,
"action"
:
"course.announcement"
,
"action-loc-key"
:
"VIEW_BUTTON"
,
"loc-key"
:
"COURSE_ANNOUNCEMENT_NOTIFICATION_BODY"
,
"loc-args"
:
[
course_display_name
],
"title-loc-key"
:
"COURSE_ANNOUNCEMENT_NOTIFICATION_TITLE"
,
"title-loc-args"
:
[],
},
channels
=
[
course_subscription_id
],
)
except
ParseError
as
error
:
log_exception
(
error
.
message
)
cms/djangoapps/contentstore/tasks.py
View file @
b124485e
...
...
@@ -115,3 +115,13 @@ def update_library_index(library_id, triggered_time_isoformat):
LOGGER
.
error
(
'Search indexing error for library
%
s -
%
s'
,
library_id
,
unicode
(
exc
))
else
:
LOGGER
.
debug
(
'Search indexing successful for library
%
s'
,
library_id
)
@task
()
def
push_course_update_task
(
course_key_string
,
course_subscription_id
,
course_display_name
):
"""
Sends a push notification for a course update.
"""
# TODO Use edx-notifications library instead (MA-638).
from
.push_notification
import
send_push_course_update
send_push_course_update
(
course_key_string
,
course_subscription_id
,
course_display_name
)
cms/djangoapps/contentstore/views/course.py
View file @
b124485e
...
...
@@ -69,6 +69,7 @@ from contentstore.views.entrance_exam import (
from
.library
import
LIBRARIES_ENABLED
from
.item
import
create_xblock_info
from
contentstore.push_notification
import
push_notification_enabled
from
course_creators.views
import
get_course_creator_status
,
add_user_with_status_unrequested
from
contentstore
import
utils
from
student.roles
import
(
...
...
@@ -778,7 +779,8 @@ def course_info_handler(request, course_key_string):
'context_course'
:
course_module
,
'updates_url'
:
reverse_course_url
(
'course_info_update_handler'
,
course_key
),
'handouts_locator'
:
course_key
.
make_usage_key
(
'course_info'
,
'handouts'
),
'base_asset_url'
:
StaticContent
.
get_base_url_path_for_course_assets
(
course_module
.
id
)
'base_asset_url'
:
StaticContent
.
get_base_url_path_for_course_assets
(
course_module
.
id
),
'push_notification_enabled'
:
push_notification_enabled
()
}
)
else
:
...
...
cms/djangoapps/contentstore/views/tests/test_course_updates.py
View file @
b124485e
...
...
@@ -2,7 +2,10 @@
unit tests for course_info views and models.
"""
import
json
from
mock
import
patch
from
django.test.utils
import
override_settings
from
contentstore.models
import
PushNotificationConfig
from
contentstore.tests.test_course_settings
import
CourseTestCase
from
contentstore.utils
import
reverse_course_url
,
reverse_usage_url
from
opaque_keys.edx.keys
import
UsageKey
...
...
@@ -234,18 +237,19 @@ class CourseUpdateTest(CourseTestCase):
payload
=
json
.
loads
(
resp
.
content
)
self
.
assertTrue
(
len
(
payload
)
==
1
)
def
test_post_course_update
(
self
):
def
post_course_update
(
self
,
send_push_notification
=
False
):
"""
Test that a user can successfully post on course updates and handouts of a
course
Posts an update to the
course
"""
course_update_url
=
self
.
create_update_url
(
course_key
=
self
.
course
.
id
)
# create a course via the view handler
self
.
client
.
ajax_post
(
course_update_url
)
block
=
u'updates'
content
=
u"Sample update"
payload
=
{
'content'
:
content
,
'date'
:
'January 8, 2013'
}
if
send_push_notification
:
payload
[
'push_notification_selected'
]
=
True
resp
=
self
.
client
.
ajax_post
(
course_update_url
,
payload
)
# check that response status is 200 not 400
...
...
@@ -254,9 +258,19 @@ class CourseUpdateTest(CourseTestCase):
payload
=
json
.
loads
(
resp
.
content
)
self
.
assertHTMLEqual
(
payload
[
'content'
],
content
)
@patch
(
"contentstore.push_notification.send_push_course_update"
)
def
test_post_course_update
(
self
,
mock_push_update
):
"""
Test that a user can successfully post on course updates and handouts of a course
"""
self
.
post_course_update
()
# check that push notifications are not sent
self
.
assertFalse
(
mock_push_update
.
called
)
updates_location
=
self
.
course
.
id
.
make_usage_key
(
'course_info'
,
'updates'
)
self
.
assertTrue
(
isinstance
(
updates_location
,
UsageKey
))
self
.
assertEqual
(
updates_location
.
name
,
block
)
self
.
assertEqual
(
updates_location
.
name
,
u'updates'
)
# check posting on handouts
handouts_location
=
self
.
course
.
id
.
make_usage_key
(
'course_info'
,
'handouts'
)
...
...
@@ -265,8 +279,28 @@ class CourseUpdateTest(CourseTestCase):
content
=
u"Sample handout"
payload
=
{
'data'
:
content
}
resp
=
self
.
client
.
ajax_post
(
course_handouts_url
,
payload
)
# check that response status is 200 not 500
self
.
assertEqual
(
resp
.
status_code
,
200
)
payload
=
json
.
loads
(
resp
.
content
)
self
.
assertHTMLEqual
(
payload
[
'data'
],
content
)
@patch
(
"contentstore.push_notification.send_push_course_update"
)
def
test_notifications_enabled_but_not_requested
(
self
,
mock_push_update
):
PushNotificationConfig
(
enabled
=
True
)
.
save
()
self
.
post_course_update
()
self
.
assertFalse
(
mock_push_update
.
called
)
@patch
(
"contentstore.push_notification.send_push_course_update"
)
def
test_notifications_enabled_and_sent
(
self
,
mock_push_update
):
PushNotificationConfig
(
enabled
=
True
)
.
save
()
self
.
post_course_update
(
send_push_notification
=
True
)
self
.
assertTrue
(
mock_push_update
.
called
)
@override_settings
(
PARSE_KEYS
=
{
"APPLICATION_ID"
:
"TEST_APPLICATION_ID"
,
"REST_API_KEY"
:
"TEST_REST_API_KEY"
})
@patch
(
"contentstore.push_notification.Push"
)
def
test_notifications_sent_to_parse
(
self
,
mock_parse_push
):
PushNotificationConfig
(
enabled
=
True
)
.
save
()
self
.
post_course_update
(
send_push_notification
=
True
)
self
.
assertTrue
(
mock_parse_push
.
alert
.
called
)
cms/envs/aws.py
View file @
b124485e
...
...
@@ -320,6 +320,11 @@ DEPRECATED_ADVANCED_COMPONENT_TYPES = ENV_TOKENS.get(
VIDEO_UPLOAD_PIPELINE
=
ENV_TOKENS
.
get
(
'VIDEO_UPLOAD_PIPELINE'
,
VIDEO_UPLOAD_PIPELINE
)
################ PUSH NOTIFICATIONS ###############
PARSE_KEYS
=
AUTH_TOKENS
.
get
(
"PARSE_KEYS"
,
{})
#date format the api will be formatting the datetime values
API_DATE_FORMAT
=
'
%
Y-
%
m-
%
d'
API_DATE_FORMAT
=
ENV_TOKENS
.
get
(
'API_DATE_FORMAT'
,
API_DATE_FORMAT
)
...
...
cms/static/js/spec/views/course_info_spec.js
0 → 100644
View file @
b124485e
requirements/edx/github.txt
View file @
b124485e
...
...
@@ -20,6 +20,7 @@
-e git+https://github.com/jazkarta/edx-jsme.git@c5bfa5d361d6685d8c643838fc0055c25f8b7999#egg=edx-jsme
-e git+https://github.com/pmitros/django-pyfs.git@d175715e0fe3367ec0f1ee429c242d603f6e8b10#egg=djpyfs
git+https://github.com/mitocw/django-cas.git@60a5b8e5a62e63e0d5d224a87f0b489201a0c695#egg=django-cas
-e git+https://github.com/dgrtwo/ParsePy.git@7949b9f754d1445eff8e8f20d0e967b9a6420639#egg=parse_rest
# Our libraries:
-e git+https://github.com/edx/XBlock.git@aed464a0e2f7478e93157150ac04133a745f5f46#egg=XBlock
...
...
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