This commit is contained in:
yumoqing 2022-05-20 17:53:06 +08:00
parent 66116f313c
commit 1ddea57261
11 changed files with 468 additions and 2 deletions

View File

@ -20,9 +20,9 @@ except:
pmp = None pmp = None
class ConfiguredServer: class ConfiguredServer:
def __init__(self,auth_klass=AuthAPI, workdir=None): def __init__(self, auth_klass=AuthAPI, workdir=None):
pp = ProgramPath()
if workdir is None: if workdir is None:
pp = ProgramPath()
self.natpmp_loop = True self.natpmp_loop = True
self.nat_heartbeat = False self.nat_heartbeat = False
workdir = pp workdir = pp

100
doodah/dir.spec Normal file
View File

@ -0,0 +1,100 @@
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(['doodah_s.py'],
pathex=['/Volumes/home/ymq/pydev/github/ahserver/doodah'],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes= [
"AppKit",
"FLAC",
"Ogg",
"Opus",
"OpusFile",
"SDL2",
"SDL2_image",
"SDL2_mixer",
"SDL2_ttf",
"caio",
"cchardet",
"cv2",
"certifi",
"ffpyplayer",
"importlib_metadata-4.11.2.dist-info",
"kivy",
"kiwisolver",
"libSDL2-2.0.0.dylib",
"libSDL2_mixer-2.0.0.dylib",
"libass.9.dylib",
"libavcodec.58.54.100.dylib",
"libavcodec.58.91.100.dylib",
"libavdevice.58.10.100.dylib",
"libavfilter.7.85.100.dylib",
"libavformat.58.29.100.dylib",
"libavformat.58.45.100.dylib",
"libavresample.4.0.0.dylib",
"libavutil.56.31.100.dylib",
"libavutil.56.51.100.dylib",
"libbluray.2.dylib",
"libfreetype.6.dylib",
"libfribidi.0.dylib",
"libmp3lame.0.dylib",
"libmpdec.3.dylib",
"libogg.0.dylib",
"libopenblas.0.dylib",
"libopus.0.dylib",
"libtiff.5.dylib",
"libvorbis.0.dylib",
"libvorbisenc.2.dylib",
"libvorbisfile.3.dylib",
"libwebp.7.dylib",
"libwebpdemux.2.dylib",
"libwebpmux.3.dylib",
"libx264.160.dylib",
"libx265.192.dylib",
"matplotlib",
"mpg123",
"multidict",
"numba",
"numpy",
"objc",
"pandas",
"psutil",
"scipy"
],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='doodah_s',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='doodah_s')

42
doodah/doodah_s.py Executable file
View File

@ -0,0 +1,42 @@
import os
import sys
from ahserver.configuredServer import ConfiguredServer
from appPublic.registerfunction import RegisterFunction
from appPublic.objectAction import ObjectAction
from ahserver.filedownload import path_encode
from imgThumb import thumb
from idFile import idFileDownload
from myauth import MyAuthAPI
from rf import getPublicKey, getI18nMapping
from loadplugins import load_plugins
def encodeFilepath(id,event,d):
if d is None:
return d
if type(d) == type([]):
return ArrayEncodeFilepath(d)
d['rows'] = ArrayEncodeFilepath(d['rows'])
return d
def ArrayEncodeFilepath(d):
ret = []
for r in d:
r['name'] = path_encode(r['name'])
ret.append(r)
return ret
rf = RegisterFunction()
rf.register('makeThumb',thumb)
rf.register('idFileDownload',idFileDownload)
rf.register('getPublicKey', getPublicKey)
rf.register('getI18nMapping', getI18nMapping)
p = os.getcwd()
if len(sys.argv) > 1:
p = sys.argv[1]
server = ConfiguredServer(auth_klass=MyAuthAPI,workdir=p)
load_plugins(p)
server.run()

115
doodah/doodah_s.spec Normal file
View File

@ -0,0 +1,115 @@
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
exs=[
"FLAC",
"Ogg",
"Opus",
"OpusFile",
"SDL2",
"SDL2_image",
"SDL2_mixer",
"SDL2_ttf",
"caio",
"cv2",
"ffpyplayer",
"kivy",
"kiwisolver",
"libSDL2-2.0.0.dylib",
"libSDL2_mixer-2.0.0.dylib",
"libass.9.dylib",
"libavcodec.58.54.100.dylib",
"libavcodec.58.91.100.dylib",
"libavdevice.58.10.100.dylib",
"libavfilter.7.85.100.dylib",
"libavformat.58.29.100.dylib",
"libavformat.58.45.100.dylib",
"libavresample.4.0.0.dylib",
"libavutil.56.31.100.dylib",
"libavutil.56.51.100.dylib",
"libbluray.2.dylib",
"libfreetype.6.dylib",
"libfribidi.0.dylib",
"libmp3lame.0.dylib",
"libmpdec.3.dylib",
"libogg.0.dylib",
"libopenblas.0.dylib",
"libopus.0.dylib",
"libvorbis.0.dylib",
"libvorbisenc.2.dylib",
"libvorbisfile.3.dylib",
"libwebp.7.dylib",
"libwebpdemux.2.dylib",
"libwebpmux.3.dylib",
"libx264.160.dylib",
"libx265.192.dylib",
"matplotlib",
"mpg123",
"multidict",
"numba",
"numpy",
"objc",
"pandas",
"psutil",
"scipy"
]
a = Analysis(['doodah_s.py'],
pathex=['/Volumes/home/ymq/pydev/github/ahserver/doodah'],
binaries=[],
datas=[],
hiddenimports=[
"multidict"
],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[
"FLAC",
"Ogg",
"Opus",
"OpusFile",
"SDL2",
"SDL2_image",
"SDL2_mixer",
"SDL2_ttf",
"cv2",
"ffpyplayer",
"kivy",
"matplotlib",
"mpg123",
"numba",
"numpy",
"objc",
"pandas",
"psutil",
"scipy"
],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='doodah_s',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None )

12
doodah/id2file.py Executable file
View File

@ -0,0 +1,12 @@
from sqlor.dbpools import runSQL
async def getFilenameFromId(idstr:str) -> str:
sql = "select * from kvobjects where id='%s'" % idstr
recs = await runSQL('homedata',sql)
if recs is None:
return None
if len(recs) == 0:
return None
return recs[0].name

21
doodah/idFile.py Executable file
View File

@ -0,0 +1,21 @@
import os
from PIL import Image, ExifTags
from io import BytesIO
from aiohttp.web_exceptions import (
HTTPException,
HTTPExpectationFailed,
HTTPForbidden,
HTTPMethodNotAllowed,
HTTPNotFound,
)
from aiohttp.web_response import Response, StreamResponse
from appPublic.registerfunction import RegisterFunction
from ahserver.filedownload import file_download
from id2file import getFilenameFromId
async def idFileDownload(*args, **kw):
id = args[0]
fname = await getFilenameFromId(id)
request = kw.get('request')
return await file_download(request,fname)

82
doodah/imgThumb.py Executable file
View File

