def finalize_source(source, format, url_suffix): source = re.sub(r'([^:])/+', r'\1/', source) if re.match(r'^https?:/', source): source = smart_escape(source) source_to_sign = source else: source = unquote(source) if not PY3: source = source.decode('utf8') source = smart_escape(source) source_to_sign = source if url_suffix != None: if re.search(r'[\./]', url_suffix): raise ValueError("url_suffix should not include . or /") source = source + "/" + url_suffix if format != None: source = source + "." + format source_to_sign = source_to_sign + "." + format return (source, source_to_sign)
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)