U
    8ÄT_Wc  ã                   @   s  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mZ d dlmZmZ G dd„ dƒZG dd„ dƒZG dd„ dƒZG dd„ dƒZG dd„ dƒZG dd„ deeeƒZG dd„ deƒZG dd„ deeƒZG dd„ deeƒZ G dd„ dee ƒZ!G d d!„ d!eeeƒZ"G d"d#„ d#ee"ƒZ#G d$d%„ d%eeeƒZ$G d&d'„ d'ee$ƒZ%G d(d)„ d)eeeeƒZ&G d*d+„ d+ee&ƒZ'G d,d-„ d-e&ƒZ(G d.d/„ d/ee(ƒZ)G d0d1„ d1eeeeeƒZ*G d2d3„ d3ee*ƒZ+d<d6d7„Z,d8d9„ Z-d:d;„ Z.dS )=é    N)Úsettings)ÚImproperlyConfigured)Úmodels)ÚHttp404)Útimezone)Úcached_property)Úgettext)ÚView)ÚBaseDetailViewÚ!SingleObjectTemplateResponseMixin)ÚMultipleObjectMixinÚ#MultipleObjectTemplateResponseMixinc                   @   sH   e Zd ZdZdZdZdd„ Zdd„ Zdd	„ Zd
d„ Z	dd„ Z
dd„ ZdS )Ú	YearMixinz-Mixin for views manipulating year-based data.z%YNc                 C   s   | j S )zv
        Get a year format string in strptime syntax to be used to parse the
        year from url variables.
        )Úyear_format©Úself© r   ú>/tmp/pip-unpacked-wheel-dv63caxw/django/views/generic/dates.pyÚget_year_format   s    zYearMixin.get_year_formatc                 C   sh   | j }|dkrdz| jd }W nF tk
rb   z| jjd }W n  tk
r\   ttdƒƒ‚Y nX Y nX |S )z8Return the year for which this view should display data.NÚyearzNo year specified)r   ÚkwargsÚKeyErrorÚrequestÚGETr   Ú_)r   r   r   r   r   Úget_year   s    zYearMixin.get_yearc                 C   s   t | |ddd�S )zGet the next valid year.Fr   ©Úis_previousÚperiod©Ú_get_next_prev©r   Údater   r   r   Úget_next_year,   s    zYearMixin.get_next_yearc                 C   s   t | |ddd�S )zGet the previous valid year.Tr   r   r   r!   r   r   r   Úget_previous_year0   s    zYearMixin.get_previous_yearc                 C   s>   z|j |jd ddd�W S  tk
r8   ttdƒƒ‚Y nX dS )úŒ
        Return the start date of the next interval.

        The interval is defined by start date <= item date < next start date.
        é   ©r   ÚmonthÚdayúDate out of rangeN)Úreplacer   Ú
ValueErrorr   r   r!   r   r   r   Ú_get_next_year4   s    zYearMixin._get_next_yearc                 C   s   |j ddd�S )ú.Return the start date of the current interval.r&   ©r(   r)   ©r+   r!   r   r   r   Ú_get_current_year?   s    zYearMixin._get_current_year)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r#   r$   r-   r1   r   r   r   r   r      s   r   c                   @   sH   e Zd ZdZdZdZdd„ Zdd„ Zdd	„ Zd
d„ Z	dd„ Z
dd„ ZdS )Ú
MonthMixinz.Mixin for views manipulating month-based data.z%bNc                 C   s   | j S )zx
        Get a month format string in strptime syntax to be used to parse the
        month from url variables.
        )Úmonth_formatr   r   r   r   Úget_month_formatI   s    zMonthMixin.get_month_formatc                 C   sh   | j }|dkrdz| jd }W nF tk
rb   z| jjd }W n  tk
r\   ttdƒƒ‚Y nX Y nX |S )z9Return the month for which this view should display data.Nr(   zNo month specified)r(   r   r   r   r   r   r   )r   r(   r   r   r   Ú	get_monthP   s    zMonthMixin.get_monthc                 C   s   t | |ddd�S )zGet the next valid month.Fr(   r   r   r!   r   r   r   Úget_next_month]   s    zMonthMixin.get_next_monthc                 C   s   t | |ddd�S )zGet the previous valid month.Tr(   r   r   r!   r   r   r   Úget_previous_montha   s    zMonthMixin.get_previous_monthc                 C   s^   |j dkrFz|j|jd ddd�W S  tk
rB   ttdƒƒ‚Y qZX n|j|j d dd�S dS )r%   é   r&   r'   r*   r/   N)r(   r+   r   r,   r   r   r!   r   r   r   Ú_get_next_monthe   s    
zMonthMixin._get_next_monthc                 C   s   |j dd�S )z/Return the start date of the previous interval.r&   )r)   r0   r!   r   r   r   Ú_get_current_months   s    zMonthMixin._get_current_month)r2   r3   r4   r5   r7   r(   r8   r9   r:   r;   r=   r>   r   r   r   r   r6   D   s   r6   c                   @   sH   e Zd ZdZdZdZdd„ Zdd„ Zdd	„ Zd
d„ Z	dd„ Z
dd„ ZdS )ÚDayMixinz,Mixin for views manipulating day-based data.z%dNc                 C   s   | j S )zt
        Get a day format string in strptime syntax to be used to parse the day
        from url variables.
        )Ú
day_formatr   r   r   r   Úget_day_format}   s    zDayMixin.get_day_formatc                 C   sh   | j }|dkrdz| jd }W nF tk
rb   z| jjd }W n  tk
r\   ttdƒƒ‚Y nX Y nX |S )z7Return the day for which this view should display data.Nr)   zNo day specified)r)   r   r   r   r   r   r   )r   r)   r   r   r   Úget_day„   s    zDayMixin.get_dayc                 C   s   t | |ddd�S )zGet the next valid day.Fr)   r   r   r!   r   r   r   Úget_next_day‘   s    zDayMixin.get_next_dayc                 C   s   t | |ddd�S )zGet the previous valid day.Tr)   r   r   r!   r   r   r   Úget_previous_day•   s    zDayMixin.get_previous_dayc                 C   s   |t jdd� S )r%   r&   ©Údays)ÚdatetimeÚ	timedeltar!   r   r   r   Ú_get_next_day™   s    zDayMixin._get_next_dayc                 C   s   |S ©r.   r   r!   r   r   r   Ú_get_current_day¡   s    zDayMixin._get_current_day)r2   r3   r4   r5   r@   r)   rA   rB   rC   rD   rI   rK   r   r   r   r   r?   x   s   r?   c                   @   sP   e Zd ZdZdZ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 )Ú	WeekMixinz-Mixin for views manipulating week-based data.ú%UNc                 C   s   | j S )zv
        Get a week format string in strptime syntax to be used to parse the
        week from url variables.
        )Úweek_formatr   r   r   r   Úget_week_format«   s    zWeekMixin.get_week_formatc                 C   sh   | j }|dkrdz| jd }W nF tk
rb   z| jjd }W n  tk
r\   ttdƒƒ‚Y nX Y nX |S )z8Return the week for which this view should display data.NÚweekzNo week specified)rP   r   r   r   r   r   r   )r   rP   r   r   r   Úget_week²   s    zWeekMixin.get_weekc                 C   s   t | |ddd�S )zGet the next valid week.FrP   r   r   r!   r   r   r   Úget_next_week¿   s    zWeekMixin.get_next_weekc                 C   s   t | |ddd�S )zGet the previous valid week.TrP   r   r   r!   r   r   r   Úget_previous_weekÃ   s    zWeekMixin.get_previous_weekc                 C   sB   z|t jd|  |¡ d� W S  tk
r<   ttdƒƒ‚Y nX dS )r%   é   rE   r*   N)rG   rH   Ú_get_weekdayÚOverflowErrorr   r   r!   r   r   r   Ú_get_next_weekÇ   s    zWeekMixin._get_next_weekc                 C   s   |t  |  |¡¡ S rJ   )rG   rH   rU   r!   r   r   r   Ú_get_current_weekÒ   s    zWeekMixin._get_current_weekc                 C   s@   |   ¡ }|dkr| ¡ S |dkr0| ¡ d d S td| ƒ‚dS )z†
        Return the weekday for a given date.

        The first day according to the week format is 0 and the last day is 6.
        ú%WrM   r&   rT   zunknown week format: %sN)rO   Úweekdayr,   )r   r"   rN   r   r   r   rU   Ö   s    zWeekMixin._get_weekday)r2   r3   r4   r5   rN   rP   rO   rQ   rR   rS   rW   rX   rU   r   r   r   r   rL   ¦   s   rL   c                   @   sD   e Zd ZdZdZdZdd„ Zdd„ Zedd	„ ƒZ	d
