home/bin/slip
Damien Broqua 0d384b22bf I3 to Sway (#1)
Added some ignored folders and files

Updated waybar clock for Debian 11

Fixed bug on screen definition

Fixed Iiyama North America PL2483H 1173700204528

Merge branch 'gentoo-sway' of git.darkou.fr:dbroqua/home into gentoo-sway

Some changes for work environment

Some changes for work environment

Merge branch 'gentoo-sway' of git.darkou.fr:dbroqua/home into gentoo-sway

Added .mp3 files

Updated waybar config for laptop

Added vim-jsx

Added Teams to startup section (sad day in life!)

Updated mpd config (local source)

Added script for syncing my music

Merge branch 'gentoo-sway' of git.darkou.fr:dbroqua/home into gentoo-sway

Updated ranger config

Merge branch 'gentoo-sway' of git.darkou.fr:dbroqua/home into gentoo-sway

Replaced termite with alacritty

Replaced termite by alacritty

Updated rsync.sh results

Merge branch 'gentoo-sway' of git.darkou.fr:dbroqua/home into gentoo-sway

Updated github user

Updated irc alias

Minor changes

Added master if fail fait dev*

Added zsh prompt

Updated output definitions

Added KDEConnect at startup

Added second screen

Merge branch 'gentoo-sway' of git.darkou.fr:dbroqua/home into gentoo-sway

Updated README

Added C.A.V.A.

Fixed bug for vte

Added Tofu HHKB keyboard config

Added script to update system

Updated FuzzFm entry

Added menu entry for Carnet

Added qcad's ebuild

Updated waybar for Thinkpad

Updated temperature list for Thinkpad

Fixed bug

Updated input for thinkpad

Added script to order files for Alpine car audio system

Updated Fuzz url

Added Grammalecte plugin

Added displays for ThinkStation and ThinkPad

Merge branch 'gentoo-sway' of framagit.org:dbroqua/home into gentoo-sway

Updated waybar for laptop

Fixed bug on adjust brightness

Moved applications

Co-authored-by: dbroqua <contact@darkou.fr>
Co-authored-by: dbroqua <dbroqua@mousur.org>
Reviewed-on: #1
Co-Authored-By: Damien Broqua <dbroqua@noreply.localhost>
Co-Committed-By: Damien Broqua <dbroqua@noreply.localhost>
2021-10-21 21:40:47 +02:00

355 lines
11 KiB
Bash
Executable File

#! /bin/bash
set -eo pipefail
VERSION="2.0.4"
# Sane defaults in case of not being set in the config / config not existing.
CREDENTIALS_FILE="$HOME/.config/slip/credentials"
RECORD_PIDFILE="/tmp/slip_record.pid"
IMAGES="$HOME/Pictures"
VIDEOS="$HOME/Videos"
GIF_SCALE="640"
GIF_FPS=15
SOUND=0
NOUPLOAD=0
DMENU_CMD="rofi -dmenu -p slip"
# Load config.
CONFIG="${XDG_CONFIG_HOME:-$HOME/.config}/slip/config"
if [ -f $CONFIG ]; then
source $CONFIG
else
echo "No config was found - using default options. Please copy the example configuration to ~/.config/slip/config from https://github.com/Toqozz/slip"
fi
CLIENT_ID="abd3a90bbfb65e9"
# Dmenu prompts.
DMENU_OPTS="screenshot
video
gif
exit"
DMENU_RECORD_OPTS="stop
cancel"
DMENU_UPLOAD_OPTS_BIG="upload (gfycat)
delete
exit"
DMENU_UPLOAD_OPTS="upload (imgur)
upload (gfycat)
delete
exit"
# Maximum size for upload (kb).
# Gfycat does not have a file limit.
MAX_GIF_SIZE_IMGUR=10000
function usage() {
echo ""
echo " slip [ -h | -v | -s | -r | -a | -q ] -nu"
echo " Uploads images taken with ffmpeg via slop to imgur. Quick video recording."
echo " That's all."
echo ""
echo " -h | --help show this help"
echo " -v | --version show version"
echo " -s | --screenshot take a screenshot (skip dmenu)"
echo " -g | --gif take a gif (skip dmenu)"
echo " -r | --record take a video (skip dmenu)"
echo " -nu | --no-upload don't upload the result"
echo " -q | --stop stop recording a video / gif (skip dmenu) (only when recording)"
echo ""
}
function upload_imgur() {
file="$1"
if [ -f "$file" ]; then
if [ -f "$CREDENTIALS_FILE" ]; then
# We have an auth token to use.
check_auth_credentials
if [ $? -ne 1 ]; then
# Token valid.
curl -sH "Authorization: Bearer ${access_token}" -F "image=@$file" "https://api.imgur.com/3/upload"
fi
else
# Imgur needs to know what program is using its services.
curl -sH "Authorization: Client-ID ${CLIENT_ID}" -F "image=@$file" "https://api.imgur.com/3/upload"
fi
else
echo "File does not exist, what happened?"
fi
}
function upload_gfycat() {
local file="$1"
local result=$(curl -s -XPOST https://api.gfycat.com/v1/gfycats -H "Content-Type: application/json")
local gfyname=$(parse "gfycat" $result)
curl -s "https://filedrop.gfycat.com/$gfyname" --upload-file "$file"
# No new line so we can append it easily.
echo -n "$gfyname"
}
function check_auth_credentials() {
token_expire_time=0
if [ -f "${CREDENTIALS_FILE}" ]; then
source "${CREDENTIALS_FILE}"
fi
if [ ! -z ${access_token} ]; then
current_time="$(date +%s)"
preemptive_refresh_time="$((10*60))"
expired="$((current_time > (token_expire_time - preemptive_refresh_time)))"
if [ "${expired}" -eq "0" ]; then
#token has expired, get a new one.
echo 'The authorization token has expired, please get a new one.'
return 1;
fi
else
return 1;
fi
}
function clip_clear() {
# Clear x cliboard selection.
xsel -bc # Ctrl-v / Shift-Insert.
# xsel -pc # Middle click.
}
# Run slop and get the geometry line.
function slop_geom() {
if [ "$1" = "image" ]; then
slop -f '%wx%h+%x+%y'
else
slop -f '%wx%h|%x,%y' # | sed -e s/+/\|/ -e s/+/,/
fi
#elif [ "$1" = "video" ]; then
#slop -f '%wx%h+%x+%y' | sed -e s/+/\|/ -e s/+/,/
#slop | sed -n 5p | sed -e s/G=// -e s/+/\|/ -e s/+/,/
#elif [ "$1" = "gif" ]; then
#slop -f '%wx%h+%x+%y' | sed -e s/+/\|/ -e s/+/,/
}
# Take the shot (or start the video.)
function shot() {
if [ "$1" = "image" ]; then
extension=".png" # img-2016-04-16-153906.png
filename="$IMAGES/img-`date +%Y-%m-%d-%H%M%S`$extension" # .png, .jpg
maim -g "$2" $filename
# TODO, do we want more dependencies? (optional dependencies?)
#ffmpeg -f x11grab -video_size "$2" -i "$DISPLAY+$3" -vframes 1 $filename &> /dev/null
elif [ "$1" = "video" ]; then
extension=".mkv" # vid-2016-04-16-153906.mkv
filename="$VIDEOS/vid-`date +%Y-%m-%d-%H%M%S`$extension" # .mkv, .mp4
if [ $SOUND == 0 ]; then
ffmpeg -f x11grab -video_size "$2" -framerate 60 -i "$DISPLAY+$3" -loglevel quiet -c:v libx264 -preset ultrafast $filename &
else
ffmpeg -f pulse -i 1 -f x11grab -video_size "$2" -framerate 60 -i "$DISPLAY+$3" -loglevel quiet -c:v libx264 -preset ultrafast $filename &
fi
echo "$! vid $filename" > "$RECORD_PIDFILE"
elif [ "$1" = "gif" ]; then
extension=".gif" # gif-2016-04-16-153906.gif
tmpfilename="/tmp/gif-`date +%Y-%m-%d-%H%M%S-tmp`.mkv"
filename="$VIDEOS/gif-`date +%Y-%m-%d-%H%M%S`$extension" # .gif
# Record a video to be converted to gif.
ffmpeg -f x11grab -video_size "$2" -framerate $GIF_FPS -i "$DISPLAY+$3" -loglevel quiet -c:v libx264 -preset ultrafast $tmpfilename &
#ffmpeg -f x11grab -video_size "$2" -framerate 15 -i "$DISPLAY+$3" -vf scale="$GIF_SCALE:-1" $filename &> /dev/null &
# We need to access this information later.
ratio=$(awk -F"x" '{ print int($1/$2) }' <<< "$2") # We only really need a binary answer.
if [ "$ratio" -ge 1 ]; then echo "$! gif $tmpfilename $filename 0" > "$RECORD_PIDFILE"
else echo "$! gif $tmpfilename $filename 1" > "$RECORD_PIDFILE"
fi
fi
}
function kill_ffmpeg() {
# Kill ffmpeg (stopping the recording.)
kill $1 || echo "Failed to kill ffmpeg, did it crash? Removing $RECORD_PIDFILE anyway."
# Remove the pid file so that slip can be used as normal again.
rm "$RECORD_PIDFILE"
}
function convert_to_gif() {
local tfn=$1
local pfn=$2
local fn=$3
local wh=$4 # 0 = width larger than height, 1 = height larger than width
local ratio
# If the width is larger than the height, we want to scale with the width, otherwise scale with the height.
if [ $wh -eq 0 ]; then
ratio="$GIF_SCALE:-1"
else
ratio="-1:$GIF_SCALE"
fi
notify "Converting to gif…"
# Give enough time to save the file.
sleep 1 && ffmpeg -i "$tfn" -loglevel quiet -vf fps=$GIF_FPS,scale="$ratio":flags=lanczos,palettegen "$pfn" &&
ffmpeg -i "$tfn" -i "$pfn" -loglevel quiet -filter_complex "fps=$GIF_FPS,scale=$ratio:flags=lanczos[x];[x][1:v]paletteuse" "$fn" &&
echo "$fn"
}
function stop_rec() {
local choice
local pid=$1 # Process id (for killing ffmpeg).
local tfn=$3 # Temp file name (for gifs).
local fn=$4 # File name for the gif/vid we're saving.
local pfn="${tfn}-palette.png" # Palette file name (for gif rendering).
# Stop recording.
kill_ffmpeg "$pid"
# When processing a gif, we canvert it straight away and then upload.
# NOTE: gfycat does not require the video to be converted, but we convert it anyway to store
# the .gif file.
# Is this actually a good idea? We could just store the .mkv instead, but then we lose the ability to store .gif.
if [ "$2" = "gif" ]; then
fn=$(convert_to_gif "$tfn" "$pfn" "$fn" "$5")
size=$(du -k $fn | cut -f1)
if [ $NOUPLOAD == 0 ]; then
if [ "$size" -lt "${MAX_GIF_SIZE_IMGUR}" ]; then
choice=$($DMENU_CMD <<< $DMENU_UPLOAD_OPTS)
else
choice=$($DMENU_CMD <<< $DMENU_UPLOAD_OPTS_BIG)
fi
if [ "$choice" = "upload (gfycat)" ]; then
clip_clear
name=$(upload_gfycat "$tfn")
url="https://gfycat.com/$name"
notify "Uploading to $url ..."
echo "$url"
echo -n "$url" | xsel -bi # Read to clipboard.
elif [ "$choice" = "upload (imgur)" ]; then
clip_clear
output=$(upload_imgur "$fn")
url=$(parse "imgur" "$output")
notify "$url"
echo "$url"
echo -n "$url" | xsel -bi # Read to clipboard.
elif [ "$choice" = "delete" ]; then
rm $fn
fi
fi
else
notify "$fn"
fi
}
# Parse x,y -- but also imgur.
function parse() {
if [ "$1" = "geometryx" ]; then
awk -F"|" '{ print $1 }' <<< "$2"
elif [ "$1" = "geometry+" ]; then
awk -F"|" '{ print $2 }' <<< "$2"
elif [ "$1" = "imgur" ]; then
jq -r ".data.link" <<< "$2"
#sed -e 's/.*\"link\":"\([^"]*\).*/\1/' -e 's/\\//g' <<< "$2"
#sed -e 's/\"link\":"\([^"]*\)/\1/' -e 's/\\//g' <<< "$2"
elif [ "$1" = "gfycat" ]; then
jq -r ".gfyname" <<< "$2"
fi
}
function notify() {
notify-send -t 7000 "slip" "$1"
}
function main() {
if [ "$1" = "screenshot" ]; then
# Run slop and get geometry from it.
# maim naturally supports slop's output coordinates.
geometry=$(slop_geom "image")
# Take the shot.
shot "image" "$geometry"
# Parse imgur json into link.
# If noupload is not set.
if [ $NOUPLOAD == 0 ]; then
#echo "uploading..."
# Clear cliboard before doing anything, so we can copy link to it later.
clip_clear
output=$(upload_imgur "$filename")
url=$(parse "imgur" "$output")
# Notify user that upload has finished.
notify "$url"
echo "$url"
# Read to clipboard, removing trailing newline.
echo -n "$url" | xsel -bi
else
notify "$filename"
fi
# echo "$url" | xsel -pi # Read to primary.
elif [ "$1" = "video" ]; then
geometry=$(slop_geom "video")
wxh=$(parse "geometryx" $geometry)
off=$(parse "geometry+" $geometry)
shot "video" "$wxh" "$off"
elif [ "$1" = "gif" ]; then
geometry=$(slop_geom "gif")
wxh=$(parse "geometryx" $geometry)
off=$(parse "geometry+" $geometry)
shot "gif" "$wxh" "$off"
elif [ "$1" = "stop" ]; then
# Get info of recording process.
local info
# Get infor from the pidfile.
info=$(cat "$RECORD_PIDFILE")
# Stop with parameters ("<pid> <type> <filename> <ratio>")
stop_rec $info
exit 0
else
exit 0
fi
}
# Dependencies.
depends="curl
jq
maim
slop
ffmpeg"
while read line
do
if ! type $line &> /dev/null ; then
echo "$line not found, expect unexpected or breakage."
fi
done <<< "$depends"
# Main.
# Yes, we could call this stuff with integers, but this is much clearer.
if [ "$1" = "-nu" -o "$1" = "--no-upload" -o "$2" = "-nu" -o "$2" = "--no-upload" ]; then
NOUPLOAD=1
fi
if [ "$1" = "-h" -o "$1" = "--help" ]; then
usage
exit 0
elif [ "$1" = "-v" -o "$1" = "--version" ]; then
echo "Version: $VERSION"
exit 0
elif [ "$1" = "-s" -o "$1" = "--screenshot" ]; then
main "screenshot"
elif [ "$1" = "-g" -o "$1" = "--gif" ]; then
main "gif"
elif [ "$1" = "-r" -o "$1" = "--record" ]; then
main "video"
elif [ "$1" = "-q" -o "$1" = "--stop" ]; then
main "stop"
elif [ $# == 0 ]; then
if [ -a "$RECORD_PIDFILE" ]; then
main $($DMENU_CMD <<< "$DMENU_RECORD_OPTS")
else
main $($DMENU_CMD <<< "$DMENU_OPTS")
fi
fi