Remove special cases for unused awards.

Removes the following awards / fields on User:
 - flairlock
 - progressivestack
 - bird
 - longpost (pizzashill)
 - marseyawarded
 - rehab
 - deflector
 - mute
 - unmutable
 - eye (All-Seeing Eye)
 - alt (Alt-Seeing Eye)

Primarily motivated by starting to remove some un-Mottelike cruft
from core commenting/posting routes. Cleared out other inapplicable
awards while in the process.
This commit is contained in:
TLSM 2022-11-07 03:01:44 -05:00 committed by Ben Rog-Wilhelm
parent 9de6f20dea
commit 3f360bb457
18 changed files with 77 additions and 582 deletions

2
.github/FUNDING.yml vendored
View file

@ -1,2 +0,0 @@
github: Aevann1
custom: ["https://marsey1.gumroad.com/l/tfcvri"]

View file

@ -21,14 +21,9 @@ function pick(kind, canbuy1, canbuy2) {
document.getElementById('kind').value=kind;
try {document.getElementsByClassName('picked')[0].classList.toggle('picked');} catch(e) {console.log(e)}
document.getElementById(kind).classList.toggle('picked')
if (kind == "flairlock") {
document.getElementById('notelabel').innerHTML = "New flair:";
document.getElementById('note').placeholder = "Insert new flair here, or leave empty to add 1 day to the duration of the current flair";
}
else {
document.getElementById('notelabel').innerHTML = "Note (optional):";
document.getElementById('note').placeholder = "Note to include in award notification";
}
document.getElementById('notelabel').innerHTML = "Note (optional):";
document.getElementById('note').placeholder = "Note to include in award notification";
}
function buy(mb) {

View file

@ -41,15 +41,7 @@ class Badge(Base):
@property
@lazy
def text(self):
if self.badge_id in {94,95,96,97,98,109}:
if self.badge_id == 94: ti = self.user.progressivestack
elif self.badge_id == 95: ti = self.user.bird
elif self.badge_id == 96: ti = self.user.flairchanged
elif self.badge_id == 97: ti = self.user.longpost
elif self.badge_id == 98: ti = self.user.marseyawarded
elif self.badge_id == 109: ti = self.user.rehab
text = self.badge.description + " until " + datetime.utcfromtimestamp(ti).strftime('%Y-%m-%d %H:%M:%S')
elif self.description: text = self.description
if self.description: text = self.description
elif self.badge.description: text = self.badge.description
else: return self.name
return f'{self.name} - {text}'

View file

@ -57,12 +57,7 @@ class User(Base):
patron_utc = Column(Integer, default=0, nullable=False)
verified = Column(String)
verifiedcolor = Column(String)
marseyawarded = Column(Integer)
rehab = Column(Integer)
longpost = Column(Integer)
winnings = Column(Integer, default=0, nullable=False)
unblockable = Column(Boolean)
bird = Column(Integer)
email = deferred(Column(String))
css = deferred(Column(String))
profilecss = deferred(Column(String))
@ -87,18 +82,11 @@ class User(Base):
newtabexternal = Column(Boolean, default=True, nullable=False)
reddit = Column(String, default='old.reddit.com', nullable=False)
nitter = Column(Boolean)
mute = Column(Boolean)
unmutable = Column(Boolean)
eye = Column(Boolean)
alt = Column(Boolean)
frontsize = Column(Integer, default=25, nullable=False)
controversial = Column(Boolean, default=False, nullable=False)
bio = deferred(Column(String))
bio_html = Column(String)
fp = Column(String)
fish = Column(Boolean)
progressivestack = Column(Integer)
deflector = Column(Integer)
friends = deferred(Column(String))
friends_html = deferred(Column(String))
enemies = deferred(Column(String))

View file

@ -42,110 +42,6 @@ COLORS = {'ff66ac','805ad5','62ca56','38a169','80ffff','2a96f3','eb4963','ff0000
LOGGEDIN_ACTIVE_TIME = 15 * 60
AWARDS = {
"ghost": {
"kind": "ghost",
"title": "Ghost",
"description": "???",
"icon": "fas fa-ghost",
"color": "text-white",
"price": 3000
},
"nword": {
"kind": "nword",
"title": "Nword Pass",
"description": "???",
"icon": "fas fa-edit",
"color": "text-success",
"price": 10000
},
"snow": {
"kind": "snow",
"title": "Snow",
"description": "???",
"icon": "fas fa-snowflake",
"color": "text-blue-200",
"price": 300
},
"gingerbread": {
"kind": "gingerbread",
"title": "Gingerbread",
"description": "???",
"icon": "fas fa-gingerbread-man",
"color": "",
"price": 300
},
"lights": {
"kind": "lights",
"title": "Lights",
"description": "???",
"icon": "fas fa-lights-holiday",
"color": "",
"price": 300
},
"candycane": {
"kind": "candycane",
"title": "Candy Cane",
"description": "???",
"icon": "fas fa-candy-cane",
"color": "",
"price": 400
},
"fireplace": {
"kind": "fireplace",
"title": "Fireplace",
"description": "???",
"icon": "fas fa-fireplace",
"color": "",
"price": 600
},
"grinch": {
"kind": "grinch",
"title": "Grinch",
"description": "???",
"icon": "fas fa-angry",
"color": "text-green-500",
"price": 1000
},
"haunt": {
"kind": "haunt",
"title": "Haunt",
"description": "???",
"icon": "fas fa-book-dead",
"color": "text-warning",
"price": 500
},
"upsidedown": {
"kind": "upsidedown",
"title": "The Upside Down",
"description": "???",
"icon": "fas fa-lights-holiday",
"color": "",
"price": 400
},
"stab": {
"kind": "stab",
"title": "Stab",
"description": "???",
"icon": "fas fa-knife-kitchen",
"color": "text-danger",
"price": 300
},
"spiders": {
"kind": "spiders",
"title": "Spiders",
"description": "???",
"icon": "fas fa-spider",
"color": "text-black",
"price": 200
},
"fog": {
"kind": "fog",
"title": "Fog",
"description": "???",
"icon": "fas fa-smoke",
"color": "text-gray",
"price": 200
},
"lootbox": {
"kind": "lootbox",
"title": "Lootstocking",
@ -210,14 +106,6 @@ AWARDS = {
"color": "text-green",
"price": 300
},
"rehab": {
"kind": "rehab",
"title": "Rehab",
"description": "Prevents the user from gambling for 24 hours in a last ditch effort to save them from themself.",
"icon": "fas fa-dice-six",
"color": "text-black",
"price": 777
},
"beano": {
"kind": "beano",
"title": "Beano",
@ -226,14 +114,6 @@ AWARDS = {
"color": "text-green",
"price": 1000
},
"progressivestack": {
"kind": "progressivestack",
"title": "Progressive Stack",
"description": "Makes votes on the recipient's posts and comments weigh double in the ranking algorithm for 6 hours.",
"icon": "fas fa-bullhorn",
"color": "text-danger",
"price": 1000
},
"pin": {
"kind": "pin",
"title": "1-Hour Pin",
@ -250,46 +130,6 @@ AWARDS = {
"color": "text-black",
"price": 1000
},
"flairlock": {
"kind": "flairlock",
"title": "1-Day Flairlock",
"description": "Sets a flair for the recipient and locks it for 24 hours.",
"icon": "fas fa-lock",
"color": "text-black",
"price": 1250
},
"pizzashill": {
"kind": "pizzashill",
"title": "Pizzashill",
"description": "Forces the recipient to make all posts/comments > 280 characters for 24 hours.",
"icon": "fas fa-pizza-slice",
"color": "text-orange",
"price": 1500
},
"bird": {
"kind": "bird",
"title": "Bird Site",
"description": "Forces the recipient to make all posts/comments < 140 characters for 24 hours.",
"icon": "fab fa-twitter",
"color": "text-blue",
"price": 1500
},
"deflector": {
"kind": "deflector",
"title": "Deflector",
"description": "Causes most awards received for the next 10 hours to be deflected back at their giver.",
"icon": "fas fa-shield",
"color": "text-pink",
"price": 2750
},
"marsey": {
"kind": "marsey",
"title": "Marsey",
"description": "Makes the recipient unable to post/comment anything but marsey emojis for 24 hours.",
"icon": "fas fa-cat",
"color": "text-orange",
"price": 3000
},
"ban": {
"kind": "ban",
"title": "1-Day Ban",
@ -322,54 +162,6 @@ AWARDS = {
"color": "text-success",
"price": 10000
},
"eye": {
"kind": "eye",
"title": "All-Seeing Eye",
"description": "Gives the recipient the ability to view private profiles.",
"icon": "fas fa-eye",
"color": "text-silver",
"price": 10000
},
"unblockable": {
"kind": "unblockable",
"title": "Unblockable",
"description": "Makes the recipient unblockable and removes all blocks on them.",
"icon": "far fa-laugh-squint",
"color": "text-lightgreen",
"price": 10000
},
"fish": {
"kind": "fish",
"title": "Fish",
"description": "This user cannot be unfollowed",
"icon": "fas fa-fish",
"color": "text-lightblue",
"price": 20000
},
"pause": {
"kind": "pause",
"title": "Pause",
"description": "Gives the recipient the ability to pause profile anthems.",
"icon": "fas fa-volume-mute",
"color": "text-danger",
"price": 20000
},
"unpausable": {
"kind": "unpausable",
"title": "Unpausable",
"description": "Makes the profile anthem of the recipient unpausable.",
"icon": "fas fa-volume",
"color": "text-success",
"price": 40000
},
"alt": {
"kind": "alt",
"title": "Alt-Seeing Eye",
"description": "Gives the recipient the ability to view alts.",
"icon": "fas fa-eye",
"color": "text-gold",
"price": 50000
},
}
AWARDS2 = deepcopy(AWARDS)
@ -415,10 +207,6 @@ mention_regex2 = re.compile('<p>@(([a-zA-Z0-9_\\-]){1,25})', flags=re.A)
valid_password_regex = re.compile("^.{8,100}$", flags=re.A)
marseyaward_body_regex = re.compile(">[^<\\s+]|[^>\\s+]<", flags=re.A)
marseyaward_title_regex = re.compile("( *<img[^>]+>)+", flags=re.A)
marsey_regex = re.compile("[a-z0-9]{1,30}", flags=re.A)
tags_regex = re.compile("[a-z0-9: ]{1,200}", flags=re.A)

View file

@ -1084,11 +1084,9 @@ def admin_title_change(user_id, v):
user=g.db.query(User).filter_by(id=user.id).one_or_none()
user.customtitle=new_name
if request.values.get("locked"): user.flairchanged = int(time.time()) + 2629746
else:
user.flairchanged = None
badge = user.has_badge(96)
if badge: g.db.delete(badge)
user.flairchanged = None
if request.values.get("locked"):
user.flairchanged = (2 << 30) - 1
g.db.add(user)

View file

@ -158,16 +158,9 @@ def award_post(pid, v):
return {"error": "You can't use this award on yourself."}, 400
if v.id != author.id:
if author.deflector and AWARDS[kind]['price'] > 300 and kind not in ('pin','unpin','benefactor'):
msg = f"@{v.username} has tried to give your [post]({post.shortlink}) the {AWARDS[kind]['title']} Award but it was deflected and applied to them :marseytroll:"
send_repeatable_notification(author.id, msg)
msg = f"@{author.username} is under the effect of a deflector award; your {AWARDS[kind]['title']} Award has been deflected back to you :marseytroll:"
send_repeatable_notification(v.id, msg)
author = v
else:
msg = f"@{v.username} has given your [post]({post.shortlink}) the {AWARDS[kind]['title']} Award!"
if note: msg += f"\n\n> {note}"
send_repeatable_notification(author.id, msg)
msg = f"@{v.username} has given your [post]({post.shortlink}) the {AWARDS[kind]['title']} Award!"
if note: msg += f"\n\n> {note}"
send_repeatable_notification(author.id, msg)
if kind == "ban":
link = f"[this post]({post.shortlink})"
@ -212,99 +205,6 @@ def award_post(pid, v):
cache.delete_memoized(frontlist)
else: post.stickied_utc = t
g.db.add(post)
elif kind == "flairlock":
new_name = note[:100].replace("𒐪","")
if not new_name and author.flairchanged:
author.flairchanged += 86400
else:
author.customtitleplain = new_name
author.customtitle = filter_emojis_only(new_name)
if len(author.customtitle) > 1000: abort(403)
author.flairchanged = int(time.time()) + 86400
if not author.has_badge(96):
badge = Badge(user_id=author.id, badge_id=96)
g.db.add(badge)
g.db.flush()
send_notification(author.id, f"@AutoJanny has given you the following profile badge:\n\n![]({badge.path})\n\n{badge.name}")
elif kind == "pause":
author.mute = True
if not author.has_badge(68):
new_badge = Badge(badge_id=68, user_id=author.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 == "unpausable":
author.unmutable = True
if not author.has_badge(67):
new_badge = Badge(badge_id=67, user_id=author.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 == "marsey":
if author.marseyawarded: author.marseyawarded += 86400
else: author.marseyawarded = int(time.time()) + 86400
if not author.has_badge(98):
badge = Badge(user_id=author.id, badge_id=98)
g.db.add(badge)
g.db.flush()
send_notification(author.id, f"@AutoJanny has given you the following profile badge:\n\n![]({badge.path})\n\n{badge.name}")
elif kind == "pizzashill":
if author.bird:
return {"error": "This user is the under the effect of a conflicting award: Bird Site award."}, 404
if author.longpost: author.longpost += 86400
else: author.longpost = int(time.time()) + 86400
if not author.has_badge(97):
badge = Badge(user_id=author.id, badge_id=97)
g.db.add(badge)
g.db.flush()
send_notification(author.id, f"@AutoJanny has given you the following profile badge:\n\n![]({badge.path})\n\n{badge.name}")
elif kind == "bird":
if author.longpost:
return {"error": "This user is the under the effect of a conflicting award: Pizzashill award."}, 404
if author.bird: author.bird += 86400
else: author.bird = int(time.time()) + 86400
if not author.has_badge(95):
badge = Badge(user_id=author.id, badge_id=95)
g.db.add(badge)
g.db.flush()
send_notification(author.id, f"@AutoJanny has given you the following profile badge:\n\n![]({badge.path})\n\n{badge.name}")
elif kind == "eye":
author.eye = True
if not author.has_badge(83):
new_badge = Badge(badge_id=83, user_id=author.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 == "alt":
author.alt = True
if not author.has_badge(84):
new_badge = Badge(badge_id=84, user_id=author.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 == "unblockable":
author.unblockable = True
if not author.has_badge(87):
new_badge = Badge(badge_id=87, user_id=author.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}")
for block in g.db.query(UserBlock).filter_by(target_id=author.id).all(): g.db.delete(block)
elif kind == "fish":
author.fish = True
if not author.has_badge(90):
new_badge = Badge(badge_id=90, user_id=author.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 == "progressivestack":
if author.progressivestack: author.progressivestack += 21600
else: author.progressivestack = int(time.time()) + 21600
if not author.has_badge(94):
badge = Badge(user_id=author.id, badge_id=94)
g.db.add(badge)
g.db.flush()
send_notification(author.id, f"@AutoJanny has given you the following profile badge:\n\n![]({badge.path})\n\n{badge.name}")
elif kind == "benefactor":
author.patron = 1
if author.patron_utc: author.patron_utc += 2629746
@ -316,17 +216,6 @@ def award_post(pid, v):
g.db.add(badge)
g.db.flush()
send_notification(v.id, f"@AutoJanny has given you the following profile badge:\n\n![]({badge.path})\n\n{badge.name}")
elif kind == "rehab":
if author.rehab: author.rehab += 86400
else: author.rehab = int(time.time()) + 86400
if not author.has_badge(109):
badge = Badge(user_id=author.id, badge_id=109)
g.db.add(badge)
g.db.flush()
send_notification(author.id, f"@AutoJanny has given you the following profile badge:\n\n![]({badge.path})\n\n{badge.name}")
elif kind == "deflector":
if author.deflector: author.deflector += 36000
else: author.deflector = int(time.time()) + 36000
elif kind == "beano":
if not author.has_badge(128):
badge = Badge(user_id=author.id, badge_id=128)
@ -381,22 +270,13 @@ def award_comment(cid, v):
author = c.author
if v.id != author.id:
if author.deflector and AWARDS[kind]['price'] > 300 and kind not in ('pin','unpin','benefactor'):
msg = f"@{v.username} has tried to give your [comment]({c.shortlink}) the {AWARDS[kind]['title']} Award but it was deflected and applied to them :marseytroll:"
send_repeatable_notification(author.id, msg)
msg = f"@{author.username} is under the effect of a deflector award; your {AWARDS[kind]['title']} Award has been deflected back to you :marseytroll:"
send_repeatable_notification(v.id, msg)
author = v
else:
msg = f"@{v.username} has given your [comment]({c.shortlink}) the {AWARDS[kind]['title']} Award!"
if note: msg += f"\n\n> {note}"
send_repeatable_notification(author.id, msg)
msg = f"@{v.username} has given your [comment]({c.shortlink}) the {AWARDS[kind]['title']} Award!"
if note: msg += f"\n\n> {note}"
send_repeatable_notification(author.id, msg)
if kind == "benefactor" and author.id == v.id:
return {"error": "You can't use this award on yourself."}, 400
if author.deflector: author = v
if kind == "ban":
link = f"[this comment]({c.shortlink})"
@ -437,99 +317,6 @@ def award_comment(cid, v):
c.is_pinned_utc = None
else: c.is_pinned_utc = t
g.db.add(c)
elif kind == "flairlock":
new_name = note[:100].replace("𒐪","")
if not new_name and author.flairchanged:
author.flairchanged += 86400
else:
author.customtitleplain = new_name
author.customtitle = filter_emojis_only(new_name)
if len(author.customtitle) > 1000: abort(403)
author.flairchanged = int(time.time()) + 86400
if not author.has_badge(96):
badge = Badge(user_id=author.id, badge_id=96)
g.db.add(badge)
g.db.flush()
send_notification(author.id, f"@AutoJanny has given you the following profile badge:\n\n![]({badge.path})\n\n{badge.name}")
elif kind == "pause":
author.mute = True
if not author.has_badge(68):
new_badge = Badge(badge_id=68, user_id=author.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 == "unpausable":
author.unmutable = True
if not author.has_badge(67):
new_badge = Badge(badge_id=67, user_id=author.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 == "marsey":
if author.marseyawarded: author.marseyawarded += 86400
else: author.marseyawarded = int(time.time()) + 86400
if not author.has_badge(98):
badge = Badge(user_id=author.id, badge_id=98)
g.db.add(badge)
g.db.flush()
send_notification(author.id, f"@AutoJanny has given you the following profile badge:\n\n![]({badge.path})\n\n{badge.name}")
elif kind == "pizzashill":
if author.bird:
return {"error": "This user is the under the effect of a conflicting award: Bird Site award."}, 404
if author.longpost: author.longpost += 86400
else: author.longpost = int(time.time()) + 86400
if not author.has_badge(97):
badge = Badge(user_id=author.id, badge_id=97)
g.db.add(badge)
g.db.flush()
send_notification(author.id, f"@AutoJanny has given you the following profile badge:\n\n![]({badge.path})\n\n{badge.name}")
elif kind == "bird":
if author.longpost:
return {"error": "This user is the under the effect of a conflicting award: Pizzashill award."}, 404
if author.bird: author.bird += 86400
else: author.bird = int(time.time()) + 86400
if not author.has_badge(95):
badge = Badge(user_id=author.id, badge_id=95)
g.db.add(badge)
g.db.flush()
send_notification(author.id, f"@AutoJanny has given you the following profile badge:\n\n![]({badge.path})\n\n{badge.name}")
elif kind == "eye":
author.eye = True
if not author.has_badge(83):
new_badge = Badge(badge_id=83, user_id=author.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 == "alt":
author.alt = True
if not author.has_badge(84):
new_badge = Badge(badge_id=84, user_id=author.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 == "unblockable":
author.unblockable = True
if not author.has_badge(87):
new_badge = Badge(badge_id=87, user_id=author.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}")
for block in g.db.query(UserBlock).filter_by(target_id=author.id).all(): g.db.delete(block)
elif kind == "fish":
author.fish = True
if not author.has_badge(90):
new_badge = Badge(badge_id=90, user_id=author.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 == "progressivestack":
if author.progressivestack: author.progressivestack += 21600
else: author.progressivestack = int(time.time()) + 21600
if not author.has_badge(94):
badge = Badge(user_id=author.id, badge_id=94)
g.db.add(badge)
g.db.flush()
send_notification(author.id, f"@AutoJanny has given you the following profile badge:\n\n![]({badge.path})\n\n{badge.name}")
elif kind == "benefactor":
author.patron = 1
if author.patron_utc: author.patron_utc += 2629746
@ -541,17 +328,6 @@ def award_comment(cid, v):
g.db.add(badge)
g.db.flush()
send_notification(v.id, f"@AutoJanny has given you the following profile badge:\n\n![]({badge.path})\n\n{badge.name}")
elif kind == "rehab":
if author.rehab: author.rehab += 86400
else: author.rehab = int(time.time()) + 86400
if not author.has_badge(109):
badge = Badge(user_id=author.id, badge_id=109)
g.db.add(badge)
g.db.flush()
send_notification(author.id, f"@AutoJanny has given you the following profile badge:\n\n![]({badge.path})\n\n{badge.name}")
elif kind == "deflector":
if author.deflector: author.deflector += 36000
else: author.deflector = int(time.time()) + 36000
elif kind == "beano":
if not author.has_badge(128):
badge = Badge(user_id=author.id, badge_id=128)

View file

@ -170,12 +170,6 @@ def api_comment(v):
body = request.values.get("body", "").strip()[:10000]
if parent_post.id not in ADMINISTRATORS:
if v.longpost and (len(body) < 280 or ' [](' in body or body.startswith('[](')):
return {"error":"You have to type more than 280 characters!"}, 403
elif v.bird and len(body) > 140:
return {"error":"You have to type less than 140 characters!"}, 403
if not body and not request.files.get('file'): return {"error":"You need to actually write something!"}, 400
if request.files.get("file") and request.headers.get("cf-ipcountry") != "T1":
@ -251,7 +245,7 @@ def api_comment(v):
is_bot = bool(request.headers.get("Authorization"))
if parent_post.id not in ADMINISTRATORS and not is_bot and not v.marseyawarded and len(body) > 10:
if parent_post.id not in ADMINISTRATORS and not is_bot and len(body) > 10:
now = int(time.time())
cutoff = now - 60 * 60 * 24
@ -324,9 +318,6 @@ def api_comment(v):
c.voted = 1
if v.marseyawarded and parent_post.id not in ADMINISTRATORS and marseyaward_body_regex.search(body_html):
return {"error":"You can only type marseys!"}, 403
g.db.commit()
if request.headers.get("Authorization"): return c.json
@ -405,11 +396,6 @@ def edit_comment(cid, v):
return {"error":"You have to actually type something!"}, 400
if body != c.body or request.files.get("file") and request.headers.get("cf-ipcountry") != "T1":
if v.longpost and (len(body) < 280 or ' [](' in body or body.startswith('[](')):
return {"error":"You have to type more than 280 characters!"}, 403
elif v.bird and len(body) > 140:
return {"error":"You have to type less than 140 characters!"}, 403
body_html = sanitize(body, edit=True)
# Spam Checking
@ -473,9 +459,6 @@ def edit_comment(cid, v):
if len(body_html) > 20000: abort(400)
if v.marseyawarded and marseyaward_body_regex.search(body_html):
return {"error":"You can only type marseys!"}, 403
c.body = body[:10000]
c.body_html = body_html

View file

@ -210,7 +210,6 @@ 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
@ -218,7 +217,6 @@ def front_all(v, sub=None, subdomain=None):
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
@ -227,60 +225,6 @@ def front_all(v, sub=None, subdomain=None):
g.db.add(v)
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()
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)

View file

@ -449,12 +449,6 @@ def edit_post(pid, v):
body, err = guarded_value("body", 0, MAX_BODY_LENGTH)
if err: return err
if v.id == p.author_id:
if v.longpost and (len(body) < 280 or ' [](' in body or body.startswith('[](')):
return {"error":"You have to type more than 280 characters!"}, 403
elif v.bird and len(body) > 140:
return {"error":"You have to type less than 140 characters!"}, 403
if title != p.title:
p.title = title
title_html = filter_emojis_only(title, edit=True)

View file

@ -70,7 +70,7 @@ def searchposts(v):
posts = posts.filter(Submission.ghost == False)
author = get_user(criteria['author'])
if not author: return {"error": "User not found"}
if author.is_private and (not v or (author.id != v.id and v.admin_level < 2 and not v.eye)):
if author.is_private and (not v or (author.id != v.id and v.admin_level < 2)):
if request.headers.get("Authorization"):
return {"error": f"@{author.username}'s profile is private; You can't use the 'author' syntax on them"}
return render_template("search.html",
@ -196,7 +196,7 @@ def searchcomments(v):
comments = comments.filter(Comment.ghost == False)
author = get_user(criteria['author'])
if not author: return {"error": "User not found"}
if author.is_private and (not v or (author.id != v.id and v.admin_level < 2 and not v.eye)):
if author.is_private and (not v or (author.id != v.id and v.admin_level < 2)):
if request.headers.get("Authorization"):
return {"error": f"@{author.username}'s profile is private; You can't use the 'author' syntax on them"}

View file

@ -557,11 +557,6 @@ def settings_block_user(v):
user = get_user(request.values.get("username"), graceful=True)
if not user: return {"error": "That user doesn't exist."}, 404
if user.unblockable:
send_notification(user.id, f"@{v.username} has tried to block you and failed because of your unblockable status!")
g.db.commit()
return {"error": "This user is unblockable."}, 403
if user.id == v.id:
return {"error": "You can't block yourself."}, 409

View file

@ -809,7 +809,7 @@ def u_username(username, v=None):
g.db.commit()
if u.is_private and (not v or (v.id != u.id and v.admin_level < 2 and not v.eye)):
if u.is_private and (not v or (v.id != u.id and v.admin_level < 2)):
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error": "That userpage is private"}
return render_template("userpage_private.html", u=u, v=v)
@ -887,7 +887,7 @@ def u_username_comments(username, v=None):
v=v)
if u.is_private and (not v or (v.id != u.id and v.admin_level < 2 and not v.eye)):
if u.is_private and (not v or (v.id != u.id and v.admin_level < 2)):
if request.headers.get("Authorization") or request.headers.get("xhr"): return {"error": "That userpage is private"}
return render_template("userpage_private.html", u=u, v=v)
@ -1011,14 +1011,8 @@ def follow_user(username, v):
@limiter.limit("1/second;30/minute;200/hour;1000/day")
@auth_required
def unfollow_user(username, v):
target = get_user(username)
if target.fish:
send_notification(target.id, f"@{v.username} has tried to unfollow you and failed because of your fish award!")
g.db.commit()
return {"error": "You can't unfollow this user!"}
follow = g.db.query(Follow).filter_by(user_id=v.id, target_id=target.id).one_or_none()
if follow:

View file

@ -289,7 +289,7 @@
<div id="comment-edit-{{c.id}}" class="d-none comment-write collapsed child">
<form id="comment-edit-form-{{c.id}}" action="/edit_comment/{{c.id}}" method="post" enctype="multipart/form-data">
<input type="hidden" name="formkey" value="{{v.formkey}}">
<textarea autocomplete="off" {% if v.longpost %}minlength="280"{% endif %} maxlength="{% if v.bird %}140{% else %}10000{% endif %}" oninput="markdown('comment-edit-body-{{c.id}}', 'preview-edit-{{c.id}}');charLimit('comment-edit-body-{{c.id}}','charcount-edit-{{c.id}}')" id="comment-edit-body-{{c.id}}" data-id="{{c.id}}" name="body" form="comment-edit-form-{{c.id}}" class="comment-box form-control rounded" aria-label="With textarea" placeholder="Add your comment..." rows="3">{{c.body}}</textarea>
<textarea autocomplete="off" maxlength="10000" oninput="markdown('comment-edit-body-{{c.id}}', 'preview-edit-{{c.id}}');charLimit('comment-edit-body-{{c.id}}','charcount-edit-{{c.id}}')" id="comment-edit-body-{{c.id}}" data-id="{{c.id}}" name="body" form="comment-edit-form-{{c.id}}" class="comment-box form-control rounded" aria-label="With textarea" placeholder="Add your comment..." rows="3">{{c.body}}</textarea>
<div class="text-small font-weight-bold mt-1" id="charcount-edit-{{c.id}}" style="right: 1rem; bottom: 0.5rem; z-index: 3;"></div>
@ -538,7 +538,7 @@
<input type="hidden" name="formkey" value="{{v.formkey}}">
<input type="hidden" name="parent_fullname" value="{{c.fullname}}">
<input autocomplete="off" id="reply-form-submission-{{c.fullname}}" type="hidden" name="submission" value="{{c.post.id}}">
<textarea required autocomplete="off" {% if v.longpost %}minlength="280"{% else %}minlength="1"{% endif %} maxlength="{% if v.bird %}140{% else %}10000{% endif %}" oninput="markdown('reply-form-body-{{c.fullname}}', 'reply-edit-{{c.id}}');charLimit('reply-form-body-{{c.fullname}}','charcount-{{c.id}}')" id="reply-form-body-{{c.fullname}}" data-fullname="{{c.fullname}}" name="body" form="reply-to-t3_{{c.id}}" class="comment-box form-control rounded" aria-label="With textarea" placeholder="Add your comment..." rows="3"></textarea>
<textarea required autocomplete="off" minlength="1" maxlength="10000" oninput="markdown('reply-form-body-{{c.fullname}}', 'reply-edit-{{c.id}}');charLimit('reply-form-body-{{c.fullname}}','charcount-{{c.id}}')" id="reply-form-body-{{c.fullname}}" data-fullname="{{c.fullname}}" name="body" form="reply-to-t3_{{c.id}}" class="comment-box form-control rounded" aria-label="With textarea" placeholder="Add your comment..." rows="3"></textarea>
<div class="text-small font-weight-bold mt-1" id="charcount-{{c.id}}" style="right: 1rem; bottom: 0.5rem; z-index: 3;"></div>

View file

@ -292,7 +292,7 @@
<input type="hidden" name="formkey" value="{{v.formkey}}">
<input type="hidden" name="current_page" value="{{request.path}}">
<input type="text" autocomplete="off" maxlength="500" name="title" class="comment-box form-control rounded" required placeholder="title" value="{{p.title}}"\>
<textarea autocomplete="off" name="body" {% if v.longpost %}minlength="280"{% endif %} maxlength="{% if v.bird %}140{% else %}20000{% endif %}" oninput="markdown('post-edit-box-{{p.id}}', 'post-edit-{{p.id}}');charLimit('post-edit-box-{{p.id}}','charcount-post-edit')" id="post-edit-box-{{p.id}}" form="post-edit-form-{{p.id}}" class="comment-box form-control rounded" aria-label="With textarea" placeholder="Add text to your post..." rows="10" data-id="{{p.id}}">{{p.body}}</textarea>
<textarea autocomplete="off" name="body" maxlength="20000" oninput="markdown('post-edit-box-{{p.id}}', 'post-edit-{{p.id}}');charLimit('post-edit-box-{{p.id}}','charcount-post-edit')" id="post-edit-box-{{p.id}}" form="post-edit-form-{{p.id}}" class="comment-box form-control rounded" aria-label="With textarea" placeholder="Add text to your post..." rows="10" data-id="{{p.id}}">{{p.body}}</textarea>
<div class="text-small font-weight-bold mt-1" id="charcount-post-edit" style="right: 1rem; bottom: 0.5rem; z-index: 3;"></div>
@ -482,7 +482,7 @@
<input type="hidden" name="formkey" value="{{v.formkey}}">
<input type="hidden" name="parent_fullname" value="t2_{{p.id}}">
<input autocomplete="off" id="reply-form-submission-{{p.fullname}}" type="hidden" name="submission" value="{{p.id}}">
<textarea required autocomplete="off" {% if not (p and p.id in ADMINISTRATORS) %}{% if v.longpost %}minlength="280"{% elif v.bird %}maxlength="140"{% endif %}{% endif %} minlength="1" maxlength="10000" oninput="markdown('reply-form-body-{{p.fullname}}', 'form-preview-{{p.id}}');charLimit('reply-form-body-{{p.fullname}}','charcount-reply')" id="reply-form-body-{{p.fullname}}" data-fullname="{{p.fullname}}" class="comment-box form-control rounded" id="comment-form" name="body" form="reply-to-{{p.fullname}}" aria-label="With textarea" placeholder="Add your comment..." rows="3"></textarea>
<textarea required autocomplete="off" minlength="1" maxlength="10000" oninput="markdown('reply-form-body-{{p.fullname}}', 'form-preview-{{p.id}}');charLimit('reply-form-body-{{p.fullname}}','charcount-reply')" id="reply-form-body-{{p.fullname}}" data-fullname="{{p.fullname}}" class="comment-box form-control rounded" id="comment-form" name="body" form="reply-to-{{p.fullname}}" aria-label="With textarea" placeholder="Add your comment..." rows="3"></textarea>
<div class="text-small font-weight-bold mt-1" id="charcount-reply" style="right: 1rem; bottom: 0.5rem; z-index: 3;"></div>

View file

@ -82,7 +82,7 @@
<label for="body" class="mt-3">Text<i class="fas fa-info-circle text-gray-400 ml-1" data-bs-toggle="tooltip" data-bs-placement="top" title="Uses markdown. Limited to 20000 characters."></i></label>
<div>
<textarea form="submitform" id="post-text" class="form-control rounded" aria-label="With textarea" placeholder="Optional if you have a link or an image." rows="7" name="body" oninput="markdown('post-text','preview');charLimit('post-text','character-count-submit-text-form');checkForRequired();savetext()" {% if v.longpost %}minlength="280"{% endif %} maxlength="{% if v.bird %}140{% else %}20000{% endif %}" required></textarea>
<textarea form="submitform" id="post-text" class="form-control rounded" aria-label="With textarea" placeholder="Optional if you have a link or an image." rows="7" name="body" oninput="markdown('post-text','preview');charLimit('post-text','character-count-submit-text-form');checkForRequired();savetext()" maxlength="20000" required></textarea>
<div class="btn btn-secondary fl-r mt-3" onclick="document.getElementById('preview').classList.toggle('d-none');">
Toggle preview

View file

@ -199,7 +199,7 @@
<a href="/views" class="btn btn-secondary">Profile views</a>
{% endif %}
{% if u.song and v and (v.id == u.id or v.mute and not u.unmutable) %}
{% if u.song and v and (v.id == u.id) %}
<a class="btn btn-secondary" role="button" onclick="toggle()">Toggle anthem</a>
{% endif %}
@ -280,7 +280,7 @@
{% if u.is_private %}
<p>User has private mode enabled.</p>
{% endif %}
{% if v and (v.admin_level > 1 or v.alt) %}
{% if v and v.admin_level >= 2 %}
<span>Alts:</span>
<ul>
{% for account in u.alts_unique %}
@ -429,7 +429,7 @@
<a href="/views" class="btn btn-secondary">Profile views</a>
{% endif %}
{% if u.song and v and (v.id == u.id or v.mute and not u.unmutable) %}
{% if u.song and v and (v.id == u.id) %}
<a class="btn btn-secondary" role="button" onclick="toggle()">Toggle anthem</a>
{% endif %}
@ -550,7 +550,7 @@
{% if u.is_private %}
<p>User has private mode enabled.</p>
{% endif %}
{% if v and (v.admin_level > 1 or v.alt) %}
{% if v and v.admin_level >= 2 %}
<span>Alts:</span>
<ul>
{% for account in u.alts_unique %}

View file

@ -0,0 +1,50 @@
"""remove many user award tracking columns
Revision ID: 0d4c7cf3da6d
Revises: 61c6f838c5c6
Create Date: 2022-11-07 08:04:52.285019+00:00
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '0d4c7cf3da6d'
down_revision = '61c6f838c5c6'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('users', 'alt')
op.drop_column('users', 'unblockable')
op.drop_column('users', 'deflector')
op.drop_column('users', 'bird')
op.drop_column('users', 'rehab')
op.drop_column('users', 'fish')
op.drop_column('users', 'mute')
op.drop_column('users', 'eye')
op.drop_column('users', 'longpost')
op.drop_column('users', 'marseyawarded')
op.drop_column('users', 'progressivestack')
op.drop_column('users', 'unmutable')
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('users', sa.Column('unmutable', sa.BOOLEAN(), autoincrement=False, nullable=True))
op.add_column('users', sa.Column('progressivestack', sa.INTEGER(), autoincrement=False, nullable=True))
op.add_column('users', sa.Column('marseyawarded', sa.INTEGER(), autoincrement=False, nullable=True))
op.add_column('users', sa.Column('longpost', sa.INTEGER(), autoincrement=False, nullable=True))
op.add_column('users', sa.Column('eye', sa.BOOLEAN(), autoincrement=False, nullable=True))
op.add_column('users', sa.Column('mute', sa.BOOLEAN(), autoincrement=False, nullable=True))
op.add_column('users', sa.Column('fish', sa.BOOLEAN(), autoincrement=False, nullable=True))
op.add_column('users', sa.Column('rehab', sa.INTEGER(), autoincrement=False, nullable=True))
op.add_column('users', sa.Column('bird', sa.INTEGER(), autoincrement=False, nullable=True))
op.add_column('users', sa.Column('deflector', sa.INTEGER(), autoincrement=False, nullable=True))
op.add_column('users', sa.Column('unblockable', sa.BOOLEAN(), autoincrement=False, nullable=True))
op.add_column('users', sa.Column('alt', sa.BOOLEAN(), autoincrement=False, nullable=True))
# ### end Alembic commands ###