Initial commit. - annna - Annna the nice friendly bot. | |
git clone git://bitreich.org/annna/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws6… | |
Log | |
Files | |
Refs | |
Tags | |
README | |
--- | |
commit a63f21cd1ad027bdff057acf9ee6d44273f778fa | |
Author: Annna Robert-Houdin <[email protected]> | |
Date: Sun, 4 Feb 2018 12:53:46 +0000 | |
Initial commit. | |
Diffstat: | |
A BUGS.md | 13 +++++++++++++ | |
A annna-alive | 11 +++++++++++ | |
A annna-checker | 21 +++++++++++++++++++++ | |
A annna-checker-dbg | 25 +++++++++++++++++++++++++ | |
A annna-say | 49 +++++++++++++++++++++++++++++… | |
A annna-shutdown | 10 ++++++++++ | |
A annna-start | 60 +++++++++++++++++++++++++++++… | |
A annna-start-services | 166 +++++++++++++++++++++++++++++… | |
A annna-stop | 6 ++++++ | |
A annna-stop-checker | 6 ++++++ | |
A annna-stop-services | 4 ++++ | |
A phlog-index | 136 +++++++++++++++++++++++++++++… | |
12 files changed, 507 insertions(+), 0 deletions(-) | |
--- | |
diff --git a/BUGS.md b/BUGS.md | |
@@ -0,0 +1,13 @@ | |
+# BUGS | |
+ | |
+* annna is disconnecting now and then from IRC | |
+ * scaleway issue? | |
+ * socat? | |
+ * ii? | |
+* listening for commands on channels does not properly work | |
+ * better event handling? | |
+ * see $HOME/bin/initimate-annna.sh for the handlers | |
+ * enter-annnas-world.sh is starting the script | |
+* access rights to channels are o+rw | |
+ * add a group for annna users | |
+ | |
diff --git a/annna-alive b/annna-alive | |
@@ -0,0 +1,11 @@ | |
+#!/bin/sh | |
+# | |
+# Check if annna is alive. | |
+# Use it this way: | |
+# | |
+# if annna-alive; then do-something; fi | |
+# | |
+ | |
+[ -z "$(pgrep -U annna -x socat)" ] && exit 1 | |
+exit 0 | |
+ | |
diff --git a/annna-checker b/annna-checker | |
@@ -0,0 +1,21 @@ | |
+#!/bin/sh | |
+# | |
+# Watch for annna, she's worth it. | |
+# | |
+ | |
+export PATH="$PATH:/home/annna/bin" | |
+ | |
+while /bin/true; | |
+do | |
+ # Is annna still in her world? | |
+ pid="$(pgrep -U annna -x socat)" | |
+ | |
+ if [ -z "$pid" ]; | |
+ then | |
+ annna-stop-services >/dev/null 2>&1 | |
+ annna-start >/dev/null 2>&1 | |
+ fi | |
+ | |
+ sleep 5 | |
+done | |
+ | |
diff --git a/annna-checker-dbg b/annna-checker-dbg | |
@@ -0,0 +1,25 @@ | |
+#!/bin/sh | |
+# | |
+# Watch for annna, she's worth it. | |
+# | |
+ | |
+export PATH="$PATH:/home/annna/bin" | |
+ | |
+logfile="/home/annna/output.log" | |
+ | |
+while /bin/true; | |
+do | |
+ # Is annna still in her world? | |
+ pid="$(pgrep -U annna -x socat)" | |
+ | |
+ if [ -z "$pid" ]; | |
+ then | |
+ annna-stop-services >/dev/null 2>&1 | |
+ annna-start 2>&1 \ | |
+ | grep -v -e ' PRIVMSG ' -e ' JOIN ' -e ' PART ' \ | |
+ >> "$logfile" | |
+ fi | |
+ | |
+ sleep 5 | |
+done | |
+ | |
diff --git a/annna-say b/annna-say | |
@@ -0,0 +1,49 @@ | |
+#!/bin/sh | |
+# | |
+# annna-say -c '#bitreich-en' Hello World! | |
+# | |
+ | |
+export PATH="$PATH:/home/annna/bin" | |
+ | |
+usage() { | |
+ printf "usage: %s [-h] [-i ircbase] -c \"channel0 ... channel1 ...\" t… | |
+ "$(basename "$1")" >&2 | |
+ exit 1 | |
+} | |
+ | |
+channels="" | |
+ircbase="/home/annna/irc/chat.freenode.net" | |
+ | |
+while getopts "hb:c:" opt; | |
+do | |
+ case $opt in | |
+ b) | |
+ ircbase="$OPTARG" | |
+ ;; | |
+ c) | |
+ channels="$OPTARG" | |
+ ;; | |
+ *) | |
+ usage $0 | |
+ ;; | |
+ esac | |
+done | |
+shift $(expr $OPTIND - 1) | |
+ | |
+[ -z "$channels" ] && usage $0 | |
+ | |
+# If annna is not alive, do not bother. | |
+annna-alive || exit 0 | |
+ | |
+for c in $channels; | |
+do | |
+ ircpath="${ircbase}/$c" | |
+ | |
+ if [ -e "$ircpath/in" ]; | |
+ then | |
+ printf "%s\n" "$@" > "${ircpath}/in" | |
+ fi | |
+done | |
+ | |
+exit 0 | |
+ | |
diff --git a/annna-shutdown b/annna-shutdown | |
@@ -0,0 +1,10 @@ | |
+#!/bin/sh | |
+# | |
+# Dare you to execute this script! You are cruel! | |
+# | |
+ | |
+export PATH="$PATH:/home/annna/bin" | |
+ | |
+annna-stop | |
+annna-stop-services | |
+ | |
diff --git a/annna-start b/annna-start | |
@@ -0,0 +1,60 @@ | |
+#!/bin/sh | |
+ | |
+export PATH="$PATH:/home/annna/bin" | |
+ | |
+# #bitreich is a forward to #bitreich-en. Annna does not need to join it. | |
+#channels="#bitreich #bitreich-con #bitreich-radio | |
+# #bitreich-scm #bitreich-en #bitreich-de" | |
+channels="#bitreich-con #bitreich-radio | |
+ #bitreich-scm #bitreich-en #bitreich-de | |
+ #bitreich-fr #bitreich-cooking" | |
+ | |
+rm -rf $HOME/irc | |
+mkdir -p $HOME/irc | |
+cd $HOME/irc | |
+rm -f $HOME/freenode.sock | |
+ | |
+# Connect | |
+socat openssl:chat.freenode.net:6697,keepalive,keepcnt=5,keepidle=1,keepintvl=… | |
+ unix-l:$HOME/freenode.sock & | |
+while [ ! -e $HOME/freenode.sock ]; | |
+do | |
+ sleep 0.5 | |
+done | |
+ | |
+ii -s chat.freenode.net -u $HOME/freenode.sock -n annna -f "Annna Robert-Houdi… | |
+ | |
+sleep 5 | |
+ | |
+# Nickserv Auth | |
+ircuser="$(grep user $HOME/irc-credentials.txt | cut -d' ' -f 2)" | |
+ircpass="$(grep pass $HOME/irc-credentials.txt | cut -d' ' -f 2)" | |
+printf "/privmsg nickserv :identify %s %s\n" "${ircuser}" "${ircpass}" \ | |
+ > chat.freenode.net/in | |
+sleep 0.5 | |
+ | |
+# Join Channels | |
+for chan in ${channels}; | |
+do | |
+ printf "/j %s\n" "${chan}" > chat.freenode.net/in | |
+ sleep 0.5 | |
+done | |
+ | |
+# Give permissions to certain channels. | |
+chmod o+rx $HOME/irc | |
+chmod o+rx $HOME/irc/chat.freenode.net | |
+## EN Channel | |
+chmod o+rx "$HOME/irc/chat.freenode.net/#bitreich-en" | |
+chmod o+w "$HOME/irc/chat.freenode.net/#bitreich-en/in" | |
+## SCM | |
+chmod o+rx "$HOME/irc/chat.freenode.net/#bitreich-scm" | |
+chmod o+w "$HOME/irc/chat.freenode.net/#bitreich-scm/in" | |
+## Radio | |
+chmod o+rx "$HOME/irc/chat.freenode.net/#bitreich-radio" | |
+chmod o+w "$HOME/irc/chat.freenode.net/#bitreich-radio/in" | |
+ | |
+# Allow commands. | |
+sleep 6 | |
+ | |
+annna-start-services | |
+ | |
diff --git a/annna-start-services b/annna-start-services | |
@@ -0,0 +1,166 @@ | |
+#!/bin/sh | |
+# | |
+# Here follow scriplets to listen for commands in annna. | |
+# If this gets too unmaintainable, consider adding some directory structure. | |
+# | |
+ | |
+brmembers="__20h__ Evil_Bob chripo posativ quinq stateless solene josuah" | |
+ | |
+botname="annna" | |
+iibase="/home/annna/irc/chat.freenode.net" | |
+function annna_say { | |
+ channel="$1" | |
+ shift 1 | |
+ | |
+ [ $# -lt 1 ] && exit 1 | |
+ | |
+ if [ -e "${iibase}/${channel}/in" ]; | |
+ then | |
+ printf "%s\n" "$@" > "${iibase}/${channel}/in" | |
+ # No spamming allowed. | |
+ sleep 0.5 | |
+ else | |
+ # Might be a user. | |
+ printf "/j %s %s\n" "$channel" "$@" > "${iibase}/in" | |
+ fi | |
+} | |
+ | |
+echo '12345 <unknown> a' > ${iibase}/#bitreich-radio/out | |
+sleep 1 | |
+# bitreich-radio | |
+{ | |
+ #tail -f -n 1 "${iibase}/#bitreich-radio/out" \ | |
+ ls "${iibase}/#bitreich-radio/out" | entr tail -n 1 "${iibase}/#bitrei… | |
+ | sed -u 's,[0-9]* <\([^ >]*\)> \(.*\)$,\1\n\2,' \ | |
+ | { | |
+ while read user; | |
+ do | |
+ read text | |
+ echo "$user" | |
+ echo "$text" | |
+ | |
+ | |
+ [ "$user" = "${botname}" ] && continue | |
+ | |
+ if [ "${text}" = "${botname}, next please" ]; | |
+ then | |
+ /br/bin/bitreich-radio-playlist-next | |
+ annna_say "#bitreich-radio" "You are very kind ${user}… | |
+ continue; | |
+ fi | |
+ | |
+ if [ "${text}" = "${botname}, please help" ]; | |
+ then | |
+ annna_say "${user}" "»next please« gets the playlist… | |
+ annna_say "${user}" "»please help« gives you this he… | |
+ continue; | |
+ fi | |
+ done | |
+ } | |
+} & | |
+ | |
+echo '12345 <unknown> a' > ${iibase}/#bitreich-en/out | |
+sleep 1 | |
+# bitreich-en | |
+{ | |
+ ls "${iibase}/#bitreich-en/out" | entr tail -n 1 "${iibase}/#bitreich-… | |
+ | sed -u 's,[0-9]* <\([^ >]*\)> \(.*\)$,\1\n\2,' \ | |
+ | { | |
+ while read user; | |
+ do | |
+ read text | |
+ | |
+ ismember=0 | |
+ for member in $brmembers; | |
+ do | |
+ [ "$user" = "$member" ] && ismember=1 | |
+ done | |
+ [ $ismember -lt 1 ] && continue | |
+ [ "$user" = "${botname}" ] && continue | |
+ | |
+ if [ "${text}" = "${botname}, can you show me the uptime pleas… | |
+ then | |
+ annna_say "#bitreich-en" "$(hostname) uptime: $(uptime… | |
+ continue; | |
+ fi | |
+ | |
+ if [ "${text}" = "${botname}, please give me the count of onli… | |
+ then | |
+ annna_say "#bitreich-en" "$(hostname): $(who -q | tail… | |
+ continue; | |
+ fi | |
+ | |
+ if [ "${text}" = "${botname}, please roll a dice for me." ]; | |
+ then | |
+ annna_say "#bitreich-en" "$((($RANDOM % 6) + 1))" | |
+ continue; | |
+ fi | |
+ | |
+ if [ "${text}" = "${botname}, please tell me your favourite fl… | |
+ then | |
+ annna_say "#bitreich-en" "My favourite flower is the b… | |
+ continue; | |
+ fi | |
+ | |
+ if [ "${text}" = "${botname}, please tell me your favourite co… | |
+ then | |
+ annna_say "#bitreich-en" "My favourite color is yellow… | |
+ continue; | |
+ fi | |
+ | |
+ if [ "${text}" = "${botname}, please dance with me." ]; | |
+ then | |
+ if [ $(($RANDOM % 2)) -gt 0 ]; | |
+ then | |
+ annna_say "#bitreich-en" "I am not that kind o… | |
+ else | |
+ annna_say "#bitreich-en" "Thank you! Let us da… | |
+ fi | |
+ | |
+ continue; | |
+ fi | |
+ | |
+ if [ "${text}" = "${botname}, please tell me who is your favou… | |
+ then | |
+ annna_say "#bitreich-en" "My favourite pleasure man is… | |
+ continue; | |
+ fi | |
+ | |
+ if [ "${text}" = "${botname}, sudo make me a sandwich" ]; | |
+ then | |
+ annna_say "#bitreich-en" "Humans are no objects." | |
+ continue; | |
+ fi | |
+ | |
+ if [ "${text}" = "${botname}, sudo please make me a sandwich" … | |
+ then | |
+ annna_say "#bitreich-en" "Here is your sandwich." | |
+ continue; | |
+ fi | |
+ | |
+ if [ "${text}" = "${botname}, please update the phlog index." … | |
+ then | |
+ /home/annna/bin/phlog-index.sh > /dev/null 2>&1 | |
+ annna_say "#bitreich-en" "Thank you for your kind requ… | |
+ continue; | |
+ fi | |
+ | |
+ if [ "${text}" = "${botname}, please help" ]; | |
+ then | |
+ annna_say "${user}" "»can you show me the uptime plea… | |
+ annna_say "${user}" "»please give me the count of onl… | |
+ annna_say "${user}" "»please tell me your favourite f… | |
+ annna_say "${user}" "»please tell me your favourite c… | |
+ annna_say "${user}" "»please dance with me.«, ${user… | |
+ annna_say "${user}" "»please update the phlog index.�… | |
+ annna_say "${user}" "»sudo make me a sandwich«, ${us… | |
+ annna_say "${user}" "»sudo please make me a sandwich�… | |
+ annna_say "${user}" "»please tell me who is your favo… | |
+ annna_say "${user}" "»please roll a dice for me.«, $… | |
+ annna_say "${user}" "»please help« gives you this he… | |
+ continue; | |
+ fi | |
+ done | |
+ } | |
+} & | |
+ | |
diff --git a/annna-stop b/annna-stop | |
@@ -0,0 +1,6 @@ | |
+#!/bin/sh | |
+ | |
+export PATH="$PATH:/home/annna/bin" | |
+ | |
+pkill -KILL -U annna -x socat | |
+ | |
diff --git a/annna-stop-checker b/annna-stop-checker | |
@@ -0,0 +1,6 @@ | |
+#!/bin/sh | |
+ | |
+export PATH="$PATH:/home/annna/bin" | |
+ | |
+pkill -KILL -U annna -f annna-checker | |
+ | |
diff --git a/annna-stop-services b/annna-stop-services | |
@@ -0,0 +1,4 @@ | |
+#!/bin/sh | |
+ | |
+pkill -f "tail -f -n 1 /home/annna/irc.*" | |
+ | |
diff --git a/phlog-index b/phlog-index | |
@@ -0,0 +1,136 @@ | |
+#!/bin/sh | |
+ | |
+export PATH="$PATH:/home/annna/bin" | |
+ | |
+doforce=0 | |
+if [ $# -gt 0 ]; | |
+then | |
+ if [ "$1" = "-f" ]; | |
+ then | |
+ doforce=1 | |
+ fi | |
+fi | |
+ | |
+base="$HOME/phlogs" | |
+cache="$base/cache" | |
+gopherbase="/usr/%s/phlog/%s" | |
+ircchans="#bitreich-en #bitreich-de #bitreich-fr" | |
+ | |
+find /home/*/gopher/phlog \ | |
+ -name "*.md" \ | |
+ -printf "%f %T@ %u %p\n" > $cache/lsr.new | |
+ | |
+cd $cache | |
+ | |
+if [ -e lsr.old -a $doforce -eq 0 ]; | |
+then | |
+ diff lsr.new lsr.old > lsr.diff | |
+else | |
+ cp lsr.new lsr.diff | |
+fi | |
+ | |
+if [ $(stat --printf="%s" lsr.diff) -eq 0 ]; | |
+then | |
+ exit 0 | |
+fi | |
+ | |
+# First create the links for all news. | |
+cat lsr.new \ | |
+| sort -r \ | |
+| while read f; | |
+do | |
+ IFS=' ' read -r fname unixt user fpath <<< $f | |
+ tstamp="$(sed -n 1p "$fpath" | cut -d' ' -f 2)" | |
+ [ -z "$tstamp" ] && continue | |
+ title="$(sed -n 3p "$fpath" | sed 's,\t, ,g')" | |
+ [ -z "$title" ] && continue | |
+ | |
+ gphpth="$(printf "$gopherbase" "$user" "$fname")" | |
+ printf "[0|%s – »%s« by %s|%s|server|port]\n" \ | |
+ "$tstamp" "$title" "$user" \ | |
+ "$gphpth" | |
+done \ | |
+ > ../agg.gph | |
+ | |
+# Create the atom feed. Only the first 64 news items. | |
+cat lsr.new \ | |
+| sort -r \ | |
+| head -n 64 \ | |
+| while read f; | |
+do | |
+ IFS=' ' read -r fname unixt user fpath <<< $f | |
+ tstamp="$(sed -n 1p "$fpath" | cut -d' ' -f 2-)" | |
+ [ -z "$tstamp" ] && continue | |
+ title="$(sed -n 3p "$fpath" | sed 's,\t, ,g')" | |
+ [ -z "$title" ] && continue | |
+ | |
+ updated="$(date -d "${tstamp}" -u +%FT%T%z)" | |
+ gphpth="$(printf "$gopherbase" "$user" "$fname")" | |
+ furi="$(printf "gopher://bitreich.org/0%s" "$gphpth")" | |
+ printf "\t\t<entry>\n" | |
+ printf "\t\t<id>%s</id>\n" "$furi" | |
+ printf "\t\t<title><![CDATA[%s]]></title>\n" "$title" | |
+ printf "\t\t<link href=\"%s\" />\n" "$furi" | |
+ printf "\t\t<author><name>%s</name></author>\n" "$user" | |
+ printf "\t\t<content><![CDATA[" | |
+ cat $fpath | sed 's,$,<br/>,g' | |
+ printf "]]></content>\n" | |
+ printf "\t\t<updated>%s</updated>\n" "$updated" | |
+ printf "\t\t</entry>\n" | |
+done \ | |
+ > ../agg.atom.xml | |
+ | |
+# Talk to IRC about the news. | |
+if [ $doforce -eq 0 ]; | |
+then | |
+ cat lsr.diff \ | |
+ | sort \ | |
+ | while read f; | |
+ do | |
+ IFS=' ' read -r dire fname unixt user fpath <<< $f | |
+ [ -z "$fpath" ] && continue | |
+ [ -z "$user" ] && continue | |
+ [ -z "$unixt" ] && continue | |
+ [ -z "$fname" ] && continue | |
+ [ -z "$dire" ] && continue | |
+ | |
+ # If the post disappeared, don't tell IRC. | |
+ [ "$dire" = ">" ] && continue | |
+ | |
+ tstamp="$(sed -n 1p "$fpath" | cut -d' ' -f 2)" | |
+ [ -z "$tstamp" ] && continue | |
+ title="$(sed -n 3p "$fpath" | sed 's,\t, ,g')" | |
+ [ -z "$title" ] && continue | |
+ | |
+ gphpth="$(printf "$gopherbase" "$user" "$fname")" | |
+ annna-say -c "$ircchans" \ | |
+ "$(printf "%s – »%s« by %s gopher://bitreich.org/0… | |
+ "$tstamp" "$title" "$user" "$gphpth")" | |
+ done | |
+fi | |
+ | |
+cp lsr.new lsr.old | |
+ | |
+# Now change the gph files in a really easy way. | |
+{ | |
+ printf "/N_E_W_S/+1,/C_O_M_M/-4d\n" | |
+ printf "/N_E_W_S/r !cat /home/annna/phlogs/agg.gph | head -n 4\n" | |
+ printf "w\nq\n" | |
+} | ed -s /br/gopher/index.gph | |
+ | |
+{ | |
+ printf "/N_E_W_S/+1,\$-3d\n" | |
+ printf "/N_E_W_S/r !cat /home/annna/phlogs/agg.gph | head -n 256\n" | |
+ printf "w\nq\n" | |
+} | ed -s /br/gopher/news.gph | |
+ | |
+# Make the atom news file ready for consumption. | |
+{ | |
+ printf "/updated/+1,/\\/feed/-1d\n" | |
+ printf "/updated/c\n" | |
+ printf "\t<updated>%s</updated>\n" "$(date -u +%F%T%z)" | |
+ printf ".\n" | |
+ printf "/updated/r !cat /home/annna/phlogs/agg.atom.xml\n" | |
+ printf "w\nq\n" | |
+} | ed -s /br/gopher/news.atom.xml | |
+ |