Add statistics page & statistics api
This commit is contained in:
parent
98922ce312
commit
96da02d311
3
app.py
3
app.py
|
@ -5,6 +5,8 @@ import logging
|
|||
from apps.admin import admin as blueprint_admin
|
||||
from apps.auth import auth as blueprint_auth
|
||||
|
||||
from apps.group_stat_api import group_stat_api as blueprint_stat_api
|
||||
|
||||
from config import secret_key
|
||||
|
||||
app = Flask(__name__)
|
||||
|
@ -12,6 +14,7 @@ app.secret_key = secret_key
|
|||
|
||||
app.register_blueprint(blueprint_auth)
|
||||
app.register_blueprint(blueprint_admin)
|
||||
app.register_blueprint(blueprint_stat_api)
|
||||
|
||||
if __name__ == '__main__':
|
||||
from database import build_database
|
||||
|
|
|
@ -11,6 +11,10 @@ def admin_page():
|
|||
return render_template("index.html", username=session["username"])
|
||||
return redirect(url_for("auth.login_page"))
|
||||
|
||||
@admin.route("/stat")
|
||||
def chart():
|
||||
return render_template("statistics.html")
|
||||
|
||||
@admin.route("/members")
|
||||
def table_of_members():
|
||||
return render_template("members.html", members=Member.select())
|
||||
|
|
|
@ -20,7 +20,7 @@ def login_page():
|
|||
session["username"] = username
|
||||
return redirect(url_for("admin.admin_page"))
|
||||
|
||||
flash("password/username not valid")
|
||||
flash("wrong nickname/password!")
|
||||
return redirect(url_for("auth.login_page"))
|
||||
|
||||
@auth.route("/logout")
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
from flask import Blueprint, jsonify
|
||||
|
||||
group_stat_api = Blueprint('group_stat_api', __name__)
|
||||
|
||||
|
||||
@group_stat_api.route("/top3_users",methods=["POST"])
|
||||
def top_users():
|
||||
# TODO: database
|
||||
return jsonify({
|
||||
"members": ["Mr.D", "𝙲𝚊𝚝𝚒𝚘𝚗", "Тёма","Others"],
|
||||
"counts":[4026,3024,2024,4096]
|
||||
})
|
39
database.py
39
database.py
|
@ -1,7 +1,8 @@
|
|||
from peewee import Model,CharField
|
||||
|
||||
from peewee import Model, CharField, BigIntegerField, DateField, TimestampField
|
||||
from playhouse.db_url import connect
|
||||
|
||||
from datetime import date, datetime
|
||||
|
||||
from config import db_url
|
||||
db = connect(db_url)
|
||||
|
||||
|
@ -12,17 +13,31 @@ class WebUser(Model):
|
|||
class Meta:
|
||||
db_table = "webusers"
|
||||
database = db
|
||||
|
||||
@staticmethod
|
||||
def userExists(username) -> bool:
|
||||
"""Check if the username exists in a database."""
|
||||
query = WebUser.select().where(WebUser.username == username)
|
||||
|
||||
if (query):
|
||||
if (query.exists()):
|
||||
return True
|
||||
|
||||
return False
|
||||
class Member(Model):
|
||||
user_id = BigIntegerField()
|
||||
first_name = CharField()
|
||||
username = CharField(null=True)
|
||||
|
||||
role = CharField(default="member")
|
||||
|
||||
warns = BigIntegerField(default=0)
|
||||
|
||||
joined = DateField(default=date.today())
|
||||
|
||||
|
||||
class Meta:
|
||||
db_table = "members"
|
||||
database = db
|
||||
|
||||
class Message(Model):
|
||||
user_id = BigIntegerField()
|
||||
timestamp = TimestampField(default=datetime.now())
|
||||
|
||||
class Meta:
|
||||
db_table = "messages"
|
||||
database = db
|
||||
|
||||
def build_database():
|
||||
# db.create_tables([Message])
|
||||
db.create_tables([WebUser])
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
#top-users {
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
const options = {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'}
|
||||
}
|
||||
|
||||
fetch("/top3_users", options)
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error: ${response.status}`);
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}).then((data) => {
|
||||
const ctx = document.getElementById('top-users');
|
||||
|
||||
new Chart(ctx, {
|
||||
type: 'pie',
|
||||
data: {
|
||||
labels: data["members"],
|
||||
datasets: [{
|
||||
data: data["counts"]
|
||||
}]
|
||||
},
|
||||
|
||||
plugins: [ChartDataLabels],
|
||||
options: {
|
||||
maintainAspectRatio: false,
|
||||
plugins :{
|
||||
legend: false,
|
||||
|
||||
datalabels: {
|
||||
color: '#f4f6fc',
|
||||
formatter: function(value, context) {
|
||||
return context.chart.data.labels[context.dataIndex];
|
||||
}
|
||||
},
|
||||
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: (context) => {
|
||||
let sum = 0;
|
||||
let value = context.parsed;
|
||||
let dataArray = context.dataset.data;
|
||||
dataArray.map(data => {
|
||||
sum += data;
|
||||
});
|
||||
let percentage = Math.round(value*100 / sum);
|
||||
|
||||
return `${percentage}%`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
})
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Statistics</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link rel="stylesheet" href="../static/css/statistics.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-datalabels/2.2.0/chartjs-plugin-datalabels.min.js" integrity="sha512-JPcRR8yFa8mmCsfrw4TNte1ZvF1e3+1SdGMslZvmrzDYxS69J7J49vkFL8u6u8PlPJK+H3voElBtUCzaXj+6ig==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
||||
|
||||
<div>
|
||||
<canvas id="top-users"></canvas>
|
||||
</div>
|
||||
|
||||
<script src="../static/js/top-users.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue