
    gF                     *   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 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  e       r e       Zn, ej2                   ej4                         ej6                        Zg dZdZd Zd Zd Z d Z!d Z"d Z#d Z$d Z%d Z&d Z'd Z(d Z)d-dZ*d-dZ+d-dZ,d-dZ-d Z.d.dZ/d.dZ0d.d Z1d! Z2d" Z3d# Z4d.d$Z5d.d%Z6g d&Z7d' Z8g d(Z9d) Z:d* Z;d/d+Z<	 	 d0d,Z=y# e$ r d	 ZY w xY w# e$ r	 d d
lmZ Y w xY w)1    N)string_types)	HTTPError)utils)instance)Error)build_eager)AppEngineManageris_appengine_sandboxc                       y)NF r       (/opt/Tautulli/lib/cloudinary/uploader.pyr
   r
      s    r   )OrderedDict)filenametimeout
chunk_size	use_cachei -1c                 J    t        j                  di |}t        d|fd| i|S )Nuploadfiler   r   build_upload_paramscall_cacheable_apir   optionsparamss      r   r   r   +   s,    &&11FhETEWEEr   c                      t        | f|dd|S )NT)upload_presetunsigned)r   )r   r   r   s      r   unsigned_uploadr    0   s    $NmdNgNNr   c                     t        | fi |}t        j                  |d   t        |d         |j	                  d      |      S )N	public_idversionformat)r#   r$   metadata)r   
cloudinaryCloudinaryImagestrget)r   r   results      r   upload_imager+   4   sF    D$G$F%%{S	):%;zz(#f6 6r   c                     t         }t        | d      r| j                  t        kD  rt        } || fi |}t        j                  |d   t        |d         |j                  d      |d   |d   |      S )Nsizer"   r#   r$   typeresource_type)r#   r$   r.   r/   r%   )	r   hasattrr-   UPLOAD_LARGE_CHUNK_SIZEupload_larger&   CloudinaryResourcer(   r)   )r   r   upload_funcr*   s       r   upload_resourcer5   ;   sv    KtV-D!D"))F(({S	):%;zz(#&._-@ @r   c                    t        j                  |       rt        | fi |S t        | d      rt	        | j
                        r| }nt        | d      }d}|5  t        j                         }d}|j                  dt              }t        j                  |      }|j                  dt        |d      r&t        |j                  t              r|j                  nd      }|j                  |      }	|	rmd	j                  ||t        |	      z   d
z
  |      }
|t        |	      z  }|
|d}t!        ||	ffd|i|}|j                  d      |d<   |j                  |      }	|	rmddd       |S # 1 sw Y   |S xY w) Upload large files. readrbNr   r   r   namestreamzbytes {0}-{1}/{2}   )zContent-RangezX-Unique-Upload-Idhttp_headersr"   )r   is_remote_urlr   r0   callabler8   openrandom_public_idr)   r1   file_io_size
isinstancer:   r(   r$   lenupload_large_part)r   r   file_ioupload_result	upload_idcurrent_locr   	file_size	file_namechunkcontent_ranger=   s               r   r2   r2   H   sj   4 d&g&&tV$))!4tT"M	 -**,	[[/FG
&&w/	KK#GV4GLLRU9VGLL\df	 Z(/66{KRUV[R\D\_`D`bklM3u:%K-:R[\L-y%.@g|g_fgM#0#4#4[#AGK LL,E -. /-. s   DE&&E0c                 \    t        j                  di |}d|vrd|d<   t        d|fd| i|S )r7   r/   rawr   r   r   r   r   s      r   rE   rE   n   s>    &&11Fg%#( hETEWEEr   c                     t        j                         |j                  d      |j                  d      | d}t        d|fi |S )Nr.   
invalidate)	timestampr.   rQ   r"   destroyr   nowr)   call_apir"   r   r   s      r   rS   rS   x   sA    YY[F#kk,/	F Iv111r   c                    t        j                         |j                  d      |j                  d      |j                  d      | ||j                  d      |j                  d      |j                  d      d	}t        d|fi |S )	Nr.   	overwriterQ   to_typecontextr%   )	rR   r.   rY   rQ   from_public_idto_public_idrZ   r[   r%   renamerT   )r\   r]   r   r   s       r   r^   r^      st    YY[F#[[-kk,/($;;y);;y)KK
+
F Hf000r   c                     t        j                         t        j                  |       t        j                  |      |j	                  d      |j	                  d      d}t        d|fi |S )a  
    Populates metadata fields with the given values. Existing values will be overwritten.

    Any metadata-value pairs given are merged with any existing metadata-value pairs
    (an empty value for an existing metadata field clears the value)

    :param metadata: A list of custom metadata fields (by external_id) and the values to assign to each
                     of them.
    :param public_ids: An array of Public IDs of assets uploaded to Cloudinary.
    :param options: Options such as
            *resource_type* (the type of file. Default: image. Valid values: image, raw, or video) and
            *type* (The storage type. Default: upload. Valid values: upload, private, or authenticated.)

    :return: A list of public IDs that were updated
    :rtype: mixed
    r.   clear_invalid)rR   r%   
