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
|
CFLAGS = -Wall -Werror
|
||||||
TARGETS = bot
|
TARGETS = bot factoids
|
||||||
TARGETS += extras/factoids
|
|
||||||
|
|
||||||
all: $(TARGETS)
|
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
|
.PHONY: clean
|
||||||
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.
|
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
|
Caution
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
@ -103,26 +113,6 @@ much more difficult to accidentally create an exploit. Or create a new
|
||||||
handler in Python, Ruby, etc.
|
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
|
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
|
-- A very simple bot which will join IRC, join #newmont, and
|
||||||
-- respond to any messages with "strawberry" in them. It also
|
-- talk about strawberries. It also has some naïve nickname
|
||||||
-- has some naïve nickname collision avoidance.
|
-- collision avoidance.
|
||||||
--
|
--
|
||||||
-- This is a good place to start if you're not going to write
|
-- 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
|
-- 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")
|
prefix = os.getenv("prefix")
|
||||||
|
@ -21,17 +21,23 @@ io.stderr:write(">>> [" .. command .. "] " ..
|
||||||
(forum or "-") .. " " ..
|
(forum or "-") .. " " ..
|
||||||
(text or "") .. "\n")
|
(text or "") .. "\n")
|
||||||
|
|
||||||
|
--
|
||||||
-- Our behavior depends on what the command is
|
-- Our behavior depends on what the command is
|
||||||
|
--
|
||||||
|
|
||||||
if (command == "_INIT_") then
|
if (command == "_INIT_") then
|
||||||
-- bot sends this when it first starts up, so we can log in
|
-- bot sends this when it first starts up, so we can log in
|
||||||
print("NICK nemont")
|
print("NICK nemont")
|
||||||
print("USER newmont newmont newmont :Sample bot")
|
print("USER newmont newmont newmont :Sample bot")
|
||||||
|
|
||||||
elseif (command == "433") then
|
elseif (command == "433") then
|
||||||
-- Couldn't get the nickname we asked for
|
-- Couldn't get the nickname we asked for
|
||||||
print("NICK bot_" .. (os.time() % 500))
|
print("NICK bot_" .. (os.time() % 500))
|
||||||
|
|
||||||
elseif (command == "001") then
|
elseif (command == "001") then
|
||||||
-- IRC server sends this after successful login
|
-- IRC server sends this after successful login
|
||||||
print("JOIN #newmont")
|
print("JOIN #newmont")
|
||||||
|
|
||||||
elseif (command == "PRIVMSG") then
|
elseif (command == "PRIVMSG") then
|
||||||
-- Somebody said something!
|
-- Somebody said something!
|
||||||
if (text:find("strawberry")) then
|
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);
|
fseek(ctx->f, (ctx->hash_val % 256) * 8, SEEK_SET);
|
||||||
ctx->hash_pos = read_u32le(ctx->f);
|
ctx->hash_pos = read_u32le(ctx->f);
|
||||||
ctx->hash_len = 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;
|
ctx->entry = (ctx->hash_val / 256) % ctx->hash_len;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
|
@ -140,7 +143,7 @@ cdb_next(struct cdb_ctx *ctx, char *buf, size_t buflen)
|
||||||
uint32_t klen;
|
uint32_t klen;
|
||||||
uint32_t dlen;
|
uint32_t dlen;
|
||||||
|
|
||||||
for (;;) {
|
for (; ctx->hash_len > 0;) {
|
||||||
fseek(ctx->f, ctx->hash_pos + (ctx->entry * 8), SEEK_SET);
|
fseek(ctx->f, ctx->hash_pos + (ctx->entry * 8), SEEK_SET);
|
||||||
ctx->entry = (ctx->entry + 1) % ctx->hash_len;
|
ctx->entry = (ctx->entry + 1) % ctx->hash_len;
|
||||||
|
|
Loading…
Reference in New Issue