Skip to content
Snippets Groups Projects
Verified Commit 0f276fb3 authored by Jonathan Weth's avatar Jonathan Weth :keyboard:
Browse files

Refactor this app to support multiple poster groups with own configuration

parent 0aca15a4
No related branches found
No related tags found
1 merge request!14Resolve "Not mensa-specific"
Pipeline #19982 passed
Showing
with 508 additions and 187 deletions
from django.contrib import admin
from .models import Poster
from .models import Poster, PosterGroup
admin.site.register(PosterGroup)
admin.site.register(Poster)
File deleted
File deleted
from django import forms
from django.core.validators import FileExtensionValidator
from django.utils import timezone
from material import Layout, Row
from .models import Poster
from .models import Poster, PosterGroup
current_year = timezone.datetime.now().year
options_for_year = [(current_year, current_year), (current_year + 1, current_year + 1)]
calendar_weeks = [(cw, str(cw)) for cw in range(1, 53)]
class PosterUploadForm(forms.ModelForm):
calendar_week = forms.ChoiceField(choices=calendar_weeks, initial=timezone.datetime.now().isocalendar()[1])
year = forms.ChoiceField(
initial=timezone.datetime.now().year, choices=options_for_year
)
pdf = forms.FileField(
validators=[FileExtensionValidator(allowed_extensions=["pdf"])],
)
class PosterGroupForm(forms.ModelForm):
"""Form to manage poster groups."""
layout = Layout(
Row("calendar_week", "year"),
Row("pdf")
Row("slug"),
Row("name"),
Row("publishing_day", "publishing_time"),
Row("default_pdf"),
Row("show_in_menu", "public"),
)
class Meta:
model = PosterGroup
fields = [
"slug",
"name",
"publishing_day",
"publishing_time",
"default_pdf",
"show_in_menu",
"public",
]
class PosterUploadForm(forms.ModelForm):
"""Form for uploading new posters."""
class Meta:
model = Poster
fields = ("calendar_week", "year", "pdf")
fields = ["group", "week", "year", "pdf"]
from typing import Any, Dict, List
from django.apps import apps
from django.urls import reverse
from django.utils.functional import lazy
from django.utils.translation import ugettext_lazy as _
def _get_menu_entries() -> List[Dict[str, Any]]:
"""Build menu entries for all poster groups.
This will include only poster groups where ``show_in_menu`` is enabled.
"""
PosterGroup = apps.get_model("resint", "PosterGroup")
return [
{
"name": group.name,
"url": reverse("poster_show_current", args=[group.slug]),
"icon": "picture_as_pdf",
"validators": ["menu_generator.validators.is_authenticated"],
}
for group in PosterGroup.objects.filter(show_in_menu=True)
]
get_menu_entries_lazy = lazy(_get_menu_entries, list)
MENUS = {
"NAV_MENU_CORE": [
{
......@@ -7,23 +32,22 @@ MENUS = {
"url": "#",
"icon": "open_in_browser",
"root": True,
"validators": [
"menu_generator.validators.is_authenticated",
],
"validators": ["menu_generator.validators.is_authenticated",],
"submenu": [
{
"name": _("Current poster"),
"url": "poster_show_current",
"icon": "picture_as_pdf",
"name": _("Manage posters"),
"url": "poster_index",
"icon": "file_upload",
"validators": ["menu_generator.validators.is_authenticated"],
},
{
"name": _("Upload poster"),
"url": "poster_index",
"icon": "file_upload",
"name": _("Poster groups"),
"url": "poster_group_list",
"icon": "topic",
"validators": ["menu_generator.validators.is_authenticated"],
},
],
]
+ get_menu_entries_lazy(),
}
]
}
# Generated by Django 3.0.4 on 2020-03-29 16:02
# Generated by Django 3.2.4 on 2021-06-30 18:23
import aleksis.apps.resint.models
import django.contrib.postgres.fields.jsonb
import calendarweek.calendarweek
import django.contrib.sites.managers
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
......@@ -10,22 +13,61 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
('sites', '0002_alter_domain_unique'),
]
operations = [
migrations.CreateModel(
name='PosterGroup',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('extended_data', models.JSONField(default=dict, editable=False)),
('slug', models.SlugField(help_text="If you use 'example', the filename will be 'example.pdf'.", verbose_name='Slug used in URL name')),
('name', models.CharField(max_length=255, verbose_name='Name')),
('publishing_day', models.PositiveSmallIntegerField(choices=[(0, 'Montag'), (1, 'Dienstag'), (2, 'Mittwoch'), (3, 'Donnerstag'), (4, 'Freitag'), (5, 'Samstag'), (6, 'Sonntag')], verbose_name='Publishing weekday')),
('publishing_time', models.TimeField(verbose_name='Publishing time')),
('default_pdf', models.FileField(help_text='This PDF file will be shown if there is no current PDF.', upload_to='default_posters/', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['pdf'])], verbose_name='Default PDF')),
('show_in_menu', models.BooleanField(default=True, verbose_name='Show in menu')),
('public', models.BooleanField(default=False, verbose_name='Show for not logged-in users')),
('site', models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.site')),
],
options={
'verbose_name': 'Poster group',
'verbose_name_plural': 'Poster groups',
},
managers=[
('objects', django.contrib.sites.managers.CurrentSiteManager()),
],
),
migrations.CreateModel(
name='Poster',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('extended_data', django.contrib.postgres.fields.jsonb.JSONField(default=dict, editable=False)),
('calendar_week', models.IntegerField(verbose_name='CW')),
('year', models.IntegerField(verbose_name='Year')),
('pdf', models.FileField(upload_to=aleksis.apps.resint.models.path_and_rename_poster, verbose_name='PDF')),
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('extended_data', models.JSONField(default=dict, editable=False)),
('week', models.PositiveSmallIntegerField(choices=[(1, '1'), (2, '2'), (3, '3'), (4, '4'), (5, '5'), (6, '6'), (7, '7'), (8, '8'), (9, '9'), (10, '10'), (11, '11'), (12, '12'), (13, '13'), (14, '14'), (15, '15'), (16, '16'), (17, '17'), (18, '18'), (19, '19'), (20, '20'), (21, '21'), (22, '22'), (23, '23'), (24, '24'), (25, '25'), (26, '26'), (27, '27'), (28, '28'), (29, '29'), (30, '30'), (31, '31'), (32, '32'), (33, '33'), (34, '34'), (35, '35'), (36, '36'), (37, '37'), (38, '38'), (39, '39'), (40, '40'), (41, '41'), (42, '42'), (43, '43'), (44, '44'), (45, '45'), (46, '46'), (47, '47'), (48, '48'), (49, '49'), (50, '50'), (51, '51'), (52, '52')], default=calendarweek.calendarweek.CalendarWeek.current_week, validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(53)], verbose_name='Calendar week')),
('year', models.PositiveSmallIntegerField(default=aleksis.apps.resint.models._get_current_year, verbose_name='Year')),
('pdf', models.FileField(upload_to='posters/', validators=[django.core.validators.FileExtensionValidator(allowed_extensions=['pdf'])], verbose_name='PDF')),
('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='posters', to='resint.postergroup', verbose_name='Poster group')),
('site', models.ForeignKey(default=1, editable=False, on_delete=django.db.models.deletion.CASCADE, to='sites.site')),
],
options={
'verbose_name': 'Poster',
'verbose_name_plural': 'Posters',
'unique_together': {('calendar_week', 'year')},
},
managers=[
('objects', django.contrib.sites.managers.CurrentSiteManager()),
],
),
migrations.AddConstraint(
model_name='postergroup',
constraint=models.UniqueConstraint(fields=('site_id', 'name'), name='unique_site_name'),
),
migrations.AddConstraint(
model_name='postergroup',
constraint=models.UniqueConstraint(fields=('site_id', 'slug'), name='unique_site_slug'),
),
migrations.AddConstraint(
model_name='poster',
constraint=models.UniqueConstraint(fields=('site_id', 'week', 'year'), name='unique_site_week_year'),
),
]
from datetime import datetime
from typing import Optional
from django.core.validators import FileExtensionValidator, MaxValueValidator, MinValueValidator
from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from calendarweek import CalendarWeek
from calendarweek.django import i18n_day_name_choices_lazy
from aleksis.core.mixins import ExtensibleModel
from aleksis.core.util.core_helpers import path_and_rename
def path_and_rename_poster(instance, filename: str) -> str:
return path_and_rename(instance, filename, upload_to="poster")
class PosterGroup(ExtensibleModel):
"""Group for time-based documents, called posters."""
slug = models.SlugField(
verbose_name=_("Slug used in URL name"),
help_text=_("If you use 'example', the filename will be 'example.pdf'."),
)
name = models.CharField(max_length=255, verbose_name=_("Name"))
publishing_day = models.PositiveSmallIntegerField(
verbose_name=_("Publishing weekday"), choices=i18n_day_name_choices_lazy()
)
publishing_time = models.TimeField(verbose_name=_("Publishing time"))
default_pdf = models.FileField(
upload_to="default_posters/",
verbose_name=_("Default PDF"),
help_text=_("This PDF file will be shown if there is no current PDF."),
validators=[FileExtensionValidator(allowed_extensions=["pdf"])],
)
show_in_menu = models.BooleanField(default=True, verbose_name=_("Show in menu"))
public = models.BooleanField(default=False, verbose_name=_("Show for not logged-in users"))
class Meta:
verbose_name = _("Poster group")
verbose_name_plural = _("Poster groups")
constraints = [
models.UniqueConstraint(fields=["site_id", "name"], name="unique_site_name"),
models.UniqueConstraint(fields=["site_id", "slug"], name="unique_site_slug"),
]
def __str__(self) -> str:
return f"{self.name} ({self.publishing_day_name}, {self.publishing_time})"
@property
def publishing_day_name(self) -> str:
"""Return the full name of the publishing day (e. g. Monday)."""
return i18n_day_name_choices_lazy()[self.publishing_day][1]
@property
def filename(self) -> str:
"""Return the filename for the currently valid PDF file."""
return f"{self.slug}.pdf"
@property
def current_poster(self) -> Optional["Poster"]:
"""Get the currently valid poster."""
# Get current date with year and calendar week
current = timezone.datetime.now()
cw = CalendarWeek.from_date(current)
# Create datetime with the friday of the week and the toggle time
day = cw[self.publishing_day]
day_and_time = timezone.datetime.combine(day, self.publishing_time)
# Check whether to show the poster of the next week or the current week
if current > day_and_time:
cw += 1
# Look for matching PDF in DB
try:
obj = self.posters.get(year=cw.year, week=cw.week)
return obj
# Or show the default PDF
except Poster.DoesNotExist:
return None
def _get_current_year() -> int:
"""Get the current year."""
return timezone.now().year
calendar_weeks = [(cw, str(cw)) for cw in range(1, 53)]
class Poster(ExtensibleModel):
calendar_week = models.IntegerField(verbose_name=_("CW"))
year = models.IntegerField(verbose_name=_("Year"))
pdf = models.FileField(upload_to=path_and_rename_poster, verbose_name=_("PDF"))
"""A time-based document."""
group = models.ForeignKey(
to=PosterGroup,
related_name="posters",
on_delete=models.CASCADE,
verbose_name=_("Poster group"),
)
week = models.PositiveSmallIntegerField(
verbose_name=_("Calendar week"),
validators=[MinValueValidator(1), MaxValueValidator(53)],
default=CalendarWeek.current_week,
choices=calendar_weeks,
)
year = models.PositiveSmallIntegerField(verbose_name=_("Year"), default=_get_current_year)
pdf = models.FileField(
upload_to="posters/",
verbose_name=_("PDF"),
validators=[FileExtensionValidator(allowed_extensions=["pdf"])],
)
class Meta:
unique_together = ("calendar_week", "year")
constraints = [
models.UniqueConstraint(
fields=["site_id", "week", "year"], name="unique_site_week_year"
)
]
verbose_name = _("Poster")
verbose_name_plural = _("Posters")
def __str__(self):
return "{} {}/{}".format(_("CW"), self.calendar_week, self.year)
def __str__(self) -> str:
return f"{self.group.name}: {self.week}/{self.year}"
@property
def valid_from(self) -> datetime:
"""Return the time this poster is valid from."""
cw = CalendarWeek(week=self.week, year=self.year) - 1
day = cw[self.group.publishing_day]
return timezone.datetime.combine(day, self.group.publishing_time)
@property
def valid_to(self) -> datetime:
"""Return the time this poster is valid to."""
cw = CalendarWeek(week=self.week, year=self.year)
day = cw[self.group.publishing_day]
return timezone.datetime.combine(day, self.group.publishing_time)
import os
from datetime import time
from django.utils.translation import gettext_lazy as _
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
CONSTANCE_CONFIG = {
"RESINT_NEW_WEEK_DAY": (4, _("Weekday at which the poster of the next week is to be shown"), "weekday_field"),
"RESINT_NEW_WEEK_TIME": (time(14, 00), _("Time at which the poster of the next week is to be shown"), time)
}
CONSTANCE_CONFIG_FIELDSETS = {
"Resint settings": ("RESINT_NEW_WEEK_DAY", "RESINT_NEW_WEEK_TIME"),
}
{% extends 'core/base.html' %}
{% load material_form i18n %}
{% block browser_title %}
{% blocktrans %}Create poster group{% endblocktrans %}
{% endblock %}
{% block page_title %}
{% blocktrans %}Create poster group{% endblocktrans %}
{% endblock %}
{% block content %}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{% form form=form %}{% endform %}
{% include "core/partials/save_button.html" %}
</form>
{% endblock %}
{% extends 'core/base.html' %}
{% load material_form i18n %}
{% block page_title %}
{% trans "Edit poster group" %}
{% endblock %}
{% block browser_title %}
{% trans "Edit poster group" %}
{% endblock %}
{% block content %}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{% form form=form %}{% endform %}
{% include "core/partials/save_button.html" %}
</form>
{% endblock %}
{% extends 'core/base.html' %}
{% load material_form i18n %}
{% block browser_title %}{% blocktrans %}Poster groups{% endblocktrans %}{% endblock %}
{% block content %}
<a class="waves-effect waves-light btn green modal-trigger right" href="{% url "create_poster_group" %}">
<i class="material-icons left">add</i>{% blocktrans %}Create new poster group{% endblocktrans %}
</a>
<h1>{% blocktrans %}Poster groups{% endblocktrans %}</h1>
<table>
<thead>
<tr>
<th>{% blocktrans %}Name{% endblocktrans %}</th>
<th>{% blocktrans %}Filename{% endblocktrans %}</th>
<th>{% blocktrans %}Publishing day{% endblocktrans %}</th>
<th>{% blocktrans %}Publishing time{% endblocktrans %}</th>
<th>{% blocktrans %}Default PDF file{% endblocktrans %}</th>
<th>{% blocktrans %}Actions{% endblocktrans %}</th>
</tr>
</thead>
<tbody>
{% for poster_group in postergroup_list %}
<tr>
<td>{{ poster_group.name }}</td>
<td>
<a href="{% url "poster_show_current" poster_group.slug %}"><code>{{ poster_group.filename }}</code></a>
</td>
<td>{{ poster_group.publishing_day_name }}</td>
<td>{{ poster_group.publishing_time }}</td>
<td>
<a href="{{ poster_group.default_pdf.url }}" class="btn-flat" target="_blank">
<i class="material-icons left">picture_as_pdf</i>
{% trans "Open" %}
</a>
</td>
<td>
<a href="{% url 'edit_poster_group' poster_group.id %}"
class="waves-effect waves-light btn-flat orange-text">
<i class="material-icons left">edit</i>
{% trans "Edit" %}
</a>
<a href="{% url 'delete_poster_group' poster_group.id %}"
class="waves-effect waves-light btn-flat red-text">
<i class="material-icons left">delete</i>
{% trans "Delete" %}
</a>
</td>
</tr>
{% empty %}
<tr>
<td colspan="4">{% blocktrans %}There are no poster groups available.{% endblocktrans %}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
{% extends "core/base.html" %}
{% load msg_box static i18n %}
{% block content %}
<a class="waves-effect waves-light btn green" href="{% url "poster_upload" %}"><i class="material-icons left">add</i>
{% trans "Upload new poster" %}
</a>
<a class="waves-effect waves-light btn orange" href="{% url "poster_show_current" %}"><i class="material-icons left">picture_as_pdf</i>
{% trans "Show current poster" %}
</a>
<h5>{% trans "All uploaded posters" %}</h5>
<ul class="collection">
{% for poster in posters %}
<li class="collection-item ">
<span class="title">{{ poster }}</span>
<p>
<a class="btn-flat waves-effect waves-green" href="{% get_media_prefix %}{{ poster.pdf }}" target="_blank">
<i class="material-icons left">picture_as_pdf</i> {% trans "Show" %}
</a>
<a class="btn-flat delete-poster waves-effect waves-red" href="{% url "poster_delete" poster.id %}">
<i class="material-icons left">delete</i> {% trans "Delete" %}
</a>
</p>
</li>
{% endfor %}
</ul>
<script type="text/javascript">
$(".delete-poster").click(function (e) {
if (!confirm("Wirklich löschen?")) {
e.preventDefault();
}
})
</script>
{% endblock %}
{% extends "core/base.html" %}
{% load static i18n %}
{% block content %}
<h1>{% trans "Posters" %}</h1>
<div class="row">
{% for group in poster_groups %}
<div class="col s12 m6 l4 xl3">
<div class="card">
<div class="card-content">
<div class="card-title">{{ group.name }}</div>
{% with current_poster=group.current_poster %}
{% if current_poster %}
<p class="margin-bottom">
<i class="material-icons left">picture_as_pdf</i>
<a href="{{ current_poster.pdf.url }}">
{% blocktrans with week=current_poster.week year=current_poster.year %}
Week {{ week }}/{{ year }}
{% endblocktrans %}
</a>
</p>
<p>
<i class="material-icons left">schedule</i>
{{ current_poster.valid_from }}–{{ current_poster.valid_to }}
</p>
{% else %}
<p>
<i class="material-icons left">picture_as_pdf</i>
{% trans "There is no poster for this week." %}
</p>
{% endif %}
{% endwith %}
</div>
<div class="card-action">
<a href="{% url "poster_show_current" group.slug %}">
{% trans "Show current PDF" %}
</a>
</div>
</div>
</div>
{% endfor %}
</div>
<a class="waves-effect waves-light btn green right" href="{% url "poster_upload" %}">
<i class="material-icons left">add</i>
{% trans "Upload new poster" %}
</a>
<h2>{% trans "All uploaded posters" %}</h2>
<table>
<thead>
<tr>
<th>{% trans "Group" %}</th>
<th>{% trans "Week" %}</th>
<th>{% trans "Valid from ... to" %}</th>
<th>{% trans "Actions" %}</th>
</tr>
</thead>
{% for poster in poster_list %}
<tr>
<td>{{ poster.group }}</td>
<td>{{ poster.week }}/{{ poster.year }}</td>
<td>{{ poster.valid_from }}–{{ poster.valid_to }}</td>
<td>
<a class="btn-flat waves-effect waves-green" href="{{ poster.pdf.url }}" target="_blank">
<i class="material-icons left">picture_as_pdf</i> {% trans "Show" %}
</a>
<a class="btn-flat red-text waves-effect waves-red" href="{% url "poster_delete" poster.id %}">
<i class="material-icons left">delete</i> {% trans "Delete" %}
</a>
</td>
</tr>
{% endfor %}
</table>
{% endblock %}
{% extends 'core/base.html' %}
{% load material_form i18n %}
{% block content %}
<h4>{% blocktrans %}Upload poster{% endblocktrans %}</h4>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{% form form=form %}{% endform %}
<button type="submit" class="waves-effect waves-light btn green">
<i class="material-icons left">save</i>{% blocktrans %}Upload poster{% endblocktrans %}
</button>
</form>
{% endblock %}
{% extends "core/base.html" %}
{% load msg_box i18n material_form %}
{% block page_title %}{% trans "Upload poster" %}{% endblock %}
{% block content %}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{% form form=form %}{% endform %}
<button class="waves-effect waves-light btn green" type="submit">
<i class="material-icons left">cloud_upload</i>
{% trans "Upload and publish poster" %}
</button>
</form>
<p>
<a href="{% url 'poster_index' %}" class="waves-effect waves-teal btn-flat">{% trans "Back to overview" %}</a>
</p>
{% endblock %}
from django.urls import path
from . import views
from .views import (
PosterCurrentView,
PosterDeleteView,
PosterGroupCreateView,
PosterGroupDeleteView,
PosterGroupEditView,
PosterGroupListView,
PosterListView,
PosterUploadView,
)
urlpatterns = [
path('', views.index, name="poster_index"),
path('upload/', views.upload, name="poster_upload"),
path('delete/<int:id>', views.delete, name="poster_delete"),
path('current.pdf', views.show_current, name="poster_show_current"),
path('<str:msg>', views.index, name="poster_index_msg"),
path("", PosterListView.as_view(), name="poster_index"),
path("upload/", PosterUploadView.as_view(), name="poster_upload"),
path("<int:pk>/delete/", PosterDeleteView.as_view(), name="poster_delete"),
path("<str:slug>.pdf", PosterCurrentView.as_view(), name="poster_show_current"),
path("groups/", PosterGroupListView.as_view(), name="poster_group_list"),
path("groups/create/", PosterGroupCreateView.as_view(), name="create_poster_group"),
path("groups/<int:pk>/edit/", PosterGroupEditView.as_view(), name="edit_poster_group"),
path("groups/<int:pk>/delete/", PosterGroupDeleteView.as_view(), name="delete_poster_group"),
]
import os
from typing import Any, Dict
from django.conf import settings
from django.contrib.auth.decorators import login_required, permission_required
from django.http import FileResponse
from django.shortcuts import get_object_or_404, redirect, render
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.db.models import QuerySet
from django.http import FileResponse, HttpRequest
from django.urls import reverse_lazy
from django.utils.translation import gettext as _
from django.views import View
from django.views.generic.detail import SingleObjectMixin
from django.views.generic.list import ListView
from calendarweek import CalendarWeek
from constance import config
from aleksis.core.mixins import AdvancedCreateView, AdvancedDeleteView, AdvancedEditView
from aleksis.core.util import messages
from .forms import PosterGroupForm, PosterUploadForm
from .models import Poster, PosterGroup
from .forms import PosterUploadForm
from .models import Poster
from .settings import BASE_DIR
class PosterGroupListView(ListView):
"""Show a list of all poster groups."""
@login_required
@permission_required("resint.add_poster")
def upload(request):
if request.method == 'POST':
form = PosterUploadForm(request.POST, request.FILES)
if form.is_valid():
form.save()
template_name = "resint/group/list.html"
model = PosterGroup
messages.success(request, _("The poster was uploaded successfully."))
return redirect('poster_index')
else:
form = PosterUploadForm()
return render(request, 'resint/upload.html', {
'form': form
})
class PosterGroupCreateView(AdvancedCreateView):
"""Create a new poster group."""
@login_required
@permission_required("resint.add_poster")
def delete(request, id):
poster = get_object_or_404(Poster, pk=id)
poster.delete()
model = PosterGroup
success_url = reverse_lazy("poster_group_list")
template_name = "resint/group/create.html"
success_message = _("The poster group has been saved.")
form_class = PosterGroupForm
messages.success(request, _("The poster was deleted successfully."))
return redirect("poster_index")
class PosterGroupEditView(AdvancedEditView):
"""Edit an existing poster group."""
@login_required
@permission_required("poster.add_poster")
def index(request):
posters = Poster.objects.all().order_by("calendar_week", "year")
return render(request, 'resint/index.html', {"posters": posters})
model = PosterGroup
success_url = reverse_lazy("poster_group_list")
template_name = "resint/group/edit.html"
success_message = _("The poster group has been saved.")
form_class = PosterGroupForm
def return_pdf(filename):
"""Read and response a PDF file"""
class PosterGroupDeleteView(AdvancedDeleteView):
"""Delete a poster group."""
file = open(filename, "rb")
return FileResponse(file, content_type="application/pdf")
model = PosterGroup
success_url = reverse_lazy("poster_group_list")
success_message = _("The poster group has been deleted.")
template_name = "core/pages/delete.html"
def return_default_pdf():
"""Response the default PDF"""
class PosterListView(ListView):
"""Show a list of all uploaded posters."""
return return_pdf(os.path.join(BASE_DIR, "default.pdf"))
template_name = "resint/poster/list.html"
model = Poster
def get_queryset(self) -> QuerySet:
return Poster.objects.all().order_by("-year", "-week")
def show_current(request):
# Get current date with year and calendar week
current_date = timezone.datetime.now()
cw = CalendarWeek.from_date(current_date)
def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
context = super().get_context_data(**kwargs)
context["poster_groups"] = PosterGroup.objects.all().order_by("name")
return context
# Create datetime with the friday of the week and the toggle time
friday = cw[int(config.RESINT_NEW_WEEK_DAY)]
friday = timezone.datetime.combine(friday, config.RESINT_NEW_WEEK_TIME)
# Check whether to show the poster of the next week or the current week
if current_date > friday:
cw += 1
class PosterUploadView(AdvancedCreateView):
"""Upload a new poster."""
# Look for matching PDF in DB
try:
obj = Poster.objects.get(year=cw.year, calendar_week=cw.week)
return return_pdf(os.path.join(settings.MEDIA_ROOT, str(obj.pdf)))
model = Poster
success_url = reverse_lazy("poster_index")
template_name = "resint/poster/upload.html"
success_message = _("The poster has been uploaded.")
form_class = PosterUploadForm
# Or show the default PDF
except Poster.DoesNotExist:
return return_default_pdf()
class PosterDeleteView(AdvancedDeleteView):
"""Delete an uploaded poster."""
model = Poster
success_url = reverse_lazy("poster_index")
success_message = _("The poster has been deleted.")
template_name = "core/pages/delete.html"
class PosterCurrentView(SingleObjectMixin, View):
"""Show the poster which is currently valid."""
model = PosterGroup
def get(self, request: HttpRequest, *args: Any, **kwargs: Any) -> FileResponse:
group = self.get_object()
current_poster = group.current_poster
file = current_poster.pdf if current_poster else group.default_pdf
return FileResponse(file, content_type="application/pdf")
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment