o
    ).hD                     @   s   d Z ddlZddlmZ ddlmZ ddlmZ ddlm	Z	 ddlm
Z ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZ ddlmZ G dd dZG dd dZG dd deZG dd deZG dd deZ
G dd deZdS )z
Parsers are used to parse the content of incoming HTTP requests.

They give us a generic way of being able to handle various media types
on the request, such as form content or json encoded data.
    N)settings)StopFutureHandlers)	QueryDict)	ChunkIter)MultiPartParser)MultiPartParserError)	renderers)parse_header_parameters)
ParseError)api_settings)jsonc                   @   s   e Zd Zdd ZdS )DataAndFilesc                 C   s   || _ || _d S )N)datafiles)selfr   r    r   U/var/www/supernova/superenvnew/lib/python3.10/site-packages/rest_framework/parsers.py__init__   s   
zDataAndFiles.__init__N)__name__
__module____qualname__r   r   r   r   r   r      s    r   c                   @   s   e Zd ZdZdZdddZdS )
BaseParserz
    All parsers should extend `BaseParser`, specifying a `media_type`
    attribute, and overriding the `.parse()` method.
    Nc                 C   s   t d)z
        Given a stream to read from, return the parsed representation.
        Should return parsed data, or a `DataAndFiles` object consisting of the
        parsed data and files.
        z.parse() must be overridden.)NotImplementedError)r   stream
media_typeparser_contextr   r   r   parse%   s   zBaseParser.parseNNr   r   r   __doc__r   r   r   r   r   r   r      s    r   c                   @   s*   e Zd ZdZdZejZej	Z
dddZdS )
JSONParserz&
    Parses JSON-serialized data.
    zapplication/jsonNc              
   C   sn   |pi }| dtj}zt||}| jrtjnd}tj||dW S  t	y6 } zt
dt| d}~ww )zX
        Parses the incoming bytestream as JSON and returns the resulting data.
        encodingN)parse_constantzJSON parse error - %s)getr   DEFAULT_CHARSETcodecs	getreaderstrictr   strict_constantload
ValueErrorr
   str)r   r   r   r   r!   decoded_streamr"   excr   r   r   r   6   s   zJSONParser.parser   )r   r   r   r   r   r   JSONRendererrenderer_classr   STRICT_JSONr'   r   r   r   r   r   r    .   s    r    c                   @      e Zd ZdZdZdddZdS )
FormParserz
    Parser for form data.
    z!application/x-www-form-urlencodedNc                 C   s&   |pi }| dtj}t| |dS )zt
        Parses the incoming bytestream as a URL encoded form,
        and returns the resulting QueryDict.
        r!   )r!   )r#   r   r$   r   read)r   r   r   r   r!   r   r   r   r   K   s   zFormParser.parser   r   r   r   r   r   r2   E       r2   c                   @   r1   )r   zF
    Parser for multipart form data, which may include file data.
    zmultipart/form-dataNc              
   C   s   |pi }|d }| dtj}|j }||d< |j}zt||||}| \}	}
t|	|
W S  t	yB } zt
dt| d}~ww )a	  
        Parses the incoming bytestream as a multipart encoded form,
        and returns a DataAndFiles object.

        `.data` will be a `QueryDict` containing all the form parameters.
        `.files` will be a `QueryDict` containing all the form files.
        requestr!   CONTENT_TYPEzMultipart form parse error - %sN)r#   r   r$   METAcopyupload_handlersDjangoMultiPartParserr   r   r   r
   r+   )r   r   r   r   r5   r!   metar9   parserr   r   r-   r   r   r   r   [   s   
zMultiPartParser.parser   r   r   r   r   r   r   U   r4   r   c                   @   s0   e Zd ZdZdZdddZdddZd	d
 ZdS )FileUploadParserz&
    Parser for file upload data.
    z*/*zFFileUpload parse error - none of upload handlers can handle the streamz`Missing filename. Request should include a Content-Disposition header with a filename parameter.)	unhandledno_filenameNc              	   C   s  |pi }|d }| dtj}|j}|j}| |||}|s%t| jd | d| dd}	zt| d| dd	}
W n t	t
fyJ   d
}
Y nw |D ]}||||
d
|}|d
urgti d|d i  S qMdd |D }tdg| }t||}d	gt| }t|D ]!\}}z|d
||	|
| W q ty   |d
|d  }Y  nw |D ]%}t|D ]\}}t|}|||| }||  |7  < |d
u r nqqt|D ]\}}||| }|d
urti d|i  S qt| jd )a  
        Treats the incoming bytestream as a raw file upload and returns
        a `DataAndFiles` object.

        `.data` will be None (we expect request body to be a file content).
        `.files` will be a `QueryDict` containing one 'file' element.
        r5   r!   r?   HTTP_CONTENT_TYPEr6    HTTP_CONTENT_LENGTHCONTENT_LENGTHr   Nfile   c                 S   s   g | ]}|j r|j qS r   )
chunk_size).0xr   r   r   
<listcomp>   s    z*FileUploadParser.parse.<locals>.<listcomp>ir>   )r#   r   r$   r7   r9   get_filenamer
   errorsintr*   	TypeErrorhandle_raw_inputr   minr   len	enumeratenew_filer   receive_data_chunkfile_complete)r   r   r   r   r5   r!   r;   r9   filenamecontent_typecontent_lengthhandlerresultpossible_sizesrF   chunkscountersindexchunkchunk_lengthfile_objr   r   r   r   |   sp   




zFileUploadParser.parsec              
   C   st   z|d d W S  t y   Y nw z|d j}t|d \}}d|v r(|d W S |d W S  tt tfy9   Y dS w )z
        Detects the uploaded file name. First searches a 'filename' url kwarg.
        Then tries to parse Content-Disposition header.
        kwargsrU   r5   HTTP_CONTENT_DISPOSITIONz	filename*N)KeyErrorr7   r	   AttributeErrorr*   )r   r   r   r   r;   dispositionparamsr   r   r   rJ      s   


zFileUploadParser.get_filenamer   )r   r   r   r   r   rK   r   rJ   r   r   r   r   r=   r   s    
Cr=   )r   r%   django.confr   django.core.files.uploadhandlerr   django.httpr   django.http.multipartparserr   r   r:   r   rest_frameworkr   rest_framework.compatr	   rest_framework.exceptionsr
   rest_framework.settingsr   rest_framework.utilsr   r   r   r    r2   r=   r   r   r   r   <module>   s&    