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 serve_file(id, reduced=False): """Serve the content (binary data) of a file. :param str id: the ``id`` value of the file whose file data will be served. :param bool reduced: toggles serving of file data or reduced-size file data. """ file = Session.query(File).options(subqueryload(File.parent_file)).get(id) if getattr(file, 'parent_file', None): file = file.parent_file elif getattr(file, 'url', None): response.status_int = 400 return json.dumps({'error': u'The content of file %s is stored elsewhere at %s' % (id, file.url)}) if file: files_dir = h.get_OLD_directory_path('files', config=config) if reduced: filename = getattr(file, 'lossy_filename', None) if not filename: response.status_int = 404 return json.dumps({'error': u'There is no size-reduced copy of file %s' % id}) file_path = os.path.join(files_dir, 'reduced_files', filename) else: file_path = os.path.join(files_dir, file.filename) unrestricted_users = h.get_unrestricted_users() if h.user_is_authorized_to_access_model(session['user'], file, unrestricted_users): return forward(FileApp(file_path)) else: response.status_int = 403 return json.dumps(h.unauthorized_msg) else: response.status_int = 404 return json.dumps({'error': 'There is no file with id %s' % id})
def edit(self, id): """Return a file and the data needed to update it. :URL: ``GET /files/edit`` with optional query string parameters :param str id: the ``id`` value of the file that will be updated. :returns: a dictionary of the form:: {"file": {...}, "data": {...}} where the value of the ``file`` key is a dictionary representation of the file and the value of the ``data`` key is a dictionary containing the objects necessary to update a file, viz. the return value of :func:`FilesController.new` .. note:: This action can be thought of as a combination of :func:`FilesController.show` and :func:`FilesController.new`. See :func:`get_new_edit_file_data` to understand how the query string parameters can affect the contents of the lists in the ``data`` dictionary. """ response.content_type = 'application/json' file = h.eagerload_file(Session.query(File)).get(id) if file: unrestricted_users = h.get_unrestricted_users() if h.user_is_authorized_to_access_model(session['user'], file, unrestricted_users): return {'data': get_new_edit_file_data(request.GET), 'file': file} else: response.status_int = 403 return h.unauthorized_msg else: response.status_int = 404 return {'error': 'There is no file 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]}
def get_collection(collection_id, user, unrestricted_users): """Return the collection such that ``collection.id==collection_id``. If the collection does not exist or if ``user`` is not authorized to access it, raise an appropriate error. :param int collection_id: the ``id`` value of a collection. :param user: a user model of the logged in user. :param list unrestricted_users: the unrestricted users of the system. :return: a collection model object. """ collection = Session.query(Collection).get(collection_id) if collection: if user is None or unrestricted_users is None or \ h.user_is_authorized_to_access_model(user, collection, unrestricted_users): return collection else: raise UnauthorizedCollectionReferenceError(collection_id) raise InvalidCollectionReferenceError(collection_id)
def get_collection(collection_id, user, unrestricted_users): """Return the collection such that ``collection.id==collection_id``. If the collection does not exist or if ``user`` is not authorized to access it, raise an appropriate error. :param int collection_id: the ``id`` value of a collection. :param user: a user model of the logged in user. :param list unrestricted_users: the unrestricted users of the system. :return: a collection model object. """ collection = Session.query(Collection).get(collection_id) if collection: if user is None or unrestricted_users is None or \ h.user_is_authorized_to_access_model(user, collection, unrestricted_users): return collection else: raise UnauthorizedCollectionReferenceError(collection_id) raise InvalidCollectionReferenceError(collection_id)
def show(self, id): """Return a form backup. :URL: ``GET /formbackups/id`` :param str id: the ``id`` value of the form backup to be returned. :returns: a form backup model object. """ form_backup = Session.query(FormBackup).get(id) if form_backup: unrestricted_users = h.get_unrestricted_users() user = session['user'] if h.user_is_authorized_to_access_model(user, form_backup, unrestricted_users): return form_backup else: response.status_int = 403 return h.unauthorized_msg else: response.status_int = 404 return {'error': 'There is no form backup with id %s' % id}
def show(self, id): """Return a file. :URL: ``GET /files/id`` :param str id: the ``id`` value of the file to be returned. :returns: a file model object. """ file = h.eagerload_file(Session.query(File)).get(id) if file: unrestricted_users = h.get_unrestricted_users() user = session['user'] if h.user_is_authorized_to_access_model(user, file, unrestricted_users): return file else: response.status_int = 403 return h.unauthorized_msg else: response.status_int = 404 return {'error': 'There is no file with id %s' % id}
def show(self, id): """Return a form backup. :URL: ``GET /formbackups/id`` :param str id: the ``id`` value of the form backup to be returned. :returns: a form backup model object. """ form_backup = Session.query(FormBackup).get(id) if form_backup: unrestricted_users = h.get_unrestricted_users() user = session['user'] if h.user_is_authorized_to_access_model(user, form_backup, unrestricted_users): return form_backup else: response.status_int = 403 return h.unauthorized_msg else: response.status_int = 404 return {'error': 'There is no form backup 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 update(self, id): """Update a file and return it. :URL: ``PUT /files/id`` :Request body: JSON object representing the file with updated attribute values. :param str id: the ``id`` value of the file to be updated. :returns: the updated file model. """ file = h.eagerload_file(Session.query(File)).get(int(id)) if file: unrestricted_users = h.get_unrestricted_users() user = session['user'] if h.user_is_authorized_to_access_model(user, file, unrestricted_users): try: if getattr(file, 'parent_file', None): file = update_subinterval_referencing_file(file) elif getattr(file, 'url', None): file = update_externally_hosted_file(file) else: file = update_file(file) # file will be False if there are no changes if file: Session.add(file) Session.commit() return file 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 Invalid, e: response.status_int = 400 return {'errors': e.unpack_errors()} else: response.status_int = 403 return h.unauthorized_msg
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] }