from flask import g import time import calendar import matplotlib.pyplot as plt from sqlalchemy.sql import func from files.classes.user import User from files.classes.post import Post from files.classes.comment import Comment from files.classes.votes import Vote, CommentVote from files.classes.emoji import * from files.classes.award import AwardRelationship from files.helpers.config.const import * def generate_charts_task(site): chart(kind='daily', site=site) 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) num_of_weeks = 30 chart_width = int(num_of_weeks/0.7) 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)) daily_times = [time.strftime('%Y-%m-%d', time.gmtime(day_cutoffs[i + 1])) for i in range(len(day_cutoffs) - 1)][::-1] daily_signups = [g.db.query(User).filter( User.created_utc < day_cutoffs[i], User.created_utc > day_cutoffs[i + 1]).count() for i in range(len(day_cutoffs) - 1)][::-1] 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() for i in range(len(day_cutoffs) - 1)][::-1] comment_stats = [g.db.query(Comment).filter( Comment.created_utc < day_cutoffs[i], Comment.created_utc > day_cutoffs[i + 1], Comment.is_banned == False, Comment.author_id != AUTOJANNY_ID).count() for i in range(len(day_cutoffs) - 1)][::-1] plt.rcParams['figure.figsize'] = (chart_width, chart_width) 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) signup_chart.grid(), posts_chart.grid(), comments_chart.grid() 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') signup_chart.set_ylim(ymin=0) posts_chart.set_ylim(ymin=0) comments_chart.set_ylim(ymin=0) signup_chart.set_ylabel("Signups") posts_chart.set_ylabel("Posts") comments_chart.set_ylabel("Comments") comments_chart.set_xlabel("Time (UTC) YYYY-MM-DD") file = chart_path(kind, site) plt.savefig(file, bbox_inches='tight') plt.clf() return file def chart_path(kind, site): return f'/{site}_{kind}.png' def stats(): now = time.time() day = int(now) - 86400 week = int(now) - 604800 posters = g.db.query(Post.author_id).distinct(Post.author_id).filter(Post.created_utc > week).all() commenters = g.db.query(Comment.author_id).distinct(Comment.author_id).filter(Comment.created_utc > week).all() voters = g.db.query(Vote.user_id).distinct(Vote.user_id).filter(Vote.created_utc > week).all() commentvoters = g.db.query(CommentVote.user_id).distinct(CommentVote.user_id).filter(CommentVote.created_utc > week).all() active_users = set(posters) | set(commenters) | set(voters) | set(commentvoters) stats = { "time": int(time.time()), "marseys": "{:,}".format(g.db.query(Emoji).filter(Emoji.kind=="Marsey", Emoji.submitter_id==None).count()), "users": "{:,}".format(g.db.query(User).count()), "private users": "{:,}".format(g.db.query(User).filter_by(is_private=True).count()), "banned users": "{:,}".format(g.db.query(User).filter(User.is_banned != None).count()), "verified email users": "{:,}".format(g.db.query(User).filter_by(is_activated=True).count()), "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(len(active_users)), "users online in the past 7 days": "{:,}".format(g.db.query(User).filter(User.last_active > week).count()), } if SITE_NAME == 'rDrama' or FEATURES['HOUSES']: stats2 = { "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), } stats.update(stats2) return stats