def create_new(self, user, name, guild, parent_id, category, archived, npc=False): self.user = user self.name = name self.guild = guild self.npc = npc self.category = category if category == 'Character' and not npc: self.refresh = 3 self.fate_points = 3 self.stress = STRESS self.stress_titles = STRESS_TITLES self.consequences = CONSEQUENCES self.consequences_titles = CONSEQUENCES_TITLES if parent_id: self.parent_id = parent_id self.created_by = str(user.id) self.created = T.now() self.updated_by = str(user.id) self.updated = T.now() self.save() return self
def create_new(self, name, text): self.name = name self.text = text self.created = T.now() self.updated = T.now() self.save() return self
def create_new(self, name, guild, user): self.name = name self.guild = guild self.created_by = str(user.id) self.created = T.now() self.updated_by = str(user.id) self.updated = T.now() self.save() return self
def create_new(self, user, guild, channel_id, name, archived): self.name = name self.guild = guild self.channel_id = channel_id self.created_by = str(user.id) self.created = T.now() self.updated_by = str(user.id) self.updated = T.now() self.save() return self
def create_new(self, name, guild, discriminator=None, display_name=None): self.guild = guild self.name = name if discriminator: self.discriminator = discriminator if display_name: self.display_name = display_name self.created = T.now() self.updated = T.now() self.save() return self
def create_new(self, parent_id, name, user_id, guild, category, data, action): self.parent_id = parent_id self.user_id = user_id self.guild = guild self.name = name self.category = category self.data = data self.action = action self.created_by = str(user_id) self.created = T.now() self.updated_by = str(user_id) self.updated = T.now() self.save() return self
def reverse_archive(self, user): for s in Session().get_by_parent(parent_id=str(self.id)): s.reverse_archive(self.user) s.archived = True s.updated_by = str(user.id) s.updated = T.now() s.save()
def character(self, args): """Edit the Session as a character Parameters ---------- args : list(str) List of strings with subcommands Returns ------- list(str) - the response messages string array """ self.check_session() if self.user: self.user.active_character = str(self.session.character.id) self.channel.updated_by = str(self.user.id) self.user.updated = T.now() self.user.save() command = CharacterCommand(parent=self.parent, ctx=self.ctx, args=args, guild=self.guild, user=self.user, channel=self.channel, char=self.session.character) return command.run()
def description(self, args): """Add/edit the description for a Session Parameters ---------- args : list(str) List of strings with subcommands Returns ------- list(str) - the response messages string array """ if len(args) == 1: raise Exception('No description provided') self.check_session() description = ' '.join(args[1:]) self.session.description = description self.session.updated_by = str(self.user.id) self.session.updated = T.now() self.session.save() return [ f'Description updated to "{description}"', self.session.get_string(self.channel) ]
def delete_scene(self, args, guild, channel, scenario, sc, user): messages = [] search = '' if len(args) == 1: if not sc: raise Exception('No scene provided for deletion') else: search = ' '.join(args[1:]) sc = Scene().find(guild.name, str(channel.id), str(scenario.id), search) if not sc: return [f'{search} was not found. No changes made.'] else: search = str(sc.name) scenario_id = str(sc.scenario_id) if sc.scenario_id else '' channel_id = str(sc.channel_id) if sc.channel_id else '' sc.character.archive(user) sc.archived = True sc.updated_by = str(user.id) sc.updated = T.now() sc.save() messages.append(f'***{search}*** removed') if scenario_id: secenario = Scenario().get_by_id(scenario_id) messages.append(secenario.get_string(channel)) elif channel_id: channel = Channel().get_by_id(channel_id) messages.append(channel.get_string()) return messages
def reverse_archive(self, user): for z in Exchange().get_by_parent(parent_id=str(self.id)): z.reverse_archive(user) z.archived = True z.updated_by = str(user.id) z.updated = T.now() z.save()
def reverse_restore(self, user): for z in Zone().get_by_parent(parent_id=str(self.id)): z.reverse_restore(user) z.archived = False z.updated_by = str(user.id) z.updated = T.now() z.save()
def reverse_archive(self, user): for c in Character().get_by_parent(self): c.reverse_archive(self.user) c.archived = True c.updated_by = str(user.id) c.updated = T.now() c.save()
def reverse_restore(self, user): for s in Scene().get_by_parent(parent_id=str(self.id)): s.reverse_restore(user) s.archived = False s.updated_by = str(user.id) s.updated = T.now() s.save()
def reverse_restore(self, user): for c in Character().get_by_parent(parent=self, archived=True): c.reverse_restore(self.user) c.archived = False c.updated_by = str(user.id) c.updated = T.now() c.save()
def get_answer(self): """ Check for an answer if a dialog has been recorded in the user's record A dialog records the original command, the question string, and the answer. The command will track the previous command that started the dialog. The question will store the current state of the dialog. The answer is stored for processing by the command handler. """ guild = self.ctx.guild if self.ctx.guild else self.ctx.author self.user = User().find(self.ctx.author.name, guild.name) if self.user and self.user.command: answer = ' '.join(self.args[0:]) self.args = tuple(self.user.command.split(' ')) if len(self.args) and self.args[0].lower() == 'new': self.new = True self.args = self.args[1:] if len(self.args) and self.args[0].lower() == 'delete': self.delete = True self.args = self.args[1:] self.command = self.args[0].lower() self.user.answer = answer self.user.updated_by = str(self.user.id) self.user.updated = T.now() self.user.save()
def description(self, args): """Add/edit the description for an Engagement Parameters ---------- args : list(str) List of strings with subcommands Returns ------- list(str) - the response messages string array """ if len(args) == 1: return ['No description provided'] if not self.engagement: return ['You don\'t have an active engagement.\nTry this: ".d s name {name}"'] else: description = ' '.join(args[1:]) self.engagement.description = description self.engagement.updated_by = str(self.user.id) self.engagement.updated = T.now() self.engagement.save() return [ f'Description updated to "{description}"', self.engagement.get_string(self.channel) ]
def end(self, args): """Add an end time to the Engagement Parameters ---------- args : list(str) List of strings with subcommands Returns ------- list(str) - the response messages string array """ self.check_engagement() if len(args) > 1 and args[1] == 'delete': self.engagement.ended_on = None engagement_svc.save(self.engagement, self.user) return [self.dialog('')] else: if not self.engagement.started_on: raise Exception(f'***{self.engagement.name}*** has not yet started.') if self.engagement.ended_on: raise Exception(f'***{self.engagement.name}*** already ended on {T.to(self.engagement.ended_on, self.user)}') else: self.engagement.ended_on = T.now() engagement_svc.save(self.engagement, self.user) return [self.dialog('')]
def url(self): """Set/edit the user's contact information""" if len(self.args) < 2: return [f'No contact info provided.```css\n.d u contact "CONTACT INFO"```'] self.user.url = ' '.join(self.args[1:]) self.user.updated_by = str(self.user.id) self.user.updated = T.now() self.user.save() return [self.user.get_string()]
def get_or_create(self, user, guild, channel, name, archived=False): scenario = self.find(guild, str(channel.id), name, archived) if scenario is None: scenario = self.create_new(user, guild, str(channel.id), name, archived) scenario.character = Character().get_or_create( user, name, guild, scenario, 'Scenario', archived) scenario.updated_by = str(user.id) scenario.updated = T.now() scenario.save() return scenario
def loss_dc(output, label): """ adopted from nussl loss function: https://github.com/interactiveaudiolab/nussl/blob/master/nussl/transformers/transformer_deep_clustering.py inputs: output: a tuple containing a batch_size X T X F X embedding_dim tensor label: a tuple containing a batch_size X T X F X num_speaker tensor outputs: loss of deep clustering model/layer """ assert len(output)==1, "Number of output must be 1 for Deep Clustering" assert len(label)==1, "Number of label must be 1 for Deep Clustering" embedding = output[0] label = label[0].float() batch_size, time_size, frequency_size,one_hot_dim = label.size() _, _, _, embedding_dim = embedding.size() embedding = embedding.view(-1, embedding_dim) label = label.view(-1, one_hot_dim) # remove the loss of silence TF regions silence_mask = torch.sum(label, dim=-1, keepdim=True) embedding = silence_mask * embedding # referred as weight VA class_weights = F.normalize(torch.sum(label, dim=-2), p=1, dim=-1).unsqueeze(0) class_weights = 1.0 / (torch.sqrt(class_weights) + 1e-7) weights = torch.mm(label, class_weights.transpose(1, 0)) label = label * weights.repeat(1, label.size()[-1]) embedding = embedding * weights.repeat(1, embedding.size()[-1]) # do batch affinity matrix computation embedding = embedding.view(batch_size,-1,embedding_dim) label = label.view(batch_size,-1,one_hot_dim) loss_est = norm(torch.bmm(T(embedding), embedding)) loss_est_true = 2*norm(torch.bmm(T(embedding), label)) loss_true = norm(torch.bmm(T(label), label)) loss_embedding = loss_est - loss_est_true + loss_true return loss_embedding
def loss_dc(output, label): """ adopted from nussl loss function: https://github.com/interactiveaudiolab/nussl/blob/master/nussl/transformers/transformer_deep_clustering.py inputs: output: a tuple containing a batch_size X T X F X embedding_dim tensor label: a tuple containing a batch_size X T X F X num_speaker tensor outputs: loss of deep clustering model/layer """ assert len(output) == 1, "Number of output must be 1 for Deep Clustering" assert len(label) == 2, "Number of label must be 2 for Deep Clustering" embedding, = output label, mag_mix = label label = label.float() batch_size, frame_dim, frequency_dim, one_hot_dim = label.size() _, _, _, embedding_dim = embedding.size() embedding = embedding.view(batch_size, -1, embedding_dim) mag_mix = mag_mix.detach().view(batch_size, -1) label = label.view(batch_size, -1, one_hot_dim) # remove the loss of silence TF regions silence_mask = label.sum(2, keepdim=True) embedding = silence_mask * embedding # referred as weight WR # W_i = |x_i| / \sigma_j{|x_j|} weights = torch.sqrt(mag_mix / mag_mix.sum(1, keepdim=True)) label = label * weights.view(batch_size, frame_dim * frequency_dim, 1) embedding = embedding * weights.view(batch_size, frame_dim * frequency_dim, 1) # do batch affinity matrix computation loss_est = norm(torch.bmm(T(embedding), embedding)) loss_est_true = 2 * norm(torch.bmm(T(embedding), label)) loss_true = norm(torch.bmm(T(label), label)) loss_embedding = loss_est - loss_est_true + loss_true return loss_embedding
def save_user(self, user): """Save a User Document Parameters ---------- user : User The User mongoengine Document for saving """ if user: user.updated_by = str(user.id) user.updated = T.now() user.save()
def get_or_create(self, name, guild, discriminator=None, display_name=None): user = self.find(name, guild) if user is None: user = self.create_new(name, guild, discriminator, display_name) elif discriminator and not user.discriminator: user.discriminator = discriminator user.display_name = display_name user.updated = T.now() user.save() return user
def save(self, item, user): """Save an item Parameters ---------- item : mongoengine.Document The item to save user : User The user to save as the updated_by """ if item: item.updated_by = str(user.id) item.updated = T.now() item.history_id = '' item.save()
def time_zone(self): """Set/edit the user's timezone information""" tz_help = 'Try this:```css\n.d u timezone "ZONE SEARCH"\n/* "ZONE SEARCH" must be at least 3 characters */```' tz_search = ''.join([ 'Try one of these searches:```css\n', '.d u tz US/\n', '.d u tz America\n', '.d u tz Canada\n', '.d u tz Europe\n', '.d u tz Asia\n', '.d u tz Atlantic\n', '.d u tz Pacific\n', '.d u tz Indian\n', '.d u tz Africa\n', '.d u tz Australia\n', '.d u tz Antarctica\n', '```' ]) if len(self.args) == 0: if not self.user: return ['No active user or name provided'] if len(self.args) < 2: return [f'No time zone provided. {tz_help}',tz_search] if self.args[1] in ['list', 'l']: if len(self.args) <3: return [f'No time zone search term provided. {tz_help}', tz_search] if len(self.args[2]) <3: return ['No time zone search term must be at least 3 characters```css\n/* EXAMPLES */\n.d u tz New_York\n.d u timezone London```'] search = self.args[2].lower() tz = [tz for tz in pytz.all_timezones if search in tz.lower()] if len(tz) == 0: return [f'Time zone \'{search}\' not found', tz_search] return ['\n'.join(tz)] else: search = self.args[1].lower() tz = [tz for tz in pytz.all_timezones if search in tz.lower()] if len(tz) == 0: return [f'Time zone \'{search}\' not found', tz_search] if len(tz) > 1: timezones = '\n'.join([f'.d u tz {t}' for t in tz]) return [f'Time zone search \'{search}\' returned more than one. Try one of these:```css\n{timezones}```'] self.user.time_zone = tz[0] self.user.updated_by = str(self.user.id) self.user.updated = T.now() self.user.save() return [f'Saved time zone as ***{tz[0]}***\n\n{self.user.get_string()}']
def start(self, args): """Add a start time to the Engagement Parameters ---------- args : list(str) List of strings with subcommands Returns ------- list(str) - the response messages string array """ self.check_engagement() if self.engagement.started_on: raise Exception(f'***{self.engagement.name}*** already began on {T.to(self.engagement.started_on, self.user)}') else: self.engagement.started_on = T.now() engagement_svc.save(self.engagement, self.user) return [self.dialog('')]
def __init__(self, parent, ctx, args, guild, user, channel): """ Command handler for channel command Parameters ---------- parent : DreamcraftHandler The handler for Dreamcraft Bot commands and subcommands ctx : object(Context) The Discord.Context object used to retrieve and send information to Discord users args : array(str) The arguments sent to the bot to parse and evaluate guild : Guild The guild object containing information about the server issuing commands user : User The user database object containing information about the user's current setttings, and dialogs channel : Channel The channel from which commands were issued Returns ------- ChannelCommand - object for processing channel subcommands """ self.parent = parent self.new = parent.new self.delete = parent.delete self.ctx = ctx self.args = args[1:] self.command = self.args[0].lower() if len(self.args) > 0 else 'chan' self.guild = guild self.user = user self.channel = channel if self.user.name not in self.channel.users: self.channel.users.append(self.user.name) self.channel.updated_by = str(self.user.id) self.channel.updated = T.now() self.channel.save() self.char = Character().get_by_id(self.user.active_character) if self.user and self.user.active_character else None
def setup(self, ctx, args): """ Setup the Dreamcraft Handler with new args Parameters ---------- args : array(str) The arguments sent to the bot to parse and evaluate """ self.new = False if len(args) and args[0].lower() == 'new': self.new = True args = args[1:] if len(args) > 1 else args self.delete = False if len(args) and args[0].lower() == 'delete': self.delete = True args = args[1:] if len(args) > 1 else args self.args = args self.guild = ctx.guild if ctx.guild else ctx.author self.user = User().get_or_create(ctx.author.name, self.guild.name, ctx.author.discriminator, ctx.author.display_name) # The 'channel' variable can either be the name of the channel on a server or 'private' if Direct Message channel = 'private' if ctx.channel.type.name == 'private' else ctx.channel.name self.channel = Channel().get_or_create(channel, self.guild.name, self.user) # Add the user to the list of channel users if str(self.user.name) not in self.channel.users: self.channel.users.append(str(self.user.name)) self.channel.updated_by = str(self.user.id) self.channel.updated = T.now() self.channel.save() self.char = Character().get_by_id(self.user.active_character) if self.user and self.user.active_character else None self.module = self.char.category if self.char else None self.command = self.args[0].lower() self.alias_commands = [] self.func = None self.messages = [] self.image = ''
def alias(self): """Set/edit the user's alias commands""" if len(self.args) < 3: return [f'No alias command provided.```css\n.d alias ALIAS "ORIGINAL COMMAND 1" [... "ORIGINAL COMMAND 2"]```'] aliases = {} if self.args[1] in ['delete','d']: alias = self.args[2] if self.user.aliases and alias in self.user.aliases: for a in self.user.aliases: if a != alias: aliases[a] = self.user.aliases[a] else: alias = self.args[1] if alias in RESERVED: raise Exception(f'_{alias}_ is a reserved command or subcommand') commands = self.args[2:] aliases = self.user.aliases if self.user.aliases else {} aliases[alias] = commands self.user.aliases = aliases self.user.updated_by = str(self.user.id) self.user.updated = T.now() self.user.save() return [self.user.get_string()]