o
    ).h\                     @   sH  d Z ddlmZmZ ddlmZ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mZ ddlmZ ddlmZ ddlmZ ddlmZmZ d(ddZ dd Z!dd Z"dd Z#dd Z$edg dZ%edg dZ&e&dd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+dS ))zk
Pagination serializers determine the structure of the output that should
be used for paginated responses.
    )	b64decode	b64encode)OrderedDict
namedtuple)parse)InvalidPage)	Paginator)loader)	force_str)gettext_lazy)coreapi
coreschema)NotFound)Response)api_settings)remove_query_paramreplace_query_paramFNc                 C   s4   t | }|dk s|dkr|rt |rt||S |S )z7
    Cast a string to a strictly positive integer.
    r   )int
ValueErrormin)integer_stringstrictcutoffret r   X/var/www/supernova/superenvnew/lib/python3.10/site-packages/rest_framework/pagination.py_positive_int   s   
r   c                 C   s   | | r
| | d S | | S )zD
    Returns 'a' divided by 'b', with any remainder rounded up.
       r   )abr   r   r   _divide_with_ceil"   s   r    c                    s   | dksJ  | ksJ  dkrt td d S d| d | | d  h}| dkr2|d |d |  d krF| d  | d   fddt|D }| dkr[|dd |  d k rk|t|d d |S )	a  
    This utility function determines a list of page numbers to display.
    This gives us a nice contextually relevant set of page numbers.

    For example:
    current=14, final=16 -> [1, None, 13, 14, 15, 16]

    This implementation gives one page to each side of the cursor,
    or two pages to the side when the cursor is at the edge, then
    ensures that any breaks between non-continuous page numbers never
    remove only a single page.

    For an alternative implementation which gives two pages to each side of
    the cursor, eg. as in GitHub issue list pagination, see:

    https://gist.github.com/tomchristie/321140cebb1c4a558b15
    r               c                    s(   g | ]}d |  k r krn n|qS )r   r   ).0idxfinalr   r   
<listcomp>R   s
    z/_get_displayed_page_numbers.<locals>.<listcomp>N)listrangeaddsortedinsertlen)currentr(   includedr   r'   r   _get_displayed_page_numbers,   s&   


r2   c                 C   sB   g }| D ]}|du rt }nt|||||kdd}|| q|S )zg
    Given a list of page numbers and `None` page breaks,
    return a list of `PageLink` objects.
    NFurlnumber	is_activeis_break)
PAGE_BREAKPageLinkappend)page_numbersr0   url_func
page_linkspage_number	page_linkr   r   r   _get_page_links_   s   r@   c                    s   dd  t  fdd| D S )z
    Given an order_by tuple such as `('-created', 'uuid')` reverse the
    ordering and return a new tuple, eg. `('created', '-uuid')`.
    c                 S   s   |  dr| dd  S d|  S )N-r   )
