139 lines
4.6 KiB
Python
139 lines
4.6 KiB
Python
import pathlib
|
|
from datetime import datetime
|
|
|
|
from snek.system.model import now
|
|
from snek.system.service import BaseService
|
|
|
|
|
|
class ChannelService(BaseService):
|
|
mapper_name = "channel"
|
|
|
|
async def get_home_folder(self, channel_uid):
|
|
folder = pathlib.Path(f"./drive/{channel_uid}/container/home")
|
|
if not folder.exists():
|
|
try:
|
|
folder.mkdir(parents=True, exist_ok=True)
|
|
except:
|
|
pass
|
|
return folder
|
|
|
|
async def get_attachment_folder(self, channel_uid, ensure=False):
|
|
path = pathlib.Path(f"./drive/{channel_uid}/attachments")
|
|
if ensure:
|
|
path.mkdir(parents=True, exist_ok=True)
|
|
return path
|
|
|
|
async def get(self, uid=None, **kwargs):
|
|
if uid:
|
|
kwargs["uid"] = uid
|
|
result = await super().get(**kwargs)
|
|
if result:
|
|
return result
|
|
del kwargs["uid"]
|
|
kwargs["name"] = uid
|
|
result = await super().get(**kwargs)
|
|
if result:
|
|
return result
|
|
kwargs["name"] = "#" + uid
|
|
result = await super().get(**kwargs)
|
|
if result:
|
|
return result
|
|
return None
|
|
return await super().get(**kwargs)
|
|
|
|
async def create(
|
|
self,
|
|
label,
|
|
created_by_uid,
|
|
description=None,
|
|
tag=None,
|
|
is_private=False,
|
|
is_listed=True,
|
|
):
|
|
if label[0] != "#" and is_listed:
|
|
label = f"#{label}"
|
|
count = await self.count(deleted_at=None)
|
|
if not tag and not count:
|
|
tag = "public"
|
|
model = await self.new()
|
|
model["label"] = label
|
|
model["description"] = description
|
|
model["tag"] = tag
|
|
model["created_by_uid"] = created_by_uid
|
|
model["is_private"] = is_private
|
|
model["is_listed"] = is_listed
|
|
if await self.save(model):
|
|
await self.services.container.create(model["uid"])
|
|
return model
|
|
raise Exception(f"Failed to create channel: {model.errors}.")
|
|
|
|
async def get_dm(self, user1, user2):
|
|
channel_member = await self.services.channel_member.get_dm(user1, user2)
|
|
if channel_member:
|
|
return await self.get(uid=channel_member["channel_uid"])
|
|
channel = await self.create("DM", user1, tag="dm")
|
|
await self.services.channel_member.create_dm(channel["uid"], user1, user2)
|
|
return channel
|
|
|
|
async def get_recent_users(self, channel_uid):
|
|
async for user in self.query(
|
|
"SELECT user.uid, user.username,user.color,user.last_ping,user.nick FROM channel_member INNER JOIN user ON user.uid = channel_member.user_uid WHERE channel_uid=:channel_uid AND user.last_ping >= datetime('now', '-3 minutes') ORDER BY last_ping DESC LIMIT 30",
|
|
{"channel_uid": channel_uid},
|
|
):
|
|
yield user
|
|
|
|
async def get_users(self, channel_uid):
|
|
async for channel_member in self.services.channel_member.find(
|
|
channel_uid=channel_uid,
|
|
is_banned=False,
|
|
is_muted=False,
|
|
deleted_at=None,
|
|
):
|
|
user = await self.services.user.get(uid=channel_member["user_uid"])
|
|
if user:
|
|
yield user
|
|
|
|
async def get_online_users(self, channel_uid):
|
|
async for user in self.get_users(channel_uid):
|
|
if not user["last_ping"]:
|
|
continue
|
|
|
|
if (
|
|
datetime.fromisoformat(now())
|
|
- datetime.fromisoformat(user["last_ping"])
|
|
).total_seconds() < 180:
|
|
yield user
|
|
|
|
async def get_for_user(self, user_uid):
|
|
async for channel_member in self.services.channel_member.find(
|
|
user_uid=user_uid,
|
|
is_banned=False,
|
|
deleted_at=None,
|
|
):
|
|
channel = await self.get(uid=channel_member["channel_uid"])
|
|
yield channel
|
|
|
|
async def clear(self, channel_uid):
|
|
model = await self.get(uid=channel_uid)
|
|
model['history_from'] = datetime.now()
|
|
await self.save(model)
|
|
|
|
|
|
async def ensure_public_channel(self, created_by_uid):
|
|
model = await self.get(is_listed=True, tag="public")
|
|
is_moderator = False
|
|
if not model:
|
|
is_moderator = True
|
|
model = await self.create(
|
|
"public", created_by_uid=created_by_uid, is_listed=True, tag="public"
|
|
)
|
|
await self.app.services.channel_member.create(
|
|
model["uid"],
|
|
created_by_uid,
|
|
is_moderator=is_moderator,
|
|
is_read_only=False,
|
|
is_muted=False,
|
|
is_banned=False,
|
|
)
|
|
return model
|