Add following holes for notifications.

remotes/1693045480750635534/spooky-22
Snakes 2022-06-09 16:24:24 -04:00
parent 39e0e6d017
commit dc7f13304e
13 changed files with 98 additions and 15 deletions

View File

@ -11,7 +11,6 @@ if SITE == "localhost": SITE_FULL = 'http://' + SITE
else: SITE_FULL = 'https://' + SITE
class Sub(Base):
__tablename__ = "subs"
name = Column(String, primary_key=True)
sidebar = Column(String)
@ -20,8 +19,10 @@ class Sub(Base):
bannerurl = Column(String)
css = Column(String)
blocks = relationship("SubBlock", primaryjoin="SubBlock.sub==Sub.name", viewonly=True)
blocks = relationship("SubBlock",
primaryjoin="SubBlock.sub==Sub.name", viewonly=True)
followers = relationship("SubSubscription",
primaryjoin="SubSubscription.sub==Sub.name", viewonly=True)
def __repr__(self):
return f"<Sub(name={self.name})>"

View File

@ -3,10 +3,18 @@ from sqlalchemy.orm import relationship
from files.__main__ import Base
class SubBlock(Base):
__tablename__ = "sub_blocks"
user_id = Column(Integer, ForeignKey("users.id"), primary_key=True)
sub = Column(String, ForeignKey("subs.name"), primary_key=True)
sub = Column(String(20), ForeignKey("subs.name"), primary_key=True)
def __repr__(self):
return f"<SubBlock(user_id={self.user_id}, sub={self.sub})>"
return f"<SubBlock(user_id={self.user_id}, sub={self.sub})>"
class SubSubscription(Base):
__tablename__ = "sub_subscriptions"
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"<SubSubscription(user_id={self.user_id}, sub={self.sub})>"

View File

@ -171,6 +171,15 @@ class User(Base):
def blocks(self, sub):
return g.db.query(SubBlock).filter_by(user_id=self.id, sub=sub).one_or_none()
@property
@lazy
def all_follows(self):
return [x[0] for x in g.db.query(SubSubscription.sub).filter_by(user_id=self.id).all()]
@lazy
def follows(self, sub):
return g.db.query(SubSubscription).filter_by(user_id=self.id, sub=sub).one_or_none()
@lazy
def mod_date(self, sub):
if self.id == AEVANN_ID: return 1

View File

@ -134,7 +134,7 @@ POST_RATE_LIMIT = "1/second;2/minute;10/hour;50/day"
USER_TITLE_COST = 0
if SITE in {'rdrama.net','devrama.xyz'}:
HOLE_COST = 200000
HOLE_COST = 50000
USER_TITLE_COST = 25
NOTIFICATIONS_ID = 1046
AUTOJANNY_ID = 2360

View File

@ -85,6 +85,16 @@ def publish(pid, v):
if post.club and not user.paid_dues: continue
add_notif(cid, user.id)
if post.sub and post.subr:
sub_name = post.subr.name
text = f"<a href='/h/{sub_name}'>/h/{sub_name}</a> has a new " \
+ f"post: [{post.title}]({post.shortlink})"
cid = notif_comment(text, autojanny=True)
for follow in post.subr.followers:
user = get_account(follow.user_id)
if post.club and not user.paid_dues: continue
add_notif(cid, user.id)
g.db.commit()
cache.delete_memoized(frontlist)
@ -1114,9 +1124,15 @@ def submit_post(v, sub=None):
if post.club and not user.paid_dues: continue
add_notif(cid, user.id)
if post.sub and post.subr:
sub_name = post.subr.name
text = f"<a href='/h/{sub_name}'>/h/{sub_name}</a> has a new " \
+ f"post: [{post.title}]({post.shortlink})"
cid = notif_comment(text, autojanny=True)
for follow in post.subr.followers:
user = get_account(follow.user_id)
if post.club and not user.paid_dues: continue
add_notif(cid, user.id)
if v.agendaposter and not v.marseyawarded and AGENDAPOSTER_PHRASE not in f'{post.body}{post.title}'.lower():
post.is_banned = True

View File

@ -121,6 +121,35 @@ def unblock_sub(v, sub):
return {"message": "Sub unblocked successfully!"}
@app.post("/h/<sub>/follow")
@auth_required
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()
if not existing:
subscription = SubSubscription(user_id=v.id, sub=sub.name)
g.db.add(subscription)
g.db.commit()
return {"message": "Sub followed successfully!"}
@app.post("/h/<sub>/unfollow")
@auth_required
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()
if subscription:
g.db.delete(subscription)
g.db.commit()
return {"message": "Sub unfollowed successfully!"}
@app.get("/h/<sub>/mods")
@auth_required
def mods(v, sub):
@ -134,7 +163,7 @@ def mods(v, sub):
@app.get("/h/<sub>/exilees")
@auth_required
def exilees(v, sub):
def sub_exilees(v, sub):
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
if not sub: abort(404)
@ -145,14 +174,27 @@ def exilees(v, sub):
@app.get("/h/<sub>/blockers")
@auth_required
def blockers(v, sub):
def sub_blockers(v, sub):
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
if not sub: abort(404)
users = g.db.query(User).join(SubBlock, SubBlock.user_id==User.id).filter_by(sub=sub.name).all()
return render_template("sub/blockers.html", v=v, sub=sub, users=users)
return render_template("sub/blockers.html",
v=v, sub=sub, users=users, verb="blocking")
@app.get("/h/<sub>/followers")
@auth_required
def sub_followers(v, sub):
sub = g.db.query(Sub).filter_by(name=sub.strip().lower()).one_or_none()
if not sub: abort(404)
users = g.db.query(User) \
.join(SubSubscription, SubSubscription.user_id==User.id) \
.filter_by(sub=sub.name).all()
return render_template("sub/blockers.html",
v=v, sub=sub, users=users, verb="following")
@app.post("/h/<sub>/add_mod")

View File

@ -44,6 +44,9 @@
{% if sub %}
<div class="mt-3">
{% if v %}
<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"></i> Follow /h/{{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"></i> Unfollow /h/{{sub.name}}</a>
<a class="btn btn-primary btn-block {% 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')">Block /h/{{sub.name}}</a>
<a class="btn btn-primary btn-block {% 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')">Unblock /h/{{sub.name}}</a>
{% else %}

View File

@ -26,6 +26,7 @@
{% endif %}
<a class="btn btn-primary btn-block mb-3" href="/h/{{sub.name}}/mods">HOLE MODS</a>
<a class="btn btn-primary btn-block mb-3" href="/h/{{sub.name}}/exilees">HOLE EXILEES</a>
<a class="btn btn-primary btn-block mb-3" href="/h/{{sub.name}}/followers">HOLE FOLLOWERS</a>
<a class="btn btn-primary btn-block mb-3" href="/h/{{sub.name}}/blockers">HOLE BLOCKERS</a>
{% else %}
<a class="btn btn-primary btn-block mb-3" href="/create_sub">CREATE HOLE</a>

View File

@ -15,6 +15,7 @@
{% endif %}
<a class="btn btn-primary btn-block" href="/h/{{sub.name}}/mods">HOLE MODS</a>
<a class="btn btn-primary btn-block" href="/h/{{sub.name}}/exilees">HOLE EXILEES</a>
<a class="btn btn-primary btn-block" href="/h/{{sub.name}}/followers">HOLE FOLLOWERS</a>
<a class="btn btn-primary btn-block" href="/h/{{sub.name}}/blockers">HOLE BLOCKERS</a>
{% endif %}

View File

@ -26,6 +26,7 @@
{% endif %}
<a class="btn btn-primary btn-block mb-3" href="/h/{{sub.name}}/mods">HOLE MODS</a>
<a class="btn btn-primary btn-block mb-3" href="/h/{{sub.name}}/exilees">HOLE EXILEES</a>
<a class="btn btn-primary btn-block mb-3" href="/h/{{sub.name}}/followers">HOLE FOLLOWERS</a>
<a class="btn btn-primary btn-block mb-3" href="/h/{{sub.name}}/blockers">HOLE BLOCKERS</a>
{% else %}
<div class="mt-4">

View File

@ -70,6 +70,7 @@ set VISITORS_HERE_FLAVOR = [
{% endif %}
<a class="btn btn-primary btn-block mb-3" href="/h/{{sub.name}}/mods">HOLE MODS</a>
<a class="btn btn-primary btn-block mb-3" href="/h/{{sub.name}}/exilees">HOLE EXILEES</a>
<a class="btn btn-primary btn-block mb-3" href="/h/{{sub.name}}/followers">HOLE FOLLOWERS</a>
<a class="btn btn-primary btn-block mb-3" href="/h/{{sub.name}}/blockers">HOLE BLOCKERS</a>
{% else %}
{% if v %}

View File

@ -4,7 +4,7 @@
</pre>
<h5>Users blocking /h/{{sub.name}}</h5>
<h5>Users {{verb}} /h/{{sub.name}}</h5>
<pre></pre>
<div class="overflow-x-auto"><table class="table table-striped mb-5">
<thead class="bg-primary text-white">

View File

@ -1,6 +1,6 @@
{%-
set CACHE_VER = {
'css/main.css': 296,
'css/main.css': 297,
'css/4chan.css': 59,
'css/classic.css': 59,