ratatoskr/ratatoskr.sh

262 lines
8.8 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
# Display usage information.
help() {
echo "${0##*/}"
echo "Released under the terms of the WTFPL License"
echo -e "Usage:\n"
for i in "${!command[@]}" ; do
echo "-${i/:/ <parameter>}: ${command[${i}]}"
done | sort
echo
echo "Configuration files can be found in ${configPath}"
echo
exit 0
}
# Get an oauth token
get_oauth_token() {
echo "Welcome to ${softwareName}!"
echo
echo "Let's get you connected to your instance."
while [[ -z "${instanceURL}" ]]; do
echo
read -er -p "Enter the URL of a Pleroma instance: " instanceURL
if [[ ! "${instanceURL}" =~ ^https:// ]]; then
instanceURL="https://${instanceURL}"
fi
done
redirectURI="urn:ietf:wg:oauth:2.0:oob"
website="https://git.stormux.org/storm/ratatoskr"
# get client id and secret
curl -s -X POST -d client_name="${softwareName}" -d "redirect_uris=${redirectURI}" -d "scopes=read write follow push" -d "website=${website}" "${instanceURL}/api/v1/apps" |
jq --raw-output '"client_id=\"\(.client_id)\"\nclient_secret=\"\(.client_secret)\""' > "${configPath}/${configFile}"
# Load the new variables from the configuration file
source "${configPath}/${configFile}"
# Create the url to get the oauth token
local url="${instanceURL}/oauth/authorize?client_id=${client_id}&redirect_uri=${redirectURI}&response_type=code&scope=read%20write%20follow%20push"
echo "Please open the following url in your browser."
echo "Copy the generated token, and paste it here, then press enter to continue."
echo
if command -v xclip &> /dev/null ; then
echo "${url}" | tee >(xclip -selection clipboard -d "${DISPLAY:-:0}" 2> /dev/null &&
echo "For convenience the url has been copied to your clipboard.")
else
echo "${url}"
fi
echo
read -er oauth_token
# This is actually a authorization token, so get the actual token.
oauth_token="$(curl -sS -d "client_id=${client_id}" -d "client_secret=${client_secret}" -d "code=${oauth_token}" -d "grant_type=authorization_code" "${instanceURL}/oauth/token" | jq --raw-output '(.access_token)')"
echo "oauth_token=\"${oauth_token}\"" >> "${configPath}/${configFile}"
echo "instanceURL=\"${instanceURL}\"" >> "${configPath}/${configFile}"
}
2023-01-30 02:05:54 -05:00
play_sound() {
2023-01-30 12:54:28 -05:00
if [[ "${enable_sound}" == "false" ]]; then
return
fi
soundName="$*"
declare -A sounds=(
2024-05-11 20:52:52 -04:00
[error]="|sox -n -p synth saw E2 fade 0 0.25 0.05 repeat norm -7"
[music]="|sox -np synth pl E2 pl B2 overdrive 100 remix - overdrive 100 fade h .25 1 .25 norm -11"
[post]='|sox -np synth .05 tri C2:C7'
)
if [[ -n "${sounds[${soundName}]}" ]]; then
2024-05-11 20:52:52 -04:00
sox -qV0 "${sounds[${soundName}]}" -d gain -9 &> /dev/null &
2023-01-30 02:05:54 -05:00
fi
}
# Functions that deal with posting.
# Scrobble music with -S flag
scrobble_music() {
2023-01-30 01:35:05 -05:00
local result
result="$(curl -sS --oauth2-bearer "${oauth_token}" \
-d "$(playerctl metadata -f 'album={{album}}')" \
-d "$(playerctl metadata -f 'artist={{artist}}')" \
-d "$(playerctl metadata -f 'title={{title}}')" \
2023-01-30 01:35:05 -05:00
"${instanceURL}/api/v1/pleroma/scrobble")"
# Check for errors
if [[ $? -ne 0 ]]; then
echo "there was a problem contacting the server"
2023-01-30 02:05:54 -05:00
play_sound error
2023-01-30 01:35:05 -05:00
exit 1
fi
local error="$(echo "$result" | jq -r '.error')"
if [[ "$error" != "null" ]]; then
echo "Error: $error"
2023-01-30 02:05:54 -05:00
play_sound error
2023-01-30 01:35:05 -05:00
exit 1
fi
echo "Track scrobbled!"
2023-01-30 02:05:54 -05:00
play_sound scrobble
}
# Post music with -M flag requires playerctl.
post_music() {
2023-02-01 13:20:21 -05:00
local text="$(playerctl metadata -f 'Now playing "{{title}}" by "{{artist}}" from "{{album}}" via "{{playerName}}"')"
text="${text//Now playing \"\"/Now Playing}"
text="${text// by \"\"/}"
text="${text// from \"\"/}"
if [[ "${text}" =~ ^"Now playing via" ]]; then
echo "Error, no music was detected. Maybe it is not properly tagged?"
play_sound error
exit 1
fi
local link="$(playerctl metadata -f '{{xesam:url}}')"
if [[ "${link}" =~ ^file:// ]]; then
link="https://www.youtube.com/results?search_query=$(playerctl metadata -f '{{artist}} {{title}}' | urlencode -b)"
fi
local json=$(jq -n --arg status "[${text}](${link})" --arg spoiler_text "Music" --arg content_type "text/markdown" '{status: $status, spoiler_text: $spoiler_text, content_type: $content_type}')
local result
result="$(curl -sS --oauth2-bearer "${oauth_token}" -H "Content-Type: application/json" \
-d "$json" \
"${instanceURL}/api/v1/statuses")"
# Check for errors
if [[ $? -ne 0 ]]; then
echo "there was a problem contacting the server"
2023-01-30 02:05:54 -05:00
play_sound error
exit 1
fi
local error="$(echo "$result" | jq -r '.error')"
if [[ "$error" != "null" ]]; then
echo "Error: $error"
2023-01-30 02:05:54 -05:00
play_sound error
exit 1
fi
echo "Music posted!"
2024-05-11 20:52:52 -04:00
play_sound music
}
# Post status with -p flag, command line.
post_status() {
if [[ "${*}" == "" ]]; then
return
fi
local statusText="$*"
local statusVisibility="${statusVisibility:-public}"
local statusContent_type="${statusContent_type:-text/markdown}"
local statusSpoiler_text=""
local statusJson="$(jq -n --arg status "$statusText" \
--arg spoiler_text "$statusSpoiler_text" \
--arg visibility "$statusVisibility" \
--arg content_type "$statusContent_type" \
2023-01-30 01:35:05 -05:00
'{ status: $status, spoiler_text: $spoiler_text, visibility: $visibility, content_type: $content_type }')"
local statusResult
statusResult="$(curl -sS --oauth2-bearer "${oauth_token}" -H "Content-Type: application/json" \
-d "$(echo "$statusJson" | jq 'if .spoiler_text == "" then del(.spoiler_text) else . end | if .visibility == "" then del(.visibility) else . end')" \
2023-01-30 01:35:05 -05:00
"${instanceURL}/api/v1/statuses")"
if [[ $? -ne 0 ]]; then
echo "there was a problem contacting the server"
2023-01-30 02:05:54 -05:00
play_sound error
2023-01-30 01:35:05 -05:00
exit 1
fi
local error="$(echo "$statusResult" | jq -r '.error')"
2023-01-30 01:35:05 -05:00
if [[ "$error" != "null" ]]; then
echo "Error: $error"
2023-01-30 02:05:54 -05:00
play_sound error
2023-01-30 01:35:05 -05:00
exit 1
fi
echo "Status posted!"
2023-01-30 02:05:54 -05:00
play_sound post
}
# 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.
softwareName="Ratatoskr" # The name of the client.
# Main code starts here
2023-01-30 02:05:54 -05:00
# Check for dependencies
dependencies=(
"jq"
"sox"
"urlencode"
)
for i in "${dependencies[@]}" ; do
if ! command -v "$i" &> /dev/null ; then
echo "Missing dependency: $i"
exit 2
fi
done
# make sure the configuration and soundpack paths exist:
mkdir -p "${configPath}/soundpacks"
# if the default file doesn't exist, create it
if [[ ! -e "${configPath}/${configFile}" ]]; then
get_oauth_token
else
# Read configuration file
source "${configPath}/${configFile}"
fi
# Associative array of command line parameters and short description of what they do.
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\" or echo \"Hello world\" | ${0}"
[v:]="Post visibility, [direct | followers | public | unlisted], default is public."
[S]="Scrobble the currently playing music track, requires playerctl."
)
# Handle command line parameters
# Convert the keys of the associative array to a format usable by getopt
shortOptions="${!command[*]}"
shortOptions="${shortOptions//[[:space:]]/}"
options="$(getopt -o "$shortOptions" -- "$@")"
eval set -- "$options"
while [[ $# -gt 0 ]]; do
case $1 in
--)
shift
break;;
-C)
get_oauth_token
shift;;
-v)
statusVisibility="${2}"
shift 2;;
-h)
help
exit 0;;
-M)
2023-01-30 12:54:28 -05:00
post_music
exit 0;;
-p)
if read -rt 0 ; then
post_status "$(cat)"
else
shift 3
#post_status "$@"
fi
2023-01-30 12:54:28 -05:00
exit 0;;
-S)
2023-01-30 12:54:28 -05:00
scrobble_music
exit 0;;
*)
# unexpected option
help
exit 1;;
esac
done
exit 0