U
    g,2                     @   sl   d 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 ddlmZ G dd deZG dd	 d	eZd
S )zFThis module provides a query interface for media streams and captions.    )MappingSequence)CallableListOptionalUnion)CaptionStream)
deprecatedc                   @   sZ  e Zd ZdZdd Zd6ddZee d ddd	Ze	d d
ddZ
d dddZd dddZeee dddZe	ee dddZee dddZee dddZd7e	ee dddZd8ed d!d"d#Zee dd$d%Zd&d' Zed(d9ee	 ed)d*d+Zed,ee dd-d.Zeeef d/d0d1Zedd2d3Ze	dd4d5Z dS ):StreamQueryz3Interface for querying the available media streams.c                 C   s   || _ dd |D | _dS )zConstruct a :class:`StreamQuery <StreamQuery>`.

        param list fmt_streams:
            list of :class:`Stream <Stream>` instances.
        c                 S   s   i | ]}t |j|qS  )intitag.0sr   r   0/tmp/pip-unpacked-wheel-1a9f0fi6/pytube/query.py
<dictcomp>   s      z(StreamQuery.__init__.<locals>.<dictcomp>N)fmt_streams
itag_index)selfr   r   r   r   __init__   s    zStreamQuery.__init__Nc                    s  g }sr^t ts t tr6|fdd n(t tsJt tr^|fdd rt|fdd r|fdd 
r|
fdd 	sr|	fdd  sĈr| fdd r|fd	d r|fd
d |r|dd  |r.|dd  |rB|dd  |rV|dd  |rf|| dk	r|fdd | |S )a  Apply the given filtering criterion.

        :param fps:
            (optional) The frames per second.
        :type fps:
            int or None

        :param resolution:
            (optional) Alias to ``res``.
        :type res:
            str or None

        :param res:
            (optional) The video resolution.
        :type resolution:
            str or None

        :param mime_type:
            (optional) Two-part identifier for file formats and format contents
            composed of a "type", a "subtype".
        :type mime_type:
            str or None

        :param type:
            (optional) Type part of the ``mime_type`` (e.g.: audio, video).
        :type type:
            str or None

        :param subtype:
            (optional) Sub-type part of the ``mime_type`` (e.g.: mp4, mov).
        :type subtype:
            str or None

        :param file_extension:
            (optional) Alias to ``sub_type``.
        :type file_extension:
            str or None

        :param abr:
            (optional) Average bitrate (ABR) refers to the average amount of
            data transferred per unit of time (e.g.: 64kbps, 192kbps).
        :type abr:
            str or None

        :param bitrate:
            (optional) Alias to ``abr``.
        :type bitrate:
            str or None

        :param video_codec:
            (optional) Video compression format.
        :type video_codec:
            str or None

        :param audio_codec:
            (optional) Audio compression format.
        :type audio_codec:
            str or None

        :param bool progressive:
            Excludes adaptive streams (one file contains both audio and video
            tracks).

        :param bool adaptive:
            Excludes progressive streams (audio and video are on separate
            tracks).

        :param bool is_dash:
            Include/exclude dash streams.

        :param bool only_audio:
            Excludes streams with video tracks.

        :param bool only_video:
            Excludes streams with audio tracks.

        :param custom_filter_functions:
            (optional) Interface for defining complex filters without
            subclassing.
        :type custom_filter_functions:
            list or None

        c                    s   | j  p
kS N
resolutionr   resr   r   r   <lambda>       z$StreamQuery.filter.<locals>.<lambda>c                    s   | j  p
kS r   r   r   r   r   r   r      r   c                    s
   | j  kS r   fpsr   r    r   r   r      r   c                    s
   | j  kS r   	mime_typer   r"   r   r   r      r   c                    s
   | j  kS r   typer   r$   r   r   r      r   c                    s   | j p
 kS r   )subtyper   )file_extensionr&   r   r   r      r   c                    s   | j  p
kS r   )abrr   )r(   bitrater   r   r      r   c                    s
   | j  kS r   video_codecr   r*   r   r   r      r   c                    s
   | j  kS r   audio_codecr   r,   r   r   r      r   c                 S   s   | j o| j S r   )includes_audio_trackincludes_video_trackr   r   r   r   r      s    c                 S   s   | j o| j S r   )r/   r.   r   r   r   r   r      s    c                 S   s   | j S r   )Zis_progressiver   r   r   r   r      r   c                 S   s   | j S r   )Zis_adaptiver   r   r   r   r      r   Nc                    s
   | j  kS r   is_dashr   r0   r   r   r      r   )
