From 38256781453ba03317308099784298b5b5368bf1 Mon Sep 17 00:00:00 2001 From: tata Date: Tue, 14 Nov 2023 18:24:25 +0100 Subject: [PATCH] For #79 logger in dev #70 :lipstick: css grid --- .gitignore | 3 ++ sandbox/conf/base.py | 14 ++---- sandbox/conf/dev.py | 66 +++++++++++++++++++++++++ src/comments/signals.py | 2 - src/comments/views.py | 6 +++ src/contacts/views.py | 11 +++++ src/core/utils/views_help.py | 25 ++++++++++ src/profiles/mixins.py | 8 +++ src/profiles/signals.py | 12 +++-- src/profiles/views.py | 5 ++ src/static/css/styles.css | 7 +-- src/templates/admin/base_site.html | 1 - src/templates/components/categ_bar.html | 2 +- src/templates/posts/post_list.html | 7 +-- 14 files changed, 142 insertions(+), 27 deletions(-) diff --git a/.gitignore b/.gitignore index bd13cb5..6112181 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,6 @@ docs reqs/req.txt reqs/req.in *bron +*node_modules +*logs +*.log diff --git a/sandbox/conf/base.py b/sandbox/conf/base.py index 6a847cc..6061e1d 100644 --- a/sandbox/conf/base.py +++ b/sandbox/conf/base.py @@ -1,8 +1,6 @@ """ django 4.2.1 """ - - from pathlib import Path import environ @@ -11,15 +9,11 @@ BASE_DIR = Path(__file__).resolve().parent.parent.parent # let op: +parent env = environ.Env(ALLOWED_HOSTS=(list, []), DEBUG=(bool, False)) - environ.Env.read_env(BASE_DIR / ".env") - - DEBUG = True SECRET_KEY = env("SECRET_KEY") SITE_ID = 1 AUTH_USER_MODEL = "accounts.User" - ALLOWED_HOSTS: list[str] = env("ALLOWED_HOSTS") DJANGO_APPS = [ "modeltranslation", @@ -51,7 +45,6 @@ "embed_video", ] - LOCAL_APPS = [ "src.accounts.apps.AccountsConfig", "src.profiles.apps.ProfilesConfig", @@ -161,15 +154,15 @@ EMAIL_HOST_PASSWORD = env("EMAIL_HOST_PASSWORD") EMAIL_PORT = env("EMAIL_PORT") EMAIL_USE_TLS = True -EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend" # dev.py - +EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend" # img upload limits MIN_UPLOAD_SIZE = 120 # in bytes MAX_UPLOAD_SIZE = 1024 * 1024 * 2 # 2 MB UPLOAD_FILE_TYPES = "image/jpeg,image/png,image/jpg" -FILE_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 2 # for MemFileUploadHandler info +FILE_UPLOAD_MAX_MEMORY_SIZE = 1024 * 1024 * 2 +# for MemFileUploadHandler info # allauth @@ -184,7 +177,6 @@ } ACCOUNT_ADAPTER = "src.accounts.adapters.InactiveUserEmailAdapter" - ACCOUNT_USERNAME_REQUIRED = True ACCOUNT_EMAIL_REQUIRED = True diff --git a/sandbox/conf/dev.py b/sandbox/conf/dev.py index 4992326..9cab5af 100644 --- a/sandbox/conf/dev.py +++ b/sandbox/conf/dev.py @@ -20,3 +20,69 @@ USE_CAPCHA = False +LOGGING = { + "version": 1, + "disable_existing_loggers": False, + "formatters": { + "verbose": { + "format": "{levelname} {asctime} {module} {process:d} {message}", + "style": "{", + }, + "simple": { + "format": "{levelname} {message}", + "style": "{", + }, + }, + "handlers": { + "console": { + "level": "INFO", + "class": "logging.StreamHandler", + "formatter": "simple", + }, + "dj": { + "level": "WARNING", + "class": "logging.handlers.RotatingFileHandler", + "formatter": "verbose", + "maxBytes": 1024 * 1024 * 1, # 1MB + "backupCount": 5, + "filename": "zoo/django_native.log", + }, + "upload_problems": { + "level": "WARNING", + "class": "logging.handlers.RotatingFileHandler", + "maxBytes": 1024 * 1024 * 1, + "backupCount": 5, + "formatter": "verbose", + "filename": "zoo/upload.log", + }, + "users": { + "level": "INFO", + "class": "logging.handlers.RotatingFileHandler", + "maxBytes": 1024 * 1024 * 1, + "backupCount": 5, + "formatter": "verbose", + "filename": "zoo/user_issues.log", + }, + "mail_admin": { + "level": "CRITICAL", + "class": "django.utils.log.AdminEmailHandler", + }, + }, + "loggers": { + "django": { + "handlers": ["console"], + # 'handlers': ['dj','console'], + # 'handlers': ['mail_admin','dj'], + "level": "WARNING", + "propagate": False, + }, + "upload": { + "handlers": ["upload_problems"], + "level": "WARNING", + }, + "user_issues": { + "handlers": ["users"], + "level": "INFO", + }, + }, +} diff --git a/src/comments/signals.py b/src/comments/signals.py index 901c294..82a8cdf 100644 --- a/src/comments/signals.py +++ b/src/comments/signals.py @@ -1,5 +1,3 @@ -from datetime import datetime - from django.db.models.signals import post_save from django.dispatch import receiver diff --git a/src/comments/views.py b/src/comments/views.py index fce5c75..be6bd39 100644 --- a/src/comments/views.py +++ b/src/comments/views.py @@ -1,3 +1,5 @@ +import logging + from django.contrib.auth.decorators import login_required from django.contrib.auth.mixins import LoginRequiredMixin as LRM from django.http import HttpResponse, HttpResponseForbidden, QueryDict @@ -10,6 +12,8 @@ from src.comments.models import Comment from src.posts.models.post_model import Post +logger = logging.getLogger("user_issues") + def display_all_comments(request, post_uuid): """ @@ -57,6 +61,7 @@ def post(self, request, post_uuid): no notifications in cases: - parent(replied) comm is deleted; - users comment their own comment + - banned users filter via template """ form = CommentForm(request.POST) if form.is_valid(): @@ -84,6 +89,7 @@ def handle_edit_comment(request, post_uuid, comm_id): incl method PUT (htmx) """ if request.user.banned: + logger.warning(f"banned user {request.user.id} attempted to edit comment") return HttpResponseForbidden() ctx = {"post_uuid": post_uuid, "comm_id": comm_id} diff --git a/src/contacts/views.py b/src/contacts/views.py index 0478dcc..47fc292 100644 --- a/src/contacts/views.py +++ b/src/contacts/views.py @@ -1,3 +1,5 @@ +import logging + from django.contrib import messages from django.contrib.auth.mixins import LoginRequiredMixin as LRM from django.core.mail import send_mail @@ -9,11 +11,14 @@ from django.views.generic import View from django.views.generic.edit import FormView +from src.core.utils.views_help import get_ip from src.profiles.models import Profile from .exceptions import HtmxFailureError from .forms import ContactForm +logger = logging.getLogger("user_issues") + class Subscribe(LRM, View): def get(self, request): @@ -39,11 +44,13 @@ def post(self, request, **kwargs): profile = get_object_or_404(Profile, id=_id) profile.want_news = True profile.save() + logger.info(f"{profile.id} succeeded to subscribe for news letter") messages.success(request, _("You have subscribed to the news letter")) return HttpResponse( headers={"HX-Redirect": "/"}, ) elif htmx_req is None: + logger.error(f"{request.user.id} failed htmx to subscribe for news letter") raise HtmxFailureError(_("Subscription failed")) @@ -70,6 +77,7 @@ def post(self, request, **kwargs): if htmx_req and profile.want_news: profile.want_news = False profile.save() + logger.info(f"{profile.id} succeeded to UNsubscribe for news letter") messages.success(request, _("You have unsubscribed to the news letter")) return HttpResponse( headers={ @@ -77,6 +85,7 @@ def post(self, request, **kwargs): }, ) elif htmx_req is None: + logger.error(f"{profile.id} failed htmx to Unsubscribe for news letter") raise HtmxFailureError(_("Something went wrong.Can't unsubscribe.")) except HtmxFailureError: raise @@ -124,6 +133,8 @@ def form_valid(self, form): # self.send_mail_to_admin() ? send_mail(subject, contact_message, from_email, to_email, fail_silently=True) + remote_address = get_ip(self.request) + logger.info(f"contact letter sent OK from ip: {remote_address}") messages.add_message( self.request, diff --git a/src/core/utils/views_help.py b/src/core/utils/views_help.py index 60650fc..ec0a830 100644 --- a/src/core/utils/views_help.py +++ b/src/core/utils/views_help.py @@ -1,9 +1,13 @@ +import logging + from django.contrib.postgres.search import SearchQuery from django.http import HttpResponse from django.shortcuts import render from src.posts.models.post_model import Post +logger = logging.getLogger("user_issues") + def clear(request): """(htmx) help func to clean elem on htmx requests""" @@ -47,6 +51,27 @@ def search_qs(current_lang, query): return posts +def get_ip(req): + """ + if x_forward present return it; + otherwise remote_addr or empty string + """ + try: + forward = req.META.get("HTTP_X_FORWARDED_FOR") + if forward: + return ( + req.META.get("HTTP_X_FORWARDED_FOR", req.META.get("REMOTE_ADDR", "")) + .split(",")[0] + .strip() + ) + else: + return req.META.get("REMOTE_ADDR") + + except Exception as e: + logger.warning(f"Failed to find IP in request: {e}") + return "" + + def limit_like(request, attempts=None): """ help func to detect misuse LIKE button (to logs) diff --git a/src/profiles/mixins.py b/src/profiles/mixins.py index d0f85d2..c7e6ee4 100644 --- a/src/profiles/mixins.py +++ b/src/profiles/mixins.py @@ -1,5 +1,11 @@ +import logging + from django.core.exceptions import BadRequest +from src.core.utils.views_help import get_ip + +logger = logging.getLogger("django") + class CheckJSMixin: """check if request headers present - js fetch""" @@ -7,6 +13,8 @@ class CheckJSMixin: def dispatch(self, request, *args, **kwargs): condition = request.headers.get("x-requested-with") == "XMLHttpRequest" if request.method == "POST" and not condition: + remote_address = get_ip(request) + logger.warning(f"request attempt not htmx from ip: {remote_address}") raise BadRequest() return super().dispatch(request, *args, **kwargs) diff --git a/src/profiles/signals.py b/src/profiles/signals.py index 94c1cfd..4e41b9a 100644 --- a/src/profiles/signals.py +++ b/src/profiles/signals.py @@ -1,3 +1,4 @@ +import logging from datetime import date from django.contrib.auth import get_user_model @@ -7,6 +8,7 @@ from .models import Profile User = get_user_model() +logger = logging.getLogger("user_issues") @receiver(post_save, sender=User) @@ -14,9 +16,10 @@ def create_profile(sender, instance, created, *args, **kwargs): try: if created and instance.email: Profile.objects.get_or_create(user=instance) + logger.info(f"user {instance.id} created profile successfully") except Exception as e: print("Smth went wrong with profile creation", e) - # TODO logger note + logger.error(f"user ID:{instance.id} failed to create his profile: {str(e)}") @receiver(post_delete, sender=Profile) @@ -26,8 +29,9 @@ def set_user_inactive(sender, instance, **kwargs): user_obj = instance.user user_obj.is_active = False user_obj.deactivated_on = date.today() - user_obj.save() + logger.warning( + f"{user_obj.id} deleted his account and became deactivated on {date.today()}" + ) except Exception as e: - print("Smth went wrong with user is_active", e) - # TODO logger note + logger.error(f"{user_obj.id} failed to delete his profile: {str(e)}") diff --git a/src/profiles/views.py b/src/profiles/views.py index 4f60c2c..024ca57 100644 --- a/src/profiles/views.py +++ b/src/profiles/views.py @@ -1,3 +1,5 @@ +import logging + from django.contrib import messages from django.contrib.auth import logout from django.contrib.auth.mixins import LoginRequiredMixin as LRM @@ -11,6 +13,8 @@ from .forms import ProfileForm from .models import Profile +logger = logging.getLogger("upload") + class ProfileView(LRM, CheckJSMixin, View): def get(self, request, **kwargs): @@ -35,6 +39,7 @@ def post(self, request, **kwargs): messages.success(request, "Avatar changed successfully") return JsonResponse({"status_code": 200, "resp": "OK"}) else: + logger.warning(f"Profile {profile.id} failed to upload ava") return JsonResponse({"status_code": 404, "err": form.errors}) diff --git a/src/static/css/styles.css b/src/static/css/styles.css index e95afbf..6dc74aa 100644 --- a/src/static/css/styles.css +++ b/src/static/css/styles.css @@ -103,7 +103,6 @@ footer{ grid-row:3/4; padding-left:1rem; margin-top: -25px; - } .grid-archive{ grid-row:2/3; @@ -119,18 +118,20 @@ footer{ /* margin-inline: auto; */ } .grid-categs{ - grid-row:1/3; + grid-row:1/4; } .grid-content{ - grid-row:1/3; + grid-row:1/4; padding-left:1rem; } .grid-archive{ grid-row:1/2; + } .grid-tags{ grid-row:2/3; } + } /* end test with grid layout */ diff --git a/src/templates/admin/base_site.html b/src/templates/admin/base_site.html index 8a71c25..10479fa 100644 --- a/src/templates/admin/base_site.html +++ b/src/templates/admin/base_site.html @@ -1,6 +1,5 @@ {% extends 'admin/base_site.html' %} {% load static %} {% block extrastyle %} - {% endblock %} \ No newline at end of file diff --git a/src/templates/components/categ_bar.html b/src/templates/components/categ_bar.html index a798360..e472107 100644 --- a/src/templates/components/categ_bar.html +++ b/src/templates/components/categ_bar.html @@ -1,7 +1,7 @@ {% load sidebars %}
- +
-
+
{% if posts %} {% for post in posts%} {% include "posts/parts/single_post.html" %} {% endfor %} {% include "posts/parts/pagination.html" %} {% else %} -
+
{% trans "Sorry. Nothing found for your search" %}
{% include "posts/parts/search_errors.html" %} @@ -32,7 +30,6 @@
{% show_tags %} -