Browse Source

adding framework and some commands for ircbot part

tags/v0.1
Ben Kurtovic 13 years ago
parent
commit
cfaa68c558
5 changed files with 196 additions and 0 deletions
  1. +1
    -0
      .gitignore
  2. +90
    -0
      actions.py
  3. +73
    -0
      bot.py
  4. +25
    -0
      config.py
  5. +7
    -0
      main.py

+ 1
- 0
.gitignore View File

@@ -1 +1,2 @@
*.pyc
secure_config.py

+ 90
- 0
actions.py View File

@@ -0,0 +1,90 @@
# -*- coding: utf-8 -*-

import string, re, subprocess
from config import *

s, send, say, action, notice, join = None, None, None, None, None, None

def check_triggers(cmds, act, nick, ident, host, chan, msg = None):
global s, send, say, action, notice, join # set commands as globals so we can use them in other functions
s, send, say, action, notice, join = cmds # unpack commands

if act == "join":
pass

if act == "msg_private":
pass

if act == "msg_public":
pass

if act == "msg":
if msg == "!test":
cmd_test(nick, chan)
if msg.startswith("!git"):
cmd_git(nick, host, chan, msg)

def get_args(msg): # get command arguments
args = msg.strip().split(' ') # strip out extra whitespace and split the message into a list
while '' in args: # remove any empty arguments
args.remove('')
return args[1:] # remove the command itself

def cmd_test(nick, chan): # bot test
say(chan, "'sup %s?" % nick)

def cmd_git(nick, host, chan, msg): # commands to interface with the bot's git repository
if host not in ADMINS:
say(chan, "%s: you must be a bot admin to use this command." % nick)
return

args = get_args(msg)
if not args:
say(chan, "%s: no arguments provided." % nick)
return

if args[0] == "help": # display all commands
cmds = ["branch (show current branch)", "branches (show all branches)", "checkout (switch branches)", "pull (update current branch)"]
cmds = ', '.join(cmds)
say(chan, "%s: sub-commands are: %s" % (nick, cmds))

elif args[0] == "branch": # get our current branch
branch = subprocess.check_output(['git', 'name-rev', '--name-only', 'HEAD'], stderr=subprocess.STDOUT) # git name-rev --name-only HEAD
branch = branch[:-1] # strip newline
say(chan, "%s: currently on branch '%s'." % (nick, branch))

elif args[0] == "branches": # get list of branches
branches = subprocess.check_output(['git', 'branch'], stderr=subprocess.STDOUT) # git branch
branches = branches[:-1] # strip newline
branches = branches.replace('\n* ', ', ') # cleanup extraneous characters
branches = branches.replace('* ', ' ')
branches = branches.replace('\n ', ', ')
branches = branches.strip()
say(chan, "%s: branches: %s." % (nick, branches))

elif args[0] == "checkout": # switch branches
try:
branch = args[1]
except IndexError: # no branch name provided
say(chan, "%s: switch to which branch?" % nick)
return
try:
result = subprocess.check_output(['git', 'checkout', branch], stderr=subprocess.STDOUT) # git checkout our_branch
result = result[:-1] # strip newline
result = string.lower(result[0] + result[1:]) # lowercase first word
say(chan, "%s: %s." % (nick, result))
except subprocess.CalledProcessError: # git couldn't switch branches
say(chan, "%s: branch '%s' does not exist!" % (nick, branch))

elif args[0] == "pull": # pull from remote repository
branch = subprocess.check_output(['git', 'name-rev', '--name-only', 'HEAD'], stderr=subprocess.STDOUT) # git name-rev --name-only HEAD
branch = branch[:-1] # strip newline
say(chan, "%s: pulling branch '%s' from remote..." % (nick, branch))
result = subprocess.check_output(['git', 'pull', 'origin', branch]) # pull from remote
if "Already up-to-date." in result:
say(chan, "%s: done; no new changes." % nick)
else:
say(chan, "%s: done; new changes merged." % nick)

else:
say(chan, "%s: unknown argument: '%s'." % (nick, arg[0]))

+ 73
- 0
bot.py View File

@@ -0,0 +1,73 @@
# -*- coding: utf-8 -*-

## Imports
import socket, string, re
from actions import *
from config import *
from secure_config import *

def send(msg): # send a message 'msg' to the server
s.send(msg + "\r\n")
print " %s" % msg

def say(target, msg): # send a private message 'msg' to 'target'
send("PRIVMSG %s :%s" % (target, msg))

def action(target, msg): # send a message as an action
say(target,"%sACTION %s%s" % (chr(1), msg, chr(1)))

def notice(target, msg): # send a notice 'msg' to 'target'
send("NOTICE %s :%s" % (target, msg))

def join(chan): # join channel 'chan'
send("JOIN %s" % chan)

cmds = (s, send, say, action, notice, join) # pack up commands

def main():
readbuffer = str()
data = [s, send, say, notice, join]
while 1:
readbuffer = readbuffer + s.recv(1024)
temp = string.split(readbuffer, "\n")
readbuffer = temp.pop()
for line in temp:
line2 = string.split(string.rstrip(line))

if line2[1] == "JOIN":
nick, ident, host = re.findall(":(.*?)!(.*?)@(.*?)\Z", line2[0])[0]
chan = line2[2][1:]

check_triggers(cmds, "join", nick, ident, host, chan) # check if there's anything we can respond to, and if so, respond

if line2[1] == "PRIVMSG":
nick, ident, host = re.findall(":(.*?)!(.*?)@(.*?)\Z", line2[0])[0]
msg = ' '.join(line2[3:])[1:]
chan = line2[2]

if chan == NICK: # if line2[2] is us, this is a privmsg to us, so set 'chan' as the nick of the sender
chan = nick
check_triggers(cmds, "msg_private", nick, ident, host, chan, msg) # only respond if it's a private message
else:
check_triggers(cmds, "msg_public", nick, ident, host, chan, msg) # only respond if it's a public (channel) message

check_triggers(cmds, "msg", nick, ident, host, chan, msg) # check for general messages

if msg == "!restart": # hardcode the !restart command (we can't return from within actions.py)
if host in ADMINS:
return True

if line2[0] == "PING": # If we are pinged, pong back to the server
send("PONG %s" % line2[1])

if line2[1] == "376":
if NS_AUTH:
say("NickServ", "IDENTIFY %s %s" % (NS_USER, NS_PASS))
join(CHAN)

if __name__ == "__main__":
s = socket.socket()
s.connect((HOST, PORT))
send("NICK %s" % NICK)
send("USER %s %s bla :%s" % (IDENT, HOST, REALNAME))
main()

+ 25
- 0
config.py View File

@@ -0,0 +1,25 @@
# -*- coding: utf-8 -*-

# our server's hostname
HOST = "irc.freenode.net"

# our server's port
PORT = 6667

# our nick
NICK = "EarwigBot|2"

# our ident
IDENT = "earwigbot"

# our real name
REALNAME = "[[w:en:User:EarwigBot]]"

# channel to join on startup
CHAN = "##earwigbot"

# sleep this number of seconds in between API calls and messages sent to IRC
THROTTLE = 1

# hostnames of users who can update/restart the bot with !update
ADMINS = ["wikipedia/The-Earwig"]

+ 7
- 0
main.py View File

@@ -0,0 +1,7 @@
# -*- coding: utf-8 -*-

from subprocess import *

while 1:
cmd = ['python', 'bot.py']
call(cmd)

Loading…
Cancel
Save