Init commit
This commit is contained in:
21
bin/battery
Executable file
21
bin/battery
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import subprocess
|
||||
|
||||
|
||||
def main():
|
||||
with open("/sys/class/power_supply/BAT0/capacity", "r") as f:
|
||||
capacity = f.read()
|
||||
# capacity = 10
|
||||
|
||||
if int(capacity) <= 20:
|
||||
text = "Внимание, низкий уровень заряда батареи! Подключите зарядное устройство"
|
||||
subprocess.run(["notify-send", "-u", "critical", text])
|
||||
subprocess.run(["rhvoice_say", text])
|
||||
elif int(capacity) >= 80 and int(capacity) < 100:
|
||||
text = "Батарея достаточно заряжена, можно отключать!"
|
||||
subprocess.run(["notify-send", "-t", "15000", text])
|
||||
subprocess.run(["rhvoice_say", text])
|
||||
|
||||
|
||||
main()
|
||||
3
bin/clipboard.sh
Executable file
3
bin/clipboard.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
cliphist list | rofi -theme archer -font "Iosevka Nerd Font Medium 18" -dmenu -p "Clipboard" | cliphist decode | wl-copy
|
||||
279
bin/clockv2
Executable file
279
bin/clockv2
Executable file
@@ -0,0 +1,279 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
# Работа со временем.
|
||||
|
||||
import subprocess
|
||||
from datetime import datetime
|
||||
|
||||
import requests
|
||||
|
||||
# noqa
|
||||
minutes = [
|
||||
"ноль минут",
|
||||
"одна минута",
|
||||
"две минуты",
|
||||
"три минуты",
|
||||
"четыре минуты",
|
||||
"пять минут",
|
||||
"шесть минут",
|
||||
"семь минут",
|
||||
"восемь минут",
|
||||
"девять минут",
|
||||
"десять минут",
|
||||
"одиннадцать минут",
|
||||
"двенадцать минут",
|
||||
"тринадцать минут",
|
||||
"четырнадцать минут",
|
||||
"пятнадцать минут",
|
||||
"шестнадцать минут",
|
||||
"семнадцать минут",
|
||||
"восемнадцать минут",
|
||||
"девятнадцать минут",
|
||||
"двадцать минут",
|
||||
"двадцать одна минута",
|
||||
"двадцать две минуты",
|
||||
"двадцать три минуты",
|
||||
"двадцать четыре минуты",
|
||||
"двадцать пять минут",
|
||||
"двадцать шесть минут",
|
||||
"двадцать семь минут",
|
||||
"двадцать восемь минут",
|
||||
"двадцать девять минут",
|
||||
"тридцать минут",
|
||||
"тридцать одна минута",
|
||||
"тридцать две минуты",
|
||||
"тридцать три минуты",
|
||||
"тридцать четыре минуты",
|
||||
"тридцать пять минут",
|
||||
"тридцать шесть минут",
|
||||
"тридцать семь минут",
|
||||
"тридцать восемь минут",
|
||||
"тридцать девять минут",
|
||||
"сорок минут",
|
||||
"сорок одна минута",
|
||||
"сорок две минуты",
|
||||
"сорок три минуты",
|
||||
"сорок четыре минуты",
|
||||
"сорок пять минут",
|
||||
"сорок шесть минут",
|
||||
"сорок семь минут",
|
||||
"сорок восемь минут",
|
||||
"сорок девять минут",
|
||||
"пятьдесят минут",
|
||||
"пятьдесят одна минута",
|
||||
"пятьдесят две минуты",
|
||||
"пятьдесят три минуты",
|
||||
"пятьдесят четыре минуты",
|
||||
"пятьдесят пять минут",
|
||||
"пятьдесят шесть минут",
|
||||
"пятьдесят семь минут",
|
||||
"пятьдесят восемь минут",
|
||||
"пятьдесят девять минут",
|
||||
]
|
||||
|
||||
clocks = [
|
||||
"ноль часов",
|
||||
"один час",
|
||||
"два часа",
|
||||
"три часа",
|
||||
"четыре часа",
|
||||
"пять часов",
|
||||
"шесть часов",
|
||||
"семь часов",
|
||||
"восемь часов",
|
||||
"девять часов",
|
||||
"десять часов",
|
||||
"одиннадцать часов",
|
||||
"двенадцать часов",
|
||||
"тринадцать часов",
|
||||
"четы*рнадцать часов",
|
||||
"пятнадцать часов",
|
||||
"шестнадцать часов",
|
||||
"семнадцать часов",
|
||||
"восемнадцать часов",
|
||||
"девятнадцать часов",
|
||||
"двадцать часов",
|
||||
"двадцать один час",
|
||||
"двадцать два часа",
|
||||
"двадцать три часа",
|
||||
]
|
||||
|
||||
days = [
|
||||
"ноль",
|
||||
"первое",
|
||||
"второе",
|
||||
"третье",
|
||||
"четвертое",
|
||||
"пятое",
|
||||
"шестое",
|
||||
"седьмое",
|
||||
"восьмое",
|
||||
"девятое",
|
||||
"десятое",
|
||||
"одиннадцатое",
|
||||
"двенадцатое",
|
||||
"тринадцатое",
|
||||
"четырнадцатое",
|
||||
"пятнадцатое",
|
||||
"шестнадцатое",
|
||||
"семнадцатое",
|
||||
"восемнадцатое",
|
||||
"девятнадцатое",
|
||||
"двадцатое",
|
||||
"двадцать первое",
|
||||
"двадцать второе",
|
||||
"двадцать третье",
|
||||
"двадцать четвертое",
|
||||
"двадцать пятое",
|
||||
"двадцать шестое",
|
||||
"двадцать седьмое",
|
||||
"двадцать восьмое",
|
||||
"двадцать девятое",
|
||||
"тридцатое",
|
||||
"тридцать первое",
|
||||
]
|
||||
|
||||
w_day = [
|
||||
"понед*ельник",
|
||||
"вт*орник",
|
||||
"сред*а",
|
||||
"четв*ерг",
|
||||
"п*ятница",
|
||||
"субб*ота",
|
||||
"воскрес*енье",
|
||||
]
|
||||
|
||||
month_dic = {
|
||||
1: "январ*я",
|
||||
2: "феврал*я",
|
||||
3: "м*арта",
|
||||
4: "апр*еля",
|
||||
5: "м*ая",
|
||||
6: "и*юня",
|
||||
7: "и*юля",
|
||||
8: "*августа",
|
||||
9: "сентябр*я",
|
||||
10: "октябр*я",
|
||||
11: "ноябр*я",
|
||||
12: "декабр*я",
|
||||
}
|
||||
|
||||
|
||||
def get_date():
|
||||
"""
|
||||
Получение текущего времени.
|
||||
В формате: "HH часов YY минут"
|
||||
"""
|
||||
now_time = datetime.now() # текущая дата со временем
|
||||
week_day = datetime.today().weekday()
|
||||
hour = clocks[now_time.hour]
|
||||
minute = minutes[now_time.minute]
|
||||
day = now_time.day
|
||||
month = now_time.month
|
||||
|
||||
say_date = (
|
||||
hour
|
||||
+ " "
|
||||
+ minute
|
||||
+ ", "
|
||||
+ w_day[week_day]
|
||||
+ ", "
|
||||
+ days[day]
|
||||
+ " "
|
||||
+ month_dic.get(month)
|
||||
+ ", "
|
||||
)
|
||||
|
||||
return say_date
|
||||
|
||||
|
||||
def inflect(n: object, form1: object, form2: object, form5: object) -> object:
|
||||
"""
|
||||
Приведение в соответствие слова в зависимости от числа.
|
||||
Например: inflect(18,'градус','градуса','градусов') -> 'градусов'
|
||||
"""
|
||||
n = abs(n) # убираем минус, если есть
|
||||
n = n % 100 # две последних цифры
|
||||
n1 = n % 10 # последняя цифра
|
||||
|
||||
if 10 < n < 20:
|
||||
form = form5
|
||||
elif 1 < n1 < 5:
|
||||
form = form2
|
||||
elif n1 == 1:
|
||||
form = form1
|
||||
else:
|
||||
form = form5
|
||||
|
||||
return form
|
||||
|
||||
|
||||
def temperature(n):
|
||||
if n < 0:
|
||||
f = "мор*оза"
|
||||
elif n >= 1:
|
||||
f = "тепл*а"
|
||||
else:
|
||||
f = ""
|
||||
|
||||
return f
|
||||
|
||||
|
||||
with open("/sys/class/power_supply/BAT0/capacity", "r") as f:
|
||||
capacity = f.read()
|
||||
|
||||
with open("/sys/class/power_supply/BAT0/cycle_count", "r") as f:
|
||||
cycle = f.read()
|
||||
|
||||
with open("/sys/class/power_supply/BAT0/status", "r") as f:
|
||||
status = f.read()
|
||||
|
||||
|
||||
if int(capacity) % 10 == 1:
|
||||
percent = "процент"
|
||||
elif int(capacity) % 10 == 2 or int(capacity) % 10 == 3 or int(capacity) % 10 == 4:
|
||||
percent = "процента"
|
||||
else:
|
||||
percent = "процентов"
|
||||
|
||||
if status.strip() == "Discharging":
|
||||
bstat = "Разряжается"
|
||||
else:
|
||||
bstat = "Заряжается"
|
||||
|
||||
|
||||
def main():
|
||||
str_time = get_date()
|
||||
|
||||
weather_url = (
|
||||
"http://api.openweathermap.org/data/2.5/"
|
||||
"weather?id=472757&lang=ru"
|
||||
"&appid=6f9d925282c57d29a95977d346e2d528&units=metric"
|
||||
)
|
||||
# 539221
|
||||
r = requests.get(weather_url).text.split(sep=",")
|
||||
hum = r[4].split(sep=":")[1]
|
||||
t = r[7].split(sep=":")[2]
|
||||
temp = round(float(t))
|
||||
temp_f = temperature(temp)
|
||||
lc_weather = inflect(temp, "градус", "градуса", "градусов")
|
||||
weather_string = (
|
||||
# " Сейч*ас в стан*ице Кум*ылженской" + str(temp) + lc_weather + temp_f + hum
|
||||
" Сейч*ас в Волгогр*аде"
|
||||
+ str(temp)
|
||||
+ lc_weather
|
||||
+ temp_f
|
||||
+ hum
|
||||
)
|
||||
|
||||
battery = f" Заряд батареи - {capacity} {percent}. {bstat}"
|
||||
|
||||
a = "Текущее Время " + str_time + weather_string + battery
|
||||
|
||||
return subprocess.run(["rhvoice_say", a])
|
||||
|
||||
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
print("\rПрервано пользователем!")
|
||||
86
bin/conv
Executable file
86
bin/conv
Executable file
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env lua
|
||||
|
||||
local lfs = require("lfs")
|
||||
|
||||
local function file_rename(file)
|
||||
local patterns = "[%(%)[%]{}%s]"
|
||||
local new_name = string.gsub(file, patterns, "_")
|
||||
os.rename(file, new_name)
|
||||
os.rename(new_name, string.gsub(new_name, "mkv.", ""))
|
||||
os.rename(new_name, string.gsub(new_name, "webm.", ""))
|
||||
if file ~= new_name then
|
||||
print("Файл " .. file .. " был переименован ==> " .. new_name)
|
||||
end
|
||||
end
|
||||
|
||||
-- -----------------------------------------------
|
||||
-- Скачивание файлов
|
||||
-- -----------------------------------------------
|
||||
local function downloads(url)
|
||||
local tempdir = "temp"
|
||||
lfs.mkdir(tempdir)
|
||||
|
||||
lfs.chdir(tempdir)
|
||||
print("Качаем видео...")
|
||||
os.execute("yt-dlp -o '%(title)s.%(ext)s' " .. url)
|
||||
print("Качаем перевод...")
|
||||
os.execute("vot-cli " .. url .. " --output .")
|
||||
|
||||
local video_t = ""
|
||||
local audio_t = ""
|
||||
|
||||
for f in lfs.dir(".") do
|
||||
local mode = lfs.attributes("./" .. f, "mode")
|
||||
local ext = f:match("[^.]+$")
|
||||
if mode == "file" and (ext == "webm" or ext == "mkv" or ext == "mp4") then
|
||||
video_t = f
|
||||
elseif mode == "file" and ext == "mp3" then
|
||||
audio_t = f
|
||||
else
|
||||
print("Файлы не найдены...")
|
||||
end
|
||||
end
|
||||
|
||||
print("Конвертируем...")
|
||||
os.execute(
|
||||
'ffmpeg -i "'
|
||||
.. video_t
|
||||
.. '" -i '
|
||||
.. audio_t
|
||||
.. ' -c:v copy -filter_complex "[0:a] volume=0.15 [original]; [original][1:a] amix=inputs=2:duration=longest [audio_out]" -map 0:v -map "[audio_out]" -y ../'
|
||||
.. '"'
|
||||
.. video_t
|
||||
.. '"'
|
||||
)
|
||||
|
||||
print("Удаляется файл ==> ", video_t)
|
||||
os.remove(video_t)
|
||||
print("Удаляется файл ==> ", audio_t)
|
||||
os.remove(audio_t)
|
||||
|
||||
lfs.chdir("../")
|
||||
|
||||
print("Удаляется директория ==> " .. tempdir)
|
||||
lfs.rmdir(tempdir)
|
||||
end
|
||||
|
||||
-- Открываем файл для чтения
|
||||
local file = io.open(arg[1], "r")
|
||||
|
||||
if file then
|
||||
-- Читаем и выводим построчно содержимое файла
|
||||
for line in file:lines() do
|
||||
downloads(line)
|
||||
end
|
||||
-- Закрываем файл
|
||||
file:close()
|
||||
else
|
||||
print("Не удалось открыть файл")
|
||||
end
|
||||
|
||||
for f in lfs.dir(".") do
|
||||
local mode = lfs.attributes("./" .. f, "mode")
|
||||
if mode == "file" then
|
||||
file_rename(f)
|
||||
end
|
||||
end
|
||||
103
bin/daily_backup_hardlink.sh
Executable file
103
bin/daily_backup_hardlink.sh
Executable file
@@ -0,0 +1,103 @@
|
||||
#!/bin/bash
|
||||
|
||||
export DISPLAY=:1
|
||||
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
|
||||
# === НАСТРОЙКИ ===
|
||||
|
||||
# Папка-источник, откуда копируем
|
||||
SRC="$HOME"
|
||||
|
||||
# Корневая папка для хранения бэкапов
|
||||
BACKUP_ROOT="$HOME/Share/backup/lap"
|
||||
|
||||
# Только эти подпапки будут участвовать в бэкапе (относительно SRC)
|
||||
INCLUDE_DIRS=(
|
||||
".config/nvim"
|
||||
".config/qtile"
|
||||
".config/fish"
|
||||
".config/kitty"
|
||||
".config/gtk-3.0"
|
||||
".config/gtk-4.0"
|
||||
".config/mpv"
|
||||
".config/rofi"
|
||||
".tmux"
|
||||
)
|
||||
|
||||
# Дата сегодняшнего бэкапа
|
||||
TODAY=$(date +%Y%m%d-%H%M%S)
|
||||
TODAY_DIR="$BACKUP_ROOT/$TODAY"
|
||||
LATEST_LINK="$BACKUP_ROOT/LATEST"
|
||||
|
||||
# === СОЗДАНИЕ ПАПКИ ДЛЯ БЭКАПА ===
|
||||
|
||||
mkdir -p "$TODAY_DIR"
|
||||
echo "📦 Начало бэкапа: $TODAY_DIR из $SRC"
|
||||
|
||||
# === ЕСЛИ ЕСТЬ LATEST, СРАВНИВАЕМ С НИМ ===
|
||||
|
||||
if [[ -L "$LATEST_LINK" && -d "$LATEST_LINK" ]]; then
|
||||
PREV_DIR=$(readlink -f "$LATEST_LINK")
|
||||
|
||||
echo "🔁 Сравнение с предыдущим бэкапом: $PREV_DIR"
|
||||
|
||||
for rel_dir in "${INCLUDE_DIRS[@]}"; do
|
||||
# Найдём все файлы внутри указанной папки
|
||||
find "$SRC/$rel_dir" -type f | while read -r src_file; do
|
||||
rel_path="${src_file#$SRC/}" # путь относительно SRC
|
||||
prev_file="$PREV_DIR/$rel_path" # путь в предыдущем бэкапе
|
||||
dest_file="$TODAY_DIR/$rel_path" # путь в новом бэкапе
|
||||
dest_dir=$(dirname "$dest_file")
|
||||
|
||||
mkdir -p "$dest_dir"
|
||||
|
||||
if [[ -f "$prev_file" ]]; then
|
||||
# сравнение хешей
|
||||
hash_src=$(sha256sum "$src_file" | awk '{print $1}')
|
||||
hash_prev=$(sha256sum "$prev_file" | awk '{print $1}')
|
||||
|
||||
if [[ "$hash_src" == "$hash_prev" ]]; then
|
||||
ln "$prev_file" "$dest_file"
|
||||
echo "🔗 Жёсткая ссылка: $rel_path" >/dev/null
|
||||
else
|
||||
cp "$src_file" "$dest_file"
|
||||
echo "📄 Изменён → копия: $rel_path"
|
||||
fi
|
||||
else
|
||||
cp "$src_file" "$dest_file"
|
||||
echo "📄 Новый → копия: $rel_path"
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
else
|
||||
echo "🚨 LATEST не найден. Полный бэкап."
|
||||
|
||||
for rel_dir in "${INCLUDE_DIRS[@]}"; do
|
||||
if [[ -d "$SRC/$rel_dir" ]]; then
|
||||
mkdir -p "$TODAY_DIR/$(dirname "$rel_dir")"
|
||||
cp -a "$SRC/$rel_dir" "$TODAY_DIR/$(dirname "$rel_dir")"
|
||||
echo "✅ Скопировано: $rel_dir"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# === ОБНОВЛЯЕМ ССЫЛКУ НА LATEST ===
|
||||
|
||||
rm -f "$LATEST_LINK"
|
||||
ln -s "$TODAY" "$LATEST_LINK"
|
||||
echo "✅ Обновлена ссылка LATEST → $TODAY"
|
||||
notify-send "✅ Завершили бекап → $TODAY"
|
||||
|
||||
# === УДАЛЯЕМ СТАРЫЕ БЭКАПЫ (оставляем один на каждый день по формату YYYYMMDD-HHMMSS) ===
|
||||
|
||||
echo "Удаляем лишние бэкапы"
|
||||
cd "$BACKUP_ROOT" || exit 1
|
||||
|
||||
for day in $(ls -1 | grep -E '^[0-9]{8}-[0-9]{6}$' | cut -c1-8 | sort -u); do
|
||||
keep=$(ls -1 | grep "^$day-" | sort | tail -n 1)
|
||||
|
||||
for snapshot in $(ls -1 | grep "^$day-" | grep -v "^$keep$"); do
|
||||
echo "Удаляю $snapshot"
|
||||
rm -rf "$snapshot"
|
||||
done
|
||||
done
|
||||
5
bin/hibernate.sh
Executable file
5
bin/hibernate.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
sudo rtcwake -m mem -s 1800
|
||||
sleep 3
|
||||
sudo systemctl hibernate
|
||||
71
bin/net_traf.sh
Executable file
71
bin/net_traf.sh
Executable file
@@ -0,0 +1,71 @@
|
||||
#!/bin/bash
|
||||
|
||||
# network_traffic.sh NETWORK_INTERFACE [POLLING_INTERVAL]
|
||||
|
||||
iface=${1:-lo}
|
||||
# # iface='wlp0s20f3'
|
||||
isecs=${2:-1}
|
||||
|
||||
# `snore` adapted from https://blog.dhampir.no/content/sleeping-without-a-subprocess-in-bash-and-how-to-sleep-forever
|
||||
# without MacOS workaround, TODO: with _snore_fd initialized separatedly, also i dont touch IFS so dont bother with it
|
||||
snore() {
|
||||
local IFS
|
||||
[[ -n "${_snore_fd:-}" ]] || { exec {_snore_fd}<> <(:); } 2>/dev/null
|
||||
read ${1:+-t "$1"} -u $_snore_fd || :
|
||||
}
|
||||
|
||||
# `human_readable` adapted from https://gist.github.com/cjsewell/96463db7fec6faeab291
|
||||
human_readable() {
|
||||
local value=$1
|
||||
local units=(B K M G T P)
|
||||
local index=0
|
||||
while ((value > 1000 && index < 5)); do
|
||||
((value /= 1000, index++))
|
||||
done
|
||||
echo "$value${units[$index]}"
|
||||
}
|
||||
|
||||
# sanity checking, timing here is not an issue anymore -- TODO: check how waybar reacts to `exit 1`
|
||||
test -n "${iface}" && grep -q "${iface}:" /proc/net/dev || {
|
||||
printf '{"text": "%s"}\n' "${iface} not found"
|
||||
exit 1
|
||||
}
|
||||
test "$isecs" -gt 0 || {
|
||||
printf '{"text": "%s"}\n' "${isecs} not valid"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# NOTE: `/proc/net/dev` format is:
|
||||
# RX bytes packets errs drop fifo frame compressed multicast
|
||||
# TX bytes packets errs drop fifo colls carrier compressed
|
||||
|
||||
declare -a traffic_prev traffic_curr traffic_delta
|
||||
# NOTE: array items are:
|
||||
# 0=rx_bytes 1=rx_packets 2=rx_errs 3=rx_drop
|
||||
# 4=tx_bytes 5=tx_packets 6=tx_errs 7=tx_drop
|
||||
|
||||
# TODO: rearrange the loop, do not show bogus on first iteration
|
||||
traffic_prev=(0 0 0 0 0 0 0 0)
|
||||
while snore ${isecs}; do
|
||||
traffic_curr=($(awk '/^ *'${iface}':/{print $2 " " $3 " " $4 " " $5 " " $10 " " $11 " " $12 " " $13}' /proc/net/dev))
|
||||
for i in {0..7}; do
|
||||
((traffic_delta[i] = (traffic_curr[i] - traffic_prev[i]) / isecs))
|
||||
done
|
||||
traffic_prev=(${traffic_curr[@]})
|
||||
printf '{"text": "%5s⇣ %5s⇡"}\n' $(human_readable ${traffic_delta[0]}) $(human_readable ${traffic_delta[4]})
|
||||
#printf '{"text": "%5s⇣ %5s⇡", "alt": "%s", "tooltip": "%s", "class": "%s", "percentage": %d }\n' $(human_readable ${traffic_delta[0]}) $(human_readable ${traffic_delta[4]}) '_alt' '_tooltip' '_class' 0
|
||||
done
|
||||
|
||||
# TODO: handle errors
|
||||
# TODO: aggregate interfaces (default to all from `ls /sys/class/net | grep -E '^(eth|wlan|enp|wlp)'`)
|
||||
# TODO: tooltip with details per each interface
|
||||
# TODO: colors (?)
|
||||
# TODO: styling (in waybar .css, using {percent})
|
||||
# TODO: unicode meter (" ","▁","▁","▂","▃","▄","▅","▆","▇","█")
|
||||
# TODO: split rx/tx (?)
|
||||
# TODO: test and optimize
|
||||
|
||||
# NOTE: in waybar config (do NOT use "interval"):
|
||||
# "custom/network_traffic": {
|
||||
# "exec": "~/.config/waybar/scripts/network_traffic.sh enp14s0",
|
||||
# },
|
||||
10
bin/powermenu
Executable file
10
bin/powermenu
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
choice=$(echo -e "Lock\nLogout\nReboot\nShutdown\nSleep\nHibernate" | rofi -theme archer -font "Iosevka Nerd Font Medium 18" -dmenu -p "Power menu")
|
||||
case "$choice" in
|
||||
"Lock") betterlockscreen -l ;;
|
||||
"Logout") pkill -u $USER ;;
|
||||
"Reboot") doas systemctl reboot ;;
|
||||
"Shutdown") doas systemctl poweroff ;;
|
||||
"Sleep") doas systemctl suspend ;;
|
||||
"Hibernate") doas systemctl hibernate ;;
|
||||
esac
|
||||
19
bin/rename_v3.lua
Normal file
19
bin/rename_v3.lua
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env lua
|
||||
|
||||
local lfs = require("lfs")
|
||||
|
||||
local function file_rename(file)
|
||||
local patterns = "[%(%)[%]{}%s]"
|
||||
local new_name = string.gsub(file, patterns, "_")
|
||||
os.rename(file, new_name)
|
||||
if file ~= new_name then
|
||||
print("Файл " .. file .. " был переименован ==> " .. new_name)
|
||||
end
|
||||
end
|
||||
|
||||
for f in lfs.dir(".") do
|
||||
local mode = lfs.attributes("./" .. f, "mode")
|
||||
if mode == "file" then
|
||||
file_rename(f)
|
||||
end
|
||||
end
|
||||
74
bin/rsync.sh
Executable file
74
bin/rsync.sh
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
|
||||
export DISPLAY=:1
|
||||
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
|
||||
|
||||
SRC="/home/fox/Share"
|
||||
DST="fox@archevod.netcraze.pro:/home/fox/"
|
||||
DST_LOCAL="fox@seeed:/home/fox/"
|
||||
LOCKFILE="/home/fox/bin/rsync_watch.lock"
|
||||
LOGFILE="/home/fox/bin/log/rsync_watch.log"
|
||||
NOTIFY="notify-send"
|
||||
|
||||
IP=$(ip -4 addr show wlan0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}')
|
||||
TARGET_IP="192.168.1.3"
|
||||
|
||||
# Проверяем размер файла в байтах
|
||||
FILESIZE=$(stat -c%s "$LOGFILE")
|
||||
# 100 мегабайт в байтах
|
||||
LIMIT=$((100 * 1024 * 1024))
|
||||
|
||||
log() {
|
||||
echo -e "$(date '+%Y-%m-%d %H:%M:%S') $*" | tee -a "$LOGFILE"
|
||||
}
|
||||
|
||||
if [ "$FILESIZE" -gt "$LIMIT" ]; then
|
||||
: >"$LOGFILE" # Очищаем файл (альтернативно можно использовать > "$FILE")
|
||||
log "Файл был очищен \"$(date)\""
|
||||
log ""
|
||||
fi
|
||||
|
||||
# Проверка наличия inotifywait
|
||||
if ! command -v inotifywait &>/dev/null; then
|
||||
log "Ошибка: inotifywait не установлен. Установите inotify-tools."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$IP" == "$TARGET_IP" ]]; then
|
||||
log "Старт наблюдения за $SRC\n Цель: $DST_LOCAL\n"
|
||||
else
|
||||
log "Старт наблюдения за $SRC\n Цель: $DST\n"
|
||||
fi
|
||||
|
||||
while true; do
|
||||
inotifywait -r -e modify,create,delete,move "$SRC" >/dev/null 2>&1
|
||||
|
||||
# Проверка на наличие блокировки
|
||||
if [ -f "$LOCKFILE" ] && kill -0 "$(cat "$LOCKFILE")" 2>/dev/null; then
|
||||
log "Пропущено: rsync уже запущен (PID $(cat "$LOCKFILE"))"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Установка блокировки
|
||||
echo $$ >"$LOCKFILE"
|
||||
sleep 20
|
||||
|
||||
SECONDS=0
|
||||
$NOTIFY "🔁 Начата синхронизация..."
|
||||
log "----------------------------------------"
|
||||
log "Изменения обнаружены. Запуск rsync..."
|
||||
|
||||
log "Local IP address = $IP"
|
||||
if [[ "$IP" == "$TARGET_IP" ]]; then
|
||||
rsync -auvhH --delete "$SRC" "$DST_LOCAL" >>"$LOGFILE" 2>&1
|
||||
else
|
||||
rsync -auvhH -e "ssh -p 3022" --delete "$SRC" "$DST" >>"$LOGFILE" 2>&1
|
||||
fi
|
||||
|
||||
log "Синхронизация завершена за $SECONDS сек."
|
||||
log "----------------------------------------\n"
|
||||
$NOTIFY "🔁 Синхронизация завершена за $SECONDS сек."
|
||||
|
||||
# Удаление блокировки
|
||||
rm -f "$LOCKFILE"
|
||||
done
|
||||
36
bin/test_ip.lua
Executable file
36
bin/test_ip.lua
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env lua
|
||||
|
||||
local http = require("socket.http")
|
||||
local ltn12 = require("ltn12")
|
||||
|
||||
-- Функция для получения внешнего IP-адреса
|
||||
function get_external_ip()
|
||||
local services = {
|
||||
"https://api.ipify.org",
|
||||
"https://ident.me",
|
||||
"https://ifconfig.me/ip",
|
||||
}
|
||||
|
||||
for _, url in ipairs(services) do
|
||||
local response = {}
|
||||
local _, status = http.request({
|
||||
url = url,
|
||||
sink = ltn12.sink.table(response),
|
||||
})
|
||||
|
||||
if status == 200 then
|
||||
return table.concat(response)
|
||||
end
|
||||
end
|
||||
|
||||
return nil, "Не удалось получить IP-адрес"
|
||||
end
|
||||
|
||||
-- Основная часть скрипта
|
||||
local ip, err = get_external_ip()
|
||||
|
||||
if ip then
|
||||
print(ip)
|
||||
else
|
||||
print("Ошибка: " .. err)
|
||||
end
|
||||
5
bin/waybar_clock.sh
Executable file
5
bin/waybar_clock.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
date=$(date '+%a %d %b | %H:%M |')
|
||||
|
||||
echo $date
|
||||
5
bin/wttr.sh
Executable file
5
bin/wttr.sh
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
wttr=$(curl 'https://wttr.in/Kumylzhenskaya?format=1')
|
||||
|
||||
echo $wttr
|
||||
Reference in New Issue
Block a user