def _make_push(cls, user_id, token, title, subtitle, extra): try: response = PushClient().publish( PushMessage(to=token, title=title, body=subtitle, data=extra)) except PushServerError as exc: # Encountered some likely formatting/validation error. cls.logger().error(f"Failed to push notification. Token: {token[:10]}.., Msg: {subtitle}, Extra: {extra}, Error: {exc.errors}, Response Data: {exc.response_data}") except (ConnectionError, HTTPError) as exc: # Encountered some Connection or HTTP error - retry a few times in # case it is transient. cls.logger().error(f"Failed to push notification. Token: {token[:10]}.., Msg: {subtitle}, Extra: {extra}, Error: {exc}") try: # We got a response back, but we don't know whether it's an error yet. # This call raises errors so we can handle them with normal exception # flows. response.validate_response() except DeviceNotRegisteredError: # Mark the push token as inactive UsersDAO.delete_tkn(user_id) except PushResponseError as exc: # Encountered some other per-notification error. cls.logger().error(f"Failed to push notification. Token: {token[:10]}.., Msg: {subtitle}, Extra: {extra}, Error: {exc.errors}, Response Data: {exc.push_response._asdict}")
def _calculate_popularity(cls, video, viewer_uuid, timestamp): friendship_bonus = int(UsersDAO.are_friends(video.uuid, viewer_uuid)) * 10 influencer_bonus = UsersDAO.count_friends(video.uuid) * 2 time_bonus = 60 / (cls._minutes_passed(timestamp) / 1440 + 1) return video.cached_relevance + friendship_bonus + int( time_bonus) + influencer_bonus
def delete(self, user_id, friend_id): parser = reqparse.RequestParser() parser.add_argument("x-access-token", location='headers') args = parser.parse_args() viewer_uuid = AuthSender.get_uuid_from_token(args["x-access-token"]) if not AuthSender.has_permission(user_id, viewer_uuid): raise BadRequestError( f"You don't have permission to delete other users' friends") UsersDAO.delete_friendship(user_id, friend_id) return {"msg": "OK"}, 200
def get(self, other_user_id): parser = reqparse.RequestParser() parser.add_argument("x-access-token", location='headers', required=True, help='Missing user token!') args = parser.parse_args() uuid1 = AuthSender.get_uuid_from_token(args['x-access-token']) UsersDAO.check_exists(uuid1) UsersDAO.check_exists(other_user_id) msgs = ChatsDAO.get_messages_between(uuid1, other_user_id) self.logger.info(f"Found {len(msgs)} messages between users {uuid1, other_user_id}. RESPONSECODE:200") return msgs, 200
def post(self): parser = reqparse.RequestParser() parser.add_argument("display_name", location="json", required=True, help="Missing user's full name.", type=str) parser.add_argument("email", location="json", required=True, help="Missing user's email.", type=str) parser.add_argument("phone_number", location="json", required=False, default="", type=str) parser.add_argument("image_location", location="json", required=False, default="", type=str) parser.add_argument("password", location="json", required=False, default="", type=str) parser.add_argument("x-access-token", location='headers', required=True, help='Missing user token!') args = parser.parse_args() msg, code = AuthSender.register_user(fullname=args["display_name"], email=args['email'], phone=args['phone_number'], avatar=args['image_location'], token=args['x-access-token'], password=args["password"]) if code == 201: self.logger.info( f"New user created with info: {msg}. RESPONSECODE:{code}") UsersDAO.add_user_to_db(msg['id']) else: self.logger.error( f"Failed to create user with info: {msg}. RESPONSECODE:{code}") return msg, code
def get(self, user_id): self.logger.debug(f"Starting friends search for user {user_id}") friends = UsersDAO.get_friends(user_id) self.logger.info( f"Found {len(friends['friends'])} friend(s) for user {user_id}. RESPONSECODE:200" ) return friends, 200
def delete(self, user_id): parser = reqparse.RequestParser() parser.add_argument("x-access-token", location='headers', required=True, help='Missing user token!') args = parser.parse_args() viewer_uuid = AuthSender.get_uuid_from_token(args["x-access-token"]) if not AuthSender.has_permission(user_id, viewer_uuid): self.logger.info( f"User {viewer_uuid} attempted to delete user's {user_id} account. Access Denied." ) raise BadRequestError(f"You can't delete other users profiles!") UsersDAO.delete_user(user_id, args["x-access-token"]) return {"message": "OK"}, 200
def post(self): parser = reqparse.RequestParser() parser.add_argument("x-access-token", location='headers', required=True, help='Missing user token!') parser.add_argument("push_token", location='json', type=str, required=True, help="Missing Expo Push Token") args_dict = parser.parse_args() id = AuthSender.get_uuid_from_token(args_dict["x-access-token"]) UsersDAO.set_tkn(id, args_dict["push_token"]) self.logger.info( f"Added new push token for user {id}. RESPONSECODE:200") return {"message": "OK"}, 200
def get_videos_by(cls, user_id, viewer_uuid, token): cls.logger().info(f"Grabbing all videos by user {user_id}") UsersDAO.check_exists(user_id) videos = [ v.serialize() for v in Video.query.filter(Video.uuid == user_id) ] cls.logger().info( f"Filtering by viewable videos for viewer {viewer_uuid}") filtered = [ f for f in videos if not cls._cant_view(f["is_private"], viewer_uuid, user_id) ] for f in filtered: cls.add_extra_info(f, viewer_uuid) f["author"] = AuthSender.get_author_name(f["uuid"], token) cls.logger().info( f"Found {len(filtered)} viewable videos uploaded by user {user_id}" ) return filtered
def get(self): parser = reqparse.RequestParser() parser.add_argument("x-access-token", location='headers', required=True, help='Missing user token!') args_dict = parser.parse_args() id = AuthSender.get_uuid_from_token(args_dict["x-access-token"]) self.logger.info( f"Returning push token for user {id}. RESPONSECODE:200") return {"push_token": UsersDAO.get_tkn(id)}, 200
def get(self): parser = reqparse.RequestParser() parser.add_argument("x-access-token", location='headers') args = parser.parse_args() viewer_uuid = AuthSender.get_uuid_from_token(args["x-access-token"]) reqs = UsersDAO.view_pending_reqs(viewer_uuid) self.logger.info( f"Found {len(reqs['pending_reqs'])} pending requests for user {viewer_uuid}. RESPONSECODE:200" ) return reqs, 200
def send_notification(cls, user_id, title, subtitle, message_type, extra_data): cls.logger().info(f"send_notification: Sending to user {user_id}. Title: {title}. Subtitle: {subtitle}. MsgType: {message_type}. ExtraData: {extra_data}") token = UsersDAO.get_tkn(user_id) if not token: cls.logger().error(f"No token detected for user {user_id}. Unable to send push notification") return data = extra_data.copy() data["type"] = message_type cls.logger().info(f"send_notification: Valid token found, sending notification...") cls._make_push(user_id, token, title, subtitle, data)
def get(self): count = httpDAO.count_total_30_days() requests_per_hour = httpDAO.count_reqs_per_hour() requests_per_method = httpDAO.count_reqs_per_method() requests_per_response = httpDAO.count_reqs_per_response_code() registered_users = httpDAO.count_registered_users_in_30_days() new_vids = httpDAO.count_uploaded_vids_in_30_days() new_cmnts = httpDAO.count_posted_comments_in_30_days() reqs_last_30_days = httpDAO.count_requests_in_30_days() sv_errors, sv_errors_per_path = httpDAO.count_sv_errors_in_30_days() cli_errors, cli_errors_per_path = httpDAO.count_cli_errors_in_30_days() views_per_day = httpDAO.count_views_per_day() #--- non-http stats: private_vids_count, total_vids_count, average_views = VideoDAO.count_private_over_total_vids() total_registered_users_count = UsersDAO.count_total_registered_users() return { "requests_per_hour": requests_per_hour, "requests_per_method": requests_per_method, "requests_per_code": requests_per_response, "requests_in_last_30_days": reqs_last_30_days, "sv_errors_in_last_30_days": sv_errors, "sv_errors_per_path_in_last_30_days": sv_errors_per_path, "cli_errors_in_last_30_days": cli_errors, "cli_errors_per_path_in_last_30_days": cli_errors_per_path, "new_users_in_last_30_days": registered_users, "new_vids_in_last_30_days": new_vids, "new_cmnts_in_last_30_days": new_cmnts, "views_in_last_30_days": views_per_day, "average_views": average_views, "private_and_total_vids_count": [private_vids_count, total_vids_count], "registered_users_count": total_registered_users_count, "total_count_in_last_30_days": count }
def get(self, user_id): parser = reqparse.RequestParser() parser.add_argument("x-access-token", location='headers', required=True, help='Missing user token!') args = parser.parse_args() msg, code = AuthSender.get_user_info(user_id, args['x-access-token']) if code == 200: viewer_id = AuthSender.get_uuid_from_token(args["x-access-token"]) msg["friendship_status"] = UsersDAO.get_friendship_status( user_id, viewer_id) self.logger.info( f"User {user_id} info collected: {msg}. RESPONSECODE:{code}") return msg, code
def post(self, other_user_id): parser = reqparse.RequestParser() parser.add_argument("x-access-token", location='headers', required=True, help='Missing user token!') parser.add_argument("text", location='json', type=str, required=True, help='You must include the text to be sent!') args = parser.parse_args() if args["text"] == "": raise BadRequestError("Invalid message length") sender_uuid = AuthSender.get_uuid_from_token(args['x-access-token']) author_name = AuthSender.get_author_name(sender_uuid, args["x-access-token"]) if not UsersDAO.are_friends(sender_uuid, other_user_id): raise BadRequestError("You are not friends with this user") msg = ChatsDAO.send_message(sender_uuid, other_user_id, args["text"], author_name) self.logger.info(f"Succesfully sent message from user {sender_uuid} to {other_user_id}. RESPONSECODE:200") return msg, 201
def post(self, sender_id): parser = reqparse.RequestParser() parser.add_argument("x-access-token", location='headers') parser.add_argument( "accept", location='json', type=bool, required=True, help='You must specify if you either accept or reject the request') args = parser.parse_args() viewer_uuid = AuthSender.get_uuid_from_token(args["x-access-token"]) msg = UsersDAO.respond_request(viewer_uuid, sender_id, accept=args["accept"]) self.logger.info( f"User {viewer_uuid} responded request from {sender_id}. Accepted: {args['accept']}. RESPONSECODE:200" ) return msg, 200
def post(self): parser = reqparse.RequestParser() parser.add_argument("x-access-token", location='headers') parser.add_argument( "to", type=int, required=True, help="You must specify who you are sending this request to", location='json') args = parser.parse_args() sender_uuid = AuthSender.get_uuid_from_token(args["x-access-token"]) author_name = AuthSender.get_author_name(sender_uuid, args["x-access-token"]) msg = UsersDAO.send_request(sender_uuid, args["to"], author_name) self.logger.info( f"Succesfully sent request from user {sender_uuid} to {args['to']}. RESPONSECODE:201" ) return msg, 201
def _cant_view(cls, is_private, user1_id, user2_id): return is_private and not AuthSender.has_permission( user1_id, user2_id) and not UsersDAO.are_friends( user1_id, user2_id)