diff --git a/access_log.db b/access_log.db new file mode 100644 index 0000000..77531b6 Binary files /dev/null and b/access_log.db differ diff --git a/app.py b/app.py index d5fcb7e..55d79e1 100755 --- a/app.py +++ b/app.py @@ -4,7 +4,8 @@ from PIL import Image import io from functools import wraps import mimetypes -from datetime import datetime, date +import sqlite3 +from datetime import datetime, date, timedelta from urllib.parse import unquote import diskcache import json @@ -193,6 +194,75 @@ def api_browse(subpath): 'files': files }) +@app.route("/access-log") +@require_secret +def access_log(): + # Get timeframe filter from query parameter; default to "today" + timeframe = request.args.get('timeframe', 'today') + now = datetime.now() + + # Determine the start time based on the requested timeframe + if timeframe == 'today': + # Beginning of today + start = now.replace(hour=0, minute=0, second=0, microsecond=0) + elif timeframe == '7days': + start = now - timedelta(days=7) + elif timeframe == '30days': + start = now - timedelta(days=30) + elif timeframe == '365days': + start = now - timedelta(days=365) + else: + # Default to today if an unknown timeframe is passed + start = now.replace(hour=0, minute=0, second=0, microsecond=0) + + # Query the access log database for file access counts since the 'start' time + conn = sqlite3.connect('access_log.db') + cursor = conn.cursor() + cursor.execute(''' + SELECT full_path, COUNT(*) as access_count + FROM file_access_log + WHERE timestamp >= ? + GROUP BY full_path + ORDER BY access_count DESC + ''', (start.isoformat(),)) + rows = cursor.fetchall() + conn.close() + + return render_template("access_log.html", rows=rows, timeframe=timeframe) + +def log_file_access(full_path): + """ + Log file access details to a SQLite database. + Records the timestamp, full file path, client IP, user agent, and referrer. + """ + # Connect to the database (this will create the file if it doesn't exist) + conn = sqlite3.connect('access_log.db') + cursor = conn.cursor() + # Create the table if it doesn't exist + cursor.execute(''' + CREATE TABLE IF NOT EXISTS file_access_log ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + timestamp TEXT, + full_path TEXT, + ip_address TEXT, + user_agent TEXT, + referrer TEXT + ) + ''') + # Gather information from the request + timestamp = datetime.now().isoformat() + ip_address = request.remote_addr + user_agent = request.headers.get('User-Agent') + referrer = request.headers.get('Referer') + + # Insert the access record into the database + cursor.execute(''' + INSERT INTO file_access_log (timestamp, full_path, ip_address, user_agent, referrer) + VALUES (?, ?, ?, ?, ?) + ''', (timestamp, full_path, ip_address, user_agent, referrer)) + conn.commit() + conn.close() + @app.route("/media/") @require_secret def serve_file(filename): @@ -203,6 +273,8 @@ def serve_file(filename): app.logger.error(f"File not found: {full_path}") return "File not found", 404 + log_file_access(full_path) + mime, _ = mimetypes.guess_type(full_path) mime = mime or 'application/octet-stream' diff --git a/docker-compose.yml b/docker-compose.yml index 6b78c95..00c2e96 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,3 @@ -version: "3" - services: flask-app: image: python:3.11-slim diff --git a/templates/access_log.html b/templates/access_log.html new file mode 100644 index 0000000..271ae14 --- /dev/null +++ b/templates/access_log.html @@ -0,0 +1,46 @@ + + + + + File Access Log + + + +

File Access Log ({{ timeframe }})

+
+ Today + Last 7 Days + Last 30 Days + Last 365 Days +
+
+ + + + + + + + + {% for row in rows %} + + + + + {% else %} + + + + {% endfor %} + +
File PathAccess Count
{{ row[0] }}{{ row[1] }}
No data available for the selected timeframe.
+
+ + \ No newline at end of file