
    L^iBy                     x   d dl mZ d dlZd dlZd dlZd dlZd dlZd dlmZ d dl	m
Z
 d dlZd dlmZmZ  ej        d          Z ej                    Z ej        d          Ze                    e           e                    e           d dlmZ d d	lmZ d d
lmZ d dlmZ d dlm Z m!Z! d dl"m#Z#m"Z" d ej$                    dZ%dZ&dZ'dZ(e(Z)dZ*dZ+dZ,dZ-d.                     e"            d/                     e#                      f          Z0d/                    e-e0          Z1	 da2	 d Z3d Z4 eej5                   G d de6                      Z7 G d d e7          Z8 e8            a9d! Z:d" Z; e            Z<d d#l=m>Z> d d$l?m@Z@ e G d% d&e6                      ZA G d' d(eA          ZB G d) d*eA          ZCdS )+    )absolute_importN)deepcopy)ceil)python_2_unicode_compatibleadd_metaclass
Cloudinaryz4%(asctime)s - %(name)s - %(levelname)s - %(message)s)utils)GeneralError)responsive_breakpoints_cache)
HttpClient)urlparseparse_qs)python_versionplatformCERT_REQUIRED)	cert_reqsca_certszd3jpl91pxevbkh.cloudfront.netzcloudinary-a.akamaihd.netzres.cloudinary.comzNdata:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7
cloudinaryv1_1z1.44.1z; z	Python {}zCloudinaryPython/{} ({}) c                  J    t           dk    rt          S t           dz   t          z   S )z
    Provides the `USER_AGENT` string that is passed to the Cloudinary servers.
    Prepends  `USER_PLATFORM` if it is defined.

    :returns: the user agent
    :rtype: str
    r    )USER_PLATFORM
USER_AGENT     6D:\Nbitz\venv\Lib\site-packages\cloudinary/__init__.pyget_user_agentr   <   s%     s"Z//r   c                      	 ddl m}  	 ddlm} d|j        v r$ddlm} d                     |                      adt          |          v r|j
        S d S # | $ r Y d S w xY w# t          $ r Y d S w xY w)	Nr   )ImproperlyConfigured)settingsr   )get_versionzDjango/{django_version})django_version
CLOUDINARY)django.core.exceptionsr    django.confr!   INSTALLED_APPSdjangor"   formatr   dirr$   ImportError)r    _django_settings_get_django_versions      r   import_django_settingsr.   K   s    ??????	@@@@@@
 />>>EEEEEE 9 @ @PcPcPePe @ f fs#34444'22t# 	 	 	44	    tts/   A" A
A AA" AA" "
A0/A0c                       e Zd Zd Zd Zed             Zd Zd Zed             Z	e
j        d             Zd Zd	 Ze
j        d
             Zd ZdS )
