Esempio n. 1
0
    def delete(self, id):
        """Delete an existing collection and return it.

        :URL: ``DELETE /collections/id``
        :param str id: the ``id`` value of the collection to be deleted.
        :returns: the deleted collection model.

        .. note::

           Only administrators and a collection's enterer can delete it.

        """
        collection = h.eagerload_collection(Session.query(Collection),
                                            eagerload_forms=True).get(id)
        if collection:
            if session['user'].role == u'administrator' or \
            collection.enterer is session['user']:
                session['user'] = Session.merge(session['user'])
                collection.modifier = session['user']
                collection_dict = collection.get_full_dict()
                backup_collection(collection_dict)
                update_collections_that_reference_this_collection(
                    collection, self.query_builder, deleted=True)
                Session.delete(collection)
                Session.commit()
                return collection_dict
            else:
                response.status_int = 403
                return h.unauthorized_msg
        else:
            response.status_int = 404
            return {'error': 'There is no collection with id %s' % id}
Esempio n. 2
0
    def search(self):
        """Return the list of collection resources matching the input JSON query.

        :URL: ``SEARCH /collections`` (or ``POST /collections/search``)
        :request body: A JSON object of the form::

                {"query": {"filter": [ ... ], "order_by": [ ... ]},
                 "paginator": { ... }}

            where the ``order_by`` and ``paginator`` attributes are optional.

        .. note::
        
            Search does not return the forms of all collections that match the
            search.  For that, a second request is required, i.e., to
            ``GET /collections/id``.

        """
        try:
            json_search_params = unicode(request.body, request.charset)
            python_search_params = json.loads(json_search_params)
            SQLAQuery = h.eagerload_collection(
                self.query_builder.get_SQLA_query(
                    python_search_params.get('query')))
            query = h.filter_restricted_models('Collection', SQLAQuery)
            return h.add_pagination(query,
                                    python_search_params.get('paginator'))
        except h.JSONDecodeError:
            response.status_int = 400
            return h.JSONDecodeErrorResponse
        except (OLDSearchParseError, Invalid), e:
            response.status_int = 400
            return {'errors': e.unpack_errors()}
Esempio n. 3
0
    def index(self):
        """Get all collection resources.

        :URL: ``GET /collections`` with optional query string parameters for
            ordering and pagination.
        :returns: a list of all collection resources.

        .. note::

           See :func:`utils.add_order_by` and :func:`utils.add_pagination` for the
           query string parameters that effect ordering and pagination.

        .. note::
        
            ``GET /collections`` does not return the forms of the collections
            returned.  For that, a second request is required, i.e., to
            ``GET /collections/id`` with the relevant ``id`` value.

        """
        try:
            query = h.eagerload_collection(Session.query(Collection))
            query = h.add_order_by(query, dict(request.GET),
                                   self.query_builder)
            query = h.filter_restricted_models('Collection', query)
            return h.add_pagination(query, dict(request.GET))
        except Invalid, e:
            response.status_int = 400
            return {'errors': e.unpack_errors()}
Esempio n. 4
0
    def show(self, id):
        """Return a collection.
        
        :URL: ``GET /collections/id``
        :param str id: the ``id`` value of the collection to be returned.
        :returns: a collection model object.

        .. note::

            Returns all of the forms of the collection, unlike the other
            collections actions.

        """
        collection = h.eagerload_collection(Session.query(Collection),
                                           eagerload_forms=True).get(id)
        if collection:
            unrestricted_users = h.get_unrestricted_users()
            user = session['user']
            if h.user_is_authorized_to_access_model(user, collection, unrestricted_users):
                return collection.get_full_dict()
            else:
                response.status_int = 403
                return h.unauthorized_msg
        else:
            response.status_int = 404
            return {'error': 'There is no collection with id %s' % id}
