本文目录导读:

我来帮你创建一个自动清理聊天图片的脚本,这个脚本会智能地清理指定目录下的聊天图片文件。
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)自动运行
- 可以添加通知功能(邮件/微信通知)
- 可以支持更多图片格式
- 可以添加按文件类型分类清理
需要我帮你调整某些功能或添加新的特性吗?
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播