d„ Z
dd„ ZdS )Ú	DateMixinz3Mixin class for views manipulating date-based data.NFc                 C   s    | j dkrtd| jj ƒ‚| j S )z7Get the name of the date field to be used to filter by.Nz%s.date_field is required.)Ú
date_fieldr   Ú	__class__r2   r   r   r   r   Úget_date_fieldê   s    
zDateMixin.get_date_fieldc                 C   s   | j S )zi
        Return `True` if the view should be allowed to display objects from
        the future.
        )Úallow_futurer   r   r   r   Úget_allow_futureð   s    zDateMixin.get_allow_futurec                 C   s6   | j dkr|  ¡ j n| j }|j |  ¡ ¡}t|tjƒS )zq
        Return `True` if the date field is a `DateTimeField` and `False`
        if it's a `DateField`.
        N)ÚmodelÚget_querysetÚ_metaÚ	get_fieldr^   Ú
isinstancer   ZDateTimeField)r   ra   Úfieldr   r   r   Úuses_datetime_fieldú   s    zDateMixin.uses_datetime_fieldc                 C   s,   | j r(tj |tjj¡}tjr(t |¡}|S )zó
        Convert a date into a datetime when the date field is a DateTimeField.

        When time zone support is enabled, `date` is assumed to be in the
        current time zone, so that displayed items are consistent with the URL.
        )	rg   rG   ÚcombineÚtimeÚminr   ÚUSE_TZr   Z
make_aware)r   Úvaluer   r   r   Ú_make_date_lookup_arg  s
    
zDateMixin._make_date_lookup_argc                 C   sN   |   ¡ }| jrB|  |¡}|  |tjdd� ¡}d| |d| |iS ||iS dS )z×
        Get the lookup kwargs for filtering on a single date.

        If the date field is a DateTimeField, we can't just filter on
        date_field=date because that doesn't take the time into account.
        r&   rE   ú%s__gteú%s__ltN)r^   rg   rm   rG   rH   )r   r"   r\   ÚsinceÚuntilr   r   r   Ú_make_single_date_lookup  s    
  þz"DateMixin._make_single_date_lookup)r2   r3   r4   r5   r\   r_   r^   r`   r   rg   rm   rr   r   r   r   r   r[   å   s   

	r[   c                   @   sJ   e Zd ZdZdZdZdd„ Zdd„ Zdd	„ Zd
d„ Z	dd„ Z
ddd„ZdS )ÚBaseDateListViewzFAbstract base class for date-based views displaying a list of objects.Fr   c                 O   s6   |   ¡ \| _| _}| jf | j| jdœ|—Ž}|  |¡S )N)Úobject_listÚ	date_list)Úget_dated_itemsru   rt   Zget_context_dataZrender_to_response)r   r   Úargsr   Zextra_contextÚcontextr   r   r   Úget*  s    þýzBaseDateListView.getc                 C   s   t dƒ‚dS )z#Obtain the list of dates and items.z>A DateView must provide an implementation of get_dated_items()N)ÚNotImplementedErrorr   r   r   r   rv   3  s    z BaseDateListView.get_dated_itemsc                 C   s   | j dkrd|  ¡  S | j S )zu
        Return the field or fields to use for ordering the queryset; use the
        date field by default.
        Nú-%s)Úorderingr^   r   r   r   r   Úget_ordering7  s    zBaseDateListView.get_orderingc           	      K   sœ   |   ¡ jf |Ž}|  ¡ }|  ¡ }|  ¡ }|  |¡}|s^| jrDt ¡ nt	ƒ }|jf d| |iŽ}|s˜|dkrp| n| 
¡  }|r˜ttdƒd|jjji ƒ‚|S )zs
        Get a queryset properly filtered according to `allow_future` and any
        extra lookup kwargs.
        ú%s__lteNú$No %(verbose_name_plural)s availableÚverbose_name_plural)rb   Úfilterr^   r`   Úget_allow_emptyZget_paginate_byrg   r   ÚnowÚtimezone_todayÚexistsr   r   ra   rc   r€   )	r   ÚlookupÚqsr\   r_   Úallow_emptyZpaginate_byrƒ   Zis_emptyr   r   r   Úget_dated_queryset>  s     
 ÿz#BaseDateListView.get_dated_querysetc                 C   s   | j S )zf
        Get the aggregation period for the list of dates: 'year', 'month', or
        'day'.
        )Údate_list_periodr   r   r   r   Úget_date_list_periodX  s    z%BaseDateListView.get_date_list_periodNÚASCc                 C   sr   |   ¡ }|  ¡ }|dkr |  ¡ }| jr6| |||¡}n| |||¡}|dk	rn|sn|snttdƒd|jj	j
i ƒ‚|S )zŽ
        Get a date list by calling `queryset.dates/datetimes()`, checking
        along the way for empty lists that aren't allowed.
        Nr   r€   )r^   r‚   r‹   rg   Z	datetimesÚdatesr   r   ra   rc   r€   )r   ÚquerysetZ	date_typer|   r\   rˆ   ru   r   r   r   Úget_date_list_  s     ÿÿzBaseDateListView.get_date_list)NrŒ   )r2   r3   r4   r5   rˆ   rŠ   ry   rv   r}   r‰   r‹   r�   r   r   r   r   rs   %  s   	rs   c                   @   s   e Zd ZdZdZdd„ ZdS )ÚBaseArchiveIndexViewzQ
    Base class for archives of date-based items. Requires a response mixin.
    Zlatestc                 C   s,   |   ¡ }| j|dd�}|s"| ¡ }||i fS )ú:Return (date_list, items, extra_context) for this request.ZDESC)r|   )r‰   r�   Únone)r   r‡   ru   r   r   r   rv   }  s
    z$BaseArchiveIndexView.get_dated_itemsN)r2   r3   r4   r5   Zcontext_object_namerv   r   r   r   r   r�   w  s   r�   c                   @   s   e Zd ZdZdZdS )ÚArchiveIndexViewz&Top-level archive of date-based items.Z_archiveN©r2   r3   r4   r5   Ztemplate_name_suffixr   r   r   r   r“   ˆ  s   r“   c                   @   s(   e Zd ZdZdZdZdd„ Zdd„ ZdS )	ÚBaseYearArchiveViewú*List of objects published in a given year.r(   Fc           	      C   s�   |   ¡ }|  ¡ }t||  ¡ ƒ}|  |¡}|  |  |¡¡}d| |d| |i}| jf |Ž}|  |¡}|  ¡ sr| 	¡ }||||  
|¡|  |¡dœfS )r‘   rn   ro   )r   Z	next_yearZprevious_year)r   r^   Ú_date_from_stringr   rm   r-   r‰   r�   Úget_make_object_listr’   r#   r$   )	r   r   r\   r"   rp   rq   Úlookup_kwargsr‡   ru   r   r   r   rv   ’  s&    
  þ
ýz#BaseYearArchiveView.get_dated_itemsc                 C   s   | j S )zo
        Return `True` if this view should contain the full list of objects in
        the given year.
        )Úmake_object_listr   r   r   r   r˜   ®  s    z(BaseYearArchiveView.get_make_object_listN)r2   r3   r4   r5   rŠ   rš   rv   r˜   r   r   r   r   r•   �  s
   r•   c                   @   s   e Zd ZdZdZdS )ÚYearArchiveViewr–   Z_archive_yearNr”   r   r   r   r   r›   ¶  s   r›   c                   @   s   e Zd ZdZdZdd„ ZdS )ÚBaseMonthArchiveViewú+List of objects published in a given month.r)   c           
      C   s�   |   ¡ }|  ¡ }|  ¡ }t||  ¡ ||  ¡ ƒ}|  |¡}|  |  |¡¡}d| |d| |i}| jf |Ž}|  	|¡}	|	|||  
|¡|  |¡dœfS )r‘   rn   ro   )r(   Ú
next_monthÚprevious_month)r   r9   r^   r—   r   r8   rm   r=   r‰   r�   r:   r;   )
r   r   r(   r\   r"   rp   rq   r™   r‡   ru   r   r   r   rv   ¿  s*    
 ÿ
  þ
ýz$BaseMonthArchiveView.get_dated_itemsN)r2   r3   r4   r5   rŠ   rv   r   r   r   r   rœ   »  s   rœ   c                   @   s   e Zd ZdZdZdS )ÚMonthArchiveViewr�   Z_archive_monthNr”   r   r   r   r   r    Ù  s   r    c                   @   s   e Zd ZdZdd„ ZdS )ÚBaseWeekArchiveViewú*List of objects published in a given week.c              
   C   sÔ   |   ¡ }|  ¡ }|  ¡ }|  ¡ }dddœ}z|| }W n. tk
rd   td|d t|ƒ¡f ƒ‚Y nX t||  	¡ |d||ƒ}|  
|¡}|  
|  |¡¡}	d| |d| |	i}
| jf |
Ž}d	|||  |¡|  |¡d
œfS )r‘   Ú1Ú0)rY   rM   z'Unknown week format %r. Choices are: %sz, z%wrn   ro   N)rP   Z	next_weekZprevious_week)r   rQ   r^   rO   r   r,   ÚjoinÚsortedr—   r   rm   rW   r‰   rR   rS   )r   r   rP   r\   rN   Zweek_choicesZ
week_startr"   rp   rq   r™   r‡   r   r   r   rv   á  s>    
þ
  þ
  þýz#BaseWeekArchiveView.get_dated_itemsN©r2   r3   r4   r5   rv   r   r   r   r   r¡   Þ  s   r¡   c                   @   s   e Zd ZdZdZdS )ÚWeekArchiveViewr¢   Z_archive_weekNr”   r   r   r   r   r¨     s   r¨   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚBaseDayArchiveViewú)List of objects published on a given day.c                 C   s@   |   ¡ }|  ¡ }|  ¡ }t||  ¡ ||  ¡ ||  ¡ ƒ}|  |¡S ©r‘   )r   r9   rB   r—   r   r8   rA   Ú_get_dated_items)r   r   r(   r)   r"   r   r   r   rv     s    
  þz"BaseDayArchiveView.get_dated_itemsc              	   C   sD   |   |¡}| jf |Ž}d|||  |¡|  |¡|  |¡|  |¡dœfS )z•
        Do the actual heavy lifting of getting the dated items; this accepts a
        date object so that TodayArchiveView can be trivial.
        N)r)   Zprevious_dayZnext_dayrŸ   rž   )rr   r‰   rD   rC   r;   r:   )r   r"   r™   r‡   r   r   r   r¬     s    
ûz#BaseDayArchiveView._get_dated_itemsN)r2   r3   r4   r5   rv   r¬   r   r   r   r   r©   	  s   r©   c                   @   s   e Zd ZdZdZdS )ÚDayArchiveViewrª   Ú_archive_dayNr”   r   r   r   r   r­   (  s   r­   c                   @   s   e Zd ZdZdd„ ZdS )ÚBaseTodayArchiveViewú List of objects published today.c                 C   s   |   tj ¡ ¡S r«   )r¬   rG   r"   Útodayr   r   r   r   rv   0  s    z$BaseTodayArchiveView.get_dated_itemsNr§   r   r   r   r   r¯   -  s   r¯   c                   @   s   e Zd ZdZdZdS )ÚTodayArchiveViewr°   r®   Nr”   r   r   r   r   r²   5  s   r²   c                       s"   e Zd ZdZd‡ fdd„	Z‡  ZS )ÚBaseDateDetailViewú’
    Detail view of a single object on a single date; this differs from the
    standard DetailView by accepting a year/month/day in the URL.
    Nc                    s¤   |   ¡ }|  ¡ }|  ¡ }t||  ¡ ||  ¡ ||  ¡ ƒ}|dkrF|  ¡ n|}|  ¡ s€|t	j
 ¡ kr€ttdƒ|jjj| jjdœ ƒ‚|  |¡}|jf |Ž}tƒ j|d�S )z%Get the object this request displays.NzZFuture %(verbose_name_plural)s not available because %(class_name)s.allow_future is False.)r€   Ú
class_name)rŽ   )r   r9   rB   r—   r   r8   rA   rb   r`   rG   r"   r±   r   r   ra   rc   r€   r]   r2   rr   r�   ÚsuperÚ
get_object)r   rŽ   r   r(   r)   r"   r‡   r™   ©r]   r   r   r·   ?  s*    
  þÿþý
