def migrate(bestiary): sha256 = hashlib.sha256() hash_str = json.dumps(bestiary['monsters']).encode() \ + bestiary['name'].encode() \ + str(bestiary.get('desc')).encode() sha256.update(hash_str) active = [bestiary['owner']] if bestiary.get('active') else [] server_active = [] for serv_sub in bestiary.get('server_active', []): server_active.append({ "subscriber_id": bestiary['owner'], "guild_id": serv_sub }) for monster in bestiary['monsters']: for key in ('traits', 'actions', 'reactions', 'legactions'): for trait in monster[key]: if 'attacks' in trait: del trait[ 'attacks'] # why did we store this in the first place? monsters = [Monster.from_bestiary(m) for m in bestiary['monsters']] new_bestiary = Bestiary(None, sha256.hexdigest(), bestiary['critterdb_id'], [bestiary['owner']], active, server_active, bestiary['name'], monsters, bestiary.get('desc')) return new_bestiary
async def select_monster_full(ctx, name, cutoff=5, return_key=False, pm=False, message=None, list_filter=None, return_metadata=False): """ Gets a Monster from the compendium and active bestiary/ies. """ try: bestiary = await Bestiary.from_ctx(ctx) custom_monsters = bestiary.monsters bestiary_id = bestiary.id except NoActiveBrew: custom_monsters = [] bestiary_id = None choices = list(itertools.chain(c.monster_mash, custom_monsters)) if ctx.guild: async for servbestiary in ctx.bot.mdb.bestiaries.find({"server_active": str(ctx.guild.id)}, ['monsters']): choices.extend( Monster.from_bestiary(m) for m in servbestiary['monsters'] if servbestiary['_id'] != bestiary_id) def get_homebrew_formatted_name(monster): if monster.source == 'homebrew': return f"{monster.name} ({HOMEBREW_EMOJI})" return monster.name return await search_and_select(ctx, choices, name, lambda e: e.name, cutoff, return_key, pm, message, list_filter, selectkey=get_homebrew_formatted_name, return_metadata=return_metadata)
async def load_monsters(self, ctx): if not self._monsters: bestiary = await ctx.bot.mdb.bestiaries.find_one( {"_id": self.id}, projection=['monsters']) self._monsters = [ Monster.from_bestiary(m) for m in bestiary['monsters'] ] return self._monsters
def migrate_monster(old_monster): def spaced_to_camel(spaced): return re.sub(r"\s+(\w)", lambda m: m.group(1).upper(), spaced.lower()) for old_key in ('raw_saves', 'raw_skills'): if old_key in old_monster: del old_monster[old_key] if 'spellcasting' in old_monster and old_monster['spellcasting']: old_spellcasting = old_monster.pop('spellcasting') old_monster['spellbook'] = Spellbook( {}, {}, [SpellbookSpell(s) for s in old_spellcasting['spells']], old_spellcasting['dc'], old_spellcasting['attackBonus'], old_spellcasting['casterLevel']).to_dict() else: old_monster['spellbook'] = Spellbook({}, {}, []).to_dict() base_stats = BaseStats(0, old_monster.pop('strength'), old_monster.pop('dexterity'), old_monster.pop('constitution'), old_monster.pop('intelligence'), old_monster.pop('wisdom'), old_monster.pop('charisma')) old_monster['ability_scores'] = base_stats.to_dict() old_saves = old_monster.pop('saves') saves = Saves.default(base_stats) save_updates = {} for save, value in old_saves.items(): if value != saves[save]: save_updates[save] = value saves.update(save_updates) old_monster['saves'] = saves.to_dict() old_skills = old_monster.pop('skills') skills = Skills.default(base_stats) skill_updates = {} for skill, value in old_skills.items(): name = spaced_to_camel(skill) if value != skills[name]: skill_updates[name] = value skills.update(skill_updates) old_monster['skills'] = skills.to_dict() new_monster = Monster.from_bestiary(old_monster) return new_monster
def from_dict(cls, d): if 'monsters' in d: d['monsters'] = [Monster.from_bestiary(m) for m in d['monsters']] if 'published' not in d: # versions prior to v1.5.11 don't have this tag, default to True d['published'] = True return cls(**d)
def from_raw(cls, _id, raw): monsters = [Monster.from_bestiary(m) for m in raw['monsters']] return cls(_id, raw['name'], monsters)
def from_dict(cls, d): if 'monsters' in d: d['monsters'] = [Monster.from_bestiary(m) for m in d['monsters']] return cls(**d)