#!/bin/sh #――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # Name: librejam_irc_process # Desc: Part of a game-jam chatbot. Processes lines of `ii` output from stdin # as chat commands. Outputs text to be sent to the chatroom. # Should probably not be run manually, but instead by librejam_irc. # Reqs: librejam_gemini # Date: 2022-03-30 #――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― line_date() { sed 's% .*%%' } line_sender() { line_sanitize \ | awk '{print $3}' \ | tr -d '<>' } line_message() { line_sanitize \ | after_column 3 } line_command() { line_message \ | awk '{print $1}' \ | grep '^!' } line_args() { line_message \ | after_column 1 } line_sanitize() { tr -d '$`{}^%\\' } after_column() { local column_no="$1" cut -sd ' ' -f "$((column_no+1))"- } ensure_file() { local path="$1" touch "$path" if test ! -e "$path"; then >&2 echo "${path} cannot be created; do you have write permission for this directory?" return 3 elif test ! -w "$path" -o ! -r "$path"; then >&2 echo "${path} is either not readable or not writible-- please check your permissions." return 3 fi } ensure_directory() { local path="$1" mkdir -p "$path" if test ! -d "$path"; then >&2 echo "$path isn't an accessible directory." return 2 fi } remove_line() { local path="$1" local line="$2" local tmp="$(mktemp)" grep -v "$line" "$path" \ > "$tmp" cat "$tmp" \ > "$path" echo "$line" \ >> "$path.old" } sanitize() { sed 's% %-%g' \ | tr 'A-Z' 'a-z' \ | sed 's% $%%' } init_gemini() { local sender="$1"; local url="$2"; local branch="$3"; local name="$4" local outname="$(echo "$name" | sanitize)" librejam_gemini "$sender" "$url" "$branch" "$name" "$SUBMISSIONS_DIR" \ "$ratings_path" \ > "$SUBMISSIONS_DIR/${outname}/${outname}.gmi" } update_gemini() { local sender="$1"; local url="$2"; local branch="$3"; local name="$4" local ratings_path="$5" local outname="$(echo "$name" | sanitize)" ensure_directory "$SUBMISSIONS_DIR/${outname}/" ensure_directory "$(dirname "$ratings_path")" librejam_gemini "$sender" "$url" "$branch" "$name" "$SUBMISSIONS_DIR" \ "$ratings_path" \ > "$SUBMISSIONS_DIR/${outname}/${outname}.gmi" case "$?" in 0) return 0 ;; 1) echo "$sender: I had trouble cloning your git repo― did you give me the right URL?" ;; 2) echo "$sender: Couldn't switch to the $branch branch― does $branch even exist?" ;; 3) echo "$sender: Couldn't download the archive― did you give the right URL?" ;; esac return 2 } HELP_SUBMIT="!submit [-b branch] . Submit a Librejam entry, either with a Git repository or archive over FTP/HTTP/etc. . If submitting a Git repository, you must specify the branch with the -b . argument. You can update your submission until the jam ends by re-running . this command." submit_cmd() { local args="$1"; local sender="$2" local entries="$SUBMISSIONS_DIR/entries.txt" local url="$(echo "$args" | awk '{print $1}')" local branch="$(echo "$args" | awk '{print $3}')" local name="$(echo "$args" | after_column 3)" if test ! "$(echo "$args" | awk '{print $2}')" = "-b"; then branch=":curl" name="$(echo "$args" | after_column 1)" fi ensure_file "$entries" ensure_file "$entries.old" if test "$SUBMITTING_ENDS" -le "$(date +%s)"; then echo "$sender: Sorry, but the time for submissions is over!" return fi # Just in case they've already submitted local prev_entry="$(grep "^$sender" "$entries")" if test -z "$prev_entry" -a -z "$name" -o -z "$url"; then echo "$sender: Please provide all arguments to submit!" return fi # If they've already submitted, replace empty args with implied values if test -z "$name" -a -n "$prev_entry"; then name="$(echo "$prev_entry" | after_column 3)" fi if test -z "$branch" -a -n "$prev_entry"; then branch="$(echo "$prev_entry" | awk '{print $3}')" fi if test -z "$url" -a -n "$prev_entry"; then url="$(echo "$prev_entry" | awk '{print $2}')" fi submit_game "$sender" "$prev_entry" "$url" "$branch" "$name" } submit_game() { local sender="$1"; local prev_entry="$2" local url="$3"; local branch="$4"; local name="$5" local entries="$SUBMISSIONS_DIR/entries.txt" local outname="$(echo "$name" | sanitize)" update_gemini "$sender" "$url" "$branch" "$name" if test "$?" -eq 0; then # Remove previous entry, if necessary if test -n "$prev_entry"; then remove_line "$entries" "$prev_entry" fi echo "$sender $url $branch $name" \ >> "$entries" if test "$branch" = ":curl"; then echo "$sender: $name has been submitted from archive!" else echo "$sender: $name has been submitted from git!" fi fi } HELP_RATE="!rate <1-10> [comment] . Submit your rating on a given game, with an optional comment. If you rate . a single game multiple times, the latest rating will be used." rate_cmd() { local args="$1"; local sender="$2" local id="$(echo "$args" | awk '{print $1}')" local rating="$(echo "$args" | awk '{print $2}')" local comment="$(echo "$args" | after_column 2)" local entries="$SUBMISSIONS_DIR/entries.txt" local now="$(date +%s)" if test "$now" -le "$SUBMITTING_ENDS" -o "$now" -gt "$RATING_ENDS"; then echo "$sender: Sorry, it's not time to rate!" return fi if test "$rating" -lt 1 -o "$rating" -gt 10; then echo "$sender: That's an invalid rating, sorry!" return fi local entry_count="$(wc -l "$entries" | awk '{print $1}')" if test "$id" -lt 1 -o "$id" -gt "$entry_count"; then echo "$sender: That's… that's not an ID. Try below $entry_count." return fi local entry="$(awk 'NR=='"$id" "$entries")" local outname="$(echo "$entry" | after_column 3 | sanitize)" local ratings="$SUBMISSIONS_DIR/${outname}/ratings.txt" ensure_directory "$(dirname "$ratings")" ensure_file "$ratings" if test "$sender" = "$(echo "$entry" | awk '{print $1}')"; then echo "$sender: … You can't rate your own game! xD" return fi local prev_rating="$(grep "^$sender" "$ratings" | head -1)" if test -n "$prev_rating"; then remove_line "$ratings" "$prev_rating" fi echo "$sender $rating $comment" \ >> "$ratings" echo "$sender: Rating accepted!" update_gemini "$(echo "$entry" | awk '{print $1}')" \ "$(echo "$entry" | awk '{print $2}')" \ "$(echo "$entry" | awk '{print $3}')" \ "$(echo "$entry" | after_column 3)" \ "$ratings" } HELP_LIST="!list . List all games submitted for the jam." list_cmd() { local entries="$SUBMISSIONS_DIR/entries.txt" local index="1" while read entry; do if test -n "$entry"; then local name="$(echo "$entry" | after_column 3)" echo "$entry" \ | awk '{ printf("[%s] %s | By %s | %s\n", '"$index"', "'"$name"'", $1, $2) }' index="$((index + 1))" fi done < "$entries" } HELP_ABOUT="!about . … you could just try the command. It won't bite." about_cmd() { local sender="$2" echo "$sender: I'm a bot made for Librejam (gemini://leagueh.xyz/en/librejam)." echo "My sauce is at https://github.com/jadedctrl/librejam-omnom/" echo "Current submissions are at gemini://xwx.moe/librejam/" echo "Submissions end at: $(date -ud @"$SUBMITTING_ENDS")" echo "Rating ends at: $(date -ud @"$RATING_ENDS")" } HELP_HELP="!help . … do I really have to explain this one? &2 echo "Usage: $(basename "$0") nick entry_dir submit_deadline rate_deadline" exit 1 fi ensure_directory "$SUBMISSIONS_DIR" while read line; do if echo "$line" | grep "^....-..-.. ..:.. Closing link" >/dev/null; then >&2 echo "ii has disconnected!" exit 2; fi echo "$line" | grep "<$NICK>" > /dev/null if test "$?" -ne 0; then process_line "$line" fi done