114 lines
4.1 KiB
Python
114 lines
4.1 KiB
Python
from snek.system.service import BaseService
|
|
from snek.system.template import whitelist_attributes
|
|
|
|
|
|
class ChannelMessageService(BaseService):
|
|
mapper_name = "channel_message"
|
|
|
|
async def create(self, channel_uid, user_uid, message, is_final=True):
|
|
model = await self.new()
|
|
|
|
model["channel_uid"] = channel_uid
|
|
model["user_uid"] = user_uid
|
|
model["message"] = message
|
|
model['is_final'] = is_final
|
|
|
|
context = {}
|
|
|
|
record = model.record
|
|
context.update(record)
|
|
user = await self.app.services.user.get(uid=user_uid)
|
|
context.update(
|
|
{
|
|
"user_uid": user["uid"],
|
|
"username": user["username"],
|
|
"user_nick": user["nick"],
|
|
"color": user["color"],
|
|
}
|
|
)
|
|
try:
|
|
template = self.app.jinja2_env.get_template("message.html")
|
|
model["html"] = template.render(**context)
|
|
model["html"] = whitelist_attributes(model["html"])
|
|
except Exception as ex:
|
|
print(ex, flush=True)
|
|
|
|
if await super().save(model):
|
|
return model
|
|
raise Exception(f"Failed to create channel message: {model.errors}.")
|
|
|
|
async def to_extended_dict(self, message):
|
|
user = await self.services.user.get(uid=message["user_uid"])
|
|
if not user:
|
|
return {}
|
|
return {
|
|
"uid": message["uid"],
|
|
"color": user["color"],
|
|
"user_uid": message["user_uid"],
|
|
"channel_uid": message["channel_uid"],
|
|
"user_nick": user["nick"],
|
|
"message": message["message"],
|
|
"created_at": message["created_at"],
|
|
"html": message["html"],
|
|
"username": user["username"],
|
|
}
|
|
|
|
async def save(self, model):
|
|
context = {}
|
|
context.update(model.record)
|
|
user = await self.app.services.user.get(model['user_uid'])
|
|
context.update(
|
|
{
|
|
"user_uid": user["uid"],
|
|
"username": user["username"],
|
|
"user_nick": user["nick"],
|
|
"color": user["color"],
|
|
}
|
|
)
|
|
template = self.app.jinja2_env.get_template("message.html")
|
|
model["html"] = template.render(**context)
|
|
model["html"] = whitelist_attributes(model["html"])
|
|
return await super().save(model)
|
|
|
|
async def offset(self, channel_uid, page=0, timestamp=None, page_size=30):
|
|
results = []
|
|
offset = page * page_size
|
|
try:
|
|
if timestamp:
|
|
async for model in self.query(
|
|
"SELECT * FROM channel_message WHERE channel_uid=:channel_uid AND created_at < :timestamp ORDER BY created_at DESC LIMIT :page_size OFFSET :offset",
|
|
{
|
|
"channel_uid": channel_uid,
|
|
"page_size": page_size,
|
|
"offset": offset,
|
|
"timestamp": timestamp,
|
|
},
|
|
):
|
|
results.append(model)
|
|
elif page > 0:
|
|
async for model in self.query(
|
|
"SELECT * FROM channel_message WHERE channel_uid=:channel_uid WHERE created_at < :timestamp ORDER BY created_at DESC LIMIT :page_size",
|
|
{
|
|
"channel_uid": channel_uid,
|
|
"page_size": page_size,
|
|
"offset": offset,
|
|
"timestamp": timestamp,
|
|
},
|
|
):
|
|
results.append(model)
|
|
else:
|
|
async for model in self.query(
|
|
"SELECT * FROM channel_message WHERE channel_uid=:channel_uid ORDER BY created_at DESC LIMIT :page_size OFFSET :offset",
|
|
{
|
|
"channel_uid": channel_uid,
|
|
"page_size": page_size,
|
|
"offset": offset,
|
|
},
|
|
):
|
|
results.append(model)
|
|
|
|
except:
|
|
pass
|
|
results.sort(key=lambda x: x["created_at"])
|
|
return results
|