Compare commits

...

8 Commits

16 changed files with 760 additions and 94 deletions

View File

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

View File

@ -17,6 +17,8 @@
--button-hv-fg: #1d3cab; --button-hv-fg: #1d3cab;
--button-active-fg: white; --button-active-fg: white;
--button-active-bg: #738ef2; --button-active-bg: #738ef2;
--cover-small-h: 10rem;
--cover-small-w: 10rem;
--heading-font-family: "campus_grotesk"; --heading-font-family: "campus_grotesk";
--header-height: 320px; --header-height: 320px;
--heading-link-hv-fg: #aa217b; --heading-link-hv-fg: #aa217b;
@ -32,7 +34,7 @@
--nav-active-fg: white; --nav-active-fg: white;
--preview-title-sz: 21px; --preview-title-sz: 21px;
--text-color: #75124e; --text-color: #75124e;
--text-color-light: #bbb; --text-color-light: #eee;
} }
@font-face { @font-face {
@ -90,7 +92,8 @@ body.yellow.home #grandlogo img {
content: url('/static/radiocampus/logos/logo-RC-bleu2.png'); content: url('/static/radiocampus/logos/logo-RC-bleu2.png');
} }
body.yellow .nav .nav-item.active { body.yellow .nav .nav-item.active {
color: #7E6B64 !important; color: #738EF2 !important;
text-shadow: -3px 3px 17px rgb(0, 48, 111);
} }
body.blue #grandlogo img, body.yellow #grandlogo img { body.blue #grandlogo img, body.yellow #grandlogo img {
width: 120px; width: 120px;
@ -102,11 +105,10 @@ body.blue.home #grandlogo, body.yellow.home #grandlogo {
} }
body.blue.home #grandlogo img , body.yellow.home #grandlogo img { body.blue.home #grandlogo img , body.yellow.home #grandlogo img {
margin: 12px auto 0 auto; margin: 12px auto 0 auto;
width: 960px; width: 100%;
opacity: 0.8; opacity: 0.8;
} }
.a-player-bar { .a-player-bar {
border-top: 1px solid #555; border-top: 1px solid #555;
} }
@ -127,7 +129,8 @@ a.heading.title {
} }
a.heading.title:hover { a.heading.title:hover {
color: var(--link-hv-fg); /*color: var(--link-hv-fg); */
color: #738ef2;
} }
.button, a.button, button.button { .button, a.button, button.button {
border: 0; border: 0;
@ -139,10 +142,34 @@ a.heading.title:hover {
.header.has-cover { .header.has-cover {
min-height: unset; min-height: unset;
} }
.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.list-emissions .media-content {
font-size: 0.84rem;
}
.today { .today {
color: yellow; color: yellow;
font-size: 1.4em !important; font-size: 1.4em !important;
} }
.list-grille article {
border-bottom: 1px solid black;
}
.lagrille .category {
color: white;
margin-left: 10px;
vertical-align: text-bottom;
font-size: 0.8rem;
}
.lagrille:not(.homedisplay) .heading.subtitle {
color: black;
}
.mt-3 { .mt-3 {
margin-top: unset !important; margin-top: unset !important;
} }
@ -150,9 +177,9 @@ a.heading.title:hover {
display: none; display: none;
} }
.nav.secondary .nav-item { .nav.secondary .nav-item {
color: #7E6B64 !important; color: black !important;
} }
.nav-item:hover { a.nav-item:hover {
opacity: 0.8; opacity: 0.8;
} }
.nav.primary .nav-item { .nav.primary .nav-item {
@ -162,38 +189,41 @@ a.heading.title:hover {
.page section.container { .page section.container {
margin-top: 0; margin-top: 0;
} }
.radiocampus-grid { .program-list {
flex-direction: column;
}
.list-home {
display: block; display: block;
} }
.radiocampus-grid article div.media { .list-home article div.media {
line-height: 1; line-height: 1;
padding: 0; 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; color: yellow;
} }
.radiocampus-grid article.active div.media a:before { .list-home article.active div.media a:before {
content: "\2192"; content: "\2192";
margin-right: 6px; margin-right: 6px;
} }
.radiocampus-grid article div.media a.preview-cover { .list-home article div.media a.preview-cover {
display: none; display: none;
} }
.radiocampus-grid article div.media div.media-content.flex-column { .list-home article div.media div.media-content.flex-column {
display: unset; display: unset;
} }
.radiocampus-grid article div.media div.media-content section.content { .list-home article div.media div.media-content section.content {
display: none; 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; 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; float: right;
} }
.schedule { .schedule {
background-color: unset; background-color: unset;
font-size: 0.9em; font-size: 0.9em;
@ -208,7 +238,7 @@ a.heading.title:hover {
.title, .preview .title, .preview .title:not(:last-child) { .title, .preview .title, .preview .title:not(:last-child) {
text-transform: unset; text-transform: unset;
font-weight: unset; font-weight: unset;
font-size: 1.2em; font-size: 1.2rem;
} }
@media screen and (max-width: 400px) { @media screen and (max-width: 400px) {
@ -217,6 +247,7 @@ a.heading.title:hover {
} }
} }
@media screen and (max-width: 1024px) { @media screen and (max-width: 1024px) {
:root { :root {
--header-height: 200px; --header-height: 200px;
@ -237,6 +268,9 @@ a.heading.title:hover {
.dropdown.is-right .dropdown-menu { .dropdown.is-right .dropdown-menu {
left: 0; left: 0;
} }
.grid.list-emissions {
grid-template-columns: 1fr 1fr 1fr;
}
#grandlogo { #grandlogo {
display: none; display: none;
} }
@ -268,7 +302,7 @@ a.heading.title:hover {
@media screen and (min-width: 1216px) { @media screen and (min-width: 1216px) {
.container:not(.is-max-desktop):not(.is-max-widescreen) { .container:not(.is-max-desktop):not(.is-max-widescreen) {
max-width: unset; max-width: unset;
margin: 10px 64px; margin: 0 64px;
} }
body.home .container:not(.is-max-desktop):not(.is-max-widescreen) { body.home .container:not(.is-max-desktop):not(.is-max-widescreen) {
max-width: 1152px; max-width: 1152px;
@ -276,6 +310,12 @@ a.heading.title:hover {
} }
} }
@media screen and (max-width: 900px) {
.grid.list-emissions {
grid-template-columns: 1fr 1fr;
}
}
.list-item .headings { .list-item .headings {
margin-bottom: .2rem !important; margin-bottom: .2rem !important;
} }
@ -409,3 +449,113 @@ a.heading.title: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 %} {% endblock %}
{% block nav %} {% block nav %}
<div id="grandlogo"><a href="/"><img /></a></div> <div id="grandlogo" class="container"><a href="/"><img /></a></div>
{{ block.super }} {{ block.super }}
{% endblock %} {% endblock %}
@ -17,3 +17,9 @@
{{ block.super }} {{ block.super }}
{% endif %} {% endif %}
{% endblock %} {% endblock %}
{% block header-cover %}
{% if cover and not "emissions/episodes" in request.path %}
<img src="{{ cover }}" ref="cover" class="cover">
{% endif %}
{% endblock %}

View File

@ -0,0 +1,42 @@
{% extends "aircox/basepage_list.html" %}
{% load i18n %}
{% block filters %}
{{ block.super }}
<div class="field is-horizontal">
<div class="field-label">
<label class="label">{% translate "Podcasts" %}</label>
</div>
<div class="field-body">
<div class="checkbox">
<input type="checkbox" class="checkbox" name="podcast" value="True"
{% if filterset_data.podcast %}checked{% endif %} />
</div>
</div>
</div>
{% endblock %}
{% block list-container %}
{% with list_class="list-podcasts" %}
{{ 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

@ -0,0 +1,107 @@
{% extends "aircox/page_list.html" %}
{% comment %}List of diffusions as a timetable{% endcomment %}
{% load i18n aircox humanize %}
{% block subtitle %}{{ date|date:"l d F Y" }}{% endblock %}
{% block secondary-nav %}
<nav class="nav secondary">
<div class="nav-menu nav-categories">
<a class="nav-item" id="recent-link"
href="#" onclick="javascript:display('recentdisplay');">
Derniers titres diffusés
</a>
<a class="nav-item active" id="home-link"
href="#" onclick="javascript:display('homedisplay');">
Aujourd'hui
</a>
</div>
<a-switch class="button burger"
el=".nav-categories" group="nav" icon="fas fa-tags"
aria-label="{% translate "Categories" %}">
</a-switch>
</nav>
<script>
function display(id) {
var h = document.getElementsByClassName('homedisplay');
var r = document.getElementsByClassName('recentdisplay');
if (id == "homedisplay") {
for(var i = 0; i < h.length; i++) { h[i].setAttribute('style', 'display:inline !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 < r.length; i++) { r[i].setAttribute('style', 'display:inline !important'); }
document.getElementById('recent-link').classList.add('active');
document.getElementById('home-link').classList.remove('active');
}
}
</script>
{% endblock %}
{% block breadcrumbs %}
{% endblock %}
{% block list-container %}
<br />
<div class="lagrille homedisplay">
<section class="container" style="display:flex;justify-content:flex-end;min-height:600px">
<div>
<!-- <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="list-home" %}
{{ block.super }}
{% endwith %}
</div>
</section>
</div>
<br />
<div class="recentdisplay" style="display:none">
<section class="container" style="min-height:600px">
<div>
<!-- <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="list-home" %}
{{ block.super }}
{% endwith %}
</div>
</section>
</div>
{% endblock %}
{% block list %}
{% with object_list=object_list timetable=True %}
{% with widget|default:"item" as widget %}
{% for object in object_list %}
{% if object.episode %}
<div class="homedisplay">
{% page_widget widget object.episode diffusion=object timetable=True %}
</div>
{% else %}
<div class="preview list-item logs">
<div class="media d-block content recentdisplay" style="display:none !important;">
{% for obj in object %}
{% include "aircox/widgets/track_item.html" with object=obj.track log=obj timetable=True %}
<br />
{% endfor %}
</div>
</div>
{% endif %}
{% endfor %}
{% endwith %}
{% endwith %}
{% endblock %}

View File

@ -1,33 +0,0 @@
{% extends "aircox/page_list.html" %}
{% comment %}List of diffusions as a timetable{% endcomment %}
{% load i18n aircox humanize %}
{% block subtitle %}{{ date|date:"l d F Y" }}{% endblock %}
{% block secondary-nav %}
{% endblock %}
{% block breadcrumbs %}
{% endblock %}
{% block list-container %}
<br />
<br />
<div style="display: flex; justify-content: flex-end;height:100%;">
<div style="min-width:300px;margin-right:12%">
<!-- <a href="{% url "timetable-list" date=date %}">{{ date|date:"l d F Y" }}</a> -->
<section class="clear-both list grid radiocampus-grid" role="list">
<span class="title today">Aujourd'hui</span>
</section>
{% with list_class="radiocampus-grid" %}
{{ block.super }}
{% endwith %}
</div>
</div>
{% endblock %}
{% block list %}
{% include "./widgets/logs.html" with object_list=object_list timetable=True %}
{% endblock %}

View File

@ -1,12 +1,46 @@
{% extends "aircox/page_list.html" %} {% extends "aircox/basepage_list.html" %}
{% comment %}Display a list of Pages{% endcomment %} {% comment %}Display a list of Pages{% endcomment %}
{% load i18n aircox %} {% load i18n aircox %}
{% 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 %}
{% block title %}
{% if parent %}{{ parent.title }}
{% else %}{{ block.super }}
{% endif %}
{% endblock %}
{% block header %}
{% if page and not object %}
{% with page as object %}
{{ block.super }}
{% endwith %}
{% else %}
{{ block.super }}
{% endif %}
{% endblock %}
{% block breadcrumbs %} {% block breadcrumbs %}
{% if parent and model.list_url_name %} {% if parent and model.list_url_name %}
{% include "./widgets/breadcrumbs.html" with page=parent %} {% include "./widgets/breadcrumbs.html" with page=parent %}
<a href="{% url model.list_url_name %}">{{ model|verbose_name:True }}</a> <a href="{% url model.list_url_name %}">{{ model|verbose_name:True }}</a>
{% elif page.title == "Podcasts" and not category %}
{% elif page and model.list_url_name %} {% elif page and model.list_url_name %}
<a href="{% url model.list_url_name %}">{{ page.title }}</a> <a href="{% url model.list_url_name %}">{{ page.title }}</a>
{% if category %} {% if category %}
@ -25,3 +59,24 @@
{% endblock %} {% endblock %}
{% block content-container %}{% endblock %} {% block content-container %}{% endblock %}
{% block list-pagination %}
{% include "./widgets/page_pagination.html" %}
{% endblock %}
{% block list-container %}
<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 %}
{% block list_object %}
{% page_widget item_widget|default:"program" object %}
{% endblock %}
{% empty %}
{% blocktranslate %}There is nothing published here...{% endblocktranslate %}
{% endfor %}
{% endwith %}
{% endblock %}
</section>
{% endblock %}

View File

@ -0,0 +1,62 @@
{% extends "aircox/basepage_list.html" %}
{% comment %}Display a list of Pages{% endcomment %}
{% load i18n aircox %}
{% 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 %}
{% block title %}
{% if parent %}{{ parent.title }}
{% else %}{{ block.super }}
{% endif %}
{% endblock %}
{% block header %}
{% if page and not object %}
{% with page as object %}
{{ block.super }}
{% endwith %}
{% else %}
{{ block.super }}
{% endif %}
{% endblock %}
{% 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.title == "Podcasts" and not category %}
{% elif 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 %}
{% endblock %}
{% block content-container %}{% endblock %}

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

@ -0,0 +1,95 @@
{% extends "aircox/basepage_list.html" %}
{% comment %}List of diffusions as a timetable{% endcomment %}
{% load i18n aircox humanize %}
{% block subtitle %}{{ date|date:"l d F Y" }}{% endblock %}
{% block secondary-nav %}
<nav class="nav secondary">
{% include "./widgets/dates_menu.html" with url_name=view.redirect_date_url %}
</nav>
{% endblock %}
{% block breadcrumbs %}
{% 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 %}
{% endif %}
<a href="{% url "timetable-list" date=date %}">{{ date|date:"l d F Y" }}</a>
{% endblock %}
{% block list-container %}
{% with list_class="grid" %}
<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 class="fifty">
{% block list %}
{% with object_list=object_list timetable=True %}
{% with widget|default:"item" as widget %}
{% for object in object_list %}
{% if object.episode %}
<div class="lagrille">
{% page_widget widget object.episode diffusion=object timetable=True %}
</div>
{% else %}
<div class="preview list-item logs">
<div class="media d-block content recentdisplay" style="display:none !important;">
{% for obj in object %}
{% include "aircox/widgets/track_item.html" with object=obj.track log=obj timetable=True %}
<br />
{% endfor %}
</div>
</div>
{% endif %}
{% endfor %}
{% endwith %}
{% endwith %}
{% endblock %}
</div>
</section>
</section>
{% endwith %}
{% endblock %}
{% block title %}
{% if parent %}{{ parent.title }}
{% else %}{{ block.super }}
{% endif %}
{% endblock %}
{% block header %}
{% if page and not object %}
{% with page as object %}
{{ block.super }}
{% endwith %}
{% else %}
{{ block.super }}
{% endif %}
{% endblock %}
{% block content-container %}{% endblock %}
{% block list-pagination %}
{% include "./widgets/page_pagination.html" %}
{% endblock %}

View File

@ -26,12 +26,13 @@
<a href="{{ url|escape }}" class="heading title {% block title-class %}{% endblock %}"> <a href="{{ url|escape }}" class="heading title {% block title-class %}{% endblock %}">
{% block title %}{{ title|default:"" }}{% endblock %} {% block title %}{{ title|default:"" }}{% endblock %}
</a> </a>
<span class="category">{{ object.program.category }}</span>
<span class="heading subtitle {% block subtitle-class %}{% endblock %}"> <span class="heading subtitle {% block subtitle-class %}{% endblock %}">
{% block subtitle %}{{ subtitle|default:"" }}{% endblock %} {% block subtitle %}{{ subtitle|default:"" }}{% endblock %}
</span> </span>
</br> </br>
<section class="content flex-grow-1"> <section class="content flex-grow-1 item-section">
{% block content %}{{ block.super }}{% endblock %} {% block content %}{{ block.super }}{% endblock %}
</section> </section>
{% block actions-container %}{{ block.super }}{% endblock %} {% 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 %}">{% translate "Edit" %}</a>
{% endif %}
{% endblock %}
</div>
{% endspaceless %}
{% endblock %}
</section>
{% endblock %}
{% endblock %}
</{{ tag|default:"article" }}>
{% endblock %}

View File

@ -0,0 +1,42 @@
{% extends "./preview.html" %}
{% load i18n aircox %}
{% block tag-class %}{{ block.super }} list-item is-fullwidth{% endblock %}
{% block headings %}
{% endblock %}
{% block inner %}
{% block headings-container %}{{ block.super }}{% endblock %}
{% block content-container %}
<div class="media program-list">
{% if object.cover and not no_cover %}
<a href="{{ object.get_absolute_url }}"
class="media-left preview-cover small"
style="background-image: url({{ object.cover.url }})">
</a>
{% endif %}
<div class="media-content flex-column">
{% if object|model_name == "Episode" %}
<div class="episode-date">
{{ object.pub_date|date:"d/m/Y" }}<Br/>
</div>
{% endif %}
<a href="{{ url|escape }}" class="heading title {% block title-class %}{% endblock %}">
{% block title %}{{ title|default:"" }}{% endblock %}
</a>
<span class="heading subtitle {% block subtitle-class %}{% endblock %}">
{% block subtitle %}{{ subtitle|default:"" }}{% endblock %}
</span>
</br>
<section class="content flex-grow-1">
{% block content %}{{ block.super }}{% endblock %}
</section>
{% block actions-container %}{{ block.super }}{% endblock %}
</div>
</div>
{% endblock %}
{% endblock %}

View File

@ -1,42 +1,40 @@
"""Aircox URL Configuration.
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.8/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: url(r'^$', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home')
Including another URLconf
1. Add an import: from blog import urls as blog_urls
2. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls))
"""
# from django.conf.urls.i18n import i18n_patterns
from django.conf import settings from django.conf import settings
from django.conf.urls.static import static from django.conf.urls.static import static
from django.contrib import admin from django.contrib import admin
from django.urls import include, path 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 import aircox_streamer.urls
from radiocampus.views.diffusion import TimeTableView from radiocampus.views import HomeTimeTableView, TimeTableView
urlpatterns = [ urlpatterns = [
*aircox.urls.urls,
path("streamer/", include((aircox_streamer.urls.urls, "aircox_streamer"), namespace="streamer")), path("streamer/", include((aircox_streamer.urls.urls, "aircox_streamer"), namespace="streamer")),
path("admin/", admin.site.urls), path("admin/", admin.site.urls),
path("accounts/", include("django.contrib.auth.urls")), path("accounts/", include("django.contrib.auth.urls")),
path("filer/", include("filer.urls")), path("filer/", include("filer.urls")),
] ]
for i, pa in enumerate(urlpatterns): for url in urls:
if "name" in pa.__dict__.keys() and pa.name == "home": if "name" in url.__dict__.keys():
urlpatterns.pop(i) 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: if settings.DEBUG:
from debug_toolbar.toolbar import debug_toolbar_urls from debug_toolbar.toolbar import debug_toolbar_urls

51
radiocampus/views.py Normal file
View File

@ -0,0 +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__ = ("HomeTimeTableView", "TimeTableView")
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)

View File

@ -1,13 +0,0 @@
from aircox.models import Diffusion, StaticPage
from aircox.views.page import attach
from aircox.views.diffusion import TimeTableView as AircoxTimeTableView
__all__ = "TimeTableView"
@attach
class TimeTableView(AircoxTimeTableView):
model = Diffusion
redirect_date_url = "timetable-list"
attach_to_value = StaticPage.Target.TIMETABLE
template_name = "aircox/home_timetable_list.html"