256 lines
11 KiB
Python
256 lines
11 KiB
Python
|
|
"""
|
|||
|
|
配置管理模块
|
|||
|
|
|
|||
|
|
负责应用程序的配置管理,包括配置的加载、保存和默认值设置。
|
|||
|
|
支持文件处理、文本处理、图片处理和文档格式等各类配置。
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
import os
|
|||
|
|
import configparser
|
|||
|
|
from typing import Dict, Any
|
|||
|
|
|
|||
|
|
|
|||
|
|
class Config:
|
|||
|
|
"""配置管理类,统一管理应用程序的所有配置项"""
|
|||
|
|
|
|||
|
|
def __init__(self):
|
|||
|
|
"""初始化配置,设置所有默认值"""
|
|||
|
|
# 文件处理配置
|
|||
|
|
self.txt_encoding = "utf-8"
|
|||
|
|
self.match_pattern = "exact" # exact: 完全匹配, prefix: 前缀匹配, contains: 包含
|
|||
|
|
self.output_location = "txt_folder" # txt_folder or custom
|
|||
|
|
|
|||
|
|
# 最近使用的文件夹路径
|
|||
|
|
self.last_txt_folder = ""
|
|||
|
|
self.last_images_root = ""
|
|||
|
|
self.last_output_root = ""
|
|||
|
|
|
|||
|
|
# 文字处理配置
|
|||
|
|
self.reverse_text_order = False # 转换文字顺序开关
|
|||
|
|
self.replace_punctuation = False # 是否替换标点符号
|
|||
|
|
self.add_disclaimer = False # 是否添加免责声明
|
|||
|
|
|
|||
|
|
# 错别字处理配置
|
|||
|
|
self.enable_char_errors = False # 是否启用错别字处理
|
|||
|
|
self.char_error_intensity = 0.3 # 错别字强度 0.0-1.0
|
|||
|
|
self.char_error_db_path = "data/error_chars.json" # 错别字库路径
|
|||
|
|
|
|||
|
|
# 图片处理配置
|
|||
|
|
self.image_sort_by = "name" # name or time
|
|||
|
|
self.image_resize = "none" # none or width
|
|||
|
|
self.image_width = 6 # 英寸
|
|||
|
|
self.image_alignment = "center" # left, center, right
|
|||
|
|
self.image_strategy = "cycle" # cycle, truncate, repeat_last
|
|||
|
|
|
|||
|
|
# 文档格式配置
|
|||
|
|
self.line_spacing = 1.5
|
|||
|
|
self.title_levels = 6 # 支持的最大标题层级
|
|||
|
|
|
|||
|
|
def load_from_file(self, file_path: str) -> bool:
|
|||
|
|
"""
|
|||
|
|
从配置文件加载配置
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
file_path: 配置文件路径
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
bool: 是否成功加载
|
|||
|
|
"""
|
|||
|
|
if not os.path.exists(file_path):
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
try:
|
|||
|
|
config_parser = configparser.ConfigParser()
|
|||
|
|
config_parser.read(file_path, encoding='utf-8')
|
|||
|
|
|
|||
|
|
# 加载文件处理配置
|
|||
|
|
if 'FileHandling' in config_parser:
|
|||
|
|
section = config_parser['FileHandling']
|
|||
|
|
self.txt_encoding = section.get('txt_encoding', self.txt_encoding)
|
|||
|
|
self.match_pattern = section.get('match_pattern', self.match_pattern)
|
|||
|
|
self.output_location = section.get('output_location', self.output_location)
|
|||
|
|
self.last_txt_folder = section.get('last_txt_folder', self.last_txt_folder)
|
|||
|
|
self.last_images_root = section.get('last_images_root', self.last_images_root)
|
|||
|
|
self.last_output_root = section.get('last_output_root', self.last_output_root)
|
|||
|
|
|
|||
|
|
# 加载文字处理配置
|
|||
|
|
if 'TextProcessing' in config_parser:
|
|||
|
|
section = config_parser['TextProcessing']
|
|||
|
|
self.reverse_text_order = section.getboolean('reverse_text_order', self.reverse_text_order)
|
|||
|
|
self.replace_punctuation = section.getboolean('replace_punctuation', self.replace_punctuation)
|
|||
|
|
self.add_disclaimer = section.getboolean('add_disclaimer', self.add_disclaimer)
|
|||
|
|
self.enable_char_errors = section.getboolean('enable_char_errors', self.enable_char_errors)
|
|||
|
|
self.char_error_intensity = section.getfloat('char_error_intensity', self.char_error_intensity)
|
|||
|
|
self.char_error_db_path = section.get('char_error_db_path', self.char_error_db_path)
|
|||
|
|
|
|||
|
|
# 加载图片处理配置
|
|||
|
|
if 'ImageProcessing' in config_parser:
|
|||
|
|
section = config_parser['ImageProcessing']
|
|||
|
|
self.image_sort_by = section.get('image_sort_by', self.image_sort_by)
|
|||
|
|
self.image_resize = section.get('image_resize', self.image_resize)
|
|||
|
|
self.image_width = section.getfloat('image_width', self.image_width)
|
|||
|
|
self.image_alignment = section.get('image_alignment', self.image_alignment)
|
|||
|
|
self.image_strategy = section.get('image_strategy', self.image_strategy)
|
|||
|
|
|
|||
|
|
# 加载文档格式配置
|
|||
|
|
if 'DocumentFormat' in config_parser:
|
|||
|
|
section = config_parser['DocumentFormat']
|
|||
|
|
self.line_spacing = section.getfloat('line_spacing', self.line_spacing)
|
|||
|
|
self.title_levels = section.getint('title_levels', self.title_levels)
|
|||
|
|
|
|||
|
|
return True
|
|||
|
|
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"加载配置文件失败: {e}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
def save_to_file(self, file_path: str) -> bool:
|
|||
|
|
"""
|
|||
|
|
保存配置到文件
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
file_path: 配置文件路径
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
bool: 是否成功保存
|
|||
|
|
"""
|
|||
|
|
try:
|
|||
|
|
config_parser = configparser.ConfigParser()
|
|||
|
|
|
|||
|
|
# 保存文件处理配置
|
|||
|
|
config_parser['FileHandling'] = {
|
|||
|
|
'txt_encoding': self.txt_encoding,
|
|||
|
|
'match_pattern': self.match_pattern,
|
|||
|
|
'output_location': self.output_location,
|
|||
|
|
'last_txt_folder': self.last_txt_folder,
|
|||
|
|
'last_images_root': self.last_images_root,
|
|||
|
|
'last_output_root': self.last_output_root
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 保存文字处理配置
|
|||
|
|
config_parser['TextProcessing'] = {
|
|||
|
|
'reverse_text_order': str(self.reverse_text_order),
|
|||
|
|
'replace_punctuation': str(self.replace_punctuation),
|
|||
|
|
'add_disclaimer': str(self.add_disclaimer),
|
|||
|
|
'enable_char_errors': str(self.enable_char_errors),
|
|||
|
|
'char_error_intensity': str(self.char_error_intensity),
|
|||
|
|
'char_error_db_path': self.char_error_db_path
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 保存图片处理配置
|
|||
|
|
config_parser['ImageProcessing'] = {
|
|||
|
|
'image_sort_by': self.image_sort_by,
|
|||
|
|
'image_resize': self.image_resize,
|
|||
|
|
'image_width': str(self.image_width),
|
|||
|
|
'image_alignment': self.image_alignment,
|
|||
|
|
'image_strategy': self.image_strategy
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 保存文档格式配置
|
|||
|
|
config_parser['DocumentFormat'] = {
|
|||
|
|
'line_spacing': str(self.line_spacing),
|
|||
|
|
'title_levels': str(self.title_levels)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# 确保目录存在
|
|||
|
|
os.makedirs(os.path.dirname(file_path), exist_ok=True)
|
|||
|
|
|
|||
|
|
with open(file_path, 'w', encoding='utf-8') as f:
|
|||
|
|
config_parser.write(f)
|
|||
|
|
|
|||
|
|
return True
|
|||
|
|
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"保存配置文件失败: {e}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
def to_dict(self) -> Dict[str, Any]:
|
|||
|
|
"""
|
|||
|
|
将配置转换为字典格式
|
|||
|
|
|
|||
|
|
Returns:
|
|||
|
|
Dict[str, Any]: 配置字典
|
|||
|
|
"""
|
|||
|
|
return {
|
|||
|
|
'file_handling': {
|
|||
|
|
'txt_encoding': self.txt_encoding,
|
|||
|
|
'match_pattern': self.match_pattern,
|
|||
|
|
'output_location': self.output_location,
|
|||
|
|
'last_txt_folder': self.last_txt_folder,
|
|||
|
|
'last_images_root': self.last_images_root,
|
|||
|
|
'last_output_root': self.last_output_root
|
|||
|
|
},
|
|||
|
|
'text_processing': {
|
|||
|
|
'reverse_text_order': self.reverse_text_order,
|
|||
|
|
'replace_punctuation': self.replace_punctuation,
|
|||
|
|
'add_disclaimer': self.add_disclaimer,
|
|||
|
|
'enable_char_errors': self.enable_char_errors,
|
|||
|
|
'char_error_intensity': self.char_error_intensity,
|
|||
|
|
'char_error_db_path': self.char_error_db_path
|
|||
|
|
},
|
|||
|
|
'image_processing': {
|
|||
|
|
'image_sort_by': self.image_sort_by,
|
|||
|
|
'image_resize': self.image_resize,
|
|||
|
|
'image_width': self.image_width,
|
|||
|
|
'image_alignment': self.image_alignment,
|
|||
|
|
'image_strategy': self.image_strategy
|
|||
|
|
},
|
|||
|
|
'document_format': {
|
|||
|
|
'line_spacing': self.line_spacing,
|
|||
|
|
'title_levels': self.title_levels
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
def from_dict(self, config_dict: Dict[str, Any]) -> None:
|
|||
|
|
"""
|
|||
|
|
从字典加载配置
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
config_dict: 配置字典
|
|||
|
|
"""
|
|||
|
|
# 文件处理配置
|
|||
|
|
if 'file_handling' in config_dict:
|
|||
|
|
fh = config_dict['file_handling']
|
|||
|
|
self.txt_encoding = fh.get('txt_encoding', self.txt_encoding)
|
|||
|
|
self.match_pattern = fh.get('match_pattern', self.match_pattern)
|
|||
|
|
self.output_location = fh.get('output_location', self.output_location)
|
|||
|
|
self.last_txt_folder = fh.get('last_txt_folder', self.last_txt_folder)
|
|||
|
|
self.last_images_root = fh.get('last_images_root', self.last_images_root)
|
|||
|
|
self.last_output_root = fh.get('last_output_root', self.last_output_root)
|
|||
|
|
|
|||
|
|
# 文字处理配置
|
|||
|
|
if 'text_processing' in config_dict:
|
|||
|
|
tp = config_dict['text_processing']
|
|||
|
|
self.reverse_text_order = tp.get('reverse_text_order', self.reverse_text_order)
|
|||
|
|
self.replace_punctuation = tp.get('replace_punctuation', self.replace_punctuation)
|
|||
|
|
self.add_disclaimer = tp.get('add_disclaimer', self.add_disclaimer)
|
|||
|
|
self.enable_char_errors = tp.get('enable_char_errors', self.enable_char_errors)
|
|||
|
|
self.char_error_intensity = tp.get('char_error_intensity', self.char_error_intensity)
|
|||
|
|
self.char_error_db_path = tp.get('char_error_db_path', self.char_error_db_path)
|
|||
|
|
|
|||
|
|
# 图片处理配置
|
|||
|
|
if 'image_processing' in config_dict:
|
|||
|
|
ip = config_dict['image_processing']
|
|||
|
|
self.image_sort_by = ip.get('image_sort_by', self.image_sort_by)
|
|||
|
|
self.image_resize = ip.get('image_resize', self.image_resize)
|
|||
|
|
self.image_width = ip.get('image_width', self.image_width)
|
|||
|
|
self.image_alignment = ip.get('image_alignment', self.image_alignment)
|
|||
|
|
self.image_strategy = ip.get('image_strategy', self.image_strategy)
|
|||
|
|
|
|||
|
|
# 文档格式配置
|
|||
|
|
if 'document_format' in config_dict:
|
|||
|
|
df = config_dict['document_format']
|
|||
|
|
self.line_spacing = df.get('line_spacing', self.line_spacing)
|
|||
|
|
self.title_levels = df.get('title_levels', self.title_levels)
|
|||
|
|
|
|||
|
|
def reset_to_defaults(self) -> None:
|
|||
|
|
"""重置所有配置为默认值"""
|
|||
|
|
self.__init__()
|
|||
|
|
|
|||
|
|
|
|||
|
|
# 全局配置实例
|
|||
|
|
CONFIG_FILE_PATH = os.path.join(os.path.expanduser("~"), ".txt2md2docx.ini")
|
|||
|
|
config = Config()
|
|||
|
|
|
|||
|
|
# 自动加载配置
|
|||
|
|
config.load_from_file(CONFIG_FILE_PATH)
|