#!/usr/bin/env bash # # A script to create Telegram palettes that use colors generated by pywal/wal # or from a different file containing the hex colors (see the README.md for the # format of the file). # Help function called by the --help|-h parameter. set -E trap '[ "$?" -ne 77 ] || exit 77' ERR help() { cat <] [-d|--destination=] [-g|--gaussian-blur=] [-r|--restart] $0 -p | --palette= [-t|--tiled] [-b|--background=] [-d|--destination=] [-g|--gaussian-blur=] [-r|--restart] $0 -h | --help Options: -h Show command usage. --help Show this help screen. -w --wal Generate the color palette using the colors generated by pywal/wal (Default). -p --palette Use colors from an sh file to generate the color palette. -t --tiled Use a unified color background instead of an image. -b --background Use a specific image as background. -d --destination Specify a destination folder for the generated palette. (Default: ~/.cache/wal-telegram) -g --gaussian-blur Blur the background image, takes a blur argument. see https://legacy.imagemagick.org/Usage/blur/#blur_args. -g takes no argument and uses the default value. (Default: 0x16) -r --restart Restart the telegram app after generation. EOF } usage() { cat <] [--destination=] [-g|--gaussian-blur=] [-r|--restart] $0 --palette= [--tiled] [--background=] [--destination=] [-g|--gaussian-blur=] [-r|--restart] EOF } exit_abnormal(){ usage exit 1 } script_dir=$(readlink -f ${0} | sed "s#/$(basename ${0})##") # shellcheck source=/dev/null command -v zip > /dev/null || (printf '%b\n' "\\e[1;31m::\\e[0m \\e[1;37mA zipping utility is needed for this script, consider installing zip or gzip\\e[0m" && exit 77) options=$(getopt -o hwtp:b:d:gr --long help,wal,tiled,palette:,background:,destination:,gaussian-blur:,restart -- "$@") if [ $? != 0 ] ; then exit_abnormal; fi eval set -- "$options" while true; do case "$1" in -h) usage; exit 0 ;; --help) help; exit 0 ;; -w | --wal ) if [[ "$mode" == 'palette' ]]; then printf '%b\n\n' "\\e[1;31m::\\e[0m \\e[1;37mCannot use wal and palette together.\\e[0m" exit_abnormal fi if [[ ! -d "${XDG_CACHE_HOME:-${HOME}/.cache}/wal" ]]; then printf '%b\n\n' "\\e[1;31m::\\e[0m \\e[1;37mWal must be run before running wal-telegram.\\e[0m" exit_abnormal fi mode='wal' shift ;; -t | --tiled ) bg_mode="tiled" shift ;; -p | --palette ) if [[ "$mode" == 'wal' ]]; then printf '%b\n\n' "\\e[1;31m::\\e[0m \\e[1;37mCannot use wal and palette together.\\e[0m" exit_abnormal fi if [[ ! -f "$2" ]]; then printf '%b\n\n' "\\e[1;31m::\\e[0m \\e[1;37mPalette file '$2' could not be found.\\e[0m" exit_abnormal fi mode='palette' palette_file=$2 shift 2 ;; -b | --background ) if [[ ! -f "$2" ]]; then printf '%b\n\n' "\\e[1;31m::\\e[0m \\e[1;37mBackground file '$2' could not be found.\\e[0m" exit_abnormal fi bg="$2" shift 2 ;; -d | --destination ) if (mkdir -p "$2" 2> /dev/null); then dest="$2" else printf '%b\n\n' "\\e[1;31m::\\e[0m \\e[1;37mCould not create '$2' verify the permissions in it's parent directory and retry.\\e[0m" exit_abnormal fi shift 2 ;; -g) if [ -n "$blur" ]; then printf '%b\n\n' "\\e[1;31m::\\e[0m \\e[1;37mDo not set -g and --gaussian-blur together.\\e[0m" exit_abnormal fi blur="0x16" shift ;; --gaussian-blur ) if [ -n "$blur" ]; then printf '%b\n\n' "\\e[1;31m::\\e[0m \\e[1;37mDo not set -g and --gaussian-blur together.\\e[0m" exit_abnormal fi if [ -z "$2" ] || [ "$(expr "$2" : '^[[:digit:]]\+x[[:digit:]]\+$')" -eq 0 ]; then printf '%b\n\n' "\\e[1;31m::\\e[0m \\e[1;37mBlur option not recognized, see https://legacy.imagemagick.org/Usage/blur/#blur_args for reference.\\e[0m" exit_abnormal fi blur="$2" shift 2 ;; -r | --restart ) restart_on_gen=true shift ;; -- ) shift; break ;; * ) break ;; esac done # default values [ -z "$mode" ] && mode='wal' [ -z "$bg_mode" ] && bg_mode='background' [ -z "$bg" ] && bg='wal' # source this here in case wal is not an option if [[ "$mode" == 'wal' ]]; then . "${XDG_CACHE_HOME:-${HOME}/.cache}/wal/colors.sh" else . "$palette_file" fi if [[ "$bg_mode" == 'tiled' ]] && [[ "$bg" != 'wal' ]]; then printf '%b\n' "\\e[1;31m::\\e[0m \\e[1;37mBackground option while using tiled mode is useless.\\e[0m" fi # Prepare the conditions for the other functions. prepare() { pre="/tmp/wal-telegram/$(date +%s)" [ -z "$dest" ] && dest="${XDG_CACHE_HOME:-${HOME}/.cache}/wal-telegram" mkdir -p "$pre" mkdir -p "$dest" rm -f "${dest}/${mode}.tdesktop-theme" if [[ "$bg" == "wal" ]]; then # if no background is specified if [[ "$mode" == wal ]] && [[ "$bg_mode" == "background" ]]; then # wal mode without tiled bg_path="$(<"${XDG_CACHE_HOME:-${HOME}/.cache}/wal/wal")" bg_ext="${bg_path##*.}" cp "$bg_path" "${pre}/background.${bg_ext}" elif [[ "$mode" == "palette" ]] && [[ "$bg_mode" == "background" ]]; then if [[ -f "${HOME}/.fehbg" ]]; then bg_path="$(tail -n1 "${HOME}/.fehbg" \ | sed "s/[^']*//" \ | awk '{print $1}' \ | sed "s/'//g")" bg_ext="${bg_path##*.}" if [[ -f "$bg_path" ]]; then cp "$bg_path" "${pre}/background.${bg_ext}" fi else # if .fehbg exists printf '%b\n' "\\e[1;31m::\\e[0m \\e[1;37m~/.fehbg not found, falling back to tiled background.\\e[0m" bg="tiled" fi # if .fehbg exists fi # elif mode == palette else # if bg == wal bg_ext="${bg##*.}" cp "$bg" "${pre}/background.${bg_ext}" fi # if bg == wal } # Lighten/darken by 20%, 30%, 40%, 50%, 60% some colors using only pure bash. create_colors() { colors=(0 1 2 7) for i in "${colors[@]}"; do color="color${i}" c_rgb_12d="$(( 0x"${!color:1:2}" ))" c_rgb_34d="$(( 0x"${!color:3:2}" ))" c_rgb_56d="$(( 0x"${!color:5:2}" ))" c_rgb_12d_20l="$(( c_rgb_12d + "$((c_rgb_12d / 5))" ))" c_rgb_34d_20l="$(( c_rgb_34d + "$((c_rgb_34d / 5))" ))" c_rgb_56d_20l="$(( c_rgb_56d + "$((c_rgb_56d / 5))" ))" [[ "${c_rgb_12d_20l}" -ge 255 ]] && c_rgb_12d_20l=255 [[ "${c_rgb_34d_20l}" -ge 255 ]] && c_rgb_34d_20l=255 [[ "${c_rgb_56d_20l}" -ge 255 ]] && c_rgb_56d_20l=255 printf -v c_hex_12d_20l '%x' "$c_rgb_12d_20l" printf -v c_hex_34d_20l '%x' "$c_rgb_34d_20l" printf -v c_hex_56d_20l '%x' "$c_rgb_56d_20l" [[ "${#c_hex_12d_20l}" -eq 1 ]] && c_hex_12d_20l="0${c_hex_12d_20l}" [[ "${#c_hex_34d_20l}" -eq 1 ]] && c_hex_34d_20l="0${c_hex_34d_20l}" [[ "${#c_hex_56d_20l}" -eq 1 ]] && c_hex_56d_20l="0${c_hex_56d_20l}" c_hex_20l="#${c_hex_12d_20l}${c_hex_34d_20l}${c_hex_56d_20l}" declare -g color"${i}"_lighter_20="$c_hex_20l" c_rgb_12d_30l="$(( c_rgb_12d + "$((c_rgb_12d * 3 / 10))" ))" c_rgb_34d_30l="$(( c_rgb_34d + "$((c_rgb_34d * 3 / 10))" ))" c_rgb_56d_30l="$(( c_rgb_56d + "$((c_rgb_56d * 3 / 10))" ))" [[ "${c_rgb_12d_30l}" -ge 255 ]] && c_rgb_12d_30l=255 [[ "${c_rgb_34d_30l}" -ge 255 ]] && c_rgb_34d_30l=255 [[ "${c_rgb_56d_30l}" -ge 255 ]] && c_rgb_56d_30l=255 printf -v c_hex_12d_30l '%x' "$c_rgb_12d_30l" printf -v c_hex_34d_30l '%x' "$c_rgb_34d_30l" printf -v c_hex_56d_30l '%x' "$c_rgb_56d_30l" [[ "${#c_hex_12d_30l}" -eq 1 ]] && c_hex_12d_30l="0${c_hex_12d_30l}" [[ "${#c_hex_34d_30l}" -eq 1 ]] && c_hex_34d_30l="0${c_hex_34d_30l}" [[ "${#c_hex_56d_30l}" -eq 1 ]] && c_hex_56d_30l="0${c_hex_56d_30l}" c_hex_30l="#${c_hex_12d_30l}${c_hex_34d_30l}${c_hex_56d_30l}" declare -g color"${i}"_lighter_30="$c_hex_30l" c_rgb_12d_40l="$(( c_rgb_12d + "$((c_rgb_12d * 2 / 5))" ))" c_rgb_34d_40l="$(( c_rgb_34d + "$((c_rgb_34d * 2 / 5))" ))" c_rgb_56d_40l="$(( c_rgb_56d + "$((c_rgb_56d * 2 / 5))" ))" [[ "${c_rgb_12d_40l}" -ge 255 ]] && c_rgb_12d_40l=255 [[ "${c_rgb_34d_40l}" -ge 255 ]] && c_rgb_34d_40l=255 [[ "${c_rgb_56d_40l}" -ge 255 ]] && c_rgb_56d_40l=255 printf -v c_hex_12d_40l '%x' "$c_rgb_12d_40l" printf -v c_hex_34d_40l '%x' "$c_rgb_34d_40l" printf -v c_hex_56d_40l '%x' "$c_rgb_56d_40l" [[ "${#c_hex_12d_40l}" -eq 1 ]] && c_hex_12d_40l="0${c_hex_12d_40l}" [[ "${#c_hex_34d_40l}" -eq 1 ]] && c_hex_34d_40l="0${c_hex_34d_40l}" [[ "${#c_hex_56d_40l}" -eq 1 ]] && c_hex_56d_40l="0${c_hex_56d_40l}" c_hex_40l="#${c_hex_12d_40l}${c_hex_34d_40l}${c_hex_56d_40l}" declare -g color"${i}"_lighter_40="$c_hex_40l" c_rgb_12d_50l="$(( c_rgb_12d + "$((c_rgb_12d / 2))" ))" c_rgb_34d_50l="$(( c_rgb_34d + "$((c_rgb_34d / 2))" ))" c_rgb_56d_50l="$(( c_rgb_56d + "$((c_rgb_56d / 2))" ))" [[ "${c_rgb_12d_50l}" -ge 255 ]] && c_rgb_12d_50l=255 [[ "${c_rgb_34d_50l}" -ge 255 ]] && c_rgb_34d_50l=255 [[ "${c_rgb_56d_50l}" -ge 255 ]] && c_rgb_56d_50l=255 printf -v c_hex_12d_50l '%x' "$c_rgb_12d_50l" printf -v c_hex_34d_50l '%x' "$c_rgb_34d_50l" printf -v c_hex_56d_50l '%x' "$c_rgb_56d_50l" [[ "${#c_hex_12d_50l}" -eq 1 ]] && c_hex_12d_50l="0${c_hex_12d_50l}" [[ "${#c_hex_34d_50l}" -eq 1 ]] && c_hex_34d_50l="0${c_hex_34d_50l}" [[ "${#c_hex_56d_50l}" -eq 1 ]] && c_hex_56d_50l="0${c_hex_56d_50l}" c_hex_50l="#${c_hex_12d_50l}${c_hex_34d_50l}${c_hex_56d_50l}" declare -g color"${i}"_lighter_50="$c_hex_50l" c_rgb_12d_60l="$(( c_rgb_12d + "$((c_rgb_12d * 3 / 5))" ))" c_rgb_34d_60l="$(( c_rgb_34d + "$((c_rgb_34d * 3 / 5))" ))" c_rgb_56d_60l="$(( c_rgb_56d + "$((c_rgb_56d * 3 / 5))" ))" [[ "${c_rgb_12d_60l}" -ge 255 ]] && c_rgb_12d_60l=255 [[ "${c_rgb_34d_60l}" -ge 255 ]] && c_rgb_34d_60l=255 [[ "${c_rgb_56d_60l}" -ge 255 ]] && c_rgb_56d_60l=255 printf -v c_hex_12d_60l '%x' "$c_rgb_12d_60l" printf -v c_hex_34d_60l '%x' "$c_rgb_34d_60l" printf -v c_hex_56d_60l '%x' "$c_rgb_56d_60l" [[ "${#c_hex_12d_60l}" -eq 1 ]] && c_hex_12d_60l="0${c_hex_12d_60l}" [[ "${#c_hex_34d_60l}" -eq 1 ]] && c_hex_34d_60l="0${c_hex_34d_60l}" [[ "${#c_hex_56d_60l}" -eq 1 ]] && c_hex_56d_60l="0${c_hex_56d_60l}" c_hex_60l="#${c_hex_12d_60l}${c_hex_34d_60l}${c_hex_56d_60l}" declare -g color"${i}"_lighter_60="$c_hex_60l" c_rgb_12d_20d="$(( c_rgb_12d - "$((c_rgb_12d / 5))" ))" c_rgb_34d_20d="$(( c_rgb_34d - "$((c_rgb_34d / 5))" ))" c_rgb_56d_20d="$(( c_rgb_56d - "$((c_rgb_56d / 5))" ))" printf -v c_hex_12d_20d '%x' "$c_rgb_12d_20d" printf -v c_hex_34d_20d '%x' "$c_rgb_34d_20d" printf -v c_hex_56d_20d '%x' "$c_rgb_56d_20d" [[ "${#c_hex_12d_20d}" -eq 1 ]] && c_hex_12d_20d="0${c_hex_12d_20d}" [[ "${#c_hex_34d_20d}" -eq 1 ]] && c_hex_34d_20d="0${c_hex_34d_20d}" [[ "${#c_hex_56d_20d}" -eq 1 ]] && c_hex_56d_20d="0${c_hex_56d_20d}" c_hex_20d="#${c_hex_12d_20d}${c_hex_34d_20d}${c_hex_56d_20d}" declare -g color"${i}"_darker_20="$c_hex_20d" c_rgb_12d_30d="$(( c_rgb_12d - "$((c_rgb_12d * 3 / 10))" ))" c_rgb_34d_30d="$(( c_rgb_34d - "$((c_rgb_34d * 3 / 10))" ))" c_rgb_56d_30d="$(( c_rgb_56d - "$((c_rgb_56d * 3 / 10))" ))" printf -v c_hex_12d_30d '%x' "$c_rgb_12d_30d" printf -v c_hex_34d_30d '%x' "$c_rgb_34d_30d" printf -v c_hex_56d_30d '%x' "$c_rgb_56d_30d" [[ "${#c_hex_12d_30d}" -eq 1 ]] && c_hex_12d_30d="0${c_hex_12d_30d}" [[ "${#c_hex_34d_30d}" -eq 1 ]] && c_hex_34d_30d="0${c_hex_34d_30d}" [[ "${#c_hex_56d_30d}" -eq 1 ]] && c_hex_56d_30d="0${c_hex_56d_30d}" c_hex_30d="#${c_hex_12d_30d}${c_hex_34d_30d}${c_hex_56d_30d}" declare -g color"${i}"_darker_30="$c_hex_30d" c_rgb_12d_40d="$(( c_rgb_12d - "$((c_rgb_12d * 2 / 5))" ))" c_rgb_34d_40d="$(( c_rgb_34d - "$((c_rgb_34d * 2 / 5))" ))" c_rgb_56d_40d="$(( c_rgb_56d - "$((c_rgb_56d * 2 / 5))" ))" printf -v c_hex_12d_40d '%x' "$c_rgb_12d_40d" printf -v c_hex_34d_40d '%x' "$c_rgb_34d_40d" printf -v c_hex_56d_40d '%x' "$c_rgb_56d_40d" [[ "${#c_hex_12d_40d}" -eq 1 ]] && c_hex_12d_40d="0${c_hex_12d_40d}" [[ "${#c_hex_34d_40d}" -eq 1 ]] && c_hex_34d_40d="0${c_hex_34d_40d}" [[ "${#c_hex_56d_40d}" -eq 1 ]] && c_hex_56d_40d="0${c_hex_56d_40d}" c_hex_40d="#${c_hex_12d_40d}${c_hex_34d_40d}${c_hex_56d_40d}" declare -g color"${i}"_darker_40="$c_hex_40d" c_rgb_12d_50d="$(( c_rgb_12d - "$((c_rgb_12d / 2))" ))" c_rgb_34d_50d="$(( c_rgb_34d - "$((c_rgb_34d / 2))" ))" c_rgb_56d_50d="$(( c_rgb_56d - "$((c_rgb_56d / 2))" ))" printf -v c_hex_12d_50d '%x' "$c_rgb_12d_50d" printf -v c_hex_34d_50d '%x' "$c_rgb_34d_50d" printf -v c_hex_56d_50d '%x' "$c_rgb_56d_50d" [[ "${#c_hex_12d_50d}" -eq 1 ]] && c_hex_12d_50d="0${c_hex_12d_50d}" [[ "${#c_hex_34d_50d}" -eq 1 ]] && c_hex_34d_50d="0${c_hex_34d_50d}" [[ "${#c_hex_56d_50d}" -eq 1 ]] && c_hex_56d_50d="0${c_hex_56d_50d}" c_hex_50d="#${c_hex_12d_50d}${c_hex_34d_50d}${c_hex_56d_50d}" declare -g color"${i}"_darker_50="$c_hex_50d" c_rgb_12d_60d="$(( c_rgb_12d - "$((c_rgb_12d * 3 / 5))" ))" c_rgb_34d_60d="$(( c_rgb_34d - "$((c_rgb_34d * 3 / 5))" ))" c_rgb_56d_60d="$(( c_rgb_56d - "$((c_rgb_56d * 3 / 5))" ))" printf -v c_hex_12d_60d '%x' "$c_rgb_12d_60d" printf -v c_hex_34d_60d '%x' "$c_rgb_34d_60d" printf -v c_hex_56d_60d '%x' "$c_rgb_56d_60d" [[ "${#c_hex_12d_60d}" -eq 1 ]] && c_hex_12d_60d="0${c_hex_12d_60d}" [[ "${#c_hex_34d_60d}" -eq 1 ]] && c_hex_34d_60d="0${c_hex_34d_60d}" [[ "${#c_hex_56d_60d}" -eq 1 ]] && c_hex_56d_60d="0${c_hex_56d_60d}" c_hex_60d="#${c_hex_12d_60d}${c_hex_34d_60d}${c_hex_56d_60d}" declare -g color"${i}"_darker_60="$c_hex_60d" done } # Create colors.tdesktop-palette using the colors generated by create_colors() # and the colors.wt-constants file. create_palette() { cat < "${pre}/colors.tdesktop-theme" // Colors imported by wal-telegram. color0: $color0; color1: $color1; color2: $color2; color3: $color3; color4: $color4; color5: $color5; color6: $color6; color7: $color7; color8: $color8; // Lighter and darker variants of the colors. colorLighter0_20: $color0_lighter_20; colorLighter0_30: $color0_lighter_30; colorLighter0_40: $color0_lighter_40; colorLighter0_50: $color0_lighter_50; colorLighter0_60: $color0_lighter_60; colorDarker0_20: $color0_darker_20; colorDarker0_30: $color0_darker_30; colorDarker0_40: $color0_darker_40; colorDarker0_50: $color0_darker_50; colorDarker0_60: $color0_darker_60; colorLighter1_20: $color1_lighter_20; colorLighter1_30: $color1_lighter_30; colorLighter1_40: $color1_lighter_40; colorLighter1_50: $color1_lighter_50; colorLighter1_60: $color1_lighter_60; colorDarker1_20: $color1_darker_20; colorDarker1_30: $color1_darker_30; colorDarker1_40: $color1_darker_40; colorDarker1_50: $color1_darker_50; colorDarker1_60: $color1_darker_60; colorLighter2_20: $color2_lighter_20; colorLighter2_30: $color2_lighter_30; colorLighter2_40: $color2_lighter_40; colorLighter2_50: $color2_lighter_50; colorLighter2_60: $color2_lighter_60; colorDarker2_20: $color2_darker_20; colorDarker2_30: $color2_darker_30; colorDarker2_40: $color2_darker_40; colorDarker2_50: $color2_darker_50; colorDarker2_60: $color2_darker_60; colorLighter7_20: $color7_lighter_20; colorLighter7_30: $color7_lighter_30; colorLighter7_40: $color7_lighter_40; colorLighter7_50: $color7_lighter_50; colorLighter7_60: $color7_lighter_60; colorDarker7_20: $color7_darker_20; colorDarker7_30: $color7_darker_30; colorDarker7_40: $color7_darker_40; colorDarker7_50: $color7_darker_50; colorDarker7_60: $color7_darker_60; // Alpha colors. colorAlpha0_18: ${color0}18; colorAlpha0_3c: ${color0}3c; colorAlpha0_03: ${color0}03; colorAlpha0_7f: ${color0}7f; colorAlpha0_b0: ${color0}b0; colorAlpha0_cc: ${color0}cc; colorAlpha0_00: ${color0}00; colorAlpha0_54: ${color0}54; colorAlpha0_56: ${color0}56; colorAlpha0_74: ${color0}74; colorAlpha0_40: ${color0}40; colorAlpha0_4c: ${color0}4c; colorAlpha0_b2: ${color0}b2; colorAlpha0_f2: ${color0}f2; colorAlpha0_66: ${color0}66; colorAlpha1_10: ${color1}10; colorAlpha1_33: ${color1}33; colorAlpha2_c8: ${color2}c8; colorAlpha2_4c: ${color2}4c; colorAlpha2_7f: ${color2}7f; colorAlpha2_00: ${color2}00; colorAlpha2_87: ${color2}87; colorAlpha3_64: ${color3}64; colorAlpha7_53: ${color7}53; colorAlpha7_7a: ${color7}7a; colorAlpha7_1a: ${color7}1a; colorAlpha7_2c: ${color7}2c; colorAlpha7_7f: ${color7}7f; colorAlpha7_bc: ${color7}bc; colorAlpha7_4c: ${color7}4c; colorAlpha7_6b: ${color7}6b; colorAlpha7_14: ${color7}14; EOF const="$(<"$script_dir/colors.wt-constants")" printf '%s' "$const" >> "${pre}/colors.tdesktop-theme" cd "${pre}" || exit 1; if [[ -z $bg_ext ]]; then bg_ext="png"; fi if [[ -n $blur ]]; then blur="-blur $blur"; fi if [[ "$bg_mode" = "tiled" ]]; then convert -size 256x256 "xc:$color0" tiled.png; elif [[ "$bg_mode" = "background" ]]; then size=$(magick identify -format "%w" ${bg_mode}.${bg_ext}) # shellcheck disable=SC2086 convert ${bg_mode}.${bg_ext} $blur -resize $(( size > 1920 ? size : 1920 )) ${bg_mode}.png fi zip -q ${mode}.tdesktop-theme colors.tdesktop-theme ${bg_mode}.png cp ${mode}.tdesktop-theme "$dest" [ -n "$restart_on_gen" ] && pkill -f telegram-desktop && telegram-desktop & } main() { prepare && create_colors && create_palette && printf '%b\n' "\\e[1;31m::\\e[0m \\e[1;37mPalette generated succesfully.\\e[0m" } main