improve analytics

This commit is contained in:
lelo 2025-03-23 15:32:16 +01:00
parent 40ddea4d42
commit 9d744e7948
3 changed files with 31 additions and 67 deletions

View File

@ -179,24 +179,20 @@ def dashboard():
WHERE timestamp >= ? WHERE timestamp >= ?
GROUP BY ip_address GROUP BY ip_address
ORDER BY count DESC ORDER BY count DESC
LIMIT 20 LIMIT 1000
''', (start.isoformat(),)) ''', (start.isoformat(),))
ip_rows = cursor.fetchall() ip_rows = cursor.fetchall()
# Initialize GeoIP2 reader once for efficiency # Initialize GeoIP2 reader once for efficiency
reader = geoip2.database.Reader('GeoLite2-City.mmdb') reader = geoip2.database.Reader('GeoLite2-City.mmdb')
ip_data = [] location_data = []
for ip, count in ip_rows: for ip, count in ip_rows:
country, city = lookup_location(ip, reader) country, city = lookup_location(ip, reader)
ip_data.append(dict(ip=ip, count=count, country=country, city=city)) location_data.append(dict(count=count, country=country, city=city))
reader.close() reader.close()
# Sort by count in descending order and take the top 20
# Aggregate by city (ignoring entries without a city) location_data.sort(key=lambda x: x['count'], reverse=True)
city_counts = {} location_data = location_data[:20]
for entry in ip_data:
if entry['city']:
city_counts[entry['city']] = city_counts.get(entry['city'], 0) + entry['count']
city_data = [dict(city=city, count=count) for city, count in city_counts.items()]
# Summary stats using separate SQL queries # Summary stats using separate SQL queries
cursor.execute('SELECT COUNT(*) FROM file_access_log WHERE timestamp >= ?', (start.isoformat(),)) cursor.execute('SELECT COUNT(*) FROM file_access_log WHERE timestamp >= ?', (start.isoformat(),))
@ -219,8 +215,7 @@ def dashboard():
top_files_data=top_files_data, top_files_data=top_files_data,
user_agent_data=user_agent_data, user_agent_data=user_agent_data,
referrer_data=referrer_data, referrer_data=referrer_data,
ip_data=ip_data, location_data=location_data,
city_data=city_data,
total_accesses=total_accesses, total_accesses=total_accesses,
unique_files=unique_files, unique_files=unique_files,
unique_ips=unique_ips) unique_ips=unique_ips)

View File

