2022-06-07 12:31:24 +00:00
|
|
|
from flask import g
|
|
|
|
import time
|
|
|
|
import calendar
|
|
|
|
import matplotlib.pyplot as plt
|
2023-07-13 12:51:38 +00:00
|
|
|
from sqlalchemy.sql import func, or_
|
2022-06-07 12:31:24 +00:00
|
|
|
|
|
|
|
from files.classes.user import User
|
2023-06-07 23:26:32 +00:00
|
|
|
from files.classes.post import Post
|
2022-06-07 12:31:24 +00:00
|
|
|
from files.classes.comment import Comment
|
2022-06-10 09:47:41 +00:00
|
|
|
from files.classes.votes import Vote, CommentVote
|
2023-03-18 13:34:04 +00:00
|
|
|
from files.classes.emoji import *
|
2022-06-10 09:47:41 +00:00
|
|
|
from files.classes.award import AwardRelationship
|
2022-12-11 23:44:34 +00:00
|
|
|
from files.helpers.config.const import *
|
2022-06-07 12:31:24 +00:00
|
|
|
|
|
|
|
def generate_charts_task(site):
|
2022-09-04 23:15:37 +00:00
|
|
|
chart(kind='daily', site=site)
|
2022-06-07 12:31:24 +00:00
|
|
|
chart(kind='weekly', site=site)
|
|
|
|
|
|
|
|
def chart(kind, site):
|
|
|
|
now = time.gmtime()
|
|
|
|
midnight_this_morning = time.struct_time((
|
|
|
|
now.tm_year, now.tm_mon, now.tm_mday,
|
|
|
|
0, 0, 0,
|
|
|
|
now.tm_wday, now.tm_yday, 0))
|
|
|
|
today_cutoff = calendar.timegm(midnight_this_morning)
|
|
|
|
|
2023-05-13 02:00:31 +00:00
|
|
|
num_of_weeks = 30
|
2023-05-05 21:45:25 +00:00
|
|
|
|
2023-05-04 21:25:19 +00:00
|
|
|
chart_width = int(num_of_weeks/0.7)
|
2022-06-07 12:31:24 +00:00
|
|
|
|
|
|
|
if kind == 'daily':
|
|
|
|
day_cutoffs = [today_cutoff - 86400 * i for i in range(num_of_weeks)][1:]
|
|
|
|
else:
|
|
|
|
day_cutoffs = [today_cutoff - 86400 * 7 * i for i in range(num_of_weeks)][1:]
|
|
|
|
day_cutoffs.insert(0, calendar.timegm(now))
|
|
|
|
|
2023-05-04 21:25:19 +00:00
|
|
|
daily_times = [time.strftime('%Y-%m-%d', time.gmtime(day_cutoffs[i + 1]))
|
2022-06-07 12:31:24 +00:00
|
|
|
for i in range(len(day_cutoffs) - 1)][::-1]
|
|
|
|
|
2023-03-16 06:27:58 +00:00
|
|
|
daily_signups = [g.db.query(User).filter(
|
2023-01-01 11:36:20 +00:00
|
|
|
User.created_utc < day_cutoffs[i],
|
|
|
|
User.created_utc > day_cutoffs[i + 1]).count()
|
2022-06-07 12:31:24 +00:00
|
|
|
for i in range(len(day_cutoffs) - 1)][::-1]
|
|
|
|
|
2023-06-07 23:26:32 +00:00
|
|
|
post_stats = [g.db.query(Post).filter(
|
|
|
|
Post.created_utc < day_cutoffs[i],
|
|
|
|
Post.created_utc > day_cutoffs[i + 1],
|
|
|
|
Post.is_banned == False).count()
|
2022-06-07 12:31:24 +00:00
|
|
|
for i in range(len(day_cutoffs) - 1)][::-1]
|
|
|
|
|
2023-03-16 06:27:58 +00:00
|
|
|
comment_stats = [g.db.query(Comment).filter(
|
2023-01-01 11:36:20 +00:00
|
|
|
Comment.created_utc < day_cutoffs[i],
|
2022-06-07 12:31:24 +00:00
|
|
|
Comment.created_utc > day_cutoffs[i + 1],
|
2023-01-01 11:36:20 +00:00
|
|
|
Comment.is_banned == False,
|
|
|
|
Comment.author_id != AUTOJANNY_ID).count()
|
2022-06-07 12:31:24 +00:00
|
|
|
for i in range(len(day_cutoffs) - 1)][::-1]
|
|
|
|
|
2023-05-04 21:25:19 +00:00
|
|
|
plt.rcParams['figure.figsize'] = (chart_width, chart_width)
|
2022-06-07 12:31:24 +00:00
|
|
|
|
2023-05-04 21:25:19 +00:00
|
|
|
signup_chart = plt.subplot2grid((chart_width, chart_width), (0, 0), rowspan=6, colspan=chart_width)
|
|
|
|
posts_chart = plt.subplot2grid((chart_width, chart_width), (10, 0), rowspan=6, colspan=chart_width)
|
|
|
|
comments_chart = plt.subplot2grid((chart_width, chart_width), (20, 0), rowspan=6, colspan=chart_width)
|
2022-06-07 12:31:24 +00:00
|
|
|
|
|
|
|
signup_chart.grid(), posts_chart.grid(), comments_chart.grid()
|
|
|
|
|
2022-09-04 23:15:37 +00:00
|
|
|
signup_chart.plot(daily_times, daily_signups, color='red')
|
|
|
|
posts_chart.plot(daily_times, post_stats, color='blue')
|
|
|
|
comments_chart.plot(daily_times, comment_stats, color='purple')
|
2022-06-07 12:31:24 +00:00
|
|
|
|
|
|
|
signup_chart.set_ylim(ymin=0)
|
|
|
|
posts_chart.set_ylim(ymin=0)
|
|
|
|
comments_chart.set_ylim(ymin=0)
|
|
|
|
|
2023-09-06 17:13:11 +00:00
|
|
|
signup_chart.set_xlabel("Signups", labelpad=10.0, size=30)
|
|
|
|
posts_chart.set_xlabel("Posts", labelpad=10.0, size=30)
|
|
|
|
comments_chart.set_xlabel("Comments", labelpad=10.0, size=30)
|
2022-06-07 12:31:24 +00:00
|
|
|
|
|
|
|
file = chart_path(kind, site)
|
|
|
|
|
2022-10-23 15:46:03 +00:00
|
|
|
plt.savefig(file, bbox_inches='tight')
|
2022-06-07 12:31:24 +00:00
|
|
|
plt.clf()
|
|
|
|
return file
|
|
|
|
|
|
|
|
def chart_path(kind, site):
|
|
|
|
return f'/{site}_{kind}.png'
|
2022-06-10 09:47:41 +00:00
|
|
|
|
2023-03-25 20:57:27 +00:00
|
|
|
def stats():
|
2022-11-06 00:14:58 +00:00
|
|
|
now = time.time()
|
|
|
|
day = int(now) - 86400
|
|
|
|
week = int(now) - 604800
|
2022-06-10 09:47:41 +00:00
|
|
|
|
|
|
|
stats = {
|
2024-01-23 12:56:46 +00:00
|
|
|
"Time these stats were collected": int(time.time()),
|
|
|
|
"Marseys": "{:,}".format(g.db.query(Emoji).filter(Emoji.kind=="Marsey", Emoji.submitter_id==None).count()),
|
|
|
|
"Total emojis": "{:,}".format(g.db.query(Emoji).filter(Emoji.submitter_id==None).count()),
|
|
|
|
"Users": "{:,}".format(g.db.query(User).count()),
|
|
|
|
"Banned users": "{:,}".format(g.db.query(User).filter(User.is_banned != None).count()),
|
2024-01-23 13:53:22 +00:00
|
|
|
"Users with a private profile": "{:,}".format(g.db.query(User).filter_by(is_private=True).count()),
|
|
|
|
"Users with a verified email": "{:,}".format(g.db.query(User).filter_by(email_verified=True).count()),
|
2024-01-23 12:56:46 +00:00
|
|
|
"Coins in circulation": "{:,}".format(g.db.query(func.sum(User.coins)).scalar()),
|
|
|
|
"Total shop sales": "{:,}".format(g.db.query(func.sum(User.coins_spent)).scalar()),
|
|
|
|
"Signups last 24h": "{:,}".format(g.db.query(User).filter(User.created_utc > day).count()),
|
|
|
|
"Total posts": "{:,}".format(g.db.query(Post).count()),
|
|
|
|
"Posting users": "{:,}".format(g.db.query(Post.author_id).distinct().count()),
|
|
|
|
"Listed posts": "{:,}".format(g.db.query(Post).filter_by(is_banned=False).filter(Post.deleted_utc == 0).count()),
|
|
|
|
"Removed posts (by admins)": "{:,}".format(g.db.query(Post).filter_by(is_banned=True).count()),
|
|
|
|
"Deleted posts (by author)": "{:,}".format(g.db.query(Post).filter(Post.deleted_utc > 0).count()),
|
|
|
|
"Posts last 24h": "{:,}".format(g.db.query(Post).filter(Post.created_utc > day).count()),
|
|
|
|
"Total comments": "{:,}".format(g.db.query(Comment).filter(Comment.author_id != AUTOJANNY_ID).count()),
|
|
|
|
"Commenting users": "{:,}".format(g.db.query(Comment.author_id).distinct().count()),
|
|
|
|
"Removed comments (by admins)": "{:,}".format(g.db.query(Comment).filter_by(is_banned=True).count()),
|
|
|
|
"Deleted comments (by author)": "{:,}".format(g.db.query(Comment).filter(Comment.deleted_utc > 0).count()),
|
|
|
|
"Comments last 24h": "{:,}".format(g.db.query(Comment).filter(Comment.created_utc > day, Comment.author_id != AUTOJANNY_ID).count()),
|
|
|
|
"Post votes": "{:,}".format(g.db.query(Vote).count()),
|
|
|
|
"Comment votes": "{:,}".format(g.db.query(CommentVote).count()),
|
|
|
|
"Total upvotes": "{:,}".format(g.db.query(Vote).filter_by(vote_type=1).count() + g.db.query(CommentVote).filter_by(vote_type=1).count()),
|
|
|
|
"Total downvotes": "{:,}".format(g.db.query(Vote).filter_by(vote_type=-1).count() + g.db.query(CommentVote).filter_by(vote_type=-1).count()),
|
|
|
|
"Total awards": "{:,}".format(g.db.query(AwardRelationship).count()),
|
|
|
|
"Awards given": "{:,}".format(g.db.query(AwardRelationship).filter(or_(AwardRelationship.post_id != None, AwardRelationship.comment_id != None)).count()),
|
|
|
|
"Users who posted, commented, or voted in the past 7 days": "{:,}".format(g.db.query(User).filter(User.last_active > week).count()),
|
2023-11-25 19:46:05 +00:00
|
|
|
}
|
2022-06-10 09:47:41 +00:00
|
|
|
|
2023-11-25 19:46:16 +00:00
|
|
|
if FEATURES['HOUSES']:
|
2022-06-10 09:47:41 +00:00
|
|
|
stats2 = {
|
2023-06-26 15:05:27 +00:00
|
|
|
"House Furry members": "{:,}".format(g.db.query(User).filter(User.house.like('Furry%')).count()),
|
|
|
|
"House Femboy members": "{:,}".format(g.db.query(User).filter(User.house.like('Femboy%')).count()),
|
|
|
|
"House Vampire members": "{:,}".format(g.db.query(User).filter(User.house.like('Vampire%')).count()),
|
|
|
|
"House Racist members": "{:,}".format(g.db.query(User).filter(User.house.like('Racist%')).count()),
|
|
|
|
"House Edgy members": "{:,}".format(g.db.query(User).filter(User.house.like('Edgy%')).count()),
|
|
|
|
"House Furry total truescore": "{:,}".format(g.db.query(func.sum(User.truescore)).filter(User.house.like('Furry%')).scalar() or 0),
|
|
|
|
"House Femboy total truescore": "{:,}".format(g.db.query(func.sum(User.truescore)).filter(User.house.like('Femboy%')).scalar() or 0),
|
|
|
|
"House Vampire total truescore": "{:,}".format(g.db.query(func.sum(User.truescore)).filter(User.house.like('Vampire%')).scalar() or 0),
|
|
|
|
"House Racist total truescore": "{:,}".format(g.db.query(func.sum(User.truescore)).filter(User.house.like('Racist%')).scalar() or 0),
|
|
|
|
"House Edgy total truescore": "{:,}".format(g.db.query(func.sum(User.truescore)).filter(User.house.like('Edgy%')).scalar() or 0),
|
2022-06-10 09:47:41 +00:00
|
|
|
}
|
|
|
|
stats.update(stats2)
|
|
|
|
|
|
|
|
return stats
|