Push all previous files to repo (26.01.08-LATEST)

This commit is contained in:
Andrew K
2026-01-08 22:15:32 +09:00
parent 9893d81691
commit 231384a259
12 changed files with 1235 additions and 0 deletions

132
templates/dashboard.html Normal file
View File

@@ -0,0 +1,132 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ADrive Share</title>
<script src="https://kit.fontawesome.com/972393379b.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
</head>
<body>
<div class="app">
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<ul class="flashes">
{% for category, message in messages %}
<!-- category: message, error, info, warning -->
<li class="{{ category }}"><strong>{{ message }}</strong></li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<div class="dashboard-container">
<div class="dashboard-top">
<div class="dashboard-meta">
<h2>Dashboard of {{username}}</h2>
<p style="color: gray; font-size: 15px; text-align: left;">
You are managing {{ quota_usage }}GB out of {{ quota_gb }}GB.
</p>
</div>
<!-- Quota donut visual -->
{% set r = 40 %}
{% set c = (2 * 3.141592653589793 * r) %}
{% if quota_gb and quota_gb > 0 %}
{% set used = quota_usage %}
{% set pct = (used / quota_gb) if quota_gb > 0 else 0 %}
{% else %}
{% set used = 0 %}
{% set pct = 0 %}
{% endif %}
{% if pct >= 0.9 %}
{% set stroke_color = '#DF2935' %}
{% elif pct >= 0.6 %}
{% set stroke_color = '#FDCA40' %}
{% else %}
{% set stroke_color = '#3772FF' %}
{% endif %}
<div class="quota-block">
<div class="quota-donut" role="img" aria-label="Quota usage">
<svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet">
<g transform="translate(50,50)">
<circle class="donut-ring" r="{{ r }}" cx="0" cy="0" fill="transparent" stroke-width="10" stroke-linecap="round"></circle>
<circle class="donut-fill" r="{{ r }}" cx="0" cy="0" fill="transparent" stroke-width="10" stroke-linecap="round"
stroke-dasharray="{{ c }}" stroke-dashoffset="{{ (c * (1 - pct)) }}" stroke="{{ stroke_color }}"></circle>
</g>
</svg>
<div class="quota-center">
<div class="quota-percent">{{ (pct * 100) | round }}%</div>
<div class="quota-number">{{ ('%.1f' % used) if (used is not none) else '0.0' }} / {{ ('%.1f' % quota_gb) if (quota_gb is not none) else '0.0' }} GB</div>
</div>
</div>
</div>
</div>
<table>
<tr>
<th>Filename</th>
<th>Code</th>
<th>Reusable</th>
<th>Download</th>
<th>Delete</th>
</tr>
{% for file in files %}
<tr>
<td>{{ file.file.rsplit('_', 1)[0] }}</td>
<td>{{ file.code }}</td>
<td>{{ 'Yes' if file.reusable else 'No' }}</td>
<td>
{% if file.reusable %}
<a href="/download/{{ file.code }}">Download</a>
{% else %}
<a href="/download/{{ file.code }}" style="color: rgb(255, 162, 0);">Download and Delete</a>
{% endif %}
</td>
<td>
{% if file.reusable %}
<a href="/delete/{{ file.code }}" style="color: red;">Delete</a>
{% endif %}
</td>
</tr>
{% endfor %}
</table>
<a href="/upload" class="sign-in-button" style="text-decoration: none; background: rgb(1, 60, 155)">Upload a New File</a>
<a href="/logout" class="sign-in-button" style="text-decoration: none; background: rgb(32, 0, 139)">Sign Out</a>
</div>
</div>
<script>
//document.getElementById("uploadBtn").addEventListener("click", uploadAnim);
function downloadClick(){
const codeEl = document.getElementById("codeInput");
const code = codeEl.value;
// clear input when clicked
codeEl.value = '';
const url = `/download/` + code;
location.href = url;
}
function uploadAnim(e) {
//if (document.getElementById("fileUpload").value == "") {
// document.getElementById("uploadBtn").classList.add("redBtn");
// document.getElementById("uploadBtn").value = "! ! !";
// e.preventDefault();
//} else {
// document.getElementById("uploadBtn").classList.add("yellowBtn");
// document.getElementById("uploadBtn").value = "· · ·";
//}
if (!document.getElementById("fileUpload").value == "") {
document.getElementById("uploadBtn").classList.add("yellowBtn");
document.getElementById("uploadBtn").value = "· · ·";
}
}
</script>
<script src="{{ url_for('static', filename='script.js') }}"></script>
</body>
</html>

74
templates/login.html Normal file
View File

@@ -0,0 +1,74 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ADrive Share</title>
<script src="https://kit.fontawesome.com/972393379b.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
</head>
<body>
<div class="app">
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<ul class="flashes">
{% for category, message in messages %}
<!-- category: message, error, info, warning -->
<li class="{{ category }}"><strong>{{ message }}</strong></li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<div class="form-section">
<h1>Sign In</h1>
<p style="color: gray; font-size: 15px; text-align: left;">
Enter your credentials to access your dashboard and manage your files.
</p>
<form id="loginForm" action="/login" method="post">
Username: <input type="text" name="username" id="username" placeholder="📋" required aria-required>
Passphrase: <input type="password" name="password" id="password" placeholder="🗝️" aria-required>
<input type="submit" value="Sign In" id="uploadBtn">
</form>
<a href="/register" class="sign-in-button" style="text-decoration: none; background: rgb(32, 0, 139)">Sign Up</a>
<a href="/upload" class="sign-in-button" style="text-decoration: none; background: rgb(1, 60, 155)">Guest</a>
<p style="color: gray; font-size: 11px; text-align: center;">Signing in is not required. You can at any time register and sign in to manage your existing codes for free.</p>
</div>
</div>
<script>
//document.getElementById("uploadBtn").addEventListener("click", uploadAnim);
function downloadClick(){
const codeEl = document.getElementById("codeInput");
const code = codeEl.value;
// clear input when clicked
codeEl.value = '';
const url = `/download/` + code;
location.href = url;
}
function uploadAnim(e) {
//if (document.getElementById("fileUpload").value == "") {
// document.getElementById("uploadBtn").classList.add("redBtn");
// document.getElementById("uploadBtn").value = "! ! !";
// e.preventDefault();
//} else {
// document.getElementById("uploadBtn").classList.add("yellowBtn");
// document.getElementById("uploadBtn").value = "· · ·";
//}
if (!document.getElementById("fileUpload").value == "") {
document.getElementById("uploadBtn").classList.add("yellowBtn");
document.getElementById("uploadBtn").value = "· · ·";
}
}
</script>
<script src="{{ url_for('static', filename='script.js') }}"></script>
</body>
</html>

76
templates/register.html Normal file
View File

@@ -0,0 +1,76 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ADrive Share</title>
<script src="https://kit.fontawesome.com/972393379b.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
</head>
<body>
<div class="app">
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<ul class="flashes">
{% for category, message in messages %}
<!-- category: message, error, info, warning -->
<li class="{{ category }}"><strong>{{ message }}</strong></li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<div class="form-section">
<h1>Sign Up </h1>
<p style="color: gray; font-size: 15px; text-align: left;">
With an account, you can manage up to 3GB in one dashboard. If you use up your limit, you can delete to free up space or upload files without the ability to manage them.
</p>
<form id="loginForm" action="/register" method="post">
Username: <input type="text" name="username" id="username" placeholder="📋" required aria-required>
Passphrase: <input type="password" name="password" id="password" placeholder="🗝️" aria-required>
Managable Storage Quota: <select name="quota_files" id="quota_files" class="fancy-select" disabled aria-disabled>
<option value="3GB">3GB</option>
</select>
<input type="submit" class="sign-in-button" style="background: rgb(32, 0, 139)" value="Sign Up" id="uploadBtn">
</form>
<a class="sign-in-button" href="/login" style="background: rgb(0, 95, 139); text-decoration: none;" id="signininstead">Sign In Instead</a>
<a href="/upload" class="sign-in-button" style="text-decoration: none; background: rgb(1, 60, 155)">Guest</a>
<p style="color: gray; font-size: 11px; text-align: center;">Signing in is not required. You can at any time register and sign in to manage your existing codes for free.</p>
</div>
</div>
<script>
//document.getElementById("uploadBtn").addEventListener("click", uploadAnim);
function downloadClick(){
const codeEl = document.getElementById("codeInput");
const code = codeEl.value;
// clear input when clicked
codeEl.value = '';
const url = `/download/` + code;
location.href = url;
}
function uploadAnim(e) {
//if (document.getElementById("fileUpload").value == "") {
// document.getElementById("uploadBtn").classList.add("redBtn");
// document.getElementById("uploadBtn").value = "! ! !";
// e.preventDefault();
//} else {
// document.getElementById("uploadBtn").classList.add("yellowBtn");
// document.getElementById("uploadBtn").value = "· · ·";
//}
if (!document.getElementById("fileUpload").value == "") {
document.getElementById("uploadBtn").classList.add("yellowBtn");
document.getElementById("uploadBtn").value = "· · ·";
}
}
</script>
<script src="{{ url_for('static', filename='script.js') }}"></script>
</body>
</html>

152
templates/upload.html Normal file
View File

@@ -0,0 +1,152 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ADrive Share</title>
<script src="https://kit.fontawesome.com/972393379b.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="{{ url_for('static', filename='styles.css') }}">
</head>
<body>
<div class="app">
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<ul class="flashes">
{% for category, message in messages %}
<!-- category: message, error, info, warning -->
<li class="{{ category }}"><strong>{{ message }}</strong></li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<div class="form-section">
<form id="uploadForm" action="/sendfile" method="post" enctype="multipart/form-data">
{% if loggedIn %}
<h4>You are currently logged in as {{ username }}.</h4>
{% else %}
<h4>You are currently not logged in.</h4>
{% endif %}
<span style="font-size: 20px;">
<i class="fa-solid fa-server fa-xs" style="line-height: 25px; font-size: 15px; display: inline-block;"></i>
<span id="mirrorText">Finding Nearby Mirror</span> <i class="fa-solid fa-circle-dot fa-beat-fade fa-2xs" style="color: #ff9500;" id="mirrorLogo"></i>
</span>
<span style="font-size: 20px;">
<i class="fa-solid fa-server fa-xs" style="line-height: 25px; font-size: 15px; display: inline-block;"></i>
Location Not Found <i class="fa-solid fa-circle-dot fa-2xs" style="color: #c10101;"></i>
</span>
<input type="file" name="file" id="fileUpload" required aria-required>
<input type="hidden" id="quotaGB" value="{{ quota_gb }}">
<input type="hidden" id="quotaUsedGB" value="{{ quota_usage }}">
<progress id="uploadProgress" value="0" max="100" style="display:none;width:100%;margin-top:8px"></progress>
<div id="uploadProgressText" style="display:none;font-size:13px;margin-top:4px">0%</div>
<div style="display: flex; flex-direction: row;">
<input type="checkbox" name="reusable" style="display: inline-block;">
<span>Reusable?</span>
</div>
<input type="submit" value="Upload" id="uploadBtn" onclick="uploadAnim()" style="transition-duration: 400ms;">
</form>
<form>
<input type="text" id="codeInput">
<button type="button" value="Download" onclick="downloadClick()">Download</button>
</form>
{% if not loggedIn %}
<a href="/login" class="sign-in-button" style="text-decoration: none; background: rgb(0, 81, 139)">Sign In</a>
<a href="/register" class="sign-in-button" style="text-decoration: none; background: rgb(32, 0, 139)">Register</a><br>
<p style="color: gray; font-size: 11px; text-align: center;">Signing in is not required. You can at any time register and sign in to manage your existing codes for free. You can manage up to 1GB of files.</p>
{% else %}
<a href="/dashboard" class="sign-in-button" style="text-decoration: none; background: blue">View Dashboard</a>
<a href="/logout" class="sign-in-button" style="text-decoration: none; background: rgb(79, 92, 178)">Sign Out</a>
{% endif %}
</div>
</div>
<script>
//document.getElementById("uploadBtn").addEventListener("click", uploadAnim);
function downloadClick(){
const codeEl = document.getElementById("codeInput");
const code = codeEl.value;
// clear input when clicked
codeEl.value = '';
const url = `/download/` + code;
location.href = url;
}
function uploadAnim(e) {
//if (document.getElementById("fileUpload").value == "") {
// document.getElementById("uploadBtn").classList.add("redBtn");
// document.getElementById("uploadBtn").value = "! ! !";
// e.preventDefault();
//} else {
// document.getElementById("uploadBtn").classList.add("yellowBtn");
// document.getElementById("uploadBtn").value = "· · ·";
//}
if (!document.getElementById("fileUpload").value == "") {
document.getElementById("uploadBtn").classList.add("yellowBtn");
document.getElementById("uploadBtn").value = "· · ·";
}
}
</script>
<script>
// Client-side quota check before uploading large files
(function(){
const fileInput = document.getElementById('fileUpload');
const uploadBtn = document.getElementById('uploadBtn');
const quotaGB = parseFloat(document.getElementById('quotaGB').value) || 0;
const usedGB = parseFloat(document.getElementById('quotaUsedGB').value) || 0;
const remainingGB = Math.max(0, quotaGB - usedGB);
function ensureFlashesContainer(){
let flashes = document.querySelector('.flashes');
if (!flashes){
flashes = document.createElement('ul');
flashes.className = 'flashes';
const app = document.querySelector('.app');
if (app) app.insertBefore(flashes, app.firstChild);
}
return flashes;
}
function clearClientFlash(){
const flashes = document.querySelectorAll('.flashes li.client-quota-warning');
flashes.forEach(n => n.remove());
}
function showClientFlash(message){
clearClientFlash();
const flashes = ensureFlashesContainer();
const li = document.createElement('li');
li.className = 'warning client-quota-warning';
const strong = document.createElement('strong');
strong.textContent = message;
li.appendChild(strong);
flashes.prepend(li);
}
if (fileInput){
fileInput.addEventListener('change', function(e){
clearClientFlash();
uploadBtn.disabled = false;
const f = fileInput.files && fileInput.files[0];
if (!f) return;
const fileGB = f.size / (1024 * 1024 * 1024);
if (fileGB > remainingGB){
showClientFlash('You do not have sufficient quota to manage this file. If you choose to upload this file, you will not be able to manage it through your dashboard.');
// still allow upload; server will accept but will not set owner when quota insufficient
} else {
clearClientFlash();
}
});
}
})();
</script>
<script src="{{ url_for('static', filename='script.js') }}"></script>
</body>
</html>