U
    *mh2                     @   s   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m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G dd de
ZdS )    )models)get_user_model)timezone)MinValueValidatorMaxValueValidator)	BaseModel)Channel)CampaignCreativec                   @   s   e Zd ZdZdddddgZejddZejd	d
Z	ejdeddZ
ejddZejdddZejdddZejdededgddZejd	dZejdejd	dZG dd dZdd  Zed!d" Zd#d$ Zd%S )&PlaylistTemplatez:Template for creating playlists with predefined structure.)dailyzDaily Schedule)weeklyzWeekly Schedule)specialzSpecial Event)ZholidayzHoliday Schedule)customzCustom Template   
max_lengthTblank   r   r   choicesdefaultzTemplate duration in minutes	help_text   zMinutes between ad breaksr   r      z(Maximum ad duration per break in secondsP      d   zPercentage of content vs adsr   
validatorsr   r   accounts.User	on_deletenullc                   @   s   e Zd ZdgZdS )zPlaylistTemplate.MetanameN)__name__
__module____qualname__ordering r-   r-   1/var/www/html/Adtlas/src/apps/playlists/models.pyMeta.   s   r/   c                 C   s   | j S N)r(   selfr-   r-   r.   __str__1   s    zPlaylistTemplate.__str__c                 C   s
   d| j  S )z&Calculate ad ratio from content ratio.r    )content_ratior1   r-   r-   r.   ad_ratio4   s    zPlaylistTemplate.ad_ratioc                 C   s   | j d | j d S )z*Calculate total ad time for this template.<   r    )duration_minutesr5   r1   r-   r-   r.   get_total_ad_time9   s    z"PlaylistTemplate.get_total_ad_timeN)r)   r*   r+   __doc__ZTEMPLATE_TYPESr   	CharFieldr(   	TextFielddescriptionZtemplate_typePositiveIntegerFieldr7   Zad_break_intervalmax_ad_durationr   r   r4   BooleanField	is_active
ForeignKeySET_NULL
created_byr/   r3   propertyr5   r8   r-   r-   r-   r.   r   
   s>   
r   c                   @   s|  e Zd ZdZdddddgZddd	d
gZejddZej	ddZ
ejeejddZejeejddddZe Ze ZejdeddZejeddZejdddZejdddZejdddZejdejddZejdejddddZejdddZejd d!dZejd d"dZ ejd d#dZ!G d$d% d%Z"d&d' Z#e$d(d) Z%e$d*d+ Z&e$d,d- Z'd.d/ Z(d0d1 Z)d2d3 Z*d4d5 Z+d6S )7Playlistz3Main playlist model for scheduling content and ads.)draftDraft)	scheduledZ	Scheduled)activeActive	completed	Completed)	cancelled	Cancelled)r   Low)   ZNormal)   High)   Criticalr   r   Tr   	playlistsr&   related_namer&   r'   r   rX   r   rF   r   rQ   )r   r   z+Automatically fill gaps with filler contentr   Fz-Allow playlist to run over scheduled end timez7Loop content if playlist is shorter than scheduled timer$   r%   Zapproved_playlistsr'   r   r   zTotal duration in secondszContent duration in secondszAd duration in secondsc                   @   s2   e Zd ZdgZejddgdejddgdgZdS )zPlaylist.Metaz-start_timechannel
start_timefieldsstatusNr)   r*   r+   r,   r   Indexindexesr-   r-   r-   r.   r/      s   r/   c                 C   s   | j  d| jj  S )N - )r(   r[   r1   r-   r-   r.   r3      s    zPlaylist.__str__c                 C   s,   | j r(| jr(| j| j  }t| d S dS )z!Get playlist duration in minutes.r6   r   )r\   end_timeinttotal_secondsr2   deltar-   r-   r.   r7      s    zPlaylist.duration_minutesc                 C   s.   t  }| jdko,| j|  ko(| jkS   S )z&Check if playlist is currently active.rI   )r   nowr_   r\   rd   )r2   ri   r-   r-   r.   r@      s    
zPlaylist.is_activec                 C   s   | j t kS )zCheck if playlist is upcoming.)r\   r   ri   r1   r-   r-   r.   is_upcoming   s    zPlaylist.is_upcomingc                 C   sh   | j  }tdd |D }tdd |D }tdd |D }|| _|| _|| _| jdddgd d	S )
z+Calculate total, content, and ad durations.c                 s   s   | ]}|j V  qd S r0   )duration.0itemr-   r-   r.   	<genexpr>   s     z/Playlist.calculate_durations.<locals>.<genexpr>c                 s   s   | ]}|j d kr|jV  qdS )contentN	item_typerk   rl   r-   r-   r.   ro      s     
 c                 s   s   | ]}|j d kr|jV  qdS )adNrq   rl   r-   r-   r.   ro      s     
 total_durationcontent_durationad_duration)update_fieldsN)itemsallsumrt   ru   rv   save)r2   rx   totalrp   Zadsr-   r-   r.   calculate_durations   s    
zPlaylist.calculate_durationsc                 C   s"   || _ t | _d| _|   dS )zApprove the playlist.rH   N)approved_byr   ri   approved_atr_   r{   )r2   userr-   r-   r.   approve   s    
zPlaylist.approvec                 C   s   d| _ |   dS )zActivate the playlist.rI   Nr_   r{   r1   r-   r-   r.   activate   s    zPlaylist.activatec                 C   s   d| _ |   dS )zMark playlist as completed.rL   Nr   r1   r-   r-   r.   complete   s    zPlaylist.completeN),r)   r*   r+   r9   STATUS_CHOICESZPRIORITY_CHOICESr   r:   r(   r;   r<   rA   r   CASCADEr[   r   rB   templateDateTimeFieldr\   rd   r_   r=   priorityr?   Zauto_fill_gapsZallow_overrunZloop_contentrC   r~   r   rt   ru   rv   r/   r3   rD   r7   r@   rj   r}   r   r   r   r-   r-   r-   r.   rE   >   s|   		


rE   c                   @   sD  e Zd ZdZdddddgZejeejddZ	ej
d	ed
ZejeejddddZejeejddddZej
ddZejddZej
dddZejddZejdddZejddZejdededgddZejdddZejdddZejd d!dZejd d"dZ G d#d$ d$Z!d%d& Z"e#d'd( Z$e#d)d* Z%e#d+d, Z&d-S ).PlaylistItemz#Individual items within a playlist.)rp   ZContent)rs   ZAdvertisement)ZjingleJingle)ZfillerZFiller)breakBreakrx   rW   r   r   r   TzFor ad items)r&   r'   r   r   r   r   r   i  )r   r   zDuration in secondsr   r   z0Start time offset from playlist start in secondsr   r#   g      ?g        g       @zVolume level (0.0 to 2.0)r!   z Fade in duration in millisecondsz!Fade out duration in millisecondsFzCannot be skipped or replacedzCan overlap with other itemsc                   @   s4   e Zd ZddgZejddgdejddgdgZdS )zPlaylistItem.Metaorderstart_offsetplaylistr]   rr   Nr`   r-   r-   r-   r.   r/     s   r/   c                 C   s   | j  d|   dS )Nz ())r(   Zget_item_type_displayr1   r-   r-   r.   r3   	  s    zPlaylistItem.__str__c                 C   s   | j | j S )zCalculate end time offset.)r   rk   r1   r-   r-   r.   
end_offset  s    zPlaylistItem.end_offsetc                 C   s   | j jtj| jd S )zCalculate actual start time.seconds)r   r\   r   	timedeltar   r1   r-   r-   r.   r\     s    zPlaylistItem.start_timec                 C   s   | j tj| jd S )zCalculate actual end time.r   )r\   r   r   rk   r1   r-   r-   r.   rd     s    zPlaylistItem.end_timeN)'r)   r*   r+   r9   Z
ITEM_TYPESr   rA   rE   r   r   r:   rr   r	   campaignr
   creativer(   r;   r<   	file_pathr=   rk   r   r   
FloatFieldr   r   Zvolume_levelZfade_inZfade_outr?   Zis_mandatoryZcan_overlapr/   r3   rD   r   r\   rd   r-   r-   r-   r.   r      sz   	

r   c                   @   s   e Zd ZdZddddddgZejeejdd	Z	eje
ejd
d
ddZejdeddZejd
d
dZejd
d
dZejdddZejdddZejd
dZejddZG dd dZdd Zdd Zdd Zdd Zd S )!PlaylistExecutionz-Track playlist execution and playback status.)pendingPending)playingZPlaying)pausedPausedrK   )failedZFailed)skippedZSkippedZ
executionsrW   TrY   r   r   r   rZ   r   z#Actual playback duration in secondsr   z$Current playback position in secondsr   r#   c                   @   s0   e Zd ZdgZejddgdejdgdgZdS )zPlaylistExecution.Metaz-started_atr   r_   r]   
started_atNr`   r-   r-   r-   r.   r/   D  s   r/   c                 C   s$   | j r| j jnd}| jj d| S )NzFull Playlistrc   )playlist_itemr(   r   )r2   Z	item_namer-   r-   r.   r3   K  s    zPlaylistExecution.__str__c                 C   s   d| _ t | _|   dS )zMark playback as started.r   N)r_   r   ri   r   r{   r1   r-   r-   r.   start_playbackO  s    
z PlaylistExecution.start_playbackc                 C   s<   d| _ t | _| jr0| j| j }t| | _|   dS )zMark playback as completed.rL   N)	r_   r   ri   completed_atr   re   rf   actual_durationr{   rg   r-   r-   r.   complete_playbackU  s    
z#PlaylistExecution.complete_playbackc                 C   s"   d| _ || _t | _|   dS )zMark playback as failed.r   N)r_   error_messager   ri   r   r{   )r2   r   r-   r-   r.   fail_playback^  s    
zPlaylistExecution.fail_playbackN)r)   r*   r+   r9   r   r   rA   rE   r   r   r   r   r:   r_   r   r   r   r=   r   positionr;   r   Zretry_countr/   r3   r   r   r   r-   r-   r-   r.   r     sD   			r   c                   @   s   e Zd ZdZddddgZdddd	gZejeej	d
dZ
ejeej	ddZejdedZejdeddZe ZejddZejdejdddZejdddZejddZG dd dZdd Zd ddZdS )!PlaylistConflictz-Track scheduling conflicts between playlists.)overlapzTime Overlap)resourcezResource Conflict)r   zPriority Conflict)rp   zContent Conflict)lowrP   )mediumZMedium)highrS   )criticalrU   Zconflicts_as_arW   Zconflicts_as_br   r   r   r   Fr#   r$   T)r&   r'   r   rZ   r   c                   @   s2   e Zd ZdgZejddgdejddgdgZdS )zPlaylistConflict.Metaz-created_at
playlist_ais_resolvedr]   conflict_typeseverityNr`   r-   r-   r-   r.   r/     s   r/   c                 C   s   d| j j d| jj S )Nz
Conflict: z vs )r   r(   
playlist_br1   r-   r-   r.   r3     s    zPlaylistConflict.__str__ c                 C   s(   d| _ || _t | _|| _|   dS )zMark conflict as resolved.TN)r   resolved_byr   ri   resolved_atresolution_notesr{   )r2   r   notesr-   r-   r.   resolve  s
    
zPlaylistConflict.resolveN)r   )r)   r*   r+   r9   ZCONFLICT_TYPESZSEVERITY_LEVELSr   rA   rE   r   r   r   r:   r   r   r;   r<   r?   r   rB   r   r   r   r   r/   r3   r   r-   r-   r-   r.   r   f  sH   r   N)	django.dbr   django.contrib.authr   django.utilsr   Zdjango.core.validatorsr   r   apps.common.modelsr   Zapps.channels.modelsr   Zapps.campaigns.modelsr	   r
   r   rE   r   r   r   r-   r-   r-   r.   <module>   s   4 ^J