Skip to content

Commit

Permalink
Merge pull request #13 from admtlab/develop
Browse files Browse the repository at this point in the history
User settings and privacy
  • Loading branch information
marksilvis authored Dec 5, 2017
2 parents ed0b86d + fc602a4 commit 3a4aa93
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 9 deletions.
8 changes: 5 additions & 3 deletions pittgrub/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
)
from handlers.user import (
UserHandler, UserVerificationHandler, UserPreferenceHandler,
UserPasswordHandler, UserPasswordResetHandler
UserPasswordHandler, UserPasswordResetHandler,
UserSettingsHandler
)
from handlers.notifications import NotificationHandler
from handlers.events import EventImageHandler, EventTestHandler
Expand Down Expand Up @@ -63,10 +64,11 @@ def __init__(self, debug: bool, image_store: ImageStore, static_path: str=None,
endpoints = [
(r"/(/*)", MainHandler), # index
(r"/health(/*)", HealthHandler), # check status
(r'/users(/*)', UserHandler), # all users
(r'/users/(\d+/*)', UserHandler), # single user
# (r'/users(/*)', UserHandler), # all users
# (r'/users/(\d+/*)', UserHandler), # single user
(r'/users/activate(/*)', UserVerificationHandler), # user activation
(r'/users/preferences(/*)', UserPreferenceHandler), # user preferences (food, etc)
(r'/users/settings(/*)', UserSettingsHandler), # user settings (food prefs, pantry, etc)
(r'/users/admin(/*)', AdminHandler), # make user admin
(r'/notifications(/*)', NotificationHandler), # handle notifications
(r'/token(/*)', NotificationTokenHandler), # add notification token
Expand Down
7 changes: 3 additions & 4 deletions pittgrub/db/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.pool import NullPool

from .base import Entity, ReferralStatus, UserStatus, health_check
from .default import DEFAULTS
Expand Down Expand Up @@ -68,7 +67,7 @@
})

def __bulk_insert(engine, data: Dict[str, List[Tuple[Any]]]):
schema.Base.metadata.create_all(bind=engine)
schema.Base.metadata.create_all(bind=engine)
for entity, values in data.items():
# get class of entity
cls = getattr(sys.modules[__name__], entity)
Expand All @@ -94,10 +93,10 @@ 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,
poolclass=NullPool)
pool_recycle=1800)
session = scoped_session(sessionmaker(bind=engine))
print('Inserting default data')
__bulk_insert(engine, DEFAULTS) # add default data
if generate:
if generate:
print('Generating test data')
__bulk_insert(engine, TEST_DATA) # add test data if generate flag is set to true
38 changes: 36 additions & 2 deletions pittgrub/db/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ class User(Base, Entity):
admin = Column('admin', BOOLEAN, nullable=False, default=False)
expo_token = Column('expo_token', VARCHAR(255), nullable=True)
login_count = Column('login_count', INT, nullable=False)
pitt_pantry = Column('pitt_pantry', BOOLEAN, nullable=False, default=False)
eagerness = Column('eagerness', INT, nullable=False, default=3)

# mappings
food_preferences = association_proxy('_user_foodpreferences', 'food_preference')
Expand All @@ -42,7 +44,8 @@ class User(Base, Entity):

def __init__(self, id: int=None, email: str=None, password: str=None,
status: UserStatus=None, active: bool=False, disabled: bool=False,
admin: bool=False, login_count: int=0, expo_token: str=None):
admin: bool=False, login_count: int=0, expo_token: str=None,
pitt_pantry: bool=False, eagerness: int=3):
self.id = id
self.created = datetime.datetime.utcnow()
self.email = email
Expand All @@ -53,6 +56,8 @@ def __init__(self, id: int=None, email: str=None, password: str=None,
self.admin = admin
self.login_count = login_count
self.expo_token = expo_token
self.pitt_pantry = pitt_pantry
self.eagerness = eagerness

@property
def valid(self):
Expand Down Expand Up @@ -137,13 +142,42 @@ def make_admin(self):
db.session.commit()
db.session.refresh(self)

def update_eagerness(self, value: int):
assert 0 < value
self.eagerness = value
db.session.commit()
db.session.refresh(self)

def set_pitt_pantry(self, status: bool):
assert status is not None
self.pitt_pantry = status
db.session.commit()
db.session.refresh(self)

def json_info(cls) -> Dict[str, Union[bool, int, str]]:
"""Get json serializable representation of account related info"""
return dict(
id=cls.id,
active=cls.active,
admin=cls.admin,
status=cls.status.name)

def json_settings(cls) -> Dict[str, Any]:
"""Get json serializable representation of user settings"""
return dict(
eagerness=cls.eagerness,
pantry=cls.pitt_pantry,
food_preferences=[f.json() for f in cls.food_preferences])

def json(cls, deep: bool=True) -> Dict[str, Any]:
json = dict(
id=cls.id,
email=cls.email,
active=cls.active,
admin=cls.admin,
status=cls.status.name
status=cls.status.name,
eagerness=cls.eagerness,
pantry=cls.pitt_pantry
)
if deep:
json['food_preferences'] = [f.json() for f in cls.food_preferences]
Expand Down
33 changes: 33 additions & 0 deletions pittgrub/handlers/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,39 @@ def post(self, path):
self.write_error(400, 'Missing fields')


class UserSettingsHandler(SecureHandler):
def get(self, path):
# check token
user_id = self.get_user_id()
if user_id:
user = User.get_by_id(user_id)
settings = user.json_settings()
self.success(payload=Payload(settings))
else:
self.write_error(403, 'Authentication is required')

def post(self, path):
user_id = self.get_user_id()
user = User.get_by_id(user_id)
if user is not None:
# decode json
data = json_decode(self.request.body)
logging.info(f'Updating settings for user {user_id}, settings {data}')
if 'food_preferences' in data:
# ensure preference ids are legit
preference_ids = [pref.id for pref in FoodPreference.get_all()]
if all(pref in preference_ids for pref in data['food_preferences']):
UserFoodPreference.update(user_id, preference_ids)
else:
fields = ", ".join(set(data['food_preferences'])-preference_ids)
self.write_error(401, f'Food preferences not foudn: {fields}')
if 'pantry' in data:
user.set_pitt_pantry(data['pantry'])
if 'eagerness' in data:
user.update_eagerness(data['eagerness'])
self.success(status=204)


class UserPreferenceHandler(SecureHandler):
def get(self, path):
# check token
Expand Down

0 comments on commit 3a4aa93

Please sign in to comment.