自动清理聊天图片的脚本

wen 实用脚本 1

本文目录导读:

自动清理聊天图片的脚本

  1. Python 脚本
  2. 使用说明
  3. 功能特点
  4. 注意事项
  5. 扩展建议

我来帮你创建一个自动清理聊天图片的脚本,这个脚本会智能地清理指定目录下的聊天图片文件。

Python 脚本

#!/usr/bin/env python3
"""
聊天图片自动清理脚本
功能:自动清理指定目录下的聊天图片文件
支持:按时间、大小、数量进行清理
"""
import os
import time
import shutil
import argparse
from datetime import datetime, timedelta
from pathlib import Path
import logging
# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('image_cleaner.log', encoding='utf-8'),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)
class ChatImageCleaner:
    """聊天图片清理器"""
    # 支持的图片格式
    IMAGE_EXTENSIONS = {'.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.tiff', '.ico'}
    def __init__(self, directory, max_days=None, max_size_mb=None, max_files=None):
        """
        初始化清理器
        Args:
            directory: 要清理的目录
            max_days: 保留最近多少天的文件
            max_size_mb: 目录最大大小(MB)
            max_files: 最大文件数量
        """
        self.directory = Path(directory)
        self.max_days = max_days
        self.max_size_mb = max_size_mb
        self.max_files = max_files
        if not self.directory.exists():
            raise ValueError(f"目录不存在: {directory}")
    def get_image_files(self):
        """获取所有图片文件"""
        image_files = []
        for ext in self.IMAGE_EXTENSIONS:
            image_files.extend(self.directory.rglob(f'*{ext}'))
            image_files.extend(self.directory.rglob(f'*{ext.upper()}'))
        return image_files
    def calculate_directory_size(self):
        """计算目录总大小(MB)"""
        total_size = 0
        for file_path in self.directory.rglob('*'):
            if file_path.is_file():
                total_size += file_path.stat().st_size
        return total_size / (1024 * 1024)
    def clean_by_days(self, preview=False):
        """按天数清理"""
        if not self.max_days:
            return 0
        cutoff_date = datetime.now() - timedelta(days=self.max_days)
        cleaned_count = 0
        logger.info(f"按天数清理:保留最近 {self.max_days} 天的图片")
        for image_file in self.get_image_files():
            # 获取文件修改时间
            mod_time = datetime.fromtimestamp(image_file.stat().st_mtime)
            # 如果文件在截止日期之前
            if mod_time < cutoff_date:
                if preview:
                    logger.info(f"[预览] 将删除: {image_file} (修改于 {mod_time})")
                else:
                    self.safe_delete(image_file)
                cleaned_count += 1
        return cleaned_count
    def clean_by_size(self, preview=False):
        """按大小清理"""
        if not self.max_size_mb:
            return 0
        current_size = self.calculate_directory_size()
        target_size = self.max_size_mb
        if current_size <= target_size:
            logger.info(f"当前大小 ({current_size:.2f}MB) 未超过限制 ({target_size}MB)")
            return 0
        logger.info(f"按大小清理:当前 {current_size:.2f}MB,目标 {target_size}MB")
        # 获取所有图片文件并按修改时间排序(最旧的在前)
        image_files = self.get_image_files()
        image_files.sort(key=lambda x: x.stat().st_mtime)
        cleaned_count = 0
        for image_file in image_files:
            # 重新检查大小
            current_size = self.calculate_directory_size()
            if current_size <= target_size:
                break
            if preview:
                logger.info(f"[预览] 将删除: {image_file}")
            else:
                self.safe_delete(image_file)
            cleaned_count += 1
        return cleaned_count
    def clean_by_count(self, preview=False):
        """按数量清理"""
        if not self.max_files:
            return 0
        image_files = self.get_image_files()
        if len(image_files) <= self.max_files:
            logger.info(f"当前文件数 ({len(image_files)}) 未超过限制 ({self.max_files})")
            return 0
        logger.info(f"按数量清理:当前 {len(image_files)} 个文件,目标 {self.max_files} 个")
        # 按修改时间排序(最旧的在前)
        image_files.sort(key=lambda x: x.stat().st_mtime)
        # 需要删除的文件数
        files_to_delete = len(image_files) - self.max_files
        cleaned_count = 0
        for i in range(files_to_delete):
            if preview:
                logger.info(f"[预览] 将删除: {image_files[i]}")
            else:
                self.safe_delete(image_files[i])
            cleaned_count += 1
        return cleaned_count
    def clean_all(self, preview=False):
        """执行所有清理策略"""
        total_cleaned = 0
        # 按天数清理
        total_cleaned += self.clean_by_days(preview)
        # 按大小清理
        total_cleaned += self.clean_by_size(preview)
        # 按数量清理
        total_cleaned += self.clean_by_count(preview)
        return total_cleaned
    def safe_delete(self, file_path):
        """安全删除文件"""
        try:
            # 移到回收站而不是永久删除
            trash_dir = self.directory.parent / '.trash'
            trash_dir.mkdir(exist_ok=True)
            target = trash_dir / file_path.name
            if target.exists():
                target = trash_dir / f"{file_path.stem}_{int(time.time())}{file_path.suffix}"
            shutil.move(str(file_path), str(target))
            logger.info(f"已清理: {file_path} -> {target}")
            # 或者永久删除(注释掉上面的移动,启用下面的删除)
            # os.remove(file_path)
            # logger.info(f"已删除: {file_path}")
        except Exception as e:
            logger.error(f"删除文件失败 {file_path}: {e}")
    def preview_clean(self):
        """预览将要清理的文件"""
        logger.info("=== 预览模式:显示将要清理的文件 ===")
        return self.clean_all(preview=True)
    def get_statistics(self):
        """获取目录统计信息"""
        image_files = self.get_image_files()
        total_size = sum(file.stat().st_size for file in image_files) / (1024 * 1024)
        return {
            'file_count': len(image_files),
            'total_size_mb': round(total_size, 2),
            'directory': str(self.directory)
        }
def parse_arguments():
    """解析命令行参数"""
    parser = argparse.ArgumentParser(description='聊天图片自动清理工具')
    parser.add_argument('directory', help='要清理的目录路径')
    parser.add_argument('--days', type=int, help='保留最近N天的图片')
    parser.add_argument('--size', type=float, help='目录最大大小(MB)')
    parser.add_argument('--count', type=int, help='最大文件数量')
    parser.add_argument('--preview', action='store_true', help='预览模式,不实际删除')
    parser.add_argument('--force', action='store_true', help='强制清理')
    return parser.parse_args()
def main():
    """主函数"""
    args = parse_arguments()
    try:
        cleaner = ChatImageCleaner(
            directory=args.directory,
            max_days=args.days,
            max_size_mb=args.size,
            max_files=args.count
        )
        # 显示统计信息
        stats = cleaner.get_statistics()
        logger.info(f"=== 清理前统计 ===")
        logger.info(f"目录: {stats['directory']}")
        logger.info(f"图片数量: {stats['file_count']}")
        logger.info(f"总大小: {stats['total_size_mb']:.2f}MB")
        # 预览模式
        if args.preview:
            cleaned = cleaner.preview_clean()
            logger.info(f"预览:将清理 {cleaned} 个文件")
            return
        # 确认执行
        if not args.force:
            confirm = input(f"确定要清理 {args.directory} 目录下的图片吗?(y/n): ")
            if confirm.lower() != 'y':
                logger.info("操作已取消")
                return
        # 执行清理
        cleaned = cleaner.clean_all()
        # 显示清理后统计
        stats = cleaner.get_statistics()
        logger.info(f"=== 清理后统计 ===")
        logger.info(f"已清理: {cleaned} 个文件")
        logger.info(f"剩余图片数量: {stats['file_count']}")
        logger.info(f"剩余大小: {stats['total_size_mb']:.2f}MB")
    except Exception as e:
        logger.error(f"清理过程出错: {e}")
        raise
if __name__ == '__main__':
    main()

使用说明

基本用法

# 查看帮助
python image_cleaner.py --help
# 预览清理(不实际删除)
python image_cleaner.py /path/to/chat/images --preview
# 清理超过7天的图片
python image_cleaner.py /path/to/chat/images --days 7
# 限制目录大小为100MB
python image_cleaner.py /path/to/chat/images --size 100
# 最多保留500个图片文件
python image_cleaner.py /path/to/chat/images --count 500
# 组合使用
python image_cleaner.py /path/to/chat/images --days 30 --size 500 --count 1000

示例用法

# 清理微信图片目录
python image_cleaner.py ~/Documents/WeChat\ Files/Image --days 30
# 清理QQ图片目录(预览模式)
python image_cleaner.py ~/Documents/Tencent\ Files/Image --preview
# 综合清理
python image_cleaner.py /var/www/uploads/images --days 7 --size 1000 --count 10000 --force

功能特点

  1. 多种清理策略

    • 按时间清理(保留最近N天)
    • 按大小清理(限制目录最大大小)
    • 按数量清理(限制文件数量)
  2. 安全特性

    • 预览模式(不实际删除)
    • 文件移至回收站而不是永久删除
    • 操作确认机制
  3. 日志记录

    • 记录所有操作到日志文件
    • 实时查看清理进度
  4. 支持格式

    jpg, jpeg, png, gif, bmp, webp, tiff, ico

注意事项

  1. 首次使用建议先运行预览模式
  2. 删除的文件会先移到.trash目录,确认无误后可手动删除
  3. 会递归扫描所有子目录
  4. 请根据实际需要调整清理参数

扩展建议

  1. 可以添加定时任务(cron job)自动运行
  2. 可以添加通知功能(邮件/微信通知)
  3. 可以支持更多图片格式
  4. 可以添加按文件类型分类清理

需要我帮你调整某些功能或添加新的特性吗?

抱歉,评论功能暂时关闭!