def get_tag_posts(user, tag_name): top = request.args.get('top', default=False) latest = request.args.get('latest', default=False) cursor = request.args.get('cursor') items_per_page = current_app.config['ITEMS_PER_PAGE'] nextCursor = None query = '' try: tag = Tag.query.filter_by(name=tag_name).first() except Exception as e: db.session.rollback() print(e) return server_error('An unexpected error occured.') try: sorted_posts = Post.get_by_reactions().subquery() tag_posts = Post.query.with_parent(tag).subquery() sort_top_posts = db.session.query( tag_posts, sorted_posts.c.sequence).join( sorted_posts, sorted_posts.c.id == tag_posts.c.id).subquery() top_posts = db.session.query(Post, sort_top_posts.c.sequence).join( sort_top_posts, Post.id == sort_top_posts.c.id).order_by( sort_top_posts.c.sequence.desc()) latest_posts = Post.query.with_parent(tag).order_by( Post.created_on.desc()) except Exception as e: db.session.rollback() print(e) return server_error('An unexpected error occured, please try again.') if cursor == '0' and latest: query = latest_posts.limit(items_per_page + 1).all() elif cursor == '0' and top: query = top_posts.limit(items_per_page + 1).all() else: if latest: cursor = urlsafe_base64(cursor, from_base64=True) query = latest_posts.filter( Post.created_on < cursor).limit(items_per_page + 1).all() else: cursor = urlsafe_base64(cursor, from_base64=True) query = top_posts.filter( sort_top_posts.c.sequence < cursor).limit(items_per_page + 1).all() if len(query) > items_per_page: nextCursor = urlsafe_base64( query[items_per_page - 1].created_on.isoformat()) \ if latest else urlsafe_base64( str(query[items_per_page - 1][1])) posts = [post.to_dict(user) for post in query[:items_per_page]] \ if latest else \ [post[0].to_dict(user) for post in query[:items_per_page]] return {'data': posts, 'nextCursor': nextCursor}
def get_notifications(user): cursor = request.args.get('cursor') items_per_page = current_app.config['ITEMS_PER_PAGE'] nextCursor = None notifs = None try: if cursor == '0': notifs = user.get_notifications().limit(items_per_page + 1).all() else: cursor = urlsafe_base64(cursor, from_base64=True) notifs = user.get_notifications().filter( Notification.timestamp < cursor).limit(items_per_page + 1).all() if len(notifs) > items_per_page: nextCursor = urlsafe_base64(notifs[items_per_page - 1].timestamp.isoformat()) user.last_notif_read_time = datetime.utcnow() user.save() except (IntegrityError, ValueError) as e: db.session.rollback() print(e) return server_error('Something went wrong, please try again.') else: return { 'data': NotificationSchema(many=True).dump(notifs[:items_per_page]), 'nextCursor': nextCursor }
def delete_profile(user): try: user.delete() except Exception: return server_error('Something went wrong, please try again.') else: return {'message': 'Successfully deleted profile.'}
def update_profile(user): request_data = request.get_json() print(request_data) if not request_data: return bad_request("No input data provided") try: data = ProfileSchema().load(request_data) except ValidationError as error: return error_response(422, error.messages) profile = user.profile profile.username = data.get('username') profile.name = data.get('name') profile.dob = data.get('dob') profile.bio = data.get('bio') try: profile.save() except (exc.IntegrityError, ValueError): db.session.rollback() return server_error('Something went wrong, please try again.') else: return jsonify(ProfileSchema().dump(profile))
def get_top_tags(user): """Get list of top tags not followed by user""" cursor = request.args.get('cursor') items_per_page = current_app.config['ITEMS_PER_PAGE'] nextCursor = None tags = None try: ord_tags = Tag.get_top_tags(user).subquery() query = db.session.query(Tag, ord_tags.c.nPosts).join( ord_tags, Tag.id == ord_tags.c.tags_id).order_by(ord_tags.c.nPosts.desc()) if cursor == '0': tags = query.limit(items_per_page + 1).all() else: cursor = urlsafe_base64(cursor, from_base64=True) tags = query.filter( ord_tags.c.nPosts < cursor).limit(items_per_page + 1).all() except (exc.IntegrityError, ValueError) as e: db.session.rollback() print(e) return server_error('Something went wrong, please try again.') if len(tags) > items_per_page: nextCursor = urlsafe_base64(str(tags[items_per_page - 1][1])) return { 'data': [tag[0].to_dict(user) for tag in tags[:items_per_page]], 'nextCursor': nextCursor }
def add_tag(user): req_data = request.get_json() if not req_data: return bad_request('No request data provided') try: data = TagSchema().load(req_data) except ValidationError as err: print(err) return error_response(422, err.messages) name = data.get('name') # check for existing tag tag = Tag.query.filter(Tag.name == name).first() if tag: return bad_request(f'Tag with name "{name}" already exists.') tag = Tag(name=name) try: tag.save() except (exc.IntegrityError, ValueError): db.session.rollback() return server_error('Something went wrong, please try again.') return jsonify(TagSchema().dump(tag))
def update_like(user, post_id): post = Post.find_by_id(post_id) if not post: return not_found('Post not found') try: if post.is_liked_by(user): post.likes.remove(user) db.session.delete( Notification.find_by_attr(subject='like', item_id=post.id)) else: post.likes.append(user) db.session.add( user.add_notification('like', item_id=post.id, id=post.author.id, post_id=post.id)) post.save() except (exc.IntegrityError, ValueError): db.session.rollback() return server_error('Something went wrong, please try again.') else: return jsonify(post.to_dict(user))
def update_user(id): request_data = request.get_json() if not request_data: return bad_request("No input data provided") try: data = ProfileSchema().load(request_data) user = User.find_by_id(id) existing_user = User.find_by_identity(data.get('auth')['username']) if existing_user is not None: if existing_user.id != user.id: return bad_request(f'Username already exists.') # update user user.profile.name = data.get('name') user.profile.bio = data.get('bio') user.profile.dob = data.get('dob') user.username = data.get('auth')['username'] user.is_active = data.get('auth')['is_active'] user.is_admin = data.get('auth')['is_admin'] user.save() return jsonify(UserSchema().dump(user)) # handle errors except ValidationError as err: return error_response(422, err.messages) except (exc.IntegrityError, ValueError): db.session.rollback() return server_error('Something went wrong, please try again.')
def update_group(id): request_data = request.get_json() if not request_data: return bad_request('No input data provided.') try: data = GroupSchema().load(request_data) # check for existing group name group = Group.find_by_id(id) existing_group = Group.find_by_name(name=data.get('name')) if existing_group is not None: if existing_group.id != group.id: return bad_request(f'Group already exists.') group.name = data.get('name') group.description = data.get('description') group.save() return jsonify(GroupSchema().dump(group)) # handle errors except ValidationError as err: return error_response(422, err.messages) except (exc.IntegrityError, ValueError): db.session.rollback() return server_error('Something went wrong, please try again.')
def add_group(): request_data = request.get_json() if not request_data: return bad_request('No input data provided.') try: data = GroupSchema().load(request_data) name = data.get('name') description = data.get('description') # check for existing group name group = Group.find_by_name(name=name) if group: return bad_request('Group already exist.') group = Group(name=name, description=description) group.save() response = jsonify(GroupSchema().dump(group)) response.status_code = 201 response.headers['Location'] = url_for('admin.get_group', id=group.id) return response # handle errors except ValidationError as err: return error_response(422, err.messages) except (exc.IntegrityError, ValueError): db.session.rollback() return server_error('Something went wrong, please try again.')
def get_users_to_follow(user): """Recommend users to follow""" try: users = user.get_users_to_follow() except (exc.IntegrityError, ValueError): db.session.rollback() return server_error('Something went wrong, please try again.') return jsonify(UserSchema( many=True, only=('id', 'profile',)).dump(users))
def get_tags(user): try: tags = Tag.query.all() except Exception as e: print(e) return server_error('An unexpected error occured.') return jsonify(TagSchema(many=True, only=( 'id', 'name', )).dump(tags))
def get_featured_posts(): try: res = Post.query.filter(Post.comment_id.is_(None)).all() posts = random.sample(res, k=5) except Exception: return server_error('Something went wrong, please try again.') return jsonify( PostSchema(many=True, only=('id', 'body', 'author.profile')).dump(posts))
def posts_feed(user): latest = request.args.get('latest') top = request.args.get('top') cursor = request.args.get('cursor') items_per_page = current_app.config['ITEMS_PER_PAGE'] nextCursor = None query = '' try: followed_posts = user.get_followed_posts().subquery() posts_reactions = Post.get_reactions().subquery() top_followed_posts = db.session.query( followed_posts, func.row_number().over(order_by=posts_reactions.c.reactions). label('sequence')).outerjoin( posts_reactions, followed_posts.c.posts_id == posts_reactions.c.id).subquery() top_posts = db.session.query(Post, top_followed_posts.c.sequence).join( Post, top_followed_posts.c.posts_id == Post.id).order_by( top_followed_posts.c.sequence.desc()) latest_posts = db.session.query(Post, followed_posts.c.posts_id).join( Post, Post.id == followed_posts.c.posts_id).order_by( Post.created_on.desc()) except Exception as e: db.session.rollback() print(e) return server_error('An unexpected error occured, please try again.') if cursor == '0' and latest: query = latest_posts.limit(items_per_page + 1).all() elif cursor == '0' and top: query = top_posts.limit(items_per_page + 1).all() else: if latest: cursor = urlsafe_base64(cursor, from_base64=True) query = latest_posts.filter( Post.created_on < cursor).limit(items_per_page + 1).all() else: cursor = urlsafe_base64(cursor, from_base64=True) query = top_posts.filter( top_followed_posts.c.sequence < cursor).limit(items_per_page + 1).all() if len(query) > items_per_page: nextCursor = urlsafe_base64( query[items_per_page - 1][0].created_on.isoformat()) \ if latest else urlsafe_base64( str(query[items_per_page - 1][1])) return { 'data': [post[0].to_dict(user) for post in query[:items_per_page]], 'nextCursor': nextCursor }
def get_post(user, post_id): try: print(post_id) post = Post.find_by_id(post_id) if not post: return not_found('Post not found') except Exception: return server_error('Something went wrong, please try again.') else: return jsonify(PostSchema().dump(post))
def create_message(user): req_data = request.get_json() user_id = request.args.get('user', None, int) if not req_data: return bad_request("No request data provided") try: a_user = User.find_by_id(user_id) if not a_user: return not_found('User not found.') chat = user.get_chat(a_user) if not chat: chat = Chat(user1_id=user.id, user2_id=a_user.id) db.session.add(chat) db.session.commit() message = Message() message.body = json.dumps(req_data.get('body')) message.author_id = user.id message.created_on = datetime.utcnow() message.chat_id = chat.id db.session.add(message) lrm = LastReadMessage.find_by_pk(user.id, chat.id) if lrm: lrm.timestamp = datetime.utcnow() else: lrm = LastReadMessage() lrm.user_id = user.id lrm.chat_id = chat.id lrm.timestamp = message.created_on db.session.add(lrm) user.add_notification(subject='message', item_id=message.id, id=a_user.id) user.save() except (IntegrityError, ProgrammingError, AttributeError, ValueError) as e: db.session.rollback() print(e) return server_error('Something went wrong, please try again.') else: response = jsonify(MessageSchema().dump(message)) response.status_code = 201 response.headers['Location'] = url_for('messages.get_messages', user=user, user_id=a_user.id) return response
def get_tag(user): tag_name = request.args.get('name') try: tag = Tag.query.filter_by(name=tag_name).first() except Exception as e: db.session.rollback() print(e) return server_error('An unexpected error occured.') if tag: return tag.to_dict(user) return not_found(f'Tag with name "{tag_name}" does not exist.')
def get_liked_posts(user, username, page=1): """Get a users list of liked posts""" user = User.find_by_identity(username) try: liked_posts = user.likes.order_by(Post.created_on.desc()).paginate( page, current_app.config['ITEMS_PER_PAGE']) except (exc.IntegrityError, ValueError): db.session.rollback() return server_error('Something went wrong, please try again.') else: return { 'likes': PostSchema(many=True).dump(liked_posts.items), 'hasNext': liked_posts.has_next, }
def follow_tag(user, tag_id): tag = Tag.query.filter_by(id=tag_id).first() if not tag: return bad_request(f'No tag with id "{tag_id}" exists') try: user.unfollow_tag(tag) \ if user.is_following_tag(tag) else user.follow_tag(tag) user.save() except (exc.IntegrityError, ValueError): db.session.rollback() return server_error('Something went wrong, please try again.') return TagSchema().dump(tag)
def get_user_comments(user, username, page=1): """Get a users list of comments""" user = User.find_by_identity(username) try: comments = Comment.query.with_parent(user).order_by( Comment.created_on.desc()).paginate( page, current_app.config['ITEMS_PER_PAGE']) except (exc.IntegrityError, ValueError): db.session.rollback() return server_error('Something went wrong, please try again.') else: return { 'comments': CommentSchema(many=True).dump(comments.items), 'hasNext': comments.has_next, }
def delete_comment(user, post_id, comment_id): comment = Comment.find_by_id(comment_id) if not comment: return not_found('Comment not found.') if comment.user_id != user.id: return error_response(401, 'Not authorized for that action.') try: comment.delete() except (exc.IntegrityError, ValueError): db.session.rollback() return server_error('Something went wrong, please try again.') else: return jsonify(CommentSchema().dump(comment.id))
def get_followers(user, username, page=1): """Get list of users following a user""" user = User.find_by_identity(username) try: followers = user.followers.paginate( page, current_app.config['ITEMS_PER_PAGE'], False) except (exc.IntegrityError, ValueError): db.session.rollback() return server_error('Something went wrong, please try again.') else: return { 'followers': UserSchema(many=True, only=( 'id', 'username', 'profile',)).dump(followers.items), 'count': user.followers.count(), 'hasNext': followers.has_next, }
def unfollow(user, id): followed = User.find_by_id(id) if not followed: return not_found('User not found') user.unfollow(followed) try: user.save() except (exc.IntegrityError, ValueError): db.session.rollback() return server_error('Something went wrong, please try again.') else: return jsonify(UserSchema( many=True, only=('id',)).dump(user.followed.all()))
def delete_notification(user, notif_id): try: notif = Notification.find_by_id(notif_id) if not notif: return not_found('Notification not found.') if user.id != notif.owner_id: return error_response(403, "Not allowed!") notif.delete() return {'message': 'Successfully removed.'} except (IntegrityError, ValueError) as e: db.session.rollback() print(e) return server_error('Something went wrong, please try again.')
def get_post(user, post_id): try: post = Post.find_by_id(post_id) if not post: return not_found('Post not found') except Exception: return server_error('Something went wrong, please try again.') else: post_dict = post.to_dict(user) post_dict['isLiked'] = post.is_liked_by(user) if user.id != post.author.id: post_dict['author']['isFollowing'] = user.is_following(post.author) return jsonify(post_dict)
def login_user(): data = request.get_json() if data is None: return bad_request("No input data provided") try: # check for existing user user = User.find_by_email(data.get('email')) if user and user.check_password(data.get('password')): return jsonify({'token': user.encode_auth_token()}) else: return error_response(401, 'Incorrect email or password.') except Exception: return server_error('Something went wrong, please try again.')
def delete_post(user, post_id): post = Post.find_by_id(post_id) if not post: return not_found('Post not found.') if post.user_id != user.id: return error_response(401, "You cannot delete someone else's post.") try: post.delete() except (exc.IntegrityError, ValueError): db.session.rollback() return server_error('Something went wrong, please try again.') else: return jsonify(PostSchema().dump(post.id))
def get_chat_messages(user): username = request.args.get('username', '') cursor = request.args.get('cursor') items_per_page = current_app.config['ITEMS_PER_PAGE'] a_user = Profile.find_by_username(username).user nextCursor = None msgs = None if not a_user: return not_found('User not found.') try: query = user.get_chat_messages(a_user) chat = user.get_chat(a_user) if cursor == '0': msgs = query.limit(items_per_page + 1).all() else: cursor = urlsafe_base64(cursor, from_base64=True) msgs = query.filter( Message.created_on < cursor).limit(items_per_page + 1).all() if len(msgs) > items_per_page: nextCursor = urlsafe_base64(msgs[items_per_page - 1].created_on.isoformat()) # check if lrm exist if chat: lrm = LastReadMessage.find_by_pk(user.id, chat.id) if lrm: lrm.timestamp = datetime.utcnow() else: lrm = LastReadMessage() lrm.user_id = user.id lrm.chat_id = chat.id lrm.timestamp = datetime.utcnow() lrm.save() except Exception as e: db.session.rollback() print(e) return server_error('Something went wrong, please try again.') else: return { 'data': MessageSchema(many=True).dump(msgs[:items_per_page]), 'nextCursor': nextCursor }
def get_posts(user): feed = request.args.get('feed') cursor = request.args.get('cursor') items_per_page = current_app.config['ITEMS_PER_PAGE'] nextCursor = None query = '' try: sorted_posts = Post.get_by_reactions().subquery() top_posts = db.session.query(Post, sorted_posts.c.sequence).join( sorted_posts, sorted_posts.c.id == Post.id).order_by( sorted_posts.c.sequence.desc()) latest_posts = Post.query.filter(Post.comment_id.is_(None)).order_by( Post.created_on.desc()) except Exception as e: db.session.rollback() print(e) return server_error('An unexpected error occured, please try again.') if cursor == '0' and feed == 'latest': query = latest_posts.limit(items_per_page + 1).all() elif cursor == '0' and feed == 'top': query = top_posts.limit(items_per_page + 1).all() else: if feed == 'latest': cursor = urlsafe_base64(cursor, from_base64=True) query = latest_posts.filter( Post.created_on < cursor).limit(items_per_page + 1).all() else: cursor = urlsafe_base64(cursor, from_base64=True) query = top_posts.filter( sorted_posts.c.sequence < cursor).limit(items_per_page + 1).all() if len(query) > items_per_page: nextCursor = urlsafe_base64( query[items_per_page - 1].created_on.isoformat()) \ if feed == 'latest' else urlsafe_base64( str(query[items_per_page - 1][1])) posts = [post.to_dict(user) for post in query[:items_per_page]] \ if feed == 'latest' else \ [post[0].to_dict(user) for post in query[:items_per_page]] return {'data': posts, 'nextCursor': nextCursor}
def update_comment_like(user, post_id, comment_id): comment = Comment.find_by_id(comment_id) if not comment: return not_found('Comment not found') if comment.is_liked_by(user): comment.likes.remove(user) else: comment.likes.append(user) try: comment.save() except (exc.IntegrityError, ValueError): db.session.rollback() return server_error('Something went wrong, please try again.') else: return jsonify(CommentSchema().dump(comment))