├── irc_connection.sh ├── README ├── data └── dreams.txt ├── hspbp-tiki-add-event └── magnus23.sh /irc_connection.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source ./configuration.sh 4 | 5 | mkdir -p "$IRC_CONNECTIONS" 6 | 7 | while true 8 | do 9 | (sleep 25; echo "/j $IRC_CHAN" > "$IRC_CONNECTIONS/$IRC_HOST/in") & 10 | ii \ 11 | -i "$IRC_CONNECTIONS" \ 12 | -s "$IRC_HOST" \ 13 | -p "$IRC_PORT" \ 14 | -n "$IRC_NICK" \ 15 | -f "$IRC_NICK" 16 | done 17 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This is a fork of an IRC-bot used by werebuild: http://werebuild.eu/wiki/John-Henry 2 | 3 | The code needed some updates. 4 | 5 | [CHANGELOG] 6 | 7 | - updated to ttytter for oauth support 8 | - added !tell for message relaying 9 | - added custom !postevent to the hspbp.org tiki calendar 10 | - added whitelisting support 11 | - some small fixes 12 | - added dreams and some personality 13 | - added an award system 14 | -------------------------------------------------------------------------------- /data/dreams.txt: -------------------------------------------------------------------------------- 1 | ACTION alszik 2 | ACTION morgolodik 3 | ACTION mocorog 4 | ACTION almodik 5 | ACTION rolad almodik 6 | ACTION almaban beszel, de nem erted mit mond, csak a neved hallod 7 | ACTION mentalis csapjai rakulcsolodnak es szetroppantjak elmedet 8 | ACTION egyik csapja elindul feled 9 | ACTION nem szereti ha a kaja sokat dumal 10 | halando! miert ebresztgetsz? 11 | azathoth falja fel zajongo lelked! 12 | biztos jo otlet engem ebresztgetni? 13 | CSOND LEGYEN! 14 | 'j 15 | zzzzzzzzzzzzzzzzzz 16 | .ch eves, alvas 17 | -------------------------------------------------------------------------------- /hspbp-tiki-add-event: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys, re 4 | 5 | try: 6 | msg=sys.argv[1] 7 | except: 8 | msg="2010-11-01 18:00+2 Test event|some description and an url: http://bit.ly/asdfa2" 9 | try: 10 | user=sys.argv[2] 11 | except: 12 | user="magnus23" 13 | 14 | parser=re.compile('^(?P\d{4})-(?P\d{2})-(?P\d{2}) (?P\d{2}):(?P\d{2})\+(?P\d+) (?P[^|]*)($|(?P<BODY>.*)$)') 15 | tokens=re.match(parser,msg) 16 | if len(tokens.group())>=8: 17 | params=tokens.groupdict('') 18 | params['USER']=user 19 | print """{{ "action": 'http://www.hspbp.org/tiki-calendar_edit_item.php', 20 | "resultxpath": 'string(//h:div[@style="color: #900"]/text())', 21 | "postfields": {{ 22 | "save[user]": "{USER}", 23 | "save[calendarId]": "1", 24 | "save[name]": "{TITLE}", 25 | "start_date_Year": "{YEAR}", 26 | "start_date_Month": "{MONTH}", 27 | "start_date_Day": "{DAY}", 28 | "start_Hour": "{HOUR}", 29 | "start_Minute": "{MINUTE}", 30 | "save[end_or_duration]": "duration", 31 | "duration_Hour": "{DURATION}", 32 | "duration_Minute": "0", 33 | "save[description]": "{BODY}", 34 | "save[status]": "1", 35 | "save[locationId]": "7", 36 | "recurrent": "0", 37 | "act": "Save"}} 38 | }}""".format(**params) 39 | sys.exit(0) 40 | else: 41 | sys.exit(1) 42 | -------------------------------------------------------------------------------- /magnus23.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source ./configuration.sh 4 | 5 | mkdir -p "$EVENTS" 6 | 7 | function nao 8 | { 9 | [[ -z "$1" ]] && { 10 | print "$(ddate '+Today is %{%A, the %e of %B%}, %Y.%N Celebrate %H') $(perl -e 'printf "@%.2f",(((time()+3600)%86400)/86.4)')" 11 | return 12 | } 13 | tmp=$(date -d "$1" "+%d %m %Y" 2>/dev/null) 14 | [[ -z "$tmp" ]] && { 15 | print "frmbl-grmbl" 16 | return 17 | } 18 | d=${tmp%% *}; tmp=${tmp#* } 19 | m=${tmp%% *}; tmp=${tmp#* } 20 | y=${tmp%% *}; tmp=${tmp#* } 21 | s=$(date -d "$1" "+%s") 22 | print "$(ddate '+%{%A, the %e of %B%}, %Y.%N (*%H*)' $d $m $y ) $(perl -e 'printf "@%.2f",((('$s'+3600)%86400)/86.4)')" 23 | } 24 | 25 | function dream 26 | { 27 | sleep $(( RANDOM % 120 )) 28 | d="$(shuf -n1 $BASE_DIR/dreams.txt)" 29 | print "$d" 30 | } 31 | 32 | function award 33 | { 34 | user="${1%%[ :]*}" 35 | user=${user//[^-a-zA-Z0-9_|]/} 36 | tmp="${1#*[ :]}" 37 | awardid="${tmp%% *}" 38 | awardid=${awardid//[^-a-zA-Z0-9_<]/} 39 | award="${tmp#* }" 40 | votes="$BASE_DIR/awards/$awardid" 41 | [[ -d $votes ]] || 42 | mkdir -p $votes 43 | [[ -n "$award" && ! -f $votes/award.txt ]] && 44 | echo "$award" >"$votes/award.txt" 45 | [[ "$award" == "$awardid" ]] && 46 | award=$(cat "$votes/award.txt") 47 | [[ -f "$votes/$user" ]] && 48 | (echo "$2"; cat <"$votes/$user" 2>/dev/null) | sort | uniq >"$votes/$user" || 49 | echo "$2" >"$votes/$user" 50 | 51 | print "$2 unlocks achievement: ($awardid) \"$award\" for $user" 52 | } 53 | 54 | function userawards 55 | { 56 | awards=$BASE_DIR/awards 57 | user="${1%%[ :]*}" 58 | user="${user//[^-a-zA-Z0-9_|]/}" 59 | result="" 60 | nominee="" 61 | for awardid in $(echo $awards/*/); do 62 | awardid="${awardid%/}" 63 | award=$(cat "$awardid/award.txt") 64 | rank=$(wc -l "$awardid/$user" 2>/dev/null | cut -d' ' -f1) 65 | [[ "$rank" -gt 1 ]] && 66 | result="$result, ${awardid##*/}[$rank]" 67 | [[ "$rank" -eq 1 ]] && 68 | nominee="$nominee, ${awardid##*/}" 69 | done 70 | [[ -z "$result" ]] && 71 | print "$user is a noob" || 72 | print "$user ${result##, }" 73 | 74 | [[ -n "$nominee" ]] && 75 | print "$user nominated for ${nominee##, }" 76 | } 77 | 78 | function listawards 79 | { 80 | result="" 81 | awards=$BASE_DIR/awards 82 | for awardid in $(echo $awards/*/); do 83 | awardid="${awardid%/}" 84 | result="$result, ${awardid##*/}" 85 | done 86 | [[ -z "$result" ]] && 87 | print "no awards yet" || 88 | print "${result##, }" 89 | } 90 | 91 | function listaward 92 | { 93 | awardid="${1%%[ :]*}" 94 | awardid=${awardid//[^-a-zA-Z0-9_<]/} 95 | [[ "$awardid" == "help" ]] && { 96 | print "help: !listaward id" 97 | return 98 | } 99 | votes="$BASE_DIR/awards/$awardid" 100 | [[ -d "$votes" ]] || { 101 | print "($awardid) is barely an achievement" 102 | return 103 | } 104 | award=$(cat $votes/award.txt) 105 | result="" 106 | nominee="" 107 | for user in $(echo $votes/*); do 108 | user=${user##*/} 109 | [[ "$user" == 'award.txt' ]] && continue 110 | rank=$(wc -l "$votes/$user" | cut -d' ' -f1) 111 | [[ "$rank" -gt 1 ]] && 112 | result="$result, $user[$rank]" 113 | [[ "$rank" -eq 1 ]] && 114 | nominee="$nominee, $user" 115 | done 116 | [[ -z "$result" ]] && 117 | print "locked: (${awardid}) $award " || 118 | print "(${awardid}) $award ${result##, }" 119 | [[ -n "$nominee" ]] && 120 | print "Nominated: ${nominee##, }" 121 | } 122 | 123 | function tell 124 | { 125 | user="${1%%[ :]*}" 126 | user=${user//[^-a-zA-Z0-9_<]/} 127 | msg="${1#*[ :]}" 128 | echo "$user: $2 says \"$msg\"" 129 | echo "$user: $2 says \"$msg\"" >>"$BASE_DIR/tell/$user" && 130 | print "ACK $2! Saving \"$msg\" for $user" || print "NACK" 131 | } 132 | 133 | function dotell 134 | { 135 | cat "$BASE_DIR/tell/$1" | while read line; do 136 | print "$line" 137 | done && rm "$BASE_DIR/tell/$1" 138 | } 139 | 140 | function auth 141 | { 142 | grep -qs "^$1$" $BASE_DIR/auth || { 143 | print "NOOOOOOOOO!!1!!tizenegy!!!" 144 | return 1 145 | } 146 | } 147 | 148 | function post_event 149 | { 150 | auth "$2" || return 151 | local text 152 | text="$(grep -q 8859 <<<"$(file - <<<"$1")" && \ 153 | iconv -f latin1 -t utf-8 <<<"$1" || \ 154 | echo "$1")" 155 | 156 | echo "Posting event: $text (sent by $2)" 157 | 158 | ./grindr/feedr <"$CALENDAR_LOGIN" 159 | (./hspbp-tiki-add-event "$text" "$2" | ./grindr/feedr) && 160 | print "ACK" || print "F'taghn! yyyy-mm-dd hh:mm+h <title>|<blabla>" 161 | } 162 | 163 | function post_tweet 164 | { 165 | auth "$2" || return 166 | local text 167 | text="$(grep -q 8859 <<<"$(file - <<<"$1")" && \ 168 | iconv -f latin1 -t utf-8 <<<"$1" || \ 169 | echo "$1")" 170 | 171 | echo "Tweeting: $text (sent by $2)" 172 | 173 | ttytter -silent -status="$text" && \ 174 | print "Tweet SUCCESS!" || print "Tweet failed... :(" 175 | } 176 | 177 | function get_tweets 178 | { 179 | while ! curl -f --silent --connect-timeout 15 \ 180 | 'http://search.twitter.com/search.atom?q=hspbp&show_user=true&rpp=50' | \ 181 | perl -C7 -0ne 'use HTML::Entities; print $1.";".decode_entities($2)."\n" 182 | while /<entry>.*?<id>.*?(\d*?)<\/id>.*?<title>(.*?)<\/title>/sg' | \ 183 | iconv -f latin1 -t utf-8 | sort -n | tail -n 20 184 | do 185 | debug "Getting tweets failed, stalling for 60 seconds" 186 | sleep 60 187 | done 188 | } 189 | 190 | function next_event_id 191 | { 192 | local id 193 | 194 | for ((id=1; id <= 20; id++)) 195 | do 196 | if [ ! -f "$EVENTS/$id" ] 197 | then 198 | echo $id 199 | return 0 200 | fi 201 | done 202 | 203 | return 1 204 | } 205 | 206 | function msg_nick 207 | { 208 | perl -ne 'print $1 if /^\d{4}-\d{2}-\d{2} \d{2}:\d{2} <(.*?)>/' <<<"$MSG" 209 | } 210 | 211 | function msg_text 212 | { 213 | perl -ne 'print $1 if /^\d{4}-\d{2}-\d{2} \d{2}:\d{2} <.*?> (.*)/' <<<"$MSG" 214 | } 215 | 216 | function validate_time 217 | { 218 | egrep -q '^([0-9]+(d|h|m|s)? ?)+$' <<<"$*" 219 | } 220 | 221 | function translate_time 222 | { 223 | if egrep -q '^([0-9]+[dhm]?)+$' <<<"$1" 224 | then 225 | # this is a countdown time 226 | echo "$*" | perl -ne 's/d/*86400\+/g; 227 | s/h/*3600\+/g; 228 | s/m/*60\+/g; 229 | s/s//g; 230 | s/\+$//; 231 | print time + eval' 232 | else 233 | # this is a timestamp 234 | date -d "$1" +%s 235 | fi 236 | } 237 | 238 | function print_help 239 | { 240 | print 'My available commands are: !tweet, !addquote, !lastquote, !randomquote, !addevent, !listevents, !delevent, !postevent, !tell, !award, !userawards, !listaward, !listawards, !nao' 241 | } 242 | 243 | function addquote 244 | { 245 | echo "$(date +%Y-%m-%d\ %H:%M:%S) $1" >> "$QUOTES" 246 | print "New quote accepted: $1" 247 | echo "New quote accepted: $1" 248 | } 249 | 250 | function addevent 251 | { 252 | time="$(perl -lne \ 253 | 'print $1 if /^((\d{4}-\d{2}-\d{2} )?(\d{2}:\d{2}(:\d{2})?)?|(\d+([dhm]?))+)/' <<<"$1")" 254 | if [ -n "$time" ] 255 | then 256 | time="$(translate_time "$time")" 257 | id=$(next_event_id) && \ 258 | { echo "$time" > "$EVENTS/$id" 259 | echo "$(perl -pe 's/^((\d{4}-\d{2}-\d{2} )?(\d{2}:\d{2}(:\d{2})?)?|(\d+([dhm]?))+) ?//' \ 260 | <<<"$1")" >> "$EVENTS/$id" 261 | print "Event $id successfully added. ($(timesplit $(( $time - $(date +%s) ))))" 262 | } || print "No more events can be added. Remove one using !delevent or let one expire." 263 | else 264 | print "I don't understand the time." 265 | fi 266 | } 267 | 268 | function delevent 269 | { 270 | id="$1" 271 | [ -f "$EVENTS/$id" ] && \ 272 | { 273 | rm "$EVENTS/$id" 274 | print "Event $id successfully removed." 275 | } || print "No such event." 276 | } 277 | 278 | function listevents 279 | { 280 | if [ $(ls "$EVENTS/" | grep -c '') -gt 0 ] 281 | then 282 | for event in $(grep -H '' "$EVENTS"/* | sed '0~2d' | sort -t : -k 2 -n | cut -d: -f 1) 283 | do 284 | print "Event ${event##*/}: $(sed -n 2p "$event") -"\ 285 | " $(timesplit $(( $(sed -n 1p "$event") - $(date +%s) )))" 286 | done 287 | else 288 | print "No running event countdowns." 289 | fi 290 | } 291 | 292 | function handle_commands 293 | { 294 | (tail --pid=$$ -fn0 "$IRC_CONNECTIONS/$IRC_HOST/$IRC_CHAN/out" |sed -u 's/[`$]//g') | while read MSG 295 | do 296 | 297 | case "${MSG##[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-2][0-9]:[0-5][0-9] -[\!]- }" in 298 | *changed\ mode\/$IRC_CHAN*\+o*${IRC_NICK}) 299 | print "i will spare your pathetic soul, for now."; continue;; 300 | jimm-erlang-bot\(\~jimm-erla@vsza.hu\)\ has\ joined\ $IRC_CHAN) 301 | print "ohai my dear food^Wfriend"; print "/mode $IRC_CHAN +o jimm-erlang-bot"; continue;; 302 | stf\(\~stf@92.43.201.132\)\ has\ joined\ $IRC_CHAN) 303 | print "come slave"; print "/mode $IRC_CHAN +o stf";continue;; 304 | esac 305 | 306 | message_text="$(msg_text)" 307 | [[ -f "$BASE_DIR/tell/$(msg_nick)" ]] && dotell "$(msg_nick)" 308 | 309 | case "$message_text" in 310 | !help) 311 | print_help ;; 312 | !addquote\ *) 313 | addquote "${message_text#\!addquote }" ;; 314 | !lastquote) 315 | print "Last quote: $(tail -n1 "$QUOTES")" ;; 316 | !quote|!randomquote) 317 | print "$(shuf -n1 "$QUOTES")" ;; 318 | !addevent\ *) 319 | addevent "${message_text#\!addevent }" ;; 320 | !delevent\ *) 321 | delevent "$(cut -d' ' -f2 <<<"$message_text")" ;; 322 | !listevents) 323 | listevents ;; 324 | !postevent\ *) 325 | post_event "${message_text#\!postevent }" "$(msg_nick)" ;; 326 | !tweet\ *) 327 | post_tweet "${message_text#\!tweet }" "$(msg_nick)" ;; 328 | !twitter\ *) 329 | post_tweet "${message_text#\!twitter }" "$(msg_nick)" ;; 330 | !tell\ *) 331 | tell "${message_text#\!tell }" "$(msg_nick)" ;; 332 | !award) 333 | print "help: !award user id [description]";; 334 | !award\ *) 335 | award "${message_text#\!award }" "$(msg_nick)" ;; 336 | !userawards) 337 | print "help: !userawards user";; 338 | !userawards\ *) 339 | userawards "${message_text#\!userawards }" "$(msg_nick)" ;; 340 | !listawards) 341 | listawards ;; 342 | !listaward) 343 | print "help: !listaward awardid";; 344 | !listaward\ *) 345 | listaward "${message_text#\!listaward }" "$(msg_nick)" ;; 346 | !nao) 347 | nao;; 348 | !nao\ *) 349 | nao "${message_text#\!nao }" ;; 350 | !karacsony) 351 | print "hmmm, renszarvas steak igazi inyenc falat!";; 352 | esac 353 | 354 | [[ $(msg_nick) == "$IRC_NICK" ]] || 355 | case "$message_text" in 356 | arise\ ${IRC_NICK}*) 357 | print "I will devour your disgusting soul, mortal!";; 358 | *hail\ ${IRC_NICK}*) 359 | print "Yes! Hail me! while you still can, until my tentacles will tear your soul apart!";; 360 | *fuck\ you\ ${IRC_NICK}*) print "/kick $(msg_nick)"; print "DON'T fuck with the mighty one!!!1!!!" ;; 361 | *imadom\ ${IRC_NICK}*) print "na meg egy hivo. mondjuk attol meg nem leszel finomabb...";; 362 | *${IRC_NICK}\ \<3*) print "tentacleporn!";; 363 | *fail\ ${IRC_NICK}) print "$(msg_nick), te hitetlen. te leszel a reggelim";; 364 | *${IRC_NICK}*) dream& ;; 365 | esac 366 | done 367 | } 368 | 369 | function handle_events 370 | { 371 | local event 372 | while syncSleep 373 | do 374 | for event in "$EVENTS"/* 375 | do 376 | [ -f "$event" ] && \ 377 | { 378 | remaining="$[ $(head -n1 "$event") - $(date +%s) ]" 379 | [ $remaining -le 0 ] && \ 380 | { 381 | print "NOW: $(tail -n1 "$event")" 382 | rm "$event" 383 | break 384 | } 385 | lastinterval=1000000000 386 | for interval in 2592000 604800 86400 21600 3600 900 300 60 15 5 1 387 | do 388 | if [ $remaining -lt $lastinterval ] && 389 | [ $remaining -ge $interval ] && 390 | [ $(( $remaining % $interval )) == 0 ] 391 | then 392 | [ $interval -ge 60 ] && \ 393 | print "Event $(basename $event): $(timesplit "$remaining")"\ 394 | " until $(tail -n1 "$event")" || \ 395 | print "$(timesplit "$remaining")" 396 | break 397 | fi 398 | lastinterval="$interval" 399 | done 400 | } 401 | done 402 | done 403 | } 404 | 405 | function handle_tweets 406 | { 407 | get_tweets > tweets 408 | cp tweets tweets.old 409 | 410 | while true 411 | do 412 | diff tweets tweets.old | perl -lne \ 413 | 'print "$2: $3 - http://www.twitter.com/$2/statuses/$1" if /^< (.\d+);(.\w+): ?(.*)/' | \ 414 | while read tweet 415 | do 416 | grep -q "hspbp" <<<"$tweet" && print "$tweet" 417 | echo "$tweet" >> log.txt 418 | done 419 | cp tweets tweets.old 420 | sleep 60 421 | get_tweets > tweets.new 422 | [[ -s tweets.new ]] && mv tweets.new tweets 423 | done 424 | } 425 | 426 | function enqueue 427 | { 428 | perl -e "use Tie::File; tie @a, \"Tie::File\", \"$1\"; push @a, \"\$ARGV[0]\"" "$2" 429 | } 430 | 431 | function dequeue 432 | { 433 | perl -le "use Tie::File; tie @a, \"Tie::File\", \"$1\"; print shift @a" 434 | } 435 | 436 | function print 437 | { 438 | enqueue "$MESSAGES" "$1" 439 | echo "$1" 440 | } 441 | 442 | function handle_messages 443 | { 444 | while syncSleep 445 | do 446 | MSG="$(dequeue "$MESSAGES")" 447 | if [ -n "$MSG" ]; then 448 | echo "$MSG" > "$IRC_CONNECTIONS/$IRC_HOST/$IRC_CHAN/in" 449 | fi 450 | done 451 | } 452 | 453 | function syncSleep 454 | { 455 | perl -e ' 456 | use Time::HiRes; 457 | $time = Time::HiRes::gettimeofday(); 458 | select(undef,undef,undef, '"${1:-0}"' + 1 - ($time - int($time)));' 459 | } 460 | 461 | function timesplit 462 | { 463 | local seconds 464 | local days 465 | local hours 466 | local minutes 467 | 468 | seconds=$(echo $1 | cut -d. -f 1) 469 | [ -z "$seconds" ] && seconds=0 470 | days=$[ $seconds / 86400 ] 471 | seconds=$[ $seconds % 86400 ] 472 | 473 | hours=$[ $seconds / 3600 ] 474 | seconds=$[ $seconds % 3600 ] 475 | minutes=$[ $seconds / 60 ] 476 | seconds=$[ $seconds % 60 ] 477 | 478 | [ $days -gt 0 ] && echo -n "$days days" && [ $seconds -gt 0 ] && echo -n ", " 479 | [ $hours -gt 0 ] && echo -n "$hours hours" && [ $seconds -gt 0 ] && echo -n ", " 480 | [ $minutes -gt 0 ] && echo -n "$minutes minutes" && [ $seconds -gt 0 ] && echo -n ", " 481 | [ $seconds -gt 0 ] && echo "$seconds seconds" 482 | } 483 | 484 | function handle_cron 485 | { 486 | monitored="$IRC_CONNECTIONS/$IRC_HOST/$IRC_CHAN/out" 487 | crond="$BASE_DIR/cron" 488 | [[ -f "$crond/ddate" ]] || touch -d yesterday "$crond/ddate" 489 | while true; do 490 | silence=$(( $(date '+%s') - $(stat -c '%Z' "$monitored" ) )) 491 | # wake up and play with flook 492 | [[ $silence -gt $(( 6 * 3600 )) ]] && { 493 | print "ACTION ???" 494 | print ".ch eves, alvas" 495 | } 496 | dd=$(stat -c '%Y' "$crond/ddate" ) 497 | midnight=$(date -d 00:00 '+%s') 498 | [[ "$dd" -lt "$midnight" ]] && { 499 | print "$(ddate '+Today is %{%A, the %e of %B%}, %Y. %NCelebrate %H') - All hail Eris!!5!" 500 | today=$BASE_DIR/holidays/$(date "+%d-%m") 501 | [[ -f "$today" ]] && print "$(cat $today 2>/dev/null)" 502 | touch "$crond/ddate" 503 | } 504 | sleep 512 505 | done 506 | } 507 | 508 | 509 | handle_commands & 510 | cmddesc=$! 511 | handle_tweets & 512 | twtdesc=$! 513 | handle_events & 514 | evdesc=$! 515 | handle_messages & 516 | msgdesc=$! 517 | handle_cron & 518 | crondesc=$! 519 | 520 | trap "kill $cmddesc $twtdesc $evdesc $msgdesc $crondesc; exit" 2 521 | 522 | wait 523 | --------------------------------------------------------------------------------