forked from MarseyWorld/MarseyWorld
settings: implement backend logic for permanent filters
parent
528c27a841
commit
83fe77c039
|
@ -32,7 +32,7 @@ function createXhrWithFormKey(url, method="POST", form=new FormData()) {
|
||||||
return [xhr, form]; // hacky but less stupid than what we were doing before
|
return [xhr, form]; // hacky but less stupid than what we were doing before
|
||||||
}
|
}
|
||||||
|
|
||||||
function postToast(t, url, data, extraActionsOnSuccess) {
|
function postToast(t, url, data, extraActionsOnSuccess, method="POST") {
|
||||||
const isShopConfirm = t.id.startsWith('buy1-') || t.id.startsWith('buy2-')
|
const isShopConfirm = t.id.startsWith('buy1-') || t.id.startsWith('buy2-')
|
||||||
|
|
||||||
if (!isShopConfirm)
|
if (!isShopConfirm)
|
||||||
|
@ -47,7 +47,7 @@ function postToast(t, url, data, extraActionsOnSuccess) {
|
||||||
form.append(k, data[k]);
|
form.append(k, data[k]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const xhr = createXhrWithFormKey(url, "POST", form);
|
const xhr = createXhrWithFormKey(url, method, form);
|
||||||
xhr[0].onload = function() {
|
xhr[0].onload = function() {
|
||||||
let result
|
let result
|
||||||
let message;
|
let message;
|
||||||
|
@ -78,17 +78,17 @@ function postToast(t, url, data, extraActionsOnSuccess) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function postToastReload(t, url) {
|
function postToastReload(t, url, method="POST") {
|
||||||
postToast(t, url,
|
postToast(t, url,
|
||||||
{
|
{
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
location.reload()
|
location.reload()
|
||||||
}
|
}
|
||||||
);
|
, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
function postToastSwitch(t, url, button1, button2, cls, extraActionsOnSuccess) {
|
function postToastSwitch(t, url, button1, button2, cls, extraActionsOnSuccess, method="POST") {
|
||||||
postToast(t, url,
|
postToast(t, url,
|
||||||
{
|
{
|
||||||
},
|
},
|
||||||
|
@ -104,7 +104,7 @@ function postToastSwitch(t, url, button1, button2, cls, extraActionsOnSuccess) {
|
||||||
}
|
}
|
||||||
if (extraActionsOnSuccess) extraActionsOnSuccess(xhr);
|
if (extraActionsOnSuccess) extraActionsOnSuccess(xhr);
|
||||||
}
|
}
|
||||||
);
|
, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.location.pathname != '/submit')
|
if (window.location.pathname != '/submit')
|
||||||
|
|
|
@ -213,7 +213,7 @@ THEMES = ["4chan","classic","classic_dark","coffee","dark","dramblr","light","mi
|
||||||
COMMENT_SORTS = ["hot", "new", "old", "top", "bottom", "controversial"]
|
COMMENT_SORTS = ["hot", "new", "old", "top", "bottom", "controversial"]
|
||||||
SORTS = COMMENT_SORTS + ["bump", "comments"]
|
SORTS = COMMENT_SORTS + ["bump", "comments"]
|
||||||
TIME_FILTERS = ["hour", "day", "week", "month", "year", "all"]
|
TIME_FILTERS = ["hour", "day", "week", "month", "year", "all"]
|
||||||
PAGE_SIZES = [10, 25, 50, 100]
|
PAGE_SIZES = {10, 25, 50, 100}
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
### SITE SPECIFIC CONSTANTS
|
### SITE SPECIFIC CONSTANTS
|
||||||
|
@ -594,7 +594,7 @@ else: # localhost or testing environment implied
|
||||||
FEATURES['HOUSES'] = True
|
FEATURES['HOUSES'] = True
|
||||||
FEATURES['USERS_PERMANENT_WORD_FILTERS'] = True
|
FEATURES['USERS_PERMANENT_WORD_FILTERS'] = True
|
||||||
|
|
||||||
HOUSES = ["None","Furry","Femboy","Vampire","Racist"] if FEATURES['HOUSES'] else ["None"]
|
HOUSES = ("None","Furry","Femboy","Vampire","Racist") if FEATURES['HOUSES'] else ("None")
|
||||||
|
|
||||||
bots = {AUTOJANNY_ID, SNAPPY_ID, LONGPOSTBOT_ID, ZOZBOT_ID, BASEDBOT_ID}
|
bots = {AUTOJANNY_ID, SNAPPY_ID, LONGPOSTBOT_ID, ZOZBOT_ID, BASEDBOT_ID}
|
||||||
|
|
||||||
|
|
|
@ -26,13 +26,13 @@ def settings(v):
|
||||||
def settings_personal(v):
|
def settings_personal(v):
|
||||||
return render_template("settings_personal.html", v=v)
|
return render_template("settings_personal.html", v=v)
|
||||||
|
|
||||||
@app.post("/settings/removebackground")
|
@app.delete('/settings/background')
|
||||||
@limiter.limit("1/second;30/minute;200/hour;1000/day")
|
@limiter.limit("1/second;30/minute;200/hour;1000/day")
|
||||||
@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}')
|
@limiter.limit("1/second;30/minute;200/hour;1000/day", key_func=lambda:f'{SITE}-{session.get("lo_user")}')
|
||||||
@auth_required
|
def remove_background(v):
|
||||||
def removebackground(v):
|
if v.background:
|
||||||
v.background = None
|
v.background = None
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
return {"message": "Background removed!"}
|
return {"message": "Background removed!"}
|
||||||
|
|
||||||
@app.post("/settings/profile")
|
@app.post("/settings/profile")
|
||||||
|
@ -42,78 +42,68 @@ def removebackground(v):
|
||||||
def settings_profile_post(v):
|
def settings_profile_post(v):
|
||||||
updated = False
|
updated = False
|
||||||
|
|
||||||
|
def update_flag(column_name:str, request_name:str):
|
||||||
|
request_flag = request.values.get(request_name, '') == 'true'
|
||||||
|
if request_name != getattr(v, column_name):
|
||||||
|
setattr(v, column_name, request_flag)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def update_flag_with_permanence(column_name:str, request_name:str, friendly_name:str, badge_id:Optional[int]):
|
||||||
|
current_value = getattr(v, column_name)
|
||||||
|
if FEATURES['USERS_PERMANENT_WORD_FILTERS'] and current_value > 1:
|
||||||
|
abort(403, "Cannot disable the word filter after you've already set it permanently!")
|
||||||
|
request_flag = int(request.values.get(request_name, '') == 'true')
|
||||||
|
if current_value and request_flag and request.values.get("permanent", '') == 'true' and request.values.get("username") == v.username:
|
||||||
|
if v.client: abort(403, "Cannot set filters permanently from the API")
|
||||||
|
request_flag = int(time.time())
|
||||||
|
setattr(v, column_name, request_flag)
|
||||||
|
if badge_id: badge_grant(v, badge_id)
|
||||||
|
return render_template("settings_personal.html", v=v, msg=f"Set the {friendly_name} filter permanently!")
|
||||||
|
elif current_value != request_flag:
|
||||||
|
setattr(v, column_name, request_flag)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
if request.values.get("background", v.background) != v.background:
|
if request.values.get("background", v.background) != v.background:
|
||||||
updated = True
|
updated = True
|
||||||
v.background = request.values.get("background")
|
v.background = request.values.get("background")
|
||||||
|
|
||||||
elif request.values.get("reddit", v.reddit) != v.reddit:
|
elif request.values.get("reddit", v.reddit) != v.reddit:
|
||||||
reddit = request.values.get("reddit")
|
reddit = request.values.get("reddit")
|
||||||
if reddit in {'old.reddit.com', 'reddit.com', 'i.reddit.com', 'teddit.net', 'libredd.it', 'unddit.com'}:
|
if reddit in {'old.reddit.com', 'reddit.com', 'i.reddit.com', 'teddit.net', 'libredd.it', 'unddit.com'}:
|
||||||
updated = True
|
updated = True
|
||||||
v.reddit = reddit
|
v.reddit = reddit
|
||||||
|
|
||||||
elif request.values.get("slurreplacer", v.slurreplacer) != v.slurreplacer:
|
|
||||||
updated = True
|
|
||||||
v.slurreplacer = request.values.get("slurreplacer") == 'true'
|
|
||||||
|
|
||||||
elif request.values.get("profanityreplacer", v.profanityreplacer) != v.profanityreplacer:
|
|
||||||
updated = True
|
|
||||||
v.profanityreplacer = request.values.get("profanityreplacer") == 'true'
|
|
||||||
|
|
||||||
elif request.values.get("poor", v.poor) != v.poor:
|
elif request.values.get("poor", v.poor) != v.poor:
|
||||||
updated = True
|
updated = True
|
||||||
v.poor = request.values.get("poor") == 'true'
|
|
||||||
session['poor'] = v.poor
|
session['poor'] = v.poor
|
||||||
|
|
||||||
|
slur_filter_updated = updated or update_flag_with_permanence("slurfilter", "slurfilter", "slur filter", 143)
|
||||||
|
if isinstance(slur_filter_updated, bool):
|
||||||
|
updated = slur_filter_updated
|
||||||
|
else:
|
||||||
|
g.db.add(v)
|
||||||
|
return slur_filter_updated
|
||||||
|
|
||||||
|
profanity_filter_updated = updated or update_flag_with_permanence("profanityfilter", "profanityfilter", "profanity filter", 142)
|
||||||
|
if isinstance(profanity_filter_updated, bool):
|
||||||
|
updated = profanity_filter_updated
|
||||||
|
else:
|
||||||
|
g.db.add(v)
|
||||||
|
return profanity_filter_updated
|
||||||
|
|
||||||
elif request.values.get("hidevotedon", v.hidevotedon) != v.hidevotedon:
|
updated = updated or update_flag("hidevotedon", "hidevotedon")
|
||||||
updated = True
|
updated = updated or update_flag("cardview", "cardview")
|
||||||
v.hidevotedon = request.values.get("hidevotedon") == 'true'
|
updated = updated or update_flag("highlightcomments", "highlightcomments")
|
||||||
|
updated = updated or update_flag("newtab", "newtab")
|
||||||
elif request.values.get("cardview", v.cardview) != v.cardview:
|
updated = updated or update_flag("newtabexternal", "newtabexternal")
|
||||||
updated = True
|
updated = updated or update_flag("nitter", "nitter")
|
||||||
v.cardview = request.values.get("cardview") == 'true'
|
updated = updated or update_flag("imginn", "imginn")
|
||||||
|
updated = updated or update_flag("controversial", "controversial")
|
||||||
elif request.values.get("highlightcomments", v.highlightcomments) != v.highlightcomments:
|
updated = updated or update_flag("sigs_disabled", "sigs_disabled")
|
||||||
updated = True
|
updated = updated or update_flag("over_18", "over18")
|
||||||
v.highlightcomments = request.values.get("highlightcomments") == 'true'
|
updated = updated or update_flag("is_private", "private")
|
||||||
|
updated = updated or update_flag("is_nofollow", "nofollow")
|
||||||
elif request.values.get("newtab", v.newtab) != v.newtab:
|
if not updated and request.values.get("spider", v.spider) != v.spider and v.spider <= 1:
|
||||||
updated = True
|
|
||||||
v.newtab = request.values.get("newtab") == 'true'
|
|
||||||
|
|
||||||
elif request.values.get("newtabexternal", v.newtabexternal) != v.newtabexternal:
|
|
||||||
updated = True
|
|
||||||
v.newtabexternal = request.values.get("newtabexternal") == 'true'
|
|
||||||
|
|
||||||
elif request.values.get("nitter", v.nitter) != v.nitter:
|
|
||||||
updated = True
|
|
||||||
v.nitter = request.values.get("nitter") == 'true'
|
|
||||||
|
|
||||||
elif request.values.get("imginn", v.imginn) != v.imginn:
|
|
||||||
updated = True
|
|
||||||
v.imginn = request.values.get("imginn") == 'true'
|
|
||||||
|
|
||||||
elif request.values.get("controversial", v.controversial) != v.controversial:
|
|
||||||
updated = True
|
|
||||||
v.controversial = request.values.get("controversial") == 'true'
|
|
||||||
|
|
||||||
elif request.values.get("sigs_disabled", v.sigs_disabled) != v.sigs_disabled:
|
|
||||||
updated = True
|
|
||||||
v.sigs_disabled = request.values.get("sigs_disabled") == 'true'
|
|
||||||
|
|
||||||
elif request.values.get("over18", v.over_18) != v.over_18:
|
|
||||||
updated = True
|
|
||||||
v.over_18 = request.values.get("over18") == 'true'
|
|
||||||
|
|
||||||
elif request.values.get("private", v.is_private) != v.is_private:
|
|
||||||
updated = True
|
|
||||||
v.is_private = request.values.get("private") == 'true'
|
|
||||||
|
|
||||||
elif request.values.get("nofollow", v.is_nofollow) != v.is_nofollow:
|
|
||||||
updated = True
|
|
||||||
v.is_nofollow = request.values.get("nofollow") == 'true'
|
|
||||||
|
|
||||||
elif request.values.get("spider", v.spider) != v.spider and v.spider <= 1:
|
|
||||||
updated = True
|
updated = True
|
||||||
v.spider = int(request.values.get("spider") == 'true')
|
v.spider = int(request.values.get("spider") == 'true')
|
||||||
if v.spider: badge_grant(user=v, badge_id=179)
|
if v.spider: badge_grant(user=v, badge_id=179)
|
||||||
|
@ -121,35 +111,33 @@ def settings_profile_post(v):
|
||||||
badge = v.has_badge(179)
|
badge = v.has_badge(179)
|
||||||
if badge: g.db.delete(badge)
|
if badge: g.db.delete(badge)
|
||||||
|
|
||||||
elif request.values.get("bio") == "":
|
elif not updated and request.values.get("bio") == "":
|
||||||
v.bio = None
|
v.bio = None
|
||||||
v.bio_html = None
|
v.bio_html = None
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
return render_template("settings_personal.html", v=v, msg="Your bio has been updated.")
|
return render_template("settings_personal.html", v=v, msg="Your bio has been updated.")
|
||||||
|
|
||||||
elif request.values.get("sig") == "":
|
elif not updated and request.values.get("sig") == "":
|
||||||
v.sig = None
|
v.sig = None
|
||||||
v.sig_html = None
|
v.sig_html = None
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
return render_template("settings_personal.html", v=v, msg="Your sig has been updated.")
|
return render_template("settings_personal.html", v=v, msg="Your sig has been updated.")
|
||||||
|
|
||||||
elif request.values.get("friends") == "":
|
elif not updated and request.values.get("friends") == "":
|
||||||
v.friends = None
|
v.friends = None
|
||||||
v.friends_html = None
|
v.friends_html = None
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
return render_template("settings_personal.html", v=v, msg="Your friends list has been updated.")
|
return render_template("settings_personal.html", v=v, msg="Your friends list has been updated.")
|
||||||
|
|
||||||
elif request.values.get("enemies") == "":
|
elif not updated and request.values.get("enemies") == "":
|
||||||
v.enemies = None
|
v.enemies = None
|
||||||
v.enemies_html = None
|
v.enemies_html = None
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
return render_template("settings_personal.html", v=v, msg="Your enemies list has been updated.")
|
return render_template("settings_personal.html", v=v, msg="Your enemies list has been updated.")
|
||||||
|
|
||||||
elif v.patron and request.values.get("sig"):
|
elif not updated and v.patron and request.values.get("sig"):
|
||||||
sig = request.values.get("sig")[:200].replace('\n','').replace('\r','')
|
sig = request.values.get("sig")[:200].replace('\n','').replace('\r','')
|
||||||
|
|
||||||
sig_html = sanitize(sig)
|
sig_html = sanitize(sig)
|
||||||
|
|
||||||
if len(sig_html) > 1000:
|
if len(sig_html) > 1000:
|
||||||
return render_template("settings_personal.html",
|
return render_template("settings_personal.html",
|
||||||
v=v,
|
v=v,
|
||||||
|
@ -165,7 +153,7 @@ def settings_profile_post(v):
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
elif FEATURES['USERS_PROFILE_BODYTEXT'] and request.values.get("friends"):
|
elif not updated and FEATURES['USERS_PROFILE_BODYTEXT'] and request.values.get("friends"):
|
||||||
friends = request.values.get("friends")[:500]
|
friends = request.values.get("friends")[:500]
|
||||||
|
|
||||||
friends_html = sanitize(friends)
|
friends_html = sanitize(friends)
|
||||||
|
@ -191,7 +179,7 @@ def settings_profile_post(v):
|
||||||
msg="Your friends list has been updated.")
|
msg="Your friends list has been updated.")
|
||||||
|
|
||||||
|
|
||||||
elif FEATURES['USERS_PROFILE_BODYTEXT'] and request.values.get("enemies"):
|
elif not updated and FEATURES['USERS_PROFILE_BODYTEXT'] and request.values.get("enemies"):
|
||||||
enemies = request.values.get("enemies")[:500]
|
enemies = request.values.get("enemies")[:500]
|
||||||
|
|
||||||
enemies_html = sanitize(enemies)
|
enemies_html = sanitize(enemies)
|
||||||
|
@ -217,7 +205,7 @@ def settings_profile_post(v):
|
||||||
msg="Your enemies list has been updated.")
|
msg="Your enemies list has been updated.")
|
||||||
|
|
||||||
|
|
||||||
elif FEATURES['USERS_PROFILE_BODYTEXT'] and \
|
elif not updated and FEATURES['USERS_PROFILE_BODYTEXT'] and \
|
||||||
(request.values.get("bio") or request.files.get('file')):
|
(request.values.get("bio") or request.files.get('file')):
|
||||||
bio = request.values.get("bio")[:1500]
|
bio = request.values.get("bio")[:1500]
|
||||||
|
|
||||||
|
@ -244,7 +232,7 @@ def settings_profile_post(v):
|
||||||
|
|
||||||
frontsize = request.values.get("frontsize")
|
frontsize = request.values.get("frontsize")
|
||||||
if frontsize:
|
if frontsize:
|
||||||
if frontsize in {"15", "25", "50", "100"}:
|
if frontsize in PAGE_SIZES:
|
||||||
v.frontsize = int(frontsize)
|
v.frontsize = int(frontsize)
|
||||||
updated = True
|
updated = True
|
||||||
cache.delete_memoized(frontlist)
|
cache.delete_memoized(frontlist)
|
||||||
|
@ -252,37 +240,37 @@ def settings_profile_post(v):
|
||||||
|
|
||||||
defaultsortingcomments = request.values.get("defaultsortingcomments")
|
defaultsortingcomments = request.values.get("defaultsortingcomments")
|
||||||
if defaultsortingcomments:
|
if defaultsortingcomments:
|
||||||
if defaultsortingcomments in {"new", "old", "controversial", "top", "hot", "bottom"}:
|
if defaultsortingcomments in COMMENT_SORTS:
|
||||||
v.defaultsortingcomments = defaultsortingcomments
|
v.defaultsortingcomments = defaultsortingcomments
|
||||||
updated = True
|
updated = True
|
||||||
else: abort(400)
|
else: abort(400, f"{defaultsortingcomments} is not a valid comment sort")
|
||||||
|
|
||||||
defaultsorting = request.values.get("defaultsorting")
|
defaultsorting = request.values.get("defaultsorting")
|
||||||
if defaultsorting:
|
if defaultsorting:
|
||||||
if defaultsorting in {"hot", "bump", "new", "old", "comments", "controversial", "top", "bottom"}:
|
if defaultsorting in SORTS:
|
||||||
v.defaultsorting = defaultsorting
|
v.defaultsorting = defaultsorting
|
||||||
updated = True
|
updated = True
|
||||||
else: abort(400)
|
else: abort(400, f"{defaultsorting} is not a valid post sort")
|
||||||
|
|
||||||
defaulttime = request.values.get("defaulttime")
|
defaulttime = request.values.get("defaulttime")
|
||||||
if defaulttime:
|
if defaulttime:
|
||||||
if defaulttime in {"hour", "day", "week", "month", "year", "all"}:
|
if defaulttime in TIME_FILTERS:
|
||||||
v.defaulttime = defaulttime
|
v.defaulttime = defaulttime
|
||||||
updated = True
|
updated = True
|
||||||
else: abort(400)
|
else: abort(400, f"{defaulttime} is not a valid time filter")
|
||||||
|
|
||||||
theme = request.values.get("theme")
|
theme = request.values.get("theme")
|
||||||
if theme:
|
if theme:
|
||||||
if theme in {"4chan","classic","classic_dark","coffee","dark","dramblr","light","midnight","transparent","tron","win98"}:
|
if theme in THEMES:
|
||||||
if theme == "transparent" and not v.background:
|
if theme == "transparent" and not v.background:
|
||||||
abort(400, "You need to set a background to use the transparent theme!")
|
abort(409, "You need to set a background to use the transparent theme")
|
||||||
v.theme = theme
|
v.theme = theme
|
||||||
if theme == "win98": v.themecolor = "30409f"
|
if theme == "win98": v.themecolor = "30409f"
|
||||||
updated = True
|
updated = True
|
||||||
else: abort(400)
|
else: abort(400, f"{theme} is not a valid theme")
|
||||||
|
|
||||||
house = request.values.get("house")
|
house = request.values.get("house")
|
||||||
if house and house in ("None","Furry","Femboy","Vampire","Racist") and FEATURES['HOUSES']:
|
if house and house in HOUSES and FEATURES['HOUSES']:
|
||||||
if v.bite: abort(403)
|
if v.bite: abort(403)
|
||||||
if v.house:
|
if v.house:
|
||||||
if v.house.replace(' Founder', '') == house: abort(409, f"You're already in House {house}")
|
if v.house.replace(' Founder', '') == house: abort(409, f"You're already in House {house}")
|
||||||
|
@ -306,7 +294,6 @@ def settings_profile_post(v):
|
||||||
if updated:
|
if updated:
|
||||||
g.db.add(v)
|
g.db.add(v)
|
||||||
return {"message": "Your settings have been updated."}
|
return {"message": "Your settings have been updated."}
|
||||||
|
|
||||||
else:
|
else:
|
||||||
abort(400, "You didn't change anything.")
|
abort(400, "You didn't change anything.")
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
</div>
|
</div>
|
||||||
{% if v.background %}
|
{% if v.background %}
|
||||||
<div class="d-flex mt-2">
|
<div class="d-flex mt-2">
|
||||||
<button type="button" class="btn btn-primary ml-auto mb-1" onclick="postToastReload(this,'/settings/removebackground')">Remove Background</button>
|
<button type="button" class="btn btn-primary ml-auto mb-1" onclick="postToastReload(this,'/settings/background', 'DELETE')">Remove Background</button>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div id="bgcontainer"></div>
|
<div id="bgcontainer"></div>
|
||||||
|
|
Loading…
Reference in New Issue