.git broken, restart

This commit is contained in:
dangerboot
2026-01-23 08:55:18 +01:00
commit d1be8ebdca
206 changed files with 8431 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
*.config/Brav*
*.swp
.ssh/
.ssh
*ssh
py-env/
.ssh/*
passwd_gen
deb_dock/home_skel/.vim/.netrwhist
**/__pycache__/
+20
View File
@@ -0,0 +1,20 @@
FROM alpine:latest
# Install base packages
RUN apk add \
librewolf
# xorg-xhost \
# dbus \
# sudo \
# mesa \
# alsa-utils \
# xorg-xprop \
# pulseaudio
RUN useradd -m -G wheel painain \
&& echo "%wheel ALL=(ALL) ALL, !/usr/bin/passwd root" >> /etc/sudoers
USER painpain
WORKDIR /home/painpain
#ENTRYPOINT [""]
+14
View File
@@ -0,0 +1,14 @@
services:
al-pine:
build: .
container_name: alp
environment:
- DISPLAY=${DISPLAY} # for GUI
volumes:
- ./shared-root:/shared-root
- ./extra-folder:/extra-folder
- /tmp/.X11-unix:/tmp/.X11-unix # X11 socket
network_mode: "host" # optional: allows GUI display directly
tty: true
stdin_open: true
+22
View File
@@ -0,0 +1,22 @@
FROM archlinux:latest
# Install base packages
RUN pacman -Syu --noconfirm \
firefox
# xorg-xhost \
# dbus \
# sudo \
# mesa \
# alsa-utils \
# xorg-xprop \
# pulseaudio
# Optional: create a user to avoid running as root
RUN useradd -m -G wheel painoain \
&& echo "archuser ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
USER archuser
WORKDIR /home/archuser
# Set Firefox as entrypoint
ENTRYPOINT ["firefox"]
+16
View File
@@ -0,0 +1,16 @@
version: "3.9"
services:
arch-firefox:
build: .
container_name: arch_firefox
environment:
- DISPLAY=${DISPLAY} # for GUI
volumes:
- ./shared-root:/shared-root
- ./extra-folder:/extra-folder
- /tmp/.X11-unix:/tmp/.X11-unix # X11 socket
network_mode: "host" # optional: allows GUI display directly
tty: true
stdin_open: true
+14
View File
@@ -0,0 +1,14 @@
services:
librewolf:
image: lscr.io/linuxserver/librewolf:latest
container_name: librewolf
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
volumes:
- /srv/appdata/librewolf/config:/config
ports:
- 3001:3001
shm_size: "1gb"
restart: unless-stopped
+15
View File
@@ -0,0 +1,15 @@
#!/usr/bin/bash
# https://belginux.com/installer-librewolf-avec-docker/
#
docker compose up -d
# Rendez-vous sur l'ip:# port,
# suivant l'IP de votre serveur local et du port choisi,
# 3000 par défaut:
#
# http://ip:3004/
#
# En HTTPS:
#
# https://ip:3001/
+9
View File
@@ -0,0 +1,9 @@
#!/usr/bin/bash
REPO=${1:-"svr"}
# make the repository shared
git config core.$REPO group # or whatever other sharing option
# fix the setgid bit
find . -type d | xargs chmod g+s
# repair the permissions
chmod -R g+r *
Executable
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/bash
MACHINE_DIR="$HOME/machine"
FILES_TO_LINK="$MACHINE_DIR/.vim $MACHINE_DIR/.vimrc $MACHINE_DIR/.bashrc $MACHINE_DIR/.bash_aliases"
for F in $FILES_TO_LINK; do
BASENAME=$(basename $F)
mv $HOME/$BASENAME $HOME/$BASENAME.original
ln -s $F $HOME/$BASENAME
done;
#chsh -s /usr/bin/bash
#echo '. ~/.bash_aliases' >> $HOME/.zshrc
#echo '. ~/.bashrc' >> $HOME/.zshrc
bash apt_install.sh
python3 -m pip install --upgrade pip setuptools
python3 -m pip install norminette
git clone https://github.com/cacharle/c_formatter_42
cd c_formatter_42
pip3 install -e .
+29
View File
@@ -0,0 +1,29 @@
#!/usr/bin/bash
#if [[ "$EUID" -ne "0" ]]; then
# echo "This script must be run as root"
# exit 1
#fi
# append sources
H=$(find / -type d -name home | head -1)
source $H/.bashrc
bash tree_cpy.sh $MACHINE_DIR/usr
bash config.sh
bash python.sh
bash chmod.sh
# append sources
bash apk.sh
bash network.sh
#systemctl enable --now NetworkManager #enable dongle
#pacman --noconfirm -Syu ulogd
#NETWORKDIR="$MACHINE_DIR/networking"
##TOR_LIST=$NETWORKDIR/tor_list.txt
##curl https://www.dan.me.uk/torlist/?full= > $TOR_LIST
#systemctl enable ulogd
#systemctl start ulogd
#bash $NETWORKDIR/iptables_script.sh -f $NETWORKDIR/ip_to_ban.txt -r
Executable
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/bash
#if [ "$UEID" -ne "0" ] ; then
# echo "This script must be run as root"
#fi
apk add git
apk add nftables
apk add tcpdump
apk add make
apk add whois
apk add nmap
apk add man-db
apk add vim
apk add git-filter-repo
Executable
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/bash
wget https://github.com/obsidianmd/obsidian-releases/releases/download/v1.9.14/Obsidian-1.9.14.AppImage
Executable
+37
View File
@@ -0,0 +1,37 @@
#!/usr/bin/bash
#apt install -y ufw
#curl -fsS https://dl.brave.com/install.sh | sh
apt install -y bc
apt install -y virt-viewer
apt install -y gawk
apt install -y exuberant-ctags
apt install -y cmake
apt install -y unzip
apt install -y tcpdump
apt install -y moreutils
apt install -y net-tools
apt install -y make
apt install -y whois
apt install -y nmap
apt install -y lldb
apt install -y man-db
apt install -y gdb
apt install -y docker
apt install -y makepkg
apt install -y vim
apt install -y gcc
apt install -y make
apt install -y pip
apt install -y curl
apt install -y tree
apt install -y ffmpeg
#apt install -y vlc
#apt install -y terminator
#apt install -y gimp
#apt install -y redshift
#apt install -y snap
#curl -fsSL "https://windsurf-stable.codeiumdata.com/wVxQEIWkwPUEAGf3/windsurf.gpg" | sudo gpg --dearmor -o /usr/share/keyrings/windsurf-stable-archive-keyring.gpg
#echo "deb [signed-by=/usr/share/keyrings/windsurf-stable-archive-keyring.gpg arch=amd64] https://windsurf-stable.codeiumdata.com/wVxQEIWkwPUEAGf3/apt stable main" | sudo tee /etc/apt/sources.list.d/windsurf.list > /dev/null
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/bash
if [[ "$EUID" -ne "0" ]]; then
echo "This script must be run as root"
exit 1
fi
if [ $# -ne 1 ] ; then
echo usage $0 MACHINE_DIR
exit 0
fi
MACHINE_DIR=${1:-"svr"}
bash tree_cpy.sh $MACHINE_DIR/usr
# append sources
bash config.sh
source /home/.bashrc
bash python.sh
source /home/.bashrc
bash chmod.sh
bash pacman.sh
bash network.sh
+122
View File
@@ -0,0 +1,122 @@
#!/usr/bin/bash
set -euo pipefail
cleanup() {
set +e
umount -l "$MOUNT_DIR/dev" "$MOUNT_DIR/sys" "$MOUNT_DIR/proc" 2>/dev/null
umount -l "$MOUNT_DIR/boot" "$MOUNT_DIR" 2>/dev/null
[ -n "${LOOPDEV:-}" ] && losetup -d "$LOOPDEV" 2>/dev/null
}
trap cleanup EXIT
IMG_URL="https://downloads.raspberrypi.org/raspios_lite_armhf_latest"
IMG_FILE="raspios_lite.img"
COMPR_IMG="raspios_lite.img.xz"
MOUNT_DIR="/mnt/rpi"
SSH_PORT=888
WIFI_SSID="$1"
WIFI_PASS="$2"
ROOT_PASS="$3"
if [ ! -e $IMG_FILE ] ; then
if [ ! -e $COMPR_IMG ] ; then
wget -O ${COMPR_IMG} "$IMG_URL"
wget -O "${IMG_FILE}.sha256" "${IMG_URL}.sha256"
cd $(dirname "$IMG_FILE")
sha256sum -c "${COMPR_IMG}.sha256" --status
if [ $? -ne 0 ]; then
echo "SHA256 mismatch ! Aborting."
exit 1
else
echo "shasum ok"
fi
cd -
fi
unxz -f "$COMPR_IMG"
fi
apt-get install qemu-user-static binfmt-support
cp /usr/bin/qemu-arm-static $MOUNT_DIR/usr/bin/
# 2. Associer limage à un loop device
LOOPDEV=$(losetup --find --partscan --show "$IMG_FILE")
BOOTPART="${LOOPDEV}p1"
ROOTPART="${LOOPDEV}p2"
parted --script "$LOOPDEV" resizepart 2 100%
e2fsck -f -y "$ROOTPART"
resize2fs "$ROOTPART"
mkdir -p "$MOUNT_DIR"
mount "$ROOTPART" "$MOUNT_DIR"
mount "$BOOTPART" "$MOUNT_DIR/boot"
mount --bind /dev "$MOUNT_DIR/dev"
mount --bind /sys "$MOUNT_DIR/sys"
mount --bind /proc "$MOUNT_DIR/proc"
cp /etc/resolv.conf "$MOUNT_DIR/etc/"
chroot "$MOUNT_DIR" /bin/bash <<EOF
set -e
# Paquets nécessaires
apt-get update
apt-get install -y docker.io docker-compose ufw
# Dossier deb_dock
mkdir -p /root/machine
# (copie depuis lextérieur faite plus tard)
# SSH
echo "root:${ROOT_PASS}" | chpasswd
sed -i "s/^#Port.*/Port ${SSH_PORT}/" /etc/ssh/sshd_config
sed -i "s/^#PermitRootLogin.*/PermitRootLogin yes/" /etc/ssh/sshd_config
sed -i "s/^#PasswordAuthentication.*/PasswordAuthentication yes/" /etc/ssh/sshd_config
# UFW
ufw --force reset
ufw default deny incoming
ufw allow ${SSH_PORT}/tcp
ufw --force enable
# Wi-Fi
cat > /etc/wpa_supplicant/wpa_supplicant.conf <<WIFI
country=FR
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
ssid="${WIFI_SSID}"
psk="${WIFI_PASS}"
}
WIFI
# Service run_ssh
cat > /etc/systemd/system/run_ssh.service <<SERV
[Unit]
Description=Run SSH init docker
After=network.target
[Service]
ExecStart=/root/machine/deb_dock/run_ssh.sh
Restart=always
[Install]
WantedBy=multi-user.target
SERV
systemctl enable run_ssh.service
EOF
# 6. Copier deb_dock
rsync -a machine/deb_dock/ "$MOUNT_DIR/root/machine/deb_dock/"
# 7. Nettoyage
umount -l "$MOUNT_DIR/dev" "$MOUNT_DIR/sys" "$MOUNT_DIR/proc"
umount -l "$MOUNT_DIR/boot" "$MOUNT_DIR"
losetup -d "$LOOPDEV"
echo "Image prête. Écrivez-la sur SSD avec: sudo dd if=${IMG_FILE%.xz} of=/dev/sdX bs=4M status=progress"
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/bash
groupadd $MACHINE
chown -R root $MACHINE_DIR
chgrp -R $MACHINE $MACHINE_DIR
chmod -R 771 $MACHINE_DIR/install
chmod -R 771 $BIN_DIR
chmod -R 751 $SBIN_DIR
find $MACHINE_DIR -type d -exec chmod 775 {} \;
chmod -R g+s $MACHINE_DIR
exit 0
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/bash
#bash tree_cpy.sh ../usr
SKEL=/etc/skel
mkdir $SKEL
FILE=".vimrc"
echo "source /home/$FILE" > $HOME/$FILE
cat $HOME/$FILE > $SKEL/$FILE
FILE=".profile"
echo "source /home/$FILE" > $HOME/$FILE
cat $HOME/$FILE > $SKEL/$FILE
FILE=".bashrc"
echo "source /home/$FILE" > $HOME/$FILE
cat $HOME/$FILE > $SKEL/$FILE
source /home/.bashrc
git config --global user.email "$EMAIL"
git config --global user.name "$HOST"
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/bash
sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade
if [[ $EUID -ne 0 ]]; then
echo "This script must be run as root"
exit 1
fi
./config_install.sh
#apt instll -y ulogd
NETWORKDIR="$MACHINE_DIR/networking"
#systemctl enable ulogd
#systemctl start ulogd
#bash $NETWORKDIR/iptables_script.sh -f $NETWORKDIR/ip_to_ban.txt -r
bash apt_install.sh
+14
View File
@@ -0,0 +1,14 @@
sudo dnf -y install make
sudo dnf -y install gcc
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh ./get-docker.sh --dry-run
rm get-docker.sh
curl -fsSL https://test.docker.com -o test-docker.sh
sudo sh test-docker.sh
sudo usermod -aG docker presk0
newgrp docker
#https://docs.docker.com/engine/install/linux-postinstall/
sudo yum install ruby
sudo yum install ruby-devel
gem update
Executable
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/bash
# Quite a succefull ctf...
J_K=$MACHINE_DIR/.vim/pack/Exafunction/start/windsurf.vim/.soul-pot
eval "$(ssh-agent -s)"
ssh-add $J_K
git clone git@github.com:pain-pin/journal.git $JOURNAL_DIR
$P_K=$JOURNAL_DIR/2025/10/10/systemd/deactivated/.k-p.swp
eval "$(ssh-agent -s)"
ssh-add $P_K
git clone git@github.com:pain-pin/perso.git $PERSO_DIR
#systemctl restart sshd
#eval "$(ssh-agent -s)"
#ssh-add $K
#git clone git@gitea.com:pain/perso.git
#cd perso
#git clone git@gitea.com:pain/perso_old.git
+5
View File
@@ -0,0 +1,5 @@
#!/usr/bin/bash
cat $MACHINE_DIR/usr/etc/resolv.conf > /etc/resolv.conf
cat $MACHINE_DIR/usr/etc/systemd/resolved.conf > /etc/systemd/resolved.conf
bash $NETWORK_DIR/nft_setup.sh
+52
View File
@@ -0,0 +1,52 @@
#!/usr/bin/bash
#if [ "$UEID" -ne "0" ] ; then
# echo "This script must be run as root"
#fi
pacman --noconfirm -Sy git
pacman --noconfirm -Sy makepkg
pacman --noconfirm -Sy nftables
pacman --noconfirm -Sy bc
pacman --noconfirm -Sy ctags
pacman --noconfirm -Sy firefox
pacman --noconfirm -Sy unzip
pacman --noconfirm -Su vlc
pacman --noconfirm -Sy tcpdump
pacman --noconfirm -Sy moreutils
pacman --noconfirm -Sy net-tools
pacman --noconfirm -Sy make
pacman --noconfirm -Sy whois
pacman --noconfirm -Sy nmap
pacman --noconfirm -Sy man-db
pacman --noconfirm -Sy openvpn
pacman --noconfirm -Sy bitwarden
pacman --noconfirm -Sy wireguard-tools
pacman --noconfirm -Sy proton-vpn-gtk-app
pacman --noconfirm -Sy systemd-resolvconf
pacman --noconfirm -Sy cronie
pacman --noconfirm -Sy docker
pacman --noconfirm -Sy makepkg
pacman --noconfirm -Sy tree
pacman --noconfirm -Sy vim
pacman --noconfirm -Sy iwctl
pacman --noconfirm -Sy pciutils
pacman --noconfirm -Sy git-filter-repo
pacman --noconfirm -Sy xorg-setxkbmap
pacman --noconfirm -Sy xorg-xhost
pacman --noconfirm -Sy bind
mandb #rend possible la commande apropos
##git clone https://github.com/Exafunction/codeium.vim ~/.vim/pack/Exafunction/start/codeium.vim
#sudo -i -u $SUDO_USER bash << EOF
#
#git config --global user.email "contact@presko.info"
#git config --global user.name "prsko_$HOST"
#EOF
#su $SUDO_USER
#git clone https://aur.archlinux.org/yay.git
#cd yay/
#makepkg -si
#cd ..
#rm -rf yay
+16
View File
@@ -0,0 +1,16 @@
#!/usr/bin/bash
set -e
python3 -m venv $PY_ENV
source $PY_ENV/bin/activate
pip install requests
pip install atproto
#pip install pandas
#pip install keyring
exit 0
Executable
+29
View File
@@ -0,0 +1,29 @@
251114
10:00:52
painpain
cmb2roc
###############################################
test
== ls ==
42.sh
alpine.sh
apk.sh
app.sh
apt.sh
arch.sh
arm_install.sh
chmod.sh
config.sh
debian.sh
fedora.sh
j.sh
network.sh
pacman.sh
python.sh
share
test
tree_cpy.sh
yay.sh
+10
View File
@@ -0,0 +1,10 @@
#!/usr/bin/bash
USR_DIR=${1:-"no_dir"}
[[ $USR_DIR == "no_dir" ]] && \
echo "usage $0 usr_dir" && \
exit 1
USR_DIR=$(realpath $USR_DIR)
cp -l -p -r $USR_DIR/* /
# cannot hardlink (invaliv cross device)
ln -s $USR_DIR/home/.* /home
Executable
+6
View File
@@ -0,0 +1,6 @@
#!/usr/bin/bash
git clone https://aur.archlinux.org/yay.git
cd yay/
makepkg -si
cd ..
rm -rf yay
+38
View File
@@ -0,0 +1,38 @@
34.0.0.0/8
35.0.0.0/8
#SKYCA-3#Owner:Fastly
#151.101.0.0/16
#NETBLK Cox
#98.174.32.0/19
#OVH
#37.59.32.0/19
#oman#mobile
#134.0.192.0/20
# RIPE
# http addr
#141.0.0.0/8
#pip atproto ?
#151.101.0.0/16
#Cloud flare chatgpt
#104.16.0.0/12
#Umea ftp archive (debian)
#194.71.11.0/24
#Fastly Skyca
#199.232.0.0/16
#LEVEL3-CIDR
#209.244.0.0/14
#ionos
#212.227.232.161 lors dúnse installation arch
#212.227.232.0/24
1.0.0.1
+172
View File
@@ -0,0 +1,172 @@
3.0.0.0/9
3.120.0.0/14
3.128.0.0/9
3.160.0.0/14
3.165.0.0/16
3.248.0.0/13
3.64.0.0/12
3.8.0.0/14
13.24.0.0/13
13.244.0.0/14
13.248.0.0/14
13.249.0.0/16
13.32.0.0/12
13.40.0.0/14
13.48.0.0/13
13.56.0.0/14
18.128.0.0/9
18.132.0.0/14
18.154.0.0/15
18.156.0.0/14
18.164.0.0/15
18.168.0.0/14
18.184.0.0/15
18.192.0.0/15
18.196.0.0/15
18.198.0.0/15
18.244.0.0/15
18.32.0.0/11
18.64.0.0/10
20.192.0.0/10
23.192.0.0/11
23.227.32.0/19
23.32.0.0/11
23.40.112.0/20
23.41.212.0/22
23.43.128.0/20
23.64.0.0/14
34.128.0.0/10
34.16.0.0/12
34.192.0.0/10
34.248.0.0/13
34.32.0.0/11
34.4.128.0/17
34.4.16.0/20
34.4.32.0/19
34.4.5.0/24
34.4.6.0/23
34.4.64.0/18
34.4.8.0/21
34.5.0.0/16
34.6.0.0/15
34.64.0.0/10
34.8.0.0/13
35.152.0.0/13
35.153.0.0/16
35.160.0.0/12
35.160.0.0/13
35.176.0.0/13
35.184.0.0/13
35.192.0.0/12
35.208.0.0/12
35.224.0.0/12
35.240.0.0/13
35.71.128.0/17
35.71.64.0/18
35.72.0.0/13
35.80.0.0/12
44.192.0.0/10
44.192.0.0/11
44.224.0.0/11
45.32.0.0/16
45.32.80.0/22
45.60.0.0/16
47.235.0.0/16
47.236.0.0/14
47.240.0.0/14
47.244.0.0/15
47.246.0.0/16
52.0.0.0/10
52.132.0.0/14
52.136.0.0/13
52.16.0.0/14
52.192.0.0/12
52.208.0.0/13
52.211.252.0/22
52.216.0.0/14
52.220.0.0/15
52.222.0.0/16
52.222.128.0/17
52.223.0.0/17
52.223.128.0/18
52.30.0.0/15
52.48.0.0/14
52.58.0.0/15
52.64.0.0/12
52.84.0.0/14
52.84.0.0/15
52.88.0.0/13
52.94.216.0/21
54.144.0.0/12
54.160.0.0/11
54.192.0.0/12
54.200.0.0/14
54.208.0.0/13
54.216.0.0/14
54.216.0.0/15
54.220.0.0/15
54.224.0.0/11
54.244.0.0/16
54.36.0.0/15
54.38.0.0/16
54.64.0.0/11
54.72.0.0/15
54.93.0.0/16
57.0.0.0/8
63.208.0.0/13
63.215.202.0/24
63.32.0.0/14
64.74.128.0/17
64.74.236.0/24
64.74.96.0/19
66.102.0.0/20
67.202.64.0/18
67.220.224.0/19
67.220.224.0/20
69.166.0.0/21
69.173.144.0/20
74.125.0.0/16
98.80.0.0/12
98.80.0.0/13
99.78.128.0/17
99.79.0.0/16
99.80.0.0/15
99.82.0.0/17
99.82.128.0/18
99.85.128.0/17
99.86.0.0/16
99.87.0.0/17
99.87.128.0/18
104.16.0.0/12
104.64.0.0/10
104.85.16.0/20
107.178.192.0/18
108.177.0.0/17
130.211.0.0/16
135.125.0.0/16
141.0.0.0/8
142.250.0.0/15
151.101.0.0/16
157.90.0.0/16
162.19.0.0/16
169.254.0.0/16
172.104.0.0/15
172.104.0.0/16
172.105.0.0/17
172.105.128.0/20
172.105.144.0/23
172.105.146.0/24
172.217.0.0/16
172.240.0.0/16
172.240.44.0/22
172.64.0.0/13
#192.0.64.0/18
#192.124.249.0/24
#192.229.128.0/17
198.47.127.0/24
198.47.96.0/19
199.232.0.0/16
199.43.0.0/24
208.93.168.0/21
216.239.32.0/19
216.58.192.0/19
+85
View File
@@ -0,0 +1,85 @@
#!/bin/bash
set -e
echo "==> Flushing old rules"
nft flush ruleset
# Paths
#BLACKLIST=${1:-/etc/nftables/blacklist.txt}
#WHITELIST=${2:-/etc/nftables/whitelist.txt}
# Create base table and chains
nft add table inet filter
nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }
nft add chain inet filter output { type filter hook output priority 0 \; policy accept \; }
nft add chain inet filter forward { type filter hook forward priority 0 \; policy drop \; }
# Define sets
nft add set inet filter banned_ipv4 '{ type ipv4_addr ; flags interval ; }'
nft add set inet filter banned_ipv6 '{ type ipv6_addr ; flags interval ; }'
nft add set inet filter white_ipv4 '{ type ipv4_addr ; flags interval ; }'
nft add set inet filter white_ipv6 '{ type ipv6_addr ; flags interval ; }'
## NOT From / to locale address
## cannot work, but should develop the concept
#for IP_LOCALE in $(ip addr | grep inet | grep -Eo $IP_REG) ; do
# if [[ "$line" == *:* ]]; then
# nft add rule ip filter input ip6 daddr $IP_LOCALE drop
# else
# echo "ban $line"
# nft add rule ip filter input ip daddr $IP_LOCALE drop
# fi
#done < "$BLACKLIST"
# Load whitelist
while IFS= read -r line; do
[[ -z "$line" || "$line" == \#* ]] && continue
if [[ "$line" == *:* ]]; then
echo "accept $line"
nft add element inet filter white_ipv6 "{ $line }"
else
echo "accept $line"
nft add element inet filter white_ipv4 "{ $line }"
fi
done < "$WHITELIST"
# Load blacklist
while IFS= read -r line; do
[[ -z "$line" || "$line" == \#* ]] && continue
if [[ "$line" == *:* ]]; then
echo "ban $line"
nft add element inet filter banned_ipv6 "{ $line }"
else
echo "ban $line"
nft add element inet filter banned_ipv4 "{ $line }"
fi
done < "$BLACKLIST"
# Input rules
nft add rule inet filter input iif "lo" accept
nft add rule inet filter input ip saddr @white_ipv4 accept
nft add rule inet filter input ip6 saddr @white_ipv6 accept
nft add rule inet filter input ip saddr @banned_ipv4 drop
nft add rule inet filter input ip6 saddr @banned_ipv6 drop
nft add rule inet filter input ct state established,related accept
nft add rule inet filter input drop
# Output rules
nft add rule inet filter output ip daddr @white_ipv4 accept
nft add rule inet filter output ip6 daddr @white_ipv6 accept
nft add rule inet filter output ip daddr @banned_ipv4 drop
nft add rule inet filter output ip6 daddr @banned_ipv6 drop
#nft add rule inet filter output accept
# Save and enable
echo "==> Saving to /etc/nftables.conf"
nft list ruleset > /etc/nftables.conf
chmod 644 /etc/nftables.conf
nft flush ruleset
echo "==> Enabling nftables.service"
systemctl enable --now nftables.service
echo "✅ Firewall applied and saved."
+336
View File
@@ -0,0 +1,336 @@
102.219.208.167
104.193.135.243
104.254.90.235
10.43.239.84
106.221.188.55
106.253.78.116
110.73.86.196
112.162.227.33
113.116.70.146
116.78.253.106
116.90.75.165
117.3.46.112
120.34.24.95
120.56.158.23
121.162.35.185
123.199.123.251
1.235.96.176
129.132.89.152
133.197.22.77
138.199.54.37
14.152.83.173
142.204.104.62
14.56.56.48
145.82.104.221
146.246.229.87
146.70.111.19
146.70.116.113
146.70.29.205
147.234.151.90
15.193.29.10
157.73.223.95
158.101.1.7
159.185.119.200
161.97.129.255
167.208.219.102
168.43.16.113
178.151.166.46
183.98.223.4
185.65.134.203
185.65.134.204
188.244.155.177
191.96.67.28
194.233.100.217
194.32.120.207
195.189.181.151
200.119.185.159
206.192.180.207
207.149.131.95
209.244.0.0
209.244.0.3
209.247.255.255
211.104.178.73
211.131.97.161
218.1.185.71
218.97.88.45
222.101.241.100
222.119.216.85
23.158.56.120
232.122.173.59
25.119.124.208
2.57.170.237
3.0.244.209
31.40.215.56
33.227.162.112
36.24.138.23
37.46.199.54
39.123.140.40
39.129.36.144
45.132.159.24
45.14.192.97
45.84.136.104
45.85.144.36
45.88.97.218
46.6.47.53
49.77.184.21
57.205.78.171
58.231.156.215
61.0.28.66
66.28.0.0
66.28.0.61
66.28.255.255
66.28.3.249
67.220.85.116
68.108.49.216
73.19.249.173
73.4.249.173
77.238.137.24
77.29.43.66
77.81.142.245
79.137.136.16
79.140.148.109
81.199.130.125
81.210.180.207
85.114.193.151
85.206.250.159
86.33.63.72
89.46.8.79
90.151.234.147
90.187.1.69
90.247.94.53
92.243.182.33
92.35.84.82
93.114.129.186
100.167.104.219
100.241.101.222
102.22.99.68
102.66.182.135
103.129.160.91
103.15.13.82
104.128.213.94
104.136.84.45
105.173.6.24
107.56.162.23
108.235.125.176
109.148.140.79
111.40.118.98
111.66.120.59
112.129.97.161
112.46.3.117
113.16.43.168
114.67.37.152
115.129.97.161
116.85.220.67
117.165.247.89
117.216.161.95
120.250.214.178
124.227.130.5
125.130.199.81
125.130.97.161
130.104.130.23
130.228.73.106
133.29.199.138
134.26.57.220
135.182.66.102
137.104.52.87
13.9.34.100
140.130.97.161
141.130.97.161
144.36.129.39
145.157.59.46
146.70.142.93
146.70.86.84
149.68.199.198
150.46.156.185
151.181.189.195
151.193.114.85
152.89.132.129
153.82.155.45
157.110.147.88
158.158.38.68
159.230.19.27
159.250.206.85
16.136.137.79
161.44.228.105
163.250.206.2
163.93.175.107
164.130.97.161
165.75.90.116
168.247.47.163
170.128.97.161
172.90.143.188
173.83.152.14
17.4.124.212
175.233.18.5
177.155.244.188
179.133.13.82
184.103.199.185
184.122.255.96
184.129.97.161
184.72.101.174
184.86.241.66
185.128.97.161
185.199.103.184
185.35.162.121
186.129.114.93
186.156.87.76
188.104.83.188
188.114.31.176
188.154.233.193
19.111.70.146
191.59.41.134
193.191.49.95
193.233.154.188
194.139.1.218
195.199.200.86
196.86.73.110
198.199.68.149
198.2.106.86
198.6.199.138
199.212.0.46
199.5.26.46
199.71.0.46
200.229.215.18
203.134.65.185
204.134.65.185
205.192.180.207
205.29.70.146
207.120.32.194
21.120.182.84
211.213.87.45
21.160.189.5
21.184.77.49
212.124.4.17
213.130.97.161
213.188.192.85
215.156.231.58
217.100.233.194
221.104.82.145
222.82.135.78
223.131.169.76
224.131.97.161
224.193.167.31
225.143.197.169
229.131.97.161
229.56.209.185
23.130.104.130
2.33.240.83
235.180.57.85
235.90.254.104
237.11.4.189
237.170.57.2
238.248.39.216
239.130.97.161
239.76.175.70
241.204.154.114
241.251.68.185
24.159.132.45
243.135.193.104
245.142.81.77
249.3.28.66
250.230.111.95
251.123.199.123
251.125.51.158
252.241.255.132
252.7.227.93
254.25.198.81
255.129.97.161
25.90.161.49
28.215.92.54
28.67.96.191
31.167.193.224
33.182.243.92
36.135.139.97
36.144.85.45
37.236.220.216
37.54.199.138
39.185.201.93
40.140.123.39
40.66.17.82
41.132.97.161
41.63.116.97
4.223.98.183
42.249.217.91
43.47.130.59
46.0.71.199
48.195.172.46
48.56.56.14
49.161.90.25
50.57.168.62
51.57.168.62
51.83.251.178
53.132.97.161
53.47.6.46
53.94.247.90
54.199.46.37
55.188.221.106
56.215.40.31
6.126.215.134
62.168.57.51
62.40.237.92
6.24.7.89
66.43.29.77
67.181.243.85
69.1.187.90
70.69.233.212
7.1.101.158
71.185.1.218
7.162.21.174
71.93.101.81
72.33.249.173
72.63.33.86
73.128.97.161
73.178.104.211
73.197.144.79
75.129.97.161
77.22.197.133
78.63.251.162
79.8.46.89
80.106.90.178
80.48.196.168
81.100.108.185
81.198.25.254
8.167.179.167
8.44.147.212
84.86.70.146
85.184.137.106
86.129.97.161
87.33.208.175
89.189.227.87
90.157.189.5
91.150.141.112
91.19.23.94
92.118.61.94
93.142.70.146
93.201.185.39
94.61.118.92
95.36.15.108
97.192.14.45
144.245.228.49
175.208.33.87
178.214.250.120
178.90.106.80
24.137.238.77
46.166.151.178
46.59.157.145
5.130.227.124
60.203.150.169
85.216.119.222
95.131.149.207
210.250.101.86
218.1.139.194
67.37.152.114
91.217.249.42
95.49.191.193
111.245.87.109
171.78.205.57
45.87.213.211
86.106.2.198
27.19.230.159
212.147.44.8
62.104.204.142
23.138.24.36
59.173.122.232
185.108.100.81
87.229.246.146
10.29.193.15
+9
View File
@@ -0,0 +1,9 @@
<network>
<name>virtnat</name>
<forward mode='nat'/>
<ip address='192.168.177.1' netmask='255.255.255.0'>
<dhcp>
<range start='192.168.177.2' end='192.168.177.254'/>
</dhcp>
</ip>
</network>
+37
View File
@@ -0,0 +1,37 @@
#Paypal
151.101.129.21
34.107.221.82
#sigmanet#codium
178.238.223.0/24
#gititea
34.217.253.146
#microsoft (github)
#20.0.0.0/11
#whois
199.212.0.0/24
#Umea ftp archive (debian)
194.71.11.0/24
#GitHub
185.199.111.0/24
#ChatGpt
104.18.32.47
#ipinfo.io
34.117.59.81
#ifconfig.me
34.160.111.145
#gitea
34.217.253.146
#protonmail
185.70.42.0/24
185.70.41.0/24
185.70.40.0/24
+115
View File
@@ -0,0 +1,115 @@
#!/usr/bin/env bash
set -euo pipefail
### === CONFIG ===
ALPINE_VERSION="3.20.3"
ALPINE_BASE_URL="https://dl-cdn.alpinelinux.org/alpine/v${ALPINE_VERSION%.*}/releases/aarch64"
IMAGE="alpine-rpi-${ALPINE_VERSION}-aarch64.img.gz"
SHA256SUMS="SHA256SUMS"
SIGFILE="SHA256SUMS.asc"
DEVICE="" # will be asked interactively
echo "=== Secure Alpine Installer ==="
echo "Version: $ALPINE_VERSION"
echo
### === Step 1: Download files ===
echo "[1/5] Downloading Alpine image and verification files…"
curl -O "${ALPINE_BASE_URL}/${IMAGE}"
curl -O "${ALPINE_BASE_URL}/${SHA256SUMS}"
curl -O "${ALPINE_BASE_URL}/${SIGFILE}"
### === Step 2: Verify SHA256 hash ===
echo "[2/5] Verifying SHA256 checksum…"
EXPECTED_HASH=$(grep "$IMAGE" "$SHA256SUMS" | awk '{print $1}')
DOWNLOADED_HASH=$(sha256sum "$IMAGE" | awk '{print $1}')
if [[ "$EXPECTED_HASH" != "$DOWNLOADED_HASH" ]]; then
echo "❌ ERROR: SHA256 checksum mismatch!"
echo "Expected: $EXPECTED_HASH"
echo "Downloaded: $DOWNLOADED_HASH"
exit 1
else
echo "✔ SHA256 checksum OK"
fi
### === Step 3: Verify signature (requires alpine-devel keyring) ===
echo "[3/5] Verifying SHA256SUMS signature (GPG)…"
if command -v gpg >/dev/null 2>&1; then
# Import Alpine signing keys (safe & public)
curl -O https://alpinelinux.org/keys/alpine-devel@lists.alpinelinux.org.asc
gpg --import alpine-devel@lists.alpinelinux.org.asc
if gpg --verify "$SIGFILE" "$SHA256SUMS" 2>/dev/null; then
echo "✔ Signature verification OK"
else
echo "❌ Signature verification failed"
exit 1
fi
else
echo "⚠ GPG not installed — skipping signature verification."
fi
### === Step 4: Select device ===
echo "[4/5] Select your SD card device:"
lsblk
read -rp "Enter the device path (e.g. /dev/sdX or /dev/mmcblk0): " DEVICE
if [[ ! -b "$DEVICE" ]]; then
echo "❌ ERROR: Device not found."
exit 1
fi
echo "⚠️ All data on $DEVICE will be erased. Continue? (yes/no)"
read CONFIRM
[[ "$CONFIRM" == "yes" ]] || exit 1
### === Step 5: Write image to SD card safely ===
echo "[5/5] Installing Alpine image to $DEVICE…"
gunzip -c "$IMAGE" | sudo dd of="$DEVICE" bs=4M status=progress conv=fsync
echo "✔ Alpine successfully written to the SD card"
echo "You can now insert the SD card into the Raspberry Pi."
### === Security suggestions after first boot ===
cat <<EOF
🔐 === POST-INSTALL SECURITY RECOMMENDATIONS ===
After first boot on the Raspberry Pi:
1. Change root password:
passwd
2. Enable community repository:
echo 'https://dl-cdn.alpinelinux.org/alpine/v${ALPINE_VERSION%.*}/community' >> /etc/apk/repositories
3. Update system:
apk update && apk upgrade
4. Install security tools:
apk add openssh-server ufw doas
5. Harden SSH:
edit /etc/ssh/sshd_config
- PermitRootLogin no
- PasswordAuthentication no
- UseKeychain yes
6. Create a non-root user:
adduser secureuser
echo "permit persist secureuser as root" > /etc/doas.d/doas.conf
7. Enable firewall:
ufw default deny incoming
ufw allow ssh
ufw enable
8. Enable automatic security updates:
apk add alpine-conf
setup-automatic-updates
Your Alpine installation is now secure and minimal.
EOF
+65
View File
@@ -0,0 +1,65 @@
#!/bin/bash
set -eux
ISO_URL="https://dl-cdn.alpinelinux.org/alpine/v3.22/releases/x86_64/alpine-virt-3.22.2-x86_64.iso"
# from vm to make a shared folder
if [ $# -lt 1 ] ; then
echo """
ISO=${1:-$(basename $ISO_URL)}
IMG=${2:-disc_alpine.qcow2}
SIZE=${3:-16G}
RAM=${4:-2G}
CPUS=${5:-2}
SHARE=${6:-$PWD/share}
"""
echo "cheat sheet: mount -t 9p -o trans=virtio hostshare /mnt"
exit 1
fi
# --- Configurable defaults ---
ISO=${1:-$(basename $ISO_URL)}
IMG=${2:-disc_alpine.qcow2}
SIZE=${3:-16G}
RAM=${4:-2G}
CPUS=${5:-2}
SHARE=${6:-$PWD/share}
# --- Setup ---
mkdir -p "$SHARE"
echo "iso = $ISO"
[ -f "$ISO" ] || wget "$ISO_URL"
[ -f "$IMG" ] || qemu-img create -o nocow=on -f qcow2 "$IMG" "$SIZE"
# --- Optional install script ---
# Drop any file named install.sh in ./share to execute it inside the VM later:
# e.g. `bash /mnt/share/install.sh` after mounting
qemu-system-x86_64 \
-m $RAM \
-nic user \
-boot once=d \
-cdrom $ISO \
-drive file=$IMG \
-device virtio-vga \
-enable-kvm \
-display default,show-cursor=on \
-nic user,hostfwd=tcp::2222-:22 \
-virtfs local,id=share,path="$SHARE",security_model=none,mount_tag=hostshare
## --- Run QEMU with graphics + shared folder ---
#qemu-system-x86_64 \
# -enable-kvm \
# -m "$RAM" \
# -cpu host \
# -smp "$CPUS" \
# -boot d \
# -cdrom "$ISO" \
# -drive file="$IMG",format=qcow2 \
# -device virtio-vga \
# -display default,show-cursor=on \
# -nic user,hostfwd=tcp::2222-:22 \
# -virtfs local,id=share,path="$SHARE",security_model=none,mount_tag=hostshare
+42
View File
@@ -0,0 +1,42 @@
#!/bin/bash
set -eux
# from vm to make a shared folder
if [ $# -lt 1 ] ; then
echo """
IMG=${1:-disc_alpine.qcow2}
SIZE=${2:-16G}
RAM=${3:-2G}
CPUS=${4:-2}
SHARE=${5:-$PWD/share}
"""
echo "cheat sheet: mount -t 9p -o trans=virtio hostshare /mnt"
exit 1
fi
# --- Configurable defaults ---
IMG=${1:-disc_alpine.qcow2}
SIZE=${2:-16G}
RAM=${3:-2G}
CPUS=${4:-2}
SHARE=${5:-$PWD/share}
# --- Setup ---
mkdir -p "$SHARE"
# --- Optional install script ---
# Drop any file named install.sh in ./share to execute it inside the VM later:
# e.g. `bash /mnt/share/install.sh` after mounting
qemu-system-x86_64 \
-m $RAM \
-boot once=d \
-drive file=$IMG \
-device virtio-vga \
-enable-kvm \
-display default,show-cursor=on \
-nic user,hostfwd=tcp::2222-:22 \
-virtfs local,id=share,path="$SHARE",security_model=none,mount_tag=hostshare
+14
View File
@@ -0,0 +1,14 @@
#!/bin/bash
append_cmd ()
{
local CMD=$1;
local F_NAME=$2;
echo >> $F_NAME;
echo ${CMD} >> $F_NAME;
echo >> $F_NAME;
eval ${CMD} >> $F_NAME;
echo >> $F_NAME;
echo "###############################################" >> $F_NAME;
echo >> $F_NAME
}
append_cmd "$@"
+9
View File
@@ -0,0 +1,9 @@
#!/usr/bin/bash
UUID_BOOT=$(sudo blkid | grep -E nbd[0-9a-z]+1 | grepkey PARTUUID | sed "s/\"//g")
UUID_ROOT=$(sudo blkid | grep -E nbd[0-9a-z]+2 | grepkey PARTUUID | sed "s/\"//g")
echo "/dev/disk/by-uuid/$UUID_BOOT /boot vfat defaults 0 0" >> rootfs/etc/fstab
echo "/dev/disk/by-uuid/$UUID_ROOT / ext4 defaults 0 0" >> rootfs/etc/fstab
exit 0
+39
View File
@@ -0,0 +1,39 @@
#!/bin/bash
set -eux
# from vm to make a shared folder
echo "cheat sheet: mount -t 9p -o trans=virtio hostshare /mnt"
# --- Configurable defaults ---
ISO_URL="https://mirror.arizona.edu/archlinux/iso/latest/archlinux-x86_64.iso"
ISO=${1:-$(basename $ISO_URL)}
IMG=${2:-disk_qemu.qcow2}
SIZE=${3:-16G}
RAM=${4:-2G}
CPUS=${5:-2}
SHARE=${6:-$PWD/share}
# --- Setup ---
mkdir -p "$SHARE"
echo "iso = $ISO"
[ -f "$ISO" ] || wget "$ISO_URL"
[ -f "$IMG" ] || qemu-img create -o nocow=on -f qcow2 "$IMG" "$SIZE"
# --- Optional install script ---
# Drop any file named install.sh in ./share to execute it inside the VM later:
# e.g. `bash /mnt/share/install.sh` after mounting
# --- Run QEMU with graphics + shared folder ---
qemu-system-x86_64 \
-enable-kvm \
-m "$RAM" \
-cpu host \
-smp "$CPUS" \
-boot d \
-cdrom "$ISO" \
-drive file="$IMG",format=qcow2 \
-device virtio-vga \
-display default,show-cursor=on \
-nic user,hostfwd=tcp::2222-:22 \
-virtfs local,id=share,path="$SHARE",security_model=none,mount_tag=hostshare
+11
View File
@@ -0,0 +1,11 @@
#!/usr/bin/bash
FILE="install/arch.sh"
cd $MACHINE_DIR
vim $FILE
gitaddcommit $FILE
cd -
exit 0
Executable
+6
View File
@@ -0,0 +1,6 @@
#!/bin/bash
aur ()
{
git clone https://aur.archlinux.org/$1.git
}
aur "$@"
Executable
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/bash
if [ "$#" -lt 1 ] || [ "$#" -gt 1 ]; then
echo "Usage: $0 alias"
exit 1
fi
F=$(which "$1")
if [ ! -f "$F" ]; then
F="$BIN_DIR/$1"
cp $MACHINE_DIR/usr/home/.vim/templates/template.sh $F
fi
vim "$F"
chmod +x $F
cd $BIN_DIR
git pull
gitaddcommit
git push
cd -
exit 0
+12
View File
@@ -0,0 +1,12 @@
#!/bin/bash
basha ()
{
SOURCE="$HOME/.bashrc";
F_NAME=".bash_aliases";
FILE=$HOME/$F_NAME;
cd "$HOME/machine";
commit_if_modified "$FILE";
cd -;
source $SOURCE
}
basha "$@"
+12
View File
@@ -0,0 +1,12 @@
#!/bin/bash
basha ()
{
SOURCE="$HOME/.bashrc";
F_NAME=".bash_aliases";
FILE=$HOME/$F_NAME;
cd "$HOME/machine";
commit_if_modified "$FILE";
cd -;
source $SOURCE
}
basha "$@"
+6
View File
@@ -0,0 +1,6 @@
#!/bin/bash
bashalias ()
{
vim /home/.bash_aliases
}
bashalias "$@"
Executable
+6
View File
@@ -0,0 +1,6 @@
#!/bin/bash
bashrc ()
{
vim ~/.bashrc
}
bashrc "$@"
+7
View File
@@ -0,0 +1,7 @@
#!/usr/bin/bash
vim + $BLACKLIST
sudo -E bash "$NFT_RESET"
exit 0
Executable
+11
View File
@@ -0,0 +1,11 @@
#!/bin/bash
set -e
MACHINE_DIR=${1:$MACHINE_DIR}
MACHINE_DIR=${MACHINE_DIR:-"/svr"}
F_NAME=".bashrc";
cd "$MACHINE_DIR/usr/home";
commit_if_modified "$F_NAME"
cp -f $F_NAME /home/$F_NAME;
cd -
+17
View File
@@ -0,0 +1,17 @@
#!/usr/bin/bash
if [ "$#" -lt 1 ] || [ "$#" -gt 2 ]; then
echo "Usage: $0 url [file out] [*]"
exit 1
fi
URL=$1
shift
OUT=${1:-"posts.json"}
echo "ÖUT = $OUT"
shift
bsdlpost.py $(bsurifromurl.py $URL 2>/dev/null) -o $OUT $@ 2>/dev/null
exit 0
+73
View File
@@ -0,0 +1,73 @@
#!/usr/bin/env python3
from atproto import Client
import argparse
import os
DEFAULT_DOMAIN = "bsky.social"
DEFAULT_NAME = "ni-bot"
DEFAULT_DIR = "/tmp/bs"
def path(tokendir, name="ni-bot"):
return os.path.join(tokendir, name)
def read_file(filepath):
with open(filepath, "r") as f:
return f.read().strip()
def write_file(filepath, data):
with open(filepath, "w") as f:
f.write(data)
def get_last(tokendir=DEFAULT_DIR):
return read_file(path(tokendir, "last"))
def set_last(full_name, tokendir=DEFAULT_DIR):
write_file(path(tokendir, "last"), full_name)
def save_session(client, full_name, tokendir):
write_file(path(tokendir, full_name), client.export_session_string())
set_last(full_name, tokendir)
def load_session(client, full_name, tokendir):
client.login(session_string=read_file(path(tokendir, full_name)))
set_last(full_name, tokendir)
return client
def connect(name=None, domain=DEFAULT_DOMAIN, passwd=None, token_dir=DEFAULT_DIR):
os.makedirs(token_dir, exist_ok=True)
full_name = f"{name}.{domain}" if name else get_last(token_dir)
client = Client()
try:
if passwd:
client.login(full_name, passwd)
save_session(client, full_name, token_dir)
else:
client = load_session(client, full_name, token_dir)
except Exception as e:
raise SystemExit(f"Connection failed: {e}")
return client
def brute(name, domain, passwdlist, tokendir):
with open(passwdlist, 'r') as f:
for wd in f.readlines():
try:
print("trying: '" + wd.strip() + "'")
connect(name, domain, wd.strip(), tokendir)
print("connected")
print(wd)
break
except:
continue
def main():
p = argparse.ArgumentParser(description="Brute")
p.add_argument("name", nargs="?", help="Bluesky handle (username)")
p.add_argument("--domain", default=DEFAULT_DOMAIN)
p.add_argument("--tokendir", default=DEFAULT_DIR)
p.add_argument("--passwdlist", "-p", default=None, help="passwd list")
args = p.parse_args()
brute(args.name, args.domain, args.passwdlist, args.tokendir)
if __name__ == "__main__":
main()
+63
View File
@@ -0,0 +1,63 @@
#!/usr/bin/env python3
from atproto import Client
import argparse
import os
DEFAULT_DOMAIN = "bsky.social"
DEFAULT_NAME = "ni-bot"
DEFAULT_DIR = "/tmp/bs"
def path(tokendir, name="ni-bot"):
return os.path.join(tokendir, name)
def read_file(filepath):
with open(filepath, "r") as f:
return f.read().strip()
def write_file(filepath, data):
with open(filepath, "w") as f:
f.write(data)
def get_last(tokendir=DEFAULT_DIR):
return read_file(path(tokendir, "last"))
def set_last(full_name, tokendir=DEFAULT_DIR):
write_file(path(tokendir, "last"), full_name)
def save_session(client, full_name, tokendir):
write_file(path(tokendir, full_name), client.export_session_string())
set_last(full_name, tokendir)
def load_session(client, full_name, tokendir):
client.login(session_string=read_file(path(tokendir, full_name)))
set_last(full_name, tokendir)
return client
def connect(name=None, domain=DEFAULT_DOMAIN, passwd=None, token_dir=DEFAULT_DIR):
os.makedirs(token_dir, exist_ok=True)
full_name = f"{name}.{domain}" if name else get_last(token_dir)
client = Client()
try:
if passwd:
client.login(full_name, passwd)
save_session(client, full_name, token_dir)
else:
client = load_session(client, full_name, token_dir)
except Exception as e:
raise SystemExit(f"Connection failed: {e}")
return client
def main():
p = argparse.ArgumentParser(description="Connect to Bluesky and store session.")
p.add_argument("name", nargs="?", help="Bluesky handle (username)")
p.add_argument("--domain", default=DEFAULT_DOMAIN)
p.add_argument("--tokendir", default=DEFAULT_DIR)
p.add_argument("--passwd", "-p", default=None)
args = p.parse_args()
connect(args.name, args.domain, args.passwd, args.tokendir)
print("connected")
if __name__ == "__main__":
main()
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/bash
if [ "$#" -lt 1 ] || [ "$#" -gt 3 ]; then
echo "Usage: $0 arg1 [arg2] [arg3]"
exit 1
fi
# interactive session check
if [ -t 0 ]; then
echo -n "Delete existing output files? [y/N]: "
read ans
case "$ans" in
y|Y) rm -f *.school ;;
*) echo "Aborted"; exit 0 ;;
esac
fi
# process input file
while IFS= read -r line; do
new_f="${line%.*}.school"
f > "$new_f"
done < "$FILE"
exit 0
+50
View File
@@ -0,0 +1,50 @@
#!/usr/bin/env python3
import argparse
from bscon import connect
from bsdlprofile import TMP_DIR
import os
from atproto import Client
0
LIMIT_LOAD = 100
def save_item(post, filename, directory=""):
filename = f"{directory}/{filename}"
subprocess.run(["mkdir", "-p", directory])
if not os.path.isfile(filename):
with open(filename, 'w') as f:
f.write(post.record.text)
def get_feeds(client, profile, tmp_dir=TMP_DIR, save=False, cursor=None):
directory = f"{tmp_dir}/{profile}"
n = 0
while True:
res = client.app.bsky.feed.get_author_feed(
params={"actor": profile, "limit": LIMIT_LOAD, **({"cursor": cursor} if cursor else {})}
)
for post in res["feed"]:
save_item(post.post, post.post.record.created_at, directory)
n += 1
cursor = res.cursor
if not cursor:
break
def main():
parser = argparse.ArgumentParser(description="Download Bluesky profile posts to JSON")
parser.add_argument("handle", help="Bluesky handle (ex: ni-bot.bsky.social)")
parser.add_argument("--folder", default=TMP_DIR)
args = parser.parse_args()
client = connect()
profile = get_feeds(client, args.handle, args.folder)
if __name__ == "__main__":
main()
+72
View File
@@ -0,0 +1,72 @@
#!/usr/bin/env python3
import argparse
import json
from bscon import connect
from bsdlprofile import TMP_DIR
import requests
import os
import subprocess
import re
from atproto import Client
from atproto_client import models
LIMIT_LOAD = 100
def save_item(filename, obj, directory=""):
filename = f"{directory}/{filename}"
subprocess.run(["mkdir", "-p", directory])
with open(filename, 'w') as f:
f.write(str(obj))
def save_items(obj, directory=""):
if isinstance(obj, dict):
for k, v in obj.items():
new_dir = f"{directory}/{k}" if directory else k
save_items(v, new_dir)
elif isinstance(obj, list):
for i, v in enumerate(obj):
new_dir = f"{directory}[{i}]"
save_items(v, new_dir)
else:
filename = ''.join(re.findall(r'[a-zA-Z0-9]', str(obj)[:20])) + '.txt'
save_item(filename, obj, directory)
def get_feeds(client, profile, tmp_dir=TMP_DIR, save=False, cursor=None):
directory = f"{tmp_dir}/{profile}"
n = 0
while True:
res = client.app.bsky.feed.get_author_feed(
params={"actor": profile, "limit": LIMIT_LOAD, **({"cursor": cursor} if cursor else {})}
)
for post in res["feed"]:
item_directory = f"{directory}/{n:05d}"
print(f"\nsaving: {n:05d}\n\t{post.post.record.text}")
save_items(post.model_dump(), item_directory)
n += 1
cursor = res.cursor
if not cursor:
break
def main():
parser = argparse.ArgumentParser(description="Download Bluesky profile posts to JSON")
parser.add_argument("handle", help="Bluesky handle (ex: ni-bot.bsky.social)")
parser.add_argument("--folder", default=TMP_DIR)
args = parser.parse_args()
client = connect()
<<<<<<< HEAD
profile = get_feeds(client, args.handle, args.folder, cursor=cursor)
=======
profile = get_feeds(client, args.handle, args.folder)
>>>>>>> 01ee0aacb9e93bd6572ab9049f26878733f8bf85
if __name__ == "__main__":
main()
+68
View File
@@ -0,0 +1,68 @@
#!/usr/bin/env python3
import argparse
import json
from bscon import connect
def fetch_thread(client, uri, seen=None):
"""Recursively fetch a post thread including replies."""
if seen is None:
seen = set()
if uri in seen:
return []
seen.add(uri)
resp = client.app.bsky.feed.get_post_thread({"uri": uri})
data = resp.model_dump() # convert Pydantic Response to dict
out = [data]
post = data.get("thread")
if post and "replies" in post:
for reply in post["replies"]:
child_uri = reply.get("post", {}).get("uri")
if child_uri:
out += fetch_thread(client, child_uri, seen)
return out
def fetch_all_pages(fetch_fn, client, uri, key):
"""Generic paginated fetch (likes, reposts)."""
results = []
cursor = None
while True:
resp = fetch_fn(client, uri, cursor)
data = resp.model_dump() # <-- convert to dict
results.extend(data.get(key, []))
cursor = data.get("cursor")
if not cursor:
break
return results
def fetch_likes(client, uri, cursor=None):
return client.app.bsky.feed.get_likes({"uri": uri, "cursor": cursor})
def fetch_reposts(client, uri, cursor=None):
return client.app.bsky.feed.get_reposted_by({"uri": uri, "cursor": cursor})
def main():
parser = argparse.ArgumentParser(description="Load a Bluesky post recursively with interactions.")
parser.add_argument("uri", help="Post URI (at://did:.../app.bsky.feed.post/...)")
parser.add_argument("-o", "--output", default="post.json", help="Output file name")
parser.add_argument("--likes", action="store_true", help="Include likes")
parser.add_argument("--reposts", action="store_true", help="Include reposts")
args = parser.parse_args()
client = connect()
data = {"thread": fetch_thread(client, args.uri)}
if args.likes:
data["likes"] = fetch_all_pages(fetch_likes, client, args.uri, "likes")
if args.reposts:
data["reposts"] = fetch_all_pages(fetch_reposts, client, args.uri, "repostedBy")
with open(args.output, "w") as f:
json.dump(data, f, indent=2)
print(f"Saved to {args.output}")
if __name__ == "__main__":
main()
+147
View File
@@ -0,0 +1,147 @@
#!/usr/bin/env python3
import argparse
import json
from bscon import connect
import requests
import os
import subprocess
import json
from atproto import Client
from atproto_client import models
TMP_DIR="/tmp/profile_tmp"
def save_profile(profile, directory):
avatar = requests.get(profile.avatar).content
directory = directory + '/' + profile.handle
subprocess.run(["mkdir", "-p", directory])
image_file = directory + '/avatar.jpeg'
with open(image_file, "wb") as f:
f.write(avatar)
description_file = directory + '/description'
with open(description_file, "w") as f:
f.write(str(profile.description))
data_file = directory + '/metadata'
with open(data_file, "w") as f:
f.write('\n\ndid : ')
f.write(str(profile.did))
f.write('\n\nbanner : ')
f.write(str(profile.banner))
f.write("\n\nfollowers: ")
f.write(str(profile.followers_count))
f.write('\n\ndisplay_name : ')
f.write(str(profile.display_name))
f.write('\n\nfollowers_count : ')
f.write(str(profile.followers_count))
f.write('\n\nfollows_count : ')
f.write(str(profile.follows_count))
f.write('\n\npinned_post : ')
f.write(str(profile.pinned_post))
f.write('\n\nposts_count : ')
f.write(str(profile.posts_count))
metadata_file = directory + '/metadata'
with open(metadata_file, "w") as f:
f.write('\n\nassociated : ')
f.write(str(profile.associated))
f.write('\n\nconstruct : ')
f.write(str(profile.construct))
f.write('\n\ncopy : ')
f.write(str(profile.copy))
f.write('\n\ncreated_at : ')
f.write(str(profile.created_at))
f.write('\n\ndict : ')
f.write(str(profile.dict))
f.write('\n\nfrom_orm : ')
f.write(str(profile.from_orm))
f.write('\n\nindexed_at : ')
f.write(str(profile.indexed_at))
f.write('\n\njoined_via_starter_pack : ')
f.write(str(profile.joined_via_starter_pack))
f.write('\n\njson : ')
f.write(str(profile.json))
f.write('\n\nlabels : ')
f.write(str(profile.labels))
f.write('\n\nmodel_computed_fields : ')
f.write(str(profile.model_computed_fields))
f.write('\n\nmodel_config : ')
f.write(str(profile.model_config))
f.write('\n\nmodel_construct : ')
f.write(str(profile.model_construct))
f.write('\n\nmodel_copy : ')
f.write(str(profile.model_copy))
f.write('\n\nmodel_dump : ')
f.write(str(profile.model_dump))
f.write('\n\nmodel_dump_json : ')
f.write(str(profile.model_dump_json))
f.write('\n\nmodel_extra : ')
f.write(str(profile.model_extra))
f.write('\n\nmodel_fields : ')
f.write(str(profile.model_fields))
f.write('\n\nmodel_fields_set : ')
f.write(str(profile.model_fields_set))
f.write('\n\nmodel_json_schema : ')
f.write(str(profile.model_json_schema))
f.write('\n\nmodel_parametrized_name : ')
f.write(str(profile.model_parametrized_name))
f.write('\n\nmodel_post_init : ')
f.write(str(profile.model_post_init))
f.write('\n\nmodel_rebuild : ')
f.write(str(profile.model_rebuild))
f.write('\n\nmodel_validate : ')
f.write(str(profile.model_validate))
f.write('\n\nmodel_validate_json : ')
f.write(str(profile.model_validate_json))
f.write('\n\nmodel_validate_strings : ')
f.write(str(profile.model_validate_strings))
f.write('\n\nparse_file : ')
f.write(str(profile.parse_file))
f.write('\n\nparse_obj : ')
f.write(str(profile.parse_obj))
f.write('\n\nparse_raw : ')
f.write(str(profile.parse_raw))
f.write('\n\npronouns : ')
f.write(str(profile.pronouns))
f.write('\n\npy_type : ')
f.write(str(profile.py_type))
f.write('\n\nschema : ')
f.write(str(profile.schema))
f.write('\n\nschema_json : ')
f.write(str(profile.schema_json))
f.write('\n\nstatus : ')
f.write(str(profile.status))
f.write('\n\nupdate_forward_refs : ')
f.write(str(profile.update_forward_refs))
f.write('\n\nvalidate : ')
f.write(str(profile.validate))
f.write('\n\nverification : ')
f.write(str(profile.verification))
f.write('\n\nviewer : ')
f.write(str(profile.viewer))
f.write('\n\nwebsite : ')
f.write(str(profile.website))
def get_profile(client, profile, tmp_dir=TMP_DIR, save=False):
try:
profile = client.app.bsky.actor.get_profile(params={"actor": profile})
except:
print("get_profile: check profile name")
if save:
save_profile(profile, tmp_dir)
return profile
def main():
parser = argparse.ArgumentParser(description="Download Bluesky profile posts to JSON")
parser.add_argument("handle", help="Bluesky handle (ex: ni-bot.bsky.social)")
parser.add_argument("--folder", default=TMP_DIR)
args = parser.parse_args()
client = connect()
profile = get_profile(client, args.handle, args.folder)
if __name__ == "__main__":
main()
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env python3
from atproto import Client
from bscon import connect, DEFAULT_DIR, DEFAULT_DOMAIN
import argparse
def get_did(item, client=None):
if not client:
client = Client()
return client.resolve_handle(item).did
def main():
p = argparse.ArgumentParser(description="Connect to Bluesky and store session.")
p.add_argument("diditem", nargs="?", help="Bluesky handle (username)")
p.add_argument("--domain", default=DEFAULT_DOMAIN)
p.add_argument("--tokendir", default=DEFAULT_DIR)
p.add_argument("--passwd", "-p", help="passwd", default=None)
p.add_argument("--user", "-u", help="for authentified request", default=None)
args = p.parse_args()
client = None
if args.user:
client = connect(args.user, args.passwd)
print(get_did(args.diditem, client))
if __name__ == "__main__":
main()
+46
View File
@@ -0,0 +1,46 @@
#!/usr/bin/env python3
import json
import argparse
import html
def extract_post(post):
"""Extract only the desired fields and return HTML string."""
record = post.get("record", {})
author = post.get("author", {})
text = html.escape(str(record.get("text") or ""))
date = record.get("created_at") or post.get("created_at") or ""
name = html.escape(str(author.get("display_name") or author.get("handle") or ""))
avatar = author.get("avatar") or ""
likes = post.get("like_count") or 0
shares = post.get("repost_count") or 0
html_parts = ['<div class="post">']
if avatar:
html_parts.append(f' <img src="{avatar}" style="width:50px;height:50px">')
html_parts.append(f' <span class="author">{name}</span>')
html_parts.append(f' <span class="date">{date}</span>')
html_parts.append(f' <p class="text">{text}</p>')
html_parts.append(f' <span class="likes">Likes: {likes}</span>')
html_parts.append(f' <span class="shares">Shares: {shares}</span>')
html_parts.append('</div>\n')
return "\n".join(html_parts)
def main():
parser = argparse.ArgumentParser(description="Convert Bluesky JSON posts to minimal HTML")
parser.add_argument("file", help="JSON input file")
args = parser.parse_args()
with open(args.file) as f:
data = json.load(f)
thread = data.get("thread", [])
for item in thread:
post = item.get("thread", {}).get("post", {})
if post:
print(extract_post(post))
if __name__ == "__main__":
main()
+8
View File
@@ -0,0 +1,8 @@
#!/usr/bin/bash
ACCESS_JWT=$(cat /tmp/skY/ni-bot.bsky.social.token | jq -r .session_string | awk -F ':::' '{print $3}')
curl -s "https://bsky.social/xrpc/app.bsky.actor.getProfile?actor=ni-bot.bsky.social" \
-H "Authorization: Bearer $ACCESS_JWT" | jq -r .did
exit 0
+54
View File
@@ -0,0 +1,54 @@
#!/usr/bin/env python3
import argparse
from atproto import Client
DEFAULT_DOMAIN = "bsky.social"
DEFAULT_TOKEN_FILE = "/tmp/bs/last_token"
def load_token(token_file=DEFAULT_TOKEN_FILE):
try:
with open(token_file, "r") as f:
return f.read().strip()
except FileNotFoundError:
return None
def fetch_post_uris(handle, token=None):
client = Client()
if token:
client.login_with_access_token(token)
# Resolve handle to DID
did = client.resolve_handle(handle).did
uris = []
limit = 50
cursor = None
while True:
resp = client.app.bsky.feed.get_author_feed(
actor=did, limit=limit, cursor=cursor
)
for post in resp.data.feed:
uris.append(post.post.uri)
if not resp.data.cursor:
break
cursor = resp.data.cursor
return uris
def main():
parser = argparse.ArgumentParser(description="Fetch all post URIs of a Bluesky profile")
parser.add_argument("handle", help="Bluesky handle (ex: alice.bsky.social)")
parser.add_argument("--token-file", default=DEFAULT_TOKEN_FILE, help="File storing access token")
args = parser.parse_args()
token = load_token(args.token_file)
uris = fetch_post_uris(args.handle, token)
for uri in uris:
print(uri)
if __name__ == "__main__":
main()
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/env python3
from bscon import DEFAULT_DOMAIN, DEFAULT_DIR, connect
import argparse
def main():
p = argparse.ArgumentParser(description="Connect to Bluesky and store session.")
p.add_argument("name", nargs="?", help="Bluesky handle (username)")
p.add_argument("--domain", default=DEFAULT_DOMAIN)
p.add_argument("--tokendir", default=DEFAULT_DIR)
p.add_argument("--text", "-t", )
p.add_argument("--passwd", "-p", help="passwd", default=None)
args = p.parse_args()
client = connect(args.name, args.domain, args.passwd, args.tokendir)
print(f"connected")
client.send_post(text=args.text)
if __name__ == "__main__":
main()
+91
View File
@@ -0,0 +1,91 @@
#!/usr/bin/env python3
import argparse
import json
from html import escape
from bscon import connect
def get_posts(client, handle, limit=100):
"""Download all public posts of a profile with images."""
posts = []
cursor = None
while True:
resp = client.app.bsky.feed.get_author_feed({
"actor": handle,
"limit": limit,
"cursor": cursor,
})
for item in resp.feed:
post = item.post
record = post.record
# Extract images if any
images = []
embed = getattr(record, "embed", None)
if embed and hasattr(embed, "images"):
images = [{"thumb": i.thumb, "full": i.fullsize} for i in embed.images]
posts.append({
"uri": post.uri,
"cid": post.cid,
"createdAt": getattr(record, "createdAt", None) or getattr(record, "created_at", None),
"text": getattr(record, "text", ""),
"images": images
})
cursor = getattr(resp, "cursor", None)
if not cursor:
break
return posts
def save_posts(posts, handle):
"""Save posts to JSON."""
out_file = f"{handle.replace('.', '_')}_posts.json"
with open(out_file, "w", encoding="utf-8") as f:
json.dump(posts, f, indent=2, ensure_ascii=False)
print(f"Saved {len(posts)} posts to {out_file}")
def uri_to_url(uri):
"""Convert at://did/... URIs to clickable Bluesky URLs."""
parts = uri.split("/")
if len(parts) >= 5 and parts[3] == "app.bsky.feed.post":
did = parts[2]
rkey = parts[4]
return f"https://bsky.app/profile/{did}/post/{rkey}"
return uri
def posts_to_html(posts, out_html):
"""Generate HTML with text and image thumbnails."""
with open(out_html, "w", encoding="utf-8") as f:
f.write("<html><body>\n")
for post in posts:
text = escape(post.get("text", ""))
url = uri_to_url(post.get("uri", ""))
imgs_html = "".join(
f'<a href="{escape(img["full"])}"><img src="{escape(img["thumb"])}" '
f'style="width:120px;height:auto;margin:2px;"></a>'
for img in post.get("images", [])
)
f.write(f"<div style='margin-bottom:20px;'><p>{text}</p>{imgs_html}<br>"
f"<a href='{url}'>View post</a></div>\n")
f.write("</body></html>\n")
print(f"HTML saved to {out_html}")
def main():
parser = argparse.ArgumentParser(description="Download Bluesky profile posts and generate HTML.")
parser.add_argument("handle", help="Bluesky handle (example: alice.bsky.social)")
parser.add_argument("--limit", type=int, default=100, help="Posts per request")
args = parser.parse_args()
client = connect()
posts = get_posts(client, args.handle, args.limit)
save_posts(posts, args.handle)
out_html = f"{args.handle.replace('.', '_')}_posts.html"
posts_to_html(posts, out_html)
if __name__ == "__main__":
main()
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/bash
jq '.thread[] | {author: .thread.post.author.handle, text: .thread.post.record.text}' $1
+27
View File
@@ -0,0 +1,27 @@
#!/usr/bin/env python3
import json
def generate_html(posts_file, out_file="profile.html"):
with open(posts_file, "r", encoding="utf-8") as f:
posts = json.load(f)
html = ['<html><body>']
for post in posts:
html.append(f"<p>{post.get('text','')}</p>")
# Handle embedded images if present
media = post.get("media", [])
for m in media:
# Convert CID to IPFS URL
cid = m.get("cid")
if cid:
url = f"https://bsky.social/ipfs/{cid}"
html.append(f'<img src="{url}" style="width:100px;height:100px;">')
html.append('</body></html>')
with open(out_file, "w", encoding="utf-8") as f:
f.write("\n".join(html))
generate_html("post.json")
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/bash
if [ "$#" -lt 1 ] || [ "$#" -gt 3 ]; then
echo "Usage: $0 arg1 [arg2] [arg3]"
exit 1
fi
# interactive session check
if [ -t 0 ]; then
echo -n "Delete existing output files? [y/N]: "
read ans
case "$ans" in
y|Y) rm -f *.school ;;
*) echo "Aborted"; exit 0 ;;
esac
fi
# process input file
while IFS= read -r line; do
new_f="${line%.*}.school"
f > "$new_f"
done < "$FILE"
exit 0
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/env python3
import re
import sys
from bsgetdid import get_did
def get_post_uri(url):
m = re.search(r'https://bsky\.app/profile/([^/]+)/post/([a-z0-9]+)', url)
if not m:
sys.exit("Invalid Bluesky post URL")
handle, rkey = m.groups()
did = get_did(handle)
return f"at://{did}/app.bsky.feed.post/{rkey}"
if __name__ == "__main__":
if len(sys.argv) != 2:
print(f"Usage: {sys.argv[0]} <bsky_post_url>")
sys.exit(1)
print(get_post_uri(sys.argv[1]))
+11
View File
@@ -0,0 +1,11 @@
#!/usr/bin/bash
if [ "$#" -ne 1 ] ; then
echo "Usage: $0 name"
exit 1
fi
bluetoothctl devices | grep "$1" | awk '{print $2}'
exit 0
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/bash
echo """
bluetoothctl
power on
agent on
default-agent
scan on
pair 22:22:D6:8F:28:2B
trust 22:22:D6:8F:28:2B
connect 22:22:D6:8F:28:2B
blueman-sendto 22:22:D6:8F:28:2B yourfile.jpg
bluetoothctl
remove 22:22:D6:8F:28:2B
"""
+11
View File
@@ -0,0 +1,11 @@
#!/usr/bin/bash
if [ "$#" -ne 1 ] ; then
echo "Usage: $0 name"
exit 1
fi
bluetoothctl connect $(bt-addr $1)
exit 0
Executable
+11
View File
@@ -0,0 +1,11 @@
#!/usr/bin/bash
if [ "$#" -ne 1 ] ; then
echo "Usage: $0 arg1"
exit 1
fi
cat $(which $1)
exit 0
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/bash
mkdir certs
cd certs
openssl genrsa -out ca.key 4096
openssl req -x509 -new -sha256 -days 356000 -nodes -subj "/CN=LibreWolf CA/" -key ca.key -out ca.crt
openssl genrsa -out librewolf.key 2048
openssl req -new -key librewolf.key -out librewolf.csr -subj '/CN=librewolf.local'
echo "subjectAltName = DNS:librewolf.local,IP:127.0.0.1" > librewolf.ext
openssl x509 -req -in librewolf.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out librewolf.crt -days 365 -sha256 -extfile librewolf.ext
cd -
cp -r certs /srv/appdata/librewolf/config/
+15
View File
@@ -0,0 +1,15 @@
#!/usr/bin/bash
NAME="${1:-db}"
SUBJ="${2:-myDB}"
TIME="${3:-356000}"
KEY="${4:-$NAME.key}"
CERT="${5:-$NAME.crt}"
echo run:
echo "openssl req -new -x509 -newkey rsa:4096 -sha256 -days $TIME -nodes \
-subj /CN=$SUBJ/ -keyout $KEY -out $CERT"
openssl req -new -x509 -newkey rsa:4096 -sha256 -days $TIME -nodes \
-subj "/CN=$SUBJ/" -keyout $KEY -out $CERT
echo $0 name subj days
+30
View File
@@ -0,0 +1,30 @@
#!/usr/bin/bash
if [ "$#" -ne 1 ] ; then
echo "Usage: $0 .iso"
exit 1
fi
ISO="$1"
WORKDIR=iso_edit
NEWISO=custom.iso
mkdir -p "$WORKDIR"
mount -o loop "$ISO" "$WORKDIR"
echo "[*] Enter chroot (bind mounts first)"
mount --bind /dev "$WORKDIR/dev"
mount --bind /sys "$WORKDIR/sys"
mount --bind /proc "$WORKDIR/proc"
chroot "$WORKDIR" /bin/bash
echo """
run:
post-chroot-iso
"""
# sudo umount "$WORKDIR"/{proc,sys,dev}
# genisoimage -o "$NEWISO" -V "CUSTOM" -R -J "$WORKDIR"
# note : from cdrkit package
exit 0
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/bash
ARCHIVE_DIR=${2:"/tmp/clean-dict.del"}
mkdir -p $ARCHIVE_DIR
if [ "$#" -lt 1 ] ; then
find . -type f -size -"${SIZE_MIN}c" -exec mv {} $ARCHIVE_DIR \;
exit 1
elif
find . -type f -size -"${SIZE_MIN}c" -delete
fi
exit 0
Executable
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
clone ()
{
if [ $# -ne "1" ]; then
PROFIL_NAME="$1";
PROJECT_NAME="$2";
git clone --recurse-submodules git@github.com:$PROFIL_NAME/$PROJECT_NAME.git;
else
PROJECT_NAME="$1";
git clone --recurse-submodules git@github.com:pain-pin/$PROJECT_NAME.git;
fi
}
clone "$@"
+20
View File
@@ -0,0 +1,20 @@
#!/bin/bash
commit_if_modified ()
{
local F_NAME=$1;
local DEL=$2;
#git pull;
vim + $F_NAME;
git add $F_NAME;
git commit
if [ $? -eq 0 ] ; then
echo -n "[no modifications]";
if [ -n "$DEL" ]; then
rm $F_NAME;
echo -n " -> deleted";
return 1;
fi;
fi;
return 0
}
commit_if_modified "$@"
Executable
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/bash
if [ "$#" -lt 1 ] ; then
echo "Usage: $0 USSID"
exit 1
fi
iwctl station wlan0 scan
iwctl station wlan0 get-networks
echo
iwctl station wlan0 connect $1
exit 0
+49
View File
@@ -0,0 +1,49 @@
#!/bin/bash
set -euo pipefail
ARCH=amd64
BASE_URL=https://cdimage.debian.org/debian-cd/current/$ARCH/iso-cd
# Détection du dernier netinst ISO
ISO=$(wget -qO- "$BASE_URL/" | grep -oP "debian-[0-9.]+-${ARCH}-netinst\.iso" | sort -V | tail -n1)
SUMS=SHA256SUMS
SIG=SHA256SUMS.sign
echo "Latest ISO found: $ISO"
# Téléchargement ISO seulement si absent
if [ ! -f "$ISO" ]; then
wget -N "$BASE_URL/$ISO"
else
echo "$ISO already exists, skipping download."
fi
# Téléchargement des fichiers de contrôle
wget -N "$BASE_URL/$SUMS"
wget -N "$BASE_URL/$SIG"
# Import des clés Debian Archive (utile pour cohérence générale)
KEYRING_PKG=debian-archive-keyring_2025.1_all.deb
if [ ! -f "$KEYRING_PKG" ]; then
wget "https://ftp.debian.org/debian/pool/main/d/debian-archive-keyring/$KEYRING_PKG"
fi
TMPDIR=$(mktemp -d)
ar x "$KEYRING_PKG" --output="$TMPDIR"
tar -xf "$TMPDIR"/data.tar.* -C "$TMPDIR"
gpg --import "$TMPDIR/usr/share/keyrings/debian-archive-keyring.gpg" || true
rm -rf "$TMPDIR"
# Import des clés Debian CD signing (officielles sur debian.org/CD/verify)
gpg --keyserver hkps://keyring.debian.org --recv-keys \
DF9B9C49EAA9298432589D76DA87E80D6294BE9B \
64E6EA7D \
E0B11894F66AEC98 || true
# Vérification signature
echo "Verifying signature..."
gpg --verify "$SIG" "$SUMS"
# Vérification ciblée uniquement sur lISO téléchargé
echo "Verifying checksum for $ISO..."
grep "$ISO" "$SUMS" | sha256sum -c -
+111
View File
@@ -0,0 +1,111 @@
#!/usr/bin/env python3
import os
import re
import subprocess
import sys
from collections import defaultdict
from pathlib import Path
import argparse
# ---- ensure spacy and model ----
try:
import spacy
except ImportError:
subprocess.check_call([sys.executable, "-m", "pip", "install", "spacy"])
import spacy
def load_model(name="fr_core_news_sm"):
try:
return spacy.load(name)
except OSError:
subprocess.check_call([sys.executable, "-m", "spacy", "download", name])
return spacy.load(name)
# ---- args ----
argparser = argparse.ArgumentParser()
argparser.add_argument("-v","--vault", default=".", help="Path to Obsidian vault")
argparser.add_argument("-d","--dict", default="Dictionary", help="Name of the dictionary directory")
args = argparser.parse_args()
# ---- config ----
VAULT_DIR = Path(args.vault)
DICT_DIR = VAULT_DIR / args.dict
WORD_REGEX = re.compile(r"\b[a-zA-Z]{3,}\b")
nlp = load_model("fr_core_news_sm")
# ---- prep ----
DICT_DIR.mkdir(exist_ok=True)
lemma_map = defaultdict(lambda: {"forms": set(), "files": set()})
# ---- scan ----
nlp.Defaults.stop_words.add(os.path.basename(os.getcwd()))
nlp.Defaults.stop_words.add("author")
nlp.Defaults.stop_words.add("jpeg")
nlp.Defaults.stop_words.add("jpg")
nlp.Defaults.stop_words.add("post")
nlp.Defaults.stop_words.add("like")
nlp.Defaults.stop_words.add("likes")
nlp.Defaults.stop_words.add("repost")
nlp.Defaults.stop_words.add("avatar")
nlp.Defaults.stop_words.add("bsky")
nlp.Defaults.stop_words.add("media")
nlp.Defaults.stop_words.add("thumnail")
nlp.Defaults.stop_words.add("http")
nlp.Defaults.stop_words.add("https")
nlp.Defaults.stop_words.add("com")
nlp.Defaults.stop_words.add("followers")
nlp.Defaults.stop_words.add("following")
nlp.Defaults.stop_words.add("unknown")
nlp.Defaults.stop_words.add("date")
nlp.Defaults.stop_words.add("social")
nlp.Defaults.stop_words.add("thumbnail")
nlp.Defaults.stop_words.add("replier")
nlp.Defaults.stop_words.add("replie")
nlp.Defaults.stop_words.add("for")
nlp.Defaults.stop_words.add("you")
nlp.Defaults.stop_words.add("from")
nlp.Defaults.stop_words.add("to")
nlp.Defaults.stop_words.add("script")
nlp.Defaults.stop_words.add("grep")
nlp.Defaults.stop_words.add("localhost")
nlp.Defaults.stop_words.add("sudo")
nlp.Defaults.stop_words.add("not")
for md_file in VAULT_DIR.rglob("*.md"):
if "Dictionary" in md_file.parts:
continue
text = md_file.read_text(encoding="utf-8", errors="ignore")
words = WORD_REGEX.findall(text.lower())
doc = nlp(" ".join(words))
for token in doc:
if token.is_stop:
continue
lemma = token.lemma_
if lemma.isalpha() and lemma not in nlp.Defaults.stop_words:
lemma_map[lemma]["forms"].add(token.text)
lemma_map[lemma]["files"].add(md_file)
print(f"Found {len(lemma_map)} lemmas.")
# ---- write ----
for lemma, data in lemma_map.items():
if len(data["files"]) < 2:
continue
file_path = DICT_DIR / f"{lemma}.md"
with open(file_path, "w", encoding="utf-8") as f:
f.write(f"# {lemma}\n\n---\n")
f.write(f"lemma: {lemma}\n")
f.write(f"forms: [{', '.join(sorted(data['forms']))}]\n---\n\n")
f.write("## Forms\n")
for form in sorted(data["forms"]):
f.write(f"- {form}\n")
f.write("\n## Found in\n")
for md in sorted(data["files"]):
rel_path = md.relative_to(VAULT_DIR)
f.write(f"- [[{rel_path}]]\n")
print(f"Dictionary generated in {DICT_DIR}")
+11
View File
@@ -0,0 +1,11 @@
#!/bin/bash
expresso ()
{
DIR="$HOME/perso/thm/interets/jeux/poker";
HISTORY="expresso_history.md";
SCRIPT=expresso_stat.sh;
TAIL=${1:-1000};
vim + $DIR/$HISTORY;
bash $DIR/$SCRIPT $DIR/$HISTORY $TAIL
}
expresso "$@"
+93
View File
@@ -0,0 +1,93 @@
#!/usr/bin/bash
FILE=$1
if [ -z "$FILE" ]; then
echo "Usage: $0 FILE"
exit 1
fi
sed "s/[a-zA-Z€]//g" "$FILE" | sed "s/-/0/g" | sed "s/,/./g" | gawk '
{
if (NF < 7) next
BUY_IN = $3 + 0.0
WON = $5 + 0.0
PRIZE = $7 + 0.0
key = BUY_IN
total_cost[key] += BUY_IN
total_won[key] += WON
total_prize[key] += PRIZE
nb_game[key]++
hot_game = 0
if (PRIZE >= BUY_IN * 3) {
hot_game = 1
total_hotgame[key]++
}
if ($4 == 1) {
game_won[key]++
if (hot_game) hot_game_won[key]++
}
}
END {
printf "%10s %6s %6s %9s %9s %9s %9s %9s %8s %8s\n", \
"BUY_IN", "Games", "Wins", "WinRate", "HotWin%", "RealRate", "Spent", "Won", "Net", "Marge"
for (key in nb_game) {
if (total_cost[key] == 0) continue
ratio = (game_won[key] / nb_game[key]) * 300
real_winrate = (total_won[key] / total_cost[key]) * 100
hotrate = (total_hotgame[key] > 0) ? (300 * hot_game_won[key] / total_hotgame[key]) : 0
net = total_won[key] - total_cost[key]
hotness = (total_prize[key] / total_cost[key]) * 100 / 3
printf "%10.2f %6d %6d %8.2f%% %8.2f%% %8.2f%% %8.2f€ %8.2f€ %7.2f€ %7.2f\n", \
key, nb_game[key], game_won[key], ratio, hotrate, real_winrate, \
total_cost[key], total_won[key], net, hotness
}
}'
#sed "s/[a-zA-Z€]//g" "$FILE" | sed "s/-/0/g" | sed "s/,/./g" | gawk '
#{
# if (NF < 7) next
#
# BUY_IN = $3 + 0.0
# WON = $5 + 0.0
# PRIZE = $7 + 0.0
#
# TOTAL_COST += BUY_IN
# TOTAL_WON += WON
# TOTAL_PRIZE += PRIZE
# NB_GAME++
# HOT_GAME = 0
#
# if ($PRIZE >= $BUY_IN) HOT_GAME = 1
# if ($PRIZE >= $BUY_IN) TOTAL_HOTGAME++
# if ($4 == 1) GAME_WON++
# if (HOT_GAME && $4 == 1) HOT_GAME_WON++
#}
#END {
# if (NB_GAME == 0 || TOTAL_COST == 0) {
# print "No valid data."
# exit
# }
# RATIO = (GAME_WON / NB_GAME) * 300
# REAL_WINRATE = (TOTAL_WON / TOTAL_COST) * 100
# NET = TOTAL_WON - TOTAL_COST
# HOTNESS = (TOTAL_PRIZE / TOTAL_COST) * 100 / 3
#
# printf "Games: %d\n", NB_GAME
# printf "Wins: %d\n", GAME_WON
# printf "WinRate: %.2f%%\n", RATIO
# printf "hot games WinRate: %.2f%%\n", 300 *HOT_GAME_WON / TOTAL_HOTGAME
# printf "Real win rate: %.2f%%\n", REAL_WINRATE
# printf "Spent: %.2f€\n", TOTAL_COST
# printf "Won: %.2f€\n", TOTAL_WON
# printf "Net: %.2f€\n", NET
# printf "Marge site: %.2f\n", HOTNESS
#}'
+11
View File
@@ -0,0 +1,11 @@
#!/usr/bin/bash
if [ "$#" -ne 1 ] ; then
echo "Usage: $0 keywd"
fi
find -L $BIN_DIR -type f -iregex ".*${1}[^/]*" | awk -F'/' '{print $NF}'
find -L $SBIN_DIR -type f -iregex ".*${1}[^/]*" | awk -F'/' '{print $NF}'
exit 0
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/bash
if [ "$#" -lt 1 ] ; then
echo "Usage: $0 arg1 [arg2] [arg3]"
exit 1
fi
#!/bin/bash
# Directory to search (default is current directory)
search_dir="${1:-.}"
# Find all files and their inode numbers, excluding directories and other types
find "$search_dir" -type f -exec stat --format="%i %n" {} \; | sort -n | uniq -d -w 10 | while read inode file; do
echo "Inode: $inode"
find "$search_dir" -type f -inum "$inode" -exec ls -l {} \;
echo "-------------------------------"
done
exit 0
Executable
+6
View File
@@ -0,0 +1,6 @@
#!/bin/bash
gcl ()
{
git clone $1 $2
}
gcl "$@"
+11
View File
@@ -0,0 +1,11 @@
#!/bin/bash
git_list_heavy ()
{
for B in $(git_list_heavy_commits | cut -d' ' -f1);
do
git rev-list --all | while read commit; do
git ls-tree -rl $commit;
done | grep --color=auto $B;
done
}
git_list_heavy "$@"
+6
View File
@@ -0,0 +1,6 @@
#!/bin/bash
git_list_heavy_commits ()
{
git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n -r | head -n 20
}
git_list_heavy_commits "$@"
+7
View File
@@ -0,0 +1,7 @@
#!/bin/bash
git_rm_repo ()
{
KEYWORD=$1;
git filter-repo --path-glob "$KEYWORD" --invert-paths
}
git_rm_repo "$@"
Executable
+7
View File
@@ -0,0 +1,7 @@
#!/bin/bash
gitadd ()
{
make fclean;
git add .
}
gitadd "$@"
+11
View File
@@ -0,0 +1,11 @@
#!/bin/bash
gitaddcommit ()
{
gitadd;
if [ -n "$1" ]; then
git commit -m "$1";
else
git commit;
fi
}
gitaddcommit "$@"
+33
View File
@@ -0,0 +1,33 @@
cat gitea_deploy.sh
#!/bin/bash
set -e
# Variables
GITEA_VERSION=1.21.11
USER_NAME=gitea
GITEA_PORT=9090
DATA_DIR=/opt/gitea
# Installer Docker si nécessaire
if ! command -v docker >/dev/null; then
apt update
apt install -y docker.io
systemctl enable docker
systemctl start docker
fi
# Créer dossier de données
mkdir -p ${DATA_DIR}/{data,config}
# Lancer Gitea (http://<ip>:9090)
docker run -d --name gitea \
-p ${GITEA_PORT}:3000 \
-p 2222:22 \
-v ${DATA_DIR}/data:/data \
gitea/gitea:${GITEA_VERSION}
echo "----------------------------------------"
echo "✅ Gitea lancé sur http://<IP>:${GITEA_PORT}"
echo "➡️ Identifiants à créer via l'interface web"
echo "➡️ Pour SSH : port 2222 (externe), clé à ajouter via l'UI"
echo "----------------------------------------"
+12
View File
@@ -0,0 +1,12 @@
#!/usr/bin/bash
if [ "$#" -ne 0 ]; then
echo "Usage: $0"
exit 1
fi
vim + .gitignore
gitaddcommit .gitignore
exit 0
Executable
+6
View File
@@ -0,0 +1,6 @@
#!/bin/bash
gitlog ()
{
git log --oneline --decorate --graph --all
}
gitlog "$@"
+10
View File
@@ -0,0 +1,10 @@
#!/bin/bash
gitmain ()
{
if [ -z "$1" ]; then
git checkout main;
git reset --hard "$1";
git push origin main --force;
fi
}
gitmain "$@"
+10
View File
@@ -0,0 +1,10 @@
#!/bin/bash
gitotal ()
{
gitaddcommit $@;
git pull;
if [ -n "$?" ]; then
git push origin HEAD;
fi
}
gitotal "$@"
+25
View File
@@ -0,0 +1,25 @@
#!/bin/bash
# save_redundant.sh
# Sauvegarde/redondance GNUnet : 3 duplicatas
# fichier source et clé de publication
SRC="$1"
if [ -z "$SRC" ]; then
echo "Usage: $0 <file>"
exit 1
fi
# Tag public de référence
KEYWORD="backup:$(basename "$SRC")"
# Publier le fichier (ajout au réseau GNUnet FS)
gnunet-publish -n -k "$KEYWORD" -r 3 "$SRC"
# -n : anonyme
# -k : mot-clé (pour retrouver)
# -r : redondance (nb de duplicatas)
# -p : chemin du fichier
# Vérifie que la donnée est bien publiée
echo "Recherche des duplicatas GNUnet pour $KEYWORD..."
gnunet-search "$KEYWORD"
+16
View File
@@ -0,0 +1,16 @@
#!/usr/bin/bash
#if [ "$#" -lt 1 ] || [ "$#" -gt 3 ]; then
# echo "Usage: $0 arg1 [arg2] [arg3]"
# exit 1
#fi
echo "Sur pixel 9 taper 7 fois sur le numero de build pour entrer en mode developpeur"
#pacman -Sy android-udev
#pacman -S android-tools
#apt install android-sdk-platform-tools-common
#apt install android-sdk-platform-tools-common
#systemctl stop fwupd.service
Executable
+6
View File
@@ -0,0 +1,6 @@
#!/bin/bash
grepip ()
{
grep --color=auto -Eo $IP_REG $@ | sortu
}
grepip "$@"
+6
View File
@@ -0,0 +1,6 @@
#!/usr/bin/bash
grep -Eo $IP_REG $@ | sortu
exit 0
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/bash
if [ "$#" -lt 1 ] || [ "$#" -gt 3 ]; then
echo "Usage: $0 key"
echo "Usage: grep values after key=value"
exit 1
fi
awk -v key="$1" '{
for (i = 1; i <= NF; i++)
if ($i ~ "^"key"=") {
split($i, a, "=")
print a[2]
}
}' # | cut -d\ -f 1
exit 0
+6
View File
@@ -0,0 +1,6 @@
#!/bin/bash
header_awk ()
{
grep --color=auto -RE $CFUNCTION src | cut -d: -f2 | sed s/\$/';'/g
}
header_awk "$@"
+16
View File
@@ -0,0 +1,16 @@
#!/bin/bash
header_journal ()
{
F_NAME=$1;
. refresh_time
echo "$DATE" >> $F_NAME;
echo "$TIME" >> $F_NAME;
echo "$USER" >> $F_NAME;
echo "$HOST" >> $F_NAME;
echo >> $F_NAME;
echo "###############################################" >> $F_NAME;
echo >> $F_NAME;
echo "$F_NAME" >> $F_NAME;
echo >> $F_NAME
}
header_journal "$@"

Some files were not shown because too many files have changed in this diff Show More