
    g                        d dl Z d dlZd dlZd dlZd dlZd dlZd dl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mZ d dlmZ d dlmZ d dlZd dlmZ d dlmZmZ d dlZd dlmZ d d	lmZmZ d d
lm Z m!Z!m"Z"m#Z#m$Z$m%Z% 	 d dl&m'Z( dZ*ejV                  j                  jX                  jZ                  Z-ejV                  j                  jX                  j\                  Z.	 dZ/dddZ0dZ1dZ2dZ3dZ4g dZ5g dZ6g dZ7g dZ8e7e8z   Z9dddddddd d!d"d#d$d%d&Z:d'Z;d(Z<d)Z=d*Z>e=ej~                  e>ej                  iZAe=fd+ZBd, ZCd- ZDd. ZEd/ ZFd0 ZGd1 ZHdd2ZId3 ZJd4 ZKd5 ZLd6 ZMd7 ZNd8 ZOd9 ZPd: ZQd; ZRd< ZSd= ZTd> ZUd? ZVd@ ZWe=fdAZXdB ZYdC ZZdD Z[dE Z\dF Z]dG Z^dH Z_dI Z`dJ ZaddKZbdL ZcdM ZdddNZedO ZfdP ZgdQ ZhdR ZidS ZjdT ZkdU ZldV ZmdW ZndX ZodY ZpdZ Zqd[ Zrd\ Zsd] Ztd^ Zud_ Zvd` Zwda Zxdb ZydcdddedfdgdhdidjdkdldmdndodpZzi dqdrdsdrdtdudvdudwdxdydxdzd{d|d}d~d}dddddddddddddddddddddddddddddZ{ddj                  e{j                               z   dz   Z~d Zd Zd Zd Zd Zd Zd Zd ZddZd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd ZddZddZd Zd ZddZd ZddZddZy# e)$ r dZ(Y :w xY w)    N)OrderedDict)datetimedate)Fraction)Number)	iteritems)ProxyManagerPoolManager)
auth_token)TCPKeepAlivePoolManagerTCPKeepAliveProxyManager)PY3to_bytesto_bytearray	to_stringstring_typesurlparse)Pathz(\$\([a-zA-Z]\w+\))res.cloudinary.comautolimit)widthcropz,^(?P<value>(\d+\.)?\d+)(?P<modifier>[%pP])?$z(^(\d+\.)?\d+[%pP]?\.\.(\d+\.)?\d+[%pP]?$z^(\d+)\.(\d+)?$zdftp:|https?:|s3:|gs:|data:([\w-]+\/[\w-]+(\+[\w-]+)?)?(;[\w-]+=[\w-]+)*;base64,([a-zA-Z0-9\/+\n=]+)$))font_weightnormal)
font_styler   )text_decorationnone)
text_alignN)stroker   )
api_secretr   cdn_subdomain
cloud_namecnameformatprivate_cdnresource_typesecuresecure_cdn_subdomainsecure_distributionshortensign_urlssl_detectedtype
url_suffixuse_root_pathversionlong_url_signaturesignature_algorithm).	public_idpublic_id_prefixcallbackr%   r.   backupfacesimage_metadatamedia_metadataexifcolorsuse_filenameunique_filenamedisplay_nameuse_filename_as_display_namediscard_original_filenamefilename_override
invalidatenotification_urleager_notification_urleager_asynceval
on_successproxyfolderasset_folder$use_asset_folder_as_public_id_prefixunique_display_name	overwrite
moderationraw_convertquality_overridequality_analysisocrcategorization	detectionsimilarity_searchvisual_searchbackground_removalupload_presetphashreturn_delete_tokenauto_taggingasynccinemagraph_analysisaccessibility_analysis)	timestamptransformationheaderseagertagsallowed_formatsface_coordinatescustom_coordinatesregionscontextr\   responsive_breakpointsaccess_controlmetadataaudio_codecaudio_frequencybit_ratecolor_spacedefault_imagedelaydensityfetch_formatgravityprefixpagestreaming_profilevideo_sampling)acafbrcsddldnfgppgspvs       sha1sha256c                     	 t         |   } |t	        |             j                         S # t        $ r t        dj                  |            w xY w)a  
    Computes string hash using specified algorithm and return HEX string representation of hash.

    :param s:         String to compute hash for
    :param algorithm: The name of algorithm to use for computing hash

    :return: HEX string of computed hash value
    zUnsupported hash algorithm: {})signature_algorithmsKeyError
ValueErrorr%   r   	hexdigest)s	algorithmhash_fns      %/opt/Tautulli/lib/cloudinary/utils.pycompute_hex_hashr      sV    M&y1 8A;))++  M9@@KLLMs	   	* $Ac                 @    t        | t        t        f      r| S | g S | gS N)
isinstancelisttuple)args    r   build_arrayr      s&    #e}%
		5L    c                 H   | g S t        | t              rt        j                  | t              } t        | t
              r| g} t        |       D ]Q  \  }}t        |t              rt        j                  |t              | |<   t        | |   t
              rHt        d       | S )a  
    Converts a value that can be presented as a list of dict.

    In case top level item is not a list, it is wrapped with a list

    Valid values examples:
        - Valid dict: {"k": "v", "k2","v2"}
        - List of dict: [{"k": "v"}, {"k2","v2"}]
        - JSON decodable string: '{"k": "v"}', or '[{"k": "v"}]'
        - List of JSON decodable strings: ['{"k": "v"}', '{"k2","v2"}']

    Invalid values examples:
        - ["not", "a", "dict"]
        - [123, None],
        - [["another", "list"]]

    :param val: Input value
    :type val: Union[list, dict, str]

    :return: Converted(or original) list of dict
    :raises: ValueError in case value cannot be converted to a list of dict
    )object_pairs_hookzExpected a list of dicts)r   strjsonloadsr   dict	enumerater   )valindexitems      r   build_list_of_dictsr      s    . {	#sjj<#te ~ 9tdC DKHCJ#e*d+7889 Jr   c                 ^   t        |       } t        |       dkD  rct        | d   t              rPdj	                  | D cg c]3  }dj	                  t        |      D cg c]  }t        |       c}      5 c}}      S t        | D cg c]  }t        |       c}      S c c}w c c}}w c c}w )Nr   |,)r   lenr   r   joinr   encode_list)arrayinneris      r   encode_double_arrayr      s    E
5zA~*U1Xt4xxUZ[E;u3E"Fa3q6"FG[\\.1A.// #G[.s   B$
B,	B$
B*B$
c                     t        | t              r?t        r| j                         }n| j	                         }dj                  d |D              S | S )Nr   c              3   2   K   | ]  \  }}|d z   |z     yw)=N .0kvs      r   	<genexpr>zencode_dict.<locals>.<genexpr>   s     8$!QS18   )r   r   r   itemsr   r   )r   r   s     r   encode_dictr      s?    #tIIKEMMOExx8%888Jr   c                     t        | t        t        f      rt        |       } t	        |       j                  dd      j                  dd      S )z
    Escape "=" and "|" delimiter characters and json encode lists

    :param value: Value to escape
    :type value: int or str or list or tuple

    :return: The normalized value
    :rtype: str
    r   z\=r   z\|)r   r   r   json_encoder   replacevalues    r   normalize_context_valuer      s@     %$'E"u:c5)11#u==r   c                 h    t        | t              s| S dj                  d t        |       D              S )a  
    Encode metadata fields based on incoming value.

    List and tuple values are encoded to json strings.

    :param context: dict of context to be encoded

    :return: a joined string of all keys and values properly escaped and separated by a pipe character
    r   c              3   X   K   | ]"  \  }}d j                  |t        |             $ yw)z{}={}N)r%   r   r   s      r   r   z!encode_context.<locals>.<genexpr>  s%     c1W^^A'>q'ABcs   (*)r   r   r   r   )ri   s    r   encode_contextr     s/     gt$88cPYZaPbcccr   c                 d    t        | t              s| | S t        j                  | t        d|      S )z
    Converts value to a json encoded string

    :param value: value to be encoded
    :param sort_keys: whether to sort keys

    :return: JSON encoded string
    )r   :)default
