update token generation gui
This commit is contained in:
parent
4b37684593
commit
7b73facc16
33
app.py
33
app.py
@ -17,7 +17,8 @@ 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
|
||||||
import re
|
import re
|
||||||
|
import qrcode
|
||||||
|
import base64
|
||||||
import search
|
import search
|
||||||
import auth
|
import auth
|
||||||
import analytics as a
|
import analytics as a
|
||||||
@ -415,6 +416,7 @@ def get_transcript(subpath):
|
|||||||
@auth.require_secret
|
@auth.require_secret
|
||||||
def create_share(subpath):
|
def create_share(subpath):
|
||||||
scheme = request.scheme # current scheme (http or https)
|
scheme = request.scheme # current scheme (http or https)
|
||||||
|
host = request.host
|
||||||
if 'admin ' not in session and not session.get('admin'):
|
if 'admin ' not in session and not session.get('admin'):
|
||||||
return "Unauthorized", 403
|
return "Unauthorized", 403
|
||||||
|
|
||||||
@ -440,20 +442,25 @@ def create_share(subpath):
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
print (data)
|
|
||||||
|
|
||||||
token = auth.generate_secret_key_compressed(data)
|
token = auth.generate_secret_key_compressed(data)
|
||||||
|
|
||||||
content = f"""Ordner:\\
|
|
||||||
{foldername}\\
|
|
||||||
\\
|
|
||||||
Gültig bis:\\
|
|
||||||
{validity_date}\\
|
|
||||||
\\
|
|
||||||
Link:\\
|
|
||||||
`{scheme}://{request.host}?token={token}`"""
|
|
||||||
|
|
||||||
return content, 200, {'Content-Type': 'text/markdown; charset=utf-8'}
|
url = f"{scheme}://{host}?token={token}"
|
||||||
|
qr = qrcode.QRCode(version=1, box_size=10, border=4)
|
||||||
|
qr.add_data(url)
|
||||||
|
qr.make(fit=True)
|
||||||
|
img = qr.make_image(fill_color="black", back_color="white")
|
||||||
|
buffer = io.BytesIO()
|
||||||
|
img.save(buffer, format="PNG")
|
||||||
|
buffer.seek(0)
|
||||||
|
img_base64 = base64.b64encode(buffer.getvalue()).decode('ascii')
|
||||||
|
token_item = auth.decode_secret_key_compressed(token)
|
||||||
|
|
||||||
|
return render_template('view_token.html',
|
||||||
|
token_qr_code=img_base64,
|
||||||
|
token_folder=token_item.get('folders'),
|
||||||
|
token_url=url,
|
||||||
|
token_valid_to=token_item.get('validity', 'Unbekannt')
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def query_recent_connections():
|
def query_recent_connections():
|
||||||
|
|||||||
@ -100,17 +100,11 @@ div.directory-item a, li.directory-item a, li.file-item a, li.link-item a {
|
|||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
}
|
|
||||||
.directories-grid .directory-item {
|
|
||||||
background-color: #fff;
|
|
||||||
padding: 15px;
|
|
||||||
border-radius: 5px;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* File Item Styles (for both music and image files) */
|
/* File Item Styles (for both music and image files) */
|
||||||
.file-item {
|
.file-item, .directory-item{
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr auto;
|
grid-template-columns: 1fr auto;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
@ -77,26 +77,30 @@ function renderContent(data) {
|
|||||||
share_link = '';
|
share_link = '';
|
||||||
// Render directories normally
|
// Render directories normally
|
||||||
if (data.directories.length > 0) {
|
if (data.directories.length > 0) {
|
||||||
const areAllShort = data.directories.every(dir => dir.name.length <= 15) && data.files.length === 0;
|
const areAllShort = data.directories.every(dir => dir.name.length <= 10) && data.files.length === 0;
|
||||||
if (areAllShort && data.breadcrumbs.length !== 1) {
|
if (areAllShort && data.breadcrumbs.length !== 1) {
|
||||||
contentHTML += '<div class="directories-grid">';
|
contentHTML += '<div class="directories-grid">';
|
||||||
data.directories.forEach(dir => {
|
data.directories.forEach(dir => {
|
||||||
if (admin_enabled && data.breadcrumbs.length != 1) {
|
if (admin_enabled && data.breadcrumbs.length != 1) {
|
||||||
share_link = `<a href="#" class="create-share" data-url="${dir.path}">🌐</a>`;
|
share_link = `<a href="#" class="create-share" data-url="${dir.path}">⚙️</a>`;
|
||||||
}
|
}
|
||||||
contentHTML += `<div class="directory-item">📁 <a href="#" class="directory-link" data-path="${dir.path}">${dir.name}</a>${share_link}</div>`;
|
contentHTML += `<div class="directory-item"><a href="#" class="directory-link" data-path="${dir.path}">📁 ${dir.name}</a>
|
||||||
|
${share_link}
|
||||||
|
</div>`;
|
||||||
});
|
});
|
||||||
contentHTML += '</div>';
|
contentHTML += '</div>';
|
||||||
} else {
|
} else {
|
||||||
contentHTML += '<ul>';
|
contentHTML += '<ul>';
|
||||||
data.directories.forEach(dir => {
|
data.directories.forEach(dir => {
|
||||||
if (admin_enabled && data.breadcrumbs.length != 1) {
|
if (admin_enabled && data.breadcrumbs.length != 1) {
|
||||||
share_link = `<a href="#" class="create-share" data-url="${dir.path}">🌐</a>`;
|
share_link = `<a href="#" class="create-share" data-url="${dir.path}">⚙️</a>`;
|
||||||
}
|
}
|
||||||
contentHTML += `<li class="directory-item">📁 <a href="#" class="directory-link" data-path="${dir.path}">${dir.name}</a>${share_link}</li>`;
|
contentHTML += `<li class="directory-item"><a href="#" class="directory-link" data-path="${dir.path}">📁 ${dir.name}</a>
|
||||||
|
${share_link}
|
||||||
|
</li>`;
|
||||||
});
|
});
|
||||||
if (data.breadcrumbs.length === 1) {
|
if (data.breadcrumbs.length === 1) {
|
||||||
contentHTML += `<li class="link-item" onclick="window.location.href='/search'">🔎 <a href="/search" class="link-link">Suche</a></li>`;
|
contentHTML += `<li class="link-item" onclick="window.location.href='/search'"><a href="/search" class="link-link">🔎 Suche</a></li>`;
|
||||||
}
|
}
|
||||||
contentHTML += '</ul>';
|
contentHTML += '</ul>';
|
||||||
}
|
}
|
||||||
@ -385,7 +389,7 @@ document.querySelectorAll('.play-file').forEach(link => {
|
|||||||
})
|
})
|
||||||
.then(data => {
|
.then(data => {
|
||||||
console.log(data);
|
console.log(data);
|
||||||
document.getElementById('transcriptContent').innerHTML = marked.parse(data);
|
document.getElementById('transcriptContent').innerHTML = data;
|
||||||
document.getElementById('transcriptModal').style.display = 'block';
|
document.getElementById('transcriptModal').style.display = 'block';
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
@ -538,4 +542,34 @@ function syncThemeColor() {
|
|||||||
.forEach(svg => svg.setAttribute('fill', cssVar));
|
.forEach(svg => svg.setAttribute('fill', cssVar));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function copyTokenUrl(url) {
|
||||||
|
if (navigator.clipboard && window.isSecureContext) {
|
||||||
|
// Modern approach
|
||||||
|
navigator.clipboard.writeText(url)
|
||||||
|
.then(() => {
|
||||||
|
alert('Token-URL in die Zwischenablage kopiert!');
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error('Fehler beim Kopieren: ', err);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Fallback for older browsers
|
||||||
|
const textarea = document.createElement('textarea');
|
||||||
|
textarea.value = url;
|
||||||
|
textarea.style.position = 'fixed'; // Verhindert Scrollen
|
||||||
|
textarea.style.opacity = '0';
|
||||||
|
document.body.appendChild(textarea);
|
||||||
|
textarea.focus();
|
||||||
|
textarea.select();
|
||||||
|
try {
|
||||||
|
document.execCommand('copy');
|
||||||
|
alert('Token-URL in die Zwischenablage kopiert!');
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Fallback: Kopieren fehlgeschlagen', err);
|
||||||
|
}
|
||||||
|
document.body.removeChild(textarea);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', syncThemeColor);
|
document.addEventListener('DOMContentLoaded', syncThemeColor);
|
||||||
62
templates/view_token.html
Normal file
62
templates/view_token.html
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.container-fluid {
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.qr-code {
|
||||||
|
max-width: 300px;
|
||||||
|
display: block;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
.copy-btn {
|
||||||
|
margin-top: 1rem;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
cursor: pointer;
|
||||||
|
border: 1px solid #007bff;
|
||||||
|
background-color: #007bff;
|
||||||
|
color: white;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
}
|
||||||
|
.copy-btn:active {
|
||||||
|
background-color: #0056b3;
|
||||||
|
border-color: #0056b3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4 mb-4">
|
||||||
|
<div class="card h-100 shadow-sm">
|
||||||
|
<img src="data:image/png;base64,{{ token_qr_code }}" class="card-img-top qr-code p-3" alt="QR Code for token">
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="card-text mt-2">
|
||||||
|
<h2 class="card-title">Token-Link:</h2>
|
||||||
|
<a href="{{ token_url }}" class="copy-btn" id="tokenLink">Direct Link</a>
|
||||||
|
<button class="copy-btn" onclick="copyTokenUrl('{{ token_url }}')">Copy Link</button>
|
||||||
|
</div>
|
||||||
|
<div class="card-text mt-2">
|
||||||
|
<h2 class="mt-3">Gültig bis:</h2>
|
||||||
|
{{ token_valid_to }}
|
||||||
|
</div>
|
||||||
|
<div class="card-text mt-2">
|
||||||
|
<h2 class="mt-3">Ordner:</h2>
|
||||||
|
{% for folder in token_folder %}
|
||||||
|
{{ folder.foldername }}<br>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user