1、安装库
pip install python-wordpress-xmlrpc,tkinter,xmlrpc,json
2、发布文章
url = "http://域名/xmlrpc.php"
username = 用户名
password = 密码
title = 标题
content = 内容
tags = 标签
categories = 分类
client = Client(url, username, password)#登录
post = WordPressPost()
post.title = title
post.content = content
post.post_status = 'publish'#文章状态,publish表示发布,private表示私密的,draft表示草稿
post.terms_names = {
'post_tag': tags,
'category': categories
}
client.call(posts.NewPost(post))#发布文章
3、增加功能
因为需要给同事使用,除了基本的发布文章,增加了其他功能:交互界面、保存账号密码、上传文件,以PDF文件直接发布文章、设置特色图片、文件做为下载链接转换到文章内容等。可直接编译使用。
4、整体程序代码
import tkinter as tk
from tkinter import filedialog, messagebox, Toplevel
from wordpress_xmlrpc import Client, WordPressPost
from wordpress_xmlrpc.methods import posts
from wordpress_xmlrpc.methods.media import UploadFile
import xmlrpc.client
from os.path import splitext, exists
import json
file_path = None
attachment_url = None
attachment_id=None
config_file = "config.json"
def save_credentials(username, password):
credentials = {"username": username, "password": password}
with open(config_file, "w") as f:
json.dump(credentials, f)
def load_credentials():
if exists(config_file):
with open(config_file, "r") as f:
return json.load(f)
return {}
def upload_file():#上传文件
global attachment_url, file_path, attachment_id
if file_path:
try:
url = "http://域名/xmlrpc.php"
username = username_entry.get()
password = password_entry.get()
client = Client(url, username, password)
mime_types = {
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg',
'.png': 'image/png',
'.gif': 'image/gif',
'.bmp': 'image/bmp',
'.pdf': 'application/pdf',
'.doc': 'application/msword',
'.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'.xls': 'application/vnd.ms-excel',
'.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'.ppt': 'application/vnd.ms-powerpoint',
'.pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'.txt': 'text/plain',
'.zip': 'application/zip',
'.rar': 'application/x-rar-compressed'
}
# 获取文件后缀名
file_extension = splitext(file_path)[1].lower()
mime_type = mime_types.get(file_extension, 'application/octet-stream')
data = {
'name': file_path,
'type': mime_type
}
# 显示上传进度
file_link_label.config(text="文件正在上传,请稍等!!!", fg="red", cursor="hand2")
# 上传文件
with open(file_path, 'rb') as f:
data['bits'] = xmlrpc.client.Binary(f.read())
print(data)
response = client.call(UploadFile(data))
attachment_id = response['id']
attachment_url = response['url']
file_link_label.config(text=f"文件链接: {attachment_url}", fg="blue", cursor="hand2")
file_link_label.bind("<Button-1>", lambda e: open_link(attachment_url))
print(f"特色图片: {attachment_id}")
messagebox.showinfo("成功", "文件上传成功!")
except Exception as e:
messagebox.showerror("错误", f"文件上传失败: {e}")
else:
messagebox.showwarning("警告", "请选择一个文件进行上传。")
def pdf_file_button():
global attachment_url
# 如果选中了PDF文件发布选项,则将链接添加到文章内容中
if attachment_url:
# 提取文件名作为标题
title = attachment_url.split('/')[-1].replace('-', ' ').split('.')[0]
# 生成嵌入 PDF 的短代码
shortcode = f'[pdf-embedder url="{attachment_url}" title="{title}"]'
current_content = content_text.get("1.0", tk.END)
if shortcode in current_content:
messagebox.showwarning("警告", "文章内容中已存在PDF链接,请勿重复添加。")
return
content_text.delete("1.0", tk.END)
content_text.insert(tk.END, shortcode)
else:
messagebox.showwarning("警告", "请先上传文件。")
def File_link_download():
global attachment_url
if attachment_url:
# 生成HTML a标签
link_text = "下载文件请点我!!!"
shortcode = f'<a href="{attachment_url}">{link_text}</a>'
current_content = content_text.get("1.0", tk.END)
if shortcode in current_content:
messagebox.showwarning("警告", "文章内容中已存在下载链接,请勿重复添加。")
return
content_text.insert(tk.END, shortcode)
else:
messagebox.showwarning("警告", "请先上传文件。")
def fetch_all_post_titles(client):
offset = 0
post_titles = []
while True:
posts_batch = client.call(posts.GetPosts({'number': 100, 'offset': offset}))
if not posts_batch:
break
post_titles.extend(post.title for post in posts_batch)
offset += 100
return post_titles
def publish_post():#上传文章
global attachment_url, attachment_id
url = "http://域名/xmlrpc.php"
username = username_entry.get()
password = password_entry.get()
title = title_entry.get()
content = content_text.get("1.0", tk.END).strip()
tags = tags_entry.get().split(',')
if not tags or tags == ['']:
tags = ['其他']
# 获取选择的分类
categories = [cat for cat, var in category_vars.items() if var.get()]
if not categories:
categories.append('其他')
client = Client(url, username, password)
post = WordPressPost()
post.title = title
post.content = content
post.post_status = 'publish'#文章状态,不写默认是草稿,private表示私密的,draft表示草稿,publish表示发布
post.terms_names = {
'post_tag': tags,
'category': categories
}
if attachment_id and featured_images_var.get():
post.thumbnail = attachment_id # 设置特色图片
print(f"特色图片: {attachment_id}")
try:
# 获取所有文章标题并检查是否重复
all_post_titles = fetch_all_post_titles(client)
if title in all_post_titles:
messagebox.showwarning("警告", "文章标题已存在,请更换标题。")
return
# 如果选择了文件但没有上传文件,先上传文件
if file_path and not attachment_url:
upload_file()
if attachment_id and featured_images_var.get():
post.thumbnail = attachment_id # 设置特色图片
print(f"特色图片: {attachment_id}")
# 如果有上传的文件,添加附件信息
#if attachment_url:
# 发布文章
client.call(posts.NewPost(post))
messagebox.showinfo("成功", "文章发布成功!")
# 保存用户名和密码
if save_credentials_var.get():
save_credentials(username, password)
except Exception as e:
messagebox.showerror("错误", f"发布失败: {e}")
print(f"Exception: {e}")
import traceback
traceback.print_exc()
def select_file():
global file_path, attachment_url
file_path = filedialog.askopenfilename(filetypes=[("JPEG files", "*.jpg"), ("Word files", "*.docx"), ("pdf files", "*.pdf")])
attachment_url = None
if file_path:
file_label.config(text=f"已选择文件: {file_path.split('/')[-1]}")
print(f"选择的文件: {file_path}")
def open_link(url):
import webbrowser
webbrowser.open_new(url)
def show_instructions():
# 创建新窗口
instructions_window = Toplevel(root)
instructions_window.title("软件使用说明")
# 设置窗口大小和位置
instructions_window.geometry("400x320")
# 使用说明文本
instructions_text = (
"这是一个WordPress站点的文章发布软件。\n\n"
"使用步骤:\n"
"1. 输入用户名和密码。\n"
"2. 输入文章标题和内容。\n"
"3. 选择文章的标签和分类。(不填默认是'其他')\n"
"4. 可选:选择并上传附件。 \n"
"5. 可选:PDF文件可以获取到内容中直接发布。\n"
"6. 可选:图片可以勾选作为特色图片。\n"
"7. 可选:其他文件可以做为下载链接获取到内容中。\n"
"8. 点击“发布文章”按钮,发布文章到WordPress站点。\n\n"
"您还可以选择保存用户名和密码以便下次自动填充。\n"
)
# 在窗口中添加说明文本
instructions_label = tk.Label(instructions_window, text=instructions_text, justify=tk.LEFT, wraplength=380)
instructions_label.pack(pady=10, padx=10)
# 添加关闭按钮
close_button = tk.Button(instructions_window, text="关闭", command=instructions_window.destroy)
close_button.pack(pady=5)
# 创建主窗口
root = tk.Tk()
root.title("WordPress 文章发布器")
# 组件标题
labels = ["用户名:", "密码:", "文章标题:", "文章内容:", "标签 (逗号分隔):", "分类 (多选):"]
max_label_len = max([len(label) for label in labels])
line_row = 0
column_number=6
# 用户名输入
tk.Label(root, text="用户名:").grid(row=line_row, column=0, sticky=tk.W, pady=5, padx=5)
username_entry = tk.Entry(root, width=50)
username_entry.grid(row=line_row, column=1, columnspan=column_number, pady=5, padx=5)
line_row += 1
# 密码输入
tk.Label(root, text="密码:").grid(row=line_row, column=0, sticky=tk.W, pady=5, padx=5)
password_entry = tk.Entry(root, show="*", width=50)
password_entry.grid(row=line_row, column=1, columnspan=column_number, pady=5, padx=5)
line_row += 1
# 文章标题输入
tk.Label(root, text="文章标题:").grid(row=line_row, column=0, sticky=tk.W, pady=5, padx=5)
title_entry = tk.Entry(root, width=50)
title_entry.grid(row=line_row, column=1, columnspan=column_number, pady=5, padx=5)
line_row += 1
# 文章内容输入
tk.Label(root, text="文章内容:").grid(row=line_row, column=0, sticky=tk.NW, pady=5, padx=5)
content_text = tk.Text(root, height=10, width=50)
content_text.grid(row=line_row, column=1, columnspan=column_number, pady=5, padx=5)
line_row += 1
# 文章标签输入
tk.Label(root, text="标签 (逗号分隔):").grid(row=line_row, column=0, sticky=tk.W, pady=5, padx=5)
tags_entry = tk.Entry(root, width=50)
tags_entry.grid(row=line_row, column=1, columnspan=column_number, pady=5, padx=5)
line_row += 1
# 文章分类选择
tk.Label(root, text="分类 (多选):").grid(row=line_row, column=0, sticky=tk.NW, pady=5, padx=5)
# 用于保存分类选择状态的变量
category_vars = {}
categories = ['其他', '11'] # 可根据需要添加更多分类
category_vars = {}
# 计算每行应该显示的复选框数量
num_columns = 5
# 计算总行数
num_rows = (len(categories) + num_columns - 1) // num_columns
# 创建并布局分类项复选框
for index, category in enumerate(categories):
var = tk.BooleanVar()
category_vars[category] = var
# 计算当前复选框应该放置的位置
row = index // num_columns + line_row
column = index % num_columns
# 使用grid布局放置复选框,并使其在每个单元格居中对齐
tk.Checkbutton(root, text=category, variable=var).grid(row=row + 1, column=column + 1, sticky=tk.W, pady=2, padx=5)
line_row += 6
# 文件选择按钮
tk.Label(root, text="附件:").grid(row=line_row, column=0, sticky=tk.W, pady=5, padx=5)
line_row += 1
file_btn = tk.Button(root, text="选择文件", command=select_file)
file_btn.grid(row=line_row, column=1, columnspan=column_number, pady=5, padx=5, sticky=tk.W)
line_row += 1
file_label = tk.Label(root, text="未选择文件")
file_label.grid(row=line_row, column=1, columnspan=column_number, pady=5, padx=5, sticky=tk.W)
line_row += 1
# 上传文件按钮
upload_btn = tk.Button(root, text="上传文件", command=upload_file)
upload_btn.grid(row=line_row, column=1, pady=5, padx=5, sticky=tk.W)
line_row += 1
# 文件链接标签
file_link_label = tk.Label(root, text="")
file_link_label.grid(row=line_row, column=1, columnspan=column_number, pady=5, padx=5, sticky=tk.W)
line_row += 1
# 上传文件为特色图片
featured_images_var = tk.BooleanVar(value=False) # 默认不勾选
featured_images = tk.Checkbutton(root, text="上传文件为特色图片")
featured_images.grid(row=line_row, column=1, columnspan=column_number, pady=5, padx=5, sticky=tk.W)
line_row += 1
# 将PDF文件链接放到文章内容中
pdf_file_button = tk.Button(root, text="PDF文件做为文件内容", command=pdf_file_button)
pdf_file_button.grid(row=line_row, column=1, columnspan=column_number, pady=5, padx=5, sticky=tk.W)
line_row += 1
# 将文件链接变成下载链接
download_Link = tk.Button(root, text="文件变成下载链接放文章内容中", command=File_link_download)
download_Link.grid(row=line_row, column=1, columnspan=column_number, pady=5, padx=5, sticky=tk.W)
line_row += 1
# 保存用户名和密码复选框
save_credentials_var = tk.BooleanVar(value=True) # 默认勾选
save_credentials_checkbutton = tk.Checkbutton(root, text="保存用户名和密码", variable=save_credentials_var)
save_credentials_checkbutton.grid(row=line_row, columnspan=column_number, column=1, pady=5, padx=5, sticky=tk.W)
line_row += 1
#软件说明按钮
instructions_button = tk.Button(root, text="使用说明", command=show_instructions)
instructions_button.grid(row=line_row, column=1, columnspan=column_number, pady=5, padx=5, sticky=tk.E)
line_row += 1
# 发布按钮
publish_button = tk.Button(root, text="发布文章", command=publish_post)
publish_button.grid(row=line_row, column=1, columnspan=column_number, pady=5, padx=5, sticky=tk.E)
line_row += 1
# 加载保存的用户名和密码
credentials = load_credentials()
if credentials:
username_entry.insert(0, credentials.get("username", ""))
password_entry.insert(0, credentials.get("password", ""))
# 运行主循环
root.mainloop()
5、注意:
网站防火墙需要添加白名单。
标签:xmlrpc,python,text,column,wordpress,tk,file,line,row From: https://blog.csdn.net/weixin_52037378/article/details/140133536