separators	sort_keys)r   r   r   dumps__json_serializer)r   r   s     r   r   r   !  s.     %::e%6:Ybccr   c                 $    | j                  d      S )z
    Encodes date object to `dd-mm-yyyy` format string

    :param date_obj: datetime.date object to encode

    :return: Encoded date as a string
    z%d-%m-%Y)strftime)date_objs    r   encode_date_to_usage_api_formatr   1  s     Z((r   c                     | j                  dt        j                         j                        }| j	                  dd      dk7  r|sy| j                  dd      }d| vr|| d<   yy)z
    When upload type is fetch, remove the format options.
    In addition, set the fetch_format options to the format value unless it was already set.
    Mutates the "options" parameter!

    :param options: URL and transformation options
    use_fetch_formatr.   uploadfetchNr%   rt   )pop
cloudinaryconfigr   get)optionsr   resource_formats      r   patch_fetch_formatr   <  se     {{#5z7H7H7J7[7[\{{68$/8Hkk(D1OW$"1 %r   c                  n   | j                  dt        j                         j                        }| j                  dd       }|r|j	                  d      \  | d<   | d<   | j                  d      }| j                  d      }d| v xs d| v }| j                  dd       }d	j                  t        | j                  d
d             D cg c]  }t        |       c}      }|xs |xs |dk(  xs	 |dk(  xs |}	|r8t        |      j                  d      st        |      dk(  st        |      s|	r| d= |rt        |      dk(  st        |      s|	r| d= | j                  dd       }
|
r|
j                  dd      }
| j                  dd       }|r|j                  dd      }t        | j                  dd             }t        d |D              rd }t        t        ||            }d }nd	j                  |      }g }| j                  dd       }t        |t              r)dj                  |D cg c]  }t        |       c}      }nRt        |t               rBdj                  t        |j#                               d   D cg c]  }t        |       c}      }| j                  dd       }t        |t               rC|j                  dd      j                  dd      }d|t        |j                  dd            dz  }d	j                  t        | j                  dd                   }| j                  d t        j                         j$                        }t'        | j                  d!d             }| j                  d"d       }t)        |      }|d k(  r|}| j                  d#d       }t'        |      }|d k(  r|}t+        | j                  d$d             }|rt)        |d         }t'        |d%         }t-        | j                  d&d             }| j                  d'd       }t        |t.              r.t        |j0                        dz   t        |j2                        z   }t5        | j                  dd       d      }t5        | j                  dd       d      }t7        | j                  d(d             }t9        | j                  d)d             } t;        | j                  d*d             }!t=        | j                  d+d             }"i d,t?        |      d-t?        |      d.|
d/|d0|d1|d t?        |      d2t?        |      d3t?        |      d4t?        |      d5|d6| xs |!d+|"d7t?        |      d8tA        | j                  d9d             d:|d;t?        | j                  d<d             t?        | j                  d=d             tC        | j                  d>d             t?        |      ||t?        |      t?        | j                  dd             t?        | j                  d?d             |t?        | j                  d@d             dA
}#tD        j#                         D ]  \  }$}%| j                  |%d       |#|$<    | j                  dBi       }&g }'| j#                         D ]O  \  }(}tG        jH                  dC|(      s|'jK                  dDjM                  |(t?        t        |                         Q |'jO                          |&r@|&D ];  })|'jK                  dDjM                  |)d   t?        t        |)d%                            = dEj                  |'      }&tQ        |#j#                         D $cg c]  \  }$}|s|dk(  s|$dFz   t        |      z     c}}$      }*|&r|*jS                  dt        |&             ||*jS                  ddGt        |      z          dH| v r-| dH   s| dH   dk(  r |*jK                  | j                  dH             dEj                  |*      }+||+gz   },|r8t        j                         jT                  xs tV        }-|,tY        dMi |-d   gz  },dIj                  |,D .cg c]  }.|.s|.	 c}.      }/t        |      j                  d      s|rdJ| dK<   |dk(  rdJ| dL<   |/| fS c c}w c c}w c c}w c c}}$w c c}.w )NNresponsive_widthsizexr   heightunderlayoverlayr   .anglefitr   r   owoh
background#zrgb:colorra   c              3   <   K   | ]  }t        |t                y wr   )r   r   )r   bss     r   r   z1generate_transformation_string.<locals>.<genexpr>h  s     
?B:b$
?s   c                 \    t        | t              rt        di | d   S t        |       d   S )Nr   )ra   r   )r   r   generate_transformation_string)r   s    r   recursez/generate_transformation_string.<locals>.recursei  s/    "d#5;;A>>1DQGGr   effectr   r   borderblackz%(width)spx_solid_%(color)s   )r   r   flagsdprdurationstart_offset
end_offsetoffset   video_codecaspect_ratioifcustom_functioncustom_pre_functionfpsaarbboccodueeoflfnhkikeyframe_intervalloopacityqualityradiusyzoom)
qrsotuwr   r  vcz	variablesz^\$z{0}_{1}r   _if_raw_transformation/T
responsivehidpir   )-r   r   r   r   splitr   r   r   r   
startswithis_fractionr   anyr   mapr   r   r   r   norm_range_valuenorm_auto_range_valuesplit_rangeprocess_video_codec_paramr   	numeratordenominatorprocess_layerprocess_conditionalprocess_custom_functionprocess_custom_pre_functionprocess_fpsnormalize_expression
process_kiprocess_radius_SIMPLE_TRANSFORMATION_PARAMSrematchappendr%   sortsortedinsertresponsive_width_transformation'DEFAULT_RESPONSIVE_WIDTH_TRANSFORMATIONr   )0r   r   r   r   r   	has_layerr   r   r   no_html_sizesr   r   base_transformationsr   named_transformationr   r   r   border_colorr   r   r   so_rawr   eo_rawr   r   r   r   r   r   if_valuer   r   r  paramsparamoptionr  
var_paramskeyvarsorted_paramsra   transformationsr@  transurls0                                                   r   r   r   N  sZ   {{#5z7H7H7J7[7[\;;vt$D.2jjo+'(+KK E[["Fw&AI,@I;;vt$DHHk'++gt:T.UVUc%jVWE^^$%-^47?^N^M#e*''/3u:3EUZI[_lG3v;$&+f*=H\40J''V4
KK&Ec6*&w{{3CT'JK

?*>
??	H
  $C1E$FG#"xx(<=![[4(F&$62a3q623	FD	!4+?+BCa3q6CD[[4(F&$zz'73;;CH.<;>vzz'ST?U;V2X X HH[Wd!;<=E
++eZ..044
5CJ =>H[[.F(0Lt[[t,F!&)JT
Xt45F,VAY7%fQi0
+GKKt,LMK;;~t4L,)<112S83|?W?W;XXGKK	48)DGW[[T:JGH"7;;tT#:;H-gkk:KT.RSO5gkkBWY]6^_
gkk%.
/C!%("<0 	Z 	f	
 	T 	e 	#C( 	"8, 	!&) 	":. 	e 	o4!4 	s 	!&) 	j%8$?@  	W!" 	!'++i">?#$ "'++i">?GKK$78"<0!!%(!'++c4"89!'++c4"89!'++fd";<7F< 7<<> 2vFD1u2 K,IJmmo X
U88FC j//5I#e*5UVWX OO 	\Cj//A8LSQTUVQW[8YZ[	\ $Iq\aejnoeoECK#e*4qrMQI/QH 56w&G4H,IWUiMjnoMoW[[)=>?XXm,N*n-==O*4*;*;*=*]*] +U-T 	(:]=\]^_`aa
((@e%E@
AC
5zV$(8 $
f}<_ W< 3Cn r$ As*   b&b"9b'"b,
2b,
b2#b2c                      t        j                  |      }t        |      }t         fdt        D              }|j                  d        ||d<   |S )a,  
    Helper function, allows chaining transformations to the end of transformations list

    The result of this function is an updated options parameter

    :param options:         Original options
    :param transformations: Transformations to chain at the end

    :return: Resulting options
    c              3   6   K   | ]  }|v s||   f  y wr   r   r   r  r   s     r   r   z(chain_transformations.<locals>.<genexpr>       K1a7l71:K   	r   ra   )copydeepcopyr   r   
__URL_KEYSr?  )r   rQ  url_optionss   `  r   chain_transformationsr]    sN     mmO4O!/2OK
KKK1g&$3K !r   c                 l    t        |       } t        j                  t        |       xr t	        |       dk  S )Nr   )r   r:  r;  FLOAT_REfloat)r   s    r   r(  r(    s*    JE88He$9u)99r   c                     t        | t              st        | t              rt        |       dk\  r
| d   | d   gS t        | t              r,t        j                  t        |       r| j                  dd      S y )Nr   r   z..r   )	r   r   r   r   r   r:  r;  RANGE_REr&  )ranges    r   r-  r-    s]    5$:eU#;Uqa%)$$	E<	(RXXh-F{{4##r   c                     | y t        j                  t        t        |             }|y d}|j	                  d      d}|j	                  d      |z   S )N modifierr   r   )r:  r;  RANGE_VALUE_REr   group)r   r;  rg  s      r   r+  r+    sS    }HH^SZ0E}H{{:*;;w(**r   c                 &    | dk(  r| S t        |       S )Nr   )r+  r   s    r   r,  r,    s    E""r   c                     | }t        |t              r>| d   }d| v r5|dz   | d   z   }d| v r&|dz   | d   z   }| j                  d      du r|dz   dz   }|S )Ncodecprofiler   levelb_framesF
bframes_no)r   r   r   )rK  	out_params     r   r.  r.  %  st    I)T"'N	!C%	*::I%%OeGn<	99Z(E1 )C, >Ir   c                     | y t        | t        t        f      rCdt        |       cxk  rdk  st	        d       t	        d      dj                  d | D              S t        t        |             S )Nr      zInvalid radius paramr   c              3   2   K   | ]  }t        |        y wr   r6  )r   r  s     r   r   z!process_radius.<locals>.<genexpr>:  s     ?A,Q/?r   )r   r   r   r   r   r   r6  r   )rK  s    r   r8  r8  3  sj    }%$'CJ#!#344 $344xx????E
++r   c           	      r   d }t        | t              ri }| j                         D ]  \  }}t        |t              st        |t              r\t        |      dk(  r|d   dk(  r|||<   Bt        |      D ci c]  \  }}dj                  ||      | }}}|j                  |       ||||<    |S c c}}w )Nr   r   filez{}[{}])	r   r   r   r   r   r   r   r%   update)rJ  processed_paramsrN  r   r   i_value
value_lists          r   process_paramsr|  ?  s    &$ ,,. 	.JC%&*UE*Bu:?uQx6'9,1$S)QZ[`Qab:1ghooc15w>b
b ''
3"(- %	. 	 cs   5B3c           
          t        | j                         D cg c]  \  }}|	|dk(  r|t        |      f c}}      S c c}}w )zu
    Cleans and normalizes parameters when calculating signature in Upload API.

    :param params:
    :return:
    rf  )r   r   __safe_valuerJ  r   r   s      r   cleanup_paramsr  O  s=     FLLNd&1aam\]ac\c!\!_%deeds   
A
A
A
c           
          | rt        | t              s| S t        | j                         D cg c]  \  }}|	|dk(  r|t        |      f c}}      S c c}}w )zK
    Normalizes Admin API parameters.

    :param params:
    :return:
    rf  )r   r   r   __bool_stringr  s      r   normalize_paramsr  Y  sO     FD1V\\^e6Aqq}]^bd]d!]1%&effes   
A
A
A
c                    |j                  dt        j                         j                        }|st	        d      |j                  dt        j                         j
                        }|st	        d      |j                  dt        j                         j                        }t        |       } t        | ||      | d<   || d<   | S )Napi_keyzMust supply api_keyr!   zMust supply api_secretr3   	signature)	r   r   r   r  r   r!   r3   r  api_sign_request)rJ  r   r  r!   r3   s        r   sign_requestr  f  s    kk)Z%6%6%8%@%@AG.//\:+<+<+>+I+IJJ122!++&;Z=N=N=P=d=deF#F*6:?RSF;F9Mr   c           	      
   | j                         D cg c]:  \  }}|s	|dz   t        |t              rdj                  |      n
t	        |      z   < }}}dj                  t        |            }t        ||z   |      S c c}}w )Nr   r   &)r   r   r   r   r   r>  r   )params_to_signr!   r   r   r   rJ  to_signs          r   r  r  v  sp    WeWkWkWmstqRSqrq3wAt)<#((1+#a&IsFshhvf~&GGj0)<< ts
   
A?4A?c                 x    t        j                  |       } | j                  d      }|t        di |\  | d<   }| S )Nra   r   )rY  rZ  r   r   )breakpoint_settingsra   r   s      r   breakpoint_settings_mapperr  |  sI    --(;<(,,-=>N!3Q3cTb3c0,-qr   c                 v    | y t        |       } t        j                  t        t	        t
        |                   S r   )r   r   r   r   r*  r  )breakpointss    r   &generate_responsive_breakpoints_stringr    s1    k*K::d39;GHIIr   c                 ^   t        j                  dd|       } t        j                  d|       rt        |       } | }| |fS t	        |       } t
        s| j                  d      } t        |       } | }|)t        j                  d|      rt        d      | dz   |z   } || dz   |z   } |dz   |z   }| |fS )	N([^:])/+\1/	^https?:/utf8z[\./]z$url_suffix should not include . or /r#  r   )	r:  subr;  smart_escapeunquoter   encodesearchr   )sourcer%   r/   source_to_signs       r   finalize_sourcer    s    VVK0F	xxf%f% >!! ]]6*Ff%!yy:. !GHHc\J.Fc\F*F+c1F:N>!!r   c                     |xs d}|)| dk(  r
|dk(  rd} d }n| dk(  r
|dk(  rd} d }nt        d      |r!| dk(  r|dk(  s| dk(  r|d } d }nt        d      |r| dk(  r	|dk(  rd} d }| |fS )	Nr   imageimagesrawfilesz9URL Suffix only supported for image/upload and raw/uploadz)Root path only supported for image/uploadiu)r   )r'   r.   r/   r0   r+   upload_types         r   finalize_resource_typer    s    "(KG#x(?$MKe#x(?#MKXYYW$)@)k.A MKHII=G+x0G+%%r   c                 z   | }t        |       }	|rn||t        j                  k(  r|r|dz   nt        j                  }|xs |t        j                  k(  }||r|}|rt	        j
                  dd|	z   dz   |      }d|z   }
n2|r|rd|	z   dz   nd}d	|z   |z   }
n|r|d
z   nd}|r|dz   |	z   }d	|z   dz   }
|r|
d|z   z  }
|
S )a  cdn_subdomain and secure_cdn_subdomain
    1) Customers in shared distribution (e.g. res.cloudinary.com)
      if cdn_domain is true uses res-[1-5].cloudinary.com for both http and https.
      Setting secure_cdn_subdomain to false disables this for https.
    2) Customers with private cdn
      if cdn_domain is true uses cloudname-res-[1-5].cloudinary.com for http
      if secure_cdn_domain is true uses cloudname-res-[1-5].cloudinary.com for https
      (please contact support if you require this)
    3) Customers with cname
      if cdn_domain is true uses a[1-5].cname for http. For https, uses the same naming scheme
      as 1 for shared distribution and as 2 for private distribution.z-res.cloudinary.comr   zres-z.cloudinary.comzhttps://r  r   rf  zhttp://z-resres-r#  )__crcr   OLD_AKAMAI_SHARED_CDN
SHARED_CDNr:  r  )r  r#   r&   r"   r)   r$   r(   r*   shared_domainshardrv   	subdomains               r   unsigned_download_url_prefixr    s    $OM&ME&*=AaAa*a #-/D"D$.$9$9   &U)<
@U@U)U'M#0 "$&&)=v~Pa?a)<#> 11	)6C%K#%B	Y&.+6J'E	!C%/IY&)::#
""Mr   c           
         | j                  dd      }| j                  dt        j                         j                  xs d       }|t	        d      | j                  dt        j                         j
                        }| j                  dt        j                         j                        }| j                  dt        j                         j                        }| j                  dt        j                         j                        }| j                  d	t        j                         j                        }| j                  d
t        j                         j                        }t        ||||||||      S )Nr  rf  r#   z1Must supply cloud_name in tag or in configurationr(   r&   r$   r*   r"   r)   )r   r   r   r#   r   r(   r&   r$   r*   r"   r)   r  )	r   r  r#   r(   r&   r$   r*   r"   r)   s	            r   build_distribution_domainr    s1   [[2&F\:+<+<+>+I+I+QTRJLMM[[:#4#4#6#=#=>F++mZ->->-@-L-LMKKK!2!2!4!:!:;E!++&;&0&7&7&9&M&MOKK1B1B1D1R1RSM";;'='1'8'8':'O'OQ (
K8Lv*, ,r   c                  f    d }| D ])  }|||j                         }|j                  |       + |S r   )rY  rx  )	dict_argsresult
dictionarys      r   merger    s@    F *
!~#*j)* Mr   c                    | }t        |       |j                  dd      }t        d"i |\  }}|j                  dd      }|j                  dt        j                         j
                        }|d}|j                  dd       }|j                  dd       }|j                  d	t        j                         j                        }	|j                  d
t        j                         j                        }
|j                  dt        j                         j                        }|j                  dd       }|j                  dt        j                         j                        }|j                  dd       }|j                  dt        j                         j                        }|j                  dt        j                         j                        }|dur(t        t        j                         j                  |      }| r|dk(  rt        j                  d|       r||fS t!        |||||	      \  }}t#        | ||      \  } }|sD|rB|j%                  d      dk\  r.t        j                  d|      st        j                  d|      sd}|rdt'        |      z   }nd }t        j(                  dd|      }d }|
r|r |j                  dd      rdj+                  t-        ||g            }|rt.        }t0        }nt2        }|t4        vrt7        dj9                  |            t4        |   }dt;        t=        j>                   |tA        ||z               jC                               d|       z   dz   }| |d<   tE        |      }dj+                  t-        ||||||| g            } |
rI|rGtG        |       jH                  }t        j                  jJ                  d"i t        |d |i      }| d!|} | |fS )#Nr.   r   r'   r  force_versionTr1   r%   r+   r,   r!   r/   r0   r   r2   r3   Fz^https?:r#  r   r  z^v[0-9]+1r   r  r  set_url_signaturez$Unsupported signature algorithm '{}'zs--z--r  rS  ?r   )&r   r   r   r   r   r  r+   r,   r!   r0   r2   r3   r  r   r:  r;  r  r  findr   r  r   	__compactSIGNATURE_SHA256LONG_URL_SIGNATURE_LENGTHSHORT_URL_SIGNATURE_LENGTHr   r   r%   r   base64urlsafe_b64encoder   digestr  r   pathgenerate)r  r   original_sourcer.   ra   r'   r  r1   r%   r+   r,   r!   r/   r0   r   r2   r3   r  r  r  chars_lengthr   rv   r  tokens                            r   cloudinary_urlr    s   Ow;;vx(D<GwGNGKK9MKK1B1B1D1R1RSMkk)T*G[[4(Fkk)Z%6%6%8%@%@AG{{:z'8'8':'C'CDH\:+<+<+>+I+IJJ\40JKK1B1B1D1R1RSM\40J %9:;L;L;N;a;ab!++&;Z=N=N=P=d=de:,,.99:F
tx'BHH[&,I''0tZAM4,VVZHFN}##C(A-HH\>:HH[.9G$VVK@NI~z~~6I5'Q((9nn%EFG"24L5L&::CJJK^_``&':;I$$:!567>>@BBCLRS SUYZ	 GH&w/FXXi	i&QS TFJ$$%%..RzE4=1QR"E*7?r   c                 N   |j                  dt        j                         j                        xs d}|j                  dt        j                         j                        }|st        d      t        |       } t        dj                  |t        j                  |g| z               S )Nupload_prefixzhttps://api.cloudinary.comr#   zMust supply cloud_namer#  )
r   r   r   r  r#   r   r   encode_unicode_urlr   API_VERSION)r  r   cloudinary_prefixr#   s       r   base_api_urlr  R  s    OZ5F5F5H5V5VW 87 \:+<+<+>+I+IJJ122tDchh(9:;Q;QS]'^ae'efggr   c                 B    |j                  dd      }t        || gfi |S )Nr'   r  )r   r  )actionr   r'   s      r   cloudinary_api_urlr  _  s'    KK9M/;7;;r   c                     |j                         }d|d<   t        ||      }t        | fi |dz   t        t	        |      d      z   S )Ndownloadmoder  T)rY  r  r  	urlencodebracketize_seq)r  rJ  r   cloudinary_paramss       r   cloudinary_api_download_urlr  e  sK    [[]FF6N$VW5f0036>RcCdfj9kkkr   c                    t        j                        |r=t        |t              rd|i}t	        fdt
        D              j                  |       d|d}}t        |       t        ||      }t        | fi |d   S )ap  
    Generates a cloudinary url scaled to specified width.

    :param source:          The resource
    :param width:           Width in pixels of the srcset item
    :param transformation:  Custom transformation that overrides transformations provided in options
    :param options:         A dict with additional options

    :return: Resulting URL of the item
    r"  c              3   6   K   | ]  }|v s||   f  y wr   r   rV  s     r   r   z(cloudinary_scaled_url.<locals>.<genexpr>  rW  rX  scale)r   r   r   )
rY  rZ  r   r   r   r[  rx  r   r]  r  )r  r   ra   r   scale_transformationr\  s      `  r   cloudinary_scaled_urlr  l  s     mmG$Gnl32NCN K
KK~&$+e<K{#'5IJK&0K033r   c           	      l    d }t        t        j                  t        |      |t        |                   S )z
    Based on ruby's CGI::unescape. In addition does not escape / :

    :param source: Source string to escape
    :param unsafe: Unsafe characters

    :return: Escaped string
    c                     t        ddj                  t        j                  dt	        | j                  d            z  | j                  d            D cg c]  }d|z  	 c}      j                         z         S c c}w )N%Br   z%02X)r   r   structunpackr   ri  upper)mr   s     r   packzsmart_escape.<locals>.pack  sa    chh!'sS_/Daggaj!QRAVaZR

%'  	Rs   A;)r   r:  r  r   )r  unsafer  s      r   r  r    s+    
 RVVHV,dHV4DEFFr   c                  D    dj                  d t        d      D              S )Nrf  c              3      K   | ]F  }t        j                         j                  t        j                  t        j
                  z          H y wr   )randomSystemRandomchoicestringascii_lowercasedigits)r   r   s     r   r   z#random_public_id.<locals>.<genexpr>  s;      ' &&(//0F0F0VW 's   AA   )r   rd  r   r   r   random_public_idr    s$    77 '!"I' ' 'r   c           	          dj                  | d   | d   fD cg c]  }|s|	 c}      }dj                  | d   ddt        | d         z   |g      }|d	z   | d
   z   S c c}w )Nr   r4   r%   r#  r'   r   r   r1   r   r  )r   r   )r  r   filenamer  s       r   signed_preloaded_imager    sr    xxVK%8&:J$KQqqQRH88VO,hc&BS>T8TV^_`D#:{+++ Rs
   AAc                  N    t        t        t        j                                     S r   )r   inttimer   r   r   nowr    s    s499;  r   c           
          t        t               | ||j                  d      |j                  d      |j                  d      d|      }t        di |dz   t	        |      z   S )Nr.   
attachment
expires_at)r`   r4   r%   r.   r  r  r  )r  )r  r  r   r  r  )r4   r%   r   r  s       r   private_download_urlr    sf    $UF#kk,/kk,/&  4G4s:YGX=YYYr   c           	      ~    t        t               | t        di |d   d|      }t        di |dz   t	        |      z   S )Nr   )r`   tagra   r  r   )zdownload_tag.zip)r  r  r   r  r  )r  r   r  s      r   zip_download_urlr    sO    $U8C7CAF& 	 <G<sBYO`Eaaar   c                 f    t               }| D ]!  }| |   }t        |t              r|dz  }|||<   # |S )Nz[])r   r   r   )rJ  
url_params
param_nameparam_values       r   r  r    sH    J -
Z(k4($J!,
:	-
 r   c            	      0    t        ddt        di | d| S )Ngenerate_archive)r  rJ  r   )r  archive_params)r   s    r   download_archive_urlr
    s"    &n.@IbZaIbnfmnnr   c                  \    | j                         }|j                  d       t        di |S )Nzip)target_formatr   )rY  rx  r
  )r   new_optionss     r   download_zip_urlr    s,    ,,.KU+.+..r   c                 F    | |d<   |j                  dd       t        di |S )av  
    Creates and returns a URL that when invoked creates an archive of a folder.
    :param folder_path: The full path from the root that is used to generate download url.
    :type folder_path:  str
    :param options:     Additional options.
    :type options:      dict, optional
    :return:            Signed URL to download the folder.
    :rtype:             str
    prefixesr'   allr   )
setdefaultr
  )folder_pathr   s     r   download_folderr    s,     &GJ.*'**r   c                     |j                  dt                     | |d}t        ||      }t        di |dz   t	        t        |      d      z   S )a(  
    The returned url allows downloading the backedup asset based on the the asset ID and the version ID.

    Parameters asset_id and version_id are returned with api.resource(<PUBLIC_ID1>, versions=True) API call.

    :param  asset_id:   The asset ID of the asset.
    :type   asset_id:   str
    :param  version_id: The version ID of the asset.
    :type   version_id: str
    :param  options:    Additional options.
    :type   options:    dict, optional
    :return:The signed URL for downloading backup version of the asset.
    :rtype: str
    r`   )r`   asset_id
version_idr  T)download_backup)r   r  r  r  r  r  )r  r  r   rJ  r  s        r   download_backedup_assetr    sV      [[ce4 F
 %VW55W5;iWhHiko>pppr   c                  |    t        t        j                         j                  |       }t        j                  di |S )Nr   )r  r   r   r   r  )r   token_optionss     r   generate_auth_tokenr     s1    *++-88'BM///r   c                  z   | j                  d      t               }n| j                  d      }i 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
| j                  d
      d| j                  d      xr t        | j                  d            d| j                  d      xr t        | j                  d            d| j                  d      xr t        | j                  d            d| j                  d      d| j                  d      xr t        | j                  d            d| j                  d      d| j                  d      d| j                  d      | j                  d      xr t        | j                  d            |t        | j                  d            | j                  d      | j                  d      d}|S )Nr`   allow_missingr]   r  flatten_foldersflatten_transformationskeep_derivedr  rD   rZ   r  
