147 lines
5.0 KiB
Python
Raw Permalink Normal View History

2025-02-22 16:55:41 +01:00
import os
import glob
from flask import render_template, Blueprint, current_app, request
from app.tasks import get_redis
from app.forms import ScrapingForm
from app.util import get_size
from app.config import load_config
from app.api import scraper as scraper
from app.analysis import load_data, load_analysis_modules
from datetime import datetime
views_bp = Blueprint("views", __name__)
def sizeof_fmt(num, suffix="B"):
"""Convert bytes to human readable format"""
for unit in ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"]:
if abs(num) < 1024.0:
return f"{num:3.1f} {unit}{suffix}"
num /= 1024.0
return f"{num:.1f} Yi{suffix}"
def register_views(app):
@app.route('/')
def index():
form = ScrapingForm()
return render_template('index.html', form=form)
@app.route('/results')
def results():
return render_template('results.html')
@app.route('/log_viewer')
def log_viewer():
return render_template('log_viewer.html')
@app.route('/download_results')
def download_results():
# Get the current active log file and data file from Redis and app config
redis_client = get_redis()
current_faction_id = redis_client.get("current_faction_id")
active_data_file = None
if current_faction_id:
active_data_file = redis_client.hget(f"scraper:{current_faction_id}", "data_file_name")
active_log_file = app.config['LOG_FILE_NAME']
def get_file_info(file_path, file_type='data'):
stats = os.stat(file_path)
name = os.path.basename(file_path)
# Determine if file is active
is_active = False
if file_type == 'data' and active_data_file:
is_active = os.path.abspath(file_path) == os.path.abspath(active_data_file)
elif file_type == 'log' and active_log_file:
is_active = os.path.basename(file_path) == os.path.basename(active_log_file)
return {
'name': file_path, # Full path for internal use
'name_display': name, # Just filename for display
'last_modified': stats.st_mtime, # Send timestamp instead of datetime
'created': stats.st_ctime, # Send timestamp instead of datetime
'size': sizeof_fmt(stats.st_size),
'active': is_active
}
data_files = []
log_files = []
# Get data files
data_dir = os.path.abspath(app.config['DATA']['DATA_DIR'])
if os.path.exists(data_dir):
for file in glob.glob(os.path.join(data_dir, "*.csv")):
data_files.append(get_file_info(file, 'data'))
# Get log files
log_dir = os.path.abspath(app.config['LOGGING']['LOG_DIR'])
if os.path.exists(log_dir):
for file in glob.glob(os.path.join(log_dir, "*.log")):
log_files.append(get_file_info(file, 'log'))
# Sort files by modification time, newest first
data_files.sort(key=lambda x: x['last_modified'], reverse=True)
log_files.sort(key=lambda x: x['last_modified'], reverse=True)
files = {
'data': data_files,
'log': log_files
}
return render_template('download_results.html', files=files)
views_bp = Blueprint("views", __name__)
@views_bp.route("/analyze", methods=["GET", "POST"])
def analyze():
analysis_modules = load_analysis_modules() # Load available analyses
data_dir = current_app.config.get("DATA", {}).get("DATA_DIR")
selected_file = None
selected_analyses = []
# Find all available CSV files
data_files = sorted(
glob.glob(os.path.join(data_dir, "*.csv")),
key=os.path.getmtime,
reverse=True
) if data_dir else []
context = {
"data_files": data_files,
"analyses": analysis_modules,
"selected_file": selected_file,
"selected_analyses": selected_analyses
}
if request.method == "POST":
selected_analyses = request.form.getlist("analyses")
selected_file = request.form.get("data_file")
if not selected_file:
context["error"] = "No file selected."
return render_template("analyze.html", **context)
df = load_data(selected_file)
results = {}
for analysis in analysis_modules:
if analysis.name in selected_analyses:
results[analysis.name] = analysis.execute(df) # Some may return HTML
context["results"] = results
return render_template("analyze.html", **context)
@views_bp.route('/server_time')
def server_time():
current_time = datetime.now(datetime.timezone.utc).strftime('%Y-%m-%d %H:%M:%S')
return {'server_time': current_time}
app.register_blueprint(views_bp)