def update_config(data): if isinstance(data, list): con = database.get_con() cur = database.get_cur(con) for item in data: if item.get("type") == "bool": item["val"] = (item["val"] if isinstance(item["val"], bool) else (item["val"].lower() == "true")) elif item.get("type") == "int": item["val"] = int(item["val"]) query = ( "UPDATE rb_config SET val = ? WHERE category = ? and key = ?;", (serialize_key(item["val"]), item["category"], item["key"]), ) log.debug("Result: {}".format( database.db_qry(query=query, con=con, cur=cur))) con.commit() con.close() else: if data.get("type") == "bool": data["val"] = (data["val"] if isinstance(data["val"], bool) else (data["val"].lower() == "true")) if data.get("options") in ("", [], None): data["options"] = [True, False] elif data.get("type") == "int": data["val"] = int(data["val"]) query = ( "UPDATE rb_config SET val = ? WHERE category = ? and key = ?;", (serialize_key(data["val"]), data["category"], data["key"]), ) database.db_qry(query, commit=True, closeAfter=True) return True
def delete_bot(self): con = database.get_con() cur = database.get_cur(con) queries = [ ("DELETE FROM rb_bots WHERE id=?;", (self.id, )), ("DELETE FROM rb_botConfig WHERE botId=?;", (self.id, )), ("DELETE FROM rb_privileges WHERE privilege like 'rb_bot_{}_%';". format(self.id)), ] botConfigTables = database.db_qry( "select name from sqlite_master where type='table' and name like 'rb_bot_{}_%';" .format(self.id), con=con, cur=cur, commit=False, closeAfter=False, ) if isinstance(botConfigTables, dict): for v in botConfigTables.values(): queries.append(("DROP TABLE {};", (v, ))) result = database.db_qry(queries, commit=True, closeAfter=True) if isinstance(result, list): user.remove_privilege("rb_bot_{}_ro".format(self.id)) user.remove_privilege("rb_bot_{}_startstop".format(self.id)) user.remove_privilege("rb_bot_{}_rw".format(self.id)) self.__del__() return result
def remove_privilege(privilege): # privilege = rb_privilege.privilege # Removes the privilege from all users # Remove from redball.LOGGED_IN_USERS[x]['PRIVS'] for x in redball.LOGGED_IN_USERS: if privilege in x: x.pop(x.index(privilege)) # Remove from rb_users.privileges con = database.get_con() cur = database.get_cur(con) users = database.db_qry( "SELECT id,privileges FROM rb_users;", con=con, cur=cur, logg=log ) queries = [] for x in users: p = json.loads(x["privileges"]) if privilege in p: p.pop(p.index(privilege)) queries.append( ( "UPDATE rb_users SET privileges = ? WHERE id = ?;", (json.dumps(p), x["id"]), ) ) if len(queries): database.db_qry( queries, con=con, cur=cur, commit=True, closeAfter=True, logg=log ) else: con.close()
def create_botType(**kwargs): con = database.get_con() cur = database.get_cur(con) query = ( """INSERT INTO rb_botTypes (name, description, moduleName, defaultSettings) VALUES (?,?,?,?) ;""", ( kwargs["description"].lower().strip().replace(" ", "-"), kwargs["description"], kwargs["moduleName"], json.dumps(kwargs.get("defaultSettings", "{}"), indent=2), ), ) result = database.db_qry(query, con=con, cur=cur) if isinstance(result, str) and result.find("ERROR") != -1: con.commit() con.close() return result else: insert_id = database.db_qry("SELECT last_insert_rowid() as id;", con=con, cur=cur)[0]["id"] if insert_id > 0: log.info("Created botType ({}) with id: {}.".format( kwargs["description"], insert_id)) else: insert_id = "ERROR: Failed to insert record." con.commit() con.close() return insert_id
def upgrade_database(toVer=None): # toVer = database version to upgrade to # returns True if version is satisfactory, False if error toVer = toVer if toVer else max(upgradeScripts.keys()) fromVer = database.get_database_version(logg=log) if fromVer == toVer: log.info("Database is up to date (version: {})!".format(fromVer)) return True elif fromVer > toVer: log.warning( "Current version ({}) is higher than requested version ({}). Someting's wrong but there's nothing to upgrade...".format( fromVer, toVer ) ) return True else: log.info( "Current database version {}; desired version: {}.".format(fromVer, toVer) ) log.info("Creating a backup of the database...") database.backup_database(logg=log, manual=False) con = database.get_con(logg=log) cur = database.get_cur(con=con, logg=log) while fromVer < toVer: # Apply upgrade scripts one version at a time until the database is up-to-date log.info( "Upgrading database from version {} to version {}...".format( fromVer, fromVer + 1 ) ) if len(upgradeScripts.get(fromVer + 1, [])) > 0: results = database.db_qry( query=upgradeScripts[fromVer + 1], con=con, cur=cur, commit=False, closeAfter=False, logg=log, ) if None in results: log.error( "One or more database upgrade queries failed: {}".format( results ) ) # Upgrade scripts failed. Do not commit and do not continue. return False else: con.commit() fromVer += 1 log.debug("Database upgraded to version {}.".format(fromVer)) con.close() log.debug("Database upgrade process is complete.") return True
def create_bot(self, name, botType, autoRun, redditAuth): con = database.get_con() cur = database.get_cur(con) query = ( "INSERT INTO rb_bots (name,botType,autoRun,redditAuth) values (?,?,?,?);", (name, botType, autoRun, redditAuth), ) result = database.db_qry(query, con=con, cur=cur) if isinstance(result, str) and result.find("ERROR") != -1: con.commit() con.close() return result else: insert_id = database.db_qry("SELECT last_insert_rowid() as id;", con=con, cur=cur)[0]["id"] log.info("Created bot with id: {}. Inserting default settings...". format(insert_id)) self.id = insert_id self.name = name self.botType = botType self.autoRun = autoRun self.redditAuth = redditAuth config.add_default_bot_config(insert_id, con, cur) botTypeInfo = config.get_botTypes(botType) if (botTypeInfo["defaultSettings"] and len(botTypeInfo["defaultSettings"]) > 2): defaultSettings = botTypeInfo["defaultSettings"] result = config.add_bot_config( botId=insert_id, multi=defaultSettings, replace=True, con=con, cur=cur, commit=False, closeAfter=False, ) # Create privileges and grant to creator q = """INSERT INTO rb_privileges ('privilege', 'description') VALUES ('rb_bot_{}_ro', 'Read-only access to bot id {}.'), ('rb_bot_{}_startstop', 'Access to start and stop bot id {}.'), ('rb_bot_{}_rw', 'Full access to bot id {}.') ;""".format(insert_id, insert_id, insert_id, insert_id, insert_id, insert_id) database.db_qry(q, con=con, cur=cur) con.commit() con.close() return insert_id
def create_user(**kwargs): con = database.get_con() cur = database.get_cur(con) if kwargs.get("userid") in [None, ""]: return "User ID cannot be blank." elif kwargs.get("password") and kwargs["password"] != kwargs.get( "confirm_password" ): return "Password and confirmation do not match." elif kwargs.get("password") in [None, ""]: return "Password cannot be blank." if kwargs.get("name") in [None, ""]: kwargs.update({"name": kwargs["userid"].capitalize()}) if kwargs.get("privileges") in [None, ""]: kwargs.update({"privileges": []}) query = ( """INSERT INTO rb_users (userid, name, password, email, reddit_userid, privileges, lastUpdate) VALUES (?,?,?,?,?,?,?) ;""", ( kwargs["userid"], kwargs["name"], hash_password(kwargs["password"]), kwargs["email"], kwargs["reddit_userid"], config.serialize_key(kwargs["privileges"]), time.time(), ), ) result = database.db_qry(query, con=con, cur=cur) if isinstance(result, str) and result.find("ERROR") != -1: con.commit() con.close() return result else: insert_id = database.db_qry( "SELECT last_insert_rowid() as id;", con=con, cur=cur )[0]["id"] if insert_id > 0: log.info( "Created user ({}) with id: {}.".format(kwargs["userid"], insert_id) ) else: insert_id = "ERROR: Failed to insert record." con.commit() con.close() return insert_id
def update_bot_config(botId, data): if isinstance(data, dict): data = [data] if isinstance(data, list): con = database.get_con() cur = database.get_cur(con) for item in data: if item.get("id"): q = "UPDATE rb_botConfig SET" local_args = tuple() for k, v in item.items(): if q[-1:] == "?": q += "," q += " {}=?".format(k) local_args += (v, ) q += " WHERE botId=? and id=?;" local_args += (botId, item["id"]) query = (q, local_args) else: if item.get("type") == "bool": item["val"] = (item["val"] if isinstance( item["val"], bool) else (item["val"].lower() == "true")) elif item.get("type") == "int": item["val"] = int(item["val"]) query = ( "UPDATE rb_botConfig SET val = ? WHERE category = ? and key = ? and botId=?;", (serialize_key(item["val"]), item["category"], item["key"], botId), ) log.debug("Result: {}".format( database.db_qry(query=query, con=con, cur=cur))) con.commit() con.close() else: query = ( "UPDATE rb_config SET val = ? WHERE category = ? and key = ?;", (serialize_key(data["val"]), data["category"], data["key"]), ) database.db_qry(query, commit=True, closeAfter=True) return True
def create_redditAuth(**kwargs): con = database.get_con() cur = database.get_cur(con) query = ( """INSERT INTO rb_redditAuth (description, reddit_appId, reddit_appSecret, reddit_scopes, reddit_refreshToken, reddit_uniqueCode) VALUES (?,?,?,?,?,?) ;""", ( kwargs["description"], kwargs["reddit_appId"], kwargs["reddit_appSecret"], serialize_key(kwargs["reddit_scopes"]), kwargs.get("reddit_refreshToken"), uuid.uuid4().hex, ), ) result = database.db_qry(query, con=con, cur=cur) if isinstance(result, str) and result.find("ERROR") != -1: con.commit() con.close() return result else: insert_id = database.db_qry("SELECT last_insert_rowid() as id;", con=con, cur=cur)[0]["id"] if insert_id > 0: log.info("Created redditAuth ({}) with id: {}.".format( kwargs["description"], insert_id)) redball.REDDIT_AUTH_LOCKS.update({str(insert_id): Lock()}) else: insert_id = "ERROR: Failed to insert record." con.commit() con.close() return insert_id
def create_bot(self, name, botType, autoRun, redditAuth): con = database.get_con() cur = database.get_cur(con) query = ( "INSERT INTO rb_bots (name,botType,autoRun,redditAuth) values (?,?,?,?);", (name, botType, autoRun, redditAuth), ) result = database.db_qry(query, con=con, cur=cur) if isinstance(result, str) and result.find("ERROR") != -1: con.commit() con.close() return result else: insert_id = database.db_qry("SELECT last_insert_rowid() as id;", con=con, cur=cur)[0]["id"] log.info("Created bot with id: {}. Inserting default settings...". format(insert_id)) self.id = insert_id self.name = name self.botType = botType self.autoRun = autoRun self.redditAuth = redditAuth config.add_default_bot_config(insert_id, con, cur) botTypeInfo = config.get_botTypes(botType) defaultSettingsFile = os.path.join( redball.BOT_PATH, f"{botTypeInfo['moduleName']}_config.json") log.debug( f"Default settings file for botType {botTypeInfo['name']}: {defaultSettingsFile}" ) if os.path.isfile(defaultSettingsFile): try: with open(defaultSettingsFile) as f: defaultSettings = json.load(f) except Exception as e: log.error( f"Error occurred while loading default config for [{botTypeInfo['description']}] bot type from json file [{defaultSettingsFile}]: {e}." ) defaultSettings = {} if len(defaultSettings): log.debug( f"Loaded default settings for botType {botTypeInfo['name']}: {defaultSettings}. Adding to bot {insert_id}..." ) result = config.add_bot_config( botId=insert_id, multi=defaultSettings, replace=True, con=con, cur=cur, commit=False, closeAfter=False, ) else: log.debug( f"No default settings found in the json file for botType {botTypeInfo['name']}." ) else: log.warning( f"No default settings json file found for [{botTypeInfo['description']}] bot type." ) # Create privileges and grant to creator q = """INSERT INTO rb_privileges ('privilege', 'description') VALUES ('rb_bot_{}_ro', 'Read-only access to bot id {}.'), ('rb_bot_{}_startstop', 'Access to start and stop bot id {}.'), ('rb_bot_{}_rw', 'Full access to bot id {}.') ;""".format(insert_id, insert_id, insert_id, insert_id, insert_id, insert_id) database.db_qry(q, con=con, cur=cur) con.commit() con.close() return insert_id