forked from vitorgalvao/tiny-scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpinboardlinkcheck
More file actions
executable file
·165 lines (139 loc) · 4.96 KB
/
Copy pathpinboardlinkcheck
File metadata and controls
executable file
·165 lines (139 loc) · 4.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#!/bin/bash
readonly program="$(basename "${0}")"
readonly browser_headers=(--header 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36')
function syntax_error {
echo -e "${program}: ${1}\nTry \`${program} --help\` for more information." >&2
exit 1
}
# Instructions
function usage {
echo "
Usage:
${program} [options]
'token' options are compatible between pinboardbackup, pinboardlinkcheck, pinboardurlupdate, pinboardwaybackmachine
Options:
-r, --redirect-log If set, links with 301 (Moved permanently) will be on their own log.
-l, --log-dir <dir> Directory to save logs to. Defaults to the home directory.
-i, --include-unread Also check unread bookmarks.
-g, --ignore <list> Comma-separated list of lines to ignore (delete) from log.
-t, --token <token> Your Pinboard API token.
-a, --ask-for-token Ask for your Pinboard API token on start.
-s, --save-token Save Pinboard API token to Keychain and exit. Use with '--token' or '--ask-for-token' (macOS-only).
-h, --help Show this message.
" | sed -E 's/^ {4}//'
}
# Set color for verbose messages
function bad { echo "$(tput setab 1)$(tput setaf 7)${1}$(tput sgr0) ${2}" ;}
function good { echo "$(tput setab 2)$(tput setaf 7)${1}$(tput sgr0) ${2}" ;}
function warning { echo "$(tput setab 3)$(tput setaf 7)${1}$(tput sgr0) ${2}" ;}
# Set options
while [[ "${1}" ]]; do
case "${1}" in
-h | --help)
usage
exit 0
;;
-r | --redirect-log)
redirect_log='true'
;;
-l | --log-dir)
log_dir="${2}"
shift
;;
-i | --include-unread)
keep_unread='true'
;;
-g | --ignore)
ignore_list_comma="${2}"
shift
;;
-t | --token)
token="${2}"
shift
;;
-a | --ask-for-token)
ask_for_token='true'
;;
-s | --save-token)
set_keychain_token='true'
;;
-*)
syntax_error "unrecognized option: ${1}"
;;
esac
shift
done
# Location for log files
[[ -z "${log_dir}" ]] && log_dir="${HOME}"
log_file="${log_dir}/pinboardlinkcheck.log"
[[ -n "${redirect_log}" ]] && redirect_log_file="${log_dir}/pinboardlinkcheck-redirects.log"
# Ask for api token, if option is set
if [[ -n "${ask_for_token}" ]]; then
echo 'Please insert your api token (will not be echoed)'
echo 'You can get it at https://pinboard.in/settings/password'
read -rsp '> ' token
echo
fi
# If no token given, look for it in the Keychain
[[ -z "${token}" ]] && token="$(security find-generic-password -s 'Pinboard API Token' -w)"
# Exit if no token was set
if [[ -z "${token}" ]]; then
echo 'Cannot continue without a Pinboard token.'
usage
exit 1
fi
# Check if token is correct
if ! curl --fail --silent "https://api.pinboard.in/v1/user/api_token/?auth_token=${token}" > /dev/null; then
echo "The Pinboard API token appears to be incorrect. Alternatively, Pinboard’s servers might be down." >&2
exit 1
fi
# Save token to Keychain
if [[ -n "${set_keychain_token}" ]]; then
security add-generic-password -a "${token%:*}" -s 'Pinboard API Token' -w "${token}"
exit 0
fi
# Get all your pinboard links
if [[ "${keep_unread}" ]]; then
links="$(curl --silent "https://api.pinboard.in/v1/posts/all?auth_token=${token}" | grep '^<post' | cut -d '"' -f 2 | sed '1d')"
else
links="$(curl --silent "https://api.pinboard.in/v1/posts/all?auth_token=${token}" | grep '^<post' | grep --invert-match 'toread="yes"' | cut -d '"' -f 2 | sed '1d')"
fi
link_countdown="$(wc -l <<< "${links}" | tr -d ' ')"
# Check each link individually
for page in ${links} ; do
echo -n "[${link_countdown}] "
((link_countdown--))
status="$(curl --silent "${browser_headers[@]}" --write-out '%{http_code}' --output /dev/null "${page}")"
if [[ "${status:0:1}" == '2' ]]; then
good "${status}" "${page}"
elif [[ "${status:0:1}" == '3' ]]; then
warning "${status}" "${page}"
else
bad "${status}" "${page}"
fi
# Append to log file
echo "${status} ${page}" >> "${log_file}"
done
# Cleanup
# Remove every link with a '200' code from the log
sed -i '' '/^200/d' "${log_file}"
# Order links by status code
ordered_links=$(sort "${log_file}")
echo "${ordered_links}" > "${log_file}"
# Move 301 links to redirect log, if specified
if [[ -n "${redirect_log}" ]]; then
redirectlinks="$(grep '^301' "${log_file}" | sed 's/^301 //')"
for page in ${redirectlinks}; do
redirect_url="$(curl --silent "${browser_headers[@]}" --write-out '%{redirect_url}' --output /dev/null "${page}")"
echo "${page} → ${redirect_url}" | tee -a "${redirect_log_file}"
done
# Remove 301s from the main log
sed -i '' '/^301/d' "${log_file}"
fi
# Remove ignored lines, if specified
if [[ -n "${ignore_list_comma}" ]]; then
IFS=, read -r -a ignore_list_array <<< "${ignore_list_comma}"
for element in "${ignore_list_array[@]}"; do
sed -i '' "\|${element}|d" "${log_file}"
done
fi