diff --git a/.env.dev.example b/.env.dev.example index f407c52b..f42aaaae 100644 --- a/.env.dev.example +++ b/.env.dev.example @@ -3,6 +3,7 @@ SECRET_KEY="7(2w1sedok=aznpq)ta1mc4i%4h=xx@hxwx*o57ctsuml0x%fr" # SECURITY WARNING: don't run with debug turned on in production! DEBUG=true +USE_HTTPS=false DOMAIN=your.domain.here #EMAIL=your@email.here @@ -42,6 +43,21 @@ EMAIL_HOST_PASSWORD=emailpassword123 EMAIL_USE_TLS=true EMAIL_USE_SSL=false +# S3 configuration +USE_S3=false +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= + +# Commented are example values if you use a non-AWS, S3-compatible service +# AWS S3 should work with only AWS_STORAGE_BUCKET_NAME and AWS_S3_REGION_NAME +# non-AWS S3-compatible services will need AWS_STORAGE_BUCKET_NAME, +# along with both AWS_S3_CUSTOM_DOMAIN and AWS_S3_ENDPOINT_URL + +# AWS_STORAGE_BUCKET_NAME= # "example-bucket-name" +# AWS_S3_CUSTOM_DOMAIN=None # "example-bucket-name.s3.fr-par.scw.cloud" +# AWS_S3_REGION_NAME=None # "fr-par" +# AWS_S3_ENDPOINT_URL=None # "https://s3.fr-par.scw.cloud" + # Preview image generation can be computing and storage intensive # ENABLE_PREVIEW_IMAGES=True diff --git a/.env.prod.example b/.env.prod.example index d61c46af..5115469c 100644 --- a/.env.prod.example +++ b/.env.prod.example @@ -3,6 +3,7 @@ SECRET_KEY="7(2w1sedok=aznpq)ta1mc4i%4h=xx@hxwx*o57ctsuml0x%fr" # SECURITY WARNING: don't run with debug turned on in production! DEBUG=false +USE_HTTPS=true DOMAIN=your.domain.here EMAIL=your@email.here @@ -42,6 +43,21 @@ EMAIL_HOST_PASSWORD=emailpassword123 EMAIL_USE_TLS=true EMAIL_USE_SSL=false +# S3 configuration +USE_S3=false +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= + +# Commented are example values if you use a non-AWS, S3-compatible service +# AWS S3 should work with only AWS_STORAGE_BUCKET_NAME and AWS_S3_REGION_NAME +# non-AWS S3-compatible services will need AWS_STORAGE_BUCKET_NAME, +# along with both AWS_S3_CUSTOM_DOMAIN and AWS_S3_ENDPOINT_URL + +# AWS_STORAGE_BUCKET_NAME= # "example-bucket-name" +# AWS_S3_CUSTOM_DOMAIN=None # "example-bucket-name.s3.fr-par.scw.cloud" +# AWS_S3_REGION_NAME=None # "fr-par" +# AWS_S3_ENDPOINT_URL=None # "https://s3.fr-par.scw.cloud" + # Preview image generation can be computing and storage intensive # ENABLE_PREVIEW_IMAGES=True diff --git a/bookwyrm/context_processors.py b/bookwyrm/context_processors.py index f2661a19..1f0387fe 100644 --- a/bookwyrm/context_processors.py +++ b/bookwyrm/context_processors.py @@ -11,10 +11,7 @@ def site_settings(request): # pylint: disable=unused-argument return { "site": models.SiteSettings.objects.get(), "active_announcements": models.Announcement.active_announcements(), - "static_url": settings.STATIC_URL, - "media_url": settings.MEDIA_URL, - "static_path": settings.STATIC_PATH, - "media_path": settings.MEDIA_PATH, + "media_full_url": settings.MEDIA_FULL_URL, "preview_images_enabled": settings.ENABLE_PREVIEW_IMAGES, "request_protocol": request_protocol, } diff --git a/bookwyrm/preview_images.py b/bookwyrm/preview_images.py index 510625e3..29c4961c 100644 --- a/bookwyrm/preview_images.py +++ b/bookwyrm/preview_images.py @@ -11,6 +11,7 @@ from PIL import Image, ImageDraw, ImageFont, ImageOps, ImageColor from django.core.files.base import ContentFile from django.core.files.uploadedfile import InMemoryUploadedFile +from django.core.files.storage import default_storage from django.db.models import Avg from bookwyrm import models, settings @@ -319,9 +320,9 @@ def save_and_cleanup(image, instance=None): try: try: - old_path = instance.preview_image.path + old_path = instance.preview_image.name except ValueError: - old_path = "" + old_path = None # Save image.save(image_buffer, format="jpeg", quality=75) @@ -342,8 +343,8 @@ def save_and_cleanup(image, instance=None): instance.save() # Clean up old file after saving - if os.path.exists(old_path): - os.remove(old_path) + if old_path and default_storage.exists(old_path): + default_storage.delete(old_path) finally: image_buffer.close() diff --git a/bookwyrm/settings.py b/bookwyrm/settings.py index 50b526bd..17fcfabe 100644 --- a/bookwyrm/settings.py +++ b/bookwyrm/settings.py @@ -58,6 +58,7 @@ SECRET_KEY = env("SECRET_KEY") # SECURITY WARNING: don't run with debug turned on in production! DEBUG = env.bool("DEBUG", True) +USE_HTTPS = env.bool("USE_HTTPS", False) ALLOWED_HOSTS = env.list("ALLOWED_HOSTS", ["*"]) @@ -74,6 +75,7 @@ INSTALLED_APPS = [ "django_rename_app", "bookwyrm", "celery", + "storages", ] MIDDLEWARE = [ @@ -179,19 +181,51 @@ USE_L10N = True USE_TZ = True -# Static files (CSS, JavaScript, Images) -# https://docs.djangoproject.com/en/3.2/howto/static-files/ - -PROJECT_DIR = os.path.dirname(os.path.abspath(__file__)) -STATIC_URL = "/static/" -STATIC_PATH = "%s/%s" % (DOMAIN, env("STATIC_ROOT", "static")) -STATIC_ROOT = os.path.join(BASE_DIR, env("STATIC_ROOT", "static")) -MEDIA_URL = "/images/" -MEDIA_PATH = "%s/%s" % (DOMAIN, env("MEDIA_ROOT", "images")) -MEDIA_ROOT = os.path.join(BASE_DIR, env("MEDIA_ROOT", "images")) - USER_AGENT = "%s (BookWyrm/%s; +https://%s/)" % ( requests.utils.default_user_agent(), VERSION, DOMAIN, ) + + +# Static files (CSS, JavaScript, Images) +# https://docs.djangoproject.com/en/3.2/howto/static-files/ + +PROJECT_DIR = os.path.dirname(os.path.abspath(__file__)) + +# Storage + +PROTOCOL = "http" +if USE_HTTPS: + PROTOCOL = "https" + +USE_S3 = env.bool("USE_S3", False) + +if USE_S3: + # AWS settings + AWS_ACCESS_KEY_ID = env("AWS_ACCESS_KEY_ID") + AWS_SECRET_ACCESS_KEY = env("AWS_SECRET_ACCESS_KEY") + AWS_STORAGE_BUCKET_NAME = env("AWS_STORAGE_BUCKET_NAME") + AWS_S3_CUSTOM_DOMAIN = env("AWS_S3_CUSTOM_DOMAIN") + AWS_S3_REGION_NAME = env("AWS_S3_REGION_NAME", "") + AWS_S3_ENDPOINT_URL = env("AWS_S3_ENDPOINT_URL") + AWS_DEFAULT_ACL = "public-read" + AWS_S3_OBJECT_PARAMETERS = {"CacheControl": "max-age=86400"} + # S3 Static settings + STATIC_LOCATION = "static" + STATIC_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, STATIC_LOCATION) + STATICFILES_STORAGE = "bookwyrm.storage_backends.StaticStorage" + # S3 Media settings + MEDIA_LOCATION = "images" + MEDIA_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, MEDIA_LOCATION) + MEDIA_FULL_URL = MEDIA_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 = "%s://%s%s" % (PROTOCOL, DOMAIN, MEDIA_URL) + MEDIA_ROOT = os.path.join(BASE_DIR, env("MEDIA_ROOT", "images")) diff --git a/bookwyrm/storage_backends.py b/bookwyrm/storage_backends.py new file mode 100644 index 00000000..e10dfb84 --- /dev/null +++ b/bookwyrm/storage_backends.py @@ -0,0 +1,17 @@ +"""Handles backends for storages""" +from storages.backends.s3boto3 import S3Boto3Storage + + +class StaticStorage(S3Boto3Storage): # pylint: disable=abstract-method + """Storage class for Static contents""" + + location = "static" + default_acl = "public-read" + + +class ImagesStorage(S3Boto3Storage): # pylint: disable=abstract-method + """Storage class for Image files""" + + location = "images" + default_acl = "public-read" + file_overwrite = False diff --git a/bookwyrm/templates/book/book.html b/bookwyrm/templates/book/book.html index 9a75cbe9..c5dab109 100644 --- a/bookwyrm/templates/book/book.html +++ b/bookwyrm/templates/book/book.html @@ -1,5 +1,10 @@ {% extends 'layout.html' %} -{% load i18n %}{% load bookwyrm_tags %}{% load humanize %}{% load utilities %}{% load layout %} +{% load i18n %} +{% load bookwyrm_tags %} +{% load humanize %} +{% load utilities %} +{% load static %} +{% load layout %} {% block title %}{{ book|book_title }}{% endblock %} @@ -321,5 +326,5 @@ {% endblock %} {% block scripts %} - + {% endblock %} diff --git a/bookwyrm/templates/feed/layout.html b/bookwyrm/templates/feed/layout.html index 57305df7..ad7d39f0 100644 --- a/bookwyrm/templates/feed/layout.html +++ b/bookwyrm/templates/feed/layout.html @@ -1,5 +1,6 @@ {% extends 'layout.html' %} {% load i18n %} +{% load static %} {% block title %}{% trans "Updates" %}{% endblock %} @@ -105,5 +106,5 @@ {% endblock %} {% block scripts %} - + {% endblock %} diff --git a/bookwyrm/templates/get_started/layout.html b/bookwyrm/templates/get_started/layout.html index 63c04289..08a2e7c5 100644 --- a/bookwyrm/templates/get_started/layout.html +++ b/bookwyrm/templates/get_started/layout.html @@ -1,5 +1,6 @@ {% extends 'layout.html' %} {% load i18n %} +{% load static %} {% block title %}{% trans "Welcome" %}{% endblock %} @@ -9,7 +10,7 @@