Update cloudinary to 1.20.0

This commit is contained in:
JonnyWong16 2020-03-21 19:11:41 -07:00
commit 2984629b39
27 changed files with 2865 additions and 923 deletions

View file

@ -1,17 +1,17 @@
# MIT licensed code copied from https://bitbucket.org/chrisatlee/poster
#
# Copyright (c) 2011 Chris AtLee
#
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@ -28,7 +28,4 @@ New releases of poster will always have a version number that compares greater
than an older version of poster.
New in version 0.6."""
import cloudinary.poster.streaminghttp
import cloudinary.poster.encode
version = (0, 8, 2) # Thanks JP!
version = (0, 8, 2) # Thanks JP!

View file

@ -6,9 +6,17 @@ as multipart/form-data suitable for a HTTP POST or PUT request.
multipart/form-data is the standard way to upload files over HTTP"""
__all__ = ['gen_boundary', 'encode_and_quote', 'MultipartParam',
'encode_string', 'encode_file_header', 'get_body_size', 'get_headers',
'multipart_encode']
import mimetypes
import os
import re
from email.header import Header
from cloudinary.compat import (PY3, advance_iterator, quote_plus, to_bytearray,
to_bytes, to_string)
__all__ = [
'gen_boundary', 'encode_and_quote', 'MultipartParam', 'encode_string',
'encode_file_header', 'get_body_size', 'get_headers', 'multipart_encode']
try:
from io import UnsupportedOperation
@ -17,25 +25,19 @@ except ImportError:
try:
import uuid
def gen_boundary():
"""Returns a random string to use as the boundary for a message"""
return uuid.uuid4().hex
except ImportError:
import random, sha
import random
import sha
def gen_boundary():
"""Returns a random string to use as the boundary for a message"""
bits = random.getrandbits(160)
return sha.new(str(bits)).hexdigest()
import re, os, mimetypes
from cloudinary.compat import (PY3, string_types, to_bytes, to_string,
to_bytearray, quote_plus, advance_iterator)
try:
from email.header import Header
except ImportError:
# Python 2.4
from email.Header import Header
if PY3:
def encode_and_quote(data):
if data is None:
@ -47,7 +49,7 @@ else:
"""If ``data`` is unicode, return quote_plus(data.encode("utf-8")) otherwise return quote_plus(data)"""
if data is None:
return None
if isinstance(data, unicode):
data = data.encode("utf-8")
return quote_plus(data)
@ -65,13 +67,15 @@ if PY3:
return to_bytes(str(s))
else:
def _strify(s):
"""If s is a unicode string, encode it to UTF-8 and return the results, otherwise return str(s), or None if s is None"""
"""If s is a unicode string, encode it to UTF-8 and return the results,
otherwise return str(s), or None if s is None"""
if s is None:
return None
if isinstance(s, unicode):
return s.encode("utf-8")
return str(s)
class MultipartParam(object):
"""Represents a single parameter in a multipart/form-data request
@ -105,7 +109,7 @@ class MultipartParam(object):
transferred, and the total size.
"""
def __init__(self, name, value=None, filename=None, filetype=None,
filesize=None, fileobj=None, cb=None):
filesize=None, fileobj=None, cb=None):
self.name = Header(name).encode()
self.value = _strify(value)
if filename is None:
@ -141,7 +145,7 @@ class MultipartParam(object):
fileobj.seek(0, 2)
self.filesize = fileobj.tell()
fileobj.seek(0)
except:
except Exception:
raise ValueError("Could not determine filesize")
def __cmp__(self, other):
@ -169,9 +173,9 @@ class MultipartParam(object):
"""
return cls(paramname, filename=os.path.basename(filename),
filetype=mimetypes.guess_type(filename)[0],
filesize=os.path.getsize(filename),
fileobj=open(filename, "rb"))
filetype=mimetypes.guess_type(filename)[0],
filesize=os.path.getsize(filename),
fileobj=open(filename, "rb"))
@classmethod
def from_params(cls, params):
@ -204,7 +208,7 @@ class MultipartParam(object):
filetype = None
retval.append(cls(name=name, filename=filename,
filetype=filetype, fileobj=value))
filetype=filetype, fileobj=value))
else:
retval.append(cls(name, value))
return retval
@ -216,8 +220,8 @@ class MultipartParam(object):
headers = ["--%s" % boundary]
if self.filename:
disposition = 'form-data; name="%s"; filename="%s"' % (self.name,
to_string(self.filename))
disposition = 'form-data; name="%s"; filename="%s"' % (
self.name, to_string(self.filename))
else:
disposition = 'form-data; name="%s"' % self.name
@ -267,8 +271,8 @@ class MultipartParam(object):
self.cb(self, current, total)
last_block = to_bytearray("")
encoded_boundary = "--%s" % encode_and_quote(boundary)
boundary_exp = re.compile(to_bytes("^%s$" % re.escape(encoded_boundary)),
re.M)
boundary_exp = re.compile(
to_bytes("^%s$" % re.escape(encoded_boundary)), re.M)
while True:
block = self.fileobj.read(blocksize)
if not block:
@ -296,6 +300,7 @@ class MultipartParam(object):
return len(self.encode_hdr(boundary)) + 2 + valuesize
def encode_string(boundary, name, value):
"""Returns ``name`` and ``value`` encoded as a multipart/form-data
variable. ``boundary`` is the boundary string used throughout
@ -303,8 +308,8 @@ def encode_string(boundary, name, value):
return MultipartParam(name, value).encode(boundary)
def encode_file_header(boundary, paramname, filesize, filename=None,
filetype=None):
def encode_file_header(boundary, paramname, filesize, filename=None, filetype=None):
"""Returns the leading data for a multipart/form-data field that contains
file data.
@ -324,7 +329,8 @@ def encode_file_header(boundary, paramname, filesize, filename=None,
"""
return MultipartParam(paramname, filesize=filesize, filename=filename,
filetype=filetype).encode_hdr(boundary)
filetype=filetype).encode_hdr(boundary)
def get_body_size(params, boundary):
"""Returns the number of bytes that the multipart/form-data encoding
@ -332,6 +338,7 @@ def get_body_size(params, boundary):
size = sum(p.get_size(boundary) for p in MultipartParam.from_params(params))
return size + len(boundary) + 6
def get_headers(params, boundary):
"""Returns a dictionary with Content-Type and Content-Length headers
for the multipart/form-data encoding of ``params``."""
@ -341,6 +348,7 @@ def get_headers(params, boundary):
headers['Content-Length'] = str(get_body_size(params, boundary))
return headers
class multipart_yielder:
def __init__(self, params, boundary, cb):
self.params = params
@ -396,6 +404,7 @@ class multipart_yielder:
for param in self.params:
param.reset()
def multipart_encode(params, boundary=None, cb=None):
"""Encode ``params`` as multipart/form-data.

View file

@ -27,15 +27,18 @@ Example usage:
... {'Content-Length': str(len(s))})
"""
import sys, socket
from cloudinary.compat import httplib, urllib2, NotConnected
import socket
import sys
from cloudinary.compat import NotConnected, httplib, urllib2
__all__ = ['StreamingHTTPConnection', 'StreamingHTTPRedirectHandler',
'StreamingHTTPHandler', 'register_openers']
'StreamingHTTPHandler', 'register_openers']
if hasattr(httplib, 'HTTPS'):
__all__.extend(['StreamingHTTPSHandler', 'StreamingHTTPSConnection'])
class _StreamingHTTPMixin:
"""Mixin class for HTTP and HTTPS connections that implements a streaming
send method."""
@ -62,7 +65,7 @@ class _StreamingHTTPMixin:
print("send:", repr(value))
try:
blocksize = 8192
if hasattr(value, 'read') :
if hasattr(value, 'read'):
if hasattr(value, 'seek'):
value.seek(0)
if self.debuglevel > 0:
@ -86,10 +89,12 @@ class _StreamingHTTPMixin:
self.close()
raise
class StreamingHTTPConnection(_StreamingHTTPMixin, httplib.HTTPConnection):
"""Subclass of `httplib.HTTPConnection` that overrides the `send()` method
to support iterable body objects"""
class StreamingHTTPRedirectHandler(urllib2.HTTPRedirectHandler):
"""Subclass of `urllib2.HTTPRedirectHandler` that overrides the
`redirect_request` method to properly handle redirected POST requests
@ -114,7 +119,7 @@ class StreamingHTTPRedirectHandler(urllib2.HTTPRedirectHandler):
"""
m = req.get_method()
if (code in (301, 302, 303, 307) and m in ("GET", "HEAD")
or code in (301, 302, 303) and m == "POST"):
or code in (301, 302, 303) and m == "POST"):
# Strictly (according to RFC 2616), 301 or 302 in response
# to a POST MUST NOT cause a redirection without confirmation
# from the user (of urllib2, in this case). In practice,
@ -125,14 +130,16 @@ class StreamingHTTPRedirectHandler(urllib2.HTTPRedirectHandler):
newheaders = dict((k, v) for k, v in req.headers.items()
if k.lower() not in (
"content-length", "content-type")
)
return urllib2.Request(newurl,
headers=newheaders,
origin_req_host=req.get_origin_req_host(),
unverifiable=True)
)
return urllib2.Request(
newurl,
headers=newheaders,
origin_req_host=req.get_origin_req_host(),
unverifiable=True)
else:
raise urllib2.HTTPError(req.get_full_url(), code, msg, headers, fp)
class StreamingHTTPHandler(urllib2.HTTPHandler):
"""Subclass of `urllib2.HTTPHandler` that uses
StreamingHTTPConnection as its http connection class."""
@ -156,9 +163,9 @@ class StreamingHTTPHandler(urllib2.HTTPHandler):
"No Content-Length specified for iterable body")
return urllib2.HTTPHandler.do_request_(self, req)
if hasattr(httplib, 'HTTPS'):
class StreamingHTTPSConnection(_StreamingHTTPMixin,
httplib.HTTPSConnection):
class StreamingHTTPSConnection(_StreamingHTTPMixin, httplib.HTTPSConnection):
"""Subclass of `httplib.HTTSConnection` that overrides the `send()`
method to support iterable body objects"""
@ -179,7 +186,7 @@ if hasattr(httplib, 'HTTPS'):
if hasattr(data, 'read') or hasattr(data, 'next'):
if not req.has_header('Content-length'):
raise ValueError(
"No Content-Length specified for iterable body")
"No Content-Length specified for iterable body")
return urllib2.HTTPSHandler.do_request_(self, req)
@ -188,7 +195,8 @@ def get_handlers():
if hasattr(httplib, "HTTPS"):
handlers.append(StreamingHTTPSHandler)
return handlers
def register_openers():
"""Register the streaming http handlers in the global urllib2 default
opener object.