Created
December 9, 2016 01:42
-
-
Save knowsuchagency/1b52319e4501ed54965c952ed754a894 to your computer and use it in GitHub Desktop.
vcard example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# vcard generation utility | |
# first argument is the file to be written to. It will be appended to with each new write. | |
# ex: $./vcard card | |
printWrite() { | |
# Take printf formatted string, append newline, and write to stdout and stderr | |
printf "$1\n" | tee /dev/fd/2 | |
} | |
fix() { | |
# precede each instance in $1 of , and ; with \ | |
# and output the result | |
echo "$1" | sed 's/\([\,;]\)/\\\1/g' | |
} | |
error () { | |
# error: output an error message and return | |
# the error messages contain the program name | |
# and are written to standard error | |
local prog=$(basename $0) | |
echo -e "$prog:ERROR: $*">&2 | |
} | |
fatal() { | |
# fatal: output an error message and then exit | |
# the error() function is used. | |
local prog=$(basename $0) | |
error $* | |
# if you want to output a message about how to successfully | |
# run your program (called a 'usage message'), this would | |
# be the place to do it | |
echo -e "$prog: USAGE: $prog vcardfile" >&2 | |
# now exit with an error | |
exit 1 | |
} | |
header() { | |
# write header | |
printWrite "BEGIN:VCARD\nVERSION:3.0" | |
} | |
footer() { | |
# write footer | |
echo "END:VCARD" | tee /dev/fd/2 | |
} | |
name() { | |
# get user name | |
local prefix firstName middleName lastName | |
printf "Enter your name\n\n">&2 | |
read -p "Enter prefix (empty to skip)" prefix | |
if [[ $prefix > 0 && ! $prefix =~ ^(Mr|Ms|Mrs|Dr)\.$ ]]; then | |
error "Prefix must be one of the following: Mr. Ms. Mrs. Dr." | |
return 1 | |
fi | |
read -p "Enter first name (empty to skip)" firstName | |
read -p "Enter middle name (empty to skip)" middleName | |
read -p "Enter last name (empty to skip)" lastName | |
# convert middle name to array so we can capitalize all letters in output | |
middleName=($middleName) | |
printWrite "FN:${prefix^} ${firstName^} ${middleName[*]^} ${lastName^}" | |
printWrite "N:${lastName^};${middleName[*]^};${firstName^};${prefix^};" | |
} | |
org() { | |
# here's an example function for organization | |
# it's a simple one and seems to work well | |
local co dept | |
read -p "Company name (empty to skip):" co | |
[ -z "$co" ] && return 0 | |
read -p "Department name (empty to skip):" dept | |
printWrite "ORG:$co;$dept" | |
} | |
# I'm giving you the bday function. It is one of the hardest. | |
isint() { | |
if ! [[ "$1" =~ ^[[:digit:]]+$ ]] ;then | |
echo "'$1' is not an integer" >&2 | |
return 1 | |
fi | |
} | |
# the bday function seems to work okay | |
# but there is a SMALL bug. Can you find it? (hint: the month) | |
bday() { | |
local year day month curyear | |
echo "Enter birthday:" >&2 | |
read -p "Enter 4-digit year (empty to skip birthday):" year | |
[ -z "$year" ] && return 0 | |
# year must be integer. | |
isint "$year" || return 1 | |
# dont allow year to be in the future or more than 120 years ago. | |
curyear=$(date "+%Y") | |
if ((curyear - year > 120)); then | |
echo "sorry. you're too old to be alive!" >&2 | |
return 1 | |
fi | |
if ((curyear < year)); then | |
echo "you haven't been born yet?" >&2 | |
return 1 | |
fi | |
read -p "Enter a month number (1-12)" month | |
isint "$month" || return 1 | |
if [ "$month" -le 0 -o "$month" -gt 12 ]; then | |
echo "month must be in [1,12]" >&2 | |
return 1 | |
fi | |
read -p "Enter a day number (1-31)" day | |
isint "$day" || return 1 | |
if [ "$day" -le 0 -o "$day" -gt 31 ]; then | |
echo "day must be in [1,31]" >&2 | |
return 1 | |
fi | |
[ "$day" -lt 10 ] && day=0${day} | |
[ "$month" -lt 10 ] && month=0${month} | |
printWrite "BDAY:$year-$month-$day" | |
} | |
# you'll need functions for name, telephone, email, and note to finish | |
vcard1() { | |
header | |
name || return 1 | |
org || return 1 | |
# insert functions for telephone and email here | |
bday || return 1 | |
# insert call to note function here | |
footer | |
} | |
# check to see that there is a file argument | |
vcfile=${1:?"$0 requires a filename argument"} | |
# if the file exists, make sure the user has write permissions | |
if [ -a $vcfile ] ; then | |
[ -w $vcfile ] || fatal "The file exists, but you do no have write permissions" | |
else | |
# if creating a new file, check to see if we have write permissions for the directory | |
dir=$(dirname $vcfile) | |
[ -w $dir ] || fatal "You do not have write permissions for $dir" | |
fi | |
# create a temp file for the current vcf | |
thisvcf=$(mktemp) | |
# this redirects all further stdout to the temp file | |
# MAKE SURE from this point on, that all prompts and error messages to to stderr | |
exec > "$thisvcf" | |
# call the function to create a single vcard. If it succeeds, | |
# append the current vcard to the file. otherwise give an error message | |
vcard1 && cat "$thisvcf" >> "$vcfile" || error "bad vcard entry!" | |
# clean up tempfile | |
rm -f "$thisvcf" | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment