forked from MarseyWorld/MarseyWorld
allow multiple sidebar images in holes
parent
415b245630
commit
078933f17d
|
@ -18,7 +18,7 @@ class Hole(Base):
|
|||
name = Column(VARCHAR(HOLE_NAME_COLUMN_LENGTH), primary_key=True)
|
||||
sidebar = Column(VARCHAR(HOLE_SIDEBAR_COLUMN_LENGTH))
|
||||
sidebar_html = Column(VARCHAR(HOLE_SIDEBAR_HTML_COLUMN_LENGTH))
|
||||
sidebarurl = Column(VARCHAR(HOLE_SIDEBAR_URL_COLUMN_LENGTH))
|
||||
sidebarurls = Column(MutableList.as_mutable(ARRAY(VARCHAR(HOLE_BANNER_URL_COLUMN_LENGTH))), default=MutableList([]), nullable=False)
|
||||
bannerurls = Column(MutableList.as_mutable(ARRAY(VARCHAR(HOLE_BANNER_URL_COLUMN_LENGTH))), default=MutableList([]), nullable=False)
|
||||
marseyurl = Column(VARCHAR(HOLE_MARSEY_URL_LENGTH))
|
||||
css = Column(VARCHAR(HOLE_CSS_COLUMN_LENGTH))
|
||||
|
@ -38,9 +38,9 @@ class Hole(Base):
|
|||
|
||||
@property
|
||||
@lazy
|
||||
def sidebar_url(self):
|
||||
if self.sidebarurl: return self.sidebarurl
|
||||
return f'{SITE_FULL_IMAGES}/i/{SITE_NAME}/sidebar.webp?x=6'
|
||||
def random_sidebar(self):
|
||||
if not self.sidebarurls: return None
|
||||
return random.choice(self.sidebarurls)
|
||||
|
||||
@property
|
||||
@lazy
|
||||
|
|
|
@ -511,6 +511,94 @@ def get_hole_css(hole):
|
|||
resp.headers.add("Content-Type", "text/css")
|
||||
return resp
|
||||
|
||||
@app.post("/h/<hole>/settings/sidebars/")
|
||||
@limiter.limit('1/second', scope=rpath)
|
||||
@limiter.limit('1/second', scope=rpath, key_func=get_ID)
|
||||
@limiter.limit("50/day", deduct_when=lambda response: response.status_code < 400)
|
||||
@limiter.limit("50/day", deduct_when=lambda response: response.status_code < 400, key_func=get_ID)
|
||||
@auth_required
|
||||
def upload_hole_sidebar(v, hole):
|
||||
if g.is_tor: abort(403, "Image uploads are not allowed through Tor")
|
||||
|
||||
hole = get_hole(hole)
|
||||
if not v.mods(hole.name): abort(403)
|
||||
if v.shadowbanned: abort(500)
|
||||
|
||||
file = request.files["sidebar"]
|
||||
|
||||
name = f'/images/{time.time()}'.replace('.','') + '.webp'
|
||||
file.save(name)
|
||||
sidebarurl = process_image(name, v, resize=1600)
|
||||
|
||||
hole.sidebarurls.append(sidebarurl)
|
||||
|
||||
g.db.add(hole)
|
||||
|
||||
ma = HoleAction(
|
||||
hole=hole.name,
|
||||
kind='upload_sidebar',
|
||||
user_id=v.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
return redirect(f'/h/{hole}/settings')
|
||||
|
||||
@app.post("/h/<hole>/settings/sidebars/delete/<int:index>")
|
||||
@limiter.limit("1/second;30/day", deduct_when=lambda response: response.status_code < 400)
|
||||
@limiter.limit("1/second;30/day", deduct_when=lambda response: response.status_code < 400, key_func=get_ID)
|
||||
@auth_required
|
||||
def delete_hole_sidebar(v, hole, index):
|
||||
hole = get_hole(hole)
|
||||
if not v.mods(hole.name): abort(403)
|
||||
|
||||
if not hole.sidebarurls:
|
||||
abort(404, f"Sidebar image not found (/h/{hole.name} has no sidebar images)")
|
||||
if index < 0 or index >= len(hole.sidebarurls):
|
||||
abort(404, f'Sidebar image not found (sidebar index {index} is not between 0 and {len(hole.sidebarurls)})')
|
||||
sidebar = hole.sidebarurls[index]
|
||||
try:
|
||||
remove_media_using_link(sidebar)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
del hole.sidebarurls[index]
|
||||
g.db.add(hole)
|
||||
|
||||
ma = HoleAction(
|
||||
hole=hole.name,
|
||||
kind='delete_sidebar',
|
||||
_note=index,
|
||||
user_id=v.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
return {"message": f"Deleted sidebar {index} from /h/{hole} successfully"}
|
||||
|
||||
@app.post("/h/<hole>/settings/sidebars/delete_all")
|
||||
@limiter.limit("1/10 second;30/day", deduct_when=lambda response: response.status_code < 400)
|
||||
@limiter.limit("1/10 second;30/day", deduct_when=lambda response: response.status_code < 400, key_func=get_ID)
|
||||
@auth_required
|
||||
def delete_all_hole_sidebars(v, hole):
|
||||
hole = get_hole(hole)
|
||||
if not v.mods(hole.name): abort(403)
|
||||
|
||||
for sidebar in hole.sidebarurls:
|
||||
try:
|
||||
remove_media_using_link(sidebar)
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
hole.sidebarurls = []
|
||||
g.db.add(hole)
|
||||
|
||||
ma = HoleAction(
|
||||
hole=hole.name,
|
||||
kind='delete_sidebar',
|
||||
_note='all',
|
||||
user_id=v.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
return {"message": f"Deleted all sidebar images from /h/{hole} successfully"}
|
||||
|
||||
@app.post("/h/<hole>/settings/banners/")
|
||||
@limiter.limit('1/second', scope=rpath)
|
||||
@limiter.limit('1/second', scope=rpath, key_func=get_ID)
|
||||
|
@ -599,39 +687,6 @@ def delete_all_hole_banners(v, hole):
|
|||
|
||||
return {"message": f"Deleted all banners from /h/{hole} successfully"}
|
||||
|
||||
@app.post("/h/<hole>/sidebar_image")
|
||||
@limiter.limit('1/second', scope=rpath)
|
||||
@limiter.limit('1/second', scope=rpath, key_func=get_ID)
|
||||
@limiter.limit("10/day", deduct_when=lambda response: response.status_code < 400)
|
||||
@limiter.limit("10/day", deduct_when=lambda response: response.status_code < 400, key_func=get_ID)
|
||||
@auth_required
|
||||
def hole_sidebar(v, hole):
|
||||
if g.is_tor: abort(403, "Image uploads are not allowed through TOR!")
|
||||
|
||||
hole = get_hole(hole)
|
||||
if not v.mods(hole.name): abort(403)
|
||||
if v.shadowbanned: abort(500)
|
||||
|
||||
file = request.files["sidebar"]
|
||||
name = f'/images/{time.time()}'.replace('.','') + '.webp'
|
||||
file.save(name)
|
||||
sidebarurl = process_image(name, v, resize=400)
|
||||
|
||||
if sidebarurl:
|
||||
if hole.sidebarurl:
|
||||
remove_media_using_link(hole.sidebarurl)
|
||||
hole.sidebarurl = sidebarurl
|
||||
g.db.add(hole)
|
||||
|
||||
ma = HoleAction(
|
||||
hole=hole.name,
|
||||
kind='change_sidebar_image',
|
||||
user_id=v.id
|
||||
)
|
||||
g.db.add(ma)
|
||||
|
||||
return redirect(f'/h/{hole}/settings')
|
||||
|
||||
@app.post("/h/<hole>/marsey_image")
|
||||
@limiter.limit('1/second', scope=rpath)
|
||||
@limiter.limit('1/second', scope=rpath, key_func=get_ID)
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
</span>
|
||||
</div>
|
||||
|
||||
<h5 class="mt-5">Marsey</h5>
|
||||
<h5 class="mt-5 pt-5">Marsey</h5>
|
||||
<div class="settings-section rounded">
|
||||
<img loading="lazy" alt="sub marsey picture" src="{{hole.marsey_url}}" style="max-width:100px">
|
||||
<form class="d-inline-block" action="/h/{{hole}}/marsey_image" method="post" enctype="multipart/form-data">
|
||||
|
@ -29,21 +29,35 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<h5 class=" mt-5">Sidebar Picture</h5>
|
||||
<div class="settings-section rounded">
|
||||
<img class="mr-3" loading="lazy" alt="sub sidebar picture" src="{{hole.sidebar_url}}" style="max-width:min(300px,100%)">
|
||||
<form class="d-inline-block mt-2" action="/h/{{hole}}/sidebar_image" method="post" enctype="multipart/form-data">
|
||||
<input hidden name="formkey" value="{{v|formkey}}">
|
||||
<label class="btn btn-secondary text-capitalize mr-2 mb-0">
|
||||
Upload<input autocomplete="off" type="file" accept="image/*" {% if g.is_tor %}disabled{% endif %} hidden name="sidebar" data-nonce="{{g.nonce}}" onchange_submit>
|
||||
</label>
|
||||
</form>
|
||||
<div class="text-small text-muted mt-3">
|
||||
All image files are supported. Max file size is {% if v and v.patron %}16{% else %}8{% endif %} MB.
|
||||
</div>
|
||||
<h5 class="mt-5 pt-5">Sidebar Images</h5>
|
||||
<div class="settings-section rounded hole-sidebar-update-section">
|
||||
{% for sidebar in hole.sidebarurls %}
|
||||
<section id="hole-sidebar-update-{{loop.index - 1}}" class="mt-5 d-block hole-settings-subsection" style="max-width:min(300px,100%)">
|
||||
<img class="mr-3" loading="lazy" alt="/h/{{hole.name}} sidebar" src="{{sidebar}}" style="max-height:300px;max-width:100%">
|
||||
<button class="btn btn-danger hole-sidebar-delete-button mt-2" id="hole-sidebar-delete-{{loop.index}}" data-nonce="{{g.nonce}}" data-onclick="areyousure(this)" data-areyousure="postToastReload(this, '/h/{{hole.name}}/settings/sidebars/delete/{{loop.index - 1}}')">Delete</button>
|
||||
</section>
|
||||
{% else %}
|
||||
<section id="hole-sidebar-no-sidebars" class="d-block hole-settings-subsection" style="max-width:min(300px,100%)">
|
||||
{{macros.ghost_box("No sidebar images uploaded", "", 2, "flex:1")}}
|
||||
</section>
|
||||
{% endfor %}
|
||||
{% if not g.is_tor %}
|
||||
<section id="hole-sidebar-upload-new" class="mt-5 hole-settings-subsection">
|
||||
<form class="d-inline-block" action="/h/{{hole.name}}/settings/sidebars/" method="post" enctype="multipart/form-data">
|
||||
<input hidden name="formkey" value="{{v|formkey}}">
|
||||
<label class="btn btn-secondary text-capitalize mr-2 mb-0">
|
||||
Upload New Sidebar Image<input autocomplete="off" type="file" accept="image/*" hidden name="sidebar" data-nonce="{{g.nonce}}" onchange_submit>
|
||||
</label>
|
||||
</form>
|
||||
<button type="button" class="btn btn-danger hole-sidebar-delete-button" id="hole-sidebar-delete-all" data-nonce="{{g.nonce}}" data-onclick="areyousure(this)" data-areyousure="postToastReload(this, '/h/{{hole.name}}/settings/sidebars/delete_all')">Delete All Sidebar Images</button>
|
||||
<div class="text-small text-muted mt-3">
|
||||
All image files are supported. Max file size is {% if v and v.patron %}16{% else %}8{% endif %} MB.
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<h5 class="mt-5">Banners</h5>
|
||||
<h5 class="mt-5 pt-5">Banners</h5>
|
||||
<div class="settings-section rounded hole-banner-update-section">
|
||||
{% for banner in hole.bannerurls %}
|
||||
<section id="hole-banner-update-{{loop.index - 1}}" class="mt-5 d-block hole-settings-subsection">
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
{% block pagetitle %}{{SITE_NAME if not hole else '/h/' ~ hole.name}}{% endblock %}
|
||||
|
||||
{% block head_final %}
|
||||
{% set preview = hole.siderbarurl if hole and hole.sidebarurl else hole.bannerurl %}
|
||||
{% set preview = hole.random_sidebar if hole and hole.sidebarurls else hole.bannerurl %}
|
||||
|
||||
{% if hole %}
|
||||
<meta property="og:type" content="article">
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
</h5>
|
||||
</a>
|
||||
|
||||
{% if hole %}
|
||||
{% set image = hole.sidebar_url %}
|
||||
{% if hole and hole.sidebarurls %}
|
||||
{% set image = hole.random_sidebar %}
|
||||
{% elif IS_EVENT() %}
|
||||
{% set image = macros.random_image("assets/events/" ~ IS_EVENT() ~ "/images/sidebar") %}
|
||||
{% else %}
|
||||
|
@ -15,7 +15,7 @@
|
|||
{% endif %}
|
||||
|
||||
{% if request.path != '/sidebar' %}
|
||||
{% if not (hole and hole.sidebarurl) and (IS_FISTMAS() or IS_HOMOWEEN()) %}
|
||||
{% if not (hole and hole.sidebarurls) and (IS_FISTMAS() or IS_HOMOWEEN()) %}
|
||||
{% include "events/shared/eye_tracking.html" %}
|
||||
{% elif v and (v.is_banned or v.chud) %}
|
||||
<a href="{{SITE_FULL_IMAGES}}/i/{{SITE_NAME}}/sidebar2.webp">
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
alter table holes add column sidebarurls character varying(60)[] default '{}'::character varying[] not null;
|
||||
update holes set sidebarurls = array_append(sidebarurls, sidebarurl) WHERE sidebarurl is not null;
|
||||
alter table holes drop column sidebarurl;
|
Loading…
Reference in New Issue