|
|
#!/usr/bin/env python3
|
|
|
# -*- coding: utf-8 -*-
|
|
|
"""
|
|
|
文件操作模块
|
|
|
处理文件保存和相关操作
|
|
|
"""
|
|
|
|
|
|
import os
|
|
|
from pathlib import Path
|
|
|
from mod_tpl import expand_filename_template
|
|
|
|
|
|
|
|
|
class FileSaveError(Exception):
|
|
|
"""文件保存错误异常"""
|
|
|
pass
|
|
|
|
|
|
|
|
|
def validate_save_params(content, filename_template, folder, ext):
|
|
|
"""验证保存参数"""
|
|
|
if not content or not content.strip():
|
|
|
raise FileSaveError("内容为空,无法保存!")
|
|
|
|
|
|
if not filename_template or not filename_template.strip():
|
|
|
raise FileSaveError("文件名不能为空!")
|
|
|
|
|
|
if not folder or not folder.strip():
|
|
|
raise FileSaveError("保存目录不能为空!")
|
|
|
|
|
|
if not ext or not ext.strip():
|
|
|
raise FileSaveError("文件扩展名不能为空!")
|
|
|
|
|
|
def ensure_directory_exists(directory):
|
|
|
"""确保目录存在"""
|
|
|
try:
|
|
|
Path(directory).mkdir(parents=True, exist_ok=True)
|
|
|
except Exception as e:
|
|
|
raise FileSaveError(f"创建目录失败: {str(e)}")
|
|
|
|
|
|
def build_file_path(filename_template, folder, ext):
|
|
|
"""构建完整文件路径"""
|
|
|
# 展开文件名模板
|
|
|
filename = expand_filename_template(filename_template)
|
|
|
|
|
|
# 确保扩展名以点开头
|
|
|
if not ext.startswith('.'):
|
|
|
ext = '.' + ext
|
|
|
|
|
|
# 文件名和扩展名合成最终文件名
|
|
|
full_filename = filename + ext
|
|
|
|
|
|
# 构建完整路径
|
|
|
filepath = os.path.join(folder, full_filename)
|
|
|
|
|
|
return filepath
|
|
|
|
|
|
def check_file_exists(filepath):
|
|
|
"""检查文件是否存在"""
|
|
|
return os.path.exists(filepath)
|
|
|
|
|
|
def save_note_content(content, filename_template, folder, ext, overwrite_callback=None):
|
|
|
"""
|
|
|
保存笔记内容到文件
|
|
|
|
|
|
Args:
|
|
|
content: 要保存的内容
|
|
|
filename_template: 文件名模板
|
|
|
folder: 保存目录
|
|
|
ext: 文件扩展名
|
|
|
overwrite_callback: 文件存在时的回调函数,返回True表示覆盖
|
|
|
|
|
|
Returns:
|
|
|
str: 保存的文件路径
|
|
|
|
|
|
Raises:
|
|
|
FileSaveError: 保存失败时抛出异常
|
|
|
"""
|
|
|
try:
|
|
|
# 验证参数
|
|
|
validate_save_params(content, filename_template, folder, ext)
|
|
|
|
|
|
# 确保目录存在
|
|
|
ensure_directory_exists(folder)
|
|
|
|
|
|
# 构建文件路径
|
|
|
filepath = build_file_path(filename_template, folder, ext)
|
|
|
|
|
|
# 检查文件是否已存在
|
|
|
if check_file_exists(filepath):
|
|
|
if overwrite_callback:
|
|
|
if not overwrite_callback(filepath):
|
|
|
raise FileSaveError("用户取消保存操作")
|
|
|
else:
|
|
|
raise FileSaveError(f"文件 {filepath} 已存在")
|
|
|
|
|
|
# 保存文件
|
|
|
with open(filepath, 'w', encoding='utf-8') as f:
|
|
|
f.write(content)
|
|
|
|
|
|
return filepath
|
|
|
|
|
|
except FileSaveError:
|
|
|
raise
|
|
|
except Exception as e:
|
|
|
raise FileSaveError(f"保存失败: {str(e)}")
|
|
|
|
|
|
def get_file_info(filepath):
|
|
|
"""获取文件信息"""
|
|
|
if not os.path.exists(filepath):
|
|
|
return None
|
|
|
|
|
|
stat = os.stat(filepath)
|
|
|
return {
|
|
|
'size': stat.st_size,
|
|
|
'modified': stat.st_mtime,
|
|
|
'created': stat.st_ctime,
|
|
|
} |