summaryrefslogtreecommitdiff
path: root/process_event
diff options
context:
space:
mode:
Diffstat (limited to 'process_event')
-rw-r--r--process_event449
1 files changed, 449 insertions, 0 deletions
diff --git a/process_event b/process_event
new file mode 100644
index 0000000..7d93ed5
--- /dev/null
+++ b/process_event
@@ -0,0 +1,449 @@
+#! /bin/bash
+
+# This function reads tags of xml in the same way read normally reads lines.
+function rdom
+{
+ local IFS=\>
+ read -d \< element content
+}
+
+function tell_fact # thing channel
+{
+ thing="${1}"
+ declare -l lower_case_thing="${thing}"
+ channel="${2}"
+
+ if [[ -s "info/${lower_case_thing}" ]]
+ then
+ # For the first entry we will say like: `thing is: '
+ first="${thing} is: "
+
+ uniq "info/${lower_case_thing}" |
+ while read line
+ do
+ send_msg "${channel}" "${first}${line}"
+ first=''
+ done
+
+ return
+ else
+ return 1
+ fi
+}
+
+source common_codez
+
+function remember_fact
+{
+ if grep "^${is}$" "info/${thing}" &>/dev/null
+ then
+ send_msg "${channel_it_came_from}" "${personoslash}: I know."
+ else
+ echo "${is}" >> "info/${thing}"
+ send_msg "${channel_it_came_from}" "${personoslash}: Remembered."
+ fi
+}
+
+function forget_fact
+{
+ number_of_matching_lines=$(grep -c "^${isnt}" "info/${thing}")
+
+ case "${number_of_matching_lines}" in
+ 0 )
+ send_msg "${channel_it_came_from}" "${personoslash}: I know."
+ ;;
+ 1 )
+ grep -v "^${isnt}" "info/${thing}" | sponge "info/${thing}"
+ send_msg "${channel_it_came_from}" "${personoslash}: OK, entry removed."
+ ;;
+ * )
+ send_msg "${channel_it_came_from}" "${personoslash}: Ambiguos."
+ ;;
+ esac
+}
+
+function process_event
+{
+ my_own_name='pbot'
+
+ person="${sender%%!*}"
+
+ # Remove any forward slashes.
+ personoslash="${person//\/}"
+ declare -l personoslashlower="${personoslash}"
+
+ channel_it_came_from="$( echo ${line} | cut -d ' ' -f 3 )"
+
+ # If it's a private message
+ [[ "${channel_it_came_from}" == "${my_own_name}" ]] && channel_it_came_from="${personoslash}"
+
+ ######################
+ # Echo injected data #
+ ######################
+
+ # Should send a message like: echo 'This is the message' > /tmp/un-provoked-message-store
+
+ injected_data=0
+
+ line_filtered=${line##*PRIVMSG +([![:space:]]) :}
+
+ if [[ ${personoslash} == tlCJ99mfZl ]]
+ then
+ send_msg "${channel_it_came_from}" "${line_filtered}"
+ injected_data=1
+ else
+ ###############################################################
+ # This is a message from a user. Make preperations to process #
+ ###############################################################
+
+ the_time_now=$(date +%s)
+
+ # Make this person a folder if they don't already have one.
+ if ! [[ -d "announcements/people/${personoslashlower}" ]]
+ then
+ mkdir -p "announcements/people/${personoslashlower}"
+ fi
+
+ # Record that the person has been seen, and when.
+ touch "announcements/people/${personoslashlower}/seen"
+
+ shopt -s extglob
+
+ # We want to get only the message part of the line
+ sentence="${line#* }"
+ sentence="${sentence#* }"
+ sentence="${sentence#* :}"
+
+ ##########################
+ # Shared libraries error #
+ ##########################
+
+ the_time_now=$(date +%s)
+
+ # If someone complains about error while loading shared libraries error
+ # then recomend them to the bug tracker.
+ if [[ ${sentence} == *"error while loading shared libraries"* ]]
+ then
+ # Make sure they have not already been recommended to the bug
+ # tracker less than one day ago.
+ sharlibsrecfile="announcements/people/${personoslashlower}/shared_libs"
+
+ # Have we recommended them to the bug tracker before?
+ if [[ -f ${sharlibsrecfile} ]]
+ then
+ # Was it less than a day ago?
+ (( ( $( stat -c %Y ${sharlibsrecfile} ) + 86400 ) > the_time_now )) && rec_recent=1 || rec_recent=0
+ else
+ rec_recent=0
+ fi
+
+ if ! (( rec_recent ))
+ then
+ send_msg "${channel_it_came_from}" "${person}: please report a bug, specifying the exact error message, package of the failing command and architecture: http://labs.parabola.nu"
+ touch "${sharlibsrecfile}"
+ fi
+ fi
+
+ ##########
+ # Repeat #
+ ##########
+
+ [[ ${sentence} != ${i_repeated} ]] && say_again=yesyes
+
+ # If two different people say the same thing in a row then say it again
+ # for fun.
+ if [[ ${sentence} == ${lastline} ]] && [[ ${person} != ${lastsender} ]] && [[ ${say_again} != nono ]] && [[ ${sentence} != "${my_own_name}: "* ]] # If two different people say the same thing to me in quick sucession I shouldn't repeat them.
+ then
+ send_msg "${channel_it_came_from}" "${sentence}"
+ i_repeated="${sentence}"
+ say_again=nono
+ fi
+
+ lastline="${sentence}"
+ lastsender="${person}"
+
+ #################
+ # Announcements #
+ #################
+
+ # If someone has sent this person a message then echo it to
+ # them.
+ if [[ -f "announcements/people/${personoslashlower}/messages" ]]
+ then
+ uniq "announcements/people/${personoslashlower}/messages" |
+ while read line
+ do
+ # The first field is the time, in *nix seconds, that
+ # the message was sent. The second is the name of the
+ # sender. And the rest is the message.
+ intermediate="${line#* }"
+ sender_u="${intermediate%% *}"
+ message_u="${intermediate#* }"
+ time_sent="${line%% *}"
+
+ seconds_ago_seen="$(( the_time_now - time_sent ))"
+ minutes_ago_seen="$(( ( the_time_now - time_sent ) / 60 ))"
+ hours_ago_seen="$(( ( the_time_now - time_sent ) / 3600 ))"
+ days_ago_seen="$(( ( the_time_now - time_sent ) / 86400 ))"
+ months_ago_seen="$(( ( the_time_now - time_sent ) / 2592000 ))"
+ years_ago_seen="$(( ( the_time_now - time_sent ) / 31104000 ))"
+ if (( seconds_ago_seen < 120 ))
+ then
+ units="${seconds_ago_seen} seconds"
+ elif (( minutes_ago_seen < 120 ))
+ then
+ units="${minutes_ago_seen} minutes"
+ elif (( hours_ago_seen < 48 ))
+ then
+ units="${hours_ago_seen} hours"
+ elif (( days_ago_seen < 60 ))
+ then
+ units="${days_ago_seen} days"
+ elif (( months_ago_seen < 24 ))
+ then
+ units="${months_ago_seen} months"
+ else
+ units="${years_ago_seen} years"
+ fi
+
+ send_msg "${channel_it_came_from}" "${personoslash}: ${sender_u} told me to tell you, (${units} ago): ${message_u}"
+ done
+ rm "announcements/people/${personoslashlower}/messages"
+ fi
+
+ #####################
+ # Page title getter #
+ #####################
+
+ # We don't want to get the page title if it's injected data.
+ if [[ ${line} =~ http://[^\ ]+ ]] || [[ ${line} =~ https://[^\ ]+ ]] &&
+ (( ! injected_data ))
+ then
+ url_to_get="${BASH_REMATCH}"
+
+ the_title=$(
+ curl -L --compressed "${url_to_get}" 2> /dev/null |
+ while rdom
+ do
+ if [[ ${element} = title ]] || [[ ${element} = TITLE ]]
+ then
+ sed 's/ / /g' <<< "${content}" | replace_wierd_html_chars
+ fi
+ done
+ )
+
+ if ! [[ -z ${the_title} ]]
+ then
+ send_msg "${channel_it_came_from}" "Page title: \`${the_title}'"
+ fi
+ fi
+
+ case "${sentence}" in
+ ########
+ # Seen #
+ ########
+
+ "${my_own_name}: when did you last see"* )
+ subject="${sentence##${my_own_name}: when did you last see }"
+ subject="${subject##${my_own_name}: when did you last see: }" # If there's an `:', we can still handle it.
+ subject="${subject%\?}"
+ subject="${subject%% *}"
+ declare -l subjectlower="${subject}"
+
+ if [[ "${subject}" == ${my_own_name} ]]
+ then
+ send_msg "${channel_it_came_from}" "I last saw ${subject} speak 0 seconds ago."
+ elif [[ -f "announcements/people/${subjectlower}/seen" ]]
+ then
+ seconds_ago_seen="$(( the_time_now - $( stat -c %Y announcements/people/${subjectlower}/seen ) ))"
+ minutes_ago_seen="$(( ( the_time_now - $( stat -c %Y announcements/people/${subjectlower}/seen ) ) / 60 ))"
+ hours_ago_seen="$(( ( the_time_now - $( stat -c %Y announcements/people/${subjectlower}/seen ) ) / 3600 ))"
+ days_ago_seen="$(( ( the_time_now - $( stat -c %Y announcements/people/${subjectlower}/seen ) ) / 86400 ))"
+ months_ago_seen="$(( ( the_time_now - $( stat -c %Y announcements/people/${subjectlower}/seen ) ) / 2592000 ))"
+ years_ago_seen="$(( ( the_time_now - $( stat -c %Y announcements/people/${subjectlower}/seen ) ) / 31104000 ))"
+ if (( seconds_ago_seen < 120 ))
+ then
+ send_msg "${channel_it_came_from}" "I last saw ${subject} speak ${seconds_ago_seen} seconds ago."
+ elif (( minutes_ago_seen < 120 ))
+ then
+ send_msg "${channel_it_came_from}" "I last saw ${subject} speak ${minutes_ago_seen} minutes ago."
+ elif (( hours_ago_seen < 48 ))
+ then
+ send_msg "${channel_it_came_from}" "I last saw ${subject} speak ${hours_ago_seen} hours ago."
+ elif (( days_ago_seen < 60 ))
+ then
+ send_msg "${channel_it_came_from}" "I last saw ${subject} speak ${days_ago_seen} days ago."
+ elif (( months_ago_seen < 24 ))
+ then
+ send_msg "${channel_it_came_from}" "I last saw ${subject} speak ${months_ago_seen} months ago."
+ else
+ send_msg "${channel_it_came_from}" "I last saw ${subject} speak ${years_ago_seen} years ago."
+ fi
+ else
+ send_msg "${channel_it_came_from}" "I never saw ${subject} speak."
+ fi
+ ;;
+ ########
+ # tell #
+ ########
+
+ "${my_own_name}: tell "+([![:space:]])":"+([[:space:]])+([![:space:]])* )
+ # The line will be something such as:
+ # pbot: tell fauno: you suck
+ process="${sentence##${my_own_name}: tell }"
+ subject="${process%%:*}"
+ message="${process#*:}"
+ message="${message# }"
+
+ if [[ "${subject}" == "${my_own_name}" ]]
+ then
+ send_msg "${channel_it_came_from}" "${my_own_name}: ${personoslash} told me to tell you, (0 seconds ago): ${message}"
+ else
+ declare -l subjectlower="${subject}"
+
+ [[ -d "announcements/people/${subjectlower}" ]] || mkdir -p "announcements/people/${subjectlower}"
+ # The time in *nix seconds is saved there so that
+ # pbot can say how long ago the massage was sent
+ # when he gives it to it's recipient.
+ echo "$(date +%s) ${personoslash} ${message}" >> "announcements/people/${subjectlower}/messages"
+
+ response='certainly'
+
+ send_msg "${channel_it_came_from}" "${personoslash}: ${response}"
+
+ if ! [[ -f "announcements/people/${subjectlower}/seen" ]]
+ then
+ send_msg "${channel_it_came_from}" "${personoslash}: WARNING: I HAVE NEVER SEEN \"${subject}\" HERE BEFORE. CHECK YOUR SPELLING."
+ fi
+ fi
+ ;;
+ ############
+ # factoids #
+ ############
+
+ "${my_own_name}: "+([!/])" is "+([![:space:]])* )
+ declare -l thing="${sentence#${my_own_name}: }"
+ thing="${thing%% is *}"
+ is="${sentence#* is }"
+
+ remember_fact
+ ;;
+ "${my_own_name}: "+([!/])" is: "+([![:space:]])* )
+ declare -l thing="${sentence#${my_own_name}: }"
+ thing="${thing%% is: *}"
+ is="${sentence#* is: }"
+
+ remember_fact
+ ;;
+ "${my_own_name}: "+([![:space:]])" isn't "+([![:space:]])* )
+ declare -l thing="${sentence#${my_own_name}: }"
+ thing="${thing%% isn\'t *}"
+ isnt="${sentence#* isn\'t }"
+
+ forget_fact
+ ;;
+ "${my_own_name}: "+([![:space:]])" isn't: "+([![:space:]])* )
+ declare -l thing="${sentence#${my_own_name}: }"
+ thing="${thing%% isn\'t: *}"
+ isnt="${sentence#* isn\'t: }"
+
+ forget_fact
+ ;;
+ ','+([!/]) )
+ thing="${sentence#,}"
+
+ tell_fact "${thing}" "${channel_it_came_from}"
+ ;;
+ #############
+ # Footnotes #
+ #############
+
+ *\[[[:digit:]]\]* )
+ declare -a fn
+
+ while read -d $'\0' file
+ do
+ #if match = grep "${file##*/}[ ]\?\[[[:digit:]]\]" <<< "${sentence}"
+ filename="${file##*/}"
+
+ declare -l lowersentence="${sentence}"
+
+ if [[ " ${lowersentence}" =~ [^[:alnum:]]${filename}[\ ]?\[[[:digit:]]\] ]]
+ then
+ index="${BASH_REMATCH: -2:1}"
+
+ fn[${index}]=$(head -1 "${file}")
+ fi
+ done < <(find info -print0)
+
+ for (( n=0 ; n<50 ; n++ ))
+ do
+ str="${fn[${n}]}"
+
+ [[ -z "${str}" ]] && continue
+
+ send_msg "${channel_it_came_from}" "[${n}] ${str}"
+ done
+ ;;
+ ########################
+ # unrecognised command #
+ ########################
+
+ ${my_own_name}:* | ','* )
+ while read line
+ do
+ send_msg "${personoslash}" "${line}"
+ done <<< cat << EOF
+Command not recognised. Example commands:
+${my_own_name}: tell Jack: hi Jack
+${my_own_name}: when did you last see Jill?
+${my_own_name}: lemon is yummy
+${my_own_name}: lemon isn't yummy
+,lemon
+EOF
+ ;;
+ esac
+
+# ' this comment fixes a bug in emacs shell-script-mode that messes up the syntax highlighting
+
+ # I'm dissabling this feature for now as it was being abused
+ # and would need an overhaul to be abuse-proof + nobody uses it afaik
+ # ##########################
+ # # tell someone something #
+ # ##########################
+
+ # # TODO: this should be in the case statement
+
+ # if [[ "${sentence}" =~ ${my_own_name}: tell\ [^\ ]+\ about\ [^\ ]+ ]]
+ # then
+ # # TODO: There should be the following three constraints to
+ # # prevent abuse.
+ # # 1. People may only ask the bot to tell someone about
+ # # something in the #parabola channel, not by query.
+ # # 2. pbot will only tell someone something if they're a user
+ # # he has seen in the past week
+ # # 3. each person may use tell no more than 10 times in
+ # # three hours.
+
+ # gotit="${BASH_REMATCH}" # will be like: `,tell jack about blah'
+
+ # dudep1="${gotit#,tell }"
+ # dude="${dudep1%% *}"
+ # thing="${gotit##* }"
+
+ # if [[ -n "${dude}" ]] && [[ -n "${thing}" ]]
+ # then
+ # tell_fact "${thing}" "${dude}" || send_msg "${channel_it_came_from}" "${personoslash}: Error, failed to tell ${dude} about ${thing}"
+ # fi
+ # fi
+
+ # TODO: add a birthday announcement feature, cointoss feature, timer
+ # feature.
+
+ #########
+ # Tests #
+ #########
+
+ #echo "${line}"
+ fi
+}