large commit: stealth mode, SubJoin, chudtopia

dont read if u value ur sanity
master
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 { .btn-follow {
display: block; display: block;
width: 100%; width: 100%;
}
.btn-follow + .btn-follow {
margin-top: 0.5rem; margin-top: 0.5rem;
} }
input[type=submit].btn-follow, input[type=reset].btn-follow, input[type=button].btn-follow { 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 { .desktop-expanded-image-modal::-webkit-scrollbar {
-ms-overflow-style: none; -ms-overflow-style: none;
scrollbar-width: none; scrollbar-width: none;
}
.text-stealth {
color: #a4f5f3 !important;
} }

View File

@ -17,8 +17,9 @@ from .award import *
from .marsey import * from .marsey import *
from .sub_block import * from .sub_block import *
from .sub_subscription import * from .sub_subscription import *
from .sub_join import *
from .saves import * from .saves import *
from .views import * from .views import *
from .notifications import * from .notifications import *
from .follows import * from .follows import *
from .lottery import * from .lottery import *

View File

@ -19,6 +19,7 @@ class Sub(Base):
sidebarurl = Column(String) sidebarurl = Column(String)
bannerurl = Column(String) bannerurl = Column(String)
css = Column(String) css = Column(String)
stealth = Column(Boolean)
blocks = relationship("SubBlock", primaryjoin="SubBlock.sub==Sub.name") blocks = relationship("SubBlock", primaryjoin="SubBlock.sub==Sub.name")
followers = relationship("SubSubscription", primaryjoin="SubSubscription.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 .exiles import *
from .sub_block import * from .sub_block import *
from .sub_subscription import * from .sub_subscription import *
from .sub_join import *
from files.__main__ import Base, cache from files.__main__ import Base, cache
from files.helpers.security import * from files.helpers.security import *
from copy import deepcopy from copy import deepcopy
@ -173,12 +174,18 @@ class User(Base):
@property @property
@lazy @lazy
def all_blocks(self): 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 @lazy
def blocks(self, sub): def blocks(self, sub):
return g.db.query(SubBlock).filter_by(user_id=self.id, sub=sub).one_or_none() 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 @property
@lazy @lazy
def all_follows(self): 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}' if not redir.startswith('/'): redir = f'/{redir}'
return redirect(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) 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 post.downvotes += 1
g.db.add(post) 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() g.db.flush()
autovote = Vote( autovote = Vote(
user_id=AEVANN_ID, user_id=AEVANN_ID,

View File

@ -95,8 +95,6 @@ def block_sub(v, sub):
if not sub: abort(404) if not sub: abort(404)
sub = sub.name 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() existing = g.db.query(SubBlock).filter_by(user_id=v.id, sub=sub).one_or_none()
if not existing: if not existing:
@ -104,7 +102,7 @@ def block_sub(v, sub):
g.db.add(block) g.db.add(block)
cache.delete_memoized(frontlist) cache.delete_memoized(frontlist)
return {"message": f"{HOLE_NAME.capitalize()} blocked successfully!"} return {"message": "Action successful!"}
@app.post("/h/<sub>/unblock") @app.post("/h/<sub>/unblock")
@ -120,7 +118,39 @@ def unblock_sub(v, sub):
g.db.delete(block) g.db.delete(block)
cache.delete_memoized(frontlist) 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") @app.post("/h/<sub>/follow")
@auth_required @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() sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
if not sub: abort(404) if not sub: abort(404)
existing = g.db.query(SubSubscription) \ existing = g.db.query(SubSubscription).filter_by(user_id=v.id, sub=sub.name).one_or_none()
.filter_by(user_id=v.id, sub=sub.name).one_or_none()
if not existing: if not existing:
subscription = SubSubscription(user_id=v.id, sub=sub.name) subscription = SubSubscription(user_id=v.id, sub=sub.name)
g.db.add(subscription) 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") @app.post("/h/<sub>/unfollow")
@auth_required @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() sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
if not sub: abort(404) if not sub: abort(404)
subscription = g.db.query(SubSubscription) \ subscription = g.db.query(SubSubscription).filter_by(user_id=v.id, sub=sub.name).one_or_none()
.filter_by(user_id=v.id, sub=sub.name).one_or_none()
if subscription: if subscription:
g.db.delete(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") @app.get("/h/<sub>/mods")
@auth_required @auth_required
@ -291,6 +323,7 @@ def create_sub2(v):
sub = Sub(name=name) sub = Sub(name=name)
g.db.add(sub) g.db.add(sub)
g.db.flush()
mod = Mod(user_id=v.id, sub=sub.name) mod = Mod(user_id=v.id, sub=sub.name)
g.db.add(mod) 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}" message = f"@{v.username} (Mod) has unpinned your [post]({p.shortlink}) in /h/{p.sub}"
send_repeatable_notification(p.author_id, message) 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 render_replies %}
{% if level<9 or request.path.startswith('/notifications') or request.headers.get("xhr") %} {% if level<9 or request.path.startswith('/notifications') or request.headers.get("xhr") %}
<div id="replies-of-{{c.fullname}}"> <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)}} {{single_comment(reply, level=level+1)}}
{% endfor %} {% endfor %}
</div> </div>
@ -601,7 +601,7 @@
{% if render_replies %} {% if render_replies %}
{% if level<9 or request.path.startswith('/notifications') or request.headers.get("xhr") %} {% if level<9 or request.path.startswith('/notifications') or request.headers.get("xhr") %}
<div id="replies-of-{{c.fullname}}"> <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)}} {{single_comment(reply, level=level+1)}}
{% endfor %} {% endfor %}
</div> </div>
@ -785,7 +785,7 @@
{% endmacro %} {% 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)}} {{single_comment(comment)}}

View File

@ -52,14 +52,20 @@
<div class="mt-3"> <div class="mt-3">
{% if v %} {% if v %}
{%- set hole_prefix = '/h/' if not HOLE_STYLE_FLAIR else '' -%} {%- 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> {% if sub.stealth %}
<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> <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 %} {% 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>Hide posts from main feed</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" href="/login"><i class="fas fa-bell mr-2"></i>Notify me of new posts</a>
{% endif %} {% endif %}
</div> </div>
{% endif %} {% endif %}

View File

@ -16,8 +16,6 @@
{% endif %} {% 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}}/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}}/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 %} {% endif %}
{% if v and v.can_create_hole -%} {% 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> <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> </p>
{% if sub %} {% if sub and sub.sidebar_html %}
{% if sub.sidebar_html %} <div class="mb-4">{{sub.sidebar_html|safe}}</div>
<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 %}
{% endif %} {% endif %}
<div id="sidebar-wpd--flairs"> <div id="sidebar-wpd--flairs">

View File

@ -43,8 +43,6 @@
{% endif %} {% 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}}/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}}/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 %} {% else %}
<a id="sidebar--directory--btn" class="btn btn-primary btn-block mb-3" href="/directory"> <a id="sidebar--directory--btn" class="btn btn-primary btn-block mb-3" href="/directory">
<span id="sidebar--directory--head">DIRECTORY</span> <span id="sidebar--directory--head">DIRECTORY</span>

View File

@ -28,6 +28,18 @@
</div> </div>
{% endif %} {% 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> <h2 class="h5 mt-5">Sidebar Picture</h2>
<div class="settings-section rounded"> <div class="settings-section rounded">

View File

@ -13,18 +13,14 @@
<th>#</th> <th>#</th>
<th>Name</th> <th>Name</th>
<th role="button" onclick="sort_table(2)">Posts</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> </tr>
</thead> </thead>
{% for sub, count in subs %} {% for sub, count in subs %}
<tr> <tr>
<td {% if sub.name in ['smuggies','braincels'] %}class="text-danger"{% endif %}>{{loop.index}}</td> <td {% if sub.stealth %}class="text-stealth"{% 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.stealth %}class="text-stealth"{% 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}}" {% if sub.stealth %}class="text-stealth"{% 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>
</tr> </tr>
{% endfor %} {% endfor %}
</table> </table>

View File

@ -58,7 +58,7 @@
</div> </div>
</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 ups=p.upvotes %}
{% set downs=p.downvotes %} {% set downs=p.downvotes %}

View File

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