zBaseDateDetailView.get_object)N)r2   r3   r4   r5   r·   Ú__classcell__r   r   r¸   r   r³   :  s   r³   c                   @   s   e Zd ZdZdZdS )ÚDateDetailViewr´   Z_detailNr”   r   r   r   r   rº   ]  s   rº   Ú Ú__c           	      C   sx   || | | | }t | ƒ| t |ƒ | t |ƒ }ztj ||¡ ¡ W S  tk
rr   ttdƒ||dœ ƒ‚Y nX dS )z”
    Get a datetime.date object given a format string and a year, month, and day
    (only year is mandatory). Raise a 404 for an invalid date.
    uC   Invalid date string â€œ%(datestr)sâ€� given format â€œ%(format)sâ€�)ÚdatestrÚformatN)ÚstrrG   Ústrptimer"   r,   r   r   )	r   r   r(   r7   r)   r@   Údelimr¾   r½   r   r   r   r—   e  s     þr—   c                 C   sL  |   ¡ }|  ¡ }|  ¡ }t| d| ƒ}t| d| ƒ}||ƒ||ƒ }	}
|r€|rd||	tjdd� ƒ}n|
}|sv|tƒ krz|S dS nÈ|r d| |  |	¡i}d| }nd| |  |
¡i}|}|sÜ| jrÊt	 
¡ }ntƒ }||d	| < |  ¡ jf |Ž |¡}zt|d
 |ƒ}W n tk
