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 # 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 #!/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. # Display usage information.
help() { help() {
echo "${0##*/}" echo "${0##*/}"
echo "Released under the terms of the WTFPL License" echo "Released under the terms of the WTFPL License"
echo -e "Usage:\n" echo -e "Usage:\n"
echo "With no arguments, open the interactive client."
for i in "${!command[@]}" ; do for i in "${!command[@]}" ; do
echo "-${i/:/ <parameter>}: ${command[${i}]}" echo "-${i/:/ <parameter>}: ${command[${i}]}"
done | sort done | sort
@ -66,9 +59,13 @@ play_sound() {
if [[ "${enable_sound}" == "false" ]]; then if [[ "${enable_sound}" == "false" ]]; then
return return
fi fi
local soundFile="${configPath}/soundpacks/${sound_pack:-default}/${1}.opus" soundName="$*"
if [[ -e "${soundFile}" ]]; then declare -A sounds=(
sox -qV0 "${soundFile}" -d &> /dev/null & [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 fi
} }
@ -139,10 +136,10 @@ post_music() {
# Post status with -p flag, command line. # Post status with -p flag, command line.
post_status() { post_status() {
if [[ "${1}" == "" ]]; then if [[ "${*}" == "" ]]; then
return return
fi fi
local statusText="$@" local statusText="$*"
local statusVisibility="${statusVisibility:-public}" local statusVisibility="${statusVisibility:-public}"
local statusContent_type="${statusContent_type:-text/markdown}" local statusContent_type="${statusContent_type:-text/markdown}"
local statusSpoiler_text="" 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 # Variable initialization
configPath="${XDG_CONFIG_HOME:-$HOME/.config}/ratatoskr" # Path for settings, usually ~/.config/ratatoskr 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. 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." [C]="Recreate default configuration file. Acquire new oauth token."
[h]="Help, show usage information for ${0##*/}." [h]="Help, show usage information for ${0##*/}."
[M]="Post the currently playing music track, requires playerctl." [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." [S]="Scrobble the currently playing music track, requires playerctl."
) )
@ -280,12 +219,19 @@ shortOptions="${!command[*]}"
shortOptions="${shortOptions//[[:space:]]/}" shortOptions="${shortOptions//[[:space:]]/}"
options="$(getopt -o "$shortOptions" -- "$@")" options="$(getopt -o "$shortOptions" -- "$@")"
eval set -- "$options"
while true; do while [[ $# -gt 0 ]]; do
case $1 in case $1 in
--)
shift
break;;
-C) -C)
get_oauth_token get_oauth_token
shift;; shift;;
-v)
statusVisibility="${2}"
shift 2;;
-h) -h)
help help
exit 0;; exit 0;;
@ -293,14 +239,14 @@ while true; do
post_music post_music
exit 0;; exit 0;;
-p) -p)
if [ -z "$2" ]; then if read -rt 0 ; then
post_status "$(cat)" post_status "$(cat)"
else else
shift shift 3
post_status "$@" #post_status "$@"
fi fi
exit 0;; exit 0;;
-S|--scrobble-music) -S)
scrobble_music scrobble_music
exit 0;; exit 0;;
*) *)
@ -311,35 +257,4 @@ while true; do
done 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 exit 0