This commit is contained in:
Andrey Zimin 2024-03-10 13:58:36 +03:00
parent 7343e89a17
commit 61a16825e4
14 changed files with 1293 additions and 1 deletions

View File

@ -16,6 +16,7 @@ package() {
mkdir -p ${SKEL_DIR} mkdir -p ${SKEL_DIR}
cp -r ${srcdir}/.Xresources.d ${SKEL_DIR} cp -r ${srcdir}/.Xresources.d ${SKEL_DIR}
cp -r ${srcdir}/bin ${SKEL_DIR}
install -Dm 644 ${srcdir}/.dmrc ${SKEL_DIR}/.dmrc install -Dm 644 ${srcdir}/.dmrc ${SKEL_DIR}/.dmrc
install -Dm 644 ${srcdir}/.face ${SKEL_DIR}/.face install -Dm 644 ${srcdir}/.face ${SKEL_DIR}/.face

View File

@ -0,0 +1,61 @@
#!/usr/bin/env bash
# Graphics card
CARD=`ls /sys/class/backlight | head -n 1`
# Get brightness
get_backlight() {
if [[ "$CARD" == *"intel_"* ]]; then
BNESS=`xbacklight -get`
LIGHT=${BNESS%.*}
else
LIGHT=$(printf "%.0f\n" `light -G`)
fi
echo "${LIGHT}%"
}
# Get icons
get_icon() {
backlight="$(get_backlight)"
current="${backlight%%%}"
if [[ ("$current" -ge "0") && ("$current" -le "20") ]]; then
icon='/usr/share/icons/dunst/brightness-20.png'
elif [[ ("$current" -ge "20") && ("$current" -le "40") ]]; then
icon='/usr/share/icons/dunst/brightness-40.png'
elif [[ ("$current" -ge "40") && ("$current" -le "60") ]]; then
icon='/usr/share/icons/dunst/brightness-60.png'
elif [[ ("$current" -ge "60") && ("$current" -le "80") ]]; then
icon='/usr/share/icons/dunst/brightness-80.png'
elif [[ ("$current" -ge "80") && ("$current" -le "100") ]]; then
icon='/usr/share/icons/dunst/brightness-100.png'
fi
}
# Increase brightness
inc_backlight() {
if [[ "$CARD" == *"intel_"* ]]; then
xbacklight -inc 10 && get_icon && dunstify -u low --replace=69 -i "$icon" "Brightness : $(get_backlight)"
else
light -A 5 && get_icon && dunstify -u low --replace=69 -i "$icon" "Brightness : $(get_backlight)"
fi
}
# Decrease brightness
dec_backlight() {
if [[ "$CARD" == *"intel_"* ]]; then
xbacklight -dec 10 && get_icon && dunstify -u low --replace=69 -i "$icon" "Brightness : $(get_backlight)"
else
light -U 5 && get_icon && dunstify -u low --replace=69 -i "$icon" "Brightness : $(get_backlight)"
fi
}
# Execute accordingly
if [[ "$1" == "--get" ]]; then
get_backlight
elif [[ "$1" == "--inc" ]]; then
inc_backlight
elif [[ "$1" == "--dec" ]]; then
dec_backlight
else
get_backlight
fi

7
misc/bin/scripts/system/cl Executable file
View File

@ -0,0 +1,7 @@
#!/bin/zsh
if [ -z $1 ]; then
clear
else
clear && lst
fi

View File

@ -0,0 +1,21 @@
#!/bin/bash
####################################
# script to capture colors #
####################################
# capture the color and save it to the color variable #
colorPicker=$(gpick -pso --no-newline)
# save as image #
image=/tmp/${colorPicker}.png
# copy color code to clipboard #
echo $colorPicker | tr -d "\n" | xclip -selection clipboard
# generate preview to notify it above screen #
convert -size 48x48 xc:"$colorPicker" ${image}
# notify color above screen #
dunstify -u low --replace=69 -i ${image} "$colorPicker, copied to clipboard."

16
misc/bin/scripts/system/delete Executable file
View File

@ -0,0 +1,16 @@
#!/bin/zsh
source "$HOME/bin/scripts/system/style"
trash="$HOME/.trash"
mkdir -p $trash
DATE=`date +%Y-%m-%d`
TIME=`date +%H:%M:%S`
for obj in "$@"
do
name=`echo $obj | rev | cut -d '/' -f '1' | rev`
mv -b $obj $trash/$name.$DATE.$TIME
done
echo -ne $BOLD$GREEN"... completed"$RESET_COLOR

9
misc/bin/scripts/system/lst Executable file
View File

@ -0,0 +1,9 @@
#!/bin/zsh
target=$1
if [ -z $target ]; then
target='./'
fi
lsd --tree --depth 1 -a -h --group-directories-first $target

898
misc/bin/scripts/system/nmd Executable file
View File

@ -0,0 +1,898 @@
#!/usr/bin/env python3
# encoding:utf8
"""NetworkManager command line dmenu script.
To add new connections or enable/disable networking requires policykit
permissions setup per:
https://wiki.archlinux.org/index.php/NetworkManager#Set_up_PolicyKit_permissions
OR running the script as root
Add dmenu options and default terminal if desired to
~/.config/networkmanager-dmenu/nmd.ini
"""
import pathlib
import struct
import configparser
import locale
import os
from os.path import expanduser
import shlex
from shutil import which
import sys
import uuid
import subprocess
import gi
gi.require_version('NM', '1.0')
from gi.repository import GLib, NM # noqa pylint: disable=wrong-import-position
ENV = os.environ.copy()
ENV['LC_ALL'] = 'C'
ENC = locale.getpreferredencoding()
CLIENT = NM.Client.new(None)
LOOP = GLib.MainLoop()
CONNS = CLIENT.get_connections()
CONF = configparser.ConfigParser()
CONF.read(expanduser("~/.config/networkmanager-dmenu/nmd.ini"))
def cli_args():
""" Don't override dmenu_cmd function arguments with CLI args. Removes -l
and -p if those are passed on the command line.
Exception: if -l is passed and dmenu_command is not defined, assume that the
user wants to switch dmenu to the vertical layout and include -l.
Returns: List of additional CLI arguments
"""
args = sys.argv[1:]
cmd = CONF.get('dmenu', 'dmenu_command', fallback=False)
if "-l" in args or "-p" in args:
for nope in ['-l', '-p'] if cmd is not False else ['-p']:
try:
nope_idx = args.index(nope)
del args[nope_idx]
del args[nope_idx]
except ValueError:
pass
return args
def dmenu_pass(command, color):
"""Check if dmenu passphrase patch is applied and return the correct command
line arg list
Args: command - string
color - obscure color string
Returns: list or None
"""
if command != 'dmenu':
return None
try:
# Check for dmenu password patch
dm_patch = b'P' in subprocess.run(["dmenu", "-h"],
capture_output=True,
check=False).stderr
except FileNotFoundError:
dm_patch = False
return ["-P"] if dm_patch else ["-nb", color, "-nf", color]
def dmenu_cmd(num_lines, prompt="Networks", active_lines=None):
"""Parse nmd.ini for menu options
Args: args - num_lines: number of lines to display
prompt: prompt to show
active_lines: list of line numbers to tag as active
Returns: command invocation (as a list of strings) for example
["dmenu", "-l", "<num_lines>", "-p", "<prompt>", "-i"]
"""
# Create command string
commands = {"dmenu": ["-p", str(prompt)],
"rofi": ["-dmenu", "-p", str(prompt), "-l", str(num_lines)],
"bemenu": ["-p", str(prompt)],
"wofi": ["-p", str(prompt)]}
command = shlex.split(CONF.get('dmenu', 'dmenu_command', fallback="dmenu"))
command.extend(cli_args())
command.extend(commands.get(command[0], []))
# Rofi Highlighting
rofi_highlight = CONF.getboolean('dmenu', 'rofi_highlight', fallback=False)
if rofi_highlight is True and command[0] == "rofi" and active_lines:
command.extend(["-a", ",".join([str(num) for num in active_lines])])
# Passphrase prompts
obscure = CONF.getboolean('dmenu_passphrase', 'obscure', fallback=False)
if prompt == "Passphrase" and obscure is True:
obscure_color = CONF.get('dmenu_passphrase', 'obscure_color', fallback='#222222')
pass_prompts = {"dmenu": dmenu_pass(command[0], obscure_color),
"rofi": ['-password'],
"bemenu": ['-x'],
"wofi": ['-P']}
command.extend(pass_prompts.get(command[0], []))
return command
def choose_adapter(client):
"""If there is more than one wifi adapter installed, ask which one to use
"""
devices = client.get_devices()
devices = [i for i in devices if i.get_device_type() == NM.DeviceType.WIFI]
if not devices:
return None
if len(devices) == 1:
return devices[0]
device_names = "\n".join([d.get_iface() for d in devices])
sel = subprocess.run(dmenu_cmd(len(devices), "CHOOSE ADAPTER:"),
capture_output=True,
check=False,
env=ENV,
input=device_names,
encoding=ENC).stdout
if not sel.strip():
sys.exit()
devices = [i for i in devices if i.get_iface() == sel.strip()]
assert len(devices) == 1
return devices[0]
def is_installed(cmd):
"""Check if a utility is installed"""
return which(cmd) is not None
def bluetooth_get_enabled():
"""Check if bluetooth is enabled via rfkill.
Returns None if no bluetooth device was found.
"""
# See https://www.kernel.org/doc/Documentation/ABI/stable/sysfs-class-rfkill
for path in pathlib.Path('/sys/class/rfkill/').glob('rfkill*'):
if (path / 'type').read_text().strip() == 'bluetooth':
return (path / 'soft').read_text().strip() == '0'
return None
def create_other_actions(client):
"""Return list of other actions that can be taken
"""
networking_enabled = client.networking_get_enabled()
networking_action = "Disable" if networking_enabled else "Enable"
wifi_enabled = client.wireless_get_enabled()
wifi_action = "Disable" if wifi_enabled else "Enable"
bluetooth_enabled = bluetooth_get_enabled()
bluetooth_action = "Disable" if bluetooth_enabled else "Enable"
actions = [Action(f"{wifi_action} Wifi", toggle_wifi,
not wifi_enabled),
Action(f"{networking_action} Networking",
toggle_networking, not networking_enabled)]
if bluetooth_enabled is not None:
actions.append(Action(f"{bluetooth_action} Bluetooth",
toggle_bluetooth, not bluetooth_enabled))
actions += [Action("Launch Connection Manager", launch_connection_editor),
Action("Delete a Connection", delete_connection)]
if wifi_enabled:
actions.append(Action("Rescan Wifi Networks", rescan_wifi))
return actions
def rescan_wifi():
"""
Rescan Wifi Access Points
"""
for dev in CLIENT.get_devices():
if gi.repository.NM.DeviceWifi == type(dev):
try:
dev.request_scan_async(None, rescan_cb, None)
LOOP.run()
except gi.repository.GLib.Error as err:
# Too frequent rescan error
notify("Wifi rescan failed", urgency="critical")
if not err.code == 6: # pylint: disable=no-member
raise err
def rescan_cb(dev, res, data):
"""Callback for rescan_wifi. Just for notifications
"""
if dev.request_scan_finish(res) is True:
notify("Wifi scan complete")
else:
notify("Wifi scan failed", urgency="critical")
LOOP.quit()
def ssid_to_utf8(nm_ap):
""" Convert binary ssid to utf-8 """
ssid = nm_ap.get_ssid()
if not ssid:
return ""
ret = NM.utils_ssid_to_utf8(ssid.get_data())
return ret
def prompt_saved(saved_cons):
"""Prompt for a saved connection."""
actions = create_saved_actions(saved_cons)
sel = get_selection(actions)
sel()
def ap_security(nm_ap):
"""Parse the security flags to return a string with 'WPA2', etc. """
flags = nm_ap.get_flags()
wpa_flags = nm_ap.get_wpa_flags()
rsn_flags = nm_ap.get_rsn_flags()
sec_str = ""
if ((flags & getattr(NM, '80211ApFlags').PRIVACY) and
(wpa_flags == 0) and (rsn_flags == 0)):
sec_str += " WEP"
if wpa_flags != 0:
sec_str += " WPA1"
if rsn_flags != 0:
sec_str += " WPA2"
if ((wpa_flags & getattr(NM, '80211ApSecurityFlags').KEY_MGMT_802_1X) or
(rsn_flags & getattr(NM, '80211ApSecurityFlags').KEY_MGMT_802_1X)):
sec_str += " 802.1X"
# If there is no security use "--"
if sec_str == "":
sec_str = "--"
return sec_str.lstrip()
class Action(): # pylint: disable=too-few-public-methods
"""Helper class to execute functions from a string variable"""
def __init__(self,
name,
func,
args=None,
active=False):
self.name = name
self.func = func
self.is_active = active
if args is None:
self.args = None
elif isinstance(args, list):
self.args = args
else:
self.args = [args]
def __str__(self):
return self.name
def __call__(self):
if self.args is None:
self.func()
else:
self.func(*self.args)
def conn_matches_adapter(conn, adapter):
"""Return True if the connection is applicable for the given adapter.
There seem to be two ways for a connection specify what interface it belongs
to:
- By setting 'mac-address' in [wifi] to the adapter's MAC
- By setting 'interface-name` in [connection] to the adapter's name.
Depending on how the connection was added, it seems like either
'mac-address', 'interface-name' or neither of both is set.
"""
# [wifi] mac-address
setting_wireless = conn.get_setting_wireless()
mac = setting_wireless.get_mac_address()
if mac is not None:
return mac == adapter.get_permanent_hw_address()
# [connection] interface-name
setting_connection = conn.get_setting_connection()
interface = setting_connection.get_interface_name()
if interface is not None:
return interface == adapter.get_iface()
# Neither is set, let's assume this connection is for multiple/all adapters.
return True
def process_ap(nm_ap, is_active, adapter):
"""Activate/Deactivate a connection and get password if required"""
if is_active:
CLIENT.deactivate_connection_async(nm_ap, None, deactivate_cb, nm_ap)
LOOP.run()
else:
conns_cur = [i for i in CONNS if
i.get_setting_wireless() is not None and
conn_matches_adapter(i, adapter)]
con = nm_ap.filter_connections(conns_cur)
if len(con) > 1:
raise ValueError("There are multiple connections possible")
if len(con) == 1:
CLIENT.activate_connection_async(con[0], adapter, nm_ap.get_path(),
None, activate_cb, nm_ap)
LOOP.run()
else:
if ap_security(nm_ap) != "--":
password = get_passphrase()
else:
password = ""
set_new_connection(nm_ap, password, adapter)
def activate_cb(dev, res, data):
"""Notification if activate connection completed successfully
"""
try:
conn = dev.activate_connection_finish(res)
except GLib.Error:
conn = None
if conn is not None:
notify(f"Activated {conn.get_id()}")
else:
notify(f"Problem activating {data.get_id()}", urgency="critical")
LOOP.quit()
def deactivate_cb(dev, res, data):
"""Notification if deactivate connection completed successfully
"""
if dev.deactivate_connection_finish(res) is True:
notify(f"Deactivated {data.get_id()}")
else:
notify(f"Problem deactivating {data.get_id()}", urgency="critical")
LOOP.quit()
def process_vpngsm(con, activate):
"""Activate/deactive VPN or GSM connections"""
if activate:
CLIENT.activate_connection_async(con, None, None,
None, activate_cb, con)
else:
CLIENT.deactivate_connection_async(con, None, deactivate_cb, con)
LOOP.run()
def create_ap_actions(aps, active_ap, active_connection, adapter): # noqa pylint: disable=too-many-locals,line-too-long
"""For each AP in a list, create the string and its attached function
(activate/deactivate)
"""
active_ap_bssid = active_ap.get_bssid() if active_ap is not None else ""
names = [ssid_to_utf8(ap) for ap in aps]
max_len_name = max([len(name) for name in names]) if names else 0
secs = [ap_security(ap) for ap in aps]
max_len_sec = max([len(sec) for sec in secs]) if secs else 0
ap_actions = []
for nm_ap, name, sec in zip(aps, names, secs):
bars = NM.utils_wifi_strength_bars(nm_ap.get_strength())
wifi_chars = CONF.get("dmenu", "wifi_chars", fallback=False)
if wifi_chars:
bars = "".join([wifi_chars[i] for i, j in enumerate(bars) if j == '*'])
is_active = nm_ap.get_bssid() == active_ap_bssid
compact = CONF.getboolean("dmenu", "compact", fallback=False)
if compact:
action_name = f"{name} {sec} {bars}"
else:
action_name = f"{name:<{max_len_name}s} {sec:<{max_len_sec}s} {bars:>4}"
if is_active:
ap_actions.append(Action(action_name, process_ap,
[active_connection, True, adapter],
active=True))
else:
ap_actions.append(Action(action_name, process_ap,
[nm_ap, False, adapter]))
return ap_actions
def create_vpn_actions(vpns, active):
"""Create the list of strings to display with associated function
(activate/deactivate) for VPN connections.
"""
active_vpns = [i for i in active if i.get_vpn()]
return _create_vpngsm_actions(vpns, active_vpns, "VPN")
def create_wireguard_actions(wgs, active):
"""Create the list of strings to display with associated function
(activate/deactivate) for Wireguard connections.
"""
active_wgs = [i for i in active if i.get_connection_type() == "wireguard"]
return _create_vpngsm_actions(wgs, active_wgs, "Wireguard")
def create_eth_actions(eths, active):
"""Create the list of strings to display with associated function
(activate/deactivate) for Ethernet connections.
"""
active_eths = [i for i in active if 'ethernet' in i.get_connection_type()]
return _create_vpngsm_actions(eths, active_eths, "Eth")
def create_gsm_actions(gsms, active):
"""Create the list of strings to display with associated function
(activate/deactivate) GSM connections."""
active_gsms = [i for i in active if
i.get_connection() is not None and
i.get_connection().is_type(NM.SETTING_GSM_SETTING_NAME)]
return _create_vpngsm_actions(gsms, active_gsms, "GSM")
def create_blue_actions(blues, active):
"""Create the list of strings to display with associated function
(activate/deactivate) Bluetooth connections."""
active_blues = [i for i in active if
i.get_connection() is not None and
i.get_connection().is_type(NM.SETTING_BLUETOOTH_SETTING_NAME)]
return _create_vpngsm_actions(blues, active_blues, "Bluetooth")
def create_saved_actions(saved):
"""Create the list of strings to display with associated function
(activate/deactivate) for VPN connections.
"""
return _create_vpngsm_actions(saved, [], "SAVED")
def _create_vpngsm_actions(cons, active_cons, label):
active_con_ids = [a.get_id() for a in active_cons]
actions = []
for con in cons:
is_active = con.get_id() in active_con_ids
action_name = f"{con.get_id()}:{label}"
if is_active:
active_connection = [a for a in active_cons
if a.get_id() == con.get_id()]
if len(active_connection) != 1:
raise ValueError(f"Multiple active connections match {con.get_id()}")
active_connection = active_connection[0]
actions.append(Action(action_name, process_vpngsm,
[active_connection, False], active=True))
else:
actions.append(Action(action_name, process_vpngsm,
[con, True]))
return actions
def create_wwan_actions(client):
"""Create WWWAN actions
"""
wwan_enabled = client.wwan_get_enabled()
wwan_action = "Disable" if wwan_enabled else "Enable"
return [Action(f"{wwan_action} WWAN", toggle_wwan, not wwan_enabled)]
def combine_actions(eths, aps, vpns, wgs, gsms, blues, wwan, others, saved):
# pylint: disable=too-many-arguments
"""Combine all given actions into a list of actions.
Args: args - eths: list of Actions
aps: list of Actions
vpns: list of Actions
gsms: list of Actions
blues: list of Actions
wwan: list of Actions
others: list of Actions
"""
compact = CONF.getboolean("dmenu", "compact", fallback=False)
empty_action = [Action('', None)] if not compact else []
all_actions = []
all_actions += eths + empty_action if eths else []
all_actions += aps + empty_action if aps else []
all_actions += vpns + empty_action if vpns else []
all_actions += wgs + empty_action if wgs else []
all_actions += gsms + empty_action if (gsms and wwan) else []
all_actions += blues + empty_action if blues else []
all_actions += wwan + empty_action if wwan else []
all_actions += others + empty_action if others else []
all_actions += saved + empty_action if saved else []
return all_actions
def get_selection(all_actions):
"""Spawn dmenu for selection and execute the associated action."""
rofi_highlight = CONF.getboolean('dmenu', 'rofi_highlight', fallback=False)
inp = []
if rofi_highlight is True:
inp = [str(action) for action in all_actions]
else:
inp = [('== ' if action.is_active else ' ') + str(action)
for action in all_actions]
active_lines = [index for index, action in enumerate(all_actions)
if action.is_active]
command = dmenu_cmd(len(inp), active_lines=active_lines)
sel = subprocess.run(command,
capture_output=True,
check=False,
input="\n".join(inp),
encoding=ENC,
env=ENV).stdout
if not sel.rstrip():
sys.exit()
if rofi_highlight is False:
action = [i for i in all_actions
if ((str(i).strip() == str(sel.strip())
and not i.is_active) or
('== ' + str(i) == str(sel.rstrip('\n'))
and i.is_active))]
else:
action = [i for i in all_actions if str(i).strip() == sel.strip()]
assert len(action) == 1, f"Selection was ambiguous: '{str(sel.strip())}'"
return action[0]
def toggle_networking(enable):
"""Enable/disable networking
Args: enable - boolean
"""
toggle = GLib.Variant.new_tuple(GLib.Variant.new_boolean(enable))
try:
CLIENT.dbus_call(NM.DBUS_PATH, NM.DBUS_INTERFACE, "Enable", toggle,
None, -1, None, None, None)
except AttributeError:
# Workaround for older versions of python-gobject
CLIENT.networking_set_enabled(enable)
notify(f"Networking {'enabled' if enable is True else 'disabled'}")
def toggle_wifi(enable):
"""Enable/disable Wifi
Args: enable - boolean
"""
toggle = GLib.Variant.new_boolean(enable)
try:
CLIENT.dbus_set_property(NM.DBUS_PATH, NM.DBUS_INTERFACE, "WirelessEnabled", toggle,
-1, None, None, None)
except AttributeError:
# Workaround for older versions of python-gobject
CLIENT.wireless_set_enabled(enable)
notify(f"Wifi {'enabled' if enable is True else 'disabled'}")
def toggle_wwan(enable):
"""Enable/disable WWAN
Args: enable - boolean
"""
toggle = GLib.Variant.new_boolean(enable)
try:
CLIENT.dbus_set_property(NM.DBUS_PATH, NM.DBUS_INTERFACE, "WwanEnabled", toggle,
-1, None, None, None)
except AttributeError:
# Workaround for older versions of python-gobject
CLIENT.wwan_set_enabled(enable)
notify(f"Wwan {'enabled' if enable is True else 'disabled'}")
def toggle_bluetooth(enable):
"""Enable/disable Bluetooth
Args: enable - boolean
References:
https://github.com/blueman-project/blueman/blob/master/blueman/plugins/mechanism/RfKill.py
https://www.kernel.org/doc/html/latest/driver-api/rfkill.html
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/include/uapi/linux/rfkill.h?h=v5.8.9
"""
type_bluetooth = 2
op_change_all = 3
idx = 0
soft_state = 0 if enable else 1
hard_state = 0
data = struct.pack("IBBBB", idx, type_bluetooth, op_change_all,
soft_state, hard_state)
try:
with open('/dev/rfkill', 'r+b', buffering=0) as rff:
rff.write(data)
except PermissionError:
notify("Lacking permission to write to /dev/rfkill.",
"Check README for configuration options.",
urgency="critical")
else:
notify(f"Bluetooth {'enabled' if enable else 'disabled'}")
def launch_connection_editor():
"""Launch nmtui or the gui nm-connection-editor
"""
terminal = CONF.get("editor", "terminal", fallback="xterm")
gui_if_available = CONF.getboolean("editor", "gui_if_available", fallback=True)
guis = ["gnome-continue-center", "nm-connection-editor"]
if gui_if_available is True:
for gui in guis:
if is_installed(gui):
subprocess.run(gui, check=False)
return
if is_installed("nmtui"):
subprocess.run([terminal, "-e", "nmtui"], check=False)
return
notify("No network connection editor installed", urgency="critical")
def get_passphrase():
"""Get a password
Returns: string
"""
pinentry = CONF.get("dmenu", "pinentry", fallback=None)
if pinentry:
pin = ""
out = subprocess.run(pinentry,
capture_output=True,
check=False,
encoding=ENC,
input='setdesc Get network password\ngetpin\n').stdout
if out:
res = out.split("\n")[2]
if res.startswith("D "):
pin = res.split("D ")[1]
return pin
return subprocess.run(dmenu_cmd(0, "Passphrase"),
stdin=subprocess.DEVNULL,
capture_output=True,
check=False,
encoding=ENC).stdout
def delete_connection():
"""Display list of NM connections and delete the selected one
"""
conn_acts = [Action(i.get_id(), i.delete_async, args=[None, delete_cb, None]) for i in CONNS]
conn_names = "\n".join([str(i) for i in conn_acts])
sel = subprocess.run(dmenu_cmd(len(conn_acts), "CHOOSE CONNECTION TO DELETE:"),
capture_output=True,
check=False,
input=conn_names,
encoding=ENC,
env=ENV).stdout
if not sel.strip():
sys.exit()
action = [i for i in conn_acts if str(i) == sel.rstrip("\n")]
assert len(action) == 1, f"Selection was ambiguous: {str(sel)}"
action[0]()
LOOP.run()
def delete_cb(dev, res, data):
"""Notification if delete completed successfully
"""
if dev.delete_finish(res) is True:
notify(f"Deleted {dev.get_id()}")
else:
notify(f"Problem deleting {dev.get_id()}", urgency="critical")
LOOP.quit()
def set_new_connection(nm_ap, nm_pw, adapter):
"""Setup a new NetworkManager connection
Args: ap - NM.AccessPoint
pw - string
"""
nm_pw = str(nm_pw).strip()
profile = create_wifi_profile(nm_ap, nm_pw, adapter)
CLIENT.add_and_activate_connection_async(profile, adapter, nm_ap.get_path(),
None, verify_conn, profile)
LOOP.run()
def create_wifi_profile(nm_ap, password, adapter):
# pylint: disable=line-too-long
# From https://cgit.freedesktop.org/NetworkManager/NetworkManager/tree/examples/python/gi/add_connection.py
# and https://cgit.freedesktop.org/NetworkManager/NetworkManager/tree/examples/python/dbus/add-wifi-psk-connection.py
# pylint: enable=line-too-long
"""Create the NM profile given the AP and passphrase"""
ap_sec = ap_security(nm_ap)
profile = NM.SimpleConnection.new()
s_con = NM.SettingConnection.new()
s_con.set_property(NM.SETTING_CONNECTION_ID, ssid_to_utf8(nm_ap))
s_con.set_property(NM.SETTING_CONNECTION_UUID, str(uuid.uuid4()))
s_con.set_property(NM.SETTING_CONNECTION_TYPE, "802-11-wireless")
profile.add_setting(s_con)
s_wifi = NM.SettingWireless.new()
s_wifi.set_property(NM.SETTING_WIRELESS_SSID, nm_ap.get_ssid())
s_wifi.set_property(NM.SETTING_WIRELESS_MODE, 'infrastructure')
s_wifi.set_property(NM.SETTING_WIRELESS_MAC_ADDRESS, adapter.get_permanent_hw_address())
profile.add_setting(s_wifi)
s_ip4 = NM.SettingIP4Config.new()
s_ip4.set_property(NM.SETTING_IP_CONFIG_METHOD, "auto")
profile.add_setting(s_ip4)
s_ip6 = NM.SettingIP6Config.new()
s_ip6.set_property(NM.SETTING_IP_CONFIG_METHOD, "auto")
profile.add_setting(s_ip6)
if ap_sec != "--":
s_wifi_sec = NM.SettingWirelessSecurity.new()
if "WPA" in ap_sec:
s_wifi_sec.set_property(NM.SETTING_WIRELESS_SECURITY_KEY_MGMT,
"wpa-psk")
s_wifi_sec.set_property(NM.SETTING_WIRELESS_SECURITY_AUTH_ALG,
"open")
s_wifi_sec.set_property(NM.SETTING_WIRELESS_SECURITY_PSK, password)
elif "WEP" in ap_sec:
s_wifi_sec.set_property(NM.SETTING_WIRELESS_SECURITY_KEY_MGMT,
"None")
s_wifi_sec.set_property(NM.SETTING_WIRELESS_SECURITY_WEP_KEY_TYPE,
NM.WepKeyType.PASSPHRASE)
s_wifi_sec.set_wep_key(0, password)
profile.add_setting(s_wifi_sec)
return profile
def verify_conn(client, result, data):
"""Callback function for add_and_activate_connection_async
Check if connection completes successfully. Delete the connection if there
is an error.
"""
try:
act_conn = client.add_and_activate_connection_finish(result)
conn = act_conn.get_connection()
if not all([conn.verify(),
conn.verify_secrets(),
data.verify(),
data.verify_secrets()]):
raise GLib.Error
notify(f"Added {conn.get_id()}")
except GLib.Error:
try:
notify(f"Connection to {conn.get_id()} failed",
urgency="critical")
conn.delete_async(None, None, None)
except UnboundLocalError:
pass
finally:
LOOP.quit()
def create_ap_list(adapter, active_connections):
"""Generate list of access points. Remove duplicate APs , keeping strongest
ones and the active AP
Args: adapter
active_connections - list of all active connections
Returns: aps - list of access points
active_ap - active AP
active_ap_con - active Connection
adapter
"""
aps = []
ap_names = []
active_ap = adapter.get_active_access_point()
aps_all = sorted(adapter.get_access_points(),
key=lambda a: a.get_strength(), reverse=True)
conns_cur = [i for i in CONNS if
i.get_setting_wireless() is not None and
conn_matches_adapter(i, adapter)]
try:
ap_conns = active_ap.filter_connections(conns_cur)
active_ap_name = ssid_to_utf8(active_ap)
active_ap_con = [active_conn for active_conn in active_connections
if active_conn.get_connection() in ap_conns]
except AttributeError:
active_ap_name = None
active_ap_con = []
if len(active_ap_con) > 1:
raise ValueError("Multiple connection profiles match"
" the wireless AP")
active_ap_con = active_ap_con[0] if active_ap_con else None
for nm_ap in aps_all:
ap_name = ssid_to_utf8(nm_ap)
if nm_ap != active_ap and ap_name == active_ap_name:
# Skip adding AP if it's not active but same name as active AP
continue
if ap_name not in ap_names:
ap_names.append(ap_name)
aps.append(nm_ap)
return aps, active_ap, active_ap_con, adapter
def notify(message, details=None, urgency="low"):
"""Use notify-send if available for notifications
"""
args = ["-u", urgency, "-a", "networkmanager-dmenu", message]
if details is not None:
args.append(details)
if is_installed("notify-send"):
subprocess.run(["notify-send"] + args, check=False)
def run(): # pylint: disable=too-many-locals
"""Main script entrypoint"""
active = CLIENT.get_active_connections()
adapter = choose_adapter(CLIENT)
if adapter:
ap_actions = create_ap_actions(*create_ap_list(adapter, active))
else:
ap_actions = []
vpns = [i for i in CONNS if i.is_type(NM.SETTING_VPN_SETTING_NAME)]
try:
wgs = [i for i in CONNS if i.is_type(NM.SETTING_WIREGUARD_SETTING_NAME)]
except AttributeError:
# Workaround for older versions of python-gobject with no wireguard support
wgs = []
eths = [i for i in CONNS if i.is_type(NM.SETTING_WIRED_SETTING_NAME)]
blues = [i for i in CONNS if i.is_type(NM.SETTING_BLUETOOTH_SETTING_NAME)]
vpn_actions = create_vpn_actions(vpns, active)
wg_actions = create_wireguard_actions(wgs, active)
eth_actions = create_eth_actions(eths, active)
blue_actions = create_blue_actions(blues, active)
other_actions = create_other_actions(CLIENT)
wwan_installed = is_installed("ModemManager")
if wwan_installed:
gsms = [i for i in CONNS if i.is_type(NM.SETTING_GSM_SETTING_NAME)]
gsm_actions = create_gsm_actions(gsms, active)
wwan_actions = create_wwan_actions(CLIENT)
else:
gsm_actions = []
wwan_actions = []
list_saved = CONF.getboolean('dmenu', 'list_saved', fallback=False)
saved_cons = [i for i in CONNS if i not in vpns + wgs + eths + blues]
if list_saved:
saved_actions = create_saved_actions(saved_cons)
else:
saved_actions = [Action("Saved connections", prompt_saved, [saved_cons])]
actions = combine_actions(eth_actions, ap_actions, vpn_actions, wg_actions,
gsm_actions, blue_actions, wwan_actions,
other_actions, saved_actions)
sel = get_selection(actions)
sel()
if __name__ == '__main__':
run()
# vim: set et ts=4 sw=4 :

34
misc/bin/scripts/system/srv Executable file
View File

@ -0,0 +1,34 @@
#!/usr/bin/zsh
typeset -A srv
srv["trycaster"]="ssh -p 4999 chatlanin@92.53.65.239"
srv["dev_em"]="ssh a.zimin@dev01.emd01.lwb.d-net.pro"
srv["em_prod_1"]="ssh a.zimin@prod01.emp01.lwb.d-net.pro"
srv["em_prod_2"]="ssh a.zimin@prod02.emp01.lwb.d-net.pro"
source /mnt/raid/bin/scripts/system/style
typeset -A array
array["dir"]=dir
array["srv"]=srv
MODE_1=\"$1\"
INDEX=1
if [[ $MODE_1 == \"\" ]] then
echo ""
INDEX=1
OUTPUT="POS. # SERVER NAME # COMMAND\n----#--------------------------------#--------------------------------------------------------"
for key value in ${(kv)srv}; do
OUTPUT="$OUTPUT\n $INDEX # $BOLD$BLUE$key$RESET_COLOR # $ITALIC$CYAN$value$RESET_COLOR"
INDEX=$((INDEX + 1))
done
echo -ne $OUTPUT | column -ts $'#'
read MODE_1
MODE_1=\"$MODE_1\"
fi
cmd=${${(P)array["srv"]}[$MODE_1]}
bash -c $cmd

89
misc/bin/scripts/system/style Executable file
View File

@ -0,0 +1,89 @@
#!/bin/zsh
RESET_COLOR="\033[0m"
BOLD="\033[1m"
ITALIC="\033[3m"
BLACK="\033[30m"
RED="\033[31m"
GREEN="\033[32m"
YELLOW="\033[33m"
BLUE="\033[34m"
MAGENTA="\033[35m"
CYAN="\033[36m"
WHITE="\033[37m"
PURPLE="\033[35m"
# для специфического цвета запусить в терминал
# showcolors256 или showcolors256 fg
# выбрать код цвет аи вставить тут или в коде
code_color_0=245
code_color_1=245
code_color_2=031
COLOR_BUILD_0="\033[38;5;${code_color_0}m";
COLOR_BUILD_1="\033[38;5;${code_color_1}m";
COLOR_BUILD_2="\033[38;5;${code_color_2}m";
function showcolors256() {
local row col blockrow blockcol red green blue
local showcolor=_showcolor256_${1:-bg}
local white="\033[1;37m"
local reset="\033[0m"
echo -e "Set foreground color: \\\\033[38;5;${white}NNN${reset}m"
echo -e "Set background color: \\\\033[48;5;${white}NNN${reset}m"
echo -e "Reset color & style: \\\\033[0m"
echo
echo 16 standard color codes:
for row in {0..1}; do
for col in {0..7}; do
$showcolor $(( row*8 + col )) $row
done
echo
done
echo
echo 6·6·6 RGB color codes:
for blockrow in {0..2}; do
for red in {0..5}; do
for blockcol in {0..1}; do
green=$(( blockrow*2 + blockcol ))
for blue in {0..5}; do
$showcolor $(( red*36 + green*6 + blue + 16 )) $green
done
echo -n " "
done
echo
done
echo
done
echo 24 grayscale color codes:
for row in {0..1}; do
for col in {0..11}; do
$showcolor $(( row*12 + col + 232 )) $row
done
echo
done
echo
}
function _showcolor256_fg() {
local code=$( printf %03d $1 )
echo -ne "\033[38;5;${code}m"
echo -nE " $code "
echo -ne "\033[0m"
}
function _showcolor256_bg() {
if (( $2 % 2 == 0 )); then
echo -ne "\033[1;37m"
else
echo -ne "\033[0;30m"
fi
local code=$( printf %03d $1 )
echo -ne "\033[48;5;${code}m"
echo -nE " $code "
echo -ne "\033[0m"
}

View File

@ -0,0 +1,83 @@
#!/usr/bin/env bash
## Script to take screenshots with maim
time=`date +%Y-%m-%d-%H-%M-%S`
geometry=`xrandr | grep 'current' | head -n1 | cut -d',' -f2 | tr -d '[:blank:],current'`
dir="`xdg-user-dir PICTURES`/Screenshots"
file="Screenshot_${time}_${geometry}.png"
# Commands
notify_cmd_shot="dunstify -u low --replace=699 -i /usr/share/icons/dunst/picture.png"
# notify and view screenshot
notify_view () {
${notify_cmd_shot} "Copied to clipboard."
viewnior ${dir}/"$file"
if [[ -e "$dir/$file" ]]; then
${notify_cmd_shot} "Screenshot Saved."
else
${notify_cmd_shot} "Screenshot Deleted."
fi
}
# Copy screenshot to clipboard
copy_shot () {
tee "$file" | xclip -selection clipboard -t image/png
}
# countdown
countdown () {
for sec in `seq $1 -1 1`; do
dunstify -t 1000 --replace=699 -i /usr/share/icons/dunst/timer.png "Taking shot in : $sec"
sleep 1
done
}
# take shots
shotnow () {
cd ${dir} && maim -u -f png | copy_shot
notify_view
}
shot5 () {
countdown '5'
sleep 1 && cd ${dir} && maim -u -f png | copy_shot
notify_view
}
shot10 () {
countdown '10'
sleep 1 && cd ${dir} && maim -u -f png | copy_shot
notify_view
}
shotwin () {
cd ${dir} && maim -u -f png -i `xdotool getactivewindow` | copy_shot
notify_view
}
shotarea () {
cd ${dir} && maim -u -f png -s -b 2 -c 0.35,0.55,0.85,0.25 -l | copy_shot
notify_view
}
if [[ ! -d "$dir" ]]; then
mkdir -p "$dir"
fi
if [[ "$1" == "--now" ]]; then
shotnow
elif [[ "$1" == "--in5" ]]; then
shot5
elif [[ "$1" == "--in10" ]]; then
shot10
elif [[ "$1" == "--win" ]]; then
shotwin
elif [[ "$1" == "--area" ]]; then
shotarea
else
echo -e "Available Options : --now --in5 --in10 --win --area"
fi
exit 0

65
misc/bin/scripts/system/volume Executable file
View File

@ -0,0 +1,65 @@
#!/bin/bash
#####################################
# #
# @author : 00xWolf #
#  GitHub : @mmsaeed509 #
#  Developer : Mahmoud Mohamed #
# 﫥 Copyright : Exodia OS #
# #
#####################################
# Get Volume
get_volume() {
volume=`amixer get Master | tail -n1 | awk -F ' ' '{print $5}' | tr -d '[]'`
echo "$volume"
}
# Get icons
get_icon() {
vol="$(get_volume)"
current="${vol%%%}"
if [[ "$current" -eq "0" ]]; then
icon='/usr/share/icons/dunst/volume-mute.png'
elif [[ ("$current" -ge "0") && ("$current" -le "30") ]]; then
icon='/usr/share/icons/dunst/volume-low.png'
elif [[ ("$current" -ge "30") && ("$current" -le "60") ]]; then
icon='/usr/share/icons/dunst/volume-mid.png'
elif [[ ("$current" -ge "60") && ("$current" -le "100") ]]; then
icon='/usr/share/icons/dunst/volume-high.png'
fi
}
# Increase Volume
inc_volume() {
amixer -Mq set Master,0 5%+ unmute && get_icon && dunstify -u low --replace=69 -i "$icon" "Volume : $(get_volume)"
}
# Decrease Volume
dec_volume() {
amixer -Mq set Master,0 5%- unmute && get_icon && dunstify -u low --replace=69 -i "$icon" "Volume : $(get_volume)"
}
# Toggle Mute
toggle_mute() {
status=`amixer get Master | tail -n1 | grep -wo 'on'`
if [[ "$status" == "on" ]]; then
amixer set Master toggle && dunstify -u low --replace=69 -i '/usr/share/icons/dunst/volume-mute.png' "Mute"
else
amixer set Master toggle && get_icon && dunstify -u low --replace=69 -i "$icon" "Unmute"
fi
}
# Execute accordingly
if [[ "$1" == "--get" ]]; then
get_volume
elif [[ "$1" == "--inc" ]]; then
inc_volume
elif [[ "$1" == "--dec" ]]; then
dec_volume
elif [[ "$1" == "--toggle" ]]; then
toggle_mute
else
get_volume
fi

3
misc/bin/scripts/system/vpn Executable file
View File

@ -0,0 +1,3 @@
#!/bin/zsh
sudo openvpn /home/$USER/openvpn.conf

1
misc/bin/z.lua Submodule

@ -0,0 +1 @@
Subproject commit 0992ebf9f1f6cdaa114e65d3aa76bfb1bd9a6fd4

View File

@ -31,6 +31,7 @@ BACKUP (){
echo -e ${CYAN}" ==> перемещаем текущий конфиг в backup дирректорию." ${RESET_COLOR} echo -e ${CYAN}" ==> перемещаем текущий конфиг в backup дирректорию." ${RESET_COLOR}
mv ${HOME_DIR}/.Xresources.d ${BACKUP_DIR}/${FILES_NAME}-${BACKUP_NAME}-${BACKUP_RANDOM} mv ${HOME_DIR}/.Xresources.d ${BACKUP_DIR}/${FILES_NAME}-${BACKUP_NAME}-${BACKUP_RANDOM}
mv ${HOME_DIR}/bin ${BACKUP_DIR}/${FILES_NAME}-${BACKUP_NAME}-${BACKUP_RANDOM}
mv ${HOME_DIR}/.dmrc ${BACKUP_DIR}/${FILES_NAME}-${BACKUP_NAME}-${BACKUP_RANDOM} mv ${HOME_DIR}/.dmrc ${BACKUP_DIR}/${FILES_NAME}-${BACKUP_NAME}-${BACKUP_RANDOM}
mv ${HOME_DIR}/.face ${BACKUP_DIR}/${FILES_NAME}-${BACKUP_NAME}-${BACKUP_RANDOM} mv ${HOME_DIR}/.face ${BACKUP_DIR}/${FILES_NAME}-${BACKUP_NAME}-${BACKUP_RANDOM}
mv ${HOME_DIR}/.gtkrc-2.0 ${BACKUP_DIR}/${FILES_NAME}-${BACKUP_NAME}-${BACKUP_RANDOM} mv ${HOME_DIR}/.gtkrc-2.0 ${BACKUP_DIR}/${FILES_NAME}-${BACKUP_NAME}-${BACKUP_RANDOM}
@ -49,7 +50,9 @@ INSTALL (){
mkdir -p ${HOME_DIR} mkdir -p ${HOME_DIR}
echo -e ${CYAN}" ==> перемещяем текущие настройки дял пользователя: ${PURPLE}${USER}" ${RESET_COLOR}
cp -rf ${SKEL_DIR}/.Xresources.d ${HOME_DIR} cp -rf ${SKEL_DIR}/.Xresources.d ${HOME_DIR}
cp -rf ${SKEL_DIR}/bin ${HOME_DIR}
cp ${SKEL_DIR}/.dmrc ${HOME_DIR} cp ${SKEL_DIR}/.dmrc ${HOME_DIR}
cp ${SKEL_DIR}/.face ${HOME_DIR} cp ${SKEL_DIR}/.face ${HOME_DIR}
cp ${SKEL_DIR}/.gtkrc-2.0 ${HOME_DIR} cp ${SKEL_DIR}/.gtkrc-2.0 ${HOME_DIR}
@ -60,6 +63,7 @@ INSTALL (){
echo -e ${CYAN}" ==> предоставление разрешений для пользователя: ${PURPLE}${USER}" ${RESET_COLOR} echo -e ${CYAN}" ==> предоставление разрешений для пользователя: ${PURPLE}${USER}" ${RESET_COLOR}
chown -R ${USER}:${GROUB} ${HOME_DIR}/.Xresources.d chown -R ${USER}:${GROUB} ${HOME_DIR}/.Xresources.d
chown -R ${USER}:${GROUB} ${HOME_DIR}/bin
chown -R ${USER}:${GROUB} ${HOME_DIR}/.dmrc chown -R ${USER}:${GROUB} ${HOME_DIR}/.dmrc
chown -R ${USER}:${GROUB} ${HOME_DIR}/.face chown -R ${USER}:${GROUB} ${HOME_DIR}/.face
chown -R ${USER}:${GROUB} ${HOME_DIR}/.gtkrc-2.0 chown -R ${USER}:${GROUB} ${HOME_DIR}/.gtkrc-2.0
@ -68,7 +72,7 @@ INSTALL (){
chown -R ${USER}:${GROUB} ${HOME_DIR}/.Xresources chown -R ${USER}:${GROUB} ${HOME_DIR}/.Xresources
chown -R ${USER}:${GROUB} ${HOME_DIR}/.zshrc chown -R ${USER}:${GROUB} ${HOME_DIR}/.zshrc
if [[ -d "${HOME_DIR}/.Xresources.d" && -f "${HOME_DIR}/.dmrc" && -f "${HOME_DIR}/.face" && -f "${HOME_DIR}/.fehbg" && -f "${HOME_DIR}/.gtkrc-2.0" && -f "${HOME_DIR}/.hushlogin" && -f "${HOME_DIR}/.p10k.zsh" && -f "${HOME_DIR}/.Xresources" && -f "${HOME_DIR}/.xsettingsd" && -f "${HOME_DIR}/.zshrc" ]]; then if [[ -d "${HOME_DIR}/.Xresources.d" && -d "${HOME_DIR}/bin" && -f "${HOME_DIR}/.dmrc" && -f "${HOME_DIR}/.face" && -f "${HOME_DIR}/.gtkrc-2.0" && -f "${HOME_DIR}/.hushlogin" && -f "${HOME_DIR}/.p10k.zsh" && -f "${HOME_DIR}/.Xresources" && -f "${HOME_DIR}/.zshrc" ]]; then
echo -e ${BOLD}${GREEN}"[✔] конфигурационные файлы установлены..." ${RESET_COLOR} echo -e ${BOLD}${GREEN}"[✔] конфигурационные файлы установлены..." ${RESET_COLOR}
echo -e "\n" echo -e "\n"
else else