port to new django, AI automated

This commit is contained in:
2026-03-30 22:35:36 +02:00
parent e2d166e437
commit 372da3caa9
215 changed files with 9283 additions and 2981 deletions

View File

@@ -1,4 +1,31 @@
from django.contrib import admin
from simpleforum.models import Message
admin.site.register(Message)
from .models import Message
@admin.register(Message)
class MessageAdmin(admin.ModelAdmin):
"""Admin configuration for Message model."""
list_display = ("titel", "author", "creation_time")
list_filter = ("creation_time", "author")
search_fields = ("titel", "text", "author__username")
date_hierarchy = "creation_time"
ordering = ("-creation_time",)
readonly_fields = ("creation_time",)
fieldsets = (
(
None,
{
"fields": ("titel", "text", "author"),
},
),
(
"Metadata",
{
"fields": ("creation_time",),
"classes": ("collapse",),
},
),
)

View File

@@ -0,0 +1,30 @@
# Generated by Django 5.1.15 on 2026-03-30 19:15
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Message',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('titel', models.CharField(max_length=100, verbose_name='titel')),
('text', models.TextField(verbose_name='text')),
('creation_time', models.DateTimeField(verbose_name='creation_time')),
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Author')),
],
options={
'ordering': ['-creation_time'],
},
),
]

View File

View File

@@ -1,12 +1,12 @@
from django.db import models
from django.utils.translation import ugettext as _
from django.contrib.auth.models import User
from django.core.mail import EmailMultiAlternatives
from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.core.mail import EmailMultiAlternatives
from django.template.loader import render_to_string
from django.utils.translation import gettext_lazy as _
from musicians.models import Musician
from django.template.loader import get_template
from django.template import Context
class Message(models.Model):
@@ -14,30 +14,41 @@ class Message(models.Model):
text = models.TextField(blank=False, verbose_name=_("text"))
creation_time = models.DateTimeField(verbose_name=_("creation_time"))
author = models.ForeignKey(User, verbose_name=_("Author"), on_delete=models.PROTECT)
def __unicode__(self):
author = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name=_("Author"))
class Meta:
ordering = ["-creation_time"]
def __str__(self):
return self.author.username + " : " + self.titel
@receiver(post_save, sender=Message)
def my_handler(sender, instance, created, **kwargs):
def send_forum_notification(sender, instance, created, **kwargs):
"""Send email notification when a new message is created."""
if not created:
return
receivers = [m.user.email for m in Musician.objects.all()]
receivers = [m.user.email for m in Musician.objects.all() if m.user.email]
if not receivers:
return
subject = "Blechreiz Forum: " + instance.titel
from_email = 'forum@blechreiz.com'
from_email = "forum@blechreiz.com"
c = {'messages': Message.objects.all().order_by('-creation_time')[:10]}
context = {"messages": Message.objects.all().order_by("-creation_time")[:10]}
text_template = get_template("simpleforum/mail.txt")
# html_template = get_template( "simpleforum/mail.html" )
text_content = text_template.render(Context(c))
# html_content = html_template.render( Context(c) )
text_content = render_to_string("simpleforum/mail.txt", context)
msg = EmailMultiAlternatives(subject, text_content, from_email, receivers)
# msg.attach_alternative( html_content, "text/html" )
msg.send()
# Uncomment to add HTML version:
# html_content = render_to_string("simpleforum/mail.html", context)
# msg.attach_alternative(html_content, "text/html")
try:
msg.send()
except Exception:
# Log the error but don't crash
pass

View File

@@ -1,152 +1,160 @@
{% extends "website/base.html" %}
{% load sekizai_tags staticfiles youtubefilter %}
{% block content %}
{% addtoblock "css" strip %}<link rel="stylesheet" href="{{STATIC_URL}}css/datepicker.css" type="text/css" media="screen" /> {% endaddtoblock %}
{% addtoblock "css" strip %} <link rel="stylesheet" href="{{STATIC_URL}}css/blogpost.css" type="text/css" media="screen" /> {% endaddtoblock %}
{% addtoblock "css" %}
{% extends "website/base.html" %} {% load sekizai_tags static youtubefilter %}
{% block content %} {% addtoblock "css" strip %}<link
rel="stylesheet"
href="{{STATIC_URL}}/css/datepicker.css"
type="text/css"
media="screen"
/>
{% endaddtoblock %} {% addtoblock "css" strip %}
<link
rel="stylesheet"
href="{{STATIC_URL}}/css/blogpost.css"
type="text/css"
media="screen"
/>
{% endaddtoblock %} {% addtoblock "css" %}
<style>
.embed-container {
position: relative;
padding-bottom: 56.25%; /* 16/9 ratio */
padding-top: 30px; /* IE6 workaround*/
height: 0;
overflow: hidden;
}
.embed-container iframe,
.embed-container object,
.embed-container embed {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.embed-container {
position: relative;
padding-bottom: 56.25%; /* 16/9 ratio */
padding-top: 30px; /* IE6 workaround*/
height: 0;
overflow: hidden;
}
.embed-container iframe,
.embed-container object,
.embed-container embed {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
</style>
{% endaddtoblock %}
{% addtoblock "js" %}
<script src="{{STATIC_URL}}js/bootstrap-datepicker.js"></script>
<script src="{{STATIC_URL}}js/bootstrap-datepicker.de.js"></script>
{% endaddtoblock %} {% addtoblock "js" %}
<script src="{{STATIC_URL}}/js/bootstrap-datepicker.js"></script>
<script src="{{STATIC_URL}}/js/bootstrap-datepicker.de.js"></script>
<script>
$(document).ready(function(){
var datepicker = $('#calendar').datepicker({
minViewMode: 1,
endDate: "{% now "SHORT_DATE_FORMAT" %}",
format: "dd.mm.yyyy",
language: "de",
$(document).ready(function(){
var datepicker = $('#calendar').datepicker({
minViewMode: 1,
endDate: "{% now "SHORT_DATE_FORMAT" %}",
format: "dd.mm.yyyy",
language: "de",
})
datepicker.on( "changeDate", function(e){
var month = e.date.getMonth() +1
window.location ="?month="+month + "&year="+ e.date.getFullYear() ;
} );
$('#new_message_form').submit( function() {
if ( $('#message_title').val() == "" ) {
alert( "Nachricht hat keinen Titel!");
return false;
}
if ( $('#message_text').val() == "" ) {
alert( "Nachricht hat keinen Text!");
return false;
}
return true;
});
datepicker.on( "changeDate", function(e){
var month = e.date.getMonth() +1
window.location ="?month="+month + "&year="+ e.date.getFullYear() ;
} );
$('#new_message_form').submit( function() {
if ( $('#message_title').val() == "" ) {
alert( "Nachricht hat keinen Titel!");
return false;
}
if ( $('#message_text').val() == "" ) {
alert( "Nachricht hat keinen Text!");
return false;
}
return true;
});
} );
} );
</script>
{% endaddtoblock %}
<div id="blog_post">
<div class="container">
{% if archiveMode %}
<h2>Forum Archiv {{month}}/{{year}}</h2>
{% else %}
<h2>Forum</h2>
{% endif %}
<div class="row">
<div class="container">
{% if archiveMode %}
<h2>Forum Archiv {{month}}/{{year}}</h2>
{% else %}
<h2>Forum</h2>
{% endif %}
<div class="span8">
<div class="comments">
{% for message in messages %}
<div class="comment">
<div class="row">
<div class="span1">
<img src="{{MEDIA_URL}}/user_images/{{message.author}}_thumb.png" class="img-circle author_pic">
</div>
<div class="span7">
<div class="name">
{{ message.titel }}
</div>
<div class="date"> {{ message.author.first_name}} am {{message.creation_time}} </div>
<div class="response">{{message.text | linebreaks | youtube }}</div>
</div>
</div>
</div>
{% endfor %}
</div>
<div class="row">
<div class="span8">
<div class="comments">
{% for message in messages %}
<div class="comment">
<div class="row">
<div class="span1">
<img
src="{{MEDIA_URL}}/user_images/{{message.author}}_thumb.png"
class="img-circle author_pic"
/>
</div>
<div class="span7">
<div class="name">{{ message.titel }}</div>
<div class="date">
{{ message.author.first_name}} am
{{message.creation_time}}
</div>
<div class="response">
{{message.text | linebreaks | youtube }}
</div>
</div>
</div>
</div>
{% endfor %}
</div>
<div class="new_comment" id="new_comment">
<h4>Neue Nachricht</h4>
<form id="new_message_form" method="post" action="" >
{% csrf_token %}
<div class="row">
<div class="span8">
<input placeholder="Titel / Betreff" id='message_title' name="titel" type="text">
</div>
</div>
<div class="row">
<div class="span8">
<textarea placeholder="Nachricht" rows="7" id='message_text' name="text"></textarea>
</div>
</div>
<div class="row">
<div class="span8">
<input value="Abschicken" class="btn send" type="submit">
</div>
</div>
</form>
</div>
</div>
<!-- SideBar -->
<div class="span3 sidebar offset1">
<div class="box" >
<h4>Archiv</h4>
<div id="calendar" {% if archiveMode %} data-date="01.{{month}}.{{year}}" {% endif %}></div>
</div>
<div class="box2">
<a href="#new_comment" >Nachricht schreiben</a><br/>
{% if archiveMode %}
<a href="." >Aktuelle Nachrichten</a>
{% endif%}
</div>
</div>
</div>
</div>
<div class="new_comment" id="new_comment">
<h4>Neue Nachricht</h4>
<form id="new_message_form" method="post" action="">
{% csrf_token %}
<div class="row">
<div class="span8">
<input
placeholder="Titel / Betreff"
id="message_title"
name="titel"
type="text"
/>
</div>
</div>
<div class="row">
<div class="span8">
<textarea
placeholder="Nachricht"
rows="7"
id="message_text"
name="text"
></textarea>
</div>
</div>
<div class="row">
<div class="span8">
<input
value="Abschicken"
class="btn send"
type="submit"
/>
</div>
</div>
</form>
</div>
</div>
<!-- SideBar -->
<div class="span3 sidebar offset1">
<div class="box">
<h4>Archiv</h4>
<div id="calendar" {% if archiveMode %}data-date="01.{{month}}.{{year}}"{% endif %}></div>
</div>
<div class="box2">
<a href="#new_comment">Nachricht schreiben</a><br />
{% if archiveMode %}
<a href=".">Aktuelle Nachrichten</a>
{% endif%}
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% endblock %}

View File

@@ -1,21 +1,36 @@
"""
Template filter for embedding YouTube videos in forum posts.
"""
import re
import django.template
from django import template
from django.template.defaultfilters import stringfilter
from django.utils.safestring import mark_safe
register = template.Library()
register = django.template.Library()
# Regex to match YouTube URLs
YOUTUBE_REGEX = re.compile(
r"(?:https://)?(?:http://)?(?:www\.)?youtube\.(?:com|de)/watch\?v=(?P<videoID>[-\w]*)"
)
youtubeRegex = re.compile( u'(?:https://)?(?:http://)?www.youtube.(?:com|de)/watch\?v=(?P<videoID>[-\w]*)' )
@register.filter( name='youtube' )
@register.filter(name="youtube")
@stringfilter
def youtube_filter( value ):
replacement = """
<div class="embed-container"><iframe src="//www.youtube.de/embed/\g<videoID>" frameborder="0" allowfullscreen></iframe> </div>
def youtube_filter(value):
"""
return mark_safe( youtubeRegex.sub( replacement, value ) )
Convert YouTube URLs in text to embedded video iframes.
Usage in template:
{{ message.text|youtube }}
"""
replacement = """
<div class="embed-container">
<iframe src="//www.youtube.com/embed/\\g<videoID>"
frameborder="0"
allowfullscreen>
</iframe>
</div>
"""
return mark_safe(YOUTUBE_REGEX.sub(replacement, value))

View File

@@ -1,34 +1,55 @@
from datetime import datetime
from django.shortcuts import render, redirect
from simpleforum.models import Message
from django.shortcuts import redirect, render
from django.utils import timezone
from .models import Message
def message_view(request):
if request.method == 'POST':
if 'titel' in request.POST and 'text' in request.POST:
titel = request.POST.get('titel')
text = request.POST.get('text')
"""View for displaying and creating forum messages."""
if len(titel) > 0 and len(text) > 0:
Message.objects.create(titel=titel, text=text, author=request.user, creation_time=datetime.now())
if request.method == "POST":
titel = request.POST.get("titel", "")
text = request.POST.get("text", "")
if titel and text:
Message.objects.create(
titel=titel,
text=text,
author=request.user,
creation_time=timezone.now(),
)
return redirect(message_view)
context = dict()
context = {}
if request.method == 'GET':
if 'month' in request.GET and 'year' in request.GET:
year = int(request.GET['year'])
month = int(request.GET['month'])
until_date = datetime(year, month + 1, 1)
from_date = datetime(year, month, 1)
context['archiveMode'] = True
context['year'] = year
context['month'] = month
context['messages'] = Message.objects.filter(creation_time__lt=until_date).filter(
creation_time__gte=from_date).order_by('-creation_time')
if request.method == "GET":
if "month" in request.GET and "year" in request.GET:
try:
year = int(request.GET["year"])
month = int(request.GET["month"])
from_date = datetime(year, month, 1)
# Handle December -> January transition
if month == 12:
until_date = datetime(year + 1, 1, 1)
else:
until_date = datetime(year, month + 1, 1)
context["archiveMode"] = True
context["year"] = year
context["month"] = month
context["messages"] = Message.objects.filter(
creation_time__lt=until_date, creation_time__gte=from_date
).order_by("-creation_time")
except (ValueError, TypeError):
# Invalid date parameters, fall back to default view
context["messages"] = Message.objects.order_by("-creation_time")[:20]
context["archiveMode"] = False
else:
context['messages'] = Message.objects.order_by('-creation_time')[:20]
context['archiveMode'] = False
context["messages"] = Message.objects.order_by("-creation_time")[:20]
context["archiveMode"] = False
return render(request, 'simpleforum/simpleforum.html', context)
return render(request, "simpleforum/simpleforum.html", context)