Nils
4 years ago
1 changed files with 142 additions and 0 deletions
@ -0,0 +1,142 @@ |
|||
#! /usr/bin/env python3 |
|||
# -*- coding: utf-8 -*- |
|||
""" |
|||
Copyright 2020, Nils Hilbricht, Germany ( https://www.hilbricht.net ) |
|||
|
|||
This file is part of the Laborejo Software Suite ( https://www.laborejo.org ), |
|||
|
|||
This is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
""" |
|||
|
|||
import logging; logger = logging.getLogger(__name__); logger.info("import") |
|||
|
|||
from os import getenv |
|||
import os |
|||
import pathlib |
|||
import re |
|||
|
|||
""" |
|||
https://specifications.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html |
|||
https://specifications.freedesktop.org/icon-theme-spec/icon-theme-spec-latest.html#icon_lookup |
|||
|
|||
$HOME/.icons (for backwards compatibility) |
|||
$XDG_DATA_DIRS/icons |
|||
/usr/share/pixmaps |
|||
""" |
|||
|
|||
SEARCH_DIRECTORIES = [pathlib.Path(pathlib.Path.home(), ".icons")] |
|||
|
|||
XDG_DATA_DIRS = getenv("XDG_DATA_DIRS") #colon : separated, most likely empty |
|||
if XDG_DATA_DIRS: |
|||
SEARCH_DIRECTORIES += [pathlib.Path(p, "icons") for p in XDG_DATA_DIRS.split(":")] |
|||
else: |
|||
#If $XDG_DATA_DIRS is either not set or empty, a value equal to /usr/local/share/:/usr/share/ should be used. |
|||
SEARCH_DIRECTORIES += [pathlib.Path(p, "icons") for p in "/usr/local/share/:/usr/share/".split(":")] |
|||
|
|||
SEARCH_DIRECTORIES.append(pathlib.Path("/usr/share/pixmaps")) |
|||
|
|||
|
|||
def run_fast_scandir(dir, ext): |
|||
""" |
|||
https://stackoverflow.com/questions/18394147/recursive-sub-folder-search-and-return-files-in-a-list-python |
|||
""" |
|||
subfolders, files = [], [] |
|||
|
|||
try: |
|||
for f in os.scandir(dir): |
|||
if f.is_dir(): |
|||
subfolders.append(f.path) |
|||
if f.is_file(): |
|||
if os.path.splitext(f.name)[1].lower() in ext: |
|||
files.append(f.path) |
|||
|
|||
for dir in list(subfolders): |
|||
sf, f = run_fast_scandir(dir, ext) |
|||
subfolders.extend(sf) |
|||
files.extend(f) |
|||
|
|||
except PermissionError: |
|||
pass |
|||
|
|||
except FileNotFoundError: |
|||
pass |
|||
|
|||
return subfolders, files |
|||
|
|||
|
|||
def _buildCache()->set: |
|||
result = [] |
|||
for basePath in SEARCH_DIRECTORIES: |
|||
forget, files = run_fast_scandir(basePath, [".png", ".xpm", ".svg"]) |
|||
result += files |
|||
|
|||
#Convert str to real paths |
|||
result = [pathlib.Path(r) for r in result if pathlib.Path(r).is_file()] |
|||
|
|||
return set(result) |
|||
|
|||
_cache = _buildCache() |
|||
|
|||
|
|||
rePattern = re.compile("\d+x\d+") #we don't put .* around this because we are searching for the subpattern |
|||
|
|||
def findIconPath(executableName:str)->list: |
|||
"""Return order is: svg first, then highest resolution first, then the rest unordered. |
|||
so you can use result[0] for the best variant. |
|||
It is not guaranteed that [1], or even [0] exists. |
|||
This is not a sorted list, these extra variants are just added to the front of the list again""" |
|||
|
|||
executableName = executableName.lower() |
|||
|
|||
svg = None |
|||
bestr = 0 #resolution |
|||
best = None |
|||
|
|||
result = [] |
|||
for f in _cache: |
|||
if f.stem == executableName: |
|||
if f.suffix == ".svg": |
|||
svg = f |
|||
else: |
|||
match = re.search(rePattern, str(f)) #find resolution dir like /48x48/ |
|||
if match: |
|||
resolutionAsNumber = int(match.group().split("x")[0]) |
|||
if resolutionAsNumber > bestr: #new best one |
|||
bestr = resolutionAsNumber |
|||
best = f |
|||
result.append(f) |
|||
|
|||
if best: |
|||
result.insert(0, best) |
|||
if svg: |
|||
result.insert(0, svg) |
|||
|
|||
return result |
|||
|
|||
if __name__ == "__main__": |
|||
"""Example that tries to find a few icons""" |
|||
|
|||
print("Search paths:") |
|||
print(SEARCH_DIRECTORIES) |
|||
print() |
|||
|
|||
for exe in ("ZynAddSubFx", "patroneo", "jack_mixer", "carla", "ardour6", "synthv1"): |
|||
r = findIconPath(exe) |
|||
if r: |
|||
print (f"{exe} Best resolution: {r[0]}") |
|||
else: |
|||
print (f"{exe}: No icon found ") |
|||
|
|||
|
|||
|
Loading…
Reference in new issue