large commit: stealth mode, SubJoin, chudtopia
dont read if u value ur sanityremotes/1693045480750635534/spooky-22
parent
19c38b9730
commit
9e5ddcbd92
|
@ -744,8 +744,6 @@ input[type=submit].btn-block, input[type=reset].btn-block, input[type=button].bt
|
|||
.btn-follow {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
.btn-follow + .btn-follow {
|
||||
margin-top: 0.5rem;
|
||||
}
|
||||
input[type=submit].btn-follow, input[type=reset].btn-follow, input[type=button].btn-follow {
|
||||
|
@ -6243,4 +6241,8 @@ g {
|
|||
.desktop-expanded-image-modal::-webkit-scrollbar {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.text-stealth {
|
||||
color: #a4f5f3 !important;
|
||||
}
|
|
@ -17,8 +17,9 @@ from .award import *
|
|||
from .marsey import *
|
||||
from .sub_block import *
|
||||
from .sub_subscription import *
|
||||
from .sub_join import *
|
||||
from .saves import *
|
||||
from .views import *
|
||||
from .notifications import *
|
||||
from .follows import *
|
||||
from .lottery import *
|
||||
from .lottery import *
|
|
@ -19,6 +19,7 @@ class Sub(Base):
|
|||
sidebarurl = Column(String)
|
||||
bannerurl = Column(String)
|
||||
css = Column(String)
|
||||
stealth = Column(Boolean)
|
||||
|
||||
blocks = relationship("SubBlock", primaryjoin="SubBlock.sub==Sub.name")
|
||||
followers = relationship("SubSubscription", primaryjoin="SubSubscription.sub==Sub.name")
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
from sqlalchemy import *
|
||||
from files.__main__ import Base
|
||||
|
||||
class SubJoin(Base):
|
||||
__tablename__ = "sub_joins"
|
||||
user_id = Column(Integer, ForeignKey("users.id"), primary_key=True)
|
||||
sub = Column(String(20), ForeignKey("subs.name"), primary_key=True)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<SubJoin(user_id={self.user_id}, sub={self.sub})>"
|
|
@ -19,6 +19,7 @@ from .mod import *
|
|||
from .exiles import *
|
||||
from .sub_block import *
|
||||
from .sub_subscription import *
|
||||
from .sub_join import *
|
||||
from files.__main__ import Base, cache
|
||||
from files.helpers.security import *
|
||||
from copy import deepcopy
|
||||
|
@ -173,12 +174,18 @@ class User(Base):
|
|||
@property
|
||||
@lazy
|
||||
def all_blocks(self):
|
||||
return ['smuggies','braincels'] + [x[0] for x in g.db.query(SubBlock.sub).filter_by(user_id=self.id).all()]
|
||||
stealth = set([x[0] for x in g.db.query(Sub.name).filter_by(stealth=True).all()]) - set([x[0] for x in g.db.query(SubJoin.sub).filter_by(user_id=self.id).all()])
|
||||
|
||||
return list(stealth) + [x[0] for x in g.db.query(SubBlock.sub).filter_by(user_id=self.id).all()]
|
||||
|
||||
@lazy
|
||||
def blocks(self, sub):
|
||||
return g.db.query(SubBlock).filter_by(user_id=self.id, sub=sub).one_or_none()
|
||||
|
||||
@lazy
|
||||
def subscribes(self, sub):
|
||||
return g.db.query(SubJoin).filter_by(user_id=self.id, sub=sub).one_or_none()
|
||||
|
||||
@property
|
||||
@lazy
|
||||
def all_follows(self):
|
||||
|
|
|
@ -27,7 +27,10 @@ def front_all(v, sub=None, subdomain=None):
|
|||
if not redir.startswith('/'): redir = f'/{redir}'
|
||||
return redirect(redir)
|
||||
|
||||
if sub: sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
if sub:
|
||||
sub = sub.strip().lower()
|
||||
if sub == 'chudtopia' and not (v and v.truecoins >= 20000): abort(403)
|
||||
sub = g.db.query(Sub).filter_by(name=sub).one_or_none()
|
||||
|
||||
if (request.path.startswith('/h/') or request.path.startswith('/s/')) and not sub: abort(404)
|
||||
|
||||
|
|
|
@ -1074,7 +1074,7 @@ def submit_post(v, sub=None):
|
|||
post.downvotes += 1
|
||||
g.db.add(post)
|
||||
|
||||
if SITE == 'rdrama.net' and post.sub and post.sub not in ('dankchristianmemes','fatpeoplehate','braincels','truth','smuggies') and v.id != AEVANN_ID:
|
||||
if SITE == 'rdrama.net' and post.sub and post.sub not in ('dankchristianmemes','fatpeoplehate','braincels','truth','smuggies','chudtopia') and v.id != AEVANN_ID:
|
||||
g.db.flush()
|
||||
autovote = Vote(
|
||||
user_id=AEVANN_ID,
|
||||
|
|
|
@ -95,8 +95,6 @@ def block_sub(v, sub):
|
|||
if not sub: abort(404)
|
||||
sub = sub.name
|
||||
|
||||
if v.mods(sub): return {"error": f"You can't block {HOLE_NAME}s you mod!"}
|
||||
|
||||
existing = g.db.query(SubBlock).filter_by(user_id=v.id, sub=sub).one_or_none()
|
||||
|
||||
if not existing:
|
||||
|
@ -104,7 +102,7 @@ def block_sub(v, sub):
|
|||
g.db.add(block)
|
||||
cache.delete_memoized(frontlist)
|
||||
|
||||
return {"message": f"{HOLE_NAME.capitalize()} blocked successfully!"}
|
||||
return {"message": "Action successful!"}
|
||||
|
||||
|
||||
@app.post("/h/<sub>/unblock")
|
||||
|
@ -120,7 +118,39 @@ def unblock_sub(v, sub):
|
|||
g.db.delete(block)
|
||||
cache.delete_memoized(frontlist)
|
||||
|
||||
return {"message": f"{HOLE_NAME.capitalize()} unblocked successfully!"}
|
||||
return {"message": "Action successful!"}
|
||||
|
||||
|
||||
@app.post("/h/<sub>/subscribe")
|
||||
@auth_required
|
||||
def subscribe_sub(v, sub):
|
||||
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
if not sub: abort(404)
|
||||
sub = sub.name
|
||||
|
||||
existing = g.db.query(SubJoin).filter_by(user_id=v.id, sub=sub).one_or_none()
|
||||
|
||||
if not existing:
|
||||
subscribe = SubJoin(user_id=v.id, sub=sub)
|
||||
g.db.add(subscribe)
|
||||
cache.delete_memoized(frontlist)
|
||||
|
||||
return {"message": "Action successful!"}
|
||||
|
||||
@app.post("/h/<sub>/unsubscribe")
|
||||
@auth_required
|
||||
def unsubscribe_sub(v, sub):
|
||||
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
if not sub: abort(404)
|
||||
sub = sub.name
|
||||
|
||||
subscribe = g.db.query(SubJoin).filter_by(user_id=v.id, sub=sub).one_or_none()
|
||||
|
||||
if subscribe:
|
||||
g.db.delete(subscribe)
|
||||
cache.delete_memoized(frontlist)
|
||||
|
||||
return {"message": "Action successful!"}
|
||||
|
||||
@app.post("/h/<sub>/follow")
|
||||
@auth_required
|
||||
|
@ -128,13 +158,14 @@ def follow_sub(v, sub):
|
|||
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
if not sub: abort(404)
|
||||
|
||||
existing = g.db.query(SubSubscription) \
|
||||
.filter_by(user_id=v.id, sub=sub.name).one_or_none()
|
||||
existing = g.db.query(SubSubscription).filter_by(user_id=v.id, sub=sub.name).one_or_none()
|
||||
|
||||
if not existing:
|
||||
subscription = SubSubscription(user_id=v.id, sub=sub.name)
|
||||
g.db.add(subscription)
|
||||
cache.delete_memoized(frontlist)
|
||||
|
||||
return {"message": f"{HOLE_NAME.capitalize()} followed successfully!"}
|
||||
return {"message": f"Action successful!"}
|
||||
|
||||
@app.post("/h/<sub>/unfollow")
|
||||
@auth_required
|
||||
|
@ -142,12 +173,13 @@ def unfollow_sub(v, sub):
|
|||
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
if not sub: abort(404)
|
||||
|
||||
subscription = g.db.query(SubSubscription) \
|
||||
.filter_by(user_id=v.id, sub=sub.name).one_or_none()
|
||||
subscription = g.db.query(SubSubscription).filter_by(user_id=v.id, sub=sub.name).one_or_none()
|
||||
|
||||
if subscription:
|
||||
g.db.delete(subscription)
|
||||
cache.delete_memoized(frontlist)
|
||||
|
||||
return {"message": f"{HOLE_NAME.capitalize()} unfollowed successfully!"}
|
||||
return {"message": f"Action successful!"}
|
||||
|
||||
@app.get("/h/<sub>/mods")
|
||||
@auth_required
|
||||
|
@ -291,6 +323,7 @@ def create_sub2(v):
|
|||
|
||||
sub = Sub(name=name)
|
||||
g.db.add(sub)
|
||||
g.db.flush()
|
||||
mod = Mod(user_id=v.id, sub=sub.name)
|
||||
g.db.add(mod)
|
||||
|
||||
|
@ -476,4 +509,23 @@ def hole_unpin(v, pid):
|
|||
message = f"@{v.username} (Mod) has unpinned your [post]({p.shortlink}) in /h/{p.sub}"
|
||||
send_repeatable_notification(p.author_id, message)
|
||||
|
||||
return {"message": f"Post unpinned from /h/{p.sub}"}
|
||||
return {"message": f"Post unpinned from /h/{p.sub}"}
|
||||
|
||||
|
||||
@app.post('/h/<sub>/stealth')
|
||||
@is_not_permabanned
|
||||
def sub_stealth(v, sub):
|
||||
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
|
||||
if not sub: abort(404)
|
||||
|
||||
if not v.mods(sub.name): abort(403)
|
||||
|
||||
sub.stealth = not sub.stealth
|
||||
g.db.add(sub)
|
||||
|
||||
cache.delete_memoized(frontlist)
|
||||
|
||||
if sub.stealth:
|
||||
return {"message": f"Stealth mode enabled!"}
|
||||
else:
|
||||
return {"message": f"Stealth mode disabled!"}
|
|
@ -90,7 +90,7 @@
|
|||
{% if render_replies %}
|
||||
{% if level<9 or request.path.startswith('/notifications') or request.headers.get("xhr") %}
|
||||
<div id="replies-of-{{c.fullname}}">
|
||||
{% for reply in replies %}
|
||||
{% for reply in replies if not reply.parent_submission or reply.post.sub != 'chudtopia' or (v and v.truecoins >= 20000) %}
|
||||
{{single_comment(reply, level=level+1)}}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
@ -601,7 +601,7 @@
|
|||
{% if render_replies %}
|
||||
{% if level<9 or request.path.startswith('/notifications') or request.headers.get("xhr") %}
|
||||
<div id="replies-of-{{c.fullname}}">
|
||||
{% for reply in replies %}
|
||||
{% for reply in replies if not reply.parent_submission or reply.post.sub != 'chudtopia' or (v and v.truecoins >= 20000) %}
|
||||
{{single_comment(reply, level=level+1)}}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
@ -785,7 +785,7 @@
|
|||
|
||||
{% endmacro %}
|
||||
|
||||
{% for comment in comments %}
|
||||
{% for comment in comments if not comment.parent_submission or comment.post.sub != 'chudtopia' or (v and v.truecoins >= 20000) %}
|
||||
|
||||
{{single_comment(comment)}}
|
||||
|
||||
|
|
|
@ -52,14 +52,20 @@
|
|||
<div class="mt-3">
|
||||
{% if v %}
|
||||
{%- set hole_prefix = '/h/' if not HOLE_STYLE_FLAIR else '' -%}
|
||||
<a class="btn btn-primary btn-follow {% if v.follows(sub.name) %}d-none{% endif %}" onclick="post_toast(this,'/h/{{sub.name}}/follow','follow-sub','unfollow-sub');this.classList.toggle('d-none');nextElementSibling.classList.toggle('d-none')"><i class="fas fa-bell mr-1"></i> Follow {{hole_prefix}}{{sub.name}}</a>
|
||||
<a class="btn btn-primary btn-follow {% if not v.follows(sub.name) %}d-none{% endif %}" onclick="post_toast(this,'/h/{{sub.name}}/unfollow','follow-sub','unfollow-sub');this.classList.toggle('d-none');previousElementSibling.classList.toggle('d-none')"><i class="fas fa-bell-slash mr-1"></i> Unfollow {{hole_prefix}}{{sub.name}}</a>
|
||||
|
||||
<a class="btn btn-primary btn-block mt-3 {% if v.blocks(sub.name) %}d-none{% endif %}" onclick="post_toast(this,'/h/{{sub.name}}/block','block-sub','unblock-sub');this.classList.toggle('d-none');nextElementSibling.classList.toggle('d-none')"><i class="fas fa-eye-slash mr-2"></i>Block {{hole_prefix}}{{sub.name}}</a>
|
||||
<a class="btn btn-primary btn-block mt-3 {% if not v.blocks(sub.name) %}d-none{% endif %}" onclick="post_toast(this,'/h/{{sub.name}}/unblock','block-sub','unblock-sub');this.classList.toggle('d-none');previousElementSibling.classList.toggle('d-none')"><i class="fas fa-eye mr-2"></i>Unblock {{hole_prefix}}{{sub.name}}</a>
|
||||
{% if sub.stealth %}
|
||||
<a id="subscribe-sub" class="btn btn-primary btn-block mt-3 {% if v.subscribes(sub.name) %}d-none{% endif %}" onclick="post_toast(this,'/h/{{sub.name}}/subscribe','subscribe-sub','unsubscribe-sub','d-none')"><i class="fas fa-eye mr-2"></i>Show posts in main feed</a>
|
||||
<a id="unsubscribe-sub" class="btn btn-primary btn-block mt-3 {% if not v.subscribes(sub.name) %}d-none{% endif %}" onclick="post_toast(this,'/h/{{sub.name}}/unsubscribe','subscribe-sub','unsubscribe-sub','d-none')"><i class="fas fa-eye-slash mr-2"></i>Hide posts from main feed</a>
|
||||
{% else %}
|
||||
<a id="block-sub" class="btn btn-primary btn-block mt-3 {% if v.blocks(sub.name) %}d-none{% endif %}" onclick="post_toast(this,'/h/{{sub.name}}/block','block-sub','unblock-sub','d-none')"><i class="fas fa-eye-slash mr-2"></i>Hide posts from main feed</a>
|
||||
<a id="unblock-sub" class="btn btn-primary btn-block mt-3 {% if not v.blocks(sub.name) %}d-none{% endif %}" onclick="post_toast(this,'/h/{{sub.name}}/unblock','block-sub','unblock-sub','d-none')"><i class="fas fa-eye mr-2"></i>Show posts in main feed</a>
|
||||
{% endif %}
|
||||
|
||||
<a id="follow-sub" class="btn btn-primary btn-follow {% if v.follows(sub.name) %}d-none{% endif %}" onclick="post_toast(this,'/h/{{sub.name}}/follow','follow-sub','unfollow-sub','d-none')"><i class="fas fa-bell mr-2"></i>Notify me of new posts</a>
|
||||
<a id="unfollow-sub" class="btn btn-primary btn-follow {% if not v.follows(sub.name) %}d-none{% endif %}" onclick="post_toast(this,'/h/{{sub.name}}/unfollow','follow-sub','unfollow-sub','d-none')"><i class="fas fa-bell-slash mr-2"></i>Don't notify me of new posts</a>
|
||||
{% else %}
|
||||
<a class="btn btn-primary btn-block" href="/login"><i class="fas fa-bell mr-1"></i>Follow {{hole_prefix}}{{sub.name}}</a>
|
||||
<a class="btn btn-primary btn-block mt-3" href="/login"><i class="fas fa-eye-slash mr-2"></i>Block {{hole_prefix}}{{sub.name}}</a>
|
||||
<a class="btn btn-primary btn-block mt-3" href="/login"><i class="fas fa-eye-slash mr-2"></i>Hide posts from main feed</a>
|
||||
<a class="btn btn-primary btn-block" href="/login"><i class="fas fa-bell mr-2"></i>Notify me of new posts</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
{% endif %}
|
||||
<a class="btn btn-primary btn-block" href="/h/{{sub.name}}/mods">{{HOLE_NAME|upper}} MODS</a>
|
||||
<a class="btn btn-primary btn-block" href="/h/{{sub.name}}/exilees">{{HOLE_NAME|upper}} EXILEES</a>
|
||||
<a class="btn btn-primary btn-block" href="/h/{{sub.name}}/followers">{{HOLE_NAME|upper}} FOLLOWERS</a>
|
||||
<a class="btn btn-primary btn-block" href="/h/{{sub.name}}/blockers">{{HOLE_NAME|upper}} BLOCKERS</a>
|
||||
{% endif %}
|
||||
|
||||
{% if v and v.can_create_hole -%}
|
||||
|
|
|
@ -17,14 +17,8 @@
|
|||
<a class="sidebar-link" href="/random_post" data-bs-toggle="tooltip" data-bs-placement="top" title="Random Post"><i class="fas fa-random"></i></a>
|
||||
</p>
|
||||
|
||||
{% if sub %}
|
||||
{% if sub.sidebar_html %}
|
||||
<div class="mb-4">{{sub.sidebar_html|safe}}</div>
|
||||
{% endif %}
|
||||
{% if v and v.mods(sub.name) %}
|
||||
<a class="btn btn-primary btn-block mb-3" href="/h/{{sub.name}}/followers">{{HOLE_NAME|upper}} FOLLOWERS</a>
|
||||
<a class="btn btn-primary btn-block mb-3" href="/h/{{sub.name}}/blockers">{{HOLE_NAME|upper}} BLOCKERS</a>
|
||||
{% endif %}
|
||||
{% if sub and sub.sidebar_html %}
|
||||
<div class="mb-4">{{sub.sidebar_html|safe}}</div>
|
||||
{% endif %}
|
||||
|
||||
<div id="sidebar-wpd--flairs">
|
||||
|
|
|
@ -43,8 +43,6 @@
|
|||
{% endif %}
|
||||
<a class="btn btn-primary btn-block mb-3" href="/h/{{sub.name}}/mods">{{HOLE_NAME|upper}} MODS</a>
|
||||
<a class="btn btn-primary btn-block mb-3" href="/h/{{sub.name}}/exilees">{{HOLE_NAME|upper}} EXILEES</a>
|
||||
<a class="btn btn-primary btn-block mb-3" href="/h/{{sub.name}}/followers">{{HOLE_NAME|upper}} FOLLOWERS</a>
|
||||
<a class="btn btn-primary btn-block mb-3" href="/h/{{sub.name}}/blockers">{{HOLE_NAME|upper}} BLOCKERS</a>
|
||||
{% else %}
|
||||
<a id="sidebar--directory--btn" class="btn btn-primary btn-block mb-3" href="/directory">
|
||||
<span id="sidebar--directory--head">DIRECTORY</span>
|
||||
|
|
|
@ -28,6 +28,18 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
<div class="title w-lg-25 mt-5">
|
||||
<label class="text-lg" for="stealth">Stealth Mode</label>
|
||||
</div>
|
||||
<div class="body w-lg-100">
|
||||
<div class="custom-control custom-switch">
|
||||
<input autocomplete="off" type="checkbox" class="custom-control-input" id="stealth" name="stealth" {% if sub.stealth %}checked{% endif %} onchange="post_toast(this,'/h/{{sub.name}}/stealth');">
|
||||
<label class="custom-control-label" for="stealth"></label>
|
||||
</div>
|
||||
<span class="text-small text-muted">Hide posts in this hole from the main feed for non-subscribers.</span>
|
||||
</div>
|
||||
|
||||
<h2 class="h5 mt-5">Sidebar Picture</h2>
|
||||
|
||||
<div class="settings-section rounded">
|
||||
|
|
|
@ -13,18 +13,14 @@
|
|||
<th>#</th>
|
||||
<th>Name</th>
|
||||
<th role="button" onclick="sort_table(2)">Posts</th>
|
||||
<th role="button" onclick="sort_table(3)">Followers</th>
|
||||
<th role="button" onclick="sort_table(4)">Blockers</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
{% for sub, count in subs %}
|
||||
<tr>
|
||||
<td {% if sub.name in ['smuggies','braincels'] %}class="text-danger"{% endif %}>{{loop.index}}</td>
|
||||
<td><a href="/h/{{sub.name}}" {% if sub.name in ['smuggies','braincels'] %}class="text-danger"{% endif %}>{{sub.name}}</a></td>
|
||||
<td><a href="/h/{{sub.name}}" {% if sub.name in ['smuggies','braincels'] %}class="text-danger"{% endif %}>{{count}}</a></td>
|
||||
<td><a href="/h/{{sub.name}}/followers" {% if sub.name in ['smuggies','braincels'] %}class="text-danger"{% endif %}>{{sub.follow_num}}</a></td>
|
||||
<td><a href="/h/{{sub.name}}/blockers" {% if sub.name in ['smuggies','braincels'] %}class="text-danger"{% endif %}>{{sub.block_num}}</a></td>
|
||||
<td {% if sub.stealth %}class="text-stealth"{% endif %}>{{loop.index}}</td>
|
||||
<td><a href="/h/{{sub.name}}" {% if sub.stealth %}class="text-stealth"{% endif %}>{{sub.name}}</a></td>
|
||||
<td><a href="/h/{{sub.name}}" {% if sub.stealth %}class="text-stealth"{% endif %}>{{count}}</a></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{% for p in listing %}
|
||||
{% for p in listing if p.sub != 'chudtopia' or (v and v.truecoins >= 20000) %}
|
||||
|
||||
{% set ups=p.upvotes %}
|
||||
{% set downs=p.downvotes %}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{%-
|
||||
set CACHE_VER = {
|
||||
'css/main.css': 461,
|
||||
'css/main.css': 464,
|
||||
'css/catalog.css': 2,
|
||||
|
||||
'css/4chan.css': 61,
|
||||
|
|
Loading…
Reference in New Issue