Update.
This commit is contained in:
parent
26a54848f1
commit
3ea4918ca2
src/snek
@ -41,7 +41,7 @@ from snek.system.template import (
|
||||
)
|
||||
from snek.view.about import AboutHTMLView, AboutMDView
|
||||
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.drive import DriveApiView, DriveView
|
||||
from snek.view.index import IndexView
|
||||
@ -211,10 +211,10 @@ class Application(BaseApplication):
|
||||
# app.loop = asyncio.get_running_loop()
|
||||
app.executor = ThreadPoolExecutor(max_workers=200)
|
||||
app.loop.set_default_executor(self.executor)
|
||||
for sig in (signal.SIGINT, signal.SIGTERM):
|
||||
app.loop.add_signal_handler(
|
||||
sig, lambda: asyncio.create_task(self.services.container.shutdown())
|
||||
)
|
||||
#for sig in (signal.SIGINT, signal.SIGTERM):
|
||||
#app.loop.add_signal_handler(
|
||||
# sig, lambda: asyncio.create_task(self.services.container.shutdown())
|
||||
#)
|
||||
|
||||
async def create_task(self, task):
|
||||
await self.tasks.put(task)
|
||||
@ -286,6 +286,9 @@ class Application(BaseApplication):
|
||||
self.router.add_view(
|
||||
"/channel/{channel_uid}/attachment.bin", ChannelAttachmentView
|
||||
)
|
||||
self.router.add_view(
|
||||
"/channel/{channel_uid}/attachment.sock", ChannelAttachmentUploadView
|
||||
)
|
||||
self.router.add_view(
|
||||
"/channel/attachment/{relative_url:.*}", ChannelAttachmentView
|
||||
)
|
||||
|
@ -180,7 +180,13 @@ class ChatInputComponent extends NjetComponent {
|
||||
this.uploadButton.addEventListener("uploaded", (e) => {
|
||||
this.dispatchEvent(new CustomEvent("uploaded", e));
|
||||
});
|
||||
this.uploadButton.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
this.fileUploadGrid.openFileDialog()
|
||||
|
||||
})
|
||||
this.subscribe("file-uploading", (e) => {
|
||||
|
||||
this.fileUploadGrid.style.display = "block";
|
||||
|
||||
this.uploadButton.style.display = "none";
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { NjetComponent, NjetDialog } from './njet.js';
|
||||
import { NjetComponent, NjetDialog } from '/njet.js';
|
||||
|
||||
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>'
|
||||
@ -9,8 +9,11 @@ class FileUploadGrid extends NjetComponent {
|
||||
super();
|
||||
this._grid = null;
|
||||
this._fileInput = null;
|
||||
this.channelUid = null ;
|
||||
this.uploadsDone = 0;
|
||||
this.uploadsStarted = 0;
|
||||
}
|
||||
|
||||
|
||||
openFileDialog() {
|
||||
if(this.isBusy){
|
||||
const dialog = new NjetDialog({
|
||||
@ -33,11 +36,6 @@ class FileUploadGrid extends NjetComponent {
|
||||
return true;
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.render();
|
||||
this._fileInput.addEventListener('change', e => this.handleFiles(e.target.files));
|
||||
}
|
||||
|
||||
render() {
|
||||
// Root wrapper for styling
|
||||
this.classList.add('fug-root');
|
||||
@ -55,8 +53,6 @@ class FileUploadGrid extends NjetComponent {
|
||||
this.appendChild(this._grid);
|
||||
this.uploadsDone = 0;
|
||||
this.uploadsStarted = 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
reset(){
|
||||
@ -75,6 +71,11 @@ class FileUploadGrid extends NjetComponent {
|
||||
this.uploadsStarted = files.length;
|
||||
[...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) {
|
||||
const tile = document.createElement('div');
|
||||
@ -128,9 +129,10 @@ class FileUploadGrid extends NjetComponent {
|
||||
startUpload(file, tile, progress) {
|
||||
|
||||
this.publish('file-uploading', {file: file, tile: tile, progress: progress});
|
||||
|
||||
const ws = new WebSocket(`ws://${location.host}/ws`);
|
||||
ws.binaryType = 'arraybuffer';
|
||||
|
||||
const protocol = location.protocol === "https:" ? "wss://" : "ws://";
|
||||
const ws = new WebSocket(`${protocol}${location.host}/channel/${this.channelUid}/attachment.sock`);
|
||||
ws.binaryType = 'arraybuffer';
|
||||
let sent = 0;
|
||||
|
||||
ws.onopen = async () => {
|
||||
|
@ -19,15 +19,17 @@ class ComposeFileManager:
|
||||
|
||||
async def shutdown(self):
|
||||
print("Stopping all sessions")
|
||||
|
||||
tasks = []
|
||||
for name in self.list_instances():
|
||||
proc = self.running_instances.get(name)
|
||||
if not proc:
|
||||
continue
|
||||
if proc['proc'].returncode == None:
|
||||
print("Stopping",name)
|
||||
await proc['proc'].stop()
|
||||
tasks.append(asyncio.create_task(proc['proc'].stop()))
|
||||
print("Stopped",name,"gracefully")
|
||||
|
||||
return tasks
|
||||
def _load(self):
|
||||
try:
|
||||
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):
|
||||
async def get(self):
|
||||
channel_name = self.request.match_info.get("channel")
|
||||
|
@ -509,8 +509,7 @@ class RPCView(BaseView):
|
||||
async for msg in ws:
|
||||
if msg.type == web.WSMsgType.TEXT:
|
||||
try:
|
||||
async with Profiler():
|
||||
await rpc(msg.json())
|
||||
await rpc(msg.json())
|
||||
except Exception as ex:
|
||||
print("Deleting socket", ex, flush=True)
|
||||
logger.exception(ex)
|
||||
|
Loading…
Reference in New Issue
Block a user