large commit: stealth mode, SubJoin, chudtopia

dont read if u value ur sanity
remotes/1693045480750635534/spooky-22
Aevann1 2022-08-19 23:31:26 +02:00
parent 19c38b9730
commit 9e5ddcbd92
17 changed files with 127 additions and 47 deletions

View File

@ -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;
}

View File

@ -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 *

View File

@ -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")

View File

@ -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})>"

View File

@ -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):

View File

@ -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)

View File

@ -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,

View File

@ -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!"}

View File

@ -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)}}

View File

@ -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 %}

View File

@ -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 -%}

View File

@ -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">

View File

@ -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>

View File

@ -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">

View File

@ -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>

View File

@ -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 %}

View File

@ -1,6 +1,6 @@
{%-
set CACHE_VER = {
'css/main.css': 461,
'css/main.css': 464,
'css/catalog.css': 2,
'css/4chan.css': 61,