Jak mogę pouczyć Nautilus, aby wstępnie generował miniatury?

33

Mam dużą bibliotekę dokumentów PDF (referaty, wykłady, materiały informacyjne), które chcę szybko przeglądać. Do tego potrzebuję miniaturek.

Jednocześnie jednak widzę, że ~/.thumbnailsfolder piętrzy się kciukami, których tak naprawdę nie potrzebuję. Usuwanie niepotrzebnych miniatur bez usuwania ważnych kciuków jest niemożliwe. Gdybym je usunął, musiałbym przejść do każdego folderu z ważnymi dokumentami PDF i pozwolić na regenerację pamięci podręcznej miniatur.

Chciałbym móc zautomatyzować ten proces. Czy jest jakiś sposób, aby powiedzieć nautilusowi, aby wstępnie buforował kciuki dla zestawu podanych katalogów?

Uwaga : znalazłem zestaw skryptów bash, które wydają się to robić dla zdjęć i filmów, ale nie dla żadnych innych dokumentów. Być może ktoś bardziej doświadczony w tworzeniu skryptów może dostosować je do dokumentów PDF lub przynajmniej skierować mnie w dobrym kierunku na to, co musiałbym zmodyfikować, aby działało również z dokumentami PDF.


Edytuj :

Odpowiedź na to pytanie była przytłaczająca. Chciałbym najpierw podziękować wszystkim, którzy brali udział w rozwiązaniu tego. Pytanie, odpowiedzi i cała dyskusja wokół niego są doskonałym przykładem tego, jak wysiłek wielu stron może doprowadzić do optymalnego rozwiązania. Właśnie to sprawia, że ​​Linux i Open Source są tak świetne.

Wszystkie udzielone odpowiedzi zasługiwałyby na nagrodę, którą pierwotnie złożyłem za to pytanie. Nadal jest tylko jedna nagroda. Zawdzięczam wszystkim przyszłym czytelnikom wybór odpowiedzi, która rozwiązuje problem w najbardziej efektywny sposób. Aby ustalić, które to rozwiązanie, wykonałem końcowy test, porównując trzy skrypty pod względem zgodności, szybkości i jakości wyjściowej. Oto wyniki:


Thumbnailer 1 , autor: rosch:

Kompatybilność : ✔ spacje w nazwie pliku; ✔ spacje w nazwie katalogu; ✘ zgodny z freedesktop

Szybkość : 95 plików PDF w 12,6 sek

Jakość : podstawowa jakość nautilus

Dodatkowe korzyści : 1.) automatycznie pomija pliki z istniejącymi kciukami; 2.) Nie są potrzebne żadne dodatkowe pakiety

Thumbnailer 2 , autor: Martin Orda:

Kompatybilność : ✔ spacje w nazwie pliku; ✔ spacje w nazwie katalogu; ✘ zgodny z freedesktop

Szybkość : 95 plików PDF w 70,0 sek

Jakość : znacznie lepsze skalowanie niż obrazy stockowe.

Dodatkowe korzyści : 1.) automatycznie pomija pliki z istniejącymi kciukami 2.) kompatybilny z szeroką gamą formatów obrazów oprócz PDF 3.) niezależny od platformy, nie opiera się na komponentach GNOME

Thumbnailer 3 , autor: James Henstridge:

Kompatybilność : ✔ spacje w nazwie pliku; ✔ spacje w nazwie katalogu; ✔ zgodny z freedesktop

Szybkość : 95 plików PDF w 10,8 sek

Jakość : podstawowa jakość nautilus

Dodatkowe korzyści : 1.) automatycznie pomija pliki z istniejącymi kciukami 2.) zgodny ze wszystkimi formatami plików, które są identyfikowane przez preinstalowane miniatury


Wszystkie trzy skrypty są doskonałe. Każdy ma swój odrębny zestaw zalet i wad. Rozwiązanie Roscha działa od razu po wyjęciu z pudełka i może być właściwym wyborem dla użytkowników przy minimalnej instalacji.

Martin Orda stworzył bardzo wszechstronny skrypt, który działa z różnymi formatami plików i jest niezależny od DE. Wyróżnia się jakością miniaturek, ale robi to kosztem szybkości.

Ostatecznie to rozwiązanie Jamesa najlepiej pasowało do mojego przypadku użycia. Jest szybki, wszechstronny i oferuje opcje pomijania plików z istniejącymi miniaturami.


Zwycięzca ogólny: James Henstridge


Informacje dodatkowe : Wszystkie trzy skrypty są w pełni kompatybilne ze skryptami nautilus . Możesz łatwo zainstalować je zgodnie z tym samouczkiem .


