11-11-23, 18:26
Hello,
une alternative en python3 au script bash "purge_non_existing_images.sh" pour les windowsiens (et linuxiens)
Cordialement.
une alternative en python3 au script bash "purge_non_existing_images.sh" pour les windowsiens (et linuxiens)
Code :
#!/usr/bin/python3
# -*- coding: utf-8 -*-
'''
Created on 8 nov. 2023
@author: coelb
python3 adaptation of purge_non_existing_images.sh
For Linux and Windows.
Tested with Kubuntu 22.04, Windows 10.
.
usage : python3 dtpurge.py args
./dtpurge.py args (Linux with executable file flag)
Without arguments, only list missing files referenced in db
library.db path is assumed to be standard path installation.
* -l arg can provide spécific library path
* -p delete missing references from db (before deletion, library is saved as library_original.db)
'''
import sqlite3, os, sys, platform, subprocess
from shutil import copyfile
from os.path import exists
from pathlib import Path
import argparse
#------------------------------------------------------------
dbfile = None
purge = False
def saveDb():
"""
save a db copy
"""
filen, _ = os.path.splitext(dbfile)
copyfile(dbfile, filen + "_original.db")
def readAndPurgeMissingFiles():
"""
Read missing images on disk referenced in db
Delete if -p option
"""
con = sqlite3.connect(dbfile)
cur = con.cursor()
cur.execute("SELECT images.id, film_rolls.folder || '/' || images.filename FROM images JOIN film_rolls ON images.film_id = film_rolls.id")
rows = cur.fetchall()
missingfileList = []
missingIds = []
for r in rows:
filename = r[1]
if not( exists(filename)):
missingfileList.append(filename)
missingIds.append(str(r[0]))
print (str(len(missingfileList))+ " missing files")
for file in missingfileList:
print(file)
if not purge and len(missingIds) != 0 :
print(" Use -p arg to clean db")
# clean DB
if purge and len(missingIds) != 0 :
print(" Save Db as library_original.db and clean library.db")
saveDb()
for table in ["images", "meta_data"]:
for mid in missingIds :
delId = "DELETE FROM " + table + " WHERE id=" + mid
cur.execute(delId)
for table in ["color_labels", "history", "masks_history", "selected_images", "tagged_images", "history_hash", "module_order"] :
for mid in missingIds :
delId = "DELETE FROM " + table + " WHERE imgid=" + mid
cur.execute(delId)
cur.execute("DELETE FROM film_rolls WHERE NOT EXISTS (SELECT 1 FROM images WHERE images.film_id = film_rolls.id)")
con.commit()
cur.execute("VACUUM")
cur.execute("ANALYZE")
con.close()
#------------------------------------Main-----------------------------------------------
if __name__ == '__main__':
ostype = platform.system()
home = Path.home()
# is dt running ?
if(ostype == "Linux") :
ret = subprocess.call(["pgrep","-l", "darktable"])
if not (ret) : sys.exit("error: darktable is running, please exit first")
elif(ostype == "Windows"):
cmd = 'WMIC PROCESS get Caption,Commandline,Processid'
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
for line in proc.stdout:
ind = str(line).find("darktable.exe")
if ind != -1 :
sys.exit("error: darktable is running, please exit first")
else :
sys.exit("OS not supported")
# construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-l", "--library", type=str, default=None,
help="Path to dt library.db")
ap.add_argument("-p", "--purge", action='store_true',
help="Delete missing files references")
args = vars(ap.parse_args())
if args["library"]== None :
if(ostype == "Linux") :
dbfile = str(home) + "/.config/darktable/library.db"
elif(ostype == "Windows"):
dbfile = str(home) + "/AppData/Local/darktable/library.db"
else :
dbfile = args["library"]
if not( exists(dbfile)):
sys.exit("db file not found")
if args["purge"]:
purge =True
readAndPurgeMissingFiles()
#----------------------------------------------------------------------------------
Cordialement.
Mes photos
dt compilé en local, dernière version officielle et master
dt compilé en local, dernière version officielle et master