Last active
February 17, 2023 19:30
-
-
Save dariosky/7484835c7753c2fe373debd04227b047 to your computer and use it in GitHub Desktop.
A Python script to be run in a Dropbox folder - so it exclude all the node_modules and __pycache__ folders - we want them locally but not in the cloud
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import argparse | |
import os | |
import shutil | |
from xattr import xattr | |
top_folder = "." | |
CACHE_FOLDERS = {"__pycache__", ".pytest_cache", ".cache"} | |
EXCLUDED_FOLDERS = {"node_modules", ".tox"} | CACHE_FOLDERS | |
NUKED_FOLDERS = {f"{folder} (Ignored Item Conflict)" for folder in EXCLUDED_FOLDERS} | |
def exclude_folder(root, dir_name): | |
full_path = os.path.join(root, dir_name) | |
attrs = xattr(full_path) | |
if "com.dropbox.ignored" not in attrs: | |
print(full_path) | |
xattr(full_path).set("com.dropbox.ignored", b"1") | |
def empty_folder(folder_path): | |
content = os.listdir(folder_path) | |
if content: | |
print(f"Emptying cache folder {folder_path}") | |
for f in content: | |
path = os.path.join(folder_path, f) | |
if os.path.isdir(path): | |
shutil.rmtree(path) | |
else: | |
os.remove(path) | |
def main(empty_cache=False): | |
for root, dirs, files in os.walk(top_folder, topdown=True): | |
recursive_folders = [] | |
for dir_name in dirs: | |
if dir_name in NUKED_FOLDERS: | |
full_path = os.path.join(root, dir_name) | |
print(f"Nuking the folder {full_path}") | |
shutil.rmtree(full_path) | |
continue | |
# exclude from dropbox all the excluded_folders - and all "build" folders sibilings of "node_modules" | |
if ( | |
dir_name in EXCLUDED_FOLDERS | |
or ( | |
dir_name in ("build", "dist") and "node_modules" in dirs | |
) # builds of Node | |
or ( | |
dir_name in ("target",) and "Cargo.toml" in files | |
) # targets of Rust | |
): | |
exclude_folder(root, dir_name) | |
if dir_name in CACHE_FOLDERS and empty_cache: | |
full_path = os.path.join(root, dir_name) | |
empty_folder(full_path) | |
else: | |
recursive_folders.append(dir_name) | |
dirs[:] = recursive_folders | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser( | |
description="Mark a few fat folder as ignored so they don't sync to Dropbox" | |
) | |
parser.add_argument( | |
"--empty-cache", | |
help="Empty the cache folders", | |
default=False, | |
action="store_true", | |
) | |
args = parser.parse_args() | |
main(empty_cache=args.empty_cache) |
Edit: Now it also exclude all the folders called "build" that sit next to a "node_modules" one
Edit: ignoring a little more folders used for caches - added the --delete-cache
to delete the content of the cache folders (the empty folders are kept and marked ignored)
Edit: To make it work in mac - I'm calling attr/xattr using the xattr library rather than a shell subprocess
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It use the new dropbox API that ignore files with the attr com.dropbox.ignored set
It uses xattr to read the attribute and set it only if needed (so Dropbox won't resync if you run it several times)