From 992ef73769cc2e61469a53f6dd8c2144bec99410 Mon Sep 17 00:00:00 2001 From: Solomon Laing Date: Thu, 1 Apr 2021 23:18:54 +1030 Subject: [PATCH] added some scripts from Luke Smith and Derek Taylor, also made some misc chages to keys in xmonad --- .scripts/dmenumount | 67 +++++++++++++++++++++++++++++++++ .scripts/dmenumountcifs | 19 ++++++++++ .scripts/dmenuumount | 44 ++++++++++++++++++++++ .scripts/dmsearch | 82 +++++++++++++++++++++++++++++++++++++++++ .scripts/prompt | 8 +++- .scripts/rssadd | 18 +++++++++ .xmonad/xmonad.hs | 41 ++++++++++++++------- 7 files changed, 264 insertions(+), 15 deletions(-) create mode 100755 .scripts/dmenumount create mode 100755 .scripts/dmenumountcifs create mode 100755 .scripts/dmenuumount create mode 100755 .scripts/dmsearch create mode 100755 .scripts/rssadd diff --git a/.scripts/dmenumount b/.scripts/dmenumount new file mode 100755 index 0000000..b98b6a3 --- /dev/null +++ b/.scripts/dmenumount @@ -0,0 +1,67 @@ +#!/bin/sh + +# Gives a dmenu prompt to mount unmounted drives and Android phones. If +# they're in /etc/fstab, they'll be mounted automatically. Otherwise, you'll +# be prompted to give a mountpoint from already existsing directories. If you +# input a novel directory, it will prompt you to create that directory. + +getmount() { \ + [ -z "$chosen" ] && exit 1 + # shellcheck disable=SC2086 + mp="$(find $1 2>/dev/null | dmenu -i -p "Type in mount point.")" || exit 1 + [ "$mp" = "" ] && exit 1 + if [ ! -d "$mp" ]; then + mkdiryn=$(printf "No\\nYes" | dmenu -i -p "$mp does not exist. Create it?") || exit 1 + [ "$mkdiryn" = "Yes" ] && (mkdir -p "$mp" || sudo -A mkdir -p "$mp") + fi + } + +mountusb() { \ + chosen="$(echo "$usbdrives" | dmenu -i -p "Mount which drive?")" || exit 1 + chosen="$(echo "$chosen" | awk '{print $1}')" + sudo -A mount "$chosen" 2>/dev/null && notify-send "💻 USB mounting" "$chosen mounted." && exit 0 + alreadymounted=$(lsblk -nrpo "name,type,mountpoint" | awk '$3!~/\/boot|\/home$|SWAP/&&length($3)>1{printf "-not ( -path *%s -prune ) ",$3}') + getmount "/mnt /media /mount /home -maxdepth 5 -type d $alreadymounted" + partitiontype="$(lsblk -no "fstype" "$chosen")" + case "$partitiontype" in + "vfat") sudo -A mount -t vfat "$chosen" "$mp" -o rw,umask=0000;; + "exfat") sudo -A mount "$chosen" "$mp" -o uid="$(id -u)",gid="$(id -g)";; + *) sudo -A mount "$chosen" "$mp"; user="$(whoami)"; ug="$(groups | awk '{print $1}')"; sudo -A chown "$user":"$ug" "$mp";; + esac + notify-send "💻 USB mounting" "$chosen mounted to $mp." + } + +mountandroid() { \ + chosen="$(echo "$anddrives" | dmenu -i -p "Which Android device?")" || exit 1 + chosen="$(echo "$chosen" | cut -d : -f 1)" + getmount "$HOME -maxdepth 3 -type d" + simple-mtpfs --device "$chosen" "$mp" + echo "OK" | dmenu -i -p "Tap Allow on your phone if it asks for permission and then press enter" || exit 1 + simple-mtpfs --device "$chosen" "$mp" + notify-send "🤖 Android Mounting" "Android device mounted to $mp." + } + +asktype() { \ + choice="$(printf "USB\\nAndroid" | dmenu -i -p "Mount a USB drive or Android device?")" || exit 1 + case $choice in + USB) mountusb ;; + Android) mountandroid ;; + esac + } + +anddrives=$(simple-mtpfs -l 2>/dev/null) +usbdrives="$(lsblk -rpo "name,type,size,mountpoint" | grep 'part\|rom' | awk '$4==""{printf "%s (%s)\n",$1,$3}')" + +if [ -z "$usbdrives" ]; then + [ -z "$anddrives" ] && echo "No USB drive or Android device detected" && exit + echo "Android device(s) detected." + mountandroid +else + if [ -z "$anddrives" ]; then + echo "USB drive(s) detected." + mountusb + else + echo "Mountable USB drive(s) and Android device(s) detected." + asktype + fi +fi diff --git a/.scripts/dmenumountcifs b/.scripts/dmenumountcifs new file mode 100755 index 0000000..46c2b57 --- /dev/null +++ b/.scripts/dmenumountcifs @@ -0,0 +1,19 @@ +#!/bin/sh +# Gives a dmenu prompt to mount unmounted local NAS shares for read/write. +# Requirements - "%wheel ALL=(ALL) NOPASSWD: ALL" +# +# Browse for mDNS/DNS-SD services using the Avahi daemon... +srvname=$(avahi-browse _smb._tcp -t | awk '{print $4}' | dmenu -i -p "Which NAS?") || exit 1 +notify-send "Searching for network shares..." "Please wait..." +# Choose share disk... +share=$(smbclient -L "$srvname" -N | grep Disk | awk '{print $1}' | dmenu -i -p "Mount which share?") || exit 1 +# Format URL... +share2mnt=//"$srvname".local/"$share" + +sharemount() { + mounted=$(mount -v | grep "$share2mnt") || ([ ! -d /mnt/"$share" ] && sudo mkdir /mnt/"$share") + [ -z "$mounted" ] && sudo mount -t cifs "$share2mnt" -o user=nobody,password="",noperm /mnt/"$share" && notify-send "Netshare $share mounted" && exit 0 + notify-send "Netshare $share already mounted"; exit 1 +} + +sharemount diff --git a/.scripts/dmenuumount b/.scripts/dmenuumount new file mode 100755 index 0000000..26612ef --- /dev/null +++ b/.scripts/dmenuumount @@ -0,0 +1,44 @@ +#!/bin/sh + +# A dmenu prompt to unmount drives. +# Provides you with mounted partitions, select one to unmount. +# Drives mounted at /, /boot and /home will not be options to unmount. + +unmountusb() { + [ -z "$drives" ] && exit + chosen="$(echo "$drives" | dmenu -i -p "Unmount which drive?")" || exit 1 + chosen="$(echo "$chosen" | awk '{print $1}')" + [ -z "$chosen" ] && exit + sudo -A umount "$chosen" && notify-send "💻 USB unmounting" "$chosen unmounted." + } + +unmountandroid() { \ + chosen="$(awk '/simple-mtpfs/ {print $2}' /etc/mtab | dmenu -i -p "Unmount which device?")" || exit 1 + [ -z "$chosen" ] && exit + sudo -A umount -l "$chosen" && notify-send "🤖 Android unmounting" "$chosen unmounted." + } + +asktype() { \ + choice="$(printf "USB\\nAndroid" | dmenu -i -p "Unmount a USB drive or Android device?")" || exit 1 + case "$choice" in + USB) unmountusb ;; + Android) unmountandroid ;; + esac + } + +drives=$(lsblk -nrpo "name,type,size,mountpoint" | awk '$4!~/\/boot|\/home$|SWAP/&&length($4)>1{printf "%s (%s)\n",$4,$3}') + +if ! grep simple-mtpfs /etc/mtab; then + [ -z "$drives" ] && echo "No drives to unmount." && exit + echo "Unmountable USB drive detected." + unmountusb +else + if [ -z "$drives" ] + then + echo "Unmountable Android device detected." + unmountandroid + else + echo "Unmountable USB drive(s) and Android device(s) detected." + asktype + fi +fi diff --git a/.scripts/dmsearch b/.scripts/dmsearch new file mode 100755 index 0000000..1e28a18 --- /dev/null +++ b/.scripts/dmsearch @@ -0,0 +1,82 @@ +#!/usr/bin/env bash +# +# Script name: dmsearch +# Description: Search various search engines (inspired by surfraw). +# Dependencies: dmenu and a web browser + +# Pilfered from Derek Taylor @ https://www.gitlab.com/dwt1/dmscripts + +# Contributors: Derek Taylor +# Ali Furkan Yıldız + +# Defining our web browser. +DMBROWSER="${BROWSER:-surf}" + +# An array of search engines. You can edit this list to add/remove +# search engines. The format must be: "engine_name]="url". +# The url format must allow for the search keywords at the end of the url. +# For example: https://www.amazon.com/s?k=XXXX searches Amazon for 'XXXX'. +declare -A options +options[amazon]="https://www.amazon.com/s?k=" +options[archaur]="https://aur.archlinux.org/packages/?O=0&K=" +options[archpkg]="https://archlinux.org/packages/?sort=&q=" +options[archwiki]="https://wiki.archlinux.org/index.php?search=" +options[arxiv]="https://arxiv.org/search/?searchtype=all&source=header&query=" +options[bbcnews]="https://www.bbc.co.uk/search?q=" +options[bing]="https://www.bing.com/search?q=" +options[cliki]="https://www.cliki.net/site/search?query=" +options[cnn]="https://www.cnn.com/search?q=" +options[coinbase]="https://www.coinbase.com/price?query=" +options[debianpkg]="https://packages.debian.org/search?suite=default§ion=all&arch=any&searchon=names&keywords=" +options[discogs]="https://www.discogs.com/search/?&type=all&q=" +options[duckduckgo]="https://duckduckgo.com/?q=" +options[ebay]="https://www.ebay.com/sch/i.html?&_nkw=" +options[github]="https://github.com/search?q=" +options[gitlab]="https://gitlab.com/search?search=" +options[imdb]="https://www.imdb.com/find?q=" +options[lbry]="https://lbry.tv/$/search?q=" +options[odysee]="https://odysee.com/$/search?q=" +options[reddit]="https://www.reddit.com/search/?q=" +options[slashdot]="https://slashdot.org/index2.pl?fhfilter=" +options[socialblade]="https://socialblade.com/youtube/user/" +options[sourceforge]="https://sourceforge.net/directory/?q=" +options[stack]="https://stackoverflow.com/search?q=" +options[startpage]="https://www.startpage.com/do/dsearch?query=" +options[stockquote]="https://finance.yahoo.com/quote/" +options[thesaurus]="https://www.thesaurus.com/misspelling?term=" +options[translate]="https://translate.google.com/?sl=auto&tl=en&text=" +options[urban]="https://www.urbandictionary.com/define.php?term=" +options[wayback]="https://web.archive.org/web/*/" +options[webster]="https://www.merriam-webster.com/dictionary/" +options[wikipedia]="https://en.wikipedia.org/wiki/" +options[wiktionary]="https://en.wiktionary.org/wiki/" +options[wolfram]="https://www.wolframalpha.com/input/?i=" +options[youtube]="https://www.youtube.com/results?search_query=" +options[google]="https://www.google.com/search?q=" +options[googleimages]="https://www.google.com/search?hl=en&tbm=isch&q=" +options[googlenews]="https://news.google.com/search?q=" +options[googleSupport]="https://support.google.com/search?q=" +options[googleSupportAdmin]="https://support.google.com/a/search?q=" +options[googleStructuredData]="https://search.google.com/structured-data/testing-tool#url=" +options[googleRichResults]="https://search.google.com/test/rich-results??url=" +options[googlePagespeed]="https://developers.google.com/speed/pagespeed/insights/?url=" +options[googleDevelopers]="https://developers.google.com/s/results?q=" +options[googleOpenSource]="https://opensource.google/projects/search?q=" +options[googleExperimentswithGoogle]="https://experiments.withgoogle.com/search?q=" +options[googleDataset]="https://datasetsearch.research.google.com/search?query=" + +# Picking a search engine. +# shellcheck disable=SC2154 +while [ -z "$engine" ]; do + engine=$(printf '%s\n' "${!options[@]}" | sort | dmenu -i -l 20 -p 'Choose search engine:') "$@" || exit + url="${options["${engine}"]}" || exit +done + +# Searching the chosen engine. +# shellcheck disable=SC2154 +while [ -z "$query" ]; do + query=$(echo "$engine" | dmenu -p 'Enter search query:') "$@" || exit +done + +# Display search results in web browser +$DMBROWSER "$url""$query" diff --git a/.scripts/prompt b/.scripts/prompt index 678428c..afb24a4 100755 --- a/.scripts/prompt +++ b/.scripts/prompt @@ -2,12 +2,18 @@ # A dmenu binary prompt script. # Gives a dmenu prompt labelled with $1 to perform command $2. +# To invert the options, simply provide a thrid parameter $3. # For example: # `./prompt "Do you want to shutdown?" "shutdown now"` # Taken shamelessly from Luke Smith -choice=$(echo -e "No\nYes" | dmenu -bw 0 -i -p "$1") +if [ -n "$3" ] +then + choice=$(echo -e "Yes\nNo" | dmenu -bw 0 -i -p "$1") +else + choice=$(echo -e "No\nYes" | dmenu -bw 0 -i -p "$1") +fi if [ $choice = "Yes" ] then diff --git a/.scripts/rssadd b/.scripts/rssadd new file mode 100755 index 0000000..fb60be8 --- /dev/null +++ b/.scripts/rssadd @@ -0,0 +1,18 @@ +#!/bin/sh + +if echo "$1" | grep "https*://\S\+\.[A-Za-z]\+\S*" >/dev/null; then + url="$1" +else + url="$(grep -Eom1 '<[^>]+(rel="self"|application/[a-z]+\+xml)[^>]+>' "$1" | + sed -E 's_^.*href="(https?://[^"]+)".*$_\1_')" + + ! grep "https*://\S\+\.[A-Za-z]\+\S*" <<<"$url" && + notify-send "That doesn't look like a full URL." && exit 1 +fi + +RSSFILE="${XDG_CONFIG_HOME:-$HOME/.config}/newsboat/urls" +if awk '{print $1}' "$RSSFILE" | grep "^$url$" >/dev/null; then + notify-send "You already have this RSS feed." +else + echo "$url" >> "$RSSFILE" && notify-send "RSS feed added." +fi diff --git a/.xmonad/xmonad.hs b/.xmonad/xmonad.hs index 3085a07..3c64106 100644 --- a/.xmonad/xmonad.hs +++ b/.xmonad/xmonad.hs @@ -147,14 +147,26 @@ myKeys conf@(XConfig {XMonad.modMask = modm}) = M.fromList $ , ((modm, xK_o ), spawn "rofi -show run") -- launch dmenu - , ((modm, xK_a ), spawn "dmenu_run -c -l 15 -h 26") + , ((modm, xK_a ), spawn "dmenu_run -bw 3 -c -l 15 -h 26") -- launch rofi ssh , ((modm .|. shiftMask, xK_o ), spawn "rofi -show ssh") + -- launch searcher + ,((modm, xK_s ), spawn "/home/solomon/.scripts/dmsearch") + + -- launch mounter + ,((modm, xK_c ), spawn "/home/solomon/.scripts/dmenumount") + + -- launch unmounter + ,((modm .|. shiftMask, xK_c ), spawn "/home/solomon/.scripts/dmenuumount") + -- launch my file manager , ((modm, xK_l ), spawn myFileManager) + -- launch my file manager + , ((modm .|. shiftMask, xK_l ), spawn "/home/solomon/.scripts/samedir") + -- close focused window , ((modm .|. shiftMask, xK_j ), kill) @@ -171,7 +183,7 @@ myKeys conf@(XConfig {XMonad.modMask = modm}) = M.fromList $ , ((modm, xK_Tab ), windows W.focusDown) -- Move focus to the next window - , ((modm .|. shiftMask, xK_Tab ), windows W.focusUp) + , ((modm .|. shiftMask, xK_Tab ), windows W.focusUp) -- Move focus to the next window , ((modm, xK_h ), windows W.focusDown) @@ -186,37 +198,37 @@ myKeys conf@(XConfig {XMonad.modMask = modm}) = M.fromList $ , ((modm, xK_Return), windows W.swapMaster) -- Swap the focused window with the next window - , ((modm .|. shiftMask, xK_Down ), windows W.swapDown ) + , ((modm .|. shiftMask, xK_Down ), windows W.swapDown ) -- Swap the focused window with the previous window - , ((modm .|. shiftMask, xK_Up ), windows W.swapUp ) + , ((modm .|. shiftMask, xK_Up ), windows W.swapUp ) -- Shrink the master area - , ((modm, xK_Left ), sendMessage Shrink) + , ((modm, xK_Left ), sendMessage Shrink) -- Expand the master area - , ((modm, xK_Right ), sendMessage Expand) + , ((modm, xK_Right ), sendMessage Expand) -- Push window back into tiling , ((modm, xK_y ), withFocused $ windows . W.sink) -- Increment the number of windows in the master area - , ((modm , xK_w ), sendMessage (IncMasterN 1)) + , ((modm, xK_w ), sendMessage (IncMasterN 1)) -- Deincrement the number of windows in the master area - , ((modm , xK_v), sendMessage (IncMasterN (-1))) + , ((modm, xK_v ), sendMessage (IncMasterN (-1))) -- Toggle the status bar gap -- Use this binding with avoidStruts from Hooks.ManageDocks. -- See also the statusBar function from Hooks.DynamicLog. -- - , ((modm , xK_b ), sendMessage ToggleStruts) + , ((modm, xK_b ), sendMessage ToggleStruts) -- Quit xmonad , ((modm .|. shiftMask, xK_apostrophe ), io (exitWith ExitSuccess)) -- Restart xmonad - , ((modm , xK_apostrophe ), spawn "xmonad --recompile; xmonad --restart") + , ((modm, xK_apostrophe ), spawn "xmonad --recompile; xmonad --restart") -- Run xmessage with a summary of the default keybindings (useful for beginners) , ((modm .|. shiftMask, xK_z ), spawn ("echo \"" ++ help ++ "\" | xmessage -file -")) @@ -231,16 +243,17 @@ myKeys conf@(XConfig {XMonad.modMask = modm}) = M.fromList $ ((modm .|. shiftMask, xK_s ), spawn "/home/solomon/.scripts/prompt \"Are you sure you want to Shutdown?\" \"shutdown now\"") -- prompt computer reboot - , ((modm .|. shiftMask, xK_r ), spawn "/home/solomon/.scripts/prompt \"Are you sure you want to Restart?\" \"reboot\"") + , ((modm .|. shiftMask, xK_r ), spawn "/home/solomon/.scripts/prompt \"Are you sure you want to Restart?\" \"reboot\"") + -- prompt computer lock - , ((modm .|. shiftMask, xK_l ), spawn "/home/solomon/.scripts/prompt \"Are you sure you want to lock?\" \"slock\"") + , ((modm, xK_Escape), spawn "/home/solomon/.scripts/prompt \"Are you sure you want to lock?\" \"slock\" 1") -- unlock bitwarden cli and store session key - , ((modm .|. shiftMask, xK_t ), spawn "/home/solomon/.scripts/bw-unlock") + , ((modm .|. shiftMask, xK_t ), spawn "/home/solomon/.scripts/bw-unlock") -- search for password using bitwarden cli through dmenu - , ((modm, xK_t ), spawn "/home/solomon/.scripts/passwords") + , ((modm, xK_t ), spawn "/home/solomon/.scripts/passwords") ] ++