Как создать сценарий и системное правило для всех каталогов, которые будут применять эмблему к значку каждого каталога, если папка содержит прямую подпапку .git? Я уже включил значок эмблемы github в мои эмблемы, такие как
Эффект вывода должен быть таким:
ПРИМЕЧАНИЕ: это новая и обновленная версия скрипта, для старой версии см. историю изменений этого ответа
. Сценарий, представленный ниже, позволяет либо установить значок или эмблема github-хранилища (но не оба), а также сбросить эти метаданные до значения по умолчанию. Использование очень просто, как объясняется опцией -h:
$ ./set_folder_icon.py -h
usage: set_folder_icon.py [-h] [-i ICON] [-e EMBLEM] [-r ROOT] [-u]
Finds and sets github repository icons.Choose either --icon or --emblem.
Without either the script exists with 0 exit status.For --icons, use absolute
or relative path.For --emblem use single string of text.Emblem pathnames are
in the format emblem-name.extension.The script then can becalled with -e
<name>.Use ~/.local/share/icons folder for custom emblems (if it does not
exist - create it. Store filenames in specified format
optional arguments:
-h, --help show this help message and exit
-i ICON, --icon ICON path to image to set
-e EMBLEM, --emblem EMBLEM
single-string emblem name
-r ROOT, --root ROOT where search starts,default - current working
directory
-u, --unset unset both emblem and icon. Cannot be used with -e or
-i options
Итак, если мы хотим рекурсивно искать домашнюю папку для всех github репозиториев и устанавливать их эмблему, мы сделали бы set_folder_icon.py -e myemblemname -r $HOME или просто cd; set_folder_icon.py -e myemblemname
Для достижения максимальной производительности создайте каталог ~/bin и сохраните сценарий там как set_folder_icon.py. Если вы хотите использовать его немедленно, запустите source ~/.bashrc. Если вы используете другую оболочку, убедитесь, что ваш ~/bin добавлен в переменную $PATH.
ПРИМЕЧАНИЕ. Сценарий может принимать любой произвольный файл с опцией --icon, но --emblem требует у вас есть определенный файл, который будет сохранен в ~/.local/share/icons с именем файла примерно как emblem-github. См. Раздел «Сценарий в действии» для примера
Мне удалось сохранить все мои репозитории github в папке ~/GIT.
До:
После:
Сценарий также доступен в моем личном репозитории GitHub, где он скорее получит новые изменения и исправления.
]#!/usr/bin/env python3
"""
Author: Sergiy Kolodyazhnyy
Date: 7/12/2017
Purpose: Script to find github repository folders
and set their icons for Ubuntu.
Written for: https://askubuntu.com/q/935003/295286
"""
import argparse
import os
import sys
import subprocess
import urllib.parse
def puke(message, status_code):
""" Print to stderr and exit with given code """
sys.stderr.write('>>> OOOPS. Something is wrong:\n')
sys.stderr.write(message + '\n')
sys.exit(status_code)
def run_cmd(cmdlist):
""" Reusable function for running external commands """
try:
stdout = subprocess.check_output(cmdlist)
except subprocess.CalledProcessError as cpe:
puke('Called command failed with ' + str(cpe.returncode) +
' exit status\n' + repr(cpe), 4)
else:
if stdout:
return stdout
def set_icon(directory, icon_type, image):
""" Wrapper function that specifies command and calls run_cmd()"""
key = 'metadata::' + icon_type
meta = {'metadata::custom-icon': 'string',
'metadata::emblems': 'stringv'}
# Because custom-icons and emblems type are mutually
# exclusive, we need to unset custom-icon to enable emblems
if icon_type == 'emblems':
cmd = ['gvfs-set-attribute', '-t', 'unset',
directory, 'metadata::custom-icon']
run_cmd(cmd)
cmd = ['gvfs-set-attribute', '-t', meta[key],
directory, key, image]
return run_cmd(cmd)
def unset_all(directory):
for key in ['metadata::custom-icon', 'metadata::emblems']:
run_cmd(['gvfs-set-attribute', '-t', 'unset', directory, key])
def find_directories(tree_root):
""" Does the job of recursive traversal of given directory tree,
starting at the specified tree root directory. If condition for
given subdirectory is met, calls set_icon() function"""
for current_dir, subdirs, files in os.walk(tree_root):
# This check can be adapted to other cases
if '.git' in subdirs:
print('Found', current_dir)
yield current_dir
def parse_args():
""" Parses command-line arguments """
text = ['Finds and sets github repository icons.',
'Choose either --icon or --emblem. Without either'
' the script exists with 0 exit status.',
'For --icons, use absolute or relative path.',
'For --emblem use single string of text.',
'Emblem pathnames are in the format',
' emblem-name.extension.', 'The script then can be',
'called with -e <name>.Use ~/.local/share/icons folder',
' for custom emblems (if it does not ',
'exist - create it. Store filenames in specified format']
arg_parser = argparse.ArgumentParser(description="".join(text))
arg_parser.add_argument('-i', '--icon', help='path to image to set',
type=str, required=False)
arg_parser.add_argument('-e', '--emblem', help='single-string emblem name',
type=str, required=False)
arg_parser.add_argument('-r', '--root', help='where search starts,' +
'default - current working directory',
default='.', type=str, required=False)
arg_parser.add_argument('-u', '--unset', help='unset both emblem ' +
'and icon. Cannot be used with -e or -i options',
action='store_true', required=False)
return arg_parser.parse_args()
def main():
""" Script entry point """
# Parse command-line arguments and check their correctness
args = parse_args()
status_code = {'icon_missing': 1, 'root_missing': 2,
'root_isnt_dir': 3, 'exclusion': 4,
'not_string': 5, 'conflict': 6}
if args.unset and (args.icon or args.emblem):
puke('Conflicting options', status_code['conflict'])
if not args.unset:
# both or none are given
if not args.icon and not args.emblem:
sys.exit(0)
if args.icon and args.emblem:
puke('Can only use either --icon or --emblem',
status_code['exclusion'])
# Verify correctness of either one
if args.icon and not os.path.exists(args.icon):
puke('Icon pathname does not exist',
status_code['icon_missing'])
if args.emblem:
if '/' in args.emblem:
puke('Emblem must be a single string of text,no paths',
status_code['not_string'])
if not isinstance(args.emblem, str):
puke('Given argument for emblem is not a string',
stats_code['not_string'])
# Verify correctness of the path
if not os.path.exists(args.root):
puke('Root pathname does not exist',
status_code['root_missing'])
if not os.path.isdir(args.root):
puke('Root pathname is not a directory',
status_code['root_isnt_dir'])
if args.unset:
for directory in find_directories(args.root):
print('Unsetting', directory)
unset_all(directory)
sys.exit(0)
# Everything should be OK past this point
if args.icon:
meta_type = 'custom-icon'
icon = 'file://' + urllib.parse.quote(os.path.abspath(args.icon))
if args.emblem:
meta_type = 'emblems'
icon = args.emblem
# Now do the actual traversal and icon-setting
for directory in find_directories(args.root):
set_icon(directory, meta_type, icon)
if __name__ == '__main__':
main()
Конечно, мы можем запускать скрипт вручную каждый раз (на самом деле я, вероятно, создаю функцию, которая может объединить git clone и запустить этот скрипт) хотя я бы рекомендовал, чтобы вы запускали скрипт каждый раз, когда вы входите в свой сеанс GUI. Для этого откройте меню «Запуск приложений» и добавьте скрипт (используя полный путь и полные имена файлов) в качестве записи.
личный репозиторий GitHub [!d24 ]
И в следующий раз, когда вы войдете в систему, ваши значки будут установлены.
Что касается ручной идеи, вы можете запустить git clone и сценарий один за другим с помощью оператора && или лучше но сделайте функцию в ~/.bashrc для этого так:
$ tree
.
0 directories, 0 files
$ typeset -f my_gitclone
my_gitclone ()
{
git clone "$1" && ~/GIT/sergrep/set_folder_icon.py -e github
}
$ my_gitclone https://github.com/SergKolo/sergrep
Cloning into 'sergrep'...
remote: Counting objects: 387, done.
remote: Compressing objects: 100% (17/17), done.
remote: Total 387 (delta 10), reused 17 (delta 5), pack-reused 365
Receiving objects: 100% (387/387), 115.65 KiB | 0 bytes/s, done.
Resolving deltas: 100% (203/203), done.
Checking connectivity... done.
Found ./sergrep
ПРИМЕЧАНИЕ: это новая и обновленная версия скрипта, для старой версии см. историю изменений этого ответа
. Сценарий, представленный ниже, позволяет либо установить значок или эмблема github-хранилища (но не оба), а также сбросить эти метаданные до значения по умолчанию. Использование очень просто, как объясняется опцией -h:
$ ./set_folder_icon.py -h
usage: set_folder_icon.py [-h] [-i ICON] [-e EMBLEM] [-r ROOT] [-u]
Finds and sets github repository icons.Choose either --icon or --emblem.
Without either the script exists with 0 exit status.For --icons, use absolute
or relative path.For --emblem use single string of text.Emblem pathnames are
in the format emblem-name.extension.The script then can becalled with -e
<name>.Use ~/.local/share/icons folder for custom emblems (if it does not
exist - create it. Store filenames in specified format
optional arguments:
-h, --help show this help message and exit
-i ICON, --icon ICON path to image to set
-e EMBLEM, --emblem EMBLEM
single-string emblem name
-r ROOT, --root ROOT where search starts,default - current working
directory
-u, --unset unset both emblem and icon. Cannot be used with -e or
-i options
Итак, если мы хотим рекурсивно искать домашнюю папку для всех github репозиториев и устанавливать их эмблему, мы сделали бы set_folder_icon.py -e myemblemname -r $HOME или просто cd; set_folder_icon.py -e myemblemname
Для достижения максимальной производительности создайте каталог ~/bin и сохраните сценарий там как set_folder_icon.py. Если вы хотите использовать его немедленно, запустите source ~/.bashrc. Если вы используете другую оболочку, убедитесь, что ваш ~/bin добавлен в переменную $PATH.
ПРИМЕЧАНИЕ. Сценарий может принимать любой произвольный файл с опцией --icon, но --emblem требует у вас есть определенный файл, который будет сохранен в ~/.local/share/icons с именем файла примерно как emblem-github. См. Раздел «Сценарий в действии» для примера
Мне удалось сохранить все мои репозитории github в папке ~/GIT.
До:
После:
Сценарий также доступен в моем личном репозитории GitHub, где он скорее получит новые изменения и исправления.
]#!/usr/bin/env python3
"""
Author: Sergiy Kolodyazhnyy
Date: 7/12/2017
Purpose: Script to find github repository folders
and set their icons for Ubuntu.
Written for: https://askubuntu.com/q/935003/295286
"""
import argparse
import os
import sys
import subprocess
import urllib.parse
def puke(message, status_code):
""" Print to stderr and exit with given code """
sys.stderr.write('>>> OOOPS. Something is wrong:\n')
sys.stderr.write(message + '\n')
sys.exit(status_code)
def run_cmd(cmdlist):
""" Reusable function for running external commands """
try:
stdout = subprocess.check_output(cmdlist)
except subprocess.CalledProcessError as cpe:
puke('Called command failed with ' + str(cpe.returncode) +
' exit status\n' + repr(cpe), 4)
else:
if stdout:
return stdout
def set_icon(directory, icon_type, image):
""" Wrapper function that specifies command and calls run_cmd()"""
key = 'metadata::' + icon_type
meta = {'metadata::custom-icon': 'string',
'metadata::emblems': 'stringv'}
# Because custom-icons and emblems type are mutually
# exclusive, we need to unset custom-icon to enable emblems
if icon_type == 'emblems':
cmd = ['gvfs-set-attribute', '-t', 'unset',
directory, 'metadata::custom-icon']
run_cmd(cmd)
cmd = ['gvfs-set-attribute', '-t', meta[key],
directory, key, image]
return run_cmd(cmd)
def unset_all(directory):
for key in ['metadata::custom-icon', 'metadata::emblems']:
run_cmd(['gvfs-set-attribute', '-t', 'unset', directory, key])
def find_directories(tree_root):
""" Does the job of recursive traversal of given directory tree,
starting at the specified tree root directory. If condition for
given subdirectory is met, calls set_icon() function"""
for current_dir, subdirs, files in os.walk(tree_root):
# This check can be adapted to other cases
if '.git' in subdirs:
print('Found', current_dir)
yield current_dir
def parse_args():
""" Parses command-line arguments """
text = ['Finds and sets github repository icons.',
'Choose either --icon or --emblem. Without either'
' the script exists with 0 exit status.',
'For --icons, use absolute or relative path.',
'For --emblem use single string of text.',
'Emblem pathnames are in the format',
' emblem-name.extension.', 'The script then can be',
'called with -e <name>.Use ~/.local/share/icons folder',
' for custom emblems (if it does not ',
'exist - create it. Store filenames in specified format']
arg_parser = argparse.ArgumentParser(description="".join(text))
arg_parser.add_argument('-i', '--icon', help='path to image to set',
type=str, required=False)
arg_parser.add_argument('-e', '--emblem', help='single-string emblem name',
type=str, required=False)
arg_parser.add_argument('-r', '--root', help='where search starts,' +
'default - current working directory',
default='.', type=str, required=False)
arg_parser.add_argument('-u', '--unset', help='unset both emblem ' +
'and icon. Cannot be used with -e or -i options',
action='store_true', required=False)
return arg_parser.parse_args()
def main():
""" Script entry point """
# Parse command-line arguments and check their correctness
args = parse_args()
status_code = {'icon_missing': 1, 'root_missing': 2,
'root_isnt_dir': 3, 'exclusion': 4,
'not_string': 5, 'conflict': 6}
if args.unset and (args.icon or args.emblem):
puke('Conflicting options', status_code['conflict'])
if not args.unset:
# both or none are given
if not args.icon and not args.emblem:
sys.exit(0)
if args.icon and args.emblem:
puke('Can only use either --icon or --emblem',
status_code['exclusion'])
# Verify correctness of either one
if args.icon and not os.path.exists(args.icon):
puke('Icon pathname does not exist',
status_code['icon_missing'])
if args.emblem:
if '/' in args.emblem:
puke('Emblem must be a single string of text,no paths',
status_code['not_string'])
if not isinstance(args.emblem, str):
puke('Given argument for emblem is not a string',
stats_code['not_string'])
# Verify correctness of the path
if not os.path.exists(args.root):
puke('Root pathname does not exist',
status_code['root_missing'])
if not os.path.isdir(args.root):
puke('Root pathname is not a directory',
status_code['root_isnt_dir'])
if args.unset:
for directory in find_directories(args.root):
print('Unsetting', directory)
unset_all(directory)
sys.exit(0)
# Everything should be OK past this point
if args.icon:
meta_type = 'custom-icon'
icon = 'file://' + urllib.parse.quote(os.path.abspath(args.icon))
if args.emblem:
meta_type = 'emblems'
icon = args.emblem
# Now do the actual traversal and icon-setting
for directory in find_directories(args.root):
set_icon(directory, meta_type, icon)
if __name__ == '__main__':
main()
Конечно, мы можем запускать скрипт вручную каждый раз (на самом деле я, вероятно, создаю функцию, которая может объединить git clone и запустить этот скрипт) хотя я бы рекомендовал, чтобы вы запускали скрипт каждый раз, когда вы входите в свой сеанс GUI. Для этого откройте меню «Запуск приложений» и добавьте скрипт (используя полный путь и полные имена файлов) в качестве записи.
И в следующий раз, когда вы войдете в систему, ваши значки будут установлены.
Что касается ручной идеи, вы можете запустить git clone и сценарий один за другим с помощью оператора && или лучше но сделайте функцию в ~/.bashrc для этого так:
$ tree
.
0 directories, 0 files
$ typeset -f my_gitclone
my_gitclone ()
{
git clone "$1" && ~/GIT/sergrep/set_folder_icon.py -e github
}
$ my_gitclone https://github.com/SergKolo/sergrep
Cloning into 'sergrep'...
remote: Counting objects: 387, done.
remote: Compressing objects: 100% (17/17), done.
remote: Total 387 (delta 10), reused 17 (delta 5), pack-reused 365
Receiving objects: 100% (387/387), 115.65 KiB | 0 bytes/s, done.
Resolving deltas: 100% (203/203), done.
Checking connectivity... done.
Found ./sergrep
ПРИМЕЧАНИЕ: это новая и обновленная версия скрипта, для старой версии см. историю изменений этого ответа
. Сценарий, представленный ниже, позволяет либо установить значок или эмблема github-хранилища (но не оба), а также сбросить эти метаданные до значения по умолчанию. Использование очень просто, как объясняется опцией -h:
$ ./set_folder_icon.py -h
usage: set_folder_icon.py [-h] [-i ICON] [-e EMBLEM] [-r ROOT] [-u]
Finds and sets github repository icons.Choose either --icon or --emblem.
Without either the script exists with 0 exit status.For --icons, use absolute
or relative path.For --emblem use single string of text.Emblem pathnames are
in the format emblem-name.extension.The script then can becalled with -e
<name>.Use ~/.local/share/icons folder for custom emblems (if it does not
exist - create it. Store filenames in specified format
optional arguments:
-h, --help show this help message and exit
-i ICON, --icon ICON path to image to set
-e EMBLEM, --emblem EMBLEM
single-string emblem name
-r ROOT, --root ROOT where search starts,default - current working
directory
-u, --unset unset both emblem and icon. Cannot be used with -e or
-i options
Итак, если мы хотим рекурсивно искать домашнюю папку для всех github репозиториев и устанавливать их эмблему, мы сделали бы set_folder_icon.py -e myemblemname -r $HOME или просто cd; set_folder_icon.py -e myemblemname
Для достижения максимальной производительности создайте каталог ~/bin и сохраните сценарий там как set_folder_icon.py. Если вы хотите использовать его немедленно, запустите source ~/.bashrc. Если вы используете другую оболочку, убедитесь, что ваш ~/bin добавлен в переменную $PATH.
ПРИМЕЧАНИЕ. Сценарий может принимать любой произвольный файл с опцией --icon, но --emblem требует у вас есть определенный файл, который будет сохранен в ~/.local/share/icons с именем файла примерно как emblem-github. См. Раздел «Сценарий в действии» для примера
Мне удалось сохранить все мои репозитории github в папке ~/GIT.
До:
После:
Сценарий также доступен в моем личном репозитории GitHub, где он скорее получит новые изменения и исправления.
]#!/usr/bin/env python3
"""
Author: Sergiy Kolodyazhnyy
Date: 7/12/2017
Purpose: Script to find github repository folders
and set their icons for Ubuntu.
Written for: https://askubuntu.com/q/935003/295286
"""
import argparse
import os
import sys
import subprocess
import urllib.parse
def puke(message, status_code):
""" Print to stderr and exit with given code """
sys.stderr.write('>>> OOOPS. Something is wrong:\n')
sys.stderr.write(message + '\n')
sys.exit(status_code)
def run_cmd(cmdlist):
""" Reusable function for running external commands """
try:
stdout = subprocess.check_output(cmdlist)
except subprocess.CalledProcessError as cpe:
puke('Called command failed with ' + str(cpe.returncode) +
' exit status\n' + repr(cpe), 4)
else:
if stdout:
return stdout
def set_icon(directory, icon_type, image):
""" Wrapper function that specifies command and calls run_cmd()"""
key = 'metadata::' + icon_type
meta = {'metadata::custom-icon': 'string',
'metadata::emblems': 'stringv'}
# Because custom-icons and emblems type are mutually
# exclusive, we need to unset custom-icon to enable emblems
if icon_type == 'emblems':
cmd = ['gvfs-set-attribute', '-t', 'unset',
directory, 'metadata::custom-icon']
run_cmd(cmd)
cmd = ['gvfs-set-attribute', '-t', meta[key],
directory, key, image]
return run_cmd(cmd)
def unset_all(directory):
for key in ['metadata::custom-icon', 'metadata::emblems']:
run_cmd(['gvfs-set-attribute', '-t', 'unset', directory, key])
def find_directories(tree_root):
""" Does the job of recursive traversal of given directory tree,
starting at the specified tree root directory. If condition for
given subdirectory is met, calls set_icon() function"""
for current_dir, subdirs, files in os.walk(tree_root):
# This check can be adapted to other cases
if '.git' in subdirs:
print('Found', current_dir)
yield current_dir
def parse_args():
""" Parses command-line arguments """
text = ['Finds and sets github repository icons.',
'Choose either --icon or --emblem. Without either'
' the script exists with 0 exit status.',
'For --icons, use absolute or relative path.',
'For --emblem use single string of text.',
'Emblem pathnames are in the format',
' emblem-name.extension.', 'The script then can be',
'called with -e <name>.Use ~/.local/share/icons folder',
' for custom emblems (if it does not ',
'exist - create it. Store filenames in specified format']
arg_parser = argparse.ArgumentParser(description="".join(text))
arg_parser.add_argument('-i', '--icon', help='path to image to set',
type=str, required=False)
arg_parser.add_argument('-e', '--emblem', help='single-string emblem name',
type=str, required=False)
arg_parser.add_argument('-r', '--root', help='where search starts,' +
'default - current working directory',
default='.', type=str, required=False)
arg_parser.add_argument('-u', '--unset', help='unset both emblem ' +
'and icon. Cannot be used with -e or -i options',
action='store_true', required=False)
return arg_parser.parse_args()
def main():
""" Script entry point """
# Parse command-line arguments and check their correctness
args = parse_args()
status_code = {'icon_missing': 1, 'root_missing': 2,
'root_isnt_dir': 3, 'exclusion': 4,
'not_string': 5, 'conflict': 6}
if args.unset and (args.icon or args.emblem):
puke('Conflicting options', status_code['conflict'])
if not args.unset:
# both or none are given
if not args.icon and not args.emblem:
sys.exit(0)
if args.icon and args.emblem:
puke('Can only use either --icon or --emblem',
status_code['exclusion'])
# Verify correctness of either one
if args.icon and not os.path.exists(args.icon):
puke('Icon pathname does not exist',
status_code['icon_missing'])
if args.emblem:
if '/' in args.emblem:
puke('Emblem must be a single string of text,no paths',
status_code['not_string'])
if not isinstance(args.emblem, str):
puke('Given argument for emblem is not a string',
stats_code['not_string'])
# Verify correctness of the path
if not os.path.exists(args.root):
puke('Root pathname does not exist',
status_code['root_missing'])
if not os.path.isdir(args.root):
puke('Root pathname is not a directory',
status_code['root_isnt_dir'])
if args.unset:
for directory in find_directories(args.root):
print('Unsetting', directory)
unset_all(directory)
sys.exit(0)
# Everything should be OK past this point
if args.icon:
meta_type = 'custom-icon'
icon = 'file://' + urllib.parse.quote(os.path.abspath(args.icon))
if args.emblem:
meta_type = 'emblems'
icon = args.emblem
# Now do the actual traversal and icon-setting
for directory in find_directories(args.root):
set_icon(directory, meta_type, icon)
if __name__ == '__main__':
main()
Конечно, мы можем запускать скрипт вручную каждый раз (на самом деле я, вероятно, создаю функцию, которая может объединить git clone и запустить этот скрипт) хотя я бы рекомендовал, чтобы вы запускали скрипт каждый раз, когда вы входите в свой сеанс GUI. Для этого откройте меню «Запуск приложений» и добавьте скрипт (используя полный путь и полные имена файлов) в качестве записи.
И в следующий раз, когда вы войдете в систему, ваши значки будут установлены.
Что касается ручной идеи, вы можете запустить git clone и сценарий один за другим с помощью оператора && или лучше но сделайте функцию в ~/.bashrc для этого так:
$ tree
.
0 directories, 0 files
$ typeset -f my_gitclone
my_gitclone ()
{
git clone "$1" && ~/GIT/sergrep/set_folder_icon.py -e github
}
$ my_gitclone https://github.com/SergKolo/sergrep
Cloning into 'sergrep'...
remote: Counting objects: 387, done.
remote: Compressing objects: 100% (17/17), done.
remote: Total 387 (delta 10), reused 17 (delta 5), pack-reused 365
Receiving objects: 100% (387/387), 115.65 KiB | 0 bytes/s, done.
Resolving deltas: 100% (203/203), done.
Checking connectivity... done.
Found ./sergrep