Note de ce sujet :
  • Moyenne : 0 (0 vote(s))
  • 1
  • 2
  • 3
  • 4
  • 5
Têtes de mort
#1
Hello,
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
Répondre
#2
Bonne idée ! C'est toi qui l'as codé ?
Mes photos : jpverrue.fr
Répondre
#3
@jpverrue
Oui, j'ai pompé les requêtes du sript sh pour les faire en python ( connaît  pas grand chose en SQL) puis adapté pour Windows, je ne sais pas pour Mac mais il semble que l'on peut faire tourner plus facilement des bash que sur Win ?  la db est sauvegardée avant modif au cas où. Cool
Cordialement.
Mes photos
dt compilé en local, dernière version officielle et master
Répondre
#4
Ben, bravo alors ! (Oui, sh et ses dérivés ksh, bash ... fonctionnent sous mac)
Mes photos : jpverrue.fr
Répondre
#5
Hello, complément
Pour celles et ceux qui voudrait utiliser ce code en Windows, une méthode simple :
Installer python avec l'éditeur fourni par défaut "IDLE".
Sélectionner le code ( copier tout le texte) de la fenêtre code du premier post, coller dans le bloc note, enregistrer dans un fichier nomfichier.py.
Lancer Idle, ouvrir le fichier nomfichier.py, et exécuter (F5), option -p avec run customised (shift F5), Menu Run.
Cordialement

Dites moi si vous avez essayez et si c'est utile?
Mes photos
dt compilé en local, dernière version officielle et master
Répondre


Atteindre :


Utilisateur(s) parcourant ce sujet : 2 visiteur(s)