def encode_hdr(self, boundary):
        """Returns the header of the encoding of this parameter"""
        boundary = encode_and_quote(boundary)

        headers = ["--%s" % boundary]

        if self.filename:
            disposition = 'form-data; name="%s"; filename="%s"' % (self.name,
                    to_string(self.filename))
        else:
            disposition = 'form-data; name="%s"' % self.name

        headers.append("Content-Disposition: %s" % disposition)

        if self.filetype:
            filetype = to_string(self.filetype)
        else:
            filetype = "text/plain; charset=utf-8"

        headers.append("Content-Type: %s" % filetype)

        headers.append("")
        headers.append("")

        return "\r\n".join(headers)
Exemple #2
0
    def encode_hdr(self, boundary):
        """Returns the header of the encoding of this parameter"""
        boundary = encode_and_quote(boundary)

        headers = ["--%s" % boundary]

        if self.filename:
            disposition = 'form-data; name="%s"; filename="%s"' % (
                self.name, to_string(self.filename))
        else:
            disposition = 'form-data; name="%s"' % self.name

        headers.append("Content-Disposition: %s" % disposition)

        if self.filetype:
            filetype = to_string(self.filetype)
        else:
            filetype = "text/plain; charset=utf-8"

        headers.append("Content-Type: %s" % filetype)

        headers.append("")
        headers.append("")

        return "\r\n".join(headers)
Exemple #3
0
def call_api(method, uri, params, **options):
    prefix = options.pop(
        "upload_prefix",
        cloudinary.config().upload_prefix) or "https://api.cloudinary.com"
    cloud_name = options.pop("cloud_name", cloudinary.config().cloud_name)
    if not cloud_name: raise Exception("Must supply cloud_name")
    api_key = options.pop("api_key", cloudinary.config().api_key)
    if not api_key: raise Exception("Must supply api_key")
    api_secret = options.pop("api_secret", cloudinary.config().api_secret)
    if not cloud_name: raise Exception("Must supply api_secret")

    data = to_bytes(urlencode(params))
    api_url = "/".join([prefix, "v1_1", cloud_name] + uri)
    request = urllib2.Request(api_url, data)
    # Add authentication
    byte_value = to_bytes('%s:%s' % (api_key, api_secret))
    encoded_value = base64.encodebytes(
        byte_value) if PY3 else base64.encodestring(byte_value)
    base64string = to_string(encoded_value).replace('\n', '')
    request.add_header("Authorization", "Basic %s" % base64string)
    request.add_header("User-Agent", cloudinary.USER_AGENT)
    request.get_method = lambda: method.upper()

    kw = {}
    if 'timeout' in options:
        kw['timeout'] = options['timeout']
    try:
        response = urllib2.urlopen(request, **kw)
        body = response.read()
    except HTTPError:
        e = sys.exc_info()[1]
        exception_class = EXCEPTION_CODES.get(e.code)
        if exception_class:
            response = e
            body = response.read()
        else:
            raise GeneralError(
                "Server returned unexpected status code - %d - %s" %
                (e.code, e.read()))
    except socket.error:
        e = sys.exc_info()[1]
        raise GeneralError("Socket Error: %s" % (str(e)))

    try:
        body = to_string(body)
        result = json.loads(body)
    except Exception:
        # Error is parsing json
        e = sys.exc_info()[1]
        raise GeneralError(
            "Error parsing server response (%d) - %s. Got - %s" %
            (response.code, body, e))

    if "error" in result:
        exception_class = exception_class or Exception
        raise exception_class(result["error"]["message"])

    return Response(result, response)
Exemple #4
0
def call_api(method, uri, params, **options):
    prefix = options.pop("upload_prefix", cloudinary.config().upload_prefix) or "https://api.cloudinary.com"
    cloud_name = options.pop("cloud_name", cloudinary.config().cloud_name)
    if not cloud_name: raise Exception("Must supply cloud_name")
    api_key = options.pop("api_key", cloudinary.config().api_key)
    if not api_key: raise Exception("Must supply api_key")
    api_secret = options.pop("api_secret", cloudinary.config().api_secret)
    if not cloud_name: raise Exception("Must supply api_secret")

    data = to_bytes(urlencode(params))
    api_url = "/".join([prefix, "v1_1", cloud_name] + uri)
    request = urllib2.Request(api_url, data)
    # Add authentication
    byte_value = to_bytes('%s:%s' % (api_key, api_secret))
    encoded_value = base64.encodebytes(byte_value) if PY3 else base64.encodestring(byte_value)
    base64string = to_string(encoded_value).replace('\n', '')
    request.add_header("Authorization", "Basic %s" % base64string)
    request.add_header("User-Agent", cloudinary.USER_AGENT)
    request.get_method = lambda: method.upper()

    kw = {}
    if 'timeout' in options:
        kw['timeout'] = options['timeout']
    try:
        response = urllib2.urlopen(request, **kw)
        body = response.read()
    except socket.error:
        e = sys.exc_info()[1]
        raise GeneralError("Socket Error: %s" % (str(e)))
    except urllib2.HTTPError:
        e = sys.exc_info()[1]
        exception_class = EXCEPTION_CODES.get(e.code)
        if exception_class:
            response = e
            body = response.read()
        else:
            raise GeneralError("Server returned unexpected status code - %d - %s" % (e.code, e.read()))

    try:
        body = to_string(body)
        result = json.loads(body)
    except Exception:
        # Error is parsing json
        e = sys.exc_info()[1]
        raise GeneralError("Error parsing server response (%d) - %s. Got - %s" % (response.code, body, e))

    if "error" in result:
        exception_class = exception_class or Exception
        raise exception_class(result["error"]["message"])

    return Response(result, response)
Exemple #5
0
def cloudinary_url(source, **options):
    original_source = source

    type = options.pop("type", "upload")
    if type == 'fetch':
        options["fetch_format"] = options.get("fetch_format", options.pop("format", None))
    transformation, options = generate_transformation_string(**options)

    resource_type = options.pop("resource_type", "image")
    version = options.pop("version", None)
    format = options.pop("format", None)
    cdn_subdomain = options.pop("cdn_subdomain", cloudinary.config().cdn_subdomain)
    secure_cdn_subdomain = options.pop("secure_cdn_subdomain", cloudinary.config().secure_cdn_subdomain)
    cname = options.pop("cname", cloudinary.config().cname)
    shorten = options.pop("shorten", cloudinary.config().shorten)

    cloud_name = options.pop("cloud_name", cloudinary.config().cloud_name or None)
    if cloud_name is None:
        raise ValueError("Must supply cloud_name in tag or in configuration")
    secure = options.pop("secure", cloudinary.config().secure)
    private_cdn = options.pop("private_cdn", cloudinary.config().private_cdn)
    secure_distribution = options.pop("secure_distribution", cloudinary.config().secure_distribution)
    sign_url = options.pop("sign_url", cloudinary.config().sign_url)
    api_secret = options.pop("api_secret", cloudinary.config().api_secret)
    url_suffix = options.pop("url_suffix", None)
    use_root_path = options.pop("use_root_path", cloudinary.config().use_root_path)
    auth_token = options.pop("auth_token", None)
    if auth_token is not False:
        auth_token = merge(cloudinary.config().auth_token, auth_token)

    if (not source) or type == "upload" and re.match(r'^https?:', source):
        return original_source, options

    resource_type, type = finalize_resource_type(resource_type, type, url_suffix, use_root_path, shorten)
    source, source_to_sign = finalize_source(source, format, url_suffix)

    if source_to_sign.find("/") >= 0 \
            and not re.match(r'^https?:/', source_to_sign) \
            and not re.match(r'^v[0-9]+', source_to_sign) \
            and not version:
        version = "1"
    if version: version = "v" + str(version)

    transformation = re.sub(r'([^:])/+', r'\1/', transformation)

    signature = None
    if sign_url and not auth_token:
        to_sign = "/".join(__compact([transformation, source_to_sign]))
        signature = "s--" + to_string(
            base64.urlsafe_b64encode(hashlib.sha1(to_bytes(to_sign + api_secret)).digest())[0:8]) + "--"

    prefix = unsigned_download_url_prefix(source, cloud_name, private_cdn, cdn_subdomain, secure_cdn_subdomain, cname,
                                          secure, secure_distribution)
    source = "/".join(__compact([prefix, resource_type, type, signature, transformation, version, source]))
    if sign_url and auth_token:
        path = urlparse(source).path
        token = cloudinary.auth_token.generate( **merge(auth_token, {"url": path}))
        source = "%s?%s" % (source, token)
    return source, options
Exemple #6
0
def cloudinary_url(source, **options):
    original_source = source

    type = options.pop("type", "upload")
    if type == 'fetch':
        options["fetch_format"] = options.get("fetch_format", options.pop("format", None))
    transformation, options = generate_transformation_string(**options)

    resource_type = options.pop("resource_type", "image")
    version = options.pop("version", None)
    format = options.pop("format", None)
    cdn_subdomain = options.pop("cdn_subdomain", cloudinary.config().cdn_subdomain)
    secure_cdn_subdomain = options.pop("secure_cdn_subdomain", cloudinary.config().secure_cdn_subdomain)
    cname = options.pop("cname", cloudinary.config().cname)
    shorten = options.pop("shorten", cloudinary.config().shorten)

    cloud_name = options.pop("cloud_name", cloudinary.config().cloud_name or None)
    if cloud_name is None:
        raise ValueError("Must supply cloud_name in tag or in configuration")
    secure = options.pop("secure", cloudinary.config().secure)
    private_cdn = options.pop("private_cdn", cloudinary.config().private_cdn)
    secure_distribution = options.pop("secure_distribution", cloudinary.config().secure_distribution)
    sign_url = options.pop("sign_url", cloudinary.config().sign_url)
    api_secret = options.pop("api_secret", cloudinary.config().api_secret)
    url_suffix = options.pop("url_suffix", None)
    use_root_path = options.pop("use_root_path", cloudinary.config().use_root_path)
    auth_token = options.pop("auth_token", None)
    if auth_token is not False:
        auth_token = merge(cloudinary.config().auth_token, auth_token)

    if (not source) or type == "upload" and re.match(r'^https?:', source):
        return original_source, options

    resource_type, type = finalize_resource_type(resource_type, type, url_suffix, use_root_path, shorten)
    source, source_to_sign = finalize_source(source, format, url_suffix)

    if source_to_sign.find("/") >= 0 \
            and not re.match(r'^https?:/', source_to_sign) \
            and not re.match(r'^v[0-9]+', source_to_sign) \
            and not version:
        version = "1"
    if version: version = "v" + str(version)

    transformation = re.sub(r'([^:])/+', r'\1/', transformation)

    signature = None
    if sign_url and not auth_token:
        to_sign = "/".join(__compact([transformation, source_to_sign]))
        signature = "s--" + to_string(
            base64.urlsafe_b64encode(hashlib.sha1(to_bytes(to_sign + api_secret)).digest())[0:8]) + "--"

    prefix = unsigned_download_url_prefix(source, cloud_name, private_cdn, cdn_subdomain, secure_cdn_subdomain, cname,
                                          secure, secure_distribution)
    source = "/".join(__compact([prefix, resource_type, type, signature, transformation, version, source]))
    if sign_url and auth_token:
        path = urlparse(source).path
        token = cloudinary.auth_token.generate( **merge(auth_token, {"url": path}))
        source = "%s?%s" % (source, token)
    return source, options
Exemple #7
0
def smart_escape(source, unsafe=r"([^a-zA-Z0-9_.\-\/:]+)"):
    def pack(m):
        return to_bytes('%' + "%".join([
            "%02X" % x
            for x in struct.unpack('B' * len(m.group(1)), m.group(1))
        ]).upper())

    return to_string(re.sub(to_bytes(unsafe), pack, to_bytes(source)))
Exemple #8
0
def base64url_encode(data):
    """
    Url safe version of urlsafe_b64encode with stripped `=` sign at the end.

    :param data: input data

    :return: Base64 URL safe encoded string
    """
    return to_string(base64.urlsafe_b64encode(to_bytes(data)))
Exemple #9
0
def base64url_encode(data):
    """
    Url safe version of urlsafe_b64encode with stripped `=` sign at the end.

    :param data: input data

    :return: Base64 URL safe encoded string
    """
    return to_string(base64.urlsafe_b64encode(to_bytes(data)))
Exemple #10
0
def smart_escape(source, unsafe=r"([^a-zA-Z0-9_.\-\/:]+)"):
    """
    Based on ruby's CGI::unescape. In addition does not escape / :

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

    :return: Escaped string
    """
    def pack(m):
        return to_bytes('%' + "%".join(
            ["%02X" % x for x in struct.unpack('B' * len(m.group(1)), m.group(1))]
        ).upper())

    return to_string(re.sub(to_bytes(unsafe), pack, to_bytes(source)))
Exemple #11
0
def smart_escape(source, unsafe=r"([^a-zA-Z0-9_.\-\/:]+)"):
    """
    Based on ruby's CGI::unescape. In addition does not escape / :

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

    :return: Escaped string
    """
    def pack(m):
        return to_bytes('%' + "%".join(
            ["%02X" % x for x in struct.unpack('B' * len(m.group(1)), m.group(1))]
        ).upper())

    return to_string(re.sub(to_bytes(unsafe), pack, to_bytes(source)))
Exemple #12
0
    def __init__(self,
                 name,
                 value=None,
                 filename=None,
                 filetype=None,
                 filesize=None,
                 fileobj=None,
                 cb=None):
        self.name = Header(name).encode()
        self.value = _strify(value)
        if filename is None:
            self.filename = None
        else:
            if PY3:
                byte_filename = filename.encode("ascii", "xmlcharrefreplace")
                self.filename = to_string(byte_filename)
                encoding = 'unicode_escape'
            else:
                if isinstance(filename, unicode):
                    # Encode with XML entities
                    self.filename = filename.encode("ascii",
                                                    "xmlcharrefreplace")
                else:
                    self.filename = str(filename)
                encoding = 'string_escape'
            self.filename = self.filename.encode(encoding).replace(
                to_bytes('"'), to_bytes('\\"'))
        self.filetype = _strify(filetype)

        self.filesize = filesize
        self.fileobj = fileobj
        self.cb = cb

        if self.value is not None and self.fileobj is not None:
            raise ValueError("Only one of value or fileobj may be specified")

        if fileobj is not None and filesize is None:
            # Try and determine the file size
            try:
                self.filesize = os.fstat(fileobj.fileno()).st_size
            except (OSError, AttributeError, UnsupportedOperation):
                try:
                    fileobj.seek(0, 2)
                    self.filesize = fileobj.tell()
                    fileobj.seek(0)
                except Exception:
                    raise ValueError("Could not determine filesize")
    def __init__(self, name, value=None, filename=None, filetype=None,
                        filesize=None, fileobj=None, cb=None):
        self.name = Header(name).encode()
        self.value = _strify(value)
        if filename is None:
            self.filename = None
        else:
            if PY3:
                byte_filename = filename.encode("ascii", "xmlcharrefreplace")
                self.filename = to_string(byte_filename)
                encoding = 'unicode_escape'
            else:
                if isinstance(filename, unicode):
                    # Encode with XML entities
                    self.filename = filename.encode("ascii", "xmlcharrefreplace")
                else:
                    self.filename = str(filename)
                encoding = 'string_escape'
            self.filename = self.filename.encode(encoding).replace(to_bytes('"'), to_bytes('\\"'))
        self.filetype = _strify(filetype)

        self.filesize = filesize
        self.fileobj = fileobj
        self.cb = cb

        if self.value is not None and self.fileobj is not None:
            raise ValueError("Only one of value or fileobj may be specified")

        if fileobj is not None and filesize is None:
            # Try and determine the file size
            try:
                self.filesize = os.fstat(fileobj.fileno()).st_size
            except (OSError, AttributeError, UnsupportedOperation):
                try:
                    fileobj.seek(0, 2)
                    self.filesize = fileobj.tell()
                    fileobj.seek(0)
                except:
                    raise ValueError("Could not determine filesize")
Exemple #14
0
def call_api(action, params, **options):
    try:
        file_io = None
        return_error = options.get("return_error")
        if options.get("unsigned"):
            params = utils.cleanup_params(params)
        else:
            params = utils.sign_request(params, options)

        param_list = []
        for k, v in params.items():
            if isinstance(v, list):
                for vv in v:
                    param_list.append((k + "[]", vv))
            elif v:
                param_list.append((k, v))

        api_url = utils.cloudinary_api_url(action, **options)

        global _initialized
        if not _initialized:
            _initialized = True
            # Register the streaming http handlers with urllib2
            register_openers()

        datagen = to_bytes("")
        headers = {}
        if "file" in options:
            file = options["file"]
            if not isinstance(file, string_types):
                datagen, headers = multipart_encode({'file': file})
            elif not re.match(
                    r'^https?:|^s3:|^data:[^;]*;base64,([a-zA-Z0-9\/+\n=]+)$',
                    file):
                file_io = open(file, "rb")
                datagen, headers = multipart_encode({'file': file_io})
            else:
                param_list.append(("file", file))
        request = urllib2.Request(api_url + "?" + urlencode(param_list),
                                  datagen, headers)
        request.add_header("User-Agent", cloudinary.USER_AGENT)

        code = 200
        try:
            response = urllib2.urlopen(request).read()
        except urllib2.HTTPError:
            e = sys.exc_info()[1]
            if not e.code in [200, 400, 500]:
                raise Error(
                    "Server returned unexpected status code - %d - %s" %
                    (e.code, e.read()))
            code = e.code
            response = e.read()

        try:
            result = json.loads(to_string(response))
        except Exception:
            e = sys.exc_info()[1]
            # Error is parsing json
            raise Error("Error parsing server response (%d) - %s. Got - %s",
                        code, response, e)

        if "error" in result:
            if return_error:
                result["error"]["http_code"] = response.code
            else:
                raise Error(result["error"]["message"])

        return result
    finally:
        if file_io: file_io.close()
Exemple #15
0
def smart_escape(string):
    pack = lambda m: to_bytes('%' + "%".join(["%02X" % x for x in struct.unpack('B'*len(m.group(1)), m.group(1))]).upper())
    return to_string(re.sub(to_bytes(r"([^a-zA-Z0-9_.\-\/:]+)"), pack, to_bytes(string)))
Exemple #16
0
def cloudinary_url(source, **options):
    original_source = source

    type = options.pop("type", "upload")
    if type == 'fetch':
        options["fetch_format"] = options.get("fetch_format", options.pop("format", None))
    transformation, options = generate_transformation_string(**options)

    resource_type = options.pop("resource_type", "image")
    version = options.pop("version", None)
    format = options.pop("format", None)
    cdn_subdomain = options.pop("cdn_subdomain", cloudinary.config().cdn_subdomain)
    cname = options.pop("cname", cloudinary.config().cname)
    shorten = options.pop("shorten", cloudinary.config().shorten)

    cloud_name = options.pop("cloud_name", cloudinary.config().cloud_name or None)
    if cloud_name == None:
        raise ValueError("Must supply cloud_name in tag or in configuration")
    secure = options.pop("secure", cloudinary.config().secure)
    private_cdn = options.pop("private_cdn", cloudinary.config().private_cdn)
    secure_distribution = options.pop("secure_distribution", cloudinary.config().secure_distribution)
    sign_url = options.pop("sign_url", cloudinary.config().sign_url)
    api_secret = options.pop("api_secret", cloudinary.config().api_secret)

    if (not source) or ((type == "upload" or type=="asset") and re.match(r'^https?:', source)):
        return (original_source, options)
    if re.match(r'^https?:', source):
        source = smart_escape(source)
    else:
        source = unquote(source)
        if not PY3: source = source.decode('utf8')
        source = smart_escape(source)
        if format:
          source = source + "." + format

    if cloud_name.startswith("/"):
        prefix = "/res" + cloud_name
    else:
        shared_domain =  not private_cdn
        if secure:        
            if not secure_distribution or secure_distribution == cloudinary.OLD_AKAMAI_SHARED_CDN:
              secure_distribution = cloud_name + "-res.cloudinary.com" if private_cdn else cloudinary.SHARED_CDN
            shared_domain = shared_domain or secure_distribution == cloudinary.SHARED_CDN
            prefix = "https://" + secure_distribution
        else:
            subdomain = "a" + str((zlib.crc32(to_bytearray(source)) & 0xffffffff)%5 + 1) + "." if cdn_subdomain else ""
            if cname:
                host = cname
            elif private_cdn:
                host = cloud_name + "-res.cloudinary.com"
            else:
                host = "res.cloudinary.com"
            prefix = "http://" + subdomain + host
        if shared_domain:
            prefix += "/" + cloud_name

    if shorten and resource_type == "image" and type == "upload":
        resource_type = "iu"
        type = ""          
    if source.find("/") >= 0 and not re.match(r'^https?:/', source) and  not re.match(r'^v[0-9]+', source) and  not version:
        version = "1"
        
    rest = "/".join(filter(lambda x: x, [transformation, "v" + str(version) if version else "", source]))
    
    if sign_url:
        signature = to_string(base64.urlsafe_b64encode( hashlib.sha1(to_bytes(rest + api_secret)).digest() )[0:8])
        rest = "s--%(signature)s--/%(rest)s" % {"signature": signature, "rest": rest}
    
    components = [prefix, resource_type, type, rest]
    source = re.sub(r'([^:])/+', r'\1/', "/".join(components))
    return (source, options)
Exemple #17
0
def call_api(action, params, http_headers={}, return_error=False, unsigned=False, file=None, timeout=None, **options):
    try:
        file_io = None
        if unsigned:
          params = utils.cleanup_params(params)
        else:
          params = utils.sign_request(params, options)
    
        param_list = []
        for k, v in params.items():
            if isinstance(v, list):          
                for vv in v:
                  param_list.append((k+"[]", vv))
            elif v:
                param_list.append((k, v))            
    
        api_url = utils.cloudinary_api_url(action, **options)
    
        global _initialized
        if not _initialized:
            _initialized = True
            # Register the streaming http handlers with urllib2
            register_openers()
    
        datagen, headers = multipart_encode({})
        if file:
            if not isinstance(file, string_types):
                datagen, headers = multipart_encode({'file': file})
            elif not re.match(r'ftp:|https?:|s3:|data:[^;]*;base64,([a-zA-Z0-9\/+\n=]+)$', file):
                file_io = open(file, "rb")
                datagen, headers = multipart_encode({'file': file_io})
            else:
                param_list.append(("file", file))

        if _is_gae():
            # Might not be needed in the future but for now this is needed in GAE
            datagen = "".join(datagen)

        request = urllib2.Request(api_url + "?" + urlencode(param_list), datagen, headers)
        request.add_header("User-Agent", cloudinary.get_user_agent())
        for k, v in http_headers.items():
            request.add_header(k, v)
    
        kw = {}
        if timeout is not None:
            kw['timeout'] = timeout

        code = 200
        try:
            response = urllib2.urlopen(request, **kw).read()
        except HTTPError:
            e = sys.exc_info()[1]
            if not e.code in [200, 400, 500]:
                raise Error("Server returned unexpected status code - %d - %s" % (e.code, e.read()))
            code = e.code
            response = e.read()
        except urllib2.URLError:
            e = sys.exc_info()[1]
            raise Error("Error - %s" % str(e))
        except socket.error:
            e = sys.exc_info()[1]
            raise Error("Socket error: %s" % str(e))
    
        try:
            result = json.loads(to_string(response))
        except Exception:
            e = sys.exc_info()[1]
            # Error is parsing json
            raise Error("Error parsing server response (%d) - %s. Got - %s", code, response, e)
    
        if "error" in result:
            if return_error:
                result["error"]["http_code"] = code
            else:
                raise Error(result["error"]["message"])
    
        return result
    finally:
        if file_io: file_io.close()    
Exemple #18
0
def smart_escape(string):
    pack = lambda m: to_bytes('%' + "%".join(
        ["%02X" % x
         for x in struct.unpack('B' * len(m.group(1)), m.group(1))]).upper())
    return to_string(
        re.sub(to_bytes(r"([^a-zA-Z0-9_.\-\/:]+)"), pack, to_bytes(string)))
Exemple #19
0
def call_api(action,
             params,
             http_headers={},
             return_error=False,
             unsigned=False,
             file=None,
             timeout=None,
             **options):
    try:
        file_io = None
        if unsigned:
            params = utils.cleanup_params(params)
        else:
            params = utils.sign_request(params, options)

        param_list = []
        for k, v in params.items():
            if isinstance(v, list):
                for vv in v:
                    param_list.append((k + "[]", vv))
            elif v:
                param_list.append((k, v))

        api_url = utils.cloudinary_api_url(action, **options)

        global _initialized
        if not _initialized:
            _initialized = True
            # Register the streaming http handlers with urllib2
            register_openers()

        if file:
            if not isinstance(file, string_types):
                param_list.append(("file", file))
            elif not re.match(
                    r'ftp:|https?:|s3:|data:[^;]*;base64,([a-zA-Z0-9\/+\n=]+)$',
                    file):
                file_io = open(file, "rb")
                param_list.append(('file', file_io))
            else:
                param_list.append(("file", file))

        datagen, headers = multipart_encode(param_list)

        if _is_gae():
            # Might not be needed in the future but for now this is needed in GAE
            datagen = "".join(datagen)

        request = urllib2.Request(api_url, datagen, headers)
        request.add_header("User-Agent", cloudinary.get_user_agent())
        for k, v in http_headers.items():
            request.add_header(k, v)

        kw = {}
        if timeout is not None:
            kw['timeout'] = timeout

        code = 200
        try:
            response = urllib2.urlopen(request, **kw).read()
        except HTTPError:
            e = sys.exc_info()[1]
            if not e.code in [200, 400, 500]:
                raise Error(
                    "Server returned unexpected status code - %d - %s" %
                    (e.code, e.read()))
            code = e.code
            response = e.read()
        except urllib2.URLError:
            e = sys.exc_info()[1]
            raise Error("Error - %s" % str(e))
        except socket.error:
            e = sys.exc_info()[1]
            raise Error("Socket error: %s" % str(e))

        try:
            result = json.loads(to_string(response))
        except Exception:
            e = sys.exc_info()[1]
            # Error is parsing json
            raise Error("Error parsing server response (%d) - %s. Got - %s",
                        code, response, e)

        if "error" in result:
            if return_error:
                result["error"]["http_code"] = code
            else:
                raise Error(result["error"]["message"])

        return result
    finally:
        if file_io: file_io.close()
Exemple #20
0
def smart_escape(source,unsafe = r"([^a-zA-Z0-9_.\-\/:]+)"):
    def pack(m):
        return to_bytes('%' + "%".join(["%02X" % x for x in struct.unpack('B' * len(m.group(1)), m.group(1))]).upper())
    return to_string(re.sub(to_bytes(unsafe), pack, to_bytes(source)))
Exemple #21
0
def cloudinary_url(source, **options):
    original_source = source

    patch_fetch_format(options)
    type = options.pop("type", "upload")

    transformation, options = generate_transformation_string(**options)

    resource_type = options.pop("resource_type", "image")

    force_version = options.pop("force_version", cloudinary.config().force_version)
    if force_version is None:
        force_version = True

    version = options.pop("version", None)

    format = options.pop("format", None)
    cdn_subdomain = options.pop("cdn_subdomain", cloudinary.config().cdn_subdomain)
    secure_cdn_subdomain = options.pop("secure_cdn_subdomain",
                                       cloudinary.config().secure_cdn_subdomain)
    cname = options.pop("cname", cloudinary.config().cname)
    shorten = options.pop("shorten", cloudinary.config().shorten)

    cloud_name = options.pop("cloud_name", cloudinary.config().cloud_name or None)
    if cloud_name is None:
        raise ValueError("Must supply cloud_name in tag or in configuration")
    secure = options.pop("secure", cloudinary.config().secure)
    private_cdn = options.pop("private_cdn", cloudinary.config().private_cdn)
    secure_distribution = options.pop("secure_distribution",
                                      cloudinary.config().secure_distribution)
    sign_url = options.pop("sign_url", cloudinary.config().sign_url)
    api_secret = options.pop("api_secret", cloudinary.config().api_secret)
    url_suffix = options.pop("url_suffix", None)
    use_root_path = options.pop("use_root_path", cloudinary.config().use_root_path)
    auth_token = options.pop("auth_token", None)
    long_url_signature = options.pop("long_url_signature", cloudinary.config().long_url_signature)
    signature_algorithm = options.pop("signature_algorithm", cloudinary.config().signature_algorithm)
    if auth_token is not False:
        auth_token = merge(cloudinary.config().auth_token, auth_token)

    if (not source) or type == "upload" and re.match(r'^https?:', source):
        return original_source, options

    resource_type, type = finalize_resource_type(
        resource_type, type, url_suffix, use_root_path, shorten)
    source, source_to_sign = finalize_source(source, format, url_suffix)

    if not version and force_version \
            and source_to_sign.find("/") >= 0 \
            and not re.match(r'^https?:/', source_to_sign) \
            and not re.match(r'^v[0-9]+', source_to_sign):
        version = "1"
    if version:
        version = "v" + str(version)
    else:
        version = None

    transformation = re.sub(r'([^:])/+', r'\1/', transformation)

    signature = None
    if sign_url and not auth_token:
        to_sign = "/".join(__compact([transformation, source_to_sign]))
        if long_url_signature:
            # Long signature forces SHA256
            signature_algorithm = SIGNATURE_SHA256
            chars_length = LONG_URL_SIGNATURE_LENGTH
        else:
            chars_length = SHORT_URL_SIGNATURE_LENGTH
        if signature_algorithm not in signature_algorithms:
            raise ValueError("Unsupported signature algorithm '{}'".format(signature_algorithm))
        hash_fn = signature_algorithms[signature_algorithm]
        signature = "s--" + to_string(
            base64.urlsafe_b64encode(
                hash_fn(to_bytes(to_sign + api_secret)).digest())[0:chars_length]) + "--"

    prefix = unsigned_download_url_prefix(
        source, cloud_name, private_cdn, cdn_subdomain, secure_cdn_subdomain,
        cname, secure, secure_distribution)
    source = "/".join(__compact(
        [prefix, resource_type, type, signature, transformation, version, source]))
    if sign_url and auth_token:
        path = urlparse(source).path
        token = cloudinary.auth_token.generate(**merge(auth_token, {"url": path}))
        source = "%s?%s" % (source, token)
    return source, options