@ -0,0 +1,82 @@
import os
from PIL import Image, ExifTags
from io import BytesIO
from aiohttp.web_exceptions import (
HTTPException,
HTTPExpectationFailed,
HTTPForbidden,
HTTPMethodNotAllowed,
HTTPNotFound,
)
from aiohttp.web_response import Response, StreamResponse
from id2file import getFilenameFromId
def imageUp(img):
try:
o = 'Orientation'
exif=dict(img._getexif().items())
if exif[o] == 3:
img = img.rotate(180, expand=True)
elif exif[o] == 6:
img = img.rotate(270, expand=True)
elif exif[o] == 8:
img = img.rotate(90, expand=True)
return img
except (AttributeError, KeyError, IndexError):
# cases: image don't have getexif
return img
def imageThumb(imgfilepath,width=None,height=None):
im = Image.open(imgfilepath)
im = imageUp(im)
mode = im.mode
if mode not in ('L', 'RGB'):
if mode == 'RGBA':
alpha = im.split()[3]
bgmask = alpha.point(lambda x: 255-x)
im = im.convert('RGB')
# paste(color, box, mask)
im.paste((255,255,255), None, bgmask)
else:
im = im.convert('RGB')
w, h = im.size
if not width and not height:
width = 256
if width:
width = int(width)
height = int(float(width) * float(h) / float(w))
else:
height = int(height)
width = int(float(height) * float(w) / float(h))
thumb = im.resize((width,height),Image.ANTIALIAS)
f = BytesIO()
thumb.save(f,format='jpeg',quality=60)
im.close()
v = f.getvalue()
return v
async def thumb(*args, **kw):
id = args[0]
request = kw.get('request')
xpath = request.path[len(options.leading):]
if xpath == '':
raise HTTPNotFound
id = xpath[1:]
imgpath = await getFilenameFromId(id)
v = imageThumb(imgpath,width=options.width,height=options.height)
response = Response(
status=200,
headers = {
'Content-Disposition': 'attrachment;filename={}'.format(os.path.basename(imgpath)),
'Content-Length':str(len(v))
}
)
await response.prepare(request)
await response.write(v)
await response.write_eof()
return response
if __name__ == '__main__':
imageThumb("/home/ymq/media/pictures/2019-08/IMG_20190804_113014.jpg", width=256)

17
doodah/loadplugins.py Normal file
View File

@ -0,0 +1,17 @@
import os
import sys
from appPublic.folderUtils import listFile
from appPublic.ExecFile import ExecFile
def load_plugins(p_dir):
ef = ExecFile()
pdir = os.path.join(p_dir, 'plugins')
if not os.path.isdir(pdir):
print('load_plugins:%s not exists' % pdir)
return
sys.path.append(pdir)
for py in listFile(pdir, suffixs=['.py'], rescursive=True):
ef.set('sys',sys)
ef.run(py)

45
doodah/myauth.py Executable file
View File

@ -0,0 +1,45 @@
from ahserver.auth_api import AuthAPI
from appPublic.jsonConfig import getConfig
from appPublic.registerfunction import getRegisterFunctionByName
class MyAuthAPI(AuthAPI):
async def needAuth(self,path):
config = getConfig()
if not config.website.authpaths:
return False
for p in config.website.authpaths:
if path.startswith(p):
if not config.website.whitelist:
return True
for p1 in config.website.whitelist:
if path.startswith(p1):
return False
return True
return False
async def checkUserPassword(self,user_id,password):
config = getConfig()
if config.users:
for userid, passwd in config.users.items():
if user_id == userid and password == passwd:
print('******user passwd check OK****************')
return True
rf = getRegisterFunctionByName('user_password_check')
if rf:
return rf(user_id, password)
return False
async def getPermissionNeed(self,path):
rf = getRegisterFunctionByName('get_need_permission')
if rf:
return rf(path)
return 'ok'
async def getUserPermissions(self,user):
rf = getRegisterFunctionByName('get_user_permissions')
if rf:
return rf(user)
return ['ok']

16
doodah/plugins/auth.py Normal file
View File

@ -0,0 +1,16 @@
from appPublic.registerfunction import registerFunction
def user_password_check(user, password):
return True
def get_need_permission(path):
return 'perm'
def get_user_permissions(user):
return ['perm']
registerFunction('user_password_check', user_password_check)
registerFunction('get_need_permission', get_need_permission)
registerFunction('get_user_permissions', get_user_permissions)

16
doodah/rf.py Executable file
View File

@ -0,0 +1,16 @@
from appPublic.jsonConfig import getConfig
from appPublic.i18n import getI18N
from ahserver.filedownload import file_download
async def getPublicKey(*args, **kw):
config = getConfig()
request = options.request
pf = config.website.rsakey.publickey
return await file_download(request,pf)
async def getI18nMapping(*args, **kw):
lang = args[0]
i18n = getI18N()
mapping = i18n.getLangDict(lang)
return mapping