def raw_exec(): if request.json: # Using application/json headers post_data = request.json else: # Using form or x-www-form-urlencoded headers post_data = request.forms if not post_data: return {'success': False} try: if "args" in post_data and "data" in post_data: output.warning( "Execution from webpanel: [%s] [%s]" % (str(post_data['args']), str(post_data['data'])), "WEBSERVER") bot.write(post_data['args'].split(), bot.format(post_data['data'])) return {'success': True} elif "args" in post_data: output.warning( "Execution from webpanel: [%s]" % str(post_data['args']), "WEBSERVER") bot.write(post_data['args'].split()) return {'success': True} else: return {'success': False} except: return {'success': False}
def mod_load(name): home = os.getcwd() name = name.replace('.py', '') # Get all files in modules directory tmp = os.listdir(os.path.join(home, 'modules')) modules = [] for module in tmp: if module.endswith('.pyc'): continue module = module.replace('.py', '') modules.append(module) if name not in modules: return {'success': False, 'message': 'Module doesn\'t exist'} if name in bot.modules: return {'success': False, 'message': 'Module already loaded'} if name in bot.load: return {'success': False, 'message': 'Module already set to load'} if name in bot.unload: # Remove from unload, and add to load del bot.unload[bot.unload.index(name)] # Try and load here. If it doesn't work, make sure it's not in bot.load, and output error # If it works, add to bot.load filename = os.path.join(home, 'modules', name + '.py') try: bot.setup_module(name, filename, is_startup=False) except Exception as e: return {'success': False, 'message': 'Exception: ' + str(e)} output.warning("Execution from webpanel: Load module %s" % str(name), "WEBSERVER") bot.load.append(name) return {'success': True}
def check(ip): ip = str(ip) data = web.get(base % web.quote(ip)).read().replace('\n', '').replace('\r', '') items = re.compile(r'<div class="contain">.*?<p>(.*?)</p>').findall(data) if not items: return item = web.striptags(items[0]) if 'We don\'t have data on this IP currently.' in item: return elif 'none of its visits have resulted' in item: return else: item = item.split('Below', 1)[0] if 'The Project Honey Pot system has ' in item: item = item.split('The Project Honey Pot system has ')[1] item = item[0].upper() + item[1:] if 'This IP has not seen any suspicious activity' in data: if 'the IP address' in item: item = item.replace('the IP address', '%s' % ip) output.warning(str(item) + 'This is an old record so it might be invalid.') return if 'the IP address' in item: item = item.replace('the IP address', '{red}%s{c}' % ip) return '{b}%s{b}' % item.strip()
def check(ip): ip = str(ip) data = web.text(base % web.quote(ip)).replace('\n', '').replace('\r', '') items = re.compile(r'<div class="contain">.*?<p>(.*?)</p>').findall(data) if not items: return item = web.striptags(items[0]) if 'We don\'t have data on this IP currently.' in item: return elif 'none of its visits have resulted' in item: return else: item = item.split('Below', 1)[0] if 'The Project Honey Pot system has ' in item: item = item.split('The Project Honey Pot system has ')[1] item = item[0].upper() + item[1:] if 'This IP has not seen any suspicious activity' in data: if 'the IP address' in item: item = item.replace('the IP address', '%s' % ip) output.warning( str(item) + 'This is an old record so it might be invalid.') return if 'the IP address' in item: item = item.replace('the IP address', '{red}%s{c}' % ip) if 'Double check your URL to make sure this error' in item: return return '{b}%s{b}' % item.strip()
def collect_incoming_data(self, data): self.buffer += data if not data: return if self.debug: output.warning(data, 'DEBUG') self.raw = data.replace('\x02', '').replace('\r', '') line = self.raw.strip() if not line.startswith(':'): return try: if line[1::].split()[0] == self.nick: return code = line.split()[1] getattr(triggers, 'trigger_%s' % code)( self, line, ) except (AttributeError, IndexError, KeyError): return
def setup(self): self.variables = {} filenames = [] if not hasattr(self.config, 'enable'): for fn in os.listdir(os.path.join(home, 'modules')): if fn.endswith('.py') and not fn.startswith('_'): filenames.append(os.path.join(home, 'modules', fn)) else: for fn in self.config.enable: filenames.append(os.path.join(home, 'modules', fn + '.py')) if hasattr(self.config, 'extra'): for fn in self.config.extra: if os.path.isfile(fn): filenames.append(fn) elif os.path.isdir(fn): for n in os.listdir(fn): if n.endswith('.py') and not n.startswith('_'): filenames.append(os.path.join(fn, n)) # Add system modules that the user should always require. Still can # be removed by deleting them or moving them out of the system # modules directory for fn in os.listdir(os.path.join(home, 'core/modules')): if fn.endswith('.py') and not fn.startswith('_'): filenames.append(os.path.join(home, 'core/modules', fn)) # Should fix excluded_modules = getattr(self.config, 'exclude', []) filenames = sorted(list(set(filenames))) # Reset some variables that way we don't get dups self.modules = [] self.cmds = {} # Load modules for filename in filenames: name = os.path.basename(filename)[:-3] if name in excluded_modules: continue #if name in sys.modules: # del sys.modules[name] try: module = imp.load_source(name, filename) except Exception as e: output.error("Failed to load %s: %s" % (name, e)) else: if hasattr(module, 'setup'): module.setup(self) self.register(vars(module)) self.modules.append(name) if self.modules: output.info('Registered modules: ' + ', '.join(self.modules)) else: output.warning('Couldn\'t find any modules') self.bind_commands()
def mod_reload(name=None): if not name: output.warning("Execution from webpanel: Reload all modules", "WEBSERVER") reload.reload_all_modules(bot) return {'reload': True} else: output.warning("Execution from webpanel: Reload module %s" % str(name), "WEBSERVER") reload.reload_module(bot, str(name)) return {'reload': True}
def update(code, input): """Pulls the latest versions of all modules from Git""" if not sys.platform.startswith('linux'): output.warning('Warning: {b}Using a non-unix OS, might fail to work!') try: proc = subprocess.Popen( 'git pull', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) git_data = proc.communicate()[0] except: return code.say('Either Git isn\'t installed or there was an error! (Using Windows?)') if git_data.strip('\n') == 'Already up-to-date.': return code.say('{b}No updates found.') data = git_data if re.match(r'^Updating [a-z0-9]{7}\.\.[a-z0-9]{7}$', data.strip('\n')): # Pretty sure files are conflicting... return code.say('{b}Files are conflicting with the update. Please refork the bot!') # per-file additions/subtractions that spam stuff data = re.sub(r'[0-9]+ [\+\-]+', '', data).replace('\n', ' ') # mode changes, as those are unimportant data = re.sub(r'create mode [0-9]+ [a-zA-Z0-9\/\\]+\.py', '', data) # commit hashes, different color data = re.sub( r'(?P<first>[a-z0-9]{7})\.\.(?P<second>[a-z0-9]{7})', '{purple}\g<first>..\g<second>{c}', data) # make different files depending on the importance data = re.sub( r'core/modules/(?P<name>[a-zA-Z0-9]+)\.py', '\g<name>.py ({red}core{c})', data) data = re.sub( r'core/(?P<name>[a-zA-Z0-9]+)\.py', '\g<name>.py ({red}core{c})', data) data = re.sub(r'code\.py', 'code.py ({red}base{c})', data) data = re.sub( r'modules/(?P<name>[a-zA-Z0-9]+)\.py', '\g<name>.py ({blue}module{c})', data) data = re.sub( r'util/(?P<name>[a-zA-Z0-9]+)\.py', '\g<name>.py ({pink}util{c})', data) data = re.sub(r'lib/(?P<dir>[a-zA-Z0-9]+)/(?P<name>[a-zA-Z0-9]+)\.py', '\g<name>.py ({pink}\g<dir> - util{c})', data) data = data.replace('Fast-forward', '') # Do a little with file changes data = re.sub( r'(?P<files>[0-9]{1,3}) files? changed', '{green}\g<files>{c} file(s) changed', data) data = re.sub(r'(?P<ins>[0-9]{1,6}) insertions\(\+\)\, (?P<dels>[0-9]{1,6}) deletions\(\-\)', '+{green}\g<ins>{c}/-{red}\g<dels>{c}', data) data = re.sub( r'(?P<chars>[0-9]{1,6}) insertions?\(\+\)', '{green}\g<chars>{c} addition(s)', data) data = re.sub( r'(?P<chars>[0-9]{1,6}) deletions?\(\+\)', '{green}\g<chars>{c} deletion(s)', data) while ' ' in data: data = data.replace(' ', ' ') code.say('Github: {b}' + data.strip()) core_stuff = ['code.py', 'core/', 'util/', 'lib/'] for item in core_stuff: if item.lower() in git_data.lower().strip('\n'): code.say( '{b}{red}Core files have been edited, restarting the bot!{c}') return code.restart() reload_all_modules(code) code.say('{b}Reloaded all modules')
def found_terminator(self): line = self.buffer self.raw = line if line.endswith('\r'): line = line[:-1] self.buffer = '' if line.startswith(':'): source, line = line[1:].split(' ', 1) else: source = None if ' :' in line: argstr, text = line.split(' :', 1) args = argstr.split() args.append(text) else: args = line.split() text = args[-1] origin = Origin(self, source, args) if args[0] == 'PING': self.write(('PONG', text)) self.lastping = int(time.time()) return if args[0] == 'PONG': self.lastping = int(time.time()) return if self.debug: output.warning(repr(self.raw), 'DEBUG') try: if source and origin.nick != self.nick: getattr(triggers, 'trigger_%s' % args[0])( self, origin, line, args, text, ) except AttributeError: pass except KeyError: pass # Execute this last so we know that out data is parsed first. # Slightly slower but we know we can get up-to-date information if args[0] == 'PRIVMSG': if self.muted and text[1::].split()[0].lower() not in [ 'unmute', 'help', 'mute' ]: return dispatch(self, origin, tuple([text] + args))
def checkping(code): while True: try: diff = int(time.time()) - code.lastping if diff > code.irc_timeout: output.warning("Connection from IRC timed out after %s seconds, initiating reconnect..." % code.irc_timeout) code.restart() except: pass time.sleep(5)
def setup(self): self.variables = {} filenames = [] for fn in os.listdir(os.path.join(home, 'modules')): if fn.endswith('.py') and not fn.startswith('_'): filenames.append(os.path.join(home, 'modules', fn)) if self.config('extra'): for fn in self.config('extra'): if os.path.isfile(fn): filenames.append(fn) elif os.path.isdir(fn): for n in os.listdir(fn): if n.endswith('.py') and not n.startswith('_'): filenames.append(os.path.join(fn, n)) # Add system modules that the user should always require. Still can # be removed by deleting them or moving them out of the system # modules directory for fn in os.listdir(os.path.join(home, 'core/modules')): if fn.endswith('.py') and not fn.startswith('_'): filenames.append(os.path.join(home, 'core/modules', fn)) # Should fix excluded_modules = self.config('excluded_modules', []) filenames = sorted(list(set(filenames))) # Reset some variables that way we don't get dups self.modules = [] self.cmds = {} # Load modules for filename in filenames: name = os.path.basename(filename)[:-3] if name in excluded_modules: continue # if name in sys.modules: # del sys.modules[name] try: module = imp.load_source(name, filename) except Exception as e: output.error("Failed to load %s: %s" % (name, e)) else: if hasattr(module, 'setup'): module.setup(self) self.register(vars(module)) self.modules.append(name) if self.modules: output.info('Registered modules: ' + ', '.join(self.modules)) else: output.warning('Couldn\'t find any modules') self.bind_commands()
def checkping(code): while True: try: diff = int(time.time()) - code.lastping if diff > code.irc_timeout: output.warning( "Connection from IRC timed out after %s seconds, initiating reconnect..." % code.irc_timeout) code.restart() except: pass time.sleep(5)
def trigger_433(code, origin, line, args, text): """ ID: ERR_NICKNAMEINUSE Decription: Returned by the NICK command when the given nickname is already in use Format: <nick> :<reason> """ if not code.debug: output.warning('Nickname {} is already in use. Trying another..'.format(code.nick)) nick = code.nick + '_' code.write(('NICK', nick)) code.nick = nick.encode('ascii', 'ignore')
def trigger_433(code, origin, line, args, text): """ ID: ERR_NICKNAMEINUSE Decription: Returned by the NICK command when the given nickname is already in use Format: <nick> :<reason> """ if not code.debug: output.warning( 'Nickname {} is already in use. Trying another..'.format( code.nick)) nick = code.nick + '_' code.write(('NICK', nick)) code.nick = nick.encode('ascii', 'ignore')
def __write(self, args, text=None, raw=False): try: if raw: temp = ' '.join(args)[:510] + ' :' + text + '\r\n' elif not raw: if text: # 510 because CR and LF count too temp = (' '.join(args) + ' :' + text)[:510] + '\r\n' else: temp = ' '.join(args)[:510] + '\r\n' self.push(temp) if self.debug and 'nickserv' not in temp.lower(): output.warning(' > ' + temp, 'DEBUG') except IndexError: return
def found_terminator(self): line = self.buffer self.raw = line if line.endswith('\r'): line = line[:-1] self.buffer = '' if line.startswith(':'): source, line = line[1:].split(' ', 1) else: source = None if ' :' in line: argstr, text = line.split(' :', 1) args = argstr.split() args.append(text) else: args = line.split() text = args[-1] origin = Origin(self, source, args) if args[0] == 'PING': self.write(('PONG', text)) return if self.debug: output.warning(repr(self.raw), 'DEBUG') try: if source and origin.nick != self.nick: getattr(triggers, 'trigger_%s' % args[0])(self, origin, line, args, text,) except AttributeError: pass # Execute this last so we know that out data is parsed first. # Slightly slower but we know we can get up-to-date information # Fixing the bug in tell.py when you tried getting the users # messages to replace too fast if args[0] == 'PRIVMSG': if self.muted and text[1::].split()[0].lower() not in ['unmute', 'help', 'mute']: return self.dispatch(origin, tuple([text] + args))
def dispatch(self, origin, args): bytes, event, args = args[0], args[1], args[2:] text = decode(bytes) # Check permissions specifically for the blocking, so we're # not blocking admins/owners. admin = check_perm(origin, [self.config('owner')]) if not admin: admin = check_perm(origin, self.config('admins', [])) # Blocking here... match = [ True if re.match( mask, '{}!{}@{}'.format(origin.nick, origin.user, origin.host)) else False for mask in self.re_blocks ] if True in match and not admin: output.warning( 'Ignoring user %s matching a mask in the ignore list' % (origin.nick), 'BLOCKS') return for priority in ('high', 'medium', 'low'): items = self.commands[priority].items() for regexp, funcs in items: for func in funcs: if event != func.event: continue match = regexp.match(text) if not match: continue code = wrapped(self, origin, text, match) input = input_wrapper(code, origin, text, bytes, match, event, args) if func.thread: targs = (self, func, origin, code, input) t = threading.Thread(target=call, args=targs) t.start() else: call(self, func, origin, code, input)
def setup(code): global bot bot = code if not bot.config('webserver'): return if not bot.config('webserver_password'): return output.warning('To use the builtin webserver, you must set a password in the config', 'WEBSERVER') try: threading.Thread(target=daemon, kwargs=dict()).start() except: return
def mod_unload(name): home = os.getcwd() name = name.strip('.py') # Get all files in modules directory tmp = os.listdir(os.path.join(home, 'modules')) modules = [] for module in tmp: if module.endswith('.pyc'): continue module = module.replace('.py', '') modules.append(module) if name not in modules: return {'success': False, 'message': 'That module doesn\'t exist'} if name in bot.unload: return {'success': False, 'message': 'Module already unloaded'} if name in bot.load: # Remove from load, and add to unload del bot.load[bot.load.index(name)] output.warning("Execution from webpanel: Unload module %s" % str(name), "WEBSERVER") bot.unload.append(name) reload.reload_all_modules(bot) return {'success': True}
def setup(code): global bot bot = code id = str(gen(0, 10000000)) bot.set('webserver.object', id) # Nasty area, we check for configuration options, some are required and some arent if not bot.config('webserver'): return if not bot.config('webserver_password'): return output.warning('To use the builtin webserver, you must set a password in the config', 'WEBSERVER') port = bot.config('webserver_port', 8888) thread.start_new_thread(checkstate, (bot, input, id,)) thread.start_new_thread(init, (str(host), int(port),))
def setup(code): global bot bot = code if not bot.config('webserver'): return if not bot.config('webserver_password'): return output.warning( 'To use the builtin webserver, you must set a password in the config', 'WEBSERVER') try: threading.Thread(target=daemon, kwargs=dict()).start() except: return
def raw_exec(): if request.json: # Using application/json headers post_data = request.json else: # Using form or x-www-form-urlencoded headers post_data = request.forms if not post_data: return {'success': False} try: if "args" in post_data and "data" in post_data: output.warning("Execution from webpanel: [%s] [%s]" % (str(post_data['args']), str(post_data['data'])), "WEBSERVER") bot.write(post_data['args'].split(), bot.format(post_data['data'])) return {'success': True} elif "args" in post_data: output.warning("Execution from webpanel: [%s]" % str(post_data['args']), "WEBSERVER") bot.write(post_data['args'].split()) return {'success': True} else: return {'success': False} except: return {'success': False}
def dispatch(self, origin, args): bytes, event, args = args[0], args[1], args[2:] text = decode(bytes) # Check permissions specifically for the blocking, so we're # not blocking admins/owners. admin = check_perm(origin, [self.config('owner')]) if not admin: admin = check_perm(origin, self.config('admins', [])) # Blocking here... match = [True if re.match(mask, '{}!{}@{}'.format(origin.nick, origin.user, origin.host)) else False for mask in self.re_blocks] if True in match and not admin: output.warning('Ignoring user %s matching a mask in the ignore list' % (origin.nick), 'BLOCKS') return for priority in ('high', 'medium', 'low'): items = self.commands[priority].items() for regexp, funcs in items: for func in funcs: if event != func.event: continue match = regexp.match(text) if not match: continue code = wrapped(self, origin, text, match) input = input_wrapper(code, origin, text, bytes, match, event, args) if func.thread: targs = (self, func, origin, code, input) t = threading.Thread(target=call, args=targs) t.start() else: call(self, func, origin, code, input)
def setup(code): global bot bot = code id = str(gen(0, 10000000)) bot.set('webserver.object', id) # Nasty area, we check for configuration options, some are required and some arent if not bot.config('webserver'): return if not bot.config('webserver_password'): return output.warning( 'To use the builtin webserver, you must set a password in the config', 'WEBSERVER') port = bot.config('webserver_port', 8888) thread.start_new_thread(checkstate, ( bot, input, id, )) thread.start_new_thread(init, ( str(host), int(port), ))
def do_GET(self): init_time = float(time.time()) def readfile(fn): if not os.path.isfile('webserver/%s' % fn): return False try: with open('webserver/%s' % fn, 'r') as f: return f.read() except: return False def finish(data='', content='application/json', code=200): self.send_response(code) self.send_header("Content-type", content) self.end_headers() done = float(time.time()) - init_time if bot.debug: output.info('Finished request for %s (took %f seconds)' % (self.path, done), 'WEBSERVER') if isinstance(data, dict): data = json.dumps(data, indent=2) self.wfile.write(data) args = {} if bot.debug: output.warning('Request for "%s" (%s)' % (self.path, ', '.join([self.command, self.request_version, list(self.client_address)[0]])), 'WEBSERVER') path = self.path.replace('?callback=?', '') if path.startswith('/?'): tmp = path.split('?', 1)[1] args = urlparse.parse_qs(tmp) # Manage here try: if 'pass' not in args: return finish({'success': False, 'message': 'Password required. Example: http://localhost:8888/?pass=mypassword'}, code=403) if args['pass'][0] != password: return finish({'success': False, 'message': 'Password incorrect'}, code=403) # Authenticated.. Now we need to find some variables in the args # 1. args (used for IRC commands) # 2. data (The argument for the IRC command (the arguments # argument!)) if 'execute' in args: cmd = args['execute'][0] if cmd == 'mute': bot.mute() if cmd == 'unmute': bot.unmute() if cmd == 'restart': bot.restart() if cmd == 'quit': bot.quit() if cmd == 'reloadall': reload.reload_all_modules(bot) return finish({'success': True, 'message': 'Reloaded all modules!'}) if cmd == 'reload': tmp = reload.reload_module(bot, args['data'][0]) return finish({'success': True, 'message': 'Reloaded %s!' % tmp['name']}) if 'args' not in args: config = {} for key, value in bot.config().iteritems(): # Add configuration to web-requests, but ensure # no passwords exists to prevent security issues if 'pass' not in key.lower(): config[key] = value data = { 'nick': bot.nick, 'chan_data': bot.chan, 'modules': sorted(bot.modules), 'docs': bot.doc, 'config': config, 'bot_startup': hrt(bot.bot_startup)[0], 'irc_startup': hrt(bot.irc_startup)[0], 'muted': bot.muted, 'other': bot.webserver_data, 'server': bot.server_options, 'logs1': bot.logs } data['logs'] = [] for log in bot.logs['bot']: tmp = log tmp['hrt'] = hrt(tmp['time'])[0] data['logs'].append(tmp) return finish({'success': True, 'data': data}) if 'data' in args: bot.write( args['args'][0].split(), bot.format(args['data'][0])) else: bot.write(args['args'][0].split()) return finish({'success': True, 'message': 'Data sent to server'}) except Exception as e: return finish({'success': False, 'message': 'An exception has occured', 'error': list(e)}, code=500) elif path.endswith('/'): target = path + 'index.html' filetype = 'text/html' else: target = path if '.' in path: filetype = 'text/' + path.split('.')[-1] else: filetype = 'text/html' if filetype == 'text/js': filetype = 'application/javascript' f = readfile(target.strip('/')) if not f: return finish('404 file now found', content='text/html', code=400) return finish(f, content=filetype, code=200)
def trigger_433(code, origin, line, args, text): output.warning('Nickname {} is already in use. Trying another..'.format( code.nick)) nick = code.nick + '_' code.write(('NICK', nick)) code.nick = nick.encode('ascii', 'ignore')
def index(): output.warning("Webpanel access from %s" % request.remote_addr, "WEBSERVER") return template('index.html')
def unmute(): output.warning("Execution from webpanel: Unmute bot", "WEBSERVER") bot.unmute() return {'muted': False}
def setup(self): self.variables = {} filenames, core_filenames = [], [] for fn in os.listdir(os.path.join(home, 'modules')): if fn.endswith('.py') and not fn.startswith('_'): if self.config('whitelisted_modules', False): if fn.split('.', 1)[0] not in self.config('whitelisted_modules', []): continue filenames.append(os.path.join(home, 'modules', fn)) if self.config('extra'): for fn in self.config('extra'): if os.path.isfile(fn): filenames.append(fn) elif os.path.isdir(fn): for n in os.listdir(fn): if n.endswith('.py') and not n.startswith('_'): filenames.append(os.path.join(fn, n)) # Add system modules that the user should always require. Still can # be removed by deleting them or moving them out of the system # modules directory for fn in os.listdir(os.path.join(home, 'core/modules')): if fn.endswith('.py') and not fn.startswith('_'): filenames.append(os.path.join(home, 'core/modules', fn)) core_filenames.append(fn.split('.', 1)[0]) excluded_modules = self.config('excluded_modules', []) if self.load: for filename in self.load: # Add user specified modules on reload if filename in filenames: continue try: fn = os.path.join(home, 'modules', filename + '.py') filenames.append(fn) except: continue filenames = sorted(list(set(filenames))) # Reset some variables that way we don't get dups self.modules = [] self.cmds = {} # Load modules for filename in filenames: name = os.path.basename(filename)[:-3] if name in excluded_modules and name not in self.load: # If the file was excluded via the config file # Don't exclude if purposely loaded continue if name in self.unload: # If the module was excluded via the reload module continue # if name in sys.modules: # del sys.modules[name] self.setup_module(name, filename) tmp_modules = [] for module in self.modules: if module not in core_filenames: tmp_modules.append(module) if core_filenames: output.info('Loaded {} core modules: {}'.format( len(core_filenames), ', '.join(core_filenames))) if self.modules: output.info('Loaded {} modules: {}'.format( len(tmp_modules), ', '.join(tmp_modules))) else: output.warning('Couldn\'t find any modules') self.bind()
def trigger_433(code, line): output.warning('Nickname %s is already in use. Trying another..' % code.nick) nick = code.nick + '_' code.write(('NICK', nick)) code.nick = nick.encode('ascii', 'ignore')
return(contents,data) # ##Seperate from function. Initial data.json check. Route to rest of script... try: if os.path.isfile(data_filename) == True: output.info("Data JSON found...") for data_file in open(data_filename, "r+"): parse_json(data_filename) output.info("'data.json' is valid. Setting up variables from data...") setup(code,contents,data) else: output.error("Data JSON was not found in working directory. Rename data_example.json to make your configuration.") if os.path.isfile('data_example.json') == False: output.info("'data_example.json' was not found... downloading it...") output.warning("Data JSON error is stopping the bot...") # ##Syntax error in data.json. Report that. except ValueError: output.error("Syntax error found in data.json. Stopping...") os._exit(0) # ## @hook(cmds=["total"]) def total(code,input,casino,not_casino,litedoge_total,cagecoin_total): if input.channel in casino[0] or not_casino[0]: #Litedoge related code.say("Total LDOGE: "+litedoge_total+".") if input.channel in casino[1] or not_casino[1]: #Cagecoin related code.say("Total CAGE: "+cagecoin_total+".") else: code.say("Total LDOGE: "+litedoge_total+".\n Total CAGE: "+cagecoin_total+".") #Anywhere. Both balances.
def update(code, input): """Pulls the latest versions of all modules from Git""" if not sys.platform.startswith('linux'): output.warning('Warning: {b}Using a non-unix OS, might fail to work!') try: proc = subprocess.Popen('git pull', stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) git_data = proc.communicate()[0] except: return code.say( 'Either Git isn\'t installed or there was an error! (Using Windows?)' ) if git_data.strip('\n') == 'Already up-to-date.': return code.say('{b}No updates found.') data = git_data if re.match(r'^Updating [a-z0-9]{7}\.\.[a-z0-9]{7}$', data.strip('\n')): # Pretty sure files are conflicting... return code.say( '{b}Files are conflicting with the update. Please refork the bot!') # per-file additions/subtractions that spam stuff data = re.sub(r'[0-9]+ [\+\-]+', '', data).replace('\n', ' ') # mode changes, as those are unimportant data = re.sub(r'create mode [0-9]+ [a-zA-Z0-9\/\\]+\.py', '', data) # commit hashes, different color data = re.sub(r'(?P<first>[a-z0-9]{7})\.\.(?P<second>[a-z0-9]{7})', '{purple}\g<first>..\g<second>{c}', data) # make different files depending on the importance data = re.sub(r'core/modules/(?P<name>[a-zA-Z0-9]+)\.py', '\g<name>.py ({red}core{c})', data) data = re.sub(r'core/(?P<name>[a-zA-Z0-9]+)\.py', '\g<name>.py ({red}core{c})', data) data = re.sub(r'code\.py', 'code.py ({red}base{c})', data) data = re.sub(r'modules/(?P<name>[a-zA-Z0-9]+)\.py', '\g<name>.py ({blue}module{c})', data) data = re.sub(r'util/(?P<name>[a-zA-Z0-9]+)\.py', '\g<name>.py ({pink}util{c})', data) data = re.sub(r'lib/(?P<dir>[a-zA-Z0-9]+)/(?P<name>[a-zA-Z0-9]+)\.py', '\g<name>.py ({pink}\g<dir> - util{c})', data) data = data.replace('Fast-forward', '') # Do a little with file changes data = re.sub(r'(?P<files>[0-9]{1,3}) files? changed', '{green}\g<files>{c} file(s) changed', data) data = re.sub( r'(?P<ins>[0-9]{1,6}) insertions\(\+\)\, (?P<dels>[0-9]{1,6}) deletions\(\-\)', '+{green}\g<ins>{c}/-{red}\g<dels>{c}', data) data = re.sub(r'(?P<chars>[0-9]{1,6}) insertions?\(\+\)', '{green}\g<chars>{c} addition(s)', data) data = re.sub(r'(?P<chars>[0-9]{1,6}) deletions?\(\+\)', '{green}\g<chars>{c} deletion(s)', data) while ' ' in data: data = data.replace(' ', ' ') code.say('Github: {b}' + data.strip()) core_stuff = ['code.py', 'core/', 'util/', 'lib/'] for item in core_stuff: if item.lower() in git_data.lower().strip('\n'): code.say( '{b}{red}Core files have been edited, restarting the bot!{c}') return code.restart() reload_all_modules(code) code.say('{b}Reloaded all modules')
def main(argv=None): # 1: Parse The Command Line parser = optparse.OptionParser('%prog [options]') parser.add_option( '-c', '--config', metavar='fn', help='use this configuration file or directory' ) opts, args = parser.parse_args(argv) # 2: Documentation output docstring() # 3: Require python 2.7 or later if sys.version_info < (2, 7): output.error('Requires Python 2.7.x, from www.python.org') sys.exit(1) # 4. Create ~/.code if not made already if not os.path.isdir(dotdir): if not os.path.isdir(dotdir): try: output.info('Creating database directory in ~/.code...') os.mkdir(dotdir) except Exception as e: output.error('There was a problem creating %s:' % dotdir) output.error(str(e)) output.error('Please fix this and then run code again.') sys.exit(1) # 5: Load The Configuration bot_config = opts.config or 'config.json' # and check if exists if not os.path.isfile(bot_config): output.error( 'Configuration file "%s" does not exist. Please copy ' 'the example.json to config.json then run Code again' % bot_config) sys.exit(1) try: config = parse_json(bot_config) except Exception as e: output.error('The config file has syntax errors. Please fix them and run Code again!\n' + str(e)) sys.exit(1) global threads for server in config['servers']: if server['host'] == 'irc.anotherexample.net': continue id = len(threads) process = Process(target=connect, args=(id, setupServer(server),)) process.daemon = True process.start() threads.append({'id': id, 'config': server, 'process': process}) time.sleep(5) # 6: Begin managing these processes try: # set some temporary variables that we will be using for config # file version checking conf_last_check = int(time.time()) conf_last_mtime = int(os.path.getmtime(bot_config)) while True: time.sleep(1) if (int(time.time()) - conf_last_check) > 10 and int(os.path.getmtime(bot_config)) > conf_last_mtime: conf_last_check = int(time.time()) conf_last_mtime = int(os.path.getmtime(bot_config)) try: # If the new configuration file isn't the same as the last # one that we saved, attempt to re-import it config_new = parse_json(bot_config) if len(config_new['servers']) == len(config['servers']) and len(config_new['servers']) == len(threads): output.success('Configuration file %s has changed! Use the restart command to take affect!' % bot_config) config = config_new for i in range(len(config['servers'])): # Once they reboot that connection, it should autoload # the new config. threads[i]['config'] = config['servers'][i] except Exception as e: # Only spit out errors once per file modification output.error("Configuration file has been changed, however I cannot read it! (%s)" % str(e)) if len(threads) == 0: output.warning('No more processes to manage. Exiting...') sys.exit() for id in range(len(threads)): p = threads[id]['process'] if p.exitcode == 0: # Assume it exited safely. Ignore the termination. p.terminate() output.status('Terminating process ID #%s (%s:%s)' % (id, threads[id]['config']['host'], threads[id]['config']['port'])) del threads[id] break if p.exitcode == 1: # Exited erronously. We'll just assume it wants a reboot. p.terminate() p = Process(target=connect, args=(id, setupServer(threads[id]['config']),)) p.daemon = True delay = threads[id]['config']['connect_delay'] if 'connect_delay' in threads[id]['config'] else 20 output.error('Restarting process id #%s (%s:%s) in %s seconds.' % ( id, threads[id]['config']['host'], threads[id]['config']['port'], str(delay) )) time.sleep(delay) output.status('Regenerating process ID #%s (%s:%s)' % (id, threads[id]['config']['host'], threads[id]['config']['port'])) p.start() threads[id]['process'] = p except KeyboardInterrupt: output.success('Shutting down bot...', 'REQUEST') for id in range(len(threads)): p = threads[id]['process'] output.status('Terminating process ID #%s (%s:%s)' % (id, threads[id]['config']['host'], threads[id]['config']['port'])) p.terminate() time.sleep(1) sys.exit()
def mute(): output.warning("Execution from webpanel: Mute bot", "WEBSERVER") bot.mute() return {'muted': True}
def shutdown(): output.warning("Execution from webpanel: Shutdown bot", "WEBSERVER") bot.quit()
def setup(self): self.variables = {} filenames, core_filenames = [], [] for fn in os.listdir(os.path.join(home, 'modules')): if fn.endswith('.py') and not fn.startswith('_'): if self.config('whitelisted_modules', False): if fn.split('.', 1)[0] not in self.config( 'whitelisted_modules', []): continue filenames.append(os.path.join(home, 'modules', fn)) if self.config('extra'): for fn in self.config('extra'): if os.path.isfile(fn): filenames.append(fn) elif os.path.isdir(fn): for n in os.listdir(fn): if n.endswith('.py') and not n.startswith('_'): filenames.append(os.path.join(fn, n)) # Add system modules that the user should always require. Still can # be removed by deleting them or moving them out of the system # modules directory for fn in os.listdir(os.path.join(home, 'core/modules')): if fn.endswith('.py') and not fn.startswith('_'): filenames.append(os.path.join(home, 'core/modules', fn)) core_filenames.append(fn.split('.', 1)[0]) excluded_modules = self.config('excluded_modules', []) if self.load: for filename in self.load: # Add user specified modules on reload if filename in filenames: continue try: fn = os.path.join(home, 'modules', filename + '.py') filenames.append(fn) except: continue filenames = sorted(list(set(filenames))) # Reset some variables that way we don't get dups self.modules = [] self.cmds = {} # Load modules for filename in filenames: name = os.path.basename(filename)[:-3] if name in excluded_modules and name not in self.load: # If the file was excluded via the config file # Don't exclude if purposely loaded continue if name in self.unload: # If the module was excluded via the reload module continue # if name in sys.modules: # del sys.modules[name] self.setup_module(name, filename) tmp_modules = [] for module in self.modules: if module not in core_filenames: tmp_modules.append(module) if core_filenames: output.info('Loaded {} core modules: {}'.format( len(core_filenames), ', '.join(core_filenames))) if self.modules: output.info('Loaded {} modules: {}'.format(len(tmp_modules), ', '.join(tmp_modules))) else: output.warning('Couldn\'t find any modules') self.bind()
def restart(): output.warning("Execution from webpanel: Restart bot", "WEBSERVER") bot.restart()