def __init__(self, *args, **kwargs): super().__init__(*args, should_spawn_thread=False, **kwargs) self.public_namespace.db = dataloader.datafile(DB_FILE, load_as='db') self.public_namespace.db.execute(CREATE_UPTIMES_TABLE_SQL) self.public_namespace.db.patch('uptimes', COLUMNS, commit=True) self.run = 0 self.spawn_process()
def __init__(self, **kwargs): super().__init__(**kwargs) self.public_namespace.active_emoji_messages = dict( ) # dict associating messages to their reaction name, for assigning emojis self.public_namespace.active_perm_messages = dict( ) # dict associating users to their command/reaction name, for assigning perms try: self.public_namespace.commandersfile = dataloader.datafile( self.config[COMMANDERS]) except FileNotFoundError: print( "The %s file is either missing or corrupted; unable to load" % self.config[COMMANDERS]) self.public_namespace.commandersfile = dataloader.newdatafile( self.config[COMMANDERS]) if not isinstance(self.public_namespace.commandersfile.content, dict): self.public_namespace.commandersfile.content = { REACTIONS: dict(), COMMANDS: dict(), PACKAGES: dict() } self.public_namespace.commandersfile.save( ) # create & save file, in case it didn't exist before # commanders is a 3-dimensional dictionary; command_type -> command_name -> {'owner':user_id, 'maintainers':[list of user_ids]} self.public_namespace.commanders = self.public_namespace.commandersfile.content self.public_namespace.OWNER = OWNER self.public_namespace.MAINTAINERS = MAINTAINERS self.public_namespace.DEFAULT_OWNER_ID = DEFAULT_OWNER_ID self.public_namespace.REACTIONS = REACTIONS self.public_namespace.COMMANDS = COMMANDS self.public_namespace.PACKAGES = PACKAGES self.public_namespace.PLUGINS = PLUGINS self.public_namespace.is_commander = self.is_commander
def add_data(self, name, content_from=DEFAULT): '''(str, str) -> None Adds configuration data to Bot's data dict. It expects that data_config contains an entry for 'name' which points to a file that it can extract content from. content_from may be specified to get data other than the default.''' data_file = dataloader.datafile(self.data_config[name]) self.data[name] = data_file.content[content_from]
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.public_namespace.database = self.public_namespace.db = dataloader.datafile(self.config['database']) # set up db if not already setup self.public_namespace.db.execute('CREATE TABLE IF NOT EXISTS filters (id INTEGER PRIMARY KEY, name TEXT UNIQUE NOT NULL)') # create columns if not exist self.public_namespace.db.patch('filters', COLUMNS, commit=True) # set up constants self.public_namespace.DELETE = DELETE self.public_namespace.PIN = PIN self.public_namespace.PIPE = PIPE self.public_namespace.NOTHING = NOTHING self.public_namespace.FILTER_ACTIONS = FILTER_ACTIONS
def __init__(self, *args, **kwargs): super().__init__(*args, should_spawn_thread=False, **kwargs) self.public_namespace.database = self.public_namespace.db = dataloader.datafile( self.config['database']) # create table if not exists self.public_namespace.db.execute(CREATE_TABLE_SQL) # create new columns if not exist self.public_namespace.db.patch('reminders', COLUMNS_TO_PATCH, commit=True) self.this_run = 0 self.spawn_process()
def __init__(self, config, log, checks, stop_queue): '''(str, Logger, fun) -> Bot config: a string which is the loaction of the base config file log: a Logger for dumping info checks: a function which checks reddit/forum/twitter for new stuff''' super().__init__() if not config: # TODO: raise some kind of exception pass self.data_config = dataloader.datafile(config).content[DEFAULT] self.log = log # TODO(14flash): Plugin refactor, where we won't need a doCheck() func anymore self.checks = checks self.data = dict() self.commands = list() self.reaction_add_commands = list() self.reaction_remove_commands = list() self.plugins = list() self.stop_queue=stop_queue
def action(self, message): quotedMessage = eval( dataloader.datafile( self.saveloc + "/" + re.search(r'(\d{18})', message.content).group(1) + ".txt").content[0]) em = embed.create_embed(author={ "name": quotedMessage["author"], "url": None, "icon_url": None }, footer={ "text": "#" + quotedMessage["channel"] + " of " + quotedMessage["server"], "icon_url": None }, description=quotedMessage["content"], colour=0xffffff) yield from self.send_message(message.channel, embed=em)
def generate_commanders(self, bot): commanders2 = dataloader.datafile( self.public_namespace.commandersfile.filename).content if not isinstance(commanders2, dict): commanders2 = dict() commanders2[self.public_namespace.COMMANDS] = dict() commanders2[self.public_namespace.REACTIONS] = dict() commanders2[self.public_namespace.PLUGINS] = dict() commanders2[self.public_namespace.PACKAGES] = dict() # ensure all commands are in commanders2 if self.public_namespace.COMMANDS not in commanders2: commanders2[self.public_namespace.COMMANDS] = dict() for name in bot.commands: if name not in commanders2[self.public_namespace.COMMANDS]: commanders2[self.public_namespace.COMMANDS][name] = "missing" # ensure all reactions are in commanders2 if self.public_namespace.REACTIONS not in commanders2: commanders2[self.public_namespace.REACTIONS] = dict() for name in bot.reactions: if name not in commanders2[self.public_namespace.REACTIONS]: commanders2[self.public_namespace.REACTIONS][name] = "missing" # ensure all plugins are in commanders2 if self.public_namespace.PLUGINS not in commanders2: commanders2[self.public_namespace.PLUGINS] = dict() for name in bot.plugins: if name not in commanders2[self.public_namespace.PLUGINS]: commanders2[self.public_namespace.PLUGINS][name] = "missing" # ensure all packages are in commanders2 if self.public_namespace.PACKAGES not in commanders2: commanders2[self.public_namespace.PACKAGES] = dict() for package in loader.sub_namespaces: if package not in commanders2[self.public_namespace.PACKAGES]: commanders2[ self.public_namespace.PACKAGES][package] = "missing" return commanders2
# this badly needs to be changed to OOP, because it's rly hurtful to understand right now from libs import dataloader timezones = dataloader.datafile("./data/timezones.csv") class SimpleTime: ''' stores a time in an easy format ''' def __init__(self, time): ''' (SimpleTime, str) -> None str must be a time in format (H)H:MM where HH and MM are valid positive integers Do I rly need to say what __init__ does? ''' timeSplit = time.split(":") try: if "am" == timeSplit[0][-2:].lower(): self.hour = int(timeSplit[0][:-2]) elif "pm" == timeSplit[0][-2:].lower(): self.hour = int(timeSplit[0][:-2]) self.hour += 12 else: self.hour = int(timeSplit[0]) except: raise ValueError("Invalid time") try: if "am" == timeSplit[1][-2:].lower(): self.minute = int(timeSplit[1][:-2]) elif "pm" == timeSplit[1][-2:].lower(): self.hour += 12 self.minute = int(timeSplit[1][:-2]) else: self.minute = int(timeSplit[1])
def action(self, message, bot): try: # boolean variables to indicate what has to and will be done for loading is_reload = False is_download = True has_config = False config_loaded = False # if no attachment, try to reload add-on if len(message.attachments) == 0: is_reload = True is_download = False args = self.collect_args(message) # info from command addon_type = args.group( 2).lower() # either 'reactions', 'commands' or 'plugins' name = args.group(1) + '.py' # name of add-on file addon_name = name[name.rfind('/') + 1:-len('.py')] package = name[name.find('/') + 1:name.rfind( '/' )] # package; middle folder (<addon_type>/<middble folder>/<name>) or None # if add-on exists, reload it if os.path.exists(name): is_reload = True elif not is_download: yield from self.send_message( message.channel, "I can't load a non-existent " + addon_type[:-1]) return elif package != None and not os.path.exists( os.path.join(addon_type, package)): # if package doesn't exist, make it os.makedirs(package) # check/setup permissions '''Add-ons in the main folder of an add-on type have their own commander permissions (ie people who can modify the add-on) Add-ons in subfolders ("packages") have package-level commander permissions (ie all add-ons in a package share permissions) ''' if package: type = self.public_namespace.PACKAGES else: type = addon_type if not is_reload and package == None: # add-on is new self.public_namespace.commanders[type][addon_name] = dict() self.public_namespace.commanders[type][addon_name][ self.public_namespace.OWNER] = message.author.id self.public_namespace.commanders[type][addon_name][ self.public_namespace.MAINTAINERS] = list() elif not is_reload and package not in self.public_namespace.commanders[ self.public_namespace.PACKAGES]: # new add-on is in a new package self.public_namespace.commanders[type][package] = dict() self.public_namespace.commanders[type][package][ self.public_namespace.OWNER] = message.author.id self.public_namespace.commanders[type][package][ self.public_namespace.MAINTAINERS] = list() elif not package and not (self.public_namespace.is_commander( message.author.id, addon_name, type) or message.author.id in bot.ADMINS): # add-on already exists and user is missing permissions yield from self.send_message( message.channel, "`%s` add-on already exists and you do not have permissions to modify it." % addon_name) return elif package and not (self.public_namespace.is_commander( message.author.id, package, type) or message.author.id in bot.ADMINS): # add-on is in package and user is missing permissions for package yield from self.send_message( message.channel, "`%s` package already exists and you do not have permissions to modify it." % package) return # download new file (if there's one to download) if is_download: # save file to temp location, for safety before file safety is verified index_pyfile = None # find python file attachment by file extension '.py' for i in range(len(message.attachments)): if message.attachments[i]['filename'].endswith('.py'): index_pyfile = i break filename = TEMP_START + str(datetime.datetime.now().isoformat( )) + 'ID' + message.author.id + '.py' temp_file = dataloader.newdatafile(filename) temp_file.content = [ requests.get(message.attachments[index_pyfile]["url"]).text ] temp_file.save() # verification try: verifyaddon.verify(filename, addon_type) except ImportError as e: if '-v' in message.content: yield from self.send_message( message.channel, "Your add-on failed to pass verification: \n" + "```" + traceback.format_exc() + "```") else: yield from self.send_message( message.channel, "Your add-on failed to pass verification: \n" + "`" + str(e) + "`") return # save file to non-temp location file = dataloader.newdatafile(name) file.content = temp_file.content file.save() if len(message.attachments) >= 2: has_config = True # save config file index_config = None # find config file for i in range(len(message.attachments)): if message.attachments[i]['filename'].endswith( '.config'): index_config = i break if index_config == None: config_loaded = False else: config_file = dataloader.newdatafile( name[:-len('.py')] + '.config') config_file.content = [ requests.get( message.attachments[index_config]["url"]).text ] config_file.save() config_loaded = True if addon_type == PLUGIN and config_loaded == False and not os.path.exists( name[:-len('.py')] + '.config'): # config file is required for plugins, so load default config_file = dataloader.newdatafile(name[:-len('.py')] + '.config') config_file.content = dataloader.datafile( DEFAULT_PLUGIN_CONFIG, load_as='text').content config_file.save(save_as='text') config_loaded = True # load add-on py_filename = name[name.rfind('/') + 1:] cmd_name = py_filename[:-len('.py')] if addon_type == COMMAND: bot.load_command(py_filename, cmd_name, package=package, reload=is_reload) elif addon_type == REACTION: bot.load_reaction(py_filename, cmd_name, package=package, reload=is_reload) elif addon_type == PLUGIN: bot.load_plugin(py_filename, cmd_name, package=package, reload=is_reload) else: bot.load_addon(py_filename, cmd_name, package=package, reload=is_reload) yield from self.send_message( message.channel, self.get_response(name, is_reload, is_download, has_config, config_loaded)) except: traceback.print_exc() yield from self.send_message( message.channel, 'An unexpected error occurred. 🔥 Please 🔥 do 🔥 not 🔥 panic, 🔥 everything 🔥 is 🔥 under 🔥 control 🔥' )
def __init__(self, **kwargs): super().__init__(**kwargs) self.karma_up_data = dataloader.datafile(self.public_namespace.config[KARMA_UP_LOC]).content self.karma_down_data = dataloader.datafile(self.public_namespace.config[KARMA_DOWN_LOC]).content
tweet = qTwitter.get() yield from bot.send_message( bot.twitterchannel, "Idea Project tweeted this: " + tweet[1] + " (from: <" + tweet[0] + ">)") while not qReddit.empty(): comment = qReddit.get() yield from bot.send_message( bot.redditchannel, "A comment has been posted here: " + comment[0] + " (direct link: <" + comment[1] + ">)") if __name__ == '__main__': # main # init stuff loop = asyncio.get_event_loop() config = dataloader.datafile("./data/config.config") config.content = config.content["DEFAULT"] credentials = dataloader.datafile(config.content["credentialsloc"]) credentials.content = credentials.content["DEFAULT"] channels = dataloader.datafile(config.content["channelsloc"]) channels.content = channels.content["DEFAULT"] perms = dataloader.datafile(config.content["permissionsloc"]) perms.content = perms.content["DEFAULT"] forumdiscorduser = dataloader.datafile( config.content["forumdiscorduserloc"]) forumdiscorduser.content = forumdiscorduser.content["DEFAULT"] log = mainLogging() stop = Queue() bot = botlib.Bot("./data/config.config", log, doChecks, stop)
def __init__(self, filename, **kwargs): super().__init__(**kwargs) self.pifile = dataloader.datafile(filename)
def action(self, message): args = self.collect_args(message) op_flag = '' msg_content = None # determine operation operation = args.group(1).lower() if args.group(1) is not None else '' if operation in todo_rm_words: op_flag = 'remove' elif operation in todo_add_words: op_flag = 'add' elif operation in todo_list_words: op_flag = 'list' else: if args.group(2): op_flag = 'add' else: op_flag = 'list' # determine if public list list_name = message.author.id task = args.group(2).strip() if args.group(2) is not None else '' if args.group(2): list_args = self.collect_list(args.group(2)) if list_args and not is_id_like(list_args.group(1)): list_name = list_args.group(1) task = args.group(2).replace(list_args.group(0), '') elif op_flag == 'add' or op_flag == 'remove': yield from self.send_message( message.channel, 'Please specify the task to %s' % op_flag) return # load files if they don't already exist if list_name not in todoFiles: try: todoFiles[list_name] = dataloader.datafile(self.saveloc + list_name + ".txt") except FileNotFoundError: todoFiles[list_name] = dataloader.newdatafile(self.saveloc + list_name + ".txt") # add task if op_flag == 'add': # TODO: check for permissions to edit list_name before adding task index = self.get_index_for_task(task, todoFiles[list_name]) if index != -1 and re.match(r'^\d+$', task) != None: msg_content = "I'm sorry, `%s` already exists" % task else: todoFiles[list_name].content.append(task) msg_content = "Task added" # remove task if op_flag == 'remove': # TODO: check for permissions to edit list_name before removing task index = self.get_index_for_task(task, todoFiles[list_name]) if index == -1 or index >= len(todoFiles[list_name].content): msg_content = "I'm sorry, I can't find `%s`." % task else: del (todoFiles[list_name].content[index]) todoFiles[list_name].save() msg_content = "Task deleted" # always list tasks after everything list_display_name = list_name if list_name != message.author.id else 'Todo' if re.search(r'\s-p', message.content, re.I) != None or list_name != message.author.id: yield from self.send_message(message.channel, msg_content, embed=embed.create_embed( title=list_display_name, description=self.todo2string( todoFiles[list_name]), colour=0xffffff)) else: yield from self.send_message(message.author, msg_content, embed=embed.create_embed( title=list_display_name, description=self.todo2string( todoFiles[list_name]), colour=0xffffff)) # save file todoFiles[list_name].save() # remove file from memory if empty, to save some memory if len(todoFiles[list_name].content) == 0: del (todoFiles[list_name])
def __init__(self, **kwargs): super().__init__(**kwargs) self.invalid_message = INVALID_MESSAGE self.invalid_messages = dataloader.datafile(INVALID_MESSAGES_LOC).content