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,6 +9,9 @@ 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() {
 | 
				
			||||||
@ -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');
 | 
				
			||||||
@ -129,8 +130,9 @@ class FileUploadGrid extends NjetComponent {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        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