Edycja 2 : Zaktualizowana recenzja z ulepszonym skryptem autorstwa Rosch.

Glutanimate
źródło
Ponieważ wiele małych plików zawsze kończy się źle. Czy znasz rozmiar swojego folderu ~ / .thumbnails?
Antoine Rodriguez
Masz na myśli rozmiar, który ma teraz? około 85 MB po ~ 1 miesiącu użytkowania.
Glutanimate,
A ile plików ma twoja biblioteka? (z przyczyn technicznych / ograniczeń)
Antoine Rodriguez
ah czekaj, przeliczyłem się; w tym niektóre pliki danych. Dokumentuje tylko, że około 2000 roku.
Glutanimate
Aby Cię zaktualizować: Mam dla Ciebie rozwiązanie. Długo się redaguje, więc daj mi kilka dni. Pozdrawiam;)
Antoine Rodriguez

Odpowiedzi:

35

Procedury kciukowe Nautilusa faktycznie pochodzą z libgnome-desktopbiblioteki, więc można uruchamiać te same miniatury poza menedżerem plików.

Interfejs API jest trochę skomplikowany, ale następujący skrypt w języku Python powinien pomóc:

#!/usr/bin/python
import os
import sys

from gi.repository import Gio, GnomeDesktop

def make_thumbnail(factory, filename):
    mtime = os.path.getmtime(filename)
    # Use Gio to determine the URI and mime type
    f = Gio.file_new_for_path(filename)
    uri = f.get_uri()
    info = f.query_info(
        'standard::content-type', Gio.FileQueryInfoFlags.NONE, None)
    mime_type = info.get_content_type()

    if factory.lookup(uri, mtime) is not None:
        print "FRESH       %s" % uri
        return False

    if not factory.can_thumbnail(uri, mime_type, mtime):
        print "UNSUPPORTED %s" % uri
        return False

    thumbnail = factory.generate_thumbnail(uri, mime_type)
    if thumbnail is None:
        print "ERROR       %s" % uri
        return False

    print "OK          %s" % uri
    factory.save_thumbnail(thumbnail, uri, mtime)
    return True

def thumbnail_folder(factory, folder):
    for dirpath, dirnames, filenames in os.walk(folder):
        for filename in filenames:
            make_thumbnail(factory, os.path.join(dirpath, filename))

def main(argv):
    factory = GnomeDesktop.DesktopThumbnailFactory()
    for filename in argv[1:]:
        if os.path.isdir(filename):
            thumbnail_folder(factory, filename)
        else:
            make_thumbnail(factory, filename)

if __name__ == '__main__':
    sys.exit(main(sys.argv))

Zapisz to w pliku i zaznacz jako plik wykonywalny. Może być również konieczne zainstalowanie gir1.2-gnomedesktop-3.0pakietu, jeśli nie jest jeszcze zainstalowany.

Następnie po prostu wywołaj skrypt z plikami lub folderami, które chcesz miniaturować jako argumenty. Miniatury zostaną zapisane w ~/.thumbnailsmiejscach, w których oczekują ich aplikacje, takie jak Nautilus.

James Henstridge
źródło
1
Dziękujemy Jamesowi za poświęcenie czasu na napisanie tego skryptu. Działa tak samo, jak w przypadku pojedynczych plików. Spośród opublikowanych rozwiązań jest to jedyne, którego dane wyjściowe są rozpoznawane przez system ( 48eebea785a185cdfc9d8f1a2ed34400.pngużywana jest poprawna nazwa pliku ). W tym momencie jednak wydaje się, że nie obsługuje katalogów. Czy jest jakiś sposób na rekurencyjne przechodzenie przez katalogi?
Glutanimate,
Gotowy. Również trochę uprościłem wyjście.
James Henstridge
Twój skrypt działa absolutnie świetnie. Właśnie tego szukałem, więc nagrodziłem cię nagrodą. Napotkałem pewne komunikaty o błędach podczas mojego ostatniego uruchomienia testowego, ale nie przeszkadzały one w generowaniu miniatur. Błędy mogą być związane z faktem, że niektóre nazwy plików zawierały niemieckie Umlauts („ä, ü, ö”). Jeszcze raz dziękuję za zapewnienie tego doskonałego rozwiązania. Odtąd moje życie będzie znacznie łatwiejsze.
Glutanimate
1
Błędy te pochodzą z parsera XML używanego przez jedną z miniatur, więc byłyby związane z zawartością jakiegoś pliku, a nie z jego nazwą. Powyższy skrypt miniatur przetwarza wszystkie pliki w katalogu, więc może nie być to plik PDF, z którym ma problem.
James Henstridge
Nie mogę utworzyć miniatur dla zwykłych plików tekstowych. Czy muszę coś skonfigurować, aby to działało?
krasnaya
18

Poniższy skrypt powinien wykonać zadanie. Używa, evince-thumbnailerktóry - o ile wiem - jest dostarczany z każdą instalacją gnome i jest domyślną miniaturą.
Zapisz jako pdfthumbnailer.sh i uczyń go wykonywalnym.
Zastosowanie :pdfthumbnailer.sh dir1 [dir2, ...]

#!/bin/bash

F1=$HOME/.thumbnails/normal
F2=$HOME/.cache/thumbnails/normal
SAVE_FOLDER=$F1
[ -e $F2 ] && SAVE_FOLDER=$F2

# the thumbnailing function
evincethumb() {
    outname=$(echo -n "$(readlink -f "$0")" | \
    perl -MURI::file -MDigest::MD5=md5_hex -ne 'print md5_hex(URI::file->new($_));')
    # no work if thumbnail already present
    [ ! -e $SAVE_FOLDER/${outname}.png ] && {
        echo "$0"
        #uncomment only one of both thumbnailers
        #convert -thumbnail 128x128 "$0"[0] $SAVE_FOLDER/${outname}.png 2>/dev/null
        evince-thumbnailer -s 128 "$0" $SAVE_FOLDER/${outname}.png 2>/dev/null
    }
}

# make our function visible to the subshell in "find -exec" below
export -f evincethumb

# loop through all given folders
for folder in "$@" ; do
    find "$folder" -type f -exec bash -c evincethumb {} \;
done

Ograniczenie :

  • nie dodaje atrybutów Thumb :: URI i Thumb :: MTime do miniatur, jak zauważył James Henstridge. Do tej pory nie widziałem żadnych dowodów na to, że domyślnieevince-thumbnailer tak postępuje. Innymi słowy ... dopóki nautilus nie zregeneruje miniatur, skrypt może zostać użyty do zadania.

Notatki :

  • drukuje nazwę pliku podczas generowania nowej miniatury, pomija generowanie, jeśli istnieje
  • prędkość: 37 plików pdf przetestowanych zarówno evince-thumbnaileri convert(z imagemagick): 3 sekundy dlaevince-thumbnailer i 14 sekund dla convert.
  • generuje miniatury rozpoznawane przez nautilus
  • nazwy ścieżek obsługiwane przez URL perla: moduł pliku (spacje i inne znaki są poprawnie tłumaczone na plik uri)
  • potrzeby perl, obecne w domyślnej instalacji
  • pliki nieobsługiwane przez evince-thumbnailerpo prostu wygenerują błąd - wyciszony za pomocą2>/dev/null
  • spójrz na linię MimeType, /usr/share/thumbnailers/evince.thumbnaileraby zobaczyć listę obsługiwanych typów plików
  • aktualizacje: od 12.04 wydaje się, że folder miniatur jest ~/.cache/thumbnails.
    Bardziej niezawodne ścieżki przy użyciu readlink.

Inspiracja :
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=683394

róż
źródło
Przede wszystkim dziękuję za odpowiedź i włożony w nią wysiłek. Zrobiłem kilka testów i oto moje wyniki: 1.) Generowanie miniatur nie działa dla katalogów ze spacjami w nazwach; 2.) miniatury utworzone przy użyciu skryptu i @Martin Orda nie są rozpoznawane przez system; pliki przetwarzane za pomocą skryptu są obsługiwane tak, jakby nie było żadnej miniatury -> wynik: zduplikowane kciuki w katalogu miniatur
Glutanimate
Hm, cóż, moje testy były jak dotąd pozytywne: nautilus rozpoznał miniatury i ich nie zregenerował. Ugh, spacje w nazwach folderów to coś, co uważam za złą praktykę ... ale zmodyfikuję skrypt. Zduplikowane miniatury? Jak nazywa się nowy tumbnail dla pliku podarunkowego?
rosch
Ok, wypróbowałem to jeszcze raz i obawiam się, że to taki sam wynik jak ostatnim razem. Poniżej znajduje się nazwa pliku miniatury skryptu generowane: 2a43dc2774e3dfe45a4337e0304e5b0a.png. W ten sposób ta sama miniatur jest nazwany przez nautilus: 48eebea785a185cdfc9d8f1a2ed34400.png. Zauważyłem również, że kciuki utworzone za pomocą skryptu mają rozmiar 128 x 171 pikseli, a wbudowany miniaturka tworzy tylko miniatury 96 x 128 pikseli.
Glutanimate,
Oto porównanie .
Glutanimate,
O twoim komentarzu o evince-thumbnailernie dodawaniu tagów PNG, to jest poprawne: kod, który wywołuje zewnętrzne miniatury, faktycznie przepisuje obrazy, aby uwzględnić tagi. Powinieneś być w stanie to zweryfikować, uruchamiając strings -ajedną z miniatur wygenerowanych przez Nautilus.
James Henstridge
10

