class RecordFilesListResource(Resource): method_decorators = [require_api_auth()] def get(self, recid): from invenio.legacy.bibdocfile.api import BibRecDocs from invenio.legacy.search_engine import check_user_can_view_record record = get_record(recid) if not record: abort(404) auth_code, _ = check_user_can_view_record(current_user, recid) if auth_code: abort(401) ids = [recid] for k in ['rel_dataset', 'rel_software']: ids.extend([int(r) for r in record.get(k, [])]) files = [] for recid in ids: record_files = BibRecDocs(recid).list_latest_files( list_hidden=False) files.extend( map( lambda f: { 'id': f.docid, 'name': '%s%s' % (f.name, f.format), 'url': url_for( 'recordfileresource', recid=recid, fileid=f.docid), }, filter(lambda f: not f.is_icon(), record_files))) return files
class TagListResource(Resource): """The tags list resource.""" method_decorators = [require_api_auth(), error_handler] def get(self): """ Get a list of tags. Get the list of tags a user owns. """ uid = current_user.get_id() tags_retrieved = tags_api.get_all_tags_of_user(uid) tags = [TagRepresenation(t) for t in tags_retrieved] return map(lambda t: t.marshal(), tags) def delete(self): """Delete all tags. Delete all the tags a user owns. """ uid = current_user.get_id() tags_api.delete_all_tags_from_user(uid) return "", 204 @require_header('Content-Type', 'application/json') def post(self): """Create a new tag. Creates a new tag and sets as owner the current user. """ json_data = request.get_json() v = RESTValidator(tag_post_schema) if v.validate(json_data) is False: raise TagValidationError( error_msg="Validation error for tag creation", status_code=400, error_list=v.get_errors()) uid = current_user.get_id() tag_to_create = tags_api.create_tag_for_user(uid, json_data['name']) tag_to_return = TagRepresenation(tag_to_create) return tag_to_return.marshal(), 201 def patch(self): """PATCH.""" abort(405) def options(self): """OPTIONS.""" abort(405) def put(self): """PUT.""" abort(405) def head(self): """HEAD.""" abort(405)
class B2Resource(Resource): method_decorators = [require_api_auth()] def get(self, **kwargs): abort(405) def post(self, **kwargs): abort(405) def put(self, **kwargs): abort(405) def delete(self, **kwargs): abort(405) def head(self, **kwargs): abort(405) def options(self, **kwargs): abort(405) def patch(self, **kwargs): abort(405)
class TestTagsResource(Resource): method_decorators = [require_api_auth()] @require_header('Content-Type', 'application/json') def get(self): import json from flask import make_response from invenio.modules.tags.models import WtgTAG from invenio.ext.restful.errors import (RestfulError, InvalidPageError) from invenio.ext.restful import pagination response = None try: endpoint = request.endpoint args = request.args page = int(args.get('page', 1)) per_page = int(args.get('per_page', 2)) # check values arguments and raise exceptions if any errors if per_page < 0: raise RestfulError( error_msg="Invalid per_page: {}".format(per_page), status_code=400) if page < 0: raise InvalidPageError( error_msg="Invalid page: {}".format(page), status_code=400) # need to sort by id # also assuming only one user so no need to filter # user's id tags_q = WtgTAG.query.order_by(WtgTAG.id) p = pagination.RestfulSQLAlchemyPagination( query=tags_q, page=page, per_page=per_page) if page > p.pages: raise InvalidPageError( error_msg="Invalid page: {}".format(page), status_code=400) tags_to_return = map( lambda x: TagRepresenation(x).marshal(), p.items) kwargs = {} kwargs['endpoint'] = endpoint kwargs['args'] = request.args link_header = p.link_header(**kwargs) response = make_response(json.dumps(tags_to_return)) response.headers[link_header[0]] = link_header[1] response.headers['Content-Type'] = request.headers[ 'Content-Type'] except (RestfulError, InvalidPageError) as e: exception = {} exception['message'] = e.error_msg exception['type'] = "{0}".format(type(e)) response = make_response(json.dumps(exception)) return response
class Test1Resource(Resource): # NOTE: Method decorators are applied in reverse order method_decorators = [ require_oauth_scopes('test:testscope'), require_api_auth(), ] def get(self): assert request.oauth.access_token return "success", 200 def post(self): assert request.oauth.access_token return "success", 200 @require_header('Content-Type', 'application/json') def put(self): return "success", 200
class TestDataResource(Resource): method_decorators = [require_api_auth()] @require_header('Content-Type', 'application/json') def get(self): import json from flask import make_response from invenio.ext.restful.errors import (InvalidPageError) from invenio.ext.restful import pagination # Test to see that the exceptions are raised correctly # In restful.py it is not needed because the error_hanler # takes care of exceptions response = None try: # test data testdata = range(25) endpoint = request.endpoint args = request.args page = int(args.get('page', 1)) per_page = int(args.get('per_page', 10)) p = pagination.RestfulPagination(page=page, per_page=per_page, total_count=len(testdata)) data_to_return = p.slice(testdata) kwargs = {} kwargs['endpoint'] = endpoint kwargs['args'] = request.args link_header = p.link_header(**kwargs) response = make_response(json.dumps(data_to_return)) response.headers[link_header[0]] = link_header[1] response.headers['Content-Type'] = request.headers[ 'Content-Type'] except InvalidPageError as e: exception = {} exception['message'] = e.error_msg exception['type'] = "{0}".format(type(e)) response = make_response(json.dumps(exception)) return response
class RecordFileResource(Resource): method_decorators = [require_api_auth()] def get(self, recid, fileid): record = get_record(recid) if not record: abort(404) uid = current_user.get_id() from invenio.legacy.bibdocfile.api import BibRecDocs record_files = BibRecDocs(recid).list_latest_files(list_hidden=False) for f in record_files: if f.docid == fileid: docfile = f break else: abort(404) if docfile.is_restricted(current_user)[0]: abort(401) filename = '%s%s' % (docfile.name, docfile.format) return send_file(docfile.fullpath, mimetype=docfile.mime, attachment_filename=filename)
return error_messages def can_access_deposit_type(type_): """Return True if current user can access given deposition type.""" if type_ is None: default_type = deposit_default_type.get() type_ = default_type and default_type.get_identifier() or None return type_ in current_user.get('precached_allowed_deposition_types', []) # ========= # Mix-ins # ========= deposition_decorators = [ require_api_auth(), error_handler, api_request_globals, ] class InputProcessorMixin(object): """Mix-in class for validating and processing deposition input data.""" input_schema = draft_data_extended_schema def validate_input(self, deposition, draft_id=None): """Validate input data for creating and update a deposition.""" v = APIValidator() draft_id = draft_id or deposition.get_default_draft_id()
error_messages.append(dict(field=field, message=msgs, code=error_codes["validation_error"])) return error_messages def can_access_deposit_type(type_): """Return True if current user can access given deposition type.""" if type_ is None: default_type = deposit_default_type.get() type_ = default_type and default_type.get_identifier() or None return type_ in current_user.get("precached_allowed_deposition_types", []) # ========= # Mix-ins # ========= deposition_decorators = [require_api_auth(), error_handler, api_request_globals] class InputProcessorMixin(object): """Mix-in class for validating and processing deposition input data.""" input_schema = draft_data_extended_schema def validate_input(self, deposition, draft_id=None): """Validate input data for creating and update a deposition.""" v = APIValidator() draft_id = draft_id or deposition.get_default_draft_id() metadata_schema = deposition.type.api_metadata_schema(draft_id) if metadata_schema:
class RecordListTagResource(Resource): """This resource handles tags when it comes to records.""" method_decorators = [require_api_auth(), error_handler] @require_header('Content-Type', 'application/json') def post(self, record_id): """Attach a list of tags to a record. If a tag in the list exists in database then it is attached to the record else the tag is created an then it is attached to the record :param record_id: the identifier of the record """ json_data = request.get_json() attachTagsValidator = RESTValidator(add_tags_schema) if attachTagsValidator.validate(json_data) is False: raise TagValidationError( error_msg="Validation error in attaching tags on record", status_code=400, error_list=attachTagsValidator.get_errors()) uid = current_user.get_id() tags_just_attached = tags_api.attach_tags_to_record( uid, json_data['tags'], record_id) if len(tags_just_attached) == 0: return [] else: return map(lambda t: TagRepresenation(t).marshal(), tags_just_attached) def get(self, record_id): """Retrieve all the attached on a record tags. :param record_id: the identifier of the record """ attached_tags = tags_api.get_attached_tags_on_record(record_id) if len(attached_tags) == 0: return [] else: return map(lambda t: TagRepresenation(t).marshal(), attached_tags) def delete(self, record_id): """Detach all the tags from a record. :param record_id: the identifier of the record """ pass def put(self, record_id): """Replace all tags for a record. :param record_id: the identifier of the record """ pass def head(self, record_id): """A HEAD request.""" abort(405) def patch(self, record_id): """A PATCH request.""" abort(405) def options(self, record_id): """A OPTIONS request.""" abort(405)
class RecordTagResource(Resource): """Handles a tag attached on a record.""" method_decorators = [require_api_auth(), error_handler] def delete(self, record_id, tag_name): """Detach a tag from a record. :param record_id: the identifier of the record :param tag_name: the name of the tag """ uid = current_user.get_id() tags_api.detach_tag_from_record(uid, tag_name, record_id) return "", 204 def post(self, record_id, tag_name): """A POST request. :param record_id: the identifier of the record :param tag_name: the name of the tag """ abort(405) def put(self, record_id, tag_name): """A PUT request. :param record_id: the identifier of the record :param tag_name: the name of the tag """ abort(405) def patch(self, record_id, tag_name): """A PATCH request. :param record_id: the identifier of the record :param tag_name: the name of the tag """ abort(405) def options(self, record_id, tag_name): """A OPTIONS request. :param record_id: the identifier of the record :param tag_name: the name of the tag """ abort(405) def head(self, record_id, tag_name): """A HEAD request. :param record_id: the identifier of the record :param tag_name: the name of the tag """ abort(405) def get(self, record_id, tag_name): """A GET request. :param record_id: the identifier of the record :param tag_name: the name of the tag """ abort(405)
class TagResource(Resource): """The Tag Resource.""" method_decorators = [require_api_auth(), error_handler] def get(self, tag_name): """Get a tag. :param tag_name: the name of the tag to retrieve """ uid = current_user.get_id() tag_retrieved = tags_api.get_tag_of_user(uid, tag_name) tag = TagRepresenation(tag_retrieved) return tag.marshal() def delete(self, tag_name): """Delete a tag. Checks if the tag is attached to records. If True, the tag is attached and then is deleted. :param tag_name: the name of the tag to delete """ uid = current_user.get_id() tags_api.delete_tag_from_user(uid, tag_name) return "", 204 @require_header('Content-Type', 'application/json') def patch(self, tag_name): """Update a tag. The attributes that can be updated are: - group name - group access rights - show_in_description :param tag_name: the name of the tag to update """ json_data = request.get_json() v = RESTValidator(tag_update_schema) if v.validate(json_data) is False: raise TagValidationError( error_msg="Validation for tag update failed", status_code=400, error_list=v.get_errors()) uid = current_user.get_id() tag_retrieved = tags_api.update_tag_of_user(uid, tag_name, json_data) tag = TagRepresenation(tag_retrieved) return tag.marshal(), 201 def post(self, tag_name): """post.""" abort(405) def options(self, tag_name): """options.""" abort(405) def put(self, tag_name): """put.""" abort(405) def head(self, tag_name): """head.""" abort(405)