Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save sosi-deadeye/ef725790d610f2a7bb182747382a4363 to your computer and use it in GitHub Desktop.
Save sosi-deadeye/ef725790d610f2a7bb182747382a4363 to your computer and use it in GitHub Desktop.
"""
Delete everything, pictures are excluded.
"""
from argparse import ArgumentParser
from pathlib import Path
from textwrap import dedent
from PIL import Image, UnidentifiedImageError
LOSS_LESS_FORMATS = (
".png",
".bmp",
".gif",
".tiff",
)
LOSSY_FORMATS = (
".jpg",
".webp",
)
RAW_FORMATS = (
".raw",
".nef",
".crw",
".cr2",
".cr3",
)
IMG_EXTENSIONS = sorted(LOSS_LESS_FORMATS + LOSSY_FORMATS + RAW_FORMATS)
def image_size_constraint(x_min, y_min):
def inner(file):
try:
x, y = Image.open(file).size
except UnidentifiedImageError:
return False
return x_min <= x and y_min <= y
return inner
def traverse_files(root, exclude, traverse_constraints=None):
for file in Path(root).rglob("*"):
excluded = file.suffix.casefold() in exclude
if excluded and traverse_constraints:
excluded = traverse_constraints(file)
yield excluded, file
def delete_files(root, exclude, delete_constraints):
for is_excluded, file in traverse_files(root, exclude, delete_constraints):
if not is_excluded:
print("Deleting file", file)
try:
file.unlink()
except PermissionError:
print("No permission to delete", file)
def count(root, exclude, count_constraints):
excluded = 0
included = 0
for is_excluded, file in traverse_files(root, exclude, count_constraints):
if is_excluded:
excluded += 1
else:
included += 1
print(
dedent(
f"""
Files total : {excluded + included:>8d}
Files to delete: {included:>8d}
Files excluded : {excluded:>8d}
"""
)
)
if __name__ == "__main__":
parser = ArgumentParser(description=__doc__)
parser.add_argument("root", help="Root directory where the files should deleted")
parser.add_argument(
"--exclude", nargs="+", choices=IMG_EXTENSIONS, default=IMG_EXTENSIONS
)
parser.add_argument(
"-c", action="store_true", help="Count how many files to delete"
)
parser.add_argument(
"-x_min", default=64, type=int, help="Minimum x size of image to keep"
)
parser.add_argument(
"-y_min", default=64, type=int, help="Minimum y size of image to keep"
)
args = parser.parse_args()
constraints = image_size_constraint(args.x_min, args.y_min)
if args.c:
count(args.root, args.exclude, constraints)
else:
delete_files(args.root, args.exclude, constraints)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment