obsidian笔记同步方案

前言

obsidian 是一款基于本地文件的笔记软件,所以笔记的多端同步是个问题,虽然官方推出了自己的同步服务,但是本着能自己解决就自己解决的态度,我自己研究出了一个比较完美的同步方案。

解决方案

因为我用的是苹果手机,所以自然而然的考虑到了 icloud 同步这个方法。 在手机版 obsidian 上创建笔记库,在 windows 上下载 icloud,登录 icloud 账号,obsidian 选择在 icloud 中打开笔记文件。 经过如上操作之后就解决了同步问题,本篇完(并没有) ^8fe52d

起初我是通过这种方案,但是使用一段时间后发现,在写笔记的过程中,obsidian 经常弹出「文件被外部修改,正在合并」的提示,然后再 icloud 中就会出现若干个重复笔记。 类似这样:

 

而且写着写着经常会有几行笔记消失了。 所以以上几宗罪使 icloud 同步变得很难用。

真·解决方案

自动同步 icloud 和本地

为了解决上述问题,我写了一个自动同步的程序,使其每隔两分钟在本地文件和 icloud 中同步一次。 同步的代码如下:

def file_cmp(f1,f2):
    res = filecmp.dircmp(f1,f2)
    common_dirs = res.common_dirs
    common_files = res.common_files
    same_files = res.same_files
    left_only = res.left_only
    right_only = res.right_only

    # 只有目标地址有的文件则直接删除
    if right_only != []:
        for i in range(0,len(right_only)):
            _newpath = f2+"\\"+right_only[i]
            if os.path.isdir(_newpath):
                os.removedirs(_newpath)
            else:
                os.remove(_newpath)


    # 共有但有不同的文件进行拷贝
    if common_files != []:
        for i in range(0,len(common_files)):
            if common_files[i] not in same_files:
                shutil.copy(f1+"\\"+common_files[i],f2+"\\"+common_files[i])

    # 只有源地址有的文件和目录则直接拷贝
    if left_only != []:
        for i in range(0,len(left_only)):
            if os.path.isdir(f1+"\\"+left_only[i]):
                shutil.copytree(f1+"\\"+left_only[i],f2+"\\"+left_only[i])
            else:
                shutil.copy(f1+"\\"+left_only[i],f2+"\\"+left_only[i])


    # 有共同目录则递归比较子目录
    if common_dirs != []:
        for i in range(0,len(common_dirs)):
            file_cmp(f1+"\\"+common_dirs[i],f2+"\\"+common_dirs[i])

然后我们建立一个 while 循环,持续运行这段代码,并且监测时间,当时间超过 2 分钟后进行一次备份。

nowtime = time.time()
    oldtime = nowtime + backuptime*60
    while True:
        nowtime = time.time()
        if nowtime >= oldtime:
            file_cmp(filepath1,filepath2)
            oldtime += backuptime*60

文件同步就实现了,但是我的笔记是需要经常在不同的设备上打开的,所以在主程序中我们加入这么一行:

# 打开软件时先从目标地址拉取最新版本
 file_cmp(filepath2,filepath1)

这样,当打开程序时,首先先拉取一次 icloud 上的笔记文件,之后就每隔 2 分钟向 icloud 中同步一次。

让 obsidian 和我的程序同步启动和关闭

同步关闭

思路是要让 obsidian 和我的程序同步关闭,则需要持续监听 obsidian 进程是否存在,如果 obsidian 进程不存在,则自动关闭程序。 代码如下:

# 监听某个进程是否存在
def checkprocess(processname):
    plist = psutil.pids() 
    msgcode = 0
    for pid in plist:
        try:
            if psutil.Process(pid).name() == processname:
                msgcode = 1
                break
            else:
                msgcode = 0
        except Exception:
            msgcode = 0
    return msgcode

以上代码是用于监听某个程序是否存在,接着我们写一个方法,让 obsidian 关闭之后,程序过 140 秒之后再结束,这样就有充足的时间备份到云端,代码如下:

def delay():
    while True:
        if checkprocess("Obsidian.exe") == 0:
            # 让程序延迟一会儿再执行,以便程序完成备份
            time.sleep(backuptime*70)
            os._exit(0)

然后在主函数中新建一个线程打开这个方法:

thread_it(delay)

现在就实现了当 Obsidian 进程关闭时,就自动关闭程序

同步启动

我们将写好的程序打包成 EXE,这里我是用 pyinstaller 作为打包工具 在命令行中输入:

pyinstaller -F -w comfile.py

等待片刻,将 dist 中的 exe 文件拷到别的地方(方便你自己找到)。 假设你已经拷好了,在同一个目录下建立一个 txt,名称和后缀改成:"obsidian.bat",如下:

 

start "" "obsidian 的路径"
start "" "刚才的拷贝的 exe 的路径"

上面输入你自己的路径,保存。 接下来,还是在这个文件夹下的空白位置右键,新建一个快捷方式,在弹出的窗口中输入如下内容:

同样的,后面输入刚才创建的的 bat 文件路径,点击下一步。

 

这里命名为 obsidian.exe,点击完成,这时文件夹下就出现了一个「obsidian.exe」的快捷方式,为了更直观的操作,我们改一下他的图标,接着我们右键这个快捷方式,找到「更改图标」按钮,在弹出来的窗口中找到 obsidian.exe 的文件路径,点击确定。 

到此,所有的操作完毕,你可以像其他快捷方式一样,将这个快捷方式拖到开始界面,任务栏或者桌面。并且,点击它会自动打开 obsidian 和文件同步程序,点开后,我们在任务管理里可以看到程序已经在运行了 当 obsidian 关闭时,该进程也会自动关闭,基本是无缝无感的操作体验。这样我的多端同步问题就解决了。

结语

本篇是基于 icloud 方式进行同步,其实 icloud 还可以替换为坚果云或者其他的云盘软件。 如果不想使用云盘软件,那么在本文的基础上,你也可以搭建基于 webdav 的同步方案,如果有需要的话我可以再出一期 webdav 的笔记同步方案。

“您的支持是我持续分享的动力”

微信收款码
微信
支付宝收款码
支付宝

目录