theme color and style fix
This commit is contained in:
parent
b7c4360560
commit
ed1608847f
34
app.py
34
app.py
@ -9,6 +9,7 @@ from datetime import datetime, date, timedelta
|
|||||||
import diskcache
|
import diskcache
|
||||||
import json
|
import json
|
||||||
import geoip2.database
|
import geoip2.database
|
||||||
|
from functools import lru_cache
|
||||||
from urllib.parse import urlparse, unquote
|
from urllib.parse import urlparse, unquote
|
||||||
from werkzeug.middleware.proxy_fix import ProxyFix
|
from werkzeug.middleware.proxy_fix import ProxyFix
|
||||||
cache = diskcache.Cache('./filecache', size_limit= 48 * 1024**3) # 32 GB limit
|
cache = diskcache.Cache('./filecache', size_limit= 48 * 1024**3) # 32 GB limit
|
||||||
@ -37,16 +38,12 @@ def require_secret(f):
|
|||||||
today = date.today()
|
today = date.today()
|
||||||
|
|
||||||
def is_valid(secret_data):
|
def is_valid(secret_data):
|
||||||
print("is_valid:", secret_data)
|
|
||||||
expiry_date = secret_data.get('expiry')
|
expiry_date = secret_data.get('expiry')
|
||||||
is_valid = expiry_date and today <= expiry_date
|
is_valid = expiry_date and today <= expiry_date
|
||||||
print("is_valid", is_valid)
|
|
||||||
return is_valid
|
return is_valid
|
||||||
|
|
||||||
# Check if a secret was provided via GET parameter
|
# Check if a secret was provided via GET parameter
|
||||||
get_secret = request.args.get('secret')
|
get_secret = request.args.get('secret')
|
||||||
print("request.args:", request.args)
|
|
||||||
print("get_secret:", get_secret)
|
|
||||||
if get_secret is not None:
|
if get_secret is not None:
|
||||||
secret_data = allowed_secrets.get(get_secret)
|
secret_data = allowed_secrets.get(get_secret)
|
||||||
if secret_data:
|
if secret_data:
|
||||||
@ -65,7 +62,6 @@ def require_secret(f):
|
|||||||
|
|
||||||
# If no secret provided via GET, check the session
|
# If no secret provided via GET, check the session
|
||||||
session_secret = session.get('secret')
|
session_secret = session.get('secret')
|
||||||
print("session_secret", session_secret)
|
|
||||||
if session_secret is not None:
|
if session_secret is not None:
|
||||||
secret_data = allowed_secrets.get(session_secret)
|
secret_data = allowed_secrets.get(session_secret)
|
||||||
if secret_data:
|
if secret_data:
|
||||||
@ -82,32 +78,33 @@ def require_secret(f):
|
|||||||
|
|
||||||
return decorated_function
|
return decorated_function
|
||||||
|
|
||||||
@app.route('/static/icons/<string:size>.png')
|
@lru_cache(maxsize=10)
|
||||||
def serve_resized_icon(size):
|
def get_cached_image(size):
|
||||||
dimensions = tuple(map(int, size.split('-')[1].split('x')))
|
dimensions = tuple(map(int, size.split('-')[1].split('x')))
|
||||||
original_logo_path = os.path.join(app.root_path, 'static', 'logo.png')
|
original_logo_path = os.path.join(app.root_path, 'static', 'logo.png')
|
||||||
|
|
||||||
with Image.open(original_logo_path) as img:
|
with Image.open(original_logo_path) as img:
|
||||||
img = img.convert("RGBA")
|
img = img.convert("RGBA")
|
||||||
|
|
||||||
# Original image dimensions
|
|
||||||
orig_width, orig_height = img.size
|
orig_width, orig_height = img.size
|
||||||
|
|
||||||
# Check if requested dimensions exceed original dimensions
|
|
||||||
if dimensions[0] >= orig_width and dimensions[1] >= orig_height:
|
if dimensions[0] >= orig_width and dimensions[1] >= orig_height:
|
||||||
# Requested size is larger or equal; return original image
|
resized_img = img
|
||||||
return send_file(original_logo_path, mimetype='image/png')
|
else:
|
||||||
|
|
||||||
# Otherwise, resize
|
|
||||||
resized_img = img.copy()
|
resized_img = img.copy()
|
||||||
resized_img.thumbnail(dimensions, Image.LANCZOS)
|
resized_img.thumbnail(dimensions, Image.LANCZOS)
|
||||||
|
|
||||||
# Save resized image to bytes
|
img_byte_arr = io.BytesIO()
|
||||||
resized_bytes = io.BytesIO()
|
resized_img.save(img_byte_arr, format='PNG')
|
||||||
resized_img.save(resized_bytes, format='PNG')
|
return img_byte_arr.getvalue()
|
||||||
resized_bytes.seek(0)
|
|
||||||
|
|
||||||
return send_file(resized_bytes, mimetype='image/png')
|
@app.route('/static/icons/<string:size>.png')
|
||||||
|
def serve_resized_icon(size):
|
||||||
|
cached_image_bytes = get_cached_image(size)
|
||||||
|
return send_file(
|
||||||
|
io.BytesIO(cached_image_bytes),
|
||||||
|
mimetype='image/png'
|
||||||
|
)
|
||||||
|
|
||||||
@app.route('/sw.js')
|
@app.route('/sw.js')
|
||||||
def serve_sw():
|
def serve_sw():
|
||||||
@ -194,7 +191,6 @@ def generate_breadcrumbs(subpath):
|
|||||||
@app.route('/api/path/<path:subpath>')
|
@app.route('/api/path/<path:subpath>')
|
||||||
@require_secret
|
@require_secret
|
||||||
def api_browse(subpath):
|
def api_browse(subpath):
|
||||||
print("subpath:", subpath)
|
|
||||||
file_root = app.config['FILE_ROOT']
|
file_root = app.config['FILE_ROOT']
|
||||||
directory = os.path.join(file_root, subpath.replace('/', os.sep))
|
directory = os.path.join(file_root, subpath.replace('/', os.sep))
|
||||||
|
|
||||||
|
|||||||
@ -14,20 +14,21 @@ function encodeSubpath(subpath) {
|
|||||||
// Global variable for gallery images (updated from current folder)
|
// Global variable for gallery images (updated from current folder)
|
||||||
let currentGalleryImages = [];
|
let currentGalleryImages = [];
|
||||||
|
|
||||||
// Render breadcrumbs, directories (grid view when appropriate), and files.
|
|
||||||
function renderContent(data) {
|
function renderContent(data) {
|
||||||
|
|
||||||
|
// Render breadcrumbs, directories (grid view when appropriate), and files.
|
||||||
let breadcrumbHTML = '';
|
let breadcrumbHTML = '';
|
||||||
data.breadcrumbs.forEach((crumb, index) => {
|
data.breadcrumbs.forEach((crumb, index) => {
|
||||||
breadcrumbHTML += `<a href="#" class="breadcrumb-link" data-path="${crumb.path}">${crumb.name}</a>`;
|
breadcrumbHTML += `<a href="#" data-path="${crumb.path}">${crumb.name}</a>`;
|
||||||
if (index < data.breadcrumbs.length - 1) {
|
if (index < data.breadcrumbs.length - 1) {
|
||||||
breadcrumbHTML += `<span>></span>`;
|
breadcrumbHTML += `<span>></span>`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
document.getElementById('breadcrumbs').innerHTML = breadcrumbHTML;
|
document.getElementById('breadcrumbs').innerHTML = breadcrumbHTML;
|
||||||
|
|
||||||
let contentHTML = '';
|
|
||||||
|
|
||||||
// Render directories.
|
// Render directories.
|
||||||
|
let contentHTML = '';
|
||||||
if (data.directories.length > 0) {
|
if (data.directories.length > 0) {
|
||||||
contentHTML += '<ul>';
|
contentHTML += '<ul>';
|
||||||
// Check if every directory name is short (≤15 characters)
|
// Check if every directory name is short (≤15 characters)
|
||||||
|
|||||||
@ -98,7 +98,7 @@
|
|||||||
/* Style the time info (positioned right below the slider) */
|
/* Style the time info (positioned right below the slider) */
|
||||||
.now-playing-info {
|
.now-playing-info {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 0.8em;
|
font-size: 1em;
|
||||||
margin-top: 0.25em;
|
margin-top: 0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -47,7 +47,6 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Loader for gallery */
|
/* Loader for gallery */
|
||||||
#gallery-loader {
|
#gallery-loader {
|
||||||
display: none; /* Hidden by default */
|
display: none; /* Hidden by default */
|
||||||
|
|||||||
BIN
static/logoW.png
Normal file
BIN
static/logoW.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 188 KiB |
@ -4,7 +4,7 @@
|
|||||||
"start_url": "/",
|
"start_url": "/",
|
||||||
"display": "fullscreen",
|
"display": "fullscreen",
|
||||||
"background_color": "#ffffff",
|
"background_color": "#ffffff",
|
||||||
"theme_color": "#3367D6",
|
"theme_color": "#34495e",
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
"src": "/static/icons/logo-192x192.png",
|
"src": "/static/icons/logo-192x192.png",
|
||||||
|
|||||||
@ -11,6 +11,25 @@ body {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
/* Header styles */
|
||||||
|
.site-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 10px 20px;
|
||||||
|
background-color: #34495e; /* Using the theme color */
|
||||||
|
color: #eee;
|
||||||
|
}
|
||||||
|
.site-header img.logo {
|
||||||
|
height: 50px;
|
||||||
|
margin-right: 15px;
|
||||||
|
}
|
||||||
|
.site-header h1 {
|
||||||
|
font-size: 1.5em;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
.wrapper {
|
.wrapper {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-rows: auto 1fr auto;
|
grid-template-rows: auto 1fr auto;
|
||||||
@ -29,16 +48,16 @@ body {
|
|||||||
|
|
||||||
/* Breadcrumb Styles */
|
/* Breadcrumb Styles */
|
||||||
.breadcrumb {
|
.breadcrumb {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 15px;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
.breadcrumb a {
|
.breadcrumb a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #3498db;
|
color: #34495e;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
.breadcrumb span {
|
.breadcrumb span {
|
||||||
color: #7f8c8d;
|
color: #c2c2c2;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,26 +109,26 @@ li {
|
|||||||
/* Link Styles */
|
/* Link Styles */
|
||||||
a.directory-link,
|
a.directory-link,
|
||||||
a.play-file {
|
a.play-file {
|
||||||
color: #2c3e50;
|
color: #34495e;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
a.directory-link:hover,
|
a.directory-link:hover,
|
||||||
a.play-file:hover {
|
a.play-file:hover {
|
||||||
color: #2980b9;
|
color: #34495e;
|
||||||
}
|
}
|
||||||
a.show-transcript {
|
a.show-transcript {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #e67e22;
|
color: #34495e;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
}
|
}
|
||||||
a.show-transcript:hover {
|
a.show-transcript:hover {
|
||||||
color: #d35400;
|
color: rgb(113, 146, 167);
|
||||||
}
|
}
|
||||||
|
|
||||||
.currently-playing {
|
.currently-playing {
|
||||||
background-color: #a6bedf; /* Adjust to your preferred color */
|
background-color: #bfd0df; /* Adjust to your preferred color */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Footer Player Styles */
|
/* Footer Player Styles */
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
<link rel="manifest" href="{{ url_for('static', filename='manifest.json') }}">
|
<link rel="manifest" href="{{ url_for('static', filename='manifest.json') }}">
|
||||||
|
|
||||||
<!-- Android Theme Color -->
|
<!-- Android Theme Color -->
|
||||||
<meta name="theme-color" content="#3367D6">
|
<meta name="theme-color" content="#34495e">
|
||||||
|
|
||||||
<!-- Apple-specific tags -->
|
<!-- Apple-specific tags -->
|
||||||
<link rel="touch-icon" href="{{ url_for('static', filename='icons/icon-192x192.png') }}">
|
<link rel="touch-icon" href="{{ url_for('static', filename='icons/icon-192x192.png') }}">
|
||||||
@ -30,31 +30,12 @@
|
|||||||
<link rel="stylesheet" href="{{ url_for('static', filename='gallery.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='gallery.css') }}">
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='audioplayer.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', filename='audioplayer.css') }}">
|
||||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||||
<style>
|
|
||||||
/* Header styles */
|
|
||||||
.site-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 10px 20px;
|
|
||||||
background-color: #9bbbff; /* Using the theme color */
|
|
||||||
color: #000000;
|
|
||||||
}
|
|
||||||
.site-header img.logo {
|
|
||||||
height: 50px;
|
|
||||||
margin-right: 15px;
|
|
||||||
}
|
|
||||||
.site-header h1 {
|
|
||||||
font-size: 1.5em;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.container {
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header class="site-header">
|
<header class="site-header">
|
||||||
<img src="https://app.bethaus-speyer.de/static/icons/logo-300x300.png" alt="Logo" class="logo">
|
<a href="#">
|
||||||
|
<img src="/static/logoW.png" alt="Logo" class="logo">
|
||||||
|
</a>
|
||||||
<h1>Gottesdienste Speyer und Schwegenheim</h1>
|
<h1>Gottesdienste Speyer und Schwegenheim</h1>
|
||||||
</header>
|
</header>
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
@ -63,7 +44,7 @@
|
|||||||
<div id="content"></div>
|
<div id="content"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Global Audio Player in Footer style="display: none;"-->
|
<!-- Global Audio Player in Footer -->
|
||||||
<footer>
|
<footer>
|
||||||
<div class="audio-player-container" id="audioPlayerContainer">
|
<div class="audio-player-container" id="audioPlayerContainer">
|
||||||
<div class="audio-player">
|
<div class="audio-player">
|
||||||
@ -92,7 +73,9 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="nowPlayingInfo" class="now-playing-info"></div>
|
<div id="nowPlayingInfo" class="now-playing-info">
|
||||||
|
keine Datei ausgewählt...
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user