startswith)xr   r   r   invertx   s   z!_reverse_ordering.<locals>.invertc                    s   g | ]} |qS r   r   )r%   itemrD   r   r   r)   {   s    z%_reverse_ordering.<locals>.<listcomp>)tuple)ordering_tupler   rF   r   _reverse_orderings   s   rI   Cursoroffsetreversepositionr9   r3   Tc                   @   sJ   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dS )BasePaginationFNc                 C      t d)Nz(paginate_queryset() must be implemented.NotImplementedErrorselfquerysetrequestviewr   r   r   paginate_queryset      z BasePagination.paginate_querysetc                 C   rP   )Nz-get_paginated_response() must be implemented.rQ   rT   datar   r   r   get_paginated_response   rY   z%BasePagination.get_paginated_responsec                 C   s   |S Nr   rT   schemar   r   r   get_paginated_response_schema      z,BasePagination.get_paginated_response_schemac                 C   rP   )Nz7to_html() must be implemented to display page controls.rQ   rT   r   r   r   to_html   rY   zBasePagination.to_htmlc                 C   s   |d S )Nresultsr   rZ   r   r   r   get_results   rY   zBasePagination.get_resultsc                 C   s   t d usJ dg S )N6coreapi must be installed to use `get_schema_fields()`)r   rT   rW   r   r   r   get_schema_fields   s   z BasePagination.get_schema_fieldsc                 C   s   g S r]   r   rg   r   r   r   get_schema_operation_parameters   ra   z.BasePagination.get_schema_operation_parametersr]   )__name__
__module____qualname__display_page_controlsrX   r\   r`   rc   re   rh   ri   r   r   r   r   rO      s    
rO   c                   @   s   e Zd ZdZejZeZdZ	e
dZdZe
dZdZdZdZe
dZdd	d
Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZdS ) PageNumberPaginationz
    A simple page number based style that supports page numbers as
    query parameters. For example:

    http://api.example.org/accounts/?page=4
    http://api.example.org/accounts/?page=4&page_size=100
    pagez.A page number within the paginated result set.N%Number of results to return per page.)last&rest_framework/pagination/numbers.htmlzInvalid page.c           	   
   C   s   |  |}|s	dS | ||}| ||}z||| _W n ty7 } z| jj|t|d}t|d}~ww |j	dkrE| j
durEd| _|| _t| jS )z
        Paginate a queryset if required, either returning a
        page object, or `None` if pagination is not configured for this view.
        N)r>   messager   T)get_page_sizedjango_paginator_classget_page_numberro   r   invalid_page_messageformatstrr   	num_pagestemplaterm   rV   r*   )	rT   rU   rV   rW   	page_size	paginatorr>   excmsgr   r   r   rX      s$   

z&PageNumberPagination.paginate_querysetc                 C   s$   |j | jd}|| jv r|j}|S Nr   )query_paramsgetpage_query_paramlast_page_stringsrz   )rT   rV   r}   r>   r   r   r   rv      s   
z$PageNumberPagination.get_page_numberc                 C   s2   t td| jjjfd|  fd|  fd|fgS Ncountnextpreviousrd   )r   r   ro   r}   r   get_next_linkget_previous_linkrZ   r   r   r   r\      s   

z+PageNumberPagination.get_paginated_responsec              	   C   sB   ddddddddj | jd	d
ddddj | jd	d
|ddS )Nobjectinteger{   typeexamplestringTuriz5http://api.example.org/accounts/?{page_query_param}=4)r   r   nullablerx   r   z5http://api.example.org/accounts/?{page_query_param}=2r   r   r   rd   r   
properties)rx   r   r^   r   r   r   r`      s*   z2PageNumberPagination.get_paginated_response_schemac              	   C   B   | j rzt|j| j  d| jdW S  ttfy   Y | jS w | jS NT)r   r   page_size_query_paramr   r   max_page_sizeKeyErrorr   r|   rT   rV   r   r   r   rt        
z"PageNumberPagination.get_page_sizec                 C   s0   | j  sd S | j }| j  }t|| j|S r]   )ro   has_nextrV   build_absolute_urinext_page_numberr   r   rT   r4   r>   r   r   r   r     s
   


z"PageNumberPagination.get_next_linkc                 C   sD   | j  sd S | j }| j  }|dkrt|| jS t|| j|S r   )ro   has_previousrV   r   previous_page_numberr   r   r   r   r   r   r   r     s   


z&PageNumberPagination.get_previous_linkc                    sT   j    fdd}jj}jjj}t||}t|||} 	 |dS )Nc                    s"   | dkr
t  jS t j| S r   )r   r   r   )r>   base_urlrT   r   r   page_number_to_url"  s   zAPageNumberPagination.get_html_context.<locals>.page_number_to_urlprevious_urlnext_urlr=   )
rV   r   ro   r5   r}   rz   r2   r@   r   r   )rT   r   r0   r(   r;   r=   r   r   r   get_html_context  s   


z%PageNumberPagination.get_html_contextc                 C      t | j}|  }||S r]   r	   get_templater{   r   renderrT   r{   contextr   r   r   rc   3     
zPageNumberPagination.to_htmlc              
   C   s~   t d usJ dtd usJ dt j| jddtjdt| jddg}| jd ur=|t j| jddtjdt| j	dd |S )	Nrf   9coreschema must be installed to use `get_schema_fields()`FqueryPagetitledescriptionnamerequiredlocationr_   	Page size)
r   r   Fieldr   Integerr
   page_query_descriptionr   r:   page_size_query_descriptionrT   rW   fieldsr   r   r   rh   8  2   
z&PageNumberPagination.get_schema_fieldsc                 C   sN   | j ddt| jddidg}| jd ur%|| jddt| jddid |S NFr   r   r   r   r   inr   r_   )r   r
   r   r   r:   r   rT   rW   
parametersr   r   r   ri   T  &   
z4PageNumberPagination.get_schema_operation_parametersr]   )rj   rk   rl   __doc__r   	PAGE_SIZEr|   DjangoPaginatorru   r   _r   r   r   r   r   r{   rw   rX   rv   r\   r`   rt   r   r   r   rc   rh   ri   r   r   r   r   rn      s.    	
	rn   c                   @   s   e Zd ZdZejZdZedZ	dZ
edZdZdZd dd	Zd
d Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZdS )!LimitOffsetPaginationz
    A limit/offset based style. For example:

    http://api.example.org/accounts/?limit=100
    http://api.example.org/accounts/?offset=400&limit=100
    limitrp   rL   z3The initial index from which to return the results.Nrr   c                 C   s   |  || _| jd u rd S | || _| || _|| _| j| jkr*| jd ur*d| _| jdks5| j| jkr7g S t	|| j| j| j  S )NTr   )
	get_limitr   	get_countr   
get_offsetrL   rV   r{   rm   r*   rS   r   r   r   rX   ~  s   
z'LimitOffsetPagination.paginate_querysetc                 C   s.   t td| jfd|  fd|  fd|fgS r   )r   r   r   r   r   rZ   r   r   r   r\     s   

z,LimitOffsetPagination.get_paginated_responsec              
   C   sJ   ddddddddj | j| jd	d
ddddj | j| jd	d
|ddS )Nr   r   r   r   r   Tr   zEhttp://api.example.org/accounts/?{offset_param}=400&{limit_param}=100)offset_paramlimit_paramr   zEhttp://api.example.org/accounts/?{offset_param}=200&{limit_param}=100r   r   )rx   offset_query_paramlimit_query_paramr^   r   r   r   r`     s*   z3LimitOffsetPagination.get_paginated_response_schemac              	   C   r   r   )r   r   r   	max_limitr   r   default_limitr   r   r   r   r     r   zLimitOffsetPagination.get_limitc              	   C   s,   z	t |j| j W S  ttfy   Y dS w Nr   )r   r   r   r   r   r   r   r   r   r     s   
z LimitOffsetPagination.get_offsetc                 C   sJ   | j | j | jkrd S | j }t|| j| j}| j | j }t|| j|S r]   )rL   r   r   rV   r   r   r   r   rT   r4   rL   r   r   r   r     s   
z#LimitOffsetPagination.get_next_linkc                 C   s^   | j dkrd S | j }t|| j| j}| j | j dkr"t|| jS | j | j }t|| j|S r   )rL   rV   r   r   r   r   r   r   r   r   r   r   r     s   

z'LimitOffsetPagination.get_previous_linkc                    s   j   jr(tjjd tjj jtjj }t|d}ndd}|kr2| fdd}t|}t||}	 
 |dS )Nr   c                    s6   | dkr
t  jS j|  j  }t j|S r   )r   r   rL   r   r   )r>   rL   r   r0   rT   r   r   r     s   zBLimitOffsetPagination.get_html_context.<locals>.page_number_to_urlr   )rV   r   r   r    rL   r   maxr2   r@   r   r   )rT   r(   r   r;   r=   r   r   r   r     s&   

z&LimitOffsetPagination.get_html_contextc                 C   r   r]   r   r   r   r   r   rc     r   zLimitOffsetPagination.to_htmlc              	   C   s*   z|  W S  ttfy   t| Y S w )zZ
        Determine an object count, supporting either querysets or regular lists.
        )r   AttributeError	TypeErrorr/   )rT   rU   r   r   r   r     s
   