�r   Y dS X | j�r@tj�r8t	 |¡}| ¡ }||ƒS dS )aV  
    Get the next or the previous valid date. The idea is to allow links on
    month/day views to never be 404s by never providing a date that'll be
    invalid for the given view.

    This is a bit complicated since it handles different intervals of time,
    hence the coupling to generic_view.

    However in essence the logic comes down to:

        * If allow_empty and allow_future are both true, this is easy: just
          return the naive result (just the next/previous day/week/month,
          regardless of object existence.)

        * If allow_empty is true, allow_future is false, and the naive result
          isn't in the future, then return it; otherwise return None.

        * If allow_empty is false and allow_future is true, return the next
          date *that contains a valid object*, even if it's in the future. If
          there are no next objects, return None.

        * If allow_empty is false and allow_future is false, return the next
          date that contains a valid object. If that date is in the future, or
          if there are no next objects, return None.
    z_get_current_%sz_get_next_%sr&   rE   Nro   r{   rn   r~   r   )r^   r‚   r`   ÚgetattrrG   rH   r„   rm   rg   r   rƒ   rb   r�   Zorder_byÚ
IndexErrorr   rk   Ú	localtimer"   )Zgeneric_viewr"   r   r   r\   rˆ   r_   Zget_currentZget_nextÚstartÚendÚresultr†   r|   rƒ   r‡   r   r   r   r    u  sB    


r    c                   C   s   t jrt ¡ S tj ¡ S dS )z1Return the current date in the current time zone.N)r   rk   r   Z	localdaterG   r"   r±   r   r   r   r   r„   Ï  s    r„   )r»   r»   r»   r»   r¼   )/rG   Zdjango.confr   Zdjango.core.exceptionsr   Z	django.dbr   Zdjango.httpr   Zdjango.utilsr   Zdjango.utils.functionalr   Zdjango.utils.translationr   r   Zdjango.views.generic.baser	   Zdjango.views.generic.detailr
   r   Zdjango.views.generic.listr   r   r   r6   r?   rL   r[   rs   r�   r“   r•   r›   rœ   r    r¡   r¨   r©   r­   r¯   r²   r³   rº   r—   r    r„   r   r   r   r   Ú<module>   sB   14.?@R)&#
Z