263 lines
9.0 KiB
Bash
Executable File
263 lines
9.0 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Enhanced Himalaya Email Management Script
|
|
# Features: Auto-discovery, smart navigation, streamlined UX
|
|
|
|
# Function to get available message IDs from himalaya
|
|
get_available_message_ids() {
|
|
himalaya envelope list | awk 'NR > 2 && /^\| [0-9]/ {gsub(/[| ]/, "", $2); if($2 ~ /^[0-9]+$/) print $2}' | sort -n
|
|
}
|
|
|
|
# Function to get the latest (most recent) message ID
|
|
get_latest_message_id() {
|
|
get_available_message_ids | tail -1
|
|
}
|
|
|
|
# Function to find the next valid message ID
|
|
find_next_message_id() {
|
|
local current_id="$1"
|
|
get_available_message_ids | awk -v current="$current_id" '$1 > current {print $1; exit}'
|
|
}
|
|
|
|
# Function to find the previous valid message ID
|
|
find_previous_message_id() {
|
|
local current_id="$1"
|
|
get_available_message_ids | awk -v current="$current_id" '$1 < current {prev=$1} END {if(prev) print prev}'
|
|
}
|
|
|
|
# Function to refresh the vim-himalaya buffer
|
|
refresh_vim_himalaya() {
|
|
if [ -S "/tmp/nvim-server" ]; then
|
|
nvim --server /tmp/nvim-server --remote-send "Himalaya<CR>" 2>/dev/null
|
|
fi
|
|
}
|
|
|
|
# Function to read a single character without waiting for Enter
|
|
read_char() {
|
|
stty -echo -icanon time 0 min 1
|
|
char=$(dd bs=1 count=1 2>/dev/null)
|
|
stty echo icanon
|
|
echo "$char"
|
|
}
|
|
|
|
# Function to safely run the himalaya command and handle failures
|
|
run_himalaya_message_read() {
|
|
local message_id="$1"
|
|
local temp_output
|
|
temp_output=$(himalaya message read "$message_id" 2>&1)
|
|
local exit_code=$?
|
|
|
|
if [ $exit_code -eq 0 ]; then
|
|
# Choose email processor based on availability
|
|
local email_processor
|
|
if [ -f "email_processor.awk" ]; then
|
|
email_processor="awk -f email_processor.awk"
|
|
elif command -v python3 >/dev/null 2>&1 && [ -f "email_processor.py" ]; then
|
|
email_processor="python3 email_processor.py"
|
|
else
|
|
email_processor="cat" # fallback to no processing
|
|
fi
|
|
|
|
# Process email content, then render with glow and display with less
|
|
echo "$temp_output" | \
|
|
$email_processor | \
|
|
# bat
|
|
glow --width 100 -p
|
|
# less -R -X -F
|
|
return 0
|
|
else
|
|
echo "Failed to open message $message_id."
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Function to create a task for the current message
|
|
create_task_for_message() {
|
|
local message_id="$1"
|
|
read -p "Task title: " task_title
|
|
if [ -n "$task_title" ]; then
|
|
if command -v task >/dev/null 2>&1; then
|
|
task add "Followup on email $message_id - $task_title" \
|
|
--project "Email" \
|
|
--due "$(date -d '+1 week' +%Y-%m-%d)" \
|
|
--priority "P3" \
|
|
--tags "email"
|
|
echo "Task created for message $message_id."
|
|
else
|
|
echo "TaskWarrior not found. Task not created."
|
|
fi
|
|
else
|
|
echo "No task title provided. Task not created."
|
|
fi
|
|
}
|
|
|
|
# Function to display the action menu and handle user choice
|
|
show_action_menu() {
|
|
local current_id="$1"
|
|
|
|
# Draw a nice border above the menu
|
|
echo ""
|
|
echo "════════════════════════════════════════════════════════════════════════════════"
|
|
echo " ACTIONS"
|
|
echo "════════════════════════════════════════════════════════════════════════════════"
|
|
echo ""
|
|
echo " t) Create task for this message"
|
|
echo " d) Delete message"
|
|
echo " a) Archive message"
|
|
echo " n) Next message"
|
|
echo " p) Previous message"
|
|
echo " r) Reopen/redisplay current message"
|
|
echo " q) Quit"
|
|
echo ""
|
|
echo "────────────────────────────────────────────────────────────────────────────────"
|
|
echo -n "Enter choice: "
|
|
|
|
local choice=$(read_char)
|
|
echo "$choice" # Echo for feedback
|
|
|
|
# Clear screen after choice is made
|
|
clear
|
|
|
|
case "$choice" in
|
|
t|T)
|
|
create_task_for_message "$current_id"
|
|
echo "Press any key to continue..."
|
|
read_char > /dev/null
|
|
process_message "$current_id"
|
|
;;
|
|
d|D)
|
|
echo "Deleting message $current_id..."
|
|
if himalaya message delete "$current_id"; then
|
|
echo "Message $current_id deleted successfully."
|
|
refresh_vim_himalaya
|
|
# Try to open next available message
|
|
local next_id=$(find_next_message_id "$current_id")
|
|
if [ -n "$next_id" ]; then
|
|
echo "Opening next message: $next_id"
|
|
process_message "$next_id"
|
|
else
|
|
echo "No more messages. Exiting."
|
|
exit 0
|
|
fi
|
|
else
|
|
echo "Failed to delete message $current_id."
|
|
echo "Press any key to continue..."
|
|
read_char > /dev/null
|
|
process_message "$current_id"
|
|
fi
|
|
;;
|
|
a|A)
|
|
echo "Archiving message $current_id..."
|
|
if himalaya message move Archives "$current_id"; then
|
|
echo "Message $current_id archived successfully."
|
|
refresh_vim_himalaya
|
|
# Try to open next available message
|
|
local next_id=$(find_next_message_id "$current_id")
|
|
if [ -n "$next_id" ]; then
|
|
echo "Opening next message: $next_id"
|
|
process_message "$next_id"
|
|
else
|
|
echo "No more messages. Exiting."
|
|
exit 0
|
|
fi
|
|
else
|
|
echo "Failed to archive message $current_id."
|
|
echo "Press any key to continue..."
|
|
read_char > /dev/null
|
|
process_message "$current_id"
|
|
fi
|
|
;;
|
|
n|N)
|
|
local next_id=$(find_next_message_id "$current_id")
|
|
if [ -n "$next_id" ]; then
|
|
echo "Opening next message: $next_id"
|
|
process_message "$next_id"
|
|
else
|
|
echo "No next message available."
|
|
echo "Press any key to continue..."
|
|
read_char > /dev/null
|
|
process_message "$current_id"
|
|
fi
|
|
;;
|
|
p|P)
|
|
local prev_id=$(find_previous_message_id "$current_id")
|
|
if [ -n "$prev_id" ]; then
|
|
echo "Opening previous message: $prev_id"
|
|
process_message "$prev_id"
|
|
else
|
|
echo "No previous message available."
|
|
echo "Press any key to continue..."
|
|
read_char > /dev/null
|
|
process_message "$current_id"
|
|
fi
|
|
;;
|
|
r|R)
|
|
echo "Reopening message $current_id..."
|
|
process_message "$current_id"
|
|
;;
|
|
q|Q)
|
|
echo "Exiting."
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "Invalid choice. Please try again."
|
|
echo "Press any key to continue..."
|
|
read_char > /dev/null
|
|
process_message "$current_id"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Function to process a message (read and show menu)
|
|
process_message() {
|
|
local message_id="$1"
|
|
local is_fallback="$2"
|
|
|
|
echo "Reading message $message_id..."
|
|
if run_himalaya_message_read "$message_id"; then
|
|
show_action_menu "$message_id"
|
|
else
|
|
echo "Error reading message $message_id."
|
|
if [ "$is_fallback" = "true" ]; then
|
|
# If this was already a fallback attempt, don't try again
|
|
echo "Unable to read any messages. Exiting."
|
|
exit 1
|
|
else
|
|
# Try to find a valid message to fall back to
|
|
echo "Trying to find an available message..."
|
|
local latest_id=$(get_latest_message_id)
|
|
if [ -n "$latest_id" ] && [ "$latest_id" != "$message_id" ]; then
|
|
echo "Opening latest message: $latest_id"
|
|
process_message "$latest_id" "true"
|
|
else
|
|
echo "No valid messages found. Exiting."
|
|
exit 1
|
|
fi
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Main script logic
|
|
|
|
# Check if message ID is provided, otherwise get the latest
|
|
if [ -z "$1" ]; then
|
|
echo "No message ID provided. Finding latest message..."
|
|
message_id=$(get_latest_message_id)
|
|
if [ -z "$message_id" ]; then
|
|
echo "No messages found in inbox."
|
|
exit 1
|
|
fi
|
|
echo "Latest message ID: $message_id"
|
|
else
|
|
message_id="$1"
|
|
fi
|
|
|
|
# Validate that himalaya is available
|
|
if ! command -v himalaya >/dev/null 2>&1; then
|
|
echo "Error: himalaya command not found. Please install himalaya."
|
|
exit 1
|
|
fi
|
|
|
|
# Start processing the message
|
|
process_message "$message_id"
|