From 424639ea80bc71857666a23f2bcb6a94ccab0bb1 Mon Sep 17 00:00:00 2001 From: thomas girod Date: Fri, 26 Jul 2024 15:14:37 +0200 Subject: [PATCH] better scss --- core/management/commands/markdown.py | 3 +- core/models.py | 7 ++-- core/scss/finder.py | 3 +- core/scss/processor.py | 56 ++++++++-------------------- core/templatetags/renderer.py | 10 +++-- core/tests.py | 3 +- core/utils.py | 5 --- core/views/files.py | 10 ++--- sas/models.py | 9 +---- sith/settings.py | 2 +- 10 files changed, 37 insertions(+), 71 deletions(-) diff --git a/core/management/commands/markdown.py b/core/management/commands/markdown.py index 09a03d0d..8b43e5ac 100644 --- a/core/management/commands/markdown.py +++ b/core/management/commands/markdown.py @@ -21,7 +21,6 @@ # # -from pathlib import Path from django.conf import settings from django.core.management.base import BaseCommand @@ -33,7 +32,7 @@ class Command(BaseCommand): help = "Output the fully rendered SYNTAX.md file" def handle(self, *args, **options): - root_path = Path(settings.BASE_DIR) + root_path = settings.BASE_DIR with open(root_path / "core/fixtures/SYNTAX.md", "r") as md: result = markdown(md.read()) print(result, end="") diff --git a/core/models.py b/core/models.py index 13332abe..c9aceab6 100644 --- a/core/models.py +++ b/core/models.py @@ -27,6 +27,7 @@ import importlib import os import unicodedata from datetime import date, timedelta +from pathlib import Path from typing import TYPE_CHECKING, Optional from django.conf import settings @@ -56,8 +57,6 @@ from django.utils.html import escape from django.utils.translation import gettext_lazy as _ from phonenumber_field.modelfields import PhoneNumberField -from core import utils - if TYPE_CHECKING: from club.models import Club @@ -377,7 +376,9 @@ class User(AbstractBaseUser): USERNAME_FIELD = "username" def promo_has_logo(self): - return utils.file_exist("./core/static/core/img/promo_%02d.png" % self.promo) + return Path( + settings.BASE_DIR / f"core/static/core/img/promo_{self.promo}.png" + ).exists() def has_module_perms(self, package_name): return self.is_active diff --git a/core/scss/finder.py b/core/scss/finder.py index cf8915ef..a4b7d030 100644 --- a/core/scss/finder.py +++ b/core/scss/finder.py @@ -22,7 +22,6 @@ # # -import os from collections import OrderedDict from django.conf import settings @@ -37,7 +36,7 @@ class ScssFinder(FileSystemFinder): def __init__(self, apps=None, *args, **kwargs): location = settings.STATIC_ROOT - if not os.path.isdir(location): + if not location.is_dir(): return self.locations = [("", location)] self.storages = OrderedDict() diff --git a/core/scss/processor.py b/core/scss/processor.py index ac851cd8..eb682747 100644 --- a/core/scss/processor.py +++ b/core/scss/processor.py @@ -21,61 +21,35 @@ # Place - Suite 330, Boston, MA 02111-1307, USA. # # - -import os -from urllib.parse import urljoin +import functools +from pathlib import Path import sass from django.conf import settings from django.core.files.base import ContentFile from django.templatetags.static import static -from django.utils.encoding import force_bytes, iri_to_uri +from django_jinja.builtins.filters import static from core.scss.storage import ScssFileStorage, find_file -class ScssProcessor(object): - """If DEBUG mode enabled : compile the scss file - Else : give the path of the corresponding css supposed to already be compiled - Don't forget to use compilestatics to compile scss for production. - """ +@functools.cache +def _scss_storage(): + return ScssFileStorage() - prefix = iri_to_uri(getattr(settings, "STATIC_URL", "/static/")) - storage = ScssFileStorage() - scss_extensions = [".scss"] - def __init__(self, path=None): - self.path = path - - def _convert_scss(self): - basename, ext = os.path.splitext(self.path) - css_filename = self.path.replace(".scss", ".css") - url = urljoin(self.prefix, css_filename) - - if not settings.DEBUG: - return url - - if ext not in self.scss_extensions: - return static(self.path) - - # Compilation on the fly +def process_scss_path(path: Path): + css_path = path.with_suffix(".css") + if settings.DEBUG: compile_args = { - "filename": find_file(self.path), + "filename": find_file(path), "include_paths": settings.SASS_INCLUDE_FOLDERS, } if settings.SASS_PRECISION: compile_args["precision"] = settings.SASS_PRECISION content = sass.compile(**compile_args) - content = force_bytes(content) - - if self.storage.exists(css_filename): - self.storage.delete(css_filename) - self.storage.save(css_filename, ContentFile(content)) - - return url - - def get_converted_scss(self): - if self.path: - return self._convert_scss() - else: - return "" + storage = _scss_storage() + if storage.exists(css_path): + storage.delete(css_path) + storage.save(css_path, ContentFile(content)) + return static(css_path) diff --git a/core/templatetags/renderer.py b/core/templatetags/renderer.py index 8d6bac64..cfd3ef91 100644 --- a/core/templatetags/renderer.py +++ b/core/templatetags/renderer.py @@ -23,15 +23,17 @@ # import datetime +from pathlib import Path import phonenumbers from django import template +from django.template import TemplateSyntaxError from django.template.defaultfilters import stringfilter from django.utils.safestring import mark_safe from django.utils.translation import ngettext from core.markdown import markdown as md -from core.scss.processor import ScssProcessor +from core.scss.processor import process_scss_path register = template.Library() @@ -86,5 +88,7 @@ def format_timedelta(value: datetime.timedelta) -> str: @register.simple_tag() def scss(path): """Return path of the corresponding css file after compilation.""" - processor = ScssProcessor(path) - return processor.get_converted_scss() + path = Path(path) + if path.suffix != ".scss": + raise TemplateSyntaxError("`scss` tag has been called with a non-scss file") + return process_scss_path(path) diff --git a/core/tests.py b/core/tests.py index 6fa24874..1377a5ae 100644 --- a/core/tests.py +++ b/core/tests.py @@ -14,7 +14,6 @@ # from datetime import date, timedelta -from pathlib import Path from smtplib import SMTPException import freezegun @@ -210,7 +209,7 @@ def test_custom_markdown_syntax(md, html): def test_full_markdown_syntax(): - syntax_path = Path(settings.BASE_DIR) / "core" / "fixtures" + syntax_path = settings.BASE_DIR / "core" / "fixtures" md = (syntax_path / "SYNTAX.md").read_text() html = (syntax_path / "SYNTAX.html").read_text() result = markdown(md) diff --git a/core/utils.py b/core/utils.py index 41d132bc..b336a125 100644 --- a/core/utils.py +++ b/core/utils.py @@ -13,7 +13,6 @@ # # -import os import re import subprocess from datetime import date @@ -96,10 +95,6 @@ def get_semester_code(d: Optional[date] = None) -> str: return "P" + str(start.year)[-2:] -def file_exist(path): - return os.path.exists(path) - - def scale_dimension(width, height, long_edge): if width > height: ratio = long_edge * 1.0 / width diff --git a/core/views/files.py b/core/views/files.py index 83f7e00c..83af9dd1 100644 --- a/core/views/files.py +++ b/core/views/files.py @@ -59,17 +59,17 @@ def send_file(request, file_id, file_class=SithFile, file_attr="file"): ): raise PermissionDenied name = f.__getattribute__(file_attr).name - filepath = os.path.join(settings.MEDIA_ROOT, name) + filepath = settings.MEDIA_ROOT / name # check if file exists on disk - if not os.path.exists(filepath.encode("utf-8")): - raise Http404() + if not filepath.exists(): + raise Http404 - with open(filepath.encode("utf-8"), "rb") as filename: + with open(filepath, "rb") as filename: wrapper = FileWrapper(filename) response = HttpResponse(wrapper, content_type=f.mime_type) response["Last-Modified"] = http_date(f.date.timestamp()) - response["Content-Length"] = os.path.getsize(filepath.encode("utf-8")) + response["Content-Length"] = filepath.stat().st_size response["Content-Disposition"] = ('inline; filename="%s"' % f.name).encode( "utf-8" ) diff --git a/sas/models.py b/sas/models.py index 7c1ae6e8..7330d823 100644 --- a/sas/models.py +++ b/sas/models.py @@ -13,7 +13,6 @@ # # -import os from io import BytesIO from django.conf import settings @@ -46,9 +45,7 @@ class Picture(SithFile): @property def is_vertical(self): - with open( - os.path.join(settings.MEDIA_ROOT, self.file.name).encode("utf-8"), "rb" - ) as f: + with open(settings.MEDIA_ROOT / self.file.name, "rb") as f: im = Image.open(BytesIO(f.read())) (w, h) = im.size return (w / h) < 1 @@ -112,9 +109,7 @@ class Picture(SithFile): def rotate(self, degree): for attr in ["file", "compressed", "thumbnail"]: name = self.__getattribute__(attr).name - with open( - os.path.join(settings.MEDIA_ROOT, name).encode("utf-8"), "r+b" - ) as file: + with open(settings.MEDIA_ROOT / name, "r+b") as file: if file: im = Image.open(BytesIO(file.read())) file.seek(0) diff --git a/sith/settings.py b/sith/settings.py index f68d85af..46157e79 100644 --- a/sith/settings.py +++ b/sith/settings.py @@ -46,7 +46,7 @@ from sentry_sdk.integrations.django import DjangoIntegration from .honeypot import custom_honeypot_error -BASE_DIR = Path(".").parent.parent +BASE_DIR = Path(__file__).parent.parent os.environ["HTTPS"] = "off"