修改获取网页内容代码

This commit is contained in:
wsb1224 2025-05-28 16:39:07 +08:00
parent 036eb90ca0
commit 0792027bea
2 changed files with 659 additions and 60 deletions

View File

@ -1,4 +1,4 @@
import json
import sys # 导入sys模块
@ -13,7 +13,7 @@ import tkinter as tk
from config import *
from tkinter import ttk, messagebox, filedialog
from tkinter import ttk, messagebox, filedialog, simpledialog
from tkinter.scrolledtext import ScrolledText
import pymysql
@ -43,16 +43,31 @@ class ArticleReplaceApp(tk.Tk):
# 创建配置页面
self.config_frame = ttk.Frame(self.notebook)
self.notebook.add(self.config_frame, text="配置")
# 初始化主页面
self.init_main_frame()
# 初始化配置页面
self.init_config_frame()
# 初始化变量
self.running = False
self.thread = None
self.total_links = 0
self.processed_links = 0
# 初始化Coze配置变量
self.template_name_var = tk.StringVar()
self.coze_workflow_id_var = tk.StringVar(value=CONFIG['Coze']['workflow_id'])
self.coze_access_token_var = tk.StringVar(value=CONFIG['Coze']['access_token'])
self.coze_is_async_var = tk.StringVar(value=CONFIG['Coze'].get('is_async', 'true'))
self.coze_input_data_template_var = tk.StringVar(value=CONFIG['Coze'].get('input_data_template', '{"article": "{article_text}", "link":"{link}", "weijin":"{weijin}"}'))
# 初始化模板数据结构
self.templates = {
"短篇": [],
"文章": []
}
# 初始化主页面
self.init_main_frame()
# 初始化配置页面
self.init_config_frame()
# 设置关闭窗口事件
self.protocol("WM_DELETE_WINDOW", self.on_close)
@ -82,14 +97,21 @@ class ArticleReplaceApp(tk.Tk):
ai_service_combo = ttk.Combobox(control_frame, textvariable=self.ai_service_var, values=["dify", "coze"], width=10, state="readonly")
ai_service_combo.grid(row=2, column=1, padx=5, pady=5, sticky=tk.W)
# 生成类型选择
ttk.Label(control_frame, text="生成类型:").grid(row=3, column=0, padx=5, pady=5, sticky=tk.W)
self.generation_type_var = tk.StringVar(value="短篇")
self.generation_type_combo = ttk.Combobox(control_frame, textvariable=self.generation_type_var, values=["短篇", "文章"], width=10, state="readonly")
self.generation_type_combo.grid(row=3, column=1, padx=5, pady=5, sticky=tk.W)
self.generation_type_combo.bind("<<ComboboxSelected>>", self.on_generation_type_changed)
# 开始按钮
self.start_button = ttk.Button(control_frame, text="开始处理", command=self.start_processing)
self.start_button.grid(row=3, column=0, columnspan=3, padx=5, pady=20)
self.start_button.grid(row=4, column=0, columnspan=3, padx=5, pady=20)
# 进度条
ttk.Label(control_frame, text="处理进度:").grid(row=4, column=0, padx=5, pady=5, sticky=tk.W)
ttk.Label(control_frame, text="处理进度:").grid(row=5, column=0, padx=5, pady=5, sticky=tk.W)
self.progress_var = tk.DoubleVar()
ttk.Progressbar(control_frame, variable=self.progress_var, maximum=100).grid(row=4, column=1, columnspan=2,
ttk.Progressbar(control_frame, variable=self.progress_var, maximum=100).grid(row=5, column=1, columnspan=2,
padx=5, pady=5, sticky=tk.EW)
# 创建右侧日志面板
@ -235,25 +257,77 @@ class ArticleReplaceApp(tk.Tk):
ttk.Entry(parent, textvariable=self.dify_input_data_template_var, width=50).grid(row=3, column=1, padx=5, pady=5)
def init_coze_config(self, parent):
# 生成类型选择(与主页面联动)
type_frame = ttk.Frame(parent)
type_frame.grid(row=0, column=0, columnspan=3, padx=5, pady=5, sticky=tk.EW)
ttk.Label(type_frame, text="生成类型:").pack(side=tk.LEFT, padx=5)
self.coze_generation_type_var = tk.StringVar(value="短篇")
self.coze_generation_type_combo = ttk.Combobox(type_frame, textvariable=self.coze_generation_type_var, values=["短篇", "文章"], width=10, state="readonly")
self.coze_generation_type_combo.pack(side=tk.LEFT, padx=5)
self.coze_generation_type_combo.bind("<<ComboboxSelected>>", self.on_coze_generation_type_changed)
# 编辑状态标签
self.edit_status_label = ttk.Label(type_frame, text="", foreground="blue")
self.edit_status_label.pack(side=tk.LEFT, padx=20)
# 加载已保存的模板
self.load_templates()
# 初始化变量跟踪
self._setup_var_trace()
# 模板管理框架
template_frame = ttk.LabelFrame(parent, text="模板管理")
template_frame.grid(row=1, column=0, columnspan=3, padx=5, pady=10, sticky=tk.EW)
# 模板列表和滚动条
list_frame = ttk.Frame(template_frame)
list_frame.grid(row=1, column=0, padx=5, pady=5, sticky=tk.W)
ttk.Label(template_frame, text="模板列表:").grid(row=0, column=0, padx=5, pady=5, sticky=tk.W)
self.template_listbox = tk.Listbox(list_frame, height=5, width=30)
scrollbar = ttk.Scrollbar(list_frame, orient="vertical", command=self.template_listbox.yview)
self.template_listbox.configure(yscrollcommand=scrollbar.set)
self.template_listbox.pack(side=tk.LEFT, fill=tk.Y)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
self.template_listbox.bind("<<ListboxSelect>>", self.on_template_selected)
# 模板操作按钮
button_frame = ttk.Frame(template_frame)
button_frame.grid(row=1, column=1, padx=10, pady=5, sticky=tk.N)
ttk.Button(button_frame, text="新增模板", command=self.add_template).pack(pady=2)
ttk.Button(button_frame, text="删除模板", command=self.delete_template).pack(pady=2)
ttk.Button(button_frame, text="重命名模板", command=self.rename_template).pack(pady=2)
ttk.Button(button_frame, text="保存模板", command=self.save_template).pack(pady=2)
ttk.Button(button_frame, text="复制模板", command=self.duplicate_template).pack(pady=2)
ttk.Button(button_frame, text="使用模板", command=self.use_template).pack(pady=2)
# 当前模板配置
config_frame = ttk.LabelFrame(parent, text="当前模板配置")
config_frame.grid(row=2, column=0, columnspan=3, padx=5, pady=10, sticky=tk.EW)
# 模板名称
ttk.Label(config_frame, text="模板名称:").grid(row=0, column=0, padx=5, pady=5, sticky=tk.W)
ttk.Entry(config_frame, textvariable=self.template_name_var, width=30).grid(row=0, column=1, padx=5, pady=5)
# Coze Workflow ID
ttk.Label(parent, text="Workflow ID:").grid(row=0, column=0, padx=5, pady=5, sticky=tk.W)
self.coze_workflow_id_var = tk.StringVar(value=CONFIG['Coze']['workflow_id'])
ttk.Entry(parent, textvariable=self.coze_workflow_id_var, width=50).grid(row=0, column=1, padx=5, pady=5)
ttk.Label(config_frame, text="Workflow ID:").grid(row=1, column=0, padx=5, pady=5, sticky=tk.W)
ttk.Entry(config_frame, textvariable=self.coze_workflow_id_var, width=50).grid(row=1, column=1, padx=5, pady=5)
# Coze Access Token
ttk.Label(parent, text="Access Token:").grid(row=1, column=0, padx=5, pady=5, sticky=tk.W)
self.coze_access_token_var = tk.StringVar(value=CONFIG['Coze']['access_token'])
ttk.Entry(parent, textvariable=self.coze_access_token_var, width=50).grid(row=1, column=1, padx=5, pady=5)
ttk.Label(config_frame, text="Access Token:").grid(row=2, column=0, padx=5, pady=5, sticky=tk.W)
ttk.Entry(config_frame, textvariable=self.coze_access_token_var, width=50).grid(row=2, column=1, padx=5, pady=5)
# Coze Is Async
ttk.Label(parent, text="Is Async:").grid(row=2, column=0, padx=5, pady=5, sticky=tk.W)
self.coze_is_async_var = tk.StringVar(value=CONFIG['Coze']['is_async'])
ttk.Combobox(parent, textvariable=self.coze_is_async_var, values=["true", "false"], width=10, state="readonly").grid(row=2, column=1, padx=5, pady=5, sticky=tk.W)
ttk.Label(config_frame, text="Is Async:").grid(row=3, column=0, padx=5, pady=5, sticky=tk.W)
ttk.Combobox(config_frame, textvariable=self.coze_is_async_var, values=["true", "false"], width=10, state="readonly").grid(row=3, column=1, padx=5, pady=5, sticky=tk.W)
# Coze Input Data Template
ttk.Label(parent, text="Input Data模板:").grid(row=3, column=0, padx=5, pady=5, sticky=tk.W)
self.coze_input_data_template_var = tk.StringVar(value=CONFIG['Coze'].get('input_data_template', '{{"article": "{article_text}", "link":"{link}", "weijin":"{weijin}"}}')) # 添加默认值
ttk.Entry(parent, textvariable=self.coze_input_data_template_var, width=50).grid(row=3, column=1, padx=5, pady=5)
ttk.Label(config_frame, text="Input Data模板:").grid(row=4, column=0, padx=5, pady=5, sticky=tk.W)
# Variable already initialized in __init__
ttk.Entry(config_frame, textvariable=self.coze_input_data_template_var, width=50).grid(row=4, column=1, padx=5, pady=5)
# 更新模板列表
self.update_template_list()
def init_baidu_config(self, parent):
# 百度 API Key
@ -339,6 +413,468 @@ class ArticleReplaceApp(tk.Tk):
CONFIG['Keywords']['banned_words'] = words
messagebox.showinfo("保存成功", "违禁词列表已更新")
def on_generation_type_changed(self, event=None):
"""主页面生成类型改变时的处理"""
# 同步到coze页面
self.coze_generation_type_var.set(self.generation_type_var.get())
self.update_template_list()
def on_coze_generation_type_changed(self, event=None):
"""coze页面生成类型改变时的处理"""
# 同步到主页面
self.generation_type_var.set(self.coze_generation_type_var.get())
self.update_template_list()
def update_template_list(self):
"""更新模板列表显示"""
current_type = self.coze_generation_type_var.get()
self.template_listbox.delete(0, tk.END)
if current_type in self.templates:
for template in self.templates[current_type]:
self.template_listbox.insert(tk.END, template['name'])
def on_template_selected(self, event=None):
"""模板选择时的处理"""
selection = self.template_listbox.curselection()
if selection:
index = selection[0]
current_type = self.coze_generation_type_var.get()
if current_type in self.templates and index < len(self.templates[current_type]):
template = self.templates[current_type][index]
self.load_template_config(template)
def load_template_config(self, template):
"""加载模板配置到界面"""
# 解绑之前的变量跟踪
self._unbind_var_trace()
self.template_name_var.set(template['name'])
self.coze_workflow_id_var.set(template.get('workflow_id', ''))
self.coze_access_token_var.set(template.get('access_token', ''))
self.coze_is_async_var.set(template.get('is_async', 'true'))
self.coze_input_data_template_var.set(template.get('input_data_template', ''))
self.edit_status_label.config(text="已加载", foreground="blue")
self.after(2000, lambda: self.edit_status_label.config(text=""))
# 重新绑定变量跟踪
self._setup_var_trace()
def _setup_var_trace(self):
"""设置变量跟踪以显示编辑状态"""
self.var_traces = []
for var in [self.template_name_var, self.coze_workflow_id_var,
self.coze_access_token_var, self.coze_is_async_var,
self.coze_input_data_template_var]:
trace_id = var.trace_add('write', lambda *args: self._show_edit_status())
self.var_traces.append((var, trace_id))
def _unbind_var_trace(self):
"""解绑变量跟踪"""
if hasattr(self, 'var_traces'):
for var, trace_id in self.var_traces:
try:
var.trace_remove('write', trace_id)
except Exception:
pass
self.var_traces = []
def _show_edit_status(self):
"""显示编辑状态"""
self.edit_status_label.config(text="未保存", foreground="red")
def add_template(self):
"""添加新模板"""
current_type = self.coze_generation_type_var.get()
# 获取当前模板列表中最大的序号
max_num = 0
for template in self.templates[current_type]:
try:
# 尝试将模板名称转换为整数
if template['name'].isdigit():
num = int(template['name'])
max_num = max(max_num, num)
except (ValueError, TypeError):
pass
template_name = f"{max_num + 1}"
# 获取当前配置作为默认值
default_workflow_id = CONFIG['Coze'].get('workflow_id', '')
default_access_token = CONFIG['Coze'].get('access_token', '')
default_is_async = CONFIG['Coze'].get('is_async', 'true')
default_template = CONFIG['Coze'].get('input_data_template',
'{"article": "{article_text}", "link":"{link}", "weijin":"{weijin}"}')
new_template = {
'name': template_name,
'type': current_type,
'workflow_id': default_workflow_id,
'access_token': default_access_token,
'is_async': default_is_async,
'input_data_template': default_template
}
self.templates[current_type].append(new_template)
self.update_template_list()
self.save_templates()
# 选中新添加的模板
self.template_listbox.selection_clear(0, tk.END)
self.template_listbox.selection_set(len(self.templates[current_type]) - 1)
self.load_template_config(new_template)
self.edit_status_label.config(text="已创建", foreground="green")
self.after(2000, lambda: self.edit_status_label.config(text="未保存", foreground="red"))
def delete_template(self):
"""删除选中的模板"""
selection = self.template_listbox.curselection()
if not selection:
messagebox.showwarning("提示", "请先选择要删除的模板")
return
index = selection[0]
current_type = self.coze_generation_type_var.get()
if current_type not in self.templates or index >= len(self.templates[current_type]):
return
template_name = self.templates[current_type][index]['name']
if messagebox.askyesno("确认删除", f"确定要删除模板 '{template_name}' 吗?"):
del self.templates[current_type][index]
self.update_template_list()
self.save_templates()
# 清除配置并更新状态
self.clear_template_config()
self.edit_status_label.config(text=f"已删除 '{template_name}'", foreground="red")
self.after(2000, lambda: self.edit_status_label.config(text=""))
# 如果还有模板,选中最后一个
if self.templates[current_type]:
last_index = len(self.templates[current_type]) - 1
self.template_listbox.selection_set(last_index)
self.load_template_config(self.templates[current_type][last_index])
def validate_template(self):
"""验证模板配置"""
name = self.template_name_var.get().strip()
workflow_id = self.coze_workflow_id_var.get().strip()
access_token = self.coze_access_token_var.get().strip()
input_template = self.coze_input_data_template_var.get().strip()
if not name:
messagebox.showerror("错误", "模板名称不能为空")
return False
if not workflow_id:
messagebox.showerror("错误", "Workflow ID不能为空")
return False
if not access_token:
messagebox.showerror("错误", "Access Token不能为空")
return False
if not input_template:
messagebox.showerror("错误", "输入数据模板不能为空")
return False
# 验证输入数据模板的JSON格式
try:
# 替换占位符以便验证JSON格式
test_template = input_template.replace('{article_text}', '')\
.replace('{link}', '')\
.replace('{weijin}', '')
json.loads(test_template)
except json.JSONDecodeError as e:
messagebox.showerror("错误", f"输入数据模板不是有效的JSON格式\n{str(e)}")
return False
return True
return True
def save_template(self):
"""保存当前模板配置"""
if not self.validate_template():
return
selection = self.template_listbox.curselection()
if selection:
index = selection[0]
current_type = self.coze_generation_type_var.get()
if current_type in self.templates and index < len(self.templates[current_type]):
template = self.templates[current_type][index]
template['name'] = self.template_name_var.get().strip()
template['workflow_id'] = self.coze_workflow_id_var.get().strip()
template['access_token'] = self.coze_access_token_var.get().strip()
template['is_async'] = self.coze_is_async_var.get()
template['input_data_template'] = self.coze_input_data_template_var.get().strip()
self.update_template_list()
self.save_templates()
self.edit_status_label.config(text="已保存", foreground="green")
self.after(2000, lambda: self.edit_status_label.config(text=""))
else:
messagebox.showwarning("未选择模板", "请先选择要保存的模板")
def rename_template(self):
"""重命名当前选中的模板"""
selection = self.template_listbox.curselection()
if not selection:
messagebox.showwarning("未选择模板", "请先选择要重命名的模板")
return
index = selection[0]
current_type = self.coze_generation_type_var.get()
if current_type not in self.templates or index >= len(self.templates[current_type]):
return
template = self.templates[current_type][index]
old_name = template['name']
# 弹出重命名对话框
new_name = simpledialog.askstring("重命名模板", "请输入新的模板名称:", initialvalue=old_name)
if new_name and new_name.strip() and new_name != old_name:
template['name'] = new_name.strip()
self.update_template_list()
self.save_templates()
# 重新选中重命名后的模板
self.template_listbox.selection_set(index)
self.edit_status_label.config(text="已重命名", foreground="green")
self.after(2000, lambda: self.edit_status_label.config(text=""))
def duplicate_template(self):
"""复制当前选中的模板"""
selection = self.template_listbox.curselection()
if not selection:
messagebox.showwarning("提示", "请先选择要复制的模板")
return
index = selection[0]
current_type = self.coze_generation_type_var.get()
if current_type not in self.templates or index >= len(self.templates[current_type]):
return
template = self.templates[current_type][index]
new_template = template.copy()
# 获取当前模板列表中最大的副本序号
base_name = template['name']
max_num = 0
for t in self.templates[current_type]:
if t['name'].startswith(f"{base_name}_副本"):
try:
num = int(t['name'].split('_副本')[-1]) if t['name'].split('_副本')[-1] else 1
max_num = max(max_num, num)
except (IndexError, ValueError):
pass
# 设置新的模板名称
new_name = f"{base_name}_副本{max_num + 1 if max_num > 0 else ''}"
new_template['name'] = new_name
self.templates[current_type].append(new_template)
self.update_template_list()
self.save_templates()
# 选中新复制的模板
new_index = len(self.templates[current_type]) - 1
self.template_listbox.selection_clear(0, tk.END)
self.template_listbox.selection_set(new_index)
self.load_template_config(new_template)
# 更新状态提示
self.edit_status_label.config(text=f"已复制为 '{new_name}'", foreground="green")
self.after(2000, lambda: self.edit_status_label.config(text="未保存", foreground="red"))
def use_template(self):
"""使用模板功能 - 弹出模板选择对话框并应用所选模板配置"""
# 创建模板选择对话框
dialog = tk.Toplevel(self)
dialog.title("选择模板")
dialog.geometry("400x300")
dialog.transient(self) # 设置为应用程序的子窗口
dialog.grab_set() # 模态对话框
dialog.resizable(False, False)
# 创建说明标签
ttk.Label(dialog, text="请选择要使用的模板:", font=("Arial", 10)).pack(pady=10)
# 创建模板类型选择框架
type_frame = ttk.Frame(dialog)
type_frame.pack(fill=tk.X, padx=10, pady=5)
ttk.Label(type_frame, text="模板类型:").pack(side=tk.LEFT, padx=5)
dialog_type_var = tk.StringVar(value=self.coze_generation_type_var.get())
type_combo = ttk.Combobox(type_frame, textvariable=dialog_type_var, values=["短篇", "文章"], width=10, state="readonly")
type_combo.pack(side=tk.LEFT, padx=5)
# 创建模板列表框架
list_frame = ttk.Frame(dialog)
list_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
# 创建模板列表和滚动条
template_listbox = tk.Listbox(list_frame, height=10, width=40)
scrollbar = ttk.Scrollbar(list_frame, orient="vertical", command=template_listbox.yview)
template_listbox.configure(yscrollcommand=scrollbar.set)
template_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
# 填充模板列表
def update_dialog_template_list():
template_listbox.delete(0, tk.END)
current_type = dialog_type_var.get()
if current_type in self.templates:
for template in self.templates[current_type]:
template_listbox.insert(tk.END, template['name'])
update_dialog_template_list()
# 绑定类型选择变更事件
def on_dialog_type_changed(event=None):
update_dialog_template_list()
type_combo.bind("<<ComboboxSelected>>", on_dialog_type_changed)
# 创建按钮框架
button_frame = ttk.Frame(dialog)
button_frame.pack(fill=tk.X, padx=10, pady=10)
# 定义确定按钮功能
def on_confirm():
selection = template_listbox.curselection()
if not selection:
messagebox.showwarning("未选择模板", "请先选择要使用的模板", parent=dialog)
return
index = selection[0]
current_type = dialog_type_var.get()
if current_type not in self.templates or index >= len(self.templates[current_type]):
return
selected_template = self.templates[current_type][index]
# 应用所选模板的配置
self.coze_generation_type_var.set(current_type) # 更新生成类型
self.generation_type_var.set(current_type) # 同步到主页面
# 更新工作流配置
self.coze_workflow_id_var.set(selected_template.get('workflow_id', ''))
self.coze_access_token_var.set(selected_template.get('access_token', ''))
self.coze_is_async_var.set(selected_template.get('is_async', 'true'))
self.coze_input_data_template_var.set(selected_template.get('input_data_template', ''))
# 更新CONFIG配置
CONFIG['Coze']['workflow_id'] = selected_template.get('workflow_id', '')
CONFIG['Coze']['access_token'] = selected_template.get('access_token', '')
CONFIG['Coze']['is_async'] = selected_template.get('is_async', 'true')
CONFIG['Coze']['input_data_template'] = selected_template.get('input_data_template', '')
# 保存配置
save_config(CONFIG)
# 更新模板列表和选中状态
self.update_template_list()
for i in range(self.template_listbox.size()):
if self.template_listbox.get(i) == selected_template['name']:
self.template_listbox.selection_set(i)
break
# 显示成功提示
self.edit_status_label.config(text=f"已应用模板 '{selected_template['name']}'", foreground="green")
self.after(2000, lambda: self.edit_status_label.config(text=""))
# 关闭对话框
dialog.destroy()
# 添加确定和取消按钮
ttk.Button(button_frame, text="确定", command=on_confirm).pack(side=tk.RIGHT, padx=5)
ttk.Button(button_frame, text="取消", command=dialog.destroy).pack(side=tk.RIGHT, padx=5)
# 设置默认选中第一个模板
if template_listbox.size() > 0:
template_listbox.selection_set(0)
# 等待对话框关闭
self.wait_window(dialog)
def clear_template_config(self):
"""清空模板配置界面"""
# 解绑变量跟踪
self._unbind_var_trace()
# 清空所有配置字段
self.template_name_var.set('')
self.coze_workflow_id_var.set('')
self.coze_access_token_var.set('')
self.coze_is_async_var.set('true')
self.coze_input_data_template_var.set('')
# 清空状态提示
self.edit_status_label.config(text="已清空", foreground="gray")
self.after(2000, lambda: self.edit_status_label.config(text=""))
# 重新绑定变量跟踪
self._setup_var_trace()
def load_templates(self):
"""从配置文件加载模板"""
try:
import json
# 检查Templates节是否存在
if 'Templates' in CONFIG:
templates_section = CONFIG['Templates']
for key in templates_section:
if key.startswith('templates_'):
template_type = key.replace('templates_', '')
if template_type in self.templates:
value = templates_section[key]
# 确保value是字符串类型
if isinstance(value, str):
self.templates[template_type] = json.loads(value)
else:
logger.warning(f"模板配置{key}的值不是字符串类型: {type(value)}")
self.templates[template_type] = []
except Exception as e:
logger.error(f"加载模板配置失败: {e}")
def save_templates(self):
"""保存模板到配置文件"""
try:
import json
# 确保Templates节存在
if 'Templates' not in CONFIG:
CONFIG.add_section('Templates')
for template_type, templates in self.templates.items():
CONFIG['Templates'][f'templates_{template_type}'] = json.dumps(templates, ensure_ascii=False)
save_config(CONFIG)
except Exception as e:
logger.error(f"保存模板配置失败: {e}")
messagebox.showerror("保存失败", f"保存模板配置时出错:{e}")
def get_current_template(self):
"""获取当前选中的模板配置"""
selection = self.template_listbox.curselection()
if selection:
index = selection[0]
current_type = self.coze_generation_type_var.get()
if current_type in self.templates and index < len(self.templates[current_type]):
return self.templates[current_type][index]
# 如果没有选中模板,返回当前界面的配置
return {
'name': self.template_name_var.get() or '默认模板',
'type': self.coze_generation_type_var.get(),
'workflow_id': self.coze_workflow_id_var.get(),
'access_token': self.coze_access_token_var.get(),
'is_async': self.coze_is_async_var.get(),
'input_data_template': self.coze_input_data_template_var.get()
}
def browse_directory(self, var):
directory = filedialog.askdirectory()
if directory:
@ -490,6 +1026,9 @@ class ArticleReplaceApp(tk.Tk):
CONFIG['Coze']['is_async'] = self.coze_is_async_var.get()
CONFIG['Coze']['input_data_template'] = self.coze_input_data_template_var.get() # 保存 Coze input data 模板
# 保存模板配置
self.save_templates()
# 更新Baidu配置
CONFIG['Baidu']['api_key'] = self.baidu_api_key_var.get()
CONFIG['Baidu']['secret_key'] = self.baidu_secret_key_var.get()
@ -560,8 +1099,14 @@ class ArticleReplaceApp(tk.Tk):
# 获取AI服务提供商选择
ai_service = self.ai_service_var.get()
# 获取生成类型
generation_type = self.generation_type_var.get()
# 获取当前选中的模板配置
current_template = self.get_current_template()
# 在新线程中运行处理任务
self.thread = threading.Thread(target=self.run_processing, args=(excel_path, num_threads, ai_service))
self.thread = threading.Thread(target=self.run_processing, args=(excel_path, num_threads, ai_service, generation_type, current_template))
self.thread.daemon = True
self.thread.start()
@ -572,7 +1117,7 @@ class ArticleReplaceApp(tk.Tk):
self.start_button.config(state=tk.NORMAL)
self.running = False
def run_processing(self, excel_path, num_threads, ai_service):
def run_processing(self, excel_path, num_threads, ai_service, generation_type=None, current_template=None):
"""在后台线程中运行处理任务"""
try:
# 更新全局变量
@ -582,9 +1127,32 @@ class ArticleReplaceApp(tk.Tk):
# 记录开始时间
start_time = time.time()
# 如果有模板配置临时更新CONFIG
original_config = None
if current_template and ai_service == 'coze':
original_config = {
'workflow_id': CONFIG['Coze']['workflow_id'],
'access_token': CONFIG['Coze']['access_token'],
'is_async': CONFIG['Coze']['is_async'],
'input_data_template': CONFIG['Coze'].get('input_data_template', '')
}
CONFIG['Coze']['workflow_id'] = current_template.get('workflow_id', '')
CONFIG['Coze']['access_token'] = current_template.get('access_token', '')
CONFIG['Coze']['is_async'] = current_template.get('is_async', 'true')
CONFIG['Coze']['input_data_template'] = current_template.get('input_data_template', '')
logger.info(f"应用模板配置: {current_template.get('name')}")
logger.info(f"Workflow ID: {CONFIG['Coze']['workflow_id']}")
logger.info(f"Access Token: {'*' * len(CONFIG['Coze']['access_token'])}")
logger.info(f"Is Async: {CONFIG['Coze']['is_async']}")
logger.info(f"Input Template: {CONFIG['Coze']['input_data_template']}")
# 读取链接并处理
logger.info(f"开始处理链接,使用 {num_threads} 个线程")
results = link_to_text(num_threads=num_threads, ai_service=ai_service)
logger.info(f"开始处理链接,使用 {num_threads} 个线程,生成类型: {generation_type}")
if current_template:
logger.info(f"使用模板: {current_template.get('name', '未命名')}")
results = link_to_text(num_threads=num_threads, ai_service=ai_service, current_template=current_template)
# 计算处理结果
total_links = len(results)
@ -604,8 +1172,15 @@ class ArticleReplaceApp(tk.Tk):
f"共处理 {total_links} 个链接\n成功: {success_links}\n失败: {total_links - success_links}\n总耗时: {elapsed_time:.2f}"))
except Exception as e:
logger.error(f"处理任务出错: {e}")
self.after(0, lambda: messagebox.showerror("处理失败", f"处理任务出错:{e}"))
self.after(0, lambda e=e: messagebox.showerror("处理错误", f"处理任务出错: {e}"))
finally:
# 恢复原始配置(如果有的话)
if original_config is not None:
CONFIG['Coze']['workflow_id'] = original_config['workflow_id']
CONFIG['Coze']['access_token'] = original_config['access_token']
CONFIG['Coze']['is_async'] = original_config['is_async']
CONFIG['Coze']['input_data_template'] = original_config['input_data_template']
# 恢复开始按钮状态
self.after(0, lambda: self.start_button.config(state=tk.NORMAL))
self.running = False

View File

@ -12,12 +12,13 @@ from config import *
# ==============================主程序===========================
def process_link(link_info, ai_service):
def process_link(link_info, ai_service, current_template=None):
link, article_type = link_info # 解包链接和类型信息
"""
处理单个链接
:param link: 要处理的链接
:param ai_service: AI服务提供商可选值dify, coze
:param current_template: 当前选择的模板配置
"""
try:
if link.startswith("https://www.toutiao.com"):
@ -81,30 +82,52 @@ def process_link(link_info, ai_service):
# }
message_content = call_dify_workflow(input_data)
elif ai_service == "coze":
# logger.info("coze正在处理")
# weijin = ""
# if check_keywords:
# weijin = "违禁"
# # 从配置加载 Coze input_data 模板
# input_data_template_str = CONFIG['Coze'].get('input_data_template',
# '{{"article": "{article_text}", "link":"{link}", "weijin":"{weijin}"}}')
# try:
# # 解析模板字符串为字典
# input_data_template = json.loads(input_data_template_str)
# # 使用实际变量格式化模板
# input_data = {k: v.format(article_text=article_text, link=link, weijin=weijin) for k, v in
# input_data_template.items()}
# except (json.JSONDecodeError, KeyError, AttributeError) as e:
# logger.error(f"处理 Coze input_data 模板时出错: {e}. 使用默认模板.")
# input_data = {
# "article": article_text,
# "link": link,
# "weijin": weijin
# }
logger.info("coze正在处理")
# 如果有模板配置临时更新CONFIG
original_config = None
if current_template:
original_config = {
'workflow_id': CONFIG['Coze']['workflow_id'],
'access_token': CONFIG['Coze']['access_token'],
'is_async': CONFIG['Coze']['is_async'],
'input_data_template': CONFIG['Coze'].get('input_data_template', '')
}
CONFIG['Coze']['workflow_id'] = current_template.get('workflow_id', '')
CONFIG['Coze']['access_token'] = current_template.get('access_token', '')
CONFIG['Coze']['is_async'] = current_template.get('is_async', 'true')
CONFIG['Coze']['input_data_template'] = current_template.get('input_data_template', '')
logger.info(f"应用模板配置: {current_template.get('name')}")
logger.info(f"Workflow ID: {CONFIG['Coze']['workflow_id']}")
logger.info(f"Access Token: {'*' * len(CONFIG['Coze']['access_token'])}")
logger.info(f"Is Async: {CONFIG['Coze']['is_async']}")
logger.info(f"Input Template: {CONFIG['Coze']['input_data_template']}")
try:
# 从配置加载 Coze input_data 模板
input_data_template_str = CONFIG['Coze'].get('input_data_template',
'{"article": "{article_text}", "link":"{link}", "weijin":"{weijin}"}')
# 解析模板字符串为字典
input_data_template = json.loads(input_data_template_str)
# 使用实际变量格式化模板
input_data = input_data_template
except (json.JSONDecodeError, KeyError, AttributeError) as e:
logger.error(f"处理 Coze input_data 模板时出错: {e}. 使用默认模板.")
input_data = {
"article": article_text
}
try:
message_content = call_coze_article_workflow(input_data)
finally:
# 恢复原始配置(如果有的话)
if original_config is not None:
CONFIG['Coze']['workflow_id'] = original_config['workflow_id']
CONFIG['Coze']['access_token'] = original_config['access_token']
CONFIG['Coze']['is_async'] = original_config['is_async']
CONFIG['Coze']['input_data_template'] = original_config['input_data_template']
# 获取当前时间并格式化
current_time = datetime.now().strftime("%H:%M:%S")
@ -151,7 +174,7 @@ def process_link(link_info, ai_service):
if img_urls:
# 在类型目录下创建图片目录
type_picture_dir = os.path.join(PICTURE_BASE_PATH, article_type)
type_picture_dir = os.path.join(IMGS_BASE_PATH, article_type)
safe_open_directory(type_picture_dir)
download_and_process_images(img_urls, file_name, type_picture_dir)
@ -160,7 +183,7 @@ def process_link(link_info, ai_service):
raise
def link_to_text(prompt1=None, prompt2=None, num_threads=None, ai_service="dify"):
def link_to_text(num_threads=None, ai_service="dify", current_template=None):
use_link_path = 'use_link_path.txt'
# 读取链接
@ -174,13 +197,14 @@ def link_to_text(prompt1=None, prompt2=None, num_threads=None, ai_service="dify"
database = CONFIG['Database']['database']
for link_info in links:
link = link_info[0] # 获取链接
link = link_info[0].strip() # 获取链接并去除空白字符
article_type = link_info[1].strip() # 获取类型并去除空白字符
logging.info(f"总共{len(links)}个链接")
# if check_link_exists(host, user, password, database, link):
# logger.info(f"链接已存在: {link}")
# continue
# else:
filtered_links.append(link)
filtered_links.append((link, article_type)) # 保存链接和类型的元组
# logger.info(f"链接不存在: {link}")
# print("链接不存在,存储到过滤器中:", link)
@ -189,7 +213,7 @@ def link_to_text(prompt1=None, prompt2=None, num_threads=None, ai_service="dify"
return []
# 使用多线程处理链接
results = process_links_with_threads(filtered_links, num_threads, ai_service)
results = process_links_with_threads(filtered_links, num_threads, ai_service, current_template)
# 记录已处理的链接
with open(use_link_path, 'a+', encoding='utf-8') as f:
@ -206,7 +230,7 @@ result_queue = queue.Queue()
# 工作线程函数
def worker(ai_service):
def worker(ai_service, current_template=None):
while True:
try:
# 从队列中获取任务
@ -217,7 +241,7 @@ def worker(ai_service):
# 处理链接
try:
logger.info(f"开始处理链接:{link}")
process_link(link, ai_service)
process_link(link, ai_service, current_template)
result_queue.put((link, True, None)) # 成功
except Exception as e:
result_queue.put((link, False, str(e))) # 失败
@ -230,7 +254,7 @@ def worker(ai_service):
# 多线程处理链接
def process_links_with_threads(links, num_threads=None, ai_service="dify"):
def process_links_with_threads(links, num_threads=None, ai_service="dify", current_template=None):
if num_threads is None:
num_threads = min(MAX_THREADS, len(links))
else:
@ -245,9 +269,9 @@ def process_links_with_threads(links, num_threads=None, ai_service="dify"):
# 创建工作线程
threads = []
# 将AI服务选择传递给worker函数
# 将AI服务选择和模板配置传递给worker函数
for _ in range(num_threads):
t = threading.Thread(target=worker, args=(ai_service,))
t = threading.Thread(target=worker, args=(ai_service, current_template))
t.daemon = True
t.start()
threads.append(t)