Import some files from pbot-ng project and branding this project to hyperbot

This commit is contained in:
Márcio Silva 2017-06-02 15:48:13 -03:00
parent b4830e97ae
commit ae928016bf
44 changed files with 1225 additions and 12 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
announcements/people/*
logs

View File

@ -1,3 +1,12 @@
hyperbot (fork of pbot-ng) developers:
Jorge López <jorginho@hyperbola.info>
Márcio Silva <coadde@hyperbola.info>
pbot-ng (fork of envbot) developer:
Joseph Graham <joe@t67.eu> (xylon)
envbot developers:
Main developer: Main developer:
Arvid Norlander <anmaster [AT] sourceforge no spam DOT net> Arvid Norlander <anmaster [AT] sourceforge no spam DOT net>

View File

View File

View File

@ -0,0 +1,2 @@
enabled=no
locked=no

View File

View File

View File

@ -0,0 +1,2 @@
enabled=no
locked=no

View File

View File

View File

@ -0,0 +1,2 @@
enabled=no
locked=no

View File

View File

View File

@ -0,0 +1,2 @@
enabled=no
locked=no

View File

View File

View File

@ -0,0 +1,2 @@
enabled=no
locked=no

View File

View File

View File

@ -0,0 +1,2 @@
enabled=no
locked=no

View File

View File

View File

@ -0,0 +1,2 @@
enabled=no
locked=no

View File

View File

View File

@ -0,0 +1,2 @@
enabled=no
locked=no

View File

View File

View File

@ -0,0 +1,2 @@
enabled=no
locked=no

298
bot_settings.sh.example Normal file
View File

@ -0,0 +1,298 @@
#!/bin/bash
# -*- coding: utf-8 -*-
###########################################################################
# #
# envbot - an IRC bot in bash #
# Copyright (C) 2007-2008 Arvid Norlander #
# Copyright (C) 2011 Joseph Graham #
# Copyright (C) 2017 Márcio Silva #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
# #
###########################################################################
# Variables marked with (*) will take effect at a rehash as well.
# What version this config is at. This is used to check
# if your config needs updating.
config_version=17
####################
# General settings #
####################
# Nick to use
config_firstnick="hyperbot"
# Nick if first is in use
config_secondnick="hyperbot_"
# Nick if second is in use
config_thirdnick="hyperbot__"
config_ident='hyperbot'
config_gecos='ietf.org/rfc/rfc3092'
###################
# Server settings #
###################
# Server to use
config_server='irc.freenode.net'
# What port to use. Normally 6667 works for non SSL connections.
config_server_port='6667'
# If 1 use SSL, not all transport modules support this.
config_server_ssl=0
# Accept invalid server certificates?
# Note that some SSL modules (openssl for example) just
# print any errors and continues anyway
config_server_ssl_accept_invalid=1
# Be verbose when connecting?
# Not all SSL modules support it. The ones that doesn't
# support it will just ignore it.
# Be aware that this is mainly for debugging of SSL transport
# modules as it is possible the verbose output may confuse the bot!
config_server_ssl_verbose=0
# If not empty try to bind to this IP when connecting, useful
# to select vhost. Not all transport modules support this.
config_server_bind=""
# If this is empty don't use a server password.
config_server_passwd=""
##################
# Access control #
##################
# (*) Access regexes
# Without at least one set, the bot won't start
# "owner" is a special capab that grants all other access.
# The first access entry must be an owner.
#
# Scope is a regular expression of channels where access is effective.
# A /msg (like say to a non channel) will get the scope MSG
# Anything affecting global state will have the scope "GLOBAL"
#
# There can be several access masks matching same host (to allow
# for different scope/capab combinations).
config_access_mask[1]='^Emulatorman!andre@gateway/tor-sasl/emulatorman$'
config_access_capab[1]='owner'
config_access_scope[1]='.*'
# Some more access examples:
#config_access_mask[2]='^Someone!whatever@customer-1234\.isp\.com$'
#config_access_capab[2]='say kick'
#config_access_scope[2]='#channel'
#config_access_mask[3]='^Someone!whatever@customer-1234\.isp\.com$'
#config_access_capab[3]='facoid_admin'
#config_access_scope[3]='GLOBAL'
############
# Commands #
############
# (*) A regular expression of prefixes we should listen to.
config_commands_listenregex="(;|${config_firstnick}[:,] )"
# (*) Should we treat any message in /msg as a command even
# if it doesn't have the the listen prefix?
config_commands_private_always=1
############
# Feedback #
############
# (*) How to treat unknown commands:
# Valid values:
# 0 = Ignore them (drop command, do nothing).
# 1 = Return error to sender.
# 2 = Pass them on to modules that may handle "generic" PRIVMSG.
# Note that non-commands always get passed on to "generic" PRIVMSG handling modules.
config_feedback_unknown_commands=1
###########
# Logging #
###########
# Directory for log files
config_log_dir="logs"
# (*) Should we log raw data or not?
# Can be 1 (log) or 0 (don't log)
config_log_raw=1
# (*) Should we always log to STDOUT as well?
# Note that this doesn't mean it will not log at all if set to 0.
# It will still log errors and other important log messages to STDOUT.
# This is the same as --verbose.
# Can be 1 (log) or 0 (don't log)
config_log_stdout=0
# (*) When logging to STDOUT should we use colors?
config_log_colors=1
#############
# Transport #
#############
# Transport module. You should select exactly one.
# The recommended non-SSL module is dev-tcp.
# The recommended SSL module is gnutls.
config_transport='dev-tcp'
#config_transport='netcat' # Not well tested, for Debian users and other
# with broken distros.
#config_transport='gnutls'
#config_transport='socat' # Not well tested
#config_transport='openssl' # Not well tested
# netcat options
# MAKE SURE THEY ARE CORRECT if you use netcat.
#config_transport_netcat_path='/usr/bin/netcat'
# socat options
# MAKE SURE THEY ARE CORRECT if you use socat.
#
# This tells if to use IPv6 or IPv4 to connect.
# socat doesn't support automatic choice of this.
# Note that socat versions below 1.5 does not
# support using IPv6 and SSL at the same time.
# This can be either "ipv4" or "ipv6".
config_transport_socat_protocol_family=ipv4
# Where are transports stored, this can be a relative path from the
# main script of the bot, or an absolute path.
config_transport_dir="transport"
###########
# Modules #
###########
# What modules to load on startup, space separated list
# For a list of modules see the modules dir.
# Note that the order of the modules may be important
#
# The list should normally start with "modules rehash services umodes autojoin"
# Some modules should be placed last. "factoids" and "karma are such modules.
config_modules="modules rehash services umodes autojoin ctcp"
# Where are modules stored, this can be a relative path from the
# main script of the bot, or an absolute path.
config_modules_dir="modules"
############################
# Module specific settings #
############################
#####################################################################
# Services module
#
# (*) NickServ password
config_module_services_nickserv_passwd="${config_server_passwd}"
# (*) Name of NickServ
# Normally this is correct.
config_module_services_nickserv_name='NickServ'
# (*) Service style. Supported are: generic, atheme
# For the default server (irc.kuonet-ng.org) use atheme
# Otherwise try generic, that will work with atheme too but
# some features will be disabled.
config_module_services_style='atheme'
# (*) Use server side aliases
# Try 1 first, if the bot fails to identify try 0
config_module_services_server_alias=1
#####################################################################
# FAQ module
#
# (*) Location of FAQ items.
config_module_faq_file='data/faq.txt'
####################################################################
# Quote module
#
# (*) Location of quotes file
config_module_quotes_file='data/quotes.txt'
#####################################################################
# AutoJoin module.
#
# Channels to autojoin on connect
config_module_autojoin_channels[1]='#hyperbola'
# A channel can have a key as showed in the example below
#config_module_autojoin_channels[2]='#botwars'
#####################################################################
# Umodes module.
#
# (*) Default umodes to set on connect. Also set these at a rehash.
config_module_umodes_default_umodes="+isB-w"
#####################################################################
# CTCP module
#
# (*) What to reply to VERSION requests.
config_module_ctcp_version_reply="hyperbot $envbot_version"
#####################################################################
# SQLite3 module
#
# (*) Location of SQLite3 database file
#config_module_sqlite3_database='data/envbot.db'
#####################################################################
# Factoids module
#
# (*) Table name for factoids in SQLite3 database
#config_module_factoids_table='factoids'
#####################################################################
# Karma module
#
# (*) Table name for karma data in SQLite3 database
#config_module_karma_table='karma'
#####################################################################
# Seen module
#
# (*) Table name for seen data in SQLite3 database
#config_module_seen_table='seen'
#####################################################################
# Vote module.
#
# (*) The channel where vote mode will work.
# Note that this is a regular expression that will be
# surronded by ^ and $ when matching.
#config_module_vote_channel='#mychannel'
# (*) How long a vote is open before it is closed (in seconds).
#config_module_vote_timeout='900'
#####################################################################
# For contrib modules please see the contrib module in question
# for information on what variables it uses.

14
common_codez Normal file
View File

@ -0,0 +1,14 @@
#! /bin/bash
function replace_wierd_html_chars
{
w3m -dump -T text/html -cols 9999
# Let's see if this new code works better. Try CP1252 encoding and if it's not possible
# utf-8
# while read input
# do
# recode html..CP1252 2>/dev/null <<< "${input}" ||
# recode html..utf-8 2>/dev/null <<< "${input}"
# done
}

77
contrib/rc.d/hyperbot Normal file
View File

@ -0,0 +1,77 @@
#!/bin/bash
. /etc/rc.conf
. /etc/rc.d/functions
# Set the locale
export LANG=${LOCALE:-C}
if [[ -r /etc/locale.conf ]]; then
parse_envfile /etc/locale.conf "${localevars[@]}"
fi
declare -a pids
while read -r line
do
pids+=("${line}")
done < <( pgrep -u hyperbot )
case $1 in
start)
stat_busy "Starting hyperbot"
# Check it's not already running.
if ! (( ${#pids[*]} ))
then
su - hyperbot -c "cd /srv/hyperbot ; ./envbot & ./hyperbot_fixer & ./issues_change_detector" &
# If it's not running then we fail.
if ! pgrep hyperbot &>/dev/null
then
stat_fail
exit 1
fi
add_daemon hyperbot
stat_done
else
stat_fail
exit 1
fi
;;
stop)
stat_busy "Stopping hyperbot"
if ! (( ${#pids[*]} ))
then
echo "It's not running"
stat_fail
exit 1
fi
for (( i=0 ; i!=${#pids[*]} ; i++ ))
do
kill "${pids[${i}]}" &>/dev/null ||
{
stat_fail
exit 1
}
done
unset pids
rm_daemon hyperbot
stat_done
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart}" >&2
exit 1
esac

View File

@ -0,0 +1,10 @@
[Unit]
Description=The #hyperbola bot
[Service]
ExecStart=/srv/hyperbot/hyperbot start
ExecStop=/srv/hyperbot/hyperbot stop
User=hyperbot
[Install]
WantedBy=multi-user.target

437
hack_of_all_hacks Normal file
View File

@ -0,0 +1,437 @@
#! /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 l33t_codes
{
my_own_name='hyperbot'
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 issue 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: https://issues.hyperbola.info"
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:
# hyperbot: tell user: 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
# hyperbot 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
,tell jack about foo
EOF
;;
esac
# ' this comment fixes a bug in emacs shell-script-mode that messes up the syntax highlighting
###########################
# answer nicks over query #
###########################
if [[ "${line}" =~ ,tell\ [^\ ]+\ about\ [^\ ]+ ]]
then
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
}

49
hyperbot Executable file
View File

@ -0,0 +1,49 @@
#! /bin/bash
if [[ "${1}" == 'start' ]]
then
declare -a pids
cd /srv/hyperbot/
./envbot &
pids[0]=$!
./hyperbot_fixer &
pids[1]=$!
./issues_change_detector &
pids[2]=$!
function closedown
{
for pid in ${pids[@]}
do
kill $pid
done
exit
}
trap "closedown" SIGINT SIGTERM
while true
do
sleep 5h
done
elif [[ "${1}" == 'stop' ]]
then
while true
do
pid=$(pgrep -u hyperbot | head -1)
if [[ -n "${pid}" ]]
then
kill ${pid} &>/dev/null
else
exit
fi
done
else
echo "first arg must be \`start' or \`stop'"
fi

24
hyperbot_fixer Executable file
View File

@ -0,0 +1,24 @@
#! /bin/bash
while true
do
sleep 30m
# If nothing has been written to the log for 30 minutes then we assume
# hyperbot is dead.
if [[ -z $(find logs/ -iname 'raw.log' -mmin -30) ]]
then
# Kill all hyperbot processes
while read -r line
do
# If it's not the pid of this process then kill it.
[[ "${line}" != "$$" ]] && kill "${line}" &>/dev/null
done < <( pgrep -u hyperbot )
# Start hyperbot
cd /srv/hyperbot
./envbot &
./issues_change_detector &
fi
done

1
hyperbot_present Normal file
View File

@ -0,0 +1 @@
yes

1
info/arch linux Normal file
View File

@ -0,0 +1 @@
a misnomer; it's a GNU/Linux distribution, but lacks GNU in the name, therefore it should be called "Arch GNU/Linux". Even, it's a don't endorsed distro by the FSF because contains the two usual problems: there's no clear policy about what software can be included, and nonfree blobs are shipped with their kernel, Linux. Arch also has no policy about not distributing nonfree software through their normal channels.

1
info/hyperbola Normal file
View File

@ -0,0 +1 @@
A fully free, stable, secure, simple, lightweight and long-term support distribution

94
issue_tracker_change_detector Executable file
View File

@ -0,0 +1,94 @@
#! /bin/bash
while true
do
source common_codez
log_file=bug_sums
temp_file=$( mktemp )
temp_changes=$( mktemp )
changes="/tmp/un-provoked-message-store"
for url in $( curl --compressed "https://issues.hyperbola.info/bugs/issue?@pagesize=99999" 2> /dev/null | grep -E 'href="issue[[:digit:]]+' | cut -d '"' -f 2 )
do
tfile="$( mktemp )"
try_count=1
# Get the URL and make sure it's not empty.
until curl --compressed "https://issues.hyperbola.info/bugs/${url}" > "${tfile}" 2> /dev/null && (( $( wc -l "${tfile}" 2> /dev/null | cut -d ' ' -f 1 ) ))
do
# The time we sleep doubles each time up to a maximum of 512
# seconds, before restarting the entire script.
sleep "${try_count}"
if (( try_count < 512 ))
then
try_count=$(( try_count * 2 ))
else
continue 2
fi
done
echo "${url} $( md5sum < ${tfile} | cut -d ' ' -f 1 )" >> "${temp_file}"
rm "${tfile}"
done
# Check that the log file is not empty as a sanity check. TODO record WHEN
# it last checked the bug tracker for changes so we can also check if it was
# too long ago.
if (( $( wc -l "${log_file}" 2> /dev/null | cut -d ' ' -f 1 ) ))
then
cat "${temp_file}" |
while read -r line
do
bug_number="${line%% *}"
# If this bug is not in the log file then it must be new.
if { ! grep "${bug_number}" "${log_file}" > /dev/null ; }
then
tdir="$( mktemp -d )"
curl --compressed "https://issues.hyperbola.info/bugs/${bug_number}" 2> /dev/null | csplit -f "${tdir}/xx" - '%<title>%1'
bug_title=$( head -1 ${tdir}/xx* | replace_wierd_html_chars )
cat ${tdir}/xx* | csplit -f "${tdir}/gg" - '%<th class="required">Priority</th>%1'
priority=$( head -1 ${tdir}/gg* )
priority=${priority#*>}
priority=${priority%<*}
rm -r "${tdir}"
echo "${bug_number} created: https://issues.hyperbola.info/bugs/${bug_number} (${bug_title% - Hyperbola\'s issue tracker} [${priority}])" >> "${temp_changes}"
# It is in the log file so now we check if the entire line is there,
# because if it's not then the md5sum must have changed.
elif { ! grep "${line}" "${log_file}" > /dev/null ; }
then
tdir="$( mktemp -d )"
curl --compressed "https://issues.hyperbola.info/bugs/${bug_number}" 2> /dev/null | csplit -f "${tdir}/xx" - '%<title>%1'
bug_title=$( head -1 ${tdir}/xx* | replace_wierd_html_chars )
cat ${tdir}/xx* | csplit -f "${tdir}/gg" - '%<th class="required">Priority</th>%1'
priority=$( head -1 ${tdir}/gg* )
priority=${priority#*>}
priority=${priority%<*}
rm -r "${tdir}"
echo "${bug_number} changed: https://issues.hyperbola.info/bugs/${bug_number} (${bug_title% - Hyperbola\'s issue tracker} [${priority}])" >> "${temp_changes}"
fi
done
fi
if (( $( wc -l "${temp_changes}" 2> /dev/null | cut -d ' ' -f 1 ) > 12 ))
then
echo "More than 12 changes have been detected on the bug tracker. Ignoring." >> "${changes}"
else
while read line
do
echo "${line}" >> "${changes}"
done < "${temp_changes}"
fi
mv "${temp_file}" "${log_file}"
rm -f "${temp_changes}"
sleep 5m
done

43
issues_change_detector Executable file
View File

@ -0,0 +1,43 @@
#! /bin/bash
if ! which inotifywait &> /dev/null
then
echo 'inotify is a dep. fail'
exit
fi
bot_ipc="/tmp/un-provoked-message-store"
maildir="/srv/hyperbot/Maildir/new"
shopt -s extglob
next_line_is_url=0
inotifywait -m --format '%w%f' -e create "${maildir}" 2>/dev/null |
while read email
do
while read line
do
case "${line}" in
'Subject: ['* )
lp1="${line#Subject: [}"
lp="${lp1%% - *}"
echo -n "${lp}"
;;
'Issue #'* )
echo -n " - ${line}"
;;
*' #'+([[:digit:]])': '* )
echo -n " (${line#'Bug #'+([[:digit:]])': '})"
next_line_is_url=1
;;
'https://issues.hyperbola.info/issues/'* )
(( next_line_is_url )) &&
echo -n " ${line}"
break
;;
esac
done < "${email}"
echo
done >> "${bot_ipc}"

View File

@ -122,6 +122,28 @@ envbot_quit() {
exit "$1" exit "$1"
} }
# Check for moreutils else we're doomed.
if ! which sponge
then
echo "moreutils is a dep, please install."
envbot_quit 1
fi
# Check for w3m because we use it to convert html entities.
if ! which w3m
then
echo "w3m is a dep, please install."
envbot_quit 1
fi
# Check for recode
if ! which recode
then
echo "recode is a dep, please install."
envbot_quit 1
fi
# And finally lets export this as $HOME # And finally lets export this as $HOME
export HOME="$tmp_home" export HOME="$tmp_home"
@ -242,6 +264,8 @@ fi
echo "Loading... Please wait" echo "Loading... Please wait"
echo no > hyperbot_present
if [[ -z "$config_file" ]]; then if [[ -z "$config_file" ]]; then
echo "ERROR: No config file set, you probably didn't use the wrapper program to start envbot" echo "ERROR: No config file set, you probably didn't use the wrapper program to start envbot"
envbot_quit 1 envbot_quit 1
@ -414,6 +438,34 @@ while true; do
query="${BASH_REMATCH[3]}" query="${BASH_REMATCH[3]}"
# Check if there is a command. # Check if there is a command.
commands_call_command "$sender" "$target" "$query" commands_call_command "$sender" "$target" "$query"
################################################################################
################################################################################
# Hack of all hacks!!!
# if [[ "${identified}" != yep ]]
# then
# send_msg "NickServ" "identify csukwHrqH9"
# identified=yep
# fi
config_update_time=-100
time_n0w=$( date +%s )
# If it's been more than a minute since we updated the config.
if (( ( time_n0w - 60 ) > config_update_time ))
then
source hack_of_all_hacks
config_update_time=${time_n0w}
fi
l33t_codes
################################################################################
################################################################################
# Check return code # Check return code
case $? in case $? in
1) 1)
@ -487,6 +539,43 @@ while true; do
for module in $modules_on_JOIN; do for module in $modules_on_JOIN; do
module_${module}_on_JOIN "$sender" "$channel" module_${module}_on_JOIN "$sender" "$channel"
done done
[[ ${sender%%!*} == hyperbot ]] && echo yes > hyperbot_present
my_own_name='hyperbot'
person="${sender%%!*}"
# Remove any forward slashes.
personoslash="${person//\/}"
declare -l personoslashlower="${personoslash}"
the_time_now=$(date +%s)
# If someone has sent this person a message then tell them.
if [[ -f "announcements/people/${personoslashlower}/messages" ]]
then
yepyep=1
# Make sure they have not already been
# told they have a message less than 1
# hour ago
if [[ -f "announcements/people/${personoslashlower}/seen" ]] && (( ( $( stat -c %Y "announcements/people/${personoslashlower}/you_have_mail" ) + 3600 ) > the_time_now ))
then
yepyep=0
fi
if (( yepyep ))
then
if (( $(wc -l hack_of_all_hacks | cut -d ' ' -f 1) > 1 ))
then
send_msg "${channel}" "${personoslash}: you have messages, type something to see them."
else
send_msg "${channel}" "${personoslash}: you have a message, type something to see it."
fi
touch "announcements/people/${personoslashlower}/you_have_mail"
fi
fi
elif [[ "$line" =~ ^:([^ ]*)\ +PART\ +(#[^ ]+)(\ +:(.*))? ]]; then elif [[ "$line" =~ ^:([^ ]*)\ +PART\ +(#[^ ]+)(\ +:(.*))? ]]; then
sender="${BASH_REMATCH[1]}" sender="${BASH_REMATCH[1]}"
channel="${BASH_REMATCH[2]}" channel="${BASH_REMATCH[2]}"
@ -496,6 +585,7 @@ while true; do
for module in $modules_on_PART; do for module in $modules_on_PART; do
module_${module}_on_PART "$sender" "$channel" "$reason" module_${module}_on_PART "$sender" "$channel" "$reason"
done done
[[ ${sender%%!*} == hyperbot ]] && echo no > hyperbot_present
elif [[ "$line" =~ ^:([^ ]*)\ +KICK\ +(#[^ ]+)\ +([^ ]+)(\ +:(.*))? ]]; then elif [[ "$line" =~ ^:([^ ]*)\ +KICK\ +(#[^ ]+)\ +([^ ]+)(\ +:(.*))? ]]; then
sender="${BASH_REMATCH[1]}" sender="${BASH_REMATCH[1]}"
channel="${BASH_REMATCH[2]}" channel="${BASH_REMATCH[2]}"

View File

@ -80,13 +80,36 @@ transport_alive() {
# 0 If Ok # 0 If Ok
# 1 If connection failed # 1 If connection failed
transport_read_line() { transport_read_line() {
read -ru 3 line while true
# Fail. do
if [[ $? -ne 0 ]]; then ze_length="$( wc -l '/tmp/un-provoked-message-store' 2> /dev/null )"
return 1
if [[ -r /tmp/un-provoked-message-store ]] &&
[[ -w /tmp/un-provoked-message-store ]] && (( ${ze_length%% *} ))
then
read -r line < /tmp/un-provoked-message-store
line=':tlCJ99mfZl!~user@2001:ba8:1f1:f216::5 PRIVMSG #hyperbola :'"${line}"
# remove the top line of the file
if (( ${ze_length%% *} < 2 ))
then
echo -n > /tmp/un-provoked-message-store
else else
time_get_current 'transport_lastvalidtime' tail -n +2 /tmp/un-provoked-message-store |
sponge /tmp/un-provoked-message-store
fi fi
break
else
read -t 5 -ru 3 line
the_return_code="${?}"
(( the_return_code == 0 )) && break
(( the_return_code > 128 )) && continue
[[ "${the_return_code}" -ne 0 ]] && return
fi
done
time_get_current 'transport_lastvalidtime'
line=${line//$'\r'/} line=${line//$'\r'/}
} }

View File

@ -165,13 +165,35 @@ transport_alive() {
# 0 If Ok # 0 If Ok
# 1 If connection failed # 1 If connection failed
transport_read_line() { transport_read_line() {
read -ru 4 line while true
# Fail. do
if [[ $? -ne 0 ]]; then ze_length="$( wc -l '/tmp/un-provoked-message-store' 2> /dev/null )"
return 1
if [[ -r /tmp/un-provoked-message-store ]] &&
[[ -w /tmp/un-provoked-message-store ]] && (( ${ze_length%% *} ))
then
read -r line < /tmp/un-provoked-message-store
line=':tlCJ99mfZl!~user@2001:ba8:1f1:f216::5 PRIVMSG #hyperbola :'"${line}"
if (( ${ze_length%% *} < 2 ))
then
echo -n > /tmp/un-provoked-message-store
else else
time_get_current 'transport_lastvalidtime' tail -n +2 /tmp/un-provoked-message-store |
sponge /tmp/un-provoked-message-store
fi fi
break
else
read -t 5 -ru 4 line
the_return_code="${?}"
(( the_return_code == 0 )) && break
(( the_return_code > 128 )) && continue
(( the_return_code -ne 0 )) && return
fi
done
time_get_current 'transport_lastvalidtime'
line=${line//$'\r'/} line=${line//$'\r'/}
} }