Exemple #22
0
def call_api(action, params, **options):
    try:
        file_io = None
        return_error = options.get("return_error")
        if options.get("unsigned"):
          params = utils.cleanup_params(params)
        else:
          params = utils.sign_request(params, options)
    
        param_list = []
        for k, v in params.items():
            if isinstance(v, list):          
                for vv in v:
                  param_list.append((k+"[]", vv))
            elif v:
                param_list.append((k, v))            
    
        api_url = utils.cloudinary_api_url(action, **options)
    
        global _initialized
        if not _initialized:
            _initialized = True
            # Register the streaming http handlers with urllib2
            register_openers()
    
        datagen = to_bytes("")
        headers = {}
        if "file" in options:
            file = options["file"]
            if not isinstance(file, string_types):
                datagen, headers = multipart_encode({'file': file})
            elif not re.match(r'^https?:|^s3:|^data:[^;]*;base64,([a-zA-Z0-9\/+\n=]+)$', file):
                file_io = open(file, "rb")
                datagen, headers = multipart_encode({'file': file_io})
            else:
                param_list.append(("file", file))
        request = urllib2.Request(api_url + "?" + urlencode(param_list), datagen, headers)
        request.add_header("User-Agent", cloudinary.USER_AGENT)
    
        kw = {}
        if 'timeout' in options:
            kw['timeout'] = options['timeout']

        code = 200
        try:
            response = urllib2.urlopen(request, **kw).read()
        except socket.error:
            e = sys.exc_info()[1]
            raise Error("Socket error: %s" % str(e))
        except urllib2.HTTPError:
            e = sys.exc_info()[1]
            if not e.code in [200, 400, 500]:
                raise Error("Server returned unexpected status code - %d - %s" % (e.code, e.read()))
            code = e.code
            response = e.read()
    
        try:
            result = json.loads(to_string(response))
        except Exception:
            e = sys.exc_info()[1]
            # Error is parsing json
            raise Error("Error parsing server response (%d) - %s. Got - %s", code, response, e)
    
        if "error" in result:
            if return_error:
                result["error"]["http_code"] = code
            else:
                raise Error(result["error"]["message"])
    
        return result
    finally:
        if file_io: file_io.close()    
Exemple #23
0
def cloudinary_url(source, **options):
    original_source = source

    type = options.pop("type", "upload")
    if type == 'fetch':
        options["fetch_format"] = options.get("fetch_format", options.pop("format", None))
    transformation, options = generate_transformation_string(**options)

    resource_type = options.pop("resource_type", "image")
    version = options.pop("version", None)
    format = options.pop("format", None)
    cdn_subdomain = options.pop("cdn_subdomain", cloudinary.config().cdn_subdomain)
    cname = options.pop("cname", cloudinary.config().cname)
    shorten = options.pop("shorten", cloudinary.config().shorten)

    cloud_name = options.pop("cloud_name", cloudinary.config().cloud_name or None)
    if cloud_name == None:
        raise ValueError("Must supply cloud_name in tag or in configuration")
    secure = options.pop("secure", cloudinary.config().secure)
    private_cdn = options.pop("private_cdn", cloudinary.config().private_cdn)
    secure_distribution = options.pop("secure_distribution", cloudinary.config().secure_distribution)
    sign_url = options.pop("sign_url", cloudinary.config().sign_url)
    api_secret = options.pop("api_secret", cloudinary.config().api_secret)

    if (not source) or ((type == "upload" or type=="asset") and re.match(r'^https?:', source)):
        return (original_source, options)
    if re.match(r'^https?:', source):
        source = smart_escape(source)
    else:
        source = unquote(source)
        if not PY3: source = source.decode('utf8')
        source = smart_escape(source)
        if format:
          source = source + "." + format

    if cloud_name.startswith("/"):
        prefix = "/res" + cloud_name
    else:
        shared_domain =  not private_cdn
        if secure:        
            if not secure_distribution or secure_distribution == cloudinary.OLD_AKAMAI_SHARED_CDN:
              secure_distribution = cloud_name + "-res.cloudinary.com" if private_cdn else cloudinary.SHARED_CDN
            shared_domain = shared_domain or secure_distribution == cloudinary.SHARED_CDN
            prefix = "https://" + secure_distribution
        else:
            subdomain = "a" + str((zlib.crc32(to_bytearray(source)) & 0xffffffff)%5 + 1) + "." if cdn_subdomain else ""
            if cname:
                host = cname
            elif private_cdn:
                host = cloud_name + "-res.cloudinary.com"
            else:
                host = "res.cloudinary.com"
            prefix = "http://" + subdomain + host
        if shared_domain:
            prefix += "/" + cloud_name

    if shorten and resource_type == "image" and type == "upload":
        resource_type = "iu"
        type = ""          
    if source.find("/") >= 0 and not re.match(r'^https?:/', source) and  not re.match(r'^v[0-9]+', source) and  not version:
        version = "1"
        
    rest = "/".join(filter(lambda x: x, [transformation, "v" + str(version) if version else "", source]))
    
    if sign_url:
        signature = to_string(base64.urlsafe_b64encode( hashlib.sha1(to_bytes(rest + api_secret)).digest() )[0:8])
        rest = "s--%(signature)s--/%(rest)s" % {"signature": signature, "rest": rest}
    
    components = [prefix, resource_type, type, rest]
    source = re.sub(r'([^:])/+', r'\1/', "/".join(components))
    return (source, options)