# Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER # DEALINGS IN THE SOFTWARE. """ Misc helper functions. """ import colorsys import json import logging import os class Color: """Color formats.""" alpha_num = "100" def __init__(self, hex_color): self.hex_color = hex_color def __str__(self): return self.hex_color @property def strip(self): """Strip '#' from color.""" return self.hex_color[1:] def read_file_json(input_file): """Read data from a json file.""" with open(input_file, "r") as json_file: return json.load(json_file) def save_file(data, export_file): """Write data to a file.""" create_dir(os.path.dirname(export_file)) try: with open(export_file, "w") as file: file.write(data) except PermissionError: logging.warning("Couldn't write to %s.", export_file) def save_file_json(data, export_file): """Write data to a json file.""" create_dir(os.path.dirname(export_file)) with open(export_file, "w") as file: json.dump(data, file, indent=4) def create_dir(directory): """Alias to create the cache dir.""" os.makedirs(directory, exist_ok=True) def hex_to_rgb(color): """Convert a hex color to rgb.""" return tuple(bytes.fromhex(color.strip("#"))) def rgb_to_hex(color): """Convert an rgb color to hex.""" return "#%02x%02x%02x" % (*color,) def darken_color(color, amount): """Darken a hex color.""" color = [int(col * (1 - amount)) for col in hex_to_rgb(color)] return rgb_to_hex(color) def lighten_color(color, amount): """Lighten a hex color.""" color = [int(col + (255 - col) * amount) for col in hex_to_rgb(color)] return rgb_to_hex(color) def blend_color(color, color2): """Blend two colors together.""" r1, g1, b1 = hex_to_rgb(color) r2, g2, b2 = hex_to_rgb(color2) r3 = int(0.5 * r1 + 0.5 * r2) g3 = int(0.5 * g1 + 0.5 * g2) b3 = int(0.5 * b1 + 0.5 * b2) return rgb_to_hex((r3, g3, b3)) def saturate_color(color, amount): """Saturate a hex color.""" r, g, b = hex_to_rgb(color) r, g, b = [x / 255.0 for x in (r, g, b)] h, l, s = colorsys.rgb_to_hls(r, g, b) s = amount r, g, b = colorsys.hls_to_rgb(h, l, s) r, g, b = [x * 255.0 for x in (r, g, b)] return rgb_to_hex((int(r), int(g), int(b))) def rgb_to_yiq(color): """Sort a list of colors.""" return colorsys.rgb_to_yiq(*hex_to_rgb(color))