public_idsfully_qualified_public_idsskip_transformation_namerd   r  target_asset_foldertarget_public_idtarget_tagsrQ  r.   use_original_filename)r(  r`   rQ  r.   r)  )r   r  r   build_eager)r   r`   rJ  s      r   r	  r	    sD   {{;'E	KK,	_5W% 	gkk,/ 	7;;'89	
 	"7;;/H#I 	N3 	F# 	GKK(:; 	W% 	GKK
+TGKK
<S0T 	gkk,/ZKL@Y4Z 	%gkk2N&O '7T_KK45U7 	#GKK0J$K 	F#HGKK4G(H  	_5!" 	w{{+@A#$ 	GKK(:;%& {{=1]k'++mB\6]&w{{3D'EFF#!(-D!E/F2 Mr   c                 t    | y dj                  t        |       D cg c]  }t        |       c}      S c c}w )Nr   )r   r   build_single_eager)rQ  ets     r   r*  r*  &  s3    88k/6RS'+STTSs   5c                     t        | t              r| S t        di | d   }|sy| j                  d      }||d|z   z   S dz   S )a9  
    Builds a single eager transformation which consists of transformation and (optionally) format joined by "/"

    :param options: Options containing transformation parameters and (optionally) a "format" key
        format can be a string value (jpg, gif, etc) or can be set to "" (empty string).
        The latter leads to transformation ending with "/", which means "No extension, use original format"
        If format is not provided or set to None, only transformation is used (without the trailing "/")

    :return: Resulting eager transformation string
    r   rf  r%   r#  r   )r   r   r   r   )r   	trans_strfile_formats      r   r,  r,  -  sV     '<(.99!<I++h'K[-Dk)MM"MMr   c                     | y t        | t              rn;t        | t              r)| j                         D cg c]  \  }}|dz   |z    } }}n| S dj	                  |       S c c}}w )Nz: 
)r   r   r   r   r   )rb   r   r   s      r   build_custom_headersr3  E  s_    	GT	"	GT	",3MMO<DAq1t8a<<<99W =s   A!c                  D   t         D ci c]  }|| v s|| j                  |       }}|j                  dt        j                         j
                        |d<   t               t        | j                  d            t        di | d   t        | j                  d            t        | j                  d            | j                  d      xr t        t        | d               | j                  d      xr t        t        | d               t        | j                  d            t        | j                  d	            t        | j                  d
            t        | j                  d            | j                  d      xr t        | j                  d            t!        | j                  d            | j                  d      xr# t        t#        | j                  d                  d}t$        D ci c]  }|||   
 }}|j'                  |       |S c c}w c c}w )NrY   rl   r   rb   rc   rd   re   rf   rg   rh   ri   r\   rj   rk   )r`   rl   ra   rb   rc   rd   re   rf   rg   rh   ri   r\   rj   rk   r   )__SIMPLE_UPLOAD_PARAMSr   r   r   r   rY   r  r   r   r3  r*  r   r   r   r   r   r  r   __SERIALIZED_UPLOAD_PARAMSrx  )r   r  rJ  serialized_paramss       r   build_upload_paramsr8  Q  s   DZtj^hls^sj'++j11tFt$jj*:K:K:M:[:[\F? U"7;;z#:;8C7CAF'I(>?W[[12F#QK4P(Q";;'89rk+V]^oVpJq>r/<N0OP1'++>R2STw{{956!'++i"89N3XGKK<W8X"HUmIn"o!++&67 @K,< =>=@& Vppz%6z%BBpp
MM#$M5 u, qs   	HH6Hc                 F   | sy t         r1t        | t               r!|xs | j                  }| j                         }nt        | t              r<t        |       rd }| }n|xs | }t        | d      5 }|j                         }d d d        nt        | d      r^t        | j                        rI| j                         }|xs4 t        | d      r&t        | j                  t              r| j                  nd}nt        | t              r| \  }}n|xs d}| }|r|fS S # 1 sw Y   xY w)Nrbreadnamestreamrw  )PathLibPathTyper   r<  
read_bytesr   is_remote_urlopenr;  hasattrcallabler   r   )rw  r  r<  dataopeneds        r   handle_file_parameterrF  o  s   :dO<$499 	D,	'DD #tDdD! %V{{}% %	v	8DII#6yy{lv)>:diiY\C]DIIck	D%	 
d !6D$<)T)% %s   -DD c                  F   | j                  d      }| j                  d      }t        |      t        |      k(  rt        d      | j                  d      t               | j                  d      | j                  d      ||t	        dd| j                  d      i| d	   d
}|S )zh
    Build params for multi, download_multi, generate_sprite, and download_generated_sprite methods
    r  urlsz;Either 'tag' or 'urls' parameter has to be set but not bothr  r]   rD   rt   r%   r   )r  r`   r]   rD   r  rH  ra   r   )r   boolr   r  r   )r   r  rH  rJ  s       r   build_multi_and_sprite_paramsrJ    s     ++e
C;;vDCyDJVWWF#UW%#KK(:;8ggkkRZF[g_fghijF Mr   c                    t        | j                  dd            }|r|j                         s|S | j                  d      }| j                  d      }g }t        D ]0  \  }}| j                  |      }||k7  s| |j	                  |       2 | j                  d      }	|	|j	                  dt        |	      z          | j                  d      }
|
|j	                  dt        |
      z          | j                  d	      }||j	                  d
t        |      z          | j                  d      }||j	                  dt        |      z          ||t        |      dk(  ry |t        d|z         |t        d|z         |j                  d|       |j                  d|       dj                  |D cg c]  }t        |       c}      S c c}w )N
text_stylerf  font_family	font_sizeletter_spacingletter_spacing_line_spacingline_spacing_font_antialiasing
antialias_font_hintinghinting_r   z$Must supply font_family for text in z"Must supply font_size for text in r   )	r   r   isspace__LAYER_KEYWORD_PARAMSr<  r   r   r?  r   )layerlayer_parameterrL  rM  rN  keywordsattrdefault_value
attr_valuerO  rQ  rS  rU  r   s                 r   __process_text_optionsr_    s   UYY|R01J*,,.))M*K		+&IH5 (mYYt_
&:+AOOJ'(
 YY/0N!)C,??@99^,L#l*;;<		"56$s+<'==>99^,L
S%667[0S]a5G?/QRR=OPPOOAy!OOA{#88X.SV.//.s   3Gc           	      R   t        | t              r]d }| j                  d      r| t        d      d  }n/| j	                  ddd      dk7  r| j                  dd      \  }}}n| S |dd	} |r|| d
<   t        | t              s| S | j                  d
      }| j                  d      }| j                  d      }| j                  d      }| j                  d      }| j                  d      }	t               }
||d}|	r|d}|
||dz   |z   }||dk7  r|dk7  rt        d|z         ||dk7  r|
j                  |       ||dk7  r|
j                  |       |dk(  s|dk(  r||t        d|z         t        | |      }||
j                  |       |#|j                  dd      }|
j                  |       |t        }t        d t        j
                  ||            }g }|D ]N  }t        j                   ||      r|j                  |       +|j                  t#        t#        |d                   P dj%                  |      }|
j                  |       nE|dk(  rt'        |	      }|
j                  |       n#|j                  dd      }|
j                  |       dj%                  |
      S )Nzfetch:z:fetch:r      rb  r   r   r   )rS  r.   r'   textr.   r4   r%   rS  r   z'Must supply public_id for for non-text r  r   	subtitlesz(Must supply either text or public_id in r#  c                 
    | d uS r   r   )r   s    r   <lambda>zprocess_layer.<locals>.<lambda>
  s
    Qd] r   z([,/])rf  )r   r   r'  r   r  r&  r   r   r   r   r<  r_  r   VAR_NAME_REfilterr:  r;  r  r   base64url_encode)rY  rZ  r'   rS  r   rb  r.   r4   r%   	fetch_url
componentstext_optionsvar_patternpartsencoded_textpartb64s                    r   r1  r1    s   %&H%H'CZZ	1b)R/$)KKQ$7!M1c L W-%2E/"eT"IIo.M99VD99VD		+&IYYx F		% IJM1T\!3Of,	]f4B_TUU ]g%=-(DH,$-;">G/YZZ-e_E#l+ !))#s3Ii(%K2BHH[$4OPEL U88K. ''- ''\$	5R(ST	U 77<(Dd#	y)#%%c3/	)$88Jr   eqneltgtltegteandormuldivaddr  pow)r   z!=<>z<=z>=z&&z||*r#  +r  ^r   r  aspectRatiocurrent_pagecpcurrentPage
face_countfc	faceCountr   r  initial_aspect_ratioiarinitialAspectRatiotrimmed_aspect_ratiotartrimmedAspectRatioinitial_heightihinitialHeightinitial_widthiwinitialWidth
page_countpc	pageCountpxpyrd   r  r  iduilsctx)page_xpageXpage_ypageYrd   r   r   initial_durationinitialDurationillustration_scoreillustrationScoreri   zG((\|\||>=|<=|&&|!=|>|=|<|/|-|\+|\*|\^)(?=[ _])|(\$_*[^_ ]+)|(?<![\$:])(r   z))c                 x    | j                  d      }t        j                  |t        j                  ||            S Nr   )ri  IF_OPERATORSr   PREDEFINED_VARS)r;  r<  s     r   translate_ifr  R  s7    ;;q>DD+//0467 7r   c                     t        | t              s| S | j                  d      }| j                  d      }|dk(  rt        |      }dj	                  ||g      S )Nfunction_typer  remoter   )r   r   r   rh  r   )r   r  r  s      r   r3  r3  Y  sX    ot,#''8M  *F !&)88]F+,,r   c                 B    t        |       }|rdj                  |      S d S )Nzpre:{0})r3  r%   )r   r   s     r   r4  r4  e  s$    #O4E&+9E"55r   c                 b    t        | t        t        f      s| S dj                  d | D              S )z
    Serializes fps transformation parameter

    :param fps: A single number, a list of mixed type, a string, including open-ended and closed range values
                Examples: '24-29.97', 24, 24.973, '-24', [24, 29.97]

    :return: string
    r  c              3   2   K   | ]  }t        |        y wr   ru  )r   r   s     r   r   zprocess_fps.<locals>.<genexpr>v  s     9(+9r   )r   r   r   r   )r  s    r   r5  r5  j  s,     cD%=)
889S999r   c                     | yt        | t              r| S t        | t              st        d      | dk  rt        d      t	        t        |             S )z
    Serializes keyframe_interval parameter
    :param ki: Keyframe interval. Should be either a string or a positive real number.
    :return: string
    Nz0Keyframe interval should be a number or a stringr   z-Keyframe interval should be greater than zero)r   r   r   r   r   r`  )r  s    r   r7  r7  y  sR     
