文件上传
This commit is contained in:
+17
-1
@@ -1,3 +1,19 @@
|
|||||||
from cachelib import RedisCache
|
from flask import current_app
|
||||||
|
from cachelib.file import FileSystemCache
|
||||||
|
from cachelib.memcached import MemcachedCache
|
||||||
|
from cachelib.redis import RedisCache
|
||||||
|
from cachelib.simple import SimpleCache
|
||||||
|
from cachelib.uwsgi import UWSGICache
|
||||||
|
|
||||||
|
cacher: dict = {
|
||||||
|
'filesystem': FileSystemCache,
|
||||||
|
'memcached': MemcachedCache,
|
||||||
|
'redis': RedisCache,
|
||||||
|
'simple': SimpleCache,
|
||||||
|
'uwsgi': UWSGICache
|
||||||
|
}
|
||||||
cache = RedisCache()
|
cache = RedisCache()
|
||||||
|
|
||||||
|
|
||||||
|
def get_cache():
|
||||||
|
return cache.get(current_app.config.get("CACHE_TYPE") or "filesystem")()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from flask_migrate import Migrate
|
from flask_migrate import Migrate
|
||||||
|
|
||||||
from common.extend.orm import db
|
from common.extend.orm import db
|
||||||
# from entrance.models import model_lists
|
from entrance.models import model_lists
|
||||||
|
|
||||||
migrate = Migrate(db=db, directory='entrance/migrations')
|
migrate = Migrate(db=db, directory='entrance/migrations')
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
from file_system_uploader import FilesystemUploader
|
||||||
|
from qiniu_uploader import QiniuUploader
|
||||||
|
from upyun_uploader import UpyunUploader
|
||||||
|
from flask import current_app
|
||||||
|
|
||||||
|
uploader: dict = {
|
||||||
|
"filesystem": FilesystemUploader,
|
||||||
|
"qiniu": QiniuUploader,
|
||||||
|
'upyun': UpyunUploader
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_uploader():
|
||||||
|
return uploader.get(current_app.config.get("UPLOAD_PROVIDER") or "filesystem")()
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
class BaseUploader(object):
|
||||||
|
def __init__(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def store(self, fileobj, filename):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def upload(self, file_obj, filename):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def download(self, filename):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def delete(self, filename):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def sync(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
import os
|
||||||
|
import posixpath
|
||||||
|
from pathlib import PurePath
|
||||||
|
from shutil import copyfileobj, rmtree
|
||||||
|
|
||||||
|
from PIL.features import codecs
|
||||||
|
from flask import current_app, send_file
|
||||||
|
from werkzeug.utils import safe_join, secure_filename
|
||||||
|
|
||||||
|
from common.utils.uploads.base_uploader import BaseUploader
|
||||||
|
|
||||||
|
|
||||||
|
def hexencode(s):
|
||||||
|
if isinstance(s, (str,)):
|
||||||
|
s = s.encode("utf-8")
|
||||||
|
encoded = codecs.encode(s, "hex")
|
||||||
|
try:
|
||||||
|
encoded = encoded.decode("utf-8")
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
pass
|
||||||
|
return encoded
|
||||||
|
|
||||||
|
|
||||||
|
class FilesystemUploader(BaseUploader):
|
||||||
|
def __init__(self, base_path=None):
|
||||||
|
super(BaseUploader, self).__init__()
|
||||||
|
self.base_path = base_path or current_app.config.get("UPLOAD_FOLDER")
|
||||||
|
|
||||||
|
def store(self, fileobj, filename):
|
||||||
|
location = os.path.join(self.base_path, filename)
|
||||||
|
directory = os.path.dirname(location)
|
||||||
|
|
||||||
|
if not os.path.exists(directory):
|
||||||
|
os.makedirs(directory)
|
||||||
|
|
||||||
|
with open(location, "wb") as dst:
|
||||||
|
copyfileobj(fileobj, dst, 16384)
|
||||||
|
|
||||||
|
return filename
|
||||||
|
|
||||||
|
def upload(self, file_obj, filename):
|
||||||
|
if len(filename) == 0:
|
||||||
|
raise Exception("Empty filenames cannot be used")
|
||||||
|
|
||||||
|
filename = secure_filename(filename)
|
||||||
|
md5hash = hexencode(os.urandom(16))
|
||||||
|
file_path = posixpath.join(md5hash, filename)
|
||||||
|
|
||||||
|
return self.store(file_obj, file_path)
|
||||||
|
|
||||||
|
def download(self, filename):
|
||||||
|
return send_file(safe_join(self.base_path, filename), as_attachment=True)
|
||||||
|
|
||||||
|
def delete(self, filename):
|
||||||
|
if os.path.exists(os.path.join(self.base_path, filename)):
|
||||||
|
file_path = PurePath(filename).parts[0]
|
||||||
|
rmtree(os.path.join(self.base_path, file_path))
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def sync(self):
|
||||||
|
pass
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
from base_uploader import BaseUploader
|
||||||
|
|
||||||
|
|
||||||
|
class QiniuUploader(BaseUploader):
|
||||||
|
def __init__(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def store(self, fileobj, filename):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def upload(self, file_obj, filename):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def download(self, filename):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def delete(self, filename):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def sync(self):
|
||||||
|
raise NotImplementedError
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
from base_uploader import BaseUploader
|
||||||
|
|
||||||
|
|
||||||
|
class UpyunUploader(BaseUploader):
|
||||||
|
def __init__(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def store(self, fileobj, filename):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def upload(self, file_obj, filename):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def download(self, filename):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def delete(self, filename):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def sync(self):
|
||||||
|
raise NotImplementedError
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
from flask import Flask
|
from flask import Flask
|
||||||
|
|
||||||
from common.extend.celery import register_celery
|
from common.extend.celeryer import register_celery
|
||||||
from common.extend.limit import limiter
|
from common.extend.limit import limiter
|
||||||
from common.extend.orm import db
|
from common.extend.orm import db
|
||||||
from common.extend.migrate import migrate
|
from common.extend.migrate import migrate
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import datetime
|
||||||
|
|
||||||
|
from common.model import BaseModel, Integer, Column, String, CHAR, DateTime, SQLAlchemyAutoSchema
|
||||||
|
|
||||||
|
|
||||||
|
class File(BaseModel):
|
||||||
|
__tablename__ = 'sys_file'
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
name = Column(String(255), nullable=False)
|
||||||
|
href = Column(String(255))
|
||||||
|
mime = Column(CHAR(50), nullable=False)
|
||||||
|
size = Column(CHAR(30), nullable=False)
|
||||||
|
create_time = Column(DateTime, default=datetime.datetime.now)
|
||||||
|
|
||||||
|
|
||||||
|
class AdminLogSchema(SQLAlchemyAutoSchema):
|
||||||
|
class Meta:
|
||||||
|
model = False
|
||||||
|
include_fk = True
|
||||||
|
load_instance = True
|
||||||
Reference in New Issue
Block a user