Update.
This commit is contained in:
parent
26a54848f1
commit
3ea4918ca2
@ -41,7 +41,7 @@ from snek.system.template import (
|
|||||||
)
|
)
|
||||||
from snek.view.about import AboutHTMLView, AboutMDView
|
from snek.view.about import AboutHTMLView, AboutMDView
|
||||||
from snek.view.avatar import AvatarView
|
from snek.view.avatar import AvatarView
|
||||||
from snek.view.channel import ChannelAttachmentView, ChannelView
|
from snek.view.channel import ChannelAttachmentView,ChannelAttachmentUploadView, ChannelView
|
||||||
from snek.view.docs import DocsHTMLView, DocsMDView
|
from snek.view.docs import DocsHTMLView, DocsMDView
|
||||||
from snek.view.drive import DriveApiView, DriveView
|
from snek.view.drive import DriveApiView, DriveView
|
||||||
from snek.view.index import IndexView
|
from snek.view.index import IndexView
|
||||||
@ -211,10 +211,10 @@ class Application(BaseApplication):
|
|||||||
# app.loop = asyncio.get_running_loop()
|
# app.loop = asyncio.get_running_loop()
|
||||||
app.executor = ThreadPoolExecutor(max_workers=200)
|
app.executor = ThreadPoolExecutor(max_workers=200)
|
||||||
app.loop.set_default_executor(self.executor)
|
app.loop.set_default_executor(self.executor)
|
||||||
for sig in (signal.SIGINT, signal.SIGTERM):
|
#for sig in (signal.SIGINT, signal.SIGTERM):
|
||||||
app.loop.add_signal_handler(
|
#app.loop.add_signal_handler(
|
||||||
sig, lambda: asyncio.create_task(self.services.container.shutdown())
|
# sig, lambda: asyncio.create_task(self.services.container.shutdown())
|
||||||
)
|
#)
|
||||||
|
|
||||||
async def create_task(self, task):
|
async def create_task(self, task):
|
||||||
await self.tasks.put(task)
|
await self.tasks.put(task)
|
||||||
@ -286,6 +286,9 @@ class Application(BaseApplication):
|
|||||||
self.router.add_view(
|
self.router.add_view(
|
||||||
"/channel/{channel_uid}/attachment.bin", ChannelAttachmentView
|
"/channel/{channel_uid}/attachment.bin", ChannelAttachmentView
|
||||||
)
|
)
|
||||||
|
self.router.add_view(
|
||||||
|
"/channel/{channel_uid}/attachment.sock", ChannelAttachmentUploadView
|
||||||
|
)
|
||||||
self.router.add_view(
|
self.router.add_view(
|
||||||
"/channel/attachment/{relative_url:.*}", ChannelAttachmentView
|
"/channel/attachment/{relative_url:.*}", ChannelAttachmentView
|
||||||
)
|
)
|
||||||
|
@ -180,7 +180,13 @@ class ChatInputComponent extends NjetComponent {
|
|||||||
this.uploadButton.addEventListener("uploaded", (e) => {
|
this.uploadButton.addEventListener("uploaded", (e) => {
|
||||||
this.dispatchEvent(new CustomEvent("uploaded", e));
|
this.dispatchEvent(new CustomEvent("uploaded", e));
|
||||||
});
|
});
|
||||||
|
this.uploadButton.addEventListener("click", (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
this.fileUploadGrid.openFileDialog()
|
||||||
|
|
||||||
|
})
|
||||||
this.subscribe("file-uploading", (e) => {
|
this.subscribe("file-uploading", (e) => {
|
||||||
|
|
||||||
this.fileUploadGrid.style.display = "block";
|
this.fileUploadGrid.style.display = "block";
|
||||||
|
|
||||||
this.uploadButton.style.display = "none";
|
this.uploadButton.style.display = "none";
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { NjetComponent, NjetDialog } from './njet.js';
|
import { NjetComponent, NjetDialog } from '/njet.js';
|
||||||
|
|
||||||
const FUG_ICONS = {
|
const FUG_ICONS = {
|
||||||
file: 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48"><rect x="8" y="8" width="32" height="40" rx="5" fill="white" stroke="%234af" stroke-width="2"/></svg>'
|
file: 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48"><rect x="8" y="8" width="32" height="40" rx="5" fill="white" stroke="%234af" stroke-width="2"/></svg>'
|
||||||
@ -9,8 +9,11 @@ class FileUploadGrid extends NjetComponent {
|
|||||||
super();
|
super();
|
||||||
this._grid = null;
|
this._grid = null;
|
||||||
this._fileInput = null;
|
this._fileInput = null;
|
||||||
|
this.channelUid = null ;
|
||||||
|
this.uploadsDone = 0;
|
||||||
|
this.uploadsStarted = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
openFileDialog() {
|
openFileDialog() {
|
||||||
if(this.isBusy){
|
if(this.isBusy){
|
||||||
const dialog = new NjetDialog({
|
const dialog = new NjetDialog({
|
||||||
@ -33,11 +36,6 @@ class FileUploadGrid extends NjetComponent {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
|
||||||
this.render();
|
|
||||||
this._fileInput.addEventListener('change', e => this.handleFiles(e.target.files));
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
// Root wrapper for styling
|
// Root wrapper for styling
|
||||||
this.classList.add('fug-root');
|
this.classList.add('fug-root');
|
||||||
@ -55,8 +53,6 @@ class FileUploadGrid extends NjetComponent {
|
|||||||
this.appendChild(this._grid);
|
this.appendChild(this._grid);
|
||||||
this.uploadsDone = 0;
|
this.uploadsDone = 0;
|
||||||
this.uploadsStarted = 0;
|
this.uploadsStarted = 0;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
reset(){
|
reset(){
|
||||||
@ -75,6 +71,11 @@ class FileUploadGrid extends NjetComponent {
|
|||||||
this.uploadsStarted = files.length;
|
this.uploadsStarted = files.length;
|
||||||
[...files].forEach(file => this.createTile(file));
|
[...files].forEach(file => this.createTile(file));
|
||||||
}
|
}
|
||||||
|
connectedCallback() {
|
||||||
|
this.channelUid = this.getAttribute('channel');
|
||||||
|
this.render();
|
||||||
|
this._fileInput.addEventListener('change', e => this.handleFiles(e.target.files));
|
||||||
|
}
|
||||||
|
|
||||||
createTile(file) {
|
createTile(file) {
|
||||||
const tile = document.createElement('div');
|
const tile = document.createElement('div');
|
||||||
@ -128,9 +129,10 @@ 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});
|
||||||
|
|
||||||
const ws = new WebSocket(`ws://${location.host}/ws`);
|
const protocol = location.protocol === "https:" ? "wss://" : "ws://";
|
||||||
ws.binaryType = 'arraybuffer';
|
const ws = new WebSocket(`${protocol}${location.host}/channel/${this.channelUid}/attachment.sock`);
|
||||||
|
ws.binaryType = 'arraybuffer';
|
||||||
let sent = 0;
|
let sent = 0;
|
||||||
|
|
||||||
ws.onopen = async () => {
|
ws.onopen = async () => {
|
||||||
|
@ -19,15 +19,17 @@ class ComposeFileManager:
|
|||||||
|
|
||||||
async def shutdown(self):
|
async def shutdown(self):
|
||||||
print("Stopping all sessions")
|
print("Stopping all sessions")
|
||||||
|
|
||||||
|
tasks = []
|
||||||
for name in self.list_instances():
|
for name in self.list_instances():
|
||||||
proc = self.running_instances.get(name)
|
proc = self.running_instances.get(name)
|
||||||
if not proc:
|
if not proc:
|
||||||
continue
|
continue
|
||||||
if proc['proc'].returncode == None:
|
if proc['proc'].returncode == None:
|
||||||
print("Stopping",name)
|
print("Stopping",name)
|
||||||
await proc['proc'].stop()
|
tasks.append(asyncio.create_task(proc['proc'].stop()))
|
||||||
print("Stopped",name,"gracefully")
|
print("Stopped",name,"gracefully")
|
||||||
|
return tasks
|
||||||
def _load(self):
|
def _load(self):
|
||||||
try:
|
try:
|
||||||
with open(self.compose_path) as f:
|
with open(self.compose_path) as f:
|
||||||
|
@ -146,6 +146,56 @@ class ChannelAttachmentView(BaseView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ChannelAttachmentUploadView(BaseView):
|
||||||
|
|
||||||
|
|
||||||
|
async def get(self):
|
||||||
|
|
||||||
|
channel_uid = self.request.match_info.get("channel_uid")
|
||||||
|
user_uid = self.request.session.get("uid")
|
||||||
|
|
||||||
|
channel_member = await self.services.channel_member.get(
|
||||||
|
user_uid=user_uid, channel_uid=channel_uid, deleted_at=None, is_banned=False
|
||||||
|
)
|
||||||
|
|
||||||
|
if not channel_member:
|
||||||
|
return web.HTTPNotFound()
|
||||||
|
|
||||||
|
ws = web.WebSocketResponse()
|
||||||
|
await ws.prepare(self.request)
|
||||||
|
|
||||||
|
file = None
|
||||||
|
filename = None
|
||||||
|
|
||||||
|
|
||||||
|
msg = await ws.receive()
|
||||||
|
if not msg.type == web.WSMsgType.TEXT:
|
||||||
|
return web.HTTPBadRequest()
|
||||||
|
|
||||||
|
data = msg.json()
|
||||||
|
if not data.get('type') == 'start':
|
||||||
|
return web.HTTPBadRequest()
|
||||||
|
|
||||||
|
filename = data['filename']
|
||||||
|
attachment = await self.services.channel_attachment.create_file(
|
||||||
|
channel_uid=channel_uid, name=filename, user_uid=user_uid
|
||||||
|
)
|
||||||
|
pathlib.Path(attachment["path"]).parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
async with aiofiles.open(attachment["path"], "wb") as f:
|
||||||
|
async for msg in ws:
|
||||||
|
if msg.type == web.WSMsgType.BINARY:
|
||||||
|
if file is not None:
|
||||||
|
await file.write(msg.data)
|
||||||
|
await ws.send_json({"type": "progress", "filename": filename, "bytes": file.tell()})
|
||||||
|
elif msg.type == web.WSMsgType.TEXT:
|
||||||
|
data = msg.json()
|
||||||
|
if data.get('type') == 'end':
|
||||||
|
await ws.send_json({"type": "done", "filename": filename})
|
||||||
|
elif msg.type == web.WSMsgType.ERROR:
|
||||||
|
break
|
||||||
|
return ws
|
||||||
|
|
||||||
|
|
||||||
class ChannelView(BaseView):
|
class ChannelView(BaseView):
|
||||||
async def get(self):
|
async def get(self):
|
||||||
channel_name = self.request.match_info.get("channel")
|
channel_name = self.request.match_info.get("channel")
|
||||||
|
@ -509,8 +509,7 @@ class RPCView(BaseView):
|
|||||||
async for msg in ws:
|
async for msg in ws:
|
||||||
if msg.type == web.WSMsgType.TEXT:
|
if msg.type == web.WSMsgType.TEXT:
|
||||||
try:
|
try:
|
||||||
async with Profiler():
|
await rpc(msg.json())
|
||||||
await rpc(msg.json())
|
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
print("Deleting socket", ex, flush=True)
|
print("Deleting socket", ex, flush=True)
|
||||||
logger.exception(ex)
|
logger.exception(ex)
|
||||||
|
Loading…
Reference in New Issue
Block a user