Exemple #1
0
    def _search_parse_cache(self, root):
        """Returns a Cache object parsed from BeautifulSoup Tag."""

        assert isinstance(root, bs4.Tag)

        # parse raw data
        favorites = root.find("span", "favorite-rank")
        typeLink, nameLink = root.find_all("a", "lnk")
        pm_only = root.find("img", title="Premium Member Only Cache") is not None
        direction, info, D_T, placed, last_found = root.find_all("span", "small")
        found = root.find("img", title="Found It!") is not None
        size = root.find("td", "AlignCenter").find("img")
        author, wp, area = [t.strip() for t in info.text.split("|")]

        # create cache object
        c = Cache(wp, self)

        # prettify data
        c.cache_type = typeLink.find("img").get("alt")
        c.name = nameLink.span.text.strip()
        c.found = found
        c.state = "Strike" not in nameLink.get("class")
        c.size = " ".join(size.get("alt").split()[1:])
        c.difficulty, c.terrain = list(map(float, D_T.text.split("/")))
        c.hidden = Util.parse_date(placed.text)
        c.author = author[3:]  # delete "by "
        c.favorites = int(favorites.text)
        c.pm_only = pm_only

        logging.debug("Cache parsed: %s", c)
        return c
Exemple #2
0
    def _search_parse_cache(self, root):
        """Returns a Cache object parsed from BeautifulSoup Tag."""

        assert isinstance(root, bs4.Tag)

        # parse raw data
        favorites = root.find("span", "favorite-rank")
        typeLink, nameLink = root.find_all("a", "lnk")
        pm_only = root.find("img",
                            title="Premium Member Only Cache") is not None
        direction, info, D_T, placed, last_found = root.find_all(
            "span", "small")
        found = root.find("img", title="Found It!") is not None
        size = root.find("td", "AlignCenter").find("img")
        author, wp, area = [t.strip() for t in info.text.split("|")]

        # create cache object
        c = Cache(wp, self)

        # prettify data
        c.cache_type = typeLink.find("img").get("alt")
        c.name = nameLink.span.text.strip()
        c.found = found
        c.state = "Strike" not in nameLink.get("class")
        c.size = " ".join(size.get("alt").split()[1:])
        c.difficulty, c.terrain = list(map(float, D_T.text.split("/")))
        c.hidden = Util.parse_date(placed.text)
        c.author = author[3:]  # delete "by "
        c.favorites = int(favorites.text)
        c.pm_only = pm_only

        logging.debug("Cache parsed: %s", c)
        return c
Exemple #3
0
    def search(self, point, limit=float("inf")):
        """Return a generator of caches around some point.

        Search for caches around some point by loading search pages and parsing the data from these
        pages. Yield :class:`.Cache` objects filled with data from search page. You can provide limit
        as a convinient way to stop generator after certain number of caches.

        :param .geo.Point point: Search center point.
        :param int limit: Maximum number of caches to generate.
        """
        logging.info("Searching at {}".format(point))

        start_index = 0
        while True:
            # get one page
            page = self._search_get_page(point, start_index)

            if not page:
                # result is empty - no more caches
                raise StopIteration()

            # parse caches in result
            for start_index, row in enumerate(page.find_all("tr"), start_index):

                limit -= 1  # handle limit
                if limit < 0:
                    raise StopIteration()

                # parse raw data
                cache_details = row.find("span", "cache-details").text.split("|")
                wp = cache_details[1].strip()

                # create and fill cache object
                c = Cache(self, wp)
                c.type = Type.from_string(cache_details[0].strip())
                c.name = row.find("span", "cache-name").text
                c.found = row.find("img", title="Found It!") is not None
                c.favorites = int(row.find(attrs={"data-column": "FavoritePoint"}).text)
                c.state = not (row.get("class") and "disabled" in row.get("class"))
                c.pm_only = row.find("td", "pm-upsell") is not None

                if c.pm_only:
                    # PM only caches doesn't have other attributes filled in
                    yield c
                    continue

                c.size = Size.from_string(row.find(attrs={"data-column": "ContainerSize"}).text)
                c.difficulty = float(row.find(attrs={"data-column": "Difficulty"}).text)
                c.terrain = float(row.find(attrs={"data-column": "Terrain"}).text)
                c.hidden = parse_date(row.find(attrs={"data-column": "PlaceDate"}).text)
                c.author = row.find("span", "owner").text[3:]  # delete "by "

                logging.debug("Cache parsed: {}".format(c))
                yield c

            start_index += 1
Exemple #4
0
    def search(self, point, limit=0):
        """Returns a generator object of caches around some point."""

        assert isinstance(point, Point)
        assert type(limit) is int

        logging.info("Searching at %s...", point)

        start_index = 0
        while True:
            # get one page
            page = self._search_get_page(point, start_index)

            if not page:
                # result is empty - no more caches
                raise StopIteration()

            # parse caches in result
            for start_index, row in enumerate(BeautifulSoup(page).find_all("tr"), start_index):

                if limit > 0 and start_index == limit:
                    raise StopIteration()

                # parse raw data
                cache_details = row.find("span", "cache-details").text.split("|")
                wp = cache_details[1].strip()

                # create and fill cache object
                c = Cache(wp, self)
                c.cache_type = cache_details[0].strip()
                c.name = row.find("span", "cache-name").text
                c.found = row.find("img", title="Found It!") is not None
                c.favorites = int(row.find(attrs={"data-column": "FavoritePoint"}).text)
                c.state = not (row.get("class") and "disabled" in row.get("class"))
                c.pm_only = row.find("td", "pm-upsell") is not None

                if c.pm_only:
                    # PM only caches doesn't have other attributes filled in
                    yield c
                    continue

                c.size = row.find(attrs={"data-column": "ContainerSize"}).text
                c.difficulty = float(row.find(attrs={"data-column": "Difficulty"}).text)
                c.terrain = float(row.find(attrs={"data-column": "Terrain"}).text)
                c.hidden = Util.parse_date(row.find(attrs={"data-column": "PlaceDate"}).text)
                c.author = row.find("span", "owner").text[3:]  # delete "by "

                logging.debug("Cache parsed: %s", c)
                yield c

            start_index += 1
Exemple #5
0
    def search(self, point, limit=float("inf")):
        """Return a generator of caches around some point.

        Search for caches around some point by loading search pages and parsing the data from these
        pages. Yield :class:`.Cache` objects filled with data from search page. You can provide limit
        as a convinient way to stop generator after certain number of caches.

        :param .geo.Point point: Search center point.
        :param int limit: Maximum number of caches to generate.
        """
        logging.info("Searching at {}".format(point))

        start_index = 0
        while True:
            # get one page
            page = self._search_get_page(point, start_index)

            if not page:
                # result is empty - no more caches
                raise StopIteration()

            # parse caches in result
            for start_index, row in enumerate(page.find_all("tr"),
                                              start_index):

                limit -= 1  # handle limit
                if limit < 0:
                    raise StopIteration()

                # parse raw data
                cache_details = row.find("span",
                                         "cache-details").text.split("|")
                wp = cache_details[1].strip()

                # create and fill cache object
                c = Cache(self, wp)
                c.type = Type.from_string(cache_details[0].strip())
                c.name = row.find("span", "cache-name").text
                badge = row.find("svg", class_="badge")
                c.found = "found" in str(badge) if badge is not None else False
                c.favorites = int(
                    row.find(attrs={
                        "data-column": "FavoritePoint"
                    }).text)
                c.state = not (row.get("class")
                               and "disabled" in row.get("class"))
                c.pm_only = row.find("td", "pm-upsell") is not None

                if c.pm_only:
                    # PM only caches doesn't have other attributes filled in
                    yield c
                    continue

                c.size = Size.from_string(
                    row.find(attrs={
                        "data-column": "ContainerSize"
                    }).text)
                c.difficulty = float(
                    row.find(attrs={
                        "data-column": "Difficulty"
                    }).text)
                c.terrain = float(
                    row.find(attrs={
                        "data-column": "Terrain"
                    }).text)
                c.hidden = parse_date(
                    row.find(attrs={
                        "data-column": "PlaceDate"
                    }).text)
                c.author = row.find("span", "owner").text[3:]  # delete "by "

                logging.debug("Cache parsed: {}".format(c))
                yield c

            start_index += 1
Exemple #6
0
    def search(self, point, limit=float("inf")):
        """Return a generator of caches around some point.

        Search for caches around some point by loading search pages and parsing the data from these
        pages. Yield :class:`.Cache` objects filled with data from search page. You can provide limit
        as a convenient way to stop generator after certain number of caches.

        :param .geo.Point point: Search center point.
        :param int limit: Maximum number of caches to generate.
        """
        logging.info("Searching at {}".format(point))

        start_index = 0
        while True:
            # get one page
            geocaches_table, whole_page = self._search_get_page(point, start_index)
            rows = geocaches_table.find_all("tr")

            # leave loop if there are no (more) results
            if not rows:
                return

            # prepare language-dependent mappings
            if start_index == 0:
                cache_sizes_filter_wrapper = whole_page.find("div", class_="cache-sizes-wrapper")
                localized_size_mapping = {
                    # key = "Small" (localized), value = Size.small
                    label.find("span").text.strip(): Size.from_number(label.find("input").get("value"))
                    for label in cache_sizes_filter_wrapper.find_all("label")
                }

            # parse caches in result
            for start_index, row in enumerate(rows, start_index):

                limit -= 1  # handle limit
                if limit < 0:
                    return

                # parse raw data
                cache_details = row.find("span", "cache-details").text.split("|")
                wp = cache_details[1].strip()

                # create and fill cache object
                # values are sanitized and converted in Cache setters
                c = Cache(self, wp)
                c.type = cache_details[0]
                c.name = row.find("span", "cache-name").text
                badge = row.find("svg", class_="badge")
                c.found = "found" in str(badge) if badge is not None else False
                c.favorites = row.find(attrs={"data-column": "FavoritePoint"}).text
                c.state = not (row.get("class") and "disabled" in row.get("class"))
                c.pm_only = row.find("td", "pm-upsell") is not None

                if c.pm_only:
                    # PM only caches doesn't have other attributes filled in
                    yield c
                    continue

                c.size = localized_size_mapping[row.find(attrs={"data-column": "ContainerSize"}).text.strip()]
                c.difficulty = row.find(attrs={"data-column": "Difficulty"}).text
                c.terrain = row.find(attrs={"data-column": "Terrain"}).text
                c.hidden = row.find(attrs={"data-column": "PlaceDate"}).text
                c.author = row.find("span", "owner").text[3:]  # delete "by "

                logging.debug("Cache parsed: {}".format(c))
                yield c

            start_index += 1
