本帖最后由 梦汐 于 2024-4-30 02:43 编辑
说明:网盘要么有同步文件夹数量限制,要么不过滤就一股脑全上传整个文件夹,于是花了一两个小时写了个脚本优化一下,缺点是额外占用存储空间,原理就是py先检测差异,然后同步到本地文件夹,再通过网盘同步本地的同步文件夹
下面是我自用的JSON,功能就是从文档里挑选出list这几个子文件夹,然后同步文件到我指定的target目录,同步完再到网盘里添加D:\\Yunchu为同步目录就可以了,如果要同步source和target的文件需要重新运行脚本
作用大概就是可以无限添加同步文件夹,且可以只保留需要的子文件夹
json
{
"Yunchu": "1.0",
"enumeration": [
{
"source": {
"mode": "contains",
"path": "C:\\Users\\25678\\Documents",
"list": [
"GitHub",
"My Games",
"图片"
]
},
"target": "D:\\Yunchu\\Documents"
}
]
}
code
import filecmp
import os
import shutil
import json
def GetFileDiff(source_dir, target_dir, inherit=None):
if inherit == None:
this = []
else:
this = inherit
dir_cmp = filecmp.dircmp(source_dir, target_dir)
for path_name in dir_cmp.left_only:
filepath = os.path.join(source_dir, path_name)
filetype = "dir" if os.path.isdir(filepath) else "file"
if filetype == "dir": # 取出目录下的子文件
for root, dir, files in os.walk(filepath):
for file in files: # 全文件夹进行复刻
source = os.path.join(root, file)
target = target_dir + source[len(source_dir):]
target = os.path.abspath(target)
bag = {
"source": source,
"target": target
}
this.append(bag)
else: # 非子目录新增文件
source = os.path.join(source_dir, filepath)
target = target_dir + source[len(source_dir):]
target = os.path.abspath(target)
bag = {
"source": source,
"target": target
}
this.append(bag)
for path_name in dir_cmp.diff_files: # 目标或源目录文件发生变化时更新目标目录文件
this.append(os.path.join(source_dir, path_name)) # 文件压缩后会与源文件不同
for path_name in dir_cmp.right_only:
# 将目标文件夹中新增的文件移动到变更文件夹中或删除
os.remove(os.path.abspath(os.path.join(target_dir, path_name)))
for common_dir in dir_cmp.common_dirs:
new_source = os.path.join(source_dir, common_dir)
new_target = os.path.join(target_dir, common_dir)
GetFileDiff(new_source, new_target, this)
return this
config = None
with open("config.json", encoding="utf-8") as file:
config = json.loads(file.read())
print(config)
def transfer(source, target):
os.makedirs(source, exist_ok=True)
os.makedirs(target, exist_ok=True)
diffs = GetFileDiff(source,target)
for diff in diffs:
os.makedirs(os.path.dirname(diff['target']), exist_ok=True)
shutil.copy(diff['source'], diff['target'])
for i, obj in enumerate(config['enumeration']):
obj_type = type(obj['source'])
if obj_type == dict:
path = obj['source']['path']
items = obj['source']['list']
for item in items:
source = os.path.join(path, item)
target = os.path.join(obj['target'], item)
transfer(source, target)
else:
source = obj['source']
target = obj['target']
transfer(source, target)
print(i, obj)
|