Compare commits
2 Commits
dev
...
fb9d6590cd
| Author | SHA1 | Date | |
|---|---|---|---|
| fb9d6590cd | |||
| 0ca97f2444 |
@@ -1,7 +1,18 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
from htmlmin import minify
|
||||
from flask import Blueprint, render_template, send_from_directory, send_file, abort
|
||||
from datetime import datetime, timedelta
|
||||
from musicbrainzngs import get_image_front
|
||||
from flask import (
|
||||
Blueprint,
|
||||
render_template,
|
||||
send_file,
|
||||
send_from_directory,
|
||||
make_response,
|
||||
abort,
|
||||
)
|
||||
|
||||
from .modules.api.lb import listens, listening
|
||||
|
||||
bp = Blueprint(
|
||||
"risdeveau",
|
||||
@@ -11,10 +22,10 @@ bp = Blueprint(
|
||||
static_folder=None
|
||||
)
|
||||
|
||||
def render_tmpl(filename: str) -> str:
|
||||
def render_tmpl(filename: str, **kwargs) -> str:
|
||||
template_path = os.path.join("risdeveau/templates", filename)
|
||||
return minify(
|
||||
render_template(template_path),
|
||||
render_template(template_path, **kwargs),
|
||||
remove_empty_space=True
|
||||
)
|
||||
|
||||
@@ -26,14 +37,14 @@ def static(filename: str):
|
||||
return send_file(path)
|
||||
return abort(404)
|
||||
|
||||
@bp.route("/asset/mb/<mbid>")
|
||||
def mb_cover(mbid):
|
||||
r = make_response(get_image_front(mbid, "250"))
|
||||
r.headers['Cache-Control'] = 'public, max-age=86400'
|
||||
r.headers['Expires'] = (datetime.now() + timedelta(days=1)) \
|
||||
.strftime('%a, %d %b %Y %H:%M:%S GMT')
|
||||
return r
|
||||
|
||||
@bp.route("/")
|
||||
def index():
|
||||
return render_tmpl('index.html')
|
||||
|
||||
@bp.route("/contacts")
|
||||
def contacts():
|
||||
return render_tmpl('contacts.html')
|
||||
|
||||
@bp.route("/donate")
|
||||
def donate():
|
||||
return render_tmpl('donate.html')
|
||||
return render_tmpl('index.html', lb=listens, lb_now=listening)
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
from flask import Flask, jsonify
|
||||
from apscheduler.schedulers.background import BackgroundScheduler
|
||||
from apscheduler.triggers.interval import IntervalTrigger
|
||||
import requests
|
||||
from datetime import datetime
|
||||
import atexit
|
||||
import re
|
||||
from urllib.parse import urlparse, parse_qs
|
||||
|
||||
listens = {}
|
||||
listening = {}
|
||||
|
||||
def yt_cover(youtube_url):
|
||||
parsed_url = urlparse(youtube_url)
|
||||
|
||||
if parsed_url.netloc in ("youtube.com", "music.youtube.com"):
|
||||
query_params = parse_qs(parsed_url.query)
|
||||
video_id = query_params.get('v', [None])[0]
|
||||
|
||||
elif parsed_url.netloc == 'youtu.be':
|
||||
video_id = parsed_url.path[1:]
|
||||
|
||||
if not video_id:
|
||||
return
|
||||
|
||||
return f"http://img.youtube.com/vi/{video_id}/sddefault.jpg"
|
||||
|
||||
def parse_listens(data: dict) -> dict:
|
||||
new_data = {
|
||||
"count": data["count"],
|
||||
"listens": []
|
||||
}
|
||||
|
||||
for track in data["listens"]:
|
||||
track = track["track_metadata"]
|
||||
|
||||
new_track = {
|
||||
"artist_name": track["artist_name"],
|
||||
"track_name": track["track_name"]
|
||||
}
|
||||
|
||||
if mb := track.get("mbid_mapping"):
|
||||
new_track["id"] = mb["caa_release_mbid"]
|
||||
new_track["artist_name"] = mb["artists"][0]["artist_credit_name"]
|
||||
new_track["track_name"] = mb["recording_name"]
|
||||
elif info := track.get("additional_info"):
|
||||
if info \
|
||||
.get("music_service_name", "") \
|
||||
.lower() in ("youtube", "youtube music"):
|
||||
if cover := yt_cover(track["additional_info"]["origin_url"]):
|
||||
new_track["cover_url"] = cover
|
||||
|
||||
if "cover_url" not in new_track.keys() and "id" in new_track.keys():
|
||||
new_track["cover_url"] = "/asset/mb/" + new_track["id"]
|
||||
|
||||
new_data["listens"].append(new_track)
|
||||
|
||||
return new_data
|
||||
|
||||
def api_request(url: str, cache):
|
||||
try:
|
||||
response = requests.get(url, timeout=10)
|
||||
if response.status_code == 200:
|
||||
cache.update({
|
||||
'data': parse_listens(response.json().get("payload")),
|
||||
'last_updated': datetime.now().isoformat(),
|
||||
'status': 'success'
|
||||
})
|
||||
else:
|
||||
cache['status'] = f'error: {response.status_code}'
|
||||
except Exception as e:
|
||||
cache['status'] = f'error: {str(e)}'
|
||||
|
||||
scheduler = BackgroundScheduler()
|
||||
scheduler.add_job(
|
||||
func=lambda: api_request("https://api.listenbrainz.org/1/user/risdeveau/listens?count=5", listens),
|
||||
trigger=IntervalTrigger(minutes=1),
|
||||
id='risdeveau.listenbrainz.listens',
|
||||
replace_existing=True
|
||||
)
|
||||
scheduler.add_job(
|
||||
func=lambda: api_request("https://api.listenbrainz.org/1/user/risdeveau/playing-now", listening),
|
||||
trigger=IntervalTrigger(seconds=15),
|
||||
id='risdeveau.listenbrainz.playing-now',
|
||||
replace_existing=True
|
||||
)
|
||||
scheduler.start()
|
||||
|
||||
atexit.register(lambda: scheduler.shutdown())
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 13 KiB |
@@ -1,29 +1,5 @@
|
||||
@use "sass:color";
|
||||
|
||||
// Palette: Catppuccin Mocha
|
||||
// https://catppuccin.com/palette/
|
||||
$base: #1e1e2e;
|
||||
$text: #cdd6f4;
|
||||
|
||||
$mantle: #181825;
|
||||
$crust: #11111b;
|
||||
|
||||
$overlay0: #6c7086;
|
||||
$overlay1: #7f849c;
|
||||
$overlay2: #9399b2;
|
||||
|
||||
$surface0: #313244;
|
||||
$surface1: #45475a;
|
||||
$surface2: #585b70;
|
||||
|
||||
$subtext0: #a6adc8;
|
||||
$subtext1: #bac2de;
|
||||
|
||||
$red: #f38ba8;
|
||||
$green: #a6e3a1;
|
||||
$peach: #fab387;
|
||||
$blue: #89b4fa;
|
||||
$mauve: #8839ef;
|
||||
@use "../../../root/static/style/catppuccin" as theme;
|
||||
|
||||
h3 {
|
||||
margin-block-end: 0;
|
||||
@@ -58,6 +34,20 @@ h3 {
|
||||
}
|
||||
}
|
||||
|
||||
.track {
|
||||
display: flex;
|
||||
|
||||
&.active {
|
||||
box-shadow: theme.$green 0 0 5px 0;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 5rem;
|
||||
height: 5rem;
|
||||
border-radius: .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
table, tbody {
|
||||
vertical-align: baseline;
|
||||
border-collapse: collapse;
|
||||
@@ -66,7 +56,7 @@ table, tbody {
|
||||
border-radius: 10px;
|
||||
|
||||
&:hover {
|
||||
background-color: color.change($surface1, $alpha:75%);
|
||||
background-color: color.change(theme.$surface1, $alpha:75%);
|
||||
}
|
||||
|
||||
th {
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
<div>
|
||||
<div class="88-31">
|
||||
<a href="https://chest.lair.moe" class="disabled">
|
||||
<img src="/static/img/88x31/gf.png"/>
|
||||
</a>
|
||||
<a href="https://preview.about.akarpov.ru" id="pie">
|
||||
<img src="/static/img/88x31/withpie.gif"/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="88-31">
|
||||
<a href="https://g.lair.moe/Sweetbread/nixos-config">
|
||||
<img src="/static/img/88x31/nixos.webp"/>
|
||||
</a>
|
||||
<img src="/static/img/88x31/teto.webp"/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,24 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Sweet Bread</title>
|
||||
|
||||
<link rel="stylesheet" href="/static/style/main.css">
|
||||
<link rel="stylesheet" href="/static/style/risdeveau.css">
|
||||
<link rel="icon" type="image/webp" href="/static/icon/us/risdeveau.webp" />
|
||||
<script
|
||||
src="https://track.lair.moe/api/script.js"
|
||||
data-site-id="1"
|
||||
defer
|
||||
></script>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
{% block head %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
{% include 'risdeveau/templates/header.tmpl' %}
|
||||
|
||||
<main>
|
||||
{% block content %}{% endblock %}
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
+2
-12
@@ -1,14 +1,4 @@
|
||||
{% extends 'risdeveau/templates/base.tmpl' %}
|
||||
|
||||
{% block head %}
|
||||
<style>
|
||||
main {
|
||||
width: -webkit-fill-available;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="block">
|
||||
<h3>Development</h3>
|
||||
<div class="blocks badges">
|
||||
<a class="block" href="//g.lair.moe/Sweetbread">
|
||||
@@ -55,4 +45,4 @@
|
||||
GameBanana
|
||||
</a>
|
||||
</div>
|
||||
{% endblock %}
|
||||
</div>
|
||||
@@ -0,0 +1,19 @@
|
||||
<div>
|
||||
<h3>Wallets</h3>
|
||||
<div class="blocks qr">
|
||||
<div class="block qr">
|
||||
<p>POL, BNB</p>
|
||||
<img src="/static/img/wallets/evm.webp">
|
||||
</div>
|
||||
|
||||
<div class="block qr">
|
||||
<p>TON</p>
|
||||
<img src="/static/img/wallets/ton.webp">
|
||||
</div>
|
||||
|
||||
<div class="block qr">
|
||||
<p>XMR</p>
|
||||
<img src="/static/img/wallets/xmr.webp">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,21 +0,0 @@
|
||||
{% extends 'risdeveau/templates/base.tmpl' %}
|
||||
|
||||
{% block content %}
|
||||
<h3>Wallets</h3>
|
||||
<div class="blocks qr">
|
||||
<div class="block qr">
|
||||
<p>POL, BNB</p>
|
||||
<img src="/static/img/wallets/evm.webp">
|
||||
</div>
|
||||
|
||||
<div class="block qr">
|
||||
<p>TON</p>
|
||||
<img src="/static/img/wallets/ton.webp">
|
||||
</div>
|
||||
|
||||
<div class="block qr">
|
||||
<p>XMR</p>
|
||||
<img src="/static/img/wallets/xmr.webp">
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -1,20 +0,0 @@
|
||||
<header>
|
||||
{%- if request.path != url_for('.index') %}
|
||||
<a href="{{ url_for('.index') }}">Main</a>
|
||||
{%- else %}
|
||||
<a href="{{ url_for('root.index') }}">Lair</a>
|
||||
{%- endif %}
|
||||
|
||||
<div class="header-links">
|
||||
{%- for (l, t) in (
|
||||
('.contacts', _('contacts')),
|
||||
('.donate', _('donate'))
|
||||
) %}
|
||||
{%- if url_for(l) == request.path %}
|
||||
<strong>{{ t }}</strong>
|
||||
{%- else %}
|
||||
<a href="{{ url_for(l) }}">{{ t }}</a>
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
</div>
|
||||
</header>
|
||||
@@ -1,69 +1,34 @@
|
||||
{% extends 'risdeveau/templates/base.tmpl' %}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Sweet Bread</title>
|
||||
|
||||
{% block content %}
|
||||
<div class="block">
|
||||
<table>
|
||||
<tr>
|
||||
<th>DoB</th>
|
||||
<td>2005-01-13</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Languages</th>
|
||||
<td>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Russian</td>
|
||||
<td>Native</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>English</td>
|
||||
<td>B2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>French</td>
|
||||
<td>A1?</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>German</td>
|
||||
<td>A2?</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Japanese</td>
|
||||
<td>Beginner</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Student</th>
|
||||
<td>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Programmer</td>
|
||||
<td>2/4yr.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Translator</td>
|
||||
<td>2/3yr.</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<link rel="stylesheet" href="/static/style/main.css">
|
||||
<link rel="stylesheet" href="/static/style/risdeveau.css">
|
||||
<link rel="stylesheet" href="/static/style/track.css">
|
||||
<link rel="icon" type="image/webp" href="/static/icon/us/risdeveau.webp" />
|
||||
<script
|
||||
src="https://track.lair.moe/api/script.js"
|
||||
data-site-id="1"
|
||||
defer
|
||||
></script>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<a href="{{ url_for('root.index') }}">Lair</a>
|
||||
</header>
|
||||
|
||||
<div class="88-31">
|
||||
<a href="https://chest.lair.moe" class="disabled">
|
||||
<img src="/static/img/88x31/gf.png"/>
|
||||
</a>
|
||||
<a href="https://preview.about.akarpov.ru" id="pie">
|
||||
<img src="/static/img/88x31/withpie.gif"/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="88-31">
|
||||
<a href="https://g.lair.moe/Sweetbread/nixos-config">
|
||||
<img src="/static/img/88x31/nixos.webp"/>
|
||||
</a>
|
||||
<img src="/static/img/88x31/teto.webp"/>
|
||||
</div>
|
||||
{% endblock %}
|
||||
<main>
|
||||
{% for m in (
|
||||
'info',
|
||||
'contacts',
|
||||
'listenbrainz',
|
||||
'donate',
|
||||
'88x31'
|
||||
) %}
|
||||
{% include 'risdeveau/templates/%s.htm' % m %}
|
||||
{% endfor %}
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
<div class="block">
|
||||
<table>
|
||||
<tr>
|
||||
<th>DoB</th>
|
||||
<td>2005-01-13</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Languages</th>
|
||||
<td>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Russian</td>
|
||||
<td>Native</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>English</td>
|
||||
<td>B2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>French</td>
|
||||
<td>A1?</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>German</td>
|
||||
<td>A2?</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Japanese</td>
|
||||
<td>Beginner</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Student</th>
|
||||
<td>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Programmer</td>
|
||||
<td>2/4yr.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Translator</td>
|
||||
<td>2/3yr.</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
@@ -0,0 +1,23 @@
|
||||
{% macro track_block(track, is_active=false) %}
|
||||
<div class="block track{% if is_active %} active{% endif %}">
|
||||
{% if track.cover_url %}
|
||||
<img src="{{ track.cover_url }}"/>
|
||||
{% endif %}
|
||||
<div>
|
||||
<p><b>{{ track.artist_name }}</b></p>
|
||||
<p>{{ track.track_name }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
<div class="block">
|
||||
<h2><a href="https://listenbrainz.org/user/risdeveau/">Listenbrainz</a></h2>
|
||||
{% if lb_now.data and lb_now.data.listens.0 %}
|
||||
{{ track_block(lb_now.data.listens.0, is_active=true) }}
|
||||
{% endif %}
|
||||
{% if lb.data and lb.data.listens %}
|
||||
{% for track in lb.data.listens %}
|
||||
{{ track_block(track) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -0,0 +1,24 @@
|
||||
// Palette: Catppuccin Mocha
|
||||
// https://catppuccin.com/palette/
|
||||
$base: #1e1e2e;
|
||||
$text: #cdd6f4;
|
||||
|
||||
$mantle: #181825;
|
||||
$crust: #11111b;
|
||||
|
||||
$overlay0: #6c7086;
|
||||
$overlay1: #7f849c;
|
||||
$overlay2: #9399b2;
|
||||
|
||||
$surface0: #313244;
|
||||
$surface1: #45475a;
|
||||
$surface2: #585b70;
|
||||
|
||||
$subtext0: #a6adc8;
|
||||
$subtext1: #bac2de;
|
||||
|
||||
$red: #f38ba8;
|
||||
$green: #a6e3a1;
|
||||
$peach: #fab387;
|
||||
$blue: #89b4fa;
|
||||
$mauve: #8839ef;
|
||||
@@ -1,29 +1,5 @@
|
||||
@use "sass:color";
|
||||
|
||||
// Palette: Catppuccin Mocha
|
||||
// https://catppuccin.com/palette/
|
||||
$base: #1e1e2e;
|
||||
$text: #cdd6f4;
|
||||
|
||||
$mantle: #181825;
|
||||
$crust: #11111b;
|
||||
|
||||
$overlay0: #6c7086;
|
||||
$overlay1: #7f849c;
|
||||
$overlay2: #9399b2;
|
||||
|
||||
$surface0: #313244;
|
||||
$surface1: #45475a;
|
||||
$surface2: #585b70;
|
||||
|
||||
$subtext0: #a6adc8;
|
||||
$subtext1: #bac2de;
|
||||
|
||||
$red: #f38ba8;
|
||||
$green: #a6e3a1;
|
||||
$peach: #fab387;
|
||||
$blue: #89b4fa;
|
||||
$mauve: #8839ef;
|
||||
@use "catppuccin" as theme;
|
||||
|
||||
|
||||
html {
|
||||
@@ -33,9 +9,9 @@ html {
|
||||
body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: $base;
|
||||
background-color: theme.$base;
|
||||
font-family: Pixeloid, PixelMPlus;
|
||||
color: $text;
|
||||
color: theme.$text;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
@@ -55,7 +31,7 @@ h1 {
|
||||
a {
|
||||
color: unset;
|
||||
text: {
|
||||
decoration: underline {color: $blue};
|
||||
decoration: underline {color: theme.$blue};
|
||||
underline-offset: 1px;
|
||||
}
|
||||
transition: 0.3s ease;
|
||||
@@ -68,7 +44,7 @@ a {
|
||||
transition: none !important;
|
||||
display: inline-block;
|
||||
transform: scale(.98) !important;
|
||||
background-color: $mantle !important;
|
||||
background-color: theme.$mantle !important;
|
||||
}
|
||||
|
||||
&.block {
|
||||
@@ -76,7 +52,7 @@ a {
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.02) translateY(-.25rem);
|
||||
background-color: $surface1;
|
||||
background-color: theme.$surface1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,7 +68,7 @@ ul {
|
||||
header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
background-color: $mantle;
|
||||
background-color: theme.$mantle;
|
||||
padding: .5rem;
|
||||
font-size: larger;
|
||||
|
||||
@@ -105,7 +81,7 @@ footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
background-color: $mantle;
|
||||
background-color: theme.$mantle;
|
||||
margin-top: 2rem;
|
||||
padding: 1rem;
|
||||
column-gap: 4ch;
|
||||
@@ -113,38 +89,48 @@ footer {
|
||||
|
||||
.mono {
|
||||
font-family: Monocraft, monospace;
|
||||
background-color: $mantle;
|
||||
background-color: theme.$mantle;
|
||||
border-radius: 2px;
|
||||
padding: 0 .25rem;
|
||||
color: $subtext0;
|
||||
color: theme.$subtext0;
|
||||
overflow-wrap: anywhere;
|
||||
|
||||
&:hover {
|
||||
transition: .3s ease;
|
||||
background-color: $crust;
|
||||
background-color: theme.$crust;
|
||||
}
|
||||
}
|
||||
|
||||
.block {
|
||||
display: block;
|
||||
background-color: $surface0;
|
||||
background-color: theme.$surface0;
|
||||
border-radius: .5rem;
|
||||
padding: .5rem;
|
||||
|
||||
h2 {
|
||||
margin: -.5rem -.5rem 1rem;
|
||||
padding: .5rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.block {
|
||||
background-color: theme.$surface1;
|
||||
}
|
||||
|
||||
& + & {
|
||||
margin-top: .5rem;
|
||||
}
|
||||
|
||||
&.red {
|
||||
background-color: color.mix($surface0, $red, 60%);
|
||||
background-color: color.mix(theme.$surface0, theme.$red, 60%);
|
||||
}
|
||||
&.orange {
|
||||
background-color: color.mix($surface0, $peach, 60%);
|
||||
background-color: color.mix(theme.$surface0, theme.$peach, 60%);
|
||||
}
|
||||
&.green {
|
||||
background-color: color.mix($surface0, $green, 60%);
|
||||
&:hover { background-color: color.mix($surface1, $green, 60%); }
|
||||
&:active { background-color: color.mix($mantle, $green, 60%) !important; }
|
||||
background-color: color.mix(theme.$surface0, theme.$green, 60%);
|
||||
&:hover { background-color: color.mix(theme.$surface1, theme.$green, 60%); }
|
||||
&:active { background-color: color.mix(theme.$mantle, theme.$green, 60%) !important; }
|
||||
}
|
||||
|
||||
& .header {
|
||||
@@ -215,9 +201,12 @@ footer {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
img {
|
||||
a, img {
|
||||
width: 88px;
|
||||
height: 31px;
|
||||
}
|
||||
|
||||
img {
|
||||
transition-timing-function: ease-out;
|
||||
transition-duration: .2s;
|
||||
|
||||
@@ -244,15 +233,15 @@ footer {
|
||||
}
|
||||
|
||||
&-track {
|
||||
background-color: $base;
|
||||
background-color: theme.$base;
|
||||
}
|
||||
|
||||
&-thumb {
|
||||
background-color: $overlay0;
|
||||
background-color: theme.$overlay0;
|
||||
border-radius: .25rem;
|
||||
|
||||
&:hover {
|
||||
background-color: $overlay1;
|
||||
background-color: theme.$overlay1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,13 @@
|
||||
></script>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="mock-email" content="admin@example.com">
|
||||
|
||||
<!-- og meta -->
|
||||
<meta property="og:type" value="website" />
|
||||
<meta property="og:url" value="https://lair.moe" />
|
||||
<meta property="og:title" value="Lair.moe" />
|
||||
<meta property="og:image" value="https://lair.moe/static/icon/lair.webp" />
|
||||
<meta property="og:description" value="{{ _("description") }}" />
|
||||
</head>
|
||||
<body>
|
||||
{% include 'header.tmpl' %}
|
||||
|
||||
@@ -49,10 +49,4 @@
|
||||
<span class="mono">200:ee1:bad2:1732:4b91:c3e3:2f08:29b3</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="webring disabled">
|
||||
<a class="block" href="https://otor.ing/lair/prev"><</a>
|
||||
<a class="block" href="https://otor.ing/">Otoring</a>
|
||||
<a class="block" href="https://otor.ing/lair/next">></a>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
Flask==3.1.1
|
||||
gunicorn
|
||||
htmlmin2
|
||||
requests
|
||||
APScheduler
|
||||
musicbrainzngs
|
||||
|
||||
Reference in New Issue
Block a user