From 05b375a14a4ac773cc2c26ab353c4d727a54d68d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Busse?= Date: Thu, 28 Jul 2016 19:51:48 +0200 Subject: [PATCH] add files --- LICENSE | 27 ++++ not_really_into_pokemon.png | Bin 0 -> 18611 bytes xkcdlock | 285 ++++++++++++++++++++++++++++++++++++ 3 files changed, 312 insertions(+) create mode 100644 LICENSE create mode 100644 not_really_into_pokemon.png create mode 100755 xkcdlock diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f5503a2 --- /dev/null +++ b/LICENSE @@ -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. diff --git a/not_really_into_pokemon.png b/not_really_into_pokemon.png new file mode 100644 index 0000000000000000000000000000000000000000..95a71f05bc857a3fb0ff418cf5a9b08c902d79c9 GIT binary patch literal 18611 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 KMNUMnLSTaUae1Kt literal 0 HcmV?d00001 diff --git a/xkcdlock b/xkcdlock new file mode 100755 index 0000000..3af0d44 --- /dev/null +++ b/xkcdlock @@ -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 || $1max {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 "$@"