diff --git a/app.py b/app.py index d4ca0f1..c70136a 100644 --- a/app.py +++ b/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 diff --git a/apps/admin.py b/apps/admin.py index 5df42bd..d63eee2 100644 --- a/apps/admin.py +++ b/apps/admin.py @@ -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()) diff --git a/apps/auth.py b/apps/auth.py index 16d4433..6972675 100644 --- a/apps/auth.py +++ b/apps/auth.py @@ -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") diff --git a/apps/group_stat_api.py b/apps/group_stat_api.py new file mode 100644 index 0000000..ffe7bc1 --- /dev/null +++ b/apps/group_stat_api.py @@ -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] + }) diff --git a/database.py b/database.py index 6d6a2c5..5489b83 100644 --- a/database.py +++ b/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]) diff --git a/static/css/statistics.css b/static/css/statistics.css new file mode 100644 index 0000000..f3b5948 --- /dev/null +++ b/static/css/statistics.css @@ -0,0 +1,4 @@ +#top-users { + width: 500px; + height: 500px; +} diff --git a/static/js/top-users.js b/static/js/top-users.js new file mode 100644 index 0000000..fc76d6b --- /dev/null +++ b/static/js/top-users.js @@ -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}%` + } + } + } + } + }, + }); +}) diff --git a/templates/statistics.html b/templates/statistics.html new file mode 100644 index 0000000..e297dfc --- /dev/null +++ b/templates/statistics.html @@ -0,0 +1,22 @@ + + + + Statistics + + + + + + + + + + +
+ +
+ + + + +