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}
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()}
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()}
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}
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()}
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}
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()}
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]}
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}
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}
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}
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}
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] }