Compare commits

...

10 commits

Author SHA1 Message Date
5b03adaaa9
updated scripts 2025-10-20 19:02:42 -05:00
devaine
2a7bd2c250
feat(server): added a new server script for desec, updates all dns' 2025-08-10 17:20:10 -05:00
devaine
016b951047
fix + feat: added a new alert system for when battery is close to 0% 2025-08-07 11:45:47 -05:00
devaine
a7967a86d7
test: no longer daemon + added 0% alert every 5 sec, bat status is back 2025-08-04 13:00:42 -05:00
devaine
16690836d6
refactor: refactored battery bash scripts into a C++ daemon 2025-07-29 15:05:52 -05:00
devaine
f5532e89ca
mild tweaking, just added "discharing" LOL 2025-04-27 23:15:07 -05:00
devaine
db605c6c98
fix: changing FULL_BATTERY value + add condition + var add
mild fixes + additions
2025-04-26 13:32:10 -05:00
devaine
9b374bb70d
feat: added notifications & daemons + simplified naming
notifications are for `dunst` a notification handler for my setup
I added volume, charging, battery, time, and brightness notifications
2025-04-26 10:22:34 -05:00
devaine
413b470d99
forgot to add gitignore to .gitignore 2024-12-08 12:40:35 -06:00
devaine
dfd00f9832
Adding Scripts 2024-12-08 12:37:25 -06:00
18 changed files with 925 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
.env
server-scripts/desec/public_ip

View file

@ -0,0 +1,75 @@
#!/bin/bash
# Constants (access to display)
export DISPLAY=:0
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus"
# Find out which battery is the laptop's battery
BATTERY=$(acpi | grep -vwE "(unavailable)" | grep -o '[0-9]' | head -n 1)
# Daemon Constants
WARNING_PERCENT=35
FULL_PERCENT=98
BAT_PERCENT=$(acpi -b | grep "Battery $BATTERY" | head -n 1 | grep -P -o "[0-9]+(?=%)")
DISCHARGING_COUNT=$(acpi -b | grep "Battery $BATTERY" | grep -c "Discharging")
NOTCHARGING_COUNT=$(acpi -b | grep "Battery $BATTERY" | grep "until" | grep -c "Not Charging")
## Conditioning Files
LOW_BAT_FILE=/tmp/battery_low
FULL_BAT_FILE=/tmp/battery_full
# Functions
battery-full() {
notify-send "Battery Full" "Battery is fully charged!" -i "battery-full-charged" -r 9991 -t 5000
touch $FULL_BAT_FILE
rm -rf $LOW_BAT_FILE
}
battery-low() {
notify-send "Low Battery" "${BAT_PERCENT}% of battery remaining." -u critical -i "battery-caution" -r 9991 -t 5000
touch $LOW_BAT_FILE
rm -rf $FULL_BAT_FILE
}
battery-normal() {
if [ "$1" == "Normal" ]; then
rm $FULL_BAT_FILE
elif [ "$1" == "Charging" ]; then
rm $LOW_BAT_FILE
fi
}
# IF the batttery is discharging AND there is a FULL_BAT_FILE exists AND battery is less than 99%
if [ "$BAT_PERCENT" -lt $FULL_PERCENT ] && [ "$DISCHARGING_COUNT" -eq 1 ] && [ -f $FULL_BAT_FILE ]; then
#echo "hit normal + full file exists + less than full %"
battery-normal "Normal"
# If charging, AND less than full percentage AND LOW_BAT_FILE exists:
elif [ "$BAT_PERCENT" -lt $FULL_PERCENT ] && [ "$DISCHARGING_COUNT" -eq 0 ] && [ -f "$EMPTY_BAT_FILE" ]; then
#echo "hit normal + warning file exists + more than warning %"
battery-normal "Charging"
fi
# IF the battery is charging AND is full (+ hasn't show any notif yet):
if [ "$BAT_PERCENT" -ge $FULL_PERCENT ] && [ ! -f $FULL_BAT_FILE ] && [ "$DISCHARGING_COUNT" = 0 ]; then
#echo "hit full + charging"
battery-full
# Another condition, battery could be full, yet it won't be charging:
elif [ "$BAT_PERCENT" -ge $FULL_PERCENT ] && [ "$NOTCHARGING_COUNT" = 1 ] && [ ! -f $LOW_BAT_FILE ]; then
#echo "hit full + not charging"
battery-full
# IF the battery is low and it's discharging (+ hasn't shown any notif yet):
elif [ "$BAT_PERCENT" -le $WARNING_PERCENT ] && [ "$DISCHARGING_COUNT" -eq 1 ] && [ ! -f $LOW_BAT_FILE ]; then
#echo "hit low + discharging"
battery-low
# If LOW_BAT_FILE Exists, Spam Until It's Charging
elif [ "$BAT_PERCENT" -le $WARNING_PERCENT ] && [ "$DISCHARGING_COUNT" -eq 1 ] && [ -f $LOW_BAT_FILE ]; then
notify-send "Low Battery" "${BAT_PERCENT}% of battery remaining." -u critical -i "battery-caution" -r 9991 -t 5000
fi
# Debug commands
#echo "$BAT_PERCENT is the battery percent"
#echo "$DISCHARGING_COUNT -- 1 = discharging, 0 = charging"

View file

@ -0,0 +1,5 @@
#!/bin/bash
while true; do
~/.scripts/notifs/battery
sleep 1
done

View file

@ -0,0 +1,28 @@
#!/bin/bash
export DISPLAY=:0
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus"
# Find out which battery is the laptop's battery
BATTERY=$(acpi | grep -vwE "(unavailable)" | grep -o '[0-9]' | head -n 1)
# 1 = Charging
# 0 = Discharging
BAT_CHARGING=$1
# Filtering one more time to find the percentage of the laptop's battery level
BAT_LEVEL=$(acpi -b | grep "Battery $BATTERY" | grep -P -o '[0-9]+(?=%)')
CHARGE_FILE=/tmp/laptop-charging
DISCHARGE_FILE=/tmp/laptop-discharging
# Notification handling
if [ "$BAT_CHARGING" -eq 1 ] && [ ! -f $CHARGE_FILE ]; then
rm $DISCHARGE_FILE
touch $CHARGE_FILE
/usr/bin/notify-send "Charging" "Charging battery at ${BAT_LEVEL}%" -u low -i "battery-level-50-charging-symbolic" -t 5000 -r 9991
elif [ "$BAT_CHARGING" -eq 0 ] && [ ! -f $DISCHARGE_FILE ]; then
rm $CHARGE_FILE
touch $DISCHARGE_FILE
/usr/bin/notify-send "Discharging" "${BAT_LEVEL}% remaining" -u low -i "battery-level-70-symbolic" -t 5000 -r 9991
fi

BIN
daemons/battery-daemon Executable file

Binary file not shown.

207
daemons/battery-daemon.cpp Normal file
View file

