U
    h,{                    @   s  d Z ddlZddlZddlmZmZmZmZmZ ddl	m
Z
 ddlmZmZmZmZmZ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mZmZ dd
lmZ ddl m!Z!m"Z"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/m0Z0 ddl1m2Z2 ddlmZ ddlmZmZ ddlmZmZmZmZ ddlmZmZmZ ddl m!Z!m"Z" ddl'm(Z( ddl3m4Z5 ddl6m7Z7 ddl8m9Z9 ddl:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZB ddlCmDZD G dd de2eZEG dd de2eZFG dd  d e2eZGG d!d" d"e2eZHG d#d$ d$eZIG d%d& d&eZJG d'd( d(eZKG d)d* d*eZLe.e,d+d,G d-d. d.eZMG d/d0 d0eZNG d1d2 d2eZOG d3d4 d4eZPG d5d6 d6eZQG d7d8 d8eZRG d9d: d:eZSG d;d< d<eZTG d=d> d>eZUG d?d@ d@eZVG dAdB dBeZWG dCdD dDe2eZXG dEdF dFe2eZYG dGdH dHe2eZZG dIdJ dJe2eZ[G dKdL dLe2eZ\G dMdN dNeZ]G dOdP dPeZ^G dQdR dReZ_G dSdT dTeZ`G dUdV dVeZaG dWdX dXeZbG dYdZ dZeZcG d[d\ d\eZdG d]d^ d^eZeG d_d` d`eZfG dadb dbeZgdS )ca1  Views for the channels app.

This module contains all view classes for managing channels, jingles, adbreaks,
and related functionality. All views inherit from Django's base View class
to provide maximum flexibility and control over request handling.

Author: Django Channels App
Version: 1.0.0
Date: 2024
    N)DictAnyListUnionOptional)logout)HttpRequestHttpResponseJsonResponseHttp404HttpResponseRedirectHttpResponseBadRequest)renderget_object_or_404redirect)reverse)View)	Paginator	EmptyPagePageNotAnInteger)messages)QCountAvgSumMaxMin)timezone)ValidationError)csrf_exempt)method_decorator)settings)LoginRequiredMixin)r   r   )r   r	   r
   r   )r   r   r   )r   r   )gettext)cache)get_client_ip)ChannelChannelZoneChannelCodecJingleAdbreak
EPGProgramChannelScheduleChannelZoneRelation)Activityc                       s  e Zd ZdZdgZdZdddddd	Z fd
dZee	dddZ
edddZdd Zdd Zdd Zdd Zdd Zdd Zeeeef dddZd d! Zd"d# Zd$d% Zeeeef dd&d'Zed(d)d*Zeeef d(d+d,Zeeejf d(d-d.Z ee!dd/d0Z"ee!dd1d2Z#ee!dd3d4Z$ee!dd5d6Z%ee!dd7d8Z&ee!dd9d:Z'ee!dd;d<Z(eedd=d>Z)ed?dd@dAZ*ee	d fdBdCZ+  Z,S )DChannelListViewa  
        Channel List View

        This view is responsible for rendering the channels list page of the application.
        It extends the Django View class and defines the HTTP GET method to handle
        the request and return the rendered channels list page template with advanced
        filtering, searching, pagination, and AJAX support.

        Methods:
            get(request): Handles the HTTP GET request and returns the rendered
                channels list page template.

        Template:
            - 'channels/channel/list.html': The HTML template used to render the channels list page.

        Features:
            - Advanced filtering by type, status, zone, and date ranges
            - Full-text search across channel name, display name, and description
            - Pagination with customizable items per page
            - AJAX support for dynamic updates
            - Statistics and analytics
            - Export functionality
            - Real-time updates
    getzchannels/channel/list.htmlzChannels - AdtlasAdtlas Development TeamzzChannels management for Adtlas TV advertising solutions. This page provides comprehensive channel management and insights.z`Adtlas, channels, TV advertising solutions, channel management, broadcasting, data visualizationchannels)titleauthordescriptionkeywordsactive_menuc                    s$   t  jf |}|dtdi |S )z
        Add channels page context data.
        
        Args:
            **kwargs: Additional keyword arguments
            
        Returns:
            dict: Updated context data
        r3   Channels)superget_context_dataupdate_)selfkwargscontext	__class__ ./var/www/html/Focus/src/apps/channels/views.pyr:   ^   s    
 z ChannelListView.get_context_datarequestreturnc           	      O   s   |j ddkr| |S | |}t|| |}|jdd}z||}W n< tk
rn   |d}Y n  t	k
r   ||j
}Y nX | | | |||}t|| j|S )a  
            Handles the HTTP GET request and returns the rendered channels list page template.

            Args:
                request (HttpRequest): The HTTP request object.
                *args: Variable length argument list.
                **kwargs: Arbitrary keyword arguments.

            Returns:
                HttpResponse: The rendered channels list page template.

            Query Parameters:
                - search: Search term for channel name/display_name/description
                - type: Filter by channel type
                - status: Filter by channel status
                - zone: Filter by channel zone
                - date_from: Start date for filtering
                - date_to: End date for filtering
                - date_range: Predefined date range
                - sort_by: Sorting field and direction
                - page: Page number for pagination
                - per_page: Number of items per page (default: 20)
        X-Requested-WithXMLHttpRequestpage   )headersr0   _handle_ajax_request_get_filtered_querysetr   _get_items_per_pageGETget_pager   r   	num_pages_log_user_activity_build_contextr   template_name)	r=   rE   argsr>   queryset	paginatorpage_numberpage_objr?   rB   rB   rC   r0   n   s    


zChannelListView.get)rE   c                 C   s`   t j  d}| ||}| ||}| ||}| ||}| 	||}| 
||}|S )z
        Build filtered queryset based on request parameters.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            QuerySet: Filtered channel queryset
        zones)r&   objectsallselect_relatedprefetch_related_apply_search_filter_apply_type_filter_apply_status_filter_apply_zone_filter_apply_date_filters_apply_sortingr=   rE   rV   rB   rB   rC   rM      s    z&ChannelListView._get_filtered_querysetc                 C   sH   |j dd }|rD|t|dt|dB t|dB t|dB }|S )z
        Apply search filter to queryset.
        
        Args:
            queryset: Base queryset
            request: Django HTTP request object
            
        Returns:
            QuerySet: Filtered queryset
        search name__icontainsZdisplay_name__icontainsdescription__icontains)Zchannel_code__icontains)rO   r0   stripfilterr   )r=   rV   rE   search_queryrB   rB   rC   r_      s    z$ChannelListView._apply_search_filterc                 C   s.   |j dd }|r*|dkr*|j|d}|S )z
        Apply channel type filter to queryset.
        
        Args:
            queryset: Base queryset
            request: Django HTTP request object
            
        Returns:
            QuerySet: Filtered queryset
        typerg   r\   channel_typerO   r0   rm   rn   )r=   rV   rE   rr   rB   rB   rC   r`      s    z"ChannelListView._apply_type_filterc                 C   s.   |j dd }|r*|dkr*|j|d}|S )z
        Apply status filter to queryset.
        
        Args:
            queryset: Base queryset
            request: Django HTTP request object
            
        Returns:
            QuerySet: Filtered queryset
        statusrg   r\   rt   rs   )r=   rV   rE   status_filterrB   rB   rC   ra      s    z$ChannelListView._apply_status_filterc                 C   s.   |j dd }|r*|dkr*|j|d}|S )z
        Apply zone filter to queryset.
        
        Args:
            queryset: Base queryset
            request: Django HTTP request object
            
        Returns:
            QuerySet: Filtered queryset
        zonerg   r\   )Z	zones__idrs   )r=   rV   rE   Zzone_filterrB   rB   rC   rb      s    z"ChannelListView._apply_zone_filterc                 C   sd  |j d}|j d}|j d}|rt  }|dkrJ|j|d}n|dkrp|tjdd }|j|d}np|d	kr|tj| d }|j|d
}nF|dkr|j	dd}	|j|	d
}n$|dkr|tjdd }
|j|
d
}|r z"tj
|d }|j|d
}W n tk
r   Y nX |r`z"tj
|d }|j|d}W n tk
r^   Y nX |S )z
        Apply date range filters to queryset.
        
        Args:
            queryset: Base queryset
            request: Django HTTP request object
            
        Returns:
            QuerySet: Filtered queryset
        	date_fromdate_to
date_rangetoday)created_at__date	yesterdayrJ   days	this_weekZcreated_at__date__gte
this_monthdaylast_30_days   %Y-%m-%d)Zcreated_at__date__lte)rO   r0   r   nowdatern   datetime	timedeltaweekdayreplacestrptime
ValueError)r=   rV   rE   rx   ry   rz   r{   r}   
week_startmonth_startr   	from_dateto_daterB   rB   rC   rc     s@    z#ChannelListView._apply_date_filtersc                 C   sL   |j dd}dddddddd	d
dddg}||kr>||}n
|d}|S )z
        Apply sorting to queryset.
        
        Args:
            queryset: Base queryset
            request: Django HTTP request object
            
        Returns:
            QuerySet: Sorted queryset
        sort_byname-namedisplay_name-display_namerr   -channel_typert   z-status
created_at-created_at
updated_at-updated_at)rO   r0   order_by)r=   rV   rE   r   valid_sort_fieldsrB   rB   rC   rd   :  s$          	
zChannelListView._apply_sortingc                 C   sh   |j }|j|||jdk|  |  | || ||  | || 	 |j
|j|jd}|| j |S )a  
        Build template context with all necessary data.
        
        Args:
            request: Django HTTP request object
            page_obj: Paginated page object
            paginator: Paginator instance
            
        Returns:
            dict: Template context
        rJ   )r2   rY   rW   is_paginatedchannel_typesstatus_choicesrZ   filter_paramssort_optionsstatsrz   total_resultscurrent_pagetotal_pages)userobject_listrQ   _get_channel_types_get_status_choices_get_available_zones_get_current_filters_get_sort_options
_get_stats_get_date_rangecountnumberr;   extra_context)r=   rE   rY   rW   r   r?   rB   rB   rC   rS   W  s$    zChannelListView._build_contextc                 C   s   t tdg S )zo
        Get available channel types.
        
        Returns:
            list: Channel type choices
        CHANNEL_TYPESgetattrr&   r=   rB   rB   rC   r     s    z"ChannelListView._get_channel_typesc                 C   s   t tdg S )zj
        Get available status choices.
        
        Returns:
            list: Status choices
        STATUS_CHOICESr   r   rB   rB   rC   r     s    z#ChannelListView._get_status_choicesc                 C   s   t jjdd ddS )z
        Get zones available to the current user.
        
        Args:
            user: Current user object
            
        Returns:
            QuerySet: Available zones
        T	is_activer   r   )r'   r[   rn   distinctr   )r=   r   rB   rB   rC   r     s    

 z$ChannelListView._get_available_zonesc                 C   sr   |j dd|j dd|j dd|j dd|j dd|j dd|j d	d|j d
d|j ddd	S )z
        Get current filter parameters for template.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            dict: Current filter values
        rf   rg   rp   r\   rt   rw   rx   ry   rz   r   r   per_page20)	rf   rp   rt   rw   rx   ry   rz   r   r   )rO   r0   )r=   rE   rB   rB   rC   r     s    z$ChannelListView._get_current_filtersrF   c                 C   sL   ddddddddddd	dd
ddddddddddddddg	S )zv
        Get available sorting options.
        
        Returns:
            list: Sort options for template
        r   z
Name (A-Z)valuelabelr   z
Name (Z-A)r   zDisplay Name (A-Z)r   zDisplay Name (Z-A)rr   z
Type (A-Z)r   z
Type (Z-A)r   zNewest Firstr   zOldest Firstr   zRecently UpdatedrB   r   rB   rB   rC   r     s    z!ChannelListView._get_sort_optionsc                 C   s   t j }t  }|tjdd }| |j	dd |j	dd |j	dd |j	dd |j	d	d |j	|d
 |
djtddd|j	d	d  |j	dd d
S )z
        Get channels statistics for dashboard.

        Args:
            user: Current user object

        Returns:
            dict: Channels statistics
           r~   activeru   T	is_onlinependinginactiveFr   rr   idr   -count)Zzones__isnull)
total_channelsactive_channelsonline_channelsZpending_channelsinactive_channelsoffline_channelsrecent_channelsZchannels_by_typeZchannels_with_zonesZchannels_without_zones)r&   r[   r\   r   r   r   r   r   r   rn   valuesannotater   r   r   )r=   r   base_querysetr{   week_agorB   rB   rC   r     s(    


zChannelListView._get_statsc              	   C   sZ   t   }||tjdd |tj| d |jdd|tjdd |tjdd dS )zz
        Get date range information for filtering.
        
        Returns:
            dict: Date range options
        rJ   r~   r   im  )r{   r}   r   r   min_datemax_date)r   r   r   r   r   r   r   )r=   r{   rB   rB   rC   r     s    
zChannelListView._get_date_rangec                 C   sp   |j d}|dkr| |S |dkr0| |S |dkrB| |S |dkrT| |S |dkrf| |S | |S )z
        Handle AJAX requests for dynamic updates.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            JsonResponse: JSON response with data
        action	get_zonesZget_channel_typesquick_statsexport_dataZ	load_more)rO   r0   _get_zones_ajax_get_channel_types_ajax_get_quick_stats_ajax_export_channels_data_ajax_load_more_channels_ajax_get_filtered_channels_ajax)r=   rE   r   rB   rB   rC   rL     s    





z$ChannelListView._handle_ajax_requestc              	   C   s.   |j }| |}tdt|dddddS )z
        Get zones via AJAX.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            JsonResponse: JSON response with zone data
        Tr   r   regioncode)successrZ   )r   r   r
   listr   )r=   rE   r   rZ   rB   rB   rC   r     s    

zChannelListView._get_zones_ajaxc                 C   s    |   }tddd |D dS )z
        Get channel types via AJAX.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            JsonResponse: JSON response with channel type data
        Tc                 S   s   g | ]}|d  |d dqS )r   rJ   r   rB   ).0ctrB   rB   rC   
<listcomp>8  s     z;ChannelListView._get_channel_types_ajax.<locals>.<listcomp>)r   r   )r   r
   )r=   rE   r   rB   rB   rC   r   *  s
    
z'ChannelListView._get_channel_types_ajaxc                 C   s   |j }| |}td|dS )z
        Get quick statistics via AJAX.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            JsonResponse: JSON response with statistics
        T)r   r   )r   r   r
   )r=   rE   r   r   rB   rB   rC   r   ;  s    

z%ChannelListView._get_quick_stats_ajaxc                 C   s,   |  |}tdd|  dd| dS )z
        Export channels data via AJAX.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            JsonResponse: JSON response with export status
        TzExport prepared for 	 channels#)r   messagedownload_urlr   )rM   r
   r   re   rB   rB   rC   r   M  s    
z*ChannelListView._export_channels_data_ajaxc           	      C   s   t |jdd}| |}| |}t||}z||}W n& ttfk
rd   t	ddd Y S X g }|j
D ]L}||j|jt|ddt|ddt|d	dt|d
r|j ndd qpt	d|| | r| nd|j|jdS )z
        Load more channels via AJAX for infinite scroll.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            JsonResponse: JSON response with additional channels
        rI   rJ   FInvalid pager   errorr   rg   rr   rt   r   )r   r   r   rr   rt   r   TN)r   r2   has_next	next_pager   r   )intrO   r0   rN   rM   r   rP   r   r   r
   r   appendr   r   r   hasattrr   	isoformatr   next_page_numberr   rQ   )	r=   rE   rI   r   rV   rW   rY   channels_datachannelrB   rB   rC   r   c  s4    








	z(ChannelListView._load_more_channels_ajaxc                 C   s   |  |}t|| |}|jdd}z||}W n& ttfk
r\   tddd Y S X g }|j	D ]L}|
|j|jt|ddt|ddt|d	dt|d
r|j ndd qhtd||j|j|j| | dS )z
        Get filtered channels via AJAX.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            JsonResponse: JSON response with filtered channels
        rI   rJ   Fr   r   r   rg   rr   rt   rZ   r   )r   r   r   rr   rt   
zone_countT)r   r2   r   r   r   r   has_previous)rM   r   rN   rO   r0   rP   r   r   r
   r   r   r   r   r   r   rZ   r   r   rQ   r   r   )r=   rE   rV   rW   rI   rY   r   r   rB   rB   rC   r     s4    






	z+ChannelListView._get_filtered_channels_ajaxc              	   C   sD   z$t |jdd}tdt|dW S  ttfk
r>   Y dS X dS )z
        Get number of items per page from request or default.
        
        Args:
            request: Django HTTP request object
            
        Returns:
            int: Items per page
        r      
   d   N)r   rO   r0   maxminr   	TypeError)r=   rE   r   rB   rB   rC   rN     s
    
z#ChannelListView._get_items_per_pageNc                 C   sX   |j }tj|dd|r|jnd d|t||jdd| || |	 dd d	S )
aZ  
        Log user activity for auditing purposes.
        
        Records the user's action with relevant metadata including IP address,
        user agent, and timestamp for security and analytics purposes.
        
        Args:
            request (HttpRequest): The HTTP request object
            
        Returns:
            None
        Zviews_channelsUser Systemz viewed channels listHTTP_USER_AGENTrg   )Zfilters_appliedZresults_countr   r   r5   rE   
ip_address
user_agentmetadataN)
r   r.   log_activityemailr%   METAr0   r   rM   r   )r=   rE   r   rB   rB   rC   rR     s    z"ChannelListView._log_user_activityc                    s   t  j|f||S )a0  
        Override dispatch method for additional request processing.
        
        This method is called before any HTTP method handler. Useful for
        adding common logic like additional authentication checks, rate limiting,
        or request preprocessing.
        
        Args:
            request (HttpRequest): The HTTP request object
            *args: Variable length argument list
            **kwargs: Arbitrary keyword arguments
            
        Returns:
            HttpResponse: Result from the appropriate HTTP method handler
        )r9   dispatch)r=   rE   rU   r>   r@   rB   rC   r    s    zChannelListView.dispatch)-__name__
__module____qualname____doc__http_method_namesrT   r   r:   r   r	   r0   rM   r_   r`   ra   rb   rc   rd   r   strr   rS   r   r   r   r   r   r   r   r   r   r   r   r
   rL   r   r   r   r   r   r   rN   rR   r  __classcell__rB   rB   r@   rC   r/   :   sH   33+

