async def timebomb(self, ctx, *, arg): print(f'{botutils.timenow()} ***** Bot Command: {COMMAND_PREFIX}timebomb {arg} called by {ctx.author.display_name}') # Get the last word of the message string, which will be the timer to delete the message, then split that # word into a number with a letter (example: 30m), then split the letter from the number tb_time = arg.split()[-1] tb_unit = tb_time[-1:] tb_num_units = float(tb_time[:-1]) tb_diff = None if 'm' == tb_unit: print(f'Exploding in {tb_num_units} Minutes(s)') tb_diff = timedelta(minutes=tb_num_units) elif 'h' == tb_unit: print(f'Exploding in {tb_num_units} Hours(s)') tb_diff = timedelta(hours=tb_num_units) elif 'd' == tb_unit and 45 > tb_unit: print(f'Exploding in {tb_num_units} Days(s)') tb_diff = timedelta(days=tb_num_units) else: print('Invalid time frame.') tb_explode_time = datetime.now() + tb_diff # Do the database thing db = botutils.SQLite3Helper() val = (tb_explode_time, ctx.message.guild.id, ctx.channel.id, str(ctx.author), ctx.message.id) db.execute(TIMEBOMB_SET_SQL, val) print(f"{db.cur.rowcount} time bomb set for message id {ctx.message.id} in server {ctx.message.guild.id}.")
async def listsession(self, ctx): print( f'{botutils.timenow()} ***** Bot Command: {COMMAND_PREFIX}listsession called by {ctx.author.display_name}' ) guild_id = ctx.guild.id channel_id = ctx.channel.id db = botutils.SQLite3Helper() GET_SESSION_LIST_SQL = "SELECT session_date, current_xp, session_xp FROM party_xp_session WHERE guild_id=? AND channel_id=?" sql = GET_SESSION_LIST_SQL val = (guild_id, channel_id) resultset = db.fetch(sql, val) session_list_embed_string = '' if len(resultset) == 0: await ctx.send("No sessions found.") return else: for result in resultset: session_list_embed_string = session_list_embed_string + f"{result[0]} - Starting XP: {result[1]:,}, Session XP: {result[2]:,}\n" xp_list_session_embed = discord.Embed(title="Sessions", timestamp=datetime.now(), color=discord.Color.blue()) xp_list_session_embed.add_field( name=f"Sessions", value=f"```{session_list_embed_string}```") await ctx.send(embed=xp_list_session_embed)
def load_session(self): self.guild_id = self.ctx.guild.id self.channel_id = self.ctx.channel.id sql = self.GET_SESSION_DETAIL_SQL val = (self.guild_id, self.channel_id, self.session_id) db = botutils.SQLite3Helper() result_set = db.fetch(sql, val) if len(result_set) == 0: self.session_id = -1 return for result in result_set: self.date = result[3] self.party_current_xp = result[4] self.session_total_xp = result[5] self.base_xp = result[6] self.encounter_xp = result[7] self.stg_xp = result[8] self.attuned_xp = result[9] self.trait_xp = result[10] self.relationship_xp = result[11] self.lore_xp = result[12] self.problem_xp = result[13] self.journey_xp = result[14] self.failed_xp = result[15] self.impact_xp = result[16] self.calculate_xp() self.generate_session_embed_strings()
async def requestchannel(self, ctx): print( f'{botutils.timenow()} ***** Bot Command: {COMMAND_PREFIX}requestchannel called by {ctx.author.display_name}' ) db = botutils.SQLite3Helper() request_safenick = safe_nick(ctx.author.display_name) member_channel_id = await get_member_channel_id( ctx.guild.id, str(ctx.author)) # If we get a channel ID, we need to verify that the channel still exists if (member_channel_id is not None) and (member_channel_id > 100_000_000_000_000_000): discord_member_channel = discord.utils.get(ctx.guild.channels, id=member_channel_id) # If the channel ID stored in the db does not exist, remove it, then continue on to channel creation if not discord_member_channel: print( f'Channel ID {member_channel_id} stored in db does not exist; removing record.' ) await delete_member_channel_id(member_channel_id) # If we found a channel in the db and the channel exists, tag the owner in their channel else: print(f'Channel exists: {member_channel_id}') await discord_member_channel.send( f'Welcome back to your channel, ' + format(ctx.author.mention)) return # Verified that member's channel is not stored in the db and does not exist. Create one now. mc_category = await check_member_category(ctx) # Because categories are limited to 50 channels, we need to break up the alphabet into multiple categories # In practice, I found there to be a heavy distribution of names in the first 9 letters of the alphabet, # as well as a heavy distribution in letters j/k. For my primary server, these letter distributions ended up # two relatively equal categories. # TODO: Add configuration settings for number of categories, and letter distribution in each category letters_ai = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'] conditions_ai = [ request_safenick.startswith(first_letter) for first_letter in letters_ai ] if any(conditions_ai): mc_name = mc_category + ' [A-I]' else: mc_name = mc_category + ' [J-Z]' discord_member_category = discord.utils.get(ctx.guild.categories, name=mc_name) discord_member_channel = await ctx.guild.create_text_channel( request_safenick, category=discord_member_category) sql = MEMBER_CHANNEL_SET_SQL val = (ctx.guild.id, str(ctx.author), ctx.author.display_name, discord_member_channel.id) db.execute(sql, val) print(f'{db.rowcount} channel added.') await sort_cat(ctx, mc_name) await discord_member_channel.send(f'Welcome to your channel, ' + format(ctx.author.mention))
async def save_session(self): sql = self.SAVE_SESSION_SQL val = (self.guild_id, self.channel_id, self.date, self.party_current_xp, self.session_total_xp, self.base_xp, self.encounter_xp, self.stg_xp, self.attuned_xp, self.trait_xp, self.relationship_xp, self.lore_xp, self.problem_xp, self.journey_xp, self.failed_xp, self.impact_xp) db = botutils.SQLite3Helper() result = db.execute(sql, val) return result
async def explode(override=None, tauthor=None): """ Immediately trigger deletion of all timebombs in the scope specified by override. :parameter override : all - explode all currently set timebombs on the server mine - explode all currently set timebombs on the server for the current user :return No return value. """ db = botutils.SQLite3Helper() val = None if 'all' == override: sql = TIMEBOMB_EXPLODE_ALL_SQL elif 'mine' == override: sql = TIMEBOMB_EXPLODE_MINE_SQL val = (tauthor,) else: sql = TIMEBOMB_EXPLODE_SQL if val: explodelist = db.fetch(sql, val) else: explodelist = db.fetch(sql) for row in explodelist: explode_id = row[0] explode_channel_id = row[1] explode_channel = bobobot.get_channel(explode_channel_id) explode_message = await explode_channel.fetch_message(explode_id) try: await explode_message.delete() except errors.NotFound as err: print(f'NotFound: Message ID {explode_id} not deleted.') print(err) return None except errors.Forbidden as err: print(f'Forbidden: Message ID {explode_id} not deleted.') print(err) return None except errors.ClientException as err: print(f'ClientException: Message ID {explode_id} not deleted.') print(err) return None except errors.DiscordException as err: print(f'DiscordException: Message ID {explode_id} not deleted.') print(err) return None except Exception: print('Generic exception.', exc_info()) return None print(f'Message successfully deleted. Removing {explode_id} from the database.') mysql_remove_bomb_rowcount = await mysql_remove_bomb(explode_id) if mysql_remove_bomb_rowcount != 1: print(f'Message ID {explode_id} was not removed from the database. rc: {mysql_remove_bomb_rowcount}')
async def get_member_channel_id(guild_id, member_id): db = botutils.SQLite3Helper() sql = MEMBER_CHANNEL_GET_ID_SQL val = (guild_id, member_id) result = db.fetchone(sql, val) if not result: channel_id = None else: channel_id = result[0] return channel_id
async def get_member_channel_owner(guild_id, channel_id): db = botutils.SQLite3Helper() sql = MEMBER_CHANNEL_GET_OWNER_SQL val = (guild_id, channel_id) result = db.fetchone(sql, val) if result is not None: author_id = result[0] author_nick = result[1] else: author_id = None author_nick = None return author_id, author_nick
def load_xp(self): """ Retrieve the current party XP value for the current channel.""" sql = self.GET_PARTY_XP_SQL val = (self.ctx.guild.id, self.ctx.channel.id) db = botutils.SQLite3Helper() result = db.fetchone(sql, val) if result: self.party_current_xp = result[0] self.level, self.next_level = get_party_level( self.party_current_xp) else: self.party_current_xp = None print('XPSession.load_XP() returned 0 results') return result
async def mysql_remove_bomb(message_id): """ Removes the specified message from the timebomb table. :parameter message_id : ID of the timebomb message to remove from the database :return db.rowcount : Number of rows deleted from the database. Should be 1 if delete was successful. """ db = botutils.SQLite3Helper() sql = TIMEBOMB_REMOVE_SQL val = (message_id,) db.execute(sql, val) return db.cur.rowcount
def set_xp_channel(self, starting_xp: int = 0): """ If the current channel does not exist in the database, create it to begin tracking XP in this channel. :parameter starting_xp : int This is the XP value at which to begin tracking the party's experience in the event of adding tracking to an existing game. For a new game in which the party has not yet played a session, the default value of 0 is used. :return There is no return value. """ db = botutils.SQLite3Helper() sql = self.SET_CHANNEL_XP_SQL val = (self.ctx.guild.id, self.ctx.channel.id, starting_xp) result = db.execute(sql, val) self.load_xp() return result
async def get_purge_channel_list(guild_id): db = botutils.SQLite3Helper() return dict(db.fetch(PURGE_GET_CHANNEL_LIST_SQL, (guild_id, )))
def save_xp(self): sql = self.SET_PARTY_XP_SQL val = (self.party_new_total_xp, self.ctx.guild.id, self.ctx.channel.id) db = botutils.SQLite3Helper() result = db.execute(sql, val) return result
async def get_purge_channel_setting(guild_id, channel_id): db = botutils.SQLite3Helper() return db.fetch(PURGE_GET_CHANNEL_SETTING_SQL, (guild_id, channel_id))
async def delete_member_channel_id(_channel_id): db = botutils.SQLite3Helper() sql = MEMBER_CHANNEL_DELETE_SQL val = (_channel_id, ) db.execute(sql, val)
async def get_purge_guild_list(): db = botutils.SQLite3Helper() return db.fetch(PURGE_GET_GUILD_LIST_SQL)
async def set_purge_channel(guild_id, channel_id, purge_time): db = botutils.SQLite3Helper() db.execute(PURGE_SET_CHANNEL_SQL, (guild_id, channel_id, purge_time, purge_time))
async def remove_purge_channel(guild_id, channel_id): db = botutils.SQLite3Helper() db.execute(PURGE_REMOVE_CHANNEL_SQL, (guild_id, channel_id)) return db.rowcount