2023-01-28 13:19:59 -05:00
|
|
|
#!/usr/bin/env bash
|
|
|
|
|
|
|
|
# Hopefully one day this will be a full featured Pleroma client.
|
|
|
|
# Let's see how far we can get. :)
|
|
|
|
|
2023-01-29 04:23:46 -05:00
|
|
|
# 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
|
|
|
|
echo
|
|
|
|
echo "Configuration files can be found in ${configPath}"
|
|
|
|
echo
|
|
|
|
exit 0
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-01-28 13:19:59 -05:00
|
|
|
# Get an oauth token
|
|
|
|
get_oauth_token() {
|
|
|
|
echo "Welcome to ${softwareName}!"
|
|
|
|
echo
|
|
|
|
echo "Let's get you connected to your instance."
|
2023-01-28 18:05:06 -05:00
|
|
|
while [[ -z "${instanceURL}" ]]; do
|
|
|
|
echo
|
|
|
|
read -er -p "Enter the URL of a Pleroma instance: " instanceURL
|
|
|
|
if [[ ! "${instanceURL}" =~ ^https:// ]]; then
|
|
|
|
instanceURL="https://${instanceURL}"
|
2023-01-28 13:19:59 -05:00
|
|
|
fi
|
|
|
|
done
|
2023-01-29 15:42:54 -05:00
|
|
|
redirectURI="urn:ietf:wg:oauth:2.0:oob"
|
2023-01-29 14:32:13 -05:00
|
|
|
website="https://git.stormux.org/storm/ratatoskr"
|
2023-01-28 14:57:45 -05:00
|
|
|
# get client id and secret
|
2023-01-29 14:32:13 -05:00
|
|
|
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" |
|
2023-01-28 15:43:21 -05:00
|
|
|
jq --raw-output '"client_id=\"\(.client_id)\"\nclient_secret=\"\(.client_secret)\""' > "${configPath}/${configFile}"
|
2023-01-28 15:41:06 -05:00
|
|
|
# Load the new variables from the configuration file
|
|
|
|
source "${configPath}/${configFile}"
|
|
|
|
# Create the url to get the oauth token
|
2023-01-29 04:23:46 -05:00
|
|
|
local url="${instanceURL}/oauth/authorize?client_id=${client_id}&redirect_uri=${redirectURI}&response_type=code&scope=read%20write%20follow%20push"
|
2023-01-28 15:41:06 -05:00
|
|
|
echo "Please open the following url in your browser."
|
2023-01-28 18:05:06 -05:00
|
|
|
echo "Copy the generated token, and paste it here, then press enter to continue."
|
2023-01-28 15:41:06 -05:00
|
|
|
echo
|
2023-01-28 18:12:39 -05:00
|
|
|
if command -v xclip &> /dev/null ; then
|
2023-01-29 16:35:08 -05:00
|
|
|
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}"
|
2023-01-28 18:12:39 -05:00
|
|
|
fi
|
2023-01-29 16:35:08 -05:00
|
|
|
echo
|
2023-01-28 18:05:06 -05:00
|
|
|
read -er oauth_token
|
2023-01-29 18:48:29 -05:00
|
|
|
# This is actually a authorization token, so get the actual token.
|
2023-01-29 18:53:17 -05:00
|
|
|
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)')"
|
2023-01-28 18:05:06 -05:00
|
|
|
echo "oauth_token=\"${oauth_token}\"" >> "${configPath}/${configFile}"
|
2023-01-29 14:32:13 -05:00
|
|
|
echo "instanceURL=\"${instanceURL}\"" >> "${configPath}/${configFile}"
|
2023-01-28 13:19:59 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-01-29 04:23:46 -05:00
|
|
|
# Functions that deal with posting.
|
|
|
|
|
2023-01-29 23:59:59 -05:00
|
|
|
# Scrobble music with -S flag
|
|
|
|
scrobble_music() {
|
2023-01-29 19:45:43 -05:00
|
|
|
curl -sS --oauth2-bearer "${oauth_token}" \
|
2023-01-29 14:32:13 -05:00
|
|
|
-d "$(playerctl metadata -f 'album={{album}}')" \
|
|
|
|
-d "$(playerctl metadata -f 'artist={{artist}}')" \
|
|
|
|
-d "$(playerctl metadata -f 'title={{title}}')" \
|
|
|
|
"${instanceURL}/api/v1/pleroma/scrobble"
|
2023-01-29 04:23:46 -05:00
|
|
|
exit 0
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-01-29 23:59:59 -05:00
|
|
|
# Post music with -M flag requires playerctl.
|
|
|
|
post_music() {
|
|
|
|
local text="[$(playerctl metadata -f 'Now playing "{{title}}" by "{{artist}}" from "{{album}}"')]"
|
|
|
|
local link="(https://www.youtube.com/results?search_query=$(playerctl metadata -f '{{artist}} {{title}}' | urlencode -b))"
|
|
|
|
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}')
|
2023-01-30 00:23:54 -05:00
|
|
|
local result
|
|
|
|
result="$(curl -sS --oauth2-bearer "${oauth_token}" -H "Content-Type: application/json" \
|
2023-01-29 23:59:59 -05:00
|
|
|
-d "$json" \
|
2023-01-30 00:23:54 -05:00
|
|
|
"${instanceURL}/api/v1/statuses")"
|
|
|
|
# Check for errors
|
|
|
|
if [[ $? -ne 0 ]]; then
|
|
|
|
echo "there was a problem contacting the server"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
local error="$(echo "$result" | jq -r '.error')"
|
|
|
|
if [[ "$error" != "null" ]]; then
|
|
|
|
echo "Error: $error"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
echo "Music posted!"
|
2023-01-29 23:59:59 -05:00
|
|
|
exit 0
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-01-29 19:45:43 -05:00
|
|
|
# Post status with -p flag, command line.
|
|
|
|
post_status() {
|
2023-01-29 23:59:59 -05:00
|
|
|
curl -sS --oauth2-bearer "${oauth_token}" -H "Content-Type: ${content_type:-text/markdown}" \
|
2023-01-29 19:45:43 -05:00
|
|
|
-d "status=${@}" \
|
|
|
|
"${instanceURL}/api/v1/statuses"
|
|
|
|
exit 0
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-01-28 13:19:59 -05:00
|
|
|
# Variable initialization
|
|
|
|
configPath="${XDG_CONFIG_HOME:-$HOME/.config}/ratatoskr" # Path for settings, usually ~/.config/ratatoskr
|
2023-01-28 14:57:45 -05:00
|
|
|
configFile="default.conf" # The default config file, eventually will support multiple accounts.
|
2023-01-28 13:19:59 -05:00
|
|
|
softwareName="Ratatoskr" # The name of the client.
|
|
|
|
|
|
|
|
|
|
|
|
# Main code starts here
|
2023-01-28 14:57:45 -05:00
|
|
|
|
|
|
|
# make sure the configuration path exists:
|
|
|
|
mkdir -p "${configPath}"
|
|
|
|
|
2023-01-29 04:23:46 -05:00
|
|
|
# Associative array of command line parameters and short description of what they do.
|
|
|
|
declare -A command=(
|
2023-01-29 16:35:08 -05:00
|
|
|
[C]="Recreate default configuration file. Acquire new oauth token."
|
2023-01-29 04:23:46 -05:00
|
|
|
[h]="Help, show usage information for ${0##*/}."
|
|
|
|
[M]="Post the currently playing music track, requires playerctl."
|
2023-01-29 19:45:43 -05:00
|
|
|
[p:]="Post from the command line, e.g. ${0##*/} -p \"hello world\""
|
2023-01-29 23:59:59 -05:00
|
|
|
[S]="Scrobble the currently playing music track, requires playerctl."
|
2023-01-29 04:23:46 -05:00
|
|
|
)
|
|
|
|
|
2023-01-28 18:05:06 -05:00
|
|
|
# if the default file doesn't exist, create it
|
|
|
|
if [[ ! -e "${configPath}/${configFile}" ]]; then
|
|
|
|
get_oauth_token
|
2023-01-29 04:23:46 -05:00
|
|
|
else
|
|
|
|
# Read configuration file
|
|
|
|
source "${configPath}/${configFile}"
|
2023-01-28 18:05:06 -05:00
|
|
|
fi
|
2023-01-28 14:57:45 -05:00
|
|
|
|
2023-01-29 04:23:46 -05:00
|
|
|
# Handle command line parameters
|
|
|
|
# Convert the keys of the associative array to a format usable by getopts
|
|
|
|
args="${!command[*]}"
|
|
|
|
args="${args//[[:space:]]/}"
|
|
|
|
while getopts "${args}" i ; do
|
|
|
|
case "$i" in
|
2023-01-29 16:35:08 -05:00
|
|
|
C) get_oauth_token;;
|
2023-01-29 04:23:46 -05:00
|
|
|
h) help;;
|
|
|
|
M) post_music;;
|
2023-01-29 19:45:43 -05:00
|
|
|
p) post_status "${OPTARG}";;
|
2023-01-29 23:59:59 -05:00
|
|
|
S) scrobble_music;;
|
2023-01-29 04:23:46 -05:00
|
|
|
esac
|
|
|
|
done
|
|
|
|
|
|
|
|
|
2023-01-28 13:19:59 -05:00
|
|
|
exit 0
|