@ -0,0 +1,207 @@
#include <atomic>
#include <chrono>
#include <csignal>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <sched.h> // pid_t data type
#include <string>
#include <sys/select.h>
#include <thread>
#include <unistd.h> // For fork();
using namespace std;
// atomic type => ensure that variable can be safely accessed and modified.
// // 1 = Suddenly at 0%, 0 = Not at 0%
atomic<int> BAT_EMPTY(0);
// If another instance of this program is running...
const char *lockFilePath = "/tmp/bat-daemon-run";
// Checks if the file exists. (Another instance is running)
bool isRunning() {
ifstream lockFile(lockFilePath);
return lockFile.good();
}
// Creates file w/ PID
void createLockFile() {
ofstream lockFile(lockFilePath);
lockFile << getpid();
}
// Removes file.
void removeLockFile() { remove(lockFilePath); }
void send_notifs_empty() {
while (true) {
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 100000;
ifstream BAT_PERCENT_FILE("/sys/class/power_supply/BAT0/capacity");
int BAT_PERCENT;
BAT_PERCENT_FILE >> BAT_PERCENT;
string command =
"notify-send 'Low Battery' '<b>ALERT!</b> " + to_string(BAT_PERCENT) +
"% Battery Remaining.' -u critical -i 'battery-caution' -t 5000";
// If battery is empty...
if (BAT_EMPTY.load() == 1) {
system(command.c_str());
this_thread::sleep_for(chrono::seconds(5));
} else {
select(0, NULL, NULL, NULL, &tv);
}
}
}
void send_notifs_warn(const int &percent) {
// Formulate command
string command =
"notify-send 'Low Battery' '" + to_string(percent) +
"% of battery remaining.' -u critical -i 'battery-caution' -t 5000";
// Execute command as a C-String (same contents, but compatible with C++ code)
// "Returns a pointer to an array that contains the contents of the variable"
system(command.c_str());
}
void send_notifs_charge(const int &percent, const int status) {
string command;
switch (status) {
case 1:
command = "notify-send 'Charging' 'Charging battery at " +
to_string(percent) +
"%' -u low -i 'battery-level-50-charging-symbolic' -t 5000";
break;
case 0:
command = "notify-send 'Discharging' '" + to_string(percent) +
"% remaining' -u low -i 'battery-level-70-symbolic' -t 5000";
break;
}
system(command.c_str());
}
void send_notifs_full() {
string command = "notify-send 'Battery Full' 'Battery is fully charged!' -i "
"'battery-full-charged' -t 5000";
system(command.c_str());
}
// Checks battery info. (Charging, Discharging, etc.)
void battery() {
int OLD_BAT_PERCENT = 100; // Maxing out to prevent bugs
int CHARGE = 0; // 1 = Charging, 0 = Discharging
int BAT_FULL = 0; // 1 = Full, 0 = Not Full
while (true) {
int BAT_WARN = 35;
// Read and Grab File Info:
// ifstream (input file stream) class: operates on files (I/O)
ifstream BAT_STATUS_FILE("/sys/class/power_supply/BAT0/status");
string BAT_STATUS;
ifstream BAT_PERCENT_FILE("/sys/class/power_supply/BAT0/capacity");
int BAT_PERCENT;
// If it can't extract info, exit.
if (!(BAT_PERCENT_FILE >> BAT_PERCENT) ||
!(BAT_STATUS_FILE >> BAT_STATUS)) {
exit(EXIT_FAILURE);
}
// Timing:
// timeval = Time Value accurate from microseconds to years.
struct timeval tv;
// Set intervals: 0sec + 100 milsec.
tv.tv_sec = 0;
tv.tv_usec = 100000;
// If the actual battery is charging, update all values
if (BAT_STATUS == "Charging") {
if (BAT_PERCENT < 99 && CHARGE == 0) {
CHARGE = 1;
OLD_BAT_PERCENT = BAT_PERCENT;
BAT_FULL = 0;
send_notifs_charge(BAT_PERCENT, CHARGE);
} else if (BAT_PERCENT >= 99 && BAT_FULL == 0) {
BAT_FULL = 1;
CHARGE = 1;
send_notifs_full();
} else if (BAT_PERCENT > OLD_BAT_PERCENT) {
OLD_BAT_PERCENT = BAT_PERCENT;
}
if (BAT_EMPTY.load() == 1) {
BAT_EMPTY.store(0);
}
}
// If the actual battery is discharging, update all values
if (BAT_STATUS == "Discharging") {
if (CHARGE == 1) {
CHARGE = 0;
send_notifs_charge(BAT_PERCENT, CHARGE);
} else if (BAT_PERCENT < 99 && BAT_FULL == 1) {
BAT_FULL = 0;
} else if (BAT_PERCENT <= BAT_WARN && BAT_PERCENT < OLD_BAT_PERCENT) {
OLD_BAT_PERCENT = BAT_PERCENT;
send_notifs_warn(BAT_PERCENT);
}
// Change value of BAT_EMPTY (alert notification)
if (BAT_PERCENT < 10 && BAT_EMPTY.load() == 0) {
BAT_EMPTY.store(1);
}
}
select(0, NULL, NULL, NULL, &tv);
}
}
// Initializer
int main() {
// Change directory to root
chdir("/");
// Redirects all streams to /dev/null
// freopen("/dev/null", "r", stdin);
// freopen("/dev/null", "w", stdout);
// freopen("/dev/null", "w", stderr);
if (isRunning()) {
ifstream lockFile(lockFilePath);
int pid;
lockFile >> pid;
removeLockFile();
kill(pid, 1);
}
createLockFile();
thread bg(send_notifs_empty);
bg.detach();
battery();
return 0;
}

11
notifs/battery-status Executable file
View file

@ -0,0 +1,11 @@
#!/bin/bash
BATTERY=$(acpi | grep -vwE "(unavailable)" | grep -o '[0-9]' | head -n 1)
BAT_PERCENT=$(acpi -b | grep "Battery $BATTERY" | grep -P -o "[0-9]+(?=%)")
DISCHARGING_COUNT=$(acpi -b | grep "Battery $BATTERY" | grep -E "until|remaining" | grep -c "Discharging")
NOTCHARGING_COUNT=$(acpi -b | grep "Battery $BATTERY" | grep -c "Not Charging")
if [[ $DISCHARGING_COUNT -eq 0 ]] || [[ $NOTCHARGING_COUNT -eq 1 ]]; then
dunstify "Battery Status" "Battery is currently charging at ${BAT_PERCENT}%" -i "battery-level-50-charging-symbolic" -r 9991 -t 5000
else
dunstify "Battery Status" "Battery is currently discharging at ${BAT_PERCENT}%" -i "battery-level-50-symbolic" -r 9991 -t 5000
fi

33
notifs/brightness Executable file
View file

@ -0,0 +1,33 @@
#!/bin/bash
CURRENT_BRIGHTNESS=$(xbacklight -get)
bright_inc() {
dunstify "Increasing Brightness" "Current Brightness: ${CURRENT_BRIGHTNESS}%" -i "display-brightness-medium-symbolic" -t 5000 -r 9991
}
bright_dec() {
dunstify "Decreasing Brightness" "Current Brightness: ${CURRENT_BRIGHTNESS}%" -i "display-brightness-low-symbolic" -t 5000 -r 9991
}
keybind-func() {
echo "$CURRENT_BRIGHTNESS"
}
while test $# -gt 0; do
case "$1" in
inc)
bright_inc && exit 0
;;
dec)
bright_dec && exit 0
;;
keybind)
keybind-func && exit 0
;;
esac
done

15
notifs/info Executable file
View file

@ -0,0 +1,15 @@
#!/bin/bash
# Enter scripts directory
cd ~/.scripts/notifs || exit
# Constants
CURRENT_VOL=$(./volume keybind | grep -o '^[^ ]*')
CURRENT_MIC_VOL=$(./volume keybind | awk '{ print $2 }')
BRIGHTNESS=$(./brightness keybind)
# Variables for display, basically multiplies floats to integers
DISPLAY_VOL=$(awk '{ print $1 * $2 }' <<<"${CURRENT_VOL} 100")
DISPLAY_MIC_VOL=$(awk '{ print $1 * $2 }' <<<"${CURRENT_MIC_VOL} 100")
dunstify "All other info:" "Brightness: $BRIGHTNESS%\nCurrent Volume: $DISPLAY_VOL%\nCurrent Mic. Volume: $DISPLAY_MIC_VOL%"

4
notifs/time Executable file
View file

@ -0,0 +1,4 @@
#!/bin/bash
CURRENT_TIME=$(date)
notify-send "Date / Time Info:" "${CURRENT_TIME}" -t 5000 -r 9991

130
notifs/volume Executable file
View file