z"l#	b&!KLL	QwHIIuRy>r   c                 $    | | S t        |       }|S r   ru  )conditionalr  s     r   r2  r2    s    !+.FMr   c                     t        j                  dt        |             r| S | rCt        |       }t        j                  t        t
        |      }t        j                  dd|      }|S | S )Nz^!.+!$z[ _]+r   )r:  r;  r   r  	replaceREr  )
expressionr  s     r   r6  r6    sU    	xx	3z?+	Z	<8f-r   c                 B    ||dk(  ry |du r| S dj                  | |      S )Nrf  Tz	{0}="{1}"r%   )rN  r   s     r   __join_pairr    s/    }	$
  e,,r   c                     dj                  t        | j                         D cg c]  \  }}|||v st        ||       c}}            S c c}}w )N )r   r>  r   r  )attrsonlyrN  r   s       r   
html_attrsr    sD    88Fekkms
UW[WcgjnrgrKU3stuuss
   AAc                 2    t        | t              r| rdS dS | S )Nr  0r   rI  r   s    r   r~  r~    s    !Ts S Hr   c                 2    t        | t              r| rdS dS | S )Ntruefalser  r  s    r   r  r    s    !Tv''Hr   c                 b    t        t        j                  t        |             dz  dz  dz         S )Nl       r   )r   zlibcrc32r   )r  s    r   r  r    s*    

</0:=BQFGGr   c                     t        d |       S )Nc                     | S r   r   r   s    r   re  z__compact.<locals>.<lambda>  s    A r   )rg  )r   s    r   r  r    s    +u%%r   c                     	 t        |       } t        |       } t        j                  | j                  d            }|j                  d      S # t        $ r Y Kw xY w)z
    Returns the Base64-decoded version of url.
    The method tries to unquote the url because quoting it

    :param str url:
        the url to encode. the value is URIdecoded and then
        re-encoded before converting to base64 representation

    utf-8ascii)r  	Exceptionr  r  	b64encoder  decode)rS  rp  s     r   base64_encode_urlr    sX    cl s
C


3::g.
/C::g	  s   A 	AAc                 P    t        t        j                  t        |                   S )z
    Url safe version of urlsafe_b64encode with stripped `=` sign at the end.

    :param data: input data

    :return: Base64 URL safe encoded string
    )r   r  r  r   )rD  s    r   rh  rh    s     V--htn=>>r   c                 p    t         j                  r%t        j                  | j	                  d      d      } | S )z
    Quote and encode possible unicode url string (applicable for python2)

    :param url_str: Url string to encode

    :return: Encoded string
    r  z:/?#[]@!$&'()*+,;=)sixPY2urllibquoter  )url_strs    r   r  r    s*     ww,,w~~g68LMNr   c                 |    t        | t        t        f      r| j                         S t	        dt        |       z        )zAJSON serializer for objects not serializable by default json codez*Object of type %s is not JSON serializable)r   r   r   	isoformat	TypeErrorr.   objs    r   r   r     s2    #$'(}}
