本文目录导读:

我来帮你创建一个自动清理聊天图片的脚本,这个脚本会智能地清理指定目录下的聊天图片文件。
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
功能特点
-
多种清理策略:
- 按时间清理(保留最近N天)
- 按大小清理(限制目录最大大小)
- 按数量清理(限制文件数量)
-
安全特性:
- 预览模式(不实际删除)
- 文件移至回收站而不是永久删除
- 操作确认机制
-
日志记录:
- 记录所有操作到日志文件
- 实时查看清理进度
-
支持格式:
jpg, jpeg, png, gif, bmp, webp, tiff, ico
注意事项
- 首次使用建议先运行预览模式
- 删除的文件会先移到
.trash目录,确认无误后可手动删除 - 会递归扫描所有子目录
- 请根据实际需要调整清理参数
扩展建议
- 可以添加定时任务(cron job)自动运行
- 可以添加通知功能(邮件/微信通知)
- 可以支持更多图片格式
- 可以添加按文件类型分类清理
需要我帮你调整某些功能或添加新的特性吗?