Skip to content

Instantly share code, notes, and snippets.

@dariosky
Last active February 17, 2023 19:30
Show Gist options
  • Save dariosky/7484835c7753c2fe373debd04227b047 to your computer and use it in GitHub Desktop.
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
#!/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)
@dariosky
Copy link
Author

dariosky commented May 2, 2020

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)

@dariosky
Copy link
Author

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