add files

This commit is contained in:
Björn Busse 2016-07-28 19:51:48 +02:00 committed by Björn Busse
parent cb876e3864
commit 05b375a14a
3 changed files with 312 additions and 0 deletions

27
LICENSE Normal file
View File

@ -0,0 +1,27 @@
Copyright © 2016, Björn Busse and contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Björn Busse nor the
names of contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY Björn Busse ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Björn Busse BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

BIN
not_really_into_pokemon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

285
xkcdlock Executable file
View File

@ -0,0 +1,285 @@
#!/usr/bin/env rbash
# xkcd_lock v1
#
# A wrapper around i3lock to display xkcd images on the lock screen
#
# Note that 'latest' needs an internet connection for the download!
# If the download fails it falls back to a specific hard-coded image
#
# Builtin is a function to download all images.
#
# Dependencies: rbash, i3lock, xrandr, awk, curl
#
# © 2016 Björn Busse (see also: LICENSE)
# bbusse@baerlin.eu
#
# Thanks to Randall Patrick Munroe! BTC 1FhCLQK2ZXtCUQDtG98p6fVH7S6mxAsEey
# Thanks to Michael Stapelberg for an awesome window manager - i3
#
# TODO:
# - make sure we do not exceed screen boundaries in x and y
# - add tooltip overlay and xkcd number
# - parallelize downloads
[[ "$TRACE" ]] && set -x
set -eo pipefail
readonly SCRIPT_NAME=$(basename $0)
# screensaver executable
LOCK_BIN="i3lock"
# verbosity
VERBOSE=0
# "latest" or "random"
IMG_CHOICE="random"
# path to images
IMG_PATH="${HOME}/Pictures/xkcd_comics"
# default / fallback image
IMG_DEFAULT="not_really_into_pokemon.png"
# background colour
BG_COLOUR="white"
DOWNLOAD_DISCLAIMER="\nThe downloaded images will end up in your current working directory.\n\
Since we are using restricted bash, we can not change path.\n\
Use '-y' instead of '-d' to really start the download to the current working directory.\n"
log() {
if (( 1=="${VERBOSE}" )); then
echo "$@" >&2
fi
logger -p user.notice -t $SCRIPT_NAME "$@"
}
error() {
echo "$@" >&2
logger -p user.error -t $SCRIPT_NAME "$@"
}
# does not work with restricted bash (bash -r/rbash)
get_script_path() {
echo $(dirname $(readlink -f $0))
}
show_help() {
printf "\n xkcd_lock v1\n\n\
Available options are:\n\n \
-d download images to current working directory\n \
-h show this help\n \
-i show specific image file - overrides '-m'\n \
-l lock program: one of i3lock/swaylock\n \
-m latest|random default: random\n \
-v be verbose\n\n"
}
xkcd_get_latest_image() {
if [[ -z $(which curl) ]]; then
error "Could not find curl to get latest image"
exit 1
fi
log "Looking for latest image"
local img_url=$(curl -s http://xkcd.com/index.html | \
awk '/Image URL \(for hotlinking\/embedding\): / {print $5}' | \
awk 'BEGIN{FS="<";} {print $1}')
if [[ -z $img_url ]]; then
error "Can not download latest image, using fallback image"
local img_fn="${IMG_DEFAULT}"
else
log "Downloading: $img_url"
curl -sO --max-time 6 "$img_url"
if [[ 0="$?" ]]; then
local img_fn=$(echo "$img_url" | awk 'BEGIN{FS="/";} {print $5}')
else
error "Can not download latest image, using fallback image"
local img_fn="${IMG_DEFAULT}"
fi
fi
echo "$img_fn"
}
xkcd_get_img_name() {
echo $(echo "$img_url_hotlink" | awk 'BEGIN{FS="/";} {print $5}')
}
xkcd_get_all_images() {
VERBOSE="1"
if [[ -z $(which curl) ]]; then
error "Could not find curl to download images"
exit 1
fi
log "Looking for latest image"
local nimg_latest=$(curl -s http://xkcd.com/index.html | \
awk '/Permanent link to this comic: / {print $6}' | \
awk 'BEGIN{FS="/";} {print $4}')
log "Found: $nimg_latest"
for ((i=1; i<=$nimg_latest; i++)); do
local img_url_hotlink=$(xkcd_get_hotlink_url $i)
local img_name=$(xkcd_get_img_name $img_url_hotlink)
if [[ -e "$img_name" ]]; then
log "$img_name exists. Skipping download"
continue
fi
log "Downloading ${i} ${img_url_hotlink} (${img_name})"
local r=$(curl -sO $img_url_hotlink)
log "Success: $r"
done
echo 0
}
xkcd_get_hotlink_url() {
local url="http://xkcd.com/$i"
local url_hotlink="$(curl -sL $url | awk '/Image URL \(for hotlinking\/embedding\): / {print $5}')"
echo $url_hotlink
}
get_nscreens() {
local nscreens=$(xrandr -q | awk '/ connected/ {count++} END {print count}')
echo "$nscreens"
}
screen_get_smallest_resolution() {
local res=$(xrandr -q | awk '/*/ {print $1}' \
| awk 'BEGIN{FS="x";} NR==1 || $1<min {line=$0; min=$1}; END {print line}')
echo "$res"
}
screen_get_highest_resolution() {
local res=$(xrandr -q | awk '/*/ {print $1}' \
| awk 'BEGIN{FS="x";} NR==1 || $1>max {line=$0; max=$1}; END {print line}')
echo "$res"
}
get_random_image() {
local img_fn="$(find $IMG_PATH -type f | shuf -n 1)"
if ! [[ -e "$img_fn" ]]; then
error "Could not find image to display"
fi
echo "$img_fn"
}
resize_image() {
local tmp_file=$(mktemp)
log "Resizing $img_fn to $res and saving image to $tmp_file"
convert -adaptive-resize $res $img_fn $tmp_file
if ! [[ -e "$tmp_file" ]]; then
error "Could not find resized image"
exit 1
fi
echo "$tmp_file"
}
center_image() {
local tmp_file=$(mktemp)
log "Centering $tmp_file and saving image to $tmp_file"
convert $tmp_file_r -gravity center -background $BG_COLOUR -extent $res $tmp_file
if ! [[ -e "$tmp_file" ]]; then
error "Could not find centered image"
exit 1
fi
echo "$tmp_file"
}
prepare_image() {
local res=$(screen_get_highest_resolution)
local tmp_file_r=$(resize_image $img_fn $res)
local tmp_file_c=$(center_image $tmp_file_r $res)
echo "$tmp_file_c"
}
screen_lock() {
local img_fn_final=$(prepare_image $img_fn)
log "Locking screen with $img_fn"
$LOCK_BIN -i $img_fn_final
}
main() {
local locker=$(which $LOCK_BIN)
local OPTIND
while getopts "h?i:l:vm:dy" opt; do
case "$opt" in
d)
printf "%s${DOWNLOAD_DISCLAIMER}"
printf "%s\nCurrent working directory: ${PWD}\n\n"
exit 0
;;
h|\?)
show_help
exit 0
;;
i)
local img_fn="${OPTARG}"
local r=$(screen_lock $img_fn)
exit 0
;;
l)
if [[ "sway"="${OPTARG}" ]]; then
LOCK_BIN="swaylock"
fi
;;
m)
IMG_CHOICE="${OPTARG}"
;;
v)
VERBOSE=1
;;
y)
r=$(xkcd_get_all_images)
exit 0
esac
done
if ! [[ -d "$IMG_PATH" ]]; then
error "Image directory does not exist: $IMG_PATH"
exit 1
fi
if [[ -z $(which xrandr) ]]; then
error "Could not find xrandr to determine screen size"
exit 1
fi
if [[ -z "$locker" ]]; then
error "Could not find screen locker: $lock_bin"
exit 1
fi
if [[ -z $(which convert) ]]; then
error "Could not find $convert_bin \nYou need imagick"
exit 1
fi
case "$IMG_CHOICE" in
"latest") local img_fn=$(xkcd_get_latest_image);;
"random") local img_fn=$(get_random_image);;
esac
screen_lock $img_fn
}
main "$@"