Skip to content

Instantly share code, notes, and snippets.

@Shudouken
Last active January 11, 2020 11:15
Show Gist options
  • Save Shudouken/b9a30fb7fe19f7d02608 to your computer and use it in GitHub Desktop.
Save Shudouken/b9a30fb7fe19f7d02608 to your computer and use it in GitHub Desktop.
Booru Screensaver
#!/bin/sh
verbose=false
booru=''
windowed=false
keep=false
Time=30
blacklist=('rating: explicit' 'rating: questionable')
feh_id=0
files=0
function close() {
if [[ $feh_id != 0 ]]; then
pid=$(pidof feh)
if ! [[ $pid ]]; then
exit
fi
fi
}
function usage() {
echo "Booru Screensaver Script"
echo "Fetches a random image(jpg,jpeg,png,bmp) and displays it using feh for X seconds"
echo "before fetching a new one and repeating the process until canceled"
echo "To quit the script simply close feh (press q) or CTRL+c cancel it"
echo ""
echo -e "Options (for parameters \e[94mblue\e[0m=optional, \e[31mred\e[0m=required)"
echo " Set which booru to use, by default the script will use Safebooru"
echo " -d,--danbooru use Danbooru instead"
echo " -g,--gelbooru use Gelbooru instead"
echo " -k,--konachan use Konachan instead"
echo -e " -s,--set-booru \e[31murl\e[0m try generic extraction with unsupported booru's random url"
echo ""
echo " -v,--verbose"
echo " display debug messages (blacklist, dl-links, cleanup)"
echo -e " -w,--windowed \e[94mpos\e[0m"
echo " display windowed, optionally provide feh compatible geometry position"
echo " default pos is \"700x700+0+0\""
echo -e " -K,--keep \e[94mdir\e[0m"
echo " don't delete files and keep them, optionally move them to dir"
echo " default dir is /tmp/BooruScreensaver"
echo -e " -t,--time \e[31mtime\e[0m (in whole seconds)"
echo " change the time waited before fetching a new image, default is $Time"
echo -e " -b,--blacklist \e[94mlist\e[0m"
echo " enable blacklisting, providing an optional list in the form of"
echo " \"'skirt' 'chibi' 'rating: explicit'\""
echo " default blacklist is \"'rating: explicit' 'rating: questionable'\""
exit 0
}
function setBooru() {
if [[ $booru == '' ]]; then
booru=$1
else
echo "Error: can only apply -d -g -k and -s without each other"
echo "use -h or --help for more info"
exit 1
fi
}
function setBlacklist() {
blacklist=()
for ele in $1; do
if [[ $ele == \'*\' ]]; then
blacklist+=("${ele:1:-1}")
elif [[ $ele == \'* ]]; then
temp=${ele:1}
elif [[ $ele == *\' ]]; then
blacklist+=("$temp ${ele:0:-1}")
else
echo "Error: invalid blacklist parameter \"$ele\", did you forget to 'quote'?"
echo "use -h or --help for more info"
exit 1
fi
done
}
function error() {
echo "Error: $1: $2"
echo "use -h or --help for more info"
exit 1
}
while test $# -gt 0; do
case "$1" in
-d|--danbooru)
setBooru '-d' ;;
-g|--gelbooru)
setBooru '-g' ;;
-k|--konachan)
setBooru '-k' ;;
-s|--set-booru)
setBooru '-s'
case "$2" in
""|-*) error "no valid parameter for option" "$1" ;;
*) url=$2 ;;
esac ; shift ;;
-v|--verbose)
verbose=true ;;
-w|--windowed)
windowed=true
case "$2" in
""|-*) pos='700x700+0+0' ;;
*) pos=$2 ; shift ;;
esac ;;
-K|--keep)
keep=true
case "$2" in
""|-*) mov='/tmp/BooruScreensaver/' ;;
*)
if [[ $2 == */ ]]; then
mov=$2
else
mov="$(echo $2)/"
fi
shift ;;
esac ;;
-t|--time)
case "$2" in
""|-*|*[!0-9]*) error "no valid parameter for option" "$1" ;;
*) Time=$2 ;;
esac ; shift ;;
-h|--help)
usage ;;
-b|--blacklist)
case "$2" in
""|-*) blacklist=('rating: explicit' 'rating: questionable') ;;
*) setBlacklist "$2" ; shift ;;
esac ;;
-*) error "invalid option" "$1" ;;
*) error "internal error at" "$1" ;;
esac
shift
done
if [ ! -d /tmp/BooruScreensaver ]; then
if $verbose; then
echo "Creating tmpdir - /tmp/BooruScreensaver"
fi
mkdir /tmp/BooruScreensaver
fi
if $verbose; then
if test ${#blacklist[@]} -gt 0; then
echo -n "Using blacklist: "
for ((i=0; i<${#blacklist[@]}; i++)); do
echo -n "'${blacklist[$i]}' "
done
echo ""
fi
fi
#filter according to blacklist
function filter() {
page=$(curl -s "$random")
for i in "${blacklist[@]}"
do
if [[ $(echo "$page" | grep -i "$i") ]]; then
echo "Blacklisted $i, skip $random"
echo ""
skip=1
break
fi
done
}
#get random image url and call the filter
function getRandomImage() {
skip=0
if [[ $booru == '-d' ]]; then
random=$(curl -Ls -o /dev/null -w %{url_effective} "https://danbooru.donmai.us/posts/random")
filter
link=$(echo "$page" | grep -o -P '(?<=data-file-url\=\").*?.(jpg|jpeg|png|bmp)(?=\")' | head -1)
elif [[ $booru == '-k' ]]; then
random="https://konachan.com$(curl -s https://konachan.com/post?tags=order%3Arandom | grep -i '<a class="thumb" href=' | sed -n 's/.*<a class="thumb" href="\([^"]*\)".*/\1/p')"
filter
link=$(echo "$page" | grep -i 'view larger version' | sed -n 's/.*href="\([^"]*\)".*/\1/p' | head -1)
elif [[ $booru == '-g' ]]; then
random=$(curl -Ls -o /dev/null -w %{url_effective} "https://gelbooru.com/index.php?page=post&s=random")
filter
link="https://$(echo "$page" | grep -i original | grep -o -P '(?<=https://).*.(jpg|jpeg|png|bmp)(?=\")' | head -1)"
elif [[ $booru == '-s' ]]; then
random=$(curl -Ls -o /dev/null -w %{url_effective} "$url")
filter
link="https://$(echo "$page" | grep -o -P '(?<=https://).*.(jpg|jpeg|png|bmp)(?=\")' | head -1)"
else
random=$(curl -Ls -o /dev/null -w %{url_effective} "https://safebooru.org/index.php?page=post&s=random")
filter
link="https://safebooru.org//images$(echo "$page" | grep -o -P '(?<=https://safebooru.org//images).*.(jpg|jpeg|png|bmp)(?=\")' | head -1)"
fi
}
#download image
tmpfile="/tmp/BooruScreensaver/temp"
function downloadAndDisplay() {
ext=$( echo "$link" | sed 's/.*\.//')
if [[ $ext == 'jpg' ]] || [[ $ext == 'jpeg' ]] || [[ $ext == 'png' ]] || [[ $ext == 'bmp' ]]; then
echo "url: $random"
full=$( echo "$link" | sed 's/.*\///')
file="/tmp/BooruScreensaver/$full"
if $verbose; then
echo "dl: $link"
fi
close
curl -o $file "$link"
cp $file $tmpfile
((files++))
if [[ $feh_id == 0 ]]; then
if ! $windowed; then
feh -q -Y -Z -. -F -R 1 $tmpfile 2>/dev/null & #fullscreen
else
feh -q -Y -Z -. -x -g $pos -R 1 $tmpfile 2>/dev/null & #windowed in top left corner
fi
feh_id=$!
start=`date +%s`
fi
else
echo "Not a picture($ext), skip $random"
echo ""
return
fi
if $keep; then
echo "Moving $full to $mov"
if [[ $mov != "/tmp/BooruScreensaver/" ]]; then
mv $file $mov
fi
else
if $verbose; then
echo "Removing $full"
fi
rm $file
fi
echo ""
}
function stats() {
end=`date +%s`
runtime=$((end-start))
h=$((runtime / 60 / 60))
m=$((runtime / 60 - (h * 60)))
s=$((runtime % 60))
echo "Exiting, fetched $files files in ${h}h:${m}m:${s}s"
if $verbose; then
dis=$(echo "scale=2; $runtime / $files" | bc -l)
echo "Average time between displaying files was ${dis}s as opposed to ${Time}s"
fi
}
function cleanup() {
rm $tmpfile 2>/dev/null
if test $files -gt 0; then
stats
fi
}
#main function
function main() {
getRandomImage
if [[ ! $skip == 1 ]]; then
downloadAndDisplay
fi
}
trap cleanup EXIT
while true; do
main
close
if [[ ! $skip == 1 ]]; then
for (( i=0; i<$Time; i++ )); do
sleep 1
close
done
fi
close
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment