Last active
September 7, 2020 03:41
-
-
Save genedelisa/8bb67f2ece03a1bd73bfea4904b0b3fe to your computer and use it in GitHub Desktop.
zsh script to grab cat images from Reddit. One random, All from a subreddit, optionally download them, and optionally view them via QuickLook.
This file contains hidden or 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 zsh | |
# -*- mode: shell-script -*- | |
# | |
# Time-stamp: "Last Modified 2020-05-22 14:43:23 by Gene De Lisa, genedelisa" | |
# | |
# File: ~/dotfiles/.zsh/scripts/ | |
# Gene De Lisa | |
# [email protected] | |
# http://rockhoppertech.com/blog/ | |
# grab a random images from a cat sub and view it via quicklook preview | |
# catimgreddit --quicklook | |
# | |
# grab a random images from specified sub and view it via quicklook preview | |
#catimgreddit --quicklook -s aww | |
# | |
# to view the image right in iterm2, use --imgcat instead of --quicklook | |
# download images into the current directory | |
# catimgreddit --downloadall --keep -s aww | |
# | |
# see | |
# https://www.reddit.com/dev/api/ | |
# http://github.com/reddit/reddit/wiki/API | |
# command line check | |
# curl -s -H ${USER_AGENT} "https://www.reddit.com/r/Cats/new.json?sort=new&t=day&limit=2" | jq '.' | |
################################################################################ | |
[[ $(uname) != "Darwin" ]] && print "$0 must be run on macOS" && return -1 | |
(( ! $+commands[curl] )) && {print "You need curl to be installed. Try using brew."; exit 1;} | |
# -R reset zsh options | |
# -L options LOCAL_OPTIONS, LOCAL_PATTERNS and LOCAL_TRAPS will be set | |
emulate -LR zsh | |
function message { | |
# if non zero | |
#[[ -n ${is_verbose} ]] && print Using $sr | |
#(( ${+is_verbose} )) && print is verbose test | |
if [[ ${is_verbose} == "true" ]]; then | |
print -P "%B%F{green}${@}%f%b" | |
fi | |
} | |
function errormessage { | |
if [[ ${is_verbose} == "true" ]]; then | |
print -P "%B%F{red}Error:%f%b ${@}" 1>&2 | |
fi | |
} | |
typeset -gx REDDIT_IMG_DOWNLOAD_DIR | |
#REDDIT_IMG_DOWNLOAD_DIR=${REDDIT_IMG_DOWNLOAD_DIR:-$HOME/Pictures/cats} | |
REDDIT_IMG_DOWNLOAD_DIR=${REDDIT_IMG_DOWNLOAD_DIR:-$PWD} | |
allcats=($(cat ${ZSH_SCRIPT:h}/cat-subreddits)) | |
ignoresubreddits=( | |
CatGifs | |
KittenGifs | |
CatReactionGifs | |
CatSpotting | |
Meow_Irl | |
Kitties | |
#CatReddit | |
#CatVideos | |
) | |
subreddits=( | |
Cats | |
CatPics | |
Kitten | |
Kittens | |
LookAtMyCat | |
Cat | |
Kitty | |
CatPictures | |
MaineCoon | |
MaineCoons | |
SupermodelCats | |
) | |
# use_imgcat= | |
# use_quicklook=true | |
# is_verbose= | |
typeset -a filters | |
filters=(top | |
best | |
hot | |
new | |
random | |
rising) | |
filter=top | |
sort=top | |
sorttimeslice=week | |
imgurl= | |
typeset -a imageurls | |
function grab { | |
if [[ ${sr} == "random" ]]; then | |
sr=${subreddits[$(( $RANDOM % ${#subreddits[@]} + 1 ))]} | |
message "Using random subreddit $sr" | |
else | |
message "Using specified subreddit $sr" | |
fi | |
requesturl="https://www.reddit.com/r/${sr}/${filter}.json?sort=${sort}&t=${sorttimeslice}&limit=${limit}" | |
message ${requesturl} | |
USER_AGENT="User-Agent: cli:zsh:v0.1.0 (by /u/yomama)" | |
json=$(curl -s -H ${USER_AGENT} --connect-timeout 5 -A '/u/yomama' ${requesturl}) | |
# json=$(echo -n "$json" | tr -d '[:cntrl:]' | jq '(.)' ) | |
#message "$json" | |
# extract the urls | |
typeset -a urls | |
for u in $(printf "%s" $json | jq -r '.data.children[] | .data.url'); do | |
urls+=$u | |
done | |
# get the image urls | |
for url in ${urls}; do | |
# print ${url} | |
# print ${url:e} | |
# bmp? tiff? webp? raw? | |
if [[ $url =~ .*\.(jpg|jpeg|png|gif)$ ]]; then | |
imageurls+=${url} | |
message "image url \'${url}\'" | |
fi | |
done | |
if [[ ${#imageurls[@]} == 0 ]]; then | |
errormessage no images in subreddit $sr | |
exit 1 | |
fi | |
if [[ ${downloadall} == "true" ]]; then | |
message download all | |
print ${#imageurls} | |
for imgurl in ${imageurls}; do | |
message downloading $imgurl to ${REDDIT_IMG_DOWNLOAD_DIR} | |
curl -sO ${imgurl} | |
[[ $? -ne 0 ]] && {errormessage "curl barfed while downloading ${imgurl}"; exit 1} | |
[[ ${REDDIT_IMG_DOWNLOAD_DIR} != ${PWD} ]] && {mv ${imgurl:t} ${REDDIT_IMG_DOWNLOAD_DIR};} | |
done | |
exit 0 | |
else | |
imgurl=${imageurls[$(( $RANDOM % ${#imageurls[@]} + 1 ))]} | |
message "random image url: ${imgurl}" | |
message "downloading \'${imgurl}\'" | |
curl -sO ${imgurl} | |
[[ $? -ne 0 ]] && {errormessage "curl barfed while downloading ${imgurl}"; exit 1} | |
fi | |
show | |
} | |
#imgurl=$(echo -n $imgurl | sed 's/[[:cntrl:]]*//g;s/\\n//g') | |
function show { | |
# [[ ${use_imgcat} ]] && print usimg imgcat ${use_imgcat} | |
# [[ ${use_quicklook} ]] && print using quicklook ${use_quicklook} | |
sleep 1 | |
if [[ ${use_quicklook} == "true" ]]; then | |
# qlmanage is chatty. stfu. | |
message "ql showing ${imgurl:t}" | |
qlmanage -p ${imgurl:t} >/dev/null 2>&1 | |
fi | |
if [[ ${use_imgcat} == "true" ]]; then | |
~/.iterm2/imgcat ${imgurl:t} | |
fi | |
} | |
################################################################################ | |
# If a command has a non-zero exit status, execute the ZERR trap, if set, and exit | |
# setopt err_return | |
# setopt err_exit | |
# setopt localtraps | |
# trapzerr() { | |
# print "" | |
# print "trapped zerr" >&2 | |
# } | |
trap_abort() { | |
if [[ ${downloadall} == "true" ]]; then | |
exit 0 | |
fi | |
local file=${imgurl:t} | |
if [[ -n ${keep_downloaded} ]]; then | |
message keeping downloaded files | |
message ${file} | |
return | |
fi | |
if [[ -e $file ]]; then | |
message "moving ${file} to trash" | |
mv ${file} ~/.Trash | |
fi | |
} | |
trap 'trap_abort' ABRT HUP INT QUIT TERM EXIT | |
################################################################################ | |
function usage { | |
cat <<EOF | |
Usage: ${ZSH_SCRIPT:t} [arguments] | |
Arguments: | |
-h or --help Print the usage information | |
-d or --debug Debug. Turns on xtrace | |
-v or --verbose Verbose | |
-q or --quicklook Use quicklook preview | |
-i or --imgcat Use iterm imgcat | |
-k or --keep Do not delete downloaded files | |
-z or --downloadall Download all | |
-s or --subreddit Use specific subreddit (e.g. a non cat one. But why?) | |
-l num or --limit num limit the number of responses | |
If you specify --keep, the images will be stored in REDDIT_IMG_DOWNLOAD_DIR (pwd by default) | |
EOF | |
exit 0 | |
} | |
[[ $# -lt 1 ]] && {usage} | |
################################################################################ | |
function exitIfNotMacos { | |
[[ $(uname) != "Darwin" ]] && {print "${ZSH_SCRIPT:t} must be run on macOS" && return -1} | |
return 0 | |
} | |
################################################################################ | |
function parse { | |
# -R reset zsh options | |
# -L options LOCAL_OPTIONS, LOCAL_PATTERNS and LOCAL_TRAPS will be set | |
emulate -LR zsh | |
setopt localoptions | |
# define arrays to hold the options | |
local -a help verbose debug limitopt ql imgcat subredditopt downloadopt keepopt getnew | |
if zparseopts -D -E -- \ | |
d=debug -debug=debug \ | |
v=verbose -verbose=verbose \ | |
z=downloadopt -downloadall=downloadopt \ | |
q=ql -quicklook=ql \ | |
i=imgcat -imgcat=imgcat \ | |
h=help -help=help \ | |
n=getnew -new=getnew \ | |
k=keepopt -keep=keepopt \ | |
l:=limitopt -limit:=limitopt \ | |
s:=subredditopt -subreddit:=subredditopt | |
then | |
[[ -n ${help} ]] && usage; | |
[[ -n ${verbose} ]] && {is_verbose=true;} | |
[[ -n ${debug} ]] && setopt xtrace | |
[[ -n ${imgcat} ]] && {use_imgcat=true;} | |
[[ -n ${ql} ]] && {use_quicklook=true;} | |
[[ -n ${downloadopt} ]] && {downloadall=true;} | |
[[ -n ${keepopt} ]] && {keep_downloaded=true;} | |
[[ -n ${getnew} ]] && { | |
filter=new | |
sort=new | |
sorttimeslice=day | |
} | |
if [[ ${#limitopt} -ge 2 ]]; then | |
limit=${limitopt[2]} | |
else | |
limit=100 | |
fi | |
message Using a limit of ${limit} | |
if [[ ${#subredditopt} -ge 2 ]]; then | |
sr=${subredditopt[2]} | |
else | |
sr=random | |
fi | |
message Using subreddit ${sr} | |
# be strict | |
# [[ ${#limitopt} -lt 2 ]] && | |
# {print "Missing required option: --limit num"; return 1} | |
else | |
rs=$? | |
errormessage "zparseopts wasn't happy!" $? >&2 | |
return 1 | |
fi # zparseopts | |
# the -D flag removed the options | |
# print the rest of the command line: "$@" | |
# save them for other functions | |
nonflag_args="$@" | |
#[[ -n ${list} ]] && list ${nonflag_args} | |
return 0 | |
} | |
################################################################################ | |
# "$*" always expands to something, even without arguments | |
parse "$@" | |
grab | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment