added some tests

This commit is contained in:
2025-09-29 10:20:20 +02:00
parent 6b300dc2f5
commit 7286b9b3e8
13 changed files with 3801 additions and 21 deletions

View File

@@ -679,6 +679,59 @@ def get_series():
'message': 'Error loading series data. Please try rescanning.'
})
@app.route('/api/search', methods=['POST'])
@optional_auth
@handle_api_errors
def search_series():
"""Search for series online."""
try:
# Get the search query from the request
data = request.get_json()
if not data or 'query' not in data:
return jsonify({
'status': 'error',
'message': 'Search query is required'
}), 400
query = data['query'].strip()
if not query:
return jsonify({
'status': 'error',
'message': 'Search query cannot be empty'
}), 400
# Check if series_app is available
if series_app is None:
return jsonify({
'status': 'error',
'message': 'Series application not initialized'
}), 500
# Perform the search
search_results = series_app.search(query)
# Format results for the frontend
results = []
if search_results:
for result in search_results:
if isinstance(result, dict) and 'name' in result and 'link' in result:
results.append({
'name': result['name'],
'link': result['link']
})
return jsonify({
'status': 'success',
'results': results,
'total': len(results)
})
except Exception as e:
return jsonify({
'status': 'error',
'message': f'Search failed: {str(e)}'
}), 500
@app.route('/api/rescan', methods=['POST'])
@optional_auth
def rescan_series():

View File

@@ -127,12 +127,18 @@ body {
align-items: center;
max-width: 1200px;
margin: 0 auto;
min-height: 60px;
position: relative;
width: 100%;
box-sizing: border-box;
}
.header-title {
display: flex;
align-items: center;
gap: var(--spacing-md);
flex-shrink: 1;
min-width: 150px;
}
.header-title i {
@@ -150,7 +156,10 @@ body {
.header-actions {
display: flex;
align-items: center;
gap: var(--spacing-md);
gap: var(--spacing-lg);
flex-shrink: 0;
flex-wrap: nowrap;
justify-content: flex-end;
}
/* Main content */
@@ -844,14 +853,46 @@ body {
}
/* Responsive design */
@media (max-width: 1024px) {
.header-title {
min-width: 120px;
}
.header-title h1 {
font-size: 1.4rem;
}
.header-actions {
gap: var(--spacing-sm);
}
.process-status {
gap: 4px;
}
.status-text {
font-size: 0.8rem;
}
}
@media (max-width: 768px) {
.header-content {
flex-direction: column;
gap: var(--spacing-md);
min-height: auto;
}
.header-title {
text-align: center;
min-width: auto;
justify-content: center;
}
.header-actions {
justify-content: center;
flex-wrap: wrap;
width: 100%;
gap: var(--spacing-sm);
}
.main-content {
@@ -1374,22 +1415,23 @@ body {
/* Process Status Indicators */
.process-status {
display: flex;
gap: var(--spacing-md);
gap: var(--spacing-sm);
align-items: center;
margin-right: var(--spacing-md);
}
.status-indicator {
display: flex;
align-items: center;
gap: var(--spacing-xs);
padding: var(--spacing-xs) var(--spacing-sm);
gap: var(--spacing-sm);
padding: var(--spacing-sm) var(--spacing-md);
background: var(--color-background-subtle);
border-radius: var(--border-radius);
border: 1px solid var(--color-border);
font-size: var(--font-size-caption);
color: var(--color-text-secondary);
transition: all var(--animation-duration-normal) var(--animation-easing-standard);
min-width: 0;
flex-shrink: 0;
}
.status-indicator:hover {
@@ -1405,6 +1447,8 @@ body {
.status-text {
font-weight: 500;
white-space: nowrap;
flex-shrink: 0;
margin-left: 2px;
}
.status-dot {
@@ -1451,12 +1495,17 @@ body {
.status-indicator {
font-size: 11px;
padding: 4px 6px;
padding: 6px 8px;
gap: 4px;
}
.status-text {
display: none;
}
.status-indicator i {
font-size: 14px;
}
}
/* Scheduler Configuration */

View File

@@ -489,25 +489,27 @@ class AniWorldApp {
applyFiltersAndSort() {
let filtered = [...this.seriesData];
// Sort by missing episodes first (descending), then by name if alphabetical is enabled
// Sort based on the current sorting mode
filtered.sort((a, b) => {
// Always show series with missing episodes first
if (a.missing_episodes > 0 && b.missing_episodes === 0) return -1;
if (a.missing_episodes === 0 && b.missing_episodes > 0) return 1;
// If both have missing episodes, sort by count (descending)
if (a.missing_episodes > 0 && b.missing_episodes > 0) {
if (a.missing_episodes !== b.missing_episodes) {
return b.missing_episodes - a.missing_episodes;
}
}
// Sort alphabetically if enabled
if (this.sortAlphabetical) {
// Pure alphabetical sorting when A-Z is enabled
return (a.name || a.folder).localeCompare(b.name || b.folder);
}
} else {
// Default sorting: missing episodes first (descending), then by name
// Always show series with missing episodes first
if (a.missing_episodes > 0 && b.missing_episodes === 0) return -1;
if (a.missing_episodes === 0 && b.missing_episodes > 0) return 1;
return 0;
// If both have missing episodes, sort by count (descending)
if (a.missing_episodes > 0 && b.missing_episodes > 0) {
if (a.missing_episodes !== b.missing_episodes) {
return b.missing_episodes - a.missing_episodes;
}
}
// For series with same missing episode status, maintain stable order
return 0;
}
});
// Apply missing episodes filter
@@ -516,6 +518,7 @@ class AniWorldApp {
}
this.filteredSeriesData = filtered;
this.renderSeries();
}
renderSeries() {