Remote calendar link for external sync

This commit is contained in:
Antoine Bartuccio 2025-04-07 13:58:08 +02:00
parent 811c83552f
commit b09d5e5ffd
5 changed files with 70 additions and 6 deletions

View File

@ -1,9 +1,11 @@
from pathlib import Path
from typing import final
from dateutil.relativedelta import relativedelta
from django.conf import settings
from django.contrib.sites.models import Site
from django.contrib.syndication.views import add_domain
from django.db.models import F, QuerySet
from django.http import HttpRequest
from django.urls import reverse
from django.utils import timezone
from ical.calendar import Calendar
@ -14,7 +16,14 @@ from com.models import NewsDate
from core.models import User
@final
def as_absolute_url(url: str, request: HttpRequest | None = None) -> str:
return add_domain(
Site.objects.get_current(request=request),
url,
secure=request.is_secure() if request is not None else settings.HTTPS,
)
class IcsCalendar:
_CACHE_FOLDER: Path = settings.MEDIA_ROOT / "com" / "calendars"
_INTERNAL_CALENDAR = _CACHE_FOLDER / "internal.ics"
@ -58,7 +67,9 @@ class IcsCalendar:
summary=news_date.news_title,
start=news_date.start_date,
end=news_date.end_date,
url=reverse("com:news_detail", kwargs={"news_id": news_date.news.id}),
url=as_absolute_url(
reverse("com:news_detail", kwargs={"news_id": news_date.news.id})
),
)
calendar.events.append(event)

View File

@ -303,10 +303,36 @@ export class IcsCalendar extends inheritHtmlElement("div") {
this.calendar = new Calendar(this.node, {
plugins: [dayGridPlugin, iCalendarPlugin, listPlugin],
locales: [frLocale, enLocale],
customButtons: {
getCalendarLink: {
text: gettext("Copy calendar link"),
click: async (event: Event) => {
const button = event.target as HTMLButtonElement;
button.classList.add("text-copy");
button.setAttribute(
"tooltip",
gettext("Calendar link copied to the clipboard"),
);
navigator.clipboard.writeText(
new URL(
await makeUrl(calendarCalendarInternal),
window.location.origin,
).toString(),
);
setTimeout(() => {
button.classList.remove("text-copied");
button.classList.add("text-copied");
button.classList.remove("text-copy");
button.removeAttribute("tooltip");
}, 700);
},
},
},
height: "auto",
locale: this.locale,
initialView: this.currentView(),
headerToolbar: this.currentToolbar(),
footerToolbar: { start: "getCalendarLink" },
eventSources: await this.getEventSources(),
windowResize: () => {
this.calendar.changeView(this.currentView());

View File

@ -98,4 +98,21 @@ ics-calendar {
background: white;
}
}
.fc .fc-toolbar.fc-footer-toolbar {
margin-bottom: 0.5em;
}
button.text-copy,
button.text-copy:focus,
button.text-copy:hover {
background-color: green !important;
transition: 200ms linear;
}
button.text-copied,
button.text-copied:focus,
button.text-copied:hover {
transition: 200ms linear;
}
}

View File

@ -7,7 +7,7 @@
msgid ""
msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-04-06 15:47+0200\n"
"POT-Creation-Date: 2025-04-07 13:56+0200\n"
"PO-Revision-Date: 2024-09-17 11:54+0200\n"
"Last-Translator: Sli <antoine@bartuccio.fr>\n"
"Language-Team: AE info <ae.info@utbm.fr>\n"
@ -33,6 +33,14 @@ msgstr "Dépublier"
msgid "Delete"
msgstr "Supprimer"
#: com/static/bundled/com/components/ics-calendar-index.ts
msgid "Copy calendar link"
msgstr "Copier le lien du calendrier"
#: com/static/bundled/com/components/ics-calendar-index.ts
msgid "Calendar link copied to the clipboard"
msgstr "Lien du calendrier copié dans le presse papier"
#: com/static/bundled/com/components/moderation-alert-index.ts
#, javascript-format
msgid ""

View File

@ -78,10 +78,12 @@ DEBUG = env.bool("SITH_DEBUG", default=False)
TESTING = "pytest" in sys.modules
INTERNAL_IPS = ["127.0.0.1"]
HTTPS = env.bool("HTTPS", default=True)
# force csrf tokens and cookies to be secure when in https
CSRF_COOKIE_SECURE = env.bool("HTTPS", default=True)
CSRF_COOKIE_SECURE = HTTPS
CSRF_TRUSTED_ORIGINS = env.list("CSRF_TRUSTED_ORIGINS", default=[])
SESSION_COOKIE_SECURE = env.bool("HTTPS", default=True)
SESSION_COOKIE_SECURE = HTTPS
X_FRAME_OPTIONS = "SAMEORIGIN"
ALLOWED_HOSTS = ["*"]