zLimitOffsetPagination.get_countc              	   C   sh   t d usJ dtd usJ dt j| jddtjdt| jddt j| jddtjdt| jddgS )	Nrf   r   Fr   Limitr   r   Offset)	r   r   r   r   r   r
   limit_query_descriptionr   offset_query_descriptionrg   r   r   r   rh     s*   	z'LimitOffsetPagination.get_schema_fieldsc                 C   s<   | j ddt| jddid| jddt| jddidg}|S r   )r   r
   r   r   r   r   r   r   r   ri   )  s    
z5LimitOffsetPagination.get_schema_operation_parametersr]   )rj   rk   rl   r   r   r   r   r   r   r   r   r   r   r{   rX   r\   r`   r   r   r   r   r   rc   r   rh   ri   r   r   r   r   r   o  s*    

(	r   c                   @   s   e Zd ZdZdZedZejZ	edZ
dZdZdZedZdZd	Zd&d
dZdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% ZdS )'CursorPaginationz
    The cursor pagination implementation is necessarily complex.
    For an overview of the position/offset style we use, see this post:
    https://cra.mr/2011/03/08/building-cursors-for-the-disqus-api
    cursorzThe pagination cursor value.zInvalid cursorz-createdz0rest_framework/pagination/previous_and_next.htmlNrp   i  c                 C   s  |  || _| jsd S | | _| |||| _| || _| jd u r)d\}}}n| j\}}}|r:|jt	| j }n|j| j }|d urn| jd }|
d}|d}	| jj|kr`|	d |i}
n|	d |i}
|jd
i |
}t|||| j d  }t|d | j | _t|t| jkrd}| |d | j}nd	}d }|rtt| j| _|d up|dk| _|| _| jr|| _| jr|| _n|| _|d up|dk| _| jr|| _| jr|| _| js| jr| jd urd| _| jS )N)r   FNr   rA   __lt__gtr   TFr   )rt   r|   r   r   get_orderingorderingdecode_cursorr   order_byrI   rB   lstriprM   filterr*   ro   r/   _get_position_from_instancereversedr   r   next_positionprevious_positionr{   rm   )rT   rU   rV   rW   rL   rM   current_positionorderis_reversed
order_attrkwargsrd   has_following_positionfollowing_positionr   r   r   rX   ]  sZ   




z"CursorPagination.paginate_querysetc              	   C   r   r   r   r   r   r   r   rt     r   zCursorPagination.get_page_sizec                 C   s   | j sd S | jr | jr | jjr | jjdkr | | jd | j}n| j}d}d}t| jD ]}| || j}||kr=d} n|}|d7 }q,| jrf|sf| j	sR| j
}d }n| jjr\d}| j}n
| jj| j
 }| j}| jsl| j}t|d|d}| |S )Nr   r   FTr   rK   )r   ro   r   rM   rL   r   r   r   r   r   r|   r   rJ   encode_cursorrT   comparerL   has_item_with_unique_positionrE   rN   r   r   r   r   r     s6    


zCursorPagination.get_next_linkc                 C   s   | j sd S | jr | jr | jjs | jjdkr | | jd | j}n| j}d}d}| jD ]}| || j}||kr;d} n|}|d7 }q*| jrd|sd| jsP| j	}d }n| jjr_| jj| j	 }| j
}nd}| j
}| jsj| j}t|d|d}| |S )Nr   FTr   rK   )r   ro   r   rM   rL   r   r   r   r   r|   r   rJ   r   r   r   r   r   r     s6    



z"CursorPagination.get_previous_linkc                 C   s   dd t |dg D }|r)|d }| }||||}|dus(J dj|jdn| j}|dus4J dd	|vs<J d
t|tttfsOJ djt	|jdt|trW|fS t|S )zV
        Return a tuple of strings, that may be used in an `order_by` method.
        c                 S   s   g | ]	}t |d r|qS )r   )hasattr)r%   
