Last active
June 3, 2022 21:24
-
-
Save morganestes/242cb28d73fcff094e64e93f106906d2 to your computer and use it in GitHub Desktop.
Download files uploaded to a Slack instance using data from a Slack JSON export file.
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
#!/bin/bash | |
# | |
# Parses Slack JSON exports for files and downloads them. | |
# | |
# Requires 'jq' (https://stedolan.github.io/jq/) and 'httpie' (https://httpie.org/). | |
# | |
## | |
# Checks for a single dependency. | |
# | |
# @param string DEP The function name to check. | |
## | |
function check_dep() { | |
local DEP="${1}" | |
local HAS_DEP | |
[ -z "${DEP}" ] && printf "No function name given to check.\n" && exit 0 | |
printf "Checking for %s...\n" "${DEP}" | |
HAS_DEP="$( | |
type "${DEP}" >/dev/null 2>&1 | |
echo $? | |
)" | |
if [ "${HAS_DEP}" -eq 1 ]; then | |
printf "%s not found.\n" "${DEP}" | |
exit 1 | |
else | |
printf "%s found. Continuing...\n" "${DEP}" | |
fi | |
echo '----------------' | |
printf '\n' | |
} | |
## | |
# Checks the dependencies used for the script. | |
## | |
function check_deps() { | |
declare -A deps | |
deps["jq"]="https://stedolan.github.io/jq/" | |
deps["http"]="https://httpie.org/" | |
for dep in "${!deps[@]}"; do | |
check_dep "${dep}" | |
if [ "$?" -eq 1 ]; then | |
printf "%s missing. Download from %s and install before continuing.\n" "${dep}" "${deps[$dep]}" | |
fi | |
done | |
} | |
## | |
# Parses the Slack export JSON for uploaded files and downloads them to the current directory. | |
# | |
# @param string source_file Path to the Slack export JSON file. | |
## | |
function main() { | |
local source_file="${1}" | |
local link_count=0 | |
declare links=() | |
local output_path # @todo Make this a parameter and configure it for httpie's --continue flag. | |
local session_file | |
local file_hash | |
check_deps | |
if [[ ! -f "${source_file}" ]]; then | |
printf "%s not found.\nPlease check the filename and try again.\n" "${source_file}" | |
exit 0 | |
else | |
printf "Parsing %s for files to download...\n" "${source_file}" | |
fi | |
# Parse the JSON using jq, combining them into a list of URLs for uploaded files. | |
while read -r url; do | |
links+=("${url}") | |
done < <( | |
jq -rc '.[]?.subtype="file_share" | | |
[.[]?.files[]?.url_private_download] | | |
unique | | |
.[]' \ | |
"${source_file}" | |
) | |
link_count="${#links[@]}" | |
if [[ "${link_count}" -gt 0 ]]; then | |
output_path="$(pwd)" # @todo make this a variable parameter. | |
file_hash="$(md5 -q "${source_file}")" | |
session_file="${output_path}/httpie-session-${file_hash}.json" | |
# this doesn't do anything yet, since we're alreay starting in an existing directory | |
mkdir -p "${output_path}" | |
printf "Downloading %d files to %s\nusing httpie session from %s\n" "$link_count" "${output_path}" "${session_file}" | |
echo '----------------' | |
printf '\n' | |
for link in "${links[@]}"; do | |
printf "\nTrying %s\n" "${link}" | |
if http --check-status --ignore-stdin --timeout=2.5 HEAD "${link}" &>/dev/null; then | |
http --session "${session_file}" --ignore-stdin -xbd "${link}" | |
else | |
case $? in | |
2) printf 'Request timed out!\n\n' ;; | |
3) printf 'Unexpected HTTP 3xx Redirection!\n\n' ;; | |
4) printf 'HTTP 4xx Client Error!\n\n' ;; | |
5) printf 'HTTP 5xx Server Error!\n\n' ;; | |
6) printf 'Exceeded --max-redirects=<n> redirects!\n\n' ;; | |
*) printf 'Other Error!\n\n' ;; | |
esac | |
fi | |
done | |
else | |
printf 'Nothing found to download.\n\n' | |
fi | |
} | |
main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment