Compare commits

...

10 Commits

15 changed files with 348 additions and 50 deletions

View File

@ -37,3 +37,4 @@ class EpisodeAdmin(SortableAdminBase, ChildPageAdmin):
# readonly_fields = ('parent',)
inlines = (TrackInline, EpisodeSoundInline, DiffusionInline)
ordering = ["-pub_date"]

View File

@ -181,8 +181,8 @@ class Settings(BaseSettings):
"""Allow comments."""
# ---- bleach
ALLOWED_TAGS = [*sanitizer.ALLOWED_TAGS, "br", "p", "h3", "h4", "h5"]
ALLOWED_ATTRIBUTES = sanitizer.ALLOWED_ATTRIBUTES
ALLOWED_TAGS = [*sanitizer.ALLOWED_TAGS, "br", "p", "hr", "h2", "h3", "h4", "h5", "iframe", "pre"]
ALLOWED_ATTRIBUTES = [*sanitizer.ALLOWED_ATTRIBUTES, "src", "width", "height", "frameborder", "href"]
ALLOWED_PROTOCOLS = sanitizer.ALLOWED_PROTOCOLS

Binary file not shown.

View File

@ -93,6 +93,7 @@ body.yellow.home #grandlogo img {
}
body.yellow .nav .nav-item.active {
color: #738EF2 !important;
text-shadow: -3px 3px 17px rgb(0, 48, 111);
}
body.blue #grandlogo img, body.yellow #grandlogo img {
width: 120px;
@ -104,11 +105,10 @@ body.blue.home #grandlogo, body.yellow.home #grandlogo {
}
body.blue.home #grandlogo img , body.yellow.home #grandlogo img {
margin: 12px auto 0 auto;
width: 960px;
width: 100%;
opacity: 0.8;
}
.a-player-bar {
border-top: 1px solid #555;
}
@ -129,7 +129,8 @@ a.heading.title {
}
a.heading.title:hover {
color: var(--link-hv-fg);
/*color: var(--link-hv-fg); */
color: #738ef2;
}
.button, a.button, button.button {
border: 0;
@ -141,23 +142,27 @@ a.heading.title:hover {
.header.has-cover {
min-height: unset;
}
.grid.listfive {
.item-section {display:flex; align-items:end}
.fifty {
width: 55%;
}
.grid.list-emissions {
grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
grid-auto-flow: dense;
gap: 0.2rem;
}
.grid.listfive .media-content {
.grid.list-emissions .media-content {
font-size: 0.84rem;
}
.today {
color: yellow;
font-size: 1.4em !important;
}
.lagrille:not(.homedisplay) article {
.list-grille article {
border-bottom: 1px solid black;
}
.lagrille .category {
color: grey;
color: white;
margin-left: 10px;
vertical-align: text-bottom;
font-size: 0.8rem;
@ -188,35 +193,35 @@ a.nav-item:hover {
flex-direction: column;
}
.radiocampus-grid {
.list-home {
display: block;
}
.radiocampus-grid article div.media {
.list-home article div.media {
line-height: 1;
padding: 0;
}
.radiocampus-grid article.active div.media div.media-content a, .radiocampus-grid article.active div.media div.media-content span {
.list-home article.active div.media div.media-content a, .list-home article.active div.media div.media-content span {
color: yellow;
}
.radiocampus-grid article.active div.media a:before {
.list-home article.active div.media a:before {
content: "\2192";
margin-right: 6px;
}
.radiocampus-grid article div.media a.preview-cover {
.list-home article div.media a.preview-cover {
display: none;
}
.radiocampus-grid article div.media div.media-content.flex-column {
.list-home article div.media div.media-content.flex-column {
display: unset;
}
.radiocampus-grid article div.media div.media-content section.content {
.list-home article div.media div.media-content section.content {
display: none;
}
.radiocampus-grid article div.media div.media-content div.episode-date {
.list-home article div.media div.media-content div.episode-date {
display: none;
}
.radiocampus-grid article div.media div.media-content span.heading.subtitle {
.list-home article div.media div.media-content span.heading.subtitle {
float: right;
}
.schedule {
@ -263,7 +268,7 @@ a.nav-item:hover {
.dropdown.is-right .dropdown-menu {
left: 0;
}
.grid.listfive {
.grid.list-emissions {
grid-template-columns: 1fr 1fr 1fr;
}
#grandlogo {
@ -297,7 +302,7 @@ a.nav-item:hover {
@media screen and (min-width: 1216px) {
.container:not(.is-max-desktop):not(.is-max-widescreen) {
max-width: unset;
margin: 10px 64px;
margin: 0 64px;
}
body.home .container:not(.is-max-desktop):not(.is-max-widescreen) {
max-width: 1152px;
@ -306,7 +311,7 @@ a.nav-item:hover {
}
@media screen and (max-width: 900px) {
.grid.listfive {
.grid.list-emissions {
grid-template-columns: 1fr 1fr;
}
}
@ -444,3 +449,113 @@ a.nav-item:hover {
}
}
*/
/* fred fixes */
.grid.list-emissions:not(.list-home) {display: flex !important;flex-wrap: wrap !important; gap: 20px 1rem;}
.grid.list-emissions:not(.list-home) > .list-item {width: calc(20% - 2rem) !important ;}
.grid.list-emissions:not(.list-home) > .list-item .preview-cover {max-width: 100% !important;
display: block;
width: 100% !important;
min-width: auto;
aspect-ratio: 1 / 1;
height: fit-content;
background-size: contain;
background-position: center;
background-color: white;
margin-bottom: 0.5rem;
}
.grid.list-emissions:not(.list-home) .media-content {margin-top: 0;}
.grid.list-emissions:not(.list-home) > .list-item .media .media-content > br, .grid.listfive > .list-item .media .media-content .episode-date > br {display: none;}
.grid.list-emissions:not(.list-home) .list-item .subtitle {text-align: left !important;font-size: 0.8rem !important;}
.grid.list-emissions:not(.list-home) .preview.active .heading:not(:empty) {
color: #738EF2 !important;
}
.grid.list-podcasts {display: flex !important;flex-wrap: wrap !important; gap: 20px 1rem;}
.grid.list-podcasts > .list-item {width: calc(50% - 2rem) !important ;}
.grid.list-podcasts > .list-item .preview-cover {max-width: 100% !important;
display: block;
width: 50% !important;
min-width: auto;
aspect-ratio: 1 / 1;
height: fit-content;
background-size: contain;
background-position: center;
background-color: white;
}
.grid.list-podcasts .media-content {margin-top: 0;}
.grid.list-podcasts .media .media-left {width: 25% !important;}
.grid.list-podcasts .media .media-content {width: 75%;}
.grid.list-podcasts > .list-item .media .media-content > br, .grid.list-emissions > .list-item .media .media-content .episode-date > br {display: none;}
.grid.list-podcasts .list-item .subtitle {text-align: left !important;font-size: 0.8rem !important;}
.grid.list-podcasts .preview.active .heading:not(:empty) {
color: #738EF2 !important;
}
@media screen and (max-width: 1224px) {
.grid.list-emissions:not(.list-home) > .list-item {width: calc(33% - 2rem) !important;;}
}
@media screen and (max-width: 924px) {
.grid.list-emissions:not(.list-home) > .list-item {width: calc(50% - 2rem) !important;}
}
@media screen and (max-width: 1024px) {
.grid.list-emissions > .list-item {width: 100% !important;}
.program-list {flex-direction: column;}
.grid.list-podcasts > .list-item {width: 100% !important ;}
}
.list-item .subtitle:not(:empty) {
min-width: auto !important;
}
@media screen and (max-width: 924px) {
.a-player-bar-content {overflow: hidden;}
.a-player-bar-content .title {
display: inline-block;
padding-right: 2em;
padding-left: 100%;
white-space: nowrap;
animation: defilement-rtl 55s infinite linear;
overflow: visible;}
@keyframes defilement-rtl {
0% {
transform: translate3d(0,0,0); /* position initiale à droite */
}
100% {
transform: translate3d(-100%,0,0); /* position finale à gauche */
}
}
}
@media screen and (max-width: 540px) {
.media {
flex-direction: column;
}
.grid.list-podcasts .media .media-content {width:100%}
.grid.list-emissions:not(.list-home) > .list-item {
width: 100% !important;
}
}
.list-item .media-content {height:auto;}

View File

@ -8,7 +8,7 @@
{% endblock %}
{% block nav %}
<div id="grandlogo"><a href="/"><img /></a></div>
<div id="grandlogo" class="container"><a href="/"><img /></a></div>
{{ block.super }}
{% endblock %}
@ -17,3 +17,9 @@
{{ block.super }}
{% endif %}
{% endblock %}
{% block header-cover %}
{% if cover and not "emissions/episodes" in request.path %}
<img src="{{ cover }}" ref="cover" class="cover">
{% endif %}
{% endblock %}

View File

@ -21,3 +21,22 @@
{{ block.super }}
{% endwith %}
{% endblock %}
{% block secondary-nav %}
{% if not parent and categories %}
<nav class="nav secondary">
<div class="nav-menu nav-categories">
{% for cat in categories %}
<a class="nav-item{% if cat == category %} active{% endif %}"
href="{% url request.resolver_match.url_name category_slug=cat.slug %}">
{{ cat.title }}
</a>
{% endfor %}
</div>
<a-switch class="button burger"
el=".nav-categories" group="nav" icon="fas fa-tags"
aria-label="{% translate "Categories" %}">
</a-switch>
</nav>
{% endif %}
{% endblock %}

View File

@ -30,10 +30,14 @@ function display(id) {
if (id == "homedisplay") {
for(var i = 0; i < h.length; i++) { h[i].setAttribute('style', 'display:inline !important'); }
for(var i = 0; i < h.length; i++) { r[i].setAttribute('style', 'display:none !important'); }
for(var i = 0; i < r.length; i++) { r[i].setAttribute('style', 'display:none !important'); }
document.getElementById('recent-link').classList.remove('active');
document.getElementById('home-link').classList.add('active');
} else {
for(var i = 0; i < h.length; i++) { h[i].setAttribute('style', 'display:none !important'); }
for(var i = 0; i < h.length; i++) { r[i].setAttribute('style', 'display:inline !important'); }
for(var i = 0; i < r.length; i++) { r[i].setAttribute('style', 'display:inline !important'); }
document.getElementById('recent-link').classList.add('active');
document.getElementById('home-link').classList.remove('active');
}
@ -55,7 +59,7 @@ function display(id) {
<!-- <a href="{% url "timetable-list" date=date %}">{{ date|date:"l d F Y" }}</a> -->
<section class="clear-both list grid radiocampus-grid" role="list">
</section>
{% with list_class="radiocampus-grid" %}
{% with list_class="list-home" %}
{{ block.super }}
{% endwith %}
</div>
@ -69,7 +73,7 @@ function display(id) {
<!-- <a href="{% url "timetable-list" date=date %}">{{ date|date:"l d F Y" }}</a> -->
<section class="clear-both list grid radiocampus-grid" role="list">
</section>
{% with list_class="radiocampus-grid" %}
{% with list_class="list-home" %}
{{ block.super }}
{% endwith %}
</div>

View File

@ -65,7 +65,7 @@
{% endblock %}
{% block list-container %}
<section class="container clear-both list grid {{ list_class|default:"" }} listfive" role="list">
<section class="container clear-both list grid {{ list_class|default:"" }} list-emissions" role="list">
{% block list %}
{% with has_headline=True %}
{% for object in object_list %}

View File

@ -0,0 +1,32 @@
{% extends "./base.html" %}
{% load aircox %}
{% comment %}
Override is a trick here: it allows to change title at two different different
places inside the page: inside `<title>` tag, and inside the page
content.
{% endcomment %}
{% block head-title %}
{% block title %}
{% if page and page.title %}{{ page.title }}{% endif %}
{% endblock %}
{% if page and page.title %}&mdash;{% endif %}
{{ station.name }}
{% endblock %}
{% block header %}{% if page %}{{ block.super }}{% endif %}{% endblock %}
{% block secondary-nav %}
{% if '/pages/' in request.path %}
<nav class="nav secondary">
<div class="nav-menu nav-categories">
{% nav_items "secondary" css_class="nav-item" active_class="active" as items %}
{% for item, render in items %}
{{ render }}
{% endfor %}
</div>
</nav>
{% endif %}
{% endblock %}

View File

@ -12,23 +12,13 @@
{% block breadcrumbs %}
{% if parent and model.list_url_name %}
{% include "./widgets/breadcrumbs.html" with page=parent %}
<a href="{% url model.list_url_name %}">{{ model|verbose_name:True }}</a>
{% elif page and model.list_url_name %}
{% if page and model.list_url_name %}
<a href="{% url model.list_url_name %}">{{ page.title }}</a>
{% if category %}
<a href="{% url request.resolver_match.url_name category_slug=category.slug %}">
{{ category.title }}
</a>
{% endif %}
{% else %}
<a href="{% url request.resolver_match.url_name %}">{{ model|verbose_name:True }}</a>
{% if category %}
<a href="{% url request.resolver_match.url_name category_slug=category.slug %}">
{{ category.title }}
</a>
{% endif %}
{% endif %}
<a href="{% url "timetable-list" date=date %}">{{ date|date:"l d F Y" }}</a>
{% endblock %}
@ -36,9 +26,9 @@
{% block list-container %}
{% with list_class="grid" %}
<section class="container clear-both list grid radiocampus-grid listfive" role="list">
<section class="container clear-both list grid list-grille list-home list-emissions" role="list">
<section class="container" style="display:flex;justify-content:flex-end;min-height:600px">
<div style="max-width:600px;">
<div class="fifty">
{% block list %}
{% with object_list=object_list timetable=True %}
{% with widget|default:"item" as widget %}

View File

@ -32,7 +32,7 @@
</span>
</br>
<section class="content flex-grow-1">
<section class="content flex-grow-1 item-section">
{% block content %}{{ block.super }}{% endblock %}
</section>
{% block actions-container %}{{ block.super }}{% endblock %}

View File

@ -0,0 +1,71 @@
{% load i18n %}
{% comment %}
Content related context:
- object: object to display
- cover: cover
- title: title
- subtitle: subtitle
- content: content to display
Components:
- no_cover: don't show cover
- no_content: don't show content
Styling related context:
- is_active: add "active" css class
- is_small: add "small" css class
- is_tiny: add "tiny" css class
- tag
- tag_class: css class to set to main tag
- tag_extra: extra tag attributes
{% endcomment %}
{% load aircox %}
{% block outer %}
<{{ tag|default:"article" }} id="{{ object|object_id }}" class="preview {% if not cover %}no-cover {% endif %}{% if is_active %}active {% endif %}{% if is_tiny %}tiny{% elif is_small %}small{% endif %}{% block tag-class %}{{ tag_class|default:"" }} {% endblock %}" {% block tag-extra %}{% endblock %}>
{% block inner %}
{% block headings-container %}
<header class="headings{% block headings-class %}{% endblock %}"{% block headings-tag-extra %}{% endblock %}>
{% block headings %}
{% block title-container %}
<a href="{{ url|escape }}" class="heading title {% block title-class %}{% endblock %}"{% if title %} title="{{ title|escape }}"{% endif %}>
{% block title %}{{ title|default:"" }}{% endblock %}
</a>
{% endblock %}
{% block subtitle-container %}
<span class="heading subtitle {% block subtitle-class %}{% endblock %}">
{% block subtitle %}{{ subtitle|default:"" }}{% endblock %}
</span>
{% endblock %}
{% endblock %}
</header>
{% endblock %}
{% block content-container %}
<section class="content headings-container">
{% block content %}
{% if content and not no_content %}
{% autoescape off %}
{{ content|striptags|linebreaks }}
{% endautoescape %}
{% endif %}
{% spaceless %}
<div class="actions">
{% block actions %}
{% if admin and object.edit_url_name %}
<a href="{% url object.edit_url_name pk=object.pk %}" target="_self">{% translate "Edit" %}</a>
{% endif %}
{% endblock %}
</div>
{% endspaceless %}
{% endblock %}
</section>
{% endblock %}
{% endblock %}
</{{ tag|default:"article" }}>
{% endblock %}

View File

@ -2,25 +2,41 @@ from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import include, path
from django.utils.translation import gettext_lazy as _
import aircox.urls
from aircox.urls import urls
import aircox_streamer.urls
from radiocampus.views import TimeTableView
from radiocampus.views import HomeTimeTableView, TimeTableView
from aircox.views.dashboard import DashboardView
urlpatterns = [
*aircox.urls.urls,
path("streamer/", include((aircox_streamer.urls.urls, "aircox_streamer"), namespace="streamer")),
path("admin/", admin.site.urls),
path("accounts/", include("django.contrib.auth.urls")),
path("filer/", include("filer.urls")),
path("gestion/", DashboardView.as_view(), name="dashboard"),
]
for i, pa in enumerate(urlpatterns):
if "name" in pa.__dict__.keys() and pa.name == "home":
urlpatterns.pop(i)
for url in urls:
if "name" in url.__dict__.keys():
if url.name == "home" or url.name == "timetable-list":
continue
urlpatterns.append(url)
urlpatterns.append(path("", TimeTableView.as_view(), name="home"))
urlpatterns.append(path("", HomeTimeTableView.as_view(), name="home"))
urlpatterns.extend(
[
path(_("timetable/"), TimeTableView.as_view(), name="timetable-list"),
path(
_("timetable/<date:date>/"),
TimeTableView.as_view(),
name="timetable-list",
),
]
)
if settings.DEBUG:
from debug_toolbar.toolbar import debug_toolbar_urls

View File

@ -1,7 +1,51 @@
import datetime
from django.urls import reverse
from aircox.models import Diffusion, Log, StaticPage
from aircox.views.diffusion import TimeTableView as AircoxTimeTableView
from aircox.views.diffusion import BaseDiffusionListView
from aircox.views.mixins import GetDateMixin
from aircox.views.page import attach
__all__ = "TimeTableView"
__all__ = ("HomeTimeTableView", "TimeTableView")
class TimeTableView(AircoxTimeTableView):
class HomeTimeTableView(AircoxTimeTableView):
template_name = "aircox/home.html"
@attach
class TimeTableView(GetDateMixin, BaseDiffusionListView):
model = Diffusion
redirect_date_url = "timetable-list"
attach_to_value = StaticPage.Target.TIMETABLE
template_name = "aircox/timetable_list.html"
def get_date(self, param="date"):
date = super().get_date(param)
return date if date is not None else datetime.date.today()
def get_logs(self, date):
return Log.objects.on_air().date(self.date).filter(track__isnull=False)
def get_queryset(self):
return super().get_queryset().date(self.date)
@classmethod
def get_secondary_nav(cls):
date = datetime.date.today()
start = date - datetime.timedelta(days=3)
dates = [start + datetime.timedelta(days=i) for i in range(0, 7)]
return tuple((date.strftime("%A %d"), reverse("timetable-list", kwargs={"date": date})) for date in dates)
def get_context_data(self, object_list=None, **kwargs):
start = self.date - datetime.timedelta(days=3)
dates = [start + datetime.timedelta(days=i) for i in range(0, 7)]
if object_list is None:
logs = self.get_logs(self.date)
object_list = Log.merge_diffusions(logs, self.object_list, group_logs=True)
object_list = list(reversed(object_list))
return super().get_context_data(date=self.date, dates=dates, object_list=object_list, **kwargs)