141 lines
4.4 KiB
Bash
Executable File
141 lines
4.4 KiB
Bash
Executable File
#!/bin/sh
|
||
#―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
|
||
# Name: sfeed_mastodon
|
||
# Desc: Post feed data from sfeed to the fediverse.
|
||
# Reqs: curl, jq
|
||
# Date: 2023-11-16
|
||
# Lisc: GPLv3
|
||
# Auth: @jadedctrl@jam.xwx.moe
|
||
#―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
|
||
|
||
# Print a friendly usage message.
|
||
usage() {
|
||
echo "usage: $(basename $0) [-h] [-a FEDI_AUTH] SERVER_URL"
|
||
echo "Posts sfeed(1) feed data from stdin to Mastodon-compatible servers."
|
||
echo ""
|
||
echo " -h print this message and exit"
|
||
echo " -a the authorization token for your account; see below"
|
||
echo " -t template for post contents; see below"
|
||
echo ""
|
||
echo "To find your authorization token, you can snoop through request headers in"
|
||
echo "your web-browser. In Firefox, this can be done through:"
|
||
echo ' Developer Tools (F12) → Network → Headers'
|
||
echo 'Look for your $FEDI_AUTH value in the Authorization header like so:'
|
||
echo ' Authorization: Bearer $FEDI_AUTH'
|
||
echo 'Either place this value in your $FEDI_AUTH environment variable, or pass it'
|
||
echo "with -a."
|
||
echo ""
|
||
echo "The template (-t) is an HTML value for this script’s post format."
|
||
echo "Post-related variables go within {{double-braces}}, and the following"
|
||
echo "variables are recognized: title, url, desc, desc_short, unix_date."
|
||
echo "By default, the template used is:"
|
||
echo " <b>{{title}}</b><br>{{url}}<br><br><blockquote>{{desc_short}}</blockquote>"
|
||
}
|
||
|
||
|
||
# Deescape a URL-escaped string (percent-encoded), passed over stdin.
|
||
url_deescape() {
|
||
sed 's@+@ @g;s@%@\\x@g' \
|
||
| xargs -0 printf "%b"
|
||
}
|
||
|
||
|
||
# Takes a post’s contents and create the corresponding client-API JSON.
|
||
post_json() {
|
||
local message_text="$1"
|
||
printf '{ "content_type": "text/html", "visibility": "unlisted",'
|
||
printf '"status": "%s" }\n' "$message_text"
|
||
}
|
||
|
||
|
||
# Post a status with HTML content to the given Mastodon-compatible server.
|
||
post_status() {
|
||
local server="$1"
|
||
local auth_token="$2"
|
||
local message_text="$3"
|
||
|
||
curl --request POST \
|
||
--header "Authorization: Bearer $auth_token" \
|
||
--header "Content-Type: application/json" \
|
||
--data "$(post_json "$message_text" | tr -d '\n')" \
|
||
"${server}/api/v1/statuses"
|
||
}
|
||
|
||
|
||
# Print an sfeed post line as per $TEMPLATE, with the following variables:
|
||
# {{title}}, {{unix_date}}, {{url}}, {{desc}}, {{desc_short}}
|
||
sfeed_post_text() {
|
||
local sfeed_line="$1"
|
||
local unix_date="$(echo "$line" | awk --field-separator '\t' '{print $1}')"
|
||
local title="$(echo "$line" | awk --field-separator '\t' '{print $2}')"
|
||
local url="$(echo "$line" | awk --field-separator '\t' '{print $3}' | url_deescape)"
|
||
local desc="$(echo "$line" | awk --field-separator '\t' '{print $4}')"
|
||
local desc_snip="$(echo "$desc" | head -c250)[…]"
|
||
|
||
printf "$TEMPLATE" \
|
||
| tr -d '|' \
|
||
| sed "s|{{title}}|$title|g" \
|
||
| sed "s|{{unix_date}}|$unix_date|g" \
|
||
| sed "s|{{url}}|$url|g" \
|
||
| sed "s|{{desc}}|$desc|g" \
|
||
| sed "s|{{desc_short}}|$desc_snip|g" \
|
||
| sed 's|\\n||g' \
|
||
| sed 's|"|\\"|g' \
|
||
| tr -d ' \n'
|
||
}
|
||
|
||
|
||
# Post an sfeed feed entry, by line, to a Mastodon-compatible fedi server.
|
||
post_sfeed_line() {
|
||
local server="$1"
|
||
local auth="$2"
|
||
local line="$3"
|
||
local message_text="$(sfeed_post_text "$line")"
|
||
post_status "$server" "$auth" "$message_text"
|
||
}
|
||
|
||
|
||
TEMPLATE='<b>{{title}}</b><br>{{url}}<br><br><blockquote>{{desc_short}}</blockquote>'
|
||
while getopts 'ha:t:' arg; do
|
||
case $arg in
|
||
h)
|
||
usage
|
||
exit 0
|
||
;;
|
||
a)
|
||
FEDI_AUTH="$OPTARG"
|
||
;;
|
||
t)
|
||
TEMPLATE="$OPTARG"
|
||
;;
|
||
esac
|
||
done
|
||
|
||
shift $((OPTIND-1))
|
||
SERVER_URL="$1"
|
||
|
||
|
||
if test -z "$FEDI_AUTH"; then
|
||
1>&2 echo 'You need to set the environment variable $FEDI_AUTH!'
|
||
1>&2 echo 'You can find your auth key by examining the "Authentication: Bearer" header'
|
||
1>&2 echo "used in requests by your server's web-client."
|
||
1>&2 echo 'In Firefox, F12→Network.'
|
||
1>&2 echo ""
|
||
exit 2
|
||
fi
|
||
|
||
if test -z "$SERVER_URL"; then
|
||
1>&2 echo "No server specified!"
|
||
1>&2 echo "Make sure to provide a server base URL (like https://fedi.server) as the last argument."
|
||
1>&2 echo ""
|
||
1>&2 usage
|
||
exit 3
|
||
fi
|
||
|
||
|
||
IFS="
|
||
"
|
||
while read -r line; do
|
||
post_sfeed_line "$SERVER_URL" "$FEDI_AUTH" "$line"
|
||
done
|