mirror of
https://github.com/Alexander-D-Karpov/akarpov
synced 2024-11-25 16:23:43 +03:00
updated production, fixed image crop
This commit is contained in:
parent
b94ee139c7
commit
6769b2f6de
|
@ -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,
|
||||||
)
|
)
|
||||||
|
|
|
@ -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"])
|
||||||
|
|
|
@ -1 +1,5 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<p> this is me, and thats my website </p>
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -1 +1,5 @@
|
||||||
{% extends "base.html" %}
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<p>This is my site %evil text%</p>
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<header>
|
<header>
|
||||||
<!-- here’s the avatar -->
|
<!-- here’s 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 -->
|
||||||
|
|
|
@ -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,
|
||||||
)
|
)
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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/",
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user