diff --git a/files/classes/user.py b/files/classes/user.py index e9e4dbcaa..ec4ec48bd 100644 --- a/files/classes/user.py +++ b/files/classes/user.py @@ -78,10 +78,10 @@ class User(Base): patron_utc = Column(Integer, default=0) verified = Column(String) verifiedcolor = Column(String) - marseyawarded = Column(Integer) - rehab = Column(Integer) - longpost = Column(Integer) - bird = Column(Integer) + marseyawarded = Column(Integer, default=0) + rehab = Column(Integer, default=0) + longpost = Column(Integer, default=0) + bird = Column(Integer, default=0) email = deferred(Column(String)) css = Column(String) profilecss = deferred(Column(String)) @@ -104,7 +104,7 @@ class User(Base): hidevotedon = Column(Boolean, default=False) slurreplacer = Column(Integer, default=1) profanityreplacer = Column(Integer, default=1) - flairchanged = Column(Integer) + flairchanged = Column(Integer, default=0) newtab = Column(Boolean, default=False) newtabexternal = Column(Boolean, default=True) reddit = Column(String, default='old.reddit.com') @@ -118,8 +118,8 @@ class User(Base): sig_html = Column(String) fp = Column(String) sigs_disabled = Column(Boolean) - progressivestack = Column(Integer) - deflector = Column(Integer) + progressivestack = Column(Integer, default=0) + deflector = Column(Integer, default=0) friends = deferred(Column(String)) friends_html = deferred(Column(String)) enemies = deferred(Column(String)) @@ -148,11 +148,11 @@ class User(Base): last_viewed_log_notifs = Column(Integer, default=0) last_viewed_reddit_notifs = Column(Integer, default=0) pronouns = Column(String, default='they/them') - bite = Column(Integer) - earlylife = Column(Integer) - owoify = Column(Integer) + bite = Column(Integer, default=0) + earlylife = Column(Integer, default=0) + owoify = Column(Integer, default=0) marsify = Column(Integer, default=0) - rainbow = Column(Integer) + rainbow = Column(Integer, default=0) spider = Column(Integer, default=0) blacklisted_by = Column(Integer, ForeignKey("users.id")) diff --git a/files/helpers/awards.py b/files/helpers/awards.py deleted file mode 100644 index 1efa6b5e3..000000000 --- a/files/helpers/awards.py +++ /dev/null @@ -1,116 +0,0 @@ -import time - -from flask import g - -from files.classes.user import User -from files.helpers.alerts import send_repeatable_notification -from files.helpers.config.const import * -from files.helpers.useractions import * - -def award_timers(v, bot=False): - now = time.time() - - 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(f"Your {patron} status has expired!") - for i in (22,23,24,25,26,27,28): - badge = v.has_badge(i) - if badge: g.db.delete(badge) - if v.unban_utc and v.unban_utc < now: - v.is_banned = None - v.unban_utc = 0 - v.ban_reason = None - notify_if_not_bot("You have been unbanned!") - if v.agendaposter and v.agendaposter != 1 and v.agendaposter < now: - v.agendaposter = 0 - v.agendaposter_phrase = None - v.chudded_by = None - notify_if_not_bot("Your chud status has expired!") - badge = v.has_badge(58) - if badge: g.db.delete(badge) - 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) - 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) - 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) - 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) - if v.progressivestack and v.progressivestack != 1 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) - 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) - if v.deflector and v.deflector < now: - v.deflector = None - notify_if_not_bot("Your deflector has expired!") - if v.owoify and v.owoify < now: - v.owoify = None - notify_if_not_bot("Your OwOify status has expired!") - badge = v.has_badge(167) - if badge: g.db.delete(badge) - if v.bite and v.bite < now: - v.bite = None - badge = v.has_badge(168) - if badge: g.db.delete(badge) - - v.house = v.old_house - notify_if_not_bot(f"Your vampire status has ended. You're now back in House {v.old_house.replace(' Founder', '')}!") - v.old_house = '' - - if v.earlylife and v.earlylife < now: - v.earlylife = None - notify_if_not_bot("Your earlylife status has expired!") - badge = v.has_badge(169) - if badge: g.db.delete(badge) - if v.marsify and v.marsify != 1 and v.marsify < now: - v.marsify = 0 - if SITE_NAME != 'rDrama': notify_if_not_bot("Your marsify status has expired!") - badge = v.has_badge(170) - if badge: g.db.delete(badge) - if v.rainbow and v.rainbow < now: - v.rainbow = None - notify_if_not_bot("Your rainbow has expired!") - badge = v.has_badge(171) - if badge: g.db.delete(badge) - if v.spider and v.spider != 1 and v.spider < now: - v.spider = 0 - notify_if_not_bot("Your spider friend has left you!") - badge = v.has_badge(179) - if badge: g.db.delete(badge) - - if time.time() - v.created_utc > 365 * 86400: - badge_grant(user=v, badge_id=134) - - if time.time() - v.created_utc > 365 * 86400 * 2: - badge_grant(user=v, badge_id=237) - - g.db.add(v) - - -def award_timers_bots_task(): - accs = g.db.query(User).filter(User.id.in_(bots)) - for u in accs: - award_timers(u, bot=True) diff --git a/files/helpers/cron.py b/files/helpers/cron.py index b64eb7c77..85d004ea5 100644 --- a/files/helpers/cron.py +++ b/files/helpers/cron.py @@ -5,11 +5,11 @@ from sys import stdout from shutil import make_archive from hashlib import md5 from collections import Counter +from sqlalchemy.orm import load_only import click import requests -import files.helpers.awards as awards import files.helpers.offsitementions as offsitementions import files.helpers.stats as stats import files.routes.static as route_static @@ -32,21 +32,51 @@ def cron(every_5m, every_1h, every_1d, every_1mo): g.db = db_session() g.v = None + #I put commit under each task to release database locks and prevent main flask app crashing if every_5m: + t = time.time() + _award_timers_task() + g.db.commit() + print(f'_award_timers_task: {time.time() - t}', flush=True) + if FEATURES['GAMBLING']: + t = time.time() check_if_end_lottery_task() + g.db.commit() + print(f'check_if_end_lottery_task: {time.time() - t}', flush=True) + + t = time.time() spin_roulette_wheel() - offsitementions.offsite_mentions_task(cache) + g.db.commit() + print(f'spin_roulette_wheel: {time.time() - t}', flush=True) + #offsitementions.offsite_mentions_task(cache) if every_1h: - awards.award_timers_bots_task() + t = time.time() _generate_emojis_zip() + g.db.commit() + print(f'_generate_emojis_zip: {time.time() - t}', flush=True) + + t = time.time() _leaderboard_task() + g.db.commit() + print(f'_leaderboard_task: {time.time() - t}', flush=True) if every_1d: + t = time.time() stats.generate_charts_task(SITE) + g.db.commit() + print(f'generate_charts_task: {time.time() - t}', flush=True) + + t = time.time() _sub_inactive_purge_task() + g.db.commit() + print(f'_sub_inactive_purge_task: {time.time() - t}', flush=True) + + t = time.time() cache.set('stats', stats.stats()) + g.db.commit() + print(f'stats: {time.time() - t}', flush=True) g.db.commit() g.db.close() @@ -160,3 +190,55 @@ def _leaderboard_task(): cache.set("users9", list(users9)) cache.set("users9_1", list(users9_1)) cache.set("users9_2", list(users9_2)) + + +def _process_timer(attr, badge_ids, text, extra_attrs={}): + now = time.time() + users = g.db.query(User).options(load_only(User.id)).filter(1 < attr, attr < now) + uids = set([x.id for x in users]) + + #set user attributes + attr_dict = {attr: 0} | extra_attrs + users.update(attr_dict) + + #remove corresponding badges + if badge_ids: + g.db.query(Badge).options(load_only(Badge.badge_id)).filter(Badge.badge_id.in_(badge_ids), Badge.user_id.in_(uids)).delete() + + #notify users + for uid in uids: + send_repeatable_notification(uid, text) + g.db.commit() + + +def _award_timers_task(): + #only awards + _process_timer(User.deflector, [], "The deflector award you received has expired!") + _process_timer(User.progressivestack, [94], "The progressive stack award you received has expired!") + _process_timer(User.bird, [95], "The bird site award you received has expired!") + _process_timer(User.longpost, [97], "The pizzashill award you received has expired!") + _process_timer(User.marseyawarded, [98], "The marsey award you received has expired!") + _process_timer(User.rehab, [109], "The rehab award you received has expired!") + _process_timer(User.owoify, [167], "The OwOify award you received has expired!") + _process_timer(User.bite, [168], "Your vampire status has ended. You're now back in your original house!", { + User.house: User.old_house, + User.old_house: '', + }) + _process_timer(User.earlylife, [169], "The earlylife award you received has expired!") + _process_timer(User.marsify, [170], "The marsify award you received has expired!") + _process_timer(User.rainbow, [171], "The rainbow award you received has expired!") + _process_timer(User.spider, [179], "The spider award you received has expired!") + + #both awards and janny powers + _process_timer(User.unban_utc, [], "Your temporary ban has expired!", { + User.is_banned: None, + User.ban_reason: None, + }) + _process_timer(User.patron_utc, [22,23,24,25,26,27,28], f"Your {patron} status has expired!", { + User.patron: 0, + }) + _process_timer(User.agendaposter, [58], "Your temporary chud status has expired!", { + User.agendaposter_phrase: None, + User.chudded_by: None, + }) + _process_timer(User.flairchanged, [96], "Your temporary flair-lock has expired. You can now change your flair!") diff --git a/files/helpers/useractions.py b/files/helpers/useractions.py index c89f3d823..54b2c705a 100644 --- a/files/helpers/useractions.py +++ b/files/helpers/useractions.py @@ -3,9 +3,10 @@ from flask import g from files.classes.badges import Badge from files.helpers.alerts import send_repeatable_notification -def badge_grant(user, badge_id, description=None, url=None, notify=True): +def badge_grant(user, badge_id, description=None, url=None, notify=True, check_if_exists=True): assert user != None - if user.has_badge(badge_id): + + if check_if_exists and user.has_badge(badge_id): return if description and len(description) > 256: diff --git a/files/routes/admin.py b/files/routes/admin.py index fa3e37f9e..4fb167e75 100644 --- a/files/routes/admin.py +++ b/files/routes/admin.py @@ -905,7 +905,7 @@ def admin_title_change(user_id, v): user.customtitle=new_name if request.values.get("locked"): user.flairchanged = int(time.time()) + 2629746 else: - user.flairchanged = None + user.flairchanged = 0 badge = user.has_badge(96) if badge: g.db.delete(badge) diff --git a/files/routes/front.py b/files/routes/front.py index c57bb7c9f..3d9379788 100644 --- a/files/routes/front.py +++ b/files/routes/front.py @@ -4,7 +4,6 @@ from sqlalchemy.orm import load_only from files.classes.submission import Submission from files.classes.votes import Vote -from files.helpers.awards import award_timers from files.helpers.config.const import * from files.helpers.get import * from files.helpers.sorting_and_time import * @@ -61,9 +60,8 @@ def front_all(v, sub=None, subdomain=None): posts = get_posts(ids, v=v, eager=True) - if v: - if v.hidevotedon: posts = [x for x in posts if not hasattr(x, 'voted') or not x.voted] - award_timers(v) + if v and v.hidevotedon: + posts = [x for x in posts if not hasattr(x, 'voted') or not x.voted] if v and v.client: return {"data": [x.json(g.db) for x in posts], "total": total} return render_template("home.html", v=v, listing=posts, total=total, sort=sort, t=t, page=page, sub=sub, home=True, pins=pins, size=size) @@ -148,6 +146,12 @@ def frontlist(v=None, sort="hot", page=1, t="all", ids_only=True, filter_words=' pins = pins.order_by(Submission.created_utc.desc()).all() posts = pins + posts + if time.time() - v.created_utc > 365 * 86400: + badge_grant(user=v, badge_id=134) + + if time.time() - v.created_utc > 365 * 86400 * 2: + badge_grant(user=v, badge_id=237) + if ids_only: posts = [x.id for x in posts] return posts, total, size diff --git a/migrations/20230513-move-award-timers-and-yearly-badges-to-cron.sql b/migrations/20230513-move-award-timers-and-yearly-badges-to-cron.sql new file mode 100644 index 000000000..6d899c6b0 --- /dev/null +++ b/migrations/20230513-move-award-timers-and-yearly-badges-to-cron.sql @@ -0,0 +1,33 @@ +update users set deflector=0 where deflector is null; +update users set progressivestack=0 where progressivestack is null; +update users set bird=0 where bird is null; +update users set longpost=0 where longpost is null; +update users set marseyawarded=0 where marseyawarded is null; +update users set rehab=0 where rehab is null; +update users set owoify=0 where owoify is null; +update users set bite=0 where bite is null; +update users set earlylife=0 where earlylife is null; +update users set marsify=0 where marsify is null; +update users set rainbow=0 where rainbow is null; +update users set spider=0 where spider is null; +update users set unban_utc=0 where unban_utc is null; +update users set agendaposter=0 where agendaposter is null; +update users set flairchanged=0 where flairchanged is null; +update users set patron_utc=0 where patron_utc is null; + +create index users_deflector_idx on users using btree(deflector); +create index users_progressivestack_idx on users using btree(progressivestack); +create index users_bird_idx on users using btree(bird); +create index users_longpost_idx on users using btree(longpost); +create index users_marseyawarded_idx on users using btree(marseyawarded); +create index users_rehab_idx on users using btree(rehab); +create index users_owoify_idx on users using btree(owoify); +create index users_bite_idx on users using btree(bite); +create index users_earlylife_idx on users using btree(earlylife); +create index users_marsify_idx on users using btree(marsify); +create index users_rainbow_idx on users using btree(rainbow); +create index users_spider_idx on users using btree(spider); +create index users_unban_utc_idx on users using btree(unban_utc); +create index users_agendaposter_idx on users using btree(agendaposter); +create index users_flairchanged_idx on users using btree(flairchanged); +create index users_patron_utc_idx on users using btree(patron_utc);