Compare commits
No commits in common. "75f12c1971e23ea7b3f63a88eeb2426bcfb70e03" and "c53b93055470338dbc33774dd03d5c48ed3ce5b0" have entirely different histories.
75f12c1971
...
c53b930554
@ -11,15 +11,11 @@ class ChannelModel(BaseModel):
|
|||||||
is_listed = ModelField(name="is_listed", required=True, kind=bool, value=True)
|
is_listed = ModelField(name="is_listed", required=True, kind=bool, value=True)
|
||||||
index = ModelField(name="index", required=True, kind=int, value=1000)
|
index = ModelField(name="index", required=True, kind=int, value=1000)
|
||||||
last_message_on = ModelField(name="last_message_on", required=False, kind=str)
|
last_message_on = ModelField(name="last_message_on", required=False, kind=str)
|
||||||
history_start = ModelField(name="history_start", required=False, kind=str)
|
|
||||||
|
|
||||||
async def get_last_message(self) -> ChannelMessageModel:
|
async def get_last_message(self) -> ChannelMessageModel:
|
||||||
history_start_filter = ""
|
|
||||||
if self["history_start"]:
|
|
||||||
history_start_filter = f" AND created_at > '{self['history_start']}' "
|
|
||||||
try:
|
try:
|
||||||
async for model in self.app.services.channel_message.query(
|
async for model in self.app.services.channel_message.query(
|
||||||
"SELECT uid FROM channel_message WHERE channel_uid=:channel_uid" + history_start_filter + " ORDER BY created_at DESC LIMIT 1",
|
"SELECT uid FROM channel_message WHERE channel_uid=:channel_uid ORDER BY created_at DESC LIMIT 1",
|
||||||
{"channel_uid": self["uid"]},
|
{"channel_uid": self["uid"]},
|
||||||
):
|
):
|
||||||
|
|
||||||
|
|||||||
@ -88,18 +88,12 @@ class ChannelMessageService(BaseService):
|
|||||||
return await super().save(model)
|
return await super().save(model)
|
||||||
|
|
||||||
async def offset(self, channel_uid, page=0, timestamp=None, page_size=30):
|
async def offset(self, channel_uid, page=0, timestamp=None, page_size=30):
|
||||||
channel = await self.services.channel.get(uid=channel_uid)
|
|
||||||
if not channel:
|
|
||||||
return []
|
|
||||||
history_start_filter = ""
|
|
||||||
if channel["history_start"]:
|
|
||||||
history_start_filter = f" AND created_at > '{channel['history_start']}'"
|
|
||||||
results = []
|
results = []
|
||||||
offset = page * page_size
|
offset = page * page_size
|
||||||
try:
|
try:
|
||||||
if timestamp:
|
if timestamp:
|
||||||
async for model in self.query(
|
async for model in self.query(
|
||||||
f"SELECT * FROM channel_message WHERE channel_uid=:channel_uid AND created_at < :timestamp {history_start_filter} ORDER BY created_at DESC LIMIT :page_size OFFSET :offset",
|
"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,
|
"channel_uid": channel_uid,
|
||||||
"page_size": page_size,
|
"page_size": page_size,
|
||||||
@ -110,7 +104,7 @@ class ChannelMessageService(BaseService):
|
|||||||
results.append(model)
|
results.append(model)
|
||||||
elif page > 0:
|
elif page > 0:
|
||||||
async for model in self.query(
|
async for model in self.query(
|
||||||
f"SELECT * FROM channel_message WHERE channel_uid=:channel_uid WHERE created_at < :timestamp {history_start_filter} ORDER BY created_at DESC LIMIT :page_size",
|
"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,
|
"channel_uid": channel_uid,
|
||||||
"page_size": page_size,
|
"page_size": page_size,
|
||||||
@ -121,7 +115,7 @@ class ChannelMessageService(BaseService):
|
|||||||
results.append(model)
|
results.append(model)
|
||||||
else:
|
else:
|
||||||
async for model in self.query(
|
async for model in self.query(
|
||||||
f"SELECT * FROM channel_message WHERE channel_uid=:channel_uid {history_start_filter} ORDER BY created_at DESC LIMIT :page_size OFFSET :offset",
|
"SELECT * FROM channel_message WHERE channel_uid=:channel_uid ORDER BY created_at DESC LIMIT :page_size OFFSET :offset",
|
||||||
{
|
{
|
||||||
"channel_uid": channel_uid,
|
"channel_uid": channel_uid,
|
||||||
"page_size": page_size,
|
"page_size": page_size,
|
||||||
@ -130,7 +124,7 @@ class ChannelMessageService(BaseService):
|
|||||||
):
|
):
|
||||||
results.append(model)
|
results.append(model)
|
||||||
|
|
||||||
except Exception as ex:
|
except:
|
||||||
print(ex)
|
pass
|
||||||
results.sort(key=lambda x: x["created_at"])
|
results.sort(key=lambda x: x["created_at"])
|
||||||
return results
|
return results
|
||||||
|
|||||||
@ -12,7 +12,6 @@ class UserService(BaseService):
|
|||||||
|
|
||||||
async def search(self, query, **kwargs):
|
async def search(self, query, **kwargs):
|
||||||
query = query.strip().lower()
|
query = query.strip().lower()
|
||||||
kwarggs["deleted_at"] = None
|
|
||||||
if not query:
|
if not query:
|
||||||
return []
|
return []
|
||||||
results = []
|
results = []
|
||||||
|
|||||||
@ -181,8 +181,8 @@ class ChatInputComponent extends NjetComponent {
|
|||||||
this.dispatchEvent(new CustomEvent("uploaded", e));
|
this.dispatchEvent(new CustomEvent("uploaded", e));
|
||||||
});
|
});
|
||||||
this.uploadButton.addEventListener("click", (e) => {
|
this.uploadButton.addEventListener("click", (e) => {
|
||||||
e.preventDefault();
|
// e.preventDefault();
|
||||||
this.fileUploadGrid.openFileDialog()
|
// this.fileUploadGrid.openFileDialog()
|
||||||
|
|
||||||
})
|
})
|
||||||
this.subscribe("file-uploading", (e) => {
|
this.subscribe("file-uploading", (e) => {
|
||||||
|
|||||||
@ -130,8 +130,7 @@ class FileUploadGrid extends NjetComponent {
|
|||||||
startUpload(file, tile, progress) {
|
startUpload(file, tile, progress) {
|
||||||
|
|
||||||
this.publish('file-uploading', {file: file, tile: tile, progress: progress});
|
this.publish('file-uploading', {file: file, tile: tile, progress: progress});
|
||||||
console.info("File uploading",file)
|
|
||||||
|
|
||||||
const protocol = location.protocol === "https:" ? "wss://" : "ws://";
|
const protocol = location.protocol === "https:" ? "wss://" : "ws://";
|
||||||
const ws = new WebSocket(`${protocol}${location.host}/channel/${this.channelUid}/attachment.sock`);
|
const ws = new WebSocket(`${protocol}${location.host}/channel/${this.channelUid}/attachment.sock`);
|
||||||
ws.binaryType = 'arraybuffer';
|
ws.binaryType = 'arraybuffer';
|
||||||
@ -149,7 +148,7 @@ class FileUploadGrid extends NjetComponent {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ws.onmessage = (event) => {
|
ws.onmessage = (event) => {
|
||||||
console.info(event.data)
|
|
||||||
|
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
if (data.type === 'progress') {
|
if (data.type === 'progress') {
|
||||||
@ -162,7 +161,7 @@ class FileUploadGrid extends NjetComponent {
|
|||||||
this.publish('file-uploaded', {file: file, tile: tile, progress: progress});
|
this.publish('file-uploaded', {file: file, tile: tile, progress: progress});
|
||||||
progress.style.width = '100%';
|
progress.style.width = '100%';
|
||||||
tile.classList.add('fug-done');
|
tile.classList.add('fug-done');
|
||||||
console.info("Closed")
|
|
||||||
ws.close();
|
ws.close();
|
||||||
|
|
||||||
this.reset()
|
this.reset()
|
||||||
|
|||||||
@ -112,9 +112,9 @@ class UploadButtonElement extends HTMLElement {
|
|||||||
this.channelUid = this.getAttribute("channel");
|
this.channelUid = this.getAttribute("channel");
|
||||||
this.uploadButton = this.container.querySelector(".upload-button");
|
this.uploadButton = this.container.querySelector(".upload-button");
|
||||||
this.fileInput = this.container.querySelector(".hidden-input");
|
this.fileInput = this.container.querySelector(".hidden-input");
|
||||||
/*this.uploadButton.addEventListener("click", () => {
|
this.uploadButton.addEventListener("click", () => {
|
||||||
this.fileInput.click();
|
this.fileInput.click();
|
||||||
});*/
|
});
|
||||||
this.fileInput.addEventListener("change", () => {
|
this.fileInput.addEventListener("change", () => {
|
||||||
this.uploadFiles();
|
this.uploadFiles();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -25,11 +25,9 @@ class BaseMapper:
|
|||||||
return asyncio.get_event_loop()
|
return asyncio.get_event_loop()
|
||||||
|
|
||||||
async def run_in_executor(self, func, *args, **kwargs):
|
async def run_in_executor(self, func, *args, **kwargs):
|
||||||
use_semaphore = kwargs.pop("use_semaphore", False)
|
async with self.semaphore:
|
||||||
if use_semaphore:
|
return func(*args, **kwargs)
|
||||||
async with self.semaphore:
|
# return await self.loop.run_in_executor(None, lambda: func(*args, **kwargs))
|
||||||
return func(*args, **kwargs)
|
|
||||||
return await self.loop.run_in_executor(None, lambda: func(*args, **kwargs))
|
|
||||||
|
|
||||||
async def new(self):
|
async def new(self):
|
||||||
return self.model_class(mapper=self, app=self.app)
|
return self.model_class(mapper=self, app=self.app)
|
||||||
@ -41,8 +39,7 @@ class BaseMapper:
|
|||||||
async def get(self, uid: str = None, **kwargs) -> BaseModel:
|
async def get(self, uid: str = None, **kwargs) -> BaseModel:
|
||||||
if uid:
|
if uid:
|
||||||
kwargs["uid"] = uid
|
kwargs["uid"] = uid
|
||||||
if not kwargs.get("deleted_at"):
|
|
||||||
kwargs["deleted_at"] = None
|
|
||||||
record = await self.run_in_executor(self.table.find_one, **kwargs)
|
record = await self.run_in_executor(self.table.find_one, **kwargs)
|
||||||
if not record:
|
if not record:
|
||||||
return None
|
return None
|
||||||
@ -51,6 +48,7 @@ class BaseMapper:
|
|||||||
for key, value in record.items():
|
for key, value in record.items():
|
||||||
model[key] = value
|
model[key] = value
|
||||||
return model
|
return model
|
||||||
|
return await self.model_class.from_record(mapper=self, record=record)
|
||||||
|
|
||||||
async def exists(self, **kwargs):
|
async def exists(self, **kwargs):
|
||||||
return await self.run_in_executor(self.table.exists, **kwargs)
|
return await self.run_in_executor(self.table.exists, **kwargs)
|
||||||
@ -62,39 +60,26 @@ class BaseMapper:
|
|||||||
if not model.record.get("uid"):
|
if not model.record.get("uid"):
|
||||||
raise Exception(f"Attempt to save without uid: {model.record}.")
|
raise Exception(f"Attempt to save without uid: {model.record}.")
|
||||||
model.updated_at.update()
|
model.updated_at.update()
|
||||||
return await self.run_in_executor(self.table.upsert, model.record, ["uid"],use_semaphore=True)
|
return await self.run_in_executor(self.table.upsert, model.record, ["uid"])
|
||||||
|
|
||||||
async def find(self, **kwargs) -> typing.AsyncGenerator:
|
async def find(self, **kwargs) -> typing.AsyncGenerator:
|
||||||
if not kwargs.get("_limit"):
|
if not kwargs.get("_limit"):
|
||||||
kwargs["_limit"] = self.default_limit
|
kwargs["_limit"] = self.default_limit
|
||||||
if not kwargs.get("deleted_at"):
|
|
||||||
kwargs["deleted_at"] = None
|
|
||||||
for record in await self.run_in_executor(self.table.find, **kwargs):
|
for record in await self.run_in_executor(self.table.find, **kwargs):
|
||||||
model = await self.new()
|
model = await self.new()
|
||||||
for key, value in record.items():
|
for key, value in record.items():
|
||||||
model[key] = value
|
model[key] = value
|
||||||
yield model
|
yield model
|
||||||
|
|
||||||
async def _use_semaphore(self, sql):
|
|
||||||
sql = sql.lower().strip()
|
|
||||||
return "insert" in sql or "update" in sql or "delete" in sql
|
|
||||||
|
|
||||||
async def query(self, sql, *args):
|
async def query(self, sql, *args):
|
||||||
for record in await self.run_in_executor(self.db.query, sql, *args, use_semaphore=await self._use_semaphore(sql)):
|
for record in await self.run_in_executor(self.db.query, sql, *args):
|
||||||
yield dict(record)
|
yield dict(record)
|
||||||
|
|
||||||
async def update(self, model):
|
async def update(self, model):
|
||||||
if not model["deleted_at"] is None:
|
|
||||||
raise Exception("Can't update deleted record.")
|
|
||||||
model.updated_at.update()
|
model.updated_at.update()
|
||||||
return await self.run_in_executor(self.table.update, model.record, ["uid"],use_semaphore=True)
|
return await self.run_in_executor(self.table.update, model.record, ["uid"])
|
||||||
|
|
||||||
async def upsert(self, model):
|
|
||||||
model.updated_at.update()
|
|
||||||
return await self.run_in_executor(self.table.upsert, model.record, ["uid"],use_semaphore=True)
|
|
||||||
|
|
||||||
async def delete(self, **kwargs) -> int:
|
async def delete(self, **kwargs) -> int:
|
||||||
if not kwargs or not isinstance(kwargs, dict):
|
if not kwargs or not isinstance(kwargs, dict):
|
||||||
raise Exception("Can't execute delete with no filter.")
|
raise Exception("Can't execute delete with no filter.")
|
||||||
kwargs["use_semaphore"] = True
|
|
||||||
return await self.run_in_executor(self.table.delete, **kwargs)
|
return await self.run_in_executor(self.table.delete, **kwargs)
|
||||||
|
|||||||
@ -18,7 +18,6 @@
|
|||||||
<script src="/generic-form.js" type="module"></script>
|
<script src="/generic-form.js" type="module"></script>
|
||||||
<script src="/html-frame.js" type="module"></script>
|
<script src="/html-frame.js" type="module"></script>
|
||||||
<script src="/app.js" type="module"></script>
|
<script src="/app.js" type="module"></script>
|
||||||
<script src="/editor.js" type="module"></script>
|
|
||||||
<script src="/file-manager.js" type="module"></script>
|
<script src="/file-manager.js" type="module"></script>
|
||||||
<script src="/user-list.js"></script>
|
<script src="/user-list.js"></script>
|
||||||
<script src="/message-list.js" type="module"></script>
|
<script src="/message-list.js" type="module"></script>
|
||||||
|
|||||||
@ -192,18 +192,13 @@ class ChannelAttachmentUploadView(BaseView):
|
|||||||
channel_uid=channel_uid, name=filename, user_uid=user_uid
|
channel_uid=channel_uid, name=filename, user_uid=user_uid
|
||||||
)
|
)
|
||||||
pathlib.Path(attachment["path"]).parent.mkdir(parents=True, exist_ok=True)
|
pathlib.Path(attachment["path"]).parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
async with aiofiles.open(attachment["path"], "wb") as f:
|
||||||
async with aiofiles.open(attachment["path"], "wb") as file:
|
|
||||||
print("File openend.", filename)
|
|
||||||
async for msg in ws:
|
async for msg in ws:
|
||||||
if msg.type == web.WSMsgType.BINARY:
|
if msg.type == web.WSMsgType.BINARY:
|
||||||
print("Binary",filename)
|
|
||||||
if file is not None:
|
if file is not None:
|
||||||
await file.write(msg.data)
|
await file.write(msg.data)
|
||||||
await ws.send_json({"type": "progress", "filename": filename, "bytes": await file.tell()})
|
await ws.send_json({"type": "progress", "filename": filename, "bytes": file.tell()})
|
||||||
elif msg.type == web.WSMsgType.TEXT:
|
elif msg.type == web.WSMsgType.TEXT:
|
||||||
print("TExt",filename)
|
|
||||||
print(msg.json())
|
|
||||||
data = msg.json()
|
data = msg.json()
|
||||||
if data.get('type') == 'end':
|
if data.get('type') == 'end':
|
||||||
await ws.send_json({"type": "done", "filename": filename})
|
await ws.send_json({"type": "done", "filename": filename})
|
||||||
|
|||||||
@ -202,14 +202,7 @@ class RPCView(BaseView):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
return channels
|
return channels
|
||||||
|
|
||||||
async def clear_channel(self, channel_uid):
|
|
||||||
self._require_login()
|
|
||||||
user = await self.services.user.get(uid=self.user_uid)
|
|
||||||
if not user["is_admin"]:
|
|
||||||
raise Exception("Not allowed")
|
|
||||||
return await self.services.channel_message.clear(channel_uid)
|
|
||||||
|
|
||||||
async def write_container(self, channel_uid, content,timeout=3):
|
async def write_container(self, channel_uid, content,timeout=3):
|
||||||
self._require_login()
|
self._require_login()
|
||||||
channel_member = await self.services.channel_member.get(
|
channel_member = await self.services.channel_member.get(
|
||||||
|
|||||||
@ -71,7 +71,6 @@ class WebView(BaseView):
|
|||||||
await self.app.services.channel_member.save(channel_member)
|
await self.app.services.channel_member.save(channel_member)
|
||||||
|
|
||||||
user = await self.services.user.get(uid=self.session.get("uid"))
|
user = await self.services.user.get(uid=self.session.get("uid"))
|
||||||
|
|
||||||
messages = [
|
messages = [
|
||||||
await self.app.services.channel_message.to_extended_dict(message)
|
await self.app.services.channel_message.to_extended_dict(message)
|
||||||
for message in await self.app.services.channel_message.offset(
|
for message in await self.app.services.channel_message.offset(
|
||||||
@ -82,7 +81,7 @@ class WebView(BaseView):
|
|||||||
await self.app.services.notification.mark_as_read(
|
await self.app.services.notification.mark_as_read(
|
||||||
self.session.get("uid"), message["uid"]
|
self.session.get("uid"), message["uid"]
|
||||||
)
|
)
|
||||||
print(messages)
|
|
||||||
name = await channel_member.get_name()
|
name = await channel_member.get_name()
|
||||||
return await self.render_template(
|
return await self.render_template(
|
||||||
"web.html",
|
"web.html",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user