def validation(self, file, sizes): """ Validates an image based on predefined paramters of type and size. """ if file.size > FILE_SIZE_LIMIT: raise UnsupportedMediaType( file.content_type, detail="'img' must be less than %sMB" % settings.FILE_MB_LIMIT, ) if file.content_type not in FILE_TYPES: raise UnsupportedMediaType( file.content_type, detail="'img' must be of type(s) %s" % str(FILE_TYPES), ) if sizes: if len(sizes) < 1: raise ParseError(detail="'sizes' must have at least one size.") if not isinstance(sizes, list): raise ParseError( detail="'sizes' must be a json-parsable array.") for size in sizes: if not isinstance(size, int): raise ParseError( detail="'sizes' must be an array of integers.") return True
def patch(self, request, course_id): """ Implement a handler for the PATCH method. """ if request.content_type != MergePatchParser.media_type: raise UnsupportedMediaType(request.content_type) kwargs = self._get_request_kwargs(course_id) form = CourseDiscussionSettingsForm(kwargs, request_user=request.user) if not form.is_valid(): raise ValidationError(form.errors) course = form.cleaned_data['course'] course_key = form.cleaned_data['course_key'] discussion_settings = CourseDiscussionSettings.get(course_key) serializer = DiscussionSettingsSerializer( discussion_settings, context={ 'course': course, 'settings': discussion_settings, }, data=request.data, partial=True, ) if not serializer.is_valid(): raise ValidationError(serializer.errors) serializer.save() return Response(status=status.HTTP_204_NO_CONTENT)
def post(self, request): self.check_permissions(request) if 'rssFeed' not in request.data: raise UnsupportedMediaType('RSS Feed missing') rss_feed_url = request.data.get('rssFeed') try: response = requests.get(rss_feed_url) if response.status_code is not 200: raise ParseError('We couldn\'t access your RSS feed. Make sure that it is hosted somewhere that allows'\ 'third parties to download it (CORS is not enabled). A common problem is that the link '\ 'you uploaded is hosted on WordPress instead of your Podcast Host.') rss_feed_parser = pyPodcastParser.Podcast.Podcast(response.content) verify_podcast_with_listen_notes(rss_feed_parser) confirmation_code = PodcastConfirmation.objects.create( rss_feed_url=rss_feed_url, owner=request.user).rss_confirmation_code email = rss_feed_parser.owner_email send_podcast_confirmation_code_email(email, confirmation_code) return Response(status=status.HTTP_201_CREATED) except AttributeError: raise ParseError( 'Could not read RSS. Please ensure it is valid and that it contains an email field' ) except SMTPException: raise ParseError( 'Failed to send out the confirmation email, please ensure the one listed in your rss feed ' 'is valid')
def upload_examples(self, request, **kwargs): try: repository = get_object_or_404(Repository, pk=request.data.get("repository")) except DjangoValidationError: raise PermissionDenied() user_authorization = repository.get_user_authorization(request.user) if not user_authorization.can_write: raise PermissionDenied() f = request.FILES.get("file") try: json_data = json.loads(f.read().decode()) except json.decoder.JSONDecodeError: raise UnsupportedMediaType("json") count_added = 0 not_added = [] for data in json_data: response_data = data response_data["repository"] = request.data.get("repository") response_data["repository_version"] = request.data.get( "repository_version") serializer = RepositoryExampleSerializer( data=response_data, context={"request": request}) if serializer.is_valid(): serializer.save() count_added += 1 else: not_added.append(data) return Response({"added": count_added, "not_added": not_added})
def wrapper(*args, **kwargs) -> Response: if len(args) == 1: request = args[0] elif len(args) == 2: # in case of class method , `self` is first arg request = args[1] else: raise TypeError( "Invalid func arguments, only kwargs after request param") if request.method in methods: try: if isinstance(request.data, QueryDict): """ in case of QueryDict, the request is under form-data format hence it will be normalized into an array example inputs: key: value1 key: value2 -> request.data["key"] = ["value1", "value2"] calling request.data.dict() will omit others data validated_input = input_model(**request.data.dict()) for simple use case, we only allow json content type """ raise UnsupportedMediaType("form-data") else: validated_input = input_model(**request.data) kwargs[arg_name] = validated_input except ValidationError as e: return Response({"errors": errors_wrapper(e.errors())}, status=400) return f(*args, **kwargs)
def patch(self, request, course_id): """ Implement a handler for the PATCH method. """ if request.content_type != MergePatchParser.media_type: raise UnsupportedMediaType(request.content_type) kwargs = self._get_request_kwargs(course_id) form = CourseDiscussionSettingsForm(kwargs, request_user=request.user) if not form.is_valid(): raise ValidationError(form.errors) course = form.cleaned_data['course'] course_key = form.cleaned_data['course_key'] discussion_settings = get_course_discussion_settings(course_key) serializer = DiscussionSettingsSerializer( data=request.data, partial=True, course=course, discussion_settings=discussion_settings) if not serializer.is_valid(): raise ValidationError(serializer.errors) settings_to_change = serializer.validated_data['settings_to_change'] try: discussion_settings = set_course_discussion_settings( course_key, **settings_to_change) except ValueError as e: raise ValidationError(text_type(e)) return Response(status=status.HTTP_204_NO_CONTENT)
def _check_type(self, op_type, item): allowed_types = self.allowed_types.get(item, None) if allowed_types is None: raise NotFound() if isinstance(allowed_types, (list, tuple)) and op_type not in allowed_types: raise UnsupportedMediaType(media_type=op_type)
def parse(self, stream, media_type=None, parser_context=None): """ Parse the request, returning a DataAndFiles object with the data dict left empty, and the body of the request placed in files['file']. """ upload_media_types = getattr(parser_context['view'], 'upload_media_types', set()) if media_type not in upload_media_types: raise UnsupportedMediaType(media_type) filename = self.get_filename(stream, media_type, parser_context) if media_type in self.file_extensions: fileparts = filename.rsplit('.', 1) if len(fileparts) < 2: ext = '' else: ext = '.{}'.format(fileparts[1]) if ext.lower() not in self.file_extensions[media_type]: errmsg = ( u'File extension does not match requested Content-type. ' u'Filename: "{filename}", Content-type: "{contenttype}"') raise ParseError( errmsg.format(filename=filename, contenttype=media_type)) return super(TypedFileUploadParser, self).parse(stream, media_type, parser_context)
def parse_proxy_response(self, response): """ Modified version of rest_framework.request.Request._parse(self) """ parsers = self.get_parsers() stream = StringIO(response._content) content_type = response.headers.get('content-type', None) if stream is None or content_type is None: return {} parser = None for item in parsers: if media_type_matches(item.media_type, content_type): parser = item if not parser: raise UnsupportedMediaType(content_type) parsed = parser.parse(stream, content_type) # Parser classes may return the raw data, or a # DataAndFiles object. Return only data. try: return parsed.data except AttributeError: return parsed
def partial_update(self, request, comment_id): """ Implements the PATCH method for the instance endpoint as described in the class docstring. """ if request.content_type != MergePatchParser.media_type: raise UnsupportedMediaType(request.content_type) return Response(update_comment(request, comment_id, request.data))
def execute(self, serializer, user, option=None, **extra): # pylint: disable=protected-access tp = self._exec_types.get(self.kind, None) if tp is None: raise UnsupportedMediaType(media_type=self.kind) return serializer._execution( tp, self.get_data_with_options(option, **extra), user, template=self.id, template_option=option )
def execute(self, serializer, user): # pylint: disable=protected-access tp = self._exec_types.get(self.kind, None) if tp is None: raise UnsupportedMediaType(media_type=self.kind) data = self.get_data() data.pop("project", None) vars = data.pop("vars", {}) data.update(vars) return serializer._execution(tp, data, user)
def upload_photo(self, request, **kwargs): # pragma: no cover file = request.FILES.get("file") serializer = UserPhotoSerializer(data=request.data) serializer.is_valid(raise_exception=True) if filetype.is_image(file): user = self.request.user user.photo = file user.save(update_fields=["photo"]) # Update avatar on integrations celery_app.send_task("update_user_photo", args=[user.email, self._get_photo_url(user)]) # Update avatar in all rocket chat registered for authorization in user.authorizations_user.all(): for project in authorization.organization.project.all(): for service_status in project.service_status.filter( service__service_type=Service.SERVICE_TYPE_CHAT): upload_photo_rocket( server_rocket=service_status.service.url, jwt_token=self.request.auth, avatar_url=user.photo.url, ) return Response({"photo": user.photo.url}) try: raise UnsupportedMediaType( filetype.get_type(file.content_type).extension, detail=_( "We accept images only in the formats: .png, .jpeg, .gif"), ) except Exception: raise UnsupportedMediaType( None, detail=_( "We accept images only in the formats: .png, .jpeg, .gif"), )
def wrapper(*args, **kwargs): if len(args) == 1: request = args[0] elif len(args) == 2: # in case of class method , `self` is first arg request = args[1] else: raise TypeError( "Invalid func arguments, only kwargs after request param") try: get_func_args = { arg: kwargs[arg] for arg in inspect.getfullargspec(get_func).args } except KeyError: return try: obj = get_func(**get_func_args) except ValueError as e: raise NotFound(msg or str(e)) obj_passed = False if (pass_to == "request" or "request" in pass_to) and request.method in [ "POST", "PUT", "PATCH", ]: if isinstance(request.data, QueryDict): raise UnsupportedMediaType("form-data") request.data[to_name] = obj obj_passed = True if pass_to == "kwargs" or "kwargs" in pass_to: kwargs[to_name] = obj obj_passed = True if pass_to == "kwargs_data" or "kwargs_data" in pass_to: if "_data" not in kwargs: kwargs["_data"] = request.data.copy() kwargs["_data"][to_name] = obj obj_passed = True if remove and obj_passed: for arg in get_func_args: del kwargs[arg] return f(*args, **kwargs)
def validate(self, attrs): file = attrs.get('file', '') if file: if file.content_type in settings.CONTENT_TYPES: if file.size > settings.MAX_UPLOAD_SIZE: raise NotAcceptable({ 'error': 'Please keep file size under %s KB. Current file size %s KB' % (settings.MAX_UPLOAD_SIZE, file.size) }) else: raise UnsupportedMediaType(file.name) return attrs
def post(self, request): try: file = request.data['file'] if file.content_type == 'image/png' or file.content_type == 'image/jpeg': user = request.user # removing previously saved file user.profile_pic.delete() user.profile_pic = file user.save() return Response(UserSerializer(user).data, status=status.HTTP_202_ACCEPTED) else: raise UnsupportedMediaType(file.content_type) except KeyError: return Response("file missing.", status=status.HTTP_404_NOT_FOUND)
def execute(self, user: User, option: str = None, **extra): # pylint: disable=protected-access tp = self._exec_types.get(self.kind, None) if tp is None: raise UnsupportedMediaType(media_type=self.kind) # nocv client = Client(SERVER_NAME='TEMPLATE') client.force_login(user) url = "/{}/{}/project/{}/execute_{}/".format( getattr(settings, 'API_URL'), getattr(settings, 'VST_API_VERSION'), self.project.id, tp) data = dict(template=self.id, template_option=option, **self.get_data_with_options(option, **extra)) response = client.post(url, data=json.dumps(data), content_type="application/json") return response
def _symlink_workaround_temp_uploaded_file(file_field, check_open_by_mdtraj=True): # TODO: avoid this hack of symlinking the temporary file top_file_faked = file_field.path top_file_real = file_field.file.file.name _, ext = os.path.splitext(top_file_faked) if check_open_by_mdtraj: from mdtraj.formats.registry import _FormatRegistry as reg if ext not in reg.loaders: raise UnsupportedMediaType( ext, "The extension of the uploaded" " topology file is not supported! " "Unsupported media file extensions: %s" % reg.loaders.keys()) os.symlink(top_file_real, top_file_faked) try: yield top_file_faked finally: os.unlink(top_file_faked)
def resizeImage(file, size, filename, downloaded): ''' This function take file and resize parameter and resize the image using pillow. ''' if downloaded: im = file format = im.format else: try: im = Image.open(file) im.verify() except: raise UnsupportedMediaType('Invalid Image type') im = Image.open(file) format = im.format try: width, height = size.split('x') im = im.resize((int(width), int(height)), PIL.Image.ANTIALIAS) except: raise ParseError('Invalid resize value') return createFieldImage(im, filename, format)
def post(self, request): self.check_permissions(request) if 'confirmationCode' not in request.data: raise UnsupportedMediaType('Confirmation code missing!') try: confirmation_code = request.data.get('confirmationCode') confirmation_expired_time = datetime.now() - timedelta( hours=RSS_CODE_EXPIRATION_HOURS) rss_code_confirmation = PodcastConfirmation.objects\ .filter(pending=True, owner=request.user, created_at__gte=confirmation_expired_time)\ .get(rss_confirmation_code=confirmation_code) rss_code_confirmation.pending = False rss_code_confirmation.save() if rss_code_confirmation.created_at < (timezone.now() - timedelta(hours=2)): raise ParseError('Code invalid') else: response = requests.get(rss_code_confirmation.rss_feed_url) feed_data = pyPodcastParser.Podcast.Podcast(response.content) if Podcast.objects.filter(title=feed_data.title).count() > 0: return Response(status=status.HTTP_403_FORBIDDEN) image_url = feed_data.image_link if feed_data.image_link is not None else feed_data.itune_image podcast = Podcast.objects.create( owner=request.user, title=feed_data.title, image_link=image_url, confirmation=rss_code_confirmation) for category in feed_data.itunes_categories: podcast.categories.create(name=category) podcast.save() return Response(PodcastSerializer(podcast).data, status=status.HTTP_200_OK) except AttributeError: raise ParseError( 'Could not read podcast RSS. Please ensure it is valid and resubmit. It should ' 'contain a title, description/summary and image link.') except PodcastConfirmation.DoesNotExist: raise ParseError('Code invalid')
def get_full_mime_type(meta: dict) -> MimeV3Type: mime = meta.get('HTTP_ACCEPT_TYPE', SUMMARY_FORMAT) try: return MimeV3Type(mime) except ValueError: raise UnsupportedMediaType(mime)
def post(self, request, *args, **kwargs): if "file" not in request.FILES or "json" not in request.POST: raise BadRequestError( ERROR_CODES_DETAILS["ftl_missing_file_or_json_in_body"], "ftl_missing_file_or_json_in_body", ) file_obj = request.FILES["file"] if file_obj.size == 0: raise BadRequestError( ERROR_CODES_DETAILS["ftl_file_empty"], "ftl_file_empty", ) mime = guess_mimetype(file_obj, filename=file_obj.name) extension = mimetype_to_ext(mime) if not extension: raise UnsupportedMediaType( mime, ERROR_CODES_DETAILS["ftl_document_type_unsupported"], "ftl_document_type_unsupported", ) payload = json.loads(request.POST["json"]) if "ftl_folder" in payload and payload["ftl_folder"]: try: ftl_folder = get_object_or_404( FTLFolder.objects.filter(org=self.request.user.org), id=payload["ftl_folder"], ) except Http404: raise BadRequestError( ERROR_CODES_DETAILS["ftl_folder_not_found"], "ftl_folder_not_found", ) else: ftl_folder = None ftl_doc = FTLDocument() ftl_doc.ftl_folder = ftl_folder ftl_doc.ftl_user = self.request.user ftl_doc.binary = file_obj ftl_doc.size = file_obj.size ftl_doc.type = mime md5 = hashlib.md5() for data in ftl_doc.binary.chunks(): md5.update(data) ftl_doc.md5 = md5.hexdigest() if "md5" in payload and payload["md5"]: if payload["md5"] != ftl_doc.md5: raise BadRequestError( ERROR_CODES_DETAILS["ftl_document_md5_mismatch"], "ftl_document_md5_mismatch", ) ftl_doc.org = self.request.user.org if "title" in payload and payload["title"]: ftl_doc.title = payload["title"] else: if file_obj.name.lower().endswith(extension): ftl_doc.title = file_obj.name[:-(len(extension))] else: ftl_doc.title = file_obj.name # The actual name of the file doesn't matter because we use a random UUID. On the contrary, the extension # is important. ftl_doc.binary.name = f"document{extension}" if "created" in payload and payload["created"]: ftl_doc.created = payload["created"] if "note" in payload and payload["note"]: ftl_doc.note = payload["note"] if "thumbnail" in request.POST and request.POST["thumbnail"]: try: ftl_doc.thumbnail_binary = ContentFile( _extract_binary_from_data_uri(request.POST["thumbnail"]), "thumb.png", ) except ValueError as e: if ("ignore_thumbnail_generation_error" in payload and not payload["ignore_thumbnail_generation_error"]): raise BadRequestError( ERROR_CODES_DETAILS["ftl_thumbnail_generation_error"], "ftl_thumbnail_generation_error", ) else: pass ftl_doc.save() transaction.on_commit(lambda: apply_ftl_processing.delay( ftl_doc.pid, ftl_doc.org.pk, ftl_doc.ftl_user.pk, force=[FTLPlugins.LANG_DETECTOR_LANGID], )) return Response(self.serializer_class(ftl_doc).data, status=201)
def get_media_type(content_type: str) -> str: for item in settings.MEDIA.items(): # get media types in a list and iterate through each media type if content_type in item[1]["mime_types"]: # find the mime type provided in one of the media types return item[0] # if the media type wasn't found, let the user know that the media type isn't supported raise UnsupportedMediaType(content_type)