From 1ab519531c00c9781ec3626592729ba58d58a4b6 Mon Sep 17 00:00:00 2001 From: Jonathan Hodgson Date: Tue, 2 Mar 2021 18:35:57 +0000 Subject: [PATCH 1/2] Initial work on modem functionality Including, checking for incoming calls, missed calls, sms and the start of a dialer using rofi --- bin/.bin/modem/checkCall | 128 ++++++++++++++++++++++++++++++++++++ bin/.bin/modem/checkSMS | 58 ++-------------- bin/.bin/modem/common | 54 +++++++++++++++ bin/.bin/modem/dialer | 7 +- bin/.bin/modem/missedCalls | 38 +++++++++++ bin/.bin/modem/monitorModem | 29 ++++++++ 6 files changed, 259 insertions(+), 55 deletions(-) create mode 100755 bin/.bin/modem/checkCall create mode 100644 bin/.bin/modem/common create mode 100755 bin/.bin/modem/missedCalls create mode 100755 bin/.bin/modem/monitorModem diff --git a/bin/.bin/modem/checkCall b/bin/.bin/modem/checkCall new file mode 100755 index 00000000..e6384098 --- /dev/null +++ b/bin/.bin/modem/checkCall @@ -0,0 +1,128 @@ +#!/usr/bin/env bash + + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +source "$DIR/common" + +usage(){ + echo "checkCall [options] [message|-]" + echo "Options:" + echo " -h|--help Display this help text" + echo " -m|--modem Specify a modem" + echo " --dry-run Don't actually send the message" +} + + +# Stolen from sxmo +lookupnumberfromcallid() { + local id=$1 + mmcli -m "$modem" --voice-list-calls -o "$id" -K | + grep call.properties.number | + cut -d ':' -f 2 | + tr -d ' ' +} + +lookupcontact(){ + echo "$1" | + # Remove the +44 and replace with 0 + sed 's/^\+44/0/' + # This will eventually work with abook but for now just return the number +} + +answer-call(){ + mmcli -m "$modem" -o "$1" --accept +} + +reject-call(){ + notify-send "Reject" +} + +prompt-incoming(){ + export DISPLAY=:0.0 + + local answer="" + local reject="" + + local choice='' + # Used for testing + local number="${1:-01234 567890}" + + local prompt="$(echo -en "Incoming Call\n$number")" + + while [ -z "$choice" ]; do + + choice="$(echo -e "$answer\n$reject" | rofi -dmenu -i \ + -theme themes/incoming-call.rasi -a 0 -u 1 \ + -p "$prompt" \ + -me-select-entry '' -me-accept-entry MousePrimary)" + + case "$choice" in + "$answer") echo "answer" ;; + "$reject") echo "reject" ;; + esac + done +} + +mkdir -p "$CALL_DIR" + +dryrun="false" + +# Assume we want the first modem +# can be overwritten by the -m option +modem="$(mmcli -L | grep -oE 'Modem\/[0-9]+' | head -n 1 | cut -d'/' -f2)" + + + +# Read the options and set stuff +while [[ $1 = -?* ]]; do + case $1 in + -h|--help) usage; exit;; + -m|--modem) modem="$2"; shift ;; + --dry-run) dryrun="true" ;; + --) shift; break ;; + *) die "invalid option: '$1'." ;; + esac + shift +done + + +checkIncoming(){ + local id="$( mmcli -m "$modem" --voice-list-calls | + grep -Eo '[0-9]+ incoming \(ringing-in\)' | grep -Eo '[0-9]+' )" + + local count="$(echo "$id" | deleteEmptyLines | wc -l)" + + [ "$count" -eq 0 ] && return + + local number="$(lookupnumberfromcallid "$id")" + local contact="$(lookupcontact "$number")" + + local action="$(prompt-incoming "$contact")" + + case action in + accept) answer-call "$id" ;; + reject) reject-call "$id" ;; + esac +} + +checkFinished(){ + local ids="$( mmcli -m "$modem" --voice-list-calls | + grep -Eo '[0-9]+ incoming \(terminated\)' | grep -Eo '[0-9]+' )" + + local count="$(echo "$ids" | deleteEmptyLines | wc -l)" + + [ "$count" -eq 0 ] && return + + echo "$ids" | while read -r id; do + # Delete from the modem + local number="$(lookupnumberfromcallid "$id")" + local contact="$(lookupcontact "$number")" + + echo "Missed call from $contact" >> "$CALL_DIR/missed-calls" + mmcli -m "$modem" --voice-delete-call "$id" + + done +} + +checkIncoming & +checkFinished & diff --git a/bin/.bin/modem/checkSMS b/bin/.bin/modem/checkSMS index 4658804d..f64f7cba 100755 --- a/bin/.bin/modem/checkSMS +++ b/bin/.bin/modem/checkSMS @@ -1,19 +1,15 @@ #!/usr/bin/env bash +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +source "$DIR/common" + # This is largely borrowed from: # https://git.sr.ht/~mil/sxmo-utils/tree/master/item/scripts/modem/sxmo_modemmonitor.sh # This is where sms messages will be stored -SMS_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/SMS/" - -die(){ - echo "$@" > /dev/stderr - rm "$FILE" - exit 1 -} usage(){ - echo "checkSMS [options] [message|-]" + echo "checkSMS [options]" echo "Options:" echo " -h|--help Display this help text" echo " -m|--modem Specify a modem" @@ -21,57 +17,15 @@ usage(){ } -trimWhitespace(){ - sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' -} - mkdir -p "$SMS_DIR" dryrun="false" -edit="false" # Assume we want the first modem # can be overwritten by the -m option modem="$(mmcli -L | grep -oE 'Modem\/[0-9]+' | head -n 1 | cut -d'/' -f2)" -# Iterate over options breaking -ab into -a -b when needed and --foo=bar into -# --foo bar -optstring=h -unset options -while (($#)); do - case $1 in - # If option is of type -ab - -[!-]?*) - # Loop over each character starting with the second - for ((i=1; i < ${#1}; i++)); do - c=${1:i:1} - - # Add current char to options - options+=("-$c") - - # If option takes a required argument, and it's not the last char make - # the rest of the string its argument - if [[ $optstring = *"$c:"* && ${1:i+1} ]]; then - options+=("${1:i+1}") - break - fi - done - ;; - - # If option is of type --foo=bar - --?*=*) options+=("${1%%=*}" "${1#*=}") ;; - # add --endopts for -- - --) options+=(--endopts) ;; - # Otherwise, nothing special - *) options+=("$1") ;; - esac - shift -done -set -- "${options[@]}" -unset options - - # Read the options and set stuff while [[ $1 = -?* ]]; do case $1 in @@ -88,9 +42,9 @@ done ids="$( mmcli -m "$modem" --messaging-list-sms | grep -Eo '/SMS/[0-9]+ \(received\)' | grep -Eo '[0-9]+' )" -count="$(echo "$ids" | wc -l)" +count="$(echo "$ids" | deleteEmptyLines | wc -l)" -[ "$count" -eq 0 ] && return +[ "$count" -eq 0 ] && exit echo "$ids" | while read -r id; do # Get the details of the message diff --git a/bin/.bin/modem/common b/bin/.bin/modem/common new file mode 100644 index 00000000..6ce437d3 --- /dev/null +++ b/bin/.bin/modem/common @@ -0,0 +1,54 @@ +#!/usr/bin/env bash + +CALL_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/Calls/" +SMS_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/SMS/" + +die(){ + echo "$@" > /dev/stderr + rm "$FILE" + exit 1 +} + +trimWhitespace(){ + sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' +} + +deleteEmptyLines(){ + sed '/^$/ d' +} + +# Iterate over options breaking -ab into -a -b when needed and --foo=bar into +# --foo bar +optstring=h +unset options +while (($#)); do + case $1 in + # If option is of type -ab + -[!-]?*) + # Loop over each character starting with the second + for ((i=1; i < ${#1}; i++)); do + c=${1:i:1} + + # Add current char to options + options+=("-$c") + + # If option takes a required argument, and it's not the last char make + # the rest of the string its argument + if [[ $optstring = *"$c:"* && ${1:i+1} ]]; then + options+=("${1:i+1}") + break + fi + done + ;; + + # If option is of type --foo=bar + --?*=*) options+=("${1%%=*}" "${1#*=}") ;; + # add --endopts for -- + --) options+=(--endopts) ;; + # Otherwise, nothing special + *) options+=("$1") ;; + esac + shift +done +set -- "${options[@]}" +unset options diff --git a/bin/.bin/modem/dialer b/bin/.bin/modem/dialer index 6930f14b..85733ee1 100755 --- a/bin/.bin/modem/dialer +++ b/bin/.bin/modem/dialer @@ -1,4 +1,5 @@ #!/usr/bin/env bash +export DISPLAY=:0.0 prompt="" @@ -19,14 +20,14 @@ $answer 6 9 # -# " +X" while true; do - notify-send "$prompt" + #notify-send "$prompt" input="$(echo "$options" | rofi -dmenu -p "$prompt" -theme themes/dialer.rasi \ -me-select-entry '' -me-accept-entry MousePrimary)" - [ "$input" = "#" ] && exit + [ "$input" = "X" ] && exit #exit prompt+="$input" done diff --git a/bin/.bin/modem/missedCalls b/bin/.bin/modem/missedCalls new file mode 100755 index 00000000..39e105ec --- /dev/null +++ b/bin/.bin/modem/missedCalls @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + + +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" +source "$DIR/common" + +usage(){ + echo "missedCalls" + echo "-a --all Print all (default)" + echo "-c --count Print count" + echo "-l --list Print list" +} + +toprint="all" +# Read the options and set stuff +while [[ $1 = -?* ]]; do + case $1 in + -a|--all) toprint="all" ;; + -c|--count) toprint="count" ;; + -l|--list) toprint="list" ;; + -h|--help) usage; exit;; + --) shift; break ;; + *) die "invalid option: '$1'." ;; + esac + shift +done + +[ -f "$CALL_DIR/missed-calls" ] || exit + +if [ "$toprint" = "count" ] || [ "$toprint" = "all" ]; then + count="$(cat "$CALL_DIR/missed-calls" | deleteEmptyLines | wc -l )" + echo "$count missed calls" +fi + +if [ "$toprint" = "list" ] || [ "$toprint" = "all" ]; then + cat "$CALL_DIR/missed-calls" +fi + diff --git a/bin/.bin/modem/monitorModem b/bin/.bin/modem/monitorModem new file mode 100755 index 00000000..b966d256 --- /dev/null +++ b/bin/.bin/modem/monitorModem @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +# This was mostly taken from sxmo: +# https://git.sr.ht/~mil/sxmo-utils/tree/1.3.2/item/scripts/modem/sxmo_modemmonitor.sh#L181-205 +# +# Although the proccess for managing calls etc is a bit simpler IMO + +# Monitor for incoming calls +dbus-monitor --system "interface='org.freedesktop.ModemManager1.Modem.Voice',type='signal',member='CallAdded'" | \ + while read -r line; do + echo "$line" | grep -E "^signal" && checkCall + done & + +# Monitor for incoming texts +dbus-monitor --system "interface='org.freedesktop.ModemManager1.Modem.Messaging',type='signal',member='Added'" | \ + while read -r line; do + echo "$line" | grep -E "^signal" && checkSMS + done & + +# Monitor for finished calls +dbus-monitor --system "interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',arg0='org.freedesktop.ModemManager1.Call'" | \ + while read -r line; do + echo "$line" | grep -E "^signal" && checkCall + done & + +wait +wait +wait + From f9301f19595863aaa9ec1f391891ceab6ce8b513 Mon Sep 17 00:00:00 2001 From: Jonathan Hodgson Date: Sun, 21 Mar 2021 12:47:31 +0000 Subject: [PATCH 2/2] Improves power menu Power menu will now add a suspend option for non-phones. Also, it correctly calls i3lock if not on my phone --- bin/.bin/dmenu/rofi-shutdown | 36 +++++++-- rofi/.config/rofi/themes/power-phone.rasi | 91 +++++++++++++++++++++++ rofi/.config/rofi/themes/power.rasi | 2 +- 3 files changed, 121 insertions(+), 8 deletions(-) create mode 100644 rofi/.config/rofi/themes/power-phone.rasi diff --git a/bin/.bin/dmenu/rofi-shutdown b/bin/.bin/dmenu/rofi-shutdown index 40b330af..fd8b7f1a 100755 --- a/bin/.bin/dmenu/rofi-shutdown +++ b/bin/.bin/dmenu/rofi-shutdown @@ -1,6 +1,19 @@ #!/usr/bin/sh + +isPhone(){ + case "$(hostname)" in + *-phone) return 0 ;; + *) return 1 ;; + esac +} + if type -p rofi 2> /dev/null; then - alias selectcommand="rofi -dmenu -i -theme themes/power.rasi -me-select-entry '' -me-accept-entry MousePrimary" + if isPhone; then + theme="themes/power-phone.rasi" + else + theme="themes/power.rasi" + fi + alias selectcommand="rofi -dmenu -i -theme $theme -me-select-entry '' -me-accept-entry MousePrimary" shutdown="" reboot="" lock="" @@ -15,24 +28,33 @@ else logout="Logout" fi +hostname="$(hostname)" -selection=$( \ - echo -e "$shutdown\n$reboot\n$lock\n$logout\n$suspend" | selectcommand - ); -echo $selection; +if isPhone; then + selection="$(echo -e "$shutdown\n$reboot\n$lock\n$logout" | selectcommand)" +else + notify-send "Not phone" + selection="$(echo -e "$shutdown\n$reboot\n$lock\n$logout\n$suspend" | selectcommand)" +fi sleep .2 case $selection in $lock) - #i3exit lock + if isPhone; then + screenlock --suspend + else + i3exit lock + fi ;; $logout) pkill dwm ;; $suspend) systemctl suspend - #i3exit lock + if !isPhone; then + i3exit lock + fi ;; $reboot) systemctl reboot diff --git a/rofi/.config/rofi/themes/power-phone.rasi b/rofi/.config/rofi/themes/power-phone.rasi new file mode 100644 index 00000000..22ef9d78 --- /dev/null +++ b/rofi/.config/rofi/themes/power-phone.rasi @@ -0,0 +1,91 @@ +/* + * + * Author : Aditya Shakya + * Mail : adi1090x@gmail.com + * Github : @adi1090x + * Twitter : @adi1090x + * + */ + +configuration { + disable-history: false; + fullscreen: false; + hide-scrollbar: true; + sidebar-mode: false; +} + +@import "gruvbox-dark.rasi" + +* { + background-color: @background; + text-color: @foreground; +} + +window { + transparency: "real"; + border-radius: 12px; + width: 100px; + location: east; + x-offset: -15px; + y-offset: -200px; +} + +listview { + lines: 4; + margin: 8px; + spacing: 8px; + cycle: true; + dynamic: true; + layout: vertical; +} + +mainbox { + background-color: @background; + children: [ listview ]; +} + +element { + background-color: @background-light; + text-color: @foreground; + orientation: vertical; + border-radius: 12px; +} + +element-text { + font: "iosevka 45"; + expand: true; + horizontal-align: 0.5; + vertical-align: 0; + margin: 0px 10px 63px 10px; +} + +element normal.urgent, +element alternate.urgent { + background-color: @urgent; + text-color: @foreground; + border-radius: 10px; +} + +element normal.active, +element alternate.active { + background-color: @background-alt; + text-color: @foreground; +} + +element selected { + background-color: @accent; + text-color: @background; + border: 0px; + border-radius: 10px; + border-color: @border; +} + +element selected.urgent { + background-color: @urgent; + text-color: @foreground; +} + +element selected.active { + background-color: @background-alt; + color: @foreground; +} diff --git a/rofi/.config/rofi/themes/power.rasi b/rofi/.config/rofi/themes/power.rasi index 22ef9d78..a382652f 100644 --- a/rofi/.config/rofi/themes/power.rasi +++ b/rofi/.config/rofi/themes/power.rasi @@ -31,7 +31,7 @@ window { } listview { - lines: 4; + lines: 5; margin: 8px; spacing: 8px; cycle: true;