forked from MarseyWorld/MarseyWorld
master
parent
e4ee14b955
commit
ec51c1380c
|
@ -7116,7 +7116,7 @@ input[type=number] {
|
|||
}
|
||||
}
|
||||
|
||||
.chat-owner {
|
||||
.chat-mod {
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,13 +16,15 @@ class Chat(Base):
|
|||
created_utc = Column(Integer)
|
||||
css = deferred(Column(String))
|
||||
|
||||
@property
|
||||
@lazy
|
||||
def mod_ids(self):
|
||||
return [x[0] for x in g.db.query(ChatMembership.user_id).filter_by(chat_id=self.id, is_mod=True).order_by(ChatMembership.created_utc, ChatMembership.user_id).all()]
|
||||
|
||||
@property
|
||||
@lazy
|
||||
def owner_id(self):
|
||||
owner_id = g.db.query(ChatMembership.user_id).filter_by(chat_id=self.id).order_by(ChatMembership.created_utc, ChatMembership.user_id).first()
|
||||
if not owner_id:
|
||||
return AUTOJANNY_ID
|
||||
return owner_id[0]
|
||||
return self.mod_ids[0] or AUTOJANNY_ID
|
||||
|
||||
@property
|
||||
@lazy
|
||||
|
@ -45,6 +47,7 @@ class ChatMembership(Base):
|
|||
muted = Column(Boolean, default=False)
|
||||
mentions = Column(Integer, default=0)
|
||||
created_utc = Column(Integer)
|
||||
is_mod = Column(Boolean, default=False)
|
||||
|
||||
user = relationship("User")
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ def add_notif(cid, uid, text, pushnotif_url='', check_existing=True):
|
|||
push_notif({uid}, 'New notification', text, pushnotif_url)
|
||||
|
||||
|
||||
def NOTIFY_USERS(text, v, oldtext=None, ghost=False, obj=None, followers_ping=True, commenters_ping_post_id=None, charge=True, chat=None):
|
||||
def NOTIFY_USERS(text, v, oldtext=None, ghost=False, obj=None, followers_ping=True, commenters_ping_post_id=None, charge=True, chat=None, membership=None):
|
||||
# Restrict young accounts from generating notifications
|
||||
if v.age < NOTIFICATION_SPAM_AGE_THRESHOLD:
|
||||
return set()
|
||||
|
@ -194,8 +194,8 @@ def NOTIFY_USERS(text, v, oldtext=None, ghost=False, obj=None, followers_ping=Tr
|
|||
|
||||
if i.group(1) == 'everyone':
|
||||
if chat:
|
||||
if not v.id == chat.owner_id:
|
||||
abort(403, "You need to be the chat owner to do that!")
|
||||
if not membership.is_mod:
|
||||
abort(403, "You need to be the chat owner or a mod to do that!")
|
||||
group = None
|
||||
member_ids = set(x[0] for x in g.db.query(ChatMembership.user_id).filter_by(chat_id=chat.id).all()) - {v.id}
|
||||
else:
|
||||
|
|
|
@ -15,6 +15,8 @@ group_mention_regex = re.compile('(?<![:/\w])!([\w-]{3,25})' + NOT_IN_CODE_OR_LI
|
|||
|
||||
chat_adding_regex = re.compile('\+@([\w-]{1,30})' + NOT_IN_CODE_OR_LINKS, flags=re.A)
|
||||
chat_kicking_regex = re.compile('\-@([\w-]{1,30})' + NOT_IN_CODE_OR_LINKS, flags=re.A)
|
||||
chat_jannying_regex = re.compile('\*@([\w-]{1,30})' + NOT_IN_CODE_OR_LINKS, flags=re.A)
|
||||
chat_dejannying_regex = re.compile(r'(^|\s)/@([\w-]{1,30})' + NOT_IN_CODE_OR_LINKS, flags=re.A)
|
||||
|
||||
everyone_regex = re.compile('(^|\s|>)!(everyone)' + NOT_IN_CODE_OR_LINKS, flags=re.A)
|
||||
|
||||
|
|
|
@ -69,9 +69,10 @@ def speak(data, v):
|
|||
|
||||
if chat.id == 1:
|
||||
if not v.allowed_in_chat: return ''
|
||||
membership = None
|
||||
else:
|
||||
is_member = g.db.query(ChatMembership.user_id).filter_by(user_id=v.id, chat_id=chat_id).one_or_none()
|
||||
if not is_member: return ''
|
||||
membership = g.db.query(ChatMembership.is_mod).filter_by(user_id=v.id, chat_id=chat_id).one_or_none()
|
||||
if not membership: return ''
|
||||
|
||||
image = None
|
||||
if data['file']:
|
||||
|
@ -149,7 +150,7 @@ def speak(data, v):
|
|||
ChatMembership.user_id != v.id,
|
||||
).one())
|
||||
else:
|
||||
notify_users = NOTIFY_USERS(chat_message.text, v, chat=chat)
|
||||
notify_users = NOTIFY_USERS(chat_message.text, v, chat=chat, membership=membership)
|
||||
if notify_users == 'everyone':
|
||||
notify_users = set()
|
||||
if chat_message.quotes:
|
||||
|
@ -164,7 +165,7 @@ def speak(data, v):
|
|||
|
||||
typing[request.referrer] = []
|
||||
|
||||
if v.id == chat.owner_id:
|
||||
if membership.is_mod:
|
||||
for i in chat_adding_regex.finditer(text):
|
||||
user = get_user(i.group(1), graceful=True, attributes=[User.id])
|
||||
if user and not user.has_muted(v) and not user.has_blocked(v):
|
||||
|
@ -186,6 +187,23 @@ def speak(data, v):
|
|||
g.db.flush()
|
||||
send_notification(user.id, f"@{v.username} kicked you from their chat [{chat.name}](/chat/{chat.id})")
|
||||
|
||||
if v.id == chat.owner_id:
|
||||
for i in chat_jannying_regex.finditer(text):
|
||||
user = get_user(i.group(1), graceful=True, attributes=[User.id])
|
||||
if user:
|
||||
existing = g.db.query(ChatMembership).filter_by(user_id=user.id, chat_id=chat_id, is_mod=False).one_or_none()
|
||||
if existing:
|
||||
existing.is_mod = True
|
||||
send_notification(user.id, f"@{v.username} has added you as a mod of their chat [{chat.name}](/chat/{chat.id})")
|
||||
|
||||
for i in chat_dejannying_regex.finditer(text):
|
||||
user = get_user(i.group(2), graceful=True, attributes=[User.id])
|
||||
if user:
|
||||
existing = g.db.query(ChatMembership).filter_by(user_id=user.id, chat_id=chat_id, is_mod=True).one_or_none()
|
||||
if existing:
|
||||
existing.is_mod = False
|
||||
send_notification(user.id, f"@{v.username} has removed you as a mod of their chat [{chat.name}](/chat/{chat.id})")
|
||||
|
||||
if chat.id != 1:
|
||||
alrdy_here = set(online[request.referrer].keys())
|
||||
memberships = g.db.query(ChatMembership).options(load_only(ChatMembership.user_id)).filter(
|
||||
|
|
|
@ -48,6 +48,7 @@ def chat_user(v, username):
|
|||
chat_membership = ChatMembership(
|
||||
user_id=v.id,
|
||||
chat_id=chat.id,
|
||||
is_mod=True,
|
||||
)
|
||||
g.db.add(chat_membership)
|
||||
|
||||
|
@ -128,8 +129,8 @@ def change_chat_name(v, chat_id):
|
|||
if not chat:
|
||||
abort(404, "Chat not found!")
|
||||
|
||||
if v.id != chat.owner_id:
|
||||
abort(403, "Only the chat owner can change its name!")
|
||||
if v.id not in chat.mod_ids:
|
||||
abort(403, "You need to be the chat owner or a mod to do that!")
|
||||
|
||||
new_name = request.values.get("new_name").strip()
|
||||
|
||||
|
@ -158,6 +159,12 @@ def leave_chat(v, chat_id):
|
|||
|
||||
g.db.delete(membership)
|
||||
|
||||
g.db.flush()
|
||||
if not chat.mod_ids:
|
||||
oldest_membership = g.db.query(ChatMembership).filter_by(chat_id=chat.id).order_by(ChatMembership.created_utc, ChatMembership.user_id).first()
|
||||
oldest_membership.is_mod = True
|
||||
g.db.add(oldest_membership)
|
||||
|
||||
return {"message": "Chat left successfully!"}
|
||||
|
||||
@app.post("/chat/<int:chat_id>/toggle_mute")
|
||||
|
@ -197,8 +204,8 @@ def chat_custom_css_get(v, chat_id):
|
|||
if not chat:
|
||||
abort(404, "Chat not found!")
|
||||
|
||||
if v.id != chat.owner_id:
|
||||
abort(403, "Only the chat owner can change its custom css!")
|
||||
if v.id not in chat.mod_ids:
|
||||
abort(403, "You need to be the chat owner or a mod to do that!")
|
||||
|
||||
return render_template("chat_css.html", v=v, chat=chat)
|
||||
|
||||
|
@ -213,8 +220,8 @@ def chat_custom_css_post(v, chat_id):
|
|||
if not chat:
|
||||
abort(404, "Chat not found!")
|
||||
|
||||
if v.id != chat.owner_id:
|
||||
abort(403, "Only the chat owner can change its custom css!")
|
||||
if v.id not in chat.mod_ids:
|
||||
abort(403, "You need to be the chat owner or a mod to do that!")
|
||||
|
||||
if v.shadowbanned: abort(400)
|
||||
|
||||
|
@ -257,8 +264,8 @@ def orgy_control(v, chat_id):
|
|||
if chat.id == 1:
|
||||
if v.admin_level < PERMS["ORGIES"]:
|
||||
abort(403, "Your admin-level is not sufficient enough for this action!")
|
||||
elif v.id != chat.owner_id:
|
||||
abort(403, "Only the chat owner can manage its orgies!")
|
||||
elif v.id not in chat.mod_ids:
|
||||
abort(403, "You need to be the chat owner or a mod to do that!")
|
||||
|
||||
orgies = g.db.query(Orgy).filter_by(chat_id=chat_id).order_by(Orgy.start_utc).all()
|
||||
return render_template("orgy_control.html", v=v, orgies=orgies, chat=chat)
|
||||
|
@ -277,8 +284,8 @@ def schedule_orgy(v, chat_id):
|
|||
if chat.id == 1:
|
||||
if v.admin_level < PERMS["ORGIES"]:
|
||||
abort(403, "Your admin-level is not sufficient enough for this action!")
|
||||
elif v.id != chat.owner_id:
|
||||
abort(403, "Only the chat owner can manage its orgies!")
|
||||
elif v.id not in chat.mod_ids:
|
||||
abort(403, "You need to be the chat owner or a mod to do that!")
|
||||
|
||||
link = request.values.get("link", "").strip()
|
||||
title = request.values.get("title", "").strip()
|
||||
|
@ -374,8 +381,8 @@ def remove_orgy(v, created_utc, chat_id):
|
|||
if chat.id == 1:
|
||||
if v.admin_level < PERMS["ORGIES"]:
|
||||
abort(403, "Your admin-level is not sufficient enough for this action!")
|
||||
elif v.id != chat.owner_id:
|
||||
abort(403, "Only the chat owner can manage its orgies!")
|
||||
elif v.id not in chat.mod_ids:
|
||||
abort(403, "You need to be the chat owner or a mod to do that!")
|
||||
|
||||
orgy = g.db.query(Orgy).filter_by(created_utc=created_utc).one_or_none()
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<h5 class="mt-2 mb-3 ml-1 toggleable d-mob-none" style="display:inline-block">{{chat.name}}</h5>
|
||||
<b class="mt-2 mb-2 ml-1 text-small toggleable d-md-none" style="display:inline-block">{{chat.name}}</b>
|
||||
|
||||
{% if v.id == chat.owner_id %}
|
||||
{% if v.id in chat.mod_ids %}
|
||||
<button class="chat-control fas fa-pen text-small text-muted px-2 toggleable" type="button" data-nonce="{{g.nonce}}" data-onclick="toggleElement('chat-name-form', 'chat-name')">
|
||||
</button>
|
||||
|
||||
|
@ -84,11 +84,13 @@
|
|||
</a>
|
||||
|
||||
{% if user.id == chat.owner_id %}
|
||||
<img class="ml-1 chat-owner" data-bs-toggle="tooltip" alt="Owner" title="Owner" src="{{SITE_FULL_IMAGES}}/e/marseykingretard.webp">
|
||||
<img class="ml-1 chat-mod" data-bs-toggle="tooltip" alt="Owner" title="Owner" src="{{SITE_FULL_IMAGES}}/e/marseykingretard.webp">
|
||||
{% elif user.id in chat.mod_ids %}
|
||||
<img class="ml-1 chat-mod" data-bs-toggle="tooltip" alt="Mod" title="Mod" src="{{SITE_FULL_IMAGES}}/e/marseyjanny.webp">
|
||||
{% endif %}
|
||||
|
||||
{% if membership.muted %}
|
||||
<i class="fas fa-bell-slash text-danger" data-bs-toggle="tooltip" title="Muted chat ({% if v.id == membership.user_id %}kys{% elif v.id == chat.owner_id %}kick him{% else %}kill him{% endif %})"></i>
|
||||
<i class="fas fa-bell-slash text-danger" data-bs-toggle="tooltip" title="Muted chat ({% if v.id == membership.user_id %}kys{% elif v.id in chat.mod_ids %}kick him{% else %}kill him{% endif %})"></i>
|
||||
{% endif %}
|
||||
|
||||
<i class="d-none ml-1 text-smaller text-success online-marker online-marker-{{user.id}} fas fa-circle"></i>
|
||||
|
|
|
@ -538,11 +538,13 @@
|
|||
</a>
|
||||
|
||||
{% if user.id == chat.owner_id %}
|
||||
<img class="ml-1 chat-owner" data-bs-toggle="tooltip" alt="Owner" title="Owner" src="{{SITE_FULL_IMAGES}}/e/marseykingretard.webp">
|
||||
<img class="ml-1 chat-mod" data-bs-toggle="tooltip" alt="Owner" title="Owner" src="{{SITE_FULL_IMAGES}}/e/marseykingretard.webp">
|
||||
{% elif user.id in chat.mod_ids %}
|
||||
<img class="ml-1 chat-mod" data-bs-toggle="tooltip" alt="Mod" title="Mod" src="{{SITE_FULL_IMAGES}}/e/marseyjanny.webp">
|
||||
{% endif %}
|
||||
|
||||
{% if membership.muted %}
|
||||
<i class="fas fa-bell-slash text-danger" data-bs-toggle="tooltip" title="Muted chat ({% if v.id == membership.user_id %}kys{% elif v.id == chat.owner_id %}kick him{% else %}kill him{% endif %})"></i>
|
||||
<i class="fas fa-bell-slash text-danger" data-bs-toggle="tooltip" title="Muted chat ({% if v.id == membership.user_id %}kys{% elif v.id in chat.mod_ids %}kick him{% else %}kill him{% endif %})"></i>
|
||||
{% endif %}
|
||||
|
||||
<i class="d-none ml-1 text-smaller text-success online-marker online-marker-{{user.id}} fas fa-circle"></i>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<h5 class="mt-2 mb-3 ml-1 d-mob-none" style="display:inline-block">{{orgy.title}}</h5>
|
||||
<b class="mt-2 mb-2 ml-1 text-small d-md-none" style="display:inline-block">{{orgy.title}}</b>
|
||||
|
||||
{% if v.id == chat.owner_id %}
|
||||
{% if v.id in chat.mod_ids %}
|
||||
<a href="/chat/{{chat.id}}/orgies" class="chat-control fas fa-tv text-muted mx-2"></a>
|
||||
|
||||
<a href="/chat/{{chat.id}}/custom_css" class="chat-control fas fa-palette text-muted ml-2"></a>
|
||||
|
@ -95,11 +95,13 @@
|
|||
</a>
|
||||
|
||||
{% if user.id == chat.owner_id %}
|
||||
<img class="ml-1 chat-owner" data-bs-toggle="tooltip" alt="Owner" title="Owner" src="{{SITE_FULL_IMAGES}}/e/marseykingretard.webp">
|
||||
<img class="ml-1 chat-mod" data-bs-toggle="tooltip" alt="Owner" title="Owner" src="{{SITE_FULL_IMAGES}}/e/marseykingretard.webp">
|
||||
{% elif user.id in chat.mod_ids %}
|
||||
<img class="ml-1 chat-mod" data-bs-toggle="tooltip" alt="Mod" title="Mod" src="{{SITE_FULL_IMAGES}}/e/marseyjanny.webp">
|
||||
{% endif %}
|
||||
|
||||
{% if membership.muted %}
|
||||
<i class="fas fa-bell-slash text-danger" data-bs-toggle="tooltip" title="Muted chat ({% if v.id == membership.user_id %}kys{% elif v.id == chat.owner_id %}kick him{% else %}kill him{% endif %})"></i>
|
||||
<i class="fas fa-bell-slash text-danger" data-bs-toggle="tooltip" title="Muted chat ({% if v.id == membership.user_id %}kys{% elif v.id in chat.mod_ids %}kick him{% else %}kill him{% endif %})"></i>
|
||||
{% endif %}
|
||||
|
||||
<i class="d-none ml-1 text-smaller text-success online-marker online-marker-{{user.id}} fas fa-circle"></i>
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
alter table chat_memberships add column is_mod bool not null default false;
|
||||
alter table chat_memberships alter column is_mod drop default;
|
||||
|
||||
DO
|
||||
$do$
|
||||
BEGIN
|
||||
FOR i IN 1..600 LOOP
|
||||
update chat_memberships m1 set is_mod=true where chat_id = i and user_id = (select user_id from chat_memberships m2 where m1.chat_id = m2.chat_id order by created_utc limit 1);
|
||||
END LOOP;
|
||||
END
|
||||
$do$;
|
Loading…
Reference in New Issue