pull/200/head
parent
ab22b4b385
commit
6662eb0606
|
@ -11,6 +11,7 @@ from .reports import *
|
|||
from .user import *
|
||||
from .badges import *
|
||||
from .userblock import *
|
||||
from .usermute import *
|
||||
from .post import *
|
||||
from .votes import *
|
||||
from .domains import *
|
||||
|
|
|
@ -36,6 +36,7 @@ from .sub_relationship import *
|
|||
from .sub_logs import *
|
||||
from .subscriptions import *
|
||||
from .userblock import *
|
||||
from .usermute import *
|
||||
|
||||
if SITE == 'devrama.net':
|
||||
DEFAULT_ADMIN_LEVEL = 3
|
||||
|
@ -561,6 +562,10 @@ class User(Base):
|
|||
def has_blocked(self, target):
|
||||
return g.db.query(UserBlock).filter_by(user_id=self.id, target_id=target.id).one_or_none()
|
||||
|
||||
@lazy
|
||||
def has_muted(self, target):
|
||||
return g.db.query(UserMute).filter_by(user_id=self.id, target_id=target.id).one_or_none()
|
||||
|
||||
@property
|
||||
@lazy
|
||||
def all_twoway_blocks(self):
|
||||
|
@ -1023,6 +1028,12 @@ class User(Base):
|
|||
def userblocks(self):
|
||||
return [x[0] for x in g.db.query(UserBlock.target_id).filter_by(user_id=self.id)]
|
||||
|
||||
@property
|
||||
@lazy
|
||||
def muters(self):
|
||||
return set([x[0] for x in g.db.query(UserMute.user_id).filter_by(target_id=self.id)])
|
||||
|
||||
|
||||
def get_relationship_count(self, relationship_cls):
|
||||
# TODO: deduplicate (see routes/users.py)
|
||||
if relationship_cls in {SaveRelationship, Subscription}:
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import time
|
||||
|
||||
from sqlalchemy import Column, ForeignKey
|
||||
from sqlalchemy.sql.sqltypes import *
|
||||
|
||||
from files.classes import Base
|
||||
|
||||
class UserMute(Base):
|
||||
__tablename__ = "usermutes"
|
||||
user_id = Column(Integer, ForeignKey("users.id"), primary_key=True)
|
||||
target_id = Column(Integer, ForeignKey("users.id"), primary_key=True)
|
||||
created_utc = Column(Integer)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
if "created_utc" not in kwargs: kwargs["created_utc"] = int(time.time())
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def __repr__(self):
|
||||
return f"<{self.__class__.__name__}(user={self.user_id}, target={self.target_id})>"
|
|
@ -187,7 +187,7 @@ def NOTIFY_USERS(text, v, oldtext=None, ghost=False, log_cost=None, followers_pi
|
|||
if not group: continue
|
||||
member_ids = group.member_ids
|
||||
|
||||
members = member_ids - notify_users - BOT_IDs - v.all_twoway_blocks
|
||||
members = member_ids - notify_users - BOT_IDs - v.all_twoway_blocks - v.muters
|
||||
|
||||
notify_users.update(members)
|
||||
|
||||
|
@ -210,13 +210,10 @@ def NOTIFY_USERS(text, v, oldtext=None, ghost=False, log_cost=None, followers_pi
|
|||
if coin_receivers:
|
||||
g.db.query(User).options(load_only(User.id)).filter(User.id.in_(coin_receivers)).update({ User.coins: User.coins + 10 })
|
||||
|
||||
if SITE == 'rdrama.net' and v.id in {256, 9287, 10489, 18701}:
|
||||
notify_users.discard(AEVANN_ID)
|
||||
|
||||
if len(notify_users) > 400 and v.admin_level < PERMS['POST_COMMENT_INFINITE_PINGS']:
|
||||
abort(403, "You can only notify a maximum of 400 users.")
|
||||
|
||||
return notify_users - BOT_IDs - {v.id, 0} - v.all_twoway_blocks
|
||||
return notify_users - BOT_IDs - {v.id, 0} - v.all_twoway_blocks - v.muters
|
||||
|
||||
|
||||
def push_notif(uids, title, body, url_or_comment):
|
||||
|
|
|
@ -178,7 +178,7 @@ def comment(v):
|
|||
if not body and not request.files.get('file'):
|
||||
abort(400, "You need to actually write something!")
|
||||
|
||||
if parent_user.has_blocked(v):
|
||||
if parent_user.has_blocked(v) or parent_user.has_muted(v):
|
||||
notify_op = False
|
||||
|
||||
if request.files.get("file") and not g.is_tor:
|
||||
|
|
|
@ -346,6 +346,7 @@ def notifications(v):
|
|||
if n.created_utc > 1620391248: c.notif_utc = n.created_utc
|
||||
|
||||
if not n.read: c.unread = True
|
||||
c.is_notif = True
|
||||
|
||||
if c.parent_post or c.wall_user_id:
|
||||
all_items.append(c)
|
||||
|
|
|
@ -623,6 +623,9 @@ def message2(v, username=None, id=None):
|
|||
if v.admin_level <= PERMS['MESSAGE_BLOCKED_USERS'] and hasattr(user, 'is_blocked') and user.is_blocked:
|
||||
abort(403, f"@{user.username} is blocking you!")
|
||||
|
||||
if user.has_muted(v):
|
||||
abort(403, f"@{user.username} is muting notifications from you, so messaging them is pointless!")
|
||||
|
||||
body = request.values.get("message", "")
|
||||
body = body[:COMMENT_BODY_LENGTH_LIMIT].strip()
|
||||
|
||||
|
@ -708,6 +711,9 @@ def messagereply(v):
|
|||
and hasattr(user, 'is_blocked') and user.is_blocked):
|
||||
abort(403, f"You're blocked by @{user.username}")
|
||||
|
||||
if user.has_muted(v):
|
||||
abort(403, f"@{user.username} is muting notifications from you, so messaging them is pointless!")
|
||||
|
||||
if not g.is_tor and get_setting("dm_media"):
|
||||
body = process_files(request.files, v, body, is_dm=True, dm_user=user)
|
||||
body = body[:COMMENT_BODY_LENGTH_LIMIT].strip() #process_files potentially adds characters to the post
|
||||
|
@ -1511,3 +1517,47 @@ def users_list(v):
|
|||
page=page,
|
||||
user_cards_title="Users Feed",
|
||||
)
|
||||
|
||||
@app.post("/mute_notifs/<int:uid>")
|
||||
@limiter.limit('1/second', scope=rpath)
|
||||
@limiter.limit('1/second', scope=rpath, key_func=get_ID)
|
||||
@limiter.limit("20/day", deduct_when=lambda response: response.status_code < 400)
|
||||
@limiter.limit("20/day", deduct_when=lambda response: response.status_code < 400, key_func=get_ID)
|
||||
@auth_required
|
||||
def mute_notifs(v, uid):
|
||||
user = get_account(uid)
|
||||
|
||||
if user.id == v.id:
|
||||
abort(400, "You can't mute notifications from yourself!")
|
||||
if user.id == AUTOJANNY_ID:
|
||||
abort(403, f"You can't mute notifications from @{user.username}")
|
||||
if v.has_muted(user):
|
||||
abort(409, f"You have already muted notifications from @{user.username}")
|
||||
|
||||
new_mute = UserMute(user_id=v.id, target_id=user.id)
|
||||
g.db.add(new_mute)
|
||||
|
||||
send_notification(user.id, f"@{v.username} has muted notifications from you!")
|
||||
|
||||
return {"message": f"You have muted notifications from @{user.username} successfully!"}
|
||||
|
||||
|
||||
@app.post("/unmute_notifs/<int:uid>")
|
||||
@limiter.limit('1/second', scope=rpath)
|
||||
@limiter.limit('1/second', scope=rpath, key_func=get_ID)
|
||||
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400)
|
||||
@limiter.limit(DEFAULT_RATELIMIT, deduct_when=lambda response: response.status_code < 400, key_func=get_ID)
|
||||
@auth_required
|
||||
def unmute_notifs(v, uid):
|
||||
user = get_account(uid)
|
||||
|
||||
x = v.has_muted(user)
|
||||
|
||||
if not x:
|
||||
abort(409, "You can't unmute notifications from someone you haven't muted notifications from!")
|
||||
|
||||
g.db.delete(x)
|
||||
|
||||
send_notification(user.id, f"@{v.username} has unmuted notifications from you!")
|
||||
|
||||
return {"message": f"You have unmuted notifications from @{user.username} successfully!"}
|
||||
|
|
|
@ -116,7 +116,7 @@
|
|||
|
||||
<div id="{% if comment_info and comment_info.id == c.id %}context{% else %}comment-{{c.id}}-only{% endif %}" class="{% if c.unread %}unread{% endif %} {% if c.award_count('glowie', v) %}glow{% endif %} comment-{{c.id}}-only comment-anchor {% if comment_info and comment_info.id == c.id %}context{% endif %}{% if c.is_banned %} banned{% endif %}{% if c.deleted_utc %} deleted{% endif %}">
|
||||
|
||||
<div class="user-info">
|
||||
<div class="user-info {% if request.path.startswith('/notifications') %}x-scroll{% endif %}">
|
||||
<span class="comment-collapse-icon" data-nonce="{{g.nonce}}" data-onclick="collapse_comment('{{c.id}}')"></span>
|
||||
|
||||
{% for a in c.awards %}
|
||||
|
@ -238,6 +238,11 @@
|
|||
{% if c.blackjack_result %}
|
||||
{{c.blackjack_html | safe}}
|
||||
{% endif %}
|
||||
|
||||
{% if c.is_notif or (request.path == '/notifications/messages' and c.author_id != v.id) %}
|
||||
<button type="button" class="text-danger font-weight-bold ml-1 mt-2 mr-3 p-1 {% if v.has_muted(c.author) %}d-none{% endif %}" id="mute-notifs-{{c.id}}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/mute_notifs/{{c.author.id}}','mute-notifs-{{c.id}}','unmute-notifs-{{c.id}}','d-none')">Mute notifications from @{{c.author.username}}</button>
|
||||
<button type="button" class="text-success font-weight-bold ml-1 mt-2 mr-3 p-1 {% if not v.has_muted(c.author) %}d-none{% endif %}" id="unmute-notifs-{{c.id}}" data-nonce="{{g.nonce}}" data-onclick="postToastSwitch(this,'/unmute_notifs/{{c.author.id}}','mute-notifs-{{c.id}}','unmute-notifs-{{c.id}}','d-none')">Unmute notifications from @{{c.author.username}}</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{{macros.reports(c, 'comment')}}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
CREATE TABLE public.usermutes (
|
||||
user_id integer NOT NULL,
|
||||
target_id integer NOT NULL,
|
||||
created_utc integer
|
||||
);
|
||||
|
||||
ALTER TABLE ONLY public.usermutes
|
||||
ADD CONSTRAINT usermutes_pkey PRIMARY KEY (user_id, target_id);
|
||||
|
||||
|
||||
CREATE INDEX mute_target_idx ON public.usermutes USING btree (target_id);
|
||||
|
||||
ALTER TABLE ONLY public.usermutes
|
||||
ADD CONSTRAINT mute_target_fkey FOREIGN KEY (target_id) REFERENCES public.users(id);
|
||||
|
||||
ALTER TABLE ONLY public.usermutes
|
||||
ADD CONSTRAINT mute_user_fkey FOREIGN KEY (user_id) REFERENCES public.users(id);
|
Loading…
Reference in New Issue