2024-11-28 21:28

怎么说了,obsidan 的编辑的体验还是很不错的,如果可以直接发布到博客会方便些
拾月的文章,网上看到这个博主很早之前就这么弄,很有参考价值,tks!于是也大致这么弄了下,修改小部分内容。

思路:主要就是通过 xmlrpc 这个 api 来上传文章METAWEBLOG_API = 'http://xxxx/index.php/action/xmlrpc'

补充

  1. 上传结构
    0-img
    这个分类这里是 list,数组形式的;
    post_type 里面 post 是文章,还有一个 page 应该是页面
    倒数第 2 个是是否允许评论
  2. cid 与 slug
    slug 好像是一个自定义软连接,不是太会弄,忽略掉了。
    cid 是 typecho 的一个由博客生成的 int 类型数字,代表了某一篇文章,拾月的 blog 里面用到了来控制更新,我大致也是这么弄的,但是我使用本地 json 文件控制的。
  3. 图床
    用的 picList,很方便,可以用 alist 作为图床,alist 要有外部地址即可!

😄👍还是可以的,可以直接在本地发。

代码

用的插件那个 python_scipter, 代码如下:

# 脚本1
#!/usr/local/bin/python3
# -*- coding: UTF-8 -*-

import xmlrpc.client
import datetime
import json
import time
import re
import sys
import os
from post_img_alist import *
#import yaml


# 个人信息配置
BLOG_USERNAME = '' # 博客用户名
BLOG_PASSWORD = '' # 博客密码

OB_VAULT = '' # Obsidian的vault目录
PICTURE_PATH = r"" # 本地保证图片的目录,即我的Obsidian附件目录

METAWEBLOG_API = 'http://xxxx/index.php/action/xmlrpc' # 博客metaweblog api地址
JSON_FILE_PATH = r"cid.json" # 保存文件名和cid的json文件路径 我写的绝对路径

def save_cid(filename, cid):
    """
    将文件名和对应的 CID 保存到本地 JSON 文件中。
    如果 JSON 文件不存在,会创建一个新文件。
    如果已存在,则追加新的数据。
    """
    data = {}
    
    # 如果文件已存在,先读取现有数据
    if os.path.exists(JSON_FILE_PATH):
        with open(JSON_FILE_PATH, "r", encoding="utf-8") as f:
            try:
                data = json.load(f)
            except json.JSONDecodeError:
                data = {}  # 如果文件内容为空或损坏,初始化为空字典

    # 更新数据
    data[filename] = cid

    # 保存到 JSON 文件
    with open(JSON_FILE_PATH, "w", encoding="utf-8") as f:
        json.dump(data, f, indent=4, ensure_ascii=False)

def get_cid(filename):
    """
    从本地 JSON 文件中读取指定文件名的 CID。
    如果不存在对应的文件名,返回 0。
    """
    # 如果文件不存在,直接返回 0
    if not os.path.exists(JSON_FILE_PATH):
        return 0

    # 读取 JSON 文件
    with open(JSON_FILE_PATH, "r", encoding="utf-8") as f:
        try:
            data = json.load(f)
        except json.JSONDecodeError:
            return 0  # 如果文件内容为空或损坏,返回 0

    # 返回 CID 或 0
    return data.get(filename, 0)

def custom_replace_func(match_ct):
    Name = str(match_ct).split("/")[-1]
    fileName = PICTURE_PATH+"\\"+Name
    isOk,web_url = post_upload(fileName)
    if isOk:
        return web_url
    else:
        return str(f"![1-img](![[{match_ct}]])")

def process_md_content(md_content):
    """
    处理 Markdown 内容,提取被 ![2-img](![3-img](![[ 和 ]])) 包裹的内容,并替换为自定义内容。

    :param md_content: 原始 Markdown 内容
    :param custom_replace_func: 自定义替换函数,接受一个字符串参数,返回替换后的内容
    :return: 替换后的 Markdown 内容
    """
    # 定义匹配模式
    pattern = r"!\[\[(.*?)\]\]"
    # 使用正则提取所有被 ![2-img](![3-img](![[ 和 ]])) 包裹的内容
    matches = re.findall(pattern, md_content)

    # 遍历提取的内容,并使用自定义函数替换
    for idx,match in enumerate(matches):
        # 获取自定义替换内容
        replacement = custom_replace_func(match)
        # 将原内容替换为新的内容
        md_content = md_content.replace(f"![4-img](![[{match}]])", f"![{idx}-img]({replacement})")
    
    return md_content


def read_md(file_path):
    with open(file_path, 'r', encoding='utf-8') as file:
        content = file.read()
    file_name = os.path.splitext(os.path.basename(file_path))[0]
    content = process_md_content(content)
    return content, file_name


# JSON文件路径,全局使用
json_file_path_record = r"file_record.json"

def write_to_json_file(full_path, cid):
    """
    向 JSON 文件中写入数据。检查 full_path 是否已存在,若不存在则新增。

    :param full_path: 文件完整路径 (键)
    :param cid: 文件对应的 CID (值)
    """
    # 初始化数据存储
    data = {}
    
    # 如果 JSON 文件存在,读取内容
    if os.path.exists(json_file_path_record):
        try:
            with open(json_file_path_record, 'r', encoding='utf-8') as file:
                data = json.load(file)
        except Exception as e:
            # 如果文件读取失败,打印错误,但继续初始化空数据
            print(f"读取 JSON 文件失败: {e}")
            data = {}
    
    # 检查 full_path 是否已存在
    if full_path in data:
        print(f"路径 {full_path} 已存在,跳过写入。")
        return
    
    # 添加新的 full_path 和 cid
    data[full_path] = cid
    
    # 写入更新后的数据到 JSON 文件
    try:
        with open(json_file_path_record, 'w', encoding='utf-8') as file:
            json.dump(data, file, ensure_ascii=False, indent=4)
        print(f"已成功写入 {full_path} 和 {cid} 到文件。")
    except Exception as e:
        print(f"写入 JSON 文件失败: {e}")
        
# 创建文章,若文件已经存在,则自动更新,
#     入参:file要发布的文件,post_type发布类型(post-文章,page:页面)
def new_post(file_path):
    content,filaName = read_md(file_path)
    # slug = data['meta']['slug']
    # cid = get_cid(slug)
    cid = get_cid(filaName)
    # 构建发布内容
    struct = {
        'title': filaName,
        'dateCreated': datetime.datetime.now(),
        #'wp_slug': slug, 
        'categories': ['生活随记'], # 分类
        #'mt_keywords': data['meta']['blogtags'], # 标签
        'post_type': 'post',
        'mt_allow_comments': True,
        'description': content,
    }

    client = xmlrpc.client.ServerProxy(METAWEBLOG_API)

    if int(cid) > 0:
        try:
            result = client.metaWeblog.editPost(cid, BLOG_USERNAME, BLOG_PASSWORD, struct, True)
            print('\n文章已存在(cid={cid}),更新成功,信息如下:\n'.format(cid=cid))
            for key, value in struct.items():
                if key != 'description': print(key, ': ', value)
            print('\n')
        except Exception as e:
            print(e)
    else:
        cid = client.metaWeblog.newPost('',BLOG_USERNAME, BLOG_PASSWORD, struct, True)
        if cid != 0:
            save_cid(str(filaName), str(cid))
        print('\n发布成功(cid={cid}),信息如下:\n'.format(cid=cid))
        for key, value in struct.items():
            if key != 'description': print(key, ': ', value)
        print('\n')
    write_to_json_file(file_path, cid)


#还要保存下文件路径和cid的映射关系;
python_script = sys.argv[0]
file_path = sys.argv[2]
vault_path = sys.argv[1]
abs_file_path = os.path.abspath(os.path.join(vault_path, file_path))
#filepath = r"typcho测试草稿.md"
new_post(abs_file_path)

5-img

import requests
import json
import os
localImg_url_jsonPath = r"xxx.json"

def write_localimg(local_path, network_path):
    # Initialize an empty dictionary to store the data
    data = {}
    
    # Check if the JSON file exists
    if os.path.exists(localImg_url_jsonPath):
        try:
            # Load existing data from the JSON file
            with open(localImg_url_jsonPath, 'r', encoding='utf-8') as file:
                data = json.load(file)
        except Exception as e:
            # Handle JSON file read/parsing errors
            data = {}
    
    # Add or update the mapping for the given local path
    data[local_path] = network_path
    
    # Write the updated data back to the JSON file
    with open(localImg_url_jsonPath, 'w', encoding='utf-8') as file:
        json.dump(data, file, ensure_ascii=False, indent=4)

def check_localimg(image_url):
    # Check if the JSON file exists
    if not os.path.exists(localImg_url_jsonPath):
        return False, ""
    
    try:
        # Load the JSON file
        with open(localImg_url_jsonPath, 'r', encoding='utf-8') as file:
            data = json.load(file)
        
        # Check if the local image path exists in the JSON
        if image_url in data:
            return True, data[image_url]
        else:
            return False, ""
    except Exception as e:
        # Handle JSON file read/parsing errors
        return False, ""
    
    
def post_upload(image_url):
    is_have,web_url = check_localimg(image_url)
    if is_have:
        return True, web_url
    url = "http://127.0.0.1:36677/upload?xxxxx" # alist的上传链接
    headers = {'Content-Type': 'apication/json'}
    payload = {"list": [image_url]}
    
    try:
        response = requests.post(url, headers=headers, data=json.dumps(payload))
        if response.status_code == 200:
            result = response.json()
            success = result.get("success", False)
            uploaded_url = result.get("result", [])
            uploaded_url = uploaded_url[0]
            write_localimg(image_url, uploaded_url)
            return success, uploaded_url
        else:
            return False, []
    except Exception as e:
        return False, []


if __name__ == "__main__":
    img_url = r"xxFigure_1.png"
    success, uploaded_url = post_upload(img_url)
    print(success, uploaded_url)