diff --git a/fam-edge/src/fam_edge/storage_cleaner/cleaner.py b/fam-edge/src/fam_edge/storage_cleaner/cleaner.py new file mode 100644 index 0000000..fe83957 --- /dev/null +++ b/fam-edge/src/fam_edge/storage_cleaner/cleaner.py @@ -0,0 +1,82 @@ +""" +Storage-Cleaner - 临时文件清理 + +首期仅 finally 清理(不做 Cron 兜底) +- 删除下载的视频文件 +- 删除粗抽候选帧 +- 删除压缩关键帧 +- 清理任务工作目录 +""" +import os +import shutil +from ..logger import setup_logger, log_task + +logger = setup_logger('fam-edge.storage_cleaner') + + +class StorageCleaner: + """临时文件清理器""" + + def __init__(self, task_id: int, work_dir: str): + self.task_id = task_id + self.work_dir = work_dir + + def cleanup(self): + """清理整个工作目录""" + try: + if os.path.exists(self.work_dir): + # 统计清理前大小 + total_size = 0 + for dirpath, dirnames, filenames in os.walk(self.work_dir): + for f in filenames: + fp = os.path.join(dirpath, f) + try: + total_size += os.path.getsize(fp) + except OSError: + pass + + shutil.rmtree(self.work_dir) + size_mb = total_size / (1024 * 1024) + log_task(logger, self.task_id, 'cleanup', + f'已清理工作目录: {self.work_dir} ({size_mb:.1f}MB)') + else: + log_task(logger, self.task_id, 'cleanup', + f'工作目录不存在,无需清理: {self.work_dir}') + except PermissionError as e: + logger.warning(f"[task_id={self.task_id}] 清理权限不足: {e}") + except Exception as e: + logger.warning(f"[task_id={self.task_id}] 清理异常: {e}") + + def cleanup_file(self, filepath: str): + """清理单个文件""" + try: + if os.path.exists(filepath): + os.remove(filepath) + logger.info(f"[task_id={self.task_id}] 已删除: {filepath}") + except Exception as e: + logger.warning(f"[task_id={self.task_id}] 删除文件失败 {filepath}: {e}") + + @staticmethod + def cleanup_stale_dirs(base_dir='/tmp/fam_media', max_age_hours=24): + """清理超期的残留目录(超过 max_age_hours 的 task_* 目录) + + 首期不通过 Cron 调用,可在进程启动时手动执行一次。 + """ + if not os.path.isdir(base_dir): + return + + import time + now = time.time() + max_age_seconds = max_age_hours * 3600 + + for entry in os.listdir(base_dir): + entry_path = os.path.join(base_dir, entry) + if not os.path.isdir(entry_path) or not entry.startswith('task_'): + continue + try: + dir_mtime = os.path.getmtime(entry_path) + if now - dir_mtime > max_age_seconds: + shutil.rmtree(entry_path) + logger.info(f"清理超期残留目录: {entry_path}") + except Exception as e: + logger.warning(f"清理残留目录失败 {entry_path}: {e}")