forked from MarseyWorld/MarseyWorld
master
parent
e4ee14b955
commit
ec51c1380c
|
@ -7116,7 +7116,7 @@ input[type=number] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-owner {
|
.chat-mod {
|
||||||
height: 30px;
|
height: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,13 +16,15 @@ class Chat(Base):
|
||||||
created_utc = Column(Integer)
|
created_utc = Column(Integer)
|
||||||
css = deferred(Column(String))
|
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
|
@property
|
||||||
@lazy
|
@lazy
|
||||||
def owner_id(self):
|
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()
|
return self.mod_ids[0] or AUTOJANNY_ID
|
||||||
if not owner_id:
|
|
||||||
return AUTOJANNY_ID
|
|
||||||
return owner_id[0]
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@lazy
|
@lazy
|
||||||
|
@ -45,6 +47,7 @@ class ChatMembership(Base):
|
||||||
muted = Column(Boolean, default=False)
|
muted = Column(Boolean, default=False)
|
||||||
mentions = Column(Integer, default=0)
|
mentions = Column(Integer, default=0)
|
||||||
created_utc = Column(Integer)
|
created_utc = Column(Integer)
|
||||||
|
is_mod = Column(Boolean, default=False)
|
||||||
|
|
||||||
user = relationship("User")
|
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)
|
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
|
# Restrict young accounts from generating notifications
|
||||||
if v.age < NOTIFICATION_SPAM_AGE_THRESHOLD:
|
if v.age < NOTIFICATION_SPAM_AGE_THRESHOLD:
|
||||||
return set()
|
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 i.group(1) == 'everyone':
|
||||||
if chat:
|
if chat:
|
||||||
if not v.id == chat.owner_id:
|
if not membership.is_mod:
|
||||||
abort(403, "You need to be the chat owner to do that!")
|
abort(403, "You need to be the chat owner or a mod to do that!")
|
||||||
group = None
|
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}
|
member_ids = set(x[0] for x in g.db.query(ChatMembership.user_id).filter_by(chat_id=chat.id).all()) - {v.id}
|
||||||
else:
|
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_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_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)
|
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 chat.id == 1:
|
||||||
if not v.allowed_in_chat: return ''
|
if not v.allowed_in_chat: return ''
|
||||||
|
membership = None
|
||||||
else:
|
else:
|
||||||
is_member = g.db.query(ChatMembership.user_id).filter_by(user_id=v.id, chat_id=chat_id).one_or_none()
|
membership = g.db.query(ChatMembership.is_mod).filter_by(user_id=v.id, chat_id=chat_id).one_or_none()
|
||||||
if not is_member: return ''
|
if not membership: return ''
|
||||||
|
|
||||||
image = None
|
image = None
|
||||||
if data['file']:
|
if data['file']:
|
||||||
|
@ -149,7 +150,7 @@ def speak(data, v):
|
||||||
ChatMembership.user_id != v.id,
|
ChatMembership.user_id != v.id,
|
||||||
).one())
|
).one())
|
||||||
else:
|
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':
|
if notify_users == 'everyone':
|
||||||
notify_users = set()
|
notify_users = set()
|
||||||
if chat_message.quotes:
|
if chat_message.quotes:
|
||||||
|
@ -164,7 +165,7 @@ def speak(data, v):
|
||||||
|
|
||||||
typing[request.referrer] = []
|
typing[request.referrer] = []
|
||||||
|
|
||||||
if v.id == chat.owner_id:
|
if membership.is_mod:
|
||||||
for i in chat_adding_regex.finditer(text):
|
for i in chat_adding_regex.finditer(text):
|
||||||
user = get_user(i.group(1), graceful=True, attributes=[User.id])
|
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):
|
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()
|
g.db.flush()
|
||||||
send_notification(user.id, f"@{v.username} kicked you from their chat [{chat.name}](/chat/{chat.id})")
|
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:
|
if chat.id != 1:
|
||||||
alrdy_here = set(online[request.referrer].keys())
|
alrdy_here = set(online[request.referrer].keys())
|
||||||
memberships = g.db.query(ChatMembership).options(load_only(ChatMembership.user_id)).filter(
|
memberships = g.db.query(ChatMembership).options(load_only(ChatMembership.user_id)).filter(
|
||||||
|
|
|
@ -48,6 +48,7 @@ def chat_user(v, username):
|
||||||
chat_membership = ChatMembership(
|
chat_membership = ChatMembership(
|
||||||
user_id=v.id,
|
user_id=v.id,
|
||||||
chat_id=chat.id,
|
chat_id=chat.id,
|
||||||
|
is_mod=True,
|
||||||
)
|
)
|
||||||
g.db.add(chat_membership)
|
g.db.add(chat_membership)
|
||||||
|
|
||||||
|
@ -128,8 +129,8 @@ def change_chat_name(v, chat_id):
|
||||||
if not chat:
|
if not chat:
|
||||||
abort(404, "Chat not found!")
|
abort(404, "Chat not found!")
|
||||||
|
|
||||||
if v.id != chat.owner_id:
|
if v.id not in chat.mod_ids:
|
||||||
abort(403, "Only the chat owner can change its name!")
|
abort(403, "You need to be the chat owner or a mod to do that!")
|
||||||
|
|
||||||
new_name = request.values.get("new_name").strip()
|
new_name = request.values.get("new_name").strip()
|
||||||
|
|
||||||
|
@ -158,6 +159,12 @@ def leave_chat(v, chat_id):
|
||||||
|
|
||||||
g.db.delete(membership)
|
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!"}
|
return {"message": "Chat left successfully!"}
|
||||||
|
|
||||||
@app.post("/chat/<int:chat_id>/toggle_mute")
|
@app.post("/chat/<int:chat_id>/toggle_mute")
|
||||||
|
@ -197,8 +204,8 @@ def chat_custom_css_get(v, chat_id):
|
||||||
if not chat:
|
if not chat:
|
||||||
abort(404, "Chat not found!")
|
abort(404, "Chat not found!")
|
||||||
|
|
||||||
if v.id != chat.owner_id:
|
if v.id not in chat.mod_ids:
|
||||||
abort(403, "Only the chat owner can change its custom css!")
|
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)
|
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:
|
if not chat:
|
||||||
abort(404, "Chat not found!")
|
abort(404, "Chat not found!")
|
||||||
|
|
||||||
if v.id != chat.owner_id:
|
if v.id not in chat.mod_ids:
|
||||||
abort(403, "Only the chat owner can change its custom css!")
|
abort(403, "You need to be the chat owner or a mod to do that!")
|
||||||
|
|
||||||
if v.shadowbanned: abort(400)
|
if v.shadowbanned: abort(400)
|
||||||
|
|
||||||
|
@ -257,8 +264,8 @@ def orgy_control(v, chat_id):
|
||||||
if chat.id == 1:
|
if chat.id == 1:
|
||||||
if v.admin_level < PERMS["ORGIES"]:
|
if v.admin_level < PERMS["ORGIES"]:
|
||||||
abort(403, "Your admin-level is not sufficient enough for this action!")
|
abort(403, "Your admin-level is not sufficient enough for this action!")
|
||||||
elif v.id != chat.owner_id:
|
elif v.id not in chat.mod_ids:
|
||||||
abort(403, "Only the chat owner can manage its orgies!")
|
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()
|
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)
|
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 chat.id == 1:
|
||||||
if v.admin_level < PERMS["ORGIES"]:
|
if v.admin_level < PERMS["ORGIES"]:
|
||||||
abort(403, "Your admin-level is not sufficient enough for this action!")
|
abort(403, "Your admin-level is not sufficient enough for this action!")
|
||||||
elif v.id != chat.owner_id:
|
elif v.id not in chat.mod_ids:
|
||||||
abort(403, "Only the chat owner can manage its orgies!")
|
abort(403, "You need to be the chat owner or a mod to do that!")
|
||||||
|
|
||||||
link = request.values.get("link", "").strip()
|
link = request.values.get("link", "").strip()
|
||||||
title = request.values.get("title", "").strip()
|
title = request.values.get("title", "").strip()
|
||||||
|
@ -374,8 +381,8 @@ def remove_orgy(v, created_utc, chat_id):
|
||||||
if chat.id == 1:
|
if chat.id == 1:
|
||||||
if v.admin_level < PERMS["ORGIES"]:
|
if v.admin_level < PERMS["ORGIES"]:
|
||||||
abort(403, "Your admin-level is not sufficient enough for this action!")
|
abort(403, "Your admin-level is not sufficient enough for this action!")
|
||||||
elif v.id != chat.owner_id:
|
elif v.id not in chat.mod_ids:
|
||||||
abort(403, "Only the chat owner can manage its orgies!")
|
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()
|
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>
|
<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>
|
<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 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>
|
</button>
|
||||||
|
|
||||||
|
@ -84,11 +84,13 @@
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if user.id == chat.owner_id %}
|
{% 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 %}
|
{% endif %}
|
||||||
|
|
||||||
{% if membership.muted %}
|
{% 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 %}
|
{% endif %}
|
||||||
|
|
||||||
<i class="d-none ml-1 text-smaller text-success online-marker online-marker-{{user.id}} fas fa-circle"></i>
|
<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>
|
</a>
|
||||||
|
|
||||||
{% if user.id == chat.owner_id %}
|
{% 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 %}
|
{% endif %}
|
||||||
|
|
||||||
{% if membership.muted %}
|
{% 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 %}
|
{% endif %}
|
||||||
|
|
||||||
<i class="d-none ml-1 text-smaller text-success online-marker online-marker-{{user.id}} fas fa-circle"></i>
|
<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>
|
<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>
|
<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}}/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>
|
<a href="/chat/{{chat.id}}/custom_css" class="chat-control fas fa-palette text-muted ml-2"></a>
|
||||||
|
@ -95,11 +95,13 @@
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{% if user.id == chat.owner_id %}
|
{% 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 %}
|
{% endif %}
|
||||||
|
|
||||||
{% if membership.muted %}
|
{% 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 %}
|
{% endif %}
|
||||||
|
|
||||||
<i class="d-none ml-1 text-smaller text-success online-marker online-marker-{{user.id}} fas fa-circle"></i>
|
<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