Dateien nach "static" hochladen
This commit is contained in:
parent
2ccaf70d68
commit
341c3bbebd
121
static/app.js
Normal file
121
static/app.js
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
/**
|
||||||
|
* AniWorld Downloader Web Interface
|
||||||
|
* Main JavaScript file
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Format timestamps
|
||||||
|
function formatDateTime(dateString) {
|
||||||
|
const date = new Date(dateString);
|
||||||
|
return date.toLocaleString('de-DE', {
|
||||||
|
day: '2-digit',
|
||||||
|
month: '2-digit',
|
||||||
|
year: 'numeric',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper to capitalize first letter
|
||||||
|
function capitalizeFirst(string) {
|
||||||
|
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper to truncate text with ellipsis
|
||||||
|
function truncateText(text, maxLength) {
|
||||||
|
return text.length > maxLength ? text.substring(0, maxLength) + '...' : text;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse URL parameters
|
||||||
|
function getUrlParams() {
|
||||||
|
const params = {};
|
||||||
|
const queryString = window.location.search;
|
||||||
|
const urlParams = new URLSearchParams(queryString);
|
||||||
|
|
||||||
|
for (const [key, value] of urlParams) {
|
||||||
|
params[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show notification
|
||||||
|
function showNotification(message, type = 'info') {
|
||||||
|
// Check if notification container exists
|
||||||
|
let container = document.getElementById('notification-container');
|
||||||
|
|
||||||
|
if (!container) {
|
||||||
|
container = document.createElement('div');
|
||||||
|
container.id = 'notification-container';
|
||||||
|
container.style.position = 'fixed';
|
||||||
|
container.style.top = '20px';
|
||||||
|
container.style.right = '20px';
|
||||||
|
container.style.zIndex = '9999';
|
||||||
|
document.body.appendChild(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create notification
|
||||||
|
const notification = document.createElement('div');
|
||||||
|
notification.className = `alert alert-${type} alert-dismissible fade show`;
|
||||||
|
notification.innerHTML = `
|
||||||
|
${message}
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||||
|
`;
|
||||||
|
|
||||||
|
container.appendChild(notification);
|
||||||
|
|
||||||
|
// Auto-close after 5 seconds
|
||||||
|
setTimeout(() => {
|
||||||
|
notification.classList.remove('show');
|
||||||
|
setTimeout(() => {
|
||||||
|
notification.remove();
|
||||||
|
}, 150);
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract title from URL
|
||||||
|
function extractTitleFromUrl(url) {
|
||||||
|
try {
|
||||||
|
if (url.includes('bs.to')) {
|
||||||
|
const match = url.match(/\/serie\/([^\/]+)/);
|
||||||
|
return match ? match[1].replace(/-/g, ' ') : 'Unknown Title';
|
||||||
|
} else {
|
||||||
|
const match = url.match(/\/stream\/([^\/]+)/);
|
||||||
|
return match ? match[1].replace(/-/g, ' ') : 'Unknown Title';
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
return 'Unknown Title';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if URL is valid
|
||||||
|
function isValidUrl(url) {
|
||||||
|
const pattern = /^(https?:\/\/)?(www\.)?(aniworld\.to|s\.to|bs\.to)\/.*$/;
|
||||||
|
return pattern.test(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize page-specific scripts when DOM is loaded
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
// Check for link parameter and populate the input
|
||||||
|
const urlParams = getUrlParams();
|
||||||
|
if (urlParams.link && document.getElementById('animeLink')) {
|
||||||
|
document.getElementById('animeLink').value = urlParams.link;
|
||||||
|
|
||||||
|
// Auto-analyze if requested
|
||||||
|
if (urlParams.analyze === 'true') {
|
||||||
|
document.getElementById('analyzeButton').click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply theme preference
|
||||||
|
const prefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||||
|
if (prefersDarkMode) {
|
||||||
|
document.body.classList.add('dark-mode');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle AJAX errors globally
|
||||||
|
window.addEventListener('error', function(e) {
|
||||||
|
if (e.message.includes('NetworkError') || e.message.includes('Failed to fetch')) {
|
||||||
|
showNotification('Netzwerkfehler. Bitte überprüfe deine Verbindung.', 'danger');
|
||||||
|
}
|
||||||
|
});
|
||||||
139
static/logs-bootstrap.css
Normal file
139
static/logs-bootstrap.css
Normal file
|
|
@ -0,0 +1,139 @@
|
||||||
|
/* Bootstrap-kompatible Log Styles */
|
||||||
|
.logs-container {
|
||||||
|
height: 600px;
|
||||||
|
background: #f8f9fa;
|
||||||
|
border: 1px solid #dee2e6;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logs-content {
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 1rem;
|
||||||
|
font-family: 'Courier New', monospace;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
line-height: 1.4;
|
||||||
|
background: #212529;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-entry {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
padding: 0.5rem 0.75rem;
|
||||||
|
border-radius: 0.375rem;
|
||||||
|
border-left: 4px solid transparent;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-entry:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-entry.INFO {
|
||||||
|
border-left-color: #198754;
|
||||||
|
background: rgba(25, 135, 84, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-entry.WARNING {
|
||||||
|
border-left-color: #fd7e14;
|
||||||
|
background: rgba(253, 126, 20, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-entry.ERROR {
|
||||||
|
border-left-color: #dc3545;
|
||||||
|
background: rgba(220, 53, 69, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-timestamp {
|
||||||
|
color: #6c757d;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
margin-right: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-level {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-right: 0.75rem;
|
||||||
|
min-width: 60px;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-level.INFO {
|
||||||
|
color: #198754;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-level.WARNING {
|
||||||
|
color: #fd7e14;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-level.ERROR {
|
||||||
|
color: #dc3545;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-message {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Button States */
|
||||||
|
.btn.active {
|
||||||
|
background-color: var(--bs-primary);
|
||||||
|
border-color: var(--bs-primary);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Status Indicator */
|
||||||
|
#log-status-indicator {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
#log-status-indicator:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge.bg-success {
|
||||||
|
animation: pulse 2s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes pulse {
|
||||||
|
0% { opacity: 1; }
|
||||||
|
50% { opacity: 0.7; }
|
||||||
|
100% { opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark theme for logs */
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.logs-container {
|
||||||
|
background: #343a40;
|
||||||
|
border-color: #495057;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
background: #343a40;
|
||||||
|
border-color: #495057;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
background: #495057;
|
||||||
|
border-color: #6c757d;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.logs-container {
|
||||||
|
height: 400px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logs-content {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.log-entry {
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
249
static/style.css
Normal file
249
static/style.css
Normal file
|
|
@ -0,0 +1,249 @@
|
||||||
|
:root {
|
||||||
|
--bg: #121C22;
|
||||||
|
--bg-2nd: #637CF9;
|
||||||
|
--bg-card: #1e2832;
|
||||||
|
--fg: #FFFFFF;
|
||||||
|
--fg-muted: #a0aec0;
|
||||||
|
--border-color: #2d3748;
|
||||||
|
--hover-bg: #1a242f;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: var(--bg);
|
||||||
|
color: var(--fg);
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Navbar styling */
|
||||||
|
.navbar-dark {
|
||||||
|
background-color: var(--bg-2nd) !important;
|
||||||
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-brand {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Card styling */
|
||||||
|
.card {
|
||||||
|
background-color: var(--bg-card);
|
||||||
|
border-color: var(--border-color);
|
||||||
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
background-color: var(--bg-2nd);
|
||||||
|
border-bottom-color: var(--bg-2nd);
|
||||||
|
color: var(--fg);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Form controls */
|
||||||
|
.form-control,
|
||||||
|
.form-select {
|
||||||
|
background-color: #2d3748;
|
||||||
|
border-color: var(--border-color);
|
||||||
|
color: var(--fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control:focus,
|
||||||
|
.form-select:focus {
|
||||||
|
background-color: #2d3748;
|
||||||
|
border-color: var(--bg-2nd);
|
||||||
|
color: var(--fg);
|
||||||
|
box-shadow: 0 0 0 0.2rem rgba(99, 124, 249, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control::placeholder {
|
||||||
|
color: var(--fg-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-check-input {
|
||||||
|
background-color: #2d3748;
|
||||||
|
border-color: var(--bg-2nd);
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-check-input:checked {
|
||||||
|
background-color: var(--bg-2nd);
|
||||||
|
border-color: var(--bg-2nd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Buttons */
|
||||||
|
.btn-primary {
|
||||||
|
background-color: var(--bg-2nd);
|
||||||
|
border-color: var(--bg-2nd);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover,
|
||||||
|
.btn-primary:focus {
|
||||||
|
background-color: #5a6fd8;
|
||||||
|
border-color: #5a6fd8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-outline-secondary {
|
||||||
|
color: var(--fg);
|
||||||
|
border-color: var(--fg-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-outline-secondary:hover {
|
||||||
|
background-color: #2d3748;
|
||||||
|
color: var(--fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tables */
|
||||||
|
.table {
|
||||||
|
color: var(--fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table thead th {
|
||||||
|
border-bottom-color: var(--border-color);
|
||||||
|
color: var(--fg-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table tbody tr:hover {
|
||||||
|
background-color: var(--hover-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table td, .table th {
|
||||||
|
border-color: var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Alerts */
|
||||||
|
.alert-warning,
|
||||||
|
.alert-info,
|
||||||
|
.alert-danger,
|
||||||
|
.alert-success {
|
||||||
|
background-color: #2d3748;
|
||||||
|
border-color: var(--bg-2nd);
|
||||||
|
color: var(--fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-info {
|
||||||
|
border-left: 4px solid var(--bg-2nd);
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-danger {
|
||||||
|
border-left: 4px solid #e53e3e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-success {
|
||||||
|
border-left: 4px solid #38a169;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alert-warning {
|
||||||
|
border-left: 4px solid #d69e2e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Text colors */
|
||||||
|
.text-muted {
|
||||||
|
color: var(--fg-muted) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Progress bars */
|
||||||
|
.progress {
|
||||||
|
background-color: #2d3748;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-bar {
|
||||||
|
background-color: var(--bg-2nd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* List groups */
|
||||||
|
.list-group-item {
|
||||||
|
background-color: var(--bg-card);
|
||||||
|
border-color: var(--border-color);
|
||||||
|
color: var(--fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-group-item:hover {
|
||||||
|
background-color: var(--hover-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-group-item-action:focus,
|
||||||
|
.list-group-item-action:hover {
|
||||||
|
background-color: var(--hover-bg);
|
||||||
|
color: var(--fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Badges */
|
||||||
|
.badge {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Download items */
|
||||||
|
.download-item {
|
||||||
|
background-color: var(--hover-bg);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.download-item:hover {
|
||||||
|
background-color: #243447;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Provider list */
|
||||||
|
.provider-list {
|
||||||
|
max-height: 300px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.provider-item {
|
||||||
|
cursor: move;
|
||||||
|
background-color: var(--hover-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.provider-item:hover {
|
||||||
|
background-color: #243447;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Modals */
|
||||||
|
.modal-content {
|
||||||
|
background-color: var(--bg-card);
|
||||||
|
color: var(--fg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header,
|
||||||
|
.modal-footer {
|
||||||
|
border-color: var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Spinner */
|
||||||
|
.spinner-border {
|
||||||
|
color: var(--bg-2nd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Footer */
|
||||||
|
footer {
|
||||||
|
color: var(--fg-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Media queries */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.card-body {
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
padding-left: 12px;
|
||||||
|
padding-right: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Animations */
|
||||||
|
@keyframes fadeIn {
|
||||||
|
from { opacity: 0; }
|
||||||
|
to { opacity: 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.fade-in {
|
||||||
|
animation: fadeIn 0.3s ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark mode toggle */
|
||||||
|
.dark-mode-toggle {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user