Пример #1
0
 def test_list_url_both_args(self):
     expected = "https://play.google.com/store/apps/category/GAME_ACTION/collection/topselling_free"
     self.assertEqual(
         expected,
         build_collection_url(category=self.category,
                              collection=self.collection),
     )
Пример #2
0
    def collection(
        self,
        collection_id,
        category_id=None,
        results=None,
        page=None,
        age=None,
        detailed=False,
    ):
        """Sends a POST request and fetches a list of applications belonging to
        the collection and an optional category.

        :param collection_id: the collection id, e.g. 'NEW_FREE'.
        :param category_id: (optional) the category id, e.g. 'GAME_ACTION'.
        :param results: the number of apps to retrieve at a time.
        :param page: page number to retrieve; limitation: page * results <= 500.
        :param age: an age range to filter by (only for FAMILY categories)
        :param detailed: if True, sends request per app for its full detail
        :return: a list of app dictionaries
        """
        if collection_id not in COLLECTIONS and not collection_id.startswith(
                "promotion"):
            raise ValueError("Invalid collection_id '{collection}'.".format(
                collection=collection_id))
        collection_name = COLLECTIONS.get(collection_id) or collection_id

        category = "" if category_id is None else CATEGORIES.get(category_id)
        if category is None:
            raise ValueError("Invalid category_id '{category}'.".format(
                category=category_id))

        results = s.NUM_RESULTS if results is None else results
        if results > 120:
            raise ValueError("Number of results cannot be more than 120.")

        page = 0 if page is None else page
        if page * results > 500:
            raise ValueError(
                "Start (page * results) cannot be greater than 500.")

        if category.startswith("FAMILY") and age is not None:
            self.params["age"] = AGE_RANGE[age]

        url = build_collection_url(category, collection_name)
        data = generate_post_data(results, page)
        response = send_request("POST", url, data, self.params)

        if detailed:
            apps = self._parse_multiple_apps(response)
        else:
            soup = BeautifulSoup(response.content,
                                 "lxml",
                                 from_encoding="utf8")
            apps = [
                parse_card_info(app_card)
                for app_card in soup.select('div[data-uitype="500"]')
            ]

        return apps
Пример #3
0
    def collection(self, collection_id, category_id=None, results=None,
                   page=None, age=None, detailed=False):
        """Sends a POST request and fetches a list of applications belonging to
        the collection and an optional category.

        :param collection_id: the collection id, e.g. 'NEW_FREE'.
        :param category_id: (optional) the category id, e.g. 'GAME_ACTION'.
        :param results: the number of apps to retrieve at a time.
        :param page: page number to retrieve; limitation: page * results <= 500.
        :param age: an age range to filter by (only for FAMILY categories)
        :param detailed: if True, sends request per app for its full detail
        :return: a list of app dictionaries
        """
        if (collection_id not in COLLECTIONS and
                not collection_id.startswith('promotion')):
            raise ValueError('Invalid collection_id \'{collection}\'.'.format(
                collection=collection_id))
        collection_name = COLLECTIONS.get(collection_id) or collection_id

        category = '' if category_id is None else CATEGORIES.get(category_id)
        if category is None:
            raise ValueError('Invalid category_id \'{category}\'.'.format(
                category=category_id))

        results = s.NUM_RESULTS if results is None else results
        if results > 120:
            raise ValueError('Number of results cannot be more than 120.')

        page = 0 if page is None else page
        if page * results > 500:
            raise ValueError('Start (page * results) cannot be greater than 500.')

        if category.startswith('FAMILY') and age is not None:
            self.params['age'] = AGE_RANGE[age]

        url = build_collection_url(category, collection_name)
        data = generate_post_data(results, page)
        response = send_request('POST', url, data, self.params)

        if detailed:
            apps = self._parse_multiple_apps(response)
        else:
            soup = BeautifulSoup(response.content, 'lxml', from_encoding='utf8')
            apps = [parse_card_info(app_card)
                    for app_card in soup.select('div[data-uitype="500"]')]

        return apps
    def collection(self,
                   collection_id,
                   category_id=None,
                   results=None,
                   page=None,
                   age=None,
                   detailed=False):

        if (collection_id not in COLLECTIONS
                and not collection_id.startswith('promotion')):
            raise ValueError('Invalid collection_id \'{collection}\'.'.format(
                collection=collection_id))
        collection_name = COLLECTIONS.get(collection_id) or collection_id

        category = '' if category_id is None else CATEGORIES.get(category_id)
        if category is None:
            raise ValueError('Invalid category_id \'{category}\'.'.format(
                category=category_id))

        results = s.NUM_RESULTS if results is None else results
        if results > 120:
            raise ValueError('Number of results cannot be more than 120.')

        page = 0 if page is None else page
        if page * results > 500:
            raise ValueError(
                'Start (page * results) cannot be greater than 500.')

        if category.startswith('FAMILY') and age is not None:
            self.params['age'] = AGE_RANGE[age]

        url = build_collection_url(category, collection_name)
        data = generate_post_data(results, page)
        response = send_request('POST', url, data, self.params)

        if detailed:
            apps = self._parse_multiple_apps(response)
        else:
            soup = BeautifulSoup(response.content,
                                 'lxml',
                                 from_encoding='utf8')
            apps = [
                parse_card_info(app_card)
                for app_card in soup.select('div[data-uitype="500"]')
            ]

        return apps
Пример #5
0
    async def collection(self, coln_id, catg_id=None, results=None, page=None):
        coln_name = coln_id if coln_id.startswith(
            'promotion') else lists.COLLECTIONS.get(coln_id)
        if coln_name is None:
            raise ValueError(
                'INVALID_COLLECTION_ID: {coln}'.format(coln=coln_id))

        catg_name = '' if catg_id is None else lists.CATEGORIES.get(catg_id)
        if catg_name is None:
            raise ValueError(
                'INVALID_CATEGORY_ID: {catg}'.format(catg=catg_id))
        results = settings.NUM_RESULTS if results is None else results
        if results > 120:
            raise ValueError('Number of results cannot be more than 120.')

        page = 0 if page is None else page
        if page * results > 500:
            raise ValueError(
                'Start (page * results) cannot be greater than 500.')

        url = utils.build_collection_url(catg_name, coln_name)
        data = utils.generate_post_data(results, page)
        try:
            response = await self.send_request('POST',
                                               url,
                                               data,
                                               params=self._params)
            soup = BeautifulSoup(response, 'lxml')
        except ClientResponseError as e:
            raise ValueError(
                'INVALID_COLLECTION_OR_CATEGORY_ID: {coln}; {catg} {error}'.
                format(coln=coln_id, catg=catg_id, error=e))
        apps = list(
            map(utils.parse_card_info, soup.select('div[data-uitype="500"]')))
        # TODO: soup parsing failing for certain scenarios
        # $ref: Exception #1 @ observed_error.log
        return prune_data(apps)
Пример #6
0
 def test_list_url_only_collection(self):
     expected = "https://play.google.com/store/apps/collection/topselling_free"
     self.assertEqual(expected,
                      build_collection_url(collection=self.collection))
Пример #7
0
 def test_list_url_only_category(self):
     expected = "https://play.google.com/store/apps/category/GAME_ACTION"
     self.assertEqual(build_collection_url(category=self.category),
                      expected)
Пример #8
0
 def test_list_url_no_args(self):
     expected = "https://play.google.com/store/apps"
     self.assertEqual(build_collection_url(), expected)
Пример #9
0
 def test_list_url_both_args(self):
     expected = 'https://play.google.com/store/apps/category/GAME_ACTION/collection/topselling_free'
     self.assertEqual(build_collection_url(
         category=self.category, collection=self.collection), expected)
Пример #10
0
 def test_list_url_only_collection(self):
     expected = 'https://play.google.com/store/apps/collection/topselling_free'
     self.assertEqual(build_collection_url(collection=self.collection), expected)
Пример #11
0
 def test_list_url_only_category(self):
     expected = 'https://play.google.com/store/apps/category/GAME_ACTION'
     self.assertEqual(build_collection_url(category=self.category), expected)
Пример #12
0
 def test_list_url_no_args(self):
     expected = 'https://play.google.com/store/apps'
     self.assertEqual(build_collection_url(), expected)