blog-markdown #31

Merged
PlexSheep merged 27 commits from blog-markdown into devel 2023-10-02 11:31:41 +02:00
10 changed files with 56 additions and 33 deletions
Showing only changes of commit 6d9660f44c - Show all commits

View File

@ -11,6 +11,8 @@ https://docs.djangoproject.com/en/3.2/ref/settings/
""" """
# for getting envvars # for getting envvars
import logging
from django.utils.translation import gettext_lazy as _
import os import os
# default django # default django
@ -35,7 +37,7 @@ ALLOWED_HOSTS = ["*"]
# Allow inclusion of stuff from these origins # Allow inclusion of stuff from these origins
CORS_ALLOWED_ORIGINS = [ CORS_ALLOWED_ORIGINS = [
"https://static.cscherr.de", "https://static.cscherr.de",
] ]
# Application definition # Application definition
@ -100,7 +102,6 @@ DATABASES = {
} }
# Password validation # Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators # https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
@ -123,7 +124,6 @@ AUTH_PASSWORD_VALIDATORS = [
# Internationalization # Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/ # https://docs.djangoproject.com/en/3.2/topics/i18n/
from django.utils.translation import gettext_lazy as _
LANGUAGES = [ LANGUAGES = [
("de", _("German")), ("de", _("German")),
@ -155,10 +155,10 @@ STATIC_URL = '/static/'
COMPRESS_ENABLED = True COMPRESS_ENABLED = True
STATICFILES_FINDERS = [ STATICFILES_FINDERS = [
'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder',
'compressor.finders.CompressorFinder', 'compressor.finders.CompressorFinder',
] ]
COMPRESS_PRECOMPILERS = ( COMPRESS_PRECOMPILERS = (
('text/x-scss', 'django_libsass.SassCompiler'), ('text/x-scss', 'django_libsass.SassCompiler'),
@ -173,7 +173,6 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
# Logging configs # Logging configs
import logging
myServerFormatter = ServerFormatter myServerFormatter = ServerFormatter
myServerFormatter.default_time_format = "%Y-%M-%d %H:%M:%S" myServerFormatter.default_time_format = "%Y-%M-%d %H:%M:%S"
@ -294,7 +293,7 @@ LOGGING = {
# Media stuff # Media stuff
# this is where user uploaded files will go. # this is where user uploaded files will go.
# TODO change this for prod # TODO change this for prod
#MEDIA_ROOT = "/home/plex/Documents/code/python/gawa/media" # MEDIA_ROOT = "/home/plex/Documents/code/python/gawa/media"
MEDIA_ROOT = "/app/media" MEDIA_ROOT = "/app/media"
MEDIA_URL = "/media/" MEDIA_URL = "/media/"
# FILE_UPLOAD_TEMP_DIR = "/tmp/gawa/upload" # FILE_UPLOAD_TEMP_DIR = "/tmp/gawa/upload"

View File

@ -21,7 +21,7 @@ from django.conf import settings
from django.conf.urls.static import static from django.conf.urls.static import static
urlpatterns = [ urlpatterns = [
re_path(r'^i18n/', include('django.conf.urls.i18n')), re_path(r'^i18n/', include('django.conf.urls.i18n')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += i18n_patterns( urlpatterns += i18n_patterns(

View File

@ -10,6 +10,7 @@ def regenerate(modeladmin, request, queryset):
for obj in queryset: for obj in queryset:
obj.regenerate() obj.regenerate()
@admin.register(Keyword) @admin.register(Keyword)
class KeywordAdmin(admin.ModelAdmin): class KeywordAdmin(admin.ModelAdmin):
""" """
@ -17,21 +18,25 @@ class KeywordAdmin(admin.ModelAdmin):
""" """
list_display = ["text_en", "text_de"] list_display = ["text_en", "text_de"]
@admin.register(StaticSite) @admin.register(StaticSite)
class StaticSiteAdmin(admin.ModelAdmin): class StaticSiteAdmin(admin.ModelAdmin):
""" """
Admin Interface for StaticSite Admin Interface for StaticSite
""" """
list_display = ["title_en", "subtitle_en", "title_de", "subtitle_de", "suburl"] list_display = ["title_en", "subtitle_en",
"title_de", "subtitle_de", "suburl"]
ordering = ['title_de', 'title_en'] ordering = ['title_de', 'title_en']
actions = [regenerate] actions = [regenerate]
@admin.register(Searchable) @admin.register(Searchable)
class SearchableAdmin(admin.ModelAdmin): class SearchableAdmin(admin.ModelAdmin):
""" """
Abstract Admin Interface for all Searchables Abstract Admin Interface for all Searchables
""" """
list_display = ["title_en", "subtitle_en", "title_de", "subtitle_de", "suburl"] list_display = ["title_en", "subtitle_en",
"title_de", "subtitle_de", "suburl"]
ordering = ['title_de', 'title_en'] ordering = ['title_de', 'title_en']
actions = [regenerate] actions = [regenerate]
@ -41,6 +46,7 @@ class LinkAdmin(admin.ModelAdmin):
""" """
Admin Interface for Links Admin Interface for Links
""" """
list_display = ["title_en", "title_de", "url", "suburl", "favicon", "status", "personal"] list_display = ["title_en", "title_de", "url",
"suburl", "favicon", "status", "personal"]
ordering = ['status', 'title_de', 'title_en'] ordering = ['status', 'title_de', 'title_en']
actions = [regenerate] actions = [regenerate]

View File

@ -1,5 +1,6 @@
from django.apps import AppConfig from django.apps import AppConfig
class StartConfig(AppConfig): class StartConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField' default_auto_field = 'django.db.models.BigAutoField'
name = 'start' name = 'start'

View File

@ -1,10 +1,11 @@
from django import forms from django import forms
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
class MainSearchForm(forms.Form): class MainSearchForm(forms.Form):
search = forms.CharField( search = forms.CharField(
max_length=100, max_length=100,
label='' label=''
) )
search.widget = forms.TextInput( search.widget = forms.TextInput(
attrs={ attrs={

View File

@ -15,7 +15,8 @@ class LangBasedOnUrlMiddleware(MiddlewareMixin):
def process_request(request): def process_request(request):
if hasattr(request, 'session'): if hasattr(request, 'session'):
active_session_lang = request.session.get(translation.LANGUAGE_SESSION_KEY) active_session_lang = request.session.get(
translation.LANGUAGE_SESSION_KEY)
if active_session_lang == request.LANGUAGE_CODE: if active_session_lang == request.LANGUAGE_CODE:
return return

View File

@ -1,3 +1,6 @@
import random
import favicon
import requests
from django.db import models from django.db import models
from django.db.models.options import override from django.db.models.options import override
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
@ -8,9 +11,6 @@ from django.conf import settings
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
import requests
import favicon
import random
class Keyword(models.Model): class Keyword(models.Model):
""" """
@ -26,6 +26,7 @@ class Keyword(models.Model):
verbose_name = _("Keyword") verbose_name = _("Keyword")
verbose_name_plural = _("keywords") verbose_name_plural = _("keywords")
class Searchable(models.Model): class Searchable(models.Model):
""" """
Abstract class for any model that should be searchable. Abstract class for any model that should be searchable.
@ -37,8 +38,10 @@ class Searchable(models.Model):
title_en = models.CharField(max_length=50, default="title EN") title_en = models.CharField(max_length=50, default="title EN")
subtitle_de = models.CharField(max_length=50, blank=True) subtitle_de = models.CharField(max_length=50, blank=True)
subtitle_en = models.CharField(max_length=50, blank=True) subtitle_en = models.CharField(max_length=50, blank=True)
desc_de = models.TextField(blank=True, max_length=250, unique=False, default="Beschreibung DE") desc_de = models.TextField(
desc_en = models.TextField(blank=True, max_length=250, unique=False, default="Description EN") blank=True, max_length=250, unique=False, default="Beschreibung DE")
desc_en = models.TextField(
blank=True, max_length=250, unique=False, default="Description EN")
# may be empty/blank for some entries # may be empty/blank for some entries
date = models.DateField(blank=True, null=True) date = models.DateField(blank=True, null=True)
keywords = models.ManyToManyField(Keyword) keywords = models.ManyToManyField(Keyword)
@ -61,12 +64,14 @@ class Searchable(models.Model):
""" """
regenerate a object regenerate a object
""" """
raise NotImplementedError(f"{self.__class__.__name__} does not implement regenerate") raise NotImplementedError(
f"{self.__class__.__name__} does not implement regenerate")
class Meta: class Meta:
verbose_name = _("Searchable") verbose_name = _("Searchable")
verbose_name_plural = _("Searchables") verbose_name_plural = _("Searchables")
class StaticSite(Searchable): class StaticSite(Searchable):
""" """
This model represents any static site, such as start:index, This model represents any static site, such as start:index,
@ -75,20 +80,21 @@ class StaticSite(Searchable):
Every searchable view should inherit from start.views.SearchableView. Every searchable view should inherit from start.views.SearchableView.
# TODO automate scanning for SearchableView classes # TODO automate scanning for SearchableView classes
""" """
def regenerate(self): def regenerate(self):
""" """
regenerate a object regenerate a object
""" """
logger.info(f"regenerating {self.__class__.__name__} object: {self}") logger.info(f"regenerating {self.__class__.__name__} object: {self}")
logger.warning(f"{self.__class__.__name__} cannot regenerate.") logger.warning(f"{self.__class__.__name__} cannot regenerate.")
#self.save() # self.save()
pass pass
class Meta: class Meta:
verbose_name = _("static site") verbose_name = _("static site")
verbose_name_plural = _("static sites") verbose_name_plural = _("static sites")
class Link(Searchable): class Link(Searchable):
""" """
contains all my interesting links contains all my interesting links
@ -121,11 +127,13 @@ class Link(Searchable):
icons = favicon.get(self.url, timeout=2) icons = favicon.get(self.url, timeout=2)
except (ConnectionError) as ce: except (ConnectionError) as ce:
# just keep whatever was stored if we cant get a new favicon # just keep whatever was stored if we cant get a new favicon
logger.warn(f"unable to download favicon for {self}: {ce.with_traceback(None)}") logger.warn(
f"unable to download favicon for {self}: {ce.with_traceback(None)}")
self.status = False self.status = False
except Exception as e: except Exception as e:
logger.warn(f"Unexpected Exception while downloading {self}: {e.with_traceback(None)}") logger.warn(
f"Unexpected Exception while downloading {self}: {e.with_traceback(None)}")
self.status = False self.status = False
else: else:
@ -144,9 +152,10 @@ class Link(Searchable):
except FileNotFoundError as fe: except FileNotFoundError as fe:
logger.error(f"cant write favicon to file for {self}: {fe}") logger.error(f"cant write favicon to file for {self}: {fe}")
self.favicon = None self.favicon = None
except Exception as e: except Exception as e:
logger.warn(f"Unexpected Exception while downloading {self}: {e.with_traceback(None)}") logger.warn(
f"Unexpected Exception while downloading {self}: {e.with_traceback(None)}")
self.favicon = None self.favicon = None
self.save() self.save()

View File

@ -36,4 +36,3 @@ def change_lang(context, lang="de", *args, **kwargs):
finally: finally:
activate(lang) activate(lang)
return "%s" % url return "%s" % url

View File

@ -9,5 +9,6 @@ urlpatterns = [
path("legal/", views.LegalInfo.as_view(), name="legal"), path("legal/", views.LegalInfo.as_view(), name="legal"),
path("links/", views.Links.as_view(), name="links"), path("links/", views.Links.as_view(), name="links"),
path("professional/", views.LegalInfo.as_view(), name="professional"), path("professional/", views.LegalInfo.as_view(), name="professional"),
path('language/activate/<language_code>/', views.ActivateLanguage.as_view(), name='activate_language'), path('language/activate/<language_code>/',
views.ActivateLanguage.as_view(), name='activate_language'),
] ]

View File

@ -18,6 +18,7 @@ from abc import ABC
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class SearchableView(View, ABC): class SearchableView(View, ABC):
""" """
This abstract view implements some traits of views that should show up This abstract view implements some traits of views that should show up
@ -40,6 +41,7 @@ class Index(TemplateView, SearchableView):
template_name: str = "start/index.html" template_name: str = "start/index.html"
class Professional(TemplateView, SearchableView): class Professional(TemplateView, SearchableView):
""" """
Professional informations that might interest a professional employer Professional informations that might interest a professional employer
@ -47,6 +49,7 @@ class Professional(TemplateView, SearchableView):
# TODO # TODO
template_name: str = "start/legalinfo.html" template_name: str = "start/legalinfo.html"
class LegalInfo(TemplateView, SearchableView): class LegalInfo(TemplateView, SearchableView):
""" """
Legal info that the german authorities want. Legal info that the german authorities want.
@ -54,20 +57,22 @@ class LegalInfo(TemplateView, SearchableView):
# TODO # TODO
template_name: str = "start/legalinfo.html" template_name: str = "start/legalinfo.html"
class ActivateLanguage(View): class ActivateLanguage(View):
""" """
Set the language to whatever Set the language to whatever
""" """
language_code = '' language_code = ''
redirect_to = '' redirect_to = ''
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
self.redirect_to = request.META.get('HTTP_REFERER') self.redirect_to = request.META.get('HTTP_REFERER')
self.language_code = kwargs.get('language_code') self.language_code = kwargs.get('language_code')
translation.activate(self.language_code) translation.activate(self.language_code)
request.session[translation.LANGUAGE_SESSION_KEY] = self.language_code request.session[translation.LANGUAGE_SESSION_KEY] = self.language_code
return redirect(self.redirect_to) return redirect(self.redirect_to)
class MainSearch(ListView): class MainSearch(ListView):
""" """
Search for anything. Search for anything.
@ -94,6 +99,7 @@ class MainSearch(ListView):
return render(request, "errors/bad_request.html") return render(request, "errors/bad_request.html")
return super().get(request, *args, **kwargs) return super().get(request, *args, **kwargs)
class Links(ListView): class Links(ListView):
""" """
This View contains links to various interesting sites. This View contains links to various interesting sites.
@ -115,6 +121,6 @@ class Links(ListView):
return object_list return object_list
def get_context_data(self, *, object_list=None, **kwargs): def get_context_data(self, *, object_list=None, **kwargs):
context = super().get_context_data(object_list=object_list, **kwargs) context = super().get_context_data(object_list=object_list, **kwargs)
context['personal_links'] = self.get_queryset_personal_links() context['personal_links'] = self.get_queryset_personal_links()
return context return context