o
    Mftd                     @   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                   @   H   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      | 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   \/var/www/html/analyze/labelStudio/lib/python3.10/site-packages/django/views/generic/dates.pyget_year_format      zYearMixin.get_year_formatc                 C   b   | j }|du r/z| jd }W |S  ty.   z
| jjd }W Y |S  ty-   ttdw w |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      zYearMixin.get_yearc                 C      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,      zYearMixin.get_next_yearc                 C   r!   )zGet the previous valid year.Tr   r"   r%   r'   r   r   r   get_previous_year0   r*   zYearMixin.get_previous_yearc                 C   s4   z|j |jd dddW S  ty   ttdw )
        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 range)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/   r0   r2   r'   r   r   r   _get_current_year?   s   zYearMixin._get_current_year)__name__
__module____qualname____doc__r   r   r   r   r)   r+   r4   r8   r   r   r   r   r      s    r   c                   @   r   )
MonthMixinz.Mixin for views manipulating month-based data.z%bNc                 C   r   )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   r   zMonthMixin.get_month_formatc                 C   r   )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   r    zMonthMixin.get_monthc                 C   r!   )zGet the next valid month.Fr/   r"   r%   r'   r   r   r   get_next_month]   r*   zMonthMixin.get_next_monthc                 C   r!   )zGet the previous valid month.Tr/   r"   r%   r'   r   r   r   get_previous_montha   r*   zMonthMixin.get_previous_monthc                 C   sR   |j dkrz|j|jd dddW S  ty   ttdw |j|j d ddS )r,      r-   r.   r1   r6   )r/   r2   r   r3   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-   )r0   r7   r'   r   r   r   _get_current_months   s   zMonthMixin._get_current_month)r9   r:   r;   r<   r>   r/   r?   r@   rA   rB   rD   rE   r   r   r   r   r=   D   s    r=   c                   @   r   )DayMixinz,Mixin for views manipulating day-based data.z%dNc                 C   r   )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}   r   zDayMixin.get_day_formatc                 C   r   )z7Return the day for which this view should display data.Nr0   zNo day specified)r0   r   r   r   r   r   r   )r   r0   r   r   r   get_day   r    zDayMixin.get_dayc                 C   r!   )zGet the next valid day.Fr0   r"   r%   r'   r   r   r   get_next_day   r*   zDayMixin.get_next_dayc                 C   r!   )zGet the previous valid day.Tr0   r"   r%   r'   r   r   r   get_previous_day   r*   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 r5   r   r'   r   r   r   _get_current_day   s   zDayMixin._get_current_day)r9   r:   r;   r<   rG   r0   rH   rI   rJ   rK   rP   rR   r   r   r   r   rF   x   s    rF   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   r   )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   r   zWeekMixin.get_week_formatc                 C   r   )z8Return the week for which this view should display data.NweekzNo week specified)rW   r   r   r   r   r   r   )r   rW   r   r   r   get_week   r    zWeekMixin.get_weekc                 C   r!   )zGet the next valid week.FrW   r"   r%   r'   r   r   r   get_next_week   r*   zWeekMixin.get_next_weekc                 C   r!   )zGet the previous valid week.TrW   r"   r%   r'   r   r   r   get_previous_week   r*   zWeekMixin.get_previous_weekc                 C   s8   z|t jd| | d W S  ty   ttdw )r,      rL   r1   )rN   rO   _get_weekdayOverflowErrorr   r   r'   r   r   r   _get_next_week   s
   zWeekMixin._get_next_weekc                 C   s   |t | | S rQ   )rN   rO   r\   r'   r   r   r   _get_current_week   s   zWeekMixin._get_current_weekc                 C   s<   |   }|dv r| S |dkr| d d S td| )z
        Return the weekday for a given date.

        The first day according to the week format is 0 and the last day is 6.
        >   %V%WrT   r-   r[   zunknown week format: %s)rV   weekdayr3   )r   r(   rU   r   r   r   r\      s   zWeekMixin._get_weekday)r9   r:   r;   r<   rU   rW   rV   rX   rY   rZ   r^   r_   r\   r   r   r   r   rS      s    rS   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u 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__r9   r   r   r   r   get_date_field   s   
zDateMixin.get_date_fieldc                 C   r   )zi
        Return `True` if the view should be allowed to display objects from
        the future.
        )allow_futurer   r   r   r   get_allow_future   r   zDateMixin.get_allow_futurec                 C   s6   | j du 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_fieldrf   
