working support for subfolders + versioning

This commit is contained in:
Dmitriy Kazimirov 2025-04-06 07:38:48 +00:00
parent e031c7738b
commit 2a4b2d585a
6 changed files with 78 additions and 45 deletions

View file

@ -1,6 +1,7 @@
from flask import Flask, request, jsonify, render_template, send_from_directory
from urllib.parse import unquote
from elasticsearch import Elasticsearch
import json
import os
import ebooklib
from ebooklib import epub
@ -13,14 +14,33 @@ from src.core.index import index_files, get_progress
from io import StringIO
import sys
import re
# Application version
APP_VERSION = "0.0.3 (2025 Apr 6th)"
app = Flask(__name__, static_folder='static')
app = Flask(__name__, static_folder='static')
# Add version to all template renders
@app.context_processor
def inject_version():
return {'app_version': APP_VERSION}
@app.after_request
def add_cors_headers(response):
response.headers['Access-Control-Allow-Origin'] = '*'
response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT'
response.headers['Access-Control-Allow-Headers'] = 'Content-Type'
# Add version to all JSON responses
if response.content_type == 'application/json':
try:
data = response.get_json()
if isinstance(data, dict):
data['version'] = APP_VERSION
response.data = json.dumps(data).encode('utf-8')
except:
pass
return response
# Elasticsearch Configuration
@ -245,49 +265,62 @@ def list_files():
# Check if indexing is in progress
indexing_in_progress = get_progress() is not None
# Walk through directory structure
for root, dirs, files in os.walk(books_dir):
# Skip hidden directories
dirs[:] = [d for d in dirs if not d.startswith('.')]
# Get only top-level files and directories
try:
items = os.listdir(books_dir)
except Exception as e:
return render_template('files.html', error=f"Error listing directory: {str(e)}")
# Process directories first
for item_name in sorted(items):
item_path = os.path.join(books_dir, item_name)
# Get relative path from books_dir
rel_path = os.path.relpath(root, books_dir)
if rel_path == '.':
rel_path = ''
if os.path.isdir(item_path) and not item_name.startswith('.'):
# Count files in this directory for display
dir_file_count = 0
for _, _, files in os.walk(item_path):
dir_file_count += len(files)
# Add directories first
for dir_name in sorted(dirs):
dir_path = os.path.join(rel_path, dir_name)
file_tree.append({
'type': 'directory',
'name': dir_name,
'path': dir_path,
'children': []
'name': item_name,
'path': item_name,
'file_count': dir_file_count
})
# Then process files
for item_name in sorted(items):
item_path = os.path.join(books_dir, item_name)
# Add files
for file_name in sorted(files):
file_path = os.path.join(books_dir, rel_path, file_name)
if os.path.isfile(file_path):
file_size = os.path.getsize(file_path)
# Extract book title from filename if possible
title = file_name
if ' - ' in file_name: # Common pattern in filenames
title_parts = file_name.split(' - ')
if len(title_parts) > 1:
title = ' - '.join(title_parts[:-1]) # Take all but last part
full_path = os.path.join(rel_path, file_name)
file_tree.append({
'type': 'file',
'name': file_name,
'title': title,
'path': full_path,
'size': file_size,
'size_mb': round(file_size / (1024 * 1024), 2)
})
total_files += 1
total_size += file_size
if os.path.isfile(item_path):
file_size = os.path.getsize(item_path)
# Extract book title from filename if possible
title = item_name
if ' - ' in item_name: # Common pattern in filenames
title_parts = item_name.split(' - ')
if len(title_parts) > 1:
title = ' - '.join(title_parts[:-1]) # Take all but last part
file_tree.append({
'type': 'file',
'name': item_name,
'title': title,
'path': item_name,
'size': file_size,
'size_mb': round(file_size / (1024 * 1024), 2)
})
total_files += 1
total_size += file_size
# Count all files in all subdirectories for the total count
for root, _, files in os.walk(books_dir):
for file in files:
if not os.path.basename(root).startswith('.') and not file.startswith('.'):
if root != books_dir: # Don't double count top-level files
total_files += 1
file_path = os.path.join(root, file)
if os.path.isfile(file_path):
total_size += os.path.getsize(file_path)
total_size_mb = round(total_size / (1024 * 1024), 2)

View file

@ -256,7 +256,7 @@
</script>
<footer>
<p>&copy; 2025 Book Search Engine</p>
<p>&copy; 2025 Intari | Version {{ app_version }}</p>
</footer>
</body>
</html>

View file

@ -113,14 +113,14 @@
</head>
<body>
<header>
<h1>Book Files</h1>
<h1>Books Files</h1>
</header>
<nav class="nav">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/files">File List</a></li>
<li><a href="/index_books">Re-Index Books</a></li>
<li><a href="/index_books">Re-Index Files</a></li>
</ul>
</nav>
@ -152,7 +152,7 @@
<li class="folder-item" onclick="toggleFolder(this, event)">
<div class="folder-name">
<span class="folder-icon">📁</span>
{{ item.name }}
{{ item.name }} <span class="file-name-muted">({{ item.file_count }} files)</span>
</div>
<div class="folder-contents" id="folder-{{ item.path|replace('/', '-') }}">
<!-- Contents will be populated dynamically -->
@ -326,7 +326,7 @@
</div>
<footer>
<p>&copy; 2025 Intari</p>
<p>&copy; 2025 Intari | Version {{ app_version }}</p>
</footer>
</body>
</html>

View file

@ -70,7 +70,7 @@
</div>
<footer>
<p>&copy; 2025 Intari</p>
<p>&copy; 2025 Intari | Version {{ app_version }}</p>
</footer>
<script>

View file

@ -50,7 +50,7 @@
</div>
<footer>
<p>&copy; 2025 Intari</p>
<p>&copy; 2025 Intari | Version {{ app_version }}</p>
</footer>
</body>
</html>

View file

@ -58,7 +58,7 @@
</div>
<footer>
<p>&copy; 2025 Book Search Engine</p>
<p>&copy; 2025 Intari | Version {{ app_version }}</p>
</footer>
</body>
</html>