@ -0,0 +1,130 @@
#!/bin/bash
CURRENT_VOL=$(wpctl get-volume @DEFAULT_AUDIO_SINK@ | awk '{ print $2 }')
VOL_PRESENT=$(wpctl get-volume @DEFAULT_AUDIO_SINK@ | awk '{ print $2 }' | cut -c 3,4)
CURRENT_MIC_VOL=$(wpctl get-volume @DEFAULT_AUDIO_SOURCE@ | awk '{ print $2 }')
MIC_PRESENT=$(wpctl get-volume @DEFAULT_AUDIO_SOURCE@ | awk '{ print $2 }' | cut -c 3,4)
CURRENT_MUTE=$(wpctl get-volume @DEFAULT_AUDIO_SINK@ | awk '{ print $3 }' | tr -d '[]')
CURRENT_MIC_MUTE=$(wpctl get-volume @DEFAULT_AUDIO_SOURCE@ | awk '{ print $3 }' | tr -d '[]')
vol_inc() {
if [[ "$CURRENT_VOL" == "0.0"* ]]; then
dunstify "Increasing Volume" "Current Volume: $(echo "$VOL_PRESENT" | cut -c 2)%" -i "audio-volume-high" -t 5000 -r 9991
elif [[ "$CURRENT_VOL" == "1.00" ]]; then
dunstify "Increasing Volume" "Current Volume: 100%" -i "audio-volume-high" -t 5000 -r 9991
else
dunstify "Increasing Volume" "Current Volume: ${VOL_PRESENT}%" -i "audio-volume-high" -t 5000 -r 9991
fi
}
vol_dec() {
if [[ "$CURRENT_VOL" == "0.0"* ]]; then
dunstify "Decreasing Volume" "Current Volume: $(echo "$VOL_PRESENT" | cut -c 2)%" -i "audio-volume-medium" -t 5000 -r 9991
elif [[ "$CURRENT_VOL" == "1.00" ]]; then
dunstify "Decreasing Volume" "Current Volume: 100%" -i "audio-volume-medium" -t 5000 -r 9991
else
dunstify "Decreasing Volume" "Current Volume: ${VOL_PRESENT}%" -i "audio-volume-medium" -t 5000 -r 9991
fi
}
vol_mute_toggle() {
# If "MUTED" doesn't exist, then send notification and toggle mute, otherwise (if "MUTED" DOES exist, send notif and unmute
if [ "$CURRENT_MUTE" == "MUTED" ]; then
if [[ "$CURRENT_VOL" == "0.0"* ]]; then
dunstify "Currently Muting" "Current Volume: $(echo "$VOL_PRESENT" | cut -c 2)%" -i "audio-volume-muted" -t 5000 -r 9991
elif [[ "$CURRENT_VOL" == "1.00" ]]; then
dunstify "Currently Muting" "Current Volume: 100%" -i "audio-volume-muted" -t 5000 -r 9991
else
dunstify "Currently Muting" "Current Volume: ${VOL_PRESENT}%" -i "audio-volume-muted" -t 5000 -r 9991
fi
else
if [[ "$CURRENT_VOL" == "0.0"* ]]; then
dunstify "Currently Unmuting" "Current Volume: $(echo "$VOL_PRESENT" | cut -c 2)%" -i "audio-volume-medium" -t 5000 -r 9991
elif [[ "$CURRENT_VOL" == "1.00" ]]; then
dunstify "Currently Unmuting" "Current Volume: 100%" -i "audio-volume-medium" -t 5000 -r 9991
else
dunstify "Currently Unmuting" "Current Volume: ${VOL_PRESENT}%" -i "audio-volume-medium" -t 5000 -r 9991
fi
fi
}
micInc() {
if [[ "$CURRENT_MIC_VOL" == "0.0"* ]]; then
dunstify "Increasing Microphone Volume" "Current Volume: $(echo "$MIC_PRESENT" | cut -c 2)%" -i "audio-input-microphone-high" -t 5000 -r 9991
elif [[ "$CURRENT_MIC_VOL" == "1.00" ]]; then
dunstify "Increasing Microphone Volume" "Current Volume: 100%" -i "audio-input-microphone-high" -t 5000 -r 9991
else
dunstify "Increasing Microphone Volume" "Current Volume: ${MIC_PRESENT}%" -i "audio-input-microphone-high" -t 5000 -r 9991
fi
}
micDec() {
if [[ "$CURRENT_MIC_VOL" == "0.0"* ]]; then
dunstify "Decreasing Microphone Volume" "Current Volume: $(echo "$MIC_PRESENT" | cut -c 2)%" -i "audio-input-microphone-low" -t 5000 -r 9991
elif [[ "$CURRENT_MIC_VOL" == "1.00" ]]; then
dunstify "Decreasing Microphone Volume" "Current Volume: 100%" -i "audio-input-microphone-low" -t 5000 -r 9991
else
dunstify "Decreasing Microphone Volume" "Current Volume: ${MIC_PRESENT}%" -i "audio-input-microphone-low" -t 5000 -r 9991
fi
}
mic_mute_toggle() {
# If "MUTED" doesn't exist, then send notification and toggle mute, otherwise (if "MUTED" DOES exist, send notif and unmute
if [ "$CURRENT_MIC_MUTE" == "MUTED" ]; then
if [[ "$CURRENT_MIC_VOL" == "0.0"* ]]; then
dunstify "Currently Muting Microphone" "Current Volume: $(echo "$VOL_PRESENT" | cut -c 2)%" -i "audio-input-microphone-muted" -t 5000 -r 9991
elif [[ "$CURRENT_MIC_VOL" == "1.00" ]]; then
dunstify "Currently Muting Microphone" "Current Volume: 100%" -i "audio-input-microphone-muted" -t 5000 -r 9991
else
dunstify "Currently Muting Microphone" "Current Volume: ${VOL_PRESENT}%" -i "audio-input-microphone-muted" -t 5000 -r 9991
fi
else
if [[ "$CURRENT_MIC_VOL" == "0.0"* ]]; then
dunstify "Currently Unmuting Microphone" "Current Volume: $(echo "$VOL_PRESENT" | cut -c 2)%" -i "audio-input-microphone-high" -t 5000 -r 9991
elif [[ "$CURRENT_MIC_VOL" == "1.00" ]]; then
dunstify "Currently Unmuting Microphone" "Current Volume: 100%" -i "audio-input-microphone-high" -t 5000 -r 9991
else
dunstify "Currently Unmuting Microphone" "Current Volume: ${VOL_PRESENT}%" -i "audio-input-microphone-high" -t 5000 -r 9991
fi
fi
}
keybind-func() {
echo "$CURRENT_VOL" "$CURRENT_MIC_VOL"
}
while test $# -gt 0; do
case "$1" in
inc)
vol_inc && exit 0
;;
dec)
vol_dec && exit 0
;;
mute-toggle)
vol_mute_toggle && exit 0
;;
micInc)
micInc && exit 0
;;
micDec)
micDec && exit 0
;;
micMute)
mic_mute_toggle && exit 0
;;
keybind)
keybind-func && exit 0
;;
esac
done

