feat: move config from arc

This commit is contained in:
Jamie Albert
2025-11-03 16:07:40 +00:00
parent 5bc91f8354
commit a533ac2102
25 changed files with 7584 additions and 352 deletions

14
config/dnf/dnf.conf Normal file
View File

@@ -0,0 +1,14 @@
# see `man dnf.conf` for defaults and possible options
[main]
max_parallel_downloads=10
gpgcheck=1
installonly_limit=3
clean_requirements_on_remove=True
best=False
skip_if_unavailable=True
keepcache=true
check_config_file_age=False
metadata_expire=1
max_parallel_downloads=10
defaultyes=True

View File

@@ -0,0 +1,286 @@
[/]
accent-color=['0', '0.75', '0.75']
accent-override=false
apply-accent-shell=false
apply-all-shell=false
apply-flatpak=false
apply-gtk=false
apply-menu-notif=false
apply-menu-shell=false
auto-bgalpha=false
autofg-bar=false
autofg-menu=false
autohg-bar=false
autohg-menu=false
autotheme-dark='Select Theme'
autotheme-font=false
autotheme-light='Select Theme'
autotheme-refresh=false
balpha=1.0
bartype='Trilands'
bcolor=['1.0', '1.0', '1.0']
bg-change=false
bgalpha=1.0
bgalpha-wmax=1.0
bgalpha2=0.27000000000000002
bgcolor=['0.125', '0.125', '0.125']
bgcolor-wmax=['0.125', '0.125', '0.125']
bgcolor2=['0.663', '0.714', '0.396']
bgpalette=true
bguri='file:///home/jamie/.local/share/backgrounds/2025-10-29-03-48-51-wallhaven-m3kggk.jpg'
border-wmax=false
bordertype='solid'
bottom-margin=6.5
boxalpha=1.0
boxcolor=['0.125', '0.125', '0.125']
bradius=8.0
buttonbg-wmax=true
bwidth=0.0
candy1=['0', '0.61', '0.74']
candy10=['0.09', '0.19', '0.72']
candy11=['0.75', '0.49', '0.44']
candy12=['1', '0.92', '0.12']
candy13=['0.38', '0.63', '0.92']
candy14=['0.37', '0.36', '0.39']
candy15=['0.40', '0.23', '0.72']
candy16=['1', '0.32', '0.32']
candy2=['1', '0.41', '0.41']
candy3=['0.63', '0.16', '0.8']
candy4=['0.94', '0.60', '0.23']
candy5=['0.03', '0.41', '0.62']
candy6=['0.56', '0.18', '0.43']
candy7=['0.95', '0.12', '0.67']
candy8=['0.18', '0.76', '0.49']
candy9=['0.93', '0.20', '0.23']
candyalpha=1.0
candybar=false
card-hint=10
color-scheme='prefer-dark'
corner-radius=false
count1=401044
count10=1322
count11=21
count12=8
count2=90986
count3=75564
count4=73125
count5=8514
count6=8180
count7=2959
count8=2685
count9=1592
cust-margin-wmax=false
dark-accent-color=['0', '0.75', '0.75']
dark-bcolor=['1.0', '1.0', '1.0']
dark-bgcolor=['0.125', '0.125', '0.125']
dark-bgcolor-wmax=['0.125', '0.125', '0.125']
dark-bgcolor2=['0.663', '0.714', '0.396']
dark-bguri='file:///home/jamie/.local/share/backgrounds/2025-10-29-03-48-51-wallhaven-m3kggk.jpg'
dark-boxcolor=['0.125', '0.125', '0.125']
dark-candy1=['0', '0.61', '0.74']
dark-candy10=['0.09', '0.19', '0.72']
dark-candy11=['0.75', '0.49', '0.44']
dark-candy12=['1', '0.92', '0.12']
dark-candy13=['0.38', '0.63', '0.92']
dark-candy14=['0.37', '0.36', '0.39']
dark-candy15=['0.40', '0.23', '0.72']
dark-candy16=['1', '0.32', '0.32']
dark-candy2=['1', '0.41', '0.41']
dark-candy3=['0.63', '0.16', '0.8']
dark-candy4=['0.94', '0.60', '0.23']
dark-candy5=['0.03', '0.41', '0.62']
dark-candy6=['0.56', '0.18', '0.43']
dark-candy7=['0.95', '0.12', '0.67']
dark-candy8=['0.18', '0.76', '0.49']
dark-candy9=['0.93', '0.20', '0.23']
dark-dbgcolor=['0.125', '0.125', '0.125']
dark-fgcolor=['0.922', '0.859', '0.698']
dark-hcolor=['0.314', '0.286', '0.271']
dark-hscd-color=['0.663', '0.714', '0.396']
dark-iscolor=['0.235', '0.220', '0.212']
dark-mbcolor=['1.0', '1.0', '1.0']
dark-mbgcolor=['0.125', '0.125', '0.125']
dark-mfgcolor=['1.0', '1.0', '1.0']
dark-mhcolor=['0', '0.7', '0.9']
dark-mscolor=['0', '0.7', '0.75']
dark-mshcolor=['1.0', '1.0', '1.0']
dark-palette1=['41', '44', '47']
dark-palette10=['99', '100', '108']
dark-palette11=['164', '124', '97']
dark-palette12=['166', '133', '92']
dark-palette2=['85', '85', '84']
dark-palette3=['125', '121', '116']
dark-palette4=['200', '198', '189']
dark-palette5=['153', '158', '158']
dark-palette6=['68', '76', '76']
dark-palette7=['100', '108', '108']
dark-palette8=['173', '149', '123']
dark-palette9=['141', '148', '156']
dark-shcolor=['0', '0', '0']
dark-smbgcolor=['0.125', '0.125', '0.125']
dark-vw-color=['0.663', '0.714', '0.396']
dark-winbcolor=['0.663', '0.714', '0.396']
dashdock-style='Menu'
dbgalpha=0.0
dbgcolor=['0.125', '0.125', '0.125']
dborder=true
dbradius=24.0
default-font='Sans 12'
destruct-color=['0.75', '0.11', '0.16']
disize=48.0
dshadow=false
fgalpha=1.0
fgcolor=['0.922', '0.859', '0.698']
fitts-widgets=true
font='Liga SFMono Nerd Font Medium 11'
gradient=false
gradient-direction='vertical'
gtk-popover=false
gtk-shadow='Default'
gtk-transparency=1.0
halpha=0.10000000000000001
handle-border=3.0
hbar-gtk3only=false
hcolor=['0.314', '0.286', '0.271']
headerbar-hint=0
heffect=false
height=40.0
hpad=2.0
hscd-color=['0.663', '0.714', '0.396']
import-export=true
isalpha=0.34000000000000002
iscolor=['0.235', '0.220', '0.212']
light-accent-color=['0', '0.75', '0.75']
light-bcolor=['0.000', '0.700', '0.750']
light-bgcolor=['0.125', '0.125', '0.125']
light-bgcolor-wmax=['0.125', '0.125', '0.125']
light-bgcolor2=['0', '0.7', '0.75']
light-bguri='file:///home/jamie/.local/share/backgrounds/2025-10-29-03-48-51-wallhaven-m3kggk.jpg'
light-boxcolor=['0.078', '0.086', '0.090']
light-candy1=['0', '0.61', '0.74']
light-candy10=['0.09', '0.19', '0.72']
light-candy11=['0.75', '0.49', '0.44']
light-candy12=['1', '0.92', '0.12']
light-candy13=['0.38', '0.63', '0.92']
light-candy14=['0.37', '0.36', '0.39']
light-candy15=['0.40', '0.23', '0.72']
light-candy16=['1', '0.32', '0.32']
light-candy2=['1', '0.41', '0.41']
light-candy3=['0.63', '0.16', '0.8']
light-candy4=['0.94', '0.60', '0.23']
light-candy5=['0.03', '0.41', '0.62']
light-candy6=['0.56', '0.18', '0.43']
light-candy7=['0.95', '0.12', '0.67']
light-candy8=['0.18', '0.76', '0.49']
light-candy9=['0.93', '0.20', '0.23']
light-dbgcolor=['0.125', '0.125', '0.125']
light-fgcolor=['0.984', '0.945', '0.780']
light-hcolor=['0.114', '0.125', '0.129']
light-hscd-color=['0.514', '0.647', '0.596']
light-iscolor=['0.114', '0.122', '0.118']
light-mbcolor=['0.984', '0.945', '0.780']
light-mbgcolor=['0.114', '0.125', '0.129']
light-mfgcolor=['0.984', '0.945', '0.780']
light-mhcolor=['0.557', '0.753', '0.486']
light-mscolor=['0.557', '0.753', '0.486']
light-mshcolor=['0.000', '0.700', '0.750']
light-palette1=['41', '44', '47']
light-palette10=['99', '100', '108']
light-palette11=['164', '124', '97']
light-palette12=['166', '133', '92']
light-palette2=['85', '85', '84']
light-palette3=['125', '121', '116']
light-palette4=['200', '198', '189']
light-palette5=['153', '158', '158']
light-palette6=['68', '76', '76']
light-palette7=['100', '108', '108']
light-palette8=['173', '149', '123']
light-palette9=['141', '148', '156']
light-shcolor=['0', '0', '0']
light-smbgcolor=['0.973', '0.894', '0.361']
light-vw-color=['0.514', '0.647', '0.537']
light-winbcolor=['0.514', '0.647', '0.537']
margin=0.0
margin-wmax=2.0
mbalpha=0.0
mbcolor=['1.0', '1.0', '1.0']
mbg-gradient=false
mbgalpha=1.0
mbgcolor=['0.125', '0.125', '0.125']
menu-radius=24.0
menustyle=false
mfgalpha=1.0
mfgcolor=['1.0', '1.0', '1.0']
mhalpha=0.14999999999999999
mhcolor=['0', '0.7', '0.9']
monitor-height=1080
monitor-width=1920
monitors='all'
msalpha=1.0
mscolor=['0', '0.7', '0.75']
mshalpha=0.0
mshcolor=['1.0', '1.0', '1.0']
neon=false
neon-wmax=false
notif-radius=24.0
palette1=['41', '44', '47']
palette10=['99', '100', '108']
palette11=['164', '124', '97']
palette12=['166', '133', '92']
palette2=['85', '85', '84']
palette3=['125', '121', '116']
palette4=['200', '198', '189']
palette5=['153', '158', '158']
palette6=['68', '76', '76']
palette7=['100', '108', '108']
palette8=['173', '149', '123']
palette9=['141', '148', '156']
pause-reload=false
position='Top'
prominent1=['100', '100', '100']
prominent2=['100', '100', '100']
prominent3=['100', '100', '100']
prominent4=['100', '100', '100']
prominent5=['100', '100', '100']
prominent6=['100', '100', '100']
qtoggle-radius=24.0
radius-bottomleft=true
radius-bottomright=true
radius-topleft=true
radius-topright=true
reloadstyle=true
removestyle=false
sbar-gradient='none'
set-bottom-margin=false
set-fullscreen=true
set-notif-position=false
set-notifications=false
set-overview=true
set-yarutheme=false
shadow=false
shalpha=0.20000000000000001
shcolor=['0', '0', '0']
sidebar-hint=6
slider-height=4.0
smbgalpha=0.94999999999999996
smbgcolor=['0.125', '0.125', '0.125']
smbgoverride=true
success-color=['0.15', '0.635', '0.41']
traffic-light=false
trigger-autotheme=false
trigger-reload=false
view-hint=0
vpad=5.0
vw-color=['0.663', '0.714', '0.396']
warning-color=['0.96', '0.83', '0.17']
width-bottom=true
width-left=true
width-right=true
width-top=true
winbalpha=0.75
winbcolor=['0.663', '0.714', '0.396']
winbradius=25.0
winbwidth=0.0
window-hint=0
wmax-hbarhint=false
wmaxbar=false