Exemple #7
0
    def search(self, point, limit=float("inf")):
        """Return a generator of caches around some point.

        Search for caches around some point by loading search pages and parsing the data from these
        pages. Yield :class:`.Cache` objects filled with data from search page. You can provide limit
        as a convinient way to stop generator after certain number of caches.

        :param .geo.Point point: Search center point.
        :param int limit: Maximum number of caches to generate.
        """
        logging.info("Searching at {}".format(point))

        start_index = 0
        while True:
            # get one page
            geocaches_table, whole_page = self._search_get_page(point, start_index)

            if not geocaches_table:
                # result is empty - no more caches
                return

            # prepare language-dependant mappings
            if start_index == 0:
                cache_sizes_filter_wrapper = whole_page.find("div", class_="cache-sizes-wrapper")
                localized_size_mapping = {
                    # key = "Small" (localized), value = Size.small
                    label.find("span").text.strip(): Size.from_number(label.find("input").get("value"))
                    for label in cache_sizes_filter_wrapper.find_all("label")
                }

            # parse caches in result
            for start_index, row in enumerate(geocaches_table.find_all("tr"), start_index):

                limit -= 1  # handle limit
                if limit < 0:
                    return

                # parse raw data
                cache_details = row.find("span", "cache-details").text.split("|")
                wp = cache_details[1].strip()

                # create and fill cache object
                # values are sanitized and converted in Cache setters
                c = Cache(self, wp)
                c.type = cache_details[0]
                c.name = row.find("span", "cache-name").text
                badge = row.find("svg", class_="badge")
                c.found = "found" in str(badge) if badge is not None else False
                c.favorites = row.find(attrs={"data-column": "FavoritePoint"}).text
                c.state = not (row.get("class") and "disabled" in row.get("class"))
                c.pm_only = row.find("td", "pm-upsell") is not None

                if c.pm_only:
                    # PM only caches doesn't have other attributes filled in
                    yield c
                    continue

                c.size = localized_size_mapping[row.find(attrs={"data-column": "ContainerSize"}).text.strip()]
                c.difficulty = row.find(attrs={"data-column": "Difficulty"}).text
                c.terrain = row.find(attrs={"data-column": "Terrain"}).text
                c.hidden = row.find(attrs={"data-column": "PlaceDate"}).text
                c.author = row.find("span", "owner").text[3:]  # delete "by "

                logging.debug("Cache parsed: {}".format(c))
                yield c

            start_index += 1
Exemple #8
0
    def search(self, point, limit=0):
        """Returns a generator object of caches around some point."""

        assert isinstance(point, Point)
        assert type(limit) is int

        logging.info("Searching at %s...", point)

        start_index = 0
        while True:
            # get one page
            page = self._search_get_page(point, start_index)

            if not page:
                # result is empty - no more caches
                raise StopIteration()

            # parse caches in result
            for start_index, row in enumerate(
                    BeautifulSoup(page).find_all("tr"), start_index):

                if limit > 0 and start_index == limit:
                    raise StopIteration()

                # parse raw data
                cache_details = row.find("span",
                                         "cache-details").text.split("|")
                wp = cache_details[1].strip()

                # create and fill cache object
                c = Cache(wp, self)
                c.cache_type = cache_details[0].strip()
                c.name = row.find("span", "cache-name").text
                c.found = row.find("img", title="Found It!") is not None
                c.favorites = int(
                    row.find(attrs={
                        "data-column": "FavoritePoint"
                    }).text)
                c.state = not (row.get("class")
                               and "disabled" in row.get("class"))
                c.pm_only = row.find("td", "pm-upsell") is not None

                if c.pm_only:
                    # PM only caches doesn't have other attributes filled in
                    yield c
                    continue

                c.size = row.find(attrs={"data-column": "ContainerSize"}).text
                c.difficulty = float(
                    row.find(attrs={
                        "data-column": "Difficulty"
                    }).text)
                c.terrain = float(
                    row.find(attrs={
                        "data-column": "Terrain"
                    }).text)
                c.hidden = Util.parse_date(
                    row.find(attrs={
                        "data-column": "PlaceDate"
                    }).text)
                c.author = row.find("span", "owner").text[3:]  # delete "by "

                logging.debug("Cache parsed: %s", c)
                yield c

            start_index += 1