75 lines
2.3 KiB
Python
75 lines
2.3 KiB
Python
#!/usr/bin/env python3
|
|
|
|
# SàT: a XMPP client
|
|
# Copyright (C) 2009-2020 Jérôme Poisson (goffi@goffi.org)
|
|
|
|
# This program is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
|
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
"""Misc utils for both backend and frontends"""
|
|
|
|
import collections.abc
|
|
|
|
|
|
def per_luminance(red, green, blue):
|
|
"""Caculate the perceived luminance of a RGB color
|
|
|
|
@param red(int): 0-1 normalized value of red
|
|
@param green(int): 0-1 normalized value of green
|
|
@param blue(int): 0-1 normalized value of blue
|
|
@return (float): 0-1 value of luminance (<0.5 is dark, else it's light)
|
|
"""
|
|
# cf. https://stackoverflow.com/a/1855903, thanks Gacek
|
|
|
|
return 0.299 * red + 0.587 * green + 0.114 * blue
|
|
|
|
|
|
def recursive_update(ori: dict, update: dict):
|
|
"""Recursively update a dictionary"""
|
|
# cf. https://stackoverflow.com/a/3233356, thanks Alex Martelli
|
|
for k, v in update.items():
|
|
if isinstance(v, collections.abc.Mapping):
|
|
ori[k] = recursive_update(ori.get(k, {}), v)
|
|
else:
|
|
ori[k] = v
|
|
return ori
|
|
|
|
class OrderedSet(collections.abc.MutableSet):
|
|
"""A mutable sequence which doesn't keep duplicates"""
|
|
# TODO: complete missing set methods
|
|
|
|
def __init__(self, values=None):
|
|
self._dict = {}
|
|
if values is not None:
|
|
self.update(values)
|
|
|
|
def __len__(self):
|
|
return len(self._dict)
|
|
|
|
def __iter__(self):
|
|
return iter(self._dict.keys())
|
|
|
|
def __contains__(self, item):
|
|
return item in self._dict
|
|
|
|
def add(self, item):
|
|
self._dict[item] = None
|
|
|
|
def discard(self, item):
|
|
try:
|
|
del self._dict[item]
|
|
except KeyError:
|
|
pass
|
|
|
|
def update(self, items):
|
|
self._dict.update({i: None for i in items})
|