6077
config/gtk/gnome-shell.css Normal file

File diff suppressed because it is too large Load Diff

64
config/iris/iris.conf Normal file
View File

@@ -0,0 +1,64 @@
#!/usr/bin/env bash
################################################################################
# @file_name: iris.conf
# @version: 0.0.50
# @project_name: iris
# @brief: config file for iris
#
# @author: Jamie Dobbs (awildamnesiac)
# @author_contact: awildamnesiac@protonmail.ch
#
# @license: BSD-3 Clause (Included in LICENSE)
# Copyright (C) 2021-2024, Jamie Dobbs
# All rights reserved.
# shellcheck disable=2034
################################################################################
################################################################################
# @IMPORTANT: DO NOT UPDATE THIS FILE
# UPDATE COPIES LOCATED IN $HOME/.config/iris/iris.conf
################################################################################
################################################################################
# @description: iris configuration
################################################################################
_iris_modules=( "shopt" "git" "pyenv" "ssh" "readonly" "screen" ); # enabled modules
################################################################################
# @description: prompt configuration
################################################################################
_prompt_input_newline="true"; # console input on new line: true/false
_prompt_nerd_font="true"; # change to true if nerd font is installed and enabled in your terminal (supplied in fonts): true/false
_prompt_input_symbol=""; # console input symbol
_prompt_nerd_symbol="󰥭";
# _prompt_nerd_symbol=""; # console input symbol for nerd font
_prompt_username="true"; # show current user on prompt: true/false
_prompt_hostname="ssh"; # show hostname on prompt: ssh,all,none
_prompt_dir="true"; # show dir on prompt: true/false
_prompt_display_error="true"; # displays error codes on prompt
_prompt_seperator=" "; # seperator between prompt informations
_prompt_wrapper="[]"; # wrapper for prompt information: 2 chars max (LR)
_prompt_success_color="106" # changes prompt input symbol to green if previous command is return 0
_prompt_fail_color="203"; # changes prompt input symbol to red if previous command does not return 0
_prompt_user_color="109" # sets the user color in prompt
_prompt_sudo_color="72" # sets the sudo color in prompt
_prompt_info_color="172"; # sets the info color in prompt
_prompt_input_color="254"; # sets the input color in prompt
################################################################################
# @description: aliases
################################################################################
alias mkdir='mkdir -p'; # adds -p flag to mkdir as standard
alias ll="ls -laFh"; # ll as an easier alias for ls -laFh
alias la='ls -A'; # la as an easier alias for ls -A
alias hist='history|grep'; # search history with hist needle
alias count='find . -type f | wc -l'; # counts file list
alias nano='nano -W'; # adds -W flag to nano as standard
################################################################################
# @description: misc
################################################################################
declare -g HISTTIMEFORMAT='%F %T '; # time format for history
declare -g PROMPT_DIRTRIM="2"; # trims dir path after x dirs
[[ -z "$LC_CTYPE" && -z "$LC_ALL" ]] && declare -g LC_CTYPE="${LANG%%:*}"; # passes lang to lc_ctype
[[ -z "$HISTFILE" ]] && declare -g HISTFILE="$HOME/.bash_history"; # if no HISTFILE is set, sets it to $HOME/.bash_history

View File

@@ -0,0 +1,6 @@
table inet mullvad_tailscale {
chain output {
type route hook output priority 0; policy accept;
ip daddr 100.64.0.0/10 ct mark set 0x00000f41 meta mark set 0x6d6f6c65;
}
}

View File

@@ -0,0 +1,13 @@
[Unit]
Description=Rclone Mount Service
After=network-online.target
Wants=network-online.target
[Service]
Type=forking
User=jamie
ExecStart=bash /home/jamie/dao/cradle/scripts/rclone_mount.sh
Restart=on-failure
[Install]
WantedBy=multi-user.target

11
config/rclone/rclone.conf Executable file
View File

@@ -0,0 +1,11 @@
[koofr]
type = koofr
provider = koofr
user = koofr@do-bbs.me
password = GYsZmWtUoLUsLHBd5hCiFx7-yGK2XcEGfGqMAThjgLk
[koofr_vault]
type = crypt
remote = koofr:/vault
password = SlOeftMnQNgRoo4SJRxMCeZDHckgi3xFfw3jjfOpoJJqqPSed7vG7SaCJ7ZDvRT2SlU9M8i-5YeJLnhaN6EuzBY
password2 = YBQPmGBnC-B035q15aCsm-jnJeT8oHxRI4mT-RLzFKyijilF0yh4LfP0hQsPcPH-7cKbySGTR7SaKin55xsQZ5PYaqHGHpQJuC9WBU4wBMCTpNUcZ8VWW4yPqX2w8U5Uz2sshhQXUPWC5eKVsM1GaEcsUUWio7z-u06OF-yrhCK9yjwNl7ybkWpP8cAFnfMCkwGFeGK4sl94ddQE0iKNksQeSnAR-Lb0NdLQbN4pE0Fqyj-J2Cl-xbAQJg

View File

@@ -0,0 +1,13 @@
# Default
Default look of Spotify with different color schemes.
## Screenshot
![screenshot](./ocean.png)
## Info
### Ocean
Part of material ocean themes, [checkout here](https://github.com/material-ocean) for the same theme for different applications. By @Blacksuan19

View File

@@ -0,0 +1,33 @@
[Ocean]
text = FFFFFF
subtext = F1F1F1
main = 0F111A
sidebar = 0F111A
player = 0F111A
card = 00010A
shadow = 0F111A
selected-row = F1F1F1
button = FF4151
button-active = F1F1F1
button-disabled = 434C5E
tab-active = FF4151
notification = 00010A
notification-error = FF4151
misc = 00010A
[gruvbox]
text = fbf1c7
subtext = ebdbb2
main = 1d2021
sidebar = 282828
player = 3c3836
card = 665c54
shadow = 1d2021
selected-row = d5c4a1
button = ebdbb2
button-active = 8ec07c
button-disabled = 535353
tab-active = 689d6a
notification = ebdbb2
notification-error = e2e2e2
misc = bdae93

View File

@@ -0,0 +1,16 @@
[gruvbox]
text = fbf1c7
subtext = ebdbb2
main = 1d2021
sidebar = 282828
player = 3c3836
card = 665c54
shadow = 1d2021
selected-row = d5c4a1
button = ebdbb2
button-active = 8ec07c
button-disabled = 535353
tab-active = 689d6a
notification = ebdbb2
notification-error = e2e2e2
misc = bdae93

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

17
config/ssh_config.d/10-vps.conf Executable file
View File

@@ -0,0 +1,17 @@
Host hephaestus
HostName 37.27.5.239
UserKnownHostsFile=/dev/null
StrictHostKeyChecking no
User oc
IdentityFile ~/.ssh/hephaestus
Host athena
Port 23
HostName u497749.your-storagebox.de
UserKnownHostsFile=/dev/null
StrictHostKeyChecking no
User u497749
IdentityFile ~/.ssh/athena

View File

@@ -0,0 +1,3 @@
Host github.com
User git
IdentityFile /home/orange_cashew/.ssh/github

View File

@@ -0,0 +1,657 @@
/**
* @name Gruvbox Dark
* @description Gruvbox Dark for Discord (new UI update)
* @author shved.
* @version 0.0.1
* @authorId 833767278969225266
* @website https://github.com/shvedes/discord-gruvbox
*/
* {
--gruv-dark-bg-hard: 29, 32, 33;
--gruv-dark-bg: 40 40 40;
--gruv-dark-bg-alt: 33, 33, 33;
--gruv-dark-bg-soft: 50, 48, 47;
--gruv-dark-bg1: 60, 56, 54;
--gruv-dark-bg2: 80, 73, 69;
--gruv-dark-bg3: 102, 92, 84;
--gruv-dark-bg4: 124, 111, 100;
--gruv-dark-fg-hard: 251, 241, 199;
--gruv-dark-fg: 235, 219, 178;
--gruv-dark-fg1: 213, 196, 161;
--gruv-dark-fg2: 189, 174, 147;
--gruv-dark-fg3: 168, 153, 132;
--gruv-dark-purple-dark: 177, 98, 134;
--gruv-dark-purple-light: 211, 134, 155;
--gruv-dark-yellow-dark: 215, 153, 33;
--gruv-dark-yellow-light: 250, 189, 47;
--gruv-dark-red-dark: 204, 36, 29;
--gruv-dark-red-light: 251, 73, 52;
--gruv-dark-orange-dark: 214, 93, 14;
--gruv-dark-orange-light: 254, 128, 25;
--gruv-dark-blue-dark: 69, 133, 136;
--gruv-dark-blue-light: 131, 165, 152;
--gruv-dark-green-dark: 104 157 106;
--gruv-dark-green-light: 142, 192, 124;
--gruv-dark-aqua-dark: 104, 157, 106;
--gruv-dark-aqua-light: 142, 192, 124;
--gruv-dark-gray-dark: 146, 131, 116;
--gruv-dark-gray-light: 168, 153, 132;
/* ============================================================== */
--gruv-dark-text-hard: var(--gruv-dark-fg-hard);
--gruv-dark-text-primary: var(--gruv-dark-fg);
--gruv-dark-text-secondary: var(--gruv-dark-fg1);
--gruv-dark-text-tertiary: var(--gruv-dark-fg2);
--gruv-dark-text-muted: var(--gruv-dark-fg3);
--gruv-dark-text-danger: var(--gruv-dark-red-light);
--gruv-dark-text-inverted-hard: var(--gruv-dark-text-hard);
--gruv-dark-text-inverted: var(--gruv-dark-bg);
--gruv-dark-background-positive: var(--gruv-dark-green-dark);
--gruv-dark-accent: var(--gruv-dark-green-light);
--gruv-dark-accent-hover: var(--gruv-dark-green-dark);
--gruv-dark-icon-color: var(--gruv-dark-fg2);
--gruv-dark-icon-color-hover: var(--gruv-dark-fg);
--gruv-dark-icon-color-hover-harder: var(--gruv-dark-fg-hard);
--gruv-dark-icon-color-muted: var(--gruv-dark-fg3);
--gruv-dark-link-color: var(--gruv-dark-blue-light);
--gruv-dark-border-default: var(--gruv-dark-bg2);
--gruv-dark-border-hover: var(--gruv-dark-bg3);
--gruv-dark-button-color-default: var(--gruv-dark-accent);
--gruv-dark-button-color-hover: rgba(var(--gruv-dark-button-color-default), 0.7);
--gruv-dark-button-text-default: var(--gruv-dark-bg);
--gruv-dark-button-text-dark: var(--gruv-dark-text-primary);
--gruv-dark-button-text-dark-muted: var(--gruv-dark-text-muted);
--gruv-dark-button-alt-default: var(--gruv-dark-bg-soft);
--gruv-dark-button-alt-hover: var(--gruv-dark-bg);
--gruv-dark-button-positive-default: var(--gruv-dark-green-dark);
--gruv-dark-button-positive-hover: rgba(var(--gruv-dark-green-dark), 0.8);
--gruv-dark-input-box-background: var(--gruv-dark-bg-soft);
--gruv-dark-scrollbar-color: var(--gruv-dark-bg3);
--gruv-dark-scrollbar-background: transparent;
--gruv-dark-selected-tab: var(--gruv-dark-bg1);
--gruv-dark-status-online: var(--gruv-dark-green-dark);
--gruv-dark-status-offline: var(--gruv-dark-text-muted);
--gruv-dark-status-idle: rgba(var(--gruv-dark-accent), 0.8);
--gruv-dark-status-dnd: var(--gruv-dark-red-dark);
--vc-spotify-green: rgba(var(--gruv-dark-green-dark));
--vc-spotify-green-90: rgba(var(--gruv-dark-green-dark), 0.2);
--vc-spotify-green-80: rgba(var(--gruv-dark-green-dark), 0.3);
}
.visual-refresh.theme-dark,
.visual-refresh .theme-dark,
[class*=vc-membercount-total], /* vesktop plugin */
.visual-refresh,
.theme-dark {
--__header-bar-background: rgba(var(--gruv-dark-bg-hard));
--autocomplete-bg: rgba(var(--gruv-dark-bg));
--background-primary: rgba(var(--gruv-dark-bg)); /* #282828 */
--background-secondary: rgba(var(--gruv-dark-bg-alt)) ; /* #212121 */
--background-secondary-alt: rgba(var(--gruv-dark-bg-soft));
--background-tertiary: rgba(var(--gruv-dark-bg-soft)); /* #32302f */
--background-base-lower: rgba(var(--gruv-dark-bg));
--background-base-low: rgba(var(--gruv-dark-bg));
--background-base-lowest: rgba(var(--gruv-dark-bg-hard));
--background-floating: rgba(var(--gruv-dark-bg-hard)); /* #1d2021 */
--background-surface-high: rgba(var(--gruv-dark-bg-soft));
--background-surface-higher: rgba(var(--gruv-dark-bg));
--background-surface-highest: rgba(var(--gruv-dark-bg));
--background-feedback-critical: rgba(var(--gruv-dark-red-dark), 0.08);
--background-feedback-positive: rgba(var(--gruv-dark-green-dark), 0.08);
--background-modifier-accent: rgba(var(--gruv-dark-border-default));
--background-modifier-selected: rgba(var(--gruv-dark-selected-tab));
--background-mentioned: rgba(var(--gruv-dark-accent), 0.1);
--background-mentioned-hover: rgba(var(--gruv-dark-accent), 0.15);
--background-message-automod: rgba(var(--gruv-dark-accent), 0.1);
--background-message-automod-hover: rgba(var(--gruv-dark-accent), 0.15);
--background-accent: rgba(var(--gruv-dark-bg1));
--bg-base-primary: rgba(var(--gruv-dark-bg));
--bg-base-secondary: rgba(var(--gruv-dark-bg));
--bg-base-tertiary: rgba(var(--gruv-dark-bg-hard));
--bg-surface-overlay: rgba(var(--gruv-dark-bg));
--card-primary-bg: rgba(var(--gruv-dark-bg-hard));
--bg-brand: rgba(var(--gruv-dark-accent), 0.8);
--bg-mod-faint: rgba(var(--gruv-dark-bg-soft));
--bg-mod-strong: rgba(var(--gruv-dark-bg2));
--bg-mod-subtle: rgba(var(--gruv-dark-bg1));
--border-normal: rgba(var(--gruv-dark-border-default));
--border-strong: rgba(var(--gruv-dark-border-default));
--border-faint: rgba(var(--gruv-dark-border-default));
--border-subtle: rgba(var(--gruv-dark-border-default));
--background-message-hover: rgba(var(--gruv-dark-bg1));
--text-primary: rgba(var(--gruv-dark-fg-hard)); /* #fbf1c7 */
--text-normal: rgba(var(--gruv-dark-fg)); /* #ebdbb2 */
--text-default: rgba(var(--gruv-dark-fg)); /* #ebdbb2 */
--text-secondary: rgba(var(--gruv-dark-fg1)); /* #d5c4a1 */
--text-tertiary: rgba(var(--gruv-dark-fg2)); /* #bdae93 */
--text-positive: rgba(var(--gruv-dark-green-dark));
--chat-text-muted: var(--text-tertiary);
--embed-title: rgba(var(--gruv-dark-text-hard));
--text-link: rgba(var(--gruv-dark-link-color));
--text-muted: rgba(var(--gruv-dark-text-muted));
--text-brand: rgba(var(--gruv-dark-accent));
--text-muted-on-default: rgba(var(--gruv-dark-text-muted));
--text-feedback-positive: rgba(var(--gruv-dark-green-dark));
--text-code-comment: rgba(var(--gruv-dark-gray-light));
--text-code-default: rgba(var(--gruv-dark-blue-light));
--text-code-keyword: rgba(var(--gruv-dark-purple-light));
--text-code-variable: rgba(var(--gruv-dark-blue-light));
--text-code-builtin: rgba(var(--gruv-dark-purple-light));
--text-code-string: rgba(var(--gruv-dark-aqua-light));
--header-primary: rgba(var(--gruv-dark-text-primary));
--header-secondary: rgba(var(--gruv-dark-text-tertiary));
--header-muted: rgba(var(--gruv-dark-text-muted));
--checkbox-border-default: rgba(var(--gruv-dark-border-default));
--checkbox-border-checked: rgba(var(--gruv-dark-border-default));
--checkbox-background-default: rgba(var(--gruv-dark-bg-soft));
--checkbox-background-checked: rgba(var(--gruv-dark-background-positive));
--channel-icon: rgba(var(--gruv-dark-icon-color));
--channels-default: rgba(var(--gruv-dark-fg3));
--custom-notice-background: rgba(var(--gruv-dark-green-dark));
--custom-notice-text: rgba(var(--gruv-dark-text-hard));
--notice-background-positive: rgba(var(--gruv-dark-green-dark));
--notice-background-warning: rgba(var(--gruv-dark-yellow-dark), 0.8);
--notice-background-critical: rgba(var(--gruv-dark-red-dark));
--notice-text-positive: rgba(var(--gruv-dark-text-inverted-hard));
--link-color: rgba(var(--gruv-dark-blue-dark));
--icon-primary: rgba(var(--gruv-dark-icon-color));
--icon-secondary: rgba(var(--gruv-dark-icon-color));
--icon-tertiary: rgba(var(--gruv-dark-icon-color));
--icon-default: rgba(var(--gruv-dark-icon-color));
--icon-muted: rgba(var(--gruv-dark-icon-color-muted));
--input-background: rgba(var(--gruv-dark-input-box-background));
--input-border: rgba(var(--gruv-dark-border-default));
--input-placeholder-text: rgba(var(--gruv-dark-text-tertiary));
--modal-background: rgba(var(--gruv-dark-bg-hard));
--modal-footer-background: rgba(var(--gruv-dark-bg));
--mention-foreground: rgba(var(--gruv-dark-fg-hard));
--mention-background: rgba(var(--gruv-dark-bg2));
--scrollbar-auto-thumb: rgba(var(--gruv-dark-scrollbar-color));
--scrollbar-auto-track: rgba(var(--gruv-dark-scrollbar-background));
--scrollbar-thin-thumb: rgba(var(--gruv-dark-scrollbar-color));
--scrollbar-auto-scrollbar-color-thumb: rgba(var(--gruv-dark-scrollbar-color));
--scrollbar-auto-scrollbar-color-track: rgba(var(--gruv-dark-scrollbar-color));
--button-filled-brand-text: rgba(var(--gruv-dark-button-text-default));
--button-filled-brand-border: rgba(var(--gruv-dark-button-color-default));
--button-filled-brand-background: rgba(var(--gruv-dark-button-color-default));
--button-filled-brand-background-active: rgba(var(--gruv-dark-button-color-default));
--button-filled-brand-background-hover: var(--gruv-dark-button-color-hover);
--button-danger-background: rgba(var(--gruv-dark-red-dark));
--button-danger-background-active: rgba(var(--gruv-dark-red-light));
--button-danger-background-disabled: rgba(var(--gruv-dark-red-dark), 0.8);
--button-danger-background-hover: rgba(var(--gruv-dark-red-dark), 0.7);
--button-danger-border: rgba(var(--gruv-dark-red-dark));
--button-outline-danger-background: rgba(var(--gruv-dark-button-alt-default));
--button-outline-danger-background-hover: rgba(var(--gruv-dark-button-alt-hover));
--button-outline-danger-border: rgba(var(--gruv-dark-border-default));
--button-outline-danger-border-hover: rgba(var(--gruv-dark-border-default));
--button-outline-danger-text: rgba(var(--gruv-dark-button-text-dark-muted));
--button-outline-danger-text-hover: rgba(var(--gruv-dark-text-danger));
--button-outline-positive-text: rgba(var(--gruv-dark-text-primary));
--button-positive-background: rgba(var(--gruv-dark-button-positive-default));
--button-positive-background-hover: var(--gruv-dark-button-positive-hover);
--button-positive-background-active: rgba(var(--gruv-dark-button-positive-default));
--button-positive-background-disabled: rgba(var(--gruv-dark-green-dark));
--button-positive-border: rgba(var(--gruv-dark-button-positive-default));
--button-secondary-background: rgba(var(--gruv-dark-bg-soft));
--button-secondary-background-hover: rgba(var(--gruv-dark-bg));
--button-secondary-text: rgba(var(--gruv-dark-button-text-dark-muted));
--button-transparent-background: rgba(var(--gruv-dark-button-alt-default));
--button-transparent-background-hover: rgba(var(--gruv-dark-button-alt-hover));
--button-transparent-text: rgba(var(--gruv-dark-button-text-dark));
--primary-630: rgba(var(--gruv-dark-button-alt-default));
--primary-700: rgba(var(--gruv-dark-button-alt-hover));
--background-code: rgba(var(--gruv-dark-bg-hard));
--status-online: rgba(var(--gruv-dark-status-online));
--status-offline: rgba(var(--gruv-dark-status-offline));
--status-idle: var(--gruv-dark-status-idle);
--status-dnd: rgba(var(--gruv-dark-status-dnd));
--status-positive: rgba(var(--gruv-dark-green-dark));
--status-positive-background: rgba(var(--gruv-dark-green-dark));
--status-positive-text: rgba(var(--gruv-dark-text-inverted-hard));
--status-danger: rgba(var(--gruv-dark-red-dark));
--status-danger-background: rgba(var(--gruv-dark-red-dark));
--status-danger-text: rgba(var(--gruv-dark-text-primary));
--status-warning: rgba(var(--gruv-dark-orange-dark));
--status-warning-background: rgba(var(--gruv-dark-orange-dark));
--status-warning-text: rgba(var(--gruv-dark-text-inverted-hard));
--status-speaking: rgba(var(--gruv-dark-green-light));
--info-danger-background: rgba(var(--gruv-dark-red-dark), 0.08);
--info-danger-text: rgba(rgba(gruv-dark-red-light));
--info-help-foreground: rgba(var(--gruv-dark-blue-light));
--info-help-background: rgba(var(--gruv-dark-blue-dark), 0.1);
--info-positive-background: rgba(var(--gruv-dark-green-dark), 0.08);
--info-positive-text: rgba(var(--gruv-dark-green-light));
--info-warning-background: rgba(var(--gruv-dark-orange-dark), 0.08);
--info-warning-text: rgba(var(--gruv-dark-text-primary));
--background-mod-normal: rgba(var(--gruv-dark-selected-tab));
--background-mod-strong: rgba(var(--gruv-dark-bg2));
--background-mod-subtle: rgba(var(--gruv-dark-bg-soft));
--interactive-normal: rgba(var(--gruv-dark-icon-color));
--interactive-hover: rgba(var(--gruv-dark-icon-color-hover-harder));
--interactive-active: rgba(var(--gruv-dark-icon-color-hover-harder));
--interactive-muted: rgba(var(--gruv-dark-bg3));
--message-reacted-text: rgba(var(--gruv-dark-text-hard));
--message-reacted-background: rgba(var(--gruv-dark-accent), 0.1);
--background-message-highlight: rgba(var(--gruv-dark-accent), 0.1);
--background-message-highlight-hover: rgba(var(--gruv-dark-accent), 0.15);
--spoiler-hidden-background: rgba(var(--gruv-dark-bg2));
--spoiler-hidden-background-hover: rgba(var(--gruv-dark-bg3));
--chat-background-default: rgba(var(--gruv-dark-bg-soft));
--premium-nitro-pink-text: rgba(var(--gruv-dark-purple-light));
--guild-boosting-pink: rgba(var(--gruv-dark-purple-light));
--spine-default: rgba(var(--gruv-dark-bg4));
--app-border-frame: rgba(var(--gruv-dark-border-default));
--twitch: rgba(var(--gruv-dark-purple-dark));
--opacity-blurple-12: rgba(var(--gruv-dark-bg));
--custom-store-colors-premium-gradient: linear-gradient(90deg, rgba(var(--gruv-dark-purple-dark)), rgba(var(--gruv-dark-purple-light)));
--custom-premium-colors-premium-gradient-tier-0: linear-gradient(90deg, rgba(var(--gruv-dark-purple-dark)), rgba(var(--gruv-dark-purple-light)));
--custom-premium-colors-premium-gradient-tier-1: linear-gradient(90deg, rgba(var(--gruv-dark-purple-dark)), rgba(var(--gruv-dark-purple-light)));
--custom-premium-colors-premium-gradient-tier-2: linear-gradient(90deg, rgba(var(--gruv-dark-purple-dark)), rgba(var(--gruv-dark-purple-light)));
--custom-premium-colors-premium-gradient-tier-2-transparent: linear-gradient(90deg, rgba(var(--gruv-dark-purple-dark), 0.3), rgba(var(--gruv-dark-purple-light), 0.3));
--custom-premium-colors-premium-gradient-tier-2-diagonal: linear-gradient(45deg, rgba(var(--gruv-dark-purple-dark)), rgba(var(--gruv-dark-purple-light)));
--custom-premium-colors-premium-gradient-tier-2-tri-color: linear-gradient(90deg, rgba(var(--gruv-dark-purple-dark)), rgba(var(--gruv-dark-purple-light)), rgba(var(--gruv-dark-purple-dark)));
--custom-premium-colors-premium-gradient-tier-2-tri-color-reverse: linear-gradient(90deg, rgba(var(--gruv-dark-purple-dark)), rgba(var(--gruv-dark-purple-light)), rgba(var(--gruv-dark-purple-dark)));
--custom-premium-colors-premium-gradient-tier-2-tri-color-vertical: linear-gradient(0deg, rgba(var(--gruv-dark-purple-dark)), rgba(var(--gruv-dark-purple-light)), rgba(var(--gruv-dark-purple-dark)));
--custom-premium-colors-premium-gradient-tier-2-old: linear-gradient(90deg, rgba(var(--gruv-dark-purple-dark)), rgba(var(--gruv-dark-purple-light)));
--premium-nitro-pink-dark: rgba(var(--gruv-dark-purple-dark));
--premium-nitro-pink-light: rgba(var(--gruv-dark-purple-light));
--premium-perk-blue: rgba(var(--gruv-dark-blue-dark));
--premium-perk-blue-alt: rgba(var(--gruv-dark-blue-dark));
--premium-perk-dark-blue: rgba(var(--gruv-dark-blue-dark));
--brand-260: rgba(var(--gruv-dark-accent-hover), 0.8);
--brand-360: rgba(var(--gruv-dark-accent));
--brand-500: rgba(var(--gruv-dark-accent-hover), 0.8);
--brand-05: rgba(var(--gruv-dark-accent-hover), 0.2);
--white-500: rgba(var(--gruv-dark-text-hard));
--blurple-50: rgba(var(--gruv-dark-accent));
--green-300: rgba(var(--gruv-dark-green-dark));
--green-360: rgba(var(--gruv-dark-green-dark));
--color-total: rgba(var(--gruv-dark-text-muted));
--primary-300: rgba(var(--gruv-dark-text-hard));
--primary-500: rgba(var(--gruv-dark-bg1));
--white: rgba(var(--gruv-dark-text-hard));
--badge-brand-text: rgba(var(--gruv-dark-text-inverted));
--badge-brand-bg: rgba(var(--gruv-dark-accent-hover), 0.8);
--redesign-button-positive-background: rgba(var(--gruv-dark-green-dark));
--redesign-button-positive-pressed-background: rgba(var(--gruv-dark-green-dark), 0.8);
--redesign-button-positive-text: rgba(var(--gruv-dark-text-hard));
--redesign-button-overlay-alpha-text: rgba(var(--gruv-dark-text-hard));
--redesign-button-overlay-alpha-background: rgba(0, 0, 0, 0.3);
--user-profile-overlay-background: rgba(var(--gruv-dark-bg));
}
.visual-refresh .textBadge__2b1f5 {
color: rgb(var(--gruv-dark-text-inverted)) !important
}
/* Invite button inside call box */
.buttonColor__7b3e8 {
color: rgba(var(--gruv-dark-text-primary))
}
.theme-dark .button_e131a9.buttonColor_e131a9.buttonActive_e131a9 {
background-color: rgba(var(--gruv-dark-button-positive-default), 0.1)
}
.theme-dark .button_e131a9.buttonColor_e131a9.buttonActive_e131a9:hover {
background-color: rgba(var(--gruv-dark-button-positive-default), 0.2)
}
/* Input / Output Volume slider (context menu) */
:where(.visual-refresh) .mini_a562c8 .grabber_a562c8, :where(.visual-refresh) .slider_a562c8 .grabber_a562c8 {
background-color: rgba(var(--gruv-dark-text-primary))
}
[class*=notches_] {
background-color: rgba(var(--gruv-dark-bg3))
}
[class^=control_] [class*=checked_],
#vc-spotify-player [class*=barFill_] {
background-color: rgba(var(--gruv-dark-accent-hover), 0.8) !important;
}
.slider__87bf1 > rect {
fill: rgba(var(--gruv-dark-text-hard));
}
.slider__87bf1 svg > path {
fill: rgba(var(--gruv-dark-bg))
}
.container__87bf1 {
background-color: rgba(var(--gruv-dark-bg2)) !important
}
.checked__87bf1 {
background-color: rgba(var(--gruv-dark-yellow-dark)) !important;
}
/* "Share your screen" button */
.theme-dark [class*="experimentButton_"][class*="buttonColor_"][class*="buttonActive_"] {
background-color: rgba(var(--gruv-dark-green-dark), 0.2);
border: 1px solid rgba(var(--gruv-dark-green-dark), 0.25);
}
.theme-dark [class*="experimentButton_"][class*="buttonColor_"][class*="buttonActive_"]:hover {
background-color: rgba(var(--gruv-dark-green-dark), 0.4);
border: 1px solid rgba(var(--gruv-dark-green-dark), 0.3);
}
/* call container bg */
[class^=callContainer],
[class^=callContainer] [class^=scroller_] {
background-color: rgba(var(--gruv-dark-bg-hard));
}
/* Room preview animation */
.gradientBackground__11664 {
background: rgba(var(--gruv-dark-bg)) !important
}
.backgroundDark__11664 {
background: rgba(var(--gruv-dark-bg)) !important
}
.foregroundRing__11664 {
background: rgba(var(--gruv-dark-accent-hover), 0.3) !important
}
.foregroundBase__11664 {
background: rgba(var(--gruv-dark-accent-hover), 1) !important
}
/* Online statuses */
[mask^="url(#svg-mask-status-online"] {
fill: rgba(var(--gruv-dark-status-online));
}
[mask^="url(#svg-mask-status-dnd"] {
fill: rgba(var(--gruv-dark-status-dnd));
}
[mask^="url(#svg-mask-status-idle"] {
fill: var(--gruv-dark-status-idle);
}
[mask^="url(#svg-mask-status-offline"] {
fill: rgba(var(--gruv-dark-status-offline));
}
[class^=avatarWrapper_] {
[aria-label*=online i] svg > svg > rect {
fill: rgba(var(--gruv-dark-status-online)) !important;
}
}
[class^=avatarWrapper_] {
[aria-label*=idle i] svg > svg > rect {
fill: rgba(var(--gruv-dark-status-idle)) !important;
}
}
[class^=avatarWrapper_] {
[aria-label*=dnd i] svg > svg > rect {
fill: rgba(var(--gruv-dark-status-dnd)) !important;
}
}
[class^=avatarWrapper_] {
[aria-label*=invisible i] svg > svg > rect {
fill: rgba(var(--gruv-dark-status-offline)) !important;
}
}
rect[fill="#43a25a"] {
fill: var(--status-online);
}
rect[fill="#ca9654"] {
fill: var(--status-idle);
}
rect[fill="#d83a42"] {
fill: var(--status-dnd);
}
rect[fill="#82838b"] {
fill: var(--status-offline);
}
div.status_a423bd {
background-color: var(--status-online) !important;
}
/* Screenshare icon */
.icon_c9d15c > path {
fill: rgba(var(--gruv-dark-accent))
}
[class^=callContainer] [class^=root] {
background-color: rgba(var(--gruv-dark-bg-hard)) !important
}
.flex__7c0ba .lineClamp1__4bd52 {
color: rgba(var(--gruv-dark-text-hard)) !important
}
/* Vesktop plugins / themes */
.vc-addon-card {
border: 1px solid rgba(var(--gruv-dark-border-default))
}
/* Use solid background for banners in the "Discover" category */
.theme-dark .gradientOverlay_e9ef78,
.theme-dark .bannerGradient__955a3 {
background-color: rgba(var(--gruv-dark-bg));
border-bottom: 1px solid rgba(var(--gruv-dark-border-hover))
}
/* Share your screen / Stop stream / change windows / ets bototm button inside call window */
[class^="colorable_"][class*="greenGlow_"] {
background-color: rgba(var(--gruv-dark-green-dark), 0.2);
}
[class^="colorable_"][class*="greenGlow_"]:hover,
[class^="colorable_"][class*="greenGlow_"][class*="popoutOpen_"] {
background-color: rgba(var(--gruv-dark-green-dark), 0.4);
}
/* Add right border for left section */
.visual-refresh .sidebarList_c48ade {
border-right: 1px solid rgba(var(--gruv-dark-border-default))
}
/* N new messages */
.newMessagesBar__0f481 {
background-color: rgba(var(--gruv-dark-bg-soft));
color: rgba(var(--gruv-dark-text-primary))
}
.visual-refresh .barButtonAlt__0f481:hover {
background-color: transparent
}
/* Open voice button */
/* .custom-profile-theme.theme-dark .themeColor_fb7f94.secondary_fb7f94 { */
/* background-color: rgba(var(--gruv-dark-button-alt-default)) */
/* } */
/* .custom-profile-theme.theme-dark .themeColor_fb7f94.secondary_fb7f94:hover { */
/* background-color: rgba(var(--gruv-dark-button-alt-hover)) */
/* } */
.custom-profile-theme.theme-dark [class*=themeColor i][class*=secondary i] {
background-color: rgba(var(--gruv-dark-button-alt-default))
}
.custom-profile-theme.theme-dark [class*=themeColor i][class*=secondary i]:hover {
background-color: rgba(var(--gruv-dark-button-alt-hover))
}
.visual-refresh .section__00943 {
background-color: rgba(var(--gruv-dark-bg))
}
:where(.visual-refresh) .lookFilled__201d5.colorPrimary__201d5,
:where(.visual-refresh) .medium_a45028 .inner_a45028 {
background-color: rgba(var(--gruv-dark-bg))
}
.menuOverlay_af7fb7,
.card__39ec2 {
background-color: rgba(var(--gruv-dark-bg))
}
/* Background tweaks to fix Discord's inconsistent styling */
.connection_c7f964,
.connectContainer_c7f964,
.appDetailsContainer__50a54 {
background-color: rgba(var(--gruv-dark-bg-soft));
border: 1px solid rgba(var(--gruv-dark-border-default))
}
.background__1fed1,
.background__1fed1 > .fieldList__1fed1 {
background-color: var(--user-profile-overlay-background);
}
.badgeList__1fed1 {
background-color: transparent;
}
/* Hovering over gifs would cause them to go blank */
.result__2dc39:after {
content: normal;
}
/* Contrast for some action buttons was too high, so.. */
/* To see changes: Settings > Authorized Apps */
[class^="actionMenuButton_"] {
background-color: rgba(var(--gruv-dark-bg-soft));
border: 1px solid rgba(var(--gruv-dark-border-default));
border-radius: 12px
}
[class^="actionMenuButton_"]:hover {
background-color: rgba(var(--gruv-dark-bg));
border: 1px solid rgba(var(--gruv-dark-border-hover));
}
.visual-refresh .searchBar__35e86 {
border: none !important
}
/* Add border to account overview */
/* Settings > My Account */
[class^=accountProfileCard__] {
border: 1px solid rgba(var(--gruv-dark-border-default));
}
[class^=accountProfileCard__] {
box-shadow: 0 0 5px black !important
}
[class^=accountProfileCard__]:hover {
box-shadow: 0 0 10px black !important
}
.visual-refresh [class^=box_],
[class^=appDetailsContainer],
[class^=connectionOptionsWrapper] {
background-color: var(--background-base-low) !important
}
/* Make all titlebars the same */
.visual-refresh .title_f75fb {
background-color: rgba(var(--gruv-dark-bg-hard)) !important
}
/* Remove bottom border for server title section */
.visual-refresh [class^=header_] {
border-bottom: none !important
}
/* ==== Nuked elements ==== */
/* Top to bottom */
/* Quests banner */
.wrapper__0d616 {
display: none !important
}

View File

@@ -8,99 +8,62 @@
# @license: GNU Affero General Public License v3.0 (Included in LICENSE)
# Copyright (C) 2025, Jamie Albert
# ---
# Requires: Bash 4.0+
set -euo pipefail
# Global configuration variables
declare -gr INSTALL_DIR="/usr/local/bin"
declare -gr SCRIPTS_DIR="scripts"
declare -gr CONFIG_DIR="config"
declare -gr DICT_DIR="dict"
declare -ga TOOLS=("japg.sh" "jade.sh" "jau.sh" "jarm.sh")
declare -g SCRIPTS_DIR; SCRIPTS_DIR="$(cd "$(dirname "$(readlink -f "$0")")" && pwd)/scripts"
declare -g CONFIG_DIR; CONFIG_DIR="$(cd "$(dirname "$(readlink -f "$0")")" && pwd)/config"
declare -g DICT_DIR; DICT_DIR="$(cd "$(dirname "$(readlink -f "$0")")" && pwd)/dict"
declare -ga TOOLS=("pwgen.sh" "jade.sh" "jau.sh" "rclone_mount.sh")
declare -gr JADE_CONFIG_DIR="/usr/local/etc/jade.sh"
# ---
# @usage: error <exit_code> <message>
# @description: Print an error message to stderr and exit with a specific code.
# @arg: $1 - The exit code to use.
# @arg: $* - The error message to print.
# @return_code: [N] The specified exit code.
# ---
error() {
declare exit_code="$1"
shift
# Use printf -v for efficient string assignment (Bash 4+)
declare error_msg
# Include the exit code in the error message
printf -v error_msg 'error[%d]: %s\n' "$exit_code" "$*"
printf '%s' "$error_msg" >&2
exit "${exit_code}"
}
# ---
# @description: Print an informational message to stdout.
# @arg: $* - The message to print.
# ---
info() {
# Use printf -v for efficient string assignment (Bash 4+)
declare info_msg
printf -v info_msg '%s\n' "$*"
printf '%s' "$info_msg"
}
# ---
# @description: Perform initial setup checks. Verifies required directories exist.
# @global: INSTALL_DIR - The target directory for installed scripts.
# @global: SCRIPTS_DIR - Path to the local scripts directory.
# @global: CONFIG_DIR - Path to the local config directory.
# @global: DICT_DIR - Path to the local dict directory.
# @return_code: [2] Scripts directory not found.
# @return_code: [3] Config directory not found.
# @return_code: [4] Dict directory not found.
# shellcheck disable=1090,1091
# ---
setup() {
[[ -d $INSTALL_DIR ]] || sudo mkdir -p "$INSTALL_DIR" || error 1 "Failed to create installation directory $INSTALL_DIR"
[[ -d "${SCRIPTS_DIR}" ]] || error 2 "Scripts directory not found: ${SCRIPTS_DIR}"
[[ -d "${CONFIG_DIR}" ]] || error 3 "Config directory not found: ${CONFIG_DIR}"
[[ -d "${DICT_DIR}" ]] || error 4 "Dict directory not found: ${DICT_DIR}"
declare script_dir; script_dir="$(cd "$(dirname "$(readlink -f "$0")")" && pwd)"
. "${script_dir}/libs/libs_cradle.sh"
[[ -d $INSTALL_DIR ]] || sudo mkdir -p "$INSTALL_DIR" || cradle::error 1 "Failed to create installation directory $INSTALL_DIR"
[[ -d "${SCRIPTS_DIR}" ]] || cradle::error 2 "Scripts directory not found: ${SCRIPTS_DIR}"
[[ -d "${CONFIG_DIR}" ]] || cradle::error 3 "Config directory not found: ${CONFIG_DIR}"
[[ -d "${DICT_DIR}" ]] || cradle::error 4 "Dict directory not found: ${DICT_DIR}"
}
# ---
# @description: Copy a single tool and make it executable.
# @arg: $1 - The name of the tool/script to install.
# @global: INSTALL_DIR - The target directory for installed scripts.
# @global: SCRIPTS_DIR - The source directory for scripts.
# @global: CONFIG_DIR - The source directory for config files.
# @global: DICT_DIR - The source directory for dict files.
# @global: JADE_CONFIG_DIR - The target directory for jade.sh config.
# @return_code: [1] General error (inherits from set -e).
# @return_code: [1] General cradle::error (inherits from set -e).
# @return_code: [5] Source file not found.
# @return_code: [6] Copy failed for the tool.
# @return_code: [7] chmod failed for the tool.
# @return_code: [8] Failed to create jade config directory.
# @return_code: [9] Failed to copy config for jade.sh.
# @return_code: [10] Config template not found for jade.sh.
# @return_code: [11] Copy failed for japg.list.
# @return_code: [11] Copy failed for pwgen.list.
# ---
install_tool() {
declare tool="$1"
declare src_path
src_path=$(realpath "${SCRIPTS_DIR}/${tool}")
[[ -f $src_path ]] || error 5 "Source file not found: $tool"
[[ -f $src_path ]] || cradle::error 5 "Source file not found: $tool"
sudo cp "$src_path" "$INSTALL_DIR/" || error 6 "Copy failed for $tool"
sudo chmod 755 "$INSTALL_DIR/$tool" || error 7 "chmod failed for $tool"
info "Installed: $INSTALL_DIR/$tool"
sudo rm -f "${INSTALL_DIR}/${tool}"
sudo ln -s "$src_path" "$INSTALL_DIR/" || cradle::error 6 "Copy failed for $tool"
sudo chmod 755 "$INSTALL_DIR/$tool" || cradle::error 7 "chmod failed for $tool"
cradle::info "Installed: $INSTALL_DIR/$tool"
case ${tool} in
japg.sh)
declare dict_src="${DICT_DIR}/japg.list"
pwgen.sh)
declare dict_src="${DICT_DIR}/pwgen.list"
if [[ -f "${dict_src}" ]]; then
sudo cp -f "${dict_src}" /usr/share/dict/ || error 11 "Copy failed for japg.list"
info " [info]: Installed /usr/share/dict/japg.list"
sudo rm -f /usr/share/dict/pwgen.list
sudo ln -s "${dict_src}" /usr/share/dict/ || cradle::error 11 "Copy failed for pwgen.list"
cradle::info "Installed /usr/share/dict/pwgen.list"
else
info " [warn]: Dict file not found at '${dict_src}', skipping installation of /usr/share/dict/japg.list"
cradle::warn "Dict file not found at '${dict_src}', skipping installation of /usr/share/dict/pwgen.list"
fi
;;
jade.sh)
@@ -108,26 +71,20 @@ install_tool() {
declare jade_config_dest="${JADE_CONFIG_DIR}/jade.conf"
if [[ -f "${jade_config_src}" ]]; then
if [[ ! -f "${jade_config_dest}" ]]; then
sudo mkdir -p "${JADE_CONFIG_DIR}" || error 8 "Failed to create jade config directory"
sudo cp -f "${jade_config_src}" "${jade_config_dest}" || error 9 "Failed to copy config for jade.sh"
info " Installed: ${jade_config_dest} - manually set variables within this file."
sudo mkdir -p "${JADE_CONFIG_DIR}" || cradle::error 8 "Failed to create jade config directory"
sudo rm -f "${jade_config_dest}"
sudo ln -s "${jade_config_src}" "${jade_config_dest}" || cradle::error 9 "Failed to copy config for jade.sh"
cradle::info "Installed ${jade_config_dest} - manually set variables within this file."
else
info " [info]: ${jade_config_dest} already exists, not overwriting."
cradle::info "${jade_config_dest} already exists, not overwriting."
fi
else
error 10 " Config template not found: '${jade_config_src}'"
cradle::error 10 "Config template not found: '${jade_config_src}'"
fi
;;
*) info " [info]: No specific install steps for $tool" ;;
esac
}
# ---
# @description: Main routine to install all specified tools.
# @arg: $@ - Command-line arguments (currently unused).
# @global: TOOLS - Array of tool names to install.
# @return_code: [N] Errors from called functions (e.g., setup, install_tool).
# ---
main() {
setup
@@ -136,7 +93,7 @@ main() {
install_tool "$tool"
done
info "All tools installed successfully."
cradle::info "All tools installed successfully."
}
main "$@"

View File

@@ -1,29 +0,0 @@
#!/usr/bin/env bash
# ---
# @file_name: jalibs.sh
# @version: 1.0.0
# @description: lib files
# @author: Jamie Albert (empty_produce)
# @author_contact: <mailto:empty.produce@flatmail.me>
# @license: GNU Affero General Public License v3.0 (Included in LICENSE)
# Copyright (C) 2025, Jamie Albert
# ---
set -euo pipefail
# ---
# Output
# ---
text::error() {
declare error_msg exit_code="$1"
shift
printf -v error_msg 'error[%d]: %s\n' "$exit_code" "$*"
printf '%s' "$error_msg" >&2
exit "${exit_code}"
}
text::info() {
declare info_msg
printf -v info_msg '%s\n' "$*"
printf '%s' "$info_msg"
}

37
libs/libs_cradle.sh Normal file
View File

@@ -0,0 +1,37 @@
#!/usr/bin/env bash
# ---
# @file_name: libs_cradle.sh
# @version: 1.0.0
# @description: lib files
# @author: Jamie Albert (empty_produce)
# @author_contact: <mailto:empty.produce@flatmail.me>
# @license: GNU Affero General Public License v3.0 (Included in LICENSE)
# Copyright (C) 2025, Jamie Albert
# ---
set -euo pipefail
# Color definitions using 256-color codes
readonly RED=$'\033[0;38;5;167m'
readonly GREEN=$'\033[0;38;5;108m'
readonly YELLOW=$'\033[1;38;5;214m'
readonly NC=$'\033[0m'
cradle::error() {
declare error_msg exit_code="${1}"
shift
printf -v error_msg 'error[%d]: %s\n' "${exit_code}" "$*"
echo -ne "${RED}[e]${NC}: ${error_msg}" >&2
exit "${exit_code}"
}
cradle::info() {
declare info_msg
printf -v info_msg '%s\n' "$*"
echo -ne "${GREEN}[i]${NC}: ${info_msg}"
}
cradle::warn() {
declare warn_msg
printf -v warn_msg '%s\n' "$*"
echo -ne "${YELLOW}[w]${NC}: ${warn_msg}"
}

149
scripts/init/install_nvidia.sh Executable file
View File

@@ -0,0 +1,149 @@
#!/bin/bash
# NVIDIA Driver Installation Script for Fedora Workstation
# Check if the script is run with sudo
if [ "$EUID" -ne 0 ]; then
echo "Please run this script with sudo"
exit 1
fi
# Funtion to echo colored text
color_echo() {
local color="$1"
local text="$2"
case "$color" in
"red") echo -e "\033[0;31m$text\033[0m" ;;
"green") echo -e "\033[0;32m$text\033[0m" ;;
"yellow") echo -e "\033[1;33m$text\033[0m" ;;
"blue") echo -e "\033[0;34m$text\033[0m" ;;
*) echo "$text" ;;
esac
}
# Set variables
ACTUAL_USER=$SUDO_USER
ACTUAL_HOME=$(eval echo ~$SUDO_USER)
LOG_FILE="/var/log/nvidia_driver_installation.log"
# Function to generate timestamps
get_timestamp() {
date +"%Y-%m-%d %H:%M:%S"
}
# Function to handle errors
handle_error() {
local exit_code=$?
local message="$1"
if [ $exit_code -ne 0 ]; then
color_echo \"red\" "ERROR: $message"
exit $exit_code
fi
}
echo "";
echo "╔══════════════════════════════════════════════════════════╗";
echo "║ ║";
echo "║ ███╗ ██╗██╗ ██╗██╗██████╗ ██╗ █████╗ ║";
echo "║ ████╗ ██║██║ ██║██║██╔══██╗██║██╔══██╗ ║";
echo "║ ██╔██╗ ██║██║ ██║██║██║ ██║██║███████║ ║";
echo "║ ██║╚██╗██║╚██╗ ██╔╝██║██║ ██║██║██╔══██║ ║";
echo "║ ██║ ╚████║ ╚████╔╝ ██║██████╔╝██║██║ ██║ ║";
echo "║ ╚═╝ ╚═══╝ ╚═══╝ ╚═╝╚═════╝ ╚═╝╚═╝ ╚═╝ ║";
echo "║ ║";
echo "║ ██████╗ ██████╗ ██╗██╗ ██╗███████╗██████╗ ███████╗ ║";
echo "║ ██╔══██╗██╔══██╗██║██║ ██║██╔════╝██╔══██╗██╔════╝ ║";
echo "║ ██║ ██║██████╔╝██║██║ ██║█████╗ ██████╔╝███████╗ ║";
echo "║ ██║ ██║██╔══██╗██║╚██╗ ██╔╝██╔══╝ ██╔══██╗╚════██║ ║";
echo "║ ██████╔╝██║ ██║██║ ╚████╔╝ ███████╗██║ ██║███████║ ║";
echo "║ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚══════╝╚═╝ ╚═╝╚══════╝ ║";
echo "║ ║";
echo "╚══════════════════════════════════════════════════════════╝";
echo "";
echo "This script installs NVIDIA drivers on Fedora Workstation"
echo ""
echo "IMPORTANT: This script should be run outside of the graphical user interface (GUI)."
echo "To access a bare terminal window:"
echo "1. Press Ctrl+Alt+F3 to switch to a virtual console."
echo "2. Log in with your username and password."
echo "3. Run this script with sudo."
echo "4. After installation, reboot your system"
echo ""
echo "If you're not comfortable with this process, please seek assistance from an experienced user."
echo ""
echo "Please choose the installation method:"
echo "1) RPM Fusion method (recommended)"
echo "2) NVIDIA official .run file method"
read -p "Enter your choice (1 or 2): " choice
case $choice in
1)
color_echo "blue" "RPM Fusion method selected"
# Add RPM Fusion repositories
color_echo "yellow" "Adding RPM Fusion repositories..."
dnf install -y https://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm
dnf install -y https://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm
handle_error "Failed to add RPM Fusion repositories"
# Update the system
color_echo "yellow" "Updating the system..."
dnf update -y
handle_error "Failed to update the system"
# Install NVIDIA drivers
color_echo "yellow" "Installing NVIDIA drivers..."
dnf install -y akmod-nvidia
handle_error "Failed to install NVIDIA drivers"
# Install CUDA (optional)
read -p "Do you want to install CUDA? (y/n): " install_cuda
if [[ $install_cuda =~ ^[Yy]$ ]]; then
color_echo "yellow" "Installing CUDA..."
dnf install -y xorg-x11-drv-nvidia-cuda
handle_error "Failed to install CUDA"
fi
;;
2)
color_echo "blue" "NVIDIA official .run file method selected"
# Install necessary packages
color_echo "yellow" "Installing necessary packages..."
dnf install -y kernel-devel kernel-headers gcc make dkms acpid libglvnd-glx libglvnd-opengl libglvnd-devel pkgconfig
handle_error "Failed to install necessary packages"
# Download the latest NVIDIA driver
color_echo "yellow" "Downloading the latest NVIDIA driver..."
driver_url=$(curl -s https://www.nvidia.com/Download/processFind.aspx?psid=101&pfid=816&osid=12&lid=1&whql=1&lang=en-us&ctk=0 | grep -o 'https://[^"]*' | grep '.run' | head -n 1)
wget $driver_url -O /tmp/nvidia_driver.run
handle_error "Failed to download NVIDIA driver"
# Stop the display manager
color_echo "blue" "Stopping the display manager..."
systemctl isolate multi-user.target
handle_error "Failed to stop the display manager"
# Install the NVIDIA driver
color_echo "yellow" "Installing the NVIDIA driver..."
bash /tmp/nvidia_driver.run --silent
handle_error "Failed to install NVIDIA driver"
# Start the display manager
color_echo "blue" "Starting the display manager..."
systemctl isolate graphical.target
handle_error "Failed to start the display manager"
;;
*)
color_echo "red" "Invalid choice. Exiting."
exit 1
;;
esac
color_echo "green" "NVIDIA driver installation completed."
echo "Installation complete. Please reboot your system to apply changes."
read -p "Do you want to reboot now? (y/n): " reboot_choice
if [[ $reboot_choice =~ ^[Yy]$ ]]; then
color_echo "green" "Rebooting the system..."
reboot
else
color_echo "blue" "Reboot postponed. Please remember to reboot your system to complete the installation."
fi

