针对写博客的流程优化

每日一言

Leaf Village Secret-Finger Justu…1,000 Years of Death!!! sticks his fingers up Naruto’s ass – Hatake Kakashi
from Naruto

背景

本人使用hexo写blog,有一台闲置的手机,结合termux终端,将hexo服务搭建在手机中,手机24小时运行,并且会将手机中的blog同步到github page上。实现内网+公网都可以访问自己的blog。

自动信息头

问题

hexo的blog都有一个信息头,用于存储该blog的一些简单信息:

1738577999910

每次都需要手动复制上一次blog的信息头,粘贴过来再改信息。非常麻烦且不方便。

解决办法

编写一个python程序,输入简单信息,自动创建模板文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
title = "blog上传服务器升级"
categories = '记录'
tags = 'python'
from datetime import datetime
# 获取当前时间
current_time = datetime.now()
# 以指定格式打印时间
formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S")
file_name = title + current_time.strftime("_%Y%m%d_%H%M%S")+ ".md"

# 获取随机中二语句
import requests
url = "https://animechan.io/api/v1/quotes/random"
response = requests.get(url, timeout=10)
content = response.json()['data']['content']
anime_name = response.json()['data']['anime']['name']
character_name = response.json()['data']['character']['name']
text = content + " -- " + character_name + '\n' + 'from ' + anime_name;

# 写入文件
with open(file_name, 'w') as f:
f.write('---\n')
f.write('title: {}\n'.format(title))
f.write('date: {}\n'.format(formatted_time))
f.write('categories: {}\n'.format(categories))
f.write('tags: {}\n'.format(tags))
f.write('---\n')
f.write('# 每日一言\n')
text = content + " -- " + character_name + '\n' + 'from ' + anime_name
f.write(text)
f.write('\n\n <!-- more --> \n\n')

只需手动填写三个基本信息,就可以将博客的模板创建出来。

将文件传输到服务器端

问题

每次在电脑端写好博客后,需要将md文件和相关图片上传到服务器。我在服务器端部署了smb服务,所以可以通过直接将文件托过去来实现,但是每次都要打开对应文件夹,托过去。虽然一开始觉得方便,但是用久了之后依然还是觉得麻烦。想要只用点一下就能够自动将md文件和图片自动上传到合适的位置。

1738581659930

实现方法

依然通过python程序实现,这次我们需要借助第三方库 pysmb

所以这里我们学习一下pysmb库简单的使用方法

准备参数

要进行smb连接,我们首先需要知道一下参数:

1
2
3
4
5
6
server_ip = "" # 服务器 IP 地址
server_name = "" # 服务器名称
share_name = "" # 共享名称
username = "" # 登录用户名
password = "" # 登录密码
port = # 指定目标端口

这里我们简单介绍三种最简单的用法:

  • 读取文件
  • 写入文件
  • 创建目录

读取文件

读取文件还需要知道文件的路径:

1
file_path = "" 
1
2
3
4
5
6
7
8
9
10
11
12
def read_file_from_smb(server_ip, server_name, share_name, file_path, username, password, port=445):
# 创建 SMB 连接
conn = SMBConnection(username, password, "client_machine_name", server_name, use_ntlm_v2=True) #创建连接实例
assert conn.connect(server_ip, port) # 连接服务器

# 以二进制打开文件
with open("downloaded_file.txt", "wb") as file_obj:
# 从 SMB 服务器读取文件
conn.retrieveFile(share_name, file_path, file_obj)

# 关闭连接
conn.close()

写入文件

1
2
3
4
5
6
7
8
9
10
11
12
def write_file_to_smb(server_ip, server_name, share_name, file_path, username, password, port=445):
# 创建 SMB 连接
conn = SMBConnection(username, password, "client_machine_name", server_name, use_ntlm_v2=True)
assert conn.connect(server_ip, port)

# 用二进制读取文件
with open("input.txt", "rb") as file_obj:
# 写入文件到 SMB 服务器
conn.storeFile(share_name, file_path, file_obj)

# 关闭连接
conn.close()

创建文件夹

创建文件夹还需要知道文件夹路径:

1
dir_path = "hexo/source/image/dir_name"  # 目录路径
1
2
3
4
5
6
7
8
9
10
def creat_dir_on_smb(server_ip, server_name, share_name, dir_path, username, password, port=445):
# 创建 SMB 连接
conn = SMBConnection(username, password, "client_machine_name", server_name, use_ntlm_v2=True)
assert conn.connect(server_ip, port)

# 创建目录
conn.createDirectory(share_name, dir_path)

# 关闭连接
conn.close()

这样的话我们只需要通过程序将博客以及博客中需要的图片一并传送到smb服务端即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# 输入文件名
filename = "测试一次_20250203_170811"
filename = filename + ".md"
import re
import os
import glob
from smb.SMBConnection import SMBConnection

# 服务器参数
server_ip = ""
server_name = "SERVER_NAME"
share_name = "blog"
file_path = "hexo/source/_posts/" + filename
username = "ulna"
password = ""
port = 4445 # 指定目标端口
directory = r"/image\\" + filename.split('.')[0]
img_dir = "hexo/source/image/" + filename.split('.')[0]
# 读取文件内容
with open(filename, 'r', encoding='utf-8') as file:
content = file.read()

# 使用正则表达式替换内容
modified_text = re.sub(r'(?<!\/)\bimage\b', r'/image', content)
def get_all_images(directory):
# 支持的图片文件扩展名
image_extensions = ['*.jpg', '*.jpeg', '*.png', '*.bmp', '*.gif']

# 初始化一个空列表来存储图片文件路径
image_files = []

# 遍历所有扩展名并获取匹配的文件
for extension in image_extensions:
image_files.extend(glob.glob(os.path.join(directory, extension)))

return image_files

def write_file_to_smb(server_ip, server_name, share_name, file_path, username, password, port=445, modified_text=""):
# 创建 SMB 连接
conn = SMBConnection(username, password, "client_machine_name", server_name, use_ntlm_v2=True)
assert conn.connect(server_ip, port)

from io import BytesIO
file_obj = BytesIO(modified_text.encode('utf-8')) # 将字符串转换为字节流
conn.storeFile(share_name, file_path, file_obj)

# 关闭连接
conn.close()

def upload_images(server_ip, server_name, share_name, img_dir, username, password, port=445, directory=""):
# 创建 SMB 连接
conn = SMBConnection(username, password, "client_machine_name", server_name, use_ntlm_v2=True)
assert conn.connect(server_ip, port)

# 获取所有图片文件
image_files = get_all_images(directory)

#新建目录
conn.createDirectory(share_name, img_dir)

# 上传所有图片文件
for image_file in image_files:
with open(image_file, 'rb') as file_obj:
conn.storeFile(share_name, img_dir + "/" + os.path.basename(image_file), file_obj)

# 关闭连接
conn.close()

write_file_to_smb(server_ip, server_name, share_name, file_path, username, password, port, modified_text)
upload_images(server_ip, server_name, share_name, img_dir, username, password, port, directory)
print("博客已上传到服务器!")

针对写博客的流程优化
http://blog.ulna520.com/2025/02/03/blog上传服务器升级_20250203_174038/
Veröffentlicht am
February 3, 2025
Urheberrechtshinweis