U
    !XhD                     @   sp   d 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	eZG d
d deZdS )a  
Electronic Program Guide (EPG) and Channel Schedule Models

This module contains models for managing television programming:
- EPGProgram: Electronic Program Guide entries for scheduled content
- ChannelSchedule: Channel broadcasting schedule and special events

These models work together to provide comprehensive programming information
and scheduling capabilities for television channels.
    )models)timezone)ValidationError)gettext_lazy)	BaseModel)Channelc                       s\  e Zd ZdZdedfdedfdedfded	fd
edfdedfdedfdedfdedfg	Zejeej	dededdZ
ejdededdZejdededdZejd eded!ed"d#Zejed$ed%d&Zejed'ed(d&Zejed)ed*d&Zejdded+ed,d-Zejdded.ed/d-Zejdded0ed1d-Zejd2ded3ed4d5Zejd6ded7ed8d5Zejd9ed:ed;d<Zejded=ed>d<Zejeded?ed@dAZ G dBdC dCZ!dDdE Z" fdFdGZ# fdHdIZ$e%dJdK Z&e%dLdM Z'e%dNdO Z(dPdQ Z)dRdS Z*dTdU Z+dVdW Z,  Z-S )X
EPGProgramaS  
    Electronic Program Guide (EPG) entries for scheduled television content.
    
    Represents individual TV programs with comprehensive metadata including
    timing, content classification, and advertising integration points.
    Used for program scheduling, content discovery, and ad insertion planning.
    
    Attributes:
        channel: Reference to the broadcasting channel
        title: Program title/name
        description: Detailed program description
        program_type: Content category classification
        start_time: Program start timestamp
        end_time: Program end timestamp
        duration: Program duration in minutes
        season_number: Season number for series content
        episode_number: Episode number within season
        original_air_date: Original broadcast date
        content_rating: Age/content rating (G, PG, PG-13, etc.)
        language: Primary program language
        subtitles_available: Whether subtitles are available
        has_ad_breaks: Whether program supports ad insertion
        ad_break_positions: List of ad insertion timestamps
    movieZMovieseriesz	TV SeriesnewsZNewsZsportsZSportsZdocumentaryZDocumentaryentertainmentZEntertainmentZkidsZKidsZmusicZMusicotherOtherZprogramsr   z!Channel broadcasting this program	on_deleterelated_nameverbose_name	help_text   zProgram TitlezFull title of the program
max_lengthr   r   TzProgram Descriptionz+Detailed description of the program contentblankr   r      zProgram Typez&Category classification of the programr   choicesdefaultr   r   
Start Timez$When the program starts broadcastingr   r   End Timez"When the program ends broadcastingDurationzProgram duration in minuteszSeason Numberz Season number for series content)nullr   r   r   zEpisode Numberz Episode number within the seasonzOriginal Air Datez'Original broadcast date of this content
   zContent Ratingz*Age/content rating (G, PG, PG-13, R, etc.))r   r   r   r   2   ZLanguagezPrimary language of the programFzSubtitles Availablez/Whether closed captions/subtitles are availabler   r   r   zHas Ad Breaksz/Whether this program supports commercial breakszAd Break Positionsz9List of timestamps (in seconds) where ads can be inserted)r   r   r   r   c                   @   s   e Zd ZdZedZedZddgZej	ddgddej	ddgd	dej	d
gddgZ
ejejeddddejejddddgZdS )zEPGProgram.MetaZepg_programszEPG ProgramzEPG Programschannel
start_timeZepg_channel_start_idxfieldsnameend_timeZepg_time_range_idxprogram_typeZepg_type_idxZend_time__gtZepg_valid_time_rangecheckr)   r   )Zduration__gtZepg_positive_durationN__name__
__module____qualname__db_table_r   verbose_name_pluralorderingr   IndexindexesCheckConstraintQFconstraints r=   r=   8/var/www/html/Focus/src/apps/channels/models/programs.pyMeta   s"   
r?   c                 C   s"   | j  d| jj d| jd S )N on z at %Y-%m-%d %H:%Mtitler%   r)   r&   strftimeselfr=   r=   r>   __str__   s    zEPGProgram.__str__c                    sr   t    | jrn| jrn| j| jkr2tdtdi| j| j  d }| jrnt|| j dkrntdtdidS )z"Validate program data consistency.r*   "End time must be after start time.<      durationz'Duration does not match the time range.N)	supercleanr&   r*   r   r4   total_secondsrK   abs)rF   Zcalculated_duration	__class__r=   r>   rM      s    
  zEPGProgram.cleanc                    s>   | j r,| jr,| js,t| j| j   d | _t j|| dS )z(Auto-calculate duration if not provided.rI   N)r&   r*   rK   intrN   rL   save)rF   argskwargsrP   r=   r>   rS      s    zEPGProgram.savec                 C   s$   t  }| j|  ko| jkS   S )z+Check if program is currently broadcasting.)r   nowr&   r*   rF   rV   r=   r=   r>   is_currently_airing   s    zEPGProgram.is_currently_airingc                 C   s   | j t kS )z3Check if program is scheduled for future broadcast.)r&   r   rV   rE   r=   r=   r>   is_upcoming   s    zEPGProgram.is_upcomingc                 C   s   | j t k S )z+Check if program has finished broadcasting.r*   r   rV   rE   r=   r=   r>   is_completed   s    zEPGProgram.is_completedc                 C   s   | j s