View File

@@ -10,36 +10,23 @@
# ---
set -euo pipefail
error() {
declare error_msg exit_code="$1"
shift
printf -v error_msg 'error[%d]: %s\n' "$exit_code" "$*"
printf '%s' "$error_msg" >&2
exit "${exit_code}"
}
info() {
declare info_msg
printf -v info_msg '%s\n' "$*"
printf '%s' "$info_msg"
}
# ---
# @return_code: [2] Unable to source.
# shellcheck source=/usr/local/etc/jade.sh/jade.conf
# shellcheck disable=2015
# shellcheck disable=2015,1090,1091
# ---
setup() {
declare -r conf="/usr/local/etc/jade.sh/jade.conf"
[[ -f "${conf}" ]] && . "${conf}" || error 2 "unable to source '${conf}'"
declare script_dir; script_dir="$(cd "$(dirname "$(readlink -f "$0")")" && pwd)"
. "${script_dir}/../libs/libs_cradle.sh"
declare -r conf="../config/jade.conf"
[[ -f "${conf}" ]] && . "${conf}" || cradle::error 2 "unable to source '${conf}'"
}
# ---
# @return_code: [3] Download failed.
# ---
download_file() {
scp -q "${REMOTE_HOST}:${REMOTE_PATH}" "$LOCAL_PATH" || error 3 'Download failed'
info "Downloaded: $LOCAL_PATH"
scp -q "${REMOTE_HOST}:${REMOTE_PATH}" "$LOCAL_PATH" || cradle::error 3 'Download failed'
cradle::info "Downloaded: $LOCAL_PATH"
}
# ---
@@ -48,11 +35,11 @@ download_file() {
# @return_code: [6] Upload failed.
# ---
upload_file() {
[[ -f "$LOCAL_PATH" ]] || error 4 "Local file missing: $LOCAL_PATH"
ssh -q "${REMOTE_HOST}" "[[ -f '${REMOTE_PATH}' ]] && cp -f '${REMOTE_PATH}' '${REMOTE_PATH}.bak'" || error 5 'Failed to create remote backup'
scp -q "$LOCAL_PATH" "${REMOTE_HOST}:${REMOTE_PATH}" || error 6 'Upload failed'
info "Uploaded: $LOCAL_PATH"
info "Remote file backed up to: ${REMOTE_PATH}.bak"
[[ -f "$LOCAL_PATH" ]] || cradle::error 4 "Local file missing: $LOCAL_PATH"
ssh -q "${REMOTE_HOST}" "[[ -f '${REMOTE_PATH}' ]] && cp -f '${REMOTE_PATH}' '${REMOTE_PATH}.bak'" || cradle::error 5 'Failed to create remote backup'
scp -q "$LOCAL_PATH" "${REMOTE_HOST}:${REMOTE_PATH}" || cradle::error 6 'Upload failed'
cradle::info "Uploaded: $LOCAL_PATH"
cradle::info "Remote file backed up to: ${REMOTE_PATH}.bak"
}
# ---
@@ -62,7 +49,7 @@ upload_file() {
edit_file() {
download_file
if ! command -v "$EDITOR" >/dev/null; then
error 7 "Editor not found: '$EDITOR'"
cradle::error 7 "Editor not found: '$EDITOR'"
fi
"$EDITOR" "$LOCAL_PATH"
}
@@ -75,8 +62,8 @@ upload_compose() {
upload_file
ssh -q "${REMOTE_HOST}" \
"cd '$(dirname "$REMOTE_PATH")' && exec docker compose up -d --remove-orphans" \
|| error 8 'Remote docker compose up failed'
info 'Remote docker compose up -d completed'
|| cradle::error 8 'Remote docker compose up failed'
cradle::info 'Remote docker compose up -d completed'
}
# ---
@@ -87,12 +74,12 @@ upload_compose() {
upload_restart() {
ssh -q "${REMOTE_HOST}" \
"cd '$(dirname "$REMOTE_PATH")' && exec docker compose down" \
|| error 9 'Remote docker compose down failed'
|| cradle::error 9 'Remote docker compose down failed'
upload_file
ssh -q "${REMOTE_HOST}" \
"cd '$(dirname "$REMOTE_PATH")' && exec docker compose up -d --remove-orphans" \
|| error 11 'Remote docker compose up failed during restart'
info 'Remote docker compose restart completed'
|| cradle::error 11 'Remote docker compose up failed during restart'
cradle::info 'Remote docker compose restart completed'
}
# ---
@@ -111,12 +98,12 @@ main() {
-u) mode='upload' ; shift ;;
-uc) mode='up' ; shift ;;
-ur) mode='restart' ; shift ;;
*) error 10 "Unknown option: $1 (use -d, -u, -uc, -ur)" ;;
*) cradle::error 10 "Unknown option: $1 (use -d, -u, -uc, -ur)" ;;
esac
done
command -v scp >/dev/null || error 12 "'scp' not found"
command -v ssh >/dev/null || error 13 "'ssh' not found"
command -v scp >/dev/null || cradle::error 12 "'scp' not found"
command -v ssh >/dev/null || cradle::error 13 "'ssh' not found"
case "$mode" in
download) download_file ;;
@@ -124,7 +111,7 @@ main() {
up) upload_compose ;;
restart) upload_restart ;;
'') edit_file ;;
*) error 14 "Unexpected mode: $mode" ;;
*) cradle::error 14 "Unexpected mode: $mode" ;;
esac
}

View File

@@ -1,91 +0,0 @@
#!/usr/bin/env bash
# ---
# @file_name: japg.sh
# @version: 1.0.0
# @description: Generate a passphrase
# @author: Jamie Albert (empty_produce)
# @author_contact: <mailto:empty.produce@flatmail.me>
# @license: GNU Affero General Public License v3.0 (Included in LICENSE)
# Copyright (C) 2025, Jamie Albert
# ---
set -euo pipefail
declare -gr WORD_LIST='/usr/share/dict/japg.list'
declare -gr DEFAULT_DELIM='-'
declare -gi DEFAULT_WORDS=5
# ---
# @usage: error <exit_code> <message>
# @description: Print an error message to stderr and exit with a specific code.
# @arg: $1 - The exit code to use.
# @arg: $* - The error message to print.
# @return_code: [N] The specified exit code.
# ---
error() {
declare exit_code="$1"
shift
printf 'error: %s\n' "$*" >&2
exit "${exit_code}"
}
# ---
# @description: Print an informational message to stdout.
# @arg: $* - The message to print.
# ---
info() {
printf '%s\n' "$*"
}
# ---
# @description: Perform initial setup checks.
# Verifies the word list file exists and xclip is installed.
# @global: WORD_LIST - Path to the word list file.
# @return_code: [2] Word-list file not found.
# @return_code: [3] Required tool 'xclip' not found.
# ---
setup() {
[[ -f "${WORD_LIST}" ]] || error 2 "Word-list not found: $WORD_LIST"
command -v xclip >/dev/null || error 3 "xclip not found (install xclip)"
}
# ---
# @description: Main routine to generate and copy the passphrase.
# @arg: $1 - Number of words (optional, defaults to DEFAULT_WORDS).
# @arg: $2 - Delimiter (optional, defaults to DEFAULT_DELIM).
# @global: WORD_LIST - Path to the word list file.
# @global: DEFAULT_WORDS - Default number of words.
# @global: DEFAULT_DELIM - Default delimiter.
# @return_code: [1] General error (inherits from set -e).
# @return_code: [4] Invalid number of words provided.
# @return_code: [2] Word-list not found (inherited from setup).
# @return_code: [3] xclip not found (inherited from setup).
# ---
main() {
setup
declare num_words="${1:-$DEFAULT_WORDS}"
declare delim="${2:-$DEFAULT_DELIM}"
[[ "${num_words}" =~ ^[1-9][0-9]*$ ]] || error 4 "num_words must be a positive integer"
declare -a words
mapfile -t words < <(shuf -n "$num_words" "$WORD_LIST") || error 1 "Failed to read words from list"
declare i
for i in "${!words[@]}"; do
words[i]="${words[i]^}"
done
declare dig_idx=$(( RANDOM % num_words ))
words[dig_idx]+=$(( RANDOM % 10 ))
declare pass
IFS="$delim"
printf -v pass '%s' "${words[*]}" || error 1 "Failed to construct passphrase"
printf '%s' "$pass" | xclip -selection clipboard || error 1 "Failed to copy passphrase to clipboard"
info "Generated password: $pass"
info "Password copied to clipboard."
}
main "$@"

