145 lines
5.9 KiB
Python
145 lines
5.9 KiB
Python
import os
|
|
import re # 导入正则表达式模块
|
|
|
|
class LamReadFileList:
|
|
@classmethod
|
|
def INPUT_TYPES(cls):
|
|
return {
|
|
"required": {
|
|
"keywords1": ("STRING", {"default": "*", "description": "First keyword(s) to filter filenames, separated by '/'"}),
|
|
},
|
|
"optional": {
|
|
"folder_path": ("STRING", { "description": "Path to the folder containing files"}),
|
|
"input_list": ("LIST", { "description": "Alternative list of files to filter"}),
|
|
"listin": ("LIST", {"description": "Unformatted text list to filter"}),
|
|
"file_formats1": ("STRING", { "default": "*", "description": "File format(s) for Keywords 1, separated by '/'"}),
|
|
"dummy_parameter": ("INT", {"default": 0}), # 添加虚拟参数
|
|
}
|
|
}
|
|
|
|
RETURN_TYPES = ("LIST", "LIST", "INT")
|
|
RETURN_NAMES = ("filtered_results", "listout", "file_count")
|
|
FUNCTION = "filter_files"
|
|
CATEGORY = "lam"
|
|
OUTPUT_NODE = True
|
|
|
|
@classmethod
|
|
def IS_CHANGED(cls, should_change=True, *args, **kwargs):
|
|
if should_change:
|
|
return float("NaN")
|
|
else:
|
|
return False
|
|
|
|
def filter_files(self, keywords1, folder_path=None, input_list=None, listin=None, dummy_parameter=0, **kwargs):
|
|
# 优先使用 listin,如果未提供则使用 input_list,如果未提供则使用 folder_path
|
|
if listin and len(listin) > 0:
|
|
all_files = listin
|
|
elif input_list and len(input_list) > 0:
|
|
all_files = input_list
|
|
elif folder_path:
|
|
#目录不存在创建目录
|
|
if not os.path.exists(folder_path):
|
|
os.makedirs(folder_path)
|
|
all_files = [os.path.join(folder_path, f) for f in os.listdir(folder_path)]
|
|
else:
|
|
all_files = []
|
|
|
|
filtered_results = []
|
|
unformatted_list = [] # 用于存储未格式化的文件列表
|
|
total_files_count = 0 # 初始化文件计数
|
|
|
|
# 获取 keywords1 作为必填字段
|
|
keywords = keywords1.split("/")
|
|
file_formats = kwargs.get("file_formats1", "").split("/")
|
|
|
|
filtered_list = []
|
|
|
|
for file in all_files:
|
|
# 忽略文件夹,只处理文件
|
|
if not os.path.isfile(file):
|
|
continue
|
|
|
|
filename, ext = os.path.splitext(os.path.basename(file))
|
|
|
|
# 处理文件格式的通配符和 OR 逻辑
|
|
format_match = False
|
|
for fmt in file_formats:
|
|
if fmt == "*":
|
|
format_match = True
|
|
break
|
|
elif "|" in fmt:
|
|
# OR 逻辑处理
|
|
or_formats = fmt.split('|')
|
|
if any(ext.lower().lstrip('.') == or_fmt.lower() for or_fmt in or_formats):
|
|
format_match = True
|
|
break
|
|
else:
|
|
if ext.lower().lstrip('.') == fmt.lower():
|
|
format_match = True
|
|
break
|
|
|
|
# 处理关键词通配符组合,使用不区分大小写的正则表达式,并处理空格视为 AND 的逻辑
|
|
keyword_match = True # 初始化为 True
|
|
for keyword in keywords:
|
|
# 分割关键词,处理空格为 AND 逻辑
|
|
sub_keywords = keyword.split()
|
|
for sub_keyword in sub_keywords:
|
|
# 否定匹配:检查是否有 "!" 否定符号
|
|
if sub_keyword.startswith("!"):
|
|
# 匹配不应包含的内容
|
|
pattern = re.compile(re.escape(sub_keyword[1:]).replace(r'\*', '.*'), re.IGNORECASE)
|
|
if pattern.search(filename):
|
|
keyword_match = False
|
|
break
|
|
else:
|
|
# 处理 OR 的逻辑
|
|
or_parts = sub_keyword.split('|')
|
|
or_match = False
|
|
for part in or_parts:
|
|
# 处理通配符的特殊情况
|
|
if part.startswith('*') and not part.endswith('*'):
|
|
# 匹配右边有内容的情况
|
|
pattern = re.compile(r'.+' + re.escape(part[1:]) + r'\b', re.IGNORECASE)
|
|
elif part.endswith('*') and not part.startswith('*'):
|
|
# 匹配左边有内容的情况
|
|
pattern = re.compile(r'\b' + re.escape(part[:-1]) + r'.+', re.IGNORECASE)
|
|
else:
|
|
# 通用匹配
|
|
pattern = re.compile(re.escape(part).replace(r'\*', '.*'), re.IGNORECASE)
|
|
|
|
if pattern.search(filename):
|
|
or_match = True
|
|
break
|
|
|
|
if not or_match:
|
|
keyword_match = False
|
|
break
|
|
|
|
if not keyword_match:
|
|
break
|
|
|
|
# 如果格式和关键词都匹配,添加到过滤列表
|
|
if format_match and keyword_match:
|
|
filtered_list.append(file)
|
|
|
|
# 将过滤后的文件列表格式化,每个文件在新行显示
|
|
formatted_list = "\n".join(filtered_list)
|
|
filtered_results.append(formatted_list)
|
|
|
|
# 保存未格式化的文件列表
|
|
unformatted_list.extend(filtered_list)
|
|
|
|
# 统计文件数量
|
|
total_files_count += len(filtered_list)
|
|
|
|
# 返回格式化列表、未格式化列表、文件计数
|
|
return (filtered_results, unformatted_list, total_files_count)
|
|
|
|
NODE_CLASS_MAPPINGS = {
|
|
"LamReadFileList": LamReadFileList
|
|
}
|
|
|
|
NODE_DISPLAY_NAME_MAPPINGS = {
|
|
"LamReadFileList": "读取文件列表"
|
|
}
|