def label_for_channel(self, channel): labels = [] for label, channels in self.channels.items(): if channel in channels: labels.append(label) if not labels: raise immp.ConfigError("Channel {} not bridged".format(repr(channel))) elif len(labels) > 1: raise immp.ConfigError("Channel {} defined more than once".format(repr(channel))) else: return labels[0]
async def commands(self, channel, user): """ Retrieve all commands, and filter against the mappings. Args: channel (.Channel): Source channel where the command will be executed. user (.User): Author of the message to trigger the command. Returns: (str, .BoundCommand) dict: Commands provided by all hooks, in this channel for this user, keyed by name. """ log.debug("Collecting commands for %r in %r", channel, user) if isinstance(channel, immp.Plug): # Look for commands for a generic channel. plug = channel channel = immp.Channel(plug, "") private = False else: plug = None private = await channel.is_private() mappings = [] for mapping in self.config["mapping"].values(): for label in mapping["groups"]: group = self.host.groups[label] if plug and group.has_plug(plug, "anywhere", "named"): mappings.append(mapping) elif not plug and await group.has_channel(channel): mappings.append(mapping) cmds = set() for mapping in mappings: cmds.update(self._mapping_cmds(mapping, channel, user, private)) mapped = {cmd.name: cmd for cmd in cmds} if len(cmds) > len(mapped): # Mapping by name silently overwrote at least one command with a duplicate name. raise immp.ConfigError( "Multiple applicable commands with the same name") return mapped
async def commands(self, channel, user): """ Retrieve all commands, and filter against the mappings. Args: channel (.Channel): Source channel where the command will be executed. user (.User): Author of the message to trigger the command. Returns: (str, .BoundCommand) dict: Commands provided by all hooks, in this channel for this user, keyed by name. """ log.debug("Collecting commands for %r in %r", user, channel) if isinstance(channel, immp.Plug): # Look for commands for a generic channel. plug = channel channel = immp.Channel(plug, "") private = False else: plug = None private = await channel.is_private() mappings = [] identities = {} for label, mapping in self.config["mapping"].items(): providers = mapping["identify"] if providers: for name, roles in providers.items(): if name not in identities: try: provider = self.host.hooks[name] identities[ name] = await provider.identity_from_user(user) except Exception: log.exception( "Exception retrieving identity from %r for map %r", name, label) identities[name] = None continue if not identities[name]: continue elif not roles or set(roles).intersection( identities[name].roles): log.debug("Identified %r as %r for map %r", user, identities[name], label) break else: log.debug("Could not identify %r for map %r, skipping", user, label) continue for name in mapping["groups"]: group = self.host.groups[name] if plug and group.has_plug(plug, "anywhere", "named"): mappings.append(mapping) elif not plug and await group.has_channel(channel): mappings.append(mapping) cmds = set() for mapping in mappings: cmds.update(self._mapping_cmds(mapping, channel, user, private)) mapped = {cmd.name: cmd for cmd in cmds} if len(cmds) > len(mapped): # Mapping by name silently overwrote at least one command with a duplicate name. raise immp.ConfigError( "Multiple applicable commands with the same name") return mapped
def _channels(self): try: return {self.host.channels[key]: tuple(self.host.channels[label] for label in value) for key, value in self.config["channels"].items()} except KeyError as e: raise immp.ConfigError("No such channel '{}'".format(repr(e.args[0])))
def channels(self): try: return {virtual: [self.host.channels[label] for label in labels] for virtual, labels in self.config["channels"].items()} except KeyError as e: raise immp.ConfigError("No channel {} on host".format(repr(e.args[0]))) from None