gdfsd
This commit is contained in:
parent
73bf0b3a30
commit
002e55476c
21 changed files with 1 additions and 129 deletions
|
@ -98,8 +98,7 @@ def before_request():
|
|||
|
||||
g.timestamp = int(time.time())
|
||||
|
||||
#do not access session for static files
|
||||
if not request.path.startswith("/assets"):
|
||||
if not request.path.startswith("/assets") and not request.path.startswith("/images") and not request.path.startswith("/hostedimages"):
|
||||
session.permanent = True
|
||||
if not session.get("session_id"): session["session_id"] = secrets.token_hex(16)
|
||||
|
||||
|
|
|
@ -102,9 +102,7 @@ class Comment(Base):
|
|||
now = time.gmtime()
|
||||
ctd = time.gmtime(self.created_utc)
|
||||
|
||||
# compute number of months
|
||||
months = now.tm_mon - ctd.tm_mon + 12 * (now.tm_year - ctd.tm_year)
|
||||
# remove a month count if current day of month < creation day of month
|
||||
if now.tm_mday < ctd.tm_mday:
|
||||
months -= 1
|
||||
|
||||
|
@ -234,7 +232,6 @@ class Comment(Base):
|
|||
'score': self.score,
|
||||
'upvotes': self.upvotes,
|
||||
'downvotes': self.downvotes,
|
||||
#'award_count': self.award_count,
|
||||
'is_bot': self.is_bot,
|
||||
'flags': flags,
|
||||
}
|
||||
|
|
|
@ -53,9 +53,7 @@ class ModAction(Base):
|
|||
now = time.gmtime()
|
||||
ctd = time.gmtime(self.created_utc)
|
||||
|
||||
# compute number of months
|
||||
months = now.tm_mon - ctd.tm_mon + 12 * (now.tm_year - ctd.tm_year)
|
||||
# remove a month count if current day of month < creation day of month
|
||||
if now.tm_mday < ctd.tm_mday:
|
||||
months -= 1
|
||||
|
||||
|
|
|
@ -107,9 +107,7 @@ class Submission(Base):
|
|||
now = time.gmtime()
|
||||
ctd = time.gmtime(self.created_utc)
|
||||
|
||||
# compute number of months
|
||||
months = now.tm_mon - ctd.tm_mon + 12 * (now.tm_year - ctd.tm_year)
|
||||
# remove a month count if current day of month < creation day of month
|
||||
if now.tm_mday < ctd.tm_mday:
|
||||
months -= 1
|
||||
|
||||
|
@ -266,7 +264,6 @@ class Submission(Base):
|
|||
'downvotes': self.downvotes,
|
||||
'stickied': self.stickied,
|
||||
'distinguish_level': self.distinguish_level,
|
||||
#'award_count': self.award_count,
|
||||
'voted': self.voted if hasattr(self, 'voted') else 0,
|
||||
'flags': flags,
|
||||
}
|
||||
|
|
|
@ -613,9 +613,7 @@ class ViewerRelationship(Base):
|
|||
now = time.gmtime()
|
||||
ctd = time.gmtime(self.created_utc)
|
||||
|
||||
# compute number of months
|
||||
months = now.tm_mon - ctd.tm_mon + 12 * (now.tm_year - ctd.tm_year)
|
||||
# remove a month count if current day of month < creation day of month
|
||||
if now.tm_mday < ctd.tm_mday:
|
||||
months -= 1
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ from .const import *
|
|||
|
||||
def send_notification(vid, user, text):
|
||||
|
||||
# for when working outside request context
|
||||
if isinstance(user, int):
|
||||
uid = user
|
||||
else:
|
||||
|
|
|
@ -20,7 +20,6 @@ def filter_comment_html(html_text):
|
|||
|
||||
domain = urlparse(href).netloc
|
||||
|
||||
# parse domain into all possible subdomains
|
||||
parts = domain.split(".")
|
||||
for i in range(len(parts)):
|
||||
new_domain = parts[i]
|
||||
|
@ -29,7 +28,6 @@ def filter_comment_html(html_text):
|
|||
|
||||
domain_list.add(new_domain)
|
||||
|
||||
# search db for domain rules that prohibit commenting
|
||||
bans = [x for x in g.db.query(BannedDomain).options(lazyload('*')).filter(BannedDomain.domain.in_(list(domain_list))).all()]
|
||||
|
||||
if bans:
|
||||
|
|
|
@ -250,7 +250,6 @@ def get_comments(cids, v=None, load_parent=False):
|
|||
|
||||
def get_domain(s):
|
||||
|
||||
# parse domain into all possible subdomains
|
||||
parts = s.split(".")
|
||||
domain_list = set([])
|
||||
for i in range(len(parts)):
|
||||
|
@ -267,8 +266,6 @@ def get_domain(s):
|
|||
if not doms:
|
||||
return None
|
||||
|
||||
# return the most specific domain - the one with the longest domain
|
||||
# property
|
||||
doms = sorted(doms, key=lambda x: len(x.domain), reverse=True)
|
||||
|
||||
return doms[0]
|
|
@ -148,7 +148,6 @@ def sanitize(sanitized, noimages=False):
|
|||
|
||||
tag.wrap(link)
|
||||
|
||||
#disguised link preventer
|
||||
for tag in soup.find_all("a"):
|
||||
|
||||
tag["target"] = "_blank"
|
||||
|
@ -160,16 +159,13 @@ def sanitize(sanitized, noimages=False):
|
|||
except:
|
||||
tag.string = ""
|
||||
|
||||
#clean up tags in code
|
||||
for tag in soup.find_all("code"):
|
||||
tag.contents=[x.string for x in tag.contents if x.string]
|
||||
|
||||
#whatever else happens with images, there are only two sets of classes allowed
|
||||
for tag in soup.find_all("img"):
|
||||
if 'profile-pic-20' not in tag.attrs.get("class",""):
|
||||
tag.attrs['class']="in-comment-image rounded-sm my-2"
|
||||
|
||||
#table format
|
||||
for tag in soup.find_all("table"):
|
||||
tag.attrs['class']="table table-striped"
|
||||
|
||||
|
|
|
@ -107,7 +107,6 @@ def auth_desired(f):
|
|||
|
||||
|
||||
def auth_required(f):
|
||||
# decorator for any view that requires login (ex. settings)
|
||||
|
||||
def wrapper(*args, **kwargs):
|
||||
|
||||
|
@ -120,7 +119,6 @@ def auth_required(f):
|
|||
|
||||
g.v = v
|
||||
|
||||
# an ugly hack to make api work
|
||||
resp = make_response(f(*args, v=v, **kwargs))
|
||||
return resp
|
||||
|
||||
|
@ -129,7 +127,6 @@ def auth_required(f):
|
|||
|
||||
|
||||
def is_not_banned(f):
|
||||
# decorator that enforces lack of ban
|
||||
|
||||
def wrapper(*args, **kwargs):
|
||||
|
||||
|
|
|
@ -658,7 +658,6 @@ def admin_image_ban(v):
|
|||
i=request.files['file']
|
||||
|
||||
|
||||
#make phash
|
||||
tempname = f"admin_image_ban_{v.username}_{int(time.time())}"
|
||||
|
||||
i.save(tempname)
|
||||
|
@ -668,20 +667,17 @@ def admin_image_ban(v):
|
|||
value = int(str(h), 16)
|
||||
bindigits = []
|
||||
|
||||
# Seed digit: 2**0
|
||||
digit = (value % 2)
|
||||
value //= 2
|
||||
bindigits.append(digit)
|
||||
|
||||
while value > 0:
|
||||
# Next power of 2**n
|
||||
digit = (value % 2)
|
||||
value //= 2
|
||||
bindigits.append(digit)
|
||||
|
||||
h = ''.join([str(d) for d in bindigits])
|
||||
|
||||
#check db for existing
|
||||
badpic = g.db.query(BadPic).options(lazyload('*')).filter_by(
|
||||
phash=h
|
||||
).first()
|
||||
|
@ -874,7 +870,6 @@ def ban_user(user_id, v):
|
|||
|
||||
if user.admin_level >= v.admin_level: abort(403)
|
||||
|
||||
# check for number of days for suspension
|
||||
if 'form' in request.values:
|
||||
days = float(request.values.get("days")) if request.values.get('days') else 0
|
||||
reason = sanitize(request.values.get("reason", ""))
|
||||
|
|
|
@ -143,7 +143,6 @@ def api_comment(v):
|
|||
level = parent.level + 1
|
||||
else: abort(400)
|
||||
|
||||
#process and sanitize
|
||||
body = request.values.get("body", "")[:10000]
|
||||
body = body.strip()
|
||||
|
||||
|
@ -162,7 +161,6 @@ def api_comment(v):
|
|||
body_md = CustomRenderer().render(mistletoe.Document(body_md))
|
||||
body_html = sanitize(body_md)
|
||||
|
||||
# Run safety filter
|
||||
bans = filter_comment_html(body_html)
|
||||
|
||||
if bans:
|
||||
|
@ -171,14 +169,12 @@ def api_comment(v):
|
|||
if ban.reason:
|
||||
reason += f" {ban.reason}"
|
||||
|
||||
#auto ban for digitally malicious content
|
||||
if any([x.reason==4 for x in bans]):
|
||||
v.ban(days=30, reason="Digitally malicious content")
|
||||
if any([x.reason==7 for x in bans]):
|
||||
v.ban( reason="Sexualizing minors")
|
||||
return {"error": reason}, 401
|
||||
|
||||
# check existing
|
||||
existing = g.db.query(Comment).options(lazyload('*')).filter(Comment.author_id == v.id,
|
||||
Comment.deleted_utc == 0,
|
||||
Comment.parent_comment_id == parent_comment_id,
|
||||
|
@ -191,10 +187,8 @@ def api_comment(v):
|
|||
if parent.author.any_block_exists(v) and not v.admin_level>=3:
|
||||
return {"error": "You can't reply to users who have blocked you, or users you have blocked."}, 403
|
||||
|
||||
# get bot status
|
||||
is_bot = request.headers.get("X-User-Type","")=="Bot"
|
||||
|
||||
# check spam - this should hopefully be faster
|
||||
if not is_bot:
|
||||
now = int(time.time())
|
||||
cutoff = now - 60 * 60 * 24
|
||||
|
@ -503,7 +497,6 @@ def api_comment(v):
|
|||
|
||||
|
||||
if not v.shadowbanned:
|
||||
# queue up notification for parent author
|
||||
notify_users = set()
|
||||
|
||||
for x in g.db.query(Subscription.user_id).options(lazyload('*')).filter_by(submission_id=c.parent_submission).all():
|
||||
|
@ -547,7 +540,6 @@ def api_comment(v):
|
|||
|
||||
|
||||
|
||||
# create auto upvote
|
||||
vote = CommentVote(user_id=v.id,
|
||||
comment_id=c.id,
|
||||
vote_type=1
|
||||
|
@ -599,7 +591,6 @@ def edit_comment(cid, v):
|
|||
ban = bans[0]
|
||||
reason = f"Remove the {ban.domain} link from your comment and try again."
|
||||
|
||||
#auto ban for digitally malicious content
|
||||
if any([x.reason==4 for x in bans]):
|
||||
v.ban(days=30, reason="Digitally malicious content is not allowed.")
|
||||
return {"error":"Digitally malicious content is not allowed."}
|
||||
|
@ -614,7 +605,6 @@ def edit_comment(cid, v):
|
|||
body=body,
|
||||
v=v
|
||||
)
|
||||
# check spam - this should hopefully be faster
|
||||
now = int(time.time())
|
||||
cutoff = now - 60 * 60 * 24
|
||||
|
||||
|
@ -741,7 +731,6 @@ def edit_comment(cid, v):
|
|||
|
||||
g.db.flush()
|
||||
|
||||
# queue up notifications for username mentions
|
||||
notify_users = set()
|
||||
soup = BeautifulSoup(body_html, features="html.parser")
|
||||
mentions = soup.find_all("a", href=re.compile("^/@(\w+)"))
|
||||
|
|
|
@ -36,7 +36,6 @@ def join_discord(v):
|
|||
def discord_redirect(v):
|
||||
|
||||
|
||||
#validate state
|
||||
now=int(time.time())
|
||||
state=request.values.get('state','').split('.')
|
||||
|
||||
|
@ -50,7 +49,6 @@ def discord_redirect(v):
|
|||
if not validate_hash(f"{timestamp}+{v.id}+discord", state):
|
||||
abort(400)
|
||||
|
||||
#get discord token
|
||||
code = request.values.get("code","")
|
||||
if not code:
|
||||
abort(400)
|
||||
|
@ -79,7 +77,6 @@ def discord_redirect(v):
|
|||
abort(403)
|
||||
|
||||
|
||||
#get user ID
|
||||
url="https://discord.com/api/users/@me"
|
||||
headers={
|
||||
'Authorization': f"Bearer {token}"
|
||||
|
@ -90,13 +87,11 @@ def discord_redirect(v):
|
|||
|
||||
|
||||
|
||||
#add user to discord
|
||||
headers={
|
||||
'Authorization': f"Bot {BOT_TOKEN}",
|
||||
'Content-Type': "application/json"
|
||||
}
|
||||
|
||||
#remove existing user if applicable
|
||||
if v.discord_id and v.discord_id != x['id']:
|
||||
url=f"https://discord.com/api/guilds/{SERVER_ID}/members/{v.discord_id}"
|
||||
requests.delete(url, headers=headers)
|
||||
|
|
|
@ -121,7 +121,6 @@ def front_all(v):
|
|||
try: page = int(request.values.get("page") or 1)
|
||||
except: abort(400)
|
||||
|
||||
# prevent invalid paging
|
||||
page = max(page, 1)
|
||||
|
||||
if v:
|
||||
|
@ -243,11 +242,9 @@ def changelog(v):
|
|||
v=v,
|
||||
)
|
||||
|
||||
# check existence of next page
|
||||
next_exists = (len(ids) > 25)
|
||||
ids = ids[:25]
|
||||
|
||||
# check if ids exist
|
||||
posts = get_posts(ids, v=v)
|
||||
|
||||
if request.headers.get("Authorization"): return {"data": [x.json for x in posts], "next_exists": next_exists}
|
||||
|
|
|
@ -22,12 +22,10 @@ def login_get(v):
|
|||
|
||||
|
||||
def check_for_alts(current_id):
|
||||
# account history
|
||||
past_accs = set(session.get("history", []))
|
||||
past_accs.add(current_id)
|
||||
session["history"] = list(past_accs)
|
||||
|
||||
# record alts
|
||||
for past_id in session["history"]:
|
||||
|
||||
if past_id == current_id:
|
||||
|
@ -95,7 +93,6 @@ def login_post():
|
|||
time.sleep(random.uniform(0, 2))
|
||||
return render_template("login.html", failed=True)
|
||||
|
||||
# test password
|
||||
|
||||
if request.values.get("password"):
|
||||
|
||||
|
@ -141,7 +138,6 @@ def login_post():
|
|||
account.unban_utc = 0
|
||||
g.db.add(account)
|
||||
|
||||
# set session and user id
|
||||
session["user_id"] = account.id
|
||||
session["session_id"] = token_hex(16)
|
||||
session["login_nonce"] = account.login_nonce
|
||||
|
@ -149,7 +145,6 @@ def login_post():
|
|||
|
||||
check_for_alts(account.id)
|
||||
|
||||
# check for previous page
|
||||
|
||||
redir = request.values.get("redirect", "/").replace("/logged_out", "")
|
||||
|
||||
|
@ -189,7 +184,6 @@ def sign_up_get(v):
|
|||
agent = request.headers.get("User-Agent", None)
|
||||
if not agent: abort(403)
|
||||
|
||||
# check for referral in link
|
||||
ref = request.values.get("ref", None)
|
||||
if ref:
|
||||
ref_user = g.db.query(User).options(lazyload('*')).filter(User.username.ilike(ref)).first()
|
||||
|
@ -200,14 +194,12 @@ def sign_up_get(v):
|
|||
if ref_user and (ref_user.id in session.get("history", [])):
|
||||
return render_template("sign_up_failed_ref.html")
|
||||
|
||||
# Make a unique form key valid for one account creation
|
||||
now = int(time.time())
|
||||
token = token_hex(16)
|
||||
session["signup_token"] = token
|
||||
|
||||
formkey_hashstr = str(now) + token + agent
|
||||
|
||||
# formkey is a hash of session token, timestamp, and IP address
|
||||
formkey = hmac.new(key=bytes(environ.get("MASTER_KEY"), "utf-16"),
|
||||
msg=bytes(formkey_hashstr, "utf-16"),
|
||||
digestmod='md5'
|
||||
|
@ -258,8 +250,6 @@ def sign_up_post(v):
|
|||
|
||||
username = request.values.get("username").strip()
|
||||
|
||||
# define function that takes an error message and generates a new signup
|
||||
# form
|
||||
def new_signup(error):
|
||||
|
||||
args = {"error": error}
|
||||
|
@ -337,7 +327,6 @@ def sign_up_post(v):
|
|||
if id_1 == 0 and users_count < 6: admin_level=6
|
||||
else: admin_level=0
|
||||
|
||||
# make new user
|
||||
new_user = User(
|
||||
username=username,
|
||||
original_username = username,
|
||||
|
@ -354,14 +343,11 @@ def sign_up_post(v):
|
|||
g.db.add(new_user)
|
||||
g.db.flush()
|
||||
|
||||
# check alts
|
||||
|
||||
check_for_alts(new_user.id)
|
||||
|
||||
# send welcome/verify email
|
||||
if email: send_verification_email(new_user)
|
||||
|
||||
# send welcome message
|
||||
if "rdrama" in request.host: send_notification(NOTIFICATIONS_ACCOUNT, new_user, "Dude bussy lmao")
|
||||
|
||||
session["user_id"] = new_user.id
|
||||
|
@ -402,7 +388,6 @@ def post_forgot():
|
|||
User.email.ilike(email)).first()
|
||||
|
||||
if user:
|
||||
# generate url
|
||||
now = int(time.time())
|
||||
token = generate_hash(f"{user.id}+{now}+forgot+{user.login_nonce}")
|
||||
url = f"https://{app.config['SERVER_NAME']}/reset?id={user.id}&time={now}&token={token}"
|
||||
|
@ -533,7 +518,6 @@ def request_2fa_disable():
|
|||
title="Removal request received",
|
||||
message="If username, password, and email match, we will send you an email.")
|
||||
|
||||
#compute token
|
||||
valid=int(time.time())
|
||||
token=generate_hash(f"{user.id}+{user.username}+disable2fa+{valid}+{user.mfa_secret}+{user.login_nonce}")
|
||||
|
||||
|
@ -569,7 +553,6 @@ def reset_2fa():
|
|||
if not validate_hash(f"{user.id}+{user.username}+disable2fa+{t}+{user.mfa_secret}+{user.login_nonce}", token):
|
||||
abort(403)
|
||||
|
||||
#validation successful, remove 2fa
|
||||
user.mfa_secret=None
|
||||
|
||||
g.db.add(user)
|
||||
|
|
|
@ -211,7 +211,6 @@ def edit_post(pid, v):
|
|||
body_md = CustomRenderer().render(mistletoe.Document(body))
|
||||
body_html = sanitize(body_md)
|
||||
|
||||
# Run safety filter
|
||||
bans = filter_comment_html(body_html)
|
||||
if bans:
|
||||
ban = bans[0]
|
||||
|
@ -219,7 +218,6 @@ def edit_post(pid, v):
|
|||
if ban.reason:
|
||||
reason += f" {ban.reason}"
|
||||
|
||||
#auto ban for digitally malicious content
|
||||
if any([x.reason==4 for x in bans]):
|
||||
v.ban(days=30, reason="Digitally malicious content is not allowed.")
|
||||
abort(403)
|
||||
|
@ -347,7 +345,6 @@ def filter_title(title):
|
|||
title = title.replace("\r", "")
|
||||
title = title.replace("\t", "")
|
||||
|
||||
# sanitize title
|
||||
title = bleach.clean(title, tags=[])
|
||||
|
||||
for i in re.finditer('(?<!"):([^ ]{1,30}?):', title):
|
||||
|
@ -370,7 +367,6 @@ def thumbnail_thread(pid):
|
|||
|
||||
def expand_url(post_url, fragment_url):
|
||||
|
||||
# convert src into full url
|
||||
if fragment_url.startswith("https://"):
|
||||
return fragment_url
|
||||
elif fragment_url.startswith("http://"):
|
||||
|
@ -393,7 +389,6 @@ def thumbnail_thread(pid):
|
|||
|
||||
fetch_url=post.url
|
||||
|
||||
#mimic chrome browser agent
|
||||
headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Safari/537.36"}
|
||||
|
||||
try:
|
||||
|
@ -407,17 +402,12 @@ def thumbnail_thread(pid):
|
|||
return
|
||||
|
||||
|
||||
#if content is image, stick with that. Otherwise, parse html.
|
||||
|
||||
if x.headers.get("Content-Type","").startswith("text/html"):
|
||||
#parse html, find image, load image
|
||||
soup=BeautifulSoup(x.content, 'html.parser')
|
||||
#parse html
|
||||
|
||||
#create list of urls to check
|
||||
thumb_candidate_urls=[]
|
||||
|
||||
#iterate through desired meta tags
|
||||
meta_tags = [
|
||||
"ruqqus:thumbnail",
|
||||
"twitter:image",
|
||||
|
@ -446,12 +436,10 @@ def thumbnail_thread(pid):
|
|||
if tag:
|
||||
thumb_candidate_urls.append(expand_url(post.url, tag['content']))
|
||||
|
||||
#parse html doc for <img> elements
|
||||
for tag in soup.find_all("img", attrs={'src':True}):
|
||||
thumb_candidate_urls.append(expand_url(post.url, tag['src']))
|
||||
|
||||
|
||||
#now we have a list of candidate urls to try
|
||||
for url in thumb_candidate_urls:
|
||||
|
||||
try:
|
||||
|
@ -475,14 +463,12 @@ def thumbnail_thread(pid):
|
|||
break
|
||||
|
||||
else:
|
||||
#getting here means we are out of candidate urls (or there never were any)
|
||||
db.close()
|
||||
return
|
||||
|
||||
|
||||
|
||||
elif x.headers.get("Content-Type","").startswith("image/"):
|
||||
#image is originally loaded fetch_url
|
||||
image_req=x
|
||||
image = PILimage.open(BytesIO(x.content))
|
||||
|
||||
|
@ -569,7 +555,6 @@ def submit_post(v):
|
|||
url = ""
|
||||
|
||||
body = request.values.get("body", "")
|
||||
# check for duplicate
|
||||
dup = g.db.query(Submission).options(lazyload('*')).filter(
|
||||
|
||||
Submission.author_id == v.id,
|
||||
|
@ -583,13 +568,11 @@ def submit_post(v):
|
|||
return redirect(dup.permalink)
|
||||
|
||||
|
||||
# check for domain specific rules
|
||||
|
||||
parsed_url = urlparse(url)
|
||||
|
||||
domain = parsed_url.netloc
|
||||
|
||||
# check ban status
|
||||
domain_obj = get_domain(domain)
|
||||
if domain_obj:
|
||||
if domain_obj.reason==4:
|
||||
|
@ -620,7 +603,6 @@ def submit_post(v):
|
|||
|
||||
else: embed = None
|
||||
|
||||
# similarity check
|
||||
now = int(time.time())
|
||||
cutoff = now - 60 * 60 * 24
|
||||
|
||||
|
@ -628,34 +610,18 @@ def submit_post(v):
|
|||
similar_posts = g.db.query(Submission).options(
|
||||
lazyload('*')
|
||||
).filter(
|
||||
#or_(
|
||||
# and_(
|
||||
Submission.author_id == v.id,
|
||||
Submission.title.op('<->')(title) < app.config["SPAM_SIMILARITY_THRESHOLD"],
|
||||
Submission.created_utc > cutoff
|
||||
# ),
|
||||
# and_(
|
||||
# Submission.title.op('<->')(title) < app.config["SPAM_SIMILARITY_THRESHOLD"]/2,
|
||||
# Submission.created_utc > cutoff
|
||||
# )
|
||||
#)
|
||||
).all()
|
||||
|
||||
if url:
|
||||
similar_urls = g.db.query(Submission).options(
|
||||
lazyload('*')
|
||||
).filter(
|
||||
#or_(
|
||||
# and_(
|
||||
Submission.author_id == v.id,
|
||||
Submission.url.op('<->')(url) < app.config["SPAM_URL_SIMILARITY_THRESHOLD"],
|
||||
Submission.created_utc > cutoff
|
||||
# ),
|
||||
# and_(
|
||||
# Submission.url.op('<->')(url) < app.config["SPAM_URL_SIMILARITY_THRESHOLD"]/2,
|
||||
# Submission.created_utc > cutoff
|
||||
# )
|
||||
#)
|
||||
).all()
|
||||
else:
|
||||
similar_urls = []
|
||||
|
@ -692,7 +658,6 @@ def submit_post(v):
|
|||
g.db.add(ma)
|
||||
return redirect("/notifications")
|
||||
|
||||
# catch too-long body
|
||||
if len(str(body)) > 10000:
|
||||
|
||||
if request.headers.get("Authorization"): return {"error":"10000 character limit for text body."}, 400
|
||||
|
@ -703,7 +668,6 @@ def submit_post(v):
|
|||
if request.headers.get("Authorization"): return {"error":"2048 character limit for URLs."}, 400
|
||||
else: return render_template("submit.html", v=v, error="2048 character limit for URLs.", title=title, url=url,body=request.values.get("body", "")), 400
|
||||
|
||||
# render text
|
||||
for i in re.finditer('^(https:\/\/.*\.(png|jpg|jpeg|gif|webp|PNG|JPG|JPEG|GIF|WEBP|9999))', body, re.MULTILINE):
|
||||
if "wikipedia" not in i.group(1): body = body.replace(i.group(1), f'})')
|
||||
body = re.sub('([^\n])\n([^\n])', r'\1\n\n\2', body)
|
||||
|
@ -720,7 +684,6 @@ def submit_post(v):
|
|||
|
||||
if len(body_html) > 20000: abort(400)
|
||||
|
||||
# Run safety filter
|
||||
bans = filter_comment_html(body_html)
|
||||
if bans:
|
||||
ban = bans[0]
|
||||
|
@ -728,7 +691,6 @@ def submit_post(v):
|
|||
if ban.reason:
|
||||
reason += f" {ban.reason}"
|
||||
|
||||
#auto ban for digitally malicious content
|
||||
if any([x.reason==4 for x in bans]):
|
||||
v.ban(days=30, reason="Digitally malicious content is not allowed.")
|
||||
abort(403)
|
||||
|
@ -736,7 +698,6 @@ def submit_post(v):
|
|||
if request.headers.get("Authorization"): return {"error": reason}, 403
|
||||
else: return render_template("submit.html", v=v, error=reason, title=title, url=url, body=request.values.get("body", "")), 403
|
||||
|
||||
# check for embeddable video
|
||||
domain = parsed_url.netloc
|
||||
|
||||
if v.paid_dues: club = bool(request.values.get("club",""))
|
||||
|
|
|
@ -14,7 +14,6 @@ valid_params=[
|
|||
|
||||
def searchparse(text):
|
||||
|
||||
#takes test in filter:term format and returns data
|
||||
|
||||
criteria = {x[0]:x[1] for x in query_regex.findall(text)}
|
||||
|
||||
|
|
|
@ -107,7 +107,6 @@ def settings_profile_post(v):
|
|||
if "wikipedia" not in i.group(1): bio = bio.replace(i.group(1), f'})')
|
||||
bio = re.sub('([^\n])\n([^\n])', r'\1\n\n\2', bio)
|
||||
|
||||
# check for uploaded image
|
||||
if request.files.get('file') and request.headers.get("cf-ipcountry") != "T1":
|
||||
|
||||
file = request.files['file']
|
||||
|
@ -123,7 +122,6 @@ def settings_profile_post(v):
|
|||
|
||||
bio_html = CustomRenderer().render(mistletoe.Document(bio))
|
||||
bio_html = sanitize(bio_html)
|
||||
# Run safety filter
|
||||
bans = filter_comment_html(bio_html)
|
||||
|
||||
if len(bio_html) > 10000:
|
||||
|
@ -137,7 +135,6 @@ def settings_profile_post(v):
|
|||
if ban.reason:
|
||||
reason += f" {ban.reason}"
|
||||
|
||||
#auto ban for digitally malicious content
|
||||
if any([x.reason==4 for x in bans]):
|
||||
v.ban(days=30, reason="Digitally malicious content is not allowed.")
|
||||
return {"error": reason}, 401
|
||||
|
@ -416,7 +413,6 @@ def settings_security_post(v):
|
|||
if new_email == v.email:
|
||||
return redirect("/settings/security?error=That email is already yours!")
|
||||
|
||||
# check to see if email is in use
|
||||
existing = g.db.query(User).options(lazyload('*')).filter(User.id != v.id,
|
||||
func.lower(User.email) == new_email.lower()).first()
|
||||
if existing:
|
||||
|
@ -492,10 +488,8 @@ def settings_log_out_others(v):
|
|||
|
||||
if not v.verifyPass(submitted_password): return render_template("settings_security.html", v=v, error="Incorrect Password"), 401
|
||||
|
||||
# increment account's nonce
|
||||
v.login_nonce += 1
|
||||
|
||||
# update cookie accordingly
|
||||
session["login_nonce"] = v.login_nonce
|
||||
|
||||
g.db.add(v)
|
||||
|
@ -865,7 +859,6 @@ def settings_title_change(v):
|
|||
|
||||
new_name=request.values.get("title").strip()[:100].replace("𒐪","")
|
||||
|
||||
#make sure name is different
|
||||
if new_name==v.customtitle:
|
||||
return render_template("settings_profile.html",
|
||||
v=v,
|
||||
|
|
|
@ -100,7 +100,6 @@ def cached_chart():
|
|||
|
||||
comment_stats = [g.db.query(Comment.id).options(lazyload('*')).filter(Comment.created_utc < day_cutoffs[i], Comment.created_utc > day_cutoffs[i + 1],Comment.is_banned == False, Comment.author_id != 1).count() for i in range(len(day_cutoffs) - 1)][2:][::-1]
|
||||
|
||||
# create multiple charts
|
||||
signup_chart = plt.subplot2grid((20, 4), (0, 0), rowspan=5, colspan=4)
|
||||
posts_chart = plt.subplot2grid((20, 4), (7, 0), rowspan=5, colspan=4)
|
||||
comments_chart = plt.subplot2grid((20, 4), (14, 0), rowspan=5, colspan=4)
|
||||
|
|
|
@ -395,13 +395,10 @@ def u_username(username, v=None):
|
|||
|
||||
if v and request.path.startswith('/logged_out'): v = None
|
||||
|
||||
# username is unique so at most this returns one result. Otherwise 404
|
||||
|
||||
# case insensitive search
|
||||
|
||||
u = get_user(username, v=v)
|
||||
|
||||
# check for wrong cases
|
||||
|
||||
if username != u.username:
|
||||
return redirect(request.path.replace(username, u.username))
|
||||
|
@ -410,7 +407,6 @@ def u_username(username, v=None):
|
|||
if request.headers.get("Authorization"): return {"error": f"That username is reserved for: {u.reserved}"}
|
||||
else: return render_template("userpage_reserved.html", u=u, v=v)
|
||||
|
||||
# viewers
|
||||
if v and u.id != v.id:
|
||||
view = g.db.query(ViewerRelationship).options(lazyload('*')).filter(
|
||||
and_(
|
||||
|
@ -457,7 +453,6 @@ def u_username(username, v=None):
|
|||
|
||||
ids = u.userpagelisting(v=v, page=page, sort=sort, t=t)
|
||||
|
||||
# we got 26 items just to see if a next page exists
|
||||
next_exists = (len(ids) > 25)
|
||||
ids = ids[:25]
|
||||
|
||||
|
@ -508,13 +503,10 @@ def u_username_comments(username, v=None):
|
|||
|
||||
if v and request.path.startswith('/logged_out'): v = None
|
||||
|
||||
# username is unique so at most this returns one result. Otherwise 404
|
||||
|
||||
# case insensitive search
|
||||
|
||||
user = get_user(username, v=v)
|
||||
|
||||
# check for wrong cases
|
||||
|
||||
if username != user.username: return redirect(f'{user.url}/comments')
|
||||
|
||||
|
@ -589,7 +581,6 @@ def u_username_comments(username, v=None):
|
|||
comments = comments.offset(25 * (page - 1)).limit(26).all()
|
||||
ids = [x.id for x in comments]
|
||||
|
||||
# we got 26 items just to see if a next page exists
|
||||
next_exists = (len(ids) > 25)
|
||||
ids = ids[:25]
|
||||
|
||||
|
@ -624,7 +615,6 @@ def follow_user(username, v):
|
|||
|
||||
if target.id==v.id: return {"error": "You can't follow yourself!"}, 400
|
||||
|
||||
# check for existing follow
|
||||
if g.db.query(Follow).options(lazyload('*')).filter_by(user_id=v.id, target_id=target.id).first(): return {"message": "User followed!"}
|
||||
|
||||
new_follow = Follow(user_id=v.id, target_id=target.id)
|
||||
|
@ -650,7 +640,6 @@ def unfollow_user(username, v):
|
|||
|
||||
if target.id == 995: abort(403)
|
||||
|
||||
# check for existing follow
|
||||
follow = g.db.query(Follow).options(lazyload('*')).filter_by(user_id=v.id, target_id=target.id).first()
|
||||
|
||||
if not follow: return {"message": "User unfollowed!"}
|
||||
|
@ -674,7 +663,6 @@ def unfollow_user(username, v):
|
|||
def remove_follow(username, v):
|
||||
target = get_user(username)
|
||||
|
||||
# check for existing follow
|
||||
follow = g.db.query(Follow).options(lazyload('*')).filter_by(user_id=target.id, target_id=v.id).first()
|
||||
|
||||
if not follow: return {"message": "Follower removed!"}
|
||||
|
|
|
@ -62,14 +62,12 @@ def api_vote_post(post_id, new, v):
|
|||
|
||||
if new not in ["-1", "0", "1"]: abort(400)
|
||||
|
||||
# disallow bots
|
||||
if request.headers.get("X-User-Type","") == "Bot": abort(403)
|
||||
|
||||
new = int(new)
|
||||
|
||||
post = get_post(post_id)
|
||||
|
||||
# check for existing vote
|
||||
existing = g.db.query(Vote).options(lazyload('*')).filter_by(user_id=v.id, submission_id=post.id).first()
|
||||
|
||||
if existing and existing.vote_type == new: return "", 204
|
||||
|
@ -127,7 +125,6 @@ def api_vote_comment(comment_id, new, v):
|
|||
|
||||
comment = get_comment(comment_id)
|
||||
|
||||
# check for existing vote
|
||||
existing = g.db.query(CommentVote).options(lazyload('*')).filter_by(user_id=v.id, comment_id=comment.id).first()
|
||||
|
||||
if existing and existing.vote_type == new: return "", 204
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue