U
    phI                     @   sh  d Z ddlZddlZddlmZ ddlmZmZ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mZ ddlmZ ddlmZmZmZ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&m'Z'm(Z(m)Z) ddl*m+Z+m,Z,m-Z- ddl.m/Z/m0Z0m1Z1 ddl2m3Z3 G dd de
eZ4G dd de
eZ5G dd de
eZ6edd Z7edd Z8edd  Z9ed!d" Z:ed#d$ Z;G d%d& d&e
eZ<G d'd( d(e
eZ=G d)d* d*e
eZ>eeed+gd,d- Z?eeed+gd.d/ Z@eeed+gd0d1 ZAG d2d3 d3e
eZBG d4d5 d5e
eZCG d6d7 d7e
eZDd8d9 ZEd:d; ZFdS )<z
Stream Management Views

This module contains views for managing streaming channels, sessions,
configurations, and real-time stream control operations.
    N)Path)renderget_object_or_404redirect)LoginRequiredMixin)login_required)require_http_methods)csrf_protect)messages)JsonResponseHttp404HttpResponse)reverse_lazy)ListView
DetailView
CreateView
UpdateView)	Paginator)method_decorator)settings   )ChannelStreamSession
HLSSegmentVideoConfigurationAudioConfiguration)start_stream_capturestop_stream_capturecreate_playlist_for_channel)ChannelFormVideoConfigurationFormAudioConfigurationForm)JingleTemplatec                       s8   e Zd ZdZeZdZdZdZdd Z	 fddZ
  ZS )	ChannelListViewzR
    List view for streaming channels with filtering and search capabilities.
    zstreams/channels/list.htmlchannels   c                 C   s   t jdd}| jjd}|rH|j|d|j|dB |j|dB }| jjd}|dkrl|jd	d
}n|dkr|jdd
}|S )z6Filter channels based on search and status parameters.
created_byz-created_atsearch)Zname__icontains)Zslug__icontains)Zdescription__icontainsstatusactiveT	is_activeinactiveF)r   objectsselect_relatedorder_byrequestGETgetfilter)selfquerysetr'   r(    r6   7/var/www/html/StreamProcessor/src/apps/streams/views.pyget_queryset)   s(    	zChannelListView.get_querysetc                    sR   t  jf |}| jjdd|d< | jjdd|d< |d D ]}| |_q>|S )z(Add additional context for the template.r'    r(   status_filterr$   )superget_context_datar0   r1   r2   get_active_sessionactive_session)r4   kwargscontextchannel	__class__r6   r7   r<   A   s    z ChannelListView.get_context_data)__name__
__module____qualname____doc__r   modeltemplate_namecontext_object_namepaginate_byr8   r<   __classcell__r6   r6   rB   r7   r#      s   r#   c                       s,   e Zd ZdZeZdZdZ fddZ  Z	S )ChannelDetailViewzP
    Detail view for individual channels with session history and controls.
    zstreams/channels/detail.htmlrA   c                    s^   t  jf |}| jjddddd |d< | j |d< tj	 |d< t
j	 |d	< |S )
z2Add session history and configuration information.video_configaudio_config-started_atN
   Zrecent_sessionsr>   video_configsaudio_configs)r;   r<   objectsessionsr.   r/   r=   r   r-   allr   r4   r?   r@   rB   r6   r7   r<   W   s     
z"ChannelDetailView.get_context_data)
rD   rE   rF   rG   r   rH   rI   rJ   r<   rL   r6   r6   rB   r7   rM   N   s
   rM   c                       s4   e Zd ZdZeZeZdZe	dZ
 fddZ  ZS )ChannelCreateViewz1
    Create view for new streaming channels.
    streams/channels/form.htmlzstreams:channel_listc                    s   | j j|j_t |S )z,Set the current user as the channel creator.)r0   userinstancer&   r;   
form_validr4   formrB   r6   r7   r\   t   s    zChannelCreateView.form_valid)rD   rE   rF   rG   r   rH   r   
form_classrI   r   success_urlr\   rL   r6   r6   rB   r7   rX   j   s   rX   c                 C   sH   t t|d}|jjdd }|||r4d|j dndd}t| d|S )	z3
    HLS media player for live stream viewing.
    idr)   r(   z/media/streams/z/hls/index.m3u8N)rA   r>   hls_urlzstreams/hls_player.html)r   r   rU   r3   firstslugr   )r0   
channel_idrA   r>   r@   r6   r6   r7   hls_player_view{   s    rh   c                 C   s   t t|d}ttjd |j d }g }| rj|d }ttt	|t
jjdd}dd |d	d
 D }||d}t| d|S )z9
    Browse and view TS segment files for a channel.
    ra   
OUTPUT_DIRhlsz*.tsTkeyreversec                 S   s(   g | ] }|t j|t j|d qS ))pathnamesize)osrn   basenamegetsize.0fr6   r6   r7   
<listcomp>   s     z#ts_file_browser.<locals>.<listcomp>N2   )rA   ts_fileszstreams/ts_browser.htmlr   r   r   r   STREAM_CONFIGrf   existssortedglobstrrq   rn   getmtimer   )r0   rg   rA   Zhls_pathry   Z
ts_patternr@   r6   r6   r7   ts_file_browser   s    r   c                 C   s   t t|d}ttjd |j d }g }| rj|d }ttt	|t
jjdd}dd |d	d
 D }||d}t| d|S )z/
    View extracted iframes for a channel.
    ra   ri   iframesz*.pngTrk   c                 S   s   g | ]}|t j|d qS ))rn   ro   )rq   rn   rr   rt   r6   r6   r7   rw      s     z"iframe_gallery.<locals>.<listcomp>Nd   )rA   iframe_fileszstreams/iframe_gallery.htmlrz   )r0   rg   rA   Ziframes_pathr   Ziframe_patternr@   r6   r6   r7   iframe_gallery   s    r   c                 C   s0   t t|d}|jjdd}||d}t| d|S )z1
    Preview jingle templates for a channel.
    ra   Tr*   )rA   jingle_templateszstreams/jingle_preview.html)r   r   r   r3   r   )r0   rg   rA   r   r@   r6   r6   r7   jingle_preview   s    r   c              
   C   s   t t|d}dddd}||kr(td|dkrDttjd | }n ttjd |j ||  | }| rt|	 s|td	d
ddddd}|j
 }||d}	t|d2}
t|
 |	d}d| d|d< |W  5 Q R  S Q R X dS )zB
    Serve media files (TS, PNG, M3U8) for the media players.
    )rf   rj   r   z
../jingles)rj   r   jingleszInvalid file typer   ri   zFile not foundz
video/mp2tzapplication/vnd.apple.mpegurlz	image/pngz
image/jpeg)z.tsz.m3u8z.pngz.jpgz.jpegzapplication/octet-streamrb)content_typezinline; filename=""zContent-DispositionN)r   r   r   r   r   
MEDIA_ROOTr{   rf   r|   is_filesuffixlowerr2   openr   read)r0   Zchannel_slugZ	file_typefilenamerA   Zfile_mappings	file_pathcontent_typesfile_extr   rv   responser6   r6   r7   serve_media_file   s0     
r   c                       s4   e Zd ZdZeZeZdZdd Z	 fddZ
  ZS )ChannelUpdateViewz6
    Update view for existing streaming channels.
    rY   c                 C   s   t dd| jjidS )z3Redirect to channel detail after successful update.streams:channel_detailpk)r?   )r   rT   r   r4   r6   r6   r7   get_success_url   s    z!ChannelUpdateView.get_success_urlc                    s   t | jd t |S )z!Add success message after update.zChannel updated successfully!r
   successr0   r;   r\   r]   rB   r6   r7   r\     s    zChannelUpdateView.form_valid)rD   rE   rF   rG   r   rH   r   r_   rI   r   r\   rL   r6   r6   rB   r7   r      s   r   c                       s8   e Zd ZdZeZdZdZdZdd Z	 fddZ
  ZS )	StreamSessionListViewzF
    List view for stream sessions with filtering and pagination.
    zstreams/sessions/list.htmlrU   r%   c                 C   sV   t jdddd}| jjd}|r4|j|d}| jjd}|rR|j|d}|S )z,Filter sessions based on channel and status.rA   rN   rO   rP   )rg   r(   rc   )r   r-   r.   r/   r0   r1   r2   r3   )r4   r5   rg   r(   r6   r6   r7   r8     s      z"StreamSessionListView.get_querysetc                    sV   t  jf |}tjjdd|d< | jjdd|d< | jjdd|d< tj	|d	< |S )
zAdd filter options to context.Tr*   r$   rA   r9   Zchannel_filterr(   r:   Zstatus_choices)
r;   r<   r   r-   r3   r0   r1   r2   r   STATUS_CHOICESrW   rB   r6   r7   r<   %  s    
z&StreamSessionListView.get_context_data)rD   rE   rF   rG   r   rH   rI   rJ   rK   r8   r<   rL   r6   r6   rB   r7   r   	  s   r   c                       s,   e Zd ZdZeZdZdZ fddZ  Z	S )StreamSessionDetailViewzN
    Detail view for individual stream sessions with segment information.
    zstreams/sessions/detail.htmlsessionc                    s   t  jf |}| jjddd |d< | jj }| |d< |jdd |d< | rt	d	d
 |D }||d< t	dd
 |D }||d< |S )z'Add segment information and statistics.-processed_atNr%   Zrecent_segmentstotal_segmentsT)is_availableZavailable_segmentsc                 s   s   | ]}|j r|j V  qd S N)durationru   segr6   r6   r7   	<genexpr>E  s      z;StreamSessionDetailView.get_context_data.<locals>.<genexpr>total_durationc                 s   s   | ]}|j r|j V  qd S r   )	file_sizer   r6   r6   r7   r   H  s      
total_size)
r;   r<   rT   segmentsr/   rV   countr3   r|   sum)r4   r?   r@   r   r   r   rB   r6   r7   r<   8  s    z(StreamSessionDetailView.get_context_data)
rD   rE   rF   rG   r   rH   rI   rJ   r<   rL   r6   r6   rB   r7   r   /  s
   r   POSTc              
   C   s  t t|d}| r.t| d td|jdS z| jd}| jd}t	j
t|j||d}t| d|j  | jd	r|  | }t| d
||dW S td|jdW S  tk
 r } z,t| dt|  td|jd W Y S d}~X Y nX dS )z
    HTMX endpoint to start stream capture for a channel.
    
    Args:
        request: HTTP request object
        channel_id: ID of the channel to start streaming
        
    Returns:
        HttpResponse: HTML content for HTMX swap
    ra   z,Channel already has an active stream sessionr   r   rN   rO   )rg   video_config_idaudio_config_idzStream capture started for 
HX-Request#streams/partials/stream_status.htmlrA   r>   zFailed to start stream: N)r   r   r=   r
   errorr   r   r   r2   r   delayr   rb   r   ro   headersrefresh_from_dbr   	Exception)r0   rg   rA   r   r   taskr>   er6   r6   r7   start_streamN  s0    
r   c              
   C   s   t t|d}| s0t| d td|jjdS znt	t
|j}t| d|jj  | jdr|j}|  | }t| d||dW S td|jjdW S  tk
r } z.t| d	t
|  td|jjd W Y S d
}~X Y nX d
S )z
    HTMX endpoint to stop an active stream session.
    
    Args:
        request: HTTP request object
        session_id: ID of the session to stop
        
    Returns:
        HttpResponse: HTML content for HTMX swap
    ra   z Session is not currently runningr   r   zStream stopped for r   r   r   zFailed to stop stream: N)r   r   
is_runningr
   r   r   rA   r   r   r   r   rb   r   ro   r   r2   r   r=   r   r   )r0   
session_idr   r   rA   r>   r   r6   r6   r7   stop_stream  s&    
r   c              
   C   s   t t|d}| r.t| d td|jdS z.|jj}|	  t
