Update drive.
This commit is contained in:
parent
c5c160baae
commit
7b32a7eba4
Makefile
src/snek
2
Makefile
2
Makefile
@ -15,7 +15,7 @@ run:
|
||||
$(GUNICORN) -w $(GUNICORN_WORKERS) -k aiohttp.worker.GunicornWebWorker snek.gunicorn:app --bind 0.0.0.0:$(PORT) --reload
|
||||
|
||||
install:
|
||||
python3 -m venv .venv
|
||||
python3.12 -m venv .venv
|
||||
$(PIP) install -e .
|
||||
|
||||
|
||||
|
@ -38,6 +38,7 @@ from snek.view.search_user import SearchUserView
|
||||
from snek.view.avatar import AvatarView
|
||||
from snek.system.profiler import profiler_handler
|
||||
from snek.view.terminal import TerminalView, TerminalSocketView
|
||||
from snek.view.drive import DriveView
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
SESSION_KEY = b"c79a0c5fda4b424189c427d28c9f7c34"
|
||||
|
||||
@ -67,6 +68,13 @@ class Application(BaseApplication):
|
||||
self.jinja2_env.add_extension(EmojiExtension)
|
||||
|
||||
self.setup_router()
|
||||
|
||||
self.cache = Cache(self)
|
||||
self.services = get_services(app=self)
|
||||
self.mappers = get_mappers(app=self)
|
||||
self.on_startup.append(self.prepare_database)
|
||||
|
||||
async def prepare_database(self,app):
|
||||
self.db.query("PRAGMA journal_mode=WAL")
|
||||
self.db.query("PRAGMA syncnorm=off")
|
||||
|
||||
@ -79,10 +87,8 @@ class Application(BaseApplication):
|
||||
self.db["channel_message"].create_index(["channel_uid","user_uid"])
|
||||
except:
|
||||
pass
|
||||
|
||||
self.cache = Cache(self)
|
||||
self.services = get_services(app=self)
|
||||
self.mappers = get_mappers(app=self)
|
||||
|
||||
await app.services.drive.prepare_all()
|
||||
|
||||
def setup_router(self):
|
||||
self.router.add_get("/", IndexView)
|
||||
@ -117,6 +123,8 @@ class Application(BaseApplication):
|
||||
self.router.add_view("/threads.html", ThreadsView)
|
||||
self.router.add_view("/terminal.ws", TerminalSocketView)
|
||||
self.router.add_view("/terminal.html", TerminalView)
|
||||
self.router.add_view("/drive.json", DriveView)
|
||||
self.router.add_view("/drive/{drive}.json", DriveView)
|
||||
|
||||
self.add_subapp(
|
||||
"/docs",
|
||||
|
@ -4,4 +4,10 @@ from snek.system.model import BaseModel,ModelField
|
||||
class DriveModel(BaseModel):
|
||||
|
||||
user_uid = ModelField(name="user_uid", required=True)
|
||||
|
||||
name = ModelField(name='name', required=False, type=str)
|
||||
|
||||
@property
|
||||
async def items(self):
|
||||
async for drive_item in self.app.services.drive_item.find(drive_uid=self['uid']):
|
||||
yield drive_item
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
from snek.system.model import BaseModel,ModelField
|
||||
|
||||
import mimetypes
|
||||
|
||||
class DriveItemModel(BaseModel):
|
||||
drive_uid = ModelField(name="drive_uid", required=True,kind=str)
|
||||
@ -7,3 +7,12 @@ class DriveItemModel(BaseModel):
|
||||
path = ModelField(name="path", required=True,kind=str)
|
||||
file_type = ModelField(name="file_type", required=True,kind=str)
|
||||
file_size = ModelField(name="file_size", required=True,kind=int)
|
||||
|
||||
@property
|
||||
def extension(self):
|
||||
return self['name'].split('.')[-1]
|
||||
|
||||
@property
|
||||
def mime_type(self):
|
||||
mimetype,_ = mimetypes.guess_type(self['name'])
|
||||
return mimetype
|
||||
|
@ -5,17 +5,75 @@ class DriveService(BaseService):
|
||||
|
||||
mapper_name = "drive"
|
||||
|
||||
async def get_by_user(self, user_uid):
|
||||
drives = []
|
||||
async for model in self.find(user_uid=user_uid):
|
||||
drives.append(model)
|
||||
return drives
|
||||
EXTENSIONS_PICTURES = ["jpg","jpeg","png","gif","svg","webp","tiff"]
|
||||
EXTENSIONS_VIDEOS = ["mp4","m4v","mov","wmv","webm","mkv","mpg","mpeg","avi","ogv","ogg","flv","3gp","3g2"]
|
||||
EXTENSIONS_ARCHIVES = ["zip","rar","7z","tar","tar.gz","tar.xz","tar.bz2","tar.lzma","tar.lz"]
|
||||
EXTENSIONS_AUDIO = ["mp3","wav","ogg","flac","m4a","wma","aac","opus","aiff","au","mid","midi"]
|
||||
EXTENSIONS_DOCS = ["pdf","doc","docx","xls","xlsx","ppt","pptx","txt","md","json","csv","xml","html","css","js","py","sql","rs","toml","yml","yaml","ini","conf","config","log","csv","tsv","java","cs","csproj","scss","less","sass","json","lock","lock.json","jsonl"]
|
||||
|
||||
async def get_or_create(self, user_uid):
|
||||
drives = await self.get_by_user(user_uid=user_uid)
|
||||
if len(drives) == 0:
|
||||
model = await self.new()
|
||||
model['user_uid'] = user_uid
|
||||
await self.save(model)
|
||||
return model
|
||||
return drives[0]
|
||||
async def get_drive_name_by_extension(self, extension):
|
||||
if extension.startswith("."):
|
||||
extension = extension[1:]
|
||||
if extension in self.EXTENSIONS_PICTURES:
|
||||
return "Pictures"
|
||||
if extension in self.EXTENSIONS_VIDEOS:
|
||||
return "Videos"
|
||||
if extension in self.EXTENSIONS_ARCHIVES:
|
||||
return "Archives"
|
||||
if extension in self.EXTENSIONS_AUDIO:
|
||||
return "Audio"
|
||||
if extension in self.EXTENSIONS_DOCS:
|
||||
return "Documents"
|
||||
return "My Drive"
|
||||
|
||||
async def get_drive_by_extension(self,user_uid, extension):
|
||||
name = await self.get_drive_name_by_extension(extension)
|
||||
return await self.get_or_create(user_uid=user_uid,name=name)
|
||||
|
||||
async def get_by_user(self, user_uid,name=None):
|
||||
kwargs = dict(
|
||||
user_uid = user_uid
|
||||
)
|
||||
async for model in self.find(**kwargs):
|
||||
if not name:
|
||||
yield model
|
||||
elif model['name'] == name:
|
||||
yield model
|
||||
elif not model['name'] and name == 'My Drive':
|
||||
model['name'] = 'My Drive'
|
||||
await self.save(model)
|
||||
yield model
|
||||
|
||||
async def get_or_create(self, user_uid,name=None,extensions=None):
|
||||
kwargs = dict(user_uid=user_uid)
|
||||
if name:
|
||||
kwargs['name'] = name
|
||||
async for model in self.get_by_user(**kwargs):
|
||||
return model
|
||||
|
||||
model = await self.new()
|
||||
model['user_uid'] = user_uid
|
||||
model['name'] = name
|
||||
await self.save(model)
|
||||
return model
|
||||
|
||||
async def prepare_default_drives(self):
|
||||
async for drive_item in self.services.drive_item.find():
|
||||
extension = drive_item.extension
|
||||
drive = await self.get_drive_by_extension(drive_item['user_uid'],extension)
|
||||
if not drive_item['drive_uid'] == drive['uid']:
|
||||
drive_item['drive_uid'] = drive['uid']
|
||||
await self.services.drive_item.save(drive_item)
|
||||
|
||||
async def prepare_default_drives_for_user(self, user_uid):
|
||||
await self.get_or_create(user_uid=user_uid,name="My Drive")
|
||||
await self.get_or_create(user_uid=user_uid,name="Shared Drive")
|
||||
await self.get_or_create(user_uid=user_uid,name="Pictures")
|
||||
await self.get_or_create(user_uid=user_uid,name="Videos")
|
||||
await self.get_or_create(user_uid=user_uid,name="Archives")
|
||||
await self.get_or_create(user_uid=user_uid,name="Documents")
|
||||
|
||||
async def prepare_all(self):
|
||||
await self.prepare_default_drives()
|
||||
async for user in self.services.user.find():
|
||||
await self.prepare_default_drives_for_user(user['uid'])
|
||||
|
@ -10,6 +10,7 @@ class DriveItemService(BaseService):
|
||||
model['drive_uid'] = drive_uid
|
||||
model['name'] = name
|
||||
model['path'] = str(path)
|
||||
model['extension'] = str(name).split(".")[-1]
|
||||
model['file_type'] = type_
|
||||
model['file_size'] = size
|
||||
if await self.save(model):
|
||||
|
@ -13,20 +13,66 @@ commands = {
|
||||
}
|
||||
|
||||
class TerminalSession:
|
||||
|
||||
async def ensure_process(self):
|
||||
if self.process:
|
||||
return
|
||||
self.process = await asyncio.create_subprocess_exec(
|
||||
*self.command.split(" "),
|
||||
stdin=self.slave,
|
||||
stdout=self.slave,
|
||||
stderr=self.slave,bufsize=0,
|
||||
universal_newlines=True
|
||||
)
|
||||
|
||||
|
||||
def __init__(self,command):
|
||||
self.master, self.slave = pty.openpty()
|
||||
self.sockets =[]
|
||||
self.buffer = b''
|
||||
self.process = subprocess.Popen(
|
||||
command.split(" "),
|
||||
stdin=self.slave,
|
||||
stdout=self.slave,
|
||||
stderr=self.slave,
|
||||
bufsize=0,
|
||||
universal_newlines=True
|
||||
)
|
||||
self.process = None
|
||||
|
||||
#self.process = subprocess.Popen(
|
||||
# command.split(" "),
|
||||
# stdin=self.slave,
|
||||
# stdout=self.slave,
|
||||
# stderr=self.slave,
|
||||
# bufsize=0,
|
||||
# universal_newlines=True
|
||||
#)
|
||||
|
||||
|
||||
async def read_output(self, ws):
|
||||
await self.ensure_process()
|
||||
self.sockets.append(ws)
|
||||
if len(self.sockets) > 1:
|
||||
start = self.buffer.index(b'\n')
|
||||
await ws.send_bytes(self.buffer[start:])
|
||||
return
|
||||
while True:
|
||||
try:
|
||||
async for data in self.process.stdout:
|
||||
if not data:
|
||||
break
|
||||
self.buffer += data
|
||||
if len(self.buffer) > 10000:
|
||||
self.buffer = self.buffer[:-10000]
|
||||
try:
|
||||
for ws in self.sockets: await ws.send_bytes(data) # Send raw bytes for ANSI support
|
||||
except:
|
||||
self.sockets.remove(ws)
|
||||
except:
|
||||
print("Terminating process")
|
||||
self.process.terminate()
|
||||
print("Terminated process")
|
||||
for ws in self.sockets:
|
||||
try:
|
||||
await ws.close()
|
||||
except Exception:
|
||||
pass
|
||||
break
|
||||
|
||||
async def read_outputa(self, ws):
|
||||
loop = asyncio.get_event_loop()
|
||||
self.sockets.append(ws)
|
||||
if len(self.sockets) > 1:
|
||||
@ -57,6 +103,7 @@ class TerminalSession:
|
||||
break
|
||||
|
||||
async def write_input(self, data):
|
||||
await self.ensure_process()
|
||||
os.write(self.master, data.encode())
|
||||
|
||||
|
||||
|
30
src/snek/view/drive.py
Normal file
30
src/snek/view/drive.py
Normal file
@ -0,0 +1,30 @@
|
||||
from snek.system.view import BaseView
|
||||
from aiohttp import web
|
||||
|
||||
class DriveView(BaseView):
|
||||
|
||||
login_required = True
|
||||
|
||||
async def get(self):
|
||||
|
||||
drive_uid = self.request.match_info.get("drive")
|
||||
|
||||
if drive_uid:
|
||||
drive = await self.services.drive.get(uid=drive_uid)
|
||||
drive_items = []
|
||||
async for item in drive.items:
|
||||
drive_items.append(item.record)
|
||||
return web.json_response(drive_items)
|
||||
|
||||
user = await self.services.user.get(uid=self.session.get("uid"))
|
||||
|
||||
|
||||
drives = []
|
||||
async for drive in self.services.drive.get_by_user(user['uid']):
|
||||
record = drive.record
|
||||
record['items'] = []
|
||||
async for item in drive.items:
|
||||
record['items'].append(item.record)
|
||||
drives.append(record)
|
||||
|
||||
return web.json_response(drives)
|
Loading…
Reference in New Issue
Block a user