public_idsr.   r`   r%   r   rU   encode_contextbuild_arrayr)   rV   )r%   ra   r   r   s       r   update_metadatare      s\    $ YY[((2''
3F# _5F J2'22r   c                 P    t        j                  di |}| |d<   t        d|fi |S )Nr"   explicitr   r   rW   s      r   rg   rg      s1    &&11F#F;j&<G<<r   c                      t        j                  di | }| j                  d      | j                  d      |d<   t        d|fi | S )Ntarget_formatgenerate_archiver   )r   archive_paramsr)   rV   )r   r   s     r   create_archiverl      sJ    !!,G,F{{?#/")++o">&:'::r   c                      t        dddi| S )Nri   zipr   )rl   )r   s    r   
create_zipro      s    9999r   c                 L    t        j                  d| |d|}t        d|fi |S )a  
    Generates sprites by merging multiple images into a single large image.

    See: `Sprite method API reference
    <https://cloudinary.com/documentation/image_upload_api_reference#sprite_method>`_

    :param tag:     The sprite is created from all images with this tag. If not set - `urls` parameter is required
    :type tag:      str
    :param urls:    List of URLs to create a sprite from. Can only be used if `tag` is not set
    :type urls:     list
    :param options: Additional options
    :type options:  dict, optional
    :return:        Dictionary with meta information URLs of generated sprite resources
    :rtype:         dict
    tagurlsspriter   r   build_multi_and_sprite_paramsrV   rr   rs   r   r   s       r   generate_spriterx      s0      00OStOwOFHf000r   c                 b    t        j                  d| |d|}t        j                  dd|d|S )a  
    Returns signed URL for the sprite endpoint with `mode=download`

    :param tag:     The sprite is created from all images with this tag. If not set - `urls` parameter is required
    :type tag:      str
    :param urls:    List of URLs to create a sprite from. Can only be used if `tag` is not set
    :type urls:     list
    :param options: Additional options
    :type options:  dict, optional
    :return:        The signed URL to download sprite
    :rtype:         str
    rq   rt   actionr   r   r   rv   cloudinary_api_download_urlrw   s       r   download_generated_spriter~      s9     00OStOwOF,,WHVWwWWr   c                 L    t        j                  d| |d|}t        d|fi |S )a  
    Creates either a single animated image, video or a PDF.

    See: `Upload method API reference
    <https://cloudinary.com/documentation/image_upload_api_reference#multi_method>`_

    :param tag:     The animated image, video or PDF is created from all images with this tag.
                    If not set - `urls` parameter is required
    :type tag:      str
    :param urls:    List of URLs to create an animated image, video or PDF from. Can only be used if `tag` is not set
    :type urls:     list
    :param options: Additional options
    :type options:  dict, optional
    :return:        Dictionary with meta information URLs of the generated file
    :rtype:         dict
    rq   multir   ru   rw   s       r   r   r      s0    " 00OStOwOFGV/w//r   c                 b    t        j                  d| |d|}t        j                  dd|d|S )a  
    Returns signed URL for the multi endpoint with `mode=download`

    :param tag:     The sprite is created from all images with this tag. If not set - `urls` parameter is required
    :type tag:      str
    :param urls:    List of URLs to create a sprite from. Can only be used if `tag` is not set
    :type urls:     list
    :param options: Additional options
    :type options:  dict, optional
    :return:        The signed URL to download multi
    :rtype:         str
    rq   r   rz   r   r|   rw   s       r   download_multir      s9     00OStOwOF,,VGFVgVVr   c           	          t        j                         | |j                  d      |j                  d      t        j                  di |d   d}t	        d|fi |S )Nr$   notification_urlr   )rR   r"   r$   r   transformationexploder   )r   rU   r)   generate_transformation_stringrV   rW   s      r   r   r   	  sX    YY[++h'#KK(:;>>II!LF Iv111r   c                 N    |j                  dd      }|rdnd}t        | ||fi |S )a?  
    Adds a single tag or a list of tags or a comma-separated tags to the assets.

    :param tag:         The tag or tags to assign. Can specify multiple tags in a single string,
                        separated by commas - "t1,t2,t3" or list of tags - ["t1","t2","t3"].
    :param public_ids:  A list of public IDs (up to 1000).
    :param options:     Configuration options may include 'exclusive' (boolean) which causes
                        clearing this tag from all other assets.

    :return:            Dictionary with a list of public IDs that were updated.
    	exclusiveNset_exclusiveadd)popcall_tags_api)rr   ra   r   r   commands        r   add_tagr     s1     K.I!*oGgz=W==r   c                     t        | d|fi |S )a  
    Removes a single tag or a list of tags or a comma-separated tags from the assets.

    :param tag:         The tag or tags to assign. Can specify multiple tags in a single string,
                        separated by commas - "t1,t2,t3" or list of tags - ["t1","t2","t3"].
    :param public_ids:  A list of public IDs (up to 1000).
    :param options:     Additional options.

    :return:            Dictionary with a list of public IDs that were updated.
    remover   rr   ra   r   s      r   
remove_tagr   %  s     h
>g>>r   c                     t        | d|fi |S )a  
    Replaces all existing tags with a single tag or a list of tags or a comma-separated tags of the assets.

    :param tag:         The tag or tags to assign. Can specify multiple tags in a single string,
                        separated by commas - "t1,t2,t3" or list of tags - ["t1","t2","t3"].
    :param public_ids:  A list of public IDs (up to 1000).
    :param options:     Additional options.

    :return:            Dictionary with a list of public IDs that were updated.
    replacer   r   s      r   replace_tagr   3  s     i?w??r   c                     t        dd| fi |S )z
    Remove all tags from the specified public IDs.

    :param public_ids: the public IDs of the resources to update
    :param options: additional options passed to the request

    :return: dictionary with a list of public IDs that were updated
    N
remove_allr   ra   r   s     r   remove_all_tagsr   A  s     |ZC7CCr   c                     t        | d|fi |S )ah  
    Add a context keys and values. If a particular key already exists, the value associated with the key is updated.

    :param context: dictionary of context
    :param public_ids: the public IDs of the resources to update
    :param options: additional options passed to the request

    :return: dictionary with a list of public IDs that were updated
    r   call_context_api)r[   ra   r   s      r   add_contextr   M  s     GUJB'BBr   c                     t        dd| fi |S )a  
    Remove all custom context from the specified public IDs.

    :param public_ids: the public IDs of the resources to update
    :param options: additional options passed to the request

    :return: dictionary with a list of public IDs that were updated
    Nr   r   r   s     r   remove_all_contextr   Z  s     D,
FgFFr   c                     t        j                         | t        j                  |      ||j                  d      d}t	        d|fi |S )Nr.   )rR   rr   ra   r   r.   tags)r   rU   rd   r)   rV   )rr   r   ra   r   r   s        r   r   r   f  sF    YY[''
3F#F FF.g..r   c                     t        j                         t        j                  |       t        j                  |      ||j	                  d      d}t        d|fi |S )Nr.   )rR   r[   ra   r   r.   r[   rb   )r[   r   ra   r   r   s        r   r   r   q  sQ    YY[''0''
3F#F Iv111r   )
r"   font_family	font_size
font_color
text_alignfont_weight
font_style
backgroundopacitytext_decorationc                     t        j                         | d}t        D ]  }|j                  |      ||<    t	        d|fi |S )N)rR   textr   )r   rU   TEXT_PARAMSr)   rV   )r   r   r   keys       r   r   r     sE     99;5F 'kk#&s'FF.g..r   )r   r"   rY   r   c            
      .   | j                  dd      | d<   t        D ci c]  }|| j                  |       }}t        j                         t	        | j                  d            t	        | j                  d            | j                  d      xr$ t        j
                  | j                  d            | j                  d      xr+ t        j                  t        j                  | d               d}|j                  |       t        d|fi | S c c}w )	z
    Creates auto-generated video slideshows.

    :param options: The optional parameters.  See the upload API documentation.

    :return: a dictionary with details about created slideshow
    r/   videor   manifest_transformationmanifest_jsonr   )rR   r   r   r   r   create_slideshow)
