U
    hL                     @   s$  d 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mZ ddlmZmZmZmZmZmZmZmZmZmZmZmZmZ ddlZddl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"ddl#m$Z$ ddl%m&Z& e&e$e"ddd Z'dS )a  
Stream Models for Stream Processor Application

This module contains Django models for managing streaming operations,
including channel configuration, stream sessions, HLS segments,
and monitoring data. These models provide the data structure for
the entire stream processing workflow.
    )models)User)timezone)MinValueValidatorMaxValueValidator)TimestampedModel	UUIDModelStatusModel)validate_hls_urlvalidate_directory_pathvalidate_name_formatvalidate_slug_formatvalidate_segment_durationvalidate_max_segmentsvalidate_retry_attemptsvalidate_video_dimensionsvalidate_video_bitratevalidate_audio_bitratevalidate_sample_ratevalidate_audio_channelsvalidate_framerateNc                   @   s  e Zd ZdZejddegddZejdde	gddZ
ejdegdd	Zejdd
dZejddddZejdegdd	ZejdegddZejdegddZejdegddZejdededgddZejeej dddZ!G dd dZ"dd  Z#d!d" Z$d#d$ Z%d%d& Z&d'd( Z'd)S )*Channela6  
    Model representing a streaming channel configuration.
    
    A channel defines the source stream URL, encoding parameters,
    and output configuration for a specific streaming operation.
    Multiple stream sessions can be associated with a single channel.
    
    Attributes:
        name (CharField): Human-readable name for the channel
        slug (SlugField): URL-friendly identifier for the channel
        hls_url (URLField): Source HLS stream URL to capture
        description (TextField): Optional description of the channel
        is_active (BooleanField): Whether the channel is currently active
        output_directory (CharField): Directory path for stream output
        segment_duration (PositiveIntegerField): HLS segment duration in seconds
        max_segments (PositiveIntegerField): Maximum number of segments to keep
        retry_attempts (PositiveIntegerField): Number of retry attempts on failure
        retry_interval (PositiveIntegerField): Seconds between retry attempts
        created_by (ForeignKey): User who created this channel
    d   Tz#Human-readable name for the channel)
max_lengthunique
validators	help_textz'URL-friendly identifier for the channel  z Source HLS stream URL to capture)r   r   r   z+Optional description of the channel contentblankr   z(Whether this channel is currently activedefaultdb_indexr      z&Directory path for stream output files   z'Duration of each HLS segment in secondsr!   r   r   
   z.Maximum number of segments to keep in playlist   z+Number of retry attempts on capture failure   i,  z&Seconds to wait between retry attemptschannelszUser who created this channel	on_deleterelated_namer   c                   @   sB   e Zd ZdZdZdgZejdgdejdgdejdgdgZdS )	zChannel.Metar   Channelsnameslugfields	is_active
created_atN	__name__
__module____qualname__verbose_nameverbose_name_pluralorderingr   Indexindexes r=   r=   8/var/www/html/StreamProcessor/src/apps/streams/models.pyMetaz   s   r?   c                 C   s   | j S )z%String representation of the channel.)r.   selfr=   r=   r>   __str__   s    zChannel.__str__c                 C   s   t j| j| jS )z*Get the full output path for this channel.)ospathjoinoutput_directoryr/   r@   r=   r=   r>   get_output_path   s    zChannel.get_output_pathc                 C   s   t j|  dS )z)Get the HLS output path for this channel.Zhls)rC   rD   rE   rG   r@   r=   r=   r>   get_hls_path   s    zChannel.get_hls_pathc                 C   s   t j|  dS )z)Get the path to the master playlist file.zplaylist.m3u8)rC   rD   rE   rH   r@   r=   r=   r>   get_playlist_path   s    zChannel.get_playlist_pathc                 C   s   | j jdd S )z9Get the currently active stream session for this channel.active)status)sessionsfilterfirstr@   r=   r=   r>   get_active_session   s    zChannel.get_active_sessionN)(r5   r6   r7   __doc__r   	CharFieldr   r.   	SlugFieldr   r/   URLFieldr
   Zhls_url	TextFielddescriptionBooleanFieldr2   r   rF   PositiveIntegerFieldr   Zsegment_durationr   Zmax_segmentsr   Zretry_attemptsr   r   Zretry_interval
ForeignKeyr   CASCADEZ
created_byr?   rB   rG   rH   rI   rO   r=   r=   r=   r>   r      s   
r   c                   @   s   e Zd ZdZejddddZejdddd	Zejd
ddd	Zej	de
dedgddZejdddd	Zejdddd	ZejdddddgddZejdddddd d!d"d#d$d%g	d&dZejdd'd(d)d*gd+dZejd
d,d-d	ZG d.d/ d/Zd0d1 Zd2S )3VideoConfigurationaM  
    Model for video encoding configuration parameters.
    
    This model stores video encoding settings that can be applied
    to stream processing operations, allowing for different quality
    profiles and encoding options.
    
    Attributes:
        name (CharField): Name for this video configuration
        resolution (CharField): Video resolution (e.g., "1920x1080")
        aspect_ratio (CharField): Video aspect ratio (e.g., "16:9")
        frame_rate (PositiveIntegerField): Video frame rate in FPS
        min_bitrate (CharField): Minimum video bitrate
        max_bitrate (CharField): Maximum video bitrate
        codec (CharField): Video codec to use
        preset (CharField): Encoding preset for speed/quality trade-off
        profile (CharField): Video profile setting
        level (CharField): Video level setting
    2   Tz!Name for this video configurationr   r   r      Z1280x720z!Video resolution (width x height)r   r!   r   r&   z16:9zVideo aspect ratio   r(   x   z%Video frame rate in frames per secondr%   Z2000kz%Minimum video bitrate (e.g., '2000k')Z4000kz%Maximum video bitrate (e.g., '4000k')h264)ra   zH.264)Zh265zH.265)Zvp9ZVP9zVideo codec to use for encodingr   r!   choicesr   medium)Z	ultrafastz
Ultra Fast)Z	superfastz
Super Fast)Zveryfastz	Very Fast)ZfasterZFaster)fastZFast)rd   ZMedium)ZslowZSlow)ZslowerZSlower)Zveryslowz	Very Slowz+Encoding preset for speed/quality trade-offmain)ZbaselineZBaseline)rf   ZMain)highZHighzVideo profile settingz3.1z(Video level setting (e.g., '3.1', '4.0')c                   @   s   e Zd ZdZdZdgZdS )zVideoConfiguration.MetazVideo ConfigurationzVideo Configurationsr.   Nr5   r6   r7   r8   r9   r:   r=   r=   r=   r>   r?     s   r?   c                 C   s   | j  d| j dS )z1String representation of the video configuration. ())r.   
resolutionr@   r=   r=   r>   rB     s    zVideoConfiguration.__str__N)r5   r6   r7   rP   r   rQ   r.   rk   Zaspect_ratiorW   r   r   Z
frame_rateZmin_bitrateZmax_bitratecodecpresetZprofilelevelr?   rB   r=   r=   r=   r>   rZ      s   rZ   c                   @   s   e Zd ZdZejddddZejdddd	d
gddZejddddZej	dddddddgddZ
ej	ddddgddZejdddZG d d! d!Zd"d# Zd$S )%AudioConfigurationao  
    Model for audio encoding configuration parameters.
    
    This model stores audio encoding settings that can be applied
    to stream processing operations, allowing for different audio
    quality profiles and encoding options.
    
    Attributes:
        name (CharField): Name for this audio configuration
        codec (CharField): Audio codec to use
        bitrate (CharField): Audio bitrate setting
        sample_rate (PositiveIntegerField): Audio sample rate in Hz
        channels (PositiveIntegerField): Number of audio channels
        normalize (BooleanField): Whether to apply audio normalization
    r[   Tz!Name for this audio configurationr\   r]   aac)rp   ZAAC)Zmp3ZMP3)ZopusZOpuszAudio codec to use for encodingrb   Z128kz$Audio bitrate (e.g., '128k', '256k')r^   逻  )i@  z8 kHz)i>  z16 kHz)i"V  z	22.05 kHz)iD  z44.1 kHz)rq   z48 kHz)i w z96 kHzzAudio sample rate in Hz)r!   rc   r      )r(   ZMono)rr   ZStereo)r$   z5.1 SurroundzNumber of audio channelsz+Apply audio normalization (loudnorm filter)r!   r   c                   @   s   e Zd ZdZdZdgZdS )zAudioConfiguration.MetazAudio ConfigurationzAudio Configurationsr.   Nrh   r=   r=   r=   r>   r?   U  s   r?   c                 C   s   | j  d| j dS )z1String representation of the audio configuration.ri   rj   )r.   bitrater@   r=   r=   r>   rB   Z  s    zAudioConfiguration.__str__N)r5   r6   r7   rP   r   rQ   r.   rl   rt   rW   Zsample_rater)   rV   	normalizer?   rB   r=   r=   r=   r>   ro     sZ   ro   c                   @   s   e Zd ZdZejeejdd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d	d
Z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dZejedddZG dd dZdd Zdd Zdd Zdd  Zd!S )"StreamSessiona  
    Model representing an active or historical stream session.
    
    A stream session tracks a specific instance of stream capture
    and processing, including start/end times, configuration used,
    and processing statistics.
    
    Attributes:
        channel (ForeignKey): Channel this session belongs to
        video_config (ForeignKey): Video configuration used
        audio_config (ForeignKey): Audio configuration used
        started_at (DateTimeField): When the session started
        ended_at (DateTimeField): When the session ended (if applicable)
        segments_processed (PositiveIntegerField): Number of segments processed
        errors_count (PositiveIntegerField): Number of errors encountered
        last_error (TextField): Last error message encountered
        process_id (CharField): System process ID for monitoring
        statistics (JSONField): Additional statistics data
    rL   zChannel this session belongs tor*   Tz)Video configuration used for this session)r+   nullr   r   z)Audio configuration used for this sessionzWhen the stream capture startedrw   r   r   zWhen the stream capture endedr   z)Number of segments successfully processedrs   z.Number of errors encountered during processingzLast error message encounteredr   r[   z System process ID for monitoring)r   r   r   z"Additional statistics and metadata)r!   r   r   c                   @   sD   e Zd ZdZdZdgZejddgdejdgdejdgdgZdS )	zStreamSession.MetazStream SessionzStream Sessionsz-started_atchannelrK   r0   
