Ejemplo n.º 1
0
    def get_one(self, name):
        """Get specified one of settings

        :param name: name
        :return: specified one
        """
        result = self._collection.find_one({'name': name})
        return deal_with_object_id(result)
Ejemplo n.º 2
0
    def get_list(self, *, size, offset):
        """Get settings list

        :param size: paging size
        :param offset: skip
        :return: list of settings
        """
        li = self._collection.find({}).skip(offset).limit(size)
        return deal_with_object_id(li)
Ejemplo n.º 3
0
    def get_comments(self, article_id, *, size, offset, fetch_deleted=False):
        """Get article content

        :param article_id: article ID
        :param size: fetch size
        :param offset: skip
        :param fetch_deleted: fetch deleted object flag, only admin can set to True
        :raise: 404 NoSuchArticleError
        :return: array of comments, count
        """

        data = self._collection.aggregate([
            # unwind comment array
            {
                '$unwind': '$comments'
            },
            # match condition
            {
                '$match': {
                    '_id': ObjectId(article_id),
                    'comments.deleted': False if not fetch_deleted else True
                }
            },
            # group date and calculate count
            {
                '$group': {
                    '_id': '$_id',
                    'count': {
                        '$sum': 1
                    },
                    'comments': {
                        '$push': '$comments'
                    }
                }
            },
            # only fetch comments
            {
                '$project': {
                    'count': 1,
                    'comments': {
                        '$slice': ['$comments', offset, size]
                    },
                }
            },
        ])

        # get result
        result = [x for x in data]

        # check result
        if len(result) == 0:
            raise NoSuchArticleError('No such articles.')

        # deal with ObjectId and return
        return deal_with_object_id(result[0]['comments']), result[0]['count']
Ejemplo n.º 4
0
    def update_one(self, name, data):
        """Update settings

        :param name: name
        :param data: data
        :return: updated object
        """
        # TODO deal with data
        result = self._collection.find_one_and_update(
            {'name': name}, data, return_document=ReturnDocument.AFTER)
        return deal_with_object_id(result)
Ejemplo n.º 5
0
    def get_content(self, article_id, *, comments_size):
        """Fetch article content

        Every times fetch the content of article,
        update the counts of views.

        :param article_id: article ID
        :param comments_size: fetch comments size
        :raise: 404 NoSuchArticleError
        """

        # edit condition
        condition = {'$match': {'_id': ObjectId(article_id), 'deleted': False}}

        # update views first
        updated = self._collection.update_one(condition,
                                              {'$inc': {
                                                  'views': 1
                                              }})

        # if no matched article
        if updated.modified_count == 0:
            raise NoSuchArticleError('No such article.')

        # format
        projection = {
            '$project': {
                '_id': 1,
                'title': 1,
                'author': 1,
                'content': 1,
                'views': 1,
                'tags': 1,
                'timestamp': 1,
                'reviews': {
                    '$size': {
                        '$filter': {
                            'input': '$comments',
                            'as': 'c',
                            'cond': {
                                '$not': '$$c.deleted'
                            }
                        }
                    }
                },
                'comments': {
                    '$slice': [{
                        '$filter': {
                            'input': '$comments',
                            'as': 'c',
                            'cond': {
                                '$not': '$$c.deleted'
                            }
                        }
                    }, comments_size]
                }
            }
        }

        # fetch document
        data = self._collection.aggregate([condition, projection])

        # put result into list, it should be only one element if succeed
        result = [x for x in data]

        # if nothing was fetched raise error
        if len(result) == 0:
            raise NoSuchArticleError('No such article.')

        # deal with ObjectId and return the first element
        return deal_with_object_id(result)[0]
Ejemplo n.º 6
0
    def get_list(self, *, size, offset, tags=None, fetch_deleted=False):
        """Fetch articles' list

        When size is 0, mean fetch all of the rest articles.

        :param size: length of list
        :param offset: counts of skips
        :param tags: tags
        :param fetch_deleted: fetch deleted object flag, only admin can set to True
        :return: fetched list, or None if nothing was fetched
        """

        # edit condition
        condition = {'$match': {}}
        if not fetch_deleted:
            condition['$match']['deleted'] = False
        if tags:
            condition['$match']['tags'] = tags

        # fetch format
        projection = {
            '$project': {
                '_id': 1,
                'title': 1,
                'author': 1,
                'peek': 1,
                'views': 1,
                'tags': 1,
                'timestamp': 1,
                'deleted': 1,
                'reviews': {
                    '$size': {
                        '$filter': {
                            'input': '$comments',
                            'as': 'c',
                            'cond': {
                                '$not': '$$c.deleted'
                            }
                        }
                    }
                }
            }
        }

        # fetch list
        cur = self._collection.aggregate([
            condition,
            projection,
            # skip first
            {
                '$skip': offset
            },
            # keep order after skip
            {
                '$limit': size
            }
        ])

        # convert to list
        result = [i for i in cur]

        # check if nothing was fetched
        if len(result) == 0:
            return None

        # convert ObjectId to str and return
        return deal_with_object_id(result)