Rozkojarzyłem się na chwilę i pobiłem mnie do tego :) Nie wiedziałem, że istnieje evince-thumbnailer (nie jestem użytkownikiem Gnome), ale zresztą, skoro już to napisałem, proszę bardzo. Wymaga zainstalowanego imagemagick, sprawdź i zainstaluj, jeśli nie ma:

which convert || sudo apt-get install imagemagick

Zapisz jako mkthumb.sh(na przykład) chmod +x mkthumb.shi uruchom go z bezwzględnymi ścieżkami jako argumentami (możesz użyć -s jako pierwszego parametru, aby pominąć generowanie już istniejących miniatur):

user@host $ ./mkthumb.sh -s /home/user/Downloads /home/user/blah
Processing directory /home/user/Downloads/pics/
OK   /home/user/Downloads/pics/FeO08.jpg
OK   /home/user/Downloads/pics/UrOCu.jpg
OK   /home/user/Downloads/pics/34ATZ.gif
OK   /home/user/Downloads/pics/WBRE3.jpg
OK   /home/user/Downloads/pics/LjLdH.jpg
OK   /home/user/Downloads/pics/xvvae (1).jpg
SKIP /home/user/Downloads/pics/itcrowd.jpg
OK   /home/user/Downloads/pics/76180344.jpg
OK   /home/user/Downloads/pics/fgk5N.jpg
....

Skrypt (zmodyfikowałem go nieznacznie, aby obsługiwał większość obrazów, możesz dodać więcej rozszerzeń, jeśli ich potrzebujesz):

#!/bin/bash

# USAGE: mkthumb.sh [-s] <abs_path> [abs_path]
# create nautilus thumbnails for images and PDFs in the directories (and their
# sub-directories) given as parameters.
# -s is used to skip generating thumbnails that already exist

skip_existing=0
if [[ "${1}" == "-s" ]]; then
  skip_existing=1
  shift
fi

mkthumb() {
  file="${1}"
  dest="${2}"
  convert -thumbnail 128x128 "${file}[0]" "${dest}" &>/dev/null
  if (( $? == 0 )); then
    echo "OK   ${file}"
  else
    echo "FAIL ${file}"
  fi
}

OLDIFS="${IFS}"
IFS=$'\n'
for dir in $@; do
  realdir=`realpath "${dir}"`
  echo "Processing directory ${realdir}"
  for file in $(find "${realdir}" -regextype posix-egrep -iregex \
  '.*\.(pdf|png|jpg|gif|jpeg)'); do
    md5=$(echo -n "${file}" | perl -MURI::file -MDigest::MD5=md5_hex -ne \
          'print md5_hex(URI::file->new($_));')
    dest="${HOME}/.thumbnails/normal/${md5}.png"
    if [[ -f "${dest}" ]]; then
      if [[ "${skip_existing}" == "0" ]]; then
        mkthumb "${file}" "${dest}"
      else
        echo "SKIP ${file}"
      fi
    else
      mkthumb "${file}" "${dest}"
    fi
  done
done
IFS="${OLDIFS}"

Bez problemów obsługuje pliki ze spacjami w ich nazwach.

A bit of testing here:

user@host $ find .thumbnails/
.thumbnails/
.thumbnails/fail
.thumbnails/fail/gnome-thumbnail-factory
.thumbnails/normal

# ok - no thumbnails present.

user@host $ ./mkthumb.sh -s /home/user/Downloads/pdf/test/
Processing directory /home/user/Downloads/pdf/test/
OK   /home/user/Downloads/pdf/test/800pdf.pdf
OK   /home/user/Downloads/pdf/test/3_TO_pricelist.pdf
OK   /home/user/Downloads/pdf/test/111011-speisekarte-mit-desserts.pdf
OK   /home/user/Downloads/pdf/test/1186157_r4f3a355eb104a (1).pdf

user@host $ touch tstamp

