Merge branch 'frost' of https://github.com/Aevann1/Drama into frost
commit
2db414f12d
|
@ -47,4 +47,9 @@ class Sub(Base):
|
|||
@property
|
||||
@lazy
|
||||
def block_num(self):
|
||||
return len(self.blocks)
|
||||
return len(self.blocks)
|
||||
|
||||
@property
|
||||
@lazy
|
||||
def follow_num(self):
|
||||
return len(self.followers)
|
|
@ -90,6 +90,7 @@ class User(Base):
|
|||
unmutable = Column(Boolean)
|
||||
eye = Column(Boolean)
|
||||
alt = Column(Boolean)
|
||||
offsitementions = Column(Boolean, default=False, nullable=False)
|
||||
frontsize = Column(Integer, default=25)
|
||||
controversial = Column(Boolean, default=False)
|
||||
bio = deferred(Column(String))
|
||||
|
@ -228,7 +229,11 @@ class User(Base):
|
|||
if self.has_badge(badge): discount -= discounts[badge]
|
||||
|
||||
return discount
|
||||
|
||||
|
||||
@property
|
||||
@lazy
|
||||
def can_view_offsitementions(self):
|
||||
return self.offsitementions or self.admin_level >= REDDIT_NOTIFS_JL_MIN
|
||||
|
||||
@property
|
||||
@lazy
|
||||
|
@ -446,22 +451,44 @@ class User(Base):
|
|||
@property
|
||||
@lazy
|
||||
def post_notifications_count(self):
|
||||
return g.db.query(Notification).join(Comment).filter(Notification.user_id == self.id, Notification.read == False, Comment.author_id == AUTOJANNY_ID).count()
|
||||
return g.db.query(Notification).join(Comment).filter(
|
||||
Notification.user_id == self.id, Notification.read == False,
|
||||
Comment.author_id == AUTOJANNY_ID).count()
|
||||
|
||||
@property
|
||||
@lazy
|
||||
def modaction_notifications_count(self):
|
||||
return g.db.query(Notification).join(Comment).filter(
|
||||
Notification.user_id == self.id, Notification.read == False,
|
||||
Comment.is_banned == False, Comment.deleted_utc == 0,
|
||||
Comment.body_html.like(f'%<p>{NOTIF_MODACTION_PREFIX}%'),
|
||||
Comment.parent_submission == None, Comment.author_id == NOTIFICATIONS_ID).count()
|
||||
|
||||
@property
|
||||
@lazy
|
||||
def reddit_notifications_count(self):
|
||||
return g.db.query(Notification).join(Comment).filter(Notification.user_id == self.id, Notification.read == False, Comment.is_banned == False, Comment.deleted_utc == 0, Comment.body_html.like('%<p>New site mention: <a href="https://old.reddit.com/r/%'), Comment.parent_submission == None, Comment.author_id == NOTIFICATIONS_ID).count()
|
||||
return g.db.query(Notification).join(Comment).filter(
|
||||
Notification.user_id == self.id, Notification.read == False,
|
||||
Comment.is_banned == False, Comment.deleted_utc == 0,
|
||||
Comment.body_html.like('%<p>New site mention: <a href="https://old.reddit.com/r/%'),
|
||||
Comment.parent_submission == None, Comment.author_id == NOTIFICATIONS_ID).count()
|
||||
|
||||
@property
|
||||
@lazy
|
||||
def normal_count(self):
|
||||
return self.notifications_count - self.post_notifications_count - self.reddit_notifications_count
|
||||
return self.notifications_count \
|
||||
- self.post_notifications_count \
|
||||
- self.modaction_notifications_count \
|
||||
- self.reddit_notifications_count
|
||||
|
||||
@property
|
||||
@lazy
|
||||
def do_posts(self):
|
||||
return self.post_notifications_count and self.notifications_count-self.reddit_notifications_count == self.post_notifications_count
|
||||
return self.post_notifications_count and \
|
||||
self.post_notifications_count == (
|
||||
self.notifications_count
|
||||
- self.modaction_notifications_count
|
||||
- self.reddit_notifications_count)
|
||||
|
||||
@property
|
||||
@lazy
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from .__main__ import app, db_session
|
||||
from .__main__ import app, db_session, cache
|
||||
from flask import g
|
||||
import files.helpers.cron
|
||||
|
||||
|
|
|
@ -5,12 +5,12 @@ from files.classes.badges import Badge, BadgeDef
|
|||
# TODO: More sanity checks on passed parameters.
|
||||
# TODO: Add `replace=False` parameter which, when set true, removes any
|
||||
# existing badge with identical id & user and replaces with new one.
|
||||
def badge_grant(user_id, badge_id, desc='', url=''):
|
||||
def badge_grant(user_id, badge_id, desc='', url='', commit=True):
|
||||
user = g.db.query(User).filter(User.id == int(user_id)).one_or_none()
|
||||
if not user:
|
||||
return False
|
||||
return None
|
||||
elif user.has_badge(badge_id):
|
||||
return True
|
||||
return None
|
||||
|
||||
badge = Badge(
|
||||
badge_id=int(badge_id),
|
||||
|
@ -20,5 +20,8 @@ def badge_grant(user_id, badge_id, desc='', url=''):
|
|||
)
|
||||
|
||||
g.db.add(badge)
|
||||
g.db.commit()
|
||||
return True
|
||||
if commit:
|
||||
g.db.commit()
|
||||
else:
|
||||
g.db.flush()
|
||||
return badge
|
||||
|
|
|
@ -114,4 +114,22 @@ def NOTIFY_USERS(text, v):
|
|||
user = get_user(i.group(2), graceful=True)
|
||||
if user and v.id != user.id and not v.any_block_exists(user): notify_users.add(user.id)
|
||||
|
||||
return notify_users - bots
|
||||
return notify_users - bots
|
||||
|
||||
def notify_mod_action(by_id, msg):
|
||||
body_html = sanitize(NOTIF_MODACTION_PREFIX + msg)
|
||||
new_comment = Comment(
|
||||
author_id=NOTIFICATIONS_ID,
|
||||
parent_submission=None,
|
||||
level=1,
|
||||
body_html=body_html,
|
||||
distinguish_level=6)
|
||||
g.db.add(new_comment)
|
||||
g.db.flush()
|
||||
new_comment.top_comment_id = new_comment.id
|
||||
|
||||
send_to = g.db.query(User).filter(
|
||||
User.admin_level >= NOTIF_MODACTION_JL_MIN, User.id != by_id).all()
|
||||
for admin in send_to:
|
||||
notif = Notification(comment_id=new_comment.id, user_id=admin.id)
|
||||
g.db.add(notif)
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
from flask import g
|
||||
import time
|
||||
from files.helpers.alerts import send_repeatable_notification
|
||||
from files.helpers.const import bots
|
||||
from files.helpers.discord import remove_role
|
||||
from files.classes.badges import Badge
|
||||
from files.classes.user import User
|
||||
|
||||
def award_timers(v, bot=False):
|
||||
now = time.time()
|
||||
dirty = False
|
||||
|
||||
def notify_if_not_bot(msg):
|
||||
if not bot:
|
||||
send_repeatable_notification(v.id,msg)
|
||||
|
||||
if v.patron_utc and v.patron_utc < now:
|
||||
v.patron = 0
|
||||
v.patron_utc = 0
|
||||
notify_if_not_bot("Your paypig status has expired!")
|
||||
if not bot and v.discord_id: remove_role(v, "1")
|
||||
dirty = True
|
||||
if v.unban_utc and v.unban_utc < now:
|
||||
v.is_banned = 0
|
||||
v.unban_utc = 0
|
||||
v.ban_evade = 0
|
||||
notify_if_not_bot("You have been unbanned!")
|
||||
dirty = True
|
||||
if v.agendaposter and v.agendaposter < now:
|
||||
v.agendaposter = 0
|
||||
notify_if_not_bot("Your chud theme has expired!")
|
||||
badge = v.has_badge(28)
|
||||
if badge: g.db.delete(badge)
|
||||
dirty = True
|
||||
if v.flairchanged and v.flairchanged < now:
|
||||
v.flairchanged = None
|
||||
notify_if_not_bot("Your flair lock has expired. You can now change your flair!")
|
||||
badge = v.has_badge(96)
|
||||
if badge: g.db.delete(badge)
|
||||
dirty = True
|
||||
if v.marseyawarded and v.marseyawarded < now:
|
||||
v.marseyawarded = None
|
||||
notify_if_not_bot("Your marsey award has expired!")
|
||||
badge = v.has_badge(98)
|
||||
if badge: g.db.delete(badge)
|
||||
dirty = True
|
||||
if v.longpost and v.longpost < now:
|
||||
v.longpost = None
|
||||
notify_if_not_bot("Your pizzashill award has expired!")
|
||||
badge = v.has_badge(97)
|
||||
if badge: g.db.delete(badge)
|
||||
dirty = True
|
||||
if v.bird and v.bird < now:
|
||||
v.bird = None
|
||||
notify_if_not_bot("Your bird site award has expired!")
|
||||
badge = v.has_badge(95)
|
||||
if badge: g.db.delete(badge)
|
||||
dirty = True
|
||||
if v.progressivestack and v.progressivestack < now:
|
||||
v.progressivestack = None
|
||||
notify_if_not_bot("Your progressive stack has expired!")
|
||||
badge = v.has_badge(94)
|
||||
if badge: g.db.delete(badge)
|
||||
dirty = True
|
||||
if v.rehab and v.rehab < now:
|
||||
v.rehab = None
|
||||
notify_if_not_bot("Your rehab has finished!")
|
||||
badge = v.has_badge(109)
|
||||
if badge: g.db.delete(badge)
|
||||
dirty = True
|
||||
if v.deflector and v.deflector < now:
|
||||
v.deflector = None
|
||||
notify_if_not_bot("Your deflector has expired!")
|
||||
dirty = True
|
||||
|
||||
if dirty:
|
||||
g.db.add(v)
|
||||
g.db.commit()
|
||||
|
||||
def award_timers_bots_task():
|
||||
accs = g.db.query(User).filter(User.id.in_(bots))
|
||||
for u in accs:
|
||||
award_timers(u, bot=True)
|
|
@ -132,9 +132,11 @@ PIN_LIMIT = 3
|
|||
POST_RATE_LIMIT = "1/second;2/minute;10/hour;50/day"
|
||||
|
||||
USER_TITLE_COST = 0
|
||||
HOLE_INACTIVITY_DELETION = False
|
||||
|
||||
if SITE in {'rdrama.net','devrama.xyz'}:
|
||||
HOLE_COST = 50000
|
||||
HOLE_INACTIVITY_DELETION = True
|
||||
USER_TITLE_COST = 25
|
||||
NOTIFICATIONS_ID = 1046
|
||||
AUTOJANNY_ID = 2360
|
||||
|
@ -660,6 +662,14 @@ AWARDS = {
|
|||
"color": "text-silver",
|
||||
"price": 10000
|
||||
},
|
||||
"offsitementions": {
|
||||
"kind": "offsitementions",
|
||||
"title": "Y'all Seein' Eye",
|
||||
"description": "Gives the recipient access to notifications when people off-site talk about us.",
|
||||
"icon": "fas fa-eyes",
|
||||
"color": "text-orange",
|
||||
"price": 10000,
|
||||
},
|
||||
"unblockable": {
|
||||
"kind": "unblockable",
|
||||
"title": "Unblockable",
|
||||
|
@ -799,8 +809,12 @@ FACTCHECK_REPLIES = ('<b style="color:#6023f8">Factcheck: This claim has been co
|
|||
if SITE_NAME == 'rDrama': patron = 'Paypig'
|
||||
else: patron = 'Patron'
|
||||
|
||||
NOTIF_MODACTION_PREFIX = '[Modaction] '
|
||||
NOTIF_MODACTION_JL_MIN = 2
|
||||
|
||||
REDDIT_NOTIFS_SITE = []
|
||||
REDDIT_NOTIFS_USERS = {}
|
||||
REDDIT_NOTIFS_JL_MIN = 1
|
||||
|
||||
if SITE_NAME == 'rDrama':
|
||||
REDDIT_NOTIFS_SITE = ['rdrama', 'marsey',]
|
||||
|
@ -814,6 +828,7 @@ if SITE_NAME == 'rDrama':
|
|||
}
|
||||
elif SITE_NAME == 'PCM':
|
||||
REDDIT_NOTIFS_SITE = ['pcmemes.net',]
|
||||
REDDIT_NOTIFS_JL_MIN = 3
|
||||
|
||||
discounts = {
|
||||
# Big Spender badges, 2pp additive discount each
|
||||
|
@ -1035,17 +1050,16 @@ linefeeds_regex = re.compile("([^\n])\n([^\n])", flags=re.A)
|
|||
def make_name(*args, **kwargs): return request.base_url
|
||||
|
||||
# Lottery
|
||||
LOTTERY_ENABLED = False
|
||||
LOTTERY_TICKET_COST = 0
|
||||
LOTTERY_SINK_RATE = 0
|
||||
LOTTERY_ROYALTY_RATE = 0
|
||||
LOTTERY_ROYALTY_ACCOUNT_ID = 0
|
||||
LOTTERY_MANAGER_ACCOUNT_ID = 0
|
||||
if SITE_NAME == 'rDrama':
|
||||
LOTTERY_ENABLED = True
|
||||
LOTTERY_TICKET_COST = 12
|
||||
LOTTERY_SINK_RATE = 3
|
||||
LOTTERY_ROYALTY_RATE = 1
|
||||
LOTTERY_ROYALTY_RATE = 0
|
||||
LOTTERY_ROYALTY_ACCOUNT_ID = 1387 # (Chapose)
|
||||
LOTTERY_MANAGER_ACCOUNT_ID = 11651 # (Lottershe)
|
||||
else:
|
||||
LOTTERY_ENABLED = False
|
||||
LOTTERY_TICKET_COST = 0
|
||||
LOTTERY_SINK_RATE = 0
|
||||
LOTTERY_ROYALTY_RATE = 0
|
||||
LOTTERY_ROYALTY_ACCOUNT_ID = 0
|
||||
LOTTERY_MANAGER_ACCOUNT_ID = 0
|
|
@ -5,6 +5,9 @@ import files.helpers.const as const
|
|||
import files.helpers.lottery as lottery
|
||||
import files.helpers.offsitementions as offsitementions
|
||||
import files.helpers.stats as stats
|
||||
import files.helpers.awards as awards
|
||||
import files.routes.static as route_static
|
||||
from files.routes.subs import sub_inactive_purge_task
|
||||
|
||||
@app.cli.command('cron', help='Run scheduled tasks.')
|
||||
@click.option('--every-5m', is_flag=True, help='Call every 5 minutes.')
|
||||
|
@ -22,4 +25,8 @@ def cron(every_5m, every_1h, every_1d):
|
|||
|
||||
if every_1d:
|
||||
stats.generate_charts_task(const.SITE)
|
||||
route_static.stats_cached()
|
||||
awards.award_timers_bots_task()
|
||||
sub_inactive_purge_task()
|
||||
|
||||
|
||||
|
|
|
@ -92,6 +92,8 @@ def check_if_end_lottery_task():
|
|||
start_new_lottery_session()
|
||||
return True
|
||||
|
||||
def lottery_ticket_net_value():
|
||||
return LOTTERY_TICKET_COST - LOTTERY_SINK_RATE - LOTTERY_ROYALTY_RATE
|
||||
|
||||
def purchase_lottery_tickets(v, quantity=1):
|
||||
if quantity < 1:
|
||||
|
@ -107,7 +109,7 @@ def purchase_lottery_tickets(v, quantity=1):
|
|||
v.currently_held_lottery_tickets += quantity
|
||||
v.total_held_lottery_tickets += quantity
|
||||
|
||||
net_ticket_value = (LOTTERY_TICKET_COST - LOTTERY_SINK_RATE - LOTTERY_ROYALTY_RATE) * quantity
|
||||
net_ticket_value = lottery_ticket_net_value() * quantity
|
||||
most_recent_lottery.prize += net_ticket_value
|
||||
most_recent_lottery.tickets_sold += quantity
|
||||
|
||||
|
@ -115,7 +117,7 @@ def purchase_lottery_tickets(v, quantity=1):
|
|||
|
||||
beneficiary = g.db.query(User).get(LOTTERY_ROYALTY_ACCOUNT_ID)
|
||||
|
||||
if beneficiary:
|
||||
if beneficiary and LOTTERY_ROYALTY_RATE:
|
||||
beneficiary.coins += LOTTERY_ROYALTY_RATE * quantity
|
||||
|
||||
g.db.commit()
|
||||
|
@ -128,16 +130,16 @@ def grant_lottery_proceeds_to_manager(prize_value):
|
|||
if manager:
|
||||
manager.coins += prize_value
|
||||
|
||||
def grant_lottery_tickets_to_user(v, amount):
|
||||
def grant_lottery_tickets_to_user(v, quantity):
|
||||
active_lottery = get_active_lottery()
|
||||
prize_value = amount * LOTTERY_TICKET_COST
|
||||
prize_value = lottery_ticket_net_value() * quantity
|
||||
|
||||
if active_lottery:
|
||||
v.currently_held_lottery_tickets += amount
|
||||
v.total_held_lottery_tickets += amount
|
||||
v.currently_held_lottery_tickets += quantity
|
||||
v.total_held_lottery_tickets += quantity
|
||||
|
||||
active_lottery.prize += prize_value
|
||||
active_lottery.tickets_sold += amount
|
||||
active_lottery.tickets_sold += quantity
|
||||
|
||||
grant_lottery_proceeds_to_manager(prize_value)
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from flask import g
|
||||
import itertools
|
||||
import requests
|
||||
from sqlalchemy import _or
|
||||
import files.helpers.const as const
|
||||
from files.classes.user import User
|
||||
from files.classes.comment import Comment
|
||||
|
@ -13,9 +14,9 @@ from files.classes.notifications import Notification
|
|||
|
||||
def offsite_mentions_task():
|
||||
if const.REDDIT_NOTIFS_SITE:
|
||||
# Site-specific logic: send to JL1+, except on PCM JL3+
|
||||
jl_min = 3 if const.SITE_NAME == 'PCM' else 1
|
||||
row_send_to = g.db.query(User.id).filter(User.admin_level >= jl_min).all()
|
||||
row_send_to = g.db.query(User.id)
|
||||
.filter(_or(User.admin_level >= const.REDDIT_NOTIFS_JL_MIN,
|
||||
User.offsitementions == True)).all()
|
||||
send_to = [x[0] for x in row_send_to]
|
||||
|
||||
site_mentions = get_mentions(const.REDDIT_NOTIFS_SITE)
|
||||
|
|
|
@ -2,10 +2,14 @@ from flask import g
|
|||
import time
|
||||
import calendar
|
||||
import matplotlib.pyplot as plt
|
||||
from sqlalchemy import *
|
||||
|
||||
from files.classes.user import User
|
||||
from files.classes.submission import Submission
|
||||
from files.classes.comment import Comment
|
||||
from files.classes.votes import Vote, CommentVote
|
||||
from files.classes.marsey import Marsey
|
||||
from files.classes.award import AwardRelationship
|
||||
from files.helpers.const import *
|
||||
|
||||
def generate_charts_task(site):
|
||||
|
@ -85,3 +89,58 @@ def chart(kind, site):
|
|||
|
||||
def chart_path(kind, site):
|
||||
return f'/{site}_{kind}.png'
|
||||
|
||||
def stats(site=None):
|
||||
day = int(time.time()) - 86400
|
||||
week = int(time.time()) - 604800
|
||||
posters = g.db.query(Submission.author_id).distinct(Submission.author_id).filter(Submission.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 = {
|
||||
"marseys": g.db.query(Marsey).count(),
|
||||
"users": g.db.query(User).count(),
|
||||
"private users": g.db.query(User).filter_by(is_private=True).count(),
|
||||
"banned users": g.db.query(User).filter(User.is_banned > 0).count(),
|
||||
"verified email users": g.db.query(User).filter_by(is_activated=True).count(),
|
||||
"coins in circulation": g.db.query(func.sum(User.coins)).scalar(),
|
||||
"total shop sales": g.db.query(func.sum(User.coins_spent)).scalar(),
|
||||
"signups last 24h": g.db.query(User).filter(User.created_utc > day).count(),
|
||||
"total posts": g.db.query(Submission).count(),
|
||||
"posting users": g.db.query(Submission.author_id).distinct().count(),
|
||||
"listed posts": g.db.query(Submission).filter_by(is_banned=False).filter(Submission.deleted_utc == 0).count(),
|
||||
"removed posts (by admins)": g.db.query(Submission).filter_by(is_banned=True).count(),
|
||||
"deleted posts (by author)": g.db.query(Submission).filter(Submission.deleted_utc > 0).count(),
|
||||
"posts last 24h": g.db.query(Submission).filter(Submission.created_utc > day).count(),
|
||||
"total comments": g.db.query(Comment).filter(Comment.author_id.notin_((AUTOJANNY_ID,NOTIFICATIONS_ID))).count(),
|
||||
"commenting users": g.db.query(Comment.author_id).distinct().count(),
|
||||
"removed comments (by admins)": g.db.query(Comment).filter_by(is_banned=True).count(),
|
||||
"deleted comments (by author)": g.db.query(Comment).filter(Comment.deleted_utc > 0).count(),
|
||||
"comments last_24h": g.db.query(Comment).filter(Comment.created_utc > day, Comment.author_id.notin_((AUTOJANNY_ID,NOTIFICATIONS_ID))).count(),
|
||||
"post votes": g.db.query(Vote).count(),
|
||||
"post voting users": g.db.query(Vote.user_id).distinct().count(),
|
||||
"comment votes": g.db.query(CommentVote).count(),
|
||||
"comment voting users": g.db.query(CommentVote.user_id).distinct().count(),
|
||||
"total upvotes": g.db.query(Vote).filter_by(vote_type=1).count() + g.db.query(CommentVote.comment_id).filter_by(vote_type=1).count(),
|
||||
"total downvotes": g.db.query(Vote).filter_by(vote_type=-1).count() + g.db.query(CommentVote.comment_id).filter_by(vote_type=-1).count(),
|
||||
"total awards": g.db.query(AwardRelationship).count(),
|
||||
"awards given": g.db.query(AwardRelationship).filter(or_(AwardRelationship.submission_id != None, AwardRelationship.comment_id != None)).count(),
|
||||
"users who posted, commented, or voted in the past 7 days": len(active_users),
|
||||
}
|
||||
|
||||
if site == 'rDrama':
|
||||
stats2 = {
|
||||
"House furry members": g.db.query(User).filter(User.house.like('Furry%')).count(),
|
||||
"House femboy members": g.db.query(User).filter(User.house.like('Femboy%')).count(),
|
||||
"House vampire members": g.db.query(User).filter(User.house.like('Vampire%')).count(),
|
||||
"House racist members": g.db.query(User).filter(User.house.like('Racist%')).count(),
|
||||
"House furry total truescore": g.db.query(func.sum(User.truecoins)).filter(User.house.like('Furry%')).scalar(),
|
||||
"House femboy total truescore": g.db.query(func.sum(User.truecoins)).filter(User.house.like('Femboy%')).scalar(),
|
||||
"House vampire total truescore": g.db.query(func.sum(User.truecoins)).filter(User.house.like('Vampire%')).scalar(),
|
||||
"House racist total truescore": g.db.query(func.sum(User.truecoins)).filter(User.house.like('Racist%')).scalar(),
|
||||
}
|
||||
stats.update(stats2)
|
||||
|
||||
return stats
|
||||
|
|
|
@ -527,25 +527,7 @@ def change_settings(v, setting):
|
|||
if site_settings[setting]: word = 'enable'
|
||||
else: word = 'disable'
|
||||
|
||||
body = f"@{v.username} has {word}d `{setting}` in the [admin dashboard](/admin)!"
|
||||
|
||||
body_html = sanitize(body)
|
||||
|
||||
new_comment = Comment(author_id=NOTIFICATIONS_ID,
|
||||
parent_submission=None,
|
||||
level=1,
|
||||
body_html=body_html,
|
||||
sentto=2,
|
||||
distinguish_level=6
|
||||
)
|
||||
g.db.add(new_comment)
|
||||
g.db.flush()
|
||||
|
||||
new_comment.top_comment_id = new_comment.id
|
||||
|
||||
for admin in g.db.query(User).filter(User.admin_level > 2, User.id != v.id).all():
|
||||
notif = Notification(comment_id=new_comment.id, user_id=admin.id)
|
||||
g.db.add(notif)
|
||||
notify_mod_action(v.id, f"@{v.username} has {word}d `{setting}` in the [admin dashboard](/admin)!")
|
||||
|
||||
ma = ModAction(
|
||||
kind=f"{word}_{setting}",
|
||||
|
@ -1018,29 +1000,7 @@ def shadowban(user_id, v):
|
|||
g.db.add(ma)
|
||||
|
||||
cache.delete_memoized(frontlist)
|
||||
|
||||
body = f"@{v.username} has shadowbanned @{user.username}"
|
||||
|
||||
body_html = sanitize(body)
|
||||
|
||||
|
||||
new_comment = Comment(author_id=NOTIFICATIONS_ID,
|
||||
parent_submission=None,
|
||||
level=1,
|
||||
body_html=body_html,
|
||||
distinguish_level=6
|
||||
)
|
||||
g.db.add(new_comment)
|
||||
g.db.flush()
|
||||
|
||||
new_comment.top_comment_id = new_comment.id
|
||||
|
||||
for admin in g.db.query(User).filter(User.admin_level > 2, User.id != v.id).all():
|
||||
notif = Notification(comment_id=new_comment.id, user_id=admin.id)
|
||||
g.db.add(notif)
|
||||
|
||||
|
||||
|
||||
notify_mod_action(v.id, f"@{v.username} has shadowbanned @{user.username}")
|
||||
g.db.commit()
|
||||
return {"message": "User shadowbanned!"}
|
||||
|
||||
|
@ -1176,28 +1136,7 @@ def ban_user(user_id, v):
|
|||
g.db.add(comment)
|
||||
except: pass
|
||||
|
||||
|
||||
body = f"@{v.username} has banned @{user.username} ({note})"
|
||||
|
||||
body_html = sanitize(body)
|
||||
|
||||
|
||||
new_comment = Comment(author_id=NOTIFICATIONS_ID,
|
||||
parent_submission=None,
|
||||
level=1,
|
||||
body_html=body_html,
|
||||
distinguish_level=6
|
||||
)
|
||||
g.db.add(new_comment)
|
||||
g.db.flush()
|
||||
|
||||
new_comment.top_comment_id = new_comment.id
|
||||
|
||||
for admin in g.db.query(User).filter(User.admin_level > 2, User.id != v.id).all():
|
||||
notif = Notification(comment_id=new_comment.id, user_id=admin.id)
|
||||
g.db.add(notif)
|
||||
|
||||
|
||||
notify_mod_action(v.id, f"@{v.username} has banned @{user.username} ({note})")
|
||||
g.db.commit()
|
||||
|
||||
if 'redir' in request.values: return redirect(user.url)
|
||||
|
@ -1273,23 +1212,10 @@ def ban_post(post_id, v):
|
|||
g.db.add(v)
|
||||
|
||||
if v.id != post.author_id:
|
||||
body = f"@{v.username} has removed [{post.title}]({post.shortlink})"
|
||||
body_html = sanitize(body)
|
||||
new_comment = Comment(author_id=NOTIFICATIONS_ID,
|
||||
parent_submission=None,
|
||||
level=1,
|
||||
body_html=body_html,
|
||||
distinguish_level=6
|
||||
)
|
||||
g.db.add(new_comment)
|
||||
g.db.flush()
|
||||
new_comment.top_comment_id = new_comment.id
|
||||
for admin in g.db.query(User).filter(User.admin_level > 2, User.id != v.id).all():
|
||||
notif = Notification(comment_id=new_comment.id, user_id=admin.id)
|
||||
g.db.add(notif)
|
||||
|
||||
requests.post(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/purge_cache', headers=CF_HEADERS, json={'files': [f"{SITE_FULL}/logged_out/"]}, timeout=5)
|
||||
notify_mod_action(v.id, f"@{v.username} has removed [{post.title}]({post.shortlink})")
|
||||
|
||||
requests.post(f'https://api.cloudflare.com/client/v4/zones/{CF_ZONE}/purge_cache',
|
||||
headers=CF_HEADERS, json={'files': [f"{SITE_FULL}/logged_out/"]}, timeout=5)
|
||||
g.db.commit()
|
||||
|
||||
return {"message": "Post removed!"}
|
||||
|
@ -1492,20 +1418,7 @@ def api_ban_comment(c_id, v):
|
|||
g.db.add(ma)
|
||||
|
||||
if v.id != comment.author_id:
|
||||
body = f"@{v.username} has removed [comment]({comment.shortlink})"
|
||||
body_html = sanitize(body)
|
||||
new_comment = Comment(author_id=NOTIFICATIONS_ID,
|
||||
parent_submission=None,
|
||||
level=1,
|
||||
body_html=body_html,
|
||||
distinguish_level=6
|
||||
)
|
||||
g.db.add(new_comment)
|
||||
g.db.flush()
|
||||
new_comment.top_comment_id = new_comment.id
|
||||
for admin in g.db.query(User).filter(User.admin_level > 2, User.id != v.id).all():
|
||||
notif = Notification(comment_id=new_comment.id, user_id=admin.id)
|
||||
g.db.add(notif)
|
||||
notify_mod_action(v.id, f"@{v.username} has removed [comment]({comment.shortlink})")
|
||||
|
||||
g.db.commit()
|
||||
return {"message": "Comment removed!"}
|
||||
|
|
|
@ -4,6 +4,7 @@ from files.helpers.alerts import *
|
|||
from files.helpers.get import *
|
||||
from files.helpers.const import *
|
||||
from files.helpers.discord import *
|
||||
from files.helpers.actions import badge_grant
|
||||
from files.classes.award import *
|
||||
from .front import frontlist
|
||||
from flask import g, request
|
||||
|
@ -301,6 +302,10 @@ def award_thing(v, thing_type, id):
|
|||
g.db.add(new_badge)
|
||||
g.db.flush()
|
||||
send_notification(author.id, f"@AutoJanny has given you the following profile badge:\n\n![]({new_badge.path})\n\n{new_badge.name}")
|
||||
elif kind == "offsitementions":
|
||||
author.offsitementions = True
|
||||
new_badge = badge_grant(user_id=author.id, badge_id=140, commit=False)
|
||||
send_notification(author.id, f"@AutoJanny has given you the following profile badge:\n\n![]({new_badge.path})\n\n{new_badge.name}")
|
||||
elif kind == "alt":
|
||||
author.alt = True
|
||||
if not author.has_badge(84):
|
||||
|
@ -443,3 +448,4 @@ def admin_userawards_post(v):
|
|||
|
||||
if v.admin_level != 3: return render_template("admin/awards.html", awards=list(AWARDS3.values()), v=v)
|
||||
return render_template("admin/awards.html", awards=list(AWARDS.values()), v=v)
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ from files.helpers.get import *
|
|||
from files.helpers.discord import *
|
||||
from files.__main__ import app, cache, limiter
|
||||
from files.classes.submission import Submission
|
||||
from files.helpers.awards import award_timers
|
||||
|
||||
defaulttimefilter = environ.get("DEFAULT_TIME_FILTER", "all").strip()
|
||||
|
||||
|
@ -43,9 +44,10 @@ def notifications(v):
|
|||
|
||||
messages = request.values.get('messages')
|
||||
modmail = request.values.get('modmail')
|
||||
modactions = request.values.get('modactions')
|
||||
posts = request.values.get('posts')
|
||||
reddit = request.values.get('reddit')
|
||||
if modmail and v.admin_level > 1:
|
||||
if modmail and v.admin_level >= 2:
|
||||
comments = g.db.query(Comment).filter(Comment.sentto==2).order_by(Comment.id.desc()).offset(25*(page-1)).limit(26).all()
|
||||
next_exists = (len(comments) > 25)
|
||||
listing = comments[:25]
|
||||
|
@ -72,7 +74,25 @@ def notifications(v):
|
|||
if n.created_utc > 1620391248: c.notif_utc = n.created_utc
|
||||
listing.append(c)
|
||||
|
||||
g.db.commit()
|
||||
next_exists = (len(notifications) > len(listing))
|
||||
elif modactions:
|
||||
notifications = g.db.query(Notification, Comment) \
|
||||
.join(Comment, Notification.comment_id == Comment.id) \
|
||||
.filter(Notification.user_id == v.id,
|
||||
Comment.body_html.like(f'%<p>{NOTIF_MODACTION_PREFIX}%'),
|
||||
Comment.parent_submission == None, Comment.author_id == NOTIFICATIONS_ID) \
|
||||
.order_by(Notification.created_utc.desc()).offset(25 * (page - 1)).limit(101).all()
|
||||
listing = []
|
||||
|
||||
for index, x in enumerate(notifications[:100]):
|
||||
n, c = x
|
||||
if n.read and index > 24: break
|
||||
elif not n.read:
|
||||
n.read = True
|
||||
c.unread = True
|
||||
g.db.add(n)
|
||||
if n.created_utc > 1620391248: c.notif_utc = n.created_utc
|
||||
listing.append(c)
|
||||
|
||||
next_exists = (len(notifications) > len(listing))
|
||||
elif reddit:
|
||||
|
@ -90,8 +110,6 @@ def notifications(v):
|
|||
if n.created_utc > 1620391248: c.notif_utc = n.created_utc
|
||||
listing.append(c)
|
||||
|
||||
g.db.commit()
|
||||
|
||||
next_exists = (len(notifications) > len(listing))
|
||||
else:
|
||||
comments = g.db.query(Comment, Notification).join(Notification, Notification.comment_id == Comment.id).filter(
|
||||
|
@ -99,7 +117,8 @@ def notifications(v):
|
|||
Comment.is_banned == False,
|
||||
Comment.deleted_utc == 0,
|
||||
Comment.author_id != AUTOJANNY_ID,
|
||||
Comment.body_html.notlike('%<p>New site mention: <a href="https://old.reddit.com/r/%')
|
||||
Comment.body_html.notlike('%<p>New site mention: <a href="https://old.reddit.com/r/%'),
|
||||
Comment.body_html.notlike(f'%<p>{NOTIF_MODACTION_PREFIX}%')
|
||||
).order_by(Notification.created_utc.desc())
|
||||
|
||||
if not (v and (v.shadowbanned or v.admin_level > 2)):
|
||||
|
@ -153,7 +172,8 @@ def notifications(v):
|
|||
next_exists=next_exists,
|
||||
page=page,
|
||||
standalone=True,
|
||||
render_replies=True
|
||||
render_replies=True,
|
||||
NOTIF_MODACTION_JL_MIN=NOTIF_MODACTION_JL_MIN,
|
||||
)
|
||||
|
||||
|
||||
|
@ -219,85 +239,7 @@ def front_all(v, sub=None, subdomain=None):
|
|||
|
||||
if v:
|
||||
if v.hidevotedon: posts = [x for x in posts if not hasattr(x, 'voted') or not x.voted]
|
||||
|
||||
|
||||
if v.patron_utc and v.patron_utc < time.time():
|
||||
v.patron = 0
|
||||
v.patron_utc = 0
|
||||
send_repeatable_notification(v.id, "Your paypig status has expired!")
|
||||
if v.discord_id: remove_role(v, "1")
|
||||
g.db.add(v)
|
||||
g.db.commit()
|
||||
|
||||
if v.unban_utc and v.unban_utc < time.time():
|
||||
v.is_banned = 0
|
||||
v.unban_utc = 0
|
||||
v.ban_evade = 0
|
||||
send_repeatable_notification(v.id, "You have been unbanned!")
|
||||
g.db.add(v)
|
||||
g.db.commit()
|
||||
|
||||
if v.agendaposter and v.agendaposter < time.time():
|
||||
v.agendaposter = 0
|
||||
send_repeatable_notification(v.id, "Your chud theme has expired!")
|
||||
g.db.add(v)
|
||||
badge = v.has_badge(28)
|
||||
if badge: g.db.delete(badge)
|
||||
g.db.commit()
|
||||
|
||||
if v.flairchanged and v.flairchanged < time.time():
|
||||
v.flairchanged = None
|
||||
send_repeatable_notification(v.id, "Your flair lock has expired. You can now change your flair!")
|
||||
g.db.add(v)
|
||||
badge = v.has_badge(96)
|
||||
if badge: g.db.delete(badge)
|
||||
g.db.commit()
|
||||
|
||||
if v.marseyawarded and v.marseyawarded < time.time():
|
||||
v.marseyawarded = None
|
||||
send_repeatable_notification(v.id, "Your marsey award has expired!")
|
||||
g.db.add(v)
|
||||
badge = v.has_badge(98)
|
||||
if badge: g.db.delete(badge)
|
||||
g.db.commit()
|
||||
|
||||
if v.longpost and v.longpost < time.time():
|
||||
v.longpost = None
|
||||
send_repeatable_notification(v.id, "Your pizzashill award has expired!")
|
||||
g.db.add(v)
|
||||
badge = v.has_badge(97)
|
||||
if badge: g.db.delete(badge)
|
||||
g.db.commit()
|
||||
|
||||
if v.bird and v.bird < time.time():
|
||||
v.bird = None
|
||||
send_repeatable_notification(v.id, "Your bird site award has expired!")
|
||||
g.db.add(v)
|
||||
badge = v.has_badge(95)
|
||||
if badge: g.db.delete(badge)
|
||||
g.db.commit()
|
||||
|
||||
if v.progressivestack and v.progressivestack < time.time():
|
||||
v.progressivestack = None
|
||||
send_repeatable_notification(v.id, "Your progressive stack has expired!")
|
||||
g.db.add(v)
|
||||
badge = v.has_badge(94)
|
||||
if badge: g.db.delete(badge)
|
||||
g.db.commit()
|
||||
|
||||
if v.rehab and v.rehab < time.time():
|
||||
v.rehab = None
|
||||
send_repeatable_notification(v.id, "Your rehab has finished!")
|
||||
g.db.add(v)
|
||||
badge = v.has_badge(109)
|
||||
if badge: g.db.delete(badge)
|
||||
g.db.commit()
|
||||
|
||||
if v.deflector and v.deflector < time.time():
|
||||
v.deflector = None
|
||||
send_repeatable_notification(v.id, "Your deflector has expired!")
|
||||
g.db.add(v)
|
||||
g.db.commit()
|
||||
award_timers(v)
|
||||
|
||||
if request.headers.get("Authorization"): return {"data": [x.json for x in posts], "next_exists": next_exists}
|
||||
return render_template("home.html", v=v, listing=posts, next_exists=next_exists, sort=sort, t=t, page=page, ccmode=ccmode, sub=sub, home=True)
|
||||
|
|
|
@ -69,151 +69,12 @@ def sidebar(v):
|
|||
@app.get("/stats")
|
||||
@auth_required
|
||||
def participation_stats(v):
|
||||
|
||||
return render_template("admin/content_stats.html", v=v, title="Content Statistics", data=stats(site=SITE))
|
||||
|
||||
return render_template("admin/content_stats.html",
|
||||
v=v, title="Content Statistics", data=stats_cached())
|
||||
|
||||
@cache.memoize(timeout=86400)
|
||||
def stats(site=None):
|
||||
day = int(time.time()) - 86400
|
||||
|
||||
week = int(time.time()) - 604800
|
||||
posters = g.db.query(Submission.author_id).distinct(Submission.author_id).filter(Submission.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 = {"marseys": g.db.query(Marsey).count(),
|
||||
"users": g.db.query(User).count(),
|
||||
"private users": g.db.query(User).filter_by(is_private=True).count(),
|
||||
"banned users": g.db.query(User).filter(User.is_banned > 0).count(),
|
||||
"verified email users": g.db.query(User).filter_by(is_activated=True).count(),
|
||||
"coins in circulation": g.db.query(func.sum(User.coins)).scalar(),
|
||||
"total shop sales": g.db.query(func.sum(User.coins_spent)).scalar(),
|
||||
"signups last 24h": g.db.query(User).filter(User.created_utc > day).count(),
|
||||
"total posts": g.db.query(Submission).count(),
|
||||
"posting users": g.db.query(Submission.author_id).distinct().count(),
|
||||
"listed posts": g.db.query(Submission).filter_by(is_banned=False).filter(Submission.deleted_utc == 0).count(),
|
||||
"removed posts (by admins)": g.db.query(Submission).filter_by(is_banned=True).count(),
|
||||
"deleted posts (by author)": g.db.query(Submission).filter(Submission.deleted_utc > 0).count(),
|
||||
"posts last 24h": g.db.query(Submission).filter(Submission.created_utc > day).count(),
|
||||
"total comments": g.db.query(Comment).filter(Comment.author_id.notin_((AUTOJANNY_ID,NOTIFICATIONS_ID))).count(),
|
||||
"commenting users": g.db.query(Comment.author_id).distinct().count(),
|
||||
"removed comments (by admins)": g.db.query(Comment).filter_by(is_banned=True).count(),
|
||||
"deleted comments (by author)": g.db.query(Comment).filter(Comment.deleted_utc > 0).count(),
|
||||
"comments last_24h": g.db.query(Comment).filter(Comment.created_utc > day, Comment.author_id.notin_((AUTOJANNY_ID,NOTIFICATIONS_ID))).count(),
|
||||
"post votes": g.db.query(Vote).count(),
|
||||
"post voting users": g.db.query(Vote.user_id).distinct().count(),
|
||||
"comment votes": g.db.query(CommentVote).count(),
|
||||
"comment voting users": g.db.query(CommentVote.user_id).distinct().count(),
|
||||
"total upvotes": g.db.query(Vote).filter_by(vote_type=1).count() + g.db.query(CommentVote.comment_id).filter_by(vote_type=1).count(),
|
||||
"total downvotes": g.db.query(Vote).filter_by(vote_type=-1).count() + g.db.query(CommentVote.comment_id).filter_by(vote_type=-1).count(),
|
||||
"total awards": g.db.query(AwardRelationship).count(),
|
||||
"awards given": g.db.query(AwardRelationship).filter(or_(AwardRelationship.submission_id != None, AwardRelationship.comment_id != None)).count(),
|
||||
"users who posted, commented, or voted in the past 7 days": len(active_users),
|
||||
}
|
||||
|
||||
|
||||
if SITE_NAME == 'rDrama':
|
||||
furries1 = g.db.query(User).filter(User.house.like('Furry%')).count()
|
||||
femboys1 = g.db.query(User).filter(User.house.like('Femboy%')).count()
|
||||
vampires1 = g.db.query(User).filter(User.house.like('Vampire%')).count()
|
||||
racists1 = g.db.query(User).filter(User.house.like('Racist%')).count()
|
||||
|
||||
furries2 = g.db.query(func.sum(User.truecoins)).filter(User.house.like('Furry%')).scalar()
|
||||
femboys2 = g.db.query(func.sum(User.truecoins)).filter(User.house.like('Femboy%')).scalar()
|
||||
vampires2 = g.db.query(func.sum(User.truecoins)).filter(User.house.like('Vampire%')).scalar()
|
||||
racists2 = g.db.query(func.sum(User.truecoins)).filter(User.house.like('Racist%')).scalar()
|
||||
|
||||
stats2 = {"House furry members": furries1,
|
||||
"House femboy members": femboys1,
|
||||
"House vampire members": vampires1,
|
||||
"House racist members": racists1,
|
||||
"House furry total truescore": furries2,
|
||||
"House femboy total truescore": femboys2,
|
||||
"House vampire total truescore": vampires2,
|
||||
"House racist total truescore": racists2,
|
||||
}
|
||||
|
||||
stats.update(stats2)
|
||||
|
||||
accs = g.db.query(User).filter(User.id.in_(bots))
|
||||
|
||||
for u in accs:
|
||||
g.db.add(u)
|
||||
|
||||
if u.patron_utc and u.patron_utc < time.time():
|
||||
u.patron = 0
|
||||
u.patron_utc = 0
|
||||
|
||||
if u.unban_utc and u.unban_utc < time.time():
|
||||
u.is_banned = 0
|
||||
u.unban_utc = 0
|
||||
u.ban_evade = 0
|
||||
|
||||
if u.agendaposter and u.agendaposter < time.time():
|
||||
u.agendaposter = 0
|
||||
badge = u.has_badge(28)
|
||||
if badge: g.db.delete(badge)
|
||||
|
||||
if u.flairchanged and u.flairchanged < time.time():
|
||||
u.flairchanged = None
|
||||
badge = u.has_badge(96)
|
||||
if badge: g.db.delete(badge)
|
||||
|
||||
if u.marseyawarded and u.marseyawarded < time.time():
|
||||
u.marseyawarded = None
|
||||
badge = u.has_badge(98)
|
||||
if badge: g.db.delete(badge)
|
||||
|
||||
if u.longpost and u.longpost < time.time():
|
||||
u.longpost = None
|
||||
badge = u.has_badge(97)
|
||||
if badge: g.db.delete(badge)
|
||||
|
||||
if u.bird and u.bird < time.time():
|
||||
u.bird = None
|
||||
badge = u.has_badge(95)
|
||||
if badge: g.db.delete(badge)
|
||||
|
||||
if u.progressivestack and u.progressivestack < time.time():
|
||||
u.progressivestack = None
|
||||
badge = u.has_badge(94)
|
||||
if badge: g.db.delete(badge)
|
||||
|
||||
if u.rehab and u.rehab < time.time():
|
||||
u.rehab = None
|
||||
badge = u.has_badge(109)
|
||||
if badge: g.db.delete(badge)
|
||||
|
||||
if u.deflector and u.deflector < time.time():
|
||||
u.deflector = None
|
||||
|
||||
one_week_ago = time.time() - 604800
|
||||
active_holes = [x[0] for x in g.db.query(Submission.sub).distinct().filter(Submission.sub != None, Submission.created_utc > one_week_ago).all()]
|
||||
|
||||
dead_holes = g.db.query(Sub).filter(Sub.name.notin_(active_holes)).all()
|
||||
names = [x.name for x in dead_holes]
|
||||
|
||||
posts = g.db.query(Submission).filter(Submission.sub.in_(names)).all()
|
||||
for post in posts:
|
||||
post.sub = None
|
||||
g.db.add(post)
|
||||
|
||||
to_delete = g.db.query(Mod).filter(Mod.sub.in_(names)).all() + g.db.query(Exile).filter(Exile.sub.in_(names)).all() + g.db.query(SubBlock).filter(SubBlock.sub.in_(names)).all() + g.db.query(SubSubscription).filter(SubSubscription.sub.in_(names)).all()
|
||||
for x in to_delete:
|
||||
g.db.delete(x)
|
||||
g.db.flush()
|
||||
|
||||
for x in dead_holes:
|
||||
g.db.delete(x)
|
||||
|
||||
g.db.commit()
|
||||
|
||||
return stats
|
||||
|
||||
def stats_cached():
|
||||
return statshelper.stats(SITE_NAME)
|
||||
|
||||
@app.get("/chart")
|
||||
def chart():
|
||||
|
|
|
@ -448,4 +448,35 @@ def sub_sidebar(v, sub):
|
|||
@auth_desired
|
||||
def subs(v):
|
||||
subs = g.db.query(Sub, func.count(Submission.sub)).outerjoin(Submission, Sub.name == Submission.sub).group_by(Sub.name).order_by(func.count(Submission.sub).desc()).all()
|
||||
return render_template('sub/subs.html', v=v, subs=subs)
|
||||
return render_template('sub/subs.html', v=v, subs=subs)
|
||||
|
||||
def sub_inactive_purge_task():
|
||||
if not HOLE_INACTIVITY_DELETION:
|
||||
return False
|
||||
|
||||
one_week_ago = time.time() - 604800
|
||||
active_holes = [x[0] for x in g.db.query(Submission.sub).distinct() \
|
||||
.filter(Submission.sub != None, Submission.created_utc > one_week_ago).all()]
|
||||
|
||||
dead_holes = g.db.query(Sub).filter(Sub.name.notin_(active_holes)).all()
|
||||
names = [x.name for x in dead_holes]
|
||||
|
||||
posts = g.db.query(Submission).filter(Submission.sub.in_(names)).all()
|
||||
for post in posts:
|
||||
post.sub = None
|
||||
g.db.add(post)
|
||||
|
||||
to_delete = g.db.query(Mod).filter(Mod.sub.in_(names)).all() \
|
||||
+ g.db.query(Exile).filter(Exile.sub.in_(names)).all() \
|
||||
+ g.db.query(SubBlock).filter(SubBlock.sub.in_(names)).all() \
|
||||
+ g.db.query(SubSubscription).filter(SubSubscription.sub.in_(names)).all()
|
||||
|
||||
for x in to_delete:
|
||||
g.db.delete(x)
|
||||
g.db.flush()
|
||||
|
||||
for x in dead_holes:
|
||||
g.db.delete(x)
|
||||
|
||||
g.db.commit()
|
||||
return True
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
<div class="row border-bottom bg-white w-200 pr-0" style="overflow: visible;">
|
||||
<div class="col p-0 w-100">
|
||||
<ul class="nav settings-nav" style="padding:0 0 0 20px">
|
||||
<ul class="nav settings-nav" style="padding:0 0 0 20px" id="notifications--nav-list">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link py-3{% if not '=true' in request.full_path %} active{% endif %}" href="/notifications">
|
||||
All {% if v.normal_count %} <span class="font-weight-bold" style="color:red">({{v.normal_count}})</span>{% endif %}
|
||||
|
@ -30,14 +30,21 @@
|
|||
Messages
|
||||
</a>
|
||||
</li>
|
||||
{% if v.admin_level > 1 %}
|
||||
{% if v.admin_level >= NOTIF_MODACTION_JL_MIN %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link py-3{% if '/notifications?modactions=true' in request.full_path %} active{% endif %}" href="/notifications?modactions=true">
|
||||
Modactions {% if v.modaction_notifications_count %}<span class="font-weight-bold" style="color:#e5990d">({{v.modaction_notifications_count}})</span>{% endif %}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if v.admin_level >= 2 %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link py-3{% if '/notifications?modmail=true' in request.full_path %} active{% endif %}" href="/notifications?modmail=true">
|
||||
Modmail
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if v.admin_level %}
|
||||
{% if v.can_view_offsitementions %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link py-3{% if '/notifications?reddit=true' in request.full_path %} active{% endif %}" href="/notifications?reddit=true">
|
||||
Reddit {% if v.reddit_notifications_count %}<span class="font-weight-bold" style="color:#805ad5">({{v.reddit_notifications_count}})</span>{% endif %}
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
<th>#</th>
|
||||
<th>Name</th>
|
||||
<th role="button" onclick="sort_table(2)">Posts</th>
|
||||
<th role="button" onclick="sort_table(3)">Blockers</th>
|
||||
|
||||
<th role="button" onclick="sort_table(3)">Followers</th>
|
||||
<th role="button" onclick="sort_table(4)">Blockers</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{% for sub, count in subs %}
|
||||
|
@ -24,6 +24,7 @@
|
|||
<td>{{loop.index}}</td>
|
||||
<td><a href="/h/{{sub.name}}">{{sub.name}}</a></td>
|
||||
<td><a href="/h/{{sub.name}}">{{count}}</a></td>
|
||||
<td><a href="/h/{{sub.name}}/followers">{{sub.follow_num}}</a></td>
|
||||
<td><a href="/h/{{sub.name}}/blockers">{{sub.block_num}}</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{%-
|
||||
set CACHE_VER = {
|
||||
'css/main.css': 297,
|
||||
'css/main.css': 299,
|
||||
|
||||
'css/4chan.css': 59,
|
||||
'css/classic.css': 59,
|
||||
|
|
|
@ -1984,6 +1984,7 @@ COPY public.badge_defs (id, name, description) FROM stdin;
|
|||
137 Lottershe Winner This user won the Lottershe grand prize.
|
||||
138 Dan This user is a Certified Dan Enthusiast.
|
||||
139 Kristallmopt This user was fired from a volunteer position
|
||||
140 Y'all Seein' Eye Gets notified when other sites talk about us
|
||||
4 White Hat Discreetly reported an exploit
|
||||
1 Alpha User Joined during open alpha
|
||||
2 Verified Email Verified Email
|
||||
|
@ -2087,7 +2088,7 @@ COPY public.badge_defs (id, name, description) FROM stdin;
|
|||
-- Name: badge_defs_id_seq; Type: SEQUENCE SET; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
SELECT pg_catalog.setval('public.badge_defs_id_seq', 139, true);
|
||||
SELECT pg_catalog.setval('public.badge_defs_id_seq', 140, true);
|
||||
|
||||
|
||||
--
|
||||
|
|
Loading…
Reference in New Issue