diff --git a/filemgr/filemgr.py b/filemgr/filemgr.py index b01cb5d..fbfc4ba 100644 --- a/filemgr/filemgr.py +++ b/filemgr/filemgr.py @@ -22,7 +22,43 @@ def get_dbname(): dbname = f('filemgr') return dbname +use_module_patches = { +} +def add_folder_patch(modulename, patch_func): + use_module_patches[modulename] = pathc_func + class FileMgr: + def __init__(self, fiid, use_module): + self.fiid = fiid + self.use_module = use_module + f = use_module_patches[use_module] + if f is None: + raise Exception(f'{use_module} not patch') + f(self) + + async def get_folder_ownerid(self, sor): + pass + + async def file_uploaded(self, request, ns, userid): + pass + + async def file_deleted(self, request, ns, userid): + pass + + async def get_organization_quota(self, sor, orgid): + return 0, '9999-12-31' + + async def is_folder_owner(self, sor, orgid): + folder_owner = await self.get_folder_ownerid(sor) + return folder_owner == orgid + + async def get_quota_used(self, sor, orgid): + sql = "select sum(filesize) as quota_used from file where orgid=${orgid}" + recs = await sor.sqlExe(sql, {'orgid': orgid}) + if len(recs) == 0: + return 0 + return recs[0].quota_used / 1000000 + async def add_file(self, request, params_kw): fs = FileStorage() webpath = params_kw.upfile @@ -33,8 +69,19 @@ class FileMgr: u = await get_session_userinfo(request) if u is None: return False + db = DBPools() async with db.sqlorContext(dbname) as sor: + bool = await self.is_folder_ownerid(sor, u.userorgid) + if not bool: + return False + quota, expired_date = await self.get_organization_quote(sor, + u.userorgid) + + quota_used = await self.get_quota_used(sor, u.userorgid) + if quota_used + filesize / 1000000 >= quota: + self.message = f'{quota=}M, {quota_used=}M {filesize=} overused' + return False recs = await sor.R('file',{'hashvalue': hashvalue}) if len(recs) > 0: os.unlink(realpath) @@ -55,43 +102,59 @@ class FileMgr: } await sor.C('file', ns) if len(recs) == 0: - rf = RegisterFunction() - await rf.exe('fileuploaded', ns) + # rf = RegisterFunction() + #await rf.exe('fileuploaded', ns) + await self.file_uploaded(request, ns, userid) return True return False - async def del_folder(self, id): + async def del_folder(self, request, id): db = DBPools() dbname = get_dbname() async with db.sqlorContext(dbname) as sor: - return await self.del_folder(sor, id) + u = await get_session_userinfo(request) + return await self.del_folder(sor, id, u.userorgid) - async def _del_folder(self, sor, id): + async def _del_folder(self, sor, id, ownerid): + await folders = await sor.R('folder', {'id': id}) + if len(fodlers) == 0: + e = Exception(f'folder({id=}) not found') + exception(f'{e=}\n{format_exc()}') + raise e + folder = folders[0] + if folder.ownerid != ownerid: + e = Exception(f'Wrong owner for folder({id=}, {ownerid=}') + exception(f'{e=}\n{format_exc()}') + raise e fs = [] - async for f in self._folder_files(sor, id): - fs.append(f) - for f in fs: - if f.filetype == 'folder': - await self._del_folder(sor, f.id) - else: - await self._del_file(sor, f.id) - + async for f in self.sor_get_subfile(sor, id): + await self._del_file(sor, f.id, ownerid) + async for f in self.sor_get_subfolder(sor, id): + await self._del_folder(sor, f.id, ownerid) + await sor.D('folder', {'id': id}) + async def del_file(self, fid): db = DBPools() dbname = get_dbname() async with db.sqlorContext(dbname) as sor: - return await self._del_file(sor, fid) + u = await get_session_userinfo(request) + return await self._del_file(sor, fid, u.userorgid) - async def _del_file(self, sor, fid): + async def _del_file(self, sor, fid, ownerid): recs = await sor.R('file', {'id': fid}) if recs: delrec = recs[0] + if delrec.ownerid != ownerid: + e = Exception(f'wrong owners:{ownerid}') + exception(f'{e=},{format_exc()}') + raise e await sor.D('file', {'id':fid}) remain = await sor.R('file', {'hashvalue':delrec.hashvalue}) if not remain: os.unlink(delrec.realpath) - rf = RegisterFunction() - await rf.exe('filedeleted', delrec) + self.file_deleted(request, delrec) + # rf = RegisterFunction() + # await rf.exe('filedeleted', delrec) async def has_sub(self, sor, folderid): sql = """select unique a.* from folder a diff --git a/models/file.xlsx b/models/file.xlsx index 489aaac..13273db 100644 Binary files a/models/file.xlsx and b/models/file.xlsx differ diff --git a/models/folder.xlsx b/models/folder.xlsx index 0167b5c..9c729e1 100644 Binary files a/models/folder.xlsx and b/models/folder.xlsx differ