def _parse_tournament_info(self, table): """Parse the tournament info table. Parameters ---------- table: :class:`bs4.BeautifulSoup` The parsed table containing the tournament's information. """ rows = table.find_all('tr') date_fields = ("start_date", "end_date") list_fields = ("worlds",) for row in rows: cols_raw = row.find_all('td') cols = [ele.text.strip() for ele in cols_raw] field, value = cols field = field.replace("\xa0", "_").replace(" ", "_").replace(":", "").lower() value = value.replace("\xa0", " ") if field in date_fields: value = parse_tibia_datetime(value) if field in list_fields: value = split_list(value, ",", ",") if field == "phase": value = try_enum(TournamentPhase, value) try: setattr(self, field, value) except AttributeError: pass
def __init__(self, rank, name, vocation, world, level, value): self.name: str = name self.rank: int = rank self.vocation = try_enum(Vocation, vocation) self.value: int = value self.world: str = world self.level: int = level
def _parse_leaderboard_entries(self, ranking_table): """Parse the leaderboards' entries. Parameters ---------- ranking_table: :class:`bs4.BeautifulSoup` The table containing the rankings. """ ranking_table_content = ranking_table.find("table", attrs={"class": "TableContent"}) header, *rows = ranking_table_content.find_all('tr') entries = [] for row in rows: raw_columns = row.find_all("td") if len(raw_columns) != 4: break cols = [c.text.strip() for c in raw_columns] rank_and_change, character, vocation, score = cols m = RANK_PATTERN.search(rank_and_change) rank = int(m.group(1)) change = int(m.group(2)) voc = try_enum(Vocation, vocation) score = parse_integer(score, 0) entries.append(TournamentLeaderboardEntry(rank=rank, change=change, name=character, vocation=voc, score=score)) # Results footer small = ranking_table.find("small") if small: pagination_text = small.text results_str = RESULTS_PATTERN.search(pagination_text) self.results_count = int(results_str.group(1)) self.entries = entries
def __init__(self, name=None, rank=None, title=None, level=0, vocation=None, **kwargs): self.name: str = name self.rank: str = rank self.title: Optional[str] = title self.vocation: Vocation = try_enum(Vocation, vocation) self.level = int(level) self.online: bool = kwargs.get("online", False) self.joined: datetime.date = try_date(kwargs.get("joined"))
def __init__(self, name, location=None, pvp_type=None, **kwargs): self.name: str = name self.location = try_enum(WorldLocation, location) self.pvp_type = try_enum(PvpType, pvp_type) self.status: bool = kwargs.get("status") self.online_count: int = kwargs.get("online_count", 0) self.record_count: int = kwargs.get("record_count", 0) self.record_date = try_datetime(kwargs.get("record_date")) self.creation_date: str = kwargs.get("creation_date") self.transfer_type = try_enum(TransferType, kwargs.get("transfer_type", TransferType.REGULAR)) self.world_quest_titles: List[str] = kwargs.get("world_quest_titles", []) self.battleye_date = try_date(kwargs.get("battleye_date")) self.battleye_type = try_enum(BattlEyeType, kwargs.get("battleye_type"), BattlEyeType.UNPROTECTED) self.experimental: bool = kwargs.get("experimental", False) self.online_players: List[OnlineCharacter] = kwargs.get("online_players", []) self.premium_only: bool = kwargs.get("premium_only", False) self.tournament_world_type = try_enum(TournamentWorldType, kwargs.get("tournament_world_type"), None)
def _parse_filters_table(self, form): """ Parse the filters table found in a highscores page. Parameters ---------- form: :class:`bs4.Tag` The table containing the filters. """ data = parse_form_data(form, include_options=True) self.world = data["world"] if data.get("world") else None self.battleye_filter = try_enum(BattlEyeHighscoresFilter, parse_integer(data.get("beprotection"), None)) self.category = try_enum(Category, parse_integer(data.get("category"), None)) self.vocation = try_enum(VocationFilter, parse_integer(data.get("profession"), None), VocationFilter.ALL) checkboxes = form.find_all("input", {"type": "checkbox", "checked": "checked"}) values = [int(c["value"]) for c in checkboxes] self.pvp_types_filter = [try_enum(PvpTypeFilter, v) for v in values] self.available_words = [v for v in data["__options__"]["world"].values() if v]
def __init__(self, name, **kwargs): self.name: str = name self.level: int = kwargs.get("level", 2) self.world: str = kwargs.get("world") self.vocation: Vocation = try_enum(Vocation, kwargs.get("vocation")) self.title: Optional[str] = kwargs.get("title") self.position: Optional[str] = kwargs.get("position") self.guild: Optional[GuildMembership] = kwargs.get("guild") self.posts: int = kwargs.get("posts", 0) self.deleted: bool = kwargs.get("deleted", False)
def __init__(self, **kwargs): self.title = kwargs.get("title") self.cycle = kwargs.get("cycle", 0) self.phase = try_enum(TournamentPhase, kwargs.get("phase")) self.start_date: datetime.datetime = kwargs.get("start_date") self.end_date: datetime.datetime = kwargs.get("end_date") self.worlds: List[str] = kwargs.get("worlds") self.rule_set: RuleSet = kwargs.get("rule_set") self.score_set: ScoreSet = kwargs.get("score_set") self.reward_set: List[RewardEntry] = kwargs.get("reward_set", []) self.archived_tournaments: List[ListedTournament] = kwargs.get("archived_tournaments", [])
def __init__(self, name, world=None, **kwargs): self.id = kwargs.get("id", 0) # type: int self.name = name # type: str self.world = world # type: str self.image_url = kwargs.get("image_url") # type: str self.beds = kwargs.get("beds", 0) # type: int self.type = try_enum(HouseType, kwargs.get("type"), HouseType.HOUSE) self.size = kwargs.get("size", 0) # type: int self.rent = kwargs.get("rent", 0) # type: int self.status = try_enum(HouseStatus, kwargs.get("status"), None) self.owner = kwargs.get("owner") # type: Optional[str] self.owner_sex = try_enum(Sex, kwargs.get("owner_sex")) self.paid_until = try_datetime(kwargs.get("paid_until")) self.transfer_date = try_datetime(kwargs.get("transfer_date")) self.transferee = kwargs.get("transferee") # type: Optional[str] self.transfer_price = kwargs.get("transfer_price", 0) # type: int self.transfer_accepted = kwargs.get("transfer_accepted", False) # type: bool self.highest_bid = kwargs.get("highest_bid", 0) # type: int self.highest_bidder = kwargs.get("highest_bidder") # type: Optional[str] self.auction_end = try_datetime(kwargs.get("auction_end"))
def _parse_author_table(cls, character_info_container): """Parses the table containing the author's information. Parameters ---------- character_info_container: :class:`bs4.Tag` The cotnainer with the character's information. Returns ------- :class:`ForumAuthor` The author's information. """ # First link belongs to character char_link = character_info_container.find("a") if not char_link: return ForumAuthor(name=character_info_container.text, deleted=True) author = cls(char_link.text) position_info = character_info_container.find("font", attrs={"class": "ff_smallinfo"}) # Position and titles are shown the same way. If we have two, the title is first and then the position. # However, if the character only has one of them, there's no way to know which is it unless we validate against # possible types if position_info and position_info.parent == character_info_container: convert_line_breaks(position_info) titles = [title for title in position_info.text.splitlines() if title] positions = ["Tutor", "Community Manager", "Customer Support", "Programmer", "Game Content Designer", "Tester"] for _title in titles: if _title in positions: author.position = _title else: author.title = _title char_info = character_info_container.find("font", attrs={"class": "ff_infotext"}) guild_info = char_info.find("font", attrs={"class": "ff_smallinfo"}) convert_line_breaks(char_info) char_info_text = char_info.text info_match = author_info_regex.search(char_info_text) if info_match: author.world = info_match.group(1) author.vocation = try_enum(Vocation, info_match.group(2)) author.level = int(info_match.group(3)) if guild_info: guild_match = guild_regexp.search(guild_info.text) guild_name = guild_match.group(2) title_match = guild_title_regexp.search(guild_name) title = None if title_match: guild_name = title_match.group(1) title = title_match.group(2) author.guild = GuildMembership(name=guild_name, rank=guild_match.group(1), title=title) author.posts = int(author_posts_regex.search(char_info_text).group(1)) return author
async def get_highscores(request: web.Request): world = request.match_info['world'] category = try_enum(tibiapy.Category, request.query.get("category", "EXPERIENCE").upper(), tibiapy.Category.EXPERIENCE) vocations = try_enum(tibiapy.VocationFilter, int(request.query.get("vocation", 0)), tibiapy.VocationFilter.ALL) battleye_type = try_enum(tibiapy.BattlEyeHighscoresFilter, int(request.query.get("battleye", -1))) page = int(request.query.get("page", 1)) pvp_params = request.query.getall("pvp", []) pvp_types = [ try_enum(tibiapy.PvpTypeFilter, param) for param in pvp_params ] pvp_types = [p for p in pvp_types if p is not None] if world.lower() == "all": world = None response = await app["tibiapy"].fetch_highscores_page( world, category, vocations, page, battleye_type, pvp_types) return json_response(response)
async def get_current_auctions(request: web.Request): page = int(request.query.get("page", 1)) filters = tibiapy.AuctionFilters() filters.world = request.query.get("world") filters.battleye = try_enum(tibiapy.BattlEyeTypeFilter, request.query.get("battleye")) filters.pvp_type = try_enum(tibiapy.PvpTypeFilter, request.query.get("pvp_type")) filters.min_level = tibiapy.utils.parse_integer( request.query.get("min_level"), None) filters.max_level = tibiapy.utils.parse_integer( request.query.get("max_level"), None) filters.vocation = try_enum(tibiapy.VocationAuctionFilter, request.query.get("vocation")) filters.skill = try_enum(tibiapy.SkillFilter, request.query.get("skill")) filters.min_skill_level = tibiapy.utils.parse_integer( request.query.get("min_skill_level"), None) filters.max_skill_level = tibiapy.utils.parse_integer( request.query.get("max_skill_level"), None) filters.order_by = try_enum(tibiapy.AuctionOrderBy, request.query.get("order_by")) filters.order = try_enum(tibiapy.AuctionOrder, request.query.get("order")) filters.item = request.query.get("item") auctions = await app["tibiapy"].fetch_current_auctions(page, filters) return web.json_response(auctions, dumps=CustomJson.dumps)
def _parse_spells_table(cls, identifier, spell_table): """Parse the table containing spell information. Parameters ---------- identifier: :class:`str` The identifier of the spell. spell_table: :class:`bs4.Tag` The table containing the spell information. Returns ------- :class:`Spell` The spell described in the table. """ attrs = cls._parse_table_attributes(spell_table) spell = cls(identifier, attrs["name"], attrs["formula"], premium="yes" in attrs["premium"], exp_level=int(attrs["exp_lvl"])) spell.vocations = [s.strip() for s in attrs["vocation"].split(",")] spell.cities = [s.strip() for s in attrs["city"].split(",")] m = group_pattern.match(attrs["group"]) groups = m.groupdict() spell.group = try_enum(SpellGroup, groups.get("group")) spell.group_secondary = groups.get("secondary") m = cooldown_pattern.match(attrs["cooldown"]) cooldowns = m.groupdict() spell.cooldown = int(cooldowns["cooldown"]) spell.cooldown_group = int(cooldowns["group_cooldown"]) spell.cooldown_group_secondary = parse_integer( cooldowns.get("secondary_group_cooldown"), None) spell.spell_type = try_enum(SpellType, attrs["type"]) spell.soul_points = parse_integer(attrs.get("soul_points"), None) spell.mana = parse_integer(attrs.get("mana"), None) spell.amount = parse_integer(attrs.get("amount"), None) spell.price = parse_integer(attrs.get("price"), 0) spell.magic_type = attrs.get("magic_type") return spell
def __init__(self, **kwargs): self.pvp_type = try_enum(PvpType, kwargs.get("pvp_type")) self.daily_tournament_playtime = self._try_parse_interval(kwargs.get("daily_tournament_playtime")) self.total_tournament_playtime = self._try_parse_interval(kwargs.get("total_tournament_playtime")) self.playtime_reduced_only_in_combat = kwargs.get("playtime_reduced_only_in_combat") self.death_penalty_modifier = kwargs.get("death_penalty_modifier") self.xp_multiplier = kwargs.get("xp_multiplier") self.skill_multiplier = kwargs.get("skill_multiplier") self.spawn_rate_multiplier = kwargs.get("spawn_rate_multiplier") self.loot_probability = kwargs.get("loot_probability") self.rent_percentage = kwargs.get("rent_percentage") self.house_auction_durations = kwargs.get("house_auction_durations") self.shared_xp_bonus = kwargs.get("shared_xp_bonus")
def _parse_entry(cls, cols_raw): img = cols_raw[0].find('img') img_url = img["src"] category_name = ICON_PATTERN.search(img_url) category = try_enum(NewsCategory, category_name.group(1)) for br in cols_raw[1].find_all("br"): br.replace_with("\n") date_str, news_type_str = cols_raw[1].text.splitlines() date = parse_tibia_date(date_str) news_type_str = news_type_str.replace('\xa0', ' ') news_type = try_enum(NewsType, news_type_str) title = cols_raw[2].text news_link = cols_raw[2].find('a') url = urllib.parse.urlparse(news_link["href"]) query = urllib.parse.parse_qs(url.query) news_id = int(query["id"][0]) return cls(news_id, title, news_type, category, date, category_icon=img_url)
def __init__(self, name, location=None, pvp_type=None, **kwargs): self.name = name # type: str self.location = try_enum(WorldLocation, location) self.pvp_type = try_enum(PvpType, pvp_type) self.status = kwargs.get("status") # type: bool self.online_count = kwargs.get("online_count", 0) # type: int self.record_count = kwargs.get("record_count", 0) # type: int self.record_date = try_datetime(kwargs.get("record_date")) self.creation_date = kwargs.get("creation_date") # type: str self.transfer_type = try_enum( TransferType, kwargs.get("transfer_type", TransferType.REGULAR)) self.world_quest_titles = kwargs.get("world_quest_titles", []) # type: List[str] self.battleye_protected = kwargs.get("battleye_protected", False) # type: bool self.battleye_date = try_date(kwargs.get("battleye_date")) self.experimental = kwargs.get("experimental", False) # type: bool self.online_players = kwargs.get("online_players", []) # type: List[OnlineCharacter] self.premium_only = kwargs.get("premium_only", False) # type: bool self.tournament_world_type = try_enum( TournamentWorldType, kwargs.get("tournament_world_type"), None)
def __init__(self, name=None, world=None, vocation=None, level=0, sex=None, **kwargs): self.name: str = name self.traded: bool = kwargs.get("traded", False) self.former_names: List[str] = kwargs.get("former_names", []) self.title: Optional[str] = kwargs.get("title") self.unlocked_titles = int(kwargs.get("unlocked_titles", 0)) self.sex = try_enum(Sex, sex) self.vocation = try_enum(Vocation, vocation) self.level = int(level) self.achievement_points = int(kwargs.get("achievement_points", 0)) self.world: str = world self.former_world: Optional[str] = kwargs.get("former_world") self.residence: str = kwargs.get("residence") self.married_to: Optional[str] = kwargs.get("married_to") self.houses: List[CharacterHouse] = kwargs.get("houses", []) self.guild_membership: Optional[GuildMembership] = kwargs.get( "guild_membership") self.last_login = try_datetime(kwargs.get("last_login")) self.account_status = try_enum(AccountStatus, kwargs.get("account_status")) self.position: Optional[str] = kwargs.get("position") self.comment: Optional[str] = kwargs.get("comment") self.account_badges: List[AccountBadge] = kwargs.get( "account_badges", []) self.achievements: List[Achievement] = kwargs.get("achievements", []) self.deaths: List[Death] = kwargs.get("deaths", []) self.deaths_truncated: bool = kwargs.get("deaths", False) self.account_information: Optional[AccountInformation] = kwargs.get( "account_information") self.other_characters: List[OtherCharacter] = kwargs.get( "other_characters", []) self.deletion_date = try_datetime(kwargs.get("deletion_date"))
def __init__(self, name=None, rank=None, title=None, level=0, vocation=None, **kwargs): self.name = name # type: str self.rank = rank # type: str self.title = title # type: Optional[str] self.vocation = try_enum(Vocation, vocation) self.level = int(level) self.online = kwargs.get("online", False) # type: bool self.joined = try_date(kwargs.get("joined"))
def _parse_filters(self, filters_table): world_select = filters_table.find("select", {"name": "world"}) for world_option in world_select.find_all("option"): world_name = world_option.text if "(" in world_name: continue self.available_worlds.append(world_name) if world_option.attrs.get("selected"): self.world = world_name for town_option in filters_table.find_all("input", {"name": "town"}): town_name = town_option.attrs.get("value") self.available_towns.append(town_name) if "checked" in town_option.attrs: self.town = town_name checked_status = filters_table.find("input", { "name": "state", "checked": True }) if checked_status.attrs.get("value"): self.status = try_enum(HouseStatus, checked_status.attrs.get("value")) checked_type = filters_table.find("input", { "name": "type", "checked": True }) if checked_type.attrs.get("value"): self.house_type = try_enum(HouseType, checked_type.attrs.get("value")[:-1]) checked_order = filters_table.find("input", { "name": "order", "checked": True }) if checked_order and checked_order.attrs.get("value"): self.order = try_enum(HouseOrder, checked_order.attrs.get("value"), HouseOrder.NAME) return self
def from_tibiadata(cls, content): """ Parses a TibiaData response into a House object. Parameters ---------- content: :class:`str` The JSON content of the TibiaData response. Returns ------- :class:`House` The house contained in the response, if found. Raises ------ InvalidContent If the content is not a house JSON response from TibiaData """ json_content = parse_json(content) try: house_json = json_content["house"] if not house_json["name"]: return None house = cls(house_json["name"], house_json["world"]) house.type = try_enum(HouseType, house_json["type"]) house.id = house_json["houseid"] house.beds = house_json["beds"] house.size = house_json["size"] house.size = house_json["size"] house.rent = house_json["rent"] house.image_url = house_json["img"] # Parsing the original status string is easier than dealing with TibiaData fields house._parse_status(house_json["status"]["original"]) except KeyError: raise InvalidContent("content is not a TibiaData house response.") return house
def _parse_rune_table(cls, table): """Parse the rune information table. Parameters ---------- table: :class:`bs4.Tag` The table containing the rune information. Returns ------- :class:`Rune` The rune described in the table. """ attrs = cls._parse_table_attributes(table) rune = Rune(name=attrs["name"], group=try_enum(SpellGroup, attrs["group"])) rune.vocations = [v.strip() for v in attrs["vocation"].split(",")] rune.magic_type = attrs.get("magic_type") rune.magic_level = parse_integer(attrs.get("mag_lvl"), 0) rune.exp_level = parse_integer(attrs.get("exp_lvl"), 0) rune.mana = parse_integer(attrs.get("mana"), None) return rune
async def filters_from_query(request): filters = tibiapy.AuctionFilters() filters.world = request.query.get("world") filters.battleye = try_enum(tibiapy.BattlEyeTypeFilter, request.query.get("battleye")) filters.pvp_type = try_enum(tibiapy.PvpTypeFilter, request.query.get("pvp_type")) filters.min_level = tibiapy.utils.parse_integer( request.query.get("min_level"), None) filters.max_level = tibiapy.utils.parse_integer( request.query.get("max_level"), None) filters.vocation = try_enum(tibiapy.VocationAuctionFilter, request.query.get("vocation")) filters.skill = try_enum(tibiapy.SkillFilter, request.query.get("skill")) filters.min_skill_level = tibiapy.utils.parse_integer( request.query.get("min_skill_level"), None) filters.max_skill_level = tibiapy.utils.parse_integer( request.query.get("max_skill_level"), None) filters.order_by = try_enum(tibiapy.AuctionOrderBy, request.query.get("order_by")) filters.order = try_enum(tibiapy.AuctionOrder, request.query.get("order")) filters.search_string = request.query.get("item") return filters
def __init__(self, name, world, level, vocation): self.name: str = name self.world: str = world self.level = int(level) self.vocation = try_enum(Vocation, vocation)
def _parse_character_information(self, rows): """ Parses the character's basic information and applies the found values. Parameters ---------- rows: :class:`list` of :class:`bs4.Tag` A list of all rows contained in the table. """ int_rows = ["level", "achievement_points"] char = {} houses = [] for row in rows: cols_raw = row.find_all('td') cols = [ele.text.strip() for ele in cols_raw] field, value = cols field = field.replace("\xa0", "_").replace(" ", "_").replace(":", "").lower() value = value.replace("\xa0", " ") # This is a special case cause we need to see the link if field == "house": house_text = value paid_until = house_regexp.search(house_text).group(1) paid_until_date = parse_tibia_date(paid_until) house_link = cols_raw[1].find('a') url = urllib.parse.urlparse(house_link["href"]) query = urllib.parse.parse_qs(url.query) houses.append({ "id": int(query["houseid"][0]), "name": house_link.text.strip(), "town": query["town"][0], "paid_until": paid_until_date }) continue if field in int_rows: value = int(value) char[field] = value # If the character is deleted, the information is fouund with the name, so we must clean it m = deleted_regexp.match(char["name"]) if m: char["name"] = m.group(1) char["deletion_date"] = parse_tibia_datetime(m.group(2)) if "guild_membership" in char: m = guild_regexp.match(char["guild_membership"]) char["guild_membership"] = GuildMembership(m.group(2), m.group(1)) if "(traded)" in char["name"]: char["name"] = char["name"].replace("(traded)", "").strip() char["traded"] = True if "former_names" in char: former_names = [ fn.strip() for fn in char["former_names"].split(",") ] char["former_names"] = former_names if "never" in char["last_login"]: char["last_login"] = None else: char["last_login"] = parse_tibia_datetime(char["last_login"]) m = title_regexp.match(char.get("title", "")) if m: name = m.group(1).strip() unlocked = int(m.group(2)) if name == "None": name = None char["title"] = name char["unlocked_titles"] = unlocked char["vocation"] = try_enum(Vocation, char["vocation"]) char["sex"] = try_enum(Sex, char["sex"]) char["account_status"] = try_enum(AccountStatus, char["account_status"]) for k, v in char.items(): try: setattr(self, k, v) except AttributeError: # This means that there is a attribute in the character's information table that does not have a # corresponding class attribute. pass self.houses = [ CharacterHouse(h["id"], h["name"], self.world, h["town"], self.name, h["paid_until"]) for h in houses ]
def __init__(self, name, world, level, vocation): self.name = name # type: str self.world = world # type: str self.level = int(level) self.vocation = try_enum(Vocation, vocation)
def from_tibiadata(cls, content): """Builds a character object from a TibiaData character response. Parameters ---------- content: :class:`str` The JSON content of the response. Returns ------- :class:`Character` The character contained in the page, or None if the character doesn't exist Raises ------ InvalidContent If content is not a JSON string of the Character response.""" json_content = parse_json(content) char = cls() try: character = json_content["characters"] if "error" in character: return None character_data = character["data"] char.name = character_data["name"] char.world = character_data["world"] char.level = character_data["level"] char.achievement_points = character_data["achievement_points"] char.sex = try_enum(Sex, character_data["sex"]) char.vocation = try_enum(Vocation, character_data["vocation"]) char.residence = character_data["residence"] char.account_status = try_enum(AccountStatus, character_data["account_status"]) except KeyError: raise InvalidContent( "content does not match a character json from TibiaData.") char.former_names = character_data.get("former_names", []) if "deleted" in character_data: char.deletion_date = parse_tibiadata_datetime( character_data["deleted"]) char.married_to = character_data.get("married_to") char.former_world = character_data.get("former_world") char.position = character_data.get("Position:") if "guild" in character_data: char.guild_membership = GuildMembership( character_data["guild"]["name"], character_data["guild"]["rank"]) if "house" in character_data: house = character_data["house"] paid_until_date = parse_tibiadata_date(house["paid"]) char.houses.append( CharacterHouse(house["houseid"], house["name"], char.world, house["town"], char.name, paid_until_date)) char.comment = character_data.get("comment") if len(character_data["last_login"]) > 0: char.last_login = parse_tibiadata_datetime( character_data["last_login"][0]) for achievement in character["achievements"]: char.achievements.append( Achievement(achievement["name"], achievement["stars"])) char._parse_deaths_tibiadata(character.get("deaths", [])) for other_char in character["other_characters"]: char.other_characters.append( OtherCharacter(other_char["name"], other_char["world"], other_char["status"] == "online", other_char["status"] == "deleted")) if character["account_information"]: acc_info = character["account_information"] created = parse_tibiadata_datetime(acc_info.get("created")) loyalty_title = None if acc_info[ "loyalty_title"] == "(no title)" else acc_info["loyalty_title"] position = acc_info.get("position") char.account_information = AccountInformation( created, loyalty_title, position) return char
def __init__(self, name, rank, vocation, value): self.name = name # type: str self.rank = rank # type: int self.vocation = try_enum(Vocation, vocation) self.value = value # type: int
def __init__(self, world, category, **kwargs): self.world = world # type: str self.category = try_enum(Category, category, Category.EXPERIENCE) self.vocation = try_enum(VocationFilter, kwargs.get("vocation"), VocationFilter.ALL) self.entries = kwargs.get("entries", []) # type: List[HighscoresEntry] self.results_count = kwargs.get("results_count") # type: int
def from_content(cls, content): """Parse the content of the spells section. Parameters ----------- content: :class:`str` The HTML content of the page. Returns ---------- :class:`SpellsSection` The spells contained and the filtering information. Raises ------ InvalidContent If content is not the HTML of the spells section. """ try: parsed_content = parse_tibiacom_content(content) table_content_container = parsed_content.find( "div", attrs={"class": "InnerTableContainer"}) spells_table = table_content_container.find( "table", class_=lambda t: t != "TableContent") spell_rows = spells_table.find_all( "tr", {'bgcolor': ["#D4C0A1", "#F1E0C6"]}) spells_section = cls() for row in spell_rows: columns = row.find_all("td") if len(columns) != 7: continue spell_link = columns[0].find("a") url = urllib.parse.urlparse(spell_link["href"]) query = urllib.parse.parse_qs(url.query) cols_text = [c.text for c in columns] identifier = query["spell"][0] match = spell_name.findall(cols_text[0]) name, words = match[0] group = try_enum(SpellGroup, cols_text[1]) spell_type = try_enum(SpellType, cols_text[2]) level = int(cols_text[3]) mana = parse_integer(cols_text[4], None) price = parse_integer(cols_text[5], 0) premium = "yes" in cols_text[6] spell = SpellEntry(name=name.strip(), words=words.strip(), spell_type=spell_type, level=level, group=group, mana=mana, premium=premium, price=price, identifier=identifier) spells_section.entries.append(spell) form = parsed_content.find("form") data = parse_form_data(form) spells_section.vocation = try_enum(VocationSpellFilter, data["vocation"]) spells_section.group = try_enum(SpellGroup, data["group"]) spells_section.premium = try_enum(SpellGroup, data["group"]) spells_section.spell_type = try_enum(SpellType, data["type"]) spells_section.sort_by = try_enum(SpellSorting, data["sort"]) spells_section.premium = "yes" in data["premium"] if data[ "premium"] else None return spells_section except (AttributeError, TypeError) as e: raise errors.InvalidContent( "content does not belong to the Spells section", e)
def from_content(cls, content, news_id=0): """ Gets a news entry by its HTML content from Tibia.com Notes ----- Since there's no way to obtain the entry's Id from the page contents, it will always be 0. A news_id can be passed to set the news_id of the resulting object. Parameters ---------- content: :class:`str` The HTML content of the page. news_id: :class:`int`, optional The news_id belonging to the content being parsed. Returns ------- :class:`News` The news article found in the page. Raises ------ InvalidContent If content is not the HTML of a news' page. """ if "(no news with id " in content: return None try: parsed_content = parse_tibiacom_content(content) # Read Information from the headline headline = parsed_content.find("div", attrs={"class": "NewsHeadline"}) img = headline.find('img') img_url = img["src"] category_name = ICON_PATTERN.search(img_url) category = try_enum(NewsCategory, category_name.group(1)) title_div = headline.find("div", attrs={"class": "NewsHeadlineText"}) title = title_div.text.replace('\xa0', ' ') date_div = headline.find("div", attrs={"class": "NewsHeadlineDate"}) date_str = date_div.text.replace('\xa0', ' ').replace('-', '').strip() date = parse_tibia_date(date_str) # Read the page's content. content_table = parsed_content.find("table") content_row = content_table.find("td") content = content_row.encode_contents().decode() thread_id = None thread_div = content_table.find("div") if thread_div: news_link = thread_div.find('a') url = urllib.parse.urlparse(news_link["href"]) query = urllib.parse.parse_qs(url.query) thread_id = int(query["threadid"][0]) return cls(news_id, title, content, date, category, thread_id=thread_id, category_icon=img_url) except AttributeError: raise InvalidContent( "content is not from the news archive section in Tibia.com")