Skip to content

Instantly share code, notes, and snippets.

@knowsuchagency
Created December 9, 2016 01:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save knowsuchagency/1b52319e4501ed54965c952ed754a894 to your computer and use it in GitHub Desktop.
Save knowsuchagency/1b52319e4501ed54965c952ed754a894 to your computer and use it in GitHub Desktop.
vcard example
#!/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