2 Commits
1.2.1 ... 1.3.0

Author SHA1 Message Date
d4cf9a53dd export results to csv
All checks were successful
release-tag / release-image (push) Successful in 5m49s
2024-07-11 22:00:22 +02:00
b1891fb51d Change styling (Felix) 2024-07-11 19:42:07 +02:00
3 changed files with 81 additions and 40 deletions

View File

@@ -3,12 +3,14 @@ import numpy as np
import re
import requests
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 app.database import get_db, engine, Base
from app.security import get_current_user
from app.crud import create_song, get_setting, set_setting, get_all_songs_and_votes
from typing import Any
router = APIRouter(
prefix="/admin",
@@ -130,5 +132,13 @@ async def toggle_veto_mode(db: Session = Depends(get_db)) -> bool:
@router.get("/results")
async def get_evaluation(db = Depends(get_db)) -> list:
return get_all_songs_and_votes(db)
async def get_evaluation(format: str = "json", db = Depends(get_db)) -> Any:
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")

View File

@@ -52,6 +52,24 @@
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,
.cover-container,
.categories {
@@ -73,7 +91,6 @@
}
}
.text {
padding: 0.3em;
margin-bottom: 0.7em;
@@ -87,6 +104,9 @@
.song {
background-color: var(--color-choriosity-red--light);
background-color: var(--color-white-100);
border: 1px solid var(--color-choriosity-red);
box-shadow: 4px 4px 8px var(--color-white-90);
padding: 0.4em;
border-radius: 0.5em;
width: 30em;
@@ -95,7 +115,6 @@
float: left;
}
.cover-container {
position: relative;
width: 10.67em;
@@ -119,7 +138,6 @@
transition: .3s ease;
}
.overlay {
position: absolute;
top: 0;
@@ -161,7 +179,6 @@
height: 60%;
}
.vote-buttons {
display: inline-block;
}
@@ -211,11 +228,11 @@
}
.button:not(.selected):not(:hover) {
background-color: #b0b0b0;
background-color: var(--color-white-90);
}
.button:hover {
filter: drop-shadow(2px 2px 2px) brightness(95%);
filter: drop-shadow(2px 2px 2px var(--color-white-70)) brightness(95%);
cursor: pointer;
}
@@ -236,7 +253,6 @@
}
.categories {
width: 60%;
overflow: hidden;
/*cursor: grab;*/
white-space: nowrap;
@@ -249,6 +265,7 @@
border-radius: 1.2em;
padding: 0 0.5em 0 0.5em;
margin-right: 0.4em;
margin-top: 0.5em;
display: inline-block;
color: white;
max-width: 10em;
@@ -258,7 +275,10 @@
}
.vote-buttons {
margin-top: 0.5em;
margin-top: 1em;
width: 100%;
display: inline-flex;
justify-content: center;
}
.song-title,
@@ -273,28 +293,44 @@
}
h1 {
padding: 0.1em;
padding-left: 0.2em;
margin-bottom: 1rem;
font-size: 1.25rem;
background-color: var(--color-choriosity-red);
font-size: 2rem;
color: white;
/*border-bottom: 0.3rem solid var(--color-choriosity-red--light);*/
clear: both;
}
#songs h1 .color {
border: 0.2rem solid color-mix(in srgb, hsl(calc(var(--hue) * 360), 100%, 40%) 50%, white);
background-color: hsl(calc(var(--hue) * 360), 100%, 40%);
border-radius: 0.5em;
margin-right: 1em;
h1#title {
margin-top: 30px;
}
#songs h1 {
border-left: 0.3em solid white;
box-shadow: -1em 0px 0px 0px hsl(calc(var(--hue) * 360), 100%, 40%);
margin-left: 1em;
padding-left: 0.3em;
h2 {
padding: 0.1em;
padding-left: 0.2em;
margin-bottom: 1rem;
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,
@@ -335,17 +371,9 @@ h1 {
width: 1.5em;
}
#title {
margin-top: 1em;
font-size: 2rem;
/*line-height: 2rem;*/
}
#title-logo {
margin-top: -0.7em;
margin-bottom: -0.8em;
vertical-align: middle;
height: 3em;
height: 6rem;
filter: drop-shadow(0 0 1px var(--color-choriosity-red--medium));
margin-right: 1em;
margin: 30px 1em 0 1em;
}

View File

@@ -168,15 +168,18 @@
abgeben.
</div>
{% else %}
<h1 id="title"><img id="title-logo" src="https://choriosity.de/assets/images/logo-choriosity_weiss.svg"> Liederwahl
</h1>
<header>
<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
einem Klick auf das Thumbnail kannst du das Lied abspielen.
</div>
{% endif %}
<div id="songs">
{% 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 -%}
<div class="song{% if (song.vote == -1) or (not song.vote and not song.singable) %} not_singable{% endif %}"
id="song-{{ song.id }}">