diff --git a/Dockerfile b/Dockerfile index 8a24e8883..349dd82b1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,13 +6,6 @@ RUN mkdir /app /app/static /app/images WORKDIR /app -# Use RUN curl because ADD will re-download the file every time to make sure it -# hasn't changed, which is exactly what we don't want -RUN mkdir -p /app/static/fonts/source_han_sans -RUN curl \ - https://github.com/adobe-fonts/source-han-sans/raw/release/Variable/OTC/SourceHanSans-VF.ttf.ttc \ - -o /app/static/fonts/source_han_sans/SourceHanSans-VF.ttf.ttc - COPY requirements.txt /app/ RUN pip install -r requirements.txt --no-cache-dir RUN apt-get update && apt-get install -y gettext libgettextpo-dev tidy && apt-get clean diff --git a/bookwyrm/apps.py b/bookwyrm/apps.py new file mode 100644 index 000000000..a3fe1c2cf --- /dev/null +++ b/bookwyrm/apps.py @@ -0,0 +1,35 @@ +import os +import urllib +import logging + +from django.apps import AppConfig + +from bookwyrm import settings + +logger = logging.getLogger(__name__) + +def download_file(url, destination): + try: + stream = urllib.request.urlopen(url) + with open(destination, "b+w") as f: + f.write(stream.read()) + except (urllib.error.HTTPError, urllib.error.URLError): + logger.error("Failed to download file %s", url) + + +class BookwyrmConfig(AppConfig): + name = "bookwyrm" + verbose_name = "BookWyrm" + + def ready(self): + if settings.ENABLE_PREVIEW_IMAGES and settings.FONTS: + # Download any fonts that we don't have yet + logger.debug("Downloading fonts..") + for name, config in settings.FONTS.items(): + font_path = os.path.join( + settings.FONT_DIR, config["directory"], config["filename"] + ) + + if "url" in config and not os.path.exists(font_path): + logger.info("Just a sec, downloading %s", name) + download_file(config["url"], font_path) diff --git a/bookwyrm/preview_images.py b/bookwyrm/preview_images.py index f48ca15e2..325742d72 100644 --- a/bookwyrm/preview_images.py +++ b/bookwyrm/preview_images.py @@ -4,6 +4,8 @@ import os import textwrap from io import BytesIO from uuid import uuid4 +import urllib +import logging import colorsys from colorthief import ColorThief @@ -17,29 +19,37 @@ from django.db.models import Avg from bookwyrm import models, settings from bookwyrm.tasks import app +logger = logging.getLogger(__name__) IMG_WIDTH = settings.PREVIEW_IMG_WIDTH IMG_HEIGHT = settings.PREVIEW_IMG_HEIGHT BG_COLOR = settings.PREVIEW_BG_COLOR TEXT_COLOR = settings.PREVIEW_TEXT_COLOR DEFAULT_COVER_COLOR = settings.PREVIEW_DEFAULT_COVER_COLOR +DEFAULT_FONT = settings.PREVIEW_DEFAULT_FONT TRANSPARENT_COLOR = (0, 0, 0, 0) margin = math.floor(IMG_HEIGHT / 10) gutter = math.floor(margin / 2) inner_img_height = math.floor(IMG_HEIGHT * 0.8) inner_img_width = math.floor(inner_img_height * 0.7) -font_dir = os.path.join(settings.STATIC_ROOT, "fonts/source_han_sans") + + +def get_imagefont(name, size): + try: + config = settings.FONTS[name] + path = os.path.join(settings.FONT_DIR, config["directory"], config["filename"]) + return ImageFont.truetype(path, size) + except KeyError: + logger.error("Font %s not found in config", name) + except OSError: + logger.error("Could not load font %s from file", name) + + return ImageFont.load_default() def get_font(weight, size=28): - """Loads custom font""" - font_path = os.path.join(font_dir, "SourceHanSans-VF.ttf.ttc") - - try: - font = ImageFont.truetype(font_path, size) - except OSError: - font = ImageFont.load_default() + font = get_imagefont(DEFAULT_FONT, size) try: if weight == "light": diff --git a/bookwyrm/settings.py b/bookwyrm/settings.py index 197e672c1..b85925b77 100644 --- a/bookwyrm/settings.py +++ b/bookwyrm/settings.py @@ -35,6 +35,9 @@ LOCALE_PATHS = [ ] LANGUAGE_COOKIE_NAME = env.str("LANGUAGE_COOKIE_NAME", "django_language") +STATIC_ROOT = os.path.join(BASE_DIR, env("STATIC_ROOT", "static")) +MEDIA_ROOT = os.path.join(BASE_DIR, env("MEDIA_ROOT", "images")) + DEFAULT_AUTO_FIELD = "django.db.models.AutoField" # Preview image @@ -44,6 +47,16 @@ PREVIEW_TEXT_COLOR = env.str("PREVIEW_TEXT_COLOR", "#363636") PREVIEW_IMG_WIDTH = env.int("PREVIEW_IMG_WIDTH", 1200) PREVIEW_IMG_HEIGHT = env.int("PREVIEW_IMG_HEIGHT", 630) PREVIEW_DEFAULT_COVER_COLOR = env.str("PREVIEW_DEFAULT_COVER_COLOR", "#002549") +PREVIEW_DEFAULT_FONT = env.str("PREVIEW_DEFAULT_FONT", "Source Han Sans") + +FONTS = { + "Source Han Sans": { + "directory": "source_han_sans", + "filename": "SourceHanSans-VF.ttf.ttc", + "url": "https://github.com/adobe-fonts/source-han-sans/raw/release/Variable/OTC/SourceHanSans-VF.ttf.ttc", + } +} +FONT_DIR = os.path.join(STATIC_ROOT, "fonts") # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/ @@ -310,13 +323,8 @@ if USE_S3: MEDIA_FULL_URL = MEDIA_URL STATIC_FULL_URL = STATIC_URL DEFAULT_FILE_STORAGE = "bookwyrm.storage_backends.ImagesStorage" - # I don't know if it's used, but the site crashes without it - STATIC_ROOT = os.path.join(BASE_DIR, env("STATIC_ROOT", "static")) - MEDIA_ROOT = os.path.join(BASE_DIR, env("MEDIA_ROOT", "images")) else: STATIC_URL = "/static/" - STATIC_ROOT = os.path.join(BASE_DIR, env("STATIC_ROOT", "static")) MEDIA_URL = "/images/" MEDIA_FULL_URL = f"{PROTOCOL}://{DOMAIN}{MEDIA_URL}" STATIC_FULL_URL = f"{PROTOCOL}://{DOMAIN}{STATIC_URL}" - MEDIA_ROOT = os.path.join(BASE_DIR, env("MEDIA_ROOT", "images"))