Wykrywanie duplikatów plików

Zabrałem się za porządki w swoich albumach zdjęciowych i szybko zauważyłem, że masa zdjęć się niepotrzebnie powtarza. By wykryć duplikaty potrzebowałem narzędzia, które przeskanuje dziesiątki gigabajtów plików. Niestety nie znalazłem żadnej takiej aplikacji, która to właściwie zrobi na moim serwerze plików QNAP. Dlatego postanowiłem napisać takie narzędzie, przy użyciu PHP i Symfony. Dodatkowo by trochę utrudnić sobie to zadanie użyłem mechanizmu kolejek, by skanowanie duplikatów mogło odbywać się równolegle przez kilka workerów, czyli wykorzystałem do tego Symfony Messenger.

Aplikacja składa się z trzech elementów: komendy pobierającej podstawową strukturę katalogów w celu odpowiedniego zakolejkowania zadań, obsługi skanowania i części analizującej zebrane wyniki. Zakolejkowanie zadań polega na połączeniu się z serwerem plików poprzez protokół smb (Windows / Samba) do wskazanego zasobu udostępniającego zdjęcia. Taki zasób składa się z kilku folderów / albumów, dla których zostanie stworzone osobne zadanie skanowania. Zadania skanowania zostają umieszczone na kolejce przez mechanizm wiadomości (Symfony Messenger) i w bazie danych, tutaj sqlite tak by wygodnie móc śledzić postęp analizy.

Skanowanie jest prostym zadaniem realizowanym przez worker, który odbiera wiadomość z adresem katalogu do analizy. Polega to na pobraniu wszystkich plików graficznych (mających odpowiednie rozszerzenie), w tym także składowanych w podkatalogach, a następnie wygenerowanie odpowiedniego hasha, przy użyciu algorytmu md5. Hash taki zostaje zapamiętany w bazie danych i stanowi rezultat skanowania.

Ostatnia część aplikacji, czyli analiza wyników sprowadza się do pobrania z bazy danych tych hashy, które występują częściej niż raz, a więc są duplikatami zdjęć (prosta komenda GROUP BY i HAVING). Komendę taką najlepiej wykonać gdy wszystkie zadania zostaną zakończone. Natomiast kasowania duplikatów pozostawiam już użytkownikowi.

Zachęcam do wypróbowania i podzielenia się opinią https://github.com/domino91/dduplicate