Lots of updates, removed the timeline display code because it's buggy and the web client does it better anyway. Repurposed this program to do posting from the cli, so for music, or from other programs, or quick posts without having the leave the cli.

This commit is contained in:
Storm Dragon 2024-05-11 18:16:00 -04:00
parent cc1dab3fdb
commit 2e8bb5961a
2 changed files with 30 additions and 109 deletions

View File

@ -1,3 +1,9 @@
# ratatoskr
A command line client for Pleroma, written in bash.
A command line client for Pleroma, written in bash. Originally it was to be a client with viewing as well as posting features, but there are plenty of clients that do decent formatting of statuses, and the web client also does a great job, especially with things like threading. So This project is mainly for posting to your instance.
It can be used to post things you may want to send like playing music, or it can be used to post from piped in information as in:
echo "Hello world" | ./ratatoskr -p
It's still very much a work in progress, but have fun with it anyway. :)

View File

@ -1,18 +1,11 @@
#!/usr/bin/env bash
# Hopefully one day this will be a full featured Pleroma client.
# Let's see how far we can get. :)
# Handle subprocesses that may not close with the main program.
trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT
# Display usage information.
help() {
echo "${0##*/}"
echo "Released under the terms of the WTFPL License"
echo -e "Usage:\n"
echo "With no arguments, open the interactive client."
for i in "${!command[@]}" ; do
echo "-${i/:/ <parameter>}: ${command[${i}]}"
done | sort
@ -66,9 +59,13 @@ play_sound() {
if [[ "${enable_sound}" == "false" ]]; then
return
fi
local soundFile="${configPath}/soundpacks/${sound_pack:-default}/${1}.opus"
if [[ -e "${soundFile}" ]]; then
sox -qV0 "${soundFile}" -d &> /dev/null &
soundName="$*"
declare -A sounds=(
[error]="|sox -n -p synth saw E2 fade 0 0.25 0.05 repeat"
[post]='|sox -np synth .05 tri C2:C7'
)
if [[ -n "${sounds[${soundName}]}" ]]; then
sox -qV0 "${sounds[${soundName}]}" -d norm -9 &> /dev/null &
fi
}
@ -139,10 +136,10 @@ post_music() {
# Post status with -p flag, command line.
post_status() {
if [[ "${1}" == "" ]]; then
if [[ "${*}" == "" ]]; then
return
fi
local statusText="$@"
local statusText="$*"
local statusVisibility="${statusVisibility:-public}"
local statusContent_type="${statusContent_type:-text/markdown}"
local statusSpoiler_text=""
@ -171,65 +168,6 @@ post_status() {
}
# Display timelines
show_timeline() {
result="$(curl -sS --oauth2-bearer "${oauth_token}" "${instanceURL}/api/v1/timelines/${timeline:-home}")"
# Error checking
# Check if the result is a valid JSON
if ! echo "$result" | jq '.' >/dev/null 2>&1; then
echo "Error: The response from the server was invalid."
play_sound error
return
fi
if [[ "${result}" == "${oldResult}" ]]; then
return
elif [[ ${#oldResult} -gt 5 ]]; then
local temperaryVariable="${result}"
result="${result//${oldResult%\]}/}"
result="${result%,\]}]"
oldResult="${temperaryVariable}"
play_sound new_${timeline:-home}
fi
error=$(echo "$result" | jq -r '.error // "null"' 2> /dev/null)
if [[ "${error:-null}" != "null" ]]; then
echo "Error fetching ${timeline:-home} timeline: $error"
play_sound error
return
fi
# handle new events
events="$(jq -r '.[].content' <<< "$result")"
spoiler_text="$(jq -r '.[].spoiler_text' <<< "$result")"
created_at="$(jq -r '.[].created_at' <<< "$result")"
stripped_events="$(echo "$events" | sed -E 's/<[^>]+>//g')"
stripped_events="${stripped_events//&#39;/\'}"
usernames="$(jq -r '.[].account.username' <<< "$result")"
echo -e "$usernames" | while read -r username; do
spoiler="$(echo "$spoiler_text" | head -n 1)"
created="$(echo "$created_at" | head -n 1)"
created="${created%.*}"
created="${created/T/ at }"
if [ -z "$spoiler" ]; then
echo "$username: $(echo "$stripped_events" | head -n 1)"
echo "Posted $created"
else
echo "$username [$spoiler]: $(echo "$stripped_events" | head -n 1)"
echo "Posted $created"
fi
stripped_events="$(echo "$stripped_events" | tail -n +2)"
spoiler_text="$(echo "$spoiler_text" | tail -n +2)"
created_at="$(echo "$created_at" | tail -n +2)"
echo
done
oldResult="${result}"
}
# Variable initialization
configPath="${XDG_CONFIG_HOME:-$HOME/.config}/ratatoskr" # Path for settings, usually ~/.config/ratatoskr
configFile="default.conf" # The default config file, eventually will support multiple accounts.
@ -270,7 +208,8 @@ declare -A command=(
[C]="Recreate default configuration file. Acquire new oauth token."
[h]="Help, show usage information for ${0##*/}."
[M]="Post the currently playing music track, requires playerctl."
[p::]="Post from the command line, e.g. ${0##*/} -p \"hello world\""
[p::]="Post from the command line, e.g. ${0##*/} -p \"hello world\" or echo \"Hello world\" | ${0}"
[v:]="Post visibility, [direct | followers | public | unlisted], default is public."
[S]="Scrobble the currently playing music track, requires playerctl."
)
@ -280,12 +219,19 @@ shortOptions="${!command[*]}"
shortOptions="${shortOptions//[[:space:]]/}"
options="$(getopt -o "$shortOptions" -- "$@")"
eval set -- "$options"
while true; do
while [[ $# -gt 0 ]]; do
case $1 in
--)
shift
break;;
-C)
get_oauth_token
shift;;
-v)
statusVisibility="${2}"
shift 2;;
-h)
help
exit 0;;
@ -293,14 +239,14 @@ while true; do
post_music
exit 0;;
-p)
if [ -z "$2" ]; then
if read -rt 0 ; then
post_status "$(cat)"
else
shift
post_status "$@"
shift 3
#post_status "$@"
fi
exit 0;;
-S|--scrobble-music)
-S)
scrobble_music
exit 0;;
*)
@ -311,35 +257,4 @@ while true; do
done
# Main loops
# Display timelines and requested information.
while : ; do
show_timeline
sleep "${interval:-300}"
done &
# Handle commands
while : ; do
# Command prompt:
read -er command
if [[ ! "${command}" =~ ^/ ]]; then
post_status "${command}"
continue
fi
case "${command}" in
"/exit"|"/quit")
exit 0
;;
"/refresh")
show_timeline
;;
*)
echo "Error: '${command}' is not a valid command."
play_sound error
;;
esac
done
exit 0