249 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			249 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/bin/sh
 | |
| 
 | |
| BOTNICK="uugbot2"
 | |
| SERVER="irc.uugrn.org"
 | |
| PORT="6660"
 | |
| CHANNEL="#bottest"
 | |
| 
 | |
| BOTDIR="$PWD"
 | |
| 
 | |
| IRCIN="$BOTDIR/irc/$SERVER/$CHANNEL/in"
 | |
| IRCOUT="$BOTDIR/irc/$SERVER/$CHANNEL/out"
 | |
| 
 | |
| ###
 | |
| ### FUNCTIONS ###
 | |
| ###
 | |
| 
 | |
| # $1 message
 | |
| say() {
 | |
|     echo "out> $1"
 | |
|     echo "$1" > $IRCIN
 | |
|     sleep 1
 | |
| }
 | |
| 
 | |
| settopic() {
 | |
|     curl -s "https://vorstand.uugrn.org/Kalender/Termine.rem" \
 | |
|         | remind -b1 -n - \
 | |
|         | sort \
 | |
|         | grep -vi vorstand \
 | |
|         | head -1 \
 | |
|         | while read -r line
 | |
|     do
 | |
|         date=$(echo "$line" \
 | |
|                 | cut -d" " -f 1 \
 | |
|                 | sed 's,\(....\)/\(..\)/\(..\),\3.\2.\1,g')
 | |
| 
 | |
|         time=$(echo "$line" \
 | |
|                 | cut -d" " -f 2)
 | |
| 
 | |
|         text=$(echo "$line" \
 | |
|                 | cut -d" " -f 3- \
 | |
|                 | cut -d"|" -f1 \
 | |
|                 | sed 's/ $//g')
 | |
| 
 | |
|         say "/topic $CHANNEL :Willkommen bei der UUGRN | Nächste Veranstaltung: $text am $date um $time Uhr."
 | |
|     done
 | |
| }
 | |
| 
 | |
| kalender() {
 | |
|     case "$1" in
 | |
|         [12345]) NUM=$1; ;;
 | |
|         *) say "Dieses Argument verstehe ich nicht (ignored)."; NUM=1; ;;
 | |
|     esac
 | |
|     curl -s "https://vorstand.uugrn.org/Kalender/Termine.rem" \
 | |
|         | remind -b1 -n - \
 | |
|         | sort \
 | |
|         | head -$NUM \
 | |
|         | while read -r line
 | |
|     do
 | |
|         date=$(echo "$line" \
 | |
|                 | cut -d" " -f 1 \
 | |
|                 | sed 's,\(....\)/\(..\)/\(..\),\3.\2.\1,g')
 | |
| 
 | |
|         time=$(echo "$line" \
 | |
|                 | cut -d" " -f 2)
 | |
| 
 | |
|         text=$(echo "$line" \
 | |
|                 | cut -d" " -f 3- \
 | |
|                 | cut -d"|" -f1 \
 | |
|                 | sed 's/ $//g')
 | |
| 
 | |
|         loc=$(echo "$line" \
 | |
|                 | cut -d" " -f 3- \
 | |
|                 | cut -d"|" -f 2-)
 | |
| 
 | |
|         if echo "$line" | fgrep -q ' |'
 | |
|         then
 | |
|             say "Am $date um $time Uhr findet \"$text\" im \"$loc\" statt."
 | |
|         else
 | |
|             say "Am $date um $time Uhr findet \"$text\" statt."
 | |
|         fi
 | |
|     done
 | |
| }
 | |
| 
 | |
| # $1 nick
 | |
| # $2 -1 decrease, +1 increase
 | |
| savekarma() {
 | |
|     [ ! -f "$BOTDIR/karma/$1" ] \
 | |
|         && echo 0 > "$BOTDIR/karma/$1"
 | |
| 
 | |
|     old=$(cat "$BOTDIR/karma/$1")
 | |
|     new=$(( old $2 ))
 | |
|     echo $new > "$BOTDIR/karma/$1"
 | |
|     say "$1 hat nun $new Gummipunkt(e)"
 | |
| }
 | |
| 
 | |
| # $1 nick
 | |
| reportkarma() {
 | |
|     n=$1
 | |
|     [ -z "$n" ] \
 | |
|         && n=$NICK
 | |
| 
 | |
|     if [ ! -f "$BOTDIR/karma/$n" ]
 | |
|     then
 | |
|         [ "$n" == "$NICK" ] \
 | |
|             && say "Du hast bisher leider noch keine Gummipunkte gesammelt, $n." \
 | |
|             || say "$n hat leider noch keine Gummipunkte gesammelt."
 | |
|     else
 | |
|         cur=$(cat "$BOTDIR/karma/$n")
 | |
|         [ "$n" == "$NICK" ] \
 | |
|             && say "Du hast momentan $cur Gummipunkt(e), $n." \
 | |
|             || say "$n hat momentan $cur Gummipunkt(e)."
 | |
|     fi
 | |
| }
 | |
| 
 | |
| karma() {
 | |
|     echo "karma: $1"
 | |
|     n="$(echo "$1" | tr -d "+-")"
 | |
|     [ -z "$n" ] && return
 | |
| 
 | |
|     [ "$n" == "$(echo "$NICK" | tr '[:upper:]' '[:lower:]' )" ] \
 | |
|         && say "So aber nicht mein lieber $NICK!" && return
 | |
| 
 | |
|     echo "$1" | fgrep -q -- "++" \
 | |
|         && savekarma $n "+1"
 | |
|     echo "$1" | fgrep -q -- "--" \
 | |
|         && savekarma $n "-1"
 | |
|     echo "$1" | fgrep -q -- "+-" \
 | |
|         && say "Echt jetzt, $NICK?"
 | |
|     echo "$1" | fgrep -q -- "-+" \
 | |
|         && say "Echt jetzt, $NICK?"
 | |
| }
 | |
| transparenzbericht() {
 | |
|     cd $BOTDIR/karma
 | |
|     say "Gummipunkte Transparenzbericht:"
 | |
|     for i in $(ls)
 | |
|     do
 | |
|         say "$i: $(cat "$i") Gummipunkte"
 | |
|     done
 | |
| }
 | |
| 
 | |
| seen() {
 | |
|     # TODO the newer ii saves unix timestamps. We could detect that and
 | |
|     # parse it on output (or input)
 | |
|     [ -z "$1" ] && return
 | |
|     [ -f "$BOTDIR/seen/$1" ] \
 | |
|         && say "$(cat "$BOTDIR/seen/$1")" \
 | |
|         || say "Hmm, ich habe keine Ahnung wann $1 zum letzten mal online war."
 | |
| }
 | |
| 
 | |
| usage() {
 | |
|     say "!kalender <anzahl>  - zeigt die nächsten Termine im UUGRN Kalender (max 5)"
 | |
|     say "!wetter <ort>       - zeigt das Wetter an <ort> oder Heidelberg"
 | |
|     say "!punkte <nick>      - zeigt den Gummipunktlevel von <nick> oder dir selbst an"
 | |
|     say "!transparenzbericht - zeigt den Gummipunkte Transparenzbericht an"
 | |
|     say "<nick>++            - vergibt einen Gummipunkt an <nick>"
 | |
|     say "<nick>--            - nimmt <nick> einen Gummipunkt weg"
 | |
|     say "!seen <nick>        - zeigt die letzte Nachricht von <nick> an"
 | |
|     say "!settopic           - setzt das topic mit dem nächsten Event im Kalender"
 | |
|     say "!hilfe              - zeigt diesen hilfetext an"
 | |
| 
 | |
| }
 | |
| 
 | |
| # $1 loc
 | |
| weather() {
 | |
|     l=$1
 | |
|     [ -z "$l" ] \
 | |
|         && l=heidelberg
 | |
|     say "$(curl -s "https://wttr.in/$l?lang=de&format=%l:+%t+%C+%w+%h+Regen")"
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| ###
 | |
| ### MAIN PROGRAM ###
 | |
| ###
 | |
| 
 | |
| mkdir -p "$BOTDIR/irc"
 | |
| mkdir -p "$BOTDIR/seen"
 | |
| mkdir -p "$BOTDIR/karma"
 | |
| cd "$BOTDIR"
 | |
| 
 | |
| # Connect ii and join channel. Afterwards $IRCIN and $IRCOUT are
 | |
| # available
 | |
| 
 | |
| echo "connecting."
 | |
| ii -i $BOTDIR/irc -s $SERVER -p $PORT -n $BOTNICK &
 | |
| PID=$!
 | |
| sleep 1
 | |
| echo "/join $CHANNEL" > $BOTDIR/irc/$SERVER/in
 | |
| sleep 1
 | |
| echo "ready."
 | |
| 
 | |
| # Listen on $IRCOUT, parse input and call functions once something
 | |
| # of interest gets posted.
 | |
| tail -n 0 -f "$IRCOUT" \
 | |
|     | while read -r line
 | |
| do
 | |
|     NICK=$(echo "$line" \
 | |
|                 | sed -n 's/^....-..-.. ..:.. <\([^>]*\).*/\1/p')
 | |
| 
 | |
|     if [ -z "$NICK" ]
 | |
|     then
 | |
| 
 | |
|     # the newer ii is using unix timestamps
 | |
|     NICK=$(echo "$line" \
 | |
|                 | sed -n 's/^[0-9]* <\([^>]*\).*/\1/p')
 | |
|     fi
 | |
| 
 | |
|     # prevent loops; so the bot can't trigger itself.
 | |
|     [ "$NICK" == "$BOTNICK" ] \
 | |
|         && continue
 | |
| 
 | |
|     COMMAND=$(echo "$line" \
 | |
|                 | tr '[:upper:]' '[:lower:]' \
 | |
|                 | sed -n 's|.*\(![a-z]*\).*|\1|p')
 | |
| 
 | |
|     # intentionally limiting the argument to one and also limit the
 | |
|     # character set for safety reasons.
 | |
|     ARG=$(echo "$line" \
 | |
|                 | tr '[:upper:]' '[:lower:]' \
 | |
|                 | sed -n 's|.*![a-z]* \([a-zA-Z0-9\-_+]*\).*|\1|p')
 | |
| 
 | |
|     # We call it gummipunkte now.
 | |
|     KARMA=$(echo "$line" \
 | |
|                 | tr '[:upper:]' '[:lower:]' \
 | |
|                 | sed -n 's|.* \([a-zA-Z0-9\-_]*[+-][+-]\).*|\1|p')
 | |
| 
 | |
|     echo "in> $line"
 | |
|     echo "in> NICK=$NICK, COMMAND=$COMMAND, ARG=$ARG, KARMA=$KARMA"
 | |
| 
 | |
|     # we just save the line and replay it on the !seen command
 | |
|     [ ! -z "$NICK" ] \
 | |
|         && echo "$line" > "$BOTDIR/seen/$NICK"
 | |
| 
 | |
|     case "$COMMAND" in
 | |
|         "!kalender") kalender $ARG; ;;
 | |
|         "!punkte") reportkarma $ARG; ;;
 | |
|         "!transparenzbericht") transparenzbericht; ;;
 | |
|         "!wetter") weather $ARG; ;;
 | |
|         "!hilfe") usage; ;;
 | |
|         "!settopic") settopic; ;;
 | |
|         "!seen") seen $ARG; ;;
 | |
|     esac
 | |
| 
 | |
|     case "$KARMA" in
 | |
|         *[+-][+-]) karma $KARMA; ;;
 | |
|     esac
 | |
| done
 |