Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5074455dac | |||
| d4cf9a53dd | |||
| b1891fb51d | |||
|
|
5ba472db42 |
14
app/crud.py
14
app/crud.py
@@ -2,6 +2,7 @@ import app.models as models
|
||||
from sqlalchemy.orm.attributes import flag_modified
|
||||
|
||||
from sqlalchemy.sql import text
|
||||
import pickle
|
||||
|
||||
def get_songs_and_vote_for_session(db, session_name) -> list[models.Song]:
|
||||
session_entry = activate_session(db, session_name)
|
||||
@@ -21,6 +22,7 @@ def get_all_songs_and_votes(db) -> list:
|
||||
songs.aca_artist,
|
||||
songs.title,
|
||||
songs.url,
|
||||
songs.categories,
|
||||
COUNT(vote) FILTER (where vote = -1) as "nein" ,
|
||||
COUNT(vote) FILTER (where vote = 0) as "neutral",
|
||||
COUNT(vote) FILTER (where vote = 1) as "ja"
|
||||
@@ -28,7 +30,17 @@ def get_all_songs_and_votes(db) -> list:
|
||||
GROUP BY song_id ORDER BY song_id
|
||||
""")).fetchall()
|
||||
|
||||
return [dict(r._mapping) for r in res]
|
||||
def process_row(r):
|
||||
e = dict(r._mapping)
|
||||
c = pickle.loads(e["categories"])
|
||||
c = {k : bool(v) for k, v in c.items()}
|
||||
e["categories"] = c
|
||||
|
||||
return e
|
||||
|
||||
res = [process_row(r) for r in res]
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def create_song(db,
|
||||
|
||||
@@ -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")
|
||||
|
||||
104
static/site.css
104
static/site.css
@@ -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,10 @@
|
||||
|
||||
.song {
|
||||
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;
|
||||
border-radius: 0.5em;
|
||||
width: 30em;
|
||||
@@ -95,11 +116,10 @@
|
||||
float: left;
|
||||
}
|
||||
|
||||
|
||||
.cover-container {
|
||||
position: relative;
|
||||
width: 10.67em;
|
||||
height: 6em;
|
||||
height: 6.7em;
|
||||
float: left;
|
||||
margin-right: 1em;
|
||||
text-align: center;
|
||||
@@ -119,7 +139,6 @@
|
||||
transition: .3s ease;
|
||||
}
|
||||
|
||||
|
||||
.overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@@ -161,9 +180,9 @@
|
||||
height: 60%;
|
||||
}
|
||||
|
||||
|
||||
.vote-buttons {
|
||||
display: inline-block;
|
||||
margin-top: 0.7em;
|
||||
}
|
||||
|
||||
.button {
|
||||
@@ -211,11 +230,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 +255,6 @@
|
||||
}
|
||||
|
||||
.categories {
|
||||
width: 60%;
|
||||
overflow: hidden;
|
||||
/*cursor: grab;*/
|
||||
white-space: nowrap;
|
||||
@@ -249,6 +267,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;
|
||||
@@ -257,9 +276,12 @@
|
||||
/*color-mix(in srgb, var(--main-color) 60%, transparent);*/
|
||||
}
|
||||
|
||||
.vote-buttons {
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
/*.vote-buttons {
|
||||
margin-top: 1em;
|
||||
width: 100%;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
}*/
|
||||
|
||||
.song-title,
|
||||
.song-artist {
|
||||
@@ -273,28 +295,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 +373,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;
|
||||
}
|
||||
@@ -168,17 +168,20 @@
|
||||
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 %}"
|
||||
<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 }}">
|
||||
<div class="cover-container">
|
||||
<img src="{{ song.thumbnail }}" class="cover">
|
||||
|
||||
Reference in New Issue
Block a user