*)r/   c                       s  e Zd ZdZddgZdZddddd	Z fd
dZee	e
dddZee	ee
ef dddZee	dddZeeeeef dddZdd Zdd Zde	dddZde	dd d!Zeeeef d"d#d$Zeeeef d"d%d&Zeeeef d"d'd(Zeeef d)d*d+Zeeef d)d,d-Zeed"d.d/Zee	edd0d1Zeed"d2d3Z eed"d4d5Z!eed"d6d7Z"eed"d8d9Z#eed"d:d;Z$d<d= Z%d>d? Z&d@dA Z'dBdC Z(dDdE Z)dFdG Z*dHdI Z+dJdK Z,dLdM Z-dNdO Z.dPdQ Z/dRdS Z0dTdU Z1dVdW Z2dXdY Z3dZd[ Z4d\d] Z5d^d_ Z6d`da Z7dbdc Z8ddde Z9dfdg Z:dhdi Z;djdk Z<dldm Z=dndo Z>dpdq Z?drds Z@dtdu ZAdvdw ZBdxdy ZCdzd{ ZDed|d"d}d~ZE  ZFS )ChannelDetailViewa  
    Channel Detail View

    This view is responsible for rendering the channel detail page of the application.
    It extends the Django View class and provides comprehensive channel information
    including zones, codecs, recent adbreaks, jingles, health status, analytics,
    and real-time monitoring data.

    Methods:
        get(request, channel_id): Handles the HTTP GET request and returns the rendered
            channel detail page template with comprehensive data.

    Template:
        - 'channels/channel/detail.html': The HTML template used to render the channel detail page.

    Features:
        - Comprehensive channel information display
        - Real-time health status monitoring
        - Advanced analytics and statistics
        - Interactive charts and graphs
        - AJAX support for dynamic updates
        - Export functionality for reports
        - Historical data analysis
        - Performance metrics tracking
        - Zone and codec management
        - Adbreak and jingle analysis

    r0   postzchannels/channel/detail.htmlr1   zODetailed channel information and analytics for Adtlas TV advertising solutions.zPAdtlas, channel details, TV advertising, channel analytics, broadcasting metricsr2   )r4   r5   r6   r7   c                    sB   t t drt jf |ni }||j dtd|jd |S )z
        Add channel detail page context data.
        
        Args:
            channel: Channel object
            **kwargs: Additional keyword arguments
            
        Returns:
            dict: Updated context data
        r:   z - Channel Details - AdtlaszChannel Details)r3   
page_titlechannel_name)r   r9   r:   r;   r   r<   )r=   r   r>   r?   r@   rB   rC   r:      s    
z"ChannelDetailView.get_context_datarE   
channel_idrF   c                 O   s^   |j ddkr| ||S | ||}|jdd}| || | |||}t|| j|S )a  
        Handles the HTTP GET request and returns the rendered channel detail page template.

        Args:
            request (HttpRequest): The HTTP request object.
            channel_id (int): Primary key of the channel to display.
            *args: Variable length argument list.
            **kwargs: Arbitrary keyword arguments.

        Returns:
            HttpResponse: The rendered channel detail page template.

        Raises:
            Http404: If channel with given ID doesn't exist or user doesn't have permission.

        Query Parameters:
            - tab: Active tab to display (overview, analytics, zones, adbreaks, jingles, health)
            - date_from: Start date for analytics filtering
            - date_to: End date for analytics filtering
            - date_range: Predefined date range for analytics
            - export: Export format (json, csv, pdf)
        rG   rH   taboverview)	rK   r0   rL   _get_channel_with_permissionsrO   rR   _build_comprehensive_contextr   rT   )r=   rE   r  rU   r>   r   
active_tabr?   rB   rB   rC   r0   3  s    zChannelDetailView.getc                 O   sl   |  ||}|jd}|dkr,| ||S |dkr@| ||S |dkrT| ||S t|d | ||S )z
        Handle POST requests for channel operations.
        
        Args:
            request: HTTP request object
            channel_id: Channel ID
            
        Returns:
            HttpResponse or JsonResponse based on request type
        r   update_statusZrefresh_healthr   zInvalid action requested.)r  POSTr0   Z_update_channel_statusZ_refresh_health_statusZ_export_channel_datar   r   )r=   rE   r  rU   r>   r   r   rB   rB   rC   r  ]  s    zChannelDetailView.post)rE   r  c                 C   s6   zt t|d}|W S  tjk
r0   tdY nX dS )aE  
        Get channel object with permission checks.
        
        Args:
            request: HTTP request object
            channel_id: Channel ID
            
        Returns:
            Channel: Channel object
            
        Raises:
            Http404: If channel doesn't exist or user lacks permission
        pkzChannel not foundN)r   r&   DoesNotExistr   )r=   rE   r  r   rB   rB   rC   r  v  s
    z/ChannelDetailView._get_channel_with_permissions)rE   r  rF   c                 C   s   |||  || || || || ||| ||| ||| || || 	 | 
 |  |  | |d}|| j || | |S )a(  
        Build comprehensive template context with all necessary data.
        
        Args:
            request: Django HTTP request object
            channel: Channel object
            active_tab: Currently active tab
            
        Returns:
            dict: Template context
        )r   r  rZ   codecsrecent_adbreaksrecent_jinglesr   	analyticsZperformance_metricshealth_statusmonitoring_dataZdate_range_optionsZexport_optionsZchart_configsZtab_configsbreadcrumbs)_get_channel_zones_get_channel_codecs_get_recent_adbreaks_get_recent_jingles_get_channel_statistics_get_channel_analytics_get_performance_metrics_get_health_status_get_monitoring_data_get_date_range_options_get_export_options_get_chart_configurations_get_tab_configurations_get_breadcrumbsr;   r   r:   )r=   rE   r   r  r?   rB   rB   rC   r    s(    


!z.ChannelDetailView._build_comprehensive_contextc                 C   s,   |j  djtdddtdddS )z
        Get zones associated with the channel.
        
        Args:
            channel: Channel object
            
        Returns:
            QuerySet: Channel zones with additional data
        r   adbreaksT)r   Zadbreaks__start_time)adbreak_countlast_activityr   )rZ   r]   r^   r   r   r   r   r=   r   rB   rB   rC   r*    s    


z$ChannelDetailView._get_channel_zonesc                 C   s   t |ddpg S )z
        Get codecs associated with the channel.
        
        Args:
            channel: Channel object
            
        Returns:
            QuerySet: Channel codecs
        r#  N)r   r;  rB   rB   rC   r+    s    z%ChannelDetailView._get_channel_codecsr   )limitc                 C   s@   t   tdd }tjj||ddd	dd| S )z
        Get recent adbreaks for the channel.
        
        Args:
            channel: Channel object
            limit: Number of adbreaks to return
            
        Returns:
            QuerySet: Recent adbreaks
        r   r~   r   	date__gtecampaignZadvertisements-start_timeN)
r   r   r   r   r*   r[   rn   r]   r^   r   )r=   r   r<  r   rB   rB   rC   r,    s    z&ChannelDetailView._get_recent_adbreaks   c                 C   s"   t jj|dddd| S )z
        Get recent jingles for the channel.
        
        Args:
            channel: Channel object
            limit: Number of jingles to return
            
        Returns:
            QuerySet: Recent jingles
        r   categoryr   N)r)   r[   rn   r]   r   )r=   r   r<  rB   rB   rC   r-    s    z%ChannelDetailView._get_recent_jinglesrD   c                 C   s
  |  |\}}t  }tjj|d}|j||gd}|j | t	jj|d | |j|d |j
tddd pd|j
tddd	 pd|j
tdd
d pd|j
tddd pd| |||| |||| || || ||j
tddd dS )z
        Get comprehensive channel statistics.
        
        Args:
            channel: Channel object
            request: HTTP request object
            
        Returns:
            dict: Channel statistics
        rB  )date__range)r   duration)avgrF  r   totalrH  )r   r   )r   r   
start_time)lastrJ  )total_zonestotal_adbreakstotal_jinglesr$  today_adbreaksZavg_adbreak_durationZtotal_airtimeZmax_adbreak_durationZmin_adbreak_durationZadbreaks_per_dayZ
peak_hoursZzone_distributionuptime_percentageZ
error_rater:  )_get_analysis_date_ranger   r   r   r*   r[   rn   rZ   r   r)   	aggregater   r   r   r   _calculate_adbreaks_per_day_get_peak_hours_get_zone_distribution_calculate_uptime_calculate_error_rate)r=   r   rE   rx   ry   r{   Zadbreaks_qsZrecent_adbreaks_qsrB   rB   rC   r.    sX    z)ChannelDetailView._get_channel_statisticsc              	   C   sP   |  |\}}| |||| |||| |||| |||| |||dS )z
        Get detailed analytics data for charts and graphs.
        
        Args:
            channel: Channel object
            request: HTTP request object
            
        Returns:
            dict: Analytics data for visualization
        )Zdaily_adbreaksZhourly_distributionZzone_performanceZduration_trendsZcomparison_data)rP  _get_daily_adbreaks_data_get_hourly_distribution_get_zone_performance_data_get_duration_trends_get_comparison_data)r=   r   rE   rx   ry   rB   rB   rC   r/  >  s    z(ChannelDetailView._get_channel_analyticsc                 C   s&   |  || || || |dS )z
        Get performance metrics for the channel.
        
        Args:
            channel: Channel object
            request: HTTP request object
            
        Returns:
            dict: Performance metrics
        )signal_qualityZtransmission_statsZ
error_logsZmaintenance_schedule)_get_signal_quality_get_transmission_stats_get_recent_errors_get_maintenance_schedule)r=   r   rE   rB   rB   rC   r0  S  s
    z*ChannelDetailView._get_performance_metricsr   c                 C   s|   d|j  }t|}|r|S | |t | || || || 	|| 
|| || |d	}t||d |S )z
        Get current health status of the channel.
        
        Args:
            channel: Channel object
            
        Returns:
            dict: Health status information
        channel_health_)	rt   
last_checksignal_strengthZconnectivity
disk_usagememory_usageZ	cpu_usagewarningsZrecommendations,  )r   r$   r0   _determine_health_statusr   r   _get_signal_strength_check_connectivity_get_disk_usage_get_memory_usage_get_cpu_usage_get_health_warnings_get_health_recommendationsset)r=   r   	cache_keyZcached_healthhealth_datarB   rB   rC   r1  e  s     
z$ChannelDetailView._get_health_statusc                 C   s.   |  || || || || |dS )z
        Get real-time monitoring data.
        
        Args:
            channel: Channel object
            
        Returns:
            dict: Monitoring data
        )live_statusZcurrent_broadcastZupcoming_schedulealertssystem_metrics)_get_live_status_get_current_broadcast_get_upcoming_schedule_get_active_alerts_get_system_metricsr;  rB   rB   rC   r2    s    z&ChannelDetailView._get_monitoring_datac                 C   sD  |j dd}|j d}|j d}t  }|r~|r~z.tj|d }tj|d }||fW S  tk
r|   Y nX |dkr||fS |dkr|tdd	 }||fS |dkr|td
d	 |fS |dkr|tdd	 |fS |dk r|j	dd}	|	|fS |dkr2|j	ddtdd	 }
|
j	dd}||
fS |td
d	 |fS )z
        Get date range for analysis from request parameters.
        
        Args:
            request: HTTP request object
            
        Returns:
            tuple: (date_from, date_to)
        rz   last_7_daysrx   ry   r   r{   r}   rJ   r~   r   r   r   r   r   
last_month)
rO   r0   r   r   r   r   r   r   r   r   )r=   rE   rz   Zdate_from_strZdate_to_strr{   rx   ry   r}   r   Zlast_month_endZlast_month_startrB   rB   rC   rP    s8    



z*ChannelDetailView._get_analysis_date_rangec                 C   s   |  ||}|jd}|dkr,| ||S |dkr@| ||S |dkrT| ||S |dkrh| ||S |dkr|| ||S tddd	S )
z
        Handle AJAX requests for dynamic updates.
        
        Args:
            request: Django HTTP request object
            channel_id: Channel ID
            
        Returns:
            JsonResponse: JSON response with requested data
        r   Zget_health_statusZget_analytics_dataZget_live_statsget_recent_activityZrefresh_monitoringFzInvalid actionr   )	r  rO   r0   _get_health_status_ajax_get_analytics_data_ajax_get_live_stats_ajax_get_recent_activity_ajax_refresh_monitoring_ajaxr
   )r=   rE   r  r   r   rB   rB   rC   rL     s    z&ChannelDetailView._handle_ajax_requestc                 C   s   |  |}td|dS )z
        Get health status via AJAX.
        
        Args:
            request: HTTP request object
            channel: Channel object
            
        Returns:
            JsonResponse: Health status data
        T)r   r'  )r1  r
   )r=   rE   r   rr  rB   rB   rC   r~    s
    
z)ChannelDetailView._get_health_status_ajaxc                 C   s   |  ||}td|dS )z
        Get analytics data via AJAX for dynamic chart updates.
        
        Args:
            request: HTTP request object
            channel: Channel object
            
        Returns:
            JsonResponse: Analytics data
        T)r   r&  )r/  r
   )r=   rE   r   Zanalytics_datarB   rB   rC   r    s
    z*ChannelDetailView._get_analytics_data_ajaxc              	   C   s^   |  ||}| |}td|di dd|dd|dd|di d	d
ddS )z
        Get live statistics via AJAX.
        
        Args:
            request: HTTP request object
            channel: Channel object
            
        Returns:
            JsonResponse: Live statistics
        Trs  viewersr   rN  rO  r   ru  rc  Good)Zcurrent_viewersZadbreaks_todayrO  r\  )r   Z
live_stats)r.  r2  r
   r0   )r=   rE   r   r   Z
monitoringrB   rB   rC   r    s    


z&ChannelDetailView._get_live_stats_ajaxc           	   
   C   s   |  |d}| |d}g }|D ]R}||j|jr<|j nd|jrNt|jndt|drht	|j
ddndd q g }|D ]B}||jt	|ddtt	|d	dt|d
r|j ndd q|td||ddS )z
        Get recent activity via AJAX.
        
        Args:
            request: HTTP request object
            channel: Channel object
            
        Returns:
            JsonResponse: Recent activity data
        rA     Nr   r?  r   rg   )r   rI  rE  campaign_namerE  r   )r   r   rE  r   T)r8  jingles)r   recent_activity)r,  r-  r   r   rI  r   rE  floatr   r   r?  r   r
   )	r=   rE   r   r$  r%  Zadbreaks_dataadbreakZjingles_datajinglerB   rB   rC   r    s0    


z+ChannelDetailView._get_recent_activity_ajaxc                 C   sD   d|j  }t| | |}| |}td||t  dS )z
        Refresh monitoring data via AJAX.
        
        Args:
            request: HTTP request object
            channel: Channel object
            
        Returns:
            JsonResponse: Updated monitoring data
        ra  T)r   r'  r(  Zlast_updated)	r   r$   deleter1  r2  r
   r   r   r   )r=   rE   r   rq  r'  r(  rB   rB   rC   r  G  s    



z*ChannelDetailView._refresh_monitoring_ajaxc                 C   s@   || j d }tjj|||gd }|dkr<t|| dS dS )z7Calculate average adbreaks per day in the given period.rJ   )r   rD  r      )r   r*   r[   rn   r   round)r=   r   rx   ry   Z
total_daysrL  rB   rB   rC   rR  b  s    
z-ChannelDetailView._calculate_adbreaks_per_dayc                 C   s
   dddgS )zGet peak hours for adbreaks.z18:00-19:00z20:00-21:00z21:00-22:00rB   r=   r   rx   ry   rB   rB   rC   rS  k  s    z!ChannelDetailView._get_peak_hoursc                 C   s   |j jtddddS )z*Get distribution of adbreaks across zones.r8  )r9  r   r9  )rZ   r   r   r   r;  rB   rB   rC   rT  q  s     z(ChannelDetailView._get_zone_distributionc                 C   s   dS )z$Calculate channel uptime percentage.g     X@rB   r;  rB   rB   rC   rU  w  s    z#ChannelDetailView._calculate_uptimec                 C   s   dS )z Calculate error rate percentage.g{Gz?rB   r;  rB   rB   rC   rV  |  s    z'ChannelDetailView._calculate_error_ratec                 C   s   dS )z/Determine overall health status of the channel.healthyrB   r;  rB   rB   rC   rh    s    z*ChannelDetailView._determine_health_statusc                 C   s   dS )zGet current signal strength._   rB   r;  rB   rB   rC   ri    s    z&ChannelDetailView._get_signal_strengthc                 C   s   dS )z"Check channel connectivity status.TrB   r;  rB   rB   rC   rj    s    z%ChannelDetailView._check_connectivityc                 C   s   dS )zGet disk usage percentage.-   rB   r;  rB   rB   rC   rk    s    z!ChannelDetailView._get_disk_usagec                 C   s   dS )zGet memory usage percentage.H   rB   r;  rB   rB   rC   rl    s    z#ChannelDetailView._get_memory_usagec                 C   s   dS )zGet CPU usage percentage.#   rB   r;  rB   rB   rC   rm    s    z ChannelDetailView._get_cpu_usagec                 C   s   g S )zGet current health warnings.rB   r;  rB   rB   rC   rn    s    z&ChannelDetailView._get_health_warningsc                 C   s   g S )zGet health recommendations.rB   r;  rB   rB   rC   ro    s    z-ChannelDetailView._get_health_recommendationsc                 C   s
   dddS )zGet live broadcasting status.Ti  )Zis_liver  rB   r;  rB   rB   rC   rv    s    z"ChannelDetailView._get_live_statusc                 C   s   dt  dS )z"Get current broadcast information.z	News Hour)programZ
started_at)r   r   r;  rB   rB   rC   rw    s    z(ChannelDetailView._get_current_broadcastc                 C   s   g S )z Get upcoming broadcast schedule.rB   r;  rB   rB   rC   rx    s    z(ChannelDetailView._get_upcoming_schedulec                 C   s   g S )z"Get active alerts for the channel.rB   r;  rB   rB   rC   ry    s    z$ChannelDetailView._get_active_alertsc                 C   s
   dddS )zGet system metrics.r  Normal)rc  ZtemperaturerB   r;  rB   rB   rC   rz    s    z%ChannelDetailView._get_system_metricsc                 C   s   g S )z#Get daily adbreaks data for charts.rB   r  rB   rB   rC   rW    s    z*ChannelDetailView._get_daily_adbreaks_datac                 C   s   g S )zGet hourly distribution data.rB   r  rB   rB   rC   rX    s    z*ChannelDetailView._get_hourly_distributionc                 C   s   g S )zGet zone performance data.rB   r  rB   rB   rC   rY    s    z,ChannelDetailView._get_zone_performance_datac                 C   s   g S )zGet duration trends data.rB   r  rB   rB   rC   rZ    s    z&ChannelDetailView._get_duration_trendsc                 C   s   g S )z*Get comparison data with previous periods.rB   r  rB   rB   rC   r[    s    z&ChannelDetailView._get_comparison_datac                 C   s   ddddS )zGet signal quality metrics.r  b   a   )ZstrengthZ	stabilityZclarityrB   r;  rB   rB   rC   r]    s    z%ChannelDetailView._get_signal_qualityc                 C   s   ddddS )zGet transmission statistics.i@B 2      )Zpackets_sentZpackets_lostZlatencyrB   r;  rB   rB   rC   r^    s    z)ChannelDetailView._get_transmission_statsc                 C   s   g S )zGet recent error logs.rB   r;  rB   rB   rC   r_    s    z$ChannelDetailView._get_recent_errorsc                 C   s   g S )zGet maintenance schedule.rB   r;  rB   rB   rC   r`    s    z+ChannelDetailView._get_maintenance_schedulec              	   C   s<   ddddddddddd	dd
ddddddddgS )z%Get date range options for filtering.r{   Todayr   r}   	Yesterdayr{  zLast 7 Daysr   zLast 30 Daysr   z
This Monthr|  z
Last MonthcustomzCustom RangerB   r   rB   rB   rC   r3    s    z)ChannelDetailView._get_date_range_optionsc                 C   s$   ddddddddddd	dgS )
zGet export format options.Zpdfz
PDF Reportr   csvzCSV Datajsonz	JSON DataexcelzExcel SpreadsheetrB   r   rB   rB   rC   r4    s
    z%ChannelDetailView._get_export_optionsc                 C   s   dddddgddddS )	z!Get chart configuration settings.z#3B82F6z#10B981z#F59E0Bz#EF4444z#8B5CF6lightT)colorstheme	animationZ
responsiverB   r   rB   rB   rC   r5    s
    z+ChannelDetailView._get_chart_configurationsc              	   C   s@   dddddddddd	d
dddddddddddddgS )zGet tab configuration settings.r  ZOverviewz	chart-bar)r   r   iconr&  	Analyticsztrending-uprZ   Zonesmapr8  AdbreaksZplayr  JinglesmusichealthZHealthZheartrB   r   rB   rB   rC   r6    s    





z)ChannelDetailView._get_tab_configurationsc                 C   s    dddddd|j dddgS )	zGet breadcrumb navigation.	Dashboardz/dashboard/)r   urlr8   z
/channels/NT)r   r  r   r   r;  rB   rB   rC   r7    s    z"ChannelDetailView._get_breadcrumbsNc                 C   sp   |j }tj|dd|r|jnd d|j d|t||jddt|j	|j|j
dd	|j
d
ddd dS )z
        Log user activity for auditing purposes.
        
        Args:
            request (HttpRequest): The HTTP request object
            channel: Channel object
            
        Returns:
            None
        Zview_channel_detailr  r  z viewed channel z detailsr  rg   r  r  rz   r{  )r  r  r  rz   r  N)r   r.   r  r	  r   r%   r
  r0   r  r   rO   )r=   rE   r   r   rB   rB   rC   rR   !  s    z$ChannelDetailView._log_user_activity)r   )rA  )Gr  r  r  r  r  rT   r   r:   r   r   r	   r0   r   r
   r  r  r  r   r   r  r*  r+  r,  r-  r.  r/  r0  r1  r2  tuplerP  rL   r~  r  r  r  r  rR  rS  rT  rU  rV  rh  ri  rj  rk  rl  rm  rn  ro  rv  rw  rx  ry  rz  rW  rX  rY  rZ  r[  r]  r^  r_  r`  r3  r4  r5  r6  r7  rR   r  rB   rB   r@   rC   r    s|   *28".)			r  c                   @   s0   e Zd ZdZeedddZeedddZdS )ChannelCreateViewa_  View for creating new channels.
    
    Handles both GET requests to display the creation form and POST requests
    to process form submission and create new channel instances.
    
    Methods:
        get: Display channel creation form
        post: Process form submission and create channel
        
    Template: channels/channel_form.html
    rD   c                 C   s   t jt jddd}t|d|S )zDisplay channel creation form.
        
        Args:
            request: HTTP request object
            
        Returns:
            HttpResponse: Rendered template with empty form
        zCreate New ChannelzCreate Channel)r   r   
form_titlesubmit_textchannels/channel/form.html)r&   r   r   r   )r=   rE   r?   rB   rB   rC   r0   K  s    
zChannelCreateView.getc                 C   s  z<|j dd }|jd}|j dd }|j d}|j d}|j dd}|j d	d }|j d
d }	|j dd }
|j dd }|j dd }|j ddk}|st|d | |W S |s|}tjj||||rt	|nd||||	|
|||d}t
|d|j d td|jdW S  tk
r } z$t|d|  | | W Y S d}~X Y nD tk
r } z$t|d|  | | W Y S d}~X Y nX dS )zProcess channel creation form submission.
        
        Args:
            request: HTTP request object with form data
            
        Returns:
            HttpResponse: Redirect to channel detail on success, or form with errors
        r   rg   logor   channel_numberrr   rt   r   r5   websitelanguagerC  target_audiencesupports_daionzChannel name is required.N)r   r  r   r  rr   rt   r5   r  r  rC  r  r  	Channel "" created successfully.channels:channel_detailr  Validation error: zError creating channel: )r  r0   rm   FILESr   r   r&   r[   creater   r   r   r   r!  r   	Exception)r=   rE   r   r  r   r  rr   rt   r5   r  r  rC  r  r  r   erB   rB   rC   r  \  sP    	zChannelCreateView.postNr  r  r  r  r   r	   r0   r  rB   rB   rB   rC   r  >  s   r  c                   @   s4   e Zd ZdZeeedddZeeedddZdS )ChannelUpdateViewa\  View for updating existing channels.
    
    Handles both GET requests to display the update form pre-filled with
    current channel data and POST requests to process updates.
    
    Methods:
        get: Display channel update form
        post: Process form submission and update channel
        
    Template: channels/channel_form.html
    r  c                 C   s4   t t|d}|tjtjd|j dd}t|d|S )aV  Display channel update form.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of channel to update
            
        Returns:
            HttpResponse: Rendered template with pre-filled form
            
        Raises:
            Http404: If channel with given ID doesn't exist
        r   zUpdate Channel: zUpdate Channel)r   r   r   r  r  r  )r   r&   r   r   r   r   )r=   rE   r  r   r?   rB   rB   rC   r0     s    
zChannelUpdateView.getc              
   C   s  t t|d}zR|jdd p&|j|_|jdd p@|j|_|jd}|r^t||_|jdpn|j	|_	|jdp|j
|_
|jdd |_|jd	d |_|jd
d |_|jdd |_|jdd |_|jddk|_|jd}|rt||_|jd}|r4t||_|  t|d|j d td|jdW S  tk
r } z&t|d|  | || W Y S d}~X Y nF tk
r } z&t|d|  | || W Y S d}~X Y nX dS )a  Process channel update form submission.
        
        Args:
            request: HTTP request object with form data
            channel_id: Primary key of channel to update
            
        Returns:
            HttpResponse: Redirect to channel detail on success, or form with errors
            
        Raises:
            Http404: If channel with given ID doesn't exist
        r   r   rg   r   r  rr   rt   r5   r  r  rC  r  r  r  max_ad_duration
min_ad_gapr  " updated successfully.r  r  r  NzError updating channel: )r   r&   r  r0   rm   r   r   r   r  rr   rt   r5   r  r  rC  r  r  r  r  saver   r   r   r!  r   r   r  )r=   rE   r  r   r  r  r  r  rB   rB   rC   r    s<    


 zChannelUpdateView.postN	r  r  r  r  r   r   r	   r0   r  rB   rB   rB   rC   r    s   r  c                   @   s4   e Zd ZdZeeedddZeeedddZdS )ChannelDeleteViewa6  View for deleting channels.
    
    Handles both GET requests to display confirmation page and POST requests
    to perform the actual deletion.
    
    Methods:
        get: Display deletion confirmation
        post: Process deletion request
        
    Template: channels/channel_confirm_delete.html
    r  c                 C   sH   t t|d}tjj|d }tjj|d }|||d}t|d|S )aX  Display channel deletion confirmation.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of channel to delete
            
        Returns:
            HttpResponse: Rendered confirmation template
            
        Raises:
            Http404: If channel with given ID doesn't exist
        r   rB  )r   adbreaks_countjingles_countz$channels/channel/confirm_delete.html)r   r&   r*   r[   rn   r   r)   r   )r=   rE   r  r   r  r  r?   rB   rB   rC   r0     s    zChannelDeleteView.getc              
   C   sp   t t|d}|j}z |  t|d| d W n4 tk
rf } zt|d|  W 5 d}~X Y nX tdS )a\  Process channel deletion request.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of channel to delete
            
        Returns:
            HttpResponse: Redirect to channel list after deletion
            
        Raises:
            Http404: If channel with given ID doesn't exist
        r   r  " deleted successfully.zError deleting channel: Nzchannels:channel_list)	r   r&   r   r  r   r   r  r   r   )r=   rE   r  r   r  r  rB   rB   rC   r    s    $zChannelDeleteView.postNr  rB   rB   rB   rC   r    s   r  c                   @   s"   e Zd ZdZeeedddZdS )JingleListViewa  View for displaying a list of jingles for a specific channel.
    
    Shows paginated jingles with filtering options by type and placement.
    
    Methods:
        get: Handle GET requests to display jingle list
        
    Template: channels/jingle_list.html
    r  c                 C   s   t t|d}|jdd}|jdd}|jdd}t|jdd}tjj|d	}|rf|j|d
}|rv|j|d}|d}t	||}	z|	
|}
W n< tk
r   |	
d}
Y n  tk
r   |	
|	j}
Y nX ||
tjtj|||	jd}t|d|S )aZ  Handle GET request to display jingle list.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of the channel
            
        Returns:
            HttpResponse: Rendered template with jingle list
            
        Raises:
            Http404: If channel with given ID doesn't exist
        r   rp   rg   	placementrI   rJ   r   r   rB  rp   r  r   )r   r  jingle_typesPLACEMENT_TYPESselected_typeZselected_placementrM  zchannels/jingle/list.html)r   r&   rO   r0   r   r)   r[   rn   r   r   rI   r   r   rQ   JINGLE_TYPESr  r   r   )r=   rE   r  r   jingle_typer  rI   r   r  rW   jingles_pager?   rB   rB   rC   r0   =  s6    


zJingleListView.getNr  r  r  r  r   r   r	   r0   rB   rB   rB   rC   r  2  s   
r  c                   @   s"   e Zd ZdZeeedddZdS )AdbreakListViewa
  View for displaying adbreaks for a specific channel.
    
    Shows paginated adbreaks with filtering by date range, type, and category.
    
    Methods:
        get: Handle GET requests to display adbreak list
        
    Template: channels/adbreak_list.html
    r  c              
   C   sT  t t|d}|jd}|jd}|jdd}|jdd}|jdd}t|jd	d
}	|s~t  tdd 	 }|st  	 }t
jj|||d}
|r|
j|d}
|r|
j|d}
|
dd}
t|
|	}z||}W n@ tk
r   |d}Y n" tk
r(   ||j}Y nX ||t
jt
j|||||jd	}t|d|S )a\  Handle GET request to display adbreak list.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of the channel
            
        Returns:
            HttpResponse: Rendered template with adbreak list
            
        Raises:
            Http404: If channel with given ID doesn't exist
        r   
start_dateend_daterp   rg   rC  rI   rJ   r   r  r   r~   r   r>  	date__lter  rC  -dater@  )	r   r8  adbreak_typescategory_choicesr  r  r  Zselected_categoryrL  zchannels/adbreak/list.html)r   r&   rO   r0   r   r   r   r   r   r   r*   r[   rn   r   r   rI   r   r   rQ   ADBREAK_TYPE_CHOICESCATEGORY_CHOICESr   r   )r=   rE   r  r   r  r  adbreak_typerC  rI   r   r8  rW   adbreaks_pager?   rB   rB   rC   r0   ~  sN    
zAdbreakListView.getNr  rB   rB   rB   rC   r  s  s   
r  c                   @   s4   e Zd ZdZeeedddZeeedddZ	dS )ChannelHealthViewa  View for monitoring channel health status.
    
    Displays real-time health information and recent health check history.
    
    Methods:
        get: Display channel health dashboard
        post: Trigger manual health check
        
    Template: channels/channel_health.html
    r  c           
      C   s   t t|d}t }|tdd }tjj|| d	 }d}|j
r||j
 }|tddk rl|jrfdnd	}n|td
dk rd}nd}||||j
|jd}	t|d|	S )aX  Display channel health dashboard.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of the channel
            
        Returns:
            HttpResponse: Rendered template with health information
            
        Raises:
            Http404: If channel with given ID doesn't exist
        r      )hoursr=  unknownrA  minutesr  offline   warningcritical)r   r'  r$  rb  r   zchannels/channel/health.html)r   r&   r   r   r   r*   r[   rn   r   r   last_health_checkr   r   )
r=   rE   r  r   r   Zlast_24hr$  r'  time_since_checkr?   rB   rB   rC   r0     s,    

zChannelHealthView.getc              
   C   s   t t|d}z,| }td|r"dndt  ddW S  tk
r~ } z(tdt|t  dd	d
 W Y S d}~X Y nX dS )aN  Trigger manual health check for the channel.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of the channel
            
        Returns:
            JsonResponse: Health check results
            
        Raises:
            Http404: If channel with given ID doesn't exist
        r   Tr  r  z#Health check completed successfully)r   rt   	timestampr   F)r   r   r    ru   N)	r   r&   check_healthr
   r   r   r   r  r  )r=   rE   r  r   Zhealth_resultr  rB   rB   rC   r    s"    



zChannelHealthView.postN)
r  r  r  r  r   r   r	   r0   r
   r  rB   rB   rB   rC   r    s   -r  r  r  c                   @   s(   e Zd ZdZdeee edddZdS )ChannelAPIViewaz  RESTful API view for channel operations.
    
    Provides JSON API endpoints for channel CRUD operations.
    Supports GET (list/detail), POST (create), PUT (update), DELETE operations.
    
    Methods:
        get: Retrieve channel(s) as JSON
        post: Create new channel via JSON
        put: Update existing channel via JSON
        delete: Delete channel via JSON
    Nr  c                 C   s  zH|rt t|d}|j|j|j|j|j|j|j|j	|j
|j|j|j|j|j|j|jr`|j nd|j |j d}t|W S tj d}|jd}|r|t|dt|dB }|jd}|r|j|d	}t|jd
d}t|jdd}	t||	}
|
|}dd |D ||	|
j |
j!|" |# dd}t|W S W n< t$k
r } ztdt%|idd W Y S d}~X Y nX dS )a  Retrieve channel(s) as JSON.
        
        Args:
            request: HTTP request object
            channel_id: Optional channel ID for single channel retrieval
            
        Returns:
            JsonResponse: Channel data or list of channels
        r   N)r   r   r   r  rr   rt   r5   r  r  rC  r  r  r  r  r   r  r   r   r   rf   rh   rj   rp   rq   rI   rJ   r   r   c              
   S   s.   g | ]&}|j |j|j|j|j|j|jd qS r   r   r   r  rr   rt   r   r  r   r   rB   rB   rC   r   h  s   
z&ChannelAPIView.get.<locals>.<listcomp>rI   r   rH  Zpagesr   r   r2   
paginationr   r  ru   )&r   r&   r   r   r   r  rr   rt   r5   r  r  rC  r  r  r  r  r   r  r   r   r   r
   r[   r\   r   rO   r0   rn   r   r   r   rI   r   rQ   r   r   r  r  )r=   rE   r  r   datar2   rf   rr   rI   r   rW   channels_pager  rB   rB   rC   r0   -  sh    




zChannelAPIView.get)N)	r  r  r  r  r   r   r   r
   r0   rB   rB   rB   rC   r    s   r  c                   @   s    e Zd ZdZeedddZdS )JingleAPIListViewzAPI view for listing all jingles.
    
    Provides JSON endpoint for retrieving all jingles with optional filtering.
    
    Methods:
        get: Retrieve all jingles as JSON
    rD   c              
   C   s  z|j d}|j d}|j d}tj }|r@|j|d}|rP|j|d}|r`|j|d}|d}t|j dd	}t|j d
d}t||}|	|}	dd |	D |||j
|j|	 |	 dd}
t|
W S  tk
r } ztdt|idd W Y S d}~X Y nX dS )zRetrieve all jingles as JSON.
        
        Args:
            request: HTTP request object
            
        Returns:
            JsonResponse: List of all jingles
        rp   r  r   r  r  r  r   rI   rJ   r   r   c                 S   sL   g | ]D}t |j|j|j|j|jt |jj|jj|jjd |j	 dqS )r   r   r   )r   r   rp   r  rE  r   r   )
r  r   r   rp   r  rE  r   r   r   r   r   r  rB   rB   rC   r     s   
z)JingleAPIListView.get.<locals>.<listcomp>rI   r   r   total_countr   r   )r  r  r   r  ru   N)rO   r0   r)   r[   r\   rn   r   r   r   rI   rQ   r   r   r   r
   r  r  )r=   rE   r  r  r  r  rI   r   rW   r  r  r  rB   rB   rC   r0     s<    	




zJingleAPIListView.getNr  r  r  r  r   r
   r0   rB   rB   rB   rC   r     s   r   c                   @   s"   e Zd ZdZeeedddZdS )ChannelJinglesAPIViewzAPI view for retrieving jingles for a specific channel.
    
    Provides JSON endpoint for getting all jingles associated with a channel.
    
    Methods:
        get: Retrieve jingles for a channel as JSON
    r  c           	   
   C   s   zt t|d}tjj|d}|jd}|r8|j|d}|jd}|rT|j|d}|d}t|j	|j
|jdd	d
 |D | d}t|W S  tk
r } ztdt|idd W Y S d}~X Y nX dS )T  Retrieve jingles for a channel as JSON.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of the channel
            
        Returns:
            JsonResponse: List of jingles for the channel
            
        Raises:
            Http404: If channel with given ID doesn't exist
        r   rB  rp   r  r  r  r   r  c              
   S   s6   g | ].}t |j|j|j|j|j|j|j d qS ))r   r   rp   r  rE  	file_pathr   )	r  r   r   rp   r  rE  r  r   r   r  rB   rB   rC   r     s   
z-ChannelJinglesAPIView.get.<locals>.<listcomp>)r   r  rM  r   r  ru   N)r   r&   r)   r[   rn   rO   r0   r   r  r   r   r   r   r
   r  )	r=   rE   r  r   r  r  r  r  r  rB   rB   rC   r0     s,    


zChannelJinglesAPIView.getNr  r  r  r  r   r  r
   r0   rB   rB   rB   rC   r    s   r  c                   @   s    e Zd ZdZeedddZdS )AdbreakAPIListViewzAPI view for listing all adbreaks.
    
    Provides JSON endpoint for retrieving all adbreaks with optional filtering.
    
    Methods:
        get: Retrieve all adbreaks as JSON
    rD   c              
   C   sv  z2|j d}|j d}|j d}|j d}|j d}|s^t  tdd  }|srt   }tjj	||d}|r|j	|d	}|r|j	|d
}|r|j	|d}|
dd}t|j dd}t|j dd}	t||	}
|
|}dd |D ||	|
j|
j| | d||dd}t|W S  tk
rp } ztdt|idd W Y S d}~X Y nX dS )zRetrieve all adbreaks as JSON.
        
        Args:
            request: HTTP request object
            
        Returns:
            JsonResponse: List of all adbreaks
        r  r  r   rp   rC  r   r~   )r>  r  r  r  r  r  r@  rI   rJ   r   r  c                 S   sb   g | ]Z}t |j|j |j |jr0|j nd |j|j|jt |j	j|j	j
|j	jddqS )Nr  )r   r   rI  end_timerE  rp   rC  r   )r  r   r   r   rI  r  rE  rp   rC  r   r   r   r   r  rB   rB   rC   r   G	  s   
z*AdbreakAPIListView.get.<locals>.<listcomp>r  r  r  )r8  r  rz   r   r  ru   N)rO   r0   r   r   r   r   r   r*   r[   rn   r   r   r   rI   rQ   r   r   r   r
   r  r  )r=   rE   r  r  r  r  rC  r8  rI   r   rW   r  r  r  rB   rB   rC   r0   	  sT    	

	 
zAdbreakAPIListView.getNr  rB   rB   rB   rC   r
  	  s   r
  c                   @   s"   e Zd ZdZeeedddZdS )ChannelAdbreaksAPIViewzAPI view for retrieving adbreaks for a specific channel.
    
    Provides JSON endpoint for getting all adbreaks associated with a channel.
    
    Methods:
        get: Retrieve adbreaks for a channel as JSON
    r  c              
   C   sh  z$t t|d}|jd}|jd}|sFt  tdd  }|sZt   }t	j
j|||d}|jd}|r|j|d}|jd	}|r|j|d
}|dd}tdd |D }	|r|	t| nd}
t|j|j|jddd |D | t|	dt|
dd||dd}t|W S  tk
rb } ztdt|idd W Y S d}~X Y nX dS )aV  Retrieve adbreaks for a channel as JSON.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of the channel
            
        Returns:
            JsonResponse: List of adbreaks for the channel
            
        Raises:
            Http404: If channel with given ID doesn't exist
        r   r  r  r   r~   r  rp   r  rC  r  r  r@  c                 s   s   | ]}|j pd V  qdS r   NrE  r   abrB   rB   rC   	<genexpr>	  s     z-ChannelAdbreaksAPIView.get.<locals>.<genexpr>r   r  c              
   S   sH   g | ]@}t |j|j |j |jr0|j nd |j|j|jdqS N)r   r   rI  r  rE  rp   rC  )	r  r   r   r   rI  r  rE  rp   rC  r  rB   rB   rC   r   	  s   
z.ChannelAdbreaksAPIView.get.<locals>.<listcomp>r  rL  total_durationZaverage_durationr  )r   r8  
statisticsrz   r   r  ru   N)r   r&   rO   r0   r   r   r   r   r   r*   r[   rn   r   sumlenr  r   r   r   r   r  r
   r  )r=   rE   r  r   r  r  r8  r  rC  r  avg_durationr  r  rB   rB   rC   r0   u	  sP    

zChannelAdbreaksAPIView.getNr	  rB   rB   rB   rC   r  l	  s   r  c                   @   s    e Zd ZdZeedddZdS )ChannelHealthAPIViewzAPI view for channel health monitoring.
    
    Provides JSON endpoint for retrieving health status of all channels.
    
    Methods:
        get: Retrieve channel health data as JSON
    rD   c                 C   s  zXt j d}|jd}|r0|j|d}|jd}|dk	r\| dk}|j|d}g }|D ]z}|j}|rt	
 | }	|	 dk rd	nd
}
|	 dkrd}
nd}
|t|j|j|j|j|j|
|r| nddd qdt|}tdd |D }tdd |D }||||| ||| t|dkr8|| d ndddt	
  d}t|W S  tk
r } ztdt|idd W Y S d}~X Y nX dS )zRetrieve channel health data as JSON.
        
        Args:
            request: HTTP request object
            
        Returns:
            JsonResponse: Health status of all channels
        r   rt   ru   onlineNtruer   rg  r  r  X  r  r       W@)r   r   r   rt   r   r'  r  rO  c                 s   s   | ]}|d  rdV  qdS )r   rJ   NrB   r   chrB   rB   rC   r  	  s      z+ChannelHealthAPIView.get.<locals>.<genexpr>c                 s   s   | ]}|d  dkrdV  qdS )r'  r  rJ   NrB   r   rB   rB   rC   r   
  s      r   r   rJ   )r   r   r   healthy_channelsZunhealthy_channelsoverall_health_percentage)r2   summarygenerated_atr   r  )r&   r[   r\   r   rO   r0   rn   lowerr  r   r   total_secondsr   r  r   r   r   rt   r   r   r  r  r  r
   r  )r=   rE   r2   rv   Zonline_filterr   rr  r   rb  r  r'  r   r   r"  r  r  rB   rB   rC   r0   	  sX    	


zChannelHealthAPIView.getNr  rB   rB   rB   rC   r  	  s   r  c                   @   s    e Zd ZdZeedddZdS )ChannelHealthDashboardViewa  View for displaying channel health monitoring dashboard.
    
    Shows comprehensive health status and monitoring information for all channels.
    
    Methods:
        get: Display health dashboard
        
    Template: channels/health_dashboard.html
    rD   c                 C   s  t j d}| }|jdd }|| }d}d}d}d}	|D ]X}
|
j}|rt | }|	 dk rt|d7 }q|	 dk r|d7 }q|d7 }qD|	d7 }	qDt t
dd	 d
dddt t
dd	 ddddg}||||||||	t|dkr|| d ndd|d
}t|d|S )zHandle GET request to display health dashboard.
        
        Args:
            request: HTTP request object
            
        Returns:
            HttpResponse: Rendered template with health dashboard
        r   Tr   r   rg  rJ   r  rA  r  z	Channel 1zHealth check passedr   )r  r   eventrt   r  z	Channel 2zConnection timeoutr  r   )
r2   r   r   r   r"  warning_channelscritical_channelsunknown_channelsr#  recent_eventszchannels/health_dashboard.html)r&   r[   r\   r   r   rn   r  r   r   r'  r   r  r   )r=   rE   r2   r   r   r   r"  r*  r+  r,  r   rb  r  r-  r?   rB   rB   rC   r0    
  sR    	



zChannelHealthDashboardView.getN)r  r  r  r  r   r	   r0   rB   rB   rB   rC   r(  
  s   
r(  c                   @   s    e Zd ZdZeedddZdS )ChannelAPIListViewzAPI view for listing all channels.
    
    Provides JSON endpoint for retrieving all channels with optional filtering.
    
    Methods:
        get: Retrieve all channels as JSON
    rD   c              
   C   s.  z|j dd }|j d}|j d}tj }|rT|t|dt|dB }|rd|j|d}|rt|j|d}|d	}t	|j d
d}t	|j dd}t
||}||}	dd |	D |||j|j|	 |	 dd}
t|
W S  tk
r( } ztdt|idd W Y S d}~X Y nX dS )zRetrieve all channels as JSON.
        
        Args:
            request: HTTP request object
            
        Returns:
            JsonResponse: List of all channels
        rf   rg   rp   rt   rh   rj   rq   ru   r   rI   rJ   r   r   c                 S   sL   g | ]D}t |j|j|j|j|j|j|j|j|j	|j
r@|j
 nd d
qS )N)
r   r   r   r  rr   rt   r   r  rC  r  )r  r   r   r   r  rr   rt   r   r  rC  r  r   r  rB   rB   rC   r   
  s   z*ChannelAPIListView.get.<locals>.<listcomp>r  r  r   r  N)rO   r0   rm   r&   r[   r\   rn   r   r   r   r   rI   rQ   r   r   r   r
   r  r  )r=   rE   ro   rr   rt   r2   rI   r   rW   r  r  r  rB   rB   rC   r0   l
  sD    	




zChannelAPIListView.getNr  rB   rB   rB   rC   r.  c
  s   r.  c                   @   s"   e Zd ZdZeeedddZdS )ChannelAPIDetailViewzAPI view for retrieving detailed channel information.
    
    Provides JSON endpoint for getting detailed information about a specific channel.
    
    Methods:
        get: Retrieve channel details as JSON
    rE   r!  rF   c           	      C   s$  zt t|d}t|jddd}tjj|ddddd	 }t	jj|d
 }t|j|j|j|j|j|j|j|jr|jjnd|j|j|j|j|j|j|j|j|jr|j nd|j |j  ||d
d |D d}t!|W S  t"k
r } zt!dt|idd W Y S d}~X Y nX dS )aC  Retrieve channel details as JSON.
        
        Args:
            request: HTTP request object
            pk: Primary key of the channel
            
        Returns:
            JsonResponse: Detailed channel information
            
        Raises:
            Http404: If channel with given ID doesn't exist
        r   r   r   r5   rB  r  r@  NrA  c                 S   s2   g | ]*}t |j|j |j |j|jd qS ))r   r   rI  rE  rp   )r  r   r   r   rI  rE  rp   r  rB   rB   rC   r   
  s   z,ChannelAPIDetailView.get.<locals>.<listcomp>)r   r   r   r  rr   rt   r   r  r5   r  r  rC  r  r  r  r  r  r   r   rZ   r  r$  r   r  ru   )#r   r&   r   rZ   r   r*   r[   rn   r   r)   r   r  r   r   r   r  rr   rt   r   r  r  r5   r  r  rC  r  r  r  r  r  r   r   r   r
   r  )	r=   rE   r!  r   rZ   r$  r  r  r  rB   rB   rC   r0   
  sB    "
zChannelAPIDetailView.getNr	  rB   rB   rB   rC   r/  
  s   r/  c                   @   s    e Zd ZdZeedddZdS )ChannelZoneAPIListViewzAPI view for listing all channel zones.
    
    Provides JSON endpoint for retrieving all zones with optional filtering.
    
    Methods:
        get: Retrieve all zones as JSON
    rD   c           
   
   C   s   z|j dd }tj }|r<|t|dt|dB }|d}t	|j dd}t	|j dd	}t
||}||}d
d |D |||j|j| | dd}t|W S  tk
r }	 ztdt|	idd W Y S d}	~	X Y nX dS )zRetrieve all zones as JSON.
        
        Args:
            request: HTTP request object
            
        Returns:
            JsonResponse: List of all zones
        rf   rg   rh   rk   r   rI   rJ   r   r   c                 S   s2   g | ]*}t |j|j|j|j |j d qS ))r   r   r5   channels_countr   )r  r   r   r5   r2   r   r   r   )r   rw   rB   rB   rC   r     s   z.ChannelZoneAPIListView.get.<locals>.<listcomp>r  )rZ   r  r   r  ru   N)rO   r0   rm   r'   r[   r\   rn   r   r   r   r   rI   rQ   r   r   r   r
   r  r  )
r=   rE   ro   rZ   rI   r   rW   
zones_pager  r  rB   rB   rC   r0      s8    	




zChannelZoneAPIListView.getNr  rB   rB   rB   rC   r1  
  s   r1  c                   @   s"   e Zd ZdZeeedddZdS )ZoneChannelsAPIViewzAPI view for retrieving channels in a specific zone.
    
    Provides JSON endpoint for getting all channels associated with a zone.
    
    Methods:
        get: Retrieve channels in a zone as JSON
    )rE   zone_idrF   c              
   C   s   zVt t|d}tjj|dd}t|j|j|j	ddd |D |
 d}t|W S  tk
r } ztdt|id	d
 W Y S d}~X Y nX dS )aE  Retrieve channels in a zone as JSON.
        
        Args:
            request: HTTP request object
            zone_id: Primary key of the zone
            
        Returns:
            JsonResponse: List of channels in the zone
            
        Raises:
            Http404: If zone with given ID doesn't exist
        r   rZ   r   )r   r   r5   c              
   S   s2   g | ]*}t |j|j|j|j|j|j|jd qS r  )r  r   r   r   r  rr   rt   r   r  rB   rB   rC   r   Y  s   
z+ZoneChannelsAPIView.get.<locals>.<listcomp>)rw   r2   r   r   r  ru   N)r   r'   r&   r[   rn   r   r  r   r   r5   r   r
   r  )r=   rE   r5  rw   r2   r  r  rB   rB   rC   r0   A  s    

zZoneChannelsAPIView.getNr	  rB   rB   rB   rC   r4  8  s   r4  c                   @   s0   e Zd ZdZeedddZeedddZdS )ChannelZoneListViewa  Enhanced view for displaying a list of all channel zones.
    
    Features:
    - Advanced filtering by status, timezone, and activity
    - Enhanced search across multiple fields
    - Statistics and analytics
    - Bulk operations support
    - Export functionality
    - AJAX support for dynamic updates
    
    Methods:
        get: Handle GET requests to display zone list
        post: Handle bulk operations
        
    Template: channels/zone/list.html
    rD   c                 C   sB  |j dd }|j dd}|j dd}|j dd}|j dd}|j d	d
}t|j dd}tjjtdtdtdddtdd}	|r|		t|dt|dB t|dB t|dB }	|r|dkr|	j	dd}	n|dkr|	j	dd}	|r|	j	|d}	dddddg}
||
kr<|dkr0d| }|	
|}	n
|	
d}	|	 }|	j	dd }|	j	dd }tjjddd  
d}t|	|}z||}W n@ tk
r   |d
}Y n" tk
r   ||j}Y nX |||||d||||||d!}|jd"d#kr6tt|d$|j |||d%S t|d&|S )'zHandle GET request to display enhanced zone list.
        
        Args:
            request: HTTP request object
            
        Returns:
            HttpResponse: Rendered template with zone list and statistics
        rf   rg   rt   r   sortr   orderascrI   rJ   r   r   r2   r   )Zchannels__status)rn   channel_relations)r2  active_channels_countrelations_countrh   )code__icontainsrk   )Ztimezone__icontainsTr   r   Fr   r2  r   desc-)flat)rZ   ro   rv   timezone_filterr   
sort_orderr   rK  active_zonesinactive_zonesavailable_timezonesrG   rH   zchannels/zone/list_partial.html)htmlrK  rD  rE  zchannels/zone/list.html)rO   r0   rm   r   r'   r[   r   r   r   rn   r   r   values_listr   r   rI   r   r   rQ   lstriprK   r
   r   contentdecode)r=   rE   ro   rv   rB  r   rC  rI   r   rZ   r   rK  rD  rE  rF  rW   r3  r?   rB   rB   rC   r0     s    





zChannelZoneListView.getc           	   
   C   sB  |j d}|j d}|s*tdddS ztjj|d}|dkrb|jdd	}t	|| d
 n|dkr|jdd	}t	|| d nd|dkr|jdd
 }| rtdddW S | }|  t	|| d ntdddW S tdddW S  tk
r< } z tddt| d W Y S d}~X Y nX dS )zHandle bulk operations on zones.
        
        Args:
            request: HTTP request object with bulk operation data
            
        Returns:
            JsonResponse: Result of bulk operation
        r   zone_idsFzNo zones selected.r   r   )id__inactivateTr   z zones activated successfully.
deactivatez  zones deactivated successfully.r  )Zchannels__isnullz2Cannot delete zones that have associated channels.z zones deleted successfully.zInvalid action.z!Operation completed successfully.zError: N)r  r0   getlistr
   r'   r[   rn   r;   r   r   r   existsr   r  r  r  )	r=   rE   r   rL  rZ   updatedZzones_with_channelsdeleted_countr  rB   rB   rC   r    s4    	
zChannelZoneListView.postNr  rB   rB   rB   rC   r7  p  s   ^r7  c                   @   s"   e Zd ZdZeeedddZdS )ChannelZoneDetailViewa  Enhanced view for displaying detailed information about a specific channel zone.
    
    Features:
    - Comprehensive zone information and statistics
    - Associated channels with filtering and pagination
    - Zone-specific configurations and relationships
    - Health monitoring and status tracking
    - Export and reporting capabilities
    
    Methods:
        get: Handle GET requests to display zone details
        
    Template: channels/zone/detail.html
    r0  c                 C   s  t t|d}|jdd }|jdd}|jdd}|jdd}t|jdd	}tjj|d
j	t
dt
dt
dd dd}	|r|	t|dt|dB t|dB }	|r|	j|d}	|r|	j|d}	|	dd}	tjj|ddddd}
|	 }|	jdd }|	jdd }|	jdd }|	dj	t
dd d!}|
 }|
jd"d# }|
jd$d% }|
jdd& }t tjd'd( }|	j|d) }|	jd"d* }|	jd+d* }t|	|}z||}W n@ tk
r   |d}Y n" tk
r&   ||j}Y nX tj}tj}|||
||||||||||||||||||d,}|jd-d.krtt |d/|j!" |||d0S t |d1|S )2ap  Handle GET request to display enhanced zone details.
        
        Args:
            request: HTTP request object
            pk: Primary key of the zone to display
            
        Returns:
            HttpResponse: Rendered template with comprehensive zone details
            
        Raises:
            Http404: If zone with given ID doesn't exist
        r   channel_searchrg   channel_statusrr   rI   rJ   r   r   r6  zone_relationsepgprogram_setchannelschedule_set)Zzone_relations_countepg_programs_countschedules_countrZ   rh   rj   )Zchannel_number__icontainsru   rq   r  r   rw   r   codecz	-prioritychannel__namer   r   maintenancer   r   r   Tr   nonevpn_typeftp_hostr   r~   )created_at__gter   F)rw   r2   rX  rV  rW  rr   r   r   r   r   maintenance_channelsr   r   r   total_relationsactive_relationsvpn_relationsftp_relationsr   available_statusesavailable_typesrG   rH   z#channels/zone/channels_partial.html)rG  r   r   r   zchannels/zone/detail.html)#r   r'   rO   r0   rm   r   r&   r[   rn   r   r   r]   r^   r   r   r-   r   r   excluder   r   r   r   r   rI   r   r   rQ   r   r   rK   r
   r   rJ  rK  )r=   rE   r!  rw   rV  rW  rr   rI   r   r2   rX  r   r   r   rg  r   rh  ri  rj  rk  Zthirty_days_agor   r   r   rW   r  rl  rm  r?   rB   rB   rC   r0      s    
   

!zChannelZoneDetailView.getNr  r  r  r  r   r  r	   r0   rB   rB   rB   rC   rU    s   rU  c                   @   s0   e Zd ZdZeedddZeedddZdS )ChannelZoneCreateViewa  Enhanced view for creating new channel zones.
    
    Features:
    - Comprehensive form validation
    - Support for all zone fields including timezone
    - Duplicate detection and prevention
    - AJAX form submission support
    - Activity logging
    
    Methods:
        get: Display zone creation form
        post: Process form submission and create zone
        
    Template: channels/zone/form.html
    rD   c                 C   s8   ddddddddd	d
dddg}dd|dd}t |d|S )zDisplay enhanced zone creation form.
        
        Args:
            request: HTTP request object
            
        Returns:
            HttpResponse: Rendered template with empty form and timezone options
        UTCAmerica/New_YorkAmerica/ChicagoAmerica/DenverAmerica/Los_AngelesEurope/LondonEurope/ParisEurope/BerlinEurope/MadridEurope/Rome
Asia/TokyoAsia/ShanghaiAustralia/SydneyzCreate New Channel ZonezCreate ZoneT)r  r  common_timezones	is_createchannels/zone/form.html)r   )r=   rE   r~  r?   rB   rB   rC   r0     s(    zChannelZoneCreateView.getc              
   C   s  z|j dd }|j dd  }|j dd }|j dd }|j ddk}g }|st|d	 nt|d
kr|d |s|d n<t|dkr|d n$tjj|d	 r|d| d tjj|d	 r|d| d |r$|D ]}t
|| q| |W S tjj|||||d}	tjj|jdd|	jd|	j d|	j dt|d t
|d|	j d |jddkrtdd|	j dtd d!|	jid"d#W S td |	jd$W S  tk
r< }
 zPd%|
 }t
|| |jddkrtd&|d' W Y S | | W Y S d(}
~
X Y np tk
r }
 zPd)|
 }t
|| |jddkrtd&|d' W Y S | | W Y S d(}
~
X Y nX d(S )*zProcess enhanced zone creation form submission.
        
        Args:
            request: HTTP request object with form data
            
        Returns:
            HttpResponse: Redirect to zone detail on success, or form with errors
        r   rg   r   r5   r   rq  r   r  Zone name is required.   )Zone name must be 255 characters or less.Zone code is required.r   (Zone code must be 10 characters or less.r   Zone code "" already exists.r  Zone name "r   r   r5   r   r   r  r'   zCreated channel zone:  ()r   r   object_type	object_idr5   r  Zone "r  rG   rH   Tchannels:zone_detailr!  r>   r   r   redirect_urlr   r  FrM  NzError creating zone: )r  r0   rm   upperr   r  r'   r[   rn   rR  r   r   r  r.   r   r   r   r   r%   r   rK   r
   r   r!  r   r   r  )r=   rE   r   r   r5   timezone_valr   errorsr   rw   r  	error_msgrB   rB   rC   r    st    	
		


zChannelZoneCreateView.postNr  rB   rB   rB   rC   rp    s   "rp  c                   @   s4   e Zd ZdZeeedddZeeedddZdS )ChannelZoneUpdateViewa  Enhanced view for updating existing channel zones.
    
    Features:
    - Comprehensive form validation with change tracking
    - Support for all zone fields including timezone
    - Duplicate detection (excluding current zone)
    - AJAX form submission support
    - Activity logging with change details
    
    Methods:
        get: Display zone update form
        post: Process form submission and update zone
        
    Template: channels/zone/form.html
    r0  c                 C   sl   t t|d}dddddddd	d
ddddg}|j|krH||j |  |d|j d|dd}t|d|S )ac  Display enhanced zone update form.
        
        Args:
            request: HTTP request object
            pk: Primary key of zone to update
            
        Returns:
            HttpResponse: Rendered template with pre-filled form and timezone options
            
        Raises:
            Http404: If zone with given ID doesn't exist
        r   rq  rr  rs  rt  ru  rv  rw  rx  ry  rz  r{  r|  r}  zUpdate Zone: zUpdate ZoneF)rw   r  r  r~  r  r  )r   r'   r   r   r8  r   r   )r=   rE   r!  rw   r~  r?   rB   rB   rC   r0   @  s2    

zChannelZoneUpdateView.getc                 C   s\  t t|d}zf|j|j|j|j|jd}|jdd	 }|jdd	 
 }|jdd	 }|jdd	 }|jd	d
k}	g }
|s|
d nt|dkr|
d |s|
d nHt|dkr|
d n0tjj|dj|jd r|
d| d tjj|dj|jd r8|
d| d |
rd|
D ]}t|| qB| ||W S ||_||_||_||_|	|_|  g }| D ]:\}}t||}||kr|| d| d| d q|rtjj|jdd|jd|j d|j dd| t|d t|d |j d! |jd"d#krftd$d |j d!t d%d&|jid'd(W S t!d%|jdW S  t"k
r } zRd)| }t|| |jd"d#krtd*|d+ W Y S | || W Y S d,}~X Y nr t#k
rV } zRd-| }t|| |jd"d#kr6td*|d+ W Y S | || W Y S d,}~X Y nX d,S ).ay  Process enhanced zone update form submission.
        
        Args:
            request: HTTP request object with form data
            pk: Primary key of zone to update
            
        Returns:
            HttpResponse: Redirect to zone detail on success, or form with errors
            
        Raises:
            Http404: If zone with given ID doesn't exist
        r   r  r   rg   r   r5   r   rq  r   r  r  r  r  r  r   r  r  r  r  r  r  z: "u   " → ""r;   r'   zUpdated channel zone: r  z). Changes: ;r  r  r  rG   rH   Tr  r!  r  r  r  FrM  NzError updating zone: )$r   r'   r   r   r5   r   r   r  r0   rm   r  r   r  r[   rn   rn  r!  rR  r   r   r  itemsr   r.   r  r   r   joinr%   r   rK   r
   r   r   r   r  )r=   rE   r!  rw   Zoriginal_valuesr   r   r5   r  r   r  r   changesfieldoriginal_value	new_valuer  r  rB   rB   rC   r  n  s    	


 	

 
zChannelZoneUpdateView.postN	r  r  r  r  r   r  r	   r0   r  rB   rB   rB   rC   r  /  s   .r  c                   @   s4   e Zd ZdZeeedddZeeedddZdS )ChannelZoneDeleteViewa  Enhanced view for deleting channel zones.
    
    Features:
    - Comprehensive dependency checking
    - Detailed impact analysis before deletion
    - Force deletion option for administrators
    - AJAX deletion support
    - Activity logging with dependency details
    
    Methods:
        get: Display deletion confirmation with impact analysis
        post: Process deletion request with safety checks
        
    Template: channels/zone/confirm_delete.html
    r0  c                 C   s  t t|d}tjj|d}| }|jdd }tjj|d}| }|jdd }	|jdd	 }
|jd
d }d}d}|D ] }||j 7 }||j	 7 }q|dkp|dkp|dkp|dk}|j
jp|j
jjdd }|||||	|
||||||dd d}t|d|S )ae  Display enhanced zone deletion confirmation.
        
        Args:
            request: HTTP request object
            pk: Primary key of zone to delete
            
        Returns:
            HttpResponse: Rendered confirmation template with impact analysis
            
        Raises:
            Http404: If zone with given ID doesn't exist
        r   r6  r   ru   r]  Tr   ra  rb  rg   rd  r   Administratorsr  Nr   )rw   r2  r<  r=  active_relations_countvpn_relations_countftp_relations_countr[  r\  has_dependenciescan_force_deleter2   z!channels/zone/confirm_delete.html)r   r'   r&   r[   rn   r   r-   rn  rY  rZ  r   is_superusergroupsrR  r   )r=   rE   r!  rw   r2   r2  r<  rX  r=  r  r  r  r[  r\  r   r  r  r?   rB   rB   rC   r0     sH    
zChannelZoneDeleteView.getc                 C   sN  t t|d}|j}|j}|jddk}ztjj|d}|	 }t
jj|d	 }	|dkr|sd| d| d	}
t||
 |jd
dkrtd|
dW S | ||W S |r|jjs|jjjdd sd}
t||
 |jd
dkrtd|
dW S | ||W S g }|dkr0|| d |	dkrJ||	 d |  tjj|jdd|d| d| d|rd|nd d| t|d d| d}|r|r|dd| d 7 }t|| |jd
dkrtd!|td"d#W S td"W S  tk
rH } z&t|d$|  td%|d W Y S d&}~X Y nX d&S )'a\  Process enhanced zone deletion request.
        
        Args:
            request: HTTP request object with form data
            pk: Primary key of zone to delete
            
        Returns:
            HttpResponse: Redirect to zone list on success
            
        Raises:
            Http404: If zone with given ID doesn't exist
        r   force_deleter  r6  r]  r   zCannot delete zone "z" because it has z> associated channels. Use force delete if you want to proceed.rG   rH   FrM  r  r  zCYou do not have permission to force delete zones with dependencies.r   z zone relationsr  r'   zDeleted channel zone: r  z). Dependencies: z, Nonez. Force delete: r  r  r  z Warning: This also removed r  .Tzchannels:zone_listr  zError deleting zone: r  N)r   r'   r   r   r  r0   r&   r[   rn   r   r-   r   r   rK   r
   r   r  r  rR  r   r  r.   r  r  r%   r   r   r   r  )r=   rE   r!  rw   	zone_nameZ	zone_coder  r2   r2  r=  r  Zdependency_infoZsuccess_msgr  rB   rB   rC   r  *  s`    &

*	

zChannelZoneDeleteView.postNr  rB   rB   rB   rC   r    s   =r  c                   @   s0   e Zd ZdZeedddZeedddZdS )JingleCreateViewaZ  View for creating new jingles.
    
    Handles both GET requests to display the creation form and POST requests
    to process form submission and create new jingle instances.
    
    Methods:
        get: Display jingle creation form
        post: Process form submission and create jingle
        
    Template: channels/jingle_form.html
    rD   c                 C   s4   t jjddd}|tjtjddd}t|d|S )zDisplay jingle creation form.
        
        Args:
            request: HTTP request object
            
        Returns:
            HttpResponse: Rendered template with empty form
        r   ru   r   zCreate New JinglezCreate Jingle)r2   r  r  r  r  zchannels/jingle/form.html)r&   r[   rn   r   r)   r  r  r   r=   rE   r2   r?   rB   rB   rC   r0     s    	zJingleCreateView.getc              
   C   sV  z|j d}|j dd }|j d}|j d}|j d}|jd}t|||gsvt|d | |W S tt|d	}t	j
j|||||rt|nd
|d}	t|d|	j d td|	jd	W S  tk
r }
 z$t|d|
  | | W Y S d
}
~
X Y nD tk
rP }
 z$t|d|
  | | W Y S d
}
~
X Y nX d
S )zProcess jingle creation form submission.
        
        Args:
            request: HTTP request object with form data
            
        Returns:
            HttpResponse: Redirect to jingle detail on success, or form with errors
        r   r   rg   rp   r  rE  filez%Channel, name, and type are required.r   N)r   r   rp   r  rE  r  Jingle "r  channels:jingle_detailr  zError creating jingle: )r  r0   rm   r  r\   r   r   r   r&   r)   r[   r  r  r   r   r   r!  r   r  )r=   rE   r  r   r  r  rE  file_uploadr   r  r  rB   rB   rC   r    s6    		zJingleCreateView.postNr  rB   rB   rB   rC   r  ~  s   r  c                   @   s"   e Zd ZdZeeedddZdS )JingleDetailViewa  View for displaying detailed information about a specific jingle.
    
    Shows jingle details including metadata and playback information.
    
    Methods:
        get: Handle GET requests to display jingle details
        
    Template: channels/jingle_detail.html
    r0  c                 C   s$   t t|d}||jd}t|d|S )aa  Handle GET request to display jingle details.
        
        Args:
            request: HTTP request object
            pk: Primary key of the jingle to display
            
        Returns:
            HttpResponse: Rendered template with jingle details
            
        Raises:
            Http404: If jingle with given ID doesn't exist
        r   r  r   zchannels/jingle/detail.htmlr   r)   r   r   r=   rE   r!  r  r?   rB   rB   rC   r0     s
    zJingleDetailView.getNro  rB   rB   rB   rC   r    s   
r  c                   @   s4   e Zd ZdZeeedddZeeedddZdS )JingleUpdateViewa3  View for updating existing jingles.
    
    Handles both GET requests to display the update form and POST requests
    to process updates.
    
    Methods:
        get: Display jingle update form
        post: Process form submission and update jingle
        
    Template: channels/jingle_form.html
    r0  c                 C   sJ   t t|d}tjjddd}||tjtjd|j dd}t	|d|S )	aK  Display jingle update form.
        
        Args:
            request: HTTP request object
            pk: Primary key of jingle to update
            
        Returns:
            HttpResponse: Rendered template with pre-filled form
            
        Raises:
            Http404: If jingle with given ID doesn't exist
        r   r   ru   r   zUpdate Jingle: zUpdate Jingle)r  r2   r  r  r  r  zchannels/jingle_form.html)
r   r)   r&   r[   rn   r   r  r  r   r   )r=   rE   r!  r  r2   r?   rB   rB   rC   r0     s    
zJingleUpdateView.getc              
   C   sZ  t t|d}z|jd}|r,t t|d|_|jdd pB|j|_|jdpV|j|_|jdpj|j	|_	|jd}|rt
||_|jd}|r||_|  t|d	|j d
 td|jdW S  tk
r } z&t|d|  | || W Y S d}~X Y nF tk
rT } z&t|d|  | || W Y S d}~X Y nX dS )ax  Process jingle update form submission.
        
        Args:
            request: HTTP request object with form data
            pk: Primary key of jingle to update
            
        Returns:
            HttpResponse: Redirect to jingle detail on success, or form with errors
            
        Raises:
            Http404: If jingle with given ID doesn't exist
        r   r   r   rg   rp   r  rE  r  r  r  r  r  NzError updating jingle: )r   r)   r  r0   r&   r   rm   r   rp   r  r  rE  r  r  r  r   r   r   r!  r   r   r  )r=   rE   r!  r  r  rE  r  r  rB   rB   rC   r    s.    
 zJingleUpdateView.postNr  rB   rB   rB   rC   r    s   r  c                   @   s4   e Zd ZdZeeedddZeeedddZdS )JingleDeleteViewa4  View for deleting jingles.
    
    Handles both GET requests to display confirmation page and POST requests
    to perform the actual deletion.
    
    Methods:
        get: Display deletion confirmation
        post: Process deletion request
        
    Template: channels/jingle_confirm_delete.html
    r0  c                 C   s$   t t|d}||jd}t|d|S )aM  Display jingle deletion confirmation.
        
        Args:
            request: HTTP request object
            pk: Primary key of jingle to delete
            
        Returns:
            HttpResponse: Rendered confirmation template
            
        Raises:
            Http404: If jingle with given ID doesn't exist
        r   r  z#channels/jingle/confirm_delete.htmlr  r  rB   rB   rC   r0   M  s
    zJingleDeleteView.getc              
   C   s   t t|d}|j}|j}z,|  t|d| d td|jdW S  t	k
r } z&t
|d|  td|d W Y S d}~X Y nX dS )	a[  Process jingle deletion request.
        
        Args:
            request: HTTP request object with form data
            pk: Primary key of jingle to delete
            
        Returns:
            HttpResponse: Redirect to jingle list on success
            
        Raises:
            Http404: If jingle with given ID doesn't exist
        r   r  r  zchannels:jingle_listr  zError deleting jingle: r  N)r   r)   r   r   r  r   r   r   r!  r  r   )r=   rE   r!  r  jingle_namer   r  rB   rB   rC   r  b  s    zJingleDeleteView.postNr  rB   rB   rB   rC   r  @  s   r  c                   @   s0   e Zd ZdZeedddZeedddZdS )AdbreakCreateViewa_  View for creating new adbreaks.
    
    Handles both GET requests to display the creation form and POST requests
    to process form submission and create new adbreak instances.
    
    Methods:
        get: Display adbreak creation form
        post: Process form submission and create adbreak
        
    Template: channels/adbreak_form.html
    rD   c                 C   s4   t jjddd}|tjtjddd}t|d|S )zDisplay adbreak creation form.
        
        Args:
            request: HTTP request object
            
        Returns:
            HttpResponse: Rendered template with empty form
        r   ru   r   zCreate New AdbreakzCreate Adbreak)r2   r  r  r  r  channels/adbreak/form.html)r&   r[   rn   r   r*   r  r  r   r  rB   rB   rC   r0     s    	zAdbreakCreateView.getc              
   C   s`  z|j d}|j d}|j d}|j d}|j d}|j d}|j d}t||||gs~t|d | |W S tt|d	}	tjj	|	||||rt
|nd
||d}
t|d|	j d td|
jd	W S  tk
r } z$t|d|  | | W Y S d
}~X Y nD tk
rZ } z$t|d|  | | W Y S d
}~X Y nX d
S )zProcess adbreak creation form submission.
        
        Args:
            request: HTTP request object with form data
            
        Returns:
            HttpResponse: Redirect to adbreak detail on success, or form with errors
        r   r   rI  r  rE  rp   rC  z1Channel, date, start time, and type are required.r   N)r   r   rI  r  rE  rp   rC  z!Adbreak created successfully for r  channels:adbreak_detailr  zError creating adbreak: )r  r0   r\   r   r   r   r&   r*   r[   r  r  r   r   r   r!  r   r  )r=   rE   r  r   rI  r  rE  r  rC  r   r  r  rB   rB   rC   r    s:    	
zAdbreakCreateView.postNr  rB   rB   rB   rC   r    s   r  c                   @   s"   e Zd ZdZeeedddZdS )AdbreakDetailViewa  View for displaying detailed information about a specific adbreak.
    
    Shows adbreak details including timing and metadata.
    
    Methods:
        get: Handle GET requests to display adbreak details
        
    Template: channels/adbreak_detail.html
    r0  c                 C   s$   t t|d}||jd}t|d|S )ae  Handle GET request to display adbreak details.
        
        Args:
            request: HTTP request object
            pk: Primary key of the adbreak to display
            
        Returns:
            HttpResponse: Rendered template with adbreak details
            
        Raises:
            Http404: If adbreak with given ID doesn't exist
        r   r  r   zchannels/adbreak/detail.htmlr   r*   r   r   r=   rE   r!  r  r?   rB   rB   rC   r0     s
    zAdbreakDetailView.getNro  rB   rB   rB   rC   r    s   
r  c                   @   s4   e Zd ZdZeeedddZeeedddZdS )AdbreakUpdateViewa7  View for updating existing adbreaks.
    
    Handles both GET requests to display the update form and POST requests
    to process updates.
    
    Methods:
        get: Display adbreak update form
        post: Process form submission and update adbreak
        
    Template: channels/adbreak_form.html
    r0  c                 C   sT   t t|d}tjjddd}||tjtjd|jj	 d|j
 dd}t|d	|S )
aN  Display adbreak update form.
        
        Args:
            request: HTTP request object
            pk: Primary key of adbreak to update
            
        Returns:
            HttpResponse: Rendered template with pre-filled form
            
        Raises:
            Http404: If adbreak with given ID doesn't exist
        r   r   ru   r   zUpdate Adbreak: z - zUpdate Adbreak)r  r2   r  r  r  r  r  )r   r*   r&   r[   rn   r   r  r  r   r   r   r   )r=   rE   r!  r  r2   r?   rB   rB   rC   r0     s    zAdbreakUpdateView.getc           
   
   C   sb  t t|d}z|jd}|r,t t|d|_|jd}|rB||_|jd}|rX||_|jd}|rn||_|jd}|rt	||_
|jdp|j|_|jdp|j|_|  t|d	 td
|jdW S  tk
r }	 z&t|d|	  | || W Y S d}	~	X Y nF tk
r\ }	 z&t|d|	  | || W Y S d}	~	X Y nX dS )a|  Process adbreak update form submission.
        
        Args:
            request: HTTP request object with form data
            pk: Primary key of adbreak to update
            
        Returns:
            HttpResponse: Redirect to adbreak detail on success, or form with errors
            
        Raises:
            Http404: If adbreak with given ID doesn't exist
        r   r   r   rI  r  rE  rp   rC  zAdbreak updated successfully.r  r  NzError updating adbreak: )r   r*   r  r0   r&   r   r   rI  r  r  rE  rp   rC  r  r   r   r   r!  r   r   r  )
r=   rE   r!  r  r  r   rI  r  rE  r  rB   rB   rC   r    s8    
 zAdbreakUpdateView.postNr  rB   rB   rB   rC   r    s   r  c                   @   s4   e Zd ZdZeeedddZeeedddZdS )AdbreakDeleteViewa6  View for deleting adbreaks.
    
    Handles both GET requests to display confirmation page and POST requests
    to perform the actual deletion.
    
    Methods:
        get: Display deletion confirmation
        post: Process deletion request
        
    Template: channels/adbreak_confirm_delete.html
    r0  c                 C   s$   t t|d}||jd}t|d|S )aP  Display adbreak deletion confirmation.
        
        Args:
            request: HTTP request object
            pk: Primary key of adbreak to delete
            
        Returns:
            HttpResponse: Rendered confirmation template
            
        Raises:
            Http404: If adbreak with given ID doesn't exist
        r   r  z$channels/adbreak/confirm_delete.htmlr  r  rB   rB   rC   r0   W  s
    zAdbreakDeleteView.getc              
   C   s   t t|d}|j}z$|  t|d td|jdW S  tk
rz } z&t	|d|  td|d W Y S d}~X Y nX dS )a_  Process adbreak deletion request.
        
        Args:
            request: HTTP request object with form data
            pk: Primary key of adbreak to delete
            
        Returns:
            HttpResponse: Redirect to adbreak list on success
            
        Raises:
            Http404: If adbreak with given ID doesn't exist
        r   zAdbreak deleted successfully.zchannels:adbreak_listr  zError deleting adbreak: r  N)
r   r*   r   r  r   r   r   r!  r  r   )r=   rE   r!  r  r   r  rB   rB   rC   r  l  s    zAdbreakDeleteView.postNr  rB   rB   rB   rC   r  J  s   r  c                   @   s"   e Zd ZdZeeedddZdS )JingleAPIViewzAPI view for jingle operations.
    
    Provides JSON endpoints for jingle management within channels.
    
    Methods:
        get: Retrieve jingles for a channel
    r  c              
   C   s  t t|d}ztjj|dd}|jd}|r>|j|d}|jd}|rZ|j|d}t|jdd	}t|jd
d}t	||}	|	
|}
|j|j|jddd |
D |||	j|	j|
 |
 dd}t|W S  tk
r } ztdt|idd W Y S d}~X Y nX dS )r  r   rB  r   rp   r  r  r  rI   rJ   r   r   r  c              
   S   s>   g | ]6}|j |j|j|j|j|jr*|jjnd |j dqS )N)r   r   rp   r  rE  file_urlr   )	r   r   rp   r  rE  r  r  r   r   r  rB   rB   rC   r     s   
z%JingleAPIView.get.<locals>.<listcomp>r  )r   r  r  r   r  ru   N)r   r&   r)   r[   rn   r   rO   r0   r   r   rI   r   r   r   r   rQ   r   r   r
   r  r  )r=   rE   r  r   r  r  r  rI   r   rW   r  r  r  rB   rB   rC   r0     s>    



zJingleAPIView.getNr  r  r  r  r   r   r
   r0   rB   rB   rB   rC   r    s   r  c                   @   s"   e Zd ZdZeeedddZdS )AdbreakAPIViewzAPI view for adbreak operations.
    
    Provides JSON endpoints for adbreak data retrieval and analysis.
    
    Methods:
        get: Retrieve adbreaks for a channel with filtering
    r  c                 C   s  t t|d}zh|jd}|jd}|sFt  tdd  }|sZt   }t	j
j|||d}|jd}|r|j|d}|jd	}|r|j|d
}|dd}tdd |D }	|r|	t| nd}
t|jdd}t|jdd}t||}||}|j|j|jd||dt|t|	dt|
dddd |D |||j|j| | dd}t|W S  tk
r } ztdt|idd W Y S d}~X Y nX dS ) aV  Retrieve adbreaks for a channel as JSON.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of the channel
            
        Returns:
            JsonResponse: List of adbreaks with statistics
            
        Raises:
            Http404: If channel with given ID doesn't exist
        r   r  r  r   r~   r  rp   r  rC  r  r  r@  c                 s   s   | ]}|j pd V  qdS r  r  r  rB   rB   rC   r  
  s     z%AdbreakAPIView.get.<locals>.<genexpr>r   rI   rJ   r   r  r  r  r  r  c              
   S   sN   g | ]F}|j |j |jr$|j nd |jr6|j nd |j|j|jdqS r  )r   r   r   rI  r  rE  rp   rC  r  rB   rB   rC   r   #  s   
z&AdbreakAPIView.get.<locals>.<listcomp>r  )r   rz   r  r8  r  r   r  ru   N)r   r&   rO   r0   r   r   r   r   r   r*   r[   rn   r   r  r  r   r   rI   r   r   r   r  r   rQ   r   r   r
   r  r  )r=   rE   r  r   r  r  r8  r  rC  r  r  rI   r   rW   r  r  r  rB   rB   rC   r0     sf    


%
zAdbreakAPIView.getNr  rB   rB   rB   rC   r    s   r  c                   @   s"   e Zd ZdZeeedddZdS )ChannelStatsAPIViewzAPI view for channel statistics and analytics.
    
    Provides aggregated statistics and metrics for channels.
    
    Methods:
        get: Retrieve channel statistics
    r  c              
   C   s~  t t|d}z.t }| }|tdd }|tdd }tjj||d	 }tjj||d	 }	tjj||d	 }
tjj||dj
tddd	 pd
}tjj||dj
tddd	 pd
}tjj|d	 }d}|j|j|j|j|jd||	|
t|dt|ddd|i||jr"|j ndd| d}t|W S  tk
rx } ztdt|idd W Y S d}~X Y nX dS )aP  Retrieve channel statistics as JSON.
        
        Args:
            request: HTTP request object
            channel_id: Primary key of the channel
            
        Returns:
            JsonResponse: Channel statistics and metrics
            
        Raises:
            Http404: If channel with given ID doesn't exist
        r   r   r~   r   )r   r   r=  rE  rG  rH  r   rB  r  )r   r   r   rt   r   r  )r{   r   r   week_durationmonth_durationrM  N)rO  r  )r   Zadbreak_statsZcontent_statsZhealth_statsr%  r   r  ru   )r   r&   r   r   r   r   r*   r[   rn   r   rQ  r   r)   r   r   r   rt   r   r  r  r   r
   r  r  )r=   rE   r  r   r   r{   r   Z	month_agorN  Zweek_adbreaksZmonth_adbreaksr  r  rM  rO  r  r  rB   rB   rC   r0   H  sx     
 
   
zChannelStatsAPIView.getNr  rB   rB   rB   rC   r  ?  s   r  )hr  r  r   typingr   r   r   r   r   django.contrib.authr   django.httpr   r	   r
   r   r   r   django.shortcutsr   r   r   django.urlsr   django.viewsr   django.core.paginatorr   r   r   django.contribr   django.db.modelsr   r   r   r   r   r   django.utilsr   django.core.exceptionsr   django.views.decorators.csrfr   django.utils.decoratorsr    django.confr!   django.contrib.auth.mixinsr"   django.utils.translationr#   r<   django.core.cacher$   apps.common.utilsr%   apps.channels.modelsr&   r'   r(   r)   r*   r+   r,   r-   apps.activities.modelsr.   r/   r  r  r  r  r  r  r  r  r   r  r
  r  r  r(  r.  r/  r1  r4  r7  rU  rp  r  r  r  r  r  r  r  r  r  r  r  r  r  rB   rB   rB   rC   <module>   s     (     D      KY[@AO]
cLA\ZONNFA8 !   . #L"T?N"[?Mi