3
notifs/window Executable file
View file

@ -0,0 +1,3 @@
#!/bin/bash
dunstify "Switching Window" "Current Window: $1" -t 1000 -r 5000
swaymsg workspace number "$1"

41
screenshot Executable file
View file

@ -0,0 +1,41 @@
#!/bin/bash
## Variables
declare -r time=$(date --iso-8601=seconds)
while (($# > 0)); do
case $1 in
-s)
REGION=yes
shift
;;
-c)
CURSOR=yes
shift
;;
*)
if [ -z "$FILENAME" ]; then
FILENAME="$1/$time.png"
shift
else
echo "wrong format"
exit 1
fi
;;
esac
done
OPTS=()
if [ -n "$REGION" ]; then
OPTS+=("-g $(slurp)")
if [ -n "$CURSOR" ]; then
OPTS+=("-c")
fi
fi
grim "${OPTS[@]}" "$FILENAME"
# https://github.com/bugaevc/wl-clipboard/issues/198 lifesaver
wl-copy --type image/png <"$FILENAME"

114
server-scripts/desec/desec.py Executable file
View file

@ -0,0 +1,114 @@
#!/usr/bin/env python
import subprocess
import json
import os
import asyncio
from time import sleep
from dotenv import load_dotenv
import urllib3
load_dotenv() # Loads up .env file
current_domain = os.getenv("CURRENT_DOMAIN")
desec_token = os.getenv("DESEC_TOKEN")
excluded_subdomains = ["mail._domainkey.mail", "mail", "_dmarc.mail"]
timeout = 1800 # In seconds, 600 = 10min, 900 = 15m, 1800 = 30min
# Credits:
# https://desec.readthedocs.io/en/latest/dns/rrsets.html#modifying-an-rrset
# for documentation
async def modifyRecords(newIP):
args = "curl https://desec.io/api/v1/domains/" + current_domain + \
"/rrsets/ --header 'Authorization: Token " + desec_token + "'"
data_binary = subprocess.run(
args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
data = data_binary.stdout.decode("utf-8")
# convert to python object from str
json_data = json.loads(data)
for i in range(len(excluded_subdomains)):
excluded_subdomains[i] = excluded_subdomains[i] + \
"." + current_domain + "."
for entry in json_data:
# Only allow "A" record subdomains at the moment
if entry["name"] not in excluded_subdomains and entry["type"] == "A":
if (entry["records"][0] != newIP):
subname = str(entry["subname"]) # Subdomain Name
# Basically runs a PATCH method for the api to change
# the ip record of all "A" record subdomains to the new
# public ip address
change_record_arg = \
"curl -X PATCH https://desec.io/api/v1/domains/" + \
current_domain + "/rrsets/" + subname + \
"/A/" + " --header 'Authorization: Token " \
+ desec_token + "'" + " --header " + \
"'Content-Type: application/json' " + \
"--data @- <<< '{\"records\": [\"" + newIP + "\"] }'"
# print(change_record_arg)
subprocess.run(change_record_arg, shell=True)
await asyncio.sleep(5)
print("done with changing records!")
def getCurrentIP():
print("getting current ip...")
# Get the current Public IP to a "public_ip" file
subprocess.run(
["curl", "ifconfig.me", "-o", "public_ip"], stderr=subprocess.DEVNULL)
async def newIPCheck():
print("checking for new ips...")
presentIPFile = open("public_ip", "r")
newIP_curl = subprocess.run(["curl", "ifconfig.me"],
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL)
newIP = newIP_curl.stdout.decode("utf-8")
if (presentIPFile.readline() == newIP):
await asyncio.sleep(timeout)
await newIPCheck()
else:
print("uh oh! public ip updated!")
await modifyRecords(newIP)
getCurrentIP() # update current ip
await newIPCheck()
def waitForConnection():
while True:
try:
response = urllib3.request("GET", "https://ifconfig.me")
return
except urllib3.exceptions.MaxRetryError:
print("Failed connection!")
sleep(1)
pass
def main():
waitForConnection()
if not os.path.exists("public_ip"):
getCurrentIP()
elif not os.path.exists(".env"):
print("no visible .env file for token!")
exit(1)
asyncio.run(newIPCheck())
if __name__ == "__main__":
main()

11
server-scripts/desec/dev.bash Executable file
View file

@ -0,0 +1,11 @@
#!/bin/bash
# If virtual environment does exist..
if [ ! -d .venv ]; then
python3 -m venv .venv
source .venv/bin/activate
pip install -U python-dotenv urllib3
pip install -U pip # Update pip to the latest version
fi
echo 'Make sure to run ". .venv/bin/activate" to enter the development environment'

7
server-scripts/desec/run.bash Executable file
View file

@ -0,0 +1,7 @@
#!/bin/bash
cd /home/user/scripts/desec
. .venv/bin/activate
./desec.py

225
ssgpg Normal file
View file

@ -0,0 +1,225 @@
#!/bin/python
# Made by Devaine
# mostly because bash was pissing me off when it comes to recursion
# also because i am lazy and i wanted to automate things
import time
import os
class GPG():
def export(id_num):
print("\n\nHere's your exported key for ID: " + id_num)
os.system("gpg --armor --export " + id_num)
def view():
id_output = os.popen("gpg --list-keys --with-colons | \
awk -F: '/^pub:/ { print $5 }'").read()
id_split = id_output.split("\n")
info_output = os.popen("gpg --list-keys --with-colons | \
awk -F: '/^uid:/ { print $10 }'").read()
info_split = info_output.split("\n")
print("\n\n----------------------")
for i in range(len(info_split) - 1):
print("ID #" + str(i) + ": " + id_split[i] +
"\nInfo: " + info_split[i])
print("\n")
def prompt():
question = input("ID # you want to export: ")
while question == "":
question = input("ID # you want to export: ")
try:
response = int(question)
except ValueError:
print("Not a valid ID number!")
time.sleep(1)
prompt()
if response >= len(info_output) - 1 or response < 0:
print("Not a valid ID number! test")
time.sleep(1)
prompt()
else:
GPG.export(id_split[response])
prompt()
def view_prompt():
prompt = input("Do you want to see the entire GPG Key? (Y/N): ")
while prompt == "":
prompt = input("Do you want to see the entire GPG Key? (Y/N): ")
ans = prompt.upper()
if "Y" in ans:
GPG.view()
elif "N" in ans:
print("Exiting...")
exit(0)
else:
print("Incorrect Reponse!")
print("Retrying...")
time.sleep(1)
GPG.view_prompt()
def gpg_keygen():
os.system("gpg --full-generate-key")
def __init__():
GPG.gpg_keygen()
GPG.view_prompt()
class SSH():
def keygen():
def fileDestination():
default_destination = os.path.expanduser("~") + "/.ssh"
print("------------")
print("Default: " + default_destination)
prompt = input("Path for Key (Press Enter for Default): ")
if prompt == "":
prompt = default_destination
if os.path.exists(prompt) is True:
os.system("ssh-keygen -f " + prompt + "/" + name + " -t ed25519")
else:
print("Path " + prompt + " doesn't exist, try again.")
time.sleep(1)
fileDestination()
def nameConfirmation(confirm):
while confirm == "":
confirm = input("Are you sure this is the name you want? (Y/N): ")
ans = confirm.upper()
if "Y" in ans:
fileDestination()
elif "N" in ans:
print("Retrying...")
SSH.keygen()
else:
print("Incorrect Reponse!")
print("Retrying...")
time.sleep(1)
nameConfirmation()
# Function starts here actually.
name = input("What is the name of your key: ")
while name == "":
name = input("What is the name of your key: ")
confirm = input("Are you sure this is the name you want (" + name + ")? (Y/N): ")
nameConfirmation(confirm)
def gpg_prompt():
prompt = input("Do you want to create a GPG Key? (Y/N): ")
while prompt == "":
prompt = input("Do you want to create a GPG Key? (Y/N): ")
ans = prompt.upper()
if "Y" in ans:
print("Starting...")
GPG.gpg_keygen()
elif "N" in ans:
GPG.view_prompt()
else:
print("Incorrect Reponse!")
time.sleep(1)
SSH.gpg_prompt()
def public_key_view():
def choose_file():
default_destination = os.path.expanduser("~") + "/.ssh"
print("------------")
print("Default Path: " + default_destination)
path = input("Enter Key Path (Press Enter for Default): ")
if path == "":
path = default_destination
if os.path.exists(path) is True:
avail_options = os.popen("ls " + path + "| grep .pub").read()
else:
print("Path " + path + " doesn't exist, try again.")
time.sleep(1)
choose_file()
options_split = avail_options.split("\n")
print("There are " + str(len(options_split) - 1)
+ " public keys available to read...")
for i in range(len(options_split) - 1):
print("Option #" + str(i) + ": " + options_split[i][:-4])
def prompt():
question = input("Choose an option (by number): ")
while question == "":
question = input("Choose an option (by number): ")
try:
response = int(question)
except ValueError:
print("Not a valid number!")
time.sleep(1)
prompt()
if response >= len(options_split) - 1 or response < 0:
print("Not a valid ID number! test")
time.sleep(1)
prompt()
else:
print("Here's the public key from Option #" + str(i)
+ " (" + options_split[response] + "):")
os.system("cat " + path + "/" + options_split[response])
prompt()
prompt = input("Do you want to view your SSH public key? (Y/N): ")
while prompt == "":
prompt = input("Do you want to view your SSH public key? (Y/N): ")
ans = prompt.upper()
if "Y" in ans:
print("Starting...")
choose_file()
elif "N" in ans:
SSH.gpg_prompt()
else:
print("Incorrect Reponse!")
time.sleep(1)
SSH.public_key_view()
def start():
ssh_prompt = input("Do you want to create a SSH Key? (Y/N): ")
while ssh_prompt == "":
ssh_prompt = input("Do you want to create a SSH Key? (Y/N): ")
ans = ssh_prompt.upper()
if "Y" in ans:
print("Starting...")
SSH.keygen()
elif "N" in ans:
SSH.public_key_view()
else:
print("Incorrect Reponse!")
time.sleep(1)
SSH.start()
if __name__ == "__main__":
SSH.start()

14
sunset Executable file
View file

@ -0,0 +1,14 @@
#!/bin/bash
# Build and Install 'redshift' for wayland: https://github.com/minus7/redshift
# You can also use gammastep
#cd $HOME/.local/bin
# killing gammastep if it already exists
if [[ $(pgrep gammastep) =~ ^[0-9]+$ ]]
then
kill $(pgrep gammastep)
else
gammastep -PO 2900
fi