Initial commit. - annna - Annna the nice friendly bot.
(HTM) git clone git://bitreich.org/annna/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/annna/
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Tags
(DIR) README
---
(DIR) commit a63f21cd1ad027bdff057acf9ee6d44273f778fa
(HTM) Author: Annna Robert-Houdin <annna@bitreich.org>
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(-)
---
(DIR) 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
+
(DIR) 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
+
(DIR) 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
+
(DIR) 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
+
(DIR) 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 ...\" text\n" \
+ "$(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
+
(DIR) 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
+
(DIR) 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=1 \
+ 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-Houdin" &
+
+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
+
(DIR) 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}/#bitreich-radio/out" \
+ | 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}. To your command."
+ continue;
+ fi
+
+ if [ "${text}" = "${botname}, please help" ];
+ then
+ annna_say "${user}" "»next please« gets the playlist further, ${user}."
+ annna_say "${user}" "»please help« gives you this help listing, ${user}."
+ 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-en/out" \
+ | 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 please?" ];
+ then
+ annna_say "#bitreich-en" "$(hostname) uptime: $(uptime)"
+ continue;
+ fi
+
+ if [ "${text}" = "${botname}, please give me the count of online users." ];
+ then
+ annna_say "#bitreich-en" "$(hostname): $(who -q | tail -n 1 | cut -d'=' -f 2)"
+ 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 flower." ];
+ then
+ annna_say "#bitreich-en" "My favourite flower is the beer flower."
+ continue;
+ fi
+
+ if [ "${text}" = "${botname}, please tell me your favourite color." ];
+ 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 of woman."
+ else
+ annna_say "#bitreich-en" "Thank you! Let us dance! :-D"
+ fi
+
+ continue;
+ fi
+
+ if [ "${text}" = "${botname}, please tell me who is your favourite pleasure man." ];
+ then
+ annna_say "#bitreich-en" "My favourite pleasure man is of course Gunther!"
+ 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 request. I have done so."
+ continue;
+ fi
+
+ if [ "${text}" = "${botname}, please help" ];
+ then
+ annna_say "${user}" "»can you show me the uptime please?« gets you the uptime, ${user}."
+ annna_say "${user}" "»please give me the count of online users.«, ${user}."
+ annna_say "${user}" "»please tell me your favourite flower.«, ${user}."
+ annna_say "${user}" "»please tell me your favourite color.«, ${user}."
+ annna_say "${user}" "»please dance with me.«, ${user}."
+ annna_say "${user}" "»please update the phlog index.«, ${user}."
+ annna_say "${user}" "»sudo make me a sandwich«, ${user}."
+ annna_say "${user}" "»sudo please make me a sandwich«, ${user}."
+ annna_say "${user}" "»please tell me who is your favourite pleasure man.«, ${user}."
+ annna_say "${user}" "»please roll a dice for me.«, ${user}."
+ annna_say "${user}" "»please help« gives you this help listing, ${user}."
+ continue;
+ fi
+ done
+ }
+} &
+
(DIR) 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
+
(DIR) 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
+
(DIR) 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.*"
+
(DIR) 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%s" \
+ "$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
+