def populate_monster_properties_from_wiki_data(self): """Populate item data from a OSRS Wiki Infobox Item template.""" logging.debug("populate_monster_properties_from_wiki_data: Populating wiki data...") # STAGE ONE: Determine then set the wiki_name and wiki_url # Manually set OSRS Wiki name if self.wikitext_found_using not in ["id"]: # Monster found in wiki by ID, cache name is the best option wiki_page_name = self.monster_name else: # Monster found using direct cache name lookup on wiki page names, # So use wiki page name in the monster_wikitext array wiki_page_name = self.monster_wikitext[0] wiki_versioned_name = None wiki_name = None # Get the versioned, or non-versioned, name from the infobox if self.infobox_version_number is not None: key = "version" + str(self.infobox_version_number) wiki_versioned_name = self.extract_infobox_value(self.template, key) else: wiki_versioned_name = self.extract_infobox_value(self.template, "version") # Set the wiki_name property if wiki_versioned_name is not None: if wiki_versioned_name.startswith("("): wiki_name = wiki_page_name + " " + wiki_versioned_name else: wiki_name = wiki_page_name + " (" + wiki_versioned_name + ")" else: wiki_name = wiki_page_name self.monster_dict["wiki_name"] = wiki_name # Set the wiki_url property if wiki_versioned_name is not None: wiki_url = wiki_page_name + "#" + wiki_versioned_name else: wiki_url = wiki_page_name wiki_url = wiki_url.replace(" ", "_") self.monster_dict["wiki_url"] = "https://oldschool.runescape.wiki/w/" + wiki_url # STAGE TWO: Extract, process and set monster properties from the infobox template # MEMBERS: Determine the members status of a monster members = None if self.infobox_version_number is not None: key = "members" + str(self.infobox_version_number) members = self.extract_infobox_value(self.template, key) if members is None: members = self.extract_infobox_value(self.template, "members") if members is not None: self.monster_dict["members"] = infobox_cleaner.clean_boolean(members) else: self.monster_dict["members"] = False # RELEASE_DATE: Determine the release date of a monster release_date = None if self.infobox_version_number is not None: key = "release" + str(self.infobox_version_number) release_date = self.extract_infobox_value(self.template, key) if release_date is None: release_date = self.extract_infobox_value(self.template, "release") if release_date is not None: self.monster_dict["release_date"] = infobox_cleaner.clean_release_date(release_date) else: self.monster_dict["release_date"] = None self.monster_dict["incomplete"] = True # HITPOINTS: Determine the hitpoints of a monster hitpoints = None if self.infobox_version_number is not None: key = "hitpoints" + str(self.infobox_version_number) hitpoints = self.extract_infobox_value(self.template, key) if hitpoints is None: hitpoints = self.extract_infobox_value(self.template, "hitpoints") if hitpoints is not None: self.monster_dict["hitpoints"] = infobox_cleaner.clean_integer(hitpoints) else: self.monster_dict["hitpoints"] = 0 self.monster_dict["incomplete"] = True # MAX HIT: Determine the max hit of a monster max_hit = None if self.infobox_version_number is not None: key = "max hit" + str(self.infobox_version_number) max_hit = self.extract_infobox_value(self.template, key) if max_hit is None: max_hit = self.extract_infobox_value(self.template, "max hit") if max_hit is not None: self.monster_dict["max_hit"] = infobox_cleaner.clean_integer(max_hit) else: self.monster_dict["max_hit"] = 0 self.monster_dict["incomplete"] = True # ATTACK TYPE: Determine the attack type of a monster attack_type = None if self.infobox_version_number is not None: key = "attack style" + str(self.infobox_version_number) attack_type = self.extract_infobox_value(self.template, key) if attack_type is None: attack_type = self.extract_infobox_value(self.template, "attack style") if attack_type is not None: self.monster_dict["attack_type"] = infobox_cleaner.clean_attack_type(attack_type) else: self.monster_dict["attack_type"] = list() self.monster_dict["incomplete"] = True # ATTACK SPEED: Determine the attack speed of a monster attack_speed = None if self.infobox_version_number is not None: key = "attack speed" + str(self.infobox_version_number) attack_speed = self.extract_infobox_value(self.template, key) if attack_speed is None: attack_speed = self.extract_infobox_value(self.template, "attack speed") if attack_speed is not None: self.monster_dict["attack_speed"] = infobox_cleaner.clean_integer(attack_speed) else: self.monster_dict["attack_speed"] = None self.monster_dict["incomplete"] = True # AGGRESSIVE: Determine the aggressive property of a monster aggressive = None if self.infobox_version_number is not None: key = "aggressive" + str(self.infobox_version_number) aggressive = self.extract_infobox_value(self.template, key) if aggressive is None: aggressive = self.extract_infobox_value(self.template, "aggressive") if aggressive is not None: self.monster_dict["aggressive"] = infobox_cleaner.clean_boolean(aggressive) else: self.monster_dict["aggressive"] = False self.monster_dict["incomplete"] = True # POISONOUS: Determine the poisonous property of a monster poisonous = None if self.infobox_version_number is not None: key = "poisonous" + str(self.infobox_version_number) poisonous = self.extract_infobox_value(self.template, key) if poisonous is None: poisonous = self.extract_infobox_value(self.template, "poisonous") if poisonous is not None: self.monster_dict["poisonous"] = infobox_cleaner.clean_boolean(poisonous) else: self.monster_dict["poisonous"] = False self.monster_dict["incomplete"] = True # IMMUNE POISON: Determine the immunity to poison property of a monster immune_poison = None if self.infobox_version_number is not None: key = "immunepoison" + str(self.infobox_version_number) immune_poison = self.extract_infobox_value(self.template, key) if immune_poison is None: immune_poison = self.extract_infobox_value(self.template, "immunepoison") if immune_poison is not None: self.monster_dict["immune_poison"] = infobox_cleaner.clean_boolean(immune_poison) else: self.monster_dict["immune_poison"] = False self.monster_dict["incomplete"] = True # IMMUNE VENOM: Determine the immunity to venom property of a monster immune_venom = None if self.infobox_version_number is not None: key = "immunevenom" + str(self.infobox_version_number) immune_venom = self.extract_infobox_value(self.template, key) if immune_venom is None: immune_venom = self.extract_infobox_value(self.template, "immunevenom") if immune_venom is not None: self.monster_dict["immune_venom"] = infobox_cleaner.clean_boolean(immune_venom) else: self.monster_dict["immune_venom"] = False self.monster_dict["incomplete"] = True # WEAKNESS: Determine any weaknesses of the monster weakness = None if self.infobox_version_number is not None: key = "weakness" + str(self.infobox_version_number) weakness = self.extract_infobox_value(self.template, key) if weakness is None: weakness = self.extract_infobox_value(self.template, "weakness") if weakness is not None: weakness = infobox_cleaner.clean_weaknesses(weakness) self.monster_dict["weakness"] = weakness else: self.monster_dict["weakness"] = list() self.monster_dict["incomplete"] = True # CATEGORY: Determine category of the monster category = None if self.infobox_version_number is not None: key = "cat" + str(self.infobox_version_number) category = self.extract_infobox_value(self.template, key) if category is None: category = self.extract_infobox_value(self.template, "cat") if category is not None: category = infobox_cleaner.clean_category(category) self.monster_dict["category"] = category else: self.monster_dict["category"] = list() self.monster_dict["incomplete"] = True # SLAYER LEVEL: Determine the slayer level required slayer_level = None if self.infobox_version_number is not None: key = "slaylvl" + str(self.infobox_version_number) slayer_level = self.extract_infobox_value(self.template, key) if slayer_level is None: slayer_level = self.extract_infobox_value(self.template, "slaylvl") if slayer_level is not None: self.monster_dict["slayer_level"] = infobox_cleaner.clean_integer(slayer_level) else: self.monster_dict["slayer_level"] = None self.monster_dict["incomplete"] = True # SLAYER XP: Determine XP given from slayer monster kill slayer_xp = None if self.infobox_version_number is not None: key = "slayxp" + str(self.infobox_version_number) slayer_xp = self.extract_infobox_value(self.template, key) if slayer_xp is None: slayer_xp = self.extract_infobox_value(self.template, "slayxp") if slayer_xp is not None: self.monster_dict["slayer_xp"] = infobox_cleaner.clean_float(slayer_xp) else: self.monster_dict["slayer_xp"] = None self.monster_dict["incomplete"] = True # Quick check for slayer XP versus slayer level # Fix None for slayer level, when a level is not required if self.monster_dict["slayer_xp"] is not None: # print("Here", self.monster_dict["slayer_xp"]) if self.monster_dict["slayer_level"] is None: self.monster_dict["slayer_level"] = 1 # SLAYER MONSTER: Determine if the monster can be a slayer task if self.monster_dict["slayer_level"] or self.monster_dict["slayer_xp"]: self.monster_dict["slayer_monster"] = True else: self.monster_dict["slayer_monster"] = False # SLAYER MASTERS: Determine the slayer masters if self.monster_dict["slayer_monster"]: slayer_masters = None if self.infobox_version_number is not None: key = "assignedby" + str(self.infobox_version_number) slayer_masters = self.extract_infobox_value(self.template, key) if slayer_masters is None: slayer_masters = self.extract_infobox_value(self.template, "assignedby") if slayer_masters is not None: slayer_masters = slayer_masters.strip() slayer_masters = slayer_masters.split(",") slayer_masters = [x.strip() for x in slayer_masters] if "steve" in slayer_masters: slayer_masters.remove("steve") if "nieve" not in slayer_masters: slayer_masters.append("nieve") self.monster_dict["slayer_masters"] = slayer_masters if self.monster_dict["slayer_masters"][0] == "No": self.monster_dict["slayer_masters"] = None else: self.monster_dict["slayer_masters"] = None self.monster_dict["incomplete"] = True # Set the slayer_masters property to an empty list if not populated try: if not self.monster_dict["slayer_masters"]: self.monster_dict["slayer_masters"] = list() except KeyError: self.monster_dict["slayer_masters"] = list() # EXAMINE: Determine the monster examine text examine = None if self.infobox_version_number is not None: key = "examine" + str(self.infobox_version_number) examine = self.extract_infobox_value(self.template, key) if examine is None: examine = self.extract_infobox_value(self.template, "examine") if examine is not None: self.monster_dict["examine"] = infobox_cleaner.clean_monster_examine(examine) else: self.monster_dict["examine"] = None self.monster_dict["incomplete"] = True # MONSTER COMBAT BONUSES: Determine stats of the monster # Initialize a dictionary that maps database_name -> infobox_name # The database_name is used in this project # The infobox_name is used by the OSRS Wiki combat_bonuses = {"attack_level": "att", "strength_level": "str", "defence_level": "def", "magic_level": "mage", "ranged_level": "range", "attack_stab": "astab", "attack_slash": "aslash", "attack_crush": "acrush", "attack_magic": "amagic", "attack_ranged": "arange", "defence_stab": "dstab", "defence_slash": "dslash", "defence_crush": "dcrush", "defence_magic": "dmagic", "defence_ranged": "drange", "attack_accuracy": "attbns", "melee_strength": "strbns", "ranged_strength": "rngbns", "magic_damage": "mbns" } # Loop each of the combat bonuses and populate for database_name, property_name in combat_bonuses.items(): value = None if self.infobox_version_number is not None: key = property_name + str(self.infobox_version_number) value = self.extract_infobox_value(self.template, key) if value is None: value = self.extract_infobox_value(self.template, property_name) if value is not None: self.monster_dict[database_name] = infobox_cleaner.clean_stats_value(value) else: self.monster_dict[database_name] = 0 self.monster_dict["incomplete"] = True # We finished processing, set incomplete to false if not true if not self.monster_dict.get("incomplete"): self.monster_dict["incomplete"] = False
def populate_item_properties_from_wiki_data(self): """Populate item data from a OSRS Wiki Infobox Item template.""" if not self.has_infobox: # Cannot populate if there is no infobox! self.populate_non_wiki_item() logging.error( "populate_item_properties_from_wiki_data: No infobox for wiki item." ) return False # STAGE ONE: Determine then set the wiki_name, wiki_url # and wiki_exchnage properties # Manually set OSRS Wiki name if self.wikitext_found_using not in ["id", "linked_id"]: # Item found in wiki by ID, cache name is the best option wiki_page_name = self.item_name elif self.wikitext_found_using == "normalized": # Item found in wiki by normalized name, normalize name is used wiki_page_name = self.normalized_name else: # Item found using direct cache name lookup on wiki page names, # So use wiki page name in the item_wikitext array wiki_page_name = self.item_wikitext[0] wiki_versioned_name = None wiki_name = None # Get the versioned, or non-versioned, name from the infobox if self.infobox_version_number is not None: key = "version" + str(self.infobox_version_number) wiki_versioned_name = self.extract_infobox_value( self.template, key) else: wiki_versioned_name = self.extract_infobox_value( self.template, "version") # Set the wiki_name property if wiki_versioned_name is not None: if wiki_versioned_name.startswith("("): wiki_name = wiki_page_name + " " + wiki_versioned_name else: wiki_name = wiki_page_name + " (" + wiki_versioned_name + ")" else: wiki_name = wiki_page_name self.item_dict["wiki_name"] = wiki_name # Set the wiki_url property if wiki_versioned_name is not None: wiki_url = wiki_page_name + "#" + wiki_versioned_name else: wiki_url = wiki_page_name wiki_url = wiki_url.replace(" ", "_") self.item_dict[ "wiki_url"] = "https://oldschool.runescape.wiki/w/" + wiki_url # Try find the OSRS Wiki Exchange name/URL exchange_base_url = "https://oldschool.runescape.wiki/w/Exchange:" if self.item_dict["tradeable_on_ge"]: gemwname = None if self.infobox_version_number is not None: key = "gemwname" + str(self.infobox_version_number) gemwname = self.extract_infobox_value(self.template, key) if gemwname is None: gemwname = self.extract_infobox_value(self.template, "gemwname") if gemwname is not None: wiki_exchange = gemwname.replace(" ", "_") else: wiki_exchange = self.item_dict["name"].replace(" ", "_") self.item_dict["wiki_exchange"] = exchange_base_url + wiki_exchange else: self.item_dict["wiki_exchange"] = None # Check if item is not actually able to be alched if wiki_name: if wiki_name in self.unalchable_items: self.item_dict["lowalch"] = None self.item_dict["highalch"] = None elif wiki_versioned_name in self.unalchable_items: self.item_dict["lowalch"] = None self.item_dict["highalch"] = None # STAGE TWO: Extract, process and set item properties from the infobox template # WEIGHT: Determine the weight of an item weight = None if self.infobox_version_number is not None: key = "weight" + str(self.infobox_version_number) weight = self.extract_infobox_value(self.template, key) if weight is None: weight = self.extract_infobox_value(self.template, "weight") if weight is not None: self.item_dict["weight"] = infobox_cleaner.clean_weight( weight, self.item_id) else: self.item_dict["weight"] = None self.item_dict["incomplete"] = True # QUEST: Determine if item is associated with a quest quest = None if self.infobox_version_number is not None: key = "quest" + str(self.infobox_version_number) quest = self.extract_infobox_value(self.template, key) if quest is None: quest = self.extract_infobox_value(self.template, "quest") if quest is not None: self.item_dict["quest_item"] = infobox_cleaner.clean_quest(quest) else: # Being here means the extraction for "quest" failed key = "questrequired" + str(self.infobox_version_number) quest = self.extract_infobox_value(self.template, key) if quest is None: quest = self.extract_infobox_value(self.template, "questrequired") if quest is not None: self.item_dict["quest_item"] = infobox_cleaner.clean_quest( quest) else: self.item_dict["quest_item"] = False # Determine the release date of an item release_date = None if self.infobox_version_number is not None: key = "release" + str(self.infobox_version_number) release_date = self.extract_infobox_value(self.template, key) if release_date is None: release_date = self.extract_infobox_value(self.template, "release") if release_date is not None: self.item_dict[ "release_date"] = infobox_cleaner.clean_release_date( release_date) else: self.item_dict["release_date"] = None self.item_dict["incomplete"] = True # Determine if an item is tradeable tradeable = None if self.infobox_version_number is not None: key = "tradeable" + str(self.infobox_version_number) tradeable = self.extract_infobox_value(self.template, key) if tradeable is None: tradeable = self.extract_infobox_value(self.template, "tradeable") if tradeable is not None: self.item_dict["tradeable"] = infobox_cleaner.clean_boolean( tradeable) else: self.item_dict["tradeable"] = False self.item_dict["incomplete"] = True # Determine the examine text of an item examine = None if self.infobox_version_number is not None: key = "examine" + str(self.infobox_version_number) examine = self.extract_infobox_value(self.template, key) if examine is None: examine = self.extract_infobox_value(self.template, "examine") if examine is not None: self.item_dict["examine"] = infobox_cleaner.clean_examine( examine, self.item_dict["name"]) else: # Being here means the extraction for "examine" failed key = "itemexamine" + str(self.infobox_version_number) examine = self.extract_infobox_value(self.template, key) if examine is None: examine = self.extract_infobox_value(self.template, "itemexamine") if examine is not None: self.item_dict["examine"] = infobox_cleaner.clean_examine( examine, self.item_dict["name"]) else: self.item_dict["examine"] = None self.item_dict["incomplete"] = True # Set item buy limit, if it is tradeable on the GE if not self.item_dict["tradeable_on_ge"]: self.item_dict["buy_limit"] = None else: buy_limit = None try: buy_limit = self.buy_limits_data[self.item_id_str] except KeyError: print( "populate_item_properties_from_wiki_data: Error setting buy limit..." ) print(f"{self.item_id} has no buy limit available. Exiting.") exit() self.item_dict["buy_limit"] = buy_limit # We finished processing, set incomplete to false if not true if not self.item_dict.get("incomplete"): self.item_dict["incomplete"] = False return True