pytable/dt_remove_secondary copy.py
2024-09-02 20:45:46 +02:00

115 lines
3.5 KiB
Python

from pytable.models import Image, ImageFlags, FilmRoll
from datetime import datetime
import peewee as pw
import os
import shutil
remove_three_stars_before = datetime(2024, 4, 1)
remove_secondary_before = datetime(2024, 6, 15)
remove_rejected_before = datetime(2024, 6, 15)
query = Image.filter()
pw.prefetch(query, FilmRoll)
def is_older_than(image, cmp):
return (image.datetime_taken or image.datetime_imported) < cmp
def should_remove(image):
return (
(is_older_than(image, remove_three_stars_before) and image.stars < 3) or
(image.flag(ImageFlags.REJECTED) and is_older_than(image, remove_rejected_before)) or
(image.group_id != image.id and is_older_than(image, remove_secondary_before))
)
file_usages = {}
for x in query:
path = os.path.join(x.film.folder, x.filename)
if path not in file_usages:
file_usages[path] = 0
if not should_remove(x):
file_usages[path] += 1
n_total = 0
n_not_needed = 0
needs_removal = []
extra_files_to_remove = []
bytes_to_remove = 0
d_root = "/home/oke/Pictures/Darktable"
d_local = "/home/oke/Pictures/DarktableLocal"
d_remote = "/home/oke/Pictures/DarktableRemote"
def potential_extras(fn):
directory, filename = os.path.split(fn)
basename, _ = os.path.splitext(filename)
iphone_movie = os.path.join(directory, "." + basename + ".mov")
yield iphone_movie
needs_fetching = []
for file, usages in file_usages.items():
if not file.startswith(d_root):
print("SKIPPNG", file)
continue
assert file.startswith(d_root)
remote_file = file.replace(d_root, d_remote)
local_file = file.replace(d_root, d_local)
if usages > 0:
if not os.path.exists(local_file):
needs_fetching.append((remote_file, local_file))
else:
n_not_needed += 1
if os.path.exists(local_file):
needs_removal.append(local_file)
bytes_to_remove += os.stat(local_file).st_size
for extra_fn in potential_extras(local_file):
if os.path.exists(extra_fn):
extra_files_to_remove.append(extra_fn)
bytes_to_remove += os.stat(extra_fn).st_size
files_to_remove = list(sorted(needs_removal + extra_files_to_remove))
needs_fetching = sorted(needs_fetching)
import pprint
print("Files to fetch: ")
pprint.pprint(needs_fetching)
print("Extra files to remove:")
pprint.pprint(extra_files_to_remove)
print("First files to remove:")
pprint.pprint(needs_removal[:10])
print("Last files to remove:")
pprint.pprint(needs_removal[-10:])
with open("remove.txt", "w") as f:
pprint.pprint(sorted(set(needs_removal).union(extra_files_to_remove)), f)
print("Not needed: %6d / %6d (%3d%%)" % (n_not_needed, len(file_usages), 100 * n_not_needed / len(file_usages)))
print()
print("Not yet deleted: %6d / %6d (%3d%%)" % (len(needs_removal), n_not_needed, 100 * len(needs_removal) / n_not_needed))
print("Bytes to free: %5.2fGB" % (bytes_to_remove / 1024. / 1024 / 1024))
print("Total files to remove: %d" % len(files_to_remove))
print()
print("Total files to fetch: %3d" % len(needs_fetching))
print()
reply = input("Type YES to remove all these files. This is not reversible... : ")
if reply == 'YES':
for fn in files_to_remove:
assert fn.startswith(d_local)
os.remove(fn)
for f, t in needs_fetching:
assert os.path.exists(f), "Backup corruped, file not found: " + f
assert not os.path.exists(t)
print(f, t)
shutil.copy(f, t)
else:
print("You did not type 'YES'. Not doing anything!")