user@host $ ./mkthumb.sh -s /home/user/Downloads/pdf/test/
Processing directory /home/user/Downloads/pdf/test/
SKIP /home/user/Downloads/pdf/test/800pdf.pdf
SKIP /home/user/Downloads/pdf/test/3_TO_pricelist.pdf
SKIP /home/user/Downloads/pdf/test/111011-speisekarte-mit-desserts.pdf
SKIP /home/user/Downloads/pdf/test/1186157_r4f3a355eb104a (1).pdf

# running nautilus once now to see if it generates new thumbnails

# checking for new thumbnails:

user@host $ find .thumbnails/ -newer tstamp

# None.
Marcin Kamiński
źródło
Dziękuję również za doskonały skrypt. Zrobiłem kilka testów i oto moje wyniki: 1.) Generowanie miniatur działa dobrze i jest szybsze niż evince-thumbnailer; 2.) miniatury utworzone zarówno za pomocą skryptu, jak i @ rosch nie są rozpoznawane przez system; pliki przetwarzane za pomocą skryptu są obsługiwane tak, jakby nie było żadnej miniatury. Nowe kciuki są tworzone podczas ręcznego dostępu do katalogów -> wynik: zduplikowane kciuki w katalogu miniatur
Glutanimate
Masz rację - sprawdziłem to jeszcze raz i stwierdziłem, że nautilus je generuje ponownie (myślę, że nie było tak, kiedy testowałem to zeszłej nocy, ale mogłem się mylić, było już późno). Jeśli rzeczywiście jest szybszy, jak napisałeś (nie korzystałem jeszcze z innych metod), popracuję nad tym za kilka godzin. Jedyny problem, jaki z tym spotykam, to zarówno pliki generowane przez mój skrypt, jak i nautilus, które mają te same właściwości: „PNG 97x128 97x128 + 0 + 0 8-bit DirectClass 20,4 KB 0,000u 0: 00 000”, gdy używam identyfikatora <thumbnail>.
Marcin Kamiński
Nie, oboje się myliliśmy :) Okazuje się, że zapomniałem, że nazwa miniatury to skrót md5 „file: //” + ścieżka_ absolutna i przez pomyłkę uruchomiłem mój skrypt jako ./mkthumb.sh -s Downloads / pdf / test zamiast. /mkthumb.sh -s / home / user / Downloads / pdf / test. Spróbuj ponownie spróbować.
Marcin Kamiński
W porządku, wykonałem kolejny test, a osobliwą rzeczą jest to, że oba skrypty skryptu wydają się mieć ten sam problem: nazwa pliku skryptu jest taka 2a43dc2774e3dfe45a4337e0304e5b0a.png, jak nautilus je nazywa 48eebea785a185cdfc9d8f1a2ed34400.png. Wymiary są jednak prawidłowe w skrypcie. Oto porównanie
Glutanimate,
Chciałbym dodać, że twój skrypt wciąż jest najszybszy z tych opublikowanych tutaj. imagemagickwydaje się także, że radzi sobie ze skalowaniem znacznie lepiej niż evince-thumbnailer(patrz porównanie powyżej w celach informacyjnych).
Glutanimate,
1

Specyfikacja miniaturek obejmuje udostępnione repozytoria miniatur, które umożliwiają dystrybucję miniaturek z generowaniem wstępnym wraz z powiązanymi plikami, bez konieczności generowania przez każdego użytkownika własnej miniatury. Teoretycznie możesz wygenerować miniatury, a następnie dodać je do wspólnego repozytorium, eliminując w ten sposób potrzebę ich generowania w przyszłości, jeśli wyczyścisz katalog miniatur lub przeniesiesz je wszystkie na inną maszynę lub cokolwiek innego.

http://specifications.freedesktop.org/thumbnail-spec/thumbnail-spec-latest.html#DIRECTORY

Ta strona Ask Ubuntu pojawia się w wynikach wyszukiwania, gdy próbowałem dowiedzieć się, czy jakakolwiek aplikacja obsługuje udostępnione repozytoria miniatur. Niestety wygląda na to, że żadna aplikacja ich nie obsługuje.

Kok
źródło
1

Napisałem pakiet, który zmodyfikował skrypt Jamesa, aby uwzględnić wieloprocesowe przetwarzanie oraz opcję rekurencyjnego generowania miniatur. Pakiet można pipzainstalować. Sprawdź tutaj instrukcje instalacji.

Przykładem zastosowania jest:

thumbgen -w 4 -r -d your_directory
  • -r: rekurencyjnie generuj miniatury

  • -w: liczba rdzeni do użycia

mudassirkhan19
źródło