Esempio n. 1
0
    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
Esempio n. 2
0
 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
Esempio n. 3
0
    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
Esempio n. 4
0
 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"))
Esempio n. 5
0
 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)
Esempio n. 6
0
    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]
Esempio n. 7
0
 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)
Esempio n. 8
0
 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", [])
Esempio n. 9
0
 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"))
Esempio n. 10
0
    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
Esempio n. 11
0
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)
Esempio n. 12
0
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)
Esempio n. 13
0
    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
Esempio n. 14
0
 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")
Esempio n. 15
0
 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)
Esempio n. 16
0
 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)
Esempio n. 17
0
 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"))
Esempio n. 18
0
 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"))
Esempio n. 19
0
 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
Esempio n. 20
0
    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
Esempio n. 21
0
    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
Esempio n. 22
0
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
Esempio n. 23
0
 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)
Esempio n. 24
0
    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
        ]
Esempio n. 25
0
 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)
Esempio n. 26
0
    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
Esempio n. 27
0
 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
Esempio n. 28
0
 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
Esempio n. 29
0
    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)
Esempio n. 30
0
    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")