Browse Source

New module to find absolute icon paths without the help of qt. Thanks for nothing, qt

master
Nils 5 years ago
parent
commit
8ad9dd1ff6
  1. 142
      engine/findicons.py

142
engine/findicons.py

@ -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…
Cancel
Save