Music production session manager
https://www.laborejo.org
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
4.4 KiB
151 lines
4.4 KiB
#! /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)
|
|
|
|
global _cache
|
|
_cache = None
|
|
def updateCache():
|
|
global _cache
|
|
_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"""
|
|
|
|
if not _cache:
|
|
raise ValueError("You need to call updateCache() first")
|
|
|
|
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
|
|
|
|
updateCache()
|
|
|
|
if __name__ == "__main__":
|
|
"""Example that tries to find a few icons"""
|
|
|
|
updateCache()
|
|
|
|
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 ")
|
|
|
|
|
|
|
|
|