mirror of https://github.com/nealey/irc-bot
Add infobot example
This commit is contained in:
parent
98aced9bbc
commit
45d4b56873
11
Makefile
11
Makefile
|
@ -1,11 +1,14 @@
|
|||
CFLAGS = -Wall -Werror
|
||||
TARGETS = bot
|
||||
TARGETS += extras/factoids
|
||||
TARGETS = bot factoids
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
extras/factoids: extras/factoids.o extras/cdb.o extras/cdbmake.o
|
||||
%: src/%
|
||||
cp $< $@
|
||||
|
||||
src/bot:
|
||||
src/factoids: src/factoids.o src/cdb.o src/cdbmake.o
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f $(TARGETS) *.o extras/*.o
|
||||
rm -f $(TARGETS) $(addprefix src/, $(TARGETS)) src/*.o
|
||||
|
|
30
README
30
README
|
@ -84,6 +84,16 @@ want, and you don't even need to restart anything to apply your changes,
|
|||
since a new handler is launched for each message.
|
||||
|
||||
|
||||
factoids
|
||||
========
|
||||
|
||||
A program to maintain a low-overhead, read-optimized database file, which
|
||||
can store multiple values for each key. This was written to help develop
|
||||
infobots, but can also be used for any other key/value store needed.
|
||||
|
||||
The `infobot.py` program in `contrib/` has a simple infobot implementation.
|
||||
|
||||
|
||||
Caution
|
||||
=======
|
||||
|
||||
|
@ -103,26 +113,6 @@ much more difficult to accidentally create an exploit. Or create a new
|
|||
handler in Python, Ruby, etc.
|
||||
|
||||
|
||||
Extras
|
||||
======
|
||||
|
||||
Included AT NO ADDITIONAL COST, in the `extras/` directory, are:
|
||||
|
||||
|
||||
newmont
|
||||
-------
|
||||
|
||||
A simple handler, written in lua.
|
||||
|
||||
|
||||
factoids
|
||||
--------
|
||||
|
||||
A program to maintain a low-overhead, read-optimized database file, which
|
||||
can store multiple values for each key. This was written to help develop
|
||||
infobots, but can also be used for any other key/value store needed.
|
||||
|
||||
|
||||
Author
|
||||
======
|
||||
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
#! /usr/bin/python
|
||||
|
||||
##
|
||||
## Example of an infobot, using the provided helper.
|
||||
##
|
||||
|
||||
import sys
|
||||
import os
|
||||
from subprocess import *
|
||||
|
||||
db = "infobot.cdb"
|
||||
|
||||
command = os.environ.get("command")
|
||||
sender = os.environ.get("sender")
|
||||
forum = os.environ.get("forum")
|
||||
text = os.environ.get("text")
|
||||
|
||||
def factoids(*args):
|
||||
cmd = ["./factoids"]
|
||||
cmd.extend(args)
|
||||
p = Popen(cmd, stdout=PIPE, stderr=STDOUT)
|
||||
for bline in p.stdout:
|
||||
line = bline.decode('utf-8')[:-1]
|
||||
print("PRIVMSG %s :%s" % (forum, line))
|
||||
|
||||
# Create db if it doesn't exist
|
||||
if not os.path.exists(db):
|
||||
factoids("-n", db)
|
||||
|
||||
if command == "_INIT_":
|
||||
print("NICK infotest")
|
||||
print("USER infotest infotest infotest: Infobot example")
|
||||
elif command == "001":
|
||||
print("JOIN #infotest")
|
||||
elif command == "PRIVMSG":
|
||||
if text[0] == "!":
|
||||
txt = text[1:]
|
||||
if " += " in txt:
|
||||
key, val = txt.split(' += ', 1)
|
||||
factoids("-a", val, db, key)
|
||||
elif " -= " in txt:
|
||||
key, glob = txt.split(' -= ', 1)
|
||||
factoids("-r", glob, db, key)
|
||||
else:
|
||||
factoids("-l", db, txt)
|
||||
else:
|
||||
factoids(db, text)
|
||||
|
|
@ -2,12 +2,12 @@
|
|||
|
||||
--
|
||||
-- A very simple bot which will join IRC, join #newmont, and
|
||||
-- respond to any messages with "strawberry" in them. It also
|
||||
-- has some naïve nickname collision avoidance.
|
||||
-- talk about strawberries. It also has some naïve nickname
|
||||
-- collision avoidance.
|
||||
--
|
||||
-- This is a good place to start if you're not going to write
|
||||
-- your handler in lua. If you *do* want to use lua, you should
|
||||
-- take a look at bot.lua instead.
|
||||
-- think about how to make a better design :)
|
||||
--
|
||||
|
||||
prefix = os.getenv("prefix")
|
||||
|
@ -21,17 +21,23 @@ io.stderr:write(">>> [" .. command .. "] " ..
|
|||
(forum or "-") .. " " ..
|
||||
(text or "") .. "\n")
|
||||
|
||||
--
|
||||
-- Our behavior depends on what the command is
|
||||
--
|
||||
|
||||
if (command == "_INIT_") then
|
||||
-- bot sends this when it first starts up, so we can log in
|
||||
print("NICK nemont")
|
||||
print("USER newmont newmont newmont :Sample bot")
|
||||
|
||||
elseif (command == "433") then
|
||||
-- Couldn't get the nickname we asked for
|
||||
print("NICK bot_" .. (os.time() % 500))
|
||||
|
||||
elseif (command == "001") then
|
||||
-- IRC server sends this after successful login
|
||||
print("JOIN #newmont")
|
||||
|
||||
elseif (command == "PRIVMSG") then
|
||||
-- Somebody said something!
|
||||
if (text:find("strawberry")) then
|
|
@ -129,7 +129,10 @@ cdb_find(struct cdb_ctx *ctx, char *key, size_t keylen)
|
|||
fseek(ctx->f, (ctx->hash_val % 256) * 8, SEEK_SET);
|
||||
ctx->hash_pos = read_u32le(ctx->f);
|
||||
ctx->hash_len = read_u32le(ctx->f);
|
||||
|
||||
if (ctx->hash_len > 0) {
|
||||
ctx->entry = (ctx->hash_val / 256) % ctx->hash_len;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
@ -140,7 +143,7 @@ cdb_next(struct cdb_ctx *ctx, char *buf, size_t buflen)
|
|||
uint32_t klen;
|
||||
uint32_t dlen;
|
||||
|
||||
for (;;) {
|
||||
for (; ctx->hash_len > 0;) {
|
||||
fseek(ctx->f, ctx->hash_pos + (ctx->entry * 8), SEEK_SET);
|
||||
ctx->entry = (ctx->entry + 1) % ctx->hash_len;
|
||||
|
Loading…
Reference in New Issue