started_atNr4   r=   r=   r=   r>   r?     s   r?   c                 C   s   | j j d| j d| j dS )z,String representation of the stream session.z - ri   rj   )ry   r.   rK   rz   r@   r=   r=   r>   rB     s    zStreamSession.__str__c                 C   s"   | j r| jpt }|| j  S dS )z&Calculate the duration of the session.N)rz   ended_atr   now)rA   end_timer=   r=   r>   duration  s    
zStreamSession.durationc                 C   s   | j dko| j S )z*Check if the session is currently running.)rJ   
processing)rK   r{   r@   r=   r=   r>   
is_running  s    zStreamSession.is_runningc                 C   s(   |  j d7  _ || _| jddgd dS )z6Add an error to the session and increment error count.r(   errors_count
last_errorupdate_fieldsN)r   r   save)rA   error_messager=   r=   r>   	add_error  s    zStreamSession.add_errorN) r5   r6   r7   rP   r   rX   r   rY   ry   rZ   SET_NULLZvideo_configro   Zaudio_configDateTimeFieldrz   r{   rW   Zsegments_processedr   rT   r   rQ   
process_id	JSONFielddictZ
statisticsr?   rB   r~   r   r   r=   r=   r=   r>   rv   _  st   	
rv   c                   @   s   e Zd ZdZeje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ededgddZejddddZejdddZejddddZG dd dZdd Zdd Zdd Zdd  Zd!S )"
HLSSegmenta  
    Model representing an individual HLS segment file.
    
    This model tracks individual .ts segment files that make up
    the HLS stream, including their metadata, file paths, and
    processing status.
    
    Attributes:
        session (ForeignKey): Stream session this segment belongs to
        filename (CharField): Name of the segment file
        file_path (CharField): Full path to the segment file
        sequence_number (PositiveIntegerField): Sequence number in playlist
        duration (FloatField): Duration of the segment in seconds
        file_size (PositiveBigIntegerField): Size of the segment file in bytes
        processed_at (DateTimeField): When the segment was processed
        is_available (BooleanField): Whether the file is currently available
    segmentsz&Stream session this segment belongs tor*   r#   zName of the segment file)r   r   r   zFull path to the segment filez#Sequence number in the HLS playlist)r   g?g      N@z"Duration of the segment in seconds)r   r   Tz!Size of the segment file in bytesrx   zWhen the segment was processed)auto_now_addr   z/Whether the segment file is currently availabler    c                   @   sN   e Zd ZdZdZddgZddgZejddgdejdgdejdgdgZ	dS )	zHLSSegment.MetazHLS SegmentzHLS Segmentssessionsequence_numberr0   processed_atis_availableN)
r5   r6   r7   r8   r9   r:   unique_togetherr   r;   r<   r=   r=   r=   r>   r?     s   r?   c                 C   s   | j jj d| j S )z)String representation of the HLS segment.z - Segment )r   ry   r.   r   r@   r=   r=   r>   rB   $  s    zHLSSegment.__str__c                 C   s   t j| jS )z2Check if the segment file actually exists on disk.)rC   rD   exists	file_pathr@   r=   r=   r>   file_exists(  s    zHLSSegment.file_existsc                 C   s,   zt j| jW S  tk
r&   Y dS X dS )z#Get the actual file size from disk.N)rC   rD   getsizer   OSErrorr@   r=   r=   r>   get_file_size,  s    zHLSSegment.get_file_sizec                 C   sR   z8t j| jr6t | j d| _| jdgd W dS W n tk
rL   Y nX dS )z"Delete the segment file from disk.Fr   r   T)rC   rD   r   r   remover   r   r   r@   r=   r=   r>   delete_file3  s    
zHLSSegment.delete_fileN)r5   r6   r7   rP   r   rX   rv   rY   r   rQ   filenamer   rW   r   
FloatFieldr   r   r~   PositiveBigIntegerField	file_sizer   r   rV   r   r?   rB   r   r   r   r=   r=   r=   r>   r     sR   r   )	post_save)receiver)senderc                 K   s*   |r&|j r&ddlm} |t|j dS )a.  
    Automatically trigger jingle detection when a new HLS segment is created.
    
    Args:
        sender: The model class (HLSSegment)
        instance: The actual instance being saved
        created: Boolean indicating if this is a new instance
        **kwargs: Additional keyword arguments
    r   )process_new_segmentN)r   Zapps.streams.tasksr   delaystrid)r   instancecreatedkwargsr   r=   r=   r>   trigger_jingle_detectionD  s    
r   )(rP   	django.dbr   django.contrib.auth.modelsr   django.utilsr   Zdjango.core.validatorsr   r   Zapps.core.modelsr   r   r	   Zapps.core.validatorsr
   r   r   r   r   r   r   r   r   r   r   r   r   rC   jsonr   rZ   ro   rv   r   Zdjango.db.models.signalsr   django.dispatchr   r   r=   r=   r=   r>   <module>   s"   	<tRxj
