2018-07-30 22:16:26 +02:00
|
|
|
# See https://zulip.readthedocs.io/en/latest/subsystems/thumbnailing.html
|
2018-03-08 09:37:09 +01:00
|
|
|
import base64
|
|
|
|
import os
|
|
|
|
import sys
|
|
|
|
import urllib
|
2019-12-20 02:58:53 +01:00
|
|
|
from urllib.parse import urljoin
|
2020-06-11 00:54:34 +02:00
|
|
|
|
2018-03-08 09:37:09 +01:00
|
|
|
from django.conf import settings
|
2021-04-16 00:59:20 +02:00
|
|
|
from django.utils.http import url_has_allowed_host_and_scheme
|
2018-03-08 09:37:09 +01:00
|
|
|
from libthumbor import CryptoURL
|
|
|
|
|
2020-04-12 19:44:42 +02:00
|
|
|
ZULIP_PATH = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
2018-03-08 09:37:09 +01:00
|
|
|
sys.path.append(ZULIP_PATH)
|
|
|
|
|
|
|
|
from zerver.lib.camo import get_camo_url
|
2020-06-11 00:54:34 +02:00
|
|
|
from zthumbor.loaders.helpers import THUMBOR_EXTERNAL_TYPE, THUMBOR_LOCAL_FILE_TYPE, THUMBOR_S3_TYPE
|
|
|
|
|
2018-03-08 09:37:09 +01:00
|
|
|
|
|
|
|
def is_thumbor_enabled() -> bool:
|
2021-02-12 08:20:45 +01:00
|
|
|
return settings.THUMBOR_URL != ""
|
2018-03-08 09:37:09 +01:00
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
|
2018-09-01 13:39:16 +02:00
|
|
|
def user_uploads_or_external(url: str) -> bool:
|
2021-04-16 00:59:20 +02:00
|
|
|
return not url_has_allowed_host_and_scheme(url, allowed_hosts=None) or url.startswith(
|
|
|
|
"/user_uploads/"
|
|
|
|
)
|
2018-09-01 13:39:16 +02:00
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
|
2018-03-08 09:37:09 +01:00
|
|
|
def get_source_type(url: str) -> str:
|
2021-02-12 08:20:45 +01:00
|
|
|
if not url.startswith("/user_uploads/"):
|
2018-03-08 09:37:09 +01:00
|
|
|
return THUMBOR_EXTERNAL_TYPE
|
|
|
|
|
|
|
|
local_uploads_dir = settings.LOCAL_UPLOADS_DIR
|
|
|
|
if local_uploads_dir:
|
|
|
|
return THUMBOR_LOCAL_FILE_TYPE
|
|
|
|
return THUMBOR_S3_TYPE
|
|
|
|
|
2021-02-12 08:19:30 +01:00
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
def generate_thumbnail_url(path: str, size: str = "0x0", is_camo_url: bool = False) -> str:
|
2019-12-12 01:28:29 +01:00
|
|
|
path = urljoin("/", path)
|
2018-03-08 09:37:09 +01:00
|
|
|
|
|
|
|
if not is_thumbor_enabled():
|
2021-04-16 00:59:20 +02:00
|
|
|
if url_has_allowed_host_and_scheme(path, allowed_hosts=None):
|
2019-12-20 02:58:53 +01:00
|
|
|
return path
|
2019-12-12 01:28:29 +01:00
|
|
|
return get_camo_url(path)
|
2018-03-08 09:37:09 +01:00
|
|
|
|
2021-04-16 00:59:20 +02:00
|
|
|
if url_has_allowed_host_and_scheme(path, allowed_hosts=None) and not path.startswith(
|
|
|
|
"/user_uploads/"
|
|
|
|
):
|
2019-12-20 02:58:53 +01:00
|
|
|
return path
|
2018-03-08 09:37:09 +01:00
|
|
|
|
|
|
|
source_type = get_source_type(path)
|
2021-02-12 08:20:45 +01:00
|
|
|
safe_url = base64.urlsafe_b64encode(path.encode()).decode("utf-8")
|
|
|
|
image_url = f"{safe_url}/source_type/{source_type}"
|
|
|
|
width, height = map(int, size.split("x"))
|
2018-03-08 09:37:09 +01:00
|
|
|
crypto = CryptoURL(key=settings.THUMBOR_KEY)
|
2019-01-04 14:35:58 +01:00
|
|
|
|
2018-12-17 17:27:05 +01:00
|
|
|
smart_crop_enabled = True
|
2021-02-12 08:20:45 +01:00
|
|
|
apply_filters = ["no_upscale()"]
|
2018-12-17 17:27:05 +01:00
|
|
|
if is_camo_url:
|
|
|
|
smart_crop_enabled = False
|
2021-02-12 08:20:45 +01:00
|
|
|
apply_filters.append("quality(100)")
|
|
|
|
if size != "0x0":
|
|
|
|
apply_filters.append("sharpen(0.5,0.2,true)")
|
2019-01-04 14:35:58 +01:00
|
|
|
|
2018-03-08 09:37:09 +01:00
|
|
|
encrypted_url = crypto.generate(
|
|
|
|
width=width,
|
|
|
|
height=height,
|
2018-12-17 17:27:05 +01:00
|
|
|
smart=smart_crop_enabled,
|
2019-01-04 14:35:58 +01:00
|
|
|
filters=apply_filters,
|
python: Use trailing commas consistently.
Automatically generated by the following script, based on the output
of lint with flake8-comma:
import re
import sys
last_filename = None
last_row = None
lines = []
for msg in sys.stdin:
m = re.match(
r"\x1b\[35mflake8 \|\x1b\[0m \x1b\[1;31m(.+):(\d+):(\d+): (\w+)", msg
)
if m:
filename, row_str, col_str, err = m.groups()
row, col = int(row_str), int(col_str)
if filename == last_filename:
assert last_row != row
else:
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
with open(filename) as f:
lines = f.readlines()
last_filename = filename
last_row = row
line = lines[row - 1]
if err in ["C812", "C815"]:
lines[row - 1] = line[: col - 1] + "," + line[col - 1 :]
elif err in ["C819"]:
assert line[col - 2] == ","
lines[row - 1] = line[: col - 2] + line[col - 1 :].lstrip(" ")
if last_filename is not None:
with open(last_filename, "w") as f:
f.writelines(lines)
Signed-off-by: Anders Kaseorg <anders@zulipchat.com>
2020-04-10 05:23:40 +02:00
|
|
|
image_url=image_url,
|
2018-03-08 09:37:09 +01:00
|
|
|
)
|
|
|
|
|
2021-02-12 08:20:45 +01:00
|
|
|
if settings.THUMBOR_URL == "http://127.0.0.1:9995":
|
2018-03-08 09:37:09 +01:00
|
|
|
# If THUMBOR_URL is the default then thumbor is hosted on same machine
|
|
|
|
# as the Zulip server and we should serve a relative URL.
|
2020-10-23 02:43:28 +02:00
|
|
|
# We add a /thumbor in front of the relative URL because we make
|
2018-03-08 09:37:09 +01:00
|
|
|
# use of a proxy pass to redirect request internally in Nginx to 9995
|
|
|
|
# port where thumbor is running.
|
2021-02-12 08:20:45 +01:00
|
|
|
thumbnail_url = "/thumbor" + encrypted_url
|
2018-03-08 09:37:09 +01:00
|
|
|
else:
|
|
|
|
thumbnail_url = urllib.parse.urljoin(settings.THUMBOR_URL, encrypted_url)
|
|
|
|
return thumbnail_url
|