def find_category(self, user, name): if isinstance(name, AbstractChannelCategory): return name if isinstance(name, ChannelCategoryBridge): return name.db_script if (found := partial_match(name, self.visible_categories(user))): return found
def find_channel(self, user, name): if isinstance(name, AbstractChannel): return name if isinstance(name, ChannelBridge): return name.db_channel if (found := partial_match(name, self.visible_channels(user))): return found
def find_template(self, template): if not template: raise ValueError("Nothing entered for Template!") if isinstance(template, DefaultPersona): return template if not (found := partial_match(template, settings.STORYTELLER_TEMPLATES.keys())): raise ValueError(f"No template {template}")
def func(self): self.chosen_switch = None try: if self.switches: if len(self.switches) > 1: raise ValueError(f"{self.key} does not support multiple simultaneous switches!") if not (switch := partial_match(self.switches[0], self.switch_options)): raise ValueError(f"{self.key} does not support switch '{self.switches[0]}`") if not (found := getattr(self, f"switch_{switch}", None)): raise ValueError(f"Command does not support switch {switch}") self.chosen_switch = switch return found()
def character_change_primary(self, session, character, theme_name): enactor = session.get_puppet_or_account() participating = character.themes.all() if not participating: raise ValueError("Character has no themes!") old_primary = character.db._primary_theme if old_primary: old_list_type = old_primary.list_type else: old_list_type = None theme_part = partial_match(theme_name, participating) if not theme_part: raise ValueError(f"Character has no Theme named {theme_name}!") character.db._primary_theme = theme_part if old_primary: tmsg.ThemeChangePrimaryMessage( enactor, target=character, old_theme_name=old_primary.theme.key, old_list_type=old_list_type, theme=theme_part.theme, list_type=theme_part.list_type).send() else: tmsg.ThemeSetPrimaryMessage(enactor, target=character, theme_name=theme_part.theme.key, list_type=theme_part.list_type)
def switch_remove(self, lhs, rhs): if not lhs: self.error("No theme name entered.") return themes = FCList.objects.all() if not themes: self.error("There are no themes!") return found = partial_match(lhs, themes) if not found: self.error("Theme not found.") return try: char = self.character.search_character(rhs) except ValueError as err: self.error(unicode(err)) return if char in found.cast.all(): found.cast.remove(char) else: self.error("They are not in that theme.") return self.sys_msg("You have been removed from Theme: %s" % found, target=char) self.sys_msg("Removed '%s' from Theme: %s" % (char, found)) self.sys_report("Removed '%s' from Theme: %s" % (char, found))
def board_lock(self, lhs=None, rhs=None): try: board_group = self.board_group board = board_group.find_board(find_name=lhs.strip(), checker=self.character) except ValueError as err: self.error(unicode(err)) return if not board.check_permission(checker=self.character, type='admin', checkadmin=False): self.error("Permission denied.") return if not rhs: self.error("Must enter a lockstring.") return for locksetting in rhs.split(';'): access_type, lockfunc = locksetting.split(':', 1) if not access_type: self.error("Must enter an access type: read, write, or admin.") return accmatch = partial_match(access_type, ['read', 'write', 'admin']) if not accmatch: self.error("Access type must be read, write, or admin.") return if not lockfunc: self.error("Lock func not entered.") return ok = False try: ok = board.locks.add(rhs) board.save(update_fields=['lock_storage']) except LockException as e: self.error(unicode(e)) if ok: self.sys_msg("Added lock '%s' to %s." % (rhs, board)) return
def do_validate(self, value, value_list): if not value: return TZ_DICT['UTC'] found = partial_match(value, TZ_DICT.keys()) if found: return TZ_DICT[found] raise ValueError("Could not find timezone '%s'!" % value)
def set(self, name=None, value=None): if self.extra.set_is_add: return self.add(name, value) choices = self.extra.stats if not name: raise ValueError("What will you set? Your choices are: %s" % ', '.join(choices)) stat = partial_match(name, choices) if not stat and self.extra.can_create: raise ValueError("That stat is not available, but can be created.") elif not stat and not self.extra.can_create: raise ValueError( "That stat is not available. Your choices are: %s" % ', '.join(choices)) val = stat.validate_set(value) my_stat = self.stats_dict.get(stat.id, None) if not val and my_stat is None: raise ValueError("There's no point in adding a Stat at zero.") if not my_stat: my_stat = self.add_stat(stat) if not val and self.extra.set_zero_is_remove: if not self.confirm_delete is my_stat and self.extra.confirm_remove: self.confirm_delete = my_stat return "This will remove %s. To confirm, enter the command again." % my_stat message = "Deleted %s." % my_stat self.delete_stat(my_stat.id) del my_stat if self.extra.clear_unused_stats and not stat.model.users.count(): self.extra.delete_stat(stat.id) return message return my_stat.set(val)
def set(self, name=None, value=None): options = {'Template': self.set_template} if not name: raise ValueError("What will you set?") found = partial_match(name, options.keys()) if found: return options[found](value) return self.template.set(name, value)
def set(self, key=None, value=None, value_list=None): if not key: raise ValueError("Nothing chosen to set!") found = partial_match(key, self.settings) if not found: raise ValueError("Sorry, could not find '%s'." % key) found.set(value, value_list) return self.set_after(found)
def set(self, name=None, value=None): choices = self.stats choice_names = ', '.join([str(ch) for ch in choices]) if not name: raise ValueError("What will you set? Choices are: %s" % choice_names) found = partial_match(name, choices) if not found: raise ValueError("Stat not found! Choices are: %s" % choice_names) return found.set(value)
def switch(self, choice=None): if not choice: raise ValueError("Nothing entered to switch modes to!") found = partial_match(choice, self.choices) if not found: raise ValueError("That is not a valid mode. Choices are: %s" % ', '.join([str(chc) for chc in self.choices])) self.mode = found return "Mode changed to: %s" % found
def find_bucket(self, account, bucket=None): if isinstance(bucket, BucketDB): return bucket if not bucket: raise ValueError("Must enter a bucket name!") found = partial_match(bucket, self.visible_buckets(account)) if not found: raise ValueError("Bucket not found.") return found
def parse_switches(self): self.final_switches = [] total_switches = [] if self.is_admin and self.admin_switches: total_switches += self.admin_switches total_switches += self.player_switches for switch in self.switches: found_switches = partial_match(switch, total_switches) if found_switches: self.final_switches.append(found_switches)
def set_template(self, value=None): choices = self.data.templates if not value: raise ValueError("What Template will you use? Choices are: %s" % ', '.join([str(tem) for tem in choices])) tem = partial_match(value, choices) if not tem: raise ValueError("Template not found. Choices are: %s" % ', '.join([str(tem) for tem in choices])) self.persona.template = tem.id self.persona.save(update_fields=['template']) self.template = tem.use(self, tem, self.persona) return "Template Changed to: %s" % tem
def do_validate(self, value, value_list): if not len(value_list): return value_list found_list = list() channels = PublicChannel.objects.filter_family() for name in value_list: found = partial_match(name, channels) if not found: raise ValueError("'%s' did not match a channel." % name) found_list.append(found) return list(set(found_list))
def getstat(self, attrname, stat): attr = self.mushget(attrname) if not attr: return attr_dict = dict() for element in attr.split('|'): name, value = element.split('~', 1) attr_dict[name] = value find_stat = partial_match(stat, attr_dict) if not find_stat: return return attr_dict[find_stat]
def select_character(self, char_name, exact=False): """ Select a character owned by the Account using this command. Args: char_name (str): The character name to search for. exact (bool): Search using exact name or not. Returns: discovered character (AthanorPlayerCharacter) """ if not self.account: raise ValueError("Must be logged in to use this feature!") if not char_name: raise ValueError("no character entered to search for!") candidates = self.controllers.get('playercharacter').all(account=self.account) if not candidates: raise ValueError("No characters to select from!") if not (found := partial_match(char_name, candidates)): raise ValueError(f"Cannot locate character named {char_name}!")
def switch_display(self, lhs, rhs): if not lhs: self.error("No theme name entered.") return themes = FCList.objects.all() if not themes: self.error("There are no themes!") return found = partial_match(lhs, themes) if not found: self.error("Theme not found.") return self.msg(found.display_list(viewer=self.character))
def set_value(self, choice): old_value = str(self.value) if len(self.choices): find_value = partial_match(choice, self.choices) if not find_value: raise ValueError("That is not a valid choice! Choose from: %s" % ", ".join(self.choices)) self.value = find_value else: final_value = clean_string(choice) self.value = final_value if not old_value == self.value: self.save()
def find_theme(self, enactor, theme_name): if isinstance(theme_name, AthanorTheme): return theme_name if isinstance(theme_name, ThemeBridge): return theme_name.db_script if isinstance(theme_name, int): theme = AthanorTheme.objects.filter_family(id=theme_name).first() if not theme: raise ValueError(f"Theme ID {theme_name}' not found!") return theme theme = partial_match(theme_name, self.themes()) if not theme: raise ValueError(f"Theme '{theme_name}' not found!") return theme.db_script
def find_faction(self, search_text): if not search_text: raise ValueError("Not faction entered to search for!") if isinstance(search_text, AthanorFaction): return search_text if isinstance(search_text, FactionBridge): return search_text.db_object search_tree = [text.strip() for text in search_text.split('/') ] if '/' in search_text else [search_text] found = None for srch in search_tree: found = partial_match(srch, self.factions(found)) if not found: raise ValueError(f"Faction {srch} not found!") return found.db_object
def find_group(search_name=None, exact=False, checker=None): if checker: group_ids = [group.id for group in Group.objects.all() if group.is_member(checker)] groups = Group.objects.filter(id__in=group_ids) else: groups = Group.objects.all() if not search_name: raise ValueError("No group entered to match.") if exact: find = groups.filter(key__iexact=search_name).first() else: find = partial_match(search_name, groups) if find: return find else: raise ValueError("Group '%s' not found. % search_name")
def switch_clearpowers(self, lhs, rhs): if not lhs: self.error("No theme name entered.") return themes = FCList.objects.all() if not themes: self.error("There are no themes!") return found = partial_match(lhs, themes) if not found: self.error("Theme not found.") return found.info = None found.save(update_fields=['powers']) self.sys_msg("Powers for %s cleared!" % found) self.sys_report("Cleared Powers for Theme: %s" % found)
def switch_delete(self, lhs, rhs): if not lhs: self.error("No theme name entered.") return themes = FCList.objects.all() if not themes: self.error("There are no themes!") return found = partial_match(lhs, themes) if not found: self.error("Theme not found.") return if not self.verify('theme delete %s' % found.id): self.sys_msg("|rWARNING|n: This will delete Theme: %s. Are you sure? Enter the same command again to verify." % found) return self.sys_msg("Theme deleted.") self.sys_report("Deleted Theme '%s'!" % found) found.delete()
def add(self, name=None, value=None): choices = self.extra.stats if not name: raise ValueError("What will you set? Your choices are: %s" % ', '.join(choices)) stat = partial_match(name, choices) if not stat and self.extra.can_create: raise ValueError("That stat is not available, but can be created.") elif not stat and not self.extra.can_create: raise ValueError( "That stat is not available. Your choices are: %s" % ', '.join(choices)) val = stat.validate_set(value) my_stat = self.stats_dict.get(stat.id, None) if not val and my_stat is None: raise ValueError("There's no point in adding a Stat at zero.") if not my_stat: my_stat = self.add_stat(stat) return my_stat.add(val)
def switch_setpowers(self, lhs, rhs): if not lhs: self.error("No theme name entered.") return themes = FCList.objects.all() if not themes: self.error("There are no themes!") return found = partial_match(lhs, themes) if not found: self.error("Theme not found.") return if not rhs: self.error("You must enter a text field!") return found.powers = rhs found.save(update_fields=['powers']) self.sys_msg("Powers for %s updated!" % found) self.sys_report("Updated Powers for Theme: %s" % found)
def switch_status(self, lhs, rhs): try: char = self.character.search_character(lhs) except ValueError as err: self.error(unicode(err)) return if not rhs: self.error("No status entered to assign!") return charstatus = GLOBAL_SETTINGS['fclist_status'] found = partial_match(rhs, charstatus) if not found: self.error("No match for status! Options: %s" % ', '.join(charstatus)) return char.config.model.character_status = found char.config.model.save(update_fields=['character_status']) self.sys_msg("Your character status is now: %s." % found, target=char) self.sys_msg("%s is now listed as %s." % (char, found)) self.sys_report("%s is now listed as %s." % (char, found))
def switch_describe(self, lhs, rhs): if not lhs: self.error("No theme name entered.") return themes = FCList.objects.all() if not themes: self.error("There are no themes!") return found = partial_match(lhs, themes) if not found: self.error("Theme not found.") return if not rhs: self.error("You must enter a description!") return found.description = rhs found.save(update_fields=['description']) self.sys_msg("Description for %s updated!" % found) self.sys_report("Updated Description for Theme: %s" % found)
def switch_powers(self, lhs, rhs): if not lhs: self.error("No theme name entered.") return themes = FCList.objects.all() if not themes: self.error("There are no themes!") return found = partial_match(lhs, themes) if not found: self.error("Theme not found.") return if not found.powers: self.error("Theme has no powers.") return message = list() message.append(self.player.render.header('Powers for Theme: %s' % found)) message.append(found.powers) message.append(self.player.render.footer()) self.msg_lines(message)
def switch_assign(self, lhs, rhs): if not lhs: self.error("No theme name entered.") return themes = FCList.objects.all() if not themes: self.error("There are no themes!") return found = partial_match(lhs, themes) if not found: self.error("Theme not found.") return try: char = self.character.search_character(rhs) except ValueError as err: self.error(unicode(err)) return found.cast.add(char) self.sys_msg("You have been added to Theme: %s" % found, target=char) self.sys_msg("Added '%s' to Theme: %s" % (char, found)) self.sys_report("Added '%s' to Theme: %s" % (char, found))
def switch_rename(self, lhs, rhs): if not lhs: self.error("No theme name entered.") return themes = FCList.objects.all() if not themes: self.error("There are no themes!") return found = partial_match(lhs, themes) if not found: self.error("Theme not found.") return if not rhs: self.error("Must enter something to rename it to!") return if FCList.objects.filter(key__iexact=rhs).exclude(id=found.id).count(): self.error("That name conflicts with another theme.") return self.sys_msg("Theme renamed to: %s" % rhs) self.sys_report("Renamed Theme '%s' to: %s" % (found, rhs)) found.key = rhs found.save()
def find_board(self, find_name=None, checker=None, visible_only=True): if not find_name: raise ValueError("No board entered to find!") if checker: if visible_only: boards = self.visible_boards(checker) else: boards = self.usable_boards(checker) else: boards = self.list if not boards: raise ValueError("No applicable boards.") try: find_num = int(find_name) except ValueError: find_board = partial_match(find_name, boards) if not find_board: raise ValueError("Board '%s' not found." % find_name) return find_board else: if find_num not in [board.order for board in boards]: raise ValueError("Board '%s' not found." % find_name) return [board for board in boards if board.order == find_num][0]
def post_edit_progress(self, lhs, rhs): if not self.isic: self.error("You must be @ic to make a post!") return if not self.character.db.curpost: self.error("You do not have a post in progress.") return if not lhs: self.error("Must choose to edit subject or text.") return choice = partial_match(lhs, ['subject', 'text']) if not choice: self.error("Must choose to edit subject or text.") return if not rhs: self.error("What will you edit?") return find, replace = rhs.split('/', 1) if not find: self.error("Nothing to find.") return self.character.db.curpost[choice] = self.character.db.curpost[choice].replace(find, replace) self.sys_msg("Edited.") return
channel_bridge__db_category__db_system__db_script=self).order_by( 'channel_bridge__db_category__db_name', 'db_key') def visible_channels(self, user): return [ channel for channel in self.channels() if channel.check_position(user, 'listener') ] def target_channel(self, session, category, name): if not (enactor := self.get_enactor(session)): raise ValueError("Permission denied.") channel_tree = defaultdict(list) for channel in self.visible_channels(enactor): channel_tree[channel.category].append(channel) if not (category := partial_match(category, channel_tree.keys())): raise ValueError("Category not found!") if not (channel := partial_match(name, channel_tree[category])): raise ValueError("Channel not found!") return (self, category, channel) def render_channel_list(self, session): if not (enactor := self.get_enactor(session)): raise ValueError("Permission denied.") if not (channels := self.visible_channels(enactor)): raise ValueError("No Channels to display!") styling = enactor.styler message = list() message.append( styling.styled_header(f"{str(self).capitalize()} Channels")) message.append(
def partial(self, match_text, candidates): return partial_match(match_text, candidates)
def convert_ex2(self, character): # First, let's convert templates. template = character.mush.getstat('D`INFO', 'Class') or 'Mortal' sub_class = character.mush.getstat('D`INFO', 'Caste') or None attribute_string = character.mush.mushget('D`ATTRIBUTES') or '' skill_string = character.mush.mushget('D`ABILITIES') or '' paths_string = character.mush.mushget('D`PATHS') or '' colleges_string = character.mush.mushget('D`COLLEGES') or '' virtues_string = character.mush.mushget('D`VIRTUES') or '' graces_string = character.mush.mushget('D`GRACES') or '' slots_string = character.mush.mushget('D`SLOTS') or '' specialties_string = character.mush.mushget('D`SPECIALTIES') power = character.mush.getstat('D`INFO', 'POWER') or 1 power_string = 'POWER~%s' % power willpower = character.mush.getstat('D`INFO', 'WILLPOWER') if willpower: willpower_string = 'WILLPOWER~%s' % willpower else: willpower_string = '' stat_string = "|".join([attribute_string, skill_string, paths_string, colleges_string, virtues_string, graces_string, slots_string, willpower_string, power_string]) stat_list = [element for element in stat_string.split('|') if len(element)] stats_dict = dict() for stat in stat_list: name, value = stat.split('~', 1) try: int_value = int(value) except ValueError: int_value = 0 stats_dict[name] = int(int_value) cache_stats = character.stats.cache_stats character.template.swap(template) character.template.template.sub_class = sub_class character.template.save() for stat in stats_dict.keys(): find_stat = partial_match(stat, cache_stats) if not find_stat: continue find_stat.current_value = stats_dict[stat] character.stats.save() merits_dict = {'D`MERITS`*': character.storyteller.merits, 'D`FLAWS`*': character.storyteller.flaws, 'D`POSITIVE_MUTATIONS`*': character.storyteller.positivemutations, 'D`NEGATIVE_MUTATIONS`*': character.storyteller.negativemutations, 'D`RAGE_MUTATIONS`*': character.storyteller.ragemutations, 'D`WARFORM_MUTATIONS`*': character.storyteller.warmutations, 'D`BACKGROUNDS`*': character.storyteller.backgrounds} for merit_type in merits_dict.keys(): self.ex2_merits(character, merit_type, merits_dict[merit_type]) character.merits.save() for charm_attr in character.mush.lattr('D`CHARMS`*'): root, charm_name, charm_type = charm_attr.split('`') if charm_type == 'SOLAR': self.ex2_charms(character, charm_attr, character.storyteller.solarcharms) if charm_type == 'LUNAR': self.ex2_charms(character, charm_attr, character.storyteller.lunarcharms) if charm_type == 'ABYSSAL': self.ex2_charms(character, charm_attr, character.storyteller.abyssalcharms) if charm_type == 'INFERNAL': self.ex2_charms(character, charm_attr, character.storyteller.infernalcharms) if charm_type == 'SIDEREAL': self.ex2_charms(character, charm_attr, character.storyteller.siderealcharms) if charm_type == 'TERRESTRIAL': self.ex2_charms(character, charm_attr, character.storyteller.terrestrialcharms) if charm_type == 'ALCHEMICAL': self.ex2_charms(character, charm_attr, character.storyteller.alchemicalcharms) if charm_type == 'RAKSHA': self.ex2_charms(character, charm_attr, character.storyteller.rakshacharms) if charm_type == 'SPIRIT': self.ex2_charms(character, charm_attr, character.storyteller.spiritcharms) if charm_type == 'GHOST': self.ex2_charms(character, charm_attr, character.storyteller.ghostcharms) if charm_type == 'JADEBORN': self.ex2_charms(character, charm_attr, character.storyteller.jadeborncharms) if charm_type == 'TERRESTRIAL_MARTIAL_ARTS': self.ex2_martial(character, charm_attr, character.storyteller.terrestrialmartialarts) if charm_type == 'CELESTIAL_MARTIAL_ARTS': self.ex2_martial(character, charm_attr, character.storyteller.celestialmartialarts) if charm_type == 'SIDEREAL_MARTIAL_ARTS': self.ex2_martial(character, charm_attr, character.storyteller.siderealmartialarts) for spell_attr in character.mush.lattr('D`SPELLS`*'): root, charm_name, charm_type = spell_attr.split('`') if charm_type in ['TERRESTRIAL', 'CELESTIAL', 'SOLAR']: self.ex2_spells(character, spell_attr, character.storyteller.sorcery) if charm_type in ['SHADOWLANDS', 'LABYRINTH', 'VOID']: self.ex2_spells(character, spell_attr, character.storyteller.necromancy) for spell_attr in character.mush.lattr('D`PROTOCOLS`*'): root, charm_name, charm_type = spell_attr.split('`') self.ex2_spells(character, spell_attr, character.storyteller.protocols) languages = character.mush.mushget('D`LANGUAGES') if languages: Language = character.storyteller.languages.custom_type language_list = languages.split('|') for language in language_list: new_lang = Language(name=language) character.advantages.cache_advantages.add(new_lang) character.advantages.save()
enactor = self._parent_operator(session) new_category = self.category_typeclass.create_bbs_category(key=name, abbr=abbr) entities = {'enactor': enactor, 'target': new_category} fmsg.Create(entities).send() return new_category def find_category(self, user, category=None): if not category: raise ValueError("Must enter a category name!") if isinstance(category, AthanorBBSCategory): return category if isinstance(category, BBSCategoryBridge): return category.db_script if not (candidates := self.visible_categories(user)): raise ValueError("No Board Categories visible!") if not (found := partial_match(category, candidates)): raise ValueError(f"Category '{category}' not found!") return found def _rename_category(self, session, category, new, oper, msg): enactor = self._parent_operator(session) category = self.find_category(enactor, category) old_name = category.fullname operation = getattr(category, oper) new_name = operation(new) entities = {'enactor': enactor, 'target': category} msg(entities, old_name=old_name).send() def rename_category(self, session, category=None, new_name=None): return self._rename_category(session, category, new_name, 'rename', fmsg.Rename)
def convert_ex3(self, character): # First, let's convert templates. template = character.mush.getstat('D`INFO', 'Class') or 'Mortal' sub_class = character.mush.getstat('D`INFO', 'Caste') or None attribute_string = character.mush.mushget('D`ATTRIBUTES') or '' skill_string = character.mush.mushget('D`ABILITIES') or '' special_string = character.mush.mushget('D`SPECIALTIES') power = character.mush.getstat('D`INFO', 'POWER') or 1 power_string = 'POWER~%s' % power willpower = character.mush.getstat('D`INFO', 'WILLPOWER') if willpower: willpower_string = 'WILLPOWER~%s' % willpower else: willpower_string = '' stat_string = "|".join([attribute_string, skill_string, willpower_string, power_string]) stat_list = [element for element in stat_string.split('|') if len(element)] stats_dict = dict() for stat in stat_list: name, value = stat.split('~', 1) try: int_value = int(value) except ValueError: int_value = 0 stats_dict[name] = int(int_value) character.setup_storyteller() character.storyteller.swap_template(template) try: character.storyteller.set('Caste', sub_class) except: pass new_stats = character.storyteller.stats.all() custom_dict = {'D`CRAFTS': 'craft', 'D`STYLES': 'style'} for k, v in custom_dict.iteritems(): self.ex3_custom(character, k, v) for special in special_string.split('|'): if not len(special) > 2: continue stat_name, spec_name = special.split('/', 1) spec_name, value = spec_name.split('~', 1) find_stat = partial_match(stat_name, new_stats) if find_stat: find_stat.specialize(dramatic_capitalize(spec_name), value) favored_string = character.mush.mushget('D`FAVORED`ABILITIES') + '|' + character.mush.mushget('D`FAVORED`ATTRIBUTES') supernal_string = character.mush.mushget('D`SUPERNAL`ABILITIES') for k, v in stats_dict.iteritems(): find_stat = partial_match(k, new_stats) if not find_stat: continue find_stat.rating = v find_stat.save() merits_dict = {'D`MERITS`*': 'merit', 'D`FLAWS`*': 'flaw'} for k, v in merits_dict.iteritems(): self.ex3_merits(character, k, v) charms_dict = {'D`CHARMS`SOLAR': 'solar_charm', 'D`CHARMS`LUNAR': 'lunar_charm', 'D`CHARMS`ABYSSAL': 'abyssal_charm'} for k, v in charms_dict.iteritems(): self.ex3_charms(character, k, v) self.ex3_spells(character)
def find_permission(self, perm): if not perm: raise ValueError("No permission entered!") if not (found := partial_match(perm, settings.PERMISSIONS.keys())): raise ValueError("Permission not found!")
def find_alias(self, alias): if isinstance(alias, AbstractChannelSubscription): return alias aliases = self.subscriptions.filter(db_namespace=self.namespace) if not (found := partial_match(alias, aliases)): raise ValueError(f"Channel Alias not found: {alias}!")