filter_clsr   r   r   r)   $  s    z1CursorPagination.get_ordering.<locals>.<listcomp>filter_backendsr   NzRUsing cursor pagination, but filter class {filter_cls} returned a `None` ordering.)r   zXUsing cursor pagination, but no ordering attribute was declared on the pagination class.__zCursor pagination does not support double underscore lookups for orderings. Orderings should be an unchanging, unique or nearly-unique field on the model, such as "-created" or "pk".z:Invalid ordering. Expected string or tuple, but got {type})r   )
getattrr   rx   rj   r   
isinstancery   r*   rG   r   )rT   rV   rU   rW   ordering_filtersr   filter_instancer   r   r   r   r      s8   

	


zCursorPagination.get_orderingc              	   C   s   |j | j}|du rdS z;t|dd}tj|dd}|ddgd }t|| j	d}|d	dgd }t
t|}|d
dgd }W n ttfyV   t| jw t|||dS )zL
        Given a request with a cursor, return a `Cursor` instance.
        NasciiT)keep_blank_valueso0r   )r   rprK   )r   r   cursor_query_paramr   encodedecoder   parse_qsr   offset_cutoffboolr   r   r   r   invalid_cursor_messagerJ   )rT   rV   encodedquerystringtokensrL   rM   rN   r   r   r   r   M  s   
zCursorPagination.decode_cursorc                 C   sp   i }|j dkrt|j |d< |jrd|d< |jdur|j|d< tj|dd}t|d	d	}t	| j
| j|S )
zM
        Given a Cursor instance, return an url with encoded cursor.
        r   r	  1r  Nr  T)doseqr  )rL   ry   rM   rN   r   	urlencoder   r  r  r   r   r  )rT   r   r  r  r  r   r   r   r   f  s   


zCursorPagination.encode_cursorc                 C   s:   |d  d}t|tr|| }t|S t||}t|S )Nr   rA   )r   r  dictr  ry   )rT   instancer   
field_nameattrr   r   r   r   v  s   

z,CursorPagination._get_position_from_instancec                 C   s&   t td|  fd|  fd|fgS )Nr   r   rd   )r   r   r   r   rZ   r   r   r   r\   ~  s
   

z'CursorPagination.get_paginated_responsec                 C   s   ddddddd|ddS )Nr   r   T)r   r   )r   r   rd   r   r   r^   r   r   r   r`     s   z.CursorPagination.get_paginated_response_schemac                 C   s   |   |  dS )N)r   r   )r   r   rb   r   r   r   r     s   z!CursorPagination.get_html_contextc                 C   r   r]   r   r   r   r   r   rc     r   zCursorPagination.to_htmlc              
   C   s~   t d usJ dtd usJ dt j| jddtjdt| jddg}| jd ur=|t j| jddtj	dt| j
dd |S )	Nrf   r   Fr   rJ   r   r   r   )r   r   r   r  Stringr
   cursor_query_descriptionr   r:   r   r   r   r   r   r   rh     r   z"CursorPagination.get_schema_fieldsc                 C   sN   | j ddt| jddidg}| jd ur%|| jddt| jddid |S )NFr   r   r   r   r   )r  r
   r  r   r:   r   r   r   r   r   ri     r   z0CursorPagination.get_schema_operation_parametersr]   )rj   rk   rl   r   r  r   r  r   r   r|   r  r   r{   r   r   r   r  rX   rt   r   r   r   r   r   r   r\   r`   r   rc   rh   ri   r   r   r   r   r   A  s4    
L55-r   )FN),r   base64r   r   collectionsr   r   urllibr   django.core.paginatorr   r   r   django.templater	   django.utils.encodingr
   django.utils.translationr   r   rest_framework.compatr   r   rest_framework.exceptionsr   rest_framework.responser   rest_framework.settingsr   rest_framework.utils.urlsr   r   r   r    r2   r@   rI   rJ   r9   r8   rO   rn   r   r   r   r   r   r   <module>   s8    

3 R S