Folks, after testing this for a while, faced problems with large amounts of data being deleted and backed up to one drive(obviously would have run into this sooner or later).
Therefore here is another implementation.
Requirements: Python and windows.
Problem 1: to identify only changed files and copy them from iCloud folder to local folder. and vice versa.
Solution - Enable \d option in XCopy
Problem 2: Delete local iles that have been deleted in drive while opening Obsidian in windows, delete drive files that have been deleted in local while closing Obsidian.
Solution - Use “rglob” and figure out which files (Not Folders this still has to be manual) to delete.
Here is the whole solution I am working with:
Python File:
import re
import os
import sys
import glob
from pathlib import Path
NOTES_FOLDER_NAME = "<your-notes-folder-name>"
LOCAL_FOLDER_PATH = "E:"
DRIVE_FOLDER_PATH = 'C:/Users/<your-user-name>/iCloudDrive/iCloud~md~obsidian'
LOCAL_NOTES_FOLDER_PATH = os.path.join(LOCAL_FOLDER_PATH, NOTES_FOLDER_NAME)
DRIVE_NOTES_FOLDER_PATH = os.path.join(DRIVE_FOLDER_PATH, NOTES_FOLDER_NAME)
def get_local_files():
return [str(i) for i in list(Path(os.path.join(LOCAL_FOLDER_PATH, NOTES_FOLDER_NAME)).rglob("*"))]
def get_drive_files():
return [str(i) for i in list(Path(os.path.join(DRIVE_FOLDER_PATH, NOTES_FOLDER_NAME)).rglob("*"))]
def remove_path_precending_note_folder(file_paths :list):
return [re.sub(r".*"+NOTES_FOLDER_NAME, NOTES_FOLDER_NAME, i) for i in file_paths]
if __name__ == "__main__":
local_files = remove_path_precending_note_folder(get_local_files())
drive_files = remove_path_precending_note_folder(get_drive_files())
if sys.argv[1] == "1":
for i in list(set(local_files) - set(drive_files)):
file_path = os.path.join(LOCAL_FOLDER_PATH, i)
if Path(file_path).is_file():
print(f"deleting {file_path}")
os.remove(file_path)
else:
print(f"{file_path} is a directory")
else:
for i in list(set(drive_files) - set(local_files)):
file_path = os.path.join(DRIVE_FOLDER_PATH, i)
if Path(file_path).is_file():
print(f"deleting {file_path}")
os.remove(file_path)
else:
print(f"{file_path} is a directory")
.bat File:
@echo off
set cloudFolder="C:\Users\<your-username>\iCloudDrive\iCloud~md~obsidian\<your-notes-folder-name>"
set localFolder="E:\<your-notes-folder-name>"
set obsidianEXEPath=C:\Users\<your-user-name>\AppData\Local\Obsidian\Obsidian.exe
echo %cloudFolder%
echo %localFolder%
XCopy %cloudFolder% %localFolder% /e /h /c /i /d /y
"<python-installation-path>" "<python-file-path>" 1
pause
start /W %obsidianEXEPath%
XCopy %localFolder% %cloudFolder% /e /h /c /i /d /y
"<python-installation-path>" "<python-file-path>" 2
pause
Also I made a shortcut and pinned it to start with the target as:
C:\Windows\System32\cmd.exe /c "C:\Users\<your-user-name>\Desktop\open obsidian.bat"
This way I can start Obsidian the normal way.
Hope this is helpful to somebody struggling like me.
Key Notes:
- Close Obsidian on mobile before working on it on the desktop.
- I faced issues with plugins, but when I installed them directly from mobile, they worked.
By no means is this the best solution, but for me it has been the fastest and reliable one.