Last active
January 11, 2020 11:15
-
-
Save Shudouken/b9a30fb7fe19f7d02608 to your computer and use it in GitHub Desktop.
Booru Screensaver
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/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