Як автоматично встановити піктограми папок з декількох папок?


10

Як встановити перше зображення кожної папки як її значок папки?

На вищезазначене запитання є відповідь, що складається зі сценарію, який працює для мене. Просто потрібно трохи покращитись.

Що це робить?

Він знаходить файли з розширеннями .jpg, .jpeg, .png, .gif, .icns, .ico та встановлює їх як значок папки папки, в якій був знайдений файл. Він працює на декількох папках, рекурсивно. В основному він намагається знайти файл зображення всередині папки, і перше знайдене зображення встановлюється як значок папки. Він чудово підходить для багатьох сценаріїв, і налаштування цього сценарію, як правило, перше, що я роблю після нової установки (адже це дивовижно).

В чому проблема?

Можливо, існує декілька каталогів, які містять безліч файлів зображень, і перший файл зображень у цьому каталозі може бути невідповідним як значок папки.

Що він повинен робити?

Замість того, щоб базуватись на розширеннях, якщо вона набула назви файлів і націлена одна (наприклад, folder.png) або декілька (наприклад albumart.png cover.png) імен файлів, тоді цю проблему можна було б вирішити.

або ще краще змусити обидва підходи працювати в одному сценарії

  • Знайдіть попередньо визначені filenames
  • Якщо знайдено, встановіть його як значок папки та перейдіть до наступної папки
  • Якщо НЕ знайдено, знайдіть попередньо визначене розширення та встановіть його як значок папки та перейдіть до наступної папки

Відповіді:


9

Я можу все-таки "трохи витончити це", але нижче - відредаговані версії пов'язаних.

Яка різниця?

Я додав попередній список до головного розділу:

specs = ["folder.png", "cover.png", "monkey.png"]

і я замінив:

try:
    first = min(p for p in os.listdir(folder) 
                if p.split(".")[-1].lower() in ext)
except ValueError:
    pass

автор:

fls = os.listdir(folder)
try:
    first = [p for p in fls if p in specs]
    first = first[0] if first else min(
        p for p in fls if p.split(".")[-1].lower() in ext
        )
except ValueError:
    pass

так що сценарій спершу намагається знайти (файл) збіги у списку specs, (лише) якщо таких немає, він переходить до пошуку розширення, що збігається, і робить фокус, якщо знайде відповідне зображення.


1. Основна версія

Для використання з цільовим каталогом як аргумент:

#!/usr/bin/env python3
import subprocess
import os
import sys

# --- set the list of valid extensions below (lowercase)
# --- use quotes, *don't* include the dot!
ext = ["jpg", "jpeg", "png", "gif", "icns", "ico"]
# --- set the list of preferred filenames
# --- use quotes
specs = ["folder.png", "cover.png", "monkey.png"]
# ---

# retrieve the path of the targeted folder
dr = sys.argv[1]

for root, dirs, files in os.walk(dr):
    for directory in dirs:
        folder = os.path.join(root, directory)
        try:
            fls = os.listdir(folder)
            first = [p for p in fls if p in specs]
            first = first[0] if first else min(
                p for p in fls if p.split(".")[-1].lower() in ext
                )
        except (ValueError, PermissionError):
            pass

        else:
            subprocess.Popen([
                "gvfs-set-attribute", "-t", "string",
                os.path.abspath(folder), "metadata::custom-icon",
                "file://"+os.path.abspath(os.path.join(folder, first))
                ])

Як користуватись

  1. Скопіюйте скрипт у порожній файл, збережіть його як change_icon.py
  2. У голові сценарію відредагуйте, якщо вам подобається, список розширень, які використовуватимуться як дійсні зображення значків. Також встановіть список бажаних імен файлів.
  3. Запустіть його з цільовим каталогом як аргумент:

    python3 /path/to/change_icon.py <targeted_directory>
    

Це воно!


2. Відредагований варіант правої кнопки миші, який буде використаний як скрипт nautilus (клацання правою кнопкою миші)

#!/usr/bin/env python3
import subprocess
import os

# --- set the list of valid extensions below (lowercase)
# --- use quotes, *don't* include the dot!
ext = ["jpg", "jpeg", "png", "gif", "icns", "ico"]
# --- set the list of preferred filenames
# --- use quotes
specs = ["folder.png", "cover.png", "aap.png"]
# ---

def fix(path):
    for c in [("%23", "#"), ("%5D", "]"), ("%5E", "^"),
              ("file://", ""), ("%20", " ")]:
        path = path.replace(c[0], c[1])
    return path

# retrieve the path of the targeted folder
current = fix(os.getenv("NAUTILUS_SCRIPT_CURRENT_URI"))
dr = os.path.realpath(current)

for root, dirs, files in os.walk(dr):
    for directory in dirs:
        folder = os.path.join(root, directory)
        try:
            fls = os.listdir(folder)
            first = [p for p in fls if p in specs]
            first = first[0] if first else min(
                p for p in fls if p.split(".")[-1].lower() in ext
                )
        except (ValueError, PermissionError):
            pass

        else:
            subprocess.Popen([
                "gvfs-set-attribute", "-t", "string",
                os.path.abspath(folder), "metadata::custom-icon",
                "file://"+os.path.abspath(os.path.join(folder, first))
                ])

Використовувати

  1. Створіть, якщо він ще не існує, каталог

    ~/.local/share/nautilus/scripts
    
  2. Скопіюйте скрипт у порожній файл, збережіть його у ~/.local/share/nautilus/scriptsвигляді set_foldericons(без розширення!) Та зробіть його виконуваним .

  3. У голові сценарію відредагуйте, якщо вам подобається, список розширень, які використовуватимуться як дійсні зображення значків. Також встановіть список бажаних імен файлів.
  4. Вийдіть із системи та ввійдіть назад, і він працює.

Якщо з якоїсь причини ви хочете скинути піктограми всередині папки до значків за замовчуванням, скористайтеся тут скриптом


2
Ви повинні переконатися, що URI від Nautilus насправді починається з file://. Замість цього replace("%20", " ")слід використовувати правильне декодування URI (наприклад urllib.parse.unquote) та пізніше кодування ( urllib.parse.quote).
Девід Фоерстер

@DavidFoerster це все-таки покращить продуктивність сценарію? Я намагався змінити subprocess.Popenдо subprocess.callале на величезних каталогів з майже 700+ підводного човна не всі значки папок chnage.
Sumeet Deshmukh

@DavidFoerster дякую! але urllib.parse.quoteдобре працює на "сухому" тесті, а не в сценарії. Потрібно з’ясувати, чому, але покинути робочу версію сценарію поки що.
Яків Влійм

@SumeetDeshmukh: Ні, але це змусить сценарій працювати з URL-адресами, які містять інші "спеціальні" символи, окрім символу пробілу (U + 0020). Крім того, було б більш надійно проти помилкового або неправдивого введення даних і зачепити його рано.
Девід Фоерстер,

@JacobVlijm: Що відбувається, коли ви намагаєтесь використовувати його в сценарії? Повідомлення про помилку? Несподівані результати? Чи unquoteпрацює так, як очікувалося?
Девід Фоерстер,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.