112 lines
3.5 KiB
Python

"""Logger view."""
import csv
import io
import datetime
from flask import Blueprint, render_template, request, send_file
from ..db import db
from ..models import ActivityLog, ActivityCategory
bp = Blueprint("logger", __name__, url_prefix="/logs")
@bp.route("/")
def list_logs():
page = request.args.get("page", 1, type=int)
per_page = 50
# Filters
category = request.args.get("category")
start_date = request.args.get("start_date")
end_date = request.args.get("end_date")
search_term = request.args.get("search_term")
if search_term == "None":
search_term = None
query = ActivityLog.query
if category:
query = query.filter(ActivityLog.category == category)
if start_date:
start_date_dt = datetime.datetime.strptime(start_date, "%Y-%m-%d")
query = query.filter(ActivityLog.timestamp >= start_date_dt)
if end_date:
end_date_dt = datetime.datetime.strptime(end_date, "%Y-%m-%d") + datetime.timedelta(days=1)
query = query.filter(ActivityLog.timestamp <= end_date_dt)
if search_term:
query = query.filter(db.or_(
ActivityLog.action.contains(search_term),
ActivityLog.description.contains(search_term)
))
pagination = query.order_by(ActivityLog.timestamp.desc()).paginate(page=page, per_page=per_page, error_out=False)
categories = [e.value for e in ActivityCategory]
return render_template(
"logger.html.jinja",
logs=pagination.items,
pagination=pagination,
categories=categories,
category=category,
start_date=start_date,
end_date=end_date,
search_term=search_term,
app_title="PaperScraper",
)
@bp.route("/download")
def download_logs():
# Filters - reuse logic from list_logs
category = request.args.get("category")
start_date = request.args.get("start_date")
end_date = request.args.get("end_date")
search_term = request.args.get("search_term")
query = ActivityLog.query
if category:
query = query.filter(ActivityLog.category == category)
if start_date:
start_date_dt = datetime.datetime.strptime(start_date, "%Y-%m-%d")
query = query.filter(ActivityLog.timestamp >= start_date_dt)
if end_date:
end_date_dt = datetime.datetime.strptime(end_date, "%Y-%m-%d") + datetime.timedelta(days=1)
query = query.filter(ActivityLog.timestamp <= end_date_dt)
if search_term:
query = query.filter(db.or_(
ActivityLog.action.contains(search_term),
ActivityLog.description.contains(search_term)
))
logs = query.order_by(ActivityLog.timestamp.desc()).all()
# Prepare CSV data
csv_data = io.StringIO()
csv_writer = csv.writer(csv_data)
csv_writer.writerow(["Timestamp", "Category", "Action", "Description", "Extra Data"]) # Header
for log in logs:
csv_writer.writerow([
log.timestamp,
log.category,
log.action,
log.description,
log.extra_data # Consider formatting this better
])
# Create response
filename = f"logs_{datetime.datetime.now().strftime('%Y%m%d_%H%M%S')}.csv"
return send_file(
io.StringIO(csv_data.getvalue()),
mimetype="text/csv",
as_attachment=True,
download_name=filename
)
@bp.route("/<int:log_id>/detail")
def log_detail(log_id):
log = ActivityLog.query.get_or_404(log_id)
return render_template("partials/log_detail_modal.html.jinja", log=log)