| d| d tdW S  tk
r } z,t| dt|  td|jd W Y S d	}~X Y nX d	S )
z
    Delete a stream session and all associated segments.
    
    Args:
        request: HTTP request object
        session_id: ID of the session to delete
        
    Returns:
        HttpResponse: Redirect to session list
    ra   z/Cannot delete a running session. Stop it first.zstreams:session_detailr   zSession for z has been deletedzstreams:session_listzFailed to delete session: N)r   r   r   r
   r   r   rb   rA   ro   deleter   r   r   )r0   r   r   channel_namer   r6   r6   r7   delete_session  s    
r   c                       s4   e Zd ZdZeZdZdZdd Z fddZ	  Z
S )ConfigurationListViewz@
    Combined list view for video and audio configurations.
    zstreams/configs/list.htmlZconfigurationsc                 C   s
   t j S )z?Return empty queryset since we handle data in get_context_data.)r   r-   noner   r6   r6   r7   r8     s    z"ConfigurationListView.get_querysetc                    s:   t  jf |}tj d|d< tj d|d< |S )z(Get both video and audio configurations.ro   rR   rS   )r;   r<   r   r-   rV   r/   r   rW   rB   r6   r7   r<     s    z&ConfigurationListView.get_context_data)rD   rE   rF   rG   r   rH   rI   rJ   r8   r<   rL   r6   r6   rB   r7   r     s   r   c                       s4   e Zd ZdZeZeZdZe	dZ
 fddZ  ZS )VideoConfigurationCreateViewz/
    Create view for video configurations.
    zstreams/configs/video_form.htmlstreams:config_listc                    s   t | jd t |S )Add success message.z)Video configuration created successfully!r   r]   rB   r6   r7   r\     s    z'VideoConfigurationCreateView.form_valid)rD   rE   rF   rG   r   rH   r    r_   rI   r   r`   r\   rL   r6   r6   rB   r7   r     s   r   c                       s4   e Zd ZdZeZeZdZe	dZ
 fddZ  ZS )AudioConfigurationCreateViewz/
    Create view for audio configurations.
    zstreams/configs/audio_form.htmlr   c                    s   t | jd t |S )r   z)Audio configuration created successfully!r   r]   rB   r6   r7   r\     s    z'AudioConfigurationCreateView.form_valid)rD   rE   rF   rG   r   rH   r!   r_   rI   r   r`   r\   rL   r6   r6   rB   r7   r     s   r   c              
   C   sj   z.t t|d}|| | d}t| d|W S  tk
rd } ztd| d W Y S d}~X Y nX dS )z
    HTMX endpoint for real-time stream status updates.
    
    Args:
        request: HTTP request object
        session_id: ID of the session to check
        
    Returns:
        HttpResponse: HTML fragment with session status
    ra   )r   r   r   z$streams/partials/session_status.htmlz!<div class="text-red-500">Error: z</div>N)r   r   r   r   r   r   r   )r0   r   r   r@   r   r6   r6   r7   stream_status  s    r   c                 C   sP   t t|d}|jd}| jdd}t|d}||}||d}t| d|S )z
    HTMX endpoint for paginated segment list.
    
    Args:
        request: HTTP request object
        session_id: ID of the session
        
    Returns:
        HttpResponse: HTML fragment with segment list
    ra   r   pager   rQ   )r   r   z"streams/partials/segment_list.html)	r   r   r   r/   r1   r2   r   get_pager   )r0   r   r   r   r   	paginatorZsegments_pager@   r6   r6   r7   segment_list!  s    

r   )GrG   rq   r~   pathlibr   django.shortcutsr   r   r   django.contrib.auth.mixinsr   django.contrib.auth.decoratorsr   django.views.decorators.httpr   django.views.decorators.csrfr	   django.contribr
   django.httpr   r   r   django.urlsr   Zdjango.views.genericr   r   r   r   django.core.paginatorr   django.utils.decoratorsr   django.confr   modelsr   r   r   r   r   tasksr   r   r   formsr   r    r!   Zapps.jingles.modelsr"   r#   rM   rX   rh   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r6   r6   r6   r7   <module>   sj   /




-&2+