Initial commit
						commit
						ce9623d1bf
					
				| 
						 | 
					@ -0,0 +1,140 @@
 | 
				
			||||||
 | 
					from PIL import Image, ImageOps, ImageDraw, ImageChops
 | 
				
			||||||
 | 
					from io import BytesIO
 | 
				
			||||||
 | 
					from glob import glob
 | 
				
			||||||
 | 
					import numpy as np
 | 
				
			||||||
 | 
					import base64
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def base64_to_img(base64_bytes: bytes) -> Image:
 | 
				
			||||||
 | 
					    img_bytes = base64.b64decode(base64_bytes)
 | 
				
			||||||
 | 
					    img_buffer = BytesIO(img_bytes)
 | 
				
			||||||
 | 
					    img = Image.open(img_buffer)
 | 
				
			||||||
 | 
					    img = img.convert("RGBA")
 | 
				
			||||||
 | 
					    return img
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def img_to_array(img: Image) -> np.array:
 | 
				
			||||||
 | 
					    img_array = np.array(img)
 | 
				
			||||||
 | 
					    return img_array
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _avg_colors(img: Image) -> tuple:
 | 
				
			||||||
 | 
					    img_array = img_to_array(img)
 | 
				
			||||||
 | 
					    avg_colors = np.mean(img_array, axis=tuple(range(img_array.ndim - 1)))
 | 
				
			||||||
 | 
					    avg_list = list(map(int, avg_colors))
 | 
				
			||||||
 | 
					    avg_list[3] = 255
 | 
				
			||||||
 | 
					    return tuple(avg_list)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def __avg_colors(pil_img):
 | 
				
			||||||
 | 
					    img = pil_img.copy()
 | 
				
			||||||
 | 
					    img.convert("RGB")
 | 
				
			||||||
 | 
					    img.resize((1, 2), resample=0)
 | 
				
			||||||
 | 
					    dominant_color = img.getpixel((0, 0))
 | 
				
			||||||
 | 
					    print(img.getpixel((0, 1)))
 | 
				
			||||||
 | 
					    return dominant_color
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def avg_colors(img):
 | 
				
			||||||
 | 
					    img_array = img_to_array(img)
 | 
				
			||||||
 | 
					    colors, count = np.unique(img_array.reshape(-1,img_array.shape[-1]), axis=0, return_counts=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return tuple(colors[count.argmax()])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def add_background(img: Image, bg_tuple: tuple) -> Image:
 | 
				
			||||||
 | 
					    bg = Image.new("RGBA", img.size, bg_tuple)
 | 
				
			||||||
 | 
					    bg.paste(img, (0, 0), img)
 | 
				
			||||||
 | 
					    return bg
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def crop_to_circle(im, template):
 | 
				
			||||||
 | 
					    im = im.copy()
 | 
				
			||||||
 | 
					    bigsize = (im.size[0] * 3, im.size[1] * 3)
 | 
				
			||||||
 | 
					    mask = Image.new('L', bigsize, 0)
 | 
				
			||||||
 | 
					    ImageDraw.Draw(mask).ellipse((0, 0) + bigsize, fill=255)
 | 
				
			||||||
 | 
					    midsize = tuple(x//2 for x in bigsize)
 | 
				
			||||||
 | 
					    if template[0] == 1:
 | 
				
			||||||
 | 
					        ImageDraw.Draw(mask).rectangle((0, 0) + midsize, fill=255)
 | 
				
			||||||
 | 
					    if template[1] == 1:
 | 
				
			||||||
 | 
					        ImageDraw.Draw(mask).rectangle((midsize[0], 0, bigsize[0], midsize[1]), fill=255)
 | 
				
			||||||
 | 
					    if template[2] == 1:
 | 
				
			||||||
 | 
					        ImageDraw.Draw(mask).rectangle((0, midsize[1], midsize[1], bigsize[1]), fill=255)
 | 
				
			||||||
 | 
					    if template[3] == 1:
 | 
				
			||||||
 | 
					        ImageDraw.Draw(mask).rectangle(midsize + bigsize, fill=255)
 | 
				
			||||||
 | 
					    mask = mask.resize(im.size, Image.ANTIALIAS)
 | 
				
			||||||
 | 
					    mask = ImageChops.darker(mask, im.split()[-1])
 | 
				
			||||||
 | 
					    im.putalpha(mask)
 | 
				
			||||||
 | 
					    return im
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def parse_file(desktop_path):
 | 
				
			||||||
 | 
					    output = {}
 | 
				
			||||||
 | 
					    with open(desktop_path, "r") as f:
 | 
				
			||||||
 | 
					        for line in f:
 | 
				
			||||||
 | 
					            if not line:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            if line.startswith("["):
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            key, value = line.split("=", 1)
 | 
				
			||||||
 | 
					            output[key] = value.strip()
 | 
				
			||||||
 | 
					    output["path"] = desktop_path
 | 
				
			||||||
 | 
					    return output
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def deparse_file(app):
 | 
				
			||||||
 | 
					    output = ["[Desktop Entry]"]
 | 
				
			||||||
 | 
					    for key, value in app.items():
 | 
				
			||||||
 | 
					        output.append(f"{key}={value}")
 | 
				
			||||||
 | 
					    return "\n".join(output)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_web_icons():
 | 
				
			||||||
 | 
					    path = os.path.join(
 | 
				
			||||||
 | 
					        os.path.expanduser("~"),
 | 
				
			||||||
 | 
					        ".local",
 | 
				
			||||||
 | 
					        "share",
 | 
				
			||||||
 | 
					        "applications",
 | 
				
			||||||
 | 
					        "sailfish-browser*.desktop"
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    return glob(path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def sailify(raw_str, pattern):
 | 
				
			||||||
 | 
					    base64_bytes = raw_str.replace("data:image/png;base64,", "", 1).encode()
 | 
				
			||||||
 | 
					    img = base64_to_img(base64_bytes)
 | 
				
			||||||
 | 
					    bg_tuple = avg_colors(img)
 | 
				
			||||||
 | 
					    img = add_background(img, bg_tuple)
 | 
				
			||||||
 | 
					    img = crop_to_circle(img, pattern)
 | 
				
			||||||
 | 
					    output_buffer = BytesIO()
 | 
				
			||||||
 | 
					    img.save(output_buffer, format="PNG")
 | 
				
			||||||
 | 
					    output_data = output_buffer.getvalue()
 | 
				
			||||||
 | 
					    output_base64 = base64.b64encode(output_data)
 | 
				
			||||||
 | 
					    return "data:image/png;base64," + output_base64.decode()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def main():
 | 
				
			||||||
 | 
					    import shutil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while True:
 | 
				
			||||||
 | 
					        apps = get_web_icons()
 | 
				
			||||||
 | 
					        apps = list(map(parse_file, apps))
 | 
				
			||||||
 | 
					        while True:
 | 
				
			||||||
 | 
					            for n, app in enumerate(apps):
 | 
				
			||||||
 | 
					                print(f"{n}) {app['Name']}")
 | 
				
			||||||
 | 
					            index = input("select an application (the index):\n>>> ")
 | 
				
			||||||
 | 
					            index = int(index)
 | 
				
			||||||
 | 
					            if index >= len(apps):
 | 
				
			||||||
 | 
					                print("Select a valid index")
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            break
 | 
				
			||||||
 | 
					        app = apps[index]
 | 
				
			||||||
 | 
					        while True:
 | 
				
			||||||
 | 
					            pattern = input("Enter the pattern (0 = round, 1 = peak):\n>>> ")
 | 
				
			||||||
 | 
					            if len(pattern) != 4:
 | 
				
			||||||
 | 
					                print("it is necessary to enter 4 characters")
 | 
				
			||||||
 | 
					            pattern = tuple(map(int, pattern))
 | 
				
			||||||
 | 
					            new_icon = sailify(app.get("old_icon", app["Icon"]), pattern)
 | 
				
			||||||
 | 
					            # Backup the original .desktop
 | 
				
			||||||
 | 
					            shutil.copyfile(app["path"], app["path"] + "_backup")
 | 
				
			||||||
 | 
					            app["old_icon"] = app.get("old_icon", app["Icon"])
 | 
				
			||||||
 | 
					            app["Icon"] = new_icon
 | 
				
			||||||
 | 
					            new_content = deparse_file(app)
 | 
				
			||||||
 | 
					            with open(app["path"], "w") as f:
 | 
				
			||||||
 | 
					                f.write(new_content)
 | 
				
			||||||
 | 
					            print(f"{app['Name']} sailified correctly")
 | 
				
			||||||
 | 
					            break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 | 
					    main()
 | 
				
			||||||
		Loading…
	
		Reference in New Issue