isinstancer   DateTimeField)r   ri   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.
        )	rp   rN   combinetimeminr   USE_TZr   
make_aware)r   valuer   r   r   _make_date_lookup_arg  s
   
zDateMixin._make_date_lookup_argc                 C   sJ   |   }| jr!| |}| |tjdd }d| |d| |iS ||i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-   rL   %s__gte%s__lt)rf   rp   rw   rN   rO   )r   r(   rd   sinceuntilr   r   r   _make_single_date_lookup  s   
z"DateMixin._make_single_date_lookup)r9   r:   r;   r<   rd   rg   rf   rh   r   rp   rw   r|   r   r   r   r   rc      s    

	rc   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d| j| jd|}| |S )N)object_list	date_listr   )get_dated_itemsr   r~   get_context_datarender_to_response)r   r   argsr   extra_contextcontextr   r   r   get*  s   
zBaseDateListView.getc                 C   s   t d)z#Obtain the list of dates and items.z>A DateView must provide an implementation of get_dated_items())NotImplementedErrorr   r   r   r   r   3  s   z BaseDateListView.get_dated_itemsc                 C   s   | j du 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)orderingrf   r   r   r   r   get_ordering7  s   zBaseDateListView.get_orderingc           	      K   s   |   jdi |}|  }|  }|  }| |}|s3| jr$t nt	 }|jdi d| |i}|sP|du r<| n|
  }|rPt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_pluralr   )rj   filterrf   rh   get_allow_emptyget_paginate_byrp   r   nowtimezone_todayexistsr   r   ri   rk   r   )	r   lookupqsrd   rg   allow_emptypaginate_byr   is_emptyr   r   r   get_dated_queryset>  s   

z#BaseDateListView.get_dated_querysetc                 C   r   )zf
        Get the aggregation period for the list of dates: 'year', 'month', or
        'day'.
        )date_list_periodr   r   r   r   get_date_list_periodX  r   z%BaseDateListView.get_date_list_periodNASCc                 C   sr   |   }|  }|du r|  }| jr||||}n||||}|dur7|s7|s7t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   )rf   r   r   rp   	datetimesdatesr   r   ri   rk   r   )r   queryset	date_typer   rd   r   r   r   r   r   get_date_list_  s   
zBaseDateListView.get_date_list)Nr   )r9   r:   r;   r<   r   r   r   r   r   r   r   r   r   r   r   r   r}   %  s    	r}   c                   @      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.
    latestc                 C   s,   |   }| j|dd}|s| }||i fS ):Return (date_list, items, extra_context) for this request.DESC)r   )r   r   none)r   r   r   r   r   r   r   }  s
   
z$BaseArchiveIndexView.get_dated_itemsN)r9   r:   r;   r<   context_object_namer   r   r   r   r   r   w  s    r   c                   @      e Zd ZdZdZdS )ArchiveIndexViewz&Top-level archive of date-based items._archiveNr9   r:   r;   r<   template_name_suffixr   r   r   r   r         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di |}| |}|  s;|	 }|||| 
|| |dfS )r   rx   ry   )r   	next_yearprevious_yearNr   )r   rf   _date_from_stringr   rw   r4   r   r   get_make_object_listr   r)   r+   )	r   r   rd   r(   rz   r{   lookup_kwargsr   r   r   r   r   r     s"   

z#BaseYearArchiveView.get_dated_itemsc                 C   r   )zo
        Return `True` if this view should contain the full list of objects in
        the given year.
        )make_object_listr   r   r   r   r     r   z(BaseYearArchiveView.get_make_object_listN)r9   r:   r;   r<   r   r   r   r   r   r   r   r   r     s    r   c                   @   r   )YearArchiveViewr   _archive_yearNr   r   r   r   r   r     r   r   c                   @   r   )BaseMonthArchiveView+List of objects published in a given month.r0   c           
      C   s   |   }|  }|  }t||  ||  }| |}| | |}d| |d| |i}| jdi |}| 	|}	|	||| 
