Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 269decb110 | |||
| 5074455dac | |||
| d4cf9a53dd | |||
| b1891fb51d |
@@ -3,12 +3,14 @@ import numpy as np
|
|||||||
import re
|
import re
|
||||||
import requests
|
import requests
|
||||||
import os
|
import os
|
||||||
from fastapi import APIRouter, Security, Depends
|
from fastapi import APIRouter, Security, Depends, HTTPException, Response
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from app.database import get_db, engine, Base
|
from app.database import get_db, engine, Base
|
||||||
from app.security import get_current_user
|
from app.security import get_current_user
|
||||||
from app.crud import create_song, get_setting, set_setting, get_all_songs_and_votes
|
from app.crud import create_song, get_setting, set_setting, get_all_songs_and_votes
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
router = APIRouter(
|
router = APIRouter(
|
||||||
prefix="/admin",
|
prefix="/admin",
|
||||||
@@ -130,5 +132,13 @@ async def toggle_veto_mode(db: Session = Depends(get_db)) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
@router.get("/results")
|
@router.get("/results")
|
||||||
async def get_evaluation(db = Depends(get_db)) -> list:
|
async def get_evaluation(format: str = "json", db = Depends(get_db)) -> Any:
|
||||||
return get_all_songs_and_votes(db)
|
res = get_all_songs_and_votes(db)
|
||||||
|
if format == "json":
|
||||||
|
return JSONResponse(content=res)
|
||||||
|
elif format == "csv":
|
||||||
|
df = pd.json_normalize(res)
|
||||||
|
df.columns = [c.split(".")[-1] for c in df.columns]
|
||||||
|
return Response(content=df.to_csv(), media_type="application/csv", headers={'Content-Disposition': 'attachment; filename="results.csv"'})
|
||||||
|
else:
|
||||||
|
raise HTTPException(status_code=404, detail="format must be json or csv")
|
||||||
|
|||||||
104
static/site.css
104
static/site.css
@@ -52,6 +52,24 @@
|
|||||||
font-family: Fira Sans, Helvetica, Arial, sans-serif;
|
font-family: Fira Sans, Helvetica, Arial, sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
background: var(--color-background);
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
background-color: var(--color-choriosity-red);
|
||||||
|
height: 80px;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::selection {
|
||||||
|
background: var(--color-choriosity-red);
|
||||||
|
color: var(--color-white-100);
|
||||||
|
}
|
||||||
|
|
||||||
.vote-buttons,
|
.vote-buttons,
|
||||||
.cover-container,
|
.cover-container,
|
||||||
.categories {
|
.categories {
|
||||||
@@ -73,7 +91,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.text {
|
.text {
|
||||||
padding: 0.3em;
|
padding: 0.3em;
|
||||||
margin-bottom: 0.7em;
|
margin-bottom: 0.7em;
|
||||||
@@ -87,6 +104,10 @@
|
|||||||
|
|
||||||
.song {
|
.song {
|
||||||
background-color: var(--color-choriosity-red--light);
|
background-color: var(--color-choriosity-red--light);
|
||||||
|
background-color: var(--color-white-100);
|
||||||
|
/*border: 1px solid var(--color-choriosity-red);*/
|
||||||
|
border: 1px solid hsl(calc(var(--hue) * 360), 100%, 40%);
|
||||||
|
box-shadow: 4px 4px 8px var(--color-white-90);
|
||||||
padding: 0.4em;
|
padding: 0.4em;
|
||||||
border-radius: 0.5em;
|
border-radius: 0.5em;
|
||||||
width: 30em;
|
width: 30em;
|
||||||
@@ -95,11 +116,10 @@
|
|||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.cover-container {
|
.cover-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 10.67em;
|
width: 10.67em;
|
||||||
height: 6em;
|
height: 6.7em;
|
||||||
float: left;
|
float: left;
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -119,7 +139,6 @@
|
|||||||
transition: .3s ease;
|
transition: .3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.overlay {
|
.overlay {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
@@ -161,9 +180,9 @@
|
|||||||
height: 60%;
|
height: 60%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.vote-buttons {
|
.vote-buttons {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
margin-top: 0.7em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
@@ -211,11 +230,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.button:not(.selected):not(:hover) {
|
.button:not(.selected):not(:hover) {
|
||||||
background-color: #b0b0b0;
|
background-color: var(--color-white-90);
|
||||||
}
|
}
|
||||||
|
|
||||||
.button:hover {
|
.button:hover {
|
||||||
filter: drop-shadow(2px 2px 2px) brightness(95%);
|
filter: drop-shadow(2px 2px 2px var(--color-white-70)) brightness(95%);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +255,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.categories {
|
.categories {
|
||||||
width: 60%;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
/*cursor: grab;*/
|
/*cursor: grab;*/
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
@@ -249,6 +267,7 @@
|
|||||||
border-radius: 1.2em;
|
border-radius: 1.2em;
|
||||||
padding: 0 0.5em 0 0.5em;
|
padding: 0 0.5em 0 0.5em;
|
||||||
margin-right: 0.4em;
|
margin-right: 0.4em;
|
||||||
|
margin-top: 0.5em;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
color: white;
|
color: white;
|
||||||
max-width: 10em;
|
max-width: 10em;
|
||||||
@@ -257,9 +276,12 @@
|
|||||||
/*color-mix(in srgb, var(--main-color) 60%, transparent);*/
|
/*color-mix(in srgb, var(--main-color) 60%, transparent);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
.vote-buttons {
|
/*.vote-buttons {
|
||||||
margin-top: 0.5em;
|
margin-top: 1em;
|
||||||
}
|
width: 100%;
|
||||||
|
display: inline-flex;
|
||||||
|
justify-content: center;
|
||||||
|
}*/
|
||||||
|
|
||||||
.song-title,
|
.song-title,
|
||||||
.song-artist {
|
.song-artist {
|
||||||
@@ -273,28 +295,44 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
padding: 0.1em;
|
font-size: 2rem;
|
||||||
padding-left: 0.2em;
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
font-size: 1.25rem;
|
|
||||||
background-color: var(--color-choriosity-red);
|
|
||||||
color: white;
|
color: white;
|
||||||
/*border-bottom: 0.3rem solid var(--color-choriosity-red--light);*/
|
|
||||||
clear: both;
|
clear: both;
|
||||||
}
|
}
|
||||||
|
|
||||||
#songs h1 .color {
|
h1#title {
|
||||||
border: 0.2rem solid color-mix(in srgb, hsl(calc(var(--hue) * 360), 100%, 40%) 50%, white);
|
margin-top: 30px;
|
||||||
background-color: hsl(calc(var(--hue) * 360), 100%, 40%);
|
|
||||||
border-radius: 0.5em;
|
|
||||||
margin-right: 1em;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#songs h1 {
|
h2 {
|
||||||
border-left: 0.3em solid white;
|
padding: 0.1em;
|
||||||
box-shadow: -1em 0px 0px 0px hsl(calc(var(--hue) * 360), 100%, 40%);
|
padding-left: 0.2em;
|
||||||
margin-left: 1em;
|
margin-bottom: 1rem;
|
||||||
padding-left: 0.3em;
|
padding-top: 1.5rem;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
clear: both;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2:after {
|
||||||
|
content: '';
|
||||||
|
border-top: 2px solid hsl(calc(var(--hue) * 360), 100%, 40%);
|
||||||
|
flex: 1 0 20px;
|
||||||
|
margin: 0 0 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2:before {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
border-radius: 7.5px;
|
||||||
|
background-color: hsl(calc(var(--hue) * 360), 100%, 40%);
|
||||||
|
margin-right: 0.3em;
|
||||||
|
margin-left: 0.3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#yt-player,
|
#yt-player,
|
||||||
@@ -335,17 +373,9 @@ h1 {
|
|||||||
width: 1.5em;
|
width: 1.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#title {
|
|
||||||
margin-top: 1em;
|
|
||||||
font-size: 2rem;
|
|
||||||
/*line-height: 2rem;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
#title-logo {
|
#title-logo {
|
||||||
margin-top: -0.7em;
|
|
||||||
margin-bottom: -0.8em;
|
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
height: 3em;
|
height: 6rem;
|
||||||
filter: drop-shadow(0 0 1px var(--color-choriosity-red--medium));
|
filter: drop-shadow(0 0 1px var(--color-choriosity-red--medium));
|
||||||
margin-right: 1em;
|
margin: 30px 1em 0 1em;
|
||||||
}
|
}
|
||||||
@@ -168,17 +168,20 @@
|
|||||||
abgeben.
|
abgeben.
|
||||||
</div>
|
</div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<h1 id="title"><img id="title-logo" src="https://choriosity.de/assets/images/logo-choriosity_weiss.svg"> Liederwahl
|
<header>
|
||||||
</h1>
|
<img id="title-logo" src="https://choriosity.de/assets/images/logo-choriosity_weiss.svg">
|
||||||
|
<h1 id="title">Liederwahl</h1>
|
||||||
|
</header>
|
||||||
|
|
||||||
<div class="text">Du kannst die Liederwahl jederzeit unterbrechen und zu einem späteren Zeitpunkt weitermachen. Mit
|
<div class="text">Du kannst die Liederwahl jederzeit unterbrechen und zu einem späteren Zeitpunkt weitermachen. Mit
|
||||||
einem Klick auf das Thumbnail kannst du das Lied abspielen.
|
einem Klick auf das Thumbnail kannst du das Lied abspielen.
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div id="songs">
|
<div id="songs">
|
||||||
{% for main_category, songs in songs_by_category.items() %}
|
{% for main_category, songs in songs_by_category.items() %}
|
||||||
<h1 style="--hue: {{ all_categories[main_category] / all_categories|length }};">{{ main_category }}</h1>
|
<h2 style="--hue: {{ all_categories[main_category] / all_categories|length }};">{{ main_category }}</h2>
|
||||||
{% for song in songs -%}
|
{% for song in songs -%}
|
||||||
<div class="song{% if (song.vote == -1) or (not song.vote and not song.singable) %} not_singable{% endif %}"
|
<div style="--hue: {{ all_categories[main_category] / all_categories|length }};" class="song{% if (song.vote == -1) or (not song.vote and not song.singable) %} not_singable{% endif %}"
|
||||||
id="song-{{ song.id }}">
|
id="song-{{ song.id }}">
|
||||||
<div class="cover-container">
|
<div class="cover-container">
|
||||||
<img src="{{ song.thumbnail }}" class="cover">
|
<img src="{{ song.thumbnail }}" class="cover">
|
||||||
@@ -194,7 +197,7 @@
|
|||||||
<div class="categories" id="container">{% for category_name, is_in_category in song.categories.items() %}{%
|
<div class="categories" id="container">{% for category_name, is_in_category in song.categories.items() %}{%
|
||||||
if is_in_category %}<span style="--hue: {{ all_categories[category_name] / all_categories|length }};">{{
|
if is_in_category %}<span style="--hue: {{ all_categories[category_name] / all_categories|length }};">{{
|
||||||
category_name }}</span>{%
|
category_name }}</span>{%
|
||||||
endif %}{% endfor %}<span style="--main-color: transparent;"> </span>
|
endif %}{% endfor %}<span style="--main-color: transparent; --hue: transparent;"> </span>
|
||||||
</div>
|
</div>
|
||||||
<div class="vote-buttons">
|
<div class="vote-buttons">
|
||||||
<div class="button button-no {% if (song.vote == -1) or (not song.vote and not song.singable) %}selected{% endif %}"
|
<div class="button button-no {% if (song.vote == -1) or (not song.vote and not song.singable) %}selected{% endif %}"
|
||||||
|
|||||||
Reference in New Issue
Block a user