From d91d64cad5c62375039ed60af8221e8f1c9bd66c Mon Sep 17 00:00:00 2001 From: lan Date: Tue, 15 Aug 2023 22:37:54 +0800 Subject: [PATCH] =?UTF-8?q?update:=E8=87=AA=E5=8A=A8=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E8=BF=87=E6=9C=9F=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/base/depends.py | 1 - apps/base/models.py | 4 ++-- apps/base/views.py | 1 + core/storage.py | 14 ++++++++++++++ core/tasks.py | 27 +++++++++++++++++++++++++++ main.py | 8 ++++++++ readme.md | 4 ++-- 7 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 core/tasks.py diff --git a/apps/base/depends.py b/apps/base/depends.py index b2cb926..324bf0f 100644 --- a/apps/base/depends.py +++ b/apps/base/depends.py @@ -12,7 +12,6 @@ from core.response import APIResponse class IPRateLimit: def __init__(self, count, minutes): - print(count, minutes) self.ips = {} self.count = count self.minutes = minutes diff --git a/apps/base/models.py b/apps/base/models.py index a50af1e..5a5d99d 100644 --- a/apps/base/models.py +++ b/apps/base/models.py @@ -28,10 +28,10 @@ class FileCodes(Model): created_at: Optional[datetime] = fields.DatetimeField(auto_now_add=True, description='创建时间') async def is_expired(self): - if self.expired_at and (self.expired_count == -1 or self.used_count < self.expired_count): + if self.expired_at and (self.expired_count == -1 or self.expired_count > 0): return self.expired_at < await get_now() else: - return self.expired_count != -1 and self.used_count >= self.expired_count + return self.expired_count != -1 and self.expired_count == 0 async def get_file_path(self): return f"{self.file_path}/{self.uuid_file_name}" diff --git a/apps/base/views.py b/apps/base/views.py index 6addb4e..ac6766a 100644 --- a/apps/base/views.py +++ b/apps/base/views.py @@ -71,6 +71,7 @@ async def select_file(data: SelectFileModel, ip: str = Depends(error_ip_limit)): if await file_code.is_expired(): return APIResponse(code=403, detail='文件已过期') file_code.used_count += 1 + file_code.expired_count -= 1 await file_code.save() return APIResponse(detail={ 'code': file_code.code, diff --git a/core/storage.py b/core/storage.py index 9664823..406695d 100644 --- a/core/storage.py +++ b/core/storage.py @@ -69,6 +69,20 @@ class S3FileStorage: return result +class FileStorageTemplate: + def __init__(self): + ... + + async def save_file(self, file: UploadFile, save_path: str): + ... + + async def delete_file(self, file_code: FileCodes): + ... + + async def get_file_url(self, file_code: FileCodes): + ... + + storages = { 'local': SystemFileStorage, 's3': S3FileStorage diff --git a/core/tasks.py b/core/tasks.py new file mode 100644 index 0000000..bcd07e2 --- /dev/null +++ b/core/tasks.py @@ -0,0 +1,27 @@ +# @Time : 2023/8/15 22:00 +# @Author : Lan +# @File : tasks.py +# @Software: PyCharm +import asyncio + +from tortoise.expressions import Q + +from apps.base.models import FileCodes +from apps.base.utils import error_ip_limit, upload_ip_limit +from core.storage import file_storage +from core.utils import get_now + + +async def delete_expire_files(): + while True: + try: + await error_ip_limit.remove_expired_ip() + await upload_ip_limit.remove_expired_ip() + expire_data = await FileCodes.filter(Q(expired_at__lt=await get_now()) | Q(expired_count=0)).all() + for exp in expire_data: + await file_storage.delete_file(exp) + await exp.delete() + except Exception as e: + print(e) + finally: + await asyncio.sleep(600) diff --git a/main.py b/main.py index 231516b..c9cff10 100644 --- a/main.py +++ b/main.py @@ -2,6 +2,7 @@ # @Author : Lan # @File : main.py # @Software: PyCharm +import asyncio import os from fastapi import FastAPI @@ -13,6 +14,7 @@ from tortoise.contrib.fastapi import register_tortoise from apps.base.views import share_api from apps.admin.views import admin_api from core.settings import data_root, settings +from core.tasks import delete_expire_files app = FastAPI() @@ -49,6 +51,12 @@ app.include_router(share_api) app.include_router(admin_api) +@app.on_event("startup") +async def startup_event(): + # 启动后台任务,不定时删除过期文件 + asyncio.create_task(delete_expire_files()) + + @app.get('/') async def index(): return HTMLResponse( diff --git a/readme.md b/readme.md index 6823267..d7f8f9c 100644 --- a/readme.md +++ b/readme.md @@ -22,7 +22,7 @@ - [x] 匿名分享:无需注册,无需登录 - [x] 管理面板:查看所有文件,删除文件 - [x] 一键部署:docker一键部署 -- [x] 自由拓展:阿里云OSS、本地文件流,可根据需求在storage文件中新增存储引擎 +- [x] 自由拓展:S3协议、本地文件流,可根据需求在storage文件中新增存储引擎 - [x] 简单明了:适合新手练手项目 ## 部署方式 @@ -165,7 +165,7 @@ docker logs filecodebox -## 配置文件 +## 配置文件(1.7及以下版本才需要) 如果需要修改配置,可以将该文件放在`/opt/FileCodeBox/`目录下,并命名为`.env`,然后重启容器即可。 如果不是Docker,则需要在项目同目录下新建一个`data`文件夹,然后在创建`.env`文件