Skip to content

Instantly share code, notes, and snippets.

@shello
Created August 3, 2014 18:49
Show Gist options
  • Save shello/7e83c41274a40a478e49 to your computer and use it in GitHub Desktop.
Save shello/7e83c41274a40a478e49 to your computer and use it in GitHub Desktop.

pinboard_backup.sh

Backup your Pinboard bookmarks!

Setup

You'll need to configure the PINBOARD_API_TOKEN variable with your API token.

You may also want to change the DEFAULT_FORMAT.

Usage

./pinboard_backup.sh -h

License

Copyright (c) 2014, Filipe Rodrigues 
All rights reserved. 

Redistribution and use in source and binary forms, with or without 
modification, are permitted provided that the following conditions are 
met: 

 * Redistributions of source code must retain the above copyright 
   notice, this list of conditions and the following disclaimer. 
 * Redistributions in binary form must reproduce the above copyright 
   notice, this list of conditions and the following disclaimer in the 
   documentation and/or other materials provided with the distribution. 
 * Neither the name of shello.org nor the names of its contributors may 
   be used to endorse or promote products derived from this software 
   without specific prior written permission. 

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
#!/usr/bin/env bash
# Configure here your pinboard API token.
# Get it from: https://pinboard.in/settings/password
PINBOARD_API_TOKEN=''
# Set the default format
DEFAULT_FORMAT=json
# Templates in printf(1) format
DEFAULT_FILENAME="pinboard.%s"
PINBOARD_ENDPOINT='https://api.pinboard.in/v1/posts/all?auth_token=%s&format=%s'
# cURL
CURL_RETRIES=3
CURL_CONNECT_TIMEOUT=10
print_error() {
echo "$@" >&2
}
print_usage() {
THIS_SCRIPT=${0// /\\\ }
print_error "Usage:
${THIS_SCRIPT} -h
${THIS_SCRIPT} [-f <json|xml>] [-z] [<dir> | <filename>]
-f <json|xml> -- select the format to save the file
-z -- gzip the output file
If the optional <filename> is \"-\", outputs to stdout."
}
cleanup() {
if [[ -f $TMP_FILE ]]; then
rm $TMP_FILE
fi
}
if [[ -z $PINBOARD_API_TOKEN ]]; then
print_error "You need to setup the PINBOARD_API_TOKEN variable."
exit 1
fi
# Parse arguments
while getopts ":hf:z" opt; do
case $opt in
h)
print_usage
exit 0
;;
f)
FORMAT=$OPTARG
if [[ $FORMAT != 'xml' && $FORMAT != 'json' ]]; then
print_error "Error: Unsupported format '${FORMAT}' specified."
exit 1
fi
;;
z)
GZIP_OUTPUT=1
;;
# Missing required argument
\:)
print_error "Error: Option -${OPTARG} requires an argument"
exit 1
;;
# Invalid option
\?)
print_error "Error: Invalid option: -${OPTARG}"
print_usage
exit 1
;;
esac
done
# Discard all parsed args
shift $(($OPTIND-1))
FORMAT=${FORMAT-$DEFAULT_FORMAT}
# Set the output file; empty means default filename in the script directory
if [[ $1 = '-' ]]; then
STDOUT=1
else
printf -v DEFAULT_FILENAME_FMT $DEFAULT_FILENAME $FORMAT
OUTPUT_FILE="${1-`dirname "$0"`/$DEFAULT_FILENAME_FMT}"
if [[ -d $OUTPUT_FILE ]]; then
OUTPUT_FILE="$OUTPUT_FILE/$DEFAULT_FILENAME_FMT"
fi
fi
TMP_FILE=`mktemp -t pinboard_backup`
# Setup the URL and do the request
printf -v URL $PINBOARD_ENDPOINT ${PINBOARD_API_TOKEN} ${FORMAT}
curl --retry $CURL_RETRIES --connect-timeout $CURL_CONNECT_TIMEOUT \
--ssl-reqd -f -o $TMP_FILE \
${URL}
CURL_EXIT=$?
if [[ $CURL_EXIT -gt 0 ]]; then
print_error "Error: cURL failed with exit code ${CURL_EXIT}."
cleanup
exit 1
fi
if [[ $GZIP_OUTPUT ]]; then
gzip $TMP_FILE
TMP_FILE=${TMP_FILE}.gz
# Deal with output filename, force .gz extension
if [[ $STDOUT -ne 1 && ${OUTPUT_FILE:(-3)} != '.gz' ]]; then
OUTPUT_FILE=$OUTPUT_FILE.gz
fi
fi
# Output the file
if [[ $STDOUT -eq 1 ]]; then
cat $TMP_FILE
else
cat $TMP_FILE > $OUTPUT_FILE
fi
cleanup
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment