This commit is contained in:
Jordan Bancino 2022-11-11 01:07:49 +00:00
parent c7a358150c
commit 6776db5ff9
6 changed files with 194 additions and 26 deletions

View file

@ -32,7 +32,7 @@ Due: July 1, 2023
making it a separate block, there's less of a chance of the
information getting destroyed. It's worth a few extra bytes of
memory to make accidents harder, I think.
[ ] Add recipe to td script to upload patches to the Matrix room
[x] Add recipe to td script to upload patches to the Matrix room
[ ] Figure out how to write unit tests for array/hashmap/etc
[~] Convert documentation to man pages
[~] Internal API docs

View file

@ -1,4 +1,4 @@
.Dd $Mdocdate: November 6 2022 $
.Dd $Mdocdate: November 11 2022 $
.Dt TELODENDRIA-CONTRIBUTING 7
.Os Telodendria Project
.Sh NAME
@ -161,9 +161,8 @@ consistent with this project or the open source licenses involved.
If you agree to the above, fill in the square brackets with an 'x', and then after
the headers, but before the checkbox, write a more thorough description of the
patch and why it was created. Then, send the resulting patch file to the public
Matrix room, as noted in
.Xr telodendria 7 ,
so it can be discussed and reviewed by the community.
Matrix room using
.Xr send-patch 1 .
.sp
Try to keep your patches on topic\(emmake one patch file per feature or bug fix
being implemented. It is okay if your patches depend on previous patches, just

170
tools/bin/send-patch Executable file
View file

@ -0,0 +1,170 @@
#!/usr/bin/env sh
#
# send-patch: "The Telodendria Patch Sender"
#
# This is a simple script for posting patch files to
# a single room(generally the Telodendria patch room.)
. "$(pwd)/tools/lib/common.sh"
# Path to the patch to send.
PATCHFILE="$1"
# Tries to decompose the name and the HS from an MXID using
# sed.
UR_NAME="$(echo "$MXID" | sed "s/\@\(.*\)\:\(.*\)/\1/")"
HS_NAME="$(echo "$MXID" | sed "s/\@\(.*\)\:\(.*\)/\2/")"
# Prompts the user for a password, while disabling echo-ing.
readpwd() {
printf "$1"
stty -echo -ctlecho
read -r "$2"; echo
stty echo ctlecho
}
# Calls curl, setting the RETURN variable for the actual
# reply from the server and the ERROR_CODE variable for a
# HTTP error code.
curlec() {
RETURN="$(curl -w "\n%{http_code}" "$@" 2> /dev/null)"
ERROR_CODE="$(echo "$RETURN" | tail -n1)"
RETURN="$(echo "$RETURN" | head -n"-1")"
}
# Prompts user to login and gives out an access token to use
# in the ACCESS_TOKEN variable
matrix_login() {
# Check authentication methods
echo "Checking authentication methods..."
curlec "$HS_BASE/_matrix/client/v3/login"
AUTH_METHODS=$RETURN
if [ $ERROR_CODE -ne 200 ]; then
echo "Homeserver does not support login."
exit 1;
fi;
SUPPORTS_PASSWORD="$(echo "$AUTH_METHODS" | jq -r '.flows[].type' | grep "m.login.password" | wc -l)"
if [ $SUPPORTS_PASSWORD -lt 1 ]; then
echo "Homeserver does not support password authentication."
exit 1;
fi;
# Homeserver does support password authentication, so request
# them one.
if [ -z "$MXPW" ]; then
readpwd "Enter your Matrix password: " MXPW
fi
# Tries to login using the "Telodendria Patch Script" device
# name
JSON="$(jq --null-input \
--arg username "$UR_NAME" \
--arg password "$MXPW" \
--arg idtype "m.id.user" \
--arg passwordtype "m.login.password" \
'{
"identifier": {
"type": $idtype,
"user": $username
},
"initial_device_display_name": "Telodendria Patch Script",
"type": $passwordtype,
"password": $password
}')"
curlec -X POST $HS_BASE/_matrix/client/v3/login --data "$JSON"
LOGIN=$RETURN
if [ $ERROR_CODE -ne 200 ]; then
echo "Login failed."
exit 1;
fi;
ACCESS_TOKEN="$(echo "$LOGIN" | jq -r .access_token)"
}
# Logs out of Matrix using the ACFESS_TOKEN environment variable
matrix_logout() {
if [ -z "$ACCESS_TOKEN" ]; then
echo "No access token"
exit 1
fi
curlec -X POST $HS_BASE/_matrix/client/v3/logout -H "Authorization: Bearer $ACCESS_TOKEN"
LOGOUT=$RETURN
if [ $ERROR_CODE -ne 200 ]; then
echo "Logout failed."
exit 1
fi;
echo "Logged out."
}
send_patch() {
if [ -z "$ACCESS_TOKEN" ]; then
matrix_login
DO_LOGOUT=1
fi
# We are sucessfully logged in as our user, now let's
# try to upload and post our patch
echo "$PATCHFILE"
curlec -X POST "$HS_BASE/_matrix/media/v3/upload" \
-H "Content-Type: text/x-patch" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-T "$PATCHFILE"
MXCID=$RETURN
if [ $ERROR_CODE -ne 200 ]; then
echo "Upload failed."
matrix_logout
exit 1;
fi;
MXCID="$(echo "$MXCID" | jq -r .content_uri)"
echo "MXC ID: $MXCID"
JSON="$(jq --null-input \
--arg name "$(basename "$PATCHFILE")" \
--arg mxc "$MXCID" \
--arg msgtype "m.file" \
--argjson size "$(wc -c "$PATCHFILE" | cut -d" " -f1)" \
'{
"body": $name,
"filename": $name,
"info": {
"mimetype": "text/x-patch",
"size": $size
},
"msgtype": $msgtype,
"url": $mxc
}')"
curl \
-X PUT \
-H "Authorization: Bearer $ACCESS_TOKEN" \
"$HS_BASE/_matrix/client/v3/rooms/$PATCHES_ROOM/send/m.room.message/$(date +%s)" \
--data "$JSON" 2> /dev/null > /dev/null && echo "Patch sent."
# Log out if we generated an access token
if [ "$DO_LOGOUT" -eq "1" ]; then
matrix_logout
fi
}
# Check if the patch file is valid.
if [ "$(basename "$PATCHFILE" .patch)" = "$PATCHFILE" ] || [ ! -f "$PATCHFILE" ]; then
echo "Format: $0 file.patch"
exit 1
fi
echo "Sending file '$PATCHFILE'"
echo "Checking homeserver's real address using .well-known..."
curlec "$HS_NAME/.well-known/matrix/client"
case "$ERROR_CODE" in
"200")
WELL_KNOWN=$RETURN
if [ -z "$WELL_KNOWN" ]; then
echo "well-known test returned 200 but no correct input was given."
exit 1
fi
# well-known entry is correct, we can now store our base endpoint
HS_BASE="$(printf "$WELL_KNOWN" | jq -r '.["m.homeserver"].base_url')" && send_patch
;;
* )
echo "$ERROR_CODE"
echo "well-known test failed."
printf "Please enter your homeserver base URL: "
read -r HS_BASE; echo
send_patch
;;
esac

View file

@ -32,14 +32,7 @@
: "${PREFIX:=/usr/local}"
# If a .env file exists in the current directory, we load it.
# As Telodendria's build infrastructure relies heavily on
# environment variables, we allow users to specify their
# Telodendria-specific variables in a dedicated .env so they don't
# have to pollute their environment.
if [ -f "$(pwd)/.env" ]; then
. "$(pwd)/.env"
fi
. "$(pwd)/tools/lib/common.sh"
if [ "$DEBUG" = "1" ]; then
CFLAGS="$CFLAGS -O0 -g"

View file

@ -4,17 +4,7 @@
#
# This script is used to manage the patch queue.
if [ -f "$(pwd)/.env" ]; then
. "$(pwd)/.env"
fi
if [ -z "$MXID" ]; then
MXID="@(${USER}:$(hostname)"
fi
if [ -z "$DISPLAY_NAME" ]; then
DISPLAY_NAME=$(getent passwd "$USER" | cut -d ':' -f 5 | cut -d ',' -f 1)
fi
. "$(pwd)/tools/lib/common.sh"
if [ -z "$TELODENDRIA_PUB" ]; then
echo "TELODENDRIA_PUB not set."
@ -39,13 +29,13 @@ matrix_send() {
--arg format "org.matrix.custom.html" \
--arg msgtype "m.text" \
'{"body":$body,"formatted_body":$formatted_body,"format":$format,"msgtype":$msgtype}' |
$CURL -X PUT -d @- "$HOMESERVER/client/v3/rooms/$ROOM_ID/send/m.room.message/$(date +%s)?access_token=$ACCESS_TOKEN"
$CURL -X PUT -d @- "$HOMESERVER/client/v3/rooms/$PATCHES_ROOM/send/m.room.message/$(date +%s)?access_token=$ACCESS_TOKEN"
fi
}
matrix_get_files() {
$CURL "$HOMESERVER/client/v3/sync?access_token=$ACCESS_TOKEN" |
jq ".rooms.join.\"$ROOM_ID\".timeline.events[] | select(.type==\"m.room.message\") | .content | select(.msgtype==\"m.file\") | [.body,.info.size,.url] | @tsv" |
jq ".rooms.join.\"$PATCHES_ROOM\".timeline.events[] | select(.type==\"m.room.message\") | .content | select(.msgtype==\"m.file\") | [.body,.info.size,.url] | @tsv" |
cut -d '"' -f 2 |
sed 's/\\t/,/g'
}

16
tools/lib/common.sh Normal file
View file

@ -0,0 +1,16 @@
#!/usr/bin/env sh
: "${PATCHES_ROOM:=!tyDHfIvAyfImrzOVVt:bancino.net}"
if [ -f "$(pwd)/.env" ]; then
. "$(pwd)/.env"
fi
if [ -z "$MXID" ]; then
MXID="@${USER}:$(hostname)"
fi
if [ -z "$DISPLAY_NAME" ]; then
DISPLAY_NAME=$(getent passwd "$USER" | cut -d ':' -f 5 | cut -d ',' -f 1)
fi