updated production, fixed image crop

This commit is contained in:
Alexander Karpov 2022-12-06 12:03:58 +03:00
parent b94ee139c7
commit 6769b2f6de
12 changed files with 77 additions and 32 deletions

View File

@ -25,7 +25,7 @@ def post_on_save(sender, instance: Post, **kwargs):
"app_label": "blog", "app_label": "blog",
"model_name": "Post", "model_name": "Post",
}, },
countdown=10, countdown=2,
) )
else: else:
instance.image_cropped = None instance.image_cropped = None
@ -87,5 +87,5 @@ def post_on_create(sender, instance: Post, created, **kwargs):
"app_label": "blog", "app_label": "blog",
"model_name": "Post", "model_name": "Post",
}, },
countdown=10, countdown=2,
) )

View File

@ -11,7 +11,7 @@ def crop_model_image(pk: int, app_label: str, model_name: str):
instance = model.objects.get(pk=pk) instance = model.objects.get(pk=pk)
instance.image_cropped.save( instance.image_cropped.save(
instance.image.path.split(".")[0].split("/")[-1] + ".png", instance.image.path.split(".")[0].split("/")[-1] + ".png",
File(crop_image(instance.image.path, cut_to=(250, 250))), File(crop_image(instance.image.path, length=250)),
save=False, save=False,
) )
instance.save(update_fields=["image_cropped"]) instance.save(update_fields=["image_cropped"])

View File

@ -1 +1,5 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block content %}
<p> this is me, and thats my website </p>
{% endblock %}

View File

@ -1 +1,5 @@
{% extends "base.html" %} {% extends 'base.html' %}
{% block content %}
<p>This is my site %evil text%</p>
{% endblock %}

View File

@ -8,7 +8,7 @@
<header> <header>
<!-- heres the avatar --> <!-- heres the avatar -->
<a target="_blank" href="#"> <a target="_blank" href="#">
{% if object.image_cropped %}<img src="{{ object.image_cropped.url }}" class="hoverZoomLink">{% endif %} {% if object.image_cropped %}<img style="object-fit: cover; width: 125px; height: 125px" src="{{ object.image_cropped.url }}" class="hoverZoomLink">{% endif %}
</a> </a>
<!-- the username --> <!-- the username -->

View File

@ -21,7 +21,7 @@ def on_change(sender, instance: User, **kwargs):
"app_label": "users", "app_label": "users",
"model_name": "User", "model_name": "User",
}, },
countdown=10, countdown=2,
) )
else: else:
instance.image_cropped = None instance.image_cropped = None
@ -39,5 +39,5 @@ def post_on_create(sender, instance: User, created, **kwargs):
"app_label": "users", "app_label": "users",
"model_name": "User", "model_name": "User",
}, },
countdown=10, countdown=2,
) )

View File

@ -5,17 +5,55 @@
from PIL import Image from PIL import Image
def crop_image(image_path: str, cut_to=(500, 500)): def crop_image(image_path: str, length: int = 500):
"""Makes image's thumbnail bt given parameters. By default, crops to 500x500""" """Makes image's thumbnail bt given parameters. By default, crops to 500x500"""
img = Image.open(image_path) image = Image.open(image_path)
blob = BytesIO() blob = BytesIO()
try: try:
img.thumbnail(cut_to, Image.ANTIALIAS) if image.size[0] < image.size[1]:
# The image is in portrait mode. Height is bigger than width.
# This makes the width fit the LENGTH in pixels while conserving the ration.
resized_image = image.resize(
(length, int(image.size[1] * (length / image.size[0])))
)
# Amount of pixel to lose in total on the height of the image.
required_loss = resized_image.size[1] - length
# Crop the height of the image so as to keep the center part.
resized_image = resized_image.crop(
box=(
0,
int(required_loss / 2),
length,
int(resized_image.size[1] - required_loss / 2),
)
)
else:
# This image is in landscape mode or already squared. The width is bigger than the heihgt.
# This makes the height fit the LENGTH in pixels while conserving the ration.
resized_image = image.resize(
(int(image.size[0] * (length / image.size[1])), length)
)
# Amount of pixel to lose in total on the width of the image.
required_loss = resized_image.size[0] - length
# Crop the width of the image so as to keep 1080 pixels of the center part.
resized_image = resized_image.crop(
box=(
int(required_loss / 2),
0,
int(resized_image.size[0] - required_loss / 2),
length,
)
)
resized_image.save(blob, "PNG")
except OSError: except OSError:
print("Can't crop") print("Can't crop")
img.save(blob, "PNG")
return blob return blob

View File

@ -59,12 +59,10 @@ COPY --from=python-build-stage /usr/src/app/wheels /wheels/
RUN pip install --no-cache-dir --no-index --find-links=/wheels/ /wheels/* \ RUN pip install --no-cache-dir --no-index --find-links=/wheels/ /wheels/* \
&& rm -rf /wheels/ && rm -rf /wheels/
COPY --chown=django:django ./compose/production/django/entrypoint /entrypoint COPY --chown=django:django ./compose/production/django/entrypoint /entrypoint
RUN sed -i 's/\r$//g' /entrypoint RUN sed -i 's/\r$//g' /entrypoint
RUN chmod +x /entrypoint RUN chmod +x /entrypoint
COPY --chown=django:django ./compose/production/django/start /start COPY --chown=django:django ./compose/production/django/start /start
RUN sed -i 's/\r$//g' /start RUN sed -i 's/\r$//g' /start
RUN chmod +x /start RUN chmod +x /start

View File

@ -4,7 +4,13 @@ set -o errexit
set -o pipefail set -o pipefail
set -o nounset set -o nounset
mkdir /app/staticfiles/
chmod -R +r /app/staticfiles/
python /app/manage.py collectstatic --noinput python /app/manage.py collectstatic --noinput
python /app/manage.py makemigrations
python /app/manage.py migrate auth
python /app/manage.py migrate
/usr/local/bin/gunicorn config.wsgi --bind 0.0.0.0:5000 --chdir=/app /usr/local/bin/gunicorn config.wsgi --bind 0.0.0.0:5000 --chdir=/app

View File

@ -7,7 +7,7 @@
from sentry_sdk.integrations.redis import RedisIntegration from sentry_sdk.integrations.redis import RedisIntegration
from .base import * # noqa from .base import * # noqa
from .base import env from .base import APPS_DIR, ROOT_DIR, env
# GENERAL # GENERAL
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -64,8 +64,16 @@
# STATIC # STATIC
# ------------------------ # ------------------------
STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage"
STATIC_ROOT = str(ROOT_DIR / "staticfiles")
# https://docs.djangoproject.com/en/dev/ref/settings/#static-url
STATIC_URL = "/static/"
# https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS
STATICFILES_DIRS = [str(APPS_DIR / "static")]
# MEDIA # MEDIA
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
MEDIA_ROOT = str(APPS_DIR / "media")
# https://docs.djangoproject.com/en/dev/ref/settings/#media-url
MEDIA_URL = "/media/"
# EMAIL # EMAIL
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -98,7 +106,7 @@
ANYMAIL = { ANYMAIL = {
"MAILGUN_API_KEY": env("MAILGUN_API_KEY"), "MAILGUN_API_KEY": env("MAILGUN_API_KEY"),
"MAILGUN_SENDER_DOMAIN": env("MAILGUN_DOMAIN"), "MAILGUN_SENDER_DOMAIN": env("MAILGUN_DOMAIN"),
"MAILGUN_API_URL": env("MAILGUN_API_URL", default="https://api.mailgun.net/v3"), "MAILGUN_API_URL": "https://api.mailgun.net/v3",
} }

View File

@ -11,7 +11,7 @@
) )
urlpatterns = [ urlpatterns = [
path("", include("akarpov.blog.urls", namespace="blog")), path("home", TemplateView.as_view(template_name="pages/home.html"), name="home"),
path( path(
"about/", TemplateView.as_view(template_name="pages/about.html"), name="about" "about/", TemplateView.as_view(template_name="pages/about.html"), name="about"
), ),
@ -22,6 +22,7 @@
path("users/", include("akarpov.users.urls", namespace="users")), path("users/", include("akarpov.users.urls", namespace="users")),
path("ckeditor/", include("ckeditor_uploader.urls")), path("ckeditor/", include("ckeditor_uploader.urls")),
path("accounts/", include("allauth.urls")), path("accounts/", include("allauth.urls")),
path("", include("akarpov.blog.urls", namespace="blog")),
# Your stuff: custom urls includes go here # Your stuff: custom urls includes go here
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
@ -35,7 +36,7 @@
path( path(
"api/docs/", "api/docs/",
SpectacularSwaggerView.as_view(url_name="api-schema"), SpectacularSwaggerView.as_view(url_name="api-schema"),
name="home", name="swagger",
), ),
path( path(
"api/redoc/", "api/redoc/",

View File

@ -31,20 +31,6 @@ services:
env_file: env_file:
- ./.envs/.production/.postgres - ./.envs/.production/.postgres
traefik:
build:
context: .
dockerfile: ./compose/production/traefik/Dockerfile
image: akarpov_production_traefik
depends_on:
- django
volumes:
- production_traefik:/etc/traefik/acme:z
ports:
- "0.0.0.0:80:80"
- "0.0.0.0:443:443"
- "0.0.0.0:5555:5555"
redis: redis:
image: redis:6 image: redis:6