This commit is contained in:
parent
7e5d880156
commit
d93f63cf82
40 changed files with 448 additions and 649 deletions
|
|
@ -6,17 +6,19 @@ declare -a files
|
|||
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
"-s") SILENT=1;;
|
||||
"-"*) SILENT=1;;
|
||||
*) files+=("$1");;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [ "$#" -gt 0 ]; then
|
||||
r="$(curl -X PUT --data-binary "@$1" "$URL" 2>/dev/null)"
|
||||
ext="$(basename -- "$1")"
|
||||
ext=".${ext##*.}"
|
||||
[ "$ext" = ".$1" ] && ext=
|
||||
if [ "${#files}" -gt 0 ]; then
|
||||
for file in "${files[@]}"; do
|
||||
r="$(curl -X PUT --data-binary "@$file" "$URL" 2>/dev/null)"
|
||||
ext="$(basename -- "$file")"
|
||||
ext=".${ext##*.}"
|
||||
[ "$ext" = ".$file" ] && ext=
|
||||
done
|
||||
else
|
||||
if [ "$SILENT" = 1 ]; then
|
||||
TMP_FILENAME="$(mktemp)"
|
||||
|
|
@ -26,9 +28,8 @@ else
|
|||
else
|
||||
r="$(curl -X PUT --data-binary @- "$URL" 2>/dev/null)"
|
||||
fi
|
||||
[ -n "$TMP_FILENAME" ] && rm "$TMP_FILENAME"
|
||||
fi
|
||||
|
||||
r="$(tr -d $'\n' <<< "$r")"
|
||||
xclip -selection clipboard <<< "$r$ext"
|
||||
echo "$r$ext"
|
||||
[ -n "$TMP_FILENAME" ] && rm "$TMP_FILENAME"
|
||||
r="$(tr -d $'\n' <<< "$r$ext")"
|
||||
xclip -selection clipboard <<< "$r"
|
||||
echo "$r"
|
||||
|
|
|
|||
7
.local/bin/scripts/cat-files
Executable file
7
.local/bin/scripts/cat-files
Executable file
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
while IFS=$'\n' read -r file; do
|
||||
echo "$file:"
|
||||
cat "$file"
|
||||
printf "\n\n"
|
||||
done < <(find "${1?}" -type f)
|
||||
4
.local/bin/scripts/dunstctl-set-paused
Executable file
4
.local/bin/scripts/dunstctl-set-paused
Executable file
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
|
||||
dunstctl set-paused "$1"
|
||||
pkill -37 dwmblocks
|
||||
|
|
@ -3,7 +3,11 @@
|
|||
url="$(git remote get-url "${1:-origin}")"
|
||||
|
||||
if [[ "$url" =~ ^https?:\/\/ ]]; then
|
||||
xdg-open "$url"
|
||||
xdg-open "${url%.git}"
|
||||
# elif [[ "$url" =~ ([a-zA-Z0-9_.-]+):(.*) ]]; then
|
||||
# url="https://${BASH_REMATCH[1]}/${BASH_REMATCH[2]}"
|
||||
# url="${url%.git}"
|
||||
# xdg-open "$url"
|
||||
elif [[ "$url" =~ ^[a-zA-Z0-9_-]+@([a-zA-Z0-9_.-]+):(.*) ]]; then
|
||||
url="https://${BASH_REMATCH[1]}/${BASH_REMATCH[2]}"
|
||||
url="${url%.git}"
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@ main() {
|
|||
"--template=${HOME}/.local/share/default.html"
|
||||
"--variable=published_time=$(date -Iseconds -d"$(stat "$1" | grep 'Birth:' | sed 's/.*Birth:\s//')")"
|
||||
)
|
||||
|
||||
set -e
|
||||
pandoc "${pandoc_options[@]}" <(shift_header "$1") > "$FILENAME" &&
|
||||
echo "$FILENAME" &&
|
||||
firefox "$FILENAME" & disown
|
||||
|
|
|
|||
|
|
@ -1,326 +0,0 @@
|
|||
#!/bin/sh
|
||||
# shellcheck disable=all
|
||||
"exec" "${HOME}/.local/share/venv/statusbar/bin/python3" "-u" "$0" "$@"
|
||||
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
import signal
|
||||
import sys
|
||||
import time
|
||||
import traceback
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import Literal, Any, TypeVar
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import requests
|
||||
from bs4 import BeautifulSoup, Tag
|
||||
|
||||
EMOJI_BY_STATUS = {
|
||||
0: '🟡',
|
||||
1: '🟢',
|
||||
2: '🔴',
|
||||
}
|
||||
TIMEOUT = 30
|
||||
CONFIG_FILE = f"{os.environ['HOME']}/.my.itmo"
|
||||
CACHE_FILE = f"{os.environ['HOME']}/.cache/my_itmo.cache"
|
||||
SECRET_FILE = f"{os.environ['HOME']}/.secrets/my_itmo.secret"
|
||||
PIPE_FILE = f"{os.environ['XDG_RUNTIME_DIR']}/my.itmo.pipe"
|
||||
|
||||
T = TypeVar('T')
|
||||
|
||||
|
||||
def run_forever(fn: Callable, *args, **kwargs):
|
||||
while True:
|
||||
try:
|
||||
fn(*args, **kwargs)
|
||||
except Exception:
|
||||
print(traceback.format_exc())
|
||||
|
||||
|
||||
def run_until_successful(fn: Callable[..., T], *args, **kwargs) -> T:
|
||||
while True:
|
||||
try:
|
||||
return fn(*args, **kwargs)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def send_message(chat_id: int, text: str, token: str):
|
||||
requests.post(f"https://api.telegram.org/bot{token}/sendMessage", data={
|
||||
'chat_id': chat_id,
|
||||
'parse_mode': 'HTML',
|
||||
'text': text
|
||||
})
|
||||
|
||||
|
||||
@dataclass
|
||||
class StatusObject:
|
||||
id: int
|
||||
name: str
|
||||
notice: str
|
||||
status: Literal[0, 1, 2]
|
||||
status_name: str
|
||||
updated_at: datetime.datetime
|
||||
created_at: datetime.datetime
|
||||
|
||||
@staticmethod
|
||||
def from_dict(data: dict[str, Any]):
|
||||
data['updated_at'] = datetime.datetime.strptime(data['updated_at'].replace("+03:00", ''), '%Y-%m-%dT%H:%M:%S')
|
||||
data['created_at'] = datetime.datetime.strptime(data['created_at'].replace("+03:00", ''), '%Y-%m-%dT%H:%M:%S')
|
||||
|
||||
return StatusObject(**data)
|
||||
|
||||
|
||||
class ApiException(Exception):
|
||||
status_code: int
|
||||
body: str
|
||||
|
||||
def __init__(self, status_code: int, body: str):
|
||||
super().__init__(status_code, body)
|
||||
self.status_code = status_code
|
||||
self.body = body
|
||||
|
||||
def __str__(self):
|
||||
return f'Status code: {self.status_code}\nBody: {self.body}'
|
||||
|
||||
|
||||
class Api:
|
||||
_session: requests.Session
|
||||
_username: str
|
||||
_password: str
|
||||
_access_token: str
|
||||
_refresh_token: str
|
||||
_expires_in: int
|
||||
_refresh_expires_in: int
|
||||
|
||||
def __init__(self, username: str, password: str, *, access_token: str | None = None,
|
||||
refresh_token: str | None = None, expires_in: int | None = None,
|
||||
refresh_expires_in: int | None = None, cookies: Any | None = None):
|
||||
self._session = requests.Session()
|
||||
self._username = username
|
||||
self._password = password
|
||||
self._refresh_token = refresh_token if refresh_token else ''
|
||||
self._expires_in = expires_in if expires_in else 0
|
||||
self._refresh_expires_in = refresh_expires_in if refresh_expires_in else 0
|
||||
if cookies: self._session.cookies.update(cookies)
|
||||
self._access_token = access_token if access_token else ''
|
||||
if access_token: self._session.headers.update({'Authorization': f'Bearer {access_token}'})
|
||||
self._ensure_authorized()
|
||||
|
||||
|
||||
def _first_auth(self):
|
||||
self._session.headers.clear()
|
||||
self._session.cookies.clear()
|
||||
code_request = run_until_successful(self._session.get, 'https://id.itmo.ru/auth/realms/itmo/protocol/openid-connect/auth', params={
|
||||
'protocol': 'oauth2',
|
||||
'response_type': 'code',
|
||||
'client_id': 'student-personal-cabinet',
|
||||
'redirect_uri': 'https://my.itmo.ru/login/callback',
|
||||
'scope': 'openid profile',
|
||||
}, timeout=2)
|
||||
soup = BeautifulSoup(code_request.text, features='html.parser')
|
||||
form = soup.find('form')
|
||||
if not isinstance(form, Tag):
|
||||
raise ApiException(code_request.status_code, code_request.text)
|
||||
|
||||
url = form.get_attribute_list('action')[0]
|
||||
auth_request = run_until_successful(self._session.post, url, data={'username': self._username, 'password': self._password})
|
||||
if auth_request.status_code != 200:
|
||||
raise ApiException(auth_request.status_code, auth_request.text)
|
||||
|
||||
parsed_url_params = {a.split('=')[0]: a.split('=')[1] for a in urlparse(auth_request.url).query.split('&')}
|
||||
|
||||
self._get_and_save_tokens({
|
||||
'code' : parsed_url_params['code'],
|
||||
'client_id': 'student-personal-cabinet',
|
||||
'redirect_uri': 'https://my.itmo.ru/login/callback',
|
||||
'audience': '',
|
||||
'response_type': 'code',
|
||||
'grant_type': 'authorization_code',
|
||||
'code_verifier': ''
|
||||
})
|
||||
|
||||
|
||||
def _renew(self):
|
||||
self._session.headers.clear()
|
||||
self._session.cookies.clear()
|
||||
self._get_and_save_tokens({
|
||||
'refresh_token': self._refresh_token,
|
||||
'scopes': 'openid profile',
|
||||
'client_id': 'student-personal-cabinet',
|
||||
'grant_type': 'refresh_token'
|
||||
})
|
||||
|
||||
|
||||
def _get_and_save_tokens(self, data: Any):
|
||||
tokens_request = run_until_successful(self._session.post, 'https://id.itmo.ru/auth/realms/itmo/protocol/openid-connect/token', data=data, timeout=2)
|
||||
if tokens_request.status_code != 200:
|
||||
raise ApiException(tokens_request.status_code, tokens_request.text)
|
||||
tokens = tokens_request.json()
|
||||
self._access_token = tokens['access_token']
|
||||
self._expires_in = int(time.time()) + tokens['expires_in'] - 10
|
||||
self._refresh_expires_in = int(time.time()) + tokens['refresh_expires_in'] - 10
|
||||
self._refresh_token = tokens['refresh_token']
|
||||
self._session.headers.update({"Authorization": f"Bearer {tokens_request.json()['access_token']}"})
|
||||
|
||||
|
||||
def _ensure_authorized(self):
|
||||
current_time = int(time.time())
|
||||
|
||||
if self._access_token and self._expires_in > current_time:
|
||||
return
|
||||
elif self._refresh_token and self._refresh_expires_in > current_time:
|
||||
self._renew()
|
||||
else:
|
||||
self._first_auth()
|
||||
|
||||
|
||||
def _make_request(self, method: Literal["GET", "POST"], endpoint: str):
|
||||
self._ensure_authorized()
|
||||
r = run_until_successful(self._session.request, method, f'https://my.itmo.ru/api/{endpoint}', timeout=2)
|
||||
|
||||
if r.status_code == 403:
|
||||
self._first_auth() # do full reauth if 403 after self._ensure_authorized()
|
||||
r = run_until_successful(self._session.request, method, f'https://my.itmo.ru/api/{endpoint}', timeout=2)
|
||||
|
||||
if r.status_code != 200 or r.json()['error_code'] != 0:
|
||||
raise ApiException(r.status_code, r.text)
|
||||
|
||||
return r.json()
|
||||
|
||||
|
||||
def get_status_list(self):
|
||||
return [StatusObject.from_dict(obj) for obj in self._make_request('GET', 'requests/my')['result']]
|
||||
|
||||
|
||||
def to_dict(self) -> Any:
|
||||
return {
|
||||
'username': self._username,
|
||||
'password': self._password,
|
||||
'access_token': self._access_token,
|
||||
'refresh_token': self._refresh_token,
|
||||
'expires_in': self._expires_in,
|
||||
'refresh_expires_in': self._refresh_expires_in,
|
||||
'cookies': self._session.cookies.get_dict()
|
||||
}
|
||||
|
||||
|
||||
@staticmethod
|
||||
def from_dict(data: Any):
|
||||
return Api(
|
||||
data['username'],
|
||||
data['password'],
|
||||
access_token = data['access_token'],
|
||||
refresh_token = data['refresh_token'],
|
||||
expires_in = data['expires_in'],
|
||||
refresh_expires_in = data['refresh_expires_in'],
|
||||
cookies = data['cookies'],
|
||||
)
|
||||
|
||||
|
||||
def listen_for_messages(api: Api, timeout=TIMEOUT, filter_func: Callable[[StatusObject], bool] | None = None):
|
||||
prev_msg = None
|
||||
while True:
|
||||
msg = list(filter(filter_func, api.get_status_list()))
|
||||
|
||||
if not msg or msg == prev_msg:
|
||||
time.sleep(timeout)
|
||||
continue
|
||||
|
||||
prev_msg = msg
|
||||
yield msg
|
||||
time.sleep(timeout)
|
||||
|
||||
|
||||
format_status = lambda status: f"{EMOJI_BY_STATUS[status.status]} {status.notice.split('.')[0].strip()}"
|
||||
format_message = lambda status: f"{EMOJI_BY_STATUS[status.status]} <b>{status.name}</b>\n\n{status.notice}"
|
||||
|
||||
|
||||
class IDsFilter:
|
||||
_ids: list[str]
|
||||
_update_time: float
|
||||
|
||||
def __init__(self):
|
||||
self._ids = []
|
||||
self._update_dict()
|
||||
|
||||
|
||||
def __call__(self, status: StatusObject) -> bool:
|
||||
if self._update_time + TIMEOUT < time.time():
|
||||
self._update_dict()
|
||||
|
||||
return str(status.id) in self._ids
|
||||
|
||||
def _update_dict(self):
|
||||
self._update_time = time.time()
|
||||
try:
|
||||
with open(CONFIG_FILE) as file:
|
||||
self._ids = file.read().strip().replace(' ', '').split(',')
|
||||
except Exception:
|
||||
self._ids = []
|
||||
|
||||
|
||||
class LastUpdateFilter:
|
||||
_update_time: datetime.datetime
|
||||
|
||||
def __init__(self, ignore_now = False) -> None:
|
||||
self._update_time = datetime.datetime.fromtimestamp(0) if not ignore_now else datetime.datetime.now()
|
||||
|
||||
def __call__(self, status: StatusObject):
|
||||
return status.updated_at >= self._update_time
|
||||
|
||||
def update(self):
|
||||
self._update_time = datetime.datetime.now()
|
||||
|
||||
|
||||
def main():
|
||||
api = None
|
||||
|
||||
if os.path.isfile(CACHE_FILE):
|
||||
with open(CACHE_FILE) as file:
|
||||
api = Api.from_dict(json.load(file))
|
||||
|
||||
if os.path.isfile(SECRET_FILE):
|
||||
with open(SECRET_FILE) as secret_file:
|
||||
data = json.load(secret_file)
|
||||
|
||||
owner_id = data['owner_id']
|
||||
bot_token = data['bot_token']
|
||||
|
||||
if not api:
|
||||
api = Api(data['username'], data['password'])
|
||||
else:
|
||||
print("Missing secret file!", file=sys.stderr)
|
||||
exit(1)
|
||||
|
||||
def die(*_):
|
||||
with open(CACHE_FILE, 'w') as file:
|
||||
json.dump(api.to_dict(), file)
|
||||
if os.path.isfile(PIPE_FILE):
|
||||
os.remove(PIPE_FILE)
|
||||
exit(0)
|
||||
|
||||
signal.signal(signal.SIGTERM, die)
|
||||
signal.signal(signal.SIGINT, die)
|
||||
|
||||
for message in listen_for_messages(api, filter_func=IDsFilter()):
|
||||
with open(PIPE_FILE, 'w') as file:
|
||||
print('\n'.join(map(format_status, message)))
|
||||
file.write(' '.join(map(format_status, message)))
|
||||
|
||||
update_filter = LastUpdateFilter(ignore_now=True)
|
||||
for message in listen_for_messages(api, filter_func=update_filter):
|
||||
formatted_messages = list(map(format_message, message))
|
||||
print('\n---\n'.join(formatted_messages))
|
||||
for message in formatted_messages:
|
||||
send_message(owner_id, message, bot_token)
|
||||
update_filter.update()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
run_forever(main)
|
||||
|
||||
# vim: ft=python
|
||||
|
|
@ -1,9 +1,6 @@
|
|||
#!/bin/bash
|
||||
|
||||
flags="-it"
|
||||
|
||||
if [ ! -t 0 ] || [ ! -t 1 ]; then
|
||||
flags=
|
||||
fi
|
||||
{ [ ! -t 0 ] || [ ! -t 1 ]; } && flags=
|
||||
|
||||
docker --context=higpu exec $flags ollama-ollama-1 ollama "$@"
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ main() {
|
|||
fi
|
||||
|
||||
[ -n "${print_response:+_}" ] && echo "$resp"
|
||||
[ "$(jq .ok <<<"$resp")" = "true" ] || jq <<< "$resp" >&2
|
||||
# [ "$(jq .ok <<<"$resp")" = "true" ] || jq <<< "$resp" >&2
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
|
|
|||
4
.local/bin/scripts/unplug
Executable file
4
.local/bin/scripts/unplug
Executable file
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
|
||||
xr internal
|
||||
systemctl suspend
|
||||
3
.local/bin/scripts/virt
Executable file
3
.local/bin/scripts/virt
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
sudo systemctl start libvirtd
|
||||
sudo virsh net-start default
|
||||
|
|
@ -1,11 +1,5 @@
|
|||
#!/bin/bash -x
|
||||
|
||||
PIPE="/var/run/vpnd.sock"
|
||||
send_cmd() {
|
||||
[ -p $PIPE ] && echo "$@" > $PIPE && \
|
||||
cat < $PIPE
|
||||
}
|
||||
|
||||
send_router_cmd() {
|
||||
touch "${HOME}/.local/state/.vpn_loading"
|
||||
pkill -36 dwmblocks
|
||||
|
|
@ -13,51 +7,40 @@ send_router_cmd() {
|
|||
rm "${HOME}/.local/state/.vpn_loading"
|
||||
}
|
||||
|
||||
awg-quick() {
|
||||
PIPE="/var/run/vpnd.sock"
|
||||
|
||||
[ -p $PIPE ] &&
|
||||
echo "$@" > $PIPE &&
|
||||
cat < $PIPE
|
||||
}
|
||||
|
||||
DEFAULT_LINK="$(resolvectl status | grep 'Default Route: yes' -B10 | grep 'Link' | tail -1 | grep -Eo '\(.*\)' | tr -d '()')"
|
||||
|
||||
if resolvectl domain "$DEFAULT_LINK" | grep -q 'wzray.com'; then
|
||||
IS_LOCAL=1
|
||||
fi
|
||||
|
||||
IFNAME='ext'
|
||||
IFNAME="awg_ext"
|
||||
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
'i'|'int') IFNAME='int';;
|
||||
'-v'|'--verbose') VERBOSE=1;;
|
||||
*) echo "Wrong argument!"; exit 1;;
|
||||
i|int|internal) IFNAME='awg_int';;
|
||||
*) echo "Wrong argument!" >&2; exit 1;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [ -z "${VERBOSE}" ]; then
|
||||
exec &>/dev/null
|
||||
UP_NAME="$(ip link | grep 'awg_' | cut -d ' ' -f 2 | sed 's,:,,')"
|
||||
|
||||
if [ -n "$UP_NAME" ]; then
|
||||
awg-quick down "$UP_NAME"
|
||||
elif [ -n "$IS_LOCAL" ]; then
|
||||
send_router_cmd toggle
|
||||
else
|
||||
set -x
|
||||
awg-quick up "${IFNAME}"
|
||||
fi
|
||||
|
||||
UP_NAME="$(send_cmd status)"
|
||||
|
||||
if [ -n "$IS_LOCAL" ]; then
|
||||
if [ -n "$UP_NAME" ]; then
|
||||
send_cmd down
|
||||
else
|
||||
send_router_cmd toggle
|
||||
fi
|
||||
else
|
||||
if [ -n "${UP_NAME}" ]; then
|
||||
if [ "${UP_NAME}" != "${IFNAME}" ]; then
|
||||
send_cmd down
|
||||
send_cmd up "$IFNAME"
|
||||
else
|
||||
send_cmd down
|
||||
fi
|
||||
else
|
||||
send_cmd up "$IFNAME"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
pkill -36 dwmblocks
|
||||
|
||||
# vim: ft=bash
|
||||
|
|
|
|||
|
|
@ -1,92 +1,49 @@
|
|||
#!/bin/bash
|
||||
# shellcheck disable=SC2034
|
||||
|
||||
die() {
|
||||
[ -n "$oc_pid" ] && kill -s TERM "$oc_pid"
|
||||
echo "exitting..."
|
||||
rm -f $PIPE
|
||||
exit 0
|
||||
}
|
||||
|
||||
trap 'die' SIGTERM SIGQUIT SIGINT
|
||||
|
||||
PIPE="/var/run/vpnd.sock"
|
||||
oc_pid=
|
||||
up_name=
|
||||
|
||||
[ -p $PIPE ] && exit 1
|
||||
[ "$(id -u)" != "0" ] && exit 1
|
||||
|
||||
trap 'die' SIGTERM SIGQUIT SIGINT
|
||||
|
||||
declare -a CONFIGS
|
||||
for config in /etc/openconnect/config_*; do
|
||||
config="$(basename "$config")"
|
||||
CONFIGS+=("${config#config_}")
|
||||
for config in /etc/amnezia/amneziawg/*; do
|
||||
config="$(basename "$config")"
|
||||
CONFIGS+=("${config%.conf}")
|
||||
done
|
||||
|
||||
COMMANDS=("up" "down" "status")
|
||||
COMMANDS=("up" "down")
|
||||
|
||||
is_really_up() {
|
||||
[ -n "$oc_pid" ] && if ! kill -0 "$oc_pid"; then
|
||||
oc_pid=
|
||||
up_name=
|
||||
fi
|
||||
die() {
|
||||
rm $PIPE
|
||||
exit 0
|
||||
}
|
||||
|
||||
in_arr() {
|
||||
declare -n arr="$2"
|
||||
declare -n arr="$2"
|
||||
|
||||
for value in "${arr[@]}"; do
|
||||
[ "$value" = "$1" ] && return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
down() {
|
||||
is_really_up
|
||||
[ -z "$oc_pid" ] && return
|
||||
kill -s TERM "$oc_pid"
|
||||
wait "$oc_pid"
|
||||
oc_pid=
|
||||
up_name=
|
||||
}
|
||||
|
||||
up() {
|
||||
is_really_up
|
||||
[ -n "$oc_pid" ] && down
|
||||
openconnect --config "/etc/openconnect/config_$1" &
|
||||
oc_pid="$!"
|
||||
up_name="$1"
|
||||
}
|
||||
|
||||
status() {
|
||||
is_really_up
|
||||
echo "$up_name" > $PIPE
|
||||
for value in "${arr[@]}"; do
|
||||
[ "$value" = "$1" ] && return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
main() {
|
||||
mkfifo $PIPE -m666
|
||||
mkfifo $PIPE -m666
|
||||
|
||||
while :; do
|
||||
read -r cmd ifname < $PIPE
|
||||
if ! in_arr "$cmd" "COMMANDS"; then
|
||||
echo "ERROR: Invalid command $cmd" > $PIPE
|
||||
else
|
||||
case "$cmd" in
|
||||
"up")
|
||||
if ! in_arr "$ifname" "CONFIGS"; then
|
||||
echo "ERROR: Invalid interface $ifname" > $PIPE
|
||||
else
|
||||
up "$ifname"
|
||||
echo "$ifname" > $PIPE
|
||||
fi
|
||||
;;
|
||||
"down") down; echo "down" > $PIPE;;
|
||||
"status") status;;
|
||||
esac
|
||||
while :; do
|
||||
read -r cmd ifname < $PIPE
|
||||
|
||||
fi
|
||||
done
|
||||
if ! in_arr "$ifname" "CONFIGS"; then
|
||||
echo "ERROR: Invalid interface $ifname" > $PIPE
|
||||
elif ! in_arr "$cmd" "COMMANDS"; then
|
||||
echo "ERROR: Invalid command $cmd" > $PIPE
|
||||
else
|
||||
awg-quick "$cmd" "$ifname" > $PIPE 2>&1
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
echo "Running..."
|
||||
main
|
||||
|
|
|
|||
9
.local/bin/scripts/wdate
Executable file
9
.local/bin/scripts/wdate
Executable file
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/sh
|
||||
|
||||
trap 'echo; exit' 'INT'
|
||||
|
||||
while :; do
|
||||
printf '\r'
|
||||
date "$@" | tr -d '\n'
|
||||
sleep 0.99
|
||||
done
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
# supress stderr
|
||||
|
||||
change_dpi() {
|
||||
sed -i -E --follow-symlinks "s/Xft\.dpi: .*?/Xft\.dpi: $1/g" ~/.Xresources
|
||||
sed -i -E --follow-symlinks "s/Xcursor\.size: .*?/Xcursor\.size: $2/g" ~/.Xresources
|
||||
|
|
@ -20,7 +18,7 @@ EXT_MON="$(xrandr | grep -ow "\(DP-[0-9]\) connected" | cut -d " " -f 1)"
|
|||
INT_MODELINE=$(cvt 1560 1040 90 | grep "Modeline" | cut -d " " -f 2- | tr -d '"')
|
||||
INT_RES="$(echo $INT_MODELINE | cut -d ' ' -f 1 | tr -d '\"')"
|
||||
|
||||
if [[ -z "${EXT_MON}" ]]; then
|
||||
if [[ -z "${EXT_MON}" ]] || [ "$1" = "internal" ]; then
|
||||
xrandr --output eDP-1 --pos 0x0 --mode "3120x2080" --rate 90 --primary --output DP-1 --off --output DP-2 --off --output DP-3 --off --output DP-4 --off
|
||||
xrandr --delmode eDP-1 "${INT_RES}"
|
||||
xrandr --rmmode "${INT_RES}"
|
||||
|
|
@ -29,9 +27,13 @@ else
|
|||
:
|
||||
xrandr --rmmode "${INT_RES}"
|
||||
# shellcheck disable=all
|
||||
xrandr --newmode $(echo $INT_MODELINE) # this is a hack to make xrandr recognize the resolution
|
||||
xrandr --addmode eDP-1 "${INT_RES}"
|
||||
xrandr --output eDP-1 --pos 2560x400 --mode "${INT_RES}" --output "${EXT_MON}" --pos 0x0 --mode "2560x1440" --rate 144 --primary
|
||||
|
||||
# temp remove edp
|
||||
# xrandr --newmode $(echo $INT_MODELINE) # this is a hack to make xrandr recognize the resolution
|
||||
# xrandr --addmode eDP-1 "${INT_RES}"
|
||||
# xrandr --output eDP-1 --pos 2560x400 --mode "${INT_RES}" --output "${EXT_MON}" --pos 0x0 --mode "2560x1440" --rate 144 --primary
|
||||
|
||||
xrandr --output eDP-1 --off --output "${EXT_MON}" --pos 0x0 --mode "2560x1440" --rate 144 --primary
|
||||
change_dpi 96 24
|
||||
fi
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue