Changement de présentation (en cours) après discussion avec Alice

This commit is contained in:
Jean-Marie Favreau 2023-11-06 00:38:58 +01:00
parent be1fbe703d
commit 713e287210
13 changed files with 647 additions and 116 deletions

View File

@ -86,6 +86,9 @@ class Event(models.Model):
tags = ArrayField(models.CharField(max_length=64), verbose_name=_('Tags'), help_text=_("A list of tags that describe the event."), blank=True, null=True)
def single_day(self):
return not self.end_day or self.end_day == self.start_day
def get_absolute_url(self):
return reverse("view_event", kwargs={"pk": self.pk, "extra": self.title})

View File

@ -0,0 +1,76 @@
const isOpenClass = "modal-is-open";
const openingClass = "modal-is-opening";
const closingClass = "modal-is-closing";
let visibleModal = null;
// Toggle modal
const toggleModal = (event) => {
event.preventDefault();
const modal = document.getElementById(event.currentTarget.getAttribute("data-target"));
typeof modal != "undefined" && modal != null && isModalOpen(modal)
? closeModal(modal)
: openModal(modal);
};
// Is modal open
const isModalOpen = (modal) => {
return modal.hasAttribute("open") && modal.getAttribute("open") != "false" ? true : false;
};
// Open modal
const openModal = (modal) => {
if (isScrollbarVisible()) {
document.documentElement.style.setProperty("--scrollbar-width", `${getScrollbarWidth()}px`);
}
modal.setAttribute("open", true);
};
// Close modal
const closeModal = (modal) => {
visibleModal = null;
document.documentElement.style.removeProperty("--scrollbar-width");
modal.removeAttribute("open");
};
// Close with a click outside
document.addEventListener("click", (event) => {
if (visibleModal != null) {
const modalContent = visibleModal.querySelector("article");
const isClickInside = modalContent.contains(event.target);
!isClickInside && closeModal(visibleModal);
}
});
// Close with Esc key
document.addEventListener("keydown", (event) => {
if (event.key === "Escape" && visibleModal != null) {
closeModal(visibleModal);
}
});
// Get scrollbar width
const getScrollbarWidth = () => {
// Creating invisible container
const outer = document.createElement("div");
outer.style.visibility = "hidden";
outer.style.overflow = "scroll"; // forcing scrollbar to appear
outer.style.msOverflowStyle = "scrollbar"; // needed for WinJS apps
document.body.appendChild(outer);
// Creating inner element and placing it in the container
const inner = document.createElement("div");
outer.appendChild(inner);
// Calculating difference between container's full width and the child width
const scrollbarWidth = outer.offsetWidth - inner.offsetWidth;
// Removing temporary elements from the DOM
outer.parentNode.removeChild(outer);
return scrollbarWidth;
};
// Is scrollbar visible
const isScrollbarVisible = () => {
return document.body.scrollHeight > screen.height;
};

View File

@ -160,4 +160,26 @@ footer {
.infos-and-buttons .buttons {
flex: auto;
}
article.day {
margin: 0;
padding: 0.3em;
}
article.day>ul {
margin: 0;
padding: 0;
>li {
list-style: none;
}
}
.right {
text-align: right;
}
.navigation {
margin: 1em 0;
}

View File

@ -0,0 +1,66 @@
{% load cat_extra %}
{% load static %}
{% with day.date|date:"Y-m-d" as daytag %}
{% with "date-"|add:daytag as daytag %}
<article class="day" id="{{ daytag }}">
<h2><a href="{% url 'day_view' day.date.year day.date.month day.date.day %}">{{ day.date | date:"l j" }}</a></h2>
{% if day.events %}
{% if resume %}
<ul>
{% for category, events in day.events_by_category.items %}
<li>{{ events.0.category | circle_cat }}
<a href="{{ daytag }}" data-target="{{ daytag }}-category-{{ category.id }}" onClick="toggleModal(event)">{{ events | length }} {{ category }}</a></li>
<dialog id="{{ daytag }}-category-{{ category.id }}">
<article>
<header>
<a href="#{{ daytag }}-category-{{ category.id }}"
aria-label="Fermer"
class="close"
data-target="{{ daytag }}-category-{{ category.id }}"
onClick="toggleModal(event)"></a>
<h3>{{ events.0.category | small_cat }} du {{ day.date | date:"l j F" }}</h3>
</header>
<ul>
{% for event in events %}
<li>
{% if event.single_day and event.start_time %}
{{ event.start_time }}
{% endif %}
<a href="{{ event.get_absolute_url }}">{{ event.title }}</a>
</li>
{% endfor %}
</ul>
<footer>
<div class="buttons">
<a href="{% url 'day_view' day.date.year day.date.month day.date.day %}" role="button">Voir la journée <svg width="1em" height="1em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<use href="{% static 'images/feather-sprite.svg' %}#chevron-right" />
</svg></a>
</div>
</footer>
</article>
</dialog>
{% endfor %}
<ul>
{% else %}
{% for event in day.events %}
<li>{{ event.category | circle_cat }}
{% if event.single_day and event.start_time %}
{{ event.start_time }}
{% endif %}
<a href="{{ daytag }}" data-target="event-{{ event.id }}" onClick="toggleModal(event)">{{ event.title }}</a>
<dialog id="event-{{ event.id }}">
{% include "agenda_culturel/event-inc.html" with event=event display="modal" close_button=1 %}
</dialog>
</li>
{% endfor %}
</ul>
{% endif %}
{% endif %}
</ul>
</article>
{% endwith %}
{% endwith %}

View File

@ -45,83 +45,120 @@
{% include "agenda_culturel/date-times-inc.html" with event=event %}
</em></p>
{% endif %}
{% elif display == "modal" %}
<header>
<a href="#event-{{ event.id }}"
aria-label="Fermer"
class="close"
data-target="event-{{ event.id }}"
onClick="toggleModal(event)"></a>
<h3>{{ event.category | small_cat }} {{ event.title }}</h3>
<p>
<svg width="1em" height="1em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<use href="{% static 'images/feather-sprite.svg' %}#map-pin" />
</svg>
{{ event.location }}
</p>
<p><svg width="1em" height="1em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<use href="{% static 'images/feather-sprite.svg' %}#calendar" />
</svg>
{% if event.end_day %}du{% else %}le{% endif %}
{% include "agenda_culturel/date-times-inc.html" with event=event %}
</p>
</header>
{% else %}
<header>
{% include "agenda_culturel/ephemeris-inc.html" with event=event %}
<h1>{{ event.title }}</h1>
<p>
<svg width="1em" height="1em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<use href="{% static 'images/feather-sprite.svg' %}#map-pin" />
</svg>
{{ event.location }}
</p>
<p><svg width="1em" height="1em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<use href="{% static 'images/feather-sprite.svg' %}#calendar" />
</svg>
{% if event.end_day %}du{% else %}le{% endif %}
{% include "agenda_culturel/date-times-inc.html" with event=event %}
</p>
<p>
<svg width="1em" height="1em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<use href="{% static 'images/feather-sprite.svg' %}#map-pin" />
</svg>
{{ event.location }}
</p>
</header>
{% endif %}
{% if event.image %}
{% if event.image and display != "modal" %}
<article class='illustration{% if display in "in list by day" %}-small{% endif %}'>
<img src="{{ event.image }}" alt="{{ event.image_alt }}" />
</article>
{% endif %}
{% if display in "in list by day" %}
{% if display in "in list by day" or display == "modal" %}
<p>{{ event.description |truncatewords:20 }}</p>
{% else %}
<p>{{ event.description }}</p>
{% endif %}
{% comment %}
On affiche le pied qui contient les informations de tags, catégories, etc
{% endcomment %}
<footer class="infos-and-buttons">
<div class="infos">
<p>
{% if mode %}
{% if category %}
{{ event.category | small_cat }}
{% else %}
{% url 'view_mode_cat' selected_mode.name event.category.pk as url_cat %}
{{ event.category | small_cat:url_cat }}
{% endif %}
{% else %}
{{ event.category | small_cat }}
{% endif %}
</p>
<p>
{% for tag in event.tags %}
<a href="{% url 'view_tag' tag %}" role="button" class="small-cat">{{ tag }}</a>
{% endfor %}
</p>
{% if event.reference_urls %}
{% if display in "in list by day" %}
<p>Source{{ event.reference_urls|pluralize }}&nbsp;:
{% else %}
<p>Cet événement est proposé par&nbsp;:
{% endif %}
{% for eurl in event.reference_urls %}
<a href="{{ eurl }}">{{ eurl|hostname }}</a>{% if not forloop.last %}, {% endif %}
{% if display == "modal" %}
<p>
{% for tag in event.tags %}
<a href="{% url 'view_tag' tag %}" role="button" class="small-cat">{{ tag }}</a>
{% endfor %}
</p>
{% else %}
<p><em>Cet événement est disponible uniquement sur les nuits énimagmatiques.</em></p>
{% endif %}
</div>
{% if user.is_authenticated %}
<div class="buttons">
<a href="{% url 'edit_event' event.id %}" role="button">éditer</a>
<a href="{% url 'delete_event' event.id %}" role="button">supprimer</a>
</div>
{% endif %}
</p>
<footer class="infos-and-buttons">
<div class="buttons">
<a href="{{ event.get_absolute_url }}" role="button">Voir l'événement <svg width="1em" height="1em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<use href="{% static 'images/feather-sprite.svg' %}#chevron-right" />
</svg></a>
</div>
</footer>
{% else %}
<footer class="infos-and-buttons">
<div class="infos">
<p>
{% if mode %}
{% if category %}
{{ event.category | small_cat }}
{% else %}
{% url 'view_mode_cat' selected_mode.name event.category.pk as url_cat %}
{{ event.category | small_cat:url_cat }}
{% endif %}
{% else %}
{{ event.category | small_cat }}
{% endif %}
</p>
<p>
{% for tag in event.tags %}
<a href="{% url 'view_tag' tag %}" role="button" class="small-cat">{{ tag }}</a>
{% endfor %}
</p>
{% if event.reference_urls %}
{% if display in "in list by day" %}
<p>Source{{ event.reference_urls|pluralize }}&nbsp;:
{% else %}
<p>Cet événement est proposé par&nbsp;:
{% endif %}
{% for eurl in event.reference_urls %}
<a href="{{ eurl }}">{{ eurl|hostname }}</a>{% if not forloop.last %}, {% endif %}
{% endfor %}
</p>
{% else %}
<p><em>Cet événement est disponible uniquement sur les nuits énimagmatiques.</em></p>
{% endif %}
</div>
{% if user.is_authenticated %}
<div class="buttons">
<a href="{% url 'edit_event' event.id %}" role="button">éditer</a>
<a href="{% url 'delete_event' event.id %}" role="button">supprimer</a>
</div>
{% endif %}
</footer>
{% endif %}
</article>

View File

@ -0,0 +1,66 @@
{% extends "agenda_culturel/page.html" %}
{% load i18n %}
{% load cat_extra %}
{% load event_extra %}
{% load utils_extra %}
{% load static %}
{% block entete_header %}
{% css_categories %}
{% endblock %}
{% block title %}
Événements du {{ date | date:"l j F" }}
{% endblock %}
{% block content %}
<h1>Les événements du {{ day | date:"l j F" }}</h1>
<article>
<div class="grid navigation">
<div>
{% with day|shift_day:-1 as pred_day %}
<a role="button" href="{% url 'day_view' pred_day.year pred_day.month pred_day.day %}"><svg width="1em" height="1em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<use href="{% static 'images/feather-sprite.svg' %}#chevron-left" />
</svg> Jour précédent</a>
{% endwith %}
</div>
<div class="right">
{% with day|shift_day:1 as next_day %}
<a role="button" href="{% url 'day_view' next_day.year next_day.month next_day.day %}">Jour suivant <svg width="1em" height="1em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<use href="{% static 'images/feather-sprite.svg' %}#chevron-right" />
</svg></a>
{% endwith %}
</div>
</div>
</article>
{% if events %}
{% for event in events %}
{% include "agenda_culturel/event-inc.html" with event=event display="in list by day" %}
{% endfor %}
{% else %}
<article>
Il n'y a pas d'événement prévu à cette date.
</article>
{% endif %}
<article>
<p>Voir aussi tous les événements
<a href="{% url 'week_view' day.year day|week %}">de la semaine
du {{ day|first_day_of_this_week }}
au {{ day|last_day_of_this_week }}</a>.</p>
</article>
{% endblock %}

View File

@ -0,0 +1,56 @@
{% extends "agenda_culturel/page.html" %}
{% load i18n %}
{% load cat_extra %}
{% load event_extra %}
{% load utils_extra %}
{% load static %}
{% block entete_header %}
{% css_categories %}
<script src="{% static 'js/modal.js' %}"></script>
{% endblock %}
{% block title %}
Événements {{ calendar.firstdate | date:"F o"|add_de }}
{% endblock %}
{% block main-fluid %}-fluid{% endblock %}
{% block footer-fluid %}-fluid{% endblock %}
{% block content %}
<h1>Événements de {{ calendar.firstdate | date:"F o" }}</h1>
<article>
<header>
<div class="grid navigation">
<div>
<a role="button" href="{% url 'month_view' calendar.previous_month.year calendar.previous_month.month %}"><svg width="1em" height="1em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<use href="{% static 'images/feather-sprite.svg' %}#chevron-left" />
</svg> Mois précédent</a>
</div>
<div class="right">
<a role="button" href="{% url 'month_view' calendar.next_month.year calendar.next_month.month %}">Mois suivant <svg width="1em" height="1em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<use href="{% static 'images/feather-sprite.svg' %}#chevron-right" />
</svg></a>
</div>
</div>
</header>
<div id="calendar">
<div class="grid">
{% for d in calendar.calendar_days_list %}
{% if forloop.counter0|divisibleby:7 and not forloop.first %}</div><div class="grid">{% endif %}
{% include "agenda_culturel/day-inc.html" with day=d resume=1 %}
{% endfor %}
</div>
</div>
</article>
{% endblock %}

View File

@ -0,0 +1,65 @@
{% extends "agenda_culturel/page.html" %}
{% load i18n %}
{% load cat_extra %}
{% load event_extra %}
{% load utils_extra %}
{% load static %}
{% block entete_header %}
{% css_categories %}
<script src="{% static 'js/modal.js' %}"></script>
{% endblock %}
{% block title %}
Événements de la semaine {{ week }} - {{ year }}
{% endblock %}
{% block main-fluid %}-fluid{% endblock %}
{% block footer-fluid %}-fluid{% endblock %}
{% block content %}
<hgroup>
<h1>Les événements de la semaine {{ week }}</h1>
<h2>Du {{ calendar.calendar_days_list.0.date }} au {{ calendar.calendar_days_list.6.date }} </h2>
</hgroup>
<article>
<header>
<div class="grid navigation">
<div>
<a role="button" href="{% url 'week_view' calendar.previous_week.year calendar.previous_week|week %}"><svg width="1em" height="1em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<use href="{% static 'images/feather-sprite.svg' %}#chevron-left" />
</svg> Semaine précédente</a>
</div>
<div class="right">
<a role="button" href="{% url 'week_view' calendar.next_week.year calendar.next_week|week %}">Semaine suivante <svg width="1em" height="1em" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<use href="{% static 'images/feather-sprite.svg' %}#chevron-right" />
</svg></a>
</div>
</div>
</header>
<div class="grid" id="calendar">
{% for d in calendar.calendar_days_list %}
{% include "agenda_culturel/day-inc.html" with day=d %}
{% endfor %}
</div>
<footer>
<p>Voir aussi tous les événements du mois de
<a href="{% url 'month_view' calendar.firstdate.year calendar.firstdate.month %}">{{ calendar.firstdate | date:"F o" }}</a>{% if calendar.firstdate.month != calendar.lastdate.month %}
ou tous les événements du mois de <a href="{% url 'month_view' calendar.lastdate.year calendar.lastdate.month %}">{{ calendar.lastdate | date:"F o" }}</a>
{% endif %}.</p>
</footer>
</article>
{% endblock %}

View File

@ -27,15 +27,26 @@
<nav class="container-fluid">
<ul>
<li>
<a href="/" aria-label="Retour accueil">
<a href="{% url 'home' %}" aria-label="Retour accueil">
<img src="{% static 'images/favicon.svg' %}" />
</a>
</li>
<li>
Les nuits énigmagmatiques
<a href="{% url 'home' %}" aria-label="Retour accueil">Les nuits énimagmatiques</a>
</li>
</ul>
<ul>
<li>
<details role="list" dir="rtl">
<summary aria-haspopup="listbox" role="link">Dates</summary>
<ul role="listbox">
<li><a href="{% url 'aujourdhui' %}">Aujourd'hui</a></li>
<li><a href="{% url 'cette_semaine' %}">Cette semaine</a></li>
<li><a href="{% url 'ce_mois_ci' %}">Ce mois-ci</a></li>
</ul>
</details>
</li>
<li>
<details role="list" dir="rtl">
<summary aria-haspopup="listbox" role="link">Événements</summary>
@ -51,11 +62,11 @@
</li>
</ul>
</nav>
<main class="container">
<main class="container{% block main-fluid %}{% endblock %}">
{% block content %}{% endblock %}
</main>
<footer class="container">
<footer class="container{% block footer-fluid %}{% endblock %}">
<div class="grid">
<ul>
<li><a href="{% url 'view_all_tags' %}">Toutes les étiquettes</a></li>

View File

@ -64,12 +64,11 @@ def css_categories():
for c in cats:
result += "a ." + c.css_class() + ","
result += "span ." + c.css_class() + " {"
result += "." + c.css_class() + " {"
result += background_color_adjust_color(adjust_lightness_saturation(c.color, .2, 0.8), 0.8)
result += "}"
result += "a:hover ." + c.css_class() + " {"
result += "*:hover ." + c.css_class() + " {"
result += background_color_adjust_color(adjust_lightness_saturation(c.color, 0.02, 1.0))
result += "}"
@ -91,4 +90,8 @@ def small_cat(category, url=None, contrast=True):
if url is None:
return mark_safe('<span class="small-cat' + class_contrast +' selected" role="button"><span class="cat ' + category.css_class() + '"></span> ' + category.name + "</span>")
else:
return mark_safe('<a class="small-cat' + class_contrast +' selected" role="button" href="' + url + '"><span class="cat ' + category.css_class() + '"></span> ' + category.name + "</a>")
return mark_safe('<a class="small-cat' + class_contrast +' selected" role="button" href="' + url + '"><span class="cat ' + category.css_class() + '"></span> ' + category.name + "</a>")
@register.filter
def circle_cat(category):
return mark_safe('<span class="cat ' + category.css_class() + '" data-tooltip="' + category.name + '"></span>')

View File

@ -2,6 +2,7 @@ from django import template
from django.utils.safestring import mark_safe
from urllib.parse import urlparse
from datetime import timedelta, date
register = template.Library()
@ -9,4 +10,25 @@ register = template.Library()
@register.filter
def hostname(url):
obj = urlparse(url)
return mark_safe(obj.hostname)
return mark_safe(obj.hostname)
@register.filter
def add_de(txt):
return ("d'" if txt[0].lower() in ['a', 'e', 'i', 'o', 'u', 'y'] else "de ") + txt
@register.filter
def week(d):
return d.isocalendar()[1]
@register.filter
def shift_day(d, shift):
return d + timedelta(days=shift)
@register.filter
def first_day_of_this_week(d):
return date.fromisocalendar(d.year, week(d), 1)
@register.filter
def last_day_of_this_week(d):
return date.fromisocalendar(d.year, week(d), 7)

View File

@ -7,12 +7,14 @@ from django.contrib.auth import views as auth_views
from .views import *
modes = '|'.join([dm.name for dm in DisplayMode])
urlpatterns = [
path("", home, name="home"),
re_path(r'^(?P<mode>' + modes + ')/$', view_mode, name='view_mode'),
re_path(r'^(?P<mode>' + modes + ')/(?P<cat_id>\d+)/$', view_mode_cat, name='view_mode_cat'),
path("semaine/<int:year>/<int:week>/", week_view, name='week_view'),
path("mois/<int:year>/<int:month>/", month_view, name='month_view'),
path("jour/<int:year>/<int:month>/<int:day>/", day_view, name='day_view'),
path("aujourdhui/", day_view, name="aujourdhui"),
path("cette-semaine/", week_view, name="cette_semaine"),
path("ce-mois-ci", month_view, name="ce_mois_ci"),
path("tag/<t>/", view_tag, name='view_tag'),
path("tags/", tag_list, name='view_all_tags'),
path("events/", event_list, name='view_all_events'),

View File

@ -9,7 +9,8 @@ from .celery import create_event_from_submission
from .models import Event, Category
from django.utils import timezone
from enum import StrEnum
from datetime import datetime, timedelta
from datetime import datetime, timedelta, date
import calendar
from django.db.models import Q
from django.urls import reverse_lazy
@ -22,66 +23,167 @@ from django.contrib.auth.decorators import login_required
import unicodedata
class DisplayMode(StrEnum):
this_week = "this week"
this_weekend = "this weekend"
next_week = "next week"
next_weekend = "next weekend"
this_month = "this month"
next_month = "next month"
def daterange(start, end, step=timedelta(1)):
if end is None:
yield start
else:
curr = start
while curr <= end:
yield curr
curr += step
def i18n_value(self):
return _(self.value)
def get_dates(self):
now = datetime.now()
if self in [DisplayMode.this_week, DisplayMode.next_week]:
day = now.weekday() # 0: Monday, 6: Sunday
start = now + timedelta(days=-day)
if self == DisplayMode.next_week:
start += timedelta(days=7)
return [start + timedelta(days=x) for x in range(0, 7)]
elif self in [DisplayMode.this_weekend, DisplayMode.next_weekend]:
day = now.weekday() # 0: Monday, 6: Sunday
start = now + timedelta(days=-day + 5)
if self == DisplayMode.next_week:
start += timedelta(days=7)
return [start + timedelta(days=x) for x in range(0, 2)]
elif self in [DisplayMode.this_month, DisplayMode.next_month]:
start = now.replace(day=1)
if self == DisplayMode.next_month:
start = (start.replace(day=1) + timedelta(days=32)).replace(day=1)
next_month = start.replace(day=28) + timedelta(days=4)
end = next_month - timedelta(days=next_month.day)
delta = end - start
return [start + timedelta(days=x) for x in range(0, delta.days + 1)]
class CalendarDay:
def __str__(self):
return str(self.i18n_value())
def __init__(self, d, on_requested_interval = True):
self.date = d
now = date.today()
self.in_past = d < now
self.events = []
self.events_by_category = {}
def is_in_past(self):
return in_past
def add_event(self, event):
self.events.append(event)
if not event.category.name in self.events_by_category:
self.events_by_category[event.category.name] = []
self.events_by_category[event.category.name].append(event)
class CalendarList:
def __init__(self, firstdate, lastdate):
self.firstdate = firstdate
self.lastdate = lastdate
# start the first day of the first week
self.c_firstdate = firstdate + timedelta(days=-firstdate.weekday())
# end the last day of the last week
self.c_lastdate = lastdate + timedelta(days=6-lastdate.weekday())
# create a list of CalendarDays
self.create_calendar_days()
# fill CalendarDays with events
self.fill_calendar_days()
def fill_calendar_days(self):
self.events = Event.objects.filter(start_day__lte=self.c_lastdate, start_day__gte=self.c_firstdate).order_by("start_day", "start_time")
for e in self.events:
for d in daterange(e.start_day, e.end_day):
if d.__str__() in self.calendar_days:
self.calendar_days[d.__str__()].add_event(e)
def create_calendar_days(self):
# create daylist
self.calendar_days = {}
for d in daterange(self.c_firstdate, self.c_lastdate):
self.calendar_days[d.strftime("%Y-%m-%d")] = CalendarDay(d, d >= self.firstdate and d <= self.lastdate)
def is_single_week(self):
return hasattr(self, "week")
def is_full_month(self):
return hasattr(self, "month")
def calendar_days_list(self):
return list(self.calendar_days.values())
class CalendarMonth(CalendarList):
def __init__(self, year, month):
self.year = year
self.month = month
r = calendar.monthrange(year, month)
first = date(year, month, r[0])
last = date(year, month, r[1])
super().__init__(first, last)
def get_month_name(self):
return self.firstdate.strftime("%B")
def next_month(self):
return self.lastdate + timedelta(days=7)
def previous_month(self):
return self.firstdate + timedelta(days=-7)
class CalendarWeek(CalendarList):
def __init__(self, year, week):
self.year = year
self.week = week
first = date.fromisocalendar(self.year, self.week, 1)
last = date.fromisocalendar(self.year, self.week, 7)
super().__init__(first, last)
def next_week(self):
return self.firstdate + timedelta(days=7)
def previous_week(self):
return self.firstdate + timedelta(days=-7)
def home(request):
# TODO: si on est au début de la semaine, on affiche la semaine en entier
# sinon, on affiche le week-end
# sauf si on est dimanche après 23h, on affiche la semaine prochaine
return view_mode(request, DisplayMode.this_week.name)
return week_view(request)
#return month_view(request, now.year, now.month)
def month_view(request, year = None, month = None):
# TODO: filter by category, tag
now = date.today()
if year == None:
year = now.year
if month == None:
month = now.month
cmonth = CalendarMonth(year, month)
context = {"year": year, "month": cmonth.get_month_name(), "calendar": cmonth }
return render(request, 'agenda_culturel/page-month.html', context)
def view_mode(request, mode):
categories = Category.objects.all()
dates = DisplayMode[mode].get_dates()
events = Event.objects.filter(Q(start_day__lte=dates[-1]) & Q(start_day__gte=dates[0])).order_by("start_day", "start_time")
context = {"modes": list(DisplayMode), "selected_mode": DisplayMode[mode], "categories": categories, "events": events, "dates": dates}
return render(request, 'agenda_culturel/page-events.html', context)
def week_view(request, year = None, week = None):
now = date.today()
if year == None:
year = now.year
if week == None:
week = now.isocalendar()[1]
cweek = CalendarWeek(year, week)
context = {"year": year, "week": week, "calendar": cweek }
return render(request, 'agenda_culturel/page-week.html', context)
def view_mode_cat(request, mode, cat_id):
category = get_object_or_404(Category, pk=cat_id)
categories = Category.objects.all()
dates = DisplayMode[mode].get_dates()
events = Event.objects.filter(start_day__lte=dates[-1], start_day__gte=dates[0], category=category).order_by("start_day", "start_time")
context = {"modes": list(DisplayMode), "selected_mode": DisplayMode[mode], "category": category, "categories": categories, "events": events, "dates": dates}
return render(request, 'agenda_culturel/page-events.html', context)
def day_view(request, year = None, month = None, day = None):
now = date.today()
if year == None:
year = now.year
if month == None:
month = now.month
if day == None:
day = now.day
day = date(year, month, day)
events = Event.objects.filter(start_day__lte=day, start_day__gte=day).order_by("start_day", "start_time")
# TODO
context = {"day": day, "events": events}
return render(request, 'agenda_culturel/page-day.html', context)
def view_tag(request, t):