def get_replies_data(id_array, current_user): # Check if the array is empty if len(id_array) == 0 or id_array is None: ## Nothing to send back... return "", 204 replies = [] replies_query = Reply.query.filter(Reply.id.in_(id_array)).all() try: for reply in replies_query: reply_info = load_reply(reply, current_user.id) replies.append(reply_info) # Re-sort it back to the original array res = [ reply for id in id_array for reply in replies if reply["id"] == id ] resp = Message(True, "Comments info sent.") resp["replies"] = res return resp, 200 except Exception as error: current_app.logger.error(error) return InternalErrResp()
def get_comments_data(id_array, current_user): # Check if the array is empty if len(id_array) == 0 or id_array is None: ## Nothing to send back... return "", 204 comments = [] comments_query = Comment.query.filter(Comment.id.in_(id_array)).all() try: for comment in comments_query: comment_info = load_comment(comment, current_user.id) comments.append(comment_info) # Re-sort it back to the original array res = [ comment for id in id_array for comment in comments if comment["id"] == id ] resp = Message(True, "Comments info sent.") resp["comments"] = res return resp, 200 except Exception as error: current_app.logger.error(error) return InternalErrResp()
def get_posts_data(id_array, current_user): # Check if the array is empty if len(id_array) == 0 or id_array is None: ## Nothing to send back.. return "", 204 posts = [] posts_query = Post.query.filter(Post.id.in_(id_array)).all() try: for post in posts_query: post_info = load_post(post, current_user.id) posts.append(post_info) # Re-sort it back to the original array res = [ post for id in id_array for post in posts if post["id"] == id ] resp = Message(True, "Posts info sent.") resp["posts"] = res return resp, 200 except Exception as error: current_app.logger.error(error) return InternalErrResp()
def update(post_public_id, data, current_user): # Query for the post post = Post.query.filter_by(public_id=post_public_id).first() if not post: resp = Message(False, "Post not found!") resp["error_reason"] = "post_404" return resp, 404 # Check post owner elif current_user.public_id == post.creator_public_id: if not data["content"]: resp = Message(False, "Content data not found!") resp["error_reason"] = "data_404" return resp, 404 try: update_post(post, data["content"]) resp = Message(True, "Post updated.") return resp, 200 except Exception as error: current_app.logger.error(error) return InternalErrResp() # Check if post is locked elif post.status.lower() == "locked": resp = Message(False, "Post is locked!") resp["error_reason"] = "post_locked" return resp, 403 resp = Message(False, "Insufficient permissions!") resp["error_reason"] = "insufficient_permissions" return resp, 403
def create(data, current_user): # Assign the vars content = data["content"] image_id = data["image_id"] # Check if the content doesn't exceed limit # This limit is temporary and can be changed, 2000 is just for testing limit = 2000 if not content: resp = Message(False, "Content can't be empty!") return resp, 403 elif len(content) > limit: resp = Message(False, f"Content exceeds limits ({ limit })") return resp, 403 try: new_post = Post( public_id=str(uuid4().int)[:15], owner_id=current_user.id, creator_public_id=current_user.public_id, content=content, image_file=image_id, ) latest_post = add_post_and_flush(new_post, current_user.id) resp = Message(True, "Post created.") resp["post"] = latest_post return resp, 201 except Exception as error: current_app.logger.error(error) return InternalErrResp()
def comment(comment_public_id, current_user): # Query for the comment comment = Comment.query.filter_by(public_id=comment_public_id).first() # Check if the comment exists if not comment: return "", 404 # Check if the user already liked if check_like(comment.likes, current_user.id): return "", 403 # Create a new like obj. comment_like = CommentLike(on_comment=comment.id, owner_id=current_user.id, liked_on=datetime.utcnow()) try: # Notify comment owner if current_user.public_id != comment.creator_public_id: notify("liked", "comment", comment.public_id, comment.creator_public_id) add_like(comment_like) resp = Message(True, "User has liked the comment.") return resp, 201 except Exception as error: current_app.logger.error(error) return InternalErrResp()
def post(post_public_id, current_user): # Query for the post using its public id post = Post.query.filter_by(public_id=post_public_id).first() # Check if the post exists if not post: resp = Message(False, "Post not found!") return resp, 404 if check_like(post.likes, current_user.id): resp = Message(False, "User already liked.") return resp, 403 # Create a new like obj. post_like = PostLike(on_post=post.id, owner_id=current_user.id, liked_on=datetime.utcnow()) # Commit the changes try: # Notify post owner if current_user.public_id != post.creator_public_id: notify("liked", "post", post.public_id, post.creator_public_id) add_like(post_like) return "", 201 except Exception as error: current_app.logger.error(error) return InternalErrResp()
def get_notifs_info(id_array, current_user): # Check if the array is empty if len(id_array) == 0 or id_array is None: return None, 204 notifs = [] notif_query = Notification.query.filter( Notification.id.in_(id_array)).all() try: for notification in notif_query: notif_info = notification_schema.dump(notification) # Load the actor as user actor = load_user(notif_info["actor"]) actor_info = user_schema.dump(actor) notif_info["actor_info"] = filter_author(actor_info) notifs.append(notif_info) # Re-sort it back to the original array res = [ notif for id in id_array for notif in notifs if notif["id"] == id ] resp = Message(True, "Notifications sent.") resp["notifications"] = res return resp, 200 except Exception as error: current_app.logger.error(error) return InternalErrResp()
def update(comment_public_id, data, current_user): # Query for the comment comment = Comment.query.filter_by(public_id=comment_public_id).first() if not comment: resp = Message(False, "Comment not found!") resp["error_reason"] = "comment_404" return resp, 404 # Check comment owner elif current_user.public_id == comment.creator_public_id: if not data["content"]: resp = Message(False, "Content data not found!") resp["error_reason"] = "data_404" return resp, 404 try: update_comment(comment, data["content"]) resp = Message(True, "Comment updated.") return resp, 200 except Exception as error: current_app.logger.error(error) return InternalErrResp() resp = Message(False, "Insufficient permissions!") resp["error_reason"] = "insufficient_permissions" return resp, 403
def reply(reply_public_id, current_user): # Query for the reply reply = Reply.query.filter_by(public_id=reply_public_id).first() # Check if the reply exists if not reply: return "", 404 # Check if the user already liked if check_like(reply.likes, current_user.id): return "", 403 # Create a new like obj. like_reply = ReplyLike(on_reply=reply.id, owner_id=current_user.id, liked_on=datetime.utcnow()) try: # Notify reply owner if current_user.public_id != reply.creator_public_id: notify("liked", "reply", reply.public_id, reply.creator_public_id) db.session.add(like_reply) db.session.commit() return "", 201 except Exception as error: current_app.logger.error(error) return InternalErrResp()
def create(post_public_id, data, current_user): # Get the post post = Post.query.filter_by(public_id=post_public_id).first() if not post: resp = Message(False, "Post not found!") resp["error_reason"] = "post_404" return resp, 404 # Assign the vars content = data["content"] # Validations limit = 1500 if not content: resp = Message(False, "Comment content not found!") resp["error_reason"] = "comment_404" return resp, 404 elif len(content) > limit: resp = Message(False, f"Comment content exceeds limits ({ limit })") return resp, 403 try: # Create a new comment obj. new_comment = Comment( public_id=str(uuid4().int)[:15], owner_id=current_user.id, creator_public_id=current_user.public_id, on_post=post.id, content=content, ) latest_comment = add_comment_and_flush(new_comment, current_user.id) # Notify post owner notify( "commented", "comment", latest_comment["public_id"], latest_comment["creator_public_id"], ) resp = Message(True, "Successfully commented.") resp["comment"] = latest_comment return resp, 201 except Exception as error: current_app.logger.error(error) return InternalErrResp()
def login_user(data): # Assign variables email = data["email"] password = data["password"] try: # Check if email or password was provided if not email or not password: resp = Message(False, "Credentials not fully provided") resp["error_reason"] = "no_credentials" return resp, 403 # Fetch the user data user = User.query.filter_by(email=email).first() if not user: resp = Message( False, "The email you have entered does not match any account") resp["error_reason"] = "email_404" return resp, 404 elif user and user.check_password(password): user_schema = UserSchema() user_info = user_schema.dump(user) # Remove sensitive information for info in private_info: del user_info[info] # Check if the user has an avatar if user_info["profile_picture"]: user_info["avatar"] = get_image( user_info["profile_picture"], "avatars") access_token = create_access_token(identity=user.id) if access_token: resp = Message(True, "Successfully logged in.") resp["access_token"] = access_token resp["user"] = user_info return resp, 200 # Return incorrect password if others fail resp = Message(False, "Failed to log in, password may be incorrect") resp["error_reason"] = "invalid_password" return resp, 403 except Exception as error: current_app.logger.error(error) return InternalErrResp()
def reply(reply_public_id, current_user): # Query for the reply reply = Reply.query.filter_by(public_id=reply_public_id).first() for like in reply.likes: if like.owner_id == current_user.id: try: remove_like(like) return "", 204 except Exception as error: current_app.logger.error(error) return InternalErrResp() return "", 404
def send_notification(data, target_user_public_id): actor = load_user(get_jwt_identity()) action = data["action"] # Post, Comment, Reply, etc. object_type = data["object_type"] object_public_id = data["object_public_id"] # Get the target user target_user = User.query.filter_by(public_id=target_user_public_id).first() if action not in valid_actions: resp = Message(False, "Invalid action!") resp["error_reason"] = "action_invalid" return resp, 403 # Validate if object_type not in allowed_types: resp = Message(False, "Object type is invalid!") resp["error_reason"] = "object_invalid" return resp, 403 notification = Notification.query.filter_by( object_type=object_type, object_public_id=object_public_id ).first() if notification is not None: return None, 204 try: new_notification = Notification( target_owner=target_user.id, actor=actor.public_id, action=action, timestamp=datetime.utcnow(), object_type=object_type, object_public_id=object_public_id, ) db.session.add(new_notification) db.session.commit() resp = Message(True, "Notification has been created.") return resp, 201 except Exception as error: current_app.logger.error(error) return InternalErrResp()
def create(comment_public_id, data, current_user): # Get the comment comment = Comment.query.filter_by(public_id=comment_public_id).first() if not comment: resp = Message(False, "Comment not found!") resp["error_reason"] = "comment_404" return resp, 404 # Assign the vars content = data["content"] limit = 1500 if not content: resp = Message(False, "Reply content not found!") return resp, 404 elif len(content) > limit: resp = Message(False, f"Reply content exceeds limits ({ limit })") return resp, 403 try: # Create new reply obj. new_reply = Reply( public_id=str(uuid4().int)[:15], owner_id=current_user.id, creator_public_id=current_user.public_id, on_comment=comment.id, content=content, ) latest_reply = add_reply_and_flush(new_reply, current_user.id) # Notify commenter notify( "replied", "reply", latest_reply["public_id"], latest_reply["creator_public_id"], ) resp = Message(True, "Replied on comment.") resp["reply"] = latest_reply return resp, 201 except Exception as error: current_app.logger.error(error) return InternalErrResp()
def comment(comment_public_id, current_user): # Query for the comment comment = Comment.query.filter_by(public_id=comment_public_id).first() for like in comment.likes: if like.owner_id == current_user.id: try: remove_like(like) return "", 200 except Exception as error: current_app.logger.error(error) return InternalErrResp() # Return 404 if item isn't found return "", 404
def get_notification_ids(current_user): try: notifs = (Notification.query.filter_by( target_owner=current_user.id).with_entities( Notification.id, Notification.timestamp).all()) notification_info = notifications_schema.dump(notifs) ids = uniq(x["id"] for x in sorted( notification_info, key=lambda x: x["timestamp"], reverse=True)) resp = Message(True, "Sent notification IDs.") resp["notif_ids"] = ids return resp, 200 except Exception as error: current_app.logger.error(error) return InternalErrResp()
def delete(comment_public_id, current_user): # Query for the comment comment = Comment.query.filter_by(public_id=comment_public_id).first() if not comment: resp = Message(False, "Comment not found!") return resp, 204 # Check comment owner elif current_user.public_id == comment.creator_public_id: try: delete_comment(comment) resp = Message(True, "Comment has been deleted.") return resp, 200 except Exception as error: current_app.logger.error(error) return InternalErrResp() resp = Message(False, "Insufficient permissions!") return resp, 403
def delete(post_public_id, current_user): post = Post.query.filter_by(public_id=post_public_id).first() if not post: resp = Message(False, "Post not found!") resp["error_reason"] = "post_404" return resp, 404 # Check post owner elif (current_user.public_id == post.creator_public_id ): # or is_admin(current_user) try: delete_post(post) resp = Message(True, "Post has been deleted.") return resp, 200 except Exception as error: current_app.logger.error(error) return InternalErrResp() resp = Message(False, "Insufficient permissions!") return resp, 403
def update(reply_public_id, data, current_user): reply = Reply.query.filter_by(public_id=reply_public_id).first() if not reply: resp = Message(False, "Reply not found!") resp["error_reason"] = "reply_404" return resp, 404 # Check reply owner elif current_user.public_id == reply.creator_public_id: try: update_reply(reply, data["content"]) resp = Message(True, "Reply updated.") return resp, 200 except Exception as error: current_app.logger.error(error) return InternalErrResp() resp = Message(False, "Insufficient permissions!") resp["error_reason"] = "insufficient_permissions" return resp, 403
def upload_file(files, foldername, extensions): if "image" not in files: resp = Message(False, "File not found!") resp["error_reason"] = "file_404" return resp, 404 file = files["image"] # Check if there is a filename if file.filename == "": resp = Message(False, "No file selected!") resp["error_reason"] = "filename" return resp, 403 # Process if it passes validation allowed_extensions = set(extensions) if file and allowed_file(file.filename, allowed_extensions): # Get the filename filename = file.filename extension = "." + filename.split(".")[1] # Hash the file and limit to 32chars hashed_file = sha256(str( file.filename).encode("utf-8")).hexdigest()[:32] # Save it and attach the extension try: file.save( os.path.join(STATIC_FOLDER_PATH + foldername + "/", hashed_file + extension)) resp = Message(True, "Image uploaded.") resp["image_id"] = hashed_file + extension return resp, 201 except Exception as error: current_app.logger.error(error) return InternalErrResp()
def read_notifications(): try: pass except Exception as error: current_app.logger.error(error) return InternalErrResp()
def register(data): try: # Assign the vars email = data["email"] username = data["username"] full_name = data["full_name"] password = data["password"] entry_key = data["entry_key"] # Check if email exists if len(email) == 0 or email is None: resp = Message(False, "Email is required!") resp["error_reason"] = "no_email" return resp, 403 # Check if the email is being used if User.query.filter_by(email=email).first() is not None: resp = Message(False, "Email is being used!") resp["error_reason"] = "email_used" return resp, 403 # Check if the email is valid elif not EMAIl_REGEX.match(email): resp = Message(False, "Invalid email!") resp["error_reason"] = "email_invalid" return resp, 403 # Check if the username is empty if len(username) == 0 or username is None: resp = Message(False, "Username is required!") resp["error_reason"] = "username_none" return resp, 403 # Check if the username is being used elif User.query.filter_by( username=username.lower()).first() is not None: resp = Message(False, "Username is already taken!") resp["error_reason"] = "username_taken" return resp, 403 # Check if the username is equal to or between 4 and 15 elif not 4 <= len(username) <= 15: resp = Message(False, "Username length is invalid!") resp["error_reason"] = "username_invalid" return resp, 403 # Check if the username is alpha numeric elif not username.isalnum(): resp = Message(False, "Username is not alpha numeric.") resp["error_reason"] = "username_not_alphanum" return resp, 403 # Verify the full name and if it exists if len(full_name) == 0 or full_name is None: full_name = None else: # Validate the full name # Remove any spaces so that it properly checks. if not full_name.replace(" ", "").isalpha(): resp = Message(False, "Name is not alphabetical!") resp["error_reason"] = "name_nonalpha" return resp, 403 # Check if the full name is equal to or between 2 and 50 elif not 2 <= len(full_name) <= 50: resp = Message(False, "Name length is invalid!") resp["error_reason"] = "name_invalid" return resp, 403 # Replace multiple spaces with one. # 'firstName lastName' -> 'firstName lastName' re.sub(" +", " ", full_name) # Check if the entry key is right if entry_key != current_app.config["ENTRY_KEY"]: resp = Message(False, "Entry key is invalid!") resp["error_reason"] = "entry_key_invalid" return resp, 403 # Create new user object new_user = User( public_id=str(uuid4().int)[:15], email=email, username=username.lower(), full_name=full_name, password=password, joined_date=datetime.now(), ) # Add and commit the user to the database db.session.add(new_user) db.session.flush() # Get the user's info user_schema = UserSchema() user_info = user_schema.dump(new_user) # Save changes db.session.commit() # Remove private information from user info for info in private_info: del user_info[info] # Return success response access_token = create_access_token(identity=new_user.id) resp = Message(True, "User registered.") resp["access_token"] = access_token resp["user"] = user_info return resp, 201 except Exception as error: current_app.logger.error(error) return InternalErrResp()