예제 #1
0
    def borrows(self, data_list):
        successful_borrows = []
        user = User.get_by_id(data_list[0]["user"]["user_id"])

        with database.atomic():
            num_book_borrowing = BookCirculation.select().where(
                (BookCirculation.user == user)
                & (BookCirculation.return_time.is_null(True))).count()

            if num_book_borrowing + len(data_list) > 5:
                raise BorrowingExceededError()

            for data in data_list:
                book = Book.get_by_id(data["book"]["book_id"])
                data['book'] = book
                data['user'] = user

                if BookCirculation.select().where(
                    (BookCirculation.book == book) &
                    (BookCirculation.return_time.is_null(True))).count() != 0:
                    raise AlreadyBorrowedError()

                successful_borrows.append(BookCirculation.create(**data))

        SendBorrowNotification(successful_borrows).start()

        return successful_borrows
예제 #2
0
    def search_content(self, params):
        index = search.Index(config.content_index)
        search_text = ''

        # This search_results objects has properties `number_found`, `results`,
        # and `cursor`. See
        # https://cloud.google.com/appengine/docs/python/search/searchresultsclass
        # search.Query docs:
        # https://cloud.google.com/appengine/docs/python/search/queryclass
        # search.QueryOptions docs:
        # https://cloud.google.com/appengine/docs/python/search/queryoptionsclass

        # Pagination using a 'page' argument pulls n arguments offset by n*page
        # pull first set of results with page=0
        page_size = 20
        offset = 0
        if 'page' in params:
            offset = int(params.pop('page')) * page_size

        # Build the SortOptions with 2 sort keys
        sort1 = search.SortExpression(
            expression='display_order',
            direction=search.SortExpression.DESCENDING,
            default_value=0)
        sort2 = search.SortExpression(
            expression='votes_for',
            direction=search.SortExpression.DESCENDING,
            default_value=0)
        sort3 = search.SortExpression(
            expression='created',
            direction=search.SortExpression.DESCENDING,
            default_value=0)
        sort_opts = search.SortOptions(expressions=[sort1, sort2, sort3])

        search_results = index.search(
            search.Query(query_string=self._stringify_search_params(params),
                         options=search.QueryOptions(
                             limit=page_size,
                             offset=offset,
                             snippeted_fields=['summary', 'body'],
                             sort_options=sort_opts,
                         )))
        for result in search_results.results:
            if 'Chapter_' in result.doc_id:
                book_id = None
                for field in result.fields:
                    if field.name == 'books':
                        book_id = field.value

                if book_id:
                    book = Book.get_by_id(book_id)
                    result.fields.append(search.TextField('bookUID', book.uid))
                    result.fields.append(
                        search.TextField('bookTitle', book.title))
                    result.fields.append(
                        search.TextField(
                            'bookIcon',
                            util.extract_value_from_json(book.icon, 'link')))
                    result.fields.append(
                        search.TextField(
                            'chapterNumber',
                            str(book.chapters.index(result.doc_id) + 1)))

        result_dicts = [
            util.search_document_to_dict(doc) for doc in search_results.results
        ]

        result_dicts = self._annotate_search_content(result_dicts)

        return result_dicts
예제 #3
0
    def delete(self, id):
        if not self.user:
            raise PermissionDenied("Public cannot delete.")

        logging.info(u'Api.delete(id={})'.format(id))

        entity = Model.get_by_id(id)
        if self.user.is_admin:
            allowed = True
        elif isinstance(entity, (Book, Page)):
            allowed = self.user.uid in entity.authors
        elif isinstance(entity, Chapter):
            books = Book.get_by_id(entity.books) or []
            allowed = all(self.user.uid in b.authors for b in books)
        else:
            allowed = entity.key.parent() == self.user.key

        if not allowed:
            raise PermissionDenied(
                "{} does not own {} and may not delete it.".format(
                    self.user, entity))

        entity.deleted = True
        # We're about to take it out of the index, so don't bother updating
        # it with the new value of the deleted property.
        # See model.Model._post_put_hook()
        entity.forbid_post_put_hook = True
        entity.put()

        if isinstance(entity, (Book, Page)):
            logging.info("Removing soft-deleted content from search.")
            search.Index(config.content_index).delete(entity.uid)

        entity_kind = Model.get_kind(entity)

        # If User object, need to remove unique properties from unique model
        if entity_kind is 'User':
            entity.remove_unique_properties(entity)

        # If vote, need to decrement vote on subject object
        if entity_kind is 'Vote':
            if entity.page_id:
                page_id = entity.page_id
                page = Page.get_by_id(page_id)
                if page is not None:
                    page.votes_for = max(page.votes_for - 1, 0)
                    page.put()
            if entity.book_id:
                book_id = entity.book_id
                book = Book.get_by_id(book_id)
                if book is not None:
                    book.votes_for = max(book.votes_for - 1, 0)
                    book.put()

        if entity_kind is 'Comment':
            if entity.page_id:
                page_id = entity.page_id
                page = Page.get_by_id(page_id)
                if page is not None:
                    page.num_comments = max(page.num_comments - 1, 0)
                    page.put()
            if entity.book_id:
                book_id = entity.book_id
                book = Book.get_by_id(book_id)
                if book is not None:
                    book.num_comments = max(book.num_comments - 1, 0)
                    book.put()