This commit is contained in:
pika 2025-03-22 12:30:45 +01:00
commit acb3c7642a
23 changed files with 3940 additions and 0 deletions

View file

@ -0,0 +1,181 @@
{% extends "base.html" %}
{% block title %}File Browser - Flask Files{% endblock %}
{% block content %}
<section class="file-browser">
<div class="browser-header">
<h2>File Browser</h2>
<div class="browser-actions">
<a href="{{ url_for('files.upload', folder=current_folder.id if current_folder else None) }}"
class="btn primary">
<i class="fas fa-cloud-upload-alt"></i> Upload
</a>
<button class="btn" id="new-folder-btn">
<i class="fas fa-folder-plus"></i> New Folder
</button>
</div>
</div>
<div class="path-nav">
<a href="{{ url_for('files.browser') }}" class="path-item">
<i class="fas fa-home"></i> Home
</a>
{% for folder in breadcrumbs %}
<span class="path-separator">/</span>
<a href="{{ url_for('files.browser', folder=folder.id) }}" class="path-item">{{ folder.name }}</a>
{% endfor %}
</div>
{% if folders or files %}
<div class="files-container">
{% if folders %}
<div class="folder-section">
<h3>Folders</h3>
<div class="files-list">
{% for folder in folders %}
<div class="file-item folder">
<a href="{{ url_for('files.browser', folder=folder.id) }}" class="file-link">
<div class="file-icon">
<i class="fas fa-folder fa-2x"></i>
</div>
<div class="file-name">{{ folder.name }}</div>
</a>
<div class="file-actions">
<button class="action-btn rename" data-id="{{ folder.id }}" title="Rename">
<i class="fas fa-edit"></i>
</button>
<button class="action-btn delete" data-id="{{ folder.id }}" title="Delete">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% if files %}
<div class="file-section">
<h3>Files</h3>
<div class="files-list">
{% for file in files %}
<div class="file-item">
<div class="file-link">
<div class="file-icon">
{% if file.name.endswith('.pdf') %}<i class="fas fa-file-pdf fa-2x"></i>
{% elif file.name.endswith(('.jpg', '.jpeg', '.png', '.gif')) %}<i
class="fas fa-file-image fa-2x"></i>
{% elif file.name.endswith(('.mp3', '.wav', '.flac')) %}<i
class="fas fa-file-audio fa-2x"></i>
{% elif file.name.endswith(('.mp4', '.mov', '.avi')) %}<i
class="fas fa-file-video fa-2x"></i>
{% elif file.name.endswith(('.doc', '.docx')) %}<i class="fas fa-file-word fa-2x"></i>
{% elif file.name.endswith(('.xls', '.xlsx')) %}<i class="fas fa-file-excel fa-2x"></i>
{% elif file.name.endswith(('.ppt', '.pptx')) %}<i class="fas fa-file-powerpoint fa-2x"></i>
{% elif file.name.endswith('.zip') %}<i class="fas fa-file-archive fa-2x"></i>
{% else %}<i class="fas fa-file fa-2x"></i>{% endif %}
</div>
<div class="file-details">
<div class="file-name">{{ file.name }}</div>
<div class="file-meta">
<span class="file-size">{{ (file.size / 1024)|round(1) }} KB</span>
<span class="file-date">{{ file.updated_at.strftime('%b %d, %Y') }}</span>
</div>
</div>
</div>
<div class="file-actions">
<a href="#" class="action-btn download" data-id="{{ file.id }}" title="Download">
<i class="fas fa-download"></i>
</a>
<a href="#" class="action-btn share" data-id="{{ file.id }}" title="Share">
<i class="fas fa-share-alt"></i>
</a>
<button class="action-btn rename" data-id="{{ file.id }}" title="Rename">
<i class="fas fa-edit"></i>
</button>
<button class="action-btn delete" data-id="{{ file.id }}" title="Delete">
<i class="fas fa-trash"></i>
</button>
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %}
</div>
{% else %}
<div class="empty-state">
<div class="empty-icon">
<i class="fas fa-folder-open fa-3x"></i>
</div>
<p>This folder is empty</p>
<p>Upload files or create a new folder to get started</p>
<div class="empty-actions">
<button class="btn primary" data-action="upload"
data-folder-id="{{ current_folder.id if current_folder else None }}">
<i class="fas fa-cloud-upload-alt"></i> Upload Files
</button>
<button class="btn" id="empty-new-folder-btn">
<i class="fas fa-folder-plus"></i> New Folder
</button>
</div>
</div>
{% endif %}
</section>
{% endblock %}
{% block extra_js %}
<script src="{{ url_for('static', filename='js/upload.js') }}"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
// New folder functionality
const newFolderBtn = document.getElementById('new-folder-btn');
const emptyNewFolderBtn = document.getElementById('empty-new-folder-btn');
function showNewFolderPrompt() {
const folderName = prompt('Enter folder name:');
if (folderName) {
createNewFolder(folderName);
}
}
function createNewFolder(name) {
const formData = new FormData();
formData.append('name', name);
{% if current_folder %}
formData.append('parent_id', '{{ current_folder.id }}');
{% endif %}
fetch('/files/create_folder', {
method: 'POST',
body: formData,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
window.location.reload();
} else {
alert(data.error || 'Failed to create folder');
}
})
.catch(error => {
console.error('Error:', error);
alert('An error occurred while creating the folder');
});
}
if (newFolderBtn) {
newFolderBtn.addEventListener('click', showNewFolderPrompt);
}
if (emptyNewFolderBtn) {
emptyNewFolderBtn.addEventListener('click', showNewFolderPrompt);
}
});
</script>
{% endblock %}

