Skip to content

Commit

Permalink
Merge pull request #12 from admtlab/develop
Browse files Browse the repository at this point in the history
Updates notifications
  • Loading branch information
marksilvis authored Nov 22, 2017
2 parents 4ccc368 + a8759d2 commit ed0b86d
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 3 deletions.
2 changes: 2 additions & 0 deletions pittgrub/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
UserHandler, UserVerificationHandler, UserPreferenceHandler,
UserPasswordHandler, UserPasswordResetHandler
)
from handlers.notifications import NotificationHandler
from handlers.events import EventImageHandler, EventTestHandler
from handlers.admin import UserReferralHandler, UserApprovedReferralHandler, UserPendingReferralHandler, AdminHandler
from storage import ImageStore
Expand Down Expand Up @@ -67,6 +68,7 @@ def __init__(self, debug: bool, image_store: ImageStore, static_path: str=None,
(r'/users/activate(/*)', UserVerificationHandler), # user activation
(r'/users/preferences(/*)', UserPreferenceHandler), # user preferences (food, etc)
(r'/users/admin(/*)', AdminHandler), # make user admin
(r'/notifications(/*)', NotificationHandler), # handle notifications
(r'/token(/*)', NotificationTokenHandler), # add notification token
(r'/signup(/*)', SignupHandler), # sign-up
(r'/signup/referral(/*)', ReferralHandler), # sign-up with reference
Expand Down
2 changes: 1 addition & 1 deletion pittgrub/db/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def init(username: str, password: str, url: str, database: str,
engine = create_engine(f"mysql+pymysql://{username}:{password}"
f"@{url}/{database}{params}",
convert_unicode=True, echo=echo,
pool_recycle=1800)
poolclass=NullPool)
session = scoped_session(sessionmaker(bind=engine))
print('Inserting default data')
__bulk_insert(engine, DEFAULTS) # add default data
Expand Down
5 changes: 4 additions & 1 deletion pittgrub/handlers/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ def send_push_notification(user: 'User', event: 'Event'):
if expo_token:
if PushClient().is_exponent_push_token(expo_token):
try:
message = PushMessage(to=expo_token, body='PittGrub: New event added', data={'data': 'A new event was added to PittGrub!'})
message = PushMessage(to=expo_token,
title='PittGrub: New event!',
body=event.title,
data={'type': 'event', 'event': event.title, 'title':'PittGrub: New event!', 'body': event.title})
response = PushClient().publish(message)
response.validate_response()
except PushServerError as e:
Expand Down
40 changes: 40 additions & 0 deletions pittgrub/handlers/notifications.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""
Handle user notifications
Author: Mark Silvis
"""
from exponent_server_sdk import (
PushClient, PushMessage, PushServerError, PushResponseError
)
from tornado.escape import json_decode

from db import User
from handlers.base import BaseHandler, CORSHandler, SecureHandler
from notifier import send_push_notification


class NotificationHandler(SecureHandler):
def post(self, path: str):
user_id = self.get_user_id()
user = User.get_by_id(user_id)
if user.email not in ('[email protected]', '[email protected]'):
self.write_error(403, 'Insufficient permissions')
else:
# get json body
data = json_decode(self.request.body)
# message field is required
if not all(key in data for key in ('title', 'body')):
self.write_error(400, f'Missing field(s): {", ".join({"title", "body"}-data.keys())}')
else:
# send message to all users
users = User.get_all()
for user in users:
if user.expo_token:
print(f"sending notification to user: {user.id}")
print(f"notification values\ntitle:{data['title']}\nbody:{data['body']}\ndata:{data.get('data')}")
notification_data = data.get('data') or dict()
notification_data['title'] = data['title']
notification_data['body'] = data['body']
notification_data['type'] = 'message'
send_push_notification(user.expo_token,
data['title'], data['body'],
notification_data)
4 changes: 3 additions & 1 deletion pittgrub/handlers/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,15 @@ def post(self, path):
user = User.get_by_id(owner)
if user is not None:
try:
logging.info('verifying token')
if verify_jwt(token, user.password):
password = data['password']
User.change_password(owner, password)
self.success(status=204)
else:
self.write_error(400, 'Password reset failed, token is expired')
except:
except Exception as e:
logging.warn(e)
self.write_error(400, 'Password reset failed, invalid token')
else:
logging.warn(f"User with id {owner} tried to reset password, but they don't exist")
Expand Down
37 changes: 37 additions & 0 deletions pittgrub/notifier.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""
Send notifications to users
Author: Mark Silvis
"""

from typing import Any, Dict, Tuple, Union

from exponent_server_sdk import (
PushClient, PushMessage, PushServerError, PushResponseError,
)


class InvalidExpoToken(Exception):
def __init__(self):
self.message = "Invalid expo token"
super(ValidationError, self).__init__(self.message)


def send_push_notification(expo_token: str,
title: str,
body: str,
data: Dict[Any, Any]=None):
"""Send notification to specified expo token
:expo_token: token to send notificaton to
:title: notification title
:body: notification body
:data: extra notification data (total payload must be under 4096 bytes)
:raises: ConnectionError, DeviceNotRegisterdError, HTTPError,
InvalidExpoToken, PushServerError, PushResponseError
"""
assert expo_token, "Expo token cannot be None"
if PushClient().is_exponent_push_token(expo_token):
message = PushMessage(to=expo_token, title=title, body=body, data=data)
response = PushClient().publish(message)
response.validate_response()
else:
raise InvalidExpoToken()

0 comments on commit ed0b86d

Please sign in to comment.