def test_gods(): character_name = "sunspire" morgue_parser = MorgueParser(open(f"support/{character_name}.txt").read()) expected = [ "Ashenzari", "Cheibriados", "Dithmenos", "Elyvilon", "Fedhas", "Gozag", "Hepliaklqana", "Kikubaaqudgha", "Makhleb", "Nemelex Xobeh", "Okawaru", "Qazlal", "Ru", "Sif Muna", "Trog", "Uskayaw", "Vehumet", "Wu Jian", "Xom", "Yredelemnul", "Zin", "The Shining One", "Beogh", ] result = morgue_parser.gods() assert result == expected
def save_a_buncha_info(character_name): character = Character(name=character_name) morgue_db = MorgueDB(character_name) morgue_file = character.s3_morgue_file() morgue_parser = MorgueParser(morgue_file) try: runes = morgue_parser.runes() if runes: nice_runes = [rune.strip() for rune in runes.split(",")] morgue_db.save_stuff("SS", "runes", nice_runes) xl_level = fetch_xl_level(morgue_file) if xl_level: morgue_db.save_stuff("S", "xl", xl_level.strip()) weapons = fetch_weapons(morgue_file) if weapons: morgue_db.save_stuff("SS", "weapons", weapons) # gods = fetch_altars(morgue_file) # morgue_db.save_stuff("SS", "gods", gods) armour = fetch_armour(morgue_file) if armour: morgue_db.save_stuff("SS", "armour", armour) except Exception as e: print(f"Error in save_a_buncha_info by we are ok: {e}")
def test_weapons(): character_name = "sunspire" morgue_parser = MorgueParser(open(f"support/{character_name}.txt").read()) expected = [ "a +9 scimitar of holy wrath (weapon)", "the +8 arc blade {discharge, rElec}", "a +7 whip of pain", "a +5 scimitar of pain", ] result = morgue_parser.weapons() assert result == expected
def fetch(self): characters = fetch_characters() for character_name in characters: character = Character(name=character_name) morgue_db = MorgueDB(character_name) morgue_parser = MorgueParser(character.non_saved_morgue_file()) runes = morgue_parser.runes() if runes: nice_runes = [rune.strip() for rune in runes.split(",")] print(f"\033[37mSaving {character_name}'s runes\033[0m") morgue_db.save_stuff("SS", "runes", nice_runes)
def test_jewellery(): character_name = "kilrfish" morgue_parser = MorgueParser(open(f"support/{character_name}.txt").read()) expected = [ "an uncursed ring of resist corrosion", "a +3 ring of strength (left hand)", "a ring of poison resistance (right hand)", "an amulet of regeneration (around neck)", "an uncursed ring of fire", "an uncursed ring of flight", ] result = morgue_parser.jewellery() assert result == expected
def test_potions(): character_name = "sunspire" morgue_parser = MorgueParser(open(f"support/{character_name}.txt").read()) expected = [ " q - 23 potions of mutation", " r - 14 potions of curing", " t - a potion of cancellation", " v - a potion of magic", " z - 5 potions of brilliance", " D - 5 potions of resistance", " J - a potion of berserk rage", " S - 5 potions of haste", " Z - 7 potions of flight", ] result = morgue_parser.potions() assert result == expected
def print_spells(self): morgue_parser = MorgueParser(self.character.morgue_file()) raw_spells = morgue_parser.spells() spells = [spell for spell in raw_spells if (len(spell.split()) >= 5)] formatted_spells = [] for spell in spells: spell_parts = spell.split() spell_parts.reverse() hunger, level, failure, power, spell_type, *spell = spell_parts formatted_spells.append( f"{' '.join(spell)} - {spell_type} - {power} - {failure}") return [ "TakeNRG Listing All Spells TakeNRG", "Spell Type Power Failure", ] + formatted_spells
def __init__(self, morgue_filepath=None, morgue_url=None, name=None, local_mode=None): self.morgue_filepath = morgue_filepath self.morgue_url = morgue_url self.name = name # self.local_mode = True self.local_mode = local_mode self._find_morguefile() self._find_name() self.key = f"{name}/morguefile.txt" self.weapons = fetch_weapons(self.non_saved_morgue_file()) self.morgue_parser = MorgueParser(self.non_saved_morgue_file())
def test_parse_spells(): morgue_file = open("support/kilrfish.txt").read() morgue_parser = MorgueParser(morgue_file) spells = morgue_parser.spells() expected_spells = [ "Animate Skeleton Necr N/A 98% 1 ##.....", "Apportation Tloc #..... 98% 1 ##.....", "Confusing Touch Hex #..... 98% 1 ##.....", "Corona Hex #...... 98% 1 ##.....", "Infusion Chrm #... 98% 1 ##.....", "Shock Conj/Air #... 98% 1 ##.....", "Summon Small Mammal Summ #... 98% 1 ##.....", "Call Imp Summ #....... 99% 2 ###....", "Ensorcelled Hibernation Hex/Ice #..... 99% 2 ###....", "Shroud of Golubria Chrm/Tloc #..... 99% 2 ###....", "Song of Slaying Chrm #....... 99% 2 ###....", "Swiftness Chrm/Air #....... 99% 2 ###....", "Call Canine Familiar Summ #....... 100% 3 ####...", "Confuse Hex #....... 100% 3 ####...", "Dazzling Spray Conj/Hex #..... 100% 3 ####...", "Portal Projectile Hex/Tloc #..... 100% 3 ####...", "Regeneration Chrm/Necr #......... 100% 3 ####...", "Spectral Weapon Hex/Chrm #....... 100% 3 ####...", "Static Discharge Conj/Air #....... 100% 3 ####...", "Summon Guardian Golem Hex/Summ #....... 100% 3 ####...", "Tukima's Dance Hex #....... 100% 3 ####...", "Airstrike Air #......... 100% 4 #####..", "Ice Form Ice/Tmut #....... 100% 4 #####..", "Leda's Liquefaction Hex/Erth #......... 100% 4 #####..", "Summon Ice Beast Ice/Summ #....... 100% 4 #####..", "Summon Lightning Spire Summ/Air #....... 100% 4 #####..", "Lightning Bolt Conj/Air #......... 100% 5 ######.", "Metabolic Englaciation Hex/Ice #......... 100% 5 ######.", "Bolt of Cold Conj/Ice #......... 100% 6 #######", "Freezing Cloud Conj/Ice/Air #......... 100% 6 #######", "Ozocubu's Refrigeration Ice #......... 100% 6 #######", "Simulacrum Ice/Necr #......... 100% 6 #######", ] assert spells == expected_spells
def test_skills(): character_name = "sunspire" morgue_parser = MorgueParser(open(f"support/{character_name}.txt").read()) expected = [ " + Level 17.1 Fighting", " + Level 16.6 Short Blades", " + Level 17.1 Long Blades", " + Level 16.6 Axes", " + Level 16.6 Maces & Flails", " + Level 16.6 Polearms", " + Level 16.6 Staves", " + Level 16.6 Slings", " + Level 16.6 Bows", " + Level 16.6 Crossbows", " + Level 16.8 Throwing", " + Level 16.8 Armour", " + Level 17.1 Dodging", " + Level 16.6 Stealth", " + Level 16.6 Shields", " + Level 16.6 Unarmed Combat", " + Level 17.2 Spellcasting", " + Level 14.3 Conjurations", " + Level 14.3 Hexes", " + Level 14.3 Charms", " + Level 14.3 Summonings", " + Level 14.3 Necromancy", " + Level 15.1 Translocations", " + Level 14.3 Transmutations", " + Level 14.3 Fire Magic", " + Level 14.3 Ice Magic", " + Level 14.3 Air Magic", " + Level 14.3 Earth Magic", " + Level 14.3 Poison Magic", " + Level 17.9 Invocations", " + Level 16.6 Evocations", ] result = morgue_parser.skills() assert result == expected
class Character: def __init__(self, morgue_filepath=None, morgue_url=None, name=None, local_mode=None): self.morgue_filepath = morgue_filepath self.morgue_url = morgue_url self.name = name # self.local_mode = True self.local_mode = local_mode self._find_morguefile() self._find_name() self.key = f"{name}/morguefile.txt" self.weapons = fetch_weapons(self.non_saved_morgue_file()) self.morgue_parser = MorgueParser(self.non_saved_morgue_file()) def __str__(self): return self.name def __repr__(self): return f"{super().__repr__()}: {self.name}" # ======================================================================================== def overview(self): morgue_parser = MorgueParser(self.non_saved_morgue_file()) return morgue_parser.overview() def spells(self): return (SpellFactory(spell).new() for spell in self.morgue_parser.spells()) def spells_above(self, level): print(f"Spells Above!: {level}") return [ spell.overview() for spell in self.spells() if spell.level >= float(level) ] # ======================================================================================== def morgue_file(self): if self.local_mode: morgue = open(self.morgue_filepath).read() else: morgue = self.s3_morgue_file() if morgue is None: morgue = self.fetch_online_morgue() return morgue def non_saved_morgue_file(self): if self.local_mode: return open(self.morgue_filepath).read() else: return self.fetch_online_morgue() def s3_morgue_file(self): try: client = boto3.client("s3") response = client.get_object(Bucket=BUCKET, Key=self.key) return response["Body"].read().decode() except Exception as e: print(f"Error fetching morguefile: {BUCKET} {self.key}") return None def fetch_online_morgue(self): response = requests.get(self.morgue_url) if response.status_code == 200: return response.text else: if not os.environ.get("TEST_MODE", False): print( f"\033[031;1mCould not find the Character at {self.morgue_url}\033[0m" ) # ======================================================================================== def _find_morguefile(self): if self.local_mode and self.morgue_filepath is None: self.morgue_filepath = self._find_morgue_filepath() else: self.morgue_url = self._find_morgue_url() def _find_name(self): if self.name: pass if self.local_mode: morgue_path = self.morgue_filepath else: morgue_path = self.morgue_url self.name = morgue_path.split("/")[-1].replace(".txt", "") def _find_morgue_url(self): MORGUE_DOMAIN = "http://crawl.akrasiac.org/rawdata" return f"{MORGUE_DOMAIN}/{self.name}/{self.name}.txt" def _find_morgue_filepath(self): return f"{find_morgue_folder()}/{self.name}.txt" def spellcasting(self): return self.lookup_skill("Spellcasting").level def skills(self): return self.morgue_parser.skills() def lookup_skill(self, desired_skill): try: raw_skill = [ skill for skill in self.skills() if desired_skill in skill ][0] return SkillFactory(raw_skill).new() except Exception as e: return Skill(skill_type=desired_skill, level=0, status=None) def intelligence(self): return self.morgue_parser.intelligence()
def process_event(event): morgue_event = MorgueEvent.from_event(event) if morgue_event.command == "!h?": return print_the_help() # Elif Island msg = None if morgue_event.is_character_command(): print("A single Character Command!") character = Character(name=morgue_event.character) formatter = Formatter(character) if morgue_event.command == "!armour": msg = formatter.print_armour() elif morgue_event.command == "!weapons": msg = formatter.print_weapons() elif morgue_event.command == "!runes": msg = formatter.print_runes() elif morgue_event.command == "!spells": if morgue_event.level_barrier: msg = character.spells_above(morgue_event.level_barrier) else: msg = formatter.print_spells() elif morgue_event.command == "!skills": msg = formatter.print_skills() elif morgue_event.command == "!version": msg = formatter.print_version() elif morgue_event.command == "!jewellery": msg = formatter.print_jewellery() print( f"WE are looking for jewellery and this is what we found {msg}" ) elif morgue_event.command == "!max_damage": msg = formatter.print_max_damage() elif morgue_event.command == "!mutations": msg = formatter.print_mutations() elif morgue_event.command == "!scrolls": msg = formatter.print_scrolls() elif morgue_event.command == "!potions": msg = formatter.print_potions() elif morgue_event.command == "!gods": msg = formatter.print_gods() elif morgue_event.command == "!overview": morgue_parser = MorgueParser(character.non_saved_morgue_file()) msg = morgue_parser.overview() elif morgue_event.command == "!fetch": morgue_saver(character, character.non_saved_morgue_file(), True) elif morgue_event.command == "!fetch_s3_morgue": print(f"We are fetching the S3 Morgue for {character.name}") with open(f"tmp/s3_{character.name}.txt", "w") as f: f.write(character.s3_morgue_file()) elif morgue_event.command == "!save_morgue": save_morgue(character) elif morgue_event.command == "!search": pass # for c in ["!armour", "!weapons", "!jewellery"]: # call_command_with_arg(formatter, c, morgue_event.args[0]) elif morgue_event.is_multi_character_command(): print("A multiple Character Command!") if morgue_event.command == "!stalk_all": characters = fetch_characters() for character in characters: character = Character(name=character) morgue_saver(character, character.non_saved_morgue_file(), True) elif morgue_event.command == "!rune_awards": rune_awards() elif morgue_event.command == "!characters": characters = fetch_characters() msg = ["All The Characters"] + [", ".join(characters)] elif morgue_event.command == "!clean_morgue": print("COMING SOON") # clean_the_morgue() elif morgue_event.command == "!weapon_awards": find_the_max_damage_for_all_characters() else: print("WE DON'T KNOW THAT COMMAND!!!!!!!") if morgue_event.search: print(f"We are searching: {morgue_event.search}") if type(msg) is list: print("Search a List") msg = [item for item in msg if morgue_event.search in item] else: print("Search a strang") if morgue_event.search not in msg: msg = None if msg: send_chat_to_stream(msg) else: print( f"No Message return for command: {morgue_event.command} character: {morgue_event.character}" )
class Formatter: def __init__(self, character=None): self.character = character self.morgue_parser = MorgueParser(self.character.morgue_file()) def construct_message(self, command): print( f"Formatter construct_message {command} for {self.character.name}") if command == "!overview": return self.print_overview() elif command == "!weapons": return self.print_weapons() elif command == "!armour": return self.print_armour() elif command == "!jewellery": return self.print_jewellery() elif command == "!skills": return self.print_skills() elif command == "!mutations": return self.print_mutations() elif command == "!potions": return self.print_potions() elif command == "!runes": return self.print_runes() elif command == "!scrolls": return self.print_scrolls() elif command == "!spells": return self.print_spells() elif command == "!version": return self.print_version() elif command == "!max_damage": return self.print_max_damage() def print_command(self, name, value): fmt_str = f"{name}: {value}" print("\n\033[35m" + fmt_str + "\033[0m") return [fmt_str] def print_gods(self, morgue_file): altars = set(fetch_altars(morgue_file)) gods_remaining = 25 - len(altars) if len(altars) == 25: return ["Kreygasm YOU HAVE SEEN EVERY GOD! Kreygasm"] else: return [ f"MercyWing1 Gods MercyWing2", ", ".join(sorted(altars)), f"You have {gods_remaining} to be found", ] def print_spells(self): morgue_parser = MorgueParser(self.character.morgue_file()) raw_spells = morgue_parser.spells() spells = [spell for spell in raw_spells if (len(spell.split()) >= 5)] formatted_spells = [] for spell in spells: spell_parts = spell.split() spell_parts.reverse() hunger, level, failure, power, spell_type, *spell = spell_parts formatted_spells.append( f"{' '.join(spell)} - {spell_type} - {power} - {failure}") return [ "TakeNRG Listing All Spells TakeNRG", "Spell Type Power Failure", ] + formatted_spells def print_skills(self): skills = fetch_skills(self.character.morgue_file()) formatted_skills = [] for skill in skills: split_skills = skill.split() if len(split_skills) == 3: _, level, *skill = skill.split() else: _, _, level, *skill = skill.split() formatted_skills.append(f"Level {level} {' '.join(skill)}") return ["PowerUpL Listing All Skills PowerUpR"] + formatted_skills # ======================================================================================== def print_version(self): return self.character.morgue_file().split("\n")[0] def print_overview(self): overview = fetch_overview(self.character.morgue_file()) print("\n\033[35m" + str(overview) + "\033[0m") return overview def print_mutations(self): return [f"Squid1 Squid2 Listing All Mutations Squid4" ] + self.print_command( "Mutations", fetch_mutations(self.character.morgue_file())) # ======================================================================================== def find_unique_items(self, items, regex): if items is None: return None uniq_items = [] for item in items: m = re.search(regex, item) if m: # This should check for the amout of groups to know whether it has amounts msg = m.group(1) uniq_items.append(m.group(1)) return uniq_items def print_runes(self): return self.morgue_parser.runes() def print_weapons(self): weapons = fetch_weapons(self.character.morgue_file()) # weapons = self.find_unique_items(raw_weapons, "\w\s-\s(.*)") if weapons: return ["twitchRaid Listing All Weapons twitchRaid"] + weapons else: return ["No Weapons Found!"] def print_armour(self): armour = self.find_unique_items( fetch_armour(self.character.morgue_file()), "\w\s-\s(.*)") if armour: return ["BloodTrail Listing All Armour BloodTrail"] + armour else: return ["No Armour Found!"] # def print_jewellery(self): # jewellery = self.find_unique_items( # fetch_jewellery(self.character.morgue_file()), "\w\s-\s(.*)" # ) # if jewellery: # return ["CoolCat Listing All Jewellery CoolCat"] + jewellery # else: # return ["No Jewellery Found!"] def print_potions(self): potions = fetch_potions(self.character.morgue_file()) formatted_potions = [] for potion in potions: m = re.search(f"\w\s-\s(\d+)\s(.*)", potion) if m: amount = m.group(1) potion_name = m.group(2) msg = f"{amount} {potion_name}" print(msg) formatted_potions.append(msg) return [f"DrinkPurple Listing All Potions DrinkPurple" ] + formatted_potions def print_scrolls(self): scrolls = fetch_scrolls(self.character.morgue_file()) formatted_scrolls = [] for scroll in scrolls: m = re.search(f"\w\s-\s(\d+)\s(.*)", scroll) if m: amount = m.group(1) scroll_name = m.group(2) msg = f"{amount} {scroll_name}" print(msg) formatted_scrolls.append(msg) return ["copyThis Listing All Scrolls copyThis"] + formatted_scrolls # ======================================================================================== def print_max_damage(self): if True: weapons = fetch_weapons(self.character.morgue_file()) return WeaponsFormatter(character=self.character, weapons=weapons).format_max_damages() else: max_damages = {} from morgue_stalker import fetch_characters characters = morgue_stalker.fetch_characters() for character in characters: max_damages[character] = max_damage( Character(name=character).morgue_file()) return max_damages
def __init__(self, character=None): self.character = character self.morgue_parser = MorgueParser(self.character.morgue_file())
class Formatter: def __init__(self, character=None): self.character = character self.morgue_parser = MorgueParser(self.character.morgue_file()) def print_command(self, name, value): fmt_str = f"{name}: {value}" print("\n\033[35m" + fmt_str + "\033[0m") return [fmt_str] def print_gods(self): gods = self.morgue_parser.gods() gods_remaining = 25 - len(gods) if len(gods) == 25: return ["Kreygasm YOU HAVE SEEN EVERY GOD! Kreygasm"] else: return [ f"MercyWing1 Gods MercyWing2", ", ".join(sorted(gods)), f"You have {gods_remaining} to be found", ] def print_spells(self): morgue_parser = MorgueParser(self.character.morgue_file()) raw_spells = morgue_parser.spells() spells = [spell for spell in raw_spells if (len(spell.split()) >= 5)] formatted_spells = [] for spell in spells: spell_parts = spell.split() spell_parts.reverse() hunger, level, failure, power, spell_type, *spell = spell_parts formatted_spells.append( f"{' '.join(spell)} - {spell_type} - {power} - {failure}") return [ "TakeNRG Listing All Spells TakeNRG", "Spell Type Power Failure", ] + formatted_spells def print_skills(self): skills = fetch_skills(self.character.morgue_file()) formatted_skills = [] for skill in skills: split_skills = skill.split() if len(split_skills) == 3: _, level, *skill = skill.split() else: _, _, level, *skill = skill.split() formatted_skills.append(f"Level {level} {' '.join(skill)}") return ["PowerUpL Listing All Skills PowerUpR"] + formatted_skills # ======================================================================================== def print_version(self): return self.character.morgue_file().split("\n")[0] def print_mutations(self): title = [f"Squid1 Squid2 Listing All Mutations Squid4"] return title + [self.morgue_parser.mutations()] # ======================================================================================== def find_unique_items(self, items, regex): if items is None: return None uniq_items = [] for item in items: m = re.search(regex, item) if m: # This should check for the amout of groups to know whether it has amounts msg = m.group(1) uniq_items.append(m.group(1)) return uniq_items def print_runes(self): return self.morgue_parser.runes() def print_weapons(self): weapons = self.morgue_parser.weapons() # weapons = self.find_unique_items(raw_weapons, "\w\s-\s(.*)") if weapons: return ["twitchRaid Listing All Weapons twitchRaid"] + weapons else: return ["No Weapons Found!"] def print_armour(self): armour = self.morgue_parser.armour() if armour: return ["BloodTrail Listing All Armour BloodTrail"] + armour else: return ["No Armour Found!"] def print_jewellery(self): jewellery = self.morgue_parser.jewellery() if jewellery: return ["CoolCat Listing All Jewellery CoolCat"] + jewellery else: return ["No Jewellery Found!"] def print_potions(self): potions = self.morgue_parser.potions() formatted_potions = [] for potion in potions: m = re.search(f"\w\s-\s(\d+)\s(.*)", potion) if m: amount = m.group(1) potion_name = m.group(2) msg = f"{amount} {potion_name}" print(msg) formatted_potions.append(msg) return [f"DrinkPurple Listing All Potions DrinkPurple" ] + formatted_potions def print_scrolls(self): scrolls = self.morgue_parser.scrolls() formatted_scrolls = [] for scroll in scrolls: m = re.search(f"\w\s-\s(\d+)\s(.*)", scroll) if m: amount = m.group(1) scroll_name = m.group(2) msg = f"{amount} {scroll_name}" print(msg) formatted_scrolls.append(msg) return ["copyThis Listing All Scrolls copyThis"] + formatted_scrolls # ======================================================================================== def print_max_damage(self): weapons = self.morgue_parser.weapons() return WeaponsFormatter(character=self.character, weapons=weapons).format_max_damages()
def test_scrolls(): character_name = "GucciMane" morgue_parser = MorgueParser(open(f"support/{character_name}.txt").read()) expected = [" b - a scroll labeled BUCEUFOSTE"] result = morgue_parser.scrolls() assert result == expected
def test_mutations(): character_name = "kilrfish" morgue_parser = MorgueParser(open(f"support/{character_name}.txt").read()) expected = "retaliatory headbutt, horns 2" result = morgue_parser.mutations() assert result == expected
def test_fetch_armour(): character_name = "kaostheory" morgue_parser = MorgueParser(open(f"support/{character_name}.txt").read()) expected_armour = [" g - a +0 pair of boots (worn)", " h - a +0 ring mail (worn)"] armour = morgue_parser.armour() assert armour == expected_armour
def test_overview(): morgue_file = open("support/Fa.txt").read() morgue_parser = MorgueParser(morgue_file) overview = morgue_parser.overview() expected_overview = "Fa the Merry Centaur (Centaur Hunter) XL: 27 Health: 243/243 Location: Pandemonium." assert overview == expected_overview
def overview(self): morgue_parser = MorgueParser(self.non_saved_morgue_file()) return morgue_parser.overview()
def test_runes(character_name, expected_runes): morgue_parser = MorgueParser(open(f"support/{character_name}.txt").read()) runes = morgue_parser.runes() assert runes == expected_runes