Files
filecodebox/core/tasks.py
T
2025-12-01 15:24:47 +08:00

84 lines
3.4 KiB
Python

# @Time : 2023/8/15 22:00
# @Author : Lan
# @File : tasks.py
# @Software: PyCharm
import asyncio
import datetime
import logging
import os
from tortoise.expressions import Q
from apps.base.models import FileCodes, UploadChunk
from apps.base.utils import ip_limit, get_chunk_file_path_name
from core.settings import settings, data_root
from core.storage import FileStorageInterface, storages
from core.utils import get_now
async def delete_expire_files():
file_storage: FileStorageInterface = storages[settings.file_storage]()
while True:
try:
# 遍历 share目录下的所有文件夹,删除空的文件夹,并判断父目录是否为空,如果为空也删除
if settings.file_storage == "local":
for root, dirs, files in os.walk(f"{data_root}/share/data"):
if not dirs and not files:
os.rmdir(root)
await ip_limit["error"].remove_expired_ip()
await ip_limit["upload"].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:
try:
await file_storage.delete_file(exp)
except Exception as e:
logging.error(f"删除过期文件失败 code={exp.code}: {e}")
try:
await exp.delete()
except Exception as e:
logging.error(f"删除记录失败 code={exp.code}: {e}")
except Exception as e:
logging.error(e)
finally:
await asyncio.sleep(600)
async def clean_incomplete_uploads():
"""清理超时未完成的分片上传"""
file_storage: FileStorageInterface = storages[settings.file_storage]()
# 默认 24 小时未完成的上传视为过期
expire_hours = getattr(settings, 'chunk_expire_hours', 24)
while True:
try:
expire_time = datetime.datetime.now() - datetime.timedelta(hours=expire_hours)
# 查找所有过期的上传会话(chunk_index=-1 的记录)
expired_sessions = await UploadChunk.filter(
chunk_index=-1,
created_at__lt=expire_time
).all()
for session in expired_sessions:
try:
# 获取分片存储路径
_, _, _, _, save_path = await get_chunk_file_path_name(
session.file_name, session.upload_id
)
# 清理存储中的临时文件
await file_storage.clean_chunks(session.upload_id, save_path)
except Exception as e:
logging.error(f"清理分片文件失败 upload_id={session.upload_id}: {e}")
try:
# 删除该会话的所有数据库记录
await UploadChunk.filter(upload_id=session.upload_id).delete()
logging.info(f"已清理过期上传会话 upload_id={session.upload_id}")
except Exception as e:
logging.error(f"删除分片记录失败 upload_id={session.upload_id}: {e}")
except Exception as e:
logging.error(f"清理未完成上传任务异常: {e}")
finally:
await asyncio.sleep(3600) # 每小时执行一次