#!/bin/bash # # ctct - a simple console contact manager # # Copyright 2015 Einhard Leichtfuß # # ctct is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published # by the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # ctct is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with ctct. If not, see . # ## DEFAULT SETTINGS: datadir=@plain_datadir@ fallback_editor=@plain_fallback_editor@ default_editor= # none - use $EDITOR system_config_dir=@plain_confdir@ user_config_dir=@plain_user_config_dir@ ## USER SETTINGS: test -f "$system_config_dir/config.sh" \ && source "$system_config_dir/config.sh" test -f "$user_config_dir/config.sh" \ && source "$user_config_dir/config.sh" ## CONSTANTS: exec_name="${0##*/}" TRUE=0 FALSE=1 function print_help() { cat << EOF usage: $exec_name [.] | [.] - show contact $exec_name [-s] - search for contact $exec_name -e . | . - edit entry $exec_name -e . - create new entry $exec_name -l - list all entries $exec_name -h - print this help EOF } function main() { if ! test -d "$datadir" then ! mkdir "$datadir" \ && print_error "$datadir could not be created, quitting..." \ && exit 1 fi test $# -eq 0 && print_help && exit 1 if [ "$1" = "-h" ] || [[ "--help" =~ ^"$1" ]]; then print_help; exit 0 elif [ "$1" = "-l" ] || [[ "--list-all" =~ ^"$1" ]]; then list_all; exit $? elif [ "$1" = "-s" ] || \ ( [[ "--search-by-name" =~ ^"$1" ]] && [[ "$1" =~ ^"--search-by-n" ]] ) then shift; find_similar "Found:" "${@,,}"; exit $? elif [ "$1" = "-S" ] || \ ( [[ "--search-by-data" =~ ^"$1" ]] && [[ "$1" =~ ^"--search-by-d" ]] ) then shift; search_file "Found:" "${@,,}"; exit $? elif [ "$1" = "-e" ] || [[ "--edit" =~ ^"$1" ]]; then edit_file "$2"; exit $? elif [[ "$1" =~ ^- ]]; then print_error "$exec_name: unknown option $1"; exit 1 fi if ! find_exact "${1,,}" then print_msg "No match found." find_similar "Did you mean:" "${@,,}" fi } function print_msg() { printf "%s\n" "$*" } function print_error() { printf "%s\n" "$*" >&2 } function find_exact() { local ret=$FALSE for file in "$datadir"/*.* do local name=${file##*/} if test "$name" = "$1" || \ test "$name" = "$(sed 's/^\(.*\)\.\(.*\)/\2.\1/' <<< "$1")" || \ [[ "$name" =~ \.$1$ ]] || [[ "$name" =~ ^$1\. ]] then print_msg "Found $name:" cat "$file" echo ret=$TRUE fi done return $ret } # $1: initial success message; $2-${$#}: search-pattern function find_similar() { local found=false msg="$1" name bool shift 1 # skip $1 # disallow '.' in any pattern # - any pattern should be either part of the first or the last name # else the reverse order (last.first) would have to be checked as well if [[ "$*" =~ \. ]] then return $FALSE fi for file in "$datadir"/*.* do name=${file##*/} bool=true for pattern in "$@" do if ! [[ "$name" =~ "$pattern" ]] then bool=false break fi done if $bool then ! $found && print_msg "$msg" && found=true print_msg " $name" fi done $found && return $TRUE || return $FALSE } function search_file() { local found=false msg="$1" pattern_string shift 1 # skip $1 IFS=$'\n' pattern_string="$*" IFS=$' \t\n' for file in "$datadir"/*.* do if grep -qF "$pattern_string" "$file" then ! $found && print_msg "$msg" && found=true print_msg " ${file##*/}" fi done $found && return $TRUE || return $FALSE } function list_all() { ls -1 "$datadir" } function edit_file() { local file if ! [[ "$1" =~ ^[a-z]+([-_][a-z]+)*\.[a-z]+([-_][a-z]+)* ]] then print_error "usage: $exec_name --edit ." return 1 fi if test -f "$datadir/$1" then file="$datadir/$1" else file="$datadir/$(sed 's/^\(.*\)\.\(.*\)/\2.\1/' <<< "$1")" if ! test -f "$file" then file="$datadir/$1" fi fi if test -n "$default_editor" then "$default_editor" "$file" elif test -n "$EDITOR" && which "$EDITOR" >/dev/null 2>&1 then "$EDITOR" "$file" else "$fallback_editor" "$file" fi } main "$@" # vim: ts=2 sw=2