diff options
| author | Chandler Justice <chandler@cock.li> | 2023-12-09 00:31:22 -0700 |
|---|---|---|
| committer | Chandler Justice <chandler@cock.li> | 2023-12-09 00:31:22 -0700 |
| commit | 7382992e00b104232454dfd3ef5f355fa3cb4095 (patch) | |
| tree | e271a76cbf0e80151cd9bca14695b5ad52d71502 /src | |
| parent | 8269c373599e34b0fe4ffd1542420286dded0739 (diff) | |
refactor complete
Diffstat (limited to 'src')
| -rw-r--r-- | src/color_engine.py | 49 | ||||
| -rw-r--r-- | src/instant_rice.py | 30 | ||||
| -rw-r--r-- | src/paths.py | 6 | ||||
| -rw-r--r-- | src/update_i3.py | 58 | ||||
| -rw-r--r-- | src/update_polybar.py | 24 | ||||
| -rw-r--r-- | src/update_rofi.py | 23 | ||||
| -rw-r--r-- | src/user_interface.py | 51 |
7 files changed, 241 insertions, 0 deletions
diff --git a/src/color_engine.py b/src/color_engine.py new file mode 100644 index 0000000..f86b2e7 --- /dev/null +++ b/src/color_engine.py @@ -0,0 +1,49 @@ +import cv2 as cv +from sklearn.cluster import KMeans + +def grabColors(img_path: str, num_colors: int) -> list(): + """ + Takes in an image, and Number of colors, then returns a list of those colors. + The list of colors will contain the most prominent colors present in the image. + img_path - the path where your image lives (IE, /home/chandler/Pictures/moss.png) + num_colors - the number of colors you need back from the image + """ + img = cv.imread(img_path) + img = cv.cvtColor(img, cv.COLOR_BGR2RGB) + + # scale image down by factor of 10 to decrease computation time + dim = (int(len(img[0])/10), int(len(img)/10)) + img = cv.resize(img, dim, interpolation= cv.INTER_AREA) + clt = KMeans(n_clusters=num_colors, n_init='auto') + clt.fit(img.reshape(-1, 3)) + return clt.cluster_centers_ + +def rgbToHex(input_values: list): + """ + Takes in a list of RBG color values and returns a list of those same colors as hex values + """ + hex_list=[] + for color in input_values: + red = int(color[0]) + green = int(color[1]) + blue = int(color[2]) + hex_list.append('#{:02x}{:02x}{:02x}'.format(red, green, blue)) + return hex_list + +def hexToRGB(hex_value: str): + hex_value = hex_value.lstrip('#') + return tuple(int(hex_value[i:i+2], 16) for i in (0, 2, 4)) + +def compColors(color_list: list): + """ + given a list of colors, generate complimentary colors to contrast the prominent colors. + return a list of these colors. + """ + compliments = [] + for color in color_list: + curr_hex = color[1:] # slice off the # from the hex code + rgb = (curr_hex[0:2], curr_hex[2:4], curr_hex[4:6]) + comp = ['%02X' % (255 - int(a, 16)) for a in rgb] + compliments.append('#' + ''.join(comp)) + return compliments + diff --git a/src/instant_rice.py b/src/instant_rice.py new file mode 100644 index 0000000..87c9968 --- /dev/null +++ b/src/instant_rice.py @@ -0,0 +1,30 @@ +import sys +import color_engine +import user_interface +import update_rofi +import update_i3 +import update_polybar +from paths import Paths + +def main(): + if '-r' in sys.argv: + img_path = user_interface.pickRandomWallpaper() + else: + img_path = sys.argv[1] + + hex_colors, hex_compliments = user_interface.colorPickerUI(img_path) + if 'polybar' in Paths: + update_polybar.updatePolybarTheme(Paths['polybar'], hex_colors, hex_compliments) + if 'rofi' in Paths: + update_rofi.updateRofiTheme(Paths['rofi'], hex_colors, hex_compliments) + if 'i3' in Paths: + update_dmenu = True if ('-dmenu' in sys.argv) else False + if '--nolock' in sys.argv: + update_i3.updatei3Theme(Paths['i3'], img_path, hex_colors, hex_compliments, False, update_dmenu) + else: + update_i3.updatei3Theme(Paths['i3'], img_path, hex_colors, hex_compliments, True, update_dmenu) + + + +if __name__ == '__main__': + main() diff --git a/src/paths.py b/src/paths.py new file mode 100644 index 0000000..7ad287b --- /dev/null +++ b/src/paths.py @@ -0,0 +1,6 @@ +Paths = { + 'i3': '/home/chandler/.config/i3/config', + 'polybar': '/home/chandler/.config/polybar/config.ini', + 'wallpapers': '/home/chandler/Pictures/papes/', + 'lockscreen': '/home/chandler/.config/i3/' + } diff --git a/src/update_i3.py b/src/update_i3.py new file mode 100644 index 0000000..6430f6e --- /dev/null +++ b/src/update_i3.py @@ -0,0 +1,58 @@ +import subprocess +import cv2 as cv +import os + +from rich import print +from paths import Paths + +def updatei3Theme(config_path: str, img_path: str, colors: list, compliments: list, lock: bool, dmenu: bool): + print('[bold red]Updating i3 color scheme') + data = '' + with open(config_path, 'r') as file: + data = file.readlines() + + for i, line in enumerate(data): + # update colors + if "set $bgcolor" in line: + data[i] = 'set $bgcolor ' + colors[0] + '\n' + if "set $in-bgcolor" in line: + data[i] = 'set $in-bgcolor ' + colors[1] + '\n' + if "set $text" in line: + data[i] = 'set $text ' + compliments[0] + '\n' + if "set $indicator" in line: + data[i] = 'set $indicator ' + colors[2] + '\n' + if "set $in-text" in line: + data[i] = 'set $in-text ' + compliments[1] + '\n' + #update background image + if "set $bgimage" in line: + data[i] = 'set $bgimage ' + img_path + '\n' + + if "bindsym $mod+d exec --no-startup-id dmenu_run" in line: + if dmenu: + print('[bold red]Updating Dmenu color scheme') + data[i] = f"bindsym $mod+d exec --no-startup-id dmenu_run -nb '{colors[0]}' -sf '{compliments[0]}' -sb '{colors[1]}' -nf '{compliments[1]}'\n" + # update i3lock image, convert to png so it plays nice w i3lock + if lock: + img = cv.imread(img_path) + imgHeight, imgWidth, _ = img.shape + screenWidth, screenHeight = getScreenResolution() + lock_scale = screenWidth / imgWidth + print('[bold red]Creating lock screen') + dim = (int(imgWidth * lock_scale), int(imgHeight * lock_scale)) + img = cv.resize(img, dim, interpolation= cv.INTER_AREA) + cv.imwrite('lock.png', img) + os.rename('lock.png', Paths['lockscreen'] + 'lock.png') + with open(config_path, 'w') as file: + file.writelines(data) + + print("[bold red]Restarting i3") + os.system("i3 restart") + + +def getScreenResolution(): + output = subprocess.Popen('xrandr | grep "\*" | cut -d" " -f4',shell=True, stdout=subprocess.PIPE).communicate()[0] + resolution = output.split()[0].split(b'x') + width = int(resolution[0].decode('UTF-8')) + height = int(resolution[1].decode('UTF-8')) + return width, height + diff --git a/src/update_polybar.py b/src/update_polybar.py new file mode 100644 index 0000000..ff395c6 --- /dev/null +++ b/src/update_polybar.py @@ -0,0 +1,24 @@ + + +def updatePolybarTheme(config_path: str, colors: list, compliments: list): + print('[bold red]Updating polybar color scheme') + data = '' + with open(config_path, 'r') as file: + data = file.readlines() + for i,line in enumerate(data): + #update colors + if "background =" in line and i == 19: + data[i] = 'background = ' + colors[0] + '\n' + if "background-alt =" in line and i == 20: + data[i] = 'background-alt = ' + colors[1] + '\n' + if "foreground =" in line and i == 21: + data[i] = 'foreground = ' + compliments[0] + '\n' + if "primary =" in line and i == 22: + data[i] = 'primary = ' + compliments[1] + '\n' + if "secondary =" in line and i == 23: + data[i] = 'secondary = ' + compliments[2] + '\n' + if "disabled =" in line and i == 25: + data[i] = 'disabled = ' + colors[2] + '\n' + with open(config_path, 'w') as file: + file.writelines(data) + diff --git a/src/update_rofi.py b/src/update_rofi.py new file mode 100644 index 0000000..a7d3aa6 --- /dev/null +++ b/src/update_rofi.py @@ -0,0 +1,23 @@ +import color_engine + +def updateRofiTheme(config_path: str, colors: list, compliments: list): + print('[bold red]Updating Rofi color scheme') + data = '' + with open(config_path, 'r') as file: + data = file.readlines() + bg = color_engine.hexToRGB(colors[1]) + fg = color_engine.hexToRGB(compliments[1]) + lbg = color_engine.hexToRGB(colors[0]) + lfg = color_engine.hexToRGB(colors[0]) + for i,line in enumerate(data): + if 'background: ' in line and i == 23: + data[i] = ' background: rgba({}, {}, {}, 70%);\n'.format(bg[0], bg[1], bg[2]) + if 'foreground: ' in line and i == 28: + data[i] = ' foreground: rgba({}, {}, {}, 100%);\n'.format(fg[0], fg[1], fg[2]) + if 'lightbg: ' in line and i == 12: + data[i] = ' lightbg: rgba({}, {}, {}, 100%);\n'.format(lbg[0], lbg[1], lgb[2]) + if 'lightfg: ' in line and i == 7: + data[i] = ' lightfg: rgba({}, {}, {}, 100%);\n'.format(lfg[0], lfg[1], lfg[2]) + with open(config_path, 'w') as file: + file.writelines(data) + diff --git a/src/user_interface.py b/src/user_interface.py new file mode 100644 index 0000000..32abf60 --- /dev/null +++ b/src/user_interface.py @@ -0,0 +1,51 @@ +import os +import random +from paths import Paths +import color_engine +from rich import print + + +def colorPickerUI(img_path: str): +#display the selected color scheme and ask user if they like it or want to generate a new color scheme + confirmed = False + while not confirmed: + print() + popularColors = color_engine.grabColors(img_path, 3) + hex_colors = color_engine.rgbToHex(popularColors) + hex_compliments = color_engine.compColors(hex_colors) + + main_colors = '' + complimentary_colors = '' + + for color in hex_colors: + main_colors += f'[on {color}] [/on {color}]' + print(main_colors) + for color in hex_compliments: + complimentary_colors += f'[on {color}] [/on {color}]' + print(complimentary_colors) + print() + count = 0 + for i in range(len(hex_colors)): + print(f'[{hex_compliments[i]} on {hex_colors[i]}]\tGenerated Color Scheme\t\t ({count})') + count += 1 + print('[bold](a)ccept (r)etry') + response = input('> ') + if response == 'r': + continue + else: + confirmed = True + return hex_colors, hex_compliments + +def pickRandomWallpaper(): + confirmed = False + while not confirmed: + wallpaper = Paths['wallpapers'] + random.choice(os.listdir(Paths['wallpapers'])) + os.system(f'viu {wallpaper}') + print(f'picked wallpaper: {wallpaper}') + print('[bold](a)ccept (r)etry') + response = input('>') + + if response == 'a': + confirmed = True + + return wallpaper |