Esempio n. 5
0
    def search(self):
        """Return the list of collection resources matching the input JSON query.

        :URL: ``SEARCH /collections`` (or ``POST /collections/search``)
        :request body: A JSON object of the form::

                {"query": {"filter": [ ... ], "order_by": [ ... ]},
                 "paginator": { ... }}

            where the ``order_by`` and ``paginator`` attributes are optional.

        .. note::
        
            Search does not return the forms of all collections that match the
            search.  For that, a second request is required, i.e., to
            ``GET /collections/id``.

        """
        try:
            json_search_params = unicode(request.body, request.charset)
            python_search_params = json.loads(json_search_params)
            SQLAQuery = h.eagerload_collection(
                self.query_builder.get_SQLA_query(python_search_params.get('query')))
            query = h.filter_restricted_models('Collection', SQLAQuery)
            return h.add_pagination(query, python_search_params.get('paginator'))
        except h.JSONDecodeError:
            response.status_int = 400
            return h.JSONDecodeErrorResponse
        except (OLDSearchParseError, Invalid), e:
            response.status_int = 400
            return {'errors': e.unpack_errors()}
Esempio n. 6
0
    def delete(self, id):
        """Delete an existing collection and return it.

        :URL: ``DELETE /collections/id``
        :param str id: the ``id`` value of the collection to be deleted.
        :returns: the deleted collection model.

        .. note::

           Only administrators and a collection's enterer can delete it.

        """
        collection = h.eagerload_collection(Session.query(Collection),
                                           eagerload_forms=True).get(id)
        if collection:
            if session['user'].role == u'administrator' or \
            collection.enterer is session['user']:
                session['user'] = Session.merge(session['user'])
                collection.modifier = session['user']
                collection_dict = collection.get_full_dict()
                backup_collection(collection_dict)
                update_collections_that_reference_this_collection(collection,
                                                self.query_builder, deleted=True)
                Session.delete(collection)
                Session.commit()
                return collection_dict
            else:
                response.status_int = 403
                return h.unauthorized_msg
        else:
            response.status_int = 404
            return {'error': 'There is no collection with id %s' % id}
Esempio n. 7
0
    def index(self):
        """Get all collection resources.

        :URL: ``GET /collections`` with optional query string parameters for
            ordering and pagination.
        :returns: a list of all collection resources.

        .. note::

           See :func:`utils.add_order_by` and :func:`utils.add_pagination` for the
           query string parameters that effect ordering and pagination.

        .. note::
        
            ``GET /collections`` does not return the forms of the collections
            returned.  For that, a second request is required, i.e., to
            ``GET /collections/id`` with the relevant ``id`` value.

        """
        try:
            query = h.eagerload_collection(Session.query(Collection))
            query = h.add_order_by(query, dict(request.GET), self.query_builder)
            query = h.filter_restricted_models('Collection', query)
            return h.add_pagination(query, dict(request.GET))
        except Invalid, e:
            response.status_int = 400
            return {'errors': e.unpack_errors()}
Esempio n. 8
0
    def update(self, id):
        """Update a collection and return it.
        
        :URL: ``PUT /collections/id``
        :Request body: JSON object representing the collection with updated attribute values.
        :param str id: the ``id`` value of the collection to be updated.
        :returns: the updated collection model.

        """
        collection = h.eagerload_collection(Session.query(Collection),
                                           eagerload_forms=True).get(int(id))
        if collection:
            unrestricted_users = h.get_unrestricted_users()
            user = session['user']
            if h.user_is_authorized_to_access_model(user, collection, unrestricted_users):
                try:
                    schema = CollectionSchema()
                    values = json.loads(unicode(request.body, request.charset))
                    collections_referenced = get_collections_referenced(
                                values['contents'], user, unrestricted_users, id)
                    values = add_contents_unpacked_to_values(values, collections_referenced)
                    values = add_form_ids_list_to_values(values)
                    state = h.get_state_object(values)
                    data = schema.to_python(values, state)
                    collection_dict = collection.get_full_dict()
                    collection, restricted, contents_changed = update_collection(
                        collection, data, collections_referenced)
                    # collection will be False if there are no changes (cf. update_collection).
                    if collection:
                        backup_collection(collection_dict)
                        update_collections_that_reference_this_collection(collection, self.query_builder,
                                            restricted=restricted, contents_changed=contents_changed)
                        Session.add(collection)
                        Session.commit()
                        return collection.get_full_dict()
                    else:
                        response.status_int = 400
                        return {'error':
                            u'The update request failed because the submitted data were not new.'}
                except h.JSONDecodeError:
                    response.status_int = 400
                    return h.JSONDecodeErrorResponse
                except CircularCollectionReferenceError, e:
                    response.status_int = 400
                    return {'error':
                        u'Circular collection reference error: collection %d references collection %d.' % (id, e.args[0])}
                except InvalidCollectionReferenceError, e:
                    response.status_int = 400
                    return {'error': u'Invalid collection reference error: there is no collection with id %d' % e.args[0]}
                except UnauthorizedCollectionReferenceError:
                    response.status_int = 403
                    return {'error': u'Unauthorized collection reference error: you are not authorized to access collection %d' % e.args[0]}
Esempio n. 9
0
    def edit(self, id):
        """Return a collection and the data needed to update it.

        :URL: ``GET /collections/edit`` with optional query string parameters 
        :param str id: the ``id`` value of the collection that will be updated.
        :returns: a dictionary of the form::

                {"collection": {...}, "data": {...}}

            where the value of the ``collection`` key is a dictionary
            representation of the collection and the value of the ``data`` key
            is a dictionary containing the objects necessary to update a
            collection, viz. the return value of
            :func:`CollectionsController.new`

        .. note::
        
           This action can be thought of as a combination of
           :func:`CollectionsController.show` and
           :func:`CollectionsController.new`.  See
           :func:`get_new_edit_collection_data` to understand how the query string
           parameters can affect the contents of the lists in the ``data``
           dictionary.

        """
        collection = h.eagerload_collection(Session.query(Collection)).get(id)
        if collection:
            unrestricted_users = h.get_unrestricted_users()
            if h.user_is_authorized_to_access_model(session['user'],
                                                    collection,
                                                    unrestricted_users):
                data = get_new_edit_collection_data(request.GET)
                return {'data': data, 'collection': collection}
            else:
                response.status_int = 403
                return h.unauthorized_msg
        else:
            response.status_int = 404
            return {'error': 'There is no collection with id %s' % id}
Esempio n. 10
0
    def show(self, id):
        """Return a collection.
        
        :URL: ``GET /collections/id``
        :param str id: the ``id`` value of the collection to be returned.
        :returns: a collection model object.

        .. note::

            Returns all of the forms of the collection, unlike the other
            collections actions.

            If there is a truthy GET param with key 'latex' and if the markup
            language is reStructuredText, then the collection's
            contents_unpacked value will be returned as a LaTeX string in the
            'latex' attribute.

        """

        collection = h.eagerload_collection(Session.query(Collection),
                                            eagerload_forms=True).get(id)
        if collection:
            unrestricted_users = h.get_unrestricted_users()
            user = session['user']
            if h.user_is_authorized_to_access_model(user, collection,
                                                    unrestricted_users):
                result = collection.get_full_dict()
                # TODO: deal with markdown2latex ...
                if request.GET.get('latex') and \
                collection.markup_language == 'reStructuredText':
                    result['latex'] = h.rst2latex(collection.contents_unpacked)
                return result
            else:
                response.status_int = 403
                return h.unauthorized_msg
        else:
            response.status_int = 404
            return {'error': 'There is no collection with id %s' % id}
Esempio n. 11
0
    def edit(self, id):
        """Return a collection and the data needed to update it.

        :URL: ``GET /collections/edit`` with optional query string parameters 
        :param str id: the ``id`` value of the collection that will be updated.
        :returns: a dictionary of the form::

                {"collection": {...}, "data": {...}}

            where the value of the ``collection`` key is a dictionary
            representation of the collection and the value of the ``data`` key
            is a dictionary containing the objects necessary to update a
            collection, viz. the return value of
            :func:`CollectionsController.new`

        .. note::
        
           This action can be thought of as a combination of
           :func:`CollectionsController.show` and
           :func:`CollectionsController.new`.  See
           :func:`get_new_edit_collection_data` to understand how the query string
           parameters can affect the contents of the lists in the ``data``
           dictionary.

        """
        collection = h.eagerload_collection(Session.query(Collection)).get(id)
        if collection:
            unrestricted_users = h.get_unrestricted_users()
            if h.user_is_authorized_to_access_model(
                                session['user'], collection, unrestricted_users):
                data = get_new_edit_collection_data(request.GET)
                return {'data': data, 'collection': collection}
            else:
                response.status_int = 403
                return h.unauthorized_msg
        else:
            response.status_int = 404
            return {'error': 'There is no collection with id %s' % id}
