Salut,
Avec le temps, peut-être avez-vous comme moi un dossier ~/.thumbnails qui affiche quelques 18.000 fichiers
Faire du nettoyage à la main est tout simplement impossible, non pas seulement du fait de l'importance de la tâche mais aussi parce que la référence au fichier original est inscrite dans l'entête du fichier.
Le nom du thumbnail est l'empreinte md5 de l'uri du fichier original.
J'ai donc, entrepris ce script afin d'automatiser cette tâche de nettoyage.
Ce code demande Python 2.5 ou supérieur mais inférieur à 3 (du reste très facile à adapter pour Python3)
ainsi que la librairie PIL
Pour vérifier si PIL est installée, dans une console, tapez : python,
ensuite à l'apparition du prompteur >>> entrez : import Image (i majuscule, hein)
un message d'erreur vous dira si PIL n'est pas installée.
Fermez la console
Dans ce cas, dans votre gestionnaire de paquet cherchez : python-imaging et installez-le.
Ou en console :
~$ sudo apt-get install python-imaging
Le script en question :
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Date : oct 01 2010
#
# Author : Vincent Vande Vyvre <vins@swing.be>
# Licence : WTPFL v2 <http://sam.zoy.org/wtfpl/>
import sys
import os
import glob
import time
import getopt
from urlparse import urlparse
from urllib import unquote
import Image
class Cleaner(object):
def __init__(self, fn, fl, web=True, removable=False):
self.fn = fn
self.fl = fl
self.web = web
self.rem = removable
self.amount_normal = 0
self.amount_large = 0
self.size_normal = 0
self.size_large = 0
self.unremoved = []
def process(self):
"""Main process.
"""
if self.fn:
# Begin ~/.thumbnails/normal process
# Assume stdout is console
print " Nettoyage du dossier %s en cours ..." % self.fn
reply = self.clean(self.fn)
self.size_normal, self.amount_normal = reply[0], reply[1]
print "\n Nettoyage du dossier %s terminé.\n" % self.fn
print " %s thumbnails supprimés." % self.amount_normal
print " %s octets libérés.\n" % self.size_normal
if self.fl:
# Begin ~/.thumbnails/large process
print " Nettoyage du dossier %s en cours ..." % self.fl
reply = self.clean(self.fl)
self.size_large, self.amount_large = reply[0], reply[1]
print "\n Nettoyage du dossier %s terminé.\n" % self.fl
print " %s thumbnails supprimés." % self.amount_large
print " %s octets libérés.\n" % self.size_large
at = self.amount_normal + self.amount_large
st = self.size_normal + self.size_large
print " Terminé, total des thumbnails supprimés : %s" % at
print " total de l'espace disque libéré : %s" % st
if self.unremoved:
# Some files are non regular
chain = """\n Les fichiers suivants ne semblent pas"\
être des thumbnails
conformes et n'ont pas pu être supprimés :"""
if len(self.unremoved) < 20:
print chain
for ur in self.unremoved:
print " ", ur
else:
# If the list is too long, we create a text file
f = os.path.join(os.path.expanduser("~"),
"thumbnail_unremoved.txt")
with open(f, "w") as fobj:
fobj.write(time.strftime("%A %d %B %Y %H:%M:%S",
time.localtime()))
fobj.write("\n")
fobj.write(chain)
fobj.write("\n ")
for u in self.unremoved:
fobj.write(u)
fobj.write("\n ")
print "\n Certains fichiers n'ont pu être supprimés."
print " La liste de ces fichiers a été créée dans "\
"ce fichier :\n"
print " %s" % f
print "\n"
# Ite missa est
sys.exit()
def clean(self, f):
"""Open one folder and create the list of files into the folder.
Keyword arguments :
f -- folder
Returns :
Number of deleted files
Sum of size of all deleted files
"""
chain = os.path.join(f, "*.*")
lst = glob.glob(chain)
thumbs = len(lst)
loop = int(thumbs/100)
tot_size, tot_thumb = 0, 0
i = 0
pc = 0
for l in lst:
i += 1
if i == loop:
pc += 1
print "\rProgress",
print ".............%s %%" % pc, #XXX strange result
i = 0
if os.path.isfile(l) and l.endswith(".png"):
try:
img = Image.open(l)
# Source: http://jens.triq.net/thumbnail-spec/index.html
if img.info.has_key("Thumb::URI"):
uri = unquote(img.info["Thumb::URI"])
reply = self.control_origin(uri, l)
if reply:
tot_size += reply
tot_thumb += 1
else:
self.unremoved.append("".join([l, " No URI key"]))
except Exception, why:
self.unremoved.append("".join([l, " ", str(why)]))
else:
self.unremoved.append("".join([l, " Not a .png file"]))
return (tot_size, tot_thumb)
def control_origin(self, uri, th):
"""Validate thumbnail or not.
Keyword arguments :
uri -- the uri of original image
th -- thumbnail (full path)
Returns :
The size of deleted file or false if not deleted
"""
delete = False
(scheme, n, path, p, q, f) = urlparse(uri)
if self.web and scheme == "http":
delete = os.stat(th).st_size
elif self.rem and path.startswith('/media/'):
delete = os.stat(th).st_size
elif scheme == "file" and not os.path.isfile(path):
delete = os.stat(th).st_size
if delete:
try:
os.unlink(th)
except why:
self.unremoved.append(th)
self.unremoved.append(why)
delete = False
return delete
print "\n ** ThCleaner **\n\n Vérification des dossiers ..."
thpath = os.path.join(os.path.expanduser("~"), ".thumbnails")
if os.path.isdir(thpath):
error = 0
thnpath = os.path.join(thpath, "normal")
# Search ~/.thumbnails/normal
if not os.path.isdir(thnpath):
thnpath, error = None, 1
thlpath = os.path.join(thpath, "large")
# Search ~/.thumbnails/large
if not os.path.isdir(thlpath):
thlpath = None
error += 1
if error != 2:
# There's at last one folder
print "\n Dossier %s reconnu, choisissez les options "\
"de nettoyage :\n" % thpath
while 1:
# Delete thumbnail of image from the web ?
r = raw_input(" - Supprimer les thumbnails provenant"
"d'internet : O-N Oui ")
if r in ["", "O", "o", "Oui", "oui", "OUI", "Oh oui"]:
w = True
break
elif r in ["N", "n", "Non", "non", "NON", "NOOON!"]:
w = False
break
else:
print " !! La réponse doit être Oui ou Non."
while 1:
# Delete thumbnails of image from removable medias ?
r = raw_input(" - Supprimer les thumbnails provenant "
"de supports amovibles : O-N Non ")
if r in ["O", "o", "Oui", "oui", "OUI", "Oh oui"]:
d = True
break
elif r in ["", "N", "n", "Non", "non", "NON", "NOOON!"]:
d = False
break
else:
print " !! La réponse doit être Oui ou Non."
cl = Cleaner(thnpath, thlpath, w, d)
cl.process()
else:
print "\n !! ThCleaner ne peut trouver les dossiers %s" \
"\n %s\n" % (thnpath, thlpath)
else:
print "\n !! ThCleaner ne peut trouver le dossier %s \n" % thpath
edit : Nutilisez pas ce code, utilisez celui décrit dans le post #6 un peu plus bas.
Exemple : /home/user/Bureau/ThCleaner.py
Ouvrez une nouvelle console dans ce dossier :
cd ~/Bureau
Ensuite entrez :
python ThCleaner.py
Vous devriez voir apparaître ceci :
vincent@tiemoko:~/Bureau$ python ThCleaner.py
** ThCleaner **
Vérification des dossiers ...
Dossier /home/vincent/.thumbnails reconnu, choisissez les options de nettoyage :
- Supprimer les thumbnails provenant d'internet : O-N Oui
Votre dossier .thumbnails peu contenir des vignettes d'images situées quelque part sur la toile (e.g. votre album photo sur Picasa)
Le choix par défaut est de supprimer ces vignettes (tapez Enter) si vous voulez les conserver entrez : n + Enter
- Supprimer les thumbnails provenant de supports amovibles : O-N Non
Si vous conservez vos images sur support amovible plutôt que sur votre disque dur il peut être utile de préservez les vignettes sans quoi Nautilus devra les reconstruire a chaque réouverture d'un disque d'image. Les CD, DVD sont identifiés et Nautilus retrouve sans problème les vignettes associées aux images originales.
Donc le choix par défaut est : Non
Si par contre la lecture de CD/DVD d'image n'est que très occasionnelle entrez : o + Enter
Note : pour Oui vous pouvez entrez O, o, Oui, oui, Oh oui et OUI
pour Non " " " N, n, Non, non, NON et NOOON!
Vous verrez ensuite apparaître ceci :
Nettoyage du dossier /home/vincent/.thumbnails/normal en cours ...
Progress .............100 %
Nettoyage du dossier /home/vincent/.thumbnails/normal terminé.
7283 thumbnails supprimés.
95510123 octets libérés.
Nettoyage du dossier /home/vincent/.thumbnails/large en cours ...
Nettoyage du dossier /home/vincent/.thumbnails/large terminé.
0 thumbnails supprimés.
0 octets libérés.
Terminé, total des thumbnails supprimés : 7283
total de l'espace disque libéré : 95510123
Ce qui signifie que mon dossier .thumbnails/normal (128x128 pixels) a été délesté de 7.283 fichiers inutiles
le dossier /large était vide au départ, l'espace liberé sur le disque est donc 95,510123 Mo
Ce qui valait la peine.
Si certains fichiers posent problème ThCleaner affichera la liste de ces fichiers, si celle-ci est trop longue un fichier texte sera créé.
Certains fichiers n'ont pu être supprimés.
La liste de ces fichiers a été créée dans ce fichier :
/home/vincent/thumbnail_unremoved.txt
@ Utilisateurs KDE : Est-ce que KDE utilise aussi un dossier ~/.thumbnails et des sous dossiers /normal et /large
Faites savoir si ce script est utilisable tel quel ou si il faut le modifier . Ce que je ferais volontiers.
Voila, je pense que ceci mérite une bière.