g S | jr| jS | jd }| jdkrD|dkrDd|d |d gS | jdkrx|dkrx|d	 }d||d |d
 |d gS | jdkrttd|dS d|d gS dS )z
        Get available advertisement insertion opportunities.
        
        Returns:
            list: List of timestamps (in seconds from start) where ads can be inserted
        rI   r	   i  r         )r
   r   i        r   iX  N)has_ad_breaksad_break_positionsrK   r+   listrange)rF   duration_secondsquarterr=   r=   r>   get_ad_opportunities   s    

zEPGProgram.get_ad_opportunitiesc                 C   s   | j s| jrdS | jt  S )z(Get time remaining until program starts.N)rX   r[   r&   r   rV   rE   r=   r=   r>   get_time_until_start   s    zEPGProgram.get_time_until_startc                 C   s   | j s
dS | jt  S )z&Get time remaining in current program.N)rX   r*   r   rV   rE   r=   r=   r>   get_time_remaining   s    zEPGProgram.get_time_remainingc                 C   s   | j |jk o| j|j kS )z4Check if this program overlaps with another program.)r&   r*   )rF   Zother_programr=   r=   r>   overlaps_with  s    
zEPGProgram.overlaps_with).r0   r1   r2   __doc__r4   ZPROGRAM_TYPESr   
ForeignKeyr   CASCADEr%   	CharFieldrC   	TextFielddescriptionr+   DateTimeFieldr&   r*   PositiveIntegerFieldrK   Zseason_numberZepisode_number	DateFieldZoriginal_air_dateZcontent_ratinglanguageBooleanFieldZsubtitles_availabler`   	JSONFieldrb   ra   r?   rG   rM   rS   propertyrX   rY   r[   rf   rg   rh   ri   __classcell__r=   r=   rP   r>   r      s   








		


r   c                       s(  e Zd ZdZdedfdedfdedfded	fd
edfdedfgZejeej	dededdZ
ejdededdZejdedededdZejededdZejededdZejded ed!d"Zejded#ed$d"Zejded%ed&d"Zejded'ed(d)Zejd*ed+ed,d)Zejded-ed.d)Zejd/ed0ed1d)Zejd2ed3ed4d)ZG d5d6 d6Zd7d8 Z fd9d:Ze d;d< Z!e d=d> Z"e d?d@ Z#e dAdB Z$dCdD Z%dEdF Z&dGdH Z'dIdJ Z(dKdL Z)e*dSdNdOZ+e*dTdQdRZ,  Z-S )UChannelSchedulea[  
    Channel broadcasting schedule for special events and programming.
    
    Manages non-regular programming schedules including special events,
    maintenance windows, and test broadcasts. Works alongside EPG programs
    to provide comprehensive channel scheduling.
    
    Attributes:
        channel: Reference to the broadcasting channel
        title: Schedule entry title
        schedule_type: Type of scheduled content
        start_time: Schedule start timestamp
        end_time: Schedule end timestamp
        description: Detailed schedule description
        content_url: Primary content stream URL
        backup_content_url: Backup content stream URL
        allow_ads: Whether ads are permitted during this schedule
        ad_break_duration: Duration of ad breaks in seconds
        is_active: Whether this schedule entry is active
    regularzRegular ProgrammingspecialzSpecial EventmaintenanceMaintenancetestzTest BroadcastZ	emergencyzEmergency BroadcastZreplayzReplay/Rerun	schedulesr   zChannel for this schedule entryr   r   zSchedule Titlez%Title or name for this schedule entryr   r   zSchedule Typez"Type of scheduled content or eventr   r   zWhen this schedule entry beginsr   r   zWhen this schedule entry endsTDescriptionz-Detailed description of the scheduled contentr   zContent URLz,Primary URL for the scheduled content streamzBackup Content URLz Backup URL for content streamingzAllow Advertisementsz0Whether ads can be inserted during this scheduler$   x   zAd Break Durationz+Duration of advertisement breaks in secondsActivez/Whether this schedule entry is currently activerJ   Priorityz3Schedule priority (higher number = higher priority)r]   zNotification Lead Timez/Minutes before start time to send notificationsc                   @   s   e Zd ZdZedZedZdddgZej	ddgddej	d	gd
dej	ddgddgZ
ejejeddddejejddddgZdS )zChannelSchedule.MetaZchannel_scheduleszChannel SchedulezChannel Schedulesr%   r&   	-priorityZschedule_channel_start_idxr'   schedule_typeZschedule_type_idx	is_activeZschedule_active_start_idxr,   Zschedule_valid_time_ranger-   rJ   )Zpriority__gteZschedule_positive_priorityNr/   r=   r=   r=   r>   r?   |  s"   

r?   c                 C   s$   | j  d| jj d| jd dS )Nr@   z (rA   )rB   rE   r=   r=   r>   rG     s    zChannelSchedule.__str__c                    s6   t    | jr2| jr2| j| jkr2tdtdidS )z#Validate schedule data consistency.r*   rH   N)rL   rM   r&   r*   r   r4   rE   rP   r=   r>   rM     s    
 zChannelSchedule.cleanc                 C   s.   | j s
dS t }| j|  ko(| jkS   S )z<Check if schedule is currently active and within time range.F)r   r   rV   r&   r*   rW   r=   r=   r>   is_currently_active  s    z#ChannelSchedule.is_currently_activec                 C   s   | j o| jt kS )zCheck if schedule is upcoming.)r   r&   r   rV   rE   r=   r=   r>   rY     s    zChannelSchedule.is_upcomingc                 C   s   | j t k S )z Check if schedule has completed.rZ   rE   r=   r=   r>   r[     s    zChannelSchedule.is_completedc                 C   s(   | j r$| jr$t| j| j   d S dS )z!Get schedule duration in minutes.rI   r   )r&   r*   rR   rN   rE   r=   r=   r>   duration_minutes  s    z ChannelSchedule.duration_minutesc                 C   s   | j p
| jS )z2Get the effective content URL (primary or backup).)content_urlbackup_content_urlrE   r=   r=   r>   get_effective_content_url  s    z)ChannelSchedule.get_effective_content_urlc                 C   s   | j s| jrdS | jt  S )z)Get time remaining until schedule starts.N)r   r[   r&   r   rV   rE   r=   r=   r>   rg     s    z$ChannelSchedule.get_time_until_startc                 C   s   | j s
dS | jt  S )z'Get time remaining in current schedule.N)r   r*   r   rV   rE   r=   r=   r>   rh     s    z"ChannelSchedule.get_time_remainingc                 C   s0   | j s
dS |  }|sdS | d }|| jkS )z;Check if notification should be sent for upcoming schedule.FrI   )rY   rg   rN   notify_before_minutes)rF   Ztime_until_startZminutes_until_startr=   r=   r>   should_send_notification  s    z(ChannelSchedule.should_send_notificationc                 C   s(   | j |j krdS | j|jk o&| j|jkS )zKCheck if this schedule conflicts with another schedule on the same channel.F)
channel_idr&   r*   )rF   Zother_scheduler=   r=   r>   conflicts_with  s
    
zChannelSchedule.conflicts_withNc                 C   s.   |dkrt  }| jj|d||dd S )z5Get active schedule for a channel at a specific time.NT)r%   r   start_time__lteZend_time__gter   )r   rV   objectsfilterorder_byfirst)clsr%   Zat_timer=   r=   r>   get_active_for_channel  s    z&ChannelSchedule.get_active_for_channel   c                 C   s2   t  }|t j|d }| jj|d||ddS )z<Get upcoming schedules for a channel within specified hours.)hoursT)r%   r   Zstart_time__gter   r&   )r   rV   	timedeltar   r   r   )r   r%   Zhours_aheadrV   r*   r=   r=   r>   get_upcoming_for_channel  s    z(ChannelSchedule.get_upcoming_for_channel)N)r   ).r0   r1   r2   rj   r4   ZSCHEDULE_TYPESr   rk   r   rl   r%   rm   rC   r   rp   r&   r*   rn   ro   URLFieldr   r   rt   Z	allow_adsrq   Zad_break_durationr   priorityr   r?   rG   rM   rv   r   rY   r[   r   r   rg   rh   r   r   classmethodr   r   rw   r=   r=   rP   r>   rx     s   






		





rx   N)rj   	django.dbr   django.utilsr   django.core.exceptionsr   django.utils.translationr   r4   apps.common.modelsr   apps.channels.models.channelsr   r   rx   r=   r=   r=   r>   <module>   s    x