Esempio n. 12
0
    def show(self, id):
        """Return a collection.
        
        :URL: ``GET /collections/id``
        :param str id: the ``id`` value of the collection to be returned.
        :returns: a collection model object.

        .. note::

            Returns all of the forms of the collection, unlike the other
            collections actions.

            If there is a truthy GET param with key 'latex' and if the markup
            language is reStructuredText, then the collection's
            contents_unpacked value will be returned as a LaTeX string in the
            'latex' attribute.

        """

        collection = h.eagerload_collection(Session.query(Collection),
                                           eagerload_forms=True).get(id)
        if collection:
            unrestricted_users = h.get_unrestricted_users()
            user = session['user']
            if h.user_is_authorized_to_access_model(user, collection, unrestricted_users):
                result = collection.get_full_dict()
                # TODO: deal with markdown2latex ...
                if request.GET.get('latex') and \
                collection.markup_language == 'reStructuredText':
                    result['latex'] = h.rst2latex(collection.contents_unpacked)
                return result
            else:
                response.status_int = 403
                return h.unauthorized_msg
        else:
            response.status_int = 404
            return {'error': 'There is no collection with id %s' % id}
Esempio n. 13
0
    def update(self, id):
        """Update a collection and return it.
        
        :URL: ``PUT /collections/id``
        :Request body: JSON object representing the collection with updated attribute values.
        :param str id: the ``id`` value of the collection to be updated.
        :returns: the updated collection model.

        """
        collection = h.eagerload_collection(Session.query(Collection),
                                            eagerload_forms=True).get(int(id))
        if collection:
            unrestricted_users = h.get_unrestricted_users()
            user = session['user']
            if h.user_is_authorized_to_access_model(user, collection,
                                                    unrestricted_users):
                try:
                    schema = CollectionSchema()
                    values = json.loads(unicode(request.body, request.charset))
                    collections_referenced = get_collections_referenced(
                        values['contents'], user, unrestricted_users, id)
                    values = add_contents_unpacked_to_values(
                        values, collections_referenced)
                    values = add_form_ids_list_to_values(values)
                    state = h.get_state_object(values)
                    data = schema.to_python(values, state)
                    collection_dict = collection.get_full_dict()
                    collection, restricted, contents_changed = update_collection(
                        collection, data, collections_referenced)
                    # collection will be False if there are no changes (cf. update_collection).
                    if collection:
                        backup_collection(collection_dict)
                        update_collections_that_reference_this_collection(
                            collection,
                            self.query_builder,
                            restricted=restricted,
                            contents_changed=contents_changed)
                        Session.add(collection)
                        Session.commit()
                        return collection.get_full_dict()
                    else:
                        response.status_int = 400
                        return {
                            'error':
                            u'The update request failed because the submitted data were not new.'
                        }
                except h.JSONDecodeError:
                    response.status_int = 400
                    return h.JSONDecodeErrorResponse
                except CircularCollectionReferenceError, e:
                    response.status_int = 400
                    return {
                        'error':
                        u'Circular collection reference error: collection %d references collection %d.'
                        % (id, e.args[0])
                    }
                except InvalidCollectionReferenceError, e:
                    response.status_int = 400
                    return {
                        'error':
                        u'Invalid collection reference error: there is no collection with id %d'
                        % e.args[0]
                    }
                except UnauthorizedCollectionReferenceError:
                    response.status_int = 403
                    return {
                        'error':
                        u'Unauthorized collection reference error: you are not authorized to access collection %d'
                        % e.args[0]
                    }