@ -41,7 +41,7 @@
<div class="col-md-4"> <div class="col-md-4">
<div class="card text-white bg-info"> <div class="card text-white bg-info">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">Total Accesses</h5> <h5 class="card-title">Alle Downloads</h5>
<p class="card-text">{{ total_accesses }}</p> <p class="card-text">{{ total_accesses }}</p>
</div> </div>
</div> </div>
@ -49,7 +49,7 @@
<div class="col-md-4"> <div class="col-md-4">
<div class="card text-white bg-success"> <div class="card text-white bg-success">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">Unique Files</h5> <h5 class="card-title">eindeutige Dateien</h5>
<p class="card-text">{{ unique_files }}</p> <p class="card-text">{{ unique_files }}</p>
</div> </div>
</div> </div>
@ -57,7 +57,7 @@
<div class="col-md-4"> <div class="col-md-4">
<div class="card text-white bg-warning"> <div class="card text-white bg-warning">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">Unique IPs</h5> <h5 class="card-title">eindeutige Nutzer</h5>
<p class="card-text">{{ unique_ips }}</p> <p class="card-text">{{ unique_ips }}</p>
</div> </div>
</div> </div>
@ -70,7 +70,7 @@
<div class="col-md-6 mb-4"> <div class="col-md-6 mb-4">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">Access Trend</h5> <h5 class="card-title">Downloads</h5>
<canvas id="accessTrendChart"></canvas> <canvas id="accessTrendChart"></canvas>
</div> </div>
</div> </div>
@ -79,7 +79,7 @@
<div class="col-md-6 mb-4"> <div class="col-md-6 mb-4">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">Top Files Accessed</h5> <h5 class="card-title">Häufig geladene Dateien</h5>
<canvas id="topFilesChart"></canvas> <canvas id="topFilesChart"></canvas>
</div> </div>
</div> </div>
@ -88,7 +88,7 @@
<div class="col-md-6 mb-4"> <div class="col-md-6 mb-4">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">User Agent Distribution</h5> <h5 class="card-title">Verwendete Endgeräte</h5>
<canvas id="userAgentChart"></canvas> <canvas id="userAgentChart"></canvas>
</div> </div>
</div> </div>
@ -97,7 +97,7 @@
<div class="col-md-6 mb-4"> <div class="col-md-6 mb-4">
<div class="card"> <div class="card">
<div class="card-body"> <div class="card-body">
<h5 class="card-title">Referrer Distribution</h5> <h5 class="card-title">Verteilung auf Ordner</h5>
<canvas id="referrerChart"></canvas> <canvas id="referrerChart"></canvas>
</div> </div>
</div> </div>
@ -107,58 +107,27 @@
<!-- New Section: IP Address Access Data --> <!-- New Section: IP Address Access Data -->
<div class="card"> <div class="card">
<div class="card-header"> <div class="card-header">
IP Address Access Distribution Verteilung der Zugriffe
</div> </div>
<div class="card-body"> <div class="card-body">
<table class="table table-bordered"> <table class="table table-bordered">
<thead> <thead>
<tr> <tr>
<th>IP Address</th> <th>Anzahl Downloads</th>
<th>Access Count</th> <th>Stadt</th>
<th>City</th> <th>Land</th>
<th>Country</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for ip in ip_data %} {% for loc in location_data %}
<tr> <tr>
<td>{{ ip.ip }}</td> <td>{{ loc.count }}</td>
<td>{{ ip.count }}</td> <td>{{ loc.city }}</td>
<td>{{ ip.city }}</td> <td>{{ loc.country }}</td>
<td>{{ ip.country }}</td>
</tr> </tr>
{% else %} {% else %}
<tr> <tr>
<td colspan="4">No IP access data available for the selected timeframe.</td> <td colspan="4">No access data available for the selected timeframe.</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<!-- New Section: Aggregated City Access Data -->
<div class="card">
<div class="card-header">
City Access Distribution
</div>
<div class="card-body">
<table class="table table-bordered">
<thead>
<tr>
<th>City</th>
<th>Access Count</th>
</tr>
</thead>
<tbody>
{% for city in city_data %}
<tr>
<td>{{ city.city }}</td>
<td>{{ city.count }}</td>
</tr>
{% else %}
<tr>
<td colspan="2">No city access data available for the selected timeframe.</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
@ -169,7 +138,7 @@
<!-- Detailed Table of Top File Accesses --> <!-- Detailed Table of Top File Accesses -->
<div class="card mb-4"> <div class="card mb-4">
<div class="card-header"> <div class="card-header">
Detailed File Access Data Detailierte Dateizugriffe (Top 20)
</div> </div>
<div class="card-body"> <div class="card-body">
<table class="table table-striped"> <table class="table table-striped">
@ -214,7 +183,7 @@
data: { data: {
labels: dailyAccessData.map(item => item.date), labels: dailyAccessData.map(item => item.date),
datasets: [{ datasets: [{
label: 'Access Count', label: 'Download Count',
data: dailyAccessData.map(item => item.count), data: dailyAccessData.map(item => item.count),
borderWidth: 2, borderWidth: 2,
fill: true fill: true
@ -224,8 +193,8 @@
responsive: true, responsive: true,
plugins: { legend: { position: 'top' } }, plugins: { legend: { position: 'top' } },
scales: { scales: {
x: { title: { display: true, text: 'Date' } }, x: { title: { display: true, text: 'Datum' } },
y: { title: { display: true, text: 'Access Count' } } y: { title: { display: true, text: 'Download Count' } }
} }
} }
}); });
@ -237,7 +206,7 @@
data: { data: {
labels: topFilesData.map(item => item.full_path), labels: topFilesData.map(item => item.full_path),
datasets: [{ datasets: [{
label: 'Access Count', label: 'Download Count',
data: topFilesData.map(item => item.access_count), data: topFilesData.map(item => item.access_count),
borderWidth: 1 borderWidth: 1
}] }]
@ -247,8 +216,8 @@
responsive: true, responsive: true,
plugins: { legend: { display: false } }, plugins: { legend: { display: false } },
scales: { scales: {
x: { title: { display: true, text: 'Access Count' } }, x: { title: { display: true, text: 'Download Count' } },
y: { title: { display: true, text: 'File Path' } } y: { title: { display: true, text: '' } }
} }
} }
}); });

View File

@ -21,7 +21,7 @@
</header> </header>
<div class="container"> <div class="container">
<div id="content">Bitte den Link aus der Telegram-Gruppe erneut anklicken.</div> <div id="content">Du hast keine gültigen Links im Speicher.<br>Bitte den Link aus der Telegram-Gruppe erneut anklicken.</div>
</div> </div>
</body> </body>
</html> </html>