From f3d9f2bdccc34b69cdc3c5337af498fa862d1b61 Mon Sep 17 00:00:00 2001 From: yumoqing Date: Wed, 16 Jul 2025 14:28:59 +0800 Subject: [PATCH] first commit --- README.md | 0 app/fileMGR.py | 20 ++++ conf/config.json | 77 +++++++++++++++ filemgr/__init__.py | 0 filemgr/filemgr.py | 209 +++++++++++++++++++++++++++++++++++++++++ filemgr/init.py | 8 ++ json/build.sh | 3 + json/folder.json | 40 ++++++++ json/folderinfo.json | 22 +++++ models/file.xlsx | Bin 0 -> 16764 bytes models/folder.xlsx | Bin 0 -> 16439 bytes models/folderinfo.xlsx | Bin 0 -> 16639 bytes pyproject.toml | 4 + setup.cfg | 15 +++ 14 files changed, 398 insertions(+) create mode 100644 README.md create mode 100644 app/fileMGR.py create mode 100755 conf/config.json create mode 100644 filemgr/__init__.py create mode 100644 filemgr/filemgr.py create mode 100644 filemgr/init.py create mode 100755 json/build.sh create mode 100644 json/folder.json create mode 100644 json/folderinfo.json create mode 100644 models/file.xlsx create mode 100644 models/folder.xlsx create mode 100644 models/folderinfo.xlsx create mode 100644 pyproject.toml create mode 100644 setup.cfg 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 0000000000000000000000000000000000000000..e7d72b3736fffd9df74db2bea60235c01c261c5b GIT binary patch literal 16764 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

-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 literal 0 HcmV?d00001 diff --git a/models/folder.xlsx b/models/folder.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..0167b5c99913bb5f584ee9b6a590ba5f693c23d1 GIT binary patch literal 16439 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 literal 0 HcmV?d00001 diff --git a/models/folderinfo.xlsx b/models/folderinfo.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..6c23e1e814176fa1161313bcd3d61a552250de75 GIT binary patch literal 16639 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 literal 0 HcmV?d00001 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