def get_post(post_id: str) -> Post: """ Fetch existing post resource. :param post_id: Identifier of post to fetch. :type post_id: str :return: Post """ try: post = Post.objects.get(pk=post_id) post.description = decrypt_content(post.description) post.content = decrypt_content(post.content) return post except (DoesNotExist, ValidationError): raise PostNotFoundError()
def get_posts(start=None, count=None) -> list: """ Fetches collection of post resources. :param start: Used for pagination, specify where to start. :type start: int :param count: Used for pagination, specify number of posts to find. :type count: int :return: [Post, ...] """ posts = Post.objects.get_public()[start:start + count] \ if start and count else Post.objects.get_public() for post in posts: post.description = decrypt_content(post.description) post.content = decrypt_content(post.content) return posts
def get_user_posts(user_id: str, start: int = None, count: int = None): """ Find all posts belonging to given user. :param user_id: Identifier of author. :type user_id: str :param start: Used for pagination, specify where to start. :type start: int :param count: Used for pagination, specify number of posts to find. :type count: int :return: [Post, ...] """ posts = Post.objects(author=user_id)[start:count] for post in posts: post.description = decrypt_content(post.description) post.content = decrypt_content(post.content) return posts
def get_comment(comment_id: str) -> Comment: """ Fetch existing comment resource. :param comment_id: Identifier of comment to fetch. :type comment_id: str """ try: comment = Comment.objects.get(pk=comment_id) comment.content = decrypt_content(comment.content) return comment except (DoesNotExist, ValidationError): raise CommentNotFoundError()
def get_user_comments(user_id: str, start: int = None, count: int = None): """ Fetch collection of comments given post. :param post_id: Identifier of post to target. :type post_id: str :param start: Used for pagination, specify where to start. :type start: int :param count: Used for pagination, specify number of posts to find. :type count: int :return: [Comment, ...] """ comments = Comment.objects(author=user_id)[start:count] for comment in comments: comment.content = decrypt_content(comment.content) return comments
def search_posts(post_search_settings: PostSearchSettingsDto, user_id, start: int = None, count: int = None) -> list: """ Search for an existing post resource. :param post_search_settings: Post search settings :type post_search_settings: PostSearchSettingsDto :param user_id: Identifier of user creating search request. :type user_id: str :param start: Used for pagination, specify where to start. :type start: int :param count: Used for pagination, specify number of posts to find. :type count: int """ post_search_requests = PostSearchRequest.objects( user_id=user_id).order_by('-time') # verify post request hasn't been made within provided parameters if post_search_requests: now = datetime.datetime.utcnow().timestamp() if now - post_search_requests[0].time.timestamp( ) <= settings.post.search_time_delay: raise ResourceNotAvailableError() # log post search request PostSearchRequest(user_id=user_id, query=post_search_settings.query, options=post_search_settings.options).save() queries = {} if PostSearchOptions.TITLE in post_search_settings.options: queries['title__contains'] = post_search_settings.query if PostSearchOptions.TAGS in post_search_settings.options: queries['tags__contains'] = post_search_settings.query try: posts = Post.objects(Q(**queries)) except InvalidQueryError: posts = Post.objects() # TODO: research how to optimize search queries for encrypted content for post in posts: post.description = decrypt_content(post.description) post.content = decrypt_content(post.content) if PostSearchOptions.CONTENT in post_search_settings.options: posts = [ post for post in posts if post_search_settings.query in post.content ] if PostSearchOptions.DESCRIPTION in post_search_settings.options: posts = [ post for post in posts if post_search_settings.query in post.description ] if PostSearchOptions.AUTHOR in post_search_settings.options: try: author = User.objects.get(username=post_search_settings.query) # filter posts by author username posts = [post for post in posts if post.author == str(author.id)] except DoesNotExist: posts = [] return posts[start:start + count] if start and count else posts