mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-12-23 00:26:33 +00:00
Download fonts at app startup instead
We can't bake the font into the Docker image as such, because we mount the volumes which blows away anything we have in the app tree beforehand. We could stash it somewhere in the image and then copy it from there on app startup or something, but at that point we might as well just download it as part of the app startup.
This commit is contained in:
parent
766a0cc652
commit
9e6390662b
4 changed files with 66 additions and 20 deletions
|
@ -6,13 +6,6 @@ RUN mkdir /app /app/static /app/images
|
||||||
|
|
||||||
WORKDIR /app
|
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/
|
COPY requirements.txt /app/
|
||||||
RUN pip install -r requirements.txt --no-cache-dir
|
RUN pip install -r requirements.txt --no-cache-dir
|
||||||
RUN apt-get update && apt-get install -y gettext libgettextpo-dev tidy && apt-get clean
|
RUN apt-get update && apt-get install -y gettext libgettextpo-dev tidy && apt-get clean
|
||||||
|
|
35
bookwyrm/apps.py
Normal file
35
bookwyrm/apps.py
Normal file
|
@ -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)
|
|
@ -4,6 +4,8 @@ import os
|
||||||
import textwrap
|
import textwrap
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
import urllib
|
||||||
|
import logging
|
||||||
|
|
||||||
import colorsys
|
import colorsys
|
||||||
from colorthief import ColorThief
|
from colorthief import ColorThief
|
||||||
|
@ -17,29 +19,37 @@ from django.db.models import Avg
|
||||||
from bookwyrm import models, settings
|
from bookwyrm import models, settings
|
||||||
from bookwyrm.tasks import app
|
from bookwyrm.tasks import app
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
IMG_WIDTH = settings.PREVIEW_IMG_WIDTH
|
IMG_WIDTH = settings.PREVIEW_IMG_WIDTH
|
||||||
IMG_HEIGHT = settings.PREVIEW_IMG_HEIGHT
|
IMG_HEIGHT = settings.PREVIEW_IMG_HEIGHT
|
||||||
BG_COLOR = settings.PREVIEW_BG_COLOR
|
BG_COLOR = settings.PREVIEW_BG_COLOR
|
||||||
TEXT_COLOR = settings.PREVIEW_TEXT_COLOR
|
TEXT_COLOR = settings.PREVIEW_TEXT_COLOR
|
||||||
DEFAULT_COVER_COLOR = settings.PREVIEW_DEFAULT_COVER_COLOR
|
DEFAULT_COVER_COLOR = settings.PREVIEW_DEFAULT_COVER_COLOR
|
||||||
|
DEFAULT_FONT = settings.PREVIEW_DEFAULT_FONT
|
||||||
TRANSPARENT_COLOR = (0, 0, 0, 0)
|
TRANSPARENT_COLOR = (0, 0, 0, 0)
|
||||||
|
|
||||||
margin = math.floor(IMG_HEIGHT / 10)
|
margin = math.floor(IMG_HEIGHT / 10)
|
||||||
gutter = math.floor(margin / 2)
|
gutter = math.floor(margin / 2)
|
||||||
inner_img_height = math.floor(IMG_HEIGHT * 0.8)
|
inner_img_height = math.floor(IMG_HEIGHT * 0.8)
|
||||||
inner_img_width = math.floor(inner_img_height * 0.7)
|
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):
|
def get_font(weight, size=28):
|
||||||
"""Loads custom font"""
|
font = get_imagefont(DEFAULT_FONT, size)
|
||||||
font_path = os.path.join(font_dir, "SourceHanSans-VF.ttf.ttc")
|
|
||||||
|
|
||||||
try:
|
|
||||||
font = ImageFont.truetype(font_path, size)
|
|
||||||
except OSError:
|
|
||||||
font = ImageFont.load_default()
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if weight == "light":
|
if weight == "light":
|
||||||
|
|
|
@ -35,6 +35,9 @@ LOCALE_PATHS = [
|
||||||
]
|
]
|
||||||
LANGUAGE_COOKIE_NAME = env.str("LANGUAGE_COOKIE_NAME", "django_language")
|
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"
|
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
|
||||||
|
|
||||||
# Preview image
|
# 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_WIDTH = env.int("PREVIEW_IMG_WIDTH", 1200)
|
||||||
PREVIEW_IMG_HEIGHT = env.int("PREVIEW_IMG_HEIGHT", 630)
|
PREVIEW_IMG_HEIGHT = env.int("PREVIEW_IMG_HEIGHT", 630)
|
||||||
PREVIEW_DEFAULT_COVER_COLOR = env.str("PREVIEW_DEFAULT_COVER_COLOR", "#002549")
|
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
|
# Quick-start development settings - unsuitable for production
|
||||||
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
|
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
|
||||||
|
@ -310,13 +323,8 @@ if USE_S3:
|
||||||
MEDIA_FULL_URL = MEDIA_URL
|
MEDIA_FULL_URL = MEDIA_URL
|
||||||
STATIC_FULL_URL = STATIC_URL
|
STATIC_FULL_URL = STATIC_URL
|
||||||
DEFAULT_FILE_STORAGE = "bookwyrm.storage_backends.ImagesStorage"
|
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:
|
else:
|
||||||
STATIC_URL = "/static/"
|
STATIC_URL = "/static/"
|
||||||
STATIC_ROOT = os.path.join(BASE_DIR, env("STATIC_ROOT", "static"))
|
|
||||||
MEDIA_URL = "/images/"
|
MEDIA_URL = "/images/"
|
||||||
MEDIA_FULL_URL = f"{PROTOCOL}://{DOMAIN}{MEDIA_URL}"
|
MEDIA_FULL_URL = f"{PROTOCOL}://{DOMAIN}{MEDIA_URL}"
|
||||||
STATIC_FULL_URL = f"{PROTOCOL}://{DOMAIN}{STATIC_URL}"
|
STATIC_FULL_URL = f"{PROTOCOL}://{DOMAIN}{STATIC_URL}"
|
||||||
MEDIA_ROOT = os.path.join(BASE_DIR, env("MEDIA_ROOT", "images"))
|
|
||||||
|
|
Loading…
Reference in a new issue