isinstancestrappendlistextend_filter)r   r!   r   r   r#   r%   r&   r'   r(   r)   r+   r-   
only_audioZ
only_videoprogressiveZadaptiver1   Zcustom_filter_functionsfiltersr   )r(   r-   r)   r'   r!   r1   r#   r   r   r&   r%   r+   r   filter   sJ    g

zStreamQuery.filter)r:   returnc                 C   s&   | j }|D ]}t||}q
tt|S r   )r   r;   r   r5   )r   r:   r   Zfilter_lambdar   r   r   r7      s    zStreamQuery._filter)attribute_namer<   c                    st    fdd| j D }|r\tt|d  tr\ztt| fdddW S  tk
rZ   Y nX tt| fdddS )zApply a sort order. Filters out stream the do not have the attribute.

        :param str attribute_name:
            The name of the attribute to sort by.
        c                    s   g | ]}t | d k	r|qS r   getattrr   r=   r   r   
<listcomp>   s   z(StreamQuery.order_by.<locals>.<listcomp>r   c                    s   t dttjt|  S )N )r   joinr;   r3   isdigitr?   r   r@   r   r   r      s   z&StreamQuery.order_by.<locals>.<lambda>)keyc                    s
   t |  S r   r>   r   r@   r   r   r      r   )r   r2   r?   r3   r   sorted
ValueError)r   r=   Zhas_attributer   r@   r   order_by   s&    
 

zStreamQuery.order_byr<   c                 C   s   t | jddd S )z_Sort streams in descending order.

        :rtype: :class:`StreamQuery <StreamQuery>`

        N)r   r   r   r   r   r   desc   s    zStreamQuery.descc                 C   s   | S )z^Sort streams in ascending order.

        :rtype: :class:`StreamQuery <StreamQuery>`

        r   rK   r   r   r   asc   s    zStreamQuery.asc)r   r<   c                 C   s   | j t|S )a6  Get the corresponding :class:`Stream <Stream>` for a given itag.

        :param int itag:
            YouTube format identifier code.
        :rtype: :class:`Stream <Stream>` or None
        :returns:
            The :class:`Stream <Stream>` matching the given itag or None if
            not found.

        )r   getr   )r   r   r   r   r   get_by_itag   s    zStreamQuery.get_by_itag)r   r<   c                 C   s   | j dd|d S )a  Get the corresponding :class:`Stream <Stream>` for a given resolution.

        Stream must be a progressive mp4.

        :param str resolution:
            Video resolution i.e. "720p", "480p", "360p", "240p", "144p"
        :rtype: :class:`Stream <Stream>` or None
        :returns:
            The :class:`Stream <Stream>` matching the given itag or None if
            not found.

        Tmp4)r9   r&   r   )r;   first)r   r   r   r   r   get_by_resolution   s
      zStreamQuery.get_by_resolutionc                 C   s   | j dddd S )zGet lowest resolution stream that is a progressive mp4.

        :rtype: :class:`Stream <Stream>` or None
        :returns:
            The :class:`Stream <Stream>` matching the given itag or None if
            not found.

        TrP   )r9   r&   r   )r;   rH   rQ   rK   r   r   r   get_lowest_resolution  s    
z!StreamQuery.get_lowest_resolutionc                 C   s   | j ddd S )zGet highest resolution stream that is a progressive video.

        :rtype: :class:`Stream <Stream>` or None
        :returns:
            The :class:`Stream <Stream>` matching the given itag or None if
            not found.

        T)r9   r   r;   rH   lastrK   r   r   r   get_highest_resolution  s    	z"StreamQuery.get_highest_resolutionrP   )r&   r<   c                 C   s   | j d|dd S )a9  Get highest bitrate audio stream for given codec (defaults to mp4)

        :param str subtype:
            Audio subtype, defaults to mp4
        :rtype: :class:`Stream <Stream>` or None
        :returns:
            The :class:`Stream <Stream>` matching the given itag or None if
            not found.
        T)r8   r&   r(   rT   )r   r&   r   r   r   get_audio_only%  s    zStreamQuery.get_audio_onlyF)is_otfr<   c                    s   |   fddgS )a  Filter stream by OTF, useful if some streams have 404 URLs

        :param bool is_otf: Set to False to retrieve only non-OTF streams
        :rtype: :class:`StreamQuery <StreamQuery>`
        :returns: A StreamQuery object with otf filtered streams
        c                    s
   | j  kS r   rX   r   rY   r   r   r   <  r   z!StreamQuery.otf.<locals>.<lambda>)r7   )r   rX   r   rY   r   otf5  s    zStreamQuery.otfc                 C   s(   z| j d W S  tk
r"   Y dS X dS )zGet the first :class:`Stream <Stream>` in the results.

        :rtype: :class:`Stream <Stream>` or None
        :returns:
            the first result of this query or None if the result doesn't
            contain any streams.

        r   Nr   
IndexErrorrK   r   r   r   rQ   >  s    	zStreamQuery.firstc                 C   s&   z| j d W S  tk
r    Y nX dS )zGet the last :class:`Stream <Stream>` in the results.

        :rtype: :class:`Stream <Stream>` or None
        :returns:
            Return the last result of this query or None if the result
            doesn't contain any streams.

        rJ   Nr[   rK   r   r   r   rU   L  s    	zStreamQuery.lastz.Get the size of this list directly using len())valuer<   c                 C   s   |r| j |S t| S )zAGet the count of items in the list.

        :rtype: int
        )r   countlen)r   r]   r   r   r   r^   Z  s    zStreamQuery.countz6This object can be treated as a list, all() is uselessc                 C   s   | j S zXGet all the results represented by this query as a list.

        :rtype: list

        r   rK   r   r   r   alle  s    zStreamQuery.allic                 C   s
   | j | S r   ra   r   rd   r   r   r   __getitem__n  s    zStreamQuery.__getitem__c                 C   s
   t | jS r   )r_   r   rK   r   r   r   __len__q  s    zStreamQuery.__len__c                 C   s   | j  S r   ra   rK   r   r   r   __repr__t  s    zStreamQuery.__repr__)NNNNNNNNNNNNNNNNN)rP   )F)N)!__name__
__module____qualname____doc__r   r;   r   r   r7   r3   rH   rL   rM   r   r   r	   rO   rR   rS   rV   rW   boolrZ   rQ   rU   r
   r^   rb   r   slicerf   rg   rh   r   r   r   r   r   	   sP                    
  #	
r   c                   @   s   e Zd ZdZee dddZedee	e dddZ
ed	ee d
ddZedddZed
ddZdd Zed
ddZdS )CaptionQueryz.Interface for querying the available captions.)captionsc                 C   s   dd |D | _ dS )zConstruct a :class:`Caption <Caption>`.

        param list captions:
            list of :class:`Caption <Caption>` instances.

        c                 S   s   i | ]}|j |qS r   )code)r   cr   r   r   r     s      z)CaptionQuery.__init__.<locals>.<dictcomp>Nlang_code_index)r   rp   r   r   r   r   {  s    zCaptionQuery.__init__z?This object can be treated as a dictionary, i.e. captions['en'])	lang_coder<   c                 C   s   | j |S )a[  Get the :class:`Caption <Caption>` for a given ``lang_code``.

        :param str lang_code:
            The code that identifies the caption language.
        :rtype: :class:`Caption <Caption>` or None
        :returns:
            The :class:`Caption <Caption>` matching the given ``lang_code`` or
            None if it does not exist.
        )rt   rN   )r   ru   r   r   r   get_by_language_code  s    z!CaptionQuery.get_by_language_codez*This object can be treated as a dictionaryrI   c                 C   s   t | j S r`   )r5   rt   valuesrK   r   r   r   rb     s    zCaptionQuery.allrc   c                 C   s
   | j | S r   rs   re   r   r   r   rf     s    zCaptionQuery.__getitem__c                 C   s
   t | jS r   )r_   rt   rK   r   r   r   rg     s    zCaptionQuery.__len__c                 C   s   t | j S r   )iterrt   rw   rK   r   r   r   __iter__  s    zCaptionQuery.__iter__c                 C   s   | j  S r   rs   rK   r   r   r   rh     s    zCaptionQuery.__repr__N)ri   rj   rk   rl   r   r   r   r
   r3   r   rv   rb   rf   r   rg   ry   rh   r   r   r   r   ro   x  s   	ro   N)rl   collections.abcr   r   typingr   r   r   r   Zpytuber   r	   Zpytube.helpersr
   r   ro   r   r   r   r   <module>   s     q