def put(self, org): """Update a organization given its identifier""" if org.deleted: api.abort(410, "Organization has been deleted") EditOrganizationPermission(org).test() form = api.validate(OrganizationForm, org) return form.save()
def put(self, org): '''Update a organization given its identifier''' if org.deleted: api.abort(410, 'Organization has been deleted') EditOrganizationPermission(org).test() form = api.validate(OrganizationForm, org) return form.save()
def put(self, reuse): '''Update a given reuse''' if reuse.deleted: api.abort(410, 'This reuse has been deleted') ReuseEditPermission(reuse).test() form = api.validate(ReuseForm, reuse) return form.save()
def put(self, dataset): '''Update a dataset given its identifier''' if dataset.deleted: api.abort(410, 'Dataset has been deleted') DatasetEditPermission(dataset).test() form = api.validate(DatasetForm, dataset) return form.save()
def delete(self, org): """Delete a organization given its identifier""" if org.deleted: api.abort(410, "Organization has been deleted") EditOrganizationPermission(org).test() org.deleted = datetime.now() org.save() return "", 204
def put(self, reuse): '''Update a given reuse''' request_deleted = request.json.get('deleted', True) if reuse.deleted and request_deleted is not None: api.abort(410, 'This reuse has been deleted') ReuseEditPermission(reuse).test() form = api.validate(ReuseForm, reuse) return form.save()
def delete(self, dataset): '''Delete a dataset given its identifier''' if dataset.deleted: api.abort(410, 'Dataset has been deleted') DatasetEditPermission(dataset).test() dataset.deleted = datetime.now() dataset.save() return '', 204
def put(self): '''Set the homepage reuses editorial selection''' if not isinstance(request.json, list): api.abort(400, 'Expect a list of reuse IDs') ids = [ObjectId(id) for id in request.json] current_site.settings.home_reuses = Reuse.objects.bulk_list(ids) current_site.save() return current_site.settings.home_reuses
def delete(self, reuse): '''Delete a given reuse''' if reuse.deleted: api.abort(410, 'This reuse has been deleted') ReuseEditPermission(reuse).test() reuse.deleted = datetime.now() reuse.save() return '', 204
def get(self, user): '''Get a user given its identifier''' if current_user.is_anonymous or not current_user.sysadmin: if not user.active: api.abort(410, 'User is not active') if user.deleted: api.abort(410, 'User has been deleted') return user
def delete(self, org): '''Delete a organization given its identifier''' if org.deleted: api.abort(410, 'Organization has been deleted') EditOrganizationPermission(org).test() org.deleted = datetime.now() org.save() return '', 204
def put(self): '''Set the homepage datasets editorial selection''' if not isinstance(request.json, list): api.abort(400, 'Expect a list of dataset IDs') ids = [ObjectId(id) for id in request.json] Site.objects(id=current_site.id).update(set__settings__home_datasets=ids) current_site.reload() return current_site.settings.home_datasets
def put(self, dataset): '''Update a dataset given its identifier''' request_deleted = request.json.get('deleted', True) if dataset.deleted and request_deleted is not None: api.abort(410, 'Dataset has been deleted') DatasetEditPermission(dataset).test() dataset.last_modified = datetime.now() form = api.validate(DatasetForm, dataset) return form.save()
def delete(self, user): '''Delete a user given its identifier''' if user.deleted: api.abort(410, 'User has already been deleted') if user == current_user._get_current_object(): api.abort(403, 'You cannot delete yourself with this API. ' + 'Use the "me" API instead.') user.mark_as_deleted() return '', 204
def delete(self, org, user): '''Delete member from an organization''' EditOrganizationPermission(org).test() member = org.member(user) if member: Organization.objects(id=org.id).update_one(pull__members=member) return '', 204 else: api.abort(404)
def put(self): '''Set the homepage datasets editorial selection''' if not isinstance(request.json, list): api.abort(400, 'Expect a list of dataset IDs') ids = [ObjectId(id) for id in request.json] Site.objects(id=current_site.id).update( set__settings__home_datasets=ids) current_site.reload() return current_site.settings.home_datasets
def post(self): '''Create a new scheduled job''' if 'crontab' in request.json and 'interval' in request.json: api.abort(400, 'Cannot define both interval and crontab schedule') if 'crontab' in request.json: form = api.validate(CrontabTaskForm) else: form = api.validate(IntervalTaskForm) return form.save(), 201
def delete(self, id, cidx): '''Delete a comment given its index''' discussion = Discussion.objects.get_or_404(id=id) if len(discussion.discussion) <= cidx: api.abort(404, 'Comment does not exist') elif cidx == 0: api.abort(400, 'You cannot delete the first comment of a discussion') discussion.discussion.pop(cidx) discussion.save() return '', 204
def delete(self, org, badge_kind): """Delete a badge for a given organization""" badge = None for badge in org.badges: if badge.kind == badge_kind: break if badge is None: api.abort(404, "Badge does not exists") org.remove_badge(badge) return "", 204
def delete(self, reuse, badge_kind): '''Delete a badge for a given reuse''' badge = None for badge in reuse.badges: if badge.kind == badge_kind: break if badge is None: api.abort(404, 'Badge does not exists') reuse.remove_badge(badge) return '', 204
def delete(self, org, badge_kind): '''Delete a badge for a given organization''' badge = None for badge in org.badges: if badge.kind == badge_kind: break if badge is None: api.abort(404, 'Badge does not exists') org.remove_badge(badge) return '', 204
def delete(self, dataset, badge_kind): '''Delete a badge for a given dataset''' badge = None for badge in dataset.badges: if badge.kind == badge_kind: break if badge is None: api.abort(404, 'Badge does not exists') dataset.remove_badge(badge) return '', 204
def parse_uploaded_image(field): '''Parse an uploaded image and save into a db.ImageField()''' args = image_parser.parse_args() image = args['file'] if image.mimetype not in IMAGES_MIMETYPES: api.abort(400, 'Unsupported image format') bbox = args.get('bbox', None) if bbox: bbox = [int(float(c)) for c in bbox.split(',')] field.save(image, bbox=bbox)
def get(self, dataset, format): if not DatasetEditPermission(dataset).can(): if dataset.private: api.abort(404) elif dataset.deleted: api.abort(410) resource = dataset_to_rdf(dataset) # bypass flask-restplus make_response, since graph_response # is handling the content negociation directly return make_response(*graph_response(resource, format))
def remove(obj, kind): ''' Handle badge removal API - Returns 404 if the badge for this kind is absent - Returns 204 on success ''' if not obj.get_badge(kind): api.abort(404, 'Badge does not exists') obj.remove_badge(kind) return '', 204
def put(self, dataset): '''Reorder resources''' ResourceEditPermission(dataset).test() data = {'resources': request.json} form = ResourcesListForm.from_json(data, obj=dataset, instance=dataset, csrf_enabled=False) if not form.validate(): api.abort(400, errors=form.errors['resources']) dataset = form.save() return dataset.resources, 200
def get(self, org, format): if org.deleted: api.abort(410) params = multi_to_dict(request.args) page = int(params.get('page', 1)) page_size = int(params.get('page_size', 100)) datasets = Dataset.objects(organization=org).visible().paginate(page, page_size) catalog = build_org_catalog(org, datasets, format=format) # bypass flask-restplus make_response, since graph_response # is handling the content negociation directly return make_response(*graph_response(catalog, format))
def handle_upload(self, dataset): prefix = '/'.join((dataset.slug, datetime.now().strftime('%Y%m%d-%H%M%S'))) infos = handle_upload(storages.resources, prefix) if 'html' in infos['mime']: api.abort(415, 'Incorrect file content type: HTML') infos['title'] = os.path.basename(infos['filename']) infos['checksum'] = Checksum(type='sha1', value=infos.pop('sha1')) infos['filesize'] = infos.pop('size') del infos['filename'] return infos
def handle_upload(self, dataset): prefix = '/'.join( (dataset.slug, datetime.now().strftime('%Y%m%d-%H%M%S'))) infos = handle_upload(storages.resources, prefix) if 'html' in infos['mime']: api.abort(415, 'Incorrect file content type: HTML') infos['title'] = os.path.basename(infos['filename']) infos['checksum'] = Checksum(type='sha1', value=infos.pop('sha1')) infos['filesize'] = infos.pop('size') del infos['filename'] return infos
def put(self, dataset): '''Reorder resources''' ResourceEditPermission(dataset).test() data = {'resources': request.json} form = ResourcesListForm.from_json(data, obj=dataset, instance=dataset, meta={'csrf': False}) if not form.validate(): api.abort(400, errors=form.errors['resources']) dataset = form.save() return dataset.resources, 200
def put(self, org): ''' Update a organization given its identifier :raises PermissionDenied: ''' request_deleted = request.json.get('deleted', True) if org.deleted and request_deleted is not None: api.abort(410, 'Organization has been deleted') EditOrganizationPermission(org).test() form = api.validate(OrganizationForm, org) return form.save()
def post(self): '''Create a new community resource''' form = api.validate(CommunityResourceForm) resource = CommunityResource() form.populate_obj(resource) if not resource.dataset: api.abort(400, errors={'dataset': 'A dataset identifier is required'}) if not resource.organization: resource.owner = current_user._get_current_object() resource.modified = datetime.now() resource.save() return resource, 201
def post(self, reuse): '''Add a dataset to a given reuse''' if 'id' not in request.json: api.abort(400, 'Expect a dataset identifier') try: dataset = Dataset.objects.get_or_404(id=request.json['id']) except Dataset.DoesNotExist: api.abort(404, 'Dataset {0} does not exists'.format(request.json['id'])) if dataset in reuse.datasets: return reuse reuse.datasets.append(dataset) reuse.save() return reuse, 201
def post(self): '''Create a new community resource''' form = api.validate(CommunityResourceForm) resource = CommunityResource() form.populate_obj(resource) if not resource.dataset: api.abort(400, errors={ 'dataset': 'A dataset identifier is required' }) if not resource.organization: resource.owner = current_user._get_current_object() resource.modified = datetime.now() resource.save() return resource, 201
def post(self): '''Create a new community resource''' form = api.validate(CommunityResourceForm) if form._fields.get('filetype').data != 'remote': return 'This endpoint only supports remote community resources', 400 resource = CommunityResource() form.populate_obj(resource) if not resource.dataset: api.abort(400, errors={'dataset': 'A dataset identifier is required'}) if not resource.organization: resource.owner = current_user._get_current_object() resource.modified = datetime.now() resource.save() return resource, 201
def delete(self, user): '''Delete a user given its identifier''' if user.deleted: api.abort(410, 'User has already been deleted') if user == current_user._get_current_object(): api.abort(403, 'You cannot delete yourself with this API. ' + 'Use the "me" API instead.') if user.avatar.filename is not None: storage = storages.avatars storage.delete(user.avatar.filename) storage.delete(user.avatar.original) for key, value in user.avatar.thumbnails.items(): storage.delete(value) user.mark_as_deleted() return '', 204
def extract_infos_from_args(self, args, dataset): prefix = '/'.join( (dataset.slug, datetime.now().strftime('%Y%m%d-%H%M%S'))) storage = storages.resources uploaded_file = args['file'] if 'html' in uploaded_file.content_type: api.abort(415, 'Incorrect file content type: HTML') filename = storage.save(uploaded_file, prefix=prefix) extension = fileutils.extension(filename) uploaded_file.seek(0) sha1 = storages.utils.sha1(uploaded_file) filesize = (os.path.getsize(storage.path(filename)) if storage.root else None) return { 'title': os.path.basename(filename), 'url': storage.url(filename, external=True), 'checksum': Checksum(type='sha1', value=sha1), 'format': extension, 'mime': storages.utils.mime(filename), 'filesize': filesize }
def extract_infos_from_args(self, args, dataset): prefix = '/'.join((dataset.slug, datetime.now().strftime('%Y%m%d-%H%M%S'))) storage = storages.resources uploaded_file = args['file'] if 'html' in uploaded_file.content_type: api.abort(415, 'Incorrect file content type: HTML') filename = storage.save(uploaded_file, prefix=prefix) extension = fileutils.extension(filename) uploaded_file.seek(0) sha1 = storages.utils.sha1(uploaded_file) filesize = (os.path.getsize(storage.path(filename)) if storage.root else None) return { 'title': os.path.basename(filename), 'url': storage.url(filename, external=True), 'checksum': Checksum(type='sha1', value=sha1), 'format': extension, 'mime': storages.utils.mime(filename), 'filesize': filesize }
def get(self): """ The returned payload is a list of OEmbed formatted responses. See: http://oembed.com/ The `references` are composed by a keyword (`kind`) followed by the `id` each of those separated by commas. E.g: dataset-5369992aa3a729239d205183,territory-fr-town-75056-comptes Only datasets and territories are supported for now. """ args = oembeds_parser.parse_args() references = args['references'].split(',') result = [] for item_reference in references: try: item_kind, item_id = item_reference.split('-', 1) except ValueError: return api.abort(400, 'Invalid ID.') if item_kind == 'dataset': try: item = Dataset.objects.get(id=item_id) except (db.ValidationError, Dataset.DoesNotExist): return api.abort(400, 'Unknown dataset ID.') elif (item_kind == 'territory' and current_app.config.get('ACTIVATE_TERRITORIES')): from udata.models import TERRITORY_DATASETS try: country, town, code, kind = item_id.split('-') except ValueError: return api.abort(400, 'Invalid territory ID.') try: geozone = GeoZone.objects.get(code=code) except GeoZone.DoesNotExist: return api.abort(400, 'Unknown territory identifier.') if kind in TERRITORY_DATASETS: item = TERRITORY_DATASETS[kind](geozone) else: return api.abort(400, 'Unknown kind of territory.') else: return api.abort(400, 'Invalid object type.') width = maxwidth = 1000 height = maxheight = 200 html = theme.render( 'embed-dataset.html', **{ 'width': width, 'height': height, 'item': item, 'item_reference': item_reference, }) result.append({ 'type': 'rich', 'version': '1.0', 'html': html, 'width': width, 'height': height, 'maxwidth': maxwidth, 'maxheight': maxheight, }) return output_json(result, 200)
def get(self): """ The returned payload is a list of OEmbed formatted responses. See: http://oembed.com/ The `references` are composed by a keyword (`kind`) followed by the `id` each of those separated by commas. E.g: dataset-5369992aa3a729239d205183,territory-fr-town-75056-comptes Only datasets and territories are supported for now. """ args = oembeds_parser.parse_args() references = args['references'].split(',') result = [] for item_reference in references: try: item_kind, item_id = item_reference.split('-', 1) except ValueError: return api.abort(400, 'Invalid ID.') if item_kind == 'dataset': try: item = Dataset.objects.get(id=item_id) except (db.ValidationError, Dataset.DoesNotExist): return api.abort(400, 'Unknown dataset ID.') elif (item_kind == 'territory' and current_app.config.get('ACTIVATE_TERRITORIES')): from udata.models import TERRITORY_DATASETS try: country, town, code, kind = item_id.split('-') except ValueError: return api.abort(400, 'Invalid territory ID.') try: geozone = GeoZone.objects.get(code=code) except GeoZone.DoesNotExist: return api.abort(400, 'Unknown territory identifier.') if kind in TERRITORY_DATASETS: item = TERRITORY_DATASETS[kind](geozone) else: return api.abort(400, 'Unknown kind of territory.') else: return api.abort(400, 'Invalid object type.') width = maxwidth = 1000 height = maxheight = 200 html = theme.render('embed-dataset.html', **{ 'width': width, 'height': height, 'item': item, 'item_reference': item_reference, }) result.append({ 'type': 'rich', 'version': '1.0', 'html': html, 'width': width, 'height': height, 'maxwidth': maxwidth, 'maxheight': maxheight, }) return output_json(result, 200)
def get(self): """ An OEmbed compliant API endpoint See: http://oembed.com/ Support datasets and reuses URLs """ args = oembed_parser.parse_args() if args['format'] != 'json': api.abort(501, 'Only JSON format is supported') url = args['url'] # Fix flask not detecting URL with https://domain:443/ if 'https:' in url and ':443/' in url: url = url.replace(':443/', '/') with current_app.test_request_context(url) as ctx: if not ctx.request.endpoint: api.abort(404, 'Unknown URL') endpoint = ctx.request.endpoint.replace('_redirect', '') view_args = ctx.request.view_args if endpoint not in self.ROUTES: api.abort(404, 'Unknown URL') param = self.ROUTES[endpoint] item = view_args[param] if isinstance(item, Exception): raise item width = maxwidth = 1000 height = maxheight = 200 params = { 'width': width, 'height': height, 'item': item, 'type': param } params[param] = item html = theme.render('oembed.html', **params) return { 'type': 'rich', 'version': '1.0', 'html': html, 'width': width, 'height': height, 'maxwidth': maxwidth, 'maxheight': maxheight, }
def post(self, id): '''Follow an user given its ID''' if id == str(current_user.id): api.abort(403, "You can't follow yourself") return super(FollowUserAPI, self).post(id)
def get(self): '''List all my reuses (including private ones)''' if not current_user.is_authenticated(): api.abort(401) return list(Reuse.objects(owner=current_user.id))