@49L
MMr   c                 Z    t        | t              xr t        j                  t        |       S )z3Basic URL scheme check to define if it's remote URL)r   r   r:  r;  REMOTE_URL_RE)rw  s    r   r@  r@    s    dL)Kbhh}d.KKr   c                     | j                         }| j                  dt        j                         | j                         }| j                  |t        j                         |S )z
    Helper function for getting file-like object size(suitable for both files and streams)

    :param file_io: io.IOBase

    :return: size
    r   )tellseekosSEEK_ENDSEEK_SET)file_ioinitial_positionr   s      r   file_io_sizer    sE     ||~LLBKK <<>DLL!2;;/Kr   c                       fd}|S )z
    Used as a class method decorator to check whether class is enabled(self.enabled is True)

    :param f: function to call

    :return: None if not enabled, otherwise calls function f
    c                  4    | d   j                   sy  | i |S r  )enabled)argskwargsr   s     r   wrapperz'check_property_enabled.<locals>.wrapper  s!    Aw$!&!!r   r   )r   r  s   ` r   check_property_enabledr    s    "
 Nr   c                     t        j                         j                  st        d      | |d}|t	        |t        j                         j                  |xs t        j                         j
                        k(  S )a
  
    Verifies the authenticity of an API response signature

    :param public_id: The public id of the asset as returned in the API response
    :param version:   The version of the asset as returned in the API response
    :param signature: Actual signature. Can be retrieved from the X-Cld-Signature header
    :param algorithm: Name of hashing algorithm to use for calculation of HMACs.
                      By default uses `cloudinary.config().signature_algorithm`

    :return: Boolean result of the validation
    Api secret key is empty)r4   r1   )r   r   r!   r  r  r3   )r4   r1   r  r   parameters_to_signs        r   verify_api_response_signaturer    ss     ))122'0%,. (&&<Z&&(<<  r   c           	      x   t        j                         j                  st        d      |t	        j                         |z
  k  ryt        | t              st        d      |t        dj                  | |t        j                         j                        |xs t        j                         j                        k(  S )a@  
    Verifies the authenticity of a notification signature

    :param body: Json of the request's body
    :param timestamp: Unix timestamp. Can be retrieved from the X-Cld-Timestamp header
    :param signature: Actual signature. Can be retrieved from the X-Cld-Signature header
    :param valid_for: The desired time in seconds for considering the request valid
    :param algorithm: Name of hashing algorithm to use for calculation of HMACs.
                      By default uses `cloudinary.config().signature_algorithm`

    :return: Boolean result of the validation
    r  FzBody should be type of stringz{}{}{})r   r   r!   r  r  r   r   r   r   r%   r3   )bodyr`   r  	valid_forr   s        r   verify_notification_signaturer  .  s     ))122499;**dC 899(i):):)<)G)GH<Z&&(<<> > >r   c                     | j                   r8| j                  rt        | j                   fi |S t        | j                   fi |S | j                  rt	        di |S t        di |S )a  
    Used to create http connector, depends on api_proxy and disable_tcp_keep_alive configuration parameters.

    :param conf: configuration object
    :param options: additional options

    :return: ProxyManager if api_proxy is set, otherwise PoolManager object
    r   )	api_proxydisable_tcp_keep_aliver	   r   r
   r   )confr   s     r   get_http_connectorr  I  sa     ~~&&:'::'B'BB""%W%%"-W--r   c                 H    t        | t              rdj                  |       S | S )Nr   )r   r   r   r  s    r   r   r   ^  s    #txx}Jr   c                 B    	  ||       S # t         t        f$ r |cY S w xY w)a  
    Attempts to cast a value to another using a given casting function
    Will return a default value if casting fails (configurable, defaults to None)

    :param val: The value to cast
    :param casting_fn: The casting function that will receive the value to cast
    :param default: The return value if casting fails

    :return: Result of casting the value or the value of the default parameter
    )r   r  )r   
casting_fnr   s      r   	safe_castr  d  s*    #	" s   
 c                     | S )z:
    Identity function. Returns the passed in values.
    r   r  s    r   __idr  u  s	     Hr   c                 |    |t         }t               }| D ]  }|| ||      <    t        |j                               S )z
    Removes duplicates from collection using key function

    :param collection: The collection to remove duplicates from
    :param key: The function to generate key from each element. If not passed, identity function is used
    )r  r   r   values)
collectionrN  	to_returnelements       r   uniquer	  |  sH     {I *")	#g,* 	  "##r   c                 *    dj                  |||       S )a^  
    Returns the fully qualified public id of form resource_type/type/public_id.

    :param public_id: The public ID of the asset.
    :type public_id: str
    :param resource_type: The type of the asset. Defaults to "image".
    :type resource_type: str
    :param type: The upload type. Defaults to "upload".
    :type type: str

    :return:
    z"{resource_type}/{type}/{public_id})r'   r.   r4   r  )r4   r'   r.   s      r   fq_public_idr    s     066]Y]ir6ssr   )F)r   )z([^a-zA-Z0-9_.\-\/:]+)r   )i   N)r  r   )r  rY  hashlibr   r  r  r:  r  r  r  r  r  collectionsr   r   r   	fractionsr   numbersr   six.moves.urllib.parser  r   urllib3r	   r
   r   r   ,cloudinary.api_client.tcp_keep_alive_managerr   r   cloudinary.compatr   r   r   r   r   r   pathlibr   r>  ImportErrorrf  movesparser  r  r  rA  rh  rc  r_  r  rX  r[  r5  r6  upload_paramsr9  r  r  SIGNATURE_SHA1r  r   r   r   r   r   r   r   r   r   r   r   r   r   r   r]  r(  r-  r+  r,  r.  r8  r|  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r
  r  r  r  r  r	  r*  r,  r3  r8  rF  rJ  r_  r1  r  r  r   keysr  r  r3  r4  r5  r7  r2  r6  r  r  r~  r  r  r  r  rh  r  r   r@  r  r  r  r  r  r   r  r  r	  r  r   r   r   <module>r     s       	  	      # #     -  ! j \ \/ %II"",,	
))


 
 
(
( .!
4:G*L '@6w. 
./ b " ')CC !!       GLLgnn  #1 , 'T0>"d d )2$Yx2:
+#	, f
g  <J =J",&6)X,&IX
h<l4@G"'
,!
Zbo/+ q20
BUN0	<*>()0XM b 

		



					 D4 D 4	
 $  c E % E % d T T D  $!" #$ ;@ ]HH_))+,-/34	7	-6
:"-vH&(?NL
  2>6.*"$$ta3  Os    J6 6K K