From 1ce128ff43e22427c3ba2353753c63971a238fe4 Mon Sep 17 00:00:00 2001 From: ra_ma Date: Fri, 20 Jun 2025 19:44:27 +0100 Subject: [PATCH] statsu --- Dockerfile | 4 +-- app.py | 77 +++++++++++++++++++++++++++++++++++--------- templates/stats.html | 4 ++- 3 files changed, 67 insertions(+), 18 deletions(-) diff --git a/Dockerfile b/Dockerfile index 54570b6..d724148 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,11 +7,11 @@ WORKDIR /opt/app # Copy the current directory contents into the container COPY . /opt/app/ -# Install system dependencies required for lxml +# Install system dependencies required for lxml and matplotlib RUN apt-get update && apt-get install -y libxml2-dev libxslt1-dev # Install Python packages -RUN pip install --no-cache-dir Flask requests python-dotenv beautifulsoup4 gunicorn lxml +RUN pip install --no-cache-dir Flask requests python-dotenv beautifulsoup4 gunicorn lxml pandas matplotlib # Make port 8182 available to the world outside this container EXPOSE 8182 diff --git a/app.py b/app.py index b93aa00..1fb769d 100644 --- a/app.py +++ b/app.py @@ -1,14 +1,23 @@ import os import requests +import time +from collections import defaultdict from flask import Flask, render_template, request, redirect, url_for, Response from dotenv import load_dotenv from bs4 import BeautifulSoup +import pandas as pd +import matplotlib.pyplot as plt +from io import BytesIO +import base64 # Load environment variables from .env file load_dotenv() app = Flask(__name__, template_folder='templates') +# Data structure to store request statistics +request_stats = defaultdict(lambda: defaultdict(int)) + def get_config(): """Retrieve configuration from environment variables.""" return { @@ -18,21 +27,18 @@ def get_config(): "min_preference": os.getenv('MIN_PREFERENCE', '0') } -@app.route('/dash/config', methods=['GET', 'POST']) -def config(): - if request.method == 'POST': - # Update environment variables with form data - os.environ['EXCLUDED_COUNTRIES'] = request.form.get('excluded_countries', '') - os.environ['PREFERRED_PROTOCOLS'] = request.form.get('preferred_protocols', '') - os.environ['PREFERRED_TYPES'] = request.form.get('preferred_types', '') - os.environ['MIN_PREFERENCE'] = request.form.get('min_preference', '') - - return redirect(url_for('config')) - - # Retrieve the current configuration - config = get_config() - return render_template('config.html', **config) +def log_request(repo, arch, protocol): + """Log request statistics.""" + timestamp = int(time.time()) + hour = time.strftime('%Y-%m-%d %H', time.localtime(timestamp)) + day = time.strftime('%Y-%m-%d', time.localtime(timestamp)) + week = time.strftime('%Y-%U', time.localtime(timestamp)) + month = time.strftime('%Y-%m', time.localtime(timestamp)) + request_stats[hour][(repo, arch, protocol)] += 1 + request_stats[day][(repo, arch, protocol)] += 1 + request_stats[week][(repo, arch, protocol)] += 1 + request_stats[month][(repo, arch, protocol)] += 1 @app.route('/metalink') def get_metalink(): # Get query parameters from the request @@ -89,9 +95,50 @@ def filter_urls(content, excluded_countries, preferred_protocols, preferred_type return filtered_content +@app.route('/dash') @app.route('/dash/stats') def stats(): - return render_template('stats.html') + # Generate some statistics + stats_data = { + 'hourly': request_stats.get(time.strftime('%Y-%m-%d %H', time.localtime()), {}), + 'daily': request_stats.get(time.strftime('%Y-%m-%d', time.localtime()), {}), + 'weekly': request_stats.get(time.strftime('%Y-%U', time.localtime()), {}), + 'monthly': request_stats.get(time.strftime('%Y-%m', time.localtime()), {}) + } + + # Convert stats data to a DataFrame for easier manipulation + df = pd.DataFrame.from_dict(stats_data, orient='index').fillna(0) + + # Generate a simple plot + plt.figure(figsize=(10, 6)) + df.sum(axis=1).plot(kind='bar') + plt.title('Request Statistics') + plt.ylabel('Number of Requests') + + # Save plot to a BytesIO object + img = BytesIO() + plt.savefig(img, format='png') + plt.close() + img.seek(0) + + # Encode the plot to base64 for embedding in HTML + plot_url = base64.b64encode(img.getvalue()).decode('utf8') + + return render_template('stats.html', plot_url=plot_url) + +@app.route('/dash/config', methods=['GET', 'POST']) +def config(): + if request.method == 'POST': + # Update environment variables with form data + os.environ['EXCLUDED_COUNTRIES'] = request.form.get('excluded_countries', '') + os.environ['PREFERRED_PROTOCOLS'] = request.form.get('preferred_protocols', '') + os.environ['PREFERRED_TYPES'] = request.form.get('preferred_types', '') + os.environ['MIN_PREFERENCE'] = request.form.get('min_preference', '') + + return redirect(url_for('config')) + + config = get_config() + return render_template('config.html', **config) @app.route('/dash/logs') def logs(): diff --git a/templates/stats.html b/templates/stats.html index 49ad036..21f6719 100644 --- a/templates/stats.html +++ b/templates/stats.html @@ -3,6 +3,8 @@ {% block content %}

Statistics

-

Statistics content goes here.

+
+ Request Statistics +
{% endblock %}