# For use with CloudBot (http://git.io/cbgit), although it'll also work as a Python module # ('import multicraft; data = multicraft.multicraft("METHOD PARAM=VALUE")') # Full API documentation coming soon (better than Multicraft's PHP-specific documentation, I'm hoping) # This file (multicraft.py) Copyright 2013 Steven Smith (blha303). All Rights Reserved. # GPLv3 license (because CloudBot is GPL) # http://opensource.org/licenses/GPL-3.0 from util import hook, http from urllib import urlencode import json url = "MULTICRAFTURL/api.php" user = "USER" apikey = 'APIKEY' @hook.command(adminonly=True) def multicraft(inp, reply=''): """multicraft [option=value]... - Call multicraft server""" def getqstring(method, user, key, data={}): values = [] for k, v in data.iteritems(): values.append(v) key = http.get("http://blha303.com.au/md5.php?q=%s%s%s%s" % (key, method, user, "".join(values))) string = urlencode(dict(_MulticraftAPIMethod=method, _MulticraftAPIUser=user, _MulticraftAPIKey=key)) string += "&" + urlencode(data) return string method = inp.split(" ")[0] moredata = {} if len(inp.split(" ")) > 1: for i in inp.split(" ")[1:]: if not "=" in i: return "Invalid data at '%s'." % i moredata[i.split("=")[0]] = i.split("=")[1] data = http.get_json(url, post_data=getqstring(method, user, apikey, data=moredata)) if not data['success']: return "Failure: %s" % ", ".join(data['errors']) else: return json.dumps(data['data']) def getCommand(inp, method): """ for methods with only an 'id' parameter, like getUser example usage: getCommand("1", "getUser") will return {"User": {"lang": "", "email": "...", "global_role": "...", "id": "1", "name": "admin"}} as a JSON string """ try: id = int(inp.split(" ")[0]) except: return "id must be an integer." data = multicraft("%s id=%s" % (method, id)) if not "Failure: " in data: return data else: return None def updateCommand(inp, method): """ For methods that take field>value parameters. inp should be a string, "field=value field=value ..." Example: updateCommand("name=admin email=admin@localhost.local", "findUsers") returns {"Users": {"1": "admin"}} as a JSON string """ inp = inp.split(" ") def fix(text): return str(text).replace('"', "'").replace("u'", "'") dats = {} for i in inp: if not "=" in i: return "Invalid data at %s" % i dats[i.split("=")[0]] = i.split("=")[1] fields = [] values = [] for k in dats: fields.append(k) values.append(dats[k]) data = multicraft("%s field=%s value=%s" % (method, fix(fields), fix(values))) if not "Failure: " in data: return data else: return None @hook.command(adminonly=True) def mcrestart(inp): """mcrestart - Restart specified server. Admin only. id must be an integer.""" data = getCommand(inp, "restartServer") if data == "[]": return "Success restarting server %s" % inp.split(" ")[0] else: return "Error restarting server %s. Invalid server ID?" % inp.split(" ")[0] @hook.command(adminonly=True, autohelp=False) def mclist(): """mclist - List servers.""" out = "" data = multicraft("listServers") if not "Failure " in data: data = json.loads(data)["Servers"] for k in data: v = data[k] if out == "": out = "%s (%s)" % (v, k) else: out = out + ", " + "%s (%s)" % (v, k) return "Servers: " + out else: return data @hook.command(adminonly=True) def mcfindusers(inp): """mcfindusers [name=value] [email=value] ... - Find user matching name, email, role, etc""" data = updateCommand(inp, "findUsers") if data: data = json.loads(data) if data["Users"] == []: return "No results." else: out = "" for i in data["Users"]: if not out: out = "%s (%s)" % (data["Users"][i], i) else: out = out + ", %s (%s)" % (data["Users"][i], i) return "Users: %s" % out else: return "Error getting data!"