diff --git a/backup_home.sh b/backup_home.sh new file mode 100755 index 0000000..0e62d40 --- /dev/null +++ b/backup_home.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# +# Ferit Yiğit BALABAN , 2022 +# +echo "Hello, $( whoami )" +echo "w/o Downloads: $( du -sh --exclude='Downloads' "$HOME" )" +echo "wth Downloads: $( du -sh "$HOME" )" +doas tar --exclude="$HOME/Downloads" --exclude="$HOME/.local/share/JetBrains" --exclude="$HOME/.cache/pip" --exclude="$HOME/.cache/yay" --exclude="$HOME/.cache/JetBrains" --exclude="$HOME/.nuget" --create --verbose --preserve-permissions --gzip --file "/home/ferit-$( date +'%y%m%d' ).tar.gz" /home/ferit diff --git a/cdd.bash b/cdd.bash new file mode 100755 index 0000000..7627138 --- /dev/null +++ b/cdd.bash @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# +# Ferit Yiğit BALABAN, +# +# cd on steroids for Johnny.Decimal directories + +# Define the cdd function +cdd() { + local input="$1" + local folder="$(basename "$PWD")" + + if [[ "$input" =~ ^[0-9]{3}\.[0-9]{2}$ ]]; then + cd "$HOME/shoka/*/*/$input *" + elif [[ "$input" =~ ^[0-9]{3}$ ]]; then + cd "$HOME/shoka/*/$input *" + elif [[ "$input" =~ ^[0-9]{2}$ && "$folder" =~ ^[0-9]{3} ]]; then + cd "$HOME/shoka/*/*/${folder:0:3}.$input *" + else + echo "Invalid input: $input" + fi +} + +# Use the cdd function with the input argument +cdd "$1" diff --git a/deprecated/unison_sync.sh b/deprecated/unison_sync.sh new file mode 100755 index 0000000..a72b3f5 --- /dev/null +++ b/deprecated/unison_sync.sh @@ -0,0 +1,32 @@ +#!/bin/bash +# +# Ferit Yiğit BALABAN , 2023 +# & ChatGPT +# + +LOCAL_DIR="$HOME/mounts/31_shoka" +REMOTE_DIR="ssh://fyb@192.168.0.3//mnt/shoka" +LOG_FILE="$HOME/navi.log" +UNISON="/usr/bin/unison" + +# Run Unison to synchronize the directories +$UNISON $LOCAL_DIR $REMOTE_DIR -batch -auto -confirmbigdel > /dev/null 2>&1 + +# Check the exit code of Unison +if [ $? -eq 0 ]; then + # Synchronization was successful, log the message and exit + echo "$(date -Iseconds) INFO: unison, sync successful" >> $LOG_FILE + exit 0 +else + # Synchronization failed, check if there were conflicts + CONFLICTS=`grep "Conflicting file" /var/log/unison.log | wc -l` + if [ $CONFLICTS -eq 0 ]; then + # There were no conflicts, log the message and exit + echo "$(date -Iseconds) INFO: unison, no diff" >> $LOG_FILE + exit 0 + else + # There were conflicts, log the message and exit with an error code + echo "$(date -Iseconds) ERROR: unison, sync conflict" >> $LOG_FILE + exit 1 + fi +fi diff --git a/dotman.py b/dotman.py index 0a8c6cd..f326563 100755 --- a/dotman.py +++ b/dotman.py @@ -1,33 +1,31 @@ #!/usr/bin/env python3 # -# Ferit Yiğit BALABAN , 2022 +# Ferit Yiğit BALABAN , 2023 # -import os.path +import os +import shlex from subprocess import run import sys -from datetime import datetime as dt -from termcolor import colored, cprint # Modify SETTINGS dictionary to set runtime variables # Access values in dictionary using pre-defined names SETTINGS = { - 'DOTFILES_REPOSITORY': '$HOME/repos/dotfiles', - 'REMOTE_REPOSITORY': 'https://github.com/fybx/dotfiles', - 'LOCAL_CONFIG': '$HOME/.config', - 'SETUP_FILE': 'same-directory' + 'URL_REPO': 'https://github.com/fybx/dotfiles', # remote repository URL + 'SHN_REPO': 'fybx/dotfiles', # remote shortname + 'DIR_REPO': '$HOME/shoka/300-399 repos/dotfiles', # local repository directory + 'DIR_CONF': '$HOME/.config', # local .config directory + 'F_DEPLOY': '$HOME/.config/dotman/deploy_list.json', # path to deploy_list.json file } -WHEREAMI = '$HOME/scripts' -VER = 'v1.7' -WER = 'v1.1' + +VER = 'v1.8' help_message = f''' -dotman {VER} dotfiles manager by fyb +dotman {VER} dotfiles manager by ferityigitbalaban Unrecognized keys are ignored. If every key supplied is unrecognized, this have the same effect as calling dotman without any key. Keys: -i, --interactive Interactively backup or deploy dotfiles. Not supplying any key will result in interactive mode. --s, --setup-dotman Interactively set variables (DOTFILES_REPOSITORY, LOCAL_CONFIG, etc.) for your dotman setup. -b, --backup Backup your dotfiles. Doesn't require user assistance but errors may occur. -d, --deploy Deploy your dotfiles. Doesn't require user assistance but errors may occur. -v, --version Shows the version and quits @@ -35,138 +33,100 @@ Keys: ''' -def get_nth_key(n: int, d: dict[str, str]): - c = 0 - for k in d.keys(): - if n == c: - return k - c += 1 +DL_FILES = [] +DL_DIRS = [] -def read_file(path: str): - with open(path, 'r') as f: - content = f.readlines() - f.close() - return content - - -def read_setup(): - path = SETTINGS['SETUP_FILE'] - lines = read_file(f'{WHEREAMI}setup.dtm') if path == 'same-directory' else read_file(os.path.expandvars(path)) - lines = [line.strip() for line in lines if not line.startswith('#') and line.replace(' ', '') != ''] - for line in lines: - key = line.split(':', 1)[0].rstrip() - value = line.split(':', 1)[1].lstrip() - SETTINGS[key] = value - - -def write_setup(): - path = f'{WHEREAMI}setup.dtm' if SETTINGS['SETUP_FILE'] == 'same-directory' else os.path.expandvars(SETTINGS['SETUP_FILE']) - - -def rrem(text: str, char: str): +def read_deploy_list(): """ - Remove characters from right until character supplied with char - :param text: Where to remove characters from - :param char: Which character to stop removing at - :return: Returns text with all characters until specified character removed + Reads file from SETTINGS.F_DEPLOY to get list of directories and files to deploy """ - iterator = len(text) - 1 - buffer = '' - while text[iterator] != char: - buffer += text[iterator] - iterator -= 1 - return text.removesuffix(buffer[::-1]) - - -def proc(command, cwd=''): - if 'cp -av' in command: - r = run(command, shell=True) + path_deploy_list = SETTINGS['F_DEPLOY'] + if os.path.exists(path_deploy_list): + with open(path_deploy_list, 'r') as f: + file = f.read() + f.close() + dict_deploy_list = json.loads(file) + DL_FILES = dict_deploy_list['files'] + DL_DIRS = dict_deploy_list['dirs'] else: - if cwd == '': - r = run(command, shell=True, capture_output=True, text=True) - else: - r = run(command, shell=True, capture_output=True, text=True, cwd=cwd) - return r.returncode, str(r.stdout) + str(r.stderr) + create_deploy_list() -def print_settings(): - count = 1 - for key, value in SETTINGS.items(): - print(f'{count}. {key}:{value}') - count += 1 +def create_deploy_list(): + """ + Creates the default deploy_list.json in path SETTINGS.F_DEPLOY + """ + dl_default = { + "files": [], + "dirs": ["dotman"], + } + with open(SETTINGS['F_DEPLOY'], 'w') as f: + f.write(json.dumps(dl_default, indent = 4)) + f.close() -def grab_dotfiles(): - os.mkdir(rrem(SETTINGS['DOTFILES_REPOSITORY'], '/')) - code, output = proc(f"git clone {SETTINGS['REMOTE_REPOSITORY']}", SETTINGS['DOTFILES_REPOSITORY']) - return code == 0, code +def copy(source, dest, interactive=False): + if interactive: + run(shlex.split(f"cp -av {source} {dest}")) + return + run(shlex.split(f"cp -a {source} {dest}")) -def copy(source, dest): - proc(f'cp -av {source} {dest}') +def backup(): + """ + Aggresively executes the steps to do checksum comparisons between local + config directory and local repository to decide which files to copy, + copy only changed files, commit and push to remote. + """ + # get list of files and directories to change (F_DEPLOY) + # get list of checksums of (F_DEPLOY), compute and compare with local repository + # if checksum(local_config) != checksum(local_repo) + # copy local_config to local_repo + # if exists(local_config in local_repo) is False + # copy local_config to local_repo + # if exists(F_DEPLOY) but not in local_config + # warn for lost file, user must either copy from local_repo to local_config or delete from F_DEPLOY + # exec git commit -m "[message]" && git push -def special_copy(source, dest): - whitelist = [ - 'fish', - 'gtk-2.0', - 'gtk-3.0', - 'htop', - 'i3', - 'kitty', - 'neofetch', - 'nitrogen', - 'picom', - 'polybar', - 'rofi', - 'xfce4', - 'navi', - 'gtk-4.0', - 'flameshot' - ] - dirs = os.listdir(source) - selected_dirs = [] - for each_name in dirs: - if each_name in whitelist: - selected_dirs.append(f'{source}{each_name}' if source.endswith('/') else f'{source}/{each_name}') - for directory in selected_dirs: - copy(directory, dest) +def deploy(interactive=False): + """ + Kindly executes the steps to get a up-to-date local repository, + deploy (copy) files and directories to the local config directory. + """ + if not os.path.exists(SETTINGS.DIR_REPO): + r = SETTINGS.DIR_REPO + r.removesuffix("/")[:r.removesuffix("/").rindex("/")] + if interactive: + print(f"Local repository at {SETTINGS['DIR_REPO']} wasn't found. Cloning at {r}") + run(shlex.split(f"/usr/bin/git clone {SETTINGS[URL_REPO]}"), text=True, cwd=r) + if interactive: + print("Pulling changes") + run(shlex.split("/usr/bin/git pull"), text=True, cwd=r) + for file in DL_FILES: + copy(files, interactive=interactive) + for directory in DL_DIRS: + copy(directory, interactive=interactive) -def commit_then_push(): - # I forget checking out to main after testing on a seperate branch - # Line below checks out for me every time it's run - proc('/usr/bin/git checkout main', SETTINGS['DOTFILES_REPOSITORY']) - proc('/usr/bin/git fetch', SETTINGS['DOTFILES_REPOSITORY']) - proc('/usr/bin/git pull', SETTINGS['DOTFILES_REPOSITORY']) - proc('/usr/bin/git add .', SETTINGS['DOTFILES_REPOSITORY']) - date = dt.now().strftime('%d.%m.%Y %H.%M') - _, output = proc(f'/usr/bin/git commit -m "dotman {date}"', SETTINGS['DOTFILES_REPOSITORY']) - if 'nothing to commit' not in output: - code, output = proc('/usr/bin/git push', SETTINGS['DOTFILES_REPOSITORY']) - if code == 0: - _, output = proc('/usr/bin/git log', SETTINGS['DOTFILES_REPOSITORY']) - commit = output.split('\n')[0].replace('commit ', '') - return 3, commit - return 0, None if code == 0 else 2, None - return 1, None +def expand_settings(): + """ + Expands variables used in SETTINGS + """ + SETTINGS['DIR_REPO'] = os.path.expandvars(SETTINGS['DIR_REPO']) + SETTINGS['DIR_CONF'] = os.path.expandvars(SETTINGS['DIR_CONF']) + SETTINGS['F_DEPLOY'] = os.path.expandvars(SETTINGS['F_DEPLOY']) def main(): - global WHEREAMI - WHEREAMI = rrem(sys.argv[0], '/') - read_setup() - SETTINGS['DOTFILES_REPOSITORY'] = os.path.expandvars(SETTINGS['DOTFILES_REPOSITORY']) - SETTINGS['LOCAL_CONFIG'] = os.path.expandvars(SETTINGS['LOCAL_CONFIG']) - remote_shortname = SETTINGS['REMOTE_REPOSITORY'].removeprefix("https://github.com/") + expand_settings() - local_repo_exists = os.path.exists(SETTINGS['DOTFILES_REPOSITORY']) + exists_dir_repo = os.path.exists(SETTINGS['DIR_REPO']) flag_interactive = False flag_backup = False flag_deploy = False - flag_setup = False flag_version = False flag_help = False sys.argv.remove(sys.argv[0]) @@ -177,92 +137,38 @@ def main(): flag_interactive = flag_interactive or key == '-i' or key == '--interactive' flag_backup = flag_backup or key == '-b' or key == '--backup' flag_deploy = flag_deploy or key == '-d' or key == '--deploy' - flag_setup = flag_setup or key == '-s' or key == '--setup-dotman' flag_version = flag_version or key == '-v' or key == '--version' flag_help = flag_help or key == '-h' or key == '--help' else: flag_interactive = True - if flag_interactive: - print(f"dotman {VER} by fyb, 2022") - if not local_repo_exists: - print(colored('Important warning:', 'red'), 'dotfiles repository cannot be located at: ', - colored(SETTINGS['DOTFILES_REPOSITORY'], 'yellow')) - print('Edit DOTFILES_REPOSITORY variable in this script to specify its location') - print(f'To grab dotfiles from', colored(f'"{remote_shortname}"', 'yellow'), end='') - ans = input('type Y. (y/N): ') - if ans.lower() == 'y' or 'yes': - grab_successed, exit_code = grab_dotfiles() - if grab_successed: - print(f'Successfully grabbed dotfiles from', colored(f'"{remote_shortname}"', 'yellow')) - else: - print(f'git exited with result code:', colored(str(exit_code), 'red'), - '. An error may have occured.') - exit(128) - else: - cprint('There isn\'t anything left for dotman to do. Have a nice day!', 'green') - exit(0) - print('dotman is', colored('ready', 'green'), 'for your command. ') - print('You can either backup to remote, or copy local repo to local config (deploy)') - ans = input('(B)ackup or (D)eploy: ') - if ans.lower() == 'b' or ans.lower() == 'backup': - print(colored('Step 1: ', 'magenta'), 'Copy from local config', colored(f"\"{SETTINGS['LOCAL_CONFIG']}\"", 'yellow'), - 'to local repo', colored(f"\"{SETTINGS['DOTFILES_REPOSITORY']}\"", 'yellow')) - special_copy(SETTINGS['LOCAL_CONFIG'], SETTINGS['DOTFILES_REPOSITORY']) - print(colored('Step 2: ', 'magenta'), f'Create a commit and push to remote repo', - colored(f"\"{SETTINGS['REMOTE_REPOSITORY']}\"", 'yellow')) - stat, _ = commit_then_push() - if stat == 0: - cprint('Backup completed. Have a nice day!', 'green') - elif stat == 1: - cprint('There was nothing to commit, aborting.', 'red') - elif stat == 2: - cprint('Couldn\'t push local to remote, aborting.', 'red') - elif stat == 3: - url = f"{SETTINGS['REMOTE_REPOSITORY']}/commit/{_}" - cprint(f'Backup completed: {url}. Have a nice day!', 'green') - exit(stat) - elif ans.lower() == 'd' or ans.lower() == 'deploy': - print(colored('Step 1:', 'magenta'), ' Copy from local repo to local config') - special_copy(SETTINGS['DOTFILES_REPOSITORY'], SETTINGS['LOCAL_CONFIG']) - cprint('Deploy completed. Have a nice day!', 'green') - exit(0) - elif flag_backup and not flag_deploy: - if local_repo_exists: - special_copy(SETTINGS['LOCAL_CONFIG'], SETTINGS['DOTFILES_REPOSITORY']) - exit(commit_then_push()) - else: - print(colored('[CRITICAL]', 'red'), 'Local repository couldn\'t be located. Aborting...') - exit(128) - elif flag_deploy and not flag_backup: - if local_repo_exists: - special_copy(SETTINGS['DOTFILES_REPOSITORY'], SETTINGS['LOCAL_CONFIG']) - exit(0) - else: - print(colored('[CRITICAL]', 'red'), 'Local repository couldn\'t be located. Aborting...') - exit(128) - elif flag_setup: - print(f'dotman interactive setup wizard {WER}') - print_settings() - ans = input('Edit settings (y/N): ') - if ans.lower() == 'y' or ans.lower() == 'yes': - print('Type in number of setting you wish to modify, and "e" or "exit" when done') + if exists_dir_repo: + if flag_interactive: while True: - num = input('Input: ') - if num.lower() == 'exit' or num.lower() == 'e': + ans = input('(B)ackup or (D)eploy is possible, select one: ').lower() + if ans == 'b' or ans == 'd': break - elif num.isnumeric() and 1 <= int(num) <= len(SETTINGS): - key = get_nth_key(int(num) - 1, SETTINGS) - SETTINGS[key] = input(f'Enter new value for {key}: ').strip() - print('Saving changes to file') - write_setup() - - elif flag_version: - print(f'dotman version: {VER.removeprefix("v")}') - exit(0) - elif not flag_deploy and not flag_backup and not flag_interactive or flag_help: - print(help_message) - exit(0) + if ans == 'b': + backup(flag_interactive) + elif ans == 'd': + deploy(flag_deploy) + else: + if flag_backup and not flag_deploy: + backup(flag_interactive) + elif flag_deploy and not flag_backup: + deploy(flag_interactive) + else: + exit(0) + else: + if flag_interactive: + print(f"local repository directory for {SETTINGS['SHN_REPO']} does not exist") + print("You can clone and deploy this repository to local config directory") + ans = input("Continue (y/N): ").lower() + if ans == "n" and not ans == "y": + exit(0) + if not flag_interactive and not flag_deploy: + exit(0) + deploy(flag_interactive) if __name__ == '__main__': diff --git a/fetchpy2 b/fetchpy2 index cc480ca..92443e0 100755 --- a/fetchpy2 +++ b/fetchpy2 @@ -7,7 +7,7 @@ import os from subprocess import run -IMG_LOC = '/home/ferit/sources/neco.png' +IMG_LOC = '/home/ferit/shoka/500-599 pictures/505 clipart/windowschan_s.png' def clr(text: str): @@ -27,9 +27,9 @@ def clr(text: str): '': info, '': info, '': info, - '': info, + '': info, '': info, - '': info, + '󰢮': info, '': info, '': info, 'ferit@navi': title, @@ -108,22 +108,23 @@ def main(): │  {distro_name}│ │  {kernel_version}│ │  {shell_name}│ -│  {package_count}│ +│  {package_count}│ ├──────── Hardware ────────┤ │  AMD Ryzen 7 5800H │ -│  NV GeForce RTX3050 Ti │ +│ 󰢮 NV GeForce RTX3050 Ti │ │  {memory_usage}│ │  {uptime}│ ╰──────────────────────────╯ ''' txt_padded = '' - img_width = 15 + img_width = 16 line_count = 0 for line in txt.splitlines(): txt_padded += ((' ' * img_width) + line + '\n') line_count += 1 - run(['/usr/bin/kitty', 'icat', '--align', 'left', IMG_LOC]) + print('') + run(['/usr/bin/kitty', 'icat', '--mirror', 'horizontal', '--align', 'left', IMG_LOC]) run(['printf', "\e[%sA\e[999999D", str(line_count)]) clr(txt_padded) diff --git a/hypr_clip b/hypr_clip new file mode 100755 index 0000000..e92bb90 --- /dev/null +++ b/hypr_clip @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +cliphist list | wofi --show dmenu | cliphist decode | wl-copy diff --git a/lock.sh b/lock.sh new file mode 100755 index 0000000..db3026b --- /dev/null +++ b/lock.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +# +# Ferit Yiğit BALABAN , 2023 +# +playerctl pause +swaylock -efklu -i "mounts/31_shoka/pictures/landscape/024.jpg" diff --git a/modeset.py b/modeset.py index 7ab4211..5ca954f 100755 --- a/modeset.py +++ b/modeset.py @@ -11,7 +11,7 @@ # Dependencies: # # - brightnessctl -# - pactl +# - pamixer # - playerctl # - wal # - betterlockscreen @@ -64,7 +64,7 @@ def set_volume(value: int, save_state=False): value = int(f.read()) f.close() value = 100 if value > 100 else 0 if value < 0 else value - run_command(f'pactl set-sink-volume @DEFAULT_SINK@ {value}%') + run_command(f'pamixer --set-volume {value}') if save_state: with open(os.path.expandvars(PATH_RESC_VOLUME), 'w') as f: f.write(str(state)) @@ -109,10 +109,7 @@ def get_brightness(device: int): def get_volume(): - r = do_query("pactl list") - for x in r.split("Sink #0")[1].split("Base Volume:")[0].split(' '): - if '%' in x: - return int(x.replace('%', '')) + return int(do_query("pamixer --get-volume")) def log(message: str): diff --git a/poweroff.sh b/poweroff.sh new file mode 100755 index 0000000..f872759 --- /dev/null +++ b/poweroff.sh @@ -0,0 +1,6 @@ +#!/bin/bash +dt=$(date -Iseconds) +unison=$($HOME/scripts/unison_sync.sh) +rm "$HOME/.cache/cliphist/db" +echo "[$dt] INFO: navi, powering off" >> navi.log +poweroff diff --git a/shutdown.sh b/shutdown.sh deleted file mode 100755 index ea552b1..0000000 --- a/shutdown.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -dt=$(date +'%d/%m/%y-%H.%M.%S') -echo "[$dt] navi shutting down..." >> navi.log -$HOME/scripts/modeset.py --shutdown -shutdown -h now diff --git a/wl_ss.sh b/wl_ss.sh new file mode 100644 index 0000000..87f7236 --- /dev/null +++ b/wl_ss.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# +# Ferit Yiğit BALABAN, +# +# Select an area with slurp, ss with grim +# and copy to clipboard. +export GRIM_DEFAULT_DIR="$HOME/items/ss" +grim -g "$( slurp )" - | wl-copy --type image/png diff --git a/wl_sss.sh b/wl_sss.sh new file mode 100755 index 0000000..89c46c7 --- /dev/null +++ b/wl_sss.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# +# Ferit Yiğit BALABAN, +# +# Select an area with slurp, ss with grim +# and copy to clipboard. +SS="$HOME/items/ss" +grim -g "$( slurp )" - | wl-copy --type image/png && wl-paste > "$SS"/$( date +'%Y-%m-%d-%H%M%S.png' )