U
    5dN1                     @   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-qmwpt_in/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                    sF  g }sr | fdd r6| fdd rL| fdd 
rb| 
fdd 	sjr~| 	fdd  sr|  fdd r| fdd r| fd	d |r| d
d  |r| dd  |r| dd  |r| dd  |r || 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  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   r.   r   r   r      r   )appendextend_filter)r   r   r   r   r!   r#   r$   r%   r&   r'   r)   r+   
only_audioZ
only_videoprogressiveZadaptiver/   Zcustom_filter_functionsfiltersr   )r&   r+   r'   r%   r   r/   r!   r   r   r$   r#   r)   r   filter   sD    g

zStreamQuery.filter)r5   returnc                 C   s&   | j }|D ]}t||}q
tt|S r   )r   r6   r   list)r   r5   r   Zfilter_lambdar   r   r   r2      s    zStreamQuery._filter)attribute_namer7   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   r9   r   r   
<listcomp>   s   z(StreamQuery.order_by.<locals>.<listcomp>r   c                    s   t dttjt|  S )N )r   joinr6   str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   
isinstancer;   r@   r   sorted
ValueError)r   r9   Zhas_attributer   r<   r   order_by   s&    
 

zStreamQuery.order_byr7   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   rI   r   r   r   asc   s    zStreamQuery.asc)r   r7   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   r7   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)r4   r$   r   )r6   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.

        TrN   )r4   r$   r   )r6   rF   rO   rI   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)r4   r   r6   rF   lastrI   r   r   r   get_highest_resolution  s    	z"StreamQuery.get_highest_resolutionrN   )r$   r7   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)r3   r$   r&   rR   )r   r$   r   r   r   get_audio_only"  s    zStreamQuery.get_audio_onlyF)is_otfr7   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   rV   r   rW   r   r   r   9  r   z!StreamQuery.otf.<locals>.<lambda>)r2   )r   rV   r   rW   r   otf2  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   
IndexErrorrI   r   r   r   rO   ;  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.

        rH   NrY   rI   r   r   r   rS   I  s    	zStreamQuery.lastz.Get the size of this list directly using len())valuer7   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\   W  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   rI   r   r   r   allb  s    zStreamQuery.allic                 C   s
   | j | S r   r_   r   rb   r   r   r   __getitem__k  s    zStreamQuery.__getitem__c                 C   s
   t | jS r   )r]   r   rI   r   r   r   __len__n  s    zStreamQuery.__len__c                 C   s   | j  S r   r_   rI   r   r   r   __repr__q  s    zStreamQuery.__repr__)NNNNNNNNNNNNNNNNN)rN   )F)N)!__name__
__module____qualname____doc__r   r6   r   r   r2   r@   rF   rJ   rK   r   r   r	   rM   rP   rQ   rT   rU   boolrX   rO   rS   r
   r\   r`   r   slicerd   re   rf   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   rn   r   r   r   r   x  s    zCaptionQuery.__init__z?This object can be treated as a dictionary, i.e. captions['en'])	lang_coder7   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.
        )rr   rL   )r   rs   r   r   r   get_by_language_code  s    z!CaptionQuery.get_by_language_codez*This object can be treated as a dictionaryrG   c                 C   s   t | j S r^   )r8   rr   valuesrI   r   r   r   r`     s    zCaptionQuery.allra   c                 C   s
   | j | S r   rq   rc   r   r   r   rd     s    zCaptionQuery.__getitem__c                 C   s
   t | jS r   )r]   rr   rI   r   r   r   re     s    zCaptionQuery.__len__c                 C   s   t | j S r   )iterrr   ru   rI   r   r   r   __iter__  s    zCaptionQuery.__iter__c                 C   s   | j  S r   rq   rI   r   r   r   rf     s    zCaptionQuery.__repr__N)rg   rh   ri   rj   r   r   r   r
   r@   r   rt   r`   rd   r   re   rw   rf   r   r   r   r   rm   u  s   	rm   N)rj   collections.abcr   r   typingr   r   r   r   Zpytuber   r	   Zpytube.helpersr
   r   rm   r   r   r   r   <module>   s     n