View file

@ -0,0 +1,140 @@
{% extends "base.html" %}
{% block title %}Upload Files - Flask Files{% endblock %}
{% block extra_css %}
<link rel="stylesheet" href="{{ url_for('static', filename='css/upload.css') }}">
{% endblock %}
{% block content %}
<section class="upload-container">
<h2>Upload Files</h2>
<div class="upload-tabs">
<button class="tab-btn active" data-tab="file-tab">Files</button>
<button class="tab-btn" data-tab="folder-tab">Folder</button>
</div>
<div class="upload-location">
<p>
Uploading to:
{% if parent_folder %}
<a href="{{ url_for('files.browser', folder_id=parent_folder.id) }}">{{ parent_folder.name }}</a>
{% else %}
<a href="{{ url_for('files.browser') }}">Root</a>
{% endif %}
</p>
</div>
<div class="tab-content active" id="file-tab">
<form id="file-upload-form" enctype="multipart/form-data" class="upload-form">
<input type="hidden" name="folder_id" value="{{ parent_folder.id if parent_folder else '' }}">
<div class="upload-dropzone" id="file-dropzone">
<i class="fas fa-cloud-upload-alt upload-icon"></i>
<p>Drag & drop files here to start uploading</p>
<p>or</p>
<label class="btn primary">
<i class="fas fa-file"></i> Select Files
<input type="file" name="files[]" multiple id="file-input" style="display: none">
</label>
</div>
<div class="upload-progress-container">
<h4>Upload Progress</h4>
<div class="progress-overall">
<div class="progress-label">
<span>Overall Progress</span>
<span id="progress-percentage">0%</span>
</div>
<div class="progress-bar-container">
<div class="progress-bar" id="progress-bar"></div>
</div>
</div>
<div class="upload-stats">
<div class="stat">
<span class="stat-label">Speed:</span>
<span class="stat-value" id="upload-speed">0 KB/s</span>
</div>
<div class="stat">
<span class="stat-label">Uploaded:</span>
<span class="stat-value" id="uploaded-size">0 KB / 0 KB</span>
</div>
<div class="stat">
<span class="stat-label">Remaining:</span>
<span class="stat-value" id="time-remaining">calculating...</span>
</div>
</div>
</div>
<div class="selected-files">
<h4>Files</h4>
<div class="file-list" id="file-list"></div>
</div>
<div class="form-actions">
<a href="{{ url_for('files.browser', folder_id=parent_folder.id if parent_folder else None) }}"
class="btn">Back to Browser</a>
</div>
</form>
</div>
<div class="tab-content" id="folder-tab">
<form id="folder-upload-form" enctype="multipart/form-data" class="upload-form">
<input type="hidden" name="folder_id" value="{{ parent_folder.id if parent_folder else '' }}">
<div class="upload-dropzone folder-dropzone" id="folder-dropzone">
<i class="fas fa-folder-open upload-icon"></i>
<p>Select a folder to upload</p>
<p>(Some browsers may not fully support folder drag & drop)</p>
<label class="btn primary">
<i class="fas fa-folder"></i> Select Folder
<input type="file" name="files[]" webkitdirectory directory multiple id="folder-input"
style="display: none">
</label>
</div>
<div class="upload-progress-container">
<h4>Upload Progress</h4>
<div class="progress-overall">
<div class="progress-label">
<span>Overall Progress</span>
<span id="folder-progress-percentage">0%</span>
</div>
<div class="progress-bar-container">
<div class="progress-bar" id="folder-progress-bar"></div>
</div>
</div>
<div class="upload-stats">
<div class="stat">
<span class="stat-label">Speed:</span>
<span class="stat-value" id="folder-upload-speed">0 KB/s</span>
</div>
<div class="stat">
<span class="stat-label">Uploaded:</span>
<span class="stat-value" id="folder-uploaded-size">0 KB / 0 KB</span>
</div>
<div class="stat">
<span class="stat-label">Remaining:</span>
<span class="stat-value" id="folder-time-remaining">calculating...</span>
</div>
</div>
</div>
<div class="selected-files">
<h4>Folder Contents</h4>
<div class="file-list" id="folder-file-list"></div>
</div>
<div class="form-actions">
<a href="{{ url_for('files.browser', folder_id=parent_folder.id if parent_folder else None) }}"
class="btn">Back to Browser</a>
</div>
</form>
</div>
</section>
{% endblock %}
{% block extra_js %}
<script src="{{ url_for('static', filename='js/upload.js') }}"></script>
{% endblock %}