from flask import Blueprint from flask import request, jsonify from peewee import SQL, fn from database import Message, Member from datetime import datetime statistics_api = Blueprint('statistics_api', __name__) @statistics_api.route("/top-users", methods=["GET"]) def top_users(): """ /top_users - top users for activity :param number - number top users """ data = [] number = int(request.args.get("number")) if not number: number = 3 query = (Member .select(fn.count(Message.id).alias("count"), Member) .join(Message) .group_by(Member) .order_by(SQL("count").desc()) ) for group in query: data.append({ "user": group.first_name, "count": group.count, }) data.insert(0, { "user": "Others", "count": sum(item["count"] for i, item in enumerate(data) if i >= number), }) return jsonify(data[:number + 1]) @statistics_api.route("/last-chat-activity", methods=["GET"]) def last_chat_activity(): """ /last-chat-activity - last chat activity selected range :param startDate: datetime at which start(optional) :param endDate: datetime at which end :param groupBy: year, month, day, hour :param formatDatetime: format string datetime object(default: %Y-%m-%d) """ data = [] start_date = request.args.get("startDate") end_date = request.args.get("endDate") if not start_date or not end_date: return jsonify({ "err": "startDate/endDate must be defined" }), 422 date_format = request.args.get("formatDatetime") if not date_format: date_format = "%Y-%m-%d" groupby_keys = ["year", "month", "week", "day"] group_by = request.args.get("groupBy") if not group_by or not (group_by in groupby_keys): return jsonify({ "err": "invalid groupBy parametr(year, month, day, hour)" }), 422 try: start_date = datetime.strptime(start_date, date_format) end_date = datetime.strptime(end_date, date_format) except ValueError: return jsonify({ "err": "Can't unparse startDate/endDate" }), 422 query = (Message .select(fn.date_trunc(group_by, Message.timestamp).alias('range'), fn.count(Message.id).alias('count')) .where((Message.timestamp >= start_date) & (Message.timestamp <= end_date)) .group_by(fn.date_trunc(group_by, Message.timestamp)) .order_by(SQL("range")) ) for record in query: data.append({ "datetime": record.range.strftime(date_format), "count": record.count, }) return jsonify(data) @statistics_api.route("/last-user-activity", methods=["GET"]) def last_user_activity(): """ /last-user-activity - user activity selected range :param user_id: user id :param startDate: datetime at which start(optional) :param endDate: datetime at which end :param groupBy: year, month, day, hour :param formatDatetime: format string datetime object(default: %Y-%m-%d) """ data = [] user_id = request.args.get("user_id") user = Member.get_or_none(Member.user_id == user_id) start_date = request.args.get("startDate") end_date = request.args.get("endDate") if not start_date or not end_date: return jsonify({ "err": "startDate/endDate must be defined" }), 422 date_format = request.args.get("formatDatetime") if not date_format: date_format = "%Y-%m-%d" groupby_keys = ["year", "month", "week", "day"] group_by = request.args.get("groupBy") if not group_by or not (group_by in groupby_keys): return jsonify({ "err": "invalid groupBy parametr(year, month, day, hour)" }), 422 try: start_date = datetime.strptime(start_date, date_format) end_date = datetime.strptime(end_date, date_format) except ValueError: return jsonify({ "err": "Can't unparse start_date and end_date" }), 422 query = (Message .select(fn.date_trunc(group_by, Message.timestamp).alias("range"), fn.count(Message.id).alias("count")) .where((Message.user == user) & (Message.timestamp >= start_date) & (Message.timestamp <= end_date)) .group_by(fn.date_trunc(group_by, Message.timestamp)) .order_by(SQL("range")) ) for record in query: data.append({ "datetime": record.range.strftime(date_format), "count": record.count, }) return jsonify(data)