async def start(self, ctx, *, args_str: str = ""): logger.info("command: start session") await channel_setup(ctx) await user_setup(ctx) if database.exists(f"session.data:{ctx.author.id}"): logger.info("already session") await ctx.send("**There is already a session running.** *Change settings/view stats with `b!session edit`*") return else: args = args_str.split(" ") logger.info(f"args: {args}") if "bw" in args: bw = "bw" else: bw = "" states_args = set(states.keys()).intersection({arg.upper() for arg in args}) if states_args: state = " ".join(states_args).strip() else: state = " ".join(check_state_role(ctx)) taxon_args = set(taxons.keys()).intersection({arg.lower() for arg in args}) if taxon_args: taxon = " ".join(taxon_args).strip() else: taxon = "" female = "female" in args or "f" in args juvenile = "juvenile" in args or "j" in args if female and juvenile: await ctx.send("**Juvenile females are not yet supported.**\n*Please try again*") return elif female: addon = "female" elif juvenile: addon = "juvenile" else: addon = "" logger.info(f"adding bw: {bw}; addon: {addon}; state: {state}") database.hmset( f"session.data:{ctx.author.id}", { "start": round(time.time()), "stop": 0, "correct": 0, "incorrect": 0, "total": 0, "bw": bw, "state": state, "addon": addon, "taxon": taxon } ) await ctx.send(f"**Session started with options:**\n{await self._get_options(ctx)}")
async def start(self, ctx, *, args_str: str = ""): logger.info("command: start race") if not str(ctx.channel.name).startswith("racing"): logger.info("not race channel") await ctx.send( "**Sorry, racing is not available in this channel.**\n" + "*Set the channel name to start with `racing` to enable it.*" ) return if database.exists(f"race.data:{ctx.channel.id}"): logger.info("already race") await ctx.send( "**There is already a race in session.** *Change settings/view stats with `b!race view`*" ) return filters = Filter.parse(args_str, use_numbers=False) if filters.vc: if database.get(f"voice.server:{ctx.guild.id}") is not None: logger.info("already vc race") await ctx.send( "**There is already a VC race in session in this server!**" ) return client = await voice_functions.get_voice_client(ctx, connect=True) if client is None: return database.set(f"voice.server:{ctx.guild.id}", str(ctx.channel.id)) args = args_str.split(" ") logger.info(f"args: {args}") taxon_args = set(taxons.keys()).intersection({arg.lower() for arg in args}) if taxon_args: taxon = " ".join(taxon_args).strip() else: taxon = "" if "strict" in args: strict = "strict" else: strict = "" if "alpha" in args: alpha = "alpha" else: alpha = "" states_args = set(states.keys()).intersection({arg.upper() for arg in args}) if states_args: if {"CUSTOM"}.issubset(states_args): if database.exists( f"custom.list:{ctx.author.id}" ) and not database.exists(f"custom.confirm:{ctx.author.id}"): states_args.discard("CUSTOM") states_args.add(f"CUSTOM:{ctx.author.id}") else: states_args.discard("CUSTOM") await ctx.send( "**You don't have a custom list set.**\n*Ignoring the argument.*" ) state = " ".join(states_args).strip() else: state = "" song = "song" in args or "songs" in args or "s" in args or filters.vc image = ( "image" in args or "images" in args or "i" in args or "picture" in args or "pictures" in args or "p" in args ) if song and image: await ctx.send( "**Songs and images are not yet supported.**\n*Please try again*" ) return if song: media = "song" elif image: media = "image" else: media = "image" ints = [] for n in args: try: ints.append(int(n)) except ValueError: continue if ints: limit = int(ints[0]) else: limit = 10 if limit > 1000000: await ctx.send("**Sorry, the maximum amount to win is 1 million.**") limit = 1000000 logger.info( f"adding filters: {filters}; state: {state}; media: {media}; limit: {limit}" ) database.hset( f"race.data:{ctx.channel.id}", mapping={ "start": round(time.time()), "stop": 0, "limit": limit, "filter": str(filters.to_int()), "state": state, "media": media, "taxon": taxon, "strict": strict, "alpha": alpha, }, ) database.zadd(f"race.scores:{ctx.channel.id}", {str(ctx.author.id): 0}) await ctx.send( f"**Race started with options:**\n{await self._get_options(ctx)}" ) media = database.hget(f"race.data:{ctx.channel.id}", "media").decode("utf-8") logger.info("clearing previous bird") database.hset(f"channel:{ctx.channel.id}", "bird", "") database.hset(f"channel:{ctx.channel.id}", "answered", "1") logger.info(f"auto sending next bird {media}") filter_int, taxon, state = database.hmget( f"race.data:{ctx.channel.id}", ["filter", "taxon", "state"] ) birds = self.bot.get_cog("Birds") await birds.send_bird_( ctx, media, Filter.from_int(int(filter_int)), # type: ignore taxon.decode("utf-8"), # type: ignore state.decode("utf-8"), # type: ignore )
async def parse(ctx, args_str: str): """Parse arguments for options.""" args = args_str.split(" ") logger.info(f"args: {args}") if not database.exists(f"race.data:{ctx.channel.id}"): roles = check_state_role(ctx) taxon_args = set(taxons.keys()).intersection( {arg.lower() for arg in args}) if taxon_args: taxon = " ".join(taxon_args).strip() else: taxon = "" state_args = set(states.keys()).intersection( {arg.upper() for arg in args}) if state_args: state = " ".join(state_args).strip() else: state = "" if database.exists(f"session.data:{ctx.author.id}"): logger.info("session parameters") if taxon_args: current_taxons = set( database.hget(f"session.data:{ctx.author.id}", "taxon").decode("utf-8").split(" ")) logger.info(f"toggle taxons: {taxon_args}") logger.info(f"current taxons: {current_taxons}") taxon_args.symmetric_difference_update(current_taxons) taxon_args.discard("") logger.info(f"new taxons: {taxon_args}") taxon = " ".join(taxon_args).strip() else: taxon = database.hget(f"session.data:{ctx.author.id}", "taxon").decode("utf-8") roles = (database.hget(f"session.data:{ctx.author.id}", "state").decode("utf-8").split(" ")) if roles[0] == "": roles = [] if not roles: logger.info("no session lists") roles = check_state_role(ctx) session_filter = int( database.hget(f"session.data:{ctx.author.id}", "filter")) filters = Filter.parse(args_str, defaults=False) if filters.vc: filters.vc = False await ctx.send("**The VC filter is not allowed inline!**") default_quality = Filter().quality if (Filter.from_int(session_filter).quality == default_quality and filters.quality and filters.quality != default_quality): filters ^= Filter() # clear defaults filters ^= session_filter else: filters = Filter.parse(args_str) if filters.vc: filters.vc = False await ctx.send("**The VC filter is not allowed inline!**") if state_args: logger.info(f"toggle states: {state_args}") logger.info(f"current states: {roles}") state_args.symmetric_difference_update(set(roles)) state_args.discard("") logger.info(f"new states: {state_args}") state = " ".join(state_args).strip() else: state = " ".join(roles).strip() if "CUSTOM" in state.upper().split(" "): if not database.exists(f"custom.list:{ctx.author.id}"): await ctx.send("**You don't have a custom list set!**") state_list = state.split(" ") state_list.remove("CUSTOM") state = " ".join(state_list) elif database.exists(f"custom.confirm:{ctx.author.id}"): await ctx.send( "**Please verify or confirm your custom list before using!**" ) state_list = state.split(" ") state_list.remove("CUSTOM") state = " ".join(state_list) else: logger.info("race parameters") race_filter = int( database.hget(f"race.data:{ctx.channel.id}", "filter")) filters = Filter.parse(args_str, defaults=False) if filters.vc: filters.vc = False await ctx.send("**The VC filter is not allowed inline!**") default_quality = Filter().quality if (Filter.from_int(race_filter).quality == default_quality and filters.quality and filters.quality != default_quality): filters ^= Filter() # clear defaults filters ^= race_filter taxon = database.hget(f"race.data:{ctx.channel.id}", "taxon").decode("utf-8") state = database.hget(f"race.data:{ctx.channel.id}", "state").decode("utf-8") logger.info( f"args: filters: {filters}; taxon: {taxon}; state: {state}") return (filters, taxon, state)
async def edit(self, ctx, *, args_str: str = ""): logger.info("command: view session") await channel_setup(ctx) await user_setup(ctx) if database.exists(f"session.data:{ctx.author.id}"): args = args_str.split(" ") logger.info(f"args: {args}") if "bw" in args: if not database.hget(f"session.data:{ctx.author.id}", "bw"): logger.info("adding bw") database.hset(f"session.data:{ctx.author.id}", "bw", "bw") else: logger.info("removing bw") database.hset(f"session.data:{ctx.author.id}", "bw", "") states_args = set(states.keys()).intersection({arg.upper() for arg in args}) if states_args: toggle_states = list(states_args) current_states = database.hget(f"session.data:{ctx.author.id}", "state").decode("utf-8").split(" ") add_states = [] logger.info(f"toggle states: {toggle_states}") logger.info(f"current states: {current_states}") for state in set(toggle_states).symmetric_difference(set(current_states)): add_states.append(state) logger.info(f"adding states: {add_states}") database.hset(f"session.data:{ctx.author.id}", "state", " ".join(add_states).strip()) taxon_args = set(taxons.keys()).intersection({arg.lower() for arg in args}) if taxon_args: toggle_taxon = list(taxon_args) current_taxons = database.hget(f"session.data:{ctx.author.id}", "taxon").decode("utf-8").split(" ") add_taxons = [] logger.info(f"toggle taxons: {toggle_taxon}") logger.info(f"current taxons: {current_taxons}") for o in set(toggle_taxon).symmetric_difference(set(current_taxons)): add_taxons.append(o) logger.info(f"adding taxons: {add_taxons}") database.hset(f"session.data:{ctx.author.id}", "taxon", " ".join(add_taxons).strip()) female = "female" in args or "f" in args juvenile = "juvenile" in args or "j" in args if female and juvenile: await ctx.send("**Juvenile females are not yet supported.**\n*Please try again*") return elif female: addon = "female" if not database.hget(f"session.data:{ctx.author.id}", "addon"): logger.info("adding female") database.hset(f"session.data:{ctx.author.id}", "addon", addon) else: logger.info("removing female") database.hset(f"session.data:{ctx.author.id}", "addon", "") elif juvenile: addon = "juvenile" if not database.hget(f"session.data:{ctx.author.id}", "addon"): logger.info("adding juvenile") database.hset(f"session.data:{ctx.author.id}", "addon", addon) else: logger.info("removing juvenile") database.hset(f"session.data:{ctx.author.id}", "addon", "") await self._send_stats(ctx, f"**Session started previously.**\n") else: await ctx.send("**There is no session running.** *You can start one with `b!session start`*")
async def edit(self, ctx, *, args_str: str = ""): logger.info("command: view session") if database.exists(f"session.data:{ctx.author.id}"): new_filter = Filter.parse(args_str, defaults=False) args = args_str.lower().split(" ") logger.info(f"args: {args}") new_filter ^= int( database.hget(f"session.data:{ctx.author.id}", "filter")) database.hset(f"session.data:{ctx.author.id}", "filter", str(new_filter.to_int())) if "wiki" in args: if database.hget(f"session.data:{ctx.author.id}", "wiki"): logger.info("enabling wiki embeds") database.hset(f"session.data:{ctx.author.id}", "wiki", "") else: logger.info("disabling wiki embeds") database.hset(f"session.data:{ctx.author.id}", "wiki", "wiki") if "strict" in args: if database.hget(f"session.data:{ctx.author.id}", "strict"): logger.info("disabling strict spelling") database.hset(f"session.data:{ctx.author.id}", "strict", "") else: logger.info("enabling strict spelling") database.hset(f"session.data:{ctx.author.id}", "strict", "strict") states_args = set(states.keys()).intersection( {arg.upper() for arg in args}) if states_args: current_states = set( database.hget(f"session.data:{ctx.author.id}", "state").decode("utf-8").split(" ")) logger.info(f"toggle states: {states_args}") logger.info(f"current states: {current_states}") states_args.symmetric_difference_update(current_states) logger.info(f"new states: {states_args}") database.hset( f"session.data:{ctx.author.id}", "state", " ".join(states_args).strip(), ) taxon_args = set(taxons.keys()).intersection( {arg.lower() for arg in args}) if taxon_args: current_taxons = set( database.hget(f"session.data:{ctx.author.id}", "taxon").decode("utf-8").split(" ")) logger.info(f"toggle taxons: {taxon_args}") logger.info(f"current taxons: {current_taxons}") taxon_args.symmetric_difference_update(current_taxons) logger.info(f"new taxons: {taxon_args}") database.hset( f"session.data:{ctx.author.id}", "taxon", " ".join(taxon_args).strip(), ) await self._send_stats(ctx, "**Session started previously.**\n") else: await ctx.send( "**There is no session running.** *You can start one with `b!session start`*" )
async def start(self, ctx, *, args_str: str = ""): logger.info("command: start session") if database.exists(f"session.data:{ctx.author.id}"): logger.info("already session") await ctx.send( "**There is already a session running.** *Change settings/view stats with `b!session edit`*" ) return filters = Filter.parse(args_str) args = args_str.lower().split(" ") logger.info(f"args: {args}") if "wiki" in args: wiki = "" else: wiki = "wiki" if "strict" in args: strict = "strict" else: strict = "" states_args = set(states.keys()).intersection( {arg.upper() for arg in args}) if states_args: state = " ".join(states_args).strip() else: state = " ".join(check_state_role(ctx)) taxon_args = set(taxons.keys()).intersection( {arg.lower() for arg in args}) if taxon_args: taxon = " ".join(taxon_args).strip() else: taxon = "" logger.info( f"adding filters: {filters}; state: {state}; wiki: {wiki}; strict: {strict}" ) database.hset( f"session.data:{ctx.author.id}", mapping={ "start": round(time.time()), "stop": 0, "correct": 0, "incorrect": 0, "total": 0, "filter": str(filters.to_int()), "state": state, "taxon": taxon, "wiki": wiki, "strict": strict, }, ) await ctx.send( f"**Session started with options:**\n{await self._get_options(ctx)}" )
async def start(self, ctx, *, args_str: str = ""): logger.info("command: start race") await channel_setup(ctx) await user_setup(ctx) if ctx.guild is None: logger.info("dm context") await ctx.send("**Sorry, racing is not avaliable in DMs.**") return if not str(ctx.channel.name).startswith("racing"): logger.info("not race channel") await ctx.send( "**Sorry, racing is not availiable in this channel.**\n" + "*Set the channel name to start with `racing` to enable it.*") return if database.exists(f"race.data:{ctx.channel.id}"): logger.info("already race") await ctx.send( "**There is already a race in session.** *Change settings/view stats with `b!race view`*" ) return else: args = args_str.split(" ") logger.info(f"args: {args}") if "bw" in args: bw = "bw" else: bw = "" taxon_args = set(taxons.keys()).intersection( {arg.lower() for arg in args}) if taxon_args: taxon = " ".join(taxon_args).strip() else: taxon = "" states_args = set(states.keys()).intersection( {arg.upper() for arg in args}) if states_args: state = " ".join(states_args).strip() else: state = " ".join(check_state_role(ctx)) female = "female" in args or "f" in args juvenile = "juvenile" in args or "j" in args if female and juvenile: await ctx.send( "**Juvenile females are not yet supported.**\n*Please try again*" ) return elif female: addon = "female" elif juvenile: addon = "juvenile" else: addon = "" song = "song" in args or "s" in args image = "image" in args or "i" in args or "picture" in args or "p" in args if song and image: await ctx.send( "**Songs and images are not yet supported.**\n*Please try again*" ) return elif song: media = "song" elif image: media = "image" else: media = "image" ints = [] for n in args: try: ints.append(int(n)) except ValueError: continue if ints: limit = int(ints[0]) else: limit = 10 if limit > 1000000: await ctx.send( "**Sorry, the maximum amount to win is 1 million.**") limit = 1000000 logger.info( f"adding bw: {bw}; addon: {addon}; state: {state}; media: {media}; limit: {limit}" ) database.hmset( f"race.data:{ctx.channel.id}", { "start": round(time.time()), "stop": 0, "limit": limit, "bw": bw, "state": state, "addon": addon, "media": media, "taxon": taxon }) database.zadd(f"race.scores:{ctx.channel.id}", {str(ctx.author.id): 0}) await ctx.send( f"**Race started with options:**\n{await self._get_options(ctx)}" ) if database.hget(f"race.data:{ctx.channel.id}", "media").decode("utf-8") == "image": logger.info("clearing previous bird") database.hset(f"channel:{ctx.channel.id}", "bird", "") database.hset(f"channel:{ctx.channel.id}", "answered", "1") logger.info("auto sending next bird image") addon, bw, taxon = database.hmget( f"race.data:{ctx.channel.id}", ["addon", "bw", "taxon"]) birds = self.bot.get_cog("Birds") await birds.send_bird_( ctx, addon.decode("utf-8"), # type: ignore bw.decode("utf-8"), # type: ignore taxon.decode("utf-8") # type: ignore ) if database.hget(f"race.data:{ctx.channel.id}", "media").decode("utf-8") == "song": logger.info("clearing previous bird") database.hset(f"channel:{ctx.channel.id}", "sBird", "") database.hset(f"channel:{ctx.channel.id}", "sAnswered", "1") logger.info("auto sending next bird song") birds = self.bot.get_cog("Birds") await birds.send_song_(ctx)
def parse(ctx, args_str: str): """Parse arguments for options.""" args = args_str.split(" ") logger.info(f"args: {args}") if not database.exists(f"race.data:{ctx.channel.id}"): roles = check_state_role(ctx) taxon_args = set(taxons.keys()).intersection( {arg.lower() for arg in args}) if taxon_args: taxon = " ".join(taxon_args).strip() else: taxon = "" state_args = set(states.keys()).intersection( {arg.upper() for arg in args}) if state_args: state = " ".join(state_args).strip() else: state = "" if database.exists(f"session.data:{ctx.author.id}"): logger.info("session parameters") if taxon_args: current_taxons = set( database.hget(f"session.data:{ctx.author.id}", "taxon").decode("utf-8").split(" ")) logger.info(f"toggle taxons: {taxon_args}") logger.info(f"current taxons: {current_taxons}") taxon_args.symmetric_difference_update(current_taxons) logger.info(f"new taxons: {taxon_args}") taxon = " ".join(taxon_args).strip() else: taxon = database.hget(f"session.data:{ctx.author.id}", "taxon").decode("utf-8") roles = (database.hget(f"session.data:{ctx.author.id}", "state").decode("utf-8").split(" ")) if roles[0] == "": roles = [] if not roles: logger.info("no session lists") roles = check_state_role(ctx) session_filter = int( database.hget(f"session.data:{ctx.author.id}", "filter")) filters = Filter.parse(args_str, defaults=False) default_quality = Filter().quality if (Filter.from_int(session_filter).quality == default_quality and filters.quality and filters.quality != default_quality): filters ^= Filter() # clear defaults filters ^= session_filter else: filters = Filter.parse(args_str) if state_args: logger.info(f"toggle states: {state_args}") logger.info(f"current states: {roles}") state_args.symmetric_difference_update(set(roles)) logger.info(f"new states: {state_args}") state = " ".join(state_args).strip() else: state = " ".join(roles).strip() else: logger.info("race parameters") race_filter = int( database.hget(f"race.data:{ctx.channel.id}", "filter")) filters = Filter.parse(args_str, defaults=False) default_quality = Filter().quality if (Filter.from_int(race_filter).quality == default_quality and filters.quality and filters.quality != default_quality): filters ^= Filter() # clear defaults filters ^= race_filter taxon = database.hget(f"race.data:{ctx.channel.id}", "taxon").decode("utf-8") state = database.hget(f"race.data:{ctx.channel.id}", "state").decode("utf-8") logger.info( f"args: filters: {filters}; taxon: {taxon}; state: {state}") return (filters, taxon, state)
async def bird(self, ctx, *, args_str: str = ""): logger.info("command: bird") await channel_setup(ctx) await user_setup(ctx) args = args_str.split(" ") logger.info(f"args: {args}") bw = "bw" in args taxon_args = set(taxons.keys()).intersection( {arg.lower() for arg in args}) if taxon_args: taxon = " ".join(taxon_args).strip() else: taxon = "" female = "female" in args or "f" in args juvenile = "juvenile" in args or "j" in args if female and juvenile: await ctx.send( "**Juvenile females are not yet supported.**\n*Please try again*" ) return elif female: add_on = "female" elif juvenile: add_on = "juvenile" else: add_on = "" if database.exists(f"session.data:{ctx.author.id}"): logger.info("session parameters") if taxon_args: toggle_taxon = list(taxon_args) current_taxons = database.hget( f"session.data:{ctx.author.id}", "taxon").decode("utf-8").split(" ") add_taxons = [] logger.info(f"toggle taxons: {toggle_taxon}") logger.info(f"current taxons: {current_taxons}") for o in set(toggle_taxon).symmetric_difference( set(current_taxons)): add_taxons.append(o) logger.info(f"adding taxons: {add_taxons}") taxon = " ".join(add_taxons).strip() else: taxon = database.hget(f"session.data:{ctx.author.id}", "taxon").decode("utf-8") session_add_on = database.hget(f"session.data:{ctx.author.id}", "addon").decode("utf-8") if add_on == "": add_on = session_add_on elif add_on == session_add_on: add_on = "" elif session_add_on == "": add_on = add_on else: await ctx.send( "**Juvenile females are not yet supported.**\n*Overriding session options...*" ) if database.hget(f"session.data:{ctx.author.id}", "bw").decode("utf-8"): bw = not bw if database.exists(f"race.data:{ctx.channel.id}"): logger.info("race parameters") race_add_on = database.hget(f"race.data:{ctx.channel.id}", "addon").decode("utf-8") if add_on == "": add_on = race_add_on elif add_on == race_add_on: add_on = "" elif race_add_on == "": add_on = add_on else: await ctx.send( "**Juvenile females are not yet supported.**\n*Overriding race options...*" ) if database.hget(f"race.data:{ctx.channel.id}", "bw").decode("utf-8"): bw = not bw logger.info(f"args: bw: {bw}; addon: {add_on}; taxon: {taxon}") if int(database.hget(f"channel:{ctx.channel.id}", "answered")): await ctx.send( f"**Recognized arguments:** *Black & White*: `{bw}`, " + f"*Female/Juvenile*: `{'None' if add_on == '' else add_on}`, " + f"*Taxons*: `{'None' if taxon == '' else taxon}`") else: await ctx.send( f"**Recognized arguments:** *Black & White*: `{bw}`, " + f"*Female/Juvenile*: `{'None' if add_on == '' else add_on}`") await self.send_bird_(ctx, add_on, bw, taxon)