ahserver_g/ahserver/filestorage.py

116 lines
2.7 KiB
Python
Raw Normal View History

2019-07-10 17:34:45 +08:00
# fileUpload.py
2023-02-22 23:37:09 +08:00
import asyncio
2019-07-10 17:34:45 +08:00
import os
import time
import tempfile
2023-02-22 22:16:41 +08:00
import aiofiles
2023-02-22 23:37:09 +08:00
import json
import time
2019-07-10 17:34:45 +08:00
from appPublic.folderUtils import _mkdir
from appPublic.jsonConfig import getConfig
2023-02-22 23:37:09 +08:00
from appPublic.Singleton import SingletonDecorator
@SingletonDecorator
class TmpFileRecord:
def __init__(self, timeout=3600):
self.filetime = {}
self.changed_flg = False
self.timeout = timeout
self.time_period = 10
self.filename = self.savefilename()
self.loop = asyncio.get_event_loop()
self.loop.call_later(0.01, self.load)
print('TmpFileRecord() .........................')
def newtmpfile(self, path:str):
self.filetime[path] = time.time()
self.change_flg = True
def savefilename(self):
config = getConfig()
root = config.filesroot or tempfile.gettempdir()
return root + '/tmpfile_rec.json'
async def save(self):
if not self.change_flg:
return
async with aiofiles.open(self.filename, 'bw') as f:
s = json.dumps(self.filetime)
b = s.encode('utf-8')
await f.write(b)
await f.flush()
self.change_flg = False
2019-07-10 17:34:45 +08:00
2023-02-22 23:37:09 +08:00
async def load(self):
print('load() called ............')
fn = self.filename
if not os.path.isfile(fn):
return
async with aiofiles.open(fn, 'br') as f:
b = await f.read()
s = b.decode('utf-8')
self.filetime = json.loads(s)
self.remove()
async def remove(self):
tim = time.time()
ft = {k:v for k,v in self.filetime.items()}
for k,v in ft:
if tim - v > self.timeout:
self.rmfile(k)
del self.tiletime[k]
await self.save()
self.loop.call_later(self.time_period, self.remove)
def rmfile(self, name:str):
config = getConfig()
os.remove(config.fileroot + name)
2019-07-10 17:34:45 +08:00
class FileStorage:
def __init__(self):
config = getConfig()
self.root = config.filesroot or tempfile.gettempdir()
2023-02-22 23:37:09 +08:00
self.tfr = TmpFileRecord()
2019-07-10 17:34:45 +08:00
def realPath(self,path):
if path[0] == '/':
path = path[1:]
p = os.path.join(self.root,path)
return p
2019-08-28 10:15:35 +08:00
def _name2path(self,name):
2019-07-10 17:34:45 +08:00
name = os.path.basename(name)
paths=[191,193,197,199,97]
v = int(time.time()*1000000)
# b = name.encode('utf8') if not isinstance(name,bytes) else name
# v = int.from_bytes(b,byteorder='big',signed=False)
path = os.path.abspath(os.path.join(self.root,
2019-08-28 10:15:35 +08:00
str(v % paths[0]),
str(v % paths[1]),
str(v % paths[2]),
str(v % paths[3]),
str(v % paths[4]),
2019-07-10 17:34:45 +08:00
name))
return path
2019-08-28 10:15:35 +08:00
async def save(self,name,read_data):
2023-02-22 22:16:41 +08:00
# print(f'FileStorage():save():{name=}')
2019-08-28 10:15:35 +08:00
p = self._name2path(name)
2023-02-22 22:16:41 +08:00
fpath = p[len(self.root):]
2019-07-10 17:34:45 +08:00
_mkdir(os.path.dirname(p))
2023-02-22 22:16:41 +08:00
async with aiofiles.open(p,'wb') as f:
siz = 0
2019-07-10 17:34:45 +08:00
while 1:
d = await read_data()
if not d:
break
2023-02-22 22:16:41 +08:00
siz += len(d);
2019-07-10 17:34:45 +08:00
await f.write(d)
2023-02-22 22:16:41 +08:00
await f.flush()
2023-02-22 23:37:09 +08:00
# print(f'{name=} file({fpath}) write {siz} bytes')
self.tfr.newtmpfile(fpath)
2023-02-22 22:16:41 +08:00
return fpath