r)   _SLIDESHOW_PARAMSr   rU   r   json_encodeencode_listrd   updaterV   )r   
param_namer   serialized_paramss       r   r   r     s      '{{?GDGODUVjj'++j11VFV YY[%gkk2B&CD#.w{{;T/U#V _5i%:K:KGKKXgLh:iF#](9(9%:K:KGTZO:\(] MM#$&:':: Ws   Dc                 d    d vryd vryt         fddD              } j                  dg       D ]w  }|j                  dd      |d<   t        j                  j	                  |d	   d
   d         d   dd |d<   |d	   D cg c]  }|d   	 }}t        j                   d   |fi | y yc c}w )zk
    Saves responsive breakpoints parsed from upload result to cache

    :param result: Upload result
    responsive_breakpointsNr"   c              3   6   K   | ]  }|v s||   f  y wNr   ).0kr*   s     r   	<genexpr>z8_save_responsive_breakpoints_to_cache.<locals>.<genexpr>  s     TaVAvay>Ts   	)r.   r/   r    raw_transformationbreakpointsr   urlr<   r$   width)dictr)   ospathsplitext%responsive_breakpoints_cache_instanceset)r*   r   r   bpr   s   `    r   %_save_responsive_breakpoints_to_cacher     s      v-& T+DTTG **%=rB _(6(:(:;KR(P$%GG,,^M-J1-Me-TUVWXYZY[\-;M-JKrr'{KK-11&2E{^V]^	_ Ls   B-c           	          t        | ||||||fi |}d|v st        j                         j                  rt	        |       |S )zB
    Calls Upload API and saves results to cache (if enabled)
    r   )rV   r&   configr   r   )	r{   r   r=   return_errorr   r   r   r   r*   s	            r   r   r     sG     fflL(DRYe]deFg!2!2!4!>!>-f5Mr   c                    t        j                  |      }dt        j                         i}	||	j	                  |       ||	j	                  |       |j                  dt        j                         j                        }
|
rdj                  |
      |	d<   n|st        j                  ||      }g }|j                         D ]U  \  }}t        |t              r*|D ]$  }|j                  dj                  |      |f       & @|sC|j                  ||f       W t        j                  | fi |}|r8|j                  d      }|j                  dt        j                  ||      f       i }|||d<   d	}	 t!        j"                  dd
|||	d|}	 t-        j.                  |j0                  j3                  d            }d|v r7|j6                  dvr|j6                  }|r
||d   d<   |S t'        |d   d         |S # t$        $ r}t'        dj                  |            d }~wt(        j*                  $ r}t'        dj                  |            d }~ww xY w# t4        $ r*}t'        d|j6                  |j0                  |fz        d }~ww xY w)Nz
User-Agentoauth_tokenz	Bearer {}authorizationz{0}[]r   r   r      POST)methodr   fieldsheaderszUnexpected error - {0!r}zSocket error: {0!r}zutf-8z1Error parsing server response (%d) - %s. Got - %serror)r   i  i  i  i  i  	http_codemessager   )r   cleanup_paramsr&   get_user_agentr   r)   r   r   r$   sign_requestitemsrC   listappendcloudinary_api_urlhandle_file_parameter_httprequestr   r   socketr   jsonloadsdatadecode	Exceptionstatus)r{   r   r=   r   r   r   r   extra_headersr   r   r   
param_listr   viapi_urlr   kwcoderesponseer*   s                         r   rV   rV     s{   !!&)FZ6689G|$ }%++mZ->->-@-L-LMK#.#5#5k#B ##FG4J &1a :!!7>>!#4a"89:q!f%& &&v99G;;z*65#>#>tX#NOP	B9D5==fGJX_fcefoHMM009:
 &??"@@??D+/F7OK( M w	233M'  :.55a899<< 5)003445
  oG8??\d\i\iklJmmnnos<   5G; .I ;	IHI4II	J	%JJ	)NNr   )NFFNN)NFFNNN)>r   r   r   sixr   urllib3.exceptionsr   r&   r   -cloudinary.cache.responsive_breakpoints_cacher   r   cloudinary.exceptionsr   cloudinary.utilsr   urllib3.contrib.appenginer	   r
   r   collectionsr   ImportErrorurllib3.packages.ordered_dictr   get_http_connectorr   CERT_KWARGSupload_optionsr1   r   r    r+   r5   r2   rE   rS   r^   re   rg   rl   ro   rx   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rV   r   r   r   <module>r     s_    	   (   k ' (P
:' E %E$$%6Z%6%6%8*:P:PQE # F
O6
@#LF2138=;:1(X"0*W"2>"?@	D
C	G/2/ ;2_, hl;K    :9:s"   C6 D 6D DDD