|| |dfS )r   rx   ry   )r/   
next_monthprevious_monthNr   )r   r@   rf   r   r   r?   rw   rD   r   r   rA   rB   )
r   r   r/   rd   r(   rz   r{   r   r   r   r   r   r   r     s$   


z$BaseMonthArchiveView.get_dated_itemsN)r9   r:   r;   r<   r   r   r   r   r   r   r     s    r   c                   @   r   )MonthArchiveViewr   _archive_monthNr   r   r   r   r   r     r   r   c                   @      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d}z|| }W n ty0   td|dt|f w |  }|dkrE|dkrEtd||f t	|||d	||}| 
|}	| 
| |}
d
| |	d| |
i}| jdi |}d||| || |dfS )r   10)ra   rT   r`   z'Unknown week format %r. Choices are: %sz, r`   z%GzeISO week directive '%s' is incompatible with the year directive '%s'. Use the ISO year '%%G' instead.z%wrx   ry   N)rW   	next_weekprevious_weekr   )r   rX   rf   rV   r   r3   joinsortedr   r   rw   r^   r   rY   rZ   )r   r   rW   rd   rU   week_choices
week_startr   r(   rz   r{   r   r   r   r   r   r     sB   
z#BaseWeekArchiveView.get_dated_itemsNr9   r:   r;   r<   r   r   r   r   r   r         r   c                   @   r   )WeekArchiveViewr   _archive_weekNr   r   r   r   r   r   	  r   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   r@   rI   r   r   r?   rH   _get_dated_items)r   r   r/   r0   r(   r   r   r   r     s   

z"BaseDayArchiveView.get_dated_itemsc              	   C   sH   |  |}| jdi |}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)r0   previous_daynext_dayr   r   r   )r|   r   rK   rJ   rB   rA   )r   r(   r   r   r   r   r   r     s   
z#BaseDayArchiveView._get_dated_itemsN)r9   r:   r;   r<   r   r   r   r   r   r   r     s    r   c                   @   r   )DayArchiveViewr   _archive_dayNr   r   r   r   r   r   -  r   r   c                   @   r   )BaseTodayArchiveView List of objects published today.c                 C   s   |  tj S r   )r   rN   r(   todayr   r   r   r   r   5  r*   z$BaseTodayArchiveView.get_dated_itemsNr   r   r   r   r   r   2  r   r   c                   @   r   )TodayArchiveViewr   r   Nr   r   r   r   r   r   :  r   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u r#|  n|}|  s@|t	j
 kr@ttd|jjj| jjd | |}|jdi |}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   )r   r@   rI   r   r   r?   rH   rj   rh   rN   r(   r   r   r   ri   rk   r   re   r9   r|   r   super
get_object)r   r   r   r/   r0   r(   r   r   re   r   r   r   D  s&   

zBaseDateDetailView.get_object)N)r9   r:   r;   r<   r   __classcell__r   r   r   r   r   ?  s    r   c                   @   r   )DateDetailViewr   _detailNr   r   r   r   r   r   b  s    r    __c           	      C   sn   || | | | }t | | t | | t | }z
tj|| W S  ty6   ttd||d w )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format)strrN   strptimer(   r3   r   r   )	r   r   r/   r>   r0   rG   delimr   r   r   r   r   r   j  s    
r   c                 C   sB  |   }|  }|  }t| d| }t| d| }||||}	}
|r?|r2||	tjdd }n|
}|s;|t kr=|S dS |rOd| | |	i}d| }nd| | |
i}|}|sm| jrdt	
 }nt }||d	| < |  jdi ||}z	t|d
 |}W n
 ty   Y dS w | jrtjrt	|}| }||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-   rL   Nry   r   rx   r   r   r   )rf   r   rh   getattrrN   rO   r   rw   rp   r   r   rj   r   order_by
IndexErrorr   rt   	localtimer(   )generic_viewr(   r#   r$   rd   r   rg   get_currentget_nextstartendresultr   r   r   r   r   r   r   r&   z  sD   


r&   c                   C   s   t jrt S tj S )z1Return the current date in the current time zone.)r   rt   r   	localdaterN   r(   r   r   r   r   r   r     s   
r   )r   r   r   r   r   )/rN   django.confr   django.core.exceptionsr   	django.dbr   django.httpr   django.utilsr   django.utils.functionalr   django.utils.translationr   r   django.views.generic.baser	   django.views.generic.detailr
   r   django.views.generic.listr   r   r   r=   rF   rS   rc   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r&   r   r   r   r   r   <module>   sD    14.?@R)+#
Z