BaseConfigc                 h    t                      }|r | j        di | |                                  d S Nr   )r.   update_load_config_from_env)selfdjango_settingss     r   __init__zBaseConfig.__init__h   sE    022 	+DK**/***""$$$$$r   c                 6    | j                             |          S N)__dict__get)r5   is     r   __getattr__zBaseConfig.__getattr__o   s    }  ###r   c                 ,    t          j        d|           S )Nz
\w+\[\w+\])rematch)keys    r   _is_nested_keyzBaseConfig._is_nested_keyr   s    xs+++r   c                    t          j        d|          }d |D             }| j        }|                                }|D ]$}||v r	||         }nt	                      }|||<   |}%t          |t                    r|d         }|||<   d S )Nz[\[\]]+c                     g | ]}||S r   r   ).0ks     r   
<listcomp>z.BaseConfig._put_nested_key.<locals>.<listcomp>x   s    '''qQ''''r   r   )r?   splitr:   popdict
isinstancelist)r5   rA   valuechainouterlast_key	inner_keyinners           r   _put_nested_keyzBaseConfig._put_nested_keyv   s    S))''E'''99;; 	 	IE!!i(#(i EEeT"" 	!HEhr   c                 F    |j                                         | j        k    S )z
        Helper function. Validates url scheme

        :param url: A named tuple containing URL components

        :return: bool True on success or False on failure
        )schemelower_uri_scheme)r5   urls     r   _is_url_scheme_validzBaseConfig._is_url_scheme_valid   s      z!!T%555r   c                      t          |           S r9   )r   )cloudinary_urls    r   _parse_cloudinary_urlz BaseConfig._parse_cloudinary_url   s    '''r   c                     t                      )z.Extract additional config from the parsed URL.NotImplementedError)r5   
parsed_urls     r   _config_from_parsed_urlz"BaseConfig._config_from_parsed_url        "###r   c                    |                      |          } | j        di | t          |j                                                  D ]A\  }}|                     |          r|                     ||           1|d         | j        |<   Bd S Nr   r   )ra   r3   r   queryitemsrB   rS   r:   )r5   r`   config_from_parsed_urlrF   vs        r   _setup_from_parsed_urlz!BaseConfig._setup_from_parsed_url   s    !%!=!=j!I!I--,---Z-..4466 	( 	(DAq""1%% ($$Q****#$Q4a  		( 	(r   c                 V    |                      |          }|                     |          S r9   )r\   ri   )r5   rX   r`   s      r   _load_from_urlzBaseConfig._load_from_url   s)    //44
**:666r   c                     t                      )z.Load config from environment variables or URL.r^   r5   s    r   r4   z BaseConfig._load_config_from_env   rb   r   c                 N    |                                 D ]\  }}|| j        |<   d S r9   )rf   r:   )r5   keywordsrF   rh   s       r   r3   zBaseConfig.update   s8    NN$$ 	! 	!DAq DM!	! 	!r   N)__name__
__module____qualname__r7   r=   staticmethodrB   rS   rY   r\   abcabstractmethodra   ri   rk   r4   r3   r   r   r   r0   r0   f   s        % % %$ $ $ , , \,      6 6 6 ( ( \( 	$ $ $( ( (7 7 7
 	$ $ $! ! ! ! !r   r0   c                   *     e Zd Z fdZd Zd Z xZS )Configc                     t           | _        t          t          |                                            | j        st          j        | _        | j        s	d| _        d S d S )N   )	
URI_SCHEMErW   superrw   r7   signature_algorithmr	   SIGNATURE_SHA1signature_version)r5   	__class__s    r   r7   zConfig.__init__   s`    %fd$$&&&' 	<',';D$% 	'%&D"""	' 	'r   c                     |                      |          st          d          |j        dk    }|j        |j        |j        |d}|r$|                    d|j        dd          i           |S )NzFInvalid CLOUDINARY_URL scheme. Expecting to start with 'cloudinary://'r   )
cloud_nameapi_key
api_secretprivate_cdnsecure_distribution   )rY   
ValueErrorpathhostnameusernamepasswordr3   )r5   r`   is_private_cdnresults       r   ra   zConfig._config_from_parsed_url   s    ((44 	gefff#B.$-!*$-)	
 
  	HMM0*/!""2EFGGGr   c                    t           j                            d          rd t           j                                        D             }|D ]V}|t	          d          d                                          }t           j        |         }|dv r|dk    } | j        di ||i Wd S t           j                            d          r4|                     t           j                            d                     d S d S )NCLOUDINARY_CLOUD_NAMEc                 H    g | ]}|                     d           r|dk    | S )CLOUDINARY_CLOUDINARY_URL)
startswith)rE   rA   s     r   rG   z0Config._load_config_from_env.<locals>.<listcomp>   sE     Y Y Y3!nn];;Y@CGW@W@W @W@W@Wr   r   )truefalser   r   r   )osenvironr;   keyslenrV   r3   rk   )r5   config_keysfull_keyconf_keyconf_vals        r   r4   zConfig._load_config_from_env   s   :>>122 	BY Y"*//*;*; Y Y YK ( 4 4#C$6$6$7$78>>@@:h/000'61H33x233334 4 Z^^,-- 	B
/? @ @AAAAA	B 	Br   )rp   rq   rr   r7   ra   r4   __classcell__r   s   @r   rw   rw      s]        ' ' ' ' '   B B B B B B Br   rw   c                  2    t          j        di |  t           S r2   )_configr3   )ro   s    r   configr      s    NXNr   c                  "    t                      ad S r9   )rw   r   r   r   r   reset_configr      s    hhGGGr   )Search)SearchFoldersc                      e Zd ZdZddddidddddidddd	id
ddd	id
gZ	 	 	 d)dZd Zd Zd Zd Z	d Z
d Zed             Zd Zd Zed             Zed             Zed             Zd Zd*dZd Zd*dZed             Zd Zd Zd  Zed*d!            Zed"             Zd# Zd$ Zd% Z ed&             Z!d' Z"d( Z#dS )+CloudinaryResourcez+
    Recommended sources for video tag
    mp4hev1video_codech265)typecodecstransformationswebmvp9auto)r   r   Nc
                    || _         |pi }|p|                    d          | _        |p|                    d          | _        |p|                    d          | _        |p|                    d          | _        |p|                    d          pd| _        |p|                    d          p|	| _        |pi | _        d S )N	public_idr)   version	signaturer   uploadresource_type)	metadatar;   r   r)   r   r   r   r   url_options)
r5   r   r)   r   r   r   r   r   r   default_resource_types
             r   r7   zCloudinaryResource.__init__	  s     !>r"?hll;&?&?6X 6 69(,,y"9"9"?hll;&?&?<HLL00<H	*dhll?.K.KdOd&,"r   c                     | j         S r9   )r   rm   s    r   __str__zCloudinaryResource.__str__  s
    ~r   c                 <    | j         t          | j                   ndS )Nr   )r   r   rm   s    r   __len__zCloudinaryResource.__len__  s    &*n&@s4>"""aGr   c                 L    t          j        | j        | j        | j                  S r9   )r	   verify_api_response_signaturer   r   r   rm   s    r   validatezCloudinaryResource.validate  s    24>4<QUQ_```r   c                     d | j         | j        | j        fv rd S d}|| j        z   dz   | j        z   dz   }| j        r|dz   t	          | j                  z   dz   }|| j         z   }| j        r|dz   | j        z   }|S )Nr   /rh   .)r   r   r   r   strr)   )r5   preps     r   get_prep_valuez!CloudinaryResource.get_prep_value  s    DNI&( ( ( 4d((3.:S@< 	8#:DL 1 11C7Ddn$; 	,#:+Dr   c                 Z    |                                  dz   |                                 z   S )N#)r   get_expected_signaturerm   s    r   get_presignedz CloudinaryResource.get_presigned-  s*    ""$$s*T-H-H-J-JJJr   c                     t          j        | j        | j        dt	                      j        t	                      j        d          S )N)r   r   r   )r~   )r	   api_sign_requestr   r   r   r   r|   rm   s    r   r   z)CloudinaryResource.get_expected_signature0  sG    %DNt|&\&\^d^f^f^q&,hh&BVWY Y Y 	Yr   c                 &     | j         di | j        S r2   )	build_urlr   rm   s    r   rX   zCloudinaryResource.url4  s    t~11 0111r   c                     t          | j        | j        | j        | j        pd          }|                    |           |                    d          p| j        }t          j	        |fi |S )Nimage)r)   r   r   r   r   )
rJ   r)   r   r   r   r3   r;   r   r	   r[   )r5   optionscombined_optionsr   s       r   __build_urlzCloudinaryResource.__build_url8  sy    t{DLty.2.@.KGM M M((($((55G	#IBB1ABBBr   c                 (     | j         di |d         S rd   )_CloudinaryResource__build_urlr5   r   s     r   r   zCloudinaryResource.build_url?  s     t**'**1--r   c                 8    |                      dd          | d<   d S )Nr)   jpg)r;   )r   s    r   default_poster_optionsz)CloudinaryResource.default_poster_optionsB  s     #KK%88r   c                  
    g dS )N)r   r   ogvr   r   r   r   default_source_typesz'CloudinaryResource.default_source_typesF  s    %%%%r   c                 "    t           fddD                       st                              d           dS  d          d         k    rt                              d           dS  d         d	k    rt                              d
           dS dS )a  
        Helper function. Validates srcset_data parameters

        :param srcset_data: A dictionary containing the following keys:
                breakpoints A list of breakpoints.
                min_width   Minimal width of the srcset images
                max_width   Maximal width of the srcset images.
                max_images  Number of srcset images to generate.

        :return: bool True on success or False on failure
        c              3   `   K   | ](}|v ot          |         t          j                  V  )d S r9   )rK   numbersNumber)rE   rF   srcset_datas     r   	<genexpr>z;CloudinaryResource._validate_srcset_data.<locals>.<genexpr>W  sV       l lWX1#R
;q>7>(R(R l l l l l lr   )	min_width	max_width
max_imageszlEither valid (min_width, max_width, max_images)or breakpoints must be provided to the image srcset attributeFr   r   z%min_width must be less than max_widthr   r   z%max_images must be a positive integerT)allloggerwarning)r   s   `r   _validate_srcset_dataz(CloudinaryResource._validate_srcset_dataJ  s      l l l l ]k l l l l l 	NN [ \ \ \5{#k+&>>>NNBCCC5|$))NNBCCC5tr   c                    |                     dt                                }|r|S |                     |          sdS |d         |d         |d         }}}|dk    r|}t          t	          t          ||z
            |dk    r|dz
  ndz                      }|}||k     r |                    |           ||z  }||k      |                    |           |S )a  
        Helper function. Calculates static responsive breakpoints using provided parameters.

        Either the breakpoints or min_width, max_width, max_images must be provided.

        :param srcset_data: A dictionary containing the following keys:
                                breakpoints A list of breakpoints.
                                min_width   Minimal width of the srcset images
                                max_width   Maximal width of the srcset images.
                                max_images  Number of srcset images to generate.

        :return: A list of breakpoints

        :raises ValueError: In case of invalid or missing parameters
        breakpointsNr   r   r   r   )r;   rL   r   intr   floatappend)r5   r   r   r   r   r   	step_sizecurr_breakpoints           r   _generate_breakpointsz(CloudinaryResource._generate_breakpointsg  s     "oomTVV<< 	))+66 	4+6{+C[Q\E]_jkw_xj9	??!IU9y#899z\]~~Z!^^cdeffgg	#	))///y(O 	)) 	9%%%r   c                    |t                      }|                    dd          }|                    dd          }|                    dd          }|                    dd	          }|                    d
          }t          t          t	          |          dz                      }d                    ||||          }	t          j        | j        |	||          }
t          
                    |
                              dd          S )a  
        Helper function. Retrieves responsive breakpoints list from cloudinary server

        When passing special string to transformation `width` parameter of form `auto:breakpoints{parameters}:json`,
        the response contains JSON with data of the responsive breakpoints

        :param srcset_data: A dictionary containing the following keys:
                                min_width   Minimal width of the srcset images
                                max_width   Maximal width of the srcset images
                                bytes_step  Minimal bytes step between images
                                max_images  Number of srcset images to generate
        :param options: Additional options

        :return: Resulting breakpoints
        Nr   2   r   i  
bytes_stepi N  r      transformationi   zHauto:breakpoints_{min_width}_{max_width}_{kbytes_step}_{max_images}:json)r   r   kbytes_stepr   r   )rJ   r;   r   r   r   r)   r	   cloudinary_scaled_urlr   _http_clientget_json)r5   r   r   r   r   r   r   r   r   breakpoints_width_parambreakpoints_urls              r   _fetch_breakpointsz%CloudinaryResource._fetch_breakpoints  s      &&KOOK44	OOK66	 __\599
 __\266
$)9::$uZ00478899"l"s"s9+Zd #t #f #f5dnF]_movww$$_5599-NNNr   c                    |                     d          }|r|S |                     d          rt          j        j         | j        fi |}|sy	  | j        |fi |}nJ# t
          $ r=}t                              d                    |j	                             Y d}~nd}~ww xY w|rt          j        j
        | j        |fi | |s|                     |          }|S )a:  
        Helper function. Gets from cache or calculates srcset breakpoints using provided parameters

        :param srcset_data: A dictionary containing the following keys:
                                breakpoints A list of breakpoints.
                                min_width   Minimal width of the srcset images
                                max_width   Maximal width of the srcset images
                                max_images  Number of srcset images to generate
        :param options: Additional options

        :return: Resulting breakpoints
        r   	use_cachez.Failed getting responsive breakpoints: {error})errorN)r;   r   instancer   r   r
   r   r   r)   messagesetr   )r5   r   r   r   es        r   _get_or_generate_breakpointsz/CloudinaryResource._get_or_generate_breakpoints  s)    "oom44 	??;'' 		f6?CDN^^V]^^K fm"9$"9+"Q"Q"Q"QKK# m m mNN#S#Z#Zabaj#Z#k#kllllllllm  f09=dnkee]deee 	B44[AAKs   A 
B$'3BB$c                 v     |sdS t                      d                     fd|D                       S )aj  
        Helper function. Generates srcset attribute value of the HTML img tag.

        :param breakpoints: A list of breakpoints.
        :param transformation: Custom transformation
        :param options:     Additional options

        :return:  Resulting srcset attribute value

        :raises ValueError: In case of invalid or missing parameters
        N, c           
      p    g | ]2}d                      t          j        j        |          |          3S )z{0} {1}w)r)   r	   r   r   )rE   wr   r5   r   s     r   rG   zACloudinaryResource._generate_srcset_attribute.<locals>.<listcomp>  s\     R R R@A %++E,GNA~w-8 -89:< < R R Rr   )rJ   join)r5   r   r   r   s   ` ``r   _generate_srcset_attributez-CloudinaryResource._generate_srcset_attribute  su      	4!!VVNyy R R R R R REPR R R S S 	Sr   c                 H    | sdS d                     d | D                       S )z
        Helper function. Generates sizes attribute value of the HTML img tag.

        :param breakpoints: A list of breakpoints.

        :return: Resulting 'sizes' attribute value
        Nr	  c              3   B   K   | ]}d                      |          V  dS )z(max-width: {bp}px) {bp}px)bpN)r)   )rE   r  s     r   r   z?CloudinaryResource._generate_sizes_attribute.<locals>.<genexpr>  s4      ZZ5<<<CCZZZZZZr   )r  )r   s    r   _generate_sizes_attributez,CloudinaryResource._generate_sizes_attribute  s2      	4yyZZkZZZZZZr   c                 6   t                      }|s|S d}d|vr9 | j        |fi |}|                    d          } | j        ||fi |}|r||d<   d|vrC|                    d          du r,|s | j        |fi |}|                     |          }|r||d<   |S )a  
        Helper function. Generates srcset and sizes attributes of the image tag

        Create both srcset and sizes here to avoid fetching breakpoints twice

        :param attributes: Existing attributes
        :param srcset_data: A dictionary containing the following keys:
                                breakpoints     A list of breakpoints.
                                min_width       Minimal width of the srcset images
                                max_width       Maximal width of the srcset images.
                                max_images      Number of srcset images to generate.
        :param options:     Additional options

        :return: The responsive attributes
        Nsrcsetr   sizesT)rJ   r  r;   r  r  )	r5   
attributesr   r   responsive_attributesr   r   srcset_attr
sizes_attrs	            r   %_generate_image_responsive_attributesz8CloudinaryResource._generate_image_responsive_attributes  s      !% 	)((:%%;$;KSS7SSK(__-=>>N9$9+~aaY`aaK >2=%h/*$$)A)AT)I)I X?d?WWwWW77DDJ <1;%g.$$r   c                 f   |                     d| j                  dk    r|                     |           |                    dt	                                }|                    dt	                                }t	                      }t          |t                    rKt                      j        pt	                      }|                                }|	                    |           n	d|vr||d<    | j
        di |\  }}|                    dt                      j                  }|                    dd          }|                    dd          }	|s|	rX|sV||d	<   |rd
nd}
d|v r|
d|d         z   z  }
|
|d<   |                    dt                      j                  }|dk    rt          } | j        ||fi |}|rdD ]}|                    |d           |	                    |           |	                    |           |r||d<   d                    t!          j        |                    S )zx
        Generates HTML img tag

        :param options: Additional options

        :return: Resulting img tag
        r   videor  r  client_hints
responsiveFhidpizdata-srczcld-responsivez	cld-hidpiclassr   responsive_placeholderblank>   widthheightNsrcz
<img {0}/>r   )r;   r   r   rI   rJ   rK   r   r  copyr3   r   r  r   CL_BLANKr  r)   r	   
html_attrs)r5   r   custom_attributessrcset_optionr   r$  attrsr  r  r  classesresponsive_attrsrA   s                r   r   zCloudinaryResource.image   sQ    ;;(:;;wFF''000#KKdff==Hdff55ffmT** 	< ((/3TVVK%**,,K}----000.;!(+%T%0000
Uyy1FGGYY|U33
		'5)) 
	% 
	 
	 #E**4E&&+G%3w//$E'N))4fhh6UVVCg~~E4EFWYdpphopp 	%* % %		#t$$$$%&&&&''' 	E%L##E$4U$;$;<<<r   c                 F    |                      |            | j        di |S r2   )r   r   r   s     r   video_thumbnailz"CloudinaryResource.video_thumbnailZ  s.    ##G,,,t~(((((r   c                     | dk    rdn| } | sdS t          |t          t          f          rd                    |          n|}|rd                    |          nd}d                    | |          S )a  
        Helper function for video(), generates video MIME type string from video_type and codecs.
        Example: video/mp4; codecs=mp4a.40.2

        :param video_type: mp4, webm, ogg etc.
        :param codecs: List or string of codecs. E.g.: "avc1.42E01E" or "avc1.42E01E, mp4a.40.2" or
                       ["avc1.42E01E", "mp4a.40.2"]

        :return: Resulting mime type
        r   oggr   r	  z; codecs={codecs_str})
codecs_strz
video/{}{})rK   rL   tupler  r)   )
video_typer   r1  codecs_attrs       r   _video_mime_typez#CloudinaryResource._video_mime_type^  s     )E11UUz
 	2*4VdE]*K*KWTYYv&&&QW
OYa-44
4KKK_a"":{;;;r   c                     |                                  }d|v r|                    d          |d<   d|v r|                    d          |d<   d|v r|d         s|                    dd           |S )z
        Helper function for video tag, collects remaining options and returns them as attributes

        :param video_options: Remaining options

        :return: Resulting attributes
        
html_widthr"  html_heightr#  posterN)r%  rI   )video_optionsr  s     r   _collect_video_tag_attributesz0CloudinaryResource._collect_video_tag_attributesu  s     #''))
:%%",..">">JwJ&&#->>-#@#@Jx z!!*X*>!NN8T***r   c                     d|vr | j         dd|i|S |d         }t          |t                    s|S d|vr | j         dd|i|S t          j        |d         fi |d         S )z
        Helper function for video tag, generates video poster URL

        :param source: The public ID of the resource
        :param video_options: Additional options

        :return: Resulting video poster URL
        r9  r   r   r   )r.  rK   rJ   r	   r[   )r5   sourcer:  poster_optionss       r   _generate_video_poster_attrz.CloudinaryResource._generate_video_poster_attr  s     =(('4'JJ&JMJJJ&x0.$// 	"!!n,,'4'KK&KNKKK#N;$?RR>RRSTUUr   c                 6   g }|                     dg           }|                     dg           }|                     di           }|rt          |t                    r|D ]}|                                }|                    |                    di                      |                    dd          }	t          j        |fd|	i|d         }
|                    d	g           }|                    d
	                    t          j
        |
|                     |	|          d                               |S |s|                                 }t          |t          t          f          s|S |D ]}	|                                }|                    |                    |	i                      t          j        |fd|	i|d         }
|                    d
	                    t          j
        |
|                     |	          d                               |S )a  
        Helper function for video tag, populates source tags from provided options.

        source_types and sources are mutually exclusive, only one of them can be used.
        If both are not provided, source types are used (for backwards compatibility)

        :param source: The public ID of the video
        :param options: Additional options

        :return: Resulting source tags (may be empty)
        sourcessource_typessource_transformationr   r   r   r)   r   r   z<source {attributes}>)r$  r   )r  )rI   rK   rL   r%  r3   r;   r	   r[   r   r)   r'  r5  r   r2  )r5   r=  r   source_tagsvideo_sourcesrB  rC  source_datar   source_typer$  r   s               r   _populate_video_source_tagsz.CloudinaryResource._populate_video_source_tags  sZ      Ir22{{>266 ',CR H H 	Zt<< 	, t t!(%%koo6G&L&LMMM)oofb99*6XX+XXXYZ[$266""#:#A#A$/TEZEZ[fhnEoEo0p0pqq $B $s $s t t t t   	74466L,u66 	' 	h 	hK$\\^^N!!"7";";K"L"LMMM&vTTkT^TTUVWC6== +CAVAVWbAcAc,d,dee  >  g  g h h h h r   c                    |                     d| j                  }|                     dt                      j                  }|sOt	          j        d                    d                    |                                                     d|          }n|}|	                    dt                                }|	                    dd          }|                     dd          }|                                }d	|vr|                     ||          |d	<   d
|vr| j        pd|d
<   |                     ||          }	|	s |dz   t          j        |          d         z   }t          j        |fi |\  }
}|	s|
|d<   |                     |          }|                    |           d                    d |	D                       }d                    t          j        |          ||          }|S )a]  
        Creates an HTML video tag for the provided +source+

        Examples:
           CloudinaryResource("mymovie.mp4").video()
           CloudinaryResource("mymovie.mp4").video(source_types = 'webm')
           CloudinaryResource("mymovie.ogv").video(poster = "myspecialplaceholder.jpg")
           CloudinaryResource("mymovie.webm").video(source_types = ['webm', 'mp4'], poster = {'effect': 'sepia'})

        :param options:
         * <tt>source_types</tt>            - Specify which source type the tag should include.
                                              defaults to webm, mp4 and ogv.
         * <tt>sources</tt>                 - Similar to source_types, but may contain codecs list.
                                              source_types and sources are mutually exclusive, only one of
                                              them can be used. If both are not provided, default source types
                                              are used.
         * <tt>source_transformation</tt>   - specific transformations to use
                                              for a specific source type.
         * <tt>poster</tt>                  - override default thumbnail:
           * url: provide an ad hoc url
           * options: with specific poster transformations and/or Cloudinary +:public_id+

        :return: Video tag
        r   use_fetch_formatz\.({0})$|r   r  fallback_contentrB  r9  r   r  r   r   r$  c              3   4   K   | ]}t          |          V  d S r9   )r   )rE   xs     r   r   z+CloudinaryResource.video.<locals>.<genexpr>  s(      ::c!ff::::::r   z/<video {attributes}>{sources}{fallback}</video>)r  rA  fallback)r;   r   r   rJ  r?   subr)   r  r   rI   rJ   r%  r?  r   rH  r	   build_arrayr[   r;  r3   r'  )r5   r   r   rJ  r=  r(  rO  rB  r>  rD  	video_urlr:  r  sources_strhtmls                  r   r  zCloudinaryResource.video  s   2 KKT^<<	";;'9688;TUU 	VK..sxx8Q8Q8S8S/T/TUUWY[deeFFF#KKdff==;;1266 {{>266 ,,, $ @ @ X XGH'))'+'9'DWGO$ 66vwGG 	Gc\E$5l$C$CA$FFF#(#7#J#J'#J#J 	= 	1'0e$77FF
+,,,gg::k:::::@GG'
33[S[ H ] ] r   c                      g }d| v r.|                     d                    | d                              d| v r.|                     d                    | d                              d                    |          S )Nr   z(min-width: {}px)r   z(max-width: {}px)z and )r   r)   r  )media_optionsmedia_query_conditionss     r   __generate_media_attrz(CloudinaryResource.__generate_media_attr  s    !#-''"))*=*D*D]S^E_*`*`aaa-''"))*=*D*D]S^E_*`*`aaa||2333r   c                     |                     d          pi }t                      j        pt                      }|                                }|                    |                    dt                                            | j        ||fi |}|                    |           d|vr | j        di |\  |d<   }d|vr( | j	        di |                     di           }|r||d<   d
                    t          j        |                    S )Nr  r  mediaz<source {0}>r   )r;   r   r  rJ   r%  r3   rI   r  r   (_CloudinaryResource__generate_media_attrr)   r	   r'  )r5   r   r*  r   r,  _
media_attrs          r   r=  zCloudinaryResource.source  s#   L))/Rhho/!&&((7;;x88999E4Ee[dd\cdd%&&& 5  !1!1!<!<G!<!<E(OQ%33QQw{{7B7O7OQQJ ,!+g%%e&6u&=&=>>>r   c                    g }|                     d          pt                      }|D ]nt          |          }dv rt          j        |d                   }t          fddD                       |d<   |                     | j        di |           o|                     | j        di |           d	                    d
                    |                    S )	NrA  r   c              3   4   K   | ]}|v ||         fV  d S r9   r   )rE   rF   r=  s     r   r   z-CloudinaryResource.picture.<locals>.<genexpr>;  s7      (k(kA_`dj_j_j!VAY_j_j_j_j(k(kr   )r   r   rZ  z<picture>{}</picture>r   r   )rI   rL   r   r	   chain_transformationsrJ   r   r=  r   r)   r  )r5   r   sub_tagsrA  curr_optionsr=  s        @r   picturezCloudinaryResource.picture2  s    ++i((2DFF 	9 	9F#G,,L6))$:<P`Iabb$((k(k(k(kA[(k(k(k$k$kL!OOKDK77,778888

--W--...'..rwwx/@/@AAAr   )	NNNNNNNNNr9   )$rp   rq   rr   __doc__default_video_sourcesr7   r   r   r   r   r   r   propertyrX   r   r   rs   r   r   r   r   r   r  r  r  r  r   r.  r5  r;  r?  rH  r  r[  r=  rc  r   r   r   r   r      s        
  -v6	
 	

  -u5
 

  -v6
 
  -v6
 
$ =A[_'+- - - -  H H Ha a a  K K KY Y Y 2 2 X2C C C. . . 9 9 \9 & & \&   \8( ( (TO O O OB" " "HS S S S* [ [ \[%% %% %%N8= 8= 8=t) ) ) < < < \<,   \(V V V,. . .`@ @ @D 4 4 \4? ? ?,B B B B Br   r   c                         e Zd Zd fd	Z xZS )CloudinaryImageNc                 N     t          t          |           j        d|dd| d S )Nr   r   r   r   )r{   rh  r7   r5   r   kwargsr   s      r   r7   zCloudinaryImage.__init__E  5    -ot$$-k	Y`kkdjkkkkkr   r9   rp   rq   rr   r7   r   r   s   @r   rh  rh  D  G        l l l l l l l l l lr   rh  c                         e Zd Zd fd	Z xZS )CloudinaryVideoNc                 N     t          t          |           j        d|dd| d S )Nr  rj  r   )r{   rq  r7   rk  s      r   r7   zCloudinaryVideo.__init__J  rm  r   r9   rn  r   s   @r   rq  rq  I  ro  r   rq  )D
__future__r   rt   loggingr   r   r?   r%  r   mathr   certifisixr   r   	getLoggerr   StreamHandlerch	Formatter	formattersetFormatter
addHandlerr   r	   cloudinary.exceptionsr
   cloudinary.cacher   cloudinary.http_clientr   cloudinary.compatr   r   r   r   whereCERT_KWARGSCF_SHARED_CDNOLD_AKAMAI_SHARED_CDNAKAMAI_SHARED_CDN
SHARED_CDNr&  rz   API_VERSIONVERSIONr  r)   _USER_PLATFORM_DETAILSr   r   r   r.   ABCMetaobjectr0   rw   r   r   r   r   cloudinary.searchr   cloudinary.search_foldersr   r   rh  rq  r   r   r   <module>r     s   & & & & & & 



   				 				              : : : : : : : :		<	(	(WGTUU	 	      "          . . . . . . 9 9 9 9 9 9 - - - - - - 0 0 0 0 0 0 0 0 - - - - - - - - ! 
 03 ( 
[

HHJJ0B0B>>CSCS0T0T#UVV '..w8NOO
 0 0 0  6 s{H! H! H! H! H! H! H! H!V(B (B (B (B (BZ (B (B (BV &((    
 z|| % $ $ $ $ $ 3 3 3 3 3 3 N	B N	B N	B N	B N	B N	B N	B N	Bbl l l l l( l l l
l l l l l( l l l l lr   