commit f3d9f2bdccc34b69cdc3c5337af498fa862d1b61 Author: yumoqing Date: Wed Jul 16 14:28:59 2025 +0800 first commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/app/fileMGR.py b/app/fileMGR.py new file mode 100644 index 0000000..18bccd6 --- /dev/null +++ b/app/fileMGR.py @@ -0,0 +1,20 @@ +from bricks_for_python.init import load_pybricks +from appbase.init import load_appbase +from rbac.init import load_rbac +from filemgr.init import load_filemgr +from ahserver.webapp import webapp + +def get_module_dbname(mn): + return 'sage' + +def init(): + g = ServerEnv() + g.get_module_dbname = get_module_dbname + load_appbase() + load_rbac() + load_filemgr() + load_bricks() + +if __name__ == '__main__': + webapp(init) + diff --git a/conf/config.json b/conf/config.json new file mode 100755 index 0000000..69adf6d --- /dev/null +++ b/conf/config.json @@ -0,0 +1,77 @@ +{ + "password_key":"!@#$%^&*(*&^%$QWERTYUIqwertyui234567", + "logger":{ + "name":"sage", + "levelname":"clientinfo", + "logfile":"$[workdir]$/logs/sage.log" + }, + "filesroot":"$[workdir]$/files", + "databases":{ + "mediadb":{ + "driver":"aiomysql", + "async_mode":true, + "coding":"utf8", + "maxconn":100, + "dbname":"mediadb", + "kwargs":{ + "user":"test", + "db":"mediadb", + "password":"QUZVcXg5V1p1STMybG5Ia6mX9D0v7+g=", + "host":"localhost" + } + } + }, + "website":{ + "paths":[ + ["$[workdir]$/wwwroot",""] + ], + "client_max_size":20000, + "host":"0.0.0.0", + "port":9080, + "coding":"utf-8", + "indexes":[ + "index.html", + "index.tmpl", + "index.ui", + "index.dspy", + "index.md" + ], + "startswiths":[ + { + "leading":"/idfile", + "registerfunction":"idfile" + } + ], + "processors":[ + [".ws","ws"], + [".xterm","xterm"], + [".proxy","proxy"], + [".llm", "llm"], + [".llms", "llms"], + [".llma", "llma"], + [".xlsxds","xlsxds"], + [".sqlds","sqlds"], + [".tmpl.js","tmpl"], + [".tmpl.css","tmpl"], + [".html.tmpl","tmpl"], + [".bcrud", "bricks_crud"], + [".tmpl","tmpl"], + [".app","app"], + [".bui","bui"], + [".ui","bui"], + [".dspy","dspy"], + [".md","md"] + ], + "session_max_time":3000, + "session_issue_time":2500, + "session_redis_oops":{ + "url":"redis://127.0.0.1:6379" + } + }, + "langMapping":{ + "zh-Hans-CN":"zh-cn", + "zh-CN":"zh-cn", + "en-us":"en", + "en-US":"en" + } +} diff --git a/filemgr/__init__.py b/filemgr/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/filemgr/filemgr.py b/filemgr/filemgr.py new file mode 100644 index 0000000..6a3e379 --- /dev/null +++ b/filemgr/filemgr.py @@ -0,0 +1,209 @@ +from traceback import format_exc +from ahserver.serverenv import get_serverenv +from ahserver.auth_api import get_session_userinfo +from sqlor.dbpools import DBPools +from appPublic.uniqueID import getID +from appPublic.log import debug, error, exception +# from appbase.params import get_parmas + +def get_dbname(): + f = get_serverenv('get_module_dbname') + dbname = f('filemgr') + return dbname + +class FileMgr: + def __init__(self, biztype): + self.biztype = biztype + + async def get_bizinfo_nodes(self, request): + db = DBPools() + dbname = get_dbname() + async with db.sqlorContext(dbname) as sor: + return await self.sor_get_bizinfo_nodes(sor, request) + return [] + + async def sor_get_bizinfo_nodes(self, sor, request): + userinfo = await get_session_userinfo(request) + ns = { + 'orgid':usrinfo.userorgid, + 'biztype':self.biztype + } + recs = await sor.R('folderinfo', ns) + return recs + + async def add_bizinfo_node(self, request, ns): + dbname = get_dbname() + db = DBPools() + async with db.sqlorContext(dbname) as sor: + return await self.sor_add_bizinfo_node(sor,request, ns) + return False + async def sor_add_bizinfo_node(self, sor, request, ns): + userinfo = await get_session_userinfo(request) + ns['orgid'] = userinfo.userorgid, + ns['biztype'] = self.biztype + ns['id'] = getID() + ns['cur_size'] = 0 + # ns['max_size'] = await get_params(sor, userinfo.userid, 'folder_max_size'); + await sor.C('folderinfo', ns) + return True + + async def delete_bizinfo_node(self, request, ns): + dbname = get_dbname() + db = DBPools() + async with db.sqlorContext(dbname) as sor: + return await self.sor_delete_bizinfo_node(self, sor, request, ns) + return False + + async def sor_delete_bizinfo_node(self, sor, request, ns): + userinfo = await get_session_userinfo(request) + ns1['orgid'] = userinfo.userorgid, + ns1['biztype'] = self.biztype + ns1['id'] = ns['id'] + await sor.D('folderinfo', ns1) + return True + + async def update_bizinfo_node(self, request, ns): + dbname = get_dbname() + db = DBPools() + async with db.sqlorContext(dbname) as sor: + return self.sor_update_bizinfo_node(sor, request, ns) + return False + + async def sor_update_bizinfo_node(self, sor, request, ns): + userinfo = await get_session_userinfo(request) + ns1['orgid'] = userinfo.userorgid, + ns1['biztype'] = self.biztype + ns1['id'] = ns['id'] + recs = await sor.R('folderinfo', ns1) + if len(recs) > 0: + await sor.U('folderinfo', ns1) + return True + return False + + async def add_folder(self, request, ns): + dbname = get_dbname() + db = DBPools() + async with db.sqlorContext(dbname) as sor: + return await self.sor_add_folder(sor, request, ns) + return False + async def sor_add_folder(self, sor, request, ns): + userinfo = await get_session_userinfo(request) + ns1['orgid'] = userinfo.userorgid, + ns1['biztype'] = self.biztype + ns1['id'] = ns['id'] + await sor.C('folderinfo', ns1) + return True + + async def get_subfolder(self, request, fid, fiid): + userinfo = await get_session_userinfo(request) + dbname = get_dbname() + db = DBPools() + async with db.sqlorContext(dbname) as sor: + return await self.sor_get_subfolder(sor, request, fid, fiid) + return [] + + async def sor_get_subfolder(self, sor, request, fid, fiid): + sql = """select x.*, 'folder' as rtype, +case when y.id is null then 1 +else 0 end as is_left +from (select a.id as fiid, b.* +from folderinfo a, folder b +where a.id = ${fiid}$ + and b.fiid = a.id + and b.parentid = ${fid}$ + and a.orgid = ${orgid}$ + and a.biztype = ${biztype}$ +order by name) as x left join ( +select unique a.* from folder a left join folder b on a.id = b.par +entid where b.id is not NULL +) as y +on x.id = y.id +""" + ns = { + 'fid':fid, + 'fiid':fiid, + 'orgid':userinfo.userorgid, + 'biztype':self.biztype + } + recs = await sor.sqlExe(sql, ns) + return recs + + async def get_files(self, request, fid, fiid): + dbname = get_dbname() + db = DBPools() + async with db.sqlorContext(dbname) as sor: + return await self.sor_get_files(sor, request, fid, fiid) + return [] + + async def sor_get_files(self, sor, request, fid, fiid): + userinfo = await get_session_userinfo(request) + sql = """select a.id as fiid, b.* +from folderinfo a, file b +where a.id = ${fiid}$ + and b.folderid = ${fid}$ + and a.orgid = ${orgid} + and b.userid = ${userid}$ + and a.biztype = ${biztype}$ +order by name""" + ns = { + 'fid':fid, + 'fiid':fiid, + 'userid':userinfo.userid, + 'orgid':userinfo.userorgid, + 'biztype':self.biztype + } + recs = await sor.sqlExe(sql, ns) + return recs + + async def get_folderinfo(self, sor, fiid): + dbname = get_dbname() + db = DBPools() + async with db.sqlorContext(dbname) as sor: + return await self.sor_get_folderinfo(sor, request, fid, fiid) + return [] + + async def sor_get_folderinfo(self, sor, fiid): + userinfo = await get_session_userinfo(request) + sql = """select * from folderinfo +where id = ${fiid}$ + and orgid = ${orgid}$ + and biztype = ${biztype}$""" + ns = { + 'id':fiid, + 'orgid':userinfo.userorgid, + 'biztype':self.biztype + } + recs = await sor.sqlExe(sql, ns) + if len(recs)>0: + return recs + return None + + async def delete_file(self, request, fid, fiid): + dbname = get_dbname() + db = DBPools() + async with db.sqlorContext(dbname) as sor: + return await self.sor_delete_file(self, sor, request, fid, fiid) + return False + + async def sor_delete_file(self, sor, request, fid, fiid): + userinfo = await get_session_userinfo(request) + sql = """select a.id as fiid, b.* +from folderinfo a, file b +where a.id = ${fiid}$ + and b.id = ${fid}$ + and a.orgid = ${orgid} + and b.userid = ${userid}$ + and a.biztype = ${biztype}$""" + ns = { + 'fid':fid, + 'fiid':fiid, + 'userid':userinfo.userid, + 'orgid':userinfo.userorgid, + 'biztype':self.biztype + } + recs = await sor.sqlExe(sql, ns) + if len(recs) > 0: + await sor.D('file', {'id': fid}) + return True + return False + diff --git a/filemgr/init.py b/filemgr/init.py new file mode 100644 index 0000000..a64a6d1 --- /dev/null +++ b/filemgr/init.py @@ -0,0 +1,8 @@ +from ahserver.serverenv import ServerEnv +from filemgr.filemgr import FileMgr + +def load_filemgr(): + g = ServerEnv() + g.FileMgr = FileMgr + + diff --git a/json/build.sh b/json/build.sh new file mode 100755 index 0000000..23fab8d --- /dev/null +++ b/json/build.sh @@ -0,0 +1,3 @@ +#!/usr/bin/bash + +xls2ui -m ../models -o ../wwwroot filemgr *.json diff --git a/json/folder.json b/json/folder.json new file mode 100644 index 0000000..c9fb694 --- /dev/null +++ b/json/folder.json @@ -0,0 +1,40 @@ +{ + "tblname": "folder", + "uitype":"tree", + "title":"目录", + "params":{ + "idField":"id", + "textField":"name", + "sortby":"name", + "editable":true, + "browserfields":{ + "alters":{} + }, + "edit_exclouded_fields":[], + "parentField":"parentid", + "toolbar":{ + "tools":[ + { + "name":"upload", + "label":"上传文件", + "icon":"{{entire_url('/bricks/imgs/upload.svg')}}" + } + ] + }, + "binds":[ + { + "wid":"upload", + "event":"upload", + "actiontype":"urlwidget", + "target":"PopupWindow", + "popupwindow_options":{ + "icon":"{{entire_url('/bricks/imgs/app.png')}}", + "title":"上传文件" + }, + "options":{ + "url":"{{entire_url('/filemgr/upload_file.ui')}}" + } + } + ] + } +} diff --git a/json/folderinfo.json b/json/folderinfo.json new file mode 100644 index 0000000..2f6612e --- /dev/null +++ b/json/folderinfo.json @@ -0,0 +1,22 @@ +{ + "tblname": "folderinfo", + "title":"目录信息", + "params": { + "sortby":"name", + "logined_userorgid":"orgid", + "browserfields": { + "exclouded": ["id", "biztype", "orgid" ], + "cwidth": {} + }, + "editexclouded": [ + "id", "orgid" + ], + "subtables": [ + { + "field":"fiid", + "title":"目录", + "subtable":"folder" + } + ] + } +} diff --git a/models/file.xlsx b/models/file.xlsx new file mode 100644 index 0000000..e7d72b3 Binary files /dev/null and b/models/file.xlsx differ diff --git a/models/folder.xlsx b/models/folder.xlsx new file mode 100644 index 0000000..0167b5c Binary files /dev/null and b/models/folder.xlsx differ diff --git a/models/folderinfo.xlsx b/models/folderinfo.xlsx new file mode 100644 index 0000000..6c23e1e Binary files /dev/null and b/models/folderinfo.xlsx differ diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..59514a1 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,4 @@ +[build-system] +requires = ["setuptools>=61", "wheel"] +build-backend = "setuptools.build_meta" + diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..08a653b --- /dev/null +++ b/setup.cfg @@ -0,0 +1,15 @@ +[metadata] +name=filemgr +version = 0.0.1 +description = A folder management package +author = "yu moqing" +author_email = "yumoqing@gmail.com" +readme = "README.md" +license = "MIT" +[options] +packages = find: +requires-python = ">=3.8" +install_requires = + apppublic + sqlor + ahserver