View File

@@ -1,63 +0,0 @@
#!/usr/bin/env bash
# ---
# @file_name: jarm.sh
# @version: 1.0.0
# @description: Lazy script for mounting rclone
# @author: Jamie Albert (empty_produce)
# @author_contact: <mailto:empty.produce@flatmail.me>
# @license: GNU Affero General Public License v3.0 (Included in LICENSE)
# Copyright (C) 2025, Jamie Albert
# ---
set -euo pipefail
# ---
# @usage: error <exit_code> <message>
# @description: Print an error message to stderr and exit with a specific code.
# @arg: $1 - The exit code to use.
# @arg: $* - The error message to print.
# @return_code: [N] The specified exit code.
# ---
error() {
declare error_msg exit_code="$1"
shift
printf -v error_msg 'error[%d]: %s\n' "$exit_code" "$*"
printf '%s' "$error_msg" >&2
exit "${exit_code}"
}
# ---
# @description: Print an informational message to stdout.
# @arg: $* - The message to print.
# ---
info() {
declare info_msg
printf -v info_msg '%s\n' "$*"
printf '%s' "$info_msg"
}
# ---
# @description: Mount koofr_vault to location
# ---
rclone_mount_koofr() {
info "Mounting koofr..."
/usr/bin/rclone mount koofr: /home/jamie/dao/storage/koofr &
}
# ---
# @description: Mount koofr_vault to location
# ---
rclone_mount_koofr_vault() {
info "Mounting vault..."
/usr/bin/rclone mount koofr_vault: /home/jamie/dao/storage/vault &
}
# ---
# @description: main function call
# @return_code: [2] Failed to mount koofr to dir.
# @return_code: [3] Failed to mount vault to dir.
main() {
rclone_mount_koofr || error 2 "Failed to mount koofr."
rclone_mount_koofr_vault || error 3 "Failed to mount vault."
}
main "$@"

View File

@@ -10,145 +10,122 @@
# ---
set -euo pipefail
# ---
# @usage: error <exit_code> <message>
# @description: Print an error message to stderr and exit with a specific code.
# @arg: $1 - The exit code to use.
# @arg: $* - The error message to print.
# @return_code: [N] The specified exit code.
# ---
error() {
declare exit_code="$1"
shift
declare error_msg
printf -v error_msg 'error[%d]: %s\n' "$exit_code" "$*"
printf '%s' "$error_msg" >&2
exit "${exit_code}"
}
# ---
# @description: Print an informational message to stdout.
# @arg: $* - The message to print.
# ---
info() {
declare info_msg
printf -v info_msg '%s\n' "$*"
printf '%s' "$info_msg"
}
# ---
# @description: Perform initial setup checks. Verifies required base commands (dnf, sudo) are available.
# @return_code: [2] Required tool 'sudo' not found.
# @return_code: [3] Required tool 'dnf' not found.
# shellcheck disable=1091
# ---
setup() {
command -v sudo >/dev/null || error 2 "sudo not found"
sudo sh -c 'command -v dnf >/dev/null' || error 3 "dnf not found (script requires a DNF-based system)"
declare script_dir; script_dir="$(cd "$(dirname "$(readlink -f "$0")")" && pwd)"
. "${script_dir}/../libs/libs_cradle.sh"
command -v sudo >/dev/null || cradle::error 2 "sudo not found"
sudo sh -c 'command -v dnf >/dev/null' || cradle::error 3 "dnf not found (script requires a DNF-based system)"
}
# ---
# @description: Install package if missing.
# @arg: $1 - The name of the package/command to check and install.
# @return_code: [1] General error (inherits from set -e).
# @return_code: [1] General cradle::error (inherits from set -e).
# @return_code: [4] Failed to install the specified package.
# ---
install_if_missing() {
declare pkg="$1"
if ! command -v "$pkg" &>/dev/null; then
info "Installing missing dependency: $pkg"
sudo dnf install -y "$pkg" || error 4 "Failed to install $pkg"
cradle::info "Installing missing dependency: $pkg"
sudo dnf install -y "$pkg" || cradle::error 4 "Failed to install $pkg"
else
info "Dependency satisfied: $pkg"
cradle::info "Dependency satisfied: $pkg"
fi
}
# ---
# @description: Refresh DNF cache and update all packages.
# @return_code: [1] General error (inherits from set -e).
# @return_code: [1] General cradle::error (inherits from set -e).
# @return_code: [5] Failed to refresh DNF cache.
# @return_code: [6] DNF update failed.
# ---
run_dnf_update() {
info "Refreshing DNF cache..."
sudo dnf -y makecache --refresh || error 5 "Failed to refresh DNF cache"
cradle::info "Refreshing DNF cache..."
sudo dnf -y makecache --refresh || cradle::error 5 "Failed to refresh DNF cache"
info "Updating all packages..."
sudo dnf -y update || error 6 "DNF update failed"
cradle::info "Updating all packages..."
sudo dnf -y update || cradle::error 6 "DNF update failed"
}
# ---
# @description: Handle leftover RPM configuration files.
# @return_code: [1] General error (inherits from set -e).
# @return_code: [1] General cradle::error (inherits from set -e).
# @return_code: [7] rpmconf execution failed.
# ---
handle_rpmconf() {
if command -v rpmconf &>/dev/null; then
info "Handling leftover RPM configuration files..."
sudo rpmconf -a || error 7 "rpmconf execution failed"
cradle::info "Handling leftover RPM configuration files..."
sudo rpmconf -a || cradle::error 7 "rpmconf execution failed"
else
info "rpmconf not available; skipping config file handling"
cradle::info "rpmconf not available; skipping config file handling"
fi
}
# ---
# @description: Install security updates if any exist.
# @return_code: [1] General error (inherits from set -e).
# @return_code: [1] General cradle::error (inherits from set -e).
# @return_code: [8] Security update failed.
# ---
install_security_updates() {
info "Checking for security updates..."
cradle::info "Checking for security updates..."
# dnf check-update returns 100 if updates are available, 1 on error, 0 if not.
# We only want to proceed if it returns 100 (success with updates) or 0 (no updates).
# Using || true prevents set -e from triggering on exit code 100.
if sudo dnf check-update --security &>/dev/null || [[ $? -eq 100 ]]; then
info "Installing security updates..."
sudo dnf -y update --security || error 8 "Security update failed"
cradle::info "Installing security updates..."
sudo dnf -y update --security || cradle::error 8 "Security update failed"
else
info "No security updates available."
cradle::info "No security updates available."
fi
}
# ---
# @description: Remove unused packages and clean cache.
# @return_code: [1] General error (inherits from set -e).
# @return_code: [1] General cradle::error (inherits from set -e).
# @return_code: [9] DNF autoremove failed.
# @return_code: [10] DNF clean failed.
# ---
cleanup_packages() {
info "Removing unused dependencies..."
sudo dnf -y autoremove || error 9 "DNF autoremove failed"
cradle::info "Removing unused dependencies..."
sudo dnf -y autoremove || cradle::error 9 "DNF autoremove failed"
info "Cleaning cached package data..."
sudo dnf clean all || error 10 "DNF clean failed"
cradle::info "Cleaning cached package data..."
sudo dnf clean all || cradle::error 10 "DNF clean failed"
}
# ---
# @description: Update Flatpak applications and remove unused runtimes.
# @return_code: [1] General error (inherits from set -e).
# @return_code: [1] General cradle::error (inherits from set -e).
# @return_code: [11] Flatpak update failed.
# @return_code: [12] Flatpak cleanup failed.
# ---
update_flatpak() {
if command -v flatpak &>/dev/null; then
info "Updating Flatpak applications..."
flatpak update -y || error 11 "Flatpak update failed"
cradle::info "Updating Flatpak applications..."
flatpak update -y || cradle::error 11 "Flatpak update failed"
info "Removing unused Flatpak runtimes..."
flatpak uninstall --unused -y || error 12 "Flatpak cleanup failed"
cradle::info "Removing unused Flatpak runtimes..."
flatpak uninstall --unused -y || cradle::error 12 "Flatpak cleanup failed"
else
info "Flatpak not installed; skipping Flatpak updates"
cradle::info "Flatpak not installed; skipping Flatpak updates"
fi
}
# ---
# @description: Main routine.
# @arg: $@ - Command-line arguments (currently unused).
# @return_code: [1] General error (inherits from set -e).
# @return_code: [1] General cradle::error (inherits from set -e).
# @return_code: [N] Errors from called functions (e.g., setup, install_if_missing, etc.).
# ---
main() {
setup
info "Starting system updates..."
cradle::info "Starting system updates..."
install_if_missing rpmconf
install_if_missing flatpak
run_dnf_update
@@ -156,7 +133,7 @@ main() {
install_security_updates
cleanup_packages
update_flatpak
info "System updates completed successfully."
cradle::info "System updates completed successfully."
}
main "$@"

66
scripts/pwgen.sh Executable file
View File

@@ -0,0 +1,66 @@
#!/usr/bin/env bash
# ---
# @file_name: pwgen.sh
# @version: 1.0.1
# @description: Generate a passphrase
# @author: Jamie Albert (empty_produce)
# @author_contact: <mailto:empty.produce@flatmail.me>
# @license: GNU Affero General Public License v3.0 (Included in LICENSE)
# Copyright (C) 2025, Jamie Albert
# ---
set -euo pipefail
declare -gr WORD_LIST='/usr/share/dict/japg.list'
declare -gr DEFAULT_DELIM='-'
declare -gi DEFAULT_WORDS=5
# ---
# @return_code: [2] Word-list file not found.
# @return_code: [3] Required tool 'xclip' not found.
# shellcheck disable=1091,1090
# ---
setup() {
declare script_dir; script_dir="$(cd "$(dirname "$(readlink -f "$0")")" && pwd)"
. "${script_dir}/../libs/libs_cradle.sh"
[[ -f "${WORD_LIST}" ]] || cradle::error 2 "Word-list not found: $WORD_LIST"
command -v xclip >/dev/null || cradle::error 3 "xclip not found (install xclip)"
}
# ---
# @arg: $1 - Number of words (optional, defaults to DEFAULT_WORDS).
# @arg: $2 - Delimiter (optional, defaults to DEFAULT_DELIM).
# @return_code: [1] General cradle::error (inherits from set -e).
# @return_code: [4] Invalid number of words provided.
# @return_code: [2] Word-list not found (inherited from setup).
# @return_code: [3] xclip not found (inherited from setup).
# ---
main() {
setup
declare num_words="${1:-$DEFAULT_WORDS}"
declare delim="${2:-$DEFAULT_DELIM}"
[[ "${num_words}" =~ ^[1-9][0-9]*$ ]] || cradle::error 4 "num_words must be a positive integer"
declare -a words
mapfile -t words < <(shuf -n "$num_words" "$WORD_LIST") || cradle::error 1 "Failed to read words from list"
declare i
for i in "${!words[@]}"; do
words[i]="${words[i]^}"
done
declare dig_idx=$(( RANDOM % num_words ))
words[dig_idx]+=$(( RANDOM % 10 ))
declare pass
IFS="$delim"
printf -v pass '%s' "${words[*]}" || cradle::error 1 "Failed to construct passphrase"
printf '%s' "$pass" | xclip -selection clipboard || cradle::error 1 "Failed to copy passphrase to clipboard"
cradle::info "Generated password: $pass"
cradle::info "Password copied to clipboard."
}
main "$@"

32
scripts/rclone_mount.sh Executable file
View File

@@ -0,0 +1,32 @@
#!/usr/bin/env bash
# ---
# @file_name: rclone_mount.sh
# @version: 1.0.0
# @description: Lazy script for mounting rclone
# @author: Jamie Albert (empty_produce)
# @author_contact: <mailto:empty.produce@flatmail.me>
# @license: GNU Affero General Public License v3.0 (Included in LICENSE)
# Copyright (C) 2025, Jamie Albert
# ---
set -euo pipefail
rclone_mount_koofr() {
echo "Mounting koofr..."
/usr/bin/rclone mount koofr: /home/jamie/dao/storage/koofr &
}
rclone_mount_koofr_vault() {
echo "Mounting vault..."
/usr/bin/rclone mount koofr_vault: /home/jamie/dao/storage/vault &
}
# ---
# @return_code: [2] Failed to mount koofr to dir.
# @return_code: [3] Failed to mount vault to dir.
# ---
main() {
rclone_mount_koofr || { echo "[2] Failed to mount koofr."; exit 2; }
rclone_mount_koofr_vault || { echo "[2] Failed to mount koofr vault."; exit 3; }
}
main "$@"