Skip to content

Instantly share code, notes, and snippets.

@nasonfish
Last active December 28, 2015 10:49
Show Gist options
  • Save nasonfish/7488961 to your computer and use it in GitHub Desktop.
Save nasonfish/7488961 to your computer and use it in GitHub Desktop.
CloudBot Scripting language
// anything following a double-slash will be ignored to the end of the line
// "when hear" means to hook into what the bot hears.
// The *s are wildcards, they mean "match any amount of any character" - so this means
// that we should use this method whenever a message contains "hello world" anywhere in the message.
//when hear "*hello world*" in "#Refract" {
// Inside of the block, or curly brackets, there are multiple ways to decide what do to.
// We can say something raw
//say "Hello, I am a CloudBot!" // This will say whatever comes next in quotes into the channel we received the trigger
//raw "PRIVMSG #cloudbot :Hey guys!" // This will send a raw message directly to IRC.
//reply "What's up?" // This will send a message to the channel we received the trigger, prefixed with "(triggerer) "
//set text "value" // This will set the variable 'text' to be equal to "value". value must be in quotes.
//say(get text) // Inside of parentheses, you can have commands.
//set site (web_get "http://nasonfish.com/") // This will get the data on this website.
//set site ((get site) title) // get a site's title
//set choice (pick "1" "2" "3" "4" "5" "6" "7" "8" "9") // random
//get input // get what they said
//say ((get input) 1) // get the first word in their message
//}
// planned things above, stuff below works
when hear "*hello there*" in "#refract" {
say "hey there!"
set hello "PRIVMSG nasonfish :testing stuff"
raw (get hello)
}
from util import hook
import re
import shlex
import fnmatch
@hook.event('PRIVMSG') # TODO more than PM?
def _all(inp, nick=None, chan=None, msg=None, raw=None,
input=None, bot=None, db=None, say=None, me=None, reply=None, conn=None):
db.execute("drop table if exists temp_variables")
db.execute("create table if not exists temp_variables(name primary key, value)")
storage = Execute(inp, nick, chan, msg, raw, input, bot, db, say, me, reply, conn)
# our goal here is to create a new language to easily interact with the bot without python-y stuff.
# so, people can make their own plugins really easily.
file = open('plugins/data/script.irc')
scripts = ""
l = file.readline()
while l != "":
l = re.sub(r'//.*', '', l)
if l is not "":
scripts += l
l = file.readline()
for match in re.finditer(r"when ([^\{]*)\{([^}]*)}", scripts, re.I):
# match.group(1) = statement that would trigger it
# match.group(2) = code to execute
caller = re.sub('[ \t\r\n]', ' ', match.group(1))
caller_cmds = shlex.split(caller)
if caller_cmds[0] == "hear":
if not fnmatch.fnmatch(inp[1], caller_cmds[1]):
continue
# print(":O ")
if caller_cmds[2] == "in":
if not fnmatch.fnmatch(chan, caller_cmds[3]):
continue
# print(":OO ")
else:
# print('oh no')
continue # we can't do anything about it :(
# okay, so it matched the criteria, so now we have to parse it.
for line in re.finditer(r"([^\r\n]*)\r?\n", match.group(2), re.I):
cmd = line.group(1)
cmd = re.sub(r"[\s]", " ", cmd)
if not re.match(r"[^ ]", cmd):
# print("ignored blank line")
continue # ignore that line, it's empty
cmd = re.sub(r"\(([^\)]+)\)", storage.execute_get_script, cmd)
storage.execute_script(cmd)
class Execute:
inp, nick, channel, msg, raw, input, bot, db, say, me, reply, conn = \
(None, None, None, None, None, None, None, None, None, None, None, None)
def __init__(self, inp, nick, channel, msg, raw, input, bot, db, say, me, reply, conn):
self.inp = inp
self.nick = nick
self.channel = channel
self.msg = msg
self.raw = raw
self.input = input
self.bot = bot
self.db = db
self.say = say
self.me = me
self.reply = reply
self.conn = conn
def execute_script(self, text):
# print('execute called')
word = shlex.split(text)
if word[0] == "say":
self.reply(word[1]) # changed for debug?
return True
elif word[0] == "raw":
self.conn.send(word[1])
return True
elif word[0] == "set":
self.db.execute("insert or replace into temp_variables(name, value) values (?, ?)", (word[1], word[2]))
return True
elif word[0] == "get":
return self.db.execute("select value from temp_variables where name=?", (word[1],)).fetchone()[0]
else:
# print("Command Unknown: " + word[0] + " (raw: "+text+")")
return False
def execute_get_script(